Thyra Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sillyCgSolve_epetra.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 #include "sillyCgSolve.hpp"
13 #include "Thyra_EpetraLinearOp.hpp"
14 #include "Thyra_DefaultSpmdVectorSpace.hpp"
19 
20 //
21 // Main driver program for epetra implementation of CG.
22 //
23 int main(int argc, char *argv[])
24 {
26  using Teuchos::RCP;
27 
28  bool success = true;
29  bool verbose = true;
30  bool result;
31 
32  //
33  // (A) Setup and get basic MPI info
34  //
35 
36  Teuchos::GlobalMPISession mpiSession(&argc,&argv);
37 #ifdef HAVE_MPI
38  MPI_Comm mpiComm = MPI_COMM_WORLD;
39 #endif
40 
41  //
42  // (B) Setup the output stream (do output only on root process!)
43  //
44 
46  out = Teuchos::VerboseObjectBase::getDefaultOStream();
47 
48  try {
49 
50  //
51  // (C) Read in commandline options
52  //
53 
54  int globalDim = 500;
55  double diagScale = 1.001;
56  bool useWithNonEpetraVectors = false;
57  double tolerance = 1e-4;
58  int maxNumIters = 300;
59 
60  CommandLineProcessor clp(false); // Don't throw exceptions
61  clp.setOption( "verbose", "quiet", &verbose, "Determines if any output is printed or not." );
62  clp.setOption( "global-dim", &globalDim, "Global dimension of the linear system." );
63  clp.setOption( "diag-scale", &diagScale, "Scaling of the diagonal to improve conditioning." );
64  clp.setOption( "use-with-non-epetra-vectors", "use-with-epetra-vectors", &useWithNonEpetraVectors
65  , "Use non-epetra vectors with Epetra operator or not." );
66  clp.setOption( "tol", &tolerance, "Relative tolerance for linear system solve." );
67  clp.setOption( "max-num-iters", &maxNumIters, "Maximum of CG iterations." );
68 
69  CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
70  if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
71 
72  TEUCHOS_TEST_FOR_EXCEPTION( globalDim < 2, std::logic_error, "Error, globalDim=" << globalDim << " < 2 is not allowed!" );
73 
74  if(verbose) *out << "\n***\n*** Running CG example using Epetra implementation\n***\n" << std::scientific;
75 
76  //
77  // (D) Setup a simple linear system with tridagonal operator:
78  //
79  // [ a*2 -1 ]
80  // [ -1 a*2 -1 ]
81  // A = [ . . . ]
82  // [ -1 a*2 -1 ]
83  // [ -1 a*2 ]
84  //
85  // (D.1) Create the tridagonal Epetra matrix operator
86  if(verbose) *out << "\n(1) Constructing tridagonal Epetra matrix A_epetra of global dimension = " << globalDim << " ...\n";
87  RCP<Epetra_Operator>
88  A_epetra = createTridiagEpetraLinearOp(
89  globalDim
90 #ifdef HAVE_MPI
91  ,mpiComm
92 #endif
93  ,diagScale,verbose,*out
94  );
95  // (D.2) Wrap the Epetra_Opertor in a Thyra::EpetraLinearOp object
96  RCP<const Thyra::LinearOpBase<double> >
97  A = Thyra::epetraLinearOp(A_epetra);
98  // (D.3) Create RHS vector b and set to a random value
99  RCP<const Thyra::VectorSpaceBase<double> >
100  b_space = A->range();
101  // (D.4) Create the RHS vector b and initialize it to a random vector
102  RCP<Thyra::VectorBase<double> > b = createMember(b_space);
103  Thyra::seed_randomize<double>(0);
104  Thyra::randomize( -1.0, +1.0, b.ptr() );
105  // (D.5) Create LHS vector x and set to zero
106  RCP<Thyra::VectorBase<double> > x = createMember(A->domain());
107  Thyra::assign( x.ptr(), 0.0 );
108  //
109  // (E) Solve the linear system with the silly CG solver
110  //
111  result = sillyCgSolve(*A, *b, maxNumIters, tolerance, x.ptr(), *out);
112  if(!result) success = false;
113  //
114  // (F) Check that the linear system was solved to the specified tolerance
115  //
116  RCP<Thyra::VectorBase<double> > r = createMember(A->range());
117  Thyra::assign(r.ptr(),*b); // r = b
118  Thyra::apply(*A,Thyra::NOTRANS,*x,r.ptr(),-1.0,+1.0); // r = -A*x + r
119  const double r_nrm = Thyra::norm(*r), b_nrm =Thyra:: norm(*b);
120  const double rel_err = r_nrm/b_nrm, relaxTol = 2.0*tolerance;
121  result = rel_err <= relaxTol;
122  if(!result) success = false;
123  if(verbose)
124  *out
125  << "\n||b-A*x||/||b|| = "<<r_nrm<<"/"<<b_nrm<<" = "<<rel_err<<(result?" <= ":" > ")
126  <<"2.0*tolerance = "<<relaxTol<<": "<<(result?"passed":"failed")<<std::endl;
127 
128  }
129  TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success)
130 
131  if (verbose) {
132  if(success) *out << "\nCongratulations! All of the tests checked out!\n";
133  else *out << "\nOh no! At least one of the tests failed!\n";
134  }
135 
136  return success ? 0 : 1;
137 
138 } // end main()
Teuchos::RCP< Epetra_Operator > createTridiagEpetraLinearOp(const int globalDim, const double diagScale, const bool verbose, std::ostream &out)
This function generates a tridiagonal linear operator using Epetra.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
int main(int argc, char *argv[])