Stratimikos Version of the Day
Loading...
Searching...
No Matches
simple_stratimikos_example.cpp

Simple example program for how the Stratimikos::DefaultLinearSolverBuilder class is used to take a parameter list (e.g. read from a file) and use it so solve a linear system read in as Epetra objects from a file.

Outline

Example program source (with line numbers)

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
10#include "Stratimikos_DefaultLinearSolverBuilder.hpp"
12#include "Teuchos_GlobalMPISession.hpp"
13#include "Teuchos_VerboseObject.hpp"
14#include "Teuchos_XMLParameterListHelpers.hpp"
15#include "Teuchos_CommandLineProcessor.hpp"
16#include "Teuchos_StandardCatchMacros.hpp"
17#ifdef HAVE_MPI
18# include "Epetra_MpiComm.h"
19#else
20# include "Epetra_SerialComm.h"
21#endif
22
23
24namespace {
25
26
27// Helper function to compute a single norm for a vector
28double epetraNorm2( const Epetra_Vector &v )
29{
30 double norm[1] = { -1.0 };
31 v.Norm2(&norm[0]);
32 return norm[0];
33}
34
35
36} // namespace
37
38
39int main(int argc, char* argv[])
40{
41
42 using Teuchos::rcp;
43 using Teuchos::RCP;
44 using Teuchos::CommandLineProcessor;
45 typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
46
47 bool success = true;
48 bool verbose = true;
49
50 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
51
52 Teuchos::RCP<Teuchos::FancyOStream>
53 out = Teuchos::VerboseObjectBase::getDefaultOStream();
54
55 try {
56
57
58 //
59 // A) Program setup code
60 //
61
62 //
63 // Read options from command-line
64 //
65
66 std::string matrixFile = "";
67 std::string extraParamsFile = "";
68 double tol = 1e-5;
69 bool onlyPrintOptions = false;
70 bool printXmlFormat = false;
71 bool showDoc = true;
72
73 Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;
74
75 CommandLineProcessor clp(false); // Don't throw exceptions
76
77 // Set up command-line options for the linear solver that will be used!
78 linearSolverBuilder.setupCLP(&clp);
79
80 clp.setOption( "matrix-file", &matrixFile
81 ,"Defines the matrix and perhaps the RHS and LHS for a linear system to be solved." );
82 clp.setOption( "tol", &tol, "Tolerance to check against the scaled residual norm." );
83 clp.setOption( "extra-params-file", &extraParamsFile, "File containing extra parameters in XML format.");
84 clp.setOption( "only-print-options", "continue-after-printing-options", &onlyPrintOptions
85 ,"Only print options and stop or continue on" );
86 clp.setOption( "print-xml-format", "print-readable-format", &printXmlFormat
87 ,"Print the valid options in XML format or in readable format." );
88 clp.setOption( "show-doc", "hide-doc", &showDoc
89 ,"Print the valid options with or without documentation." );
90
91 clp.setDocString(
92 "Simple example for the use of the Stratimikos facade Stratimikos::DefaultLinearSolverBuilder.\n"
93 "\n"
94 "To print out just the valid options use --matrix-file=\"\" --only-print-options with --print-xml-format"
95 " or --print-readable-format.\n"
96 "\n"
97 "To solve a linear system read from a file use --matrix-file=\"SomeFile.mtx\""
98 " with options read from an XML file using --linear-solver-params-file=\"SomeFile.xml\"\n"
99 );
100
101 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
102 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
103
104 //
105 // Print out the valid options and stop if asked
106 //
107
108 if(onlyPrintOptions) {
109 if(printXmlFormat)
110 Teuchos::writeParameterListToXmlOStream(
111 *linearSolverBuilder.getValidParameters()
112 ,*out
113 );
114 else
115 linearSolverBuilder.getValidParameters()->print(
116 *out,PLPrintOptions().indent(2).showTypes(true).showDoc(showDoc)
117 );
118 return 0;
119 }
120
121
122 //
123 // B) Epetra-specific code that sets up the linear system to be solved
124 //
125 // While the below code reads in the Epetra objects from a file, you can
126 // setup the Epetra objects any way you would like. Note that this next
127 // set of code as nothing to do with Thyra at all, and it should not.
128 //
129
130 *out << "\nReading linear system in Epetra format from the file \'"<<matrixFile<<"\' ...\n";
131
132#ifdef HAVE_MPI
133 Epetra_MpiComm comm(MPI_COMM_WORLD);
134#else
136#endif
137 RCP<Epetra_CrsMatrix> epetra_A;
138 RCP<Epetra_Vector> epetra_x, epetra_b;
139 EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A, NULL, &epetra_x, &epetra_b );
140
141 if(!epetra_b.get()) {
142 *out << "\nThe RHS b was not read in so generate a new random vector ...\n";
143 epetra_b = rcp(new Epetra_Vector(epetra_A->OperatorRangeMap()));
144 epetra_b->Random();
145 }
146
147 if(!epetra_x.get()) {
148 *out << "\nThe LHS x was not read in so generate a new zero vector ...\n";
149 epetra_x = rcp(new Epetra_Vector(epetra_A->OperatorDomainMap()));
150 epetra_x->PutScalar(0.0); // Initial guess is critical!
151 }
152
153 *out << "\nPrinting statistics of the Epetra linear system ...\n";
154
155 *out
156 << "\n Epetra_CrsMatrix epetra_A of dimension "
157 << epetra_A->OperatorRangeMap().NumGlobalElements()
158 << " x " << epetra_A->OperatorDomainMap().NumGlobalElements()
159 << "\n ||epetraA||inf = " << epetra_A->NormInf()
160 << "\n ||epetra_b||2 = " << epetraNorm2(*epetra_b)
161 << "\n ||epetra_x||2 = " << epetraNorm2(*epetra_x)
162 << "\n";
163
164
165 //
166 // C) The "Glue" code that takes Epetra objects and wraps them as Thyra
167 // objects
168 //
169 // This next set of code wraps the Epetra objects that define the linear
170 // system to be solved as Thyra objects so that they can be passed to the
171 // linear solver.
172 //
173
174 RCP<const Thyra::LinearOpBase<double> > A = Thyra::epetraLinearOp( epetra_A );
175 RCP<Thyra::VectorBase<double> > x = Thyra::create_Vector( epetra_x, A->domain() );
176 RCP<const Thyra::VectorBase<double> > b = Thyra::create_Vector( epetra_b, A->range() );
177
178 // Note that above Thyra is only interacted with in the most trival of
179 // ways. For most users, Thyra will only be seen as a thin wrapper that
180 // they need know little about in order to wrap their objects in order to
181 // pass them to Thyra-enabled solvers.
182
183
184 //
185 // D) Thyra-specific code for solving the linear system
186 //
187 // Note that this code has no mention of any concrete implementation and
188 // therefore can be used in any use case.
189 //
190
191 // Reading in the solver parameters from the parameters file and/or from
192 // the command line. This was setup by the command-line options
193 // set by the setupCLP(...) function above.
194 linearSolverBuilder.readParameters(out.get());
195
196 // Augment parameters if appropriate
197 if(extraParamsFile.length()) {
198 Teuchos::updateParametersFromXmlFile( "./"+extraParamsFile,
199 linearSolverBuilder.getNonconstParameterList().ptr() );
200 }
201
202 // Create a linear solver factory given information read from the
203 // parameter list.
204 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory =
205 linearSolverBuilder.createLinearSolveStrategy("");
206
207 // Setup output stream and the verbosity level
208 lowsFactory->setOStream(out);
209 lowsFactory->setVerbLevel(Teuchos::VERB_LOW);
210
211 // Create a linear solver based on the forward operator A
212 RCP<Thyra::LinearOpWithSolveBase<double> > lows =
213 Thyra::linearOpWithSolve(*lowsFactory, A);
214
215 // Solve the linear system (note: the initial guess in 'x' is critical)
216 Thyra::SolveStatus<double> status =
217 Thyra::solve<double>(*lows, Thyra::NOTRANS, *b, x.ptr());
218 *out << "\nSolve status:\n" << status;
219
220 // Write the linear solver parameters after they were read
221 linearSolverBuilder.writeParamsFile(*lowsFactory);
222
223
224 //
225 // E) Post process the solution and check the error
226 //
227 // Note that the below code is based only on the Epetra objects themselves
228 // and does not in any way depend or interact with any Thyra-based
229 // objects. The point is that most users of Thyra can largely gloss over
230 // the fact that Thyra is really being used for anything.
231 //
232
233 // Wipe out the Thyra wrapper for x to guarantee that the solution will be
234 // written back to epetra_x! At the time of this writting this is not
235 // really needed but the behavior may change at some point so this is a
236 // good idea.
237 x = Teuchos::null;
238
239 *out
240 << "\nSolution ||epetra_x||2 = " << epetraNorm2(*epetra_x) << "\n";
241
242 *out << "\nTesting the solution error ||b-A*x||/||b|| computed through the Epetra objects ...\n";
243
244 // r = b - A*x
245 Epetra_Vector epetra_r(*epetra_b);
246 {
247 Epetra_Vector epetra_A_x(epetra_A->OperatorRangeMap());
248 epetra_A->Apply(*epetra_x,epetra_A_x);
249 epetra_r.Update(-1.0,epetra_A_x,1.0);
250 }
251
252 const double
253 nrm_r = epetraNorm2(epetra_r),
254 nrm_b = epetraNorm2(*epetra_b),
255 rel_err = ( nrm_r / nrm_b );
256 const bool
257 passed = (rel_err <= tol);
258
259 *out
260 << "||b-A*x||/||b|| = " << nrm_r << "/" << nrm_b << " = " << rel_err
261 << " < tol = " << tol << " ? " << ( passed ? "passed" : "failed" ) << "\n";
262
263 if(!passed) success = false;
264
265 }
266 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success)
267
268 if (verbose) {
269 if(success) *out << "\nCongratulations! All of the tests checked out!\n";
270 else *out << "\nOh no! At least one of the tests failed!\n";
271 }
272
273 return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
274
275}
int Norm2(double *Result) const
RCP< const ParameterList > getValidParameters() const
RCP< Thyra::LinearOpWithSolveFactoryBase< Scalar > > createLinearSolveStrategy(const std::string &linearSolveStrategyName) const
void setupCLP(Teuchos::CommandLineProcessor *clp)
Setup the command-line processor to read in the needed data to extra the parameters from.
void readParameters(std::ostream *out)
Force the parameters to be read from a file and/or an extra XML string.
void writeParamsFile(const Thyra::LinearOpWithSolveFactoryBase< Scalar > &lowsFactory, const std::string &outputXmlFileName="") const
Write the parameters list for a LinearOpWithSolveFactoryBase object to a file after the parameters ar...
void readEpetraLinearSystem(const std::string &fileName, const Epetra_Comm &comm, Teuchos::RCP< Epetra_CrsMatrix > *A=NULL, Teuchos::RCP< Epetra_Map > *map=NULL, Teuchos::RCP< Epetra_Vector > *x=NULL, Teuchos::RCP< Epetra_Vector > *b=NULL, Teuchos::RCP< Epetra_Vector > *xExact=NULL)

