Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
test_single_aztecoo_thyra_solver.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //         Stratimikos: Thyra-based strategies for linear solvers
00005 //                Copyright (2006) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 #include "test_single_aztecoo_thyra_solver.hpp"
00042 
00043 #ifndef SUN_CXX
00044 
00045 #include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
00046 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
00047 #include "Thyra_PreconditionerFactoryHelpers.hpp"
00048 #include "Thyra_LinearOpWithSolveFactoryExamples.hpp"
00049 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
00050 #include "Thyra_EpetraLinearOp.hpp"
00051 #include "Thyra_LinearOpTester.hpp"
00052 #include "Thyra_LinearOpWithSolveBase.hpp"
00053 #include "Thyra_LinearOpWithSolveTester.hpp"
00054 #include "EpetraExt_readEpetraLinearSystem.h"
00055 #include "Epetra_SerialComm.h"
00056 #include "Teuchos_ParameterList.hpp"
00057 #ifdef HAVE_AZTECOO_IFPACK
00058 #  include "Thyra_IfpackPreconditionerFactory.hpp"
00059 #endif
00060 #ifdef HAVE_MPI
00061 #  include "Epetra_MpiComm.h"
00062 #endif
00063 
00064 #endif // SUN_CXX
00065 
00066 bool Thyra::test_single_aztecoo_thyra_solver(
00067   const std::string                       matrixFile
00068   ,const bool                             testTranspose
00069   ,const int                              numRandomVectors
00070   ,const double                           maxFwdError
00071   ,const double                           maxResid
00072   ,const double                           maxSolutionError
00073   ,const bool                             showAllTests
00074   ,const bool                             dumpAll
00075   ,Teuchos::ParameterList                 *aztecooLOWSFPL
00076   ,Teuchos::FancyOStream                  *out_arg
00077   )
00078 {
00079   using Teuchos::rcp;
00080   using Teuchos::RCP;
00081   using Teuchos::OSTab;
00082   typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
00083   bool result, success = true;
00084 
00085   RCP<Teuchos::FancyOStream>
00086     out = Teuchos::rcp(out_arg,false);
00087 
00088   try {
00089 
00090 #ifndef SUN_CXX
00091 
00092     if(out.get()) {
00093       *out
00094         << "\n***"
00095         << "\n*** Testing Thyra::AztecOOLinearOpWithSolveFactory (and Thyra::AztecOOLinearOpWithSolve)"
00096         << "\n***\n"
00097         << "\nEchoing input options:"
00098         << "\n  matrixFile             = " << matrixFile
00099         << "\n  testTranspose          = " << testTranspose
00100         << "\n  numRandomVectors       = " << numRandomVectors
00101         << "\n  maxFwdError            = " << maxFwdError
00102         << "\n  maxResid               = " << maxResid
00103         << "\n  showAllTests           = " << showAllTests
00104         << "\n  dumpAll                = " << dumpAll
00105         << std::endl;
00106     }
00107 
00108     const bool useAztecPrec = (
00109       aztecooLOWSFPL
00110       &&
00111       aztecooLOWSFPL->sublist("Forward Solve")
00112       .sublist("AztecOO Settings")
00113       .get("Aztec Preconditioner","none")!="none"
00114       );
00115 
00116     if(out.get()) {
00117       if(useAztecPrec)
00118         *out << "\nUsing aztec preconditioning so we will not test adjoint solves using internal preconditioning ...\n";
00119     }
00120 
00121     if(out.get()) *out << "\nA) Reading in an epetra matrix A from the file \'"<<matrixFile<<"\' ...\n";
00122 
00123 #ifdef HAVE_MPI
00124     Epetra_MpiComm comm(MPI_COMM_WORLD);
00125 #else
00126     Epetra_SerialComm comm;
00127 #endif
00128     RCP<Epetra_CrsMatrix> epetra_A;
00129     EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A );
00130 
00131     RCP<const LinearOpBase<double> > A = Thyra::epetraLinearOp(epetra_A);
00132 
00133     if(out.get() && dumpAll) *out << "\ndescribe(A) =\n" << describe(*A,Teuchos::VERB_EXTREME);
00134 
00135     if(out.get()) *out << "\nB) Creating a AztecOOLinearOpWithSolveFactory object opFactory ...\n";
00136 
00137     RCP<LinearOpWithSolveFactoryBase<double> >
00138       lowsFactory = Teuchos::rcp(new AztecOOLinearOpWithSolveFactory());
00139     if(out.get()) {
00140       *out << "\nlowsFactory.getValidParameters() initially:\n";
00141       lowsFactory->getValidParameters()->print(OSTab(out).o(),PLPrintOptions().showTypes(true).showDoc(true));
00142     }
00143     TEUCHOS_ASSERT(aztecooLOWSFPL != NULL);
00144     aztecooLOWSFPL->sublist("Forward Solve").set("Tolerance",maxResid);
00145     aztecooLOWSFPL->sublist("Adjoint Solve").set("Tolerance",maxResid);
00146     if(showAllTests) {
00147       aztecooLOWSFPL->set("Output Every RHS",bool(true));
00148     }
00149     if(out.get()) {
00150       *out << "\naztecooLOWSFPL before setting parameters:\n";
00151       aztecooLOWSFPL->print(OSTab(out).o(),0,true);
00152     }
00153     if(aztecooLOWSFPL) lowsFactory->setParameterList(Teuchos::rcp(aztecooLOWSFPL,false));
00154 
00155     if(out.get()) *out << "\nC) Creating a AztecOOLinearOpWithSolve object nsA from A ...\n";
00156 
00157     RCP<LinearOpWithSolveBase<double> >
00158       nsA = lowsFactory->createOp();
00159 
00160     Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
00161 
00162     if(out.get()) *out << "\nD) Testing the LinearOpBase interface of nsA ...\n";
00163 
00164     LinearOpTester<double> linearOpTester;
00165     linearOpTester.check_adjoint(testTranspose);
00166     linearOpTester.num_random_vectors(numRandomVectors);
00167     linearOpTester.set_all_error_tol(maxFwdError);
00168     linearOpTester.set_all_warning_tol(1e-2*maxFwdError);
00169     linearOpTester.show_all_tests(showAllTests);
00170     linearOpTester.dump_all(dumpAll);
00171     Thyra::seed_randomize<double>(0);
00172     result = linearOpTester.check(*nsA,out());
00173     if(!result) success = false;
00174 
00175     if(out.get()) *out << "\nE) Testing the LinearOpWithSolveBase interface of nsA ...\n";
00176 
00177     LinearOpWithSolveTester<double> linearOpWithSolveTester;
00178     linearOpWithSolveTester.turn_off_all_tests();
00179     linearOpWithSolveTester.check_forward_default(true);
00180     linearOpWithSolveTester.check_forward_residual(true);
00181     if(testTranspose && useAztecPrec) {
00182       linearOpWithSolveTester.check_adjoint_default(true);
00183       linearOpWithSolveTester.check_adjoint_residual(true);
00184     }
00185     else {
00186       linearOpWithSolveTester.check_adjoint_default(false);
00187       linearOpWithSolveTester.check_adjoint_residual(false);
00188     }
00189     linearOpWithSolveTester.set_all_solve_tol(maxResid);
00190     linearOpWithSolveTester.set_all_slack_error_tol(maxResid);
00191     linearOpWithSolveTester.set_all_slack_warning_tol(10.0*maxResid);
00192     linearOpWithSolveTester.forward_default_residual_error_tol(2.5*maxResid);
00193     linearOpWithSolveTester.forward_default_solution_error_error_tol(maxSolutionError);
00194     linearOpWithSolveTester.adjoint_default_residual_error_tol(2.5*maxResid);
00195     linearOpWithSolveTester.adjoint_default_solution_error_error_tol(maxSolutionError);
00196     linearOpWithSolveTester.show_all_tests(showAllTests);
00197     linearOpWithSolveTester.dump_all(dumpAll);
00198     Thyra::seed_randomize<double>(0);
00199     result = linearOpWithSolveTester.check(*nsA,out.get());
00200     if(!result) success = false;
00201 
00202     if(out.get()) *out << "\nF) Uninitialize nsA, create preconditioner for diagonal scaled by 0.99 and then reinitialize nsA reusing the old preconditioner ...\n";
00203 
00204     // Scale the diagonal of the matrix and then create the preconditioner for it
00205     Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
00206     // Above is not required but a good idea since we are changing the matrix
00207     {
00208       Epetra_Vector diag(epetra_A->RowMap());
00209       epetra_A->ExtractDiagonalCopy(diag);
00210       diag.Scale(0.5);
00211       epetra_A->ReplaceDiagonalValues(diag);
00212     }
00213     Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
00214 
00215     // Scale the matrix back again and then reuse the preconditioner
00216     Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
00217     // Above is not required but a good idea since we are changing the matrix
00218     {
00219       Epetra_Vector diag(epetra_A->RowMap());
00220       epetra_A->ExtractDiagonalCopy(diag);
00221       diag.Scale(1.0/0.5);
00222       epetra_A->ReplaceDiagonalValues(diag);
00223     }
00224     initializeAndReuseOp<double>(*lowsFactory, A, nsA.ptr());
00225 
00226     if(out.get()) *out << "\nG) Testing the LinearOpWithSolveBase interface of nsA ...\n";
00227 
00228     Thyra::seed_randomize<double>(0);
00229     result = linearOpWithSolveTester.check(*nsA,out.get());
00230     if(!result) success = false;
00231 
00232     if(useAztecPrec) {
00233 
00234       if(out.get()) *out << "\nH) Reinitialize (A,A,PRECONDITIONER_INPUT_TYPE_AS_MATRIX) => nsA ...\n";
00235 
00236       initializeApproxPreconditionedOp<double>(*lowsFactory, A, A, nsA.ptr());
00237 
00238       if(out.get()) *out << "\nI) Testing the LinearOpWithSolveBase interface of nsA ...\n";
00239 
00240       Thyra::seed_randomize<double>(0);
00241       result = linearOpWithSolveTester.check(*nsA,out.get());
00242       if(!result) success = false;
00243 
00244       if(testTranspose && useAztecPrec) {
00245         linearOpWithSolveTester.check_adjoint_default(true);
00246         linearOpWithSolveTester.check_adjoint_residual(true);
00247       }
00248       else {
00249         linearOpWithSolveTester.check_adjoint_default(false);
00250         linearOpWithSolveTester.check_adjoint_residual(false);
00251       }
00252 
00253     }
00254     else {
00255 
00256       if(out.get()) *out << "\nSkipping testing steps H and I since we are not using aztec preconditioning and therefore will not test with an external preconditioner matrix!\n";
00257 
00258     }
00259 
00260 
00261     RCP<PreconditionerFactoryBase<double> >
00262       precFactory;
00263 
00264 #ifdef HAVE_AZTECOO_IFPACK
00265 
00266     if(useAztecPrec) {
00267 
00268       if(testTranspose) {
00269         linearOpWithSolveTester.check_adjoint_default(true);
00270         linearOpWithSolveTester.check_adjoint_residual(true);
00271       }
00272 
00273       if(out.get()) *out << "\nJ) Create an ifpack preconditioner precA for A ...\n";
00274 
00275       precFactory = Teuchos::rcp(new IfpackPreconditionerFactory());
00276 
00277       if(out.get()) {
00278         *out << "\nprecFactory.description() = " << precFactory->description() << std::endl;
00279         *out << "\nprecFactory.getValidParameters() =\n";
00280         precFactory->getValidParameters()->print(OSTab(out).o(),0,true,false);
00281       }
00282 
00283       RCP<Teuchos::ParameterList>
00284         ifpackPFPL = Teuchos::rcp(new Teuchos::ParameterList("IfpackPreconditionerFactory"));
00285       ifpackPFPL->set("Prec Type","ILUT");
00286       ifpackPFPL->set("Overlap",int(1));
00287       if(out.get()) {
00288         *out << "\nifpackPFPL before setting parameters =\n";
00289         ifpackPFPL->print(OSTab(out).o(),0,true);
00290       }
00291 
00292       precFactory->setParameterList(ifpackPFPL);
00293 
00294       RCP<PreconditionerBase<double> >
00295         precA = precFactory->createPrec();
00296       Thyra::initializePrec<double>(*precFactory,A,&*precA);
00297 
00298       if(out.get()) {
00299         *out << "\nifpackPFPL after setting parameters =\n";
00300         ifpackPFPL->print(OSTab(out).o(),0,true);
00301         *out << "\nprecFactory.description() = " << precFactory->description() << std::endl;
00302       }
00303 
00304       if(out.get()) *out << "\nprecA.description() = " << precA->description() << std::endl;
00305       if(out.get() && dumpAll) *out << "\ndescribe(precA) =\n" << describe(*precA,Teuchos::VERB_EXTREME);
00306 
00307       if(out.get()) *out << "\nK) Reinitialize (A,precA->getUnspecifiedPrecOp(),PRECONDITIONER_INPUT_TYPE_AS_OPERATOR) => nsA ...\n";
00308 
00309       Thyra::initializePreconditionedOp<double>(*lowsFactory,A,precA,&*nsA);
00310 
00311       if(out.get()) *out << "\nL) Testing the LinearOpWithSolveBase interface of nsA ...\n";
00312 
00313       Thyra::seed_randomize<double>(0);
00314       result = linearOpWithSolveTester.check(*nsA,out.get());
00315       if(!result) success = false;
00316 
00317       if(testTranspose && useAztecPrec) {
00318         linearOpWithSolveTester.check_adjoint_default(true);
00319         linearOpWithSolveTester.check_adjoint_residual(true);
00320       }
00321       else {
00322         linearOpWithSolveTester.check_adjoint_default(false);
00323         linearOpWithSolveTester.check_adjoint_residual(false);
00324       }
00325 
00326     }
00327     else {
00328 
00329       if(out.get()) *out << "\nSkipping testing steps J, K, and L since we are not using aztec preconditioning and therefore will not test with an ifpack preconditioner!\n";
00330 
00331     }
00332 
00333 #else // HAVE_AZTECOO_IFPACK
00334 
00335     if(out.get()) *out << "\nSkipping testing steps J, K, and L since they require ifpack and ifpack has not been enabled!\n";
00336 
00337 #endif // HAVE_AZTECOO_IFPACK
00338 
00339 
00340     if(out.get()) *out << "\nM) Scale the epetra_A object by 2.5, and then reinitialize nsA with epetra_A ...\n";
00341 
00342     Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
00343     // Not required but a good idea since we are changing the matrix
00344     epetra_A->Scale(2.5);
00345     initializeOp<double>(*lowsFactory, A, nsA.ptr());
00346 
00347     if(out.get()) *out << "\nN) Testing the LinearOpWithSolveBase interface of nsA ...\n";
00348 
00349     Thyra::seed_randomize<double>(0);
00350     result = linearOpWithSolveTester.check(*nsA,out.get());
00351     if(!result) success = false;
00352 
00353     if(out.get()) *out << "\nO) Create a scaled (by 2.5) copy epetra_A2 of epetra_A, and then reinitialize nsA with epetra_A2 ...\n";
00354 
00355     RCP<Epetra_CrsMatrix>
00356       epetra_A2 = Teuchos::rcp(new Epetra_CrsMatrix(*epetra_A));
00357     epetra_A2->Scale(2.5);
00358     RCP<const LinearOpBase<double> >
00359       A2 = Thyra::epetraLinearOp(epetra_A2);
00360     initializeOp<double>(*lowsFactory, A2, nsA.ptr());
00361     // Note that it was okay not to uninitialize nsA first here since A, which
00362     // was used to initialize nsA last, was not changed and therefore the
00363     // state of nsA was fine throughout
00364 
00365     if(out.get()) *out << "\nP) Testing the LinearOpWithSolveBase interface of nsA ...\n";
00366 
00367     Thyra::seed_randomize<double>(0);
00368     result = linearOpWithSolveTester.check(*nsA,out.get());
00369     if(!result) success = false;
00370 
00371     if(!useAztecPrec) {
00372 
00373       if(out.get()) *out << "\nQ) Create an implicitly scaled (by 2.5) and transposed matrix A3 = scale(2.5,transpose(A)) and initialize nsA2 ...\n";
00374 
00375       RCP<const LinearOpBase<double> >
00376         A3 = scale<double>(2.5,transpose<double>(A));
00377       RCP<LinearOpWithSolveBase<double> >
00378         nsA2 = linearOpWithSolve(*lowsFactory,A3);
00379 
00380       if(out.get()) *out << "\nR) Testing the LinearOpWithSolveBase interface of nsA2 ...\n";
00381 
00382       Thyra::seed_randomize<double>(0);
00383       result = linearOpWithSolveTester.check(*nsA2,out.get());
00384       if(!result) success = false;
00385 
00386       if(out.get()) *out << "\nS) Testing that LinearOpBase interfaces of transpose(nsA) == nsA2 ...\n";
00387 
00388       result = linearOpTester.compare(
00389         *transpose(Teuchos::rcp_implicit_cast<const LinearOpBase<double> >(nsA)),*nsA2
00390         ,out()
00391         );
00392       if(!result) success = false;
00393 
00394     }
00395     else {
00396 
00397       if(out.get()) *out << "\nSkipping testing steps Q, R, and S because we are using internal AztecOO preconditioners!\n";
00398 
00399     }
00400 
00401   if(out.get()) *out << "\nT) Running example use cases ...\n";
00402 
00403   nonExternallyPreconditionedLinearSolveUseCases(
00404     *A,*lowsFactory,testTranspose,*out
00405     );
00406 
00407   if(precFactory.get()) {
00408     externallyPreconditionedLinearSolveUseCases(
00409       *A,*lowsFactory,*precFactory,false,true,*out
00410       );
00411   }
00412 
00413 #else // SUN_CXX
00414 
00415     if(out.get()) *out << "\nTest failed since is was not even compiled since SUN_CXX was defined!\n";
00416     success = false;
00417 
00418 #endif // SUN_CXX
00419 
00420   }
00421   catch( const std::exception &excpt ) {
00422     std::cerr << "\n*** Caught standard exception : " << excpt.what() << std::endl;
00423     success = false;
00424   }
00425 
00426   return success;
00427 
00428 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines