34  :check_forward_default_(check_forward_default_default_),
 
   35   forward_default_residual_warning_tol_(warning_tol_default_),
 
   36   forward_default_residual_error_tol_(error_tol_default_),
 
   37   forward_default_solution_error_warning_tol_(warning_tol_default_),
 
   38   forward_default_solution_error_error_tol_(error_tol_default_),
 
   39   check_forward_residual_(check_forward_residual_default_),
 
   40   forward_residual_solve_tol_(solve_tol_default_),
 
   41   forward_residual_slack_warning_tol_(slack_warning_tol_default_),
 
   42   forward_residual_slack_error_tol_(slack_error_tol_default_),
 
   43   check_adjoint_default_(check_adjoint_default_default_),
 
   44   adjoint_default_residual_warning_tol_(warning_tol_default_),
 
   45   adjoint_default_residual_error_tol_(error_tol_default_),
 
   46   adjoint_default_solution_error_warning_tol_(warning_tol_default_),
 
   47   adjoint_default_solution_error_error_tol_(error_tol_default_),
 
   48   check_adjoint_residual_(check_adjoint_residual_default_),
 
   49   adjoint_residual_solve_tol_(solve_tol_default_),
 
   50   adjoint_residual_slack_warning_tol_(slack_warning_tol_default_),
 
   51   adjoint_residual_slack_error_tol_(slack_error_tol_default_),
 
   52   num_random_vectors_(num_random_vectors_default_),
 
   53   show_all_tests_(show_all_tests_default_),
 
   54   dump_all_(dump_all_default_),
 
   55   num_rhs_(num_rhs_default_)
 
 
  167  using Teuchos::optInArg;
 
  168  using Teuchos::inoutArg;
 
  174  bool success = 
true, result;
 
  175  const int l_num_rhs = this->num_rhs();
 
  180  OSTab tab(out,1,
"THYRA");
 
  183    *out <<endl<< 