Command-line options for the driver program

Teuchos::GlobalMPISession::GlobalMPISession(): started serial run

Echoing the command-line:

/home/rabartl/PROJECTS/Trilinos.base/BUILDS/CMAKE/SERIAL_DEBUG/packages/stratimikos/example/Stratimikos_simple_stratimikos_example.exe --echo-command-line --help 

Usage: /home/rabartl/PROJECTS/Trilinos.base/BUILDS/CMAKE/SERIAL_DEBUG/packages/stratimikos/example/Stratimikos_simple_stratimikos_example.exe [options]
  options:
  --help                                     Prints this help message
  --pause-for-debugging                      Pauses for user input to allow attaching a debugger
  --echo-command-line                        Echo the command-line but continue as normal
  --linear-solver-params-file        string  Name of an XML file containing parameters for linear solver options to be appended first.
                                             (default: --linear-solver-params-file="")
  --extra-linear-solver-params       string  An XML string containing linear solver parameters to be appended second.
                                             (default: --extra-linear-solver-params="")
  --linear-solver-params-used-file   string  Name of an XML file that can be written with the parameter list after it has been used on completion of this program.
                                             (default: --linear-solver-params-used-file="")
  --matrix-file                      string  Defines the matrix and perhaps the RHS and LHS for a linear system to be solved.
                                             (default: --matrix-file="")
  --tol                              double  Tolerance to check against the scaled residual norm.
                                             (default: --tol=1e-05)
  --only-print-options               bool    Only print options and stop or continue on
  --continue-after-printing-options          (default: --continue-after-printing-options)
  --print-xml-format                 bool    Print the valid options in XML format or in readable format.
  --print-readable-format                    (default: --print-readable-format)
  --show-doc                         bool    Print the valid options with or without documentation.
  --hide-doc                                 (default: --show-doc)

