|
Stratimikos Package Browser (Single Doxygen Collection)
Version of the Day
|
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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 //#define THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP 00030 00031 #include "Stratimikos_InternalConfig.h" 00032 #include "Stratimikos_DefaultLinearSolverBuilder.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 00039 #ifdef HAVE_STRATIMIKOS_AMESOS 00040 # include "Thyra_AmesosLinearOpWithSolveFactory.hpp" 00041 #endif 00042 #ifdef HAVE_STRATIMIKOS_AZTECOO 00043 # include "Thyra_AztecOOLinearOpWithSolveFactory.hpp" 00044 #endif 00045 #ifdef HAVE_STRATIMIKOS_BELOS 00046 # include "Thyra_BelosLinearOpWithSolveFactory.hpp" 00047 #endif 00048 #ifdef HAVE_STRATIMIKOS_IFPACK 00049 # include "Thyra_IfpackPreconditionerFactory.hpp" 00050 #endif 00051 #ifdef HAVE_STRATIMIKOS_ML 00052 # include "Thyra_MLPreconditionerFactory.hpp" 00053 #endif 00054 00055 00056 namespace { 00057 00058 00059 const std::string LinearSolverType_name = "Linear Solver Type"; 00060 const std::string LinearSolverTypes_name = "Linear Solver Types"; 00061 const std::string PreconditionerType_name = "Preconditioner Type"; 00062 const std::string PreconditionerTypes_name = "Preconditioner Types"; 00063 const std::string None_name = "None"; 00064 const std::string EnableDelayedSolverConstruction_name = "Enable Delayed Solver Construction"; 00065 const bool EnableDelayedSolverConstruction_default = false; 00066 00067 00068 } // namespace 00069 00070 00071 namespace Stratimikos { 00072 00073 00074 // Constructors/Initializers/Accessors 00075 00076 00077 DefaultLinearSolverBuilder::DefaultLinearSolverBuilder( 00078 const std::string ¶msXmlFileName_in 00079 ,const std::string &extraParamsXmlString_in 00080 ,const std::string ¶msUsedXmlOutFileName_in 00081 ,const std::string ¶msXmlFileNameOption_in 00082 ,const std::string &extraParamsXmlStringOption_in 00083 ,const std::string ¶msUsedXmlOutFileNameOption_in 00084 ) 00085 :paramsXmlFileName_(paramsXmlFileName_in) 00086 ,extraParamsXmlString_(extraParamsXmlString_in) 00087 ,paramsUsedXmlOutFileName_(paramsUsedXmlOutFileName_in) 00088 ,paramsXmlFileNameOption_(paramsXmlFileNameOption_in) 00089 ,extraParamsXmlStringOption_(extraParamsXmlStringOption_in) 00090 ,paramsUsedXmlOutFileNameOption_(paramsUsedXmlOutFileNameOption_in) 00091 ,enableDelayedSolverConstruction_(EnableDelayedSolverConstruction_default) 00092 { 00093 this->initializeDefaults(); 00094 } 00095 00096 00097 DefaultLinearSolverBuilder::~DefaultLinearSolverBuilder() 00098 { 00099 #ifdef TEUCHOS_DEBUG 00100 // Validate that we read the parameters correctly! 00101 if (nonnull(paramList_)) { 00102 paramList_->validateParameters(*this->getValidParameters()); 00103 } 00104 #endif 00105 } 00106 00107 00108 void DefaultLinearSolverBuilder::setLinearSolveStrategyFactory( 00109 const RCP<const AbstractFactory<Thyra::LinearOpWithSolveFactoryBase<double> > > 00110 &solveStrategyFactory, 00111 const std::string &solveStrategyName, 00112 const bool makeDefault 00113 ) 00114 { 00115 validLowsfNames_.push_back(solveStrategyName); 00116 lowsfArray_.push_back(solveStrategyFactory); 00117 validParamList_ = Teuchos::null; 00118 if (makeDefault) { 00119 setDefaultLinearSolveStrategyFactoryName(solveStrategyName); 00120 } 00121 } 00122 00123 00124 void DefaultLinearSolverBuilder::setDefaultLinearSolveStrategyFactoryName( 00125 const std::string &solveStrategyName) 00126 { 00127 defaultLOWSF_ = solveStrategyName; 00128 } 00129 00130 00131 void DefaultLinearSolverBuilder::setPreconditioningStrategyFactory( 00132 const RCP<const AbstractFactory<Thyra::PreconditionerFactoryBase<double> > > 00133 &precStrategyFactory, 00134 const std::string &precStrategyName, 00135 const bool makeDefault 00136 ) 00137 { 00138 validPfNames_.push_back(precStrategyName); 00139 pfArray_.push_back(precStrategyFactory); 00140 validParamList_ = Teuchos::null; 00141 if (makeDefault) { 00142 setDefaultPreconditioningStrategyFactoryName(precStrategyName); 00143 } 00144 } 00145 00146 00147 void DefaultLinearSolverBuilder::setDefaultPreconditioningStrategyFactoryName( 00148 const std::string &precStrategyName) 00149 { 00150 defaultPF_ = precStrategyName; 00151 } 00152 00153 00154 void DefaultLinearSolverBuilder::setupCLP( Teuchos::CommandLineProcessor *clp ) 00155 { 00156 TEUCHOS_TEST_FOR_EXCEPT(clp==NULL); 00157 clp->setOption( 00158 paramsXmlFileNameOption().c_str(),¶msXmlFileName_ 00159 ,"Name of an XML file containing parameters for linear solver " 00160 "options to be appended first." 00161 ); 00162 clp->setOption( 00163 extraParamsXmlStringOption().c_str(),&extraParamsXmlString_ 00164 ,"An XML string containing linear solver parameters to be appended second." 00165 ); 00166 clp->setOption( 00167 paramsUsedXmlOutFileNameOption().c_str(),¶msUsedXmlOutFileName_ 00168 ,"Name of an XML file that can be written with the parameter list after it " 00169 "has been used on completion of this program." 00170 ); 00171 } 00172 00173 00174 void DefaultLinearSolverBuilder::readParameters( std::ostream *out ) 00175 { 00176 using Teuchos::parameterList; 00177 using Teuchos::ptr; 00178 using Teuchos::updateParametersFromXmlFile; 00179 using Teuchos::updateParametersFromXmlString; 00180 using std::endl; 00181 00182 if (!paramList_.get()) { 00183 paramList_ = parameterList("DefaultLinearSolverBuilder"); 00184 } 00185 if (paramsXmlFileName().length()) { 00186 if (out) { 00187 *out << endl << "Reading parameters from XML file \"" 00188 << paramsXmlFileName() << "\" ..." << endl; 00189 } 00190 updateParametersFromXmlFile (paramsXmlFileName (), paramList_.ptr()); 00191 } 00192 if (extraParamsXmlString().length()) { 00193 if (out) { 00194 *out << endl << "Appending extra parameters from the XML string \"" 00195 << extraParamsXmlString() << "\" ..." << endl; 00196 } 00197 updateParametersFromXmlString (extraParamsXmlString (), paramList_.ptr()); 00198 } 00199 setParameterList(paramList_); 00200 } 00201 00202 00203 void DefaultLinearSolverBuilder::writeParamsFile( 00204 const Thyra::LinearOpWithSolveFactoryBase<double> &lowsFactory, 00205 const std::string &outputXmlFileName 00206 ) const 00207 { 00208 justInTimeInitialize(); 00209 const std::string xmlOutputFile = 00210 ( outputXmlFileName.length() ? outputXmlFileName : paramsUsedXmlOutFileName() ); 00211 if (xmlOutputFile.length()) { 00212 Teuchos::writeParameterListToXmlFile(*paramList_, xmlOutputFile); 00213 } 00214 } 00215 00216 00217 std::string 00218 DefaultLinearSolverBuilder::getLinearSolveStrategyName() const 00219 { 00220 justInTimeInitialize(); 00221 return lowsfValidator_->getStringValue(*paramList_, LinearSolverType_name, 00222 defaultLOWSF_); 00223 } 00224 00225 00226 std::string 00227 DefaultLinearSolverBuilder::getPreconditionerStrategyName() const 00228 { 00229 justInTimeInitialize(); 00230 return pfValidator_->getStringValue(*paramList_, PreconditionerType_name, 00231 defaultPF_); 00232 } 00233 00234 00235 // Overridden from ParameterListAcceptor 00236 00237 00238 void DefaultLinearSolverBuilder::setParameterList( 00239 RCP<Teuchos::ParameterList> const& paramList 00240 ) 00241 { 00242 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList)); 00243 paramList->validateParameters(*this->getValidParameters()); 00244 paramList_ = paramList; 00245 enableDelayedSolverConstruction_ = paramList_->get( 00246 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default ); 00247 } 00248 00249 00250 RCP<Teuchos::ParameterList> 00251 DefaultLinearSolverBuilder::getNonconstParameterList() 00252 { 00253 return paramList_; 00254 } 00255 00256 00257 RCP<Teuchos::ParameterList> 00258 DefaultLinearSolverBuilder::unsetParameterList() 00259 { 00260 RCP<Teuchos::ParameterList> _paramList = paramList_; 00261 paramList_ = Teuchos::null; 00262 return _paramList; 00263 } 00264 00265 00266 RCP<const Teuchos::ParameterList> 00267 DefaultLinearSolverBuilder::getParameterList() const 00268 { 00269 return paramList_; 00270 } 00271 00272 00273 RCP<const Teuchos::ParameterList> 00274 DefaultLinearSolverBuilder::getValidParameters() const 00275 { 00276 using Teuchos::rcp_implicit_cast; 00277 typedef Teuchos::ParameterEntryValidator PEV; 00278 if (is_null(validParamList_)) { 00279 RCP<Teuchos::ParameterList> 00280 validParamList = Teuchos::rcp(new Teuchos::ParameterList); 00281 // Linear Solver Types 00282 lowsfValidator_ = Teuchos::rcp( 00283 new Teuchos::StringToIntegralParameterEntryValidator<int>( 00284 validLowsfNames_,LinearSolverType_name 00285 ) 00286 ); 00287 validParamList->set( 00288 LinearSolverType_name, defaultLOWSF_, 00289 (std::string("Determines the type of linear solver that will be used.\n") 00290 + "The parameters for each solver type are specified in the sublist \"" 00291 + LinearSolverTypes_name + "\"").c_str(), 00292 rcp_implicit_cast<const PEV>(lowsfValidator_) 00293 ); 00294 Teuchos::ParameterList &linearSolverTypesSL = validParamList->sublist( 00295 LinearSolverTypes_name,false, 00296 "Sublists for each of the linear solver types set using the parameter\n" 00297 "\"" + LinearSolverType_name + "\". Note that the options for each\n" 00298 "linear solver type given below will only be used if linear solvers\n" 00299 "of that type are created. It is fine to list parameter sublists for\n" 00300 "linear solver types that are not used." 00301 ); 00302 for( int i = 0; i < static_cast<int>(lowsfArray_.size()); ++i ) { 00303 const std::string 00304 &lsname = validLowsfNames_[i]; 00305 const RCP<Thyra::LinearOpWithSolveFactoryBase<double> > 00306 lowsf = lowsfArray_[i]->create(); 00307 linearSolverTypesSL.sublist(lsname).setParameters(*lowsf->getValidParameters() 00308 ).disableRecursiveValidation(); 00309 } 00310 // Preconditioner Type 00311 pfValidator_ = Teuchos::rcp( 00312 new Teuchos::StringToIntegralParameterEntryValidator<int>( 00313 validPfNames_, PreconditionerType_name ) ); 00314 validParamList->set( 00315 PreconditionerType_name, defaultPF_, 00316 (std::string("Determines the type of preconditioner that will be used.\n") 00317 + "This option is only meaningful for linear solvers that accept preconditioner" 00318 + " factory objects!\n" 00319 + "The parameters for each preconditioner are specified in the sublist \"" 00320 + PreconditionerTypes_name + "\"").c_str(), 00321 rcp_implicit_cast<const PEV>(pfValidator_) 00322 ); 00323 Teuchos::ParameterList &precTypesSL = validParamList->sublist( 00324 PreconditionerTypes_name,false, 00325 "Sublists for each of the preconditioner types set using the parameter\n" 00326 "\"" + PreconditionerType_name + "\". Note that the options for each\n" 00327 "preconditioner type given below will only be used if preconditioners\n" 00328 "of that type are created. It is fine to list parameter sublists for\n" 00329 "preconditioner types that are not used." 00330 ); 00331 for( int i = 0; i < static_cast<int>(pfArray_.size()); ++i ) { 00332 const std::string 00333 &pfname = validPfNames_[i+1]; // "None" is the 0th entry! 00334 const RCP<Thyra::PreconditionerFactoryBase<double> > 00335 pf = pfArray_[i]->create(); 00336 precTypesSL.sublist(pfname).setParameters(*pf->getValidParameters() 00337 ).disableRecursiveValidation(); 00338 } 00339 // 00340 validParamList->set( 00341 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default, 00342 "When this option is set to true, the linear solver factory will be wrapped\n" 00343 "in a delayed evaluation Decorator factory object. This results in a delay\n" 00344 "in the creation of a linear solver (and the associated preconditioner) until\n" 00345 "the first solve is actually performed. This helps in cases where it is not\n" 00346 "known a-priori if a linear solve will be needed on a given linear operator and\n" 00347 "therefore can significantly improve performance for some types of algorithms\n" 00348 "such as NOX and LOCA." 00349 ); 00350 // 00351 validParamList_ = validParamList; 00352 } 00353 return validParamList_; 00354 } 00355 00356 00357 // Overridden from LinearSolverBuilderBase. 00358 00359 00360 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > 00361 DefaultLinearSolverBuilder::createLinearSolveStrategy( 00362 const std::string &linearSolveStrategyName 00363 ) const 00364 { 00365 justInTimeInitialize(); 00366 00367 // Get the name of the linear solve strategy 00368 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP 00369 std::cout << "\nEntering DefaultLinearSolverBuilder" 00370 << "::createLinearSolveStrategy(...) ...\n"; 00371 std::cout << "\nlinearSolveStrategyName = \"" 00372 << linearSolveStrategyName << "\"\n"; 00373 std::cout << "\nlinearSolveStrategyName.length() = " 00374 << linearSolveStrategyName.length() << "\n"; 00375 std::cout << "\ndefaultLOWSF_ = \"" << defaultLOWSF_ << "\"\n"; 00376 std::cout << "\nthis->getLinearSolveStrategyName() = \"" 00377 << this->getLinearSolveStrategyName() << "\"\n"; 00378 #endif 00379 const std::string 00380 lsname = ( linearSolveStrategyName.length() 00381 ? linearSolveStrategyName 00382 : this->getLinearSolveStrategyName() ); 00383 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP 00384 std::cout << "\nlsname = \"" << lsname << "\"\n"; 00385 #endif 00386 00387 // Get the index of this linear solver strategy (this will validate!) 00388 const int 00389 ls_idx = lowsfValidator_->getIntegralValue(lsname, LinearSolverType_name); 00390 00391 // Create the uninitialized LOWSFB object 00392 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > 00393 lowsf = lowsfArray_[ls_idx]->create(); 00394 00395 // First, set the preconditioner factory and its parameters 00396 if(lowsf->acceptsPreconditionerFactory()) { 00397 const std::string &pfName = this->getPreconditionerStrategyName(); 00398 RCP<Thyra::PreconditionerFactoryBase<double> > 00399 pf = this->createPreconditioningStrategy(pfName); 00400 if(pf.get()) 00401 lowsf->setPreconditionerFactory(pf,pfName); 00402 } 00403 00404 // Now set the parameters for the linear solver (some of which might 00405 // override some preconditioner factory parameters). 00406 lowsf->setParameterList( 00407 sublist(sublist(paramList_, LinearSolverTypes_name), lsname)); 00408 // 00409 if (enableDelayedSolverConstruction_) { 00410 return Teuchos::rcp( 00411 new Thyra::DelayedLinearOpWithSolveFactory<double>(lowsf) 00412 ); 00413 } 00414 00415 return lowsf; 00416 00417 } 00418 00419 00420 RCP<Thyra::PreconditionerFactoryBase<double> > 00421 DefaultLinearSolverBuilder::createPreconditioningStrategy( 00422 const std::string &preconditioningStrategyName 00423 ) const 00424 { 00425 justInTimeInitialize(); 00426 00427 // Get the name of the preconditioning strategy 00428 const std::string 00429 pfname = ( preconditioningStrategyName.length() 00430 ? preconditioningStrategyName 00431 : this->getPreconditionerStrategyName() ); 00432 RCP<Thyra::PreconditionerFactoryBase<double> > 00433 pf = Teuchos::null; 00434 00435 // Get the index of this preconditioning strategy (this will validate!) 00436 const int 00437 pf_idx = pfValidator_->getIntegralValue(pfname, PreconditionerType_name); 00438 if( pf_idx != 0 ) { 00439 pf = pfArray_[pf_idx-1]->create(); // We offset by -1 since "None" is first! 00440 pf->setParameterList( 00441 sublist(sublist(paramList_, PreconditionerTypes_name), pfname)); 00442 } 00443 00444 return pf; 00445 00446 } 00447 00448 00449 // private 00450 00451 00452 void DefaultLinearSolverBuilder::initializeDefaults() 00453 { 00454 00455 using Teuchos::rcp; 00456 using Teuchos::abstractFactoryStd; 00457 00458 defaultLOWSF_ = ""; 00459 defaultPF_ = None_name; 00460 validLowsfNames_.resize(0); 00461 validPfNames_.resize(0); 00462 validPfNames_.push_back(None_name); // This will offset everything! 00463 00464 // 00465 // Linear Solvers 00466 // 00467 00468 #ifdef HAVE_STRATIMIKOS_BELOS 00469 setLinearSolveStrategyFactory( 00470 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>, 00471 Thyra::BelosLinearOpWithSolveFactory<double> >(), 00472 "Belos", true 00473 ); 00474 #endif 00475 00476 #ifdef HAVE_STRATIMIKOS_AMESOS 00477 setLinearSolveStrategyFactory( 00478 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>, 00479 Thyra::AmesosLinearOpWithSolveFactory>(), 00480 "Amesos", true 00481 ); 00482 #endif 00483 00484 #ifdef HAVE_STRATIMIKOS_AZTECOO 00485 setLinearSolveStrategyFactory( 00486 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>, 00487 Thyra::AztecOOLinearOpWithSolveFactory>(), 00488 "AztecOO", true 00489 ); 00490 #endif 00491 00492 #ifdef HAVE_STRATIMIKOS_AMESOS 00493 if (Teuchos::GlobalMPISession::getNProc() == 1) { 00494 setDefaultLinearSolveStrategyFactoryName("Amesos"); 00495 } 00496 #endif 00497 00498 // Note: ABove, the last LOWSF object set will be the default unless we are 00499 // on multiple processors! 00500 00501 // 00502 // Preconditioners 00503 // 00504 00505 #ifdef HAVE_STRATIMIKOS_ML 00506 setPreconditioningStrategyFactory( 00507 abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>, 00508 Thyra::MLPreconditionerFactory>(), 00509 "ML", true 00510 ); 00511 #endif 00512 00513 #ifdef HAVE_STRATIMIKOS_IFPACK 00514 setPreconditioningStrategyFactory( 00515 abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>, 00516 Thyra::IfpackPreconditionerFactory>(), 00517 "Ifpack", true 00518 ); 00519 #endif 00520 00521 // Note: Above, the last PF object set will be the default! 00522 00523 } 00524 00525 00526 void DefaultLinearSolverBuilder::justInTimeInitialize() const 00527 { 00528 paramList_.assert_not_null(); 00529 if (is_null(validParamList_)) { 00530 // Create the validators 00531 this->getValidParameters(); 00532 } 00533 } 00534 00535 00536 00537 } // namespace Stratimikos
1.7.6.1