46 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
47 #include "Thyra_PreconditionerFactoryHelpers.hpp"
48 #include "Thyra_LinearOpWithSolveFactoryExamples.hpp"
49 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
51 #include "Thyra_LinearOpTester.hpp"
52 #include "Thyra_LinearOpWithSolveBase.hpp"
53 #include "Thyra_LinearOpWithSolveTester.hpp"
54 #include "EpetraExt_readEpetraLinearSystem.h"
55 #include "Epetra_SerialComm.h"
57 #ifdef HAVE_AZTECOO_IFPACK
61 # include "Epetra_MpiComm.h"
66 bool Thyra::test_single_aztecoo_thyra_solver(
67 const std::string matrixFile
68 ,
const bool testTranspose
69 ,
const int numRandomVectors
70 ,
const double maxFwdError
71 ,
const double maxResid
72 ,
const double maxSolutionError
73 ,
const bool showAllTests
83 bool result, success =
true;
85 RCP<Teuchos::FancyOStream>
95 <<
"\n*** Testing Thyra::AztecOOLinearOpWithSolveFactory (and Thyra::AztecOOLinearOpWithSolve)"
97 <<
"\nEchoing input options:"
98 <<
"\n matrixFile = " << matrixFile
99 <<
"\n testTranspose = " << testTranspose
100 <<
"\n numRandomVectors = " << numRandomVectors
101 <<
"\n maxFwdError = " << maxFwdError
102 <<
"\n maxResid = " << maxResid
103 <<
"\n showAllTests = " << showAllTests
104 <<
"\n dumpAll = " << dumpAll
108 const bool useAztecPrec = (
111 aztecooLOWSFPL->
sublist(
"Forward Solve")
112 .sublist(
"AztecOO Settings")
113 .get(
"Aztec Preconditioner",
"none")!=
"none"
118 *out <<
"\nUsing aztec preconditioning so we will not test adjoint solves using internal preconditioning ...\n";
121 if(out.get()) *out <<
"\nA) Reading in an epetra matrix A from the file \'"<<matrixFile<<
"\' ...\n";
124 Epetra_MpiComm comm(MPI_COMM_WORLD);
126 Epetra_SerialComm comm;
128 RCP<Epetra_CrsMatrix> epetra_A;
129 EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A );
131 RCP<const LinearOpBase<double> >
A = Thyra::epetraLinearOp(epetra_A);
135 if(out.get()) *out <<
"\nB) Creating a AztecOOLinearOpWithSolveFactory object opFactory ...\n";
137 RCP<LinearOpWithSolveFactoryBase<double> >
138 lowsFactory =
Teuchos::rcp(
new AztecOOLinearOpWithSolveFactory());
140 *out <<
"\nlowsFactory.getValidParameters() initially:\n";
141 lowsFactory->getValidParameters()->print(
OSTab(out).o(),PLPrintOptions().showTypes(
true).showDoc(
true));
144 aztecooLOWSFPL->
sublist(
"Forward Solve").set(
"Tolerance",maxResid);
145 aztecooLOWSFPL->
sublist(
"Adjoint Solve").set(
"Tolerance",maxResid);
147 aztecooLOWSFPL->
set(
"Output Every RHS",
bool(
true));
150 *out <<
"\naztecooLOWSFPL before setting parameters:\n";
153 if(aztecooLOWSFPL) lowsFactory->setParameterList(
Teuchos::rcp(aztecooLOWSFPL,
false));
155 if(out.get()) *out <<
"\nC) Creating a AztecOOLinearOpWithSolve object nsA from A ...\n";
157 RCP<LinearOpWithSolveBase<double> >
158 nsA = lowsFactory->createOp();
160 Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
162 if(out.get()) *out <<
"\nD) Testing the LinearOpBase interface of nsA ...\n";
164 LinearOpTester<double> linearOpTester;
165 linearOpTester.check_adjoint(testTranspose);
166 linearOpTester.num_random_vectors(numRandomVectors);
167 linearOpTester.set_all_error_tol(maxFwdError);
168 linearOpTester.set_all_warning_tol(1e-2*maxFwdError);
169 linearOpTester.show_all_tests(showAllTests);
170 linearOpTester.dump_all(dumpAll);
171 Thyra::seed_randomize<double>(0);
172 result = linearOpTester.check(*nsA,out());
173 if(!result) success =
false;
175 if(out.get()) *out <<
"\nE) Testing the LinearOpWithSolveBase interface of nsA ...\n";
177 LinearOpWithSolveTester<double> linearOpWithSolveTester;
178 linearOpWithSolveTester.turn_off_all_tests();
179 linearOpWithSolveTester.check_forward_default(
true);
180 linearOpWithSolveTester.check_forward_residual(
true);
181 if(testTranspose && useAztecPrec) {
182 linearOpWithSolveTester.check_adjoint_default(
true);
183 linearOpWithSolveTester.check_adjoint_residual(
true);
186 linearOpWithSolveTester.check_adjoint_default(
false);
187 linearOpWithSolveTester.check_adjoint_residual(
false);
189 linearOpWithSolveTester.set_all_solve_tol(maxResid);
190 linearOpWithSolveTester.set_all_slack_error_tol(maxResid);
191 linearOpWithSolveTester.set_all_slack_warning_tol(10.0*maxResid);
192 linearOpWithSolveTester.forward_default_residual_error_tol(2.5*maxResid);
193 linearOpWithSolveTester.forward_default_solution_error_error_tol(maxSolutionError);
194 linearOpWithSolveTester.adjoint_default_residual_error_tol(2.5*maxResid);
195 linearOpWithSolveTester.adjoint_default_solution_error_error_tol(maxSolutionError);
196 linearOpWithSolveTester.show_all_tests(showAllTests);
197 linearOpWithSolveTester.dump_all(dumpAll);
198 Thyra::seed_randomize<double>(0);
199 result = linearOpWithSolveTester.check(*nsA,out.get());
200 if(!result) success =
false;
202 if(out.get()) *out <<
"\nF) Uninitialize nsA, create preconditioner for diagonal scaled by 0.99 and then reinitialize nsA reusing the old preconditioner ...\n";
205 Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
208 Epetra_Vector diag(epetra_A->RowMap());
209 epetra_A->ExtractDiagonalCopy(diag);
211 epetra_A->ReplaceDiagonalValues(diag);
213 Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
216 Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
219 Epetra_Vector diag(epetra_A->RowMap());
220 epetra_A->ExtractDiagonalCopy(diag);
222 epetra_A->ReplaceDiagonalValues(diag);
224 initializeAndReuseOp<double>(*lowsFactory, A, nsA.ptr());
226 if(out.get()) *out <<
"\nG) Testing the LinearOpWithSolveBase interface of nsA ...\n";
228 Thyra::seed_randomize<double>(0);
229 result = linearOpWithSolveTester.check(*nsA,out.get());
230 if(!result) success =
false;
234 if(out.get()) *out <<
"\nH) Reinitialize (A,A,PRECONDITIONER_INPUT_TYPE_AS_MATRIX) => nsA ...\n";
236 initializeApproxPreconditionedOp<double>(*lowsFactory, A, A, nsA.ptr());
238 if(out.get()) *out <<
"\nI) Testing the LinearOpWithSolveBase interface of nsA ...\n";
240 Thyra::seed_randomize<double>(0);
241 result = linearOpWithSolveTester.check(*nsA,out.get());
242 if(!result) success =
false;
244 if(testTranspose && useAztecPrec) {
245 linearOpWithSolveTester.check_adjoint_default(
true);
246 linearOpWithSolveTester.check_adjoint_residual(
true);
249 linearOpWithSolveTester.check_adjoint_default(
false);
250 linearOpWithSolveTester.check_adjoint_residual(
false);
256 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";
261 RCP<PreconditionerFactoryBase<double> >
264 #ifdef HAVE_AZTECOO_IFPACK
269 linearOpWithSolveTester.check_adjoint_default(
true);
270 linearOpWithSolveTester.check_adjoint_residual(
true);
273 if(out.get()) *out <<
"\nJ) Create an ifpack preconditioner precA for A ...\n";
275 precFactory =
Teuchos::rcp(
new IfpackPreconditionerFactory());
278 *out <<
"\nprecFactory.description() = " << precFactory->description() << std::endl;
279 *out <<
"\nprecFactory.getValidParameters() =\n";
280 precFactory->getValidParameters()->print(
OSTab(out).o(),0,
true,
false);
283 RCP<Teuchos::ParameterList>
285 ifpackPFPL->set(
"Prec Type",
"ILUT");
286 ifpackPFPL->set(
"Overlap",
int(1));
288 *out <<
"\nifpackPFPL before setting parameters =\n";
289 ifpackPFPL->print(
OSTab(out).o(),0,
true);
292 precFactory->setParameterList(ifpackPFPL);
294 RCP<PreconditionerBase<double> >
295 precA = precFactory->createPrec();
296 Thyra::initializePrec<double>(*precFactory,A,&*precA);
299 *out <<
"\nifpackPFPL after setting parameters =\n";
300 ifpackPFPL->print(
OSTab(out).o(),0,
true);
301 *out <<
"\nprecFactory.description() = " << precFactory->description() << std::endl;
304 if(out.get()) *out <<
"\nprecA.description() = " << precA->description() << std::endl;
307 if(out.get()) *out <<
"\nK) Reinitialize (A,precA->getUnspecifiedPrecOp(),PRECONDITIONER_INPUT_TYPE_AS_OPERATOR) => nsA ...\n";
309 Thyra::initializePreconditionedOp<double>(*lowsFactory,A,precA,&*nsA);
311 if(out.get()) *out <<
"\nL) Testing the LinearOpWithSolveBase interface of nsA ...\n";
313 Thyra::seed_randomize<double>(0);
314 result = linearOpWithSolveTester.check(*nsA,out.get());
315 if(!result) success =
false;
317 if(testTranspose && useAztecPrec) {
318 linearOpWithSolveTester.check_adjoint_default(
true);
319 linearOpWithSolveTester.check_adjoint_residual(
true);
322 linearOpWithSolveTester.check_adjoint_default(
false);
323 linearOpWithSolveTester.check_adjoint_residual(
false);
329 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";
333 #else // HAVE_AZTECOO_IFPACK
335 if(out.get()) *out <<
"\nSkipping testing steps J, K, and L since they require ifpack and ifpack has not been enabled!\n";
337 #endif // HAVE_AZTECOO_IFPACK
340 if(out.get()) *out <<
"\nM) Scale the epetra_A object by 2.5, and then reinitialize nsA with epetra_A ...\n";
342 Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
344 epetra_A->Scale(2.5);
345 initializeOp<double>(*lowsFactory, A, nsA.ptr());
347 if(out.get()) *out <<
"\nN) Testing the LinearOpWithSolveBase interface of nsA ...\n";
349 Thyra::seed_randomize<double>(0);
350 result = linearOpWithSolveTester.check(*nsA,out.get());
351 if(!result) success =
false;
353 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";
355 RCP<Epetra_CrsMatrix>
356 epetra_A2 =
Teuchos::rcp(
new Epetra_CrsMatrix(*epetra_A));
357 epetra_A2->Scale(2.5);
358 RCP<const LinearOpBase<double> >
359 A2 = Thyra::epetraLinearOp(epetra_A2);
360 initializeOp<double>(*lowsFactory, A2, nsA.ptr());
365 if(out.get()) *out <<
"\nP) Testing the LinearOpWithSolveBase interface of nsA ...\n";
367 Thyra::seed_randomize<double>(0);
368 result = linearOpWithSolveTester.check(*nsA,out.get());
369 if(!result) success =
false;
373 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";
375 RCP<const LinearOpBase<double> >
376 A3 = scale<double>(2.5,transpose<double>(A));
377 RCP<LinearOpWithSolveBase<double> >
378 nsA2 = linearOpWithSolve(*lowsFactory,A3);
380 if(out.get()) *out <<
"\nR) Testing the LinearOpWithSolveBase interface of nsA2 ...\n";
382 Thyra::seed_randomize<double>(0);
383 result = linearOpWithSolveTester.check(*nsA2,out.get());
384 if(!result) success =
false;
386 if(out.get()) *out <<
"\nS) Testing that LinearOpBase interfaces of transpose(nsA) == nsA2 ...\n";
388 result = linearOpTester.compare(
389 *transpose(Teuchos::rcp_implicit_cast<
const LinearOpBase<double> >(nsA)),*nsA2
392 if(!result) success =
false;
397 if(out.get()) *out <<
"\nSkipping testing steps Q, R, and S because we are using internal AztecOO preconditioners!\n";
401 if(out.get()) *out <<
"\nT) Running example use cases ...\n";
403 nonExternallyPreconditionedLinearSolveUseCases(
404 *A,*lowsFactory,testTranspose,*out
407 if(precFactory.get()) {
408 externallyPreconditionedLinearSolveUseCases(
409 *A,*lowsFactory,*precFactory,
false,
true,*out
415 if(out.get()) *out <<
"\nTest failed since is was not even compiled since SUN_CXX was defined!\n";
421 catch(
const std::exception &excpt ) {
422 std::cerr <<
"\n*** Caught standard exception : " << excpt.what() << std::endl;
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
RCP< ParameterList > sublist(const RCP< ParameterList > ¶mList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
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)