|
Stratimikos Package Browser (Single Doxygen Collection)
Version of the Day
|
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)
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Stratimikos: Thyra-based strategies for linear solvers 00005 // Copyright (2006) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #include "Stratimikos_DefaultLinearSolverBuilder.hpp" 00043 #include "EpetraExt_readEpetraLinearSystem.h" 00044 #include "Teuchos_GlobalMPISession.hpp" 00045 #include "Teuchos_VerboseObject.hpp" 00046 #include "Teuchos_XMLParameterListHelpers.hpp" 00047 #include "Teuchos_CommandLineProcessor.hpp" 00048 #include "Teuchos_StandardCatchMacros.hpp" 00049 #ifdef HAVE_MPI 00050 # include "Epetra_MpiComm.h" 00051 #else 00052 # include "Epetra_SerialComm.h" 00053 #endif 00054 00055 00056 namespace { 00057 00058 00059 // Helper function to compute a single norm for a vector 00060 double epetraNorm2( const Epetra_Vector &v ) 00061 { 00062 double norm[1] = { -1.0 }; 00063 v.Norm2(&norm[0]); 00064 return norm[0]; 00065 } 00066 00067 00068 } // namespace 00069 00070 00071 int main(int argc, char* argv[]) 00072 { 00073 00074 using Teuchos::rcp; 00075 using Teuchos::RCP; 00076 using Teuchos::CommandLineProcessor; 00077 typedef Teuchos::ParameterList::PrintOptions PLPrintOptions; 00078 00079 bool success = true; 00080 bool verbose = true; 00081 00082 Teuchos::GlobalMPISession mpiSession(&argc, &argv); 00083 00084 Teuchos::RCP<Teuchos::FancyOStream> 00085 out = Teuchos::VerboseObjectBase::getDefaultOStream(); 00086 00087 try { 00088 00089 00090 // 00091 // A) Program setup code 00092 // 00093 00094 // 00095 // Read options from command-line 00096 // 00097 00098 std::string matrixFile = ""; 00099 std::string extraParamsFile = ""; 00100 double tol = 1e-5; 00101 bool onlyPrintOptions = false; 00102 bool printXmlFormat = false; 00103 bool showDoc = true; 00104 00105 Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder; 00106 00107 CommandLineProcessor clp(false); // Don't throw exceptions 00108 00109 // Set up command-line options for the linear solver that will be used! 00110 linearSolverBuilder.setupCLP(&clp); 00111 00112 clp.setOption( "matrix-file", &matrixFile 00113 ,"Defines the matrix and perhaps the RHS and LHS for a linear system to be solved." ); 00114 clp.setOption( "tol", &tol, "Tolerance to check against the scaled residual norm." ); 00115 clp.setOption( "extra-params-file", &extraParamsFile, "File containing extra parameters in XML format."); 00116 clp.setOption( "only-print-options", "continue-after-printing-options", &onlyPrintOptions 00117 ,"Only print options and stop or continue on" ); 00118 clp.setOption( "print-xml-format", "print-readable-format", &printXmlFormat 00119 ,"Print the valid options in XML format or in readable format." ); 00120 clp.setOption( "show-doc", "hide-doc", &showDoc 00121 ,"Print the valid options with or without documentation." ); 00122 00123 clp.setDocString( 00124 "Simple example for the use of the Stratimikos facade Stratimikos::DefaultLinearSolverBuilder.\n" 00125 "\n" 00126 "To print out just the valid options use --matrix-file=\"\" --only-print-options with --print-xml-format" 00127 " or --print-readable-format.\n" 00128 "\n" 00129 "To solve a linear system read from a file use --matrix-file=\"SomeFile.mtx\"" 00130 " with options read from an XML file using --linear-solver-params-file=\"SomeFile.xml\"\n" 00131 ); 00132 00133 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv); 00134 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return; 00135 00136 // 00137 // Print out the valid options and stop if asked 00138 // 00139 00140 if(onlyPrintOptions) { 00141 if(printXmlFormat) 00142 Teuchos::writeParameterListToXmlOStream( 00143 *linearSolverBuilder.getValidParameters() 00144 ,*out 00145 ); 00146 else 00147 linearSolverBuilder.getValidParameters()->print( 00148 *out,PLPrintOptions().indent(2).showTypes(true).showDoc(showDoc) 00149 ); 00150 return 0; 00151 } 00152 00153 00154 // 00155 // B) Epetra-specific code that sets up the linear system to be solved 00156 // 00157 // While the below code reads in the Epetra objects from a file, you can 00158 // setup the Epetra objects any way you would like. Note that this next 00159 // set of code as nothing to do with Thyra at all, and it should not. 00160 // 00161 00162 *out << "\nReading linear system in Epetra format from the file \'"<<matrixFile<<"\' ...\n"; 00163 00164 #ifdef HAVE_MPI 00165 Epetra_MpiComm comm(MPI_COMM_WORLD); 00166 #else 00167 Epetra_SerialComm comm; 00168 #endif 00169 RCP<Epetra_CrsMatrix> epetra_A; 00170 RCP<Epetra_Vector> epetra_x, epetra_b; 00171 EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A, NULL, &epetra_x, &epetra_b ); 00172 00173 if(!epetra_b.get()) { 00174 *out << "\nThe RHS b was not read in so generate a new random vector ...\n"; 00175 epetra_b = rcp(new Epetra_Vector(epetra_A->OperatorRangeMap())); 00176 epetra_b->Random(); 00177 } 00178 00179 if(!epetra_x.get()) { 00180 *out << "\nThe LHS x was not read in so generate a new zero vector ...\n"; 00181 epetra_x = rcp(new Epetra_Vector(epetra_A->OperatorDomainMap())); 00182 epetra_x->PutScalar(0.0); // Initial guess is critical! 00183 } 00184 00185 *out << "\nPrinting statistics of the Epetra linear system ...\n"; 00186 00187 *out 00188 << "\n Epetra_CrsMatrix epetra_A of dimension " 00189 << epetra_A->OperatorRangeMap().NumGlobalElements() 00190 << " x " << epetra_A->OperatorDomainMap().NumGlobalElements() 00191 << "\n ||epetraA||inf = " << epetra_A->NormInf() 00192 << "\n ||epetra_b||2 = " << epetraNorm2(*epetra_b) 00193 << "\n ||epetra_x||2 = " << epetraNorm2(*epetra_x) 00194 << "\n"; 00195 00196 00197 // 00198 // C) The "Glue" code that takes Epetra objects and wraps them as Thyra 00199 // objects 00200 // 00201 // This next set of code wraps the Epetra objects that define the linear 00202 // system to be solved as Thyra objects so that they can be passed to the 00203 // linear solver. 00204 // 00205 00206 RCP<const Thyra::LinearOpBase<double> > A = Thyra::epetraLinearOp( epetra_A ); 00207 RCP<Thyra::VectorBase<double> > x = Thyra::create_Vector( epetra_x, A->domain() ); 00208 RCP<const Thyra::VectorBase<double> > b = Thyra::create_Vector( epetra_b, A->range() ); 00209 00210 // Note that above Thyra is only interacted with in the most trival of 00211 // ways. For most users, Thyra will only be seen as a thin wrapper that 00212 // they need know little about in order to wrap their objects in order to 00213 // pass them to Thyra-enabled solvers. 00214 00215 00216 // 00217 // D) Thyra-specific code for solving the linear system 00218 // 00219 // Note that this code has no mention of any concrete implementation and 00220 // therefore can be used in any use case. 00221 // 00222 00223 // Reading in the solver parameters from the parameters file and/or from 00224 // the command line. This was setup by the command-line options 00225 // set by the setupCLP(...) function above. 00226 linearSolverBuilder.readParameters(out.get()); 00227 00228 // Augment parameters if appropriate 00229 if(extraParamsFile.length()) { 00230 Teuchos::updateParametersFromXmlFile( "./"+extraParamsFile, 00231 linearSolverBuilder.getNonconstParameterList().ptr() ); 00232 } 00233 00234 // Create a linear solver factory given information read from the 00235 // parameter list. 00236 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory = 00237 linearSolverBuilder.createLinearSolveStrategy(""); 00238 00239 // Setup output stream and the verbosity level 00240 lowsFactory->setOStream(out); 00241 lowsFactory->setVerbLevel(Teuchos::VERB_LOW); 00242 00243 // Create a linear solver based on the forward operator A 00244 RCP<Thyra::LinearOpWithSolveBase<double> > lows = 00245 Thyra::linearOpWithSolve(*lowsFactory, A); 00246 00247 // Solve the linear system (note: the initial guess in 'x' is critical) 00248 Thyra::SolveStatus<double> status = 00249 Thyra::solve<double>(*lows, Thyra::NOTRANS, *b, x.ptr()); 00250 *out << "\nSolve status:\n" << status; 00251 00252 // Write the linear solver parameters after they were read 00253 linearSolverBuilder.writeParamsFile(*lowsFactory); 00254 00255 00256 // 00257 // E) Post process the solution and check the error 00258 // 00259 // Note that the below code is based only on the Epetra objects themselves 00260 // and does not in any way depend or interact with any Thyra-based 00261 // objects. The point is that most users of Thyra can largely gloss over 00262 // the fact that Thyra is really being used for anything. 00263 // 00264 00265 // Wipe out the Thyra wrapper for x to guarantee that the solution will be 00266 // written back to epetra_x! At the time of this writting this is not 00267 // really needed but the behavior may change at some point so this is a 00268 // good idea. 00269 x = Teuchos::null; 00270 00271 *out 00272 << "\nSolution ||epetra_x||2 = " << epetraNorm2(*epetra_x) << "\n"; 00273 00274 *out << "\nTesting the solution error ||b-A*x||/||b|| computed through the Epetra objects ...\n"; 00275 00276 // r = b - A*x 00277 Epetra_Vector epetra_r(*epetra_b); 00278 { 00279 Epetra_Vector epetra_A_x(epetra_A->OperatorRangeMap()); 00280 epetra_A->Apply(*epetra_x,epetra_A_x); 00281 epetra_r.Update(-1.0,epetra_A_x,1.0); 00282 } 00283 00284 const double 00285 nrm_r = epetraNorm2(epetra_r), 00286 nrm_b = epetraNorm2(*epetra_b), 00287 rel_err = ( nrm_r / nrm_b ); 00288 const bool 00289 passed = (rel_err <= tol); 00290 00291 *out 00292 << "||b-A*x||/||b|| = " << nrm_r << "/" << nrm_b << " = " << rel_err 00293 << " < tol = " << tol << " ? " << ( passed ? "passed" : "failed" ) << "\n"; 00294 00295 if(!passed) success = false; 00296 00297 } 00298 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success) 00299 00300 if (verbose) { 00301 if(success) *out << "\nCongratulations! All of the tests checked out!\n"; 00302 else *out << "\nOh no! At least one of the tests failed!\n"; 00303 } 00304 00305 return ( success ? EXIT_SUCCESS : EXIT_FAILURE ); 00306 00307 }
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"
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>
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) Sandia Corporation // // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive // license for use of this work by or on behalf of the U.S. Government. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) // // *********************************************************************** // @HEADER #include "Stratimikos_DefaultLinearSolverBuilder.hpp" #include "EpetraExt_readEpetraLinearSystem.h" #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 Epetra_SerialComm comm; #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 ); }
1.7.6.1