"*** Entering LinearOpWithSolveTester<"<<ST::name()<<
">::check(op,...) ...\n";
 
  184    if(show_all_tests()) {
 
  185      *out <<endl<< 
"describe forward op:\n" << Teuchos::describe(op,verbLevel);
 
  187        *out <<endl<< 
"describe adjoint op:\n";
 
  188        describeLinearOp<Scalar>(
 
  195      *out <<endl<< 
"describe op: " << op.
description() << endl;
 
  202  if( check_forward_default() ) {
 
  204    if(out.
get()) *out <<endl<< 
"this->check_forward_default()==true: Checking the default forward solve ... ";
 
  209    bool these_results = 
true;
 
  213    if (!result) these_results = 
false;
 
  218        <<endl<< 
"Checking that the forward default solve matches the forward operator:\n" 
  219        <<endl<< 
"  inv(Op)*Op*v1 == v1" 
  222        <<endl<< 
"  \\___________/" 
  225        <<endl<< 
"  v4 = v3-v1" 
  226        <<endl<< 
"  v5 = Op*v3-v2" 
  228        <<endl<< 
"  norm(v4)/norm(v1) <= forward_default_solution_error_error_tol()" 
  229        <<endl<< 
"  norm(v5)/norm(v2) <= forward_default_residual_error_tol()" 
  232      for( 
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
 
  236        *testOut <<endl<< 
"Random vector tests = " << rand_vec_i << endl;
 
  240        *testOut <<endl<< 
"v1 = randomize(-1,+1); ...\n" ;
 
  242        Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), v1.
ptr() );
 
  243        if(dump_all()) *testOut <<endl<< 
"v1 =\n" << describe(*v1,verbLevel);
 
  245        *testOut <<endl<< 
"v2 = Op*v1 ...\n" ;
 
  250        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  251        if(dump_all()) *testOut <<endl<< 
"v2 =\n" << describe(*v2,verbLevel);
 
  253        *testOut <<endl<< 
"v3 = inv(Op)*v2 ...\n" ;
 
  255        assign(v3.
ptr(), ST::zero());
 
  258          VOTS lowsTempState(
Teuchos::rcp(&op,
false),testOut,verbLevel);
 
  260          solveStatus = solve<Scalar>(op, 
NOTRANS, *v2, v3.
ptr());
 
  262          OSTab(testOut).o() <<
"\n=> Solve time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  264        if(dump_all()) *testOut <<endl<< 
"v3 =\n" << describe(*v3,verbLevel);
 
  266          <<endl<< 
"solve status:\n";
 
  267        OSTab(testOut).o() << solveStatus;
 
  269        *testOut <<endl<< 
"v4 = v3 - v1 ...\n" ;
 
  271        V_VmV( v4.
ptr(), *v3, *v1 );
 
  272        if(dump_all()) *testOut <<endl<< 
"v4 =\n" << describe(*v4,verbLevel);
 
  274        *testOut <<endl<< 
"v5 = Op*v3 - v2 ...\n" ;
 
  276        assign( v5.
ptr(), *v2 );
 
  278        Thyra::apply(op, 
NOTRANS, *v3, v5.
ptr(), as<Scalar>(1.0) ,as<Scalar>(-1.0));
 
  280        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  281        if(dump_all()) *testOut <<endl<< 
"v5 =\n" << describe(*v5,verbLevel);
 
  283        Array<ScalarMag> norms_v1(l_num_rhs), norms_v4(l_num_rhs), norms_v4_norms_v1(l_num_rhs);
 
  284        norms(*v1, norms_v1());
 
  285        norms(*v4, norms_v4());
 
  287          norms_v4.begin(), norms_v4.end(), norms_v1.begin(), norms_v4_norms_v1.
begin()
 
  288          ,std::divides<ScalarMag>()
 
  291        result = testMaxErrors<Scalar>(
 
  292          "norm(v4)/norm(v1)", norms_v4_norms_v1(),
 
  293          "forward_default_solution_error_error_tol()",
 
  294          forward_default_solution_error_error_tol(),
 
  295          "forward_default_solution_error_warning_tol()",
 
  296          forward_default_solution_error_warning_tol(),
 
  299        if(!result) these_results = 
false;
 
  301        Array<ScalarMag> norms_v2(l_num_rhs), norms_v5(l_num_rhs), norms_v5_norms_v2(l_num_rhs);
 
  302        norms(*v2, norms_v2());
 
  303        norms(*v5, norms_v5());
 
  305          norms_v5.begin(), norms_v5.end(), norms_v2.begin(), norms_v5_norms_v2.
begin()
 
  306          ,std::divides<ScalarMag>()
 
  309        result = testMaxErrors<Scalar>(
 
  310          "norm(v5)/norm(v2)", norms_v5_norms_v2(),
 
  311          "forward_default_residual_error_tol()",
 
  312          forward_default_residual_error_tol(),
 
  313          "forward_default_residual_warning_tol()",
 
  314          forward_default_residual_warning_tol(),
 
  317        if(!result) these_results = 
false;
 
  322      *testOut <<endl<< 
"Forward operator not supported, skipping check!\n";
 
  329    if(out.
get()) *out <<endl<< 
"this->check_forward_default()==false: Skipping the check of the default forward solve!\n";
 
  332  if( check_forward_residual() ) {
 
  334    if(out.
get()) *out <<endl<< 
"this->check_forward_residual()==true: Checking the forward solve with a tolerance on the residual ... ";
 
  339    bool these_results = 
true;
 
  343    if (!result) these_results = 
false;
 
  348        <<endl<< 
"Checking that the forward solve matches the forward operator to a residual tolerance:\n" 
  349        <<endl<< 
"  v3 = inv(Op)*Op*v1" 
  353        <<endl<< 
"  v4 = Op*v3-v2" 
  355        <<endl<< 
"  norm(v4)/norm(v2) <= forward_residual_solve_tol() + forward_residual_slack_error_tol()" 
  358      for( 
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
 
  362        *testOut <<endl<< 
"Random vector tests = " << rand_vec_i << endl;
 
  366        *testOut <<endl<< 
"v1 = randomize(-1,+1); ...\n" ;
 
  368        Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), v1.
ptr() );
 
  369        if(dump_all()) *testOut <<endl<< 
"v1 =\n" << describe(*v1,verbLevel);
 
  371        *testOut <<endl<< 
"v2 = Op*v1 ...\n" ;
 
  376        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  377        if(dump_all()) *testOut <<endl<< 
"v2 =\n" << describe(*v2,verbLevel);
 
  379        *testOut <<endl<< 
"v3 = inv(Op)*v2 ...\n" ;
 
  383          ,forward_residual_solve_tol()
 
  385        assign(v3.
ptr(), ST::zero());
 
  388          VOTS lowsTempState(
Teuchos::rcp(&op,
false),testOut,verbLevel);
 
  390          solveStatus = solve<Scalar>(op, 
NOTRANS, *v2, v3.
ptr(),
 
  391            optInArg(solveCriteria));
 
  393          OSTab(testOut).o() <<
"\n=> Solve time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  395        if(dump_all()) *testOut <<endl<< 
"v3 =\n" << describe(*v3,verbLevel);
 
  397          <<endl<< 
"solve status:\n";
 
  398        OSTab(testOut).o() << solveStatus;
 
  400        if(!result) these_results = 
false;
 
  402          <<endl<< 
"check: solveStatus = " << 
toString(solveStatus.
solveStatus) << 
" == SOLVE_STATUS_CONVERGED : " 
  405        *testOut <<endl<< 
"v4 = Op*v3 - v2 ...\n" ;
 
  407        assign( v4.
ptr(), *v2 );
 
  409        Thyra::apply(op, 
NOTRANS, *v3, v4.
ptr(), as<Scalar>(1.0), as<Scalar>(-1.0));
 
  411        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  412        if(dump_all()) *testOut <<endl<< 
"v4 =\n" << describe(*v4,verbLevel);
 
  414        Array<ScalarMag> norms_v2(l_num_rhs), norms_v4(l_num_rhs), norms_v4_norms_v2(l_num_rhs);
 
  415        norms(*v2, norms_v2());
 
  416        norms(*v4, norms_v4());
 
  418          norms_v4.begin(),norms_v4.end(),norms_v2.begin(),norms_v4_norms_v2.
begin()
 
  419          ,std::divides<ScalarMag>()
 
  422        result = testMaxErrors<Scalar>(
 
  423          "norm(v4)/norm(v2)", norms_v4_norms_v2(),
 
  424          "forward_residual_solve_tol()+forward_residual_slack_error_tol()",
 
  425          as<ScalarMag>(forward_residual_solve_tol()+forward_residual_slack_error_tol()),
 
  426          "forward_residual_solve_tol()_slack_warning_tol()",
 
  427          as<ScalarMag>(forward_residual_solve_tol()+forward_residual_slack_warning_tol()),
 
  430        if(!result) these_results = 
false;
 
  435      *testOut <<endl<< 
"Forward operator not supported, skipping check!\n";
 
  442    if(out.
get()) *out <<endl<< 
"this->check_forward_residual()==false: Skipping the check of the forward solve with a tolerance on the residual!\n";
 
  445  if( check_adjoint_default() ) {
 
  447    if(out.
get()) *out <<endl<< 
"this->check_adjoint_default()==true: Checking the default adjoint solve ... ";
 
  452    bool these_results = 
true;
 
  456    if (!result) these_results = 
false;
 
  461        <<endl<< 
"Checking that the adjoint default solve matches the adjoint operator:\n" 
  462        <<endl<< 
"  inv(Op')*Op'*v1 == v1" 
  465        <<endl<< 
"  \\_____________/" 
  468        <<endl<< 
"  v4 = v3-v1" 
  469        <<endl<< 
"  v5 = Op'*v3-v2" 
  471        <<endl<< 
"  norm(v4)/norm(v1) <= adjoint_default_solution_error_error_tol()" 
  472        <<endl<< 
"  norm(v5)/norm(v2) <= adjoint_default_residual_error_tol()" 
  475      for( 
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
 
  479        *testOut <<endl<< 
"Random vector tests = " << rand_vec_i << endl;
 
  483        *testOut <<endl<< 
"v1 = randomize(-1,+1); ...\n" ;
 
  485        Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), v1.
ptr() );
 
  486        if(dump_all()) *testOut <<endl<< 
"v1 =\n" << describe(*v1,verbLevel);
 
  488        *testOut <<endl<< 
"v2 = Op'*v1 ...\n" ;
 
  493        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  494        if(dump_all()) *testOut <<endl<< 
"v2 =\n" << describe(*v2,verbLevel);
 
  496        *testOut <<endl<< 
"v3 = inv(Op')*v2 ...\n" ;
 
  498        assign(v3.
ptr(), ST::zero());
 
  501          VOTS lowsTempState(
Teuchos::rcp(&op,
false),testOut,verbLevel);
 
  503          solveStatus = solve<Scalar>(op, 
CONJTRANS, *v2, v3.
ptr());
 
  505          OSTab(testOut).o() <<
"\n=> Solve time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  507        if(dump_all()) *testOut <<endl<< 
"v3 =\n" << describe(*v3,verbLevel);
 
  509          <<endl<< 
"solve status:\n";
 
  510        OSTab(testOut).o() << solveStatus;
 
  512        *testOut <<endl<< 
"v4 = v3 - v1 ...\n" ;
 
  514        V_VmV( v4.
ptr(), *v3, *v1 );
 
  515        if(dump_all()) *testOut <<endl<< 
"v4 =\n" << describe(*v4,verbLevel);
 
  517        *testOut <<endl<< 
"v5 = Op'*v3 - v2 ...\n" ;
 
  519        assign( v5.
ptr(), *v2 );
 
  521        Thyra::apply(op, 
CONJTRANS, *v3, v5.
ptr(), as<Scalar>(1.0), as<Scalar>(-1.0));
 
  523        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  524        if(dump_all()) *testOut <<endl<< 
"v5 =\n" << describe(*v5,verbLevel);
 
  526        Array<ScalarMag> norms_v1(l_num_rhs), norms_v4(l_num_rhs), norms_v4_norms_v1(l_num_rhs);
 
  527        norms(*v1, norms_v1());
 
  528        norms(*v4, norms_v4());
 
  530          norms_v4.begin(),norms_v4.end(),norms_v1.begin(),norms_v4_norms_v1.
begin()
 
  531          ,std::divides<ScalarMag>()
 
  534        result = testMaxErrors<Scalar>(
 
  535          "norm(v4)/norm(v1)", norms_v4_norms_v1(),
 
  536          "adjoint_default_solution_error_error_tol()",
 
  537          adjoint_default_solution_error_error_tol(),
 
  538          "adjoint_default_solution_error_warning_tol()",
 
  539          adjoint_default_solution_error_warning_tol(),
 
  542        if(!result) these_results = 
false;
 
  544        Array<ScalarMag> norms_v2(l_num_rhs), norms_v5(l_num_rhs), norms_v5_norms_v2(l_num_rhs);
 
  545        norms(*v2, norms_v2());
 
  546        norms(*v5, norms_v5());
 
  548          norms_v5.begin(), norms_v5.end(), norms_v2.begin(), norms_v5_norms_v2.
begin()
 
  549          ,std::divides<ScalarMag>()
 
  552        result = testMaxErrors<Scalar>(
 
  553          "norm(v5)/norm(v2)", norms_v5_norms_v2(),
 
  554          "adjoint_default_residual_error_tol()",
 
  555          adjoint_default_residual_error_tol(),
 
  556          "adjoint_default_residual_warning_tol()",
 
  557          adjoint_default_residual_warning_tol(),
 
  560        if(!result) these_results = 
false;
 
  565      *testOut <<endl<< 
"Adjoint operator not supported, skipping check!\n";
 
  572    if(out.
get()) *out <<endl<< 
"this->check_adjoint_default()==false: Skipping the check of the adjoint solve with a default tolerance!\n";
 
  575  if( check_adjoint_residual() ) {
 
  577    if(out.
get()) *out <<endl<< 
"this->check_adjoint_residual()==true: Checking the adjoint solve with a tolerance on the residual ... ";
 
  582    bool these_results = 
true;
 
  586    if (!result) these_results = 
false;
 
  591        <<endl<< 
"Checking that the adjoint solve matches the adjoint operator to a residual tolerance:\n" 
  592        <<endl<< 
"  v3 = inv(Op')*Op'*v1" 
  596        <<endl<< 
"  v4 = Op'*v3-v2" 
  598        <<endl<< 
"  norm(v4)/norm(v2) <= adjoint_residual_solve_tol() + adjoint_residual_slack_error_tol()" 
  601      for( 
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
 
  605        *testOut <<endl<< 
"Random vector tests = " << rand_vec_i << endl;
 
  609        *testOut <<endl<< 
"v1 = randomize(-1,+1); ...\n" ;
 
  611        Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), v1.
ptr() );
 
  612        if(dump_all()) *testOut <<endl<< 
"v1 =\n" << describe(*v1,verbLevel);
 
  614        *testOut <<endl<< 
"v2 = Op'*v1 ...\n" ;
 
  619        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  620        if(dump_all()) *testOut <<endl<< 
"v2 =\n" << describe(*v2,verbLevel);
 
  622        *testOut <<endl<< 
"v3 = inv(Op')*v2 ...\n" ;
 
  626          ,adjoint_residual_solve_tol()
 
  628        assign(v3.
ptr(), ST::zero());
 
  631          VOTS lowsTempState(
Teuchos::rcp(&op,
false),testOut,verbLevel);
 
  633          solveStatus = solve<Scalar>(op, 
CONJTRANS, *v2, v3.
ptr(), optInArg(solveCriteria));
 
  635          OSTab(testOut).o() <<
"\n=> Solve time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  637        if(dump_all()) *testOut <<endl<< 
"v3 =\n" << describe(*v3,verbLevel);
 
  639          <<endl<< 
"solve status:\n";
 
  640        OSTab(testOut).o() << solveStatus;
 
  642        if(!result) these_results = 
false;
 
  644          <<endl<< 
"check: solveStatus = " << 
toString(solveStatus.
solveStatus) << 
" == SOLVE_STATUS_CONVERGED : " 
  647          *testOut <<endl<<
"achievedTol==unknownTolerance(): Setting achievedTol = adjoint_residual_solve_tol() = "<<adjoint_residual_solve_tol()<<endl;
 
  649        *testOut <<endl<< 
"v4 = Op'*v3 - v2 ...\n" ;
 
  651        assign( v4.
ptr(), *v2 );
 
  653        Thyra::apply(op, 
CONJTRANS, *v3, v4.
ptr(), as<Scalar>(1.0), as<Scalar>(-1.0));
 
  655        OSTab(testOut).o() <<
"\n=> Apply time = "<<timer.
totalElapsedTime()<<
" sec\n";
 
  656        if(dump_all()) *testOut <<endl<< 
"v4 =\n" << describe(*v4,verbLevel);
 
  658        Array<ScalarMag> norms_v2(l_num_rhs), norms_v4(l_num_rhs), norms_v4_norms_v2(l_num_rhs);
 
  659        norms(*v2, norms_v2());
 
  660        norms(*v4, norms_v4());
 
  662          norms_v4.begin(),norms_v4.end(),norms_v2.begin(),norms_v4_norms_v2.
begin()
 
  663          ,std::divides<ScalarMag>()
 
  666        result = testMaxErrors<Scalar>(
 
  667          "norm(v4)/norm(v2)", norms_v4_norms_v2(),
 
  668          "adjoint_residual_solve_tol()+adjoint_residual_slack_error_tol()",
 
  669          as<ScalarMag>(adjoint_residual_solve_tol()+adjoint_residual_slack_error_tol()),
 
  670          "adjoint_residual_solve_tol()_slack_warning_tol()",
 
  671          as<ScalarMag>(adjoint_residual_solve_tol()+adjoint_residual_slack_warning_tol()),
 
  674        if(!result) these_results = 
false;
 
  679      *testOut <<endl<< 
"Adjoint operator not supported, skipping check!\n";
 
  687      *out <<endl<< 
"this->check_adjoint_residual()==false: Skipping the check of the adjoint solve with a tolerance on the residual!\n";
 
  692      *out <<endl<<
"Congratulations, this LinearOpWithSolveBase object seems to check out!\n";
 
  694      *out <<endl<<
"Oh no, at least one of the tests performed with this LinearOpWithSolveBase object failed (see above failures)!\n";
 
  695    *out <<endl<< 
"*** Leaving LinearOpWithSolveTester<"<<ST::name()<<
">::check(...)\n";