|
Stratimikos Package Browser (Single Doxygen Collection)
Version of the Day
|
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 }
1.7.6.1