DETAILED DOCUMENTATION:

Simple example for the use of the Stratimikos facade Stratimikos::DefaultLinearSolverBuilder.

To print out just the valid options use --matrix-file="" --only-print-options with --print-xml-format or --print-readable-format.

To solve a linear system from a system read from a file use --matrix-file="SomeFile.mtx" with options read from an XML file using --linear-solver-params-file="SomeFile.xml"


Example input XML file

Here is an example input XML file, called amesos.klu.xml, that specifies that the KLU solver from Amesos be used to solve the linear system:

<ParameterList>
  <Parameter isUsed="true" name="Linear Solver Type" type="string" value="Amesos"/>
  <ParameterList name="Linear Solver Types">
    <ParameterList name="Amesos">
      <ParameterList name="Amesos Settings"/>
      <Parameter name="Solver Type" type="string" value="Klu"/>
    </ParameterList>
  </ParameterList>
  <Parameter name="Preconditioner Type" type="string" value="None"/>
</ParameterList>

Example program output

Sample output looks like when using the above amesos.klu.xml file as input with a test system:

Teuchos::GlobalMPISession::GlobalMPISession(): started serial run

Echoing the command-line:

/home/rabartl/PROJECTS/Trilinos.base/BUILDS/CMAKE/SERIAL_DEBUG/packages/stratimikos/example/Stratimikos_simple_stratimikos_example.exe --echo-command-line --matrix-file=FourByFour.mtx --linear-solver-params-file=amesos.klu.xml 


