Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test_single_aztecoo_thyra_solver.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stratimikos: Thyra-based strategies for linear solvers
4 //
5 // Copyright 2006 NTESS and the Stratimikos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 
12 #ifndef SUN_CXX
13 
15 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
16 #include "Thyra_PreconditionerFactoryHelpers.hpp"
17 #include "Thyra_LinearOpWithSolveFactoryExamples.hpp"
18 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
19 #include "Thyra_EpetraLinearOp.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
28 #endif
29 #ifdef HAVE_MPI
30 # include "Epetra_MpiComm.h"
31 #endif
32 
33 #endif // SUN_CXX
34 
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
43  ,const bool dumpAll
44  ,Teuchos::ParameterList *aztecooLOWSFPL
45  ,Teuchos::FancyOStream *out_arg
46  )
47 {
48  using Teuchos::rcp;
49  using Teuchos::RCP;
50  using Teuchos::OSTab;
52  bool result, success = true;
53 
54  RCP<Teuchos::FancyOStream>
55  out = Teuchos::rcp(out_arg,false);
56 
57  try {
58 
59 #ifndef SUN_CXX
60 
61  if(out.get()) {
62  *out
63  << "\n***"
64  << "\n*** Testing Thyra::AztecOOLinearOpWithSolveFactory (and Thyra::AztecOOLinearOpWithSolve)"
65  << "\n***\n"
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
74  << std::endl;
75  }
76 
77  const bool useAztecPrec = (
78  aztecooLOWSFPL
79  &&
80  aztecooLOWSFPL->sublist("Forward Solve")
81  .sublist("AztecOO Settings")
82  .get("Aztec Preconditioner","none")!="none"
83  );
84 
85  if(out.get()) {
86  if(useAztecPrec)
87  *out << "\nUsing aztec preconditioning so we will not test adjoint solves using internal preconditioning ...\n";
88  }
89 
90  if(out.get()) *out << "\nA) Reading in an epetra matrix A from the file \'"<<matrixFile<<"\' ...\n";
91 
92 #ifdef HAVE_MPI
93  Epetra_MpiComm comm(MPI_COMM_WORLD);
94 #else
95  Epetra_SerialComm comm;
96 #endif
97  RCP<Epetra_CrsMatrix> epetra_A;
98  EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A );
99 
100  RCP<const LinearOpBase<double> > A = Thyra::epetraLinearOp(epetra_A);
101 
102  if(out.get() && dumpAll) *out << "\ndescribe(A) =\n" << describe(*A,Teuchos::VERB_EXTREME);
103 
104  if(out.get()) *out << "\nB) Creating a AztecOOLinearOpWithSolveFactory object opFactory ...\n";
105 
106  RCP<LinearOpWithSolveFactoryBase<double> >
107  lowsFactory = Teuchos::rcp(new AztecOOLinearOpWithSolveFactory());
108  if(out.get()) {
109  *out << "\nlowsFactory.getValidParameters() initially:\n";
110  lowsFactory->getValidParameters()->print(OSTab(out).o(),PLPrintOptions().showTypes(true).showDoc(true));
111  }
112  TEUCHOS_ASSERT(aztecooLOWSFPL != NULL);
113  aztecooLOWSFPL->sublist("Forward Solve").set("Tolerance",maxResid);
114  aztecooLOWSFPL->sublist("Adjoint Solve").set("Tolerance",maxResid);
115  if(showAllTests) {
116  aztecooLOWSFPL->set("Output Every RHS",bool(true));
117  }
118  if(out.get()) {
119  *out << "\naztecooLOWSFPL before setting parameters:\n";
120  aztecooLOWSFPL->print(OSTab(out).o(),0,true);
121  }
122  if(aztecooLOWSFPL) lowsFactory->setParameterList(Teuchos::rcp(aztecooLOWSFPL,false));
123 
124  if(out.get()) *out << "\nC) Creating a AztecOOLinearOpWithSolve object nsA from A ...\n";
125 
126  RCP<LinearOpWithSolveBase<double> >
127  nsA = lowsFactory->createOp();
128 
129  Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
130 
131  if(out.get()) *out << "\nD) Testing the LinearOpBase interface of nsA ...\n";
132 
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;
143 
144  if(out.get()) *out << "\nE) Testing the LinearOpWithSolveBase interface of nsA ...\n";
145 
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);
153  }
154  else {
155  linearOpWithSolveTester.check_adjoint_default(false);
156  linearOpWithSolveTester.check_adjoint_residual(false);
157  }
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;
170 
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";
172 
173  // Scale the diagonal of the matrix and then create the preconditioner for it
174  Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
175  // Above is not required but a good idea since we are changing the matrix
176  {
177  Epetra_Vector diag(epetra_A->RowMap());
178  epetra_A->ExtractDiagonalCopy(diag);
179  diag.Scale(0.5);
180  epetra_A->ReplaceDiagonalValues(diag);
181  }
182  Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());
183 
184  // Scale the matrix back again and then reuse the preconditioner
185  Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
186  // Above is not required but a good idea since we are changing the matrix
187  {
188  Epetra_Vector diag(epetra_A->RowMap());
189  epetra_A->ExtractDiagonalCopy(diag);
190  diag.Scale(1.0/0.5);
191  epetra_A->ReplaceDiagonalValues(diag);
192  }
193  initializeAndReuseOp<double>(*lowsFactory, A, nsA.ptr());
194 
195  if(out.get()) *out << "\nG) Testing the LinearOpWithSolveBase interface of nsA ...\n";
196 
197  Thyra::seed_randomize<double>(0);
198  result = linearOpWithSolveTester.check(*nsA,out.get());
199  if(!result) success = false;
200 
201  if(useAztecPrec) {
202 
203  if(out.get()) *out << "\nH) Reinitialize (A,A,PRECONDITIONER_INPUT_TYPE_AS_MATRIX) => nsA ...\n";
204 
205  initializeApproxPreconditionedOp<double>(*lowsFactory, A, A, nsA.ptr());
206 
207  if(out.get()) *out << "\nI) Testing the LinearOpWithSolveBase interface of nsA ...\n";
208 
209  Thyra::seed_randomize<double>(0);
210  result = linearOpWithSolveTester.check(*nsA,out.get());
211  if(!result) success = false;
212 
213  if(testTranspose && useAztecPrec) {
214  linearOpWithSolveTester.check_adjoint_default(true);
215  linearOpWithSolveTester.check_adjoint_residual(true);
216  }
217  else {
218  linearOpWithSolveTester.check_adjoint_default(false);
219  linearOpWithSolveTester.check_adjoint_residual(false);
220  }
221 
222  }
223  else {
224 
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";
226 
227  }
228 
229 
230  RCP<PreconditionerFactoryBase<double> >
231  precFactory;
232 
233 #ifdef HAVE_AZTECOO_IFPACK
234 
235  if(useAztecPrec) {
236 
237  if(testTranspose) {
238  linearOpWithSolveTester.check_adjoint_default(true);
239  linearOpWithSolveTester.check_adjoint_residual(true);
240  }
241 
242  if(out.get()) *out << "\nJ) Create an ifpack preconditioner precA for A ...\n";
243 
244  precFactory = Teuchos::rcp(new IfpackPreconditionerFactory());
245 
246  if(out.get()) {
247  *out << "\nprecFactory.description() = " << precFactory->description() << std::endl;
248  *out << "\nprecFactory.getValidParameters() =\n";
249  precFactory->getValidParameters()->print(OSTab(out).o(),0,true,false);
250  }
251 
252  RCP<Teuchos::ParameterList>
253  ifpackPFPL = Teuchos::rcp(new Teuchos::ParameterList("IfpackPreconditionerFactory"));
254  ifpackPFPL->set("Prec Type","ILUT");
255  ifpackPFPL->set("Overlap",int(1));
256  if(out.get()) {
257  *out << "\nifpackPFPL before setting parameters =\n";
258  ifpackPFPL->print(OSTab(out).o(),0,true);
259  }
260 
261  precFactory->setParameterList(ifpackPFPL);
262 
263  RCP<PreconditionerBase<double> >
264  precA = precFactory->createPrec();
265  Thyra::initializePrec<double>(*precFactory,A,&*precA);
266 
267  if(out.get()) {
268  *out << "\nifpackPFPL after setting parameters =\n";
269  ifpackPFPL->print(OSTab(out).o(),0,true);
270  *out << "\nprecFactory.description() = " << precFactory->description() << std::endl;
271  }
272 
273  if(out.get()) *out << "\nprecA.description() = " << precA->description() << std::endl;
274  if(out.get() && dumpAll) *out << "\ndescribe(precA) =\n" << describe(*precA,Teuchos::VERB_EXTREME);
275 
276  if(out.get()) *out << "\nK) Reinitialize (A,precA->getUnspecifiedPrecOp(),PRECONDITIONER_INPUT_TYPE_AS_OPERATOR) => nsA ...\n";
277 
278  Thyra::initializePreconditionedOp<double>(*lowsFactory,A,precA,&*nsA);
279 
280  if(out.get()) *out << "\nL) Testing the LinearOpWithSolveBase interface of nsA ...\n";
281 
282  Thyra::seed_randomize<double>(0);
283  result = linearOpWithSolveTester.check(*nsA,out.get());
284  if(!result) success = false;
285 
286  if(testTranspose && useAztecPrec) {
287  linearOpWithSolveTester.check_adjoint_default(true);
288  linearOpWithSolveTester.check_adjoint_residual(true);
289  }
290  else {
291  linearOpWithSolveTester.check_adjoint_default(false);
292  linearOpWithSolveTester.check_adjoint_residual(false);
293  }
294 
295  }
296  else {
297 
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";
299 
300  }
301 
302 #else // HAVE_AZTECOO_IFPACK
303 
304  if(out.get()) *out << "\nSkipping testing steps J, K, and L since they require ifpack and ifpack has not been enabled!\n";
305 
306 #endif // HAVE_AZTECOO_IFPACK
307 
308 
309  if(out.get()) *out << "\nM) Scale the epetra_A object by 2.5, and then reinitialize nsA with epetra_A ...\n";
310 
311  Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
312  // Not required but a good idea since we are changing the matrix
313  epetra_A->Scale(2.5);
314  initializeOp<double>(*lowsFactory, A, nsA.ptr());
315 
316  if(out.get()) *out << "\nN) Testing the LinearOpWithSolveBase interface of nsA ...\n";
317 
318  Thyra::seed_randomize<double>(0);
319  result = linearOpWithSolveTester.check(*nsA,out.get());
320  if(!result) success = false;
321 
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";
323 
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());
330  // Note that it was okay not to uninitialize nsA first here since A, which
331  // was used to initialize nsA last, was not changed and therefore the
332  // state of nsA was fine throughout
333 
334  if(out.get()) *out << "\nP) Testing the LinearOpWithSolveBase interface of nsA ...\n";
335 
336  Thyra::seed_randomize<double>(0);
337  result = linearOpWithSolveTester.check(*nsA,out.get());
338  if(!result) success = false;
339 
340  if(!useAztecPrec) {
341 
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";
343 
344  RCP<const LinearOpBase<double> >
345  A3 = scale<double>(2.5,transpose<double>(A));
346  RCP<LinearOpWithSolveBase<double> >
347  nsA2 = linearOpWithSolve(*lowsFactory,A3);
348 
349  if(out.get()) *out << "\nR) Testing the LinearOpWithSolveBase interface of nsA2 ...\n";
350 
351  Thyra::seed_randomize<double>(0);
352  result = linearOpWithSolveTester.check(*nsA2,out.get());
353  if(!result) success = false;
354 
355  if(out.get()) *out << "\nS) Testing that LinearOpBase interfaces of transpose(nsA) == nsA2 ...\n";
356 
357  result = linearOpTester.compare(
358  *transpose(Teuchos::rcp_implicit_cast<const LinearOpBase<double> >(nsA)),*nsA2
359  ,out()
360  );
361  if(!result) success = false;
362 
363  }
364  else {
365 
366  if(out.get()) *out << "\nSkipping testing steps Q, R, and S because we are using internal AztecOO preconditioners!\n";
367 
368  }
369 
370  if(out.get()) *out << "\nT) Running example use cases ...\n";
371 
372  nonExternallyPreconditionedLinearSolveUseCases(
373  *A,*lowsFactory,testTranspose,*out
374  );
375 
376  if(precFactory.get()) {
377  externallyPreconditionedLinearSolveUseCases(
378  *A,*lowsFactory,*precFactory,false,true,*out
379  );
380  }
381 
382 #else // SUN_CXX
383 
384  if(out.get()) *out << "\nTest failed since is was not even compiled since SUN_CXX was defined!\n";
385  success = false;
386 
387 #endif // SUN_CXX
388 
389  }
390  catch( const std::exception &excpt ) {
391  std::cerr << "\n*** Caught standard exception : " << excpt.what() << std::endl;
392  success = false;
393  }
394 
395  return success;
396 
397 }
RCP< ParameterList > sublist(const RCP< ParameterList > &paramList, 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)