00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "Thyra_DefaultRealLinearSolverBuilder.hpp"
00030 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
00031 #include "Thyra_EpetraThyraWrappers.hpp"
00032 #include "Thyra_EpetraLinearOp.hpp"
00033 #include "EpetraExt_readEpetraLinearSystem.h"
00034 #include "Teuchos_GlobalMPISession.hpp"
00035 #include "Teuchos_VerboseObject.hpp"
00036 #include "Teuchos_XMLParameterListHelpers.hpp"
00037 #include "Teuchos_CommandLineProcessor.hpp"
00038 #include "Teuchos_StandardCatchMacros.hpp"
00039 #ifdef HAVE_MPI
00040 # include "Epetra_MpiComm.h"
00041 #else
00042 # include "Epetra_SerialComm.h"
00043 #endif
00044
00045 namespace {
00046
00047
00048 double epetraNorm2( const Epetra_Vector &v )
00049 {
00050 double norm[1] = { -1.0 };
00051 v.Norm2(&norm[0]);
00052 return norm[0];
00053 }
00054
00055 }
00056
00057 int main(int argc, char* argv[])
00058 {
00059
00060 using Teuchos::rcp;
00061 using Teuchos::RefCountPtr;
00062 using Teuchos::CommandLineProcessor;
00063
00064 bool success = true;
00065 bool verbose = true;
00066
00067 Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00068
00069 Teuchos::RefCountPtr<Teuchos::FancyOStream>
00070 out = Teuchos::VerboseObjectBase::getDefaultOStream();
00071
00072 try {
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 std::string matrixFile = "";
00083 double tol = 1e-5;
00084 bool onlyPrintOptions = false;
00085 bool printXmlFormat = false;
00086
00087 Thyra::DefaultRealLinearSolverBuilder linearSolverBuilder;
00088
00089 CommandLineProcessor clp(false);
00090
00091
00092 linearSolverBuilder.setupCLP(&clp);
00093
00094 clp.setOption( "matrix-file", &matrixFile
00095 ,"Defines the matrix and perhaps the RHS and LHS for a linear system to be solved." );
00096 clp.setOption( "tol", &tol, "Tolerance to check against the scaled residual norm." );
00097 clp.setOption( "only-print-options", "continue-after-printing-options", &onlyPrintOptions
00098 ,"Only print options and stop or continue on" );
00099 clp.setOption( "print-xml-format", "print-readable-format", &printXmlFormat
00100 ,"Print the valid options in XML format or in readable format." );
00101
00102 clp.setDocString(
00103 "Simple example for the use of the Stratimikos facade Thyra::DefaultRealLinearSolverBuilder.\n"
00104 "\n"
00105 "To print out just the valid options use --matrix-file=\"\" --only-print-options with --print-xml-format"
00106 " or --print-readable-format.\n"
00107 "\n"
00108 "To solve a linear system from a system read from a file use --matrix-file=\"SomeFile.mtx\""
00109 " with options read from an XML file using --linear-solver-params-file=\"SomeFile.xml\"\n"
00110 );
00111
00112 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00113 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
00114
00115
00116
00117
00118
00119 if(onlyPrintOptions) {
00120 if(printXmlFormat)
00121 Teuchos::writeParameterListToXmlOStream(
00122 *linearSolverBuilder.getValidParameters()
00123 ,*out
00124 );
00125 else
00126 linearSolverBuilder.getValidParameters()->print(*out,1,true,false);
00127 return 0;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 *out << "\nReading linear system in Epetra format from the file \'"<<matrixFile<<"\' ...\n";
00139
00140 #ifdef HAVE_MPI
00141 Epetra_MpiComm comm(MPI_COMM_WORLD);
00142 #else
00143 Epetra_SerialComm comm;
00144 #endif
00145 RefCountPtr<Epetra_CrsMatrix> epetra_A;
00146 RefCountPtr<Epetra_Vector> epetra_x, epetra_b;
00147 EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A, NULL, &epetra_x, &epetra_b );
00148
00149 if(!epetra_b.get()) {
00150 *out << "\nThe RHS b was not read in so generate a new random vector ...\n";
00151 epetra_b = rcp(new Epetra_Vector(epetra_A->OperatorRangeMap()));
00152 epetra_b->Random();
00153 }
00154
00155 if(!epetra_x.get()) {
00156 *out << "\nThe LHS x was not read in so generate a new zero vector ...\n";
00157 epetra_x = rcp(new Epetra_Vector(epetra_A->OperatorDomainMap()));
00158 epetra_x->PutScalar(0.0);
00159 }
00160
00161 *out << "\nPrinting statistics of the Epetra linear system ...\n";
00162
00163 *out
00164 << "\n Epetra_CrsMatrix epetra_A of dimension "
00165 << epetra_A->OperatorRangeMap().NumGlobalElements()
00166 << " x " << epetra_A->OperatorDomainMap().NumGlobalElements()
00167 << "\n ||epetraA||inf = " << epetra_A->NormInf()
00168 << "\n ||epetra_b||2 = " << epetraNorm2(*epetra_b)
00169 << "\n ||epetra_x||2 = " << epetraNorm2(*epetra_x)
00170 << "\n";
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 RefCountPtr<const Thyra::LinearOpBase<double> > A;
00183 RefCountPtr<Thyra::VectorBase<double> > x;
00184 RefCountPtr<const Thyra::VectorBase<double> > b;
00185
00186
00187 if(1) {
00188
00189
00190
00191 RefCountPtr<const Thyra::EpetraLinearOp>
00192 _A = rcp(new Thyra::EpetraLinearOp(epetra_A));
00193
00194
00195 b = Thyra::create_Vector(epetra_b,_A->spmdRange());
00196 x = Thyra::create_Vector(epetra_x,_A->spmdDomain());
00197
00198 A = _A;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 linearSolverBuilder.readParameters(out.get());
00217
00218
00219 RefCountPtr<Thyra::LinearOpWithSolveFactoryBase<double> >
00220 lowsFactory = linearSolverBuilder.createLinearSolveStrategy("");
00221
00222 lowsFactory->setOStream(out);
00223 lowsFactory->setVerbLevel(Teuchos::VERB_LOW);
00224
00225 RefCountPtr<Thyra::LinearOpWithSolveBase<double> >
00226 lows = Thyra::linearOpWithSolve(*lowsFactory,A);
00227
00228 Thyra::SolveStatus<double>
00229 status = Thyra::solve(*lows,Thyra::NOTRANS,*b,&*x);
00230 *out << "\nSolve status:\n" << status;
00231
00232 linearSolverBuilder.writeParamsFile(*lowsFactory);
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 x = Teuchos::null;
00246
00247 *out
00248 << "\nSolution ||epetra_x||2 = " << epetraNorm2(*epetra_x) << "\n";
00249
00250 *out << "\nTesting the solution error ||b-A*x||/||b|| computed through the Epetra objects ...\n";
00251
00252
00253 Epetra_Vector epetra_r(*epetra_b);
00254 if(1) {
00255 Epetra_Vector epetra_A_x(epetra_A->OperatorRangeMap());
00256 epetra_A->Apply(*epetra_x,epetra_A_x);
00257 epetra_r.Update(-1.0,epetra_A_x,1.0);
00258 }
00259
00260 const double
00261 nrm_r = epetraNorm2(epetra_r),
00262 nrm_b = epetraNorm2(*epetra_b),
00263 rel_err = ( nrm_r / nrm_b );
00264 const bool
00265 passed = (rel_err <= tol);
00266
00267 *out
00268 << "||b-A*x||/||b|| = " << nrm_r << "/" << nrm_b << " = " << rel_err
00269 << " < tol = " << tol << " ? " << ( passed ? "passed" : "failed" ) << "\n";
00270
00271 if(!passed) success = false;
00272
00273 }
00274 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose,std::cerr,success)
00275
00276 if (verbose) {
00277 if(success) *out << "\nCongratulations! All of the tests checked out!\n";
00278 else *out << "\nOh no! At least one of the tests failed!\n";
00279 }
00280
00281 return ( success ? 0 : 1 );
00282 }