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
00030
00031
00032 #include "Thyra_DefaultRealLinearSolverBuilder.hpp"
00033 #include "Thyra_DelayedLinearOpWithSolveFactory.hpp"
00034 #include "Teuchos_AbstractFactoryStd.hpp"
00035 #include "Teuchos_CommandLineProcessor.hpp"
00036 #include "Teuchos_XMLParameterListHelpers.hpp"
00037 #include "Teuchos_GlobalMPISession.hpp"
00038 #include "Teuchos_StandardParameterEntryValidators.hpp"
00039
00040 #ifdef HAVE_STRATIMIKOS_AMESOS
00041 # include "Thyra_AmesosLinearOpWithSolveFactory.hpp"
00042 #endif
00043 #ifdef HAVE_STRATIMIKOS_AZTECOO
00044 # include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
00045 #endif
00046 #ifdef HAVE_STRATIMIKOS_BELOS
00047 # include "Thyra_BelosLinearOpWithSolveFactory.hpp"
00048 #endif
00049 #ifdef HAVE_STRATIMIKOS_IFPACK
00050 # include "Thyra_IfpackPreconditionerFactory.hpp"
00051 #endif
00052 #ifdef HAVE_STRATIMIKOS_ML
00053 # include "Thyra_MLPreconditionerFactory.hpp"
00054 #endif
00055
00056
00057 namespace {
00058
00059
00060 const std::string LinearSolverType_name = "Linear Solver Type";
00061 const std::string LinearSolverTypes_name = "Linear Solver Types";
00062 const std::string PreconditionerType_name = "Preconditioner Type";
00063 const std::string PreconditionerTypes_name = "Preconditioner Types";
00064 const std::string None_name = "None";
00065 const std::string EnableDelayedSolverConstruction_name = "Enable Delayed Solver Construction";
00066 const bool EnableDelayedSolverConstruction_default = false;
00067
00068
00069 Teuchos::RCP<const Teuchos::StringToIntegralParameterEntryValidator<int> >
00070 lowsfValidator;
00071
00072
00073 Teuchos::RCP<const Teuchos::StringToIntegralParameterEntryValidator<int> >
00074 pfValidator;
00075
00076
00077 }
00078
00079
00080 namespace Thyra {
00081
00082
00083
00084
00085
00086 DefaultRealLinearSolverBuilder::DefaultRealLinearSolverBuilder(
00087 const std::string ¶msXmlFileName
00088 ,const std::string &extraParamsXmlString
00089 ,const std::string ¶msUsedXmlOutFileName
00090 ,const std::string ¶msXmlFileNameOption
00091 ,const std::string &extraParamsXmlStringOption
00092 ,const std::string ¶msUsedXmlOutFileNameOption
00093 )
00094 :paramsXmlFileName_(paramsXmlFileName)
00095 ,extraParamsXmlString_(extraParamsXmlString)
00096 ,paramsUsedXmlOutFileName_(paramsUsedXmlOutFileName)
00097 ,paramsXmlFileNameOption_(paramsXmlFileNameOption)
00098 ,extraParamsXmlStringOption_(extraParamsXmlStringOption)
00099 ,paramsUsedXmlOutFileNameOption_(paramsUsedXmlOutFileNameOption)
00100 ,enableDelayedSolverConstruction_(EnableDelayedSolverConstruction_default)
00101 {
00102 this->initializeDefaults();
00103 }
00104
00105
00106 DefaultRealLinearSolverBuilder::~DefaultRealLinearSolverBuilder()
00107 {
00108 #ifdef TEUCHOS_DEBUG
00109
00110 if(paramList_.get())
00111 paramList_->validateParameters(*this->getValidParameters(),1);
00112 #endif
00113 }
00114
00115
00116 void DefaultRealLinearSolverBuilder::setLinearSolveStrategyFactory(
00117 const RCP<const Teuchos::AbstractFactory<LinearOpWithSolveFactoryBase<double> > > &solveStrategyFactory,
00118 const std::string &solveStrategyName
00119 )
00120 {
00121 validLowsfNames_.push_back(solveStrategyName);
00122 lowsfArray_.push_back(solveStrategyFactory);
00123 defaultLOWSF_ = solveStrategyName;
00124 validParamList_ = Teuchos::null;
00125 }
00126
00127
00128 void DefaultRealLinearSolverBuilder::setPreconditioningStrategyFactory(
00129 const RCP<const Teuchos::AbstractFactory<PreconditionerFactoryBase<double> > > &precStrategyFactory,
00130 const std::string &precStrategyName
00131 )
00132 {
00133 validPfNames_.push_back(precStrategyName);
00134 pfArray_.push_back(precStrategyFactory);
00135 defaultPF_ = precStrategyName;
00136 validParamList_ = Teuchos::null;
00137 }
00138
00139
00140 void DefaultRealLinearSolverBuilder::setupCLP( Teuchos::CommandLineProcessor *clp )
00141 {
00142 TEST_FOR_EXCEPT(clp==NULL);
00143 clp->setOption(
00144 paramsXmlFileNameOption().c_str(),¶msXmlFileName_
00145 ,"Name of an XML file containing parameters for linear solver options to be appended first."
00146 );
00147 clp->setOption(
00148 extraParamsXmlStringOption().c_str(),&extraParamsXmlString_
00149 ,"An XML string containing linear solver parameters to be appended second."
00150 );
00151 clp->setOption(
00152 paramsUsedXmlOutFileNameOption().c_str(),¶msUsedXmlOutFileName_
00153 ,"Name of an XML file that can be written with the parameter list after it has been used on completion of this program."
00154 );
00155 }
00156
00157
00158 void DefaultRealLinearSolverBuilder::readParameters( std::ostream *out )
00159 {
00160 if(!paramList_.get())
00161 paramList_ = Teuchos::rcp(new Teuchos::ParameterList("DefaultRealLinearSolverBuilder"));
00162 if(paramsXmlFileName().length()) {
00163 if(out) *out << "\nReading parameters from XML file \""<<paramsXmlFileName()<<"\" ...\n";
00164 Teuchos::updateParametersFromXmlFile(paramsXmlFileName(),&*paramList_);
00165 }
00166 if(extraParamsXmlString().length()) {
00167 if(out) *out << "\nAppending extra parameters from the XML string \""<<extraParamsXmlString()<<"\" ...\n";
00168 Teuchos::updateParametersFromXmlString(extraParamsXmlString(),&*paramList_);
00169 }
00170 }
00171
00172
00173 void DefaultRealLinearSolverBuilder::writeParamsFile(
00174 const LinearOpWithSolveFactoryBase<double> &lowsFactory,
00175 const std::string &outputXmlFileName
00176 ) const
00177 {
00178 TEST_FOR_EXCEPT(!paramList_.get());
00179 std::string xmlOutputFile
00180 = ( outputXmlFileName.length() ? outputXmlFileName : paramsUsedXmlOutFileName() );
00181 if(xmlOutputFile.length()) {
00182 Teuchos::writeParameterListToXmlFile(*paramList_,xmlOutputFile);
00183 }
00184 }
00185
00186
00187 std::string
00188 DefaultRealLinearSolverBuilder::getLinearSolveStrategyName() const
00189 {
00190 TEST_FOR_EXCEPT(!paramList_.get());
00191 if(!lowsfValidator.get())
00192 this->getValidParameters();
00193 return lowsfValidator->getStringValue(*paramList_,LinearSolverType_name,defaultLOWSF_);
00194 }
00195
00196
00197 std::string
00198 DefaultRealLinearSolverBuilder::getPreconditionerStrategyName() const
00199 {
00200 TEST_FOR_EXCEPT(!paramList_.get());
00201 if(!pfValidator.get())
00202 this->getValidParameters();
00203 return pfValidator->getStringValue(*paramList_,PreconditionerType_name,defaultPF_);
00204 }
00205
00206
00207
00208
00209
00210 void DefaultRealLinearSolverBuilder::setParameterList(
00211 RCP<Teuchos::ParameterList> const& paramList
00212 )
00213 {
00214 TEST_FOR_EXCEPT(!paramList.get());
00215
00216
00217
00218 paramList->validateParameters(*this->getValidParameters(),1);
00219 paramList_ = paramList;
00220 enableDelayedSolverConstruction_ = paramList_->get(
00221 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default );
00222 }
00223
00224
00225 RCP<Teuchos::ParameterList>
00226 DefaultRealLinearSolverBuilder::getParameterList()
00227 {
00228 return paramList_;
00229 }
00230
00231
00232 RCP<Teuchos::ParameterList>
00233 DefaultRealLinearSolverBuilder::unsetParameterList()
00234 {
00235 RCP<Teuchos::ParameterList> _paramList = paramList_;
00236 paramList_ = Teuchos::null;
00237 return _paramList;
00238 }
00239
00240
00241 RCP<const Teuchos::ParameterList>
00242 DefaultRealLinearSolverBuilder::getParameterList() const
00243 {
00244 return paramList_;
00245 }
00246
00247
00248 RCP<const Teuchos::ParameterList>
00249 DefaultRealLinearSolverBuilder::getValidParameters() const
00250 {
00251 if(!validParamList_.get()) {
00252 RCP<Teuchos::ParameterList>
00253 validParamList = Teuchos::rcp(new Teuchos::ParameterList);
00254
00255 lowsfValidator = Teuchos::rcp(
00256 new Teuchos::StringToIntegralParameterEntryValidator<int>(
00257 validLowsfNames_,LinearSolverType_name
00258 )
00259 );
00260 validParamList->set(
00261 LinearSolverType_name,defaultLOWSF_
00262 ,(std::string("Determines the type of linear solver that will be used.\n")
00263 + "The parameters for each solver type are specified in the sublist \""
00264 + LinearSolverTypes_name + "\"").c_str()
00265 ,lowsfValidator
00266 );
00267 Teuchos::ParameterList &linearSolverTypesSL = validParamList->sublist(
00268 LinearSolverTypes_name,false,
00269 "Sublists for each of the linear solver types set using the parameter\n"
00270 "\"" + LinearSolverType_name + "\". Note that the options for each\n"
00271 "linear solver type given below will only be used if linear solvers\n"
00272 "of that type are created. It is fine to list parameter sublists for\n"
00273 "linear solver types that are not used."
00274 );
00275 for( int i = 0; i < static_cast<int>(lowsfArray_.size()); ++i ) {
00276 const std::string
00277 &lsname = validLowsfNames_[i];
00278 const RCP<LinearOpWithSolveFactoryBase<double> >
00279 lowsf = lowsfArray_[i]->create();
00280 linearSolverTypesSL.sublist(lsname).setParameters(*lowsf->getValidParameters());
00281 }
00282
00283 pfValidator = Teuchos::rcp(
00284 new Teuchos::StringToIntegralParameterEntryValidator<int>(
00285 validPfNames_,PreconditionerType_name
00286 )
00287 );
00288 validParamList->set(
00289 PreconditionerType_name,defaultPF_
00290 ,(std::string("Determines the type of preconditioner that will be used.\n")
00291 + "This option is only meaningful for linear solvers that accept preconditioner"
00292 + " factory objects!\n"
00293 + "The parameters for each preconditioner are specified in the sublist \""
00294 + PreconditionerTypes_name + "\"").c_str()
00295 ,pfValidator
00296 );
00297 Teuchos::ParameterList &precTypesSL = validParamList->sublist(
00298 PreconditionerTypes_name,false,
00299 "Sublists for each of the preconditioner types set using the parameter\n"
00300 "\"" + PreconditionerType_name + "\". Note that the options for each\n"
00301 "preconditioner type given below will only be used if preconditioners\n"
00302 "of that type are created. It is fine to list parameter sublists for\n"
00303 "preconditioner types that are not used."
00304 );
00305 for( int i = 0; i < static_cast<int>(pfArray_.size()); ++i ) {
00306 const std::string
00307 &pfname = validPfNames_[i+1];
00308 const RCP<PreconditionerFactoryBase<double> >
00309 pf = pfArray_[i]->create();
00310 precTypesSL.sublist(pfname).setParameters(*pf->getValidParameters());
00311 }
00312
00313 validParamList->set(
00314 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default,
00315 "When this option is set to true, the linear solver factory will be wrapped\n"
00316 "in a delayed evaluation Decorator factory object. This results in a delay\n"
00317 "in the creation of a linear solver (and the associated preconditioner) until\n"
00318 "the first solve is actually performed. This helps in cases where it is not\n"
00319 "known a-priori if a linear solve will be needed on a given linear operator and\n"
00320 "therefore can significantly improve performance for some types of algorithms\n"
00321 "such as NOX and LOCA."
00322 );
00323
00324 validParamList_ = validParamList;
00325 }
00326 return validParamList_;
00327 }
00328
00329
00330
00331
00332
00333 RCP<LinearOpWithSolveFactoryBase<double> >
00334 DefaultRealLinearSolverBuilder::createLinearSolveStrategy(
00335 const std::string &linearSolveStrategyName
00336 ) const
00337 {
00338
00339 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
00340 std::cout << "\nEntering DefaultRealLinearSolverBuilder::createLinearSolveStrategy(...) ...\n";
00341 std::cout << "\nlinearSolveStrategyName = \"" << linearSolveStrategyName << "\"\n";
00342 std::cout << "\nlinearSolveStrategyName.length() = " << linearSolveStrategyName.length() << "\n";
00343 std::cout << "\ndefaultLOWSF_ = \"" << defaultLOWSF_ << "\"\n";
00344 std::cout << "\nthis->getLinearSolveStrategyName() = \"" << this->getLinearSolveStrategyName() << "\"\n";
00345 #endif
00346 const std::string
00347 lsname = ( linearSolveStrategyName.length()
00348 ? linearSolveStrategyName
00349 : this->getLinearSolveStrategyName() );
00350 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
00351 std::cout << "\nlsname = \"" << lsname << "\"\n";
00352 #endif
00353
00354 const int
00355 ls_idx = lowsfValidator->getIntegralValue(lsname,LinearSolverType_name);
00356
00357 RCP<LinearOpWithSolveFactoryBase<double> >
00358 lowsf = lowsfArray_[ls_idx]->create();
00359
00360 if(lowsf->acceptsPreconditionerFactory()) {
00361 const std::string &pfName = this->getPreconditionerStrategyName();
00362 RCP<PreconditionerFactoryBase<double> >
00363 pf = this->createPreconditioningStrategy(pfName);
00364 if(pf.get())
00365 lowsf->setPreconditionerFactory(pf,pfName);
00366 }
00367
00368
00369 lowsf->setParameterList(sublist(sublist(paramList_,LinearSolverTypes_name),lsname));
00370
00371 if (enableDelayedSolverConstruction_) {
00372 return Teuchos::rcp(
00373 new DelayedLinearOpWithSolveFactory<double>(lowsf)
00374 );
00375 }
00376 return lowsf;
00377 }
00378
00379
00380 RCP<PreconditionerFactoryBase<double> >
00381 DefaultRealLinearSolverBuilder::createPreconditioningStrategy(
00382 const std::string &preconditioningStrategyName
00383 ) const
00384 {
00385
00386
00387 const std::string
00388 pfname = ( preconditioningStrategyName.length()
00389 ? preconditioningStrategyName
00390 : this->getPreconditionerStrategyName() );
00391 RCP<PreconditionerFactoryBase<double> >
00392 pf = Teuchos::null;
00393
00394
00395 const int
00396 pf_idx = pfValidator->getIntegralValue(pfname,PreconditionerType_name);
00397 if( pf_idx != 0 ) {
00398 pf = pfArray_[pf_idx-1]->create();
00399 pf->setParameterList(sublist(sublist(paramList_,PreconditionerTypes_name),pfname));
00400 }
00401
00402 return pf;
00403
00404 }
00405
00406
00407
00408
00409
00410 void DefaultRealLinearSolverBuilder::initializeDefaults()
00411 {
00412
00413 using Teuchos::rcp;
00414 using Teuchos::abstractFactoryStd;
00415
00416 defaultLOWSF_ = "";
00417 defaultPF_ = None_name;
00418 validLowsfNames_.resize(0);
00419 validPfNames_.resize(0);
00420 validPfNames_.push_back(None_name);
00421
00422
00423
00424
00425
00426 #ifdef HAVE_STRATIMIKOS_BELOS
00427 setLinearSolveStrategyFactory(
00428 abstractFactoryStd<LinearOpWithSolveFactoryBase<double>,BelosLinearOpWithSolveFactory<double> >(),
00429 "Belos"
00430 );
00431 #endif
00432
00433 #ifdef HAVE_STRATIMIKOS_AMESOS
00434 setLinearSolveStrategyFactory(
00435 abstractFactoryStd<LinearOpWithSolveFactoryBase<double>,AmesosLinearOpWithSolveFactory>(),
00436 "Amesos"
00437 );
00438 #endif
00439
00440 #ifdef HAVE_STRATIMIKOS_AZTECOO
00441 setLinearSolveStrategyFactory(
00442 abstractFactoryStd<LinearOpWithSolveFactoryBase<double>,AztecOOLinearOpWithSolveFactory>(),
00443 "AztecOO"
00444 );
00445 #endif
00446
00447 #ifdef HAVE_STRATIMIKOS_AMESOS
00448 if( Teuchos::GlobalMPISession::getNProc() == 1 ) {
00449 defaultLOWSF_ = "Amesos";
00450 }
00451 #endif
00452
00453
00454
00455
00456
00457
00458
00459
00460 #ifdef HAVE_STRATIMIKOS_ML
00461 setPreconditioningStrategyFactory(
00462 abstractFactoryStd<PreconditionerFactoryBase<double>,MLPreconditionerFactory>(),
00463 "ML"
00464 );
00465 #endif
00466
00467 #ifdef HAVE_STRATIMIKOS_IFPACK
00468 setPreconditioningStrategyFactory(
00469 abstractFactoryStd<PreconditionerFactoryBase<double>,IfpackPreconditionerFactory>(),
00470 "Ifpack"
00471 );
00472 #endif
00473
00474
00475
00476 }
00477
00478
00479 }