15 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
16 #include "Thyra_PreconditionerFactoryHelpers.hpp"
17 #include "Thyra_LinearOpWithSolveFactoryExamples.hpp"
18 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
20 #include "Thyra_LinearOpTester.hpp"
21 #include "Thyra_LinearOpWithSolveBase.hpp"
22 #include "Thyra_LinearOpWithSolveTester.hpp"
23 #include "EpetraExt_readEpetraLinearSystem.h"
24 #include "Epetra_SerialComm.h"
26 #ifdef HAVE_AZTECOO_IFPACK
30 # include "Epetra_MpiComm.h"
35 bool Thyra::test_single_aztecoo_thyra_solver(
36 const std::string matrixFile
37 ,
const bool testTranspose
38 ,
const int numRandomVectors
39 ,
const double maxFwdError
40 ,
const double maxResid
41 ,
const double maxSolutionError
42 ,
const bool showAllTests
52 bool result, success =
true;
54 RCP<Teuchos::FancyOStream>
64 <<
"\n*** Testing Thyra::AztecOOLinearOpWithSolveFactory (and Thyra::AztecOOLinearOpWithSolve)"
66 <<
"\nEchoing input options:"
67 <<
"\n matrixFile = " << matrixFile
68 <<
"\n testTranspose = " << testTranspose
69 <<
"\n numRandomVectors = " << numRandomVectors
70 <<
"\n maxFwdError = " << maxFwdError
71 <<
"\n maxResid = " << maxResid
72 <<
"\n showAllTests = " << showAllTests
73 <<
"\n dumpAll = " << dumpAll
77 const bool useAztecPrec = (
80 aztecooLOWSFPL->
sublist(
"Forward Solve")
81 .sublist(
"AztecOO Settings")
82 .get(
"Aztec Preconditioner",
"none")!=
"none"
87 *out <<
"\nUsing aztec preconditioning so we will not test adjoint solves using internal preconditioning ...\n";
90 if(out.get()) *out <<
"\nA) Reading in an epetra matrix A from the file \'"<<matrixFile<<
"\' ...\n";
93 Epetra_MpiComm comm(MPI_COMM_WORLD);
95 Epetra_SerialComm comm;
97 RCP<Epetra_CrsMatrix> epetra_A;
98 EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A );
100 RCP<const LinearOpBase<double> >
A = Thyra::epetraLinearOp(epetra_A);
104 if(out.get()) *out <<
"\nB) Creating a AztecOOLinearOpWithSolveFactory object opFactory ...\n";
106 RCP<LinearOpWithSolveFactoryBase<double> >
107 lowsFactory =
Teuchos::rcp(
new AztecOOLinearOpWithSolveFactory());
109 *out <<
"\nlowsFactory.getValidParameters() initially:\n";
110 lowsFactory->getValidParameters()->print(
OSTab(out).o(),PLPrintOptions().showTypes(
true).showDoc(
true));
113 aztecooLOWSFPL->
sublist(
"Forward Solve").set(
"Tolerance",maxResid);
114 aztecooLOWSFPL->
sublist(
"Adjoint Solve").set(
"Tolerance",maxResid);
116 aztecooLOWSFPL->
set(
"Output Every RHS",
bool(
true));
119 *out <<
"\naztecooLOWSFPL before setting parameters:\n";
122 if(aztecooLOWSFPL) lowsFactory->setParameterList(
Teuchos::rcp(aztecooLOWSFPL,
false));
124 if(out.get()) *out <<
"\nC) Creating a AztecOOLinearOpWithSolve object nsA from A ...\n";
126 RCP<LinearOpWithSolveBase<double> >
127 nsA = lowsFactory->createOp();
129 Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
131 if(out.get()) *out <<
"\nD) Testing the LinearOpBase interface of nsA ...\n";
133 LinearOpTester<double> linearOpTester;
134 linearOpTester.check_adjoint(testTranspose);
135 linearOpTester.num_random_vectors(numRandomVectors);
136 linearOpTester.set_all_error_tol(maxFwdError);
137 linearOpTester.set_all_warning_tol(1e-2*maxFwdError);
138 linearOpTester.show_all_tests(showAllTests);
139 linearOpTester.dump_all(dumpAll);
140 Thyra::seed_randomize<double>(0);
141 result = linearOpTester.check(*nsA,out());
142 if(!result) success =
false;
144 if(out.get()) *out <<
"\nE) Testing the LinearOpWithSolveBase interface of nsA ...\n";
146 LinearOpWithSolveTester<double> linearOpWithSolveTester;
147 linearOpWithSolveTester.turn_off_all_tests();
148 linearOpWithSolveTester.check_forward_default(
true);
149 linearOpWithSolveTester.check_forward_residual(
true);
150 if(testTranspose && useAztecPrec) {
151 linearOpWithSolveTester.check_adjoint_default(
true);
152 linearOpWithSolveTester.check_adjoint_residual(
true);
155 linearOpWithSolveTester.check_adjoint_default(
false);
156 linearOpWithSolveTester.check_adjoint_residual(
false);
158 linearOpWithSolveTester.set_all_solve_tol(maxResid);
159 linearOpWithSolveTester.set_all_slack_error_tol(maxResid);
160 linearOpWithSolveTester.set_all_slack_warning_tol(10.0*maxResid);
161 linearOpWithSolveTester.forward_default_residual_error_tol(2.5*maxResid);
162 linearOpWithSolveTester.forward_default_solution_error_error_tol(maxSolutionError);
163 linearOpWithSolveTester.adjoint_default_residual_error_tol(2.5*maxResid);
164 linearOpWithSolveTester.adjoint_default_solution_error_error_tol(maxSolutionError);
165 linearOpWithSolveTester.show_all_tests(showAllTests);
166 linearOpWithSolveTester.dump_all(dumpAll);
167 Thyra::seed_randomize<double>(0);
168 result = linearOpWithSolveTester.check(*nsA,out.get());
169 if(!result) success =
false;
171 if(out.get()) *out <<
"\nF) Uninitialize nsA, create preconditioner for diagonal scaled by 0.99 and then reinitialize nsA reusing the old preconditioner ...\n";
174 Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
177 Epetra_Vector diag(epetra_A->RowMap());
178 epetra_A->ExtractDiagonalCopy(diag);
180 epetra_A->ReplaceDiagonalValues(diag);
182 Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
185 Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
188 Epetra_Vector diag(epetra_A->RowMap());
189 epetra_A->ExtractDiagonalCopy(diag);
191 epetra_A->ReplaceDiagonalValues(diag);
193 initializeAndReuseOp<double>(*lowsFactory, A, nsA.ptr());
195 if(out.get()) *out <<
"\nG) Testing the LinearOpWithSolveBase interface of nsA ...\n";
197 Thyra::seed_randomize<double>(0);
198 result = linearOpWithSolveTester.check(*nsA,out.get());
199 if(!result) success =
false;
203 if(out.get()) *out <<
"\nH) Reinitialize (A,A,PRECONDITIONER_INPUT_TYPE_AS_MATRIX) => nsA ...\n";
205 initializeApproxPreconditionedOp<double>(*lowsFactory, A, A, nsA.ptr());
207 if(out.get()) *out <<
"\nI) Testing the LinearOpWithSolveBase interface of nsA ...\n";
209 Thyra::seed_randomize<double>(0);
210 result = linearOpWithSolveTester.check(*nsA,out.get());
211 if(!result) success =
false;
213 if(testTranspose && useAztecPrec) {
214 linearOpWithSolveTester.check_adjoint_default(
true);
215 linearOpWithSolveTester.check_adjoint_residual(
true);
218 linearOpWithSolveTester.check_adjoint_default(
false);
219 linearOpWithSolveTester.check_adjoint_residual(
false);
225 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";
230 RCP<PreconditionerFactoryBase<double> >
233 #ifdef HAVE_AZTECOO_IFPACK
238 linearOpWithSolveTester.check_adjoint_default(
true);
239 linearOpWithSolveTester.check_adjoint_residual(
true);
242 if(out.get()) *out <<
"\nJ) Create an ifpack preconditioner precA for A ...\n";
244 precFactory =
Teuchos::rcp(
new IfpackPreconditionerFactory());
247 *out <<
"\nprecFactory.description() = " << precFactory->description() << std::endl;
248 *out <<
"\nprecFactory.getValidParameters() =\n";
249 precFactory->getValidParameters()->print(
OSTab(out).o(),0,
true,
false);
252 RCP<Teuchos::ParameterList>
254 ifpackPFPL->set(
"Prec Type",
"ILUT");
255 ifpackPFPL->set(
"Overlap",
int(1));
257 *out <<
"\nifpackPFPL before setting parameters =\n";
258 ifpackPFPL->print(
OSTab(out).o(),0,
true);
261 precFactory->setParameterList(ifpackPFPL);
263 RCP<PreconditionerBase<double> >
264 precA = precFactory->createPrec();
265 Thyra::initializePrec<double>(*precFactory,A,&*precA);
268 *out <<
"\nifpackPFPL after setting parameters =\n";
269 ifpackPFPL->print(
OSTab(out).o(),0,
true);
270 *out <<
"\nprecFactory.description() = " << precFactory->description() << std::endl;
273 if(out.get()) *out <<
"\nprecA.description() = " << precA->description() << std::endl;
276 if(out.get()) *out <<
"\nK) Reinitialize (A,precA->getUnspecifiedPrecOp(),PRECONDITIONER_INPUT_TYPE_AS_OPERATOR) => nsA ...\n";
278 Thyra::initializePreconditionedOp<double>(*lowsFactory,A,precA,&*nsA);
280 if(out.get()) *out <<
"\nL) Testing the LinearOpWithSolveBase interface of nsA ...\n";
282 Thyra::seed_randomize<double>(0);
283 result = linearOpWithSolveTester.check(*nsA,out.get());
284 if(!result) success =
false;
286 if(testTranspose && useAztecPrec) {
287 linearOpWithSolveTester.check_adjoint_default(
true);
288 linearOpWithSolveTester.check_adjoint_residual(
true);
291 linearOpWithSolveTester.check_adjoint_default(
false);
292 linearOpWithSolveTester.check_adjoint_residual(
false);
298 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";
302 #else // HAVE_AZTECOO_IFPACK
304 if(out.get()) *out <<
"\nSkipping testing steps J, K, and L since they require ifpack and ifpack has not been enabled!\n";
306 #endif // HAVE_AZTECOO_IFPACK
309 if(out.get()) *out <<
"\nM) Scale the epetra_A object by 2.5, and then reinitialize nsA with epetra_A ...\n";
311 Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
313 epetra_A->Scale(2.5);
314 initializeOp<double>(*lowsFactory, A, nsA.ptr());
316 if(out.get()) *out <<
"\nN) Testing the LinearOpWithSolveBase interface of nsA ...\n";
318 Thyra::seed_randomize<double>(0);
319 result = linearOpWithSolveTester.check(*nsA,out.get());
320 if(!result) success =
false;
322 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";
324 RCP<Epetra_CrsMatrix>
325 epetra_A2 =
Teuchos::rcp(
new Epetra_CrsMatrix(*epetra_A));
326 epetra_A2->Scale(2.5);
327 RCP<const LinearOpBase<double> >
328 A2 = Thyra::epetraLinearOp(epetra_A2);
329 initializeOp<double>(*lowsFactory, A2, nsA.ptr());
334 if(out.get()) *out <<
"\nP) Testing the LinearOpWithSolveBase interface of nsA ...\n";
336 Thyra::seed_randomize<double>(0);
337 result = linearOpWithSolveTester.check(*nsA,out.get());
338 if(!result) success =
false;
342 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";
344 RCP<const LinearOpBase<double> >
345 A3 = scale<double>(2.5,transpose<double>(A));
346 RCP<LinearOpWithSolveBase<double> >
347 nsA2 = linearOpWithSolve(*lowsFactory,A3);
349 if(out.get()) *out <<
"\nR) Testing the LinearOpWithSolveBase interface of nsA2 ...\n";
351 Thyra::seed_randomize<double>(0);
352 result = linearOpWithSolveTester.check(*nsA2,out.get());
353 if(!result) success =
false;
355 if(out.get()) *out <<
"\nS) Testing that LinearOpBase interfaces of transpose(nsA) == nsA2 ...\n";
357 result = linearOpTester.compare(
358 *transpose(Teuchos::rcp_implicit_cast<
const LinearOpBase<double> >(nsA)),*nsA2
361 if(!result) success =
false;
366 if(out.get()) *out <<
"\nSkipping testing steps Q, R, and S because we are using internal AztecOO preconditioners!\n";
370 if(out.get()) *out <<
"\nT) Running example use cases ...\n";
372 nonExternallyPreconditionedLinearSolveUseCases(
373 *A,*lowsFactory,testTranspose,*out
376 if(precFactory.get()) {
377 externallyPreconditionedLinearSolveUseCases(
378 *A,*lowsFactory,*precFactory,
false,
true,*out
384 if(out.get()) *out <<
"\nTest failed since is was not even compiled since SUN_CXX was defined!\n";
390 catch(
const std::exception &excpt ) {
391 std::cerr <<
"\n*** Caught standard exception : " << excpt.what() << std::endl;
RCP< ParameterList > sublist(const RCP< ParameterList > ¶mList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
basic_OSTab< char > OSTab
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
ParameterList::PrintOptions PLPrintOptions
#define TEUCHOS_ASSERT(assertion_test)