Reading linear system in Epetra format from the file 'FourByFour.mtx' ...

Printing statistics of the Epetra linear system ...

  Epetra_CrsMatrix epetra_A of dimension 4 x 4
  ||epetraA||inf = 1.643
  ||epetra_b||2 = 1.52593
  ||epetra_x||2 = 0

Reading parameters from XML file "amesos.klu.xml" ...
 
 Solving block system using Amesos solver Amesos_Klu ...
 
 
 Total solve time = 0 sec

Solve status:
 solveStatus = SOLVE_STATUS_CONVERGED
 achievedTol = unknownTolerance()
 message:
  Solver Amesos_Klu converged!
 extraParameters: NONE

Solution ||epetra_x||2 = 1.24984

Testing the solution error ||b-A*x||/||b|| computed through the Epetra objects ...
||b-A*x||/||b|| = 1.11022e-16/1.52593 = 7.27571e-17 < tol = 1e-05 ? passed

Congratulations! All of the tests checked out!

Example program source (without line numbers)

Here is the main driver program itself without line numbers:

// @HEADER
// *****************************************************************************
// Stratimikos: Thyra-based strategies for linear solvers
//
// Copyright 2006 NTESS and the Stratimikos contributors.
// SPDX-License-Identifier: BSD-3-Clause
// *****************************************************************************
// @HEADER
#include "Stratimikos_DefaultLinearSolverBuilder.hpp"
#include "Teuchos_GlobalMPISession.hpp"
#include "Teuchos_VerboseObject.hpp"
#include "Teuchos_XMLParameterListHelpers.hpp"
#include "Teuchos_CommandLineProcessor.hpp"
#include "Teuchos_StandardCatchMacros.hpp"
#ifdef HAVE_MPI
# include "Epetra_MpiComm.h"
#else
# include "Epetra_SerialComm.h"
#endif
namespace {
// Helper function to compute a single norm for a vector
double epetraNorm2( const Epetra_Vector &v )
{
double norm[1] = { -1.0 };
v.Norm2(&norm[0]);
return norm[0];
}
} // namespace
int main(int argc, char* argv[])
{
using Teuchos::rcp;
using Teuchos::RCP;
using Teuchos::CommandLineProcessor;
typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
bool success = true;
bool verbose = true;
Teuchos::GlobalMPISession mpiSession(&argc, &argv);
Teuchos::RCP<Teuchos::FancyOStream>
out = Teuchos::VerboseObjectBase::getDefaultOStream();
try {
//
// A) Program setup code
//
//
// Read options from command-line
//
std::string matrixFile = "";
std::string extraParamsFile = "";
double tol = 1e-5;
bool onlyPrintOptions = false;
bool printXmlFormat = false;
bool showDoc = true;
Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;
CommandLineProcessor clp(false); // Don't throw exceptions
// Set up command-line options for the linear solver that will be used!
linearSolverBuilder.setupCLP(&clp);
clp.setOption( "matrix-file", &matrixFile
,"Defines the matrix and perhaps the RHS and LHS for a linear system to be solved." );
clp.setOption( "tol", &tol, "Tolerance to check against the scaled residual norm." );
clp.setOption( "extra-params-file", &extraParamsFile, "File containing extra parameters in XML format.");
clp.setOption( "only-print-options", "continue-after-printing-options", &onlyPrintOptions
,"Only print options and stop or continue on" );
clp.setOption( "print-xml-format", "print-readable-format", &printXmlFormat
,"Print the valid options in XML format or in readable format." );
clp.setOption( "show-doc", "hide-doc", &showDoc
,"Print the valid options with or without documentation." );
clp.setDocString(
"Simple example for the use of the Stratimikos facade Stratimikos::DefaultLinearSolverBuilder.\n"
"\n"
"To print out just the valid options use --matrix-file=\"\" --only-print-options with --print-xml-format"
" or --print-readable-format.\n"
"\n"
"To solve a linear system read from a file use --matrix-file=\"SomeFile.mtx\""
" with options read from an XML file using --linear-solver-params-file=\"SomeFile.xml\"\n"
);
CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
//
// Print out the valid options and stop if asked
//
if(onlyPrintOptions) {
if(printXmlFormat)
Teuchos::writeParameterListToXmlOStream(
*linearSolverBuilder.getValidParameters()
,*out
);
else
linearSolverBuilder.getValidParameters()->print(
*out,PLPrintOptions().indent(2).showTypes(true).showDoc(showDoc)
);
return 0;
}
//
// B) Epetra-specific code that sets up the linear system to be solved
//
// While the below code reads in the Epetra objects from a file, you can
// setup the Epetra objects any way you would like. Note that this next
// set of code as nothing to do with Thyra at all, and it should not.
//
*out << "\nReading linear system in Epetra format from the file \'"<<matrixFile<<"\' ...\n";
#ifdef HAVE_MPI
Epetra_MpiComm comm(MPI_COMM_WORLD);
#else
#endif
RCP<Epetra_CrsMatrix> epetra_A;
RCP<Epetra_Vector> epetra_x, epetra_b;
EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A, NULL, &epetra_x, &epetra_b );
if(!epetra_b.get()) {
*out << "\nThe RHS b was not read in so generate a new random vector ...\n";
epetra_b = rcp(new Epetra_Vector(epetra_A->OperatorRangeMap()));
epetra_b->Random();
}
if(!epetra_x.get()) {
*out << "\nThe LHS x was not read in so generate a new zero vector ...\n";
epetra_x = rcp(new Epetra_Vector(epetra_A->OperatorDomainMap()));
epetra_x->PutScalar(0.0); // Initial guess is critical!
}
*out << "\nPrinting statistics of the Epetra linear system ...\n";
*out
<< "\n Epetra_CrsMatrix epetra_A of dimension "
<< epetra_A->OperatorRangeMap().NumGlobalElements()
<< " x " << epetra_A->OperatorDomainMap().NumGlobalElements()
<< "\n ||epetraA||inf = " << epetra_A->NormInf()
<< "\n ||epetra_b||2 = " << epetraNorm2(*epetra_b)
<< "\n ||epetra_x||2 = " << epetraNorm2(*epetra_x)
<< "\n";
//
// C) The "Glue" code that takes Epetra objects and wraps them as Thyra
// objects
//
// This next set of code wraps the Epetra objects that define the linear
// system to be solved as Thyra objects so that they can be passed to the
// linear solver.
//
RCP<const Thyra::LinearOpBase<double> > A = Thyra::epetraLinearOp( epetra_A );
RCP<Thyra::VectorBase<double> > x = Thyra::create_Vector( epetra_x, A->domain() );
RCP<const Thyra::VectorBase<double> > b = Thyra::create_Vector( epetra_b, A->range() );
// Note that above Thyra is only interacted with in the most trival of
// ways. For most users, Thyra will only be seen as a thin wrapper that
// they need know little about in order to wrap their objects in order to
// pass them to Thyra-enabled solvers.
//
// D) Thyra-specific code for solving the linear system
//
// Note that this code has no mention of any concrete implementation and
// therefore can be used in any use case.
//
// Reading in the solver parameters from the parameters file and/or from
// the command line. This was setup by the command-line options
// set by the setupCLP(...) function above.
linearSolverBuilder.readParameters(out.get());
// Augment parameters if appropriate
if(extraParamsFile.length()) {
Teuchos::updateParametersFromXmlFile( "./"+extraParamsFile,
linearSolverBuilder.getNonconstParameterList().ptr() );
}
// Create a linear solver factory given information read from the
// parameter list.
RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory =
linearSolverBuilder.createLinearSolveStrategy("");
// Setup output stream and the verbosity level
lowsFactory->setOStream(out);
lowsFactory->setVerbLevel(Teuchos::VERB_LOW);
// Create a linear solver based on the forward operator A
RCP<Thyra::LinearOpWithSolveBase<double> > lows =
Thyra::linearOpWithSolve(*lowsFactory, A);
// Solve the linear system (note: the initial guess in 'x' is critical)
Thyra::SolveStatus<double> status =
Thyra::solve<double>(*lows, Thyra::NOTRANS, *b, x.ptr());
*out << "\nSolve status:\n" << status;
// Write the linear solver parameters after they were read
linearSolverBuilder.writeParamsFile(*lowsFactory);
//
// E) Post process the solution and check the error
//
// Note that the below code is based only on the Epetra objects themselves
// and does not in any way depend or interact with any Thyra-based
// objects. The point is that most users of Thyra can largely gloss over
// the fact that Thyra is really being used for anything.
//
// Wipe out the Thyra wrapper for x to guarantee that the solution will be
// written back to epetra_x! At the time of this writting this is not
// really needed but the behavior may change at some point so this is a
// good idea.
x = Teuchos::null;
*out
<< "\nSolution ||epetra_x||2 = " << epetraNorm2(*epetra_x) << "\n";
*out << "\nTesting the solution error ||b-A*x||/||b|| computed through the Epetra objects ...\n";
// r = b - A*x
Epetra_Vector epetra_r(*epetra_b);
{
Epetra_Vector epetra_A_x(epetra_A->OperatorRangeMap());
epetra_A->Apply(*epetra_x,epetra_A_x);
epetra_r.Update(-1.0,epetra_A_x,1.0);
}
const double
nrm_r = epetraNorm2(epetra_r),
nrm_b = epetraNorm2(*epetra_b),
rel_err = ( nrm_r / nrm_b );
const bool
passed = (rel_err <= tol);
*out
<< "||b-A*x||/||b|| = " << nrm_r << "/" << nrm_b << " = " << rel_err
<< " < tol = " << tol << " ? " << ( passed ? "passed" : "failed" ) << "\n";
if(!passed) success = false;
}
TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success)
if (verbose) {
if(success) *out << "\nCongratulations! All of the tests checked out!\n";
else *out << "\nOh no! At least one of the tests failed!\n";
}
return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}

Generated on for Stratimikos by doxygen 1.15.0