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 #include "Thyra_DefaultRealLinearSolverBuilder.hpp"
00032 #include "Teuchos_AbstractFactoryStd.hpp"
00033 #include "Teuchos_CommandLineProcessor.hpp"
00034 #include "Teuchos_XMLParameterListHelpers.hpp"
00035 #include "Teuchos_GlobalMPISession.hpp"
00036
00037 #ifdef HAVE_STRATIMIKOS_AMESOS_THYRA
00038 # include "Thyra_AmesosLinearOpWithSolveFactory.hpp"
00039 #endif
00040 #ifdef HAVE_STRATIMIKOS_AZTECOO_THYRA
00041 # include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
00042 #endif
00043 #ifdef HAVE_STRATIMIKOS_BELOS_THYRA
00044 # include "Thyra_BelosLinearOpWithSolveFactory.hpp"
00045 #endif
00046 #ifdef HAVE_STRATIMIKOS_IFPACK_THYRA
00047 # include "Thyra_IfpackPreconditionerFactory.hpp"
00048 #endif
00049 #ifdef HAVE_STRATIMIKOS_ML_THYRA
00050 # include "Thyra_MLPreconditionerFactory.hpp"
00051 #endif
00052
00053 namespace {
00054
00055 const std::string LinearSolverType_name = "Linear Solver Type";
00056 const std::string LinearSolverTypes_name = "Linear Solver Types";
00057 const std::string PreconditionerType_name = "Preconditioner Type";
00058 const std::string PreconditionerTypes_name = "Preconditioner Types";
00059
00060 }
00061
00062 namespace Thyra {
00063
00064
00065
00066 DefaultRealLinearSolverBuilder::DefaultRealLinearSolverBuilder(
00067 const std::string ¶msXmlFileName
00068 ,const std::string &extraParamsXmlString
00069 ,const std::string ¶msUsedXmlOutFileName
00070 ,const std::string ¶msXmlFileNameOption
00071 ,const std::string &extraParamsXmlStringOption
00072 ,const std::string ¶msUsedXmlOutFileNameOption
00073 )
00074 :paramsXmlFileName_(paramsXmlFileName)
00075 ,extraParamsXmlString_(extraParamsXmlString)
00076 ,paramsUsedXmlOutFileName_(paramsUsedXmlOutFileName)
00077 ,paramsXmlFileNameOption_(paramsXmlFileNameOption)
00078 ,extraParamsXmlStringOption_(extraParamsXmlStringOption)
00079 ,paramsUsedXmlOutFileNameOption_(paramsUsedXmlOutFileNameOption)
00080 {
00081 this->initializeDefaults();
00082 }
00083
00084 DefaultRealLinearSolverBuilder::~DefaultRealLinearSolverBuilder()
00085 {
00086 #ifdef TEUCHOS_DEBUG
00087
00088 if(paramList_.get())
00089 paramList_->validateParameters(*this->getValidParameters(),0);
00090 #endif
00091 }
00092
00093 void DefaultRealLinearSolverBuilder::setLinearSolveStrategyFactory(
00094 const Teuchos::RefCountPtr<const Teuchos::AbstractFactory<LinearOpWithSolveFactoryBase<double> > > &solveStrategyFactory
00095 ,const std::string &solveStrategyName
00096 )
00097 {
00098 lowsf_map_[solveStrategyName] = solveStrategyFactory;
00099 validLowsfNames_.push_back(solveStrategyName);
00100 defaultLOWSF_ = solveStrategyName;
00101 validParamList_ = Teuchos::null;
00102 }
00103
00104 void DefaultRealLinearSolverBuilder::setPreconditioningStrategyFactory(
00105 const Teuchos::RefCountPtr<const Teuchos::AbstractFactory<PreconditionerFactoryBase<double> > > &precStrategyFactory
00106 ,const std::string &precStrategyName
00107 )
00108 {
00109 pf_map_[precStrategyName] = precStrategyFactory;
00110 validPfNames_.push_back(precStrategyName);
00111 defaultPF_ = precStrategyName;
00112 validParamList_ = Teuchos::null;
00113 }
00114
00115 void DefaultRealLinearSolverBuilder::setupCLP( Teuchos::CommandLineProcessor *clp )
00116 {
00117 TEST_FOR_EXCEPT(clp==NULL);
00118 clp->setOption(
00119 paramsXmlFileNameOption().c_str(),¶msXmlFileName_
00120 ,"Name of an XML file containing parameters for linear solver options to be appended first."
00121 );
00122 clp->setOption(
00123 extraParamsXmlStringOption().c_str(),&extraParamsXmlString_
00124 ,"An XML string containing linear solver parameters to be appended second."
00125 );
00126 clp->setOption(
00127 paramsUsedXmlOutFileNameOption().c_str(),¶msUsedXmlOutFileName_
00128 ,"Name of an XML file that can be written with the parameter list after it has been used on completion of this program."
00129 );
00130 }
00131
00132 void DefaultRealLinearSolverBuilder::readParameters( std::ostream *out )
00133 {
00134 if(!paramList_.get())
00135 paramList_ = Teuchos::rcp(new Teuchos::ParameterList("DefaultRealLinearSolverBuilder"));
00136 if(paramsXmlFileName().length()) {
00137 if(out) *out << "\nReading parameters from XML file \""<<paramsXmlFileName()<<"\" ...\n";
00138 Teuchos::updateParametersFromXmlFile(paramsXmlFileName(),&*paramList_);
00139 }
00140 if(extraParamsXmlString().length()) {
00141 if(out) *out << "\nAppending extra parameters from the XML string \""<<extraParamsXmlString()<<"\" ...\n";
00142 Teuchos::updateParametersFromXmlString(extraParamsXmlString(),&*paramList_);
00143 }
00144 }
00145
00146 void DefaultRealLinearSolverBuilder::writeParamsFile(
00147 const LinearOpWithSolveFactoryBase<double> &lowsFactory
00148 ,const std::string &outputXmlFileName
00149 ) const
00150 {
00151 TEST_FOR_EXCEPT(!paramList_.get());
00152 std::string xmlOutputFile
00153 = ( outputXmlFileName.length() ? outputXmlFileName : paramsUsedXmlOutFileName() );
00154 if(xmlOutputFile.length()) {
00155 Teuchos::writeParameterListToXmlFile(*paramList_,xmlOutputFile);
00156 }
00157 }
00158
00159 std::string
00160 DefaultRealLinearSolverBuilder::getLinearSolveStrategyName() const
00161 {
00162 TEST_FOR_EXCEPT(!paramList_.get());
00163 return paramList_->get(LinearSolverType_name,defaultLOWSF_);
00164 }
00165
00166 std::string
00167 DefaultRealLinearSolverBuilder::getPreconditionerStrategyName() const
00168 {
00169 TEST_FOR_EXCEPT(!paramList_.get());
00170 return paramList_->get(PreconditionerType_name,defaultPF_);
00171 }
00172
00173
00174
00175
00176 void DefaultRealLinearSolverBuilder::setParameterList(
00177 Teuchos::RefCountPtr<Teuchos::ParameterList> const& paramList
00178 )
00179 {
00180 TEST_FOR_EXCEPT(!paramList.get());
00181
00182 paramList->validateParameters(*this->getValidParameters(),0);
00183 paramList_ = paramList;
00184 }
00185
00186 Teuchos::RefCountPtr<Teuchos::ParameterList>
00187 DefaultRealLinearSolverBuilder::getParameterList()
00188 {
00189 return paramList_;
00190 }
00191
00192 Teuchos::RefCountPtr<Teuchos::ParameterList>
00193 DefaultRealLinearSolverBuilder::unsetParameterList()
00194 {
00195 Teuchos::RefCountPtr<Teuchos::ParameterList> _paramList = paramList_;
00196 paramList_ = Teuchos::null;
00197 return _paramList;
00198 }
00199
00200 Teuchos::RefCountPtr<const Teuchos::ParameterList>
00201 DefaultRealLinearSolverBuilder::getParameterList() const
00202 {
00203 return paramList_;
00204 }
00205
00206 Teuchos::RefCountPtr<const Teuchos::ParameterList>
00207 DefaultRealLinearSolverBuilder::getValidParameters() const
00208 {
00209 if(!validParamList_.get()) {
00210 Teuchos::RefCountPtr<Teuchos::ParameterList>
00211 validParamList = Teuchos::rcp(new Teuchos::ParameterList);
00212
00213 validParamList->set(LinearSolverType_name,defaultLOWSF_);
00214 Teuchos::RefCountPtr<Teuchos::ParameterList>
00215 linearSolverTypesSL = sublist(validParamList,LinearSolverTypes_name);
00216 for(
00217 lowsf_map_t::const_iterator itr = lowsf_map_.begin();
00218 itr != lowsf_map_.end();
00219 ++itr
00220 )
00221 {
00222 const std::string
00223 &name = itr->first;
00224 const Teuchos::RefCountPtr<LinearOpWithSolveFactoryBase<double> >
00225 lowsf = itr->second->create();
00226 linearSolverTypesSL->sublist(name).setParameters(*lowsf->getValidParameters());
00227 }
00228
00229 validParamList->set(PreconditionerType_name,defaultPF_);
00230 Teuchos::RefCountPtr<Teuchos::ParameterList>
00231 precTypesSL = sublist(validParamList,PreconditionerTypes_name);
00232 for(
00233 pf_map_t::const_iterator itr = pf_map_.begin();
00234 itr != pf_map_.end();
00235 ++itr
00236 )
00237 {
00238 const std::string
00239 &name = itr->first;
00240 const Teuchos::RefCountPtr<PreconditionerFactoryBase<double> >
00241 pf = itr->second->create();
00242 precTypesSL->sublist(name).setParameters(*pf->getValidParameters());
00243 }
00244 validParamList_ = validParamList;
00245 }
00246 return validParamList_;
00247 }
00248
00249
00250
00251 Teuchos::RefCountPtr<LinearOpWithSolveFactoryBase<double> >
00252 DefaultRealLinearSolverBuilder::createLinearSolveStrategy(
00253 const std::string &linearSolveStrategyName
00254 ) const
00255 {
00256
00257 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
00258 std::cout << "\nEntering DefaultRealLinearSolverBuilder::createLinearSolveStrategy(...) ...\n";
00259 std::cout << "\nlinearSolveStrategyName = \"" << linearSolveStrategyName << "\"\n";
00260 std::cout << "\nlinearSolveStrategyName.length() = " << linearSolveStrategyName.length() << "\n";
00261 std::cout << "\ndefaultLOWSF_ = \"" << defaultLOWSF_ << "\"\n";
00262 std::cout << "\nthis->getLinearSolveStrategyName() = \"" << this->getLinearSolveStrategyName() << "\"\n";
00263 #endif
00264 const std::string
00265 name = ( linearSolveStrategyName.length()
00266 ? linearSolveStrategyName
00267 : this->getLinearSolveStrategyName() );
00268 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
00269 std::cout << "\nname = \"" << name << "\"\n";
00270 #endif
00271
00272 lowsf_map_t::const_iterator itr = lowsf_map_.find(name);
00273 TEST_FOR_EXCEPTION(
00274 itr == lowsf_map_.end(), std::invalid_argument
00275 ,"Error, the value \""<<LinearSolverType_name<<"\"=\""<<name<<"\" is not a valid"
00276 " linear solver type. Valid linear solve strategy names include "
00277 <<validLinearSolveStrategyNames()<<"!"
00278 );
00279
00280 Teuchos::RefCountPtr<LinearOpWithSolveFactoryBase<double> >
00281 lowsf = itr->second->create();
00282
00283 if(lowsf->acceptsPreconditionerFactory()) {
00284 const std::string &pfName = this->getPreconditionerStrategyName();
00285 Teuchos::RefCountPtr<PreconditionerFactoryBase<double> >
00286 pf = this->createPreconditioningStrategy(pfName);
00287 if(pf.get())
00288 lowsf->setPreconditionerFactory(pf,pfName);
00289 }
00290
00291
00292 lowsf->setParameterList(sublist(sublist(paramList_,LinearSolverTypes_name),name));
00293
00294 return lowsf;
00295 }
00296
00297 Teuchos::RefCountPtr<PreconditionerFactoryBase<double> >
00298 DefaultRealLinearSolverBuilder::createPreconditioningStrategy(
00299 const std::string &preconditioningStrategyName
00300 ) const
00301 {
00302
00303 const std::string
00304 name = ( preconditioningStrategyName.length()
00305 ? preconditioningStrategyName
00306 : this->getPreconditionerStrategyName() );
00307 Teuchos::RefCountPtr<PreconditionerFactoryBase<double> >
00308 pf = Teuchos::null;
00309 if( name != "None" ) {
00310 pf_map_t::const_iterator itr = pf_map_.find(name);
00311 TEST_FOR_EXCEPTION(
00312 itr == pf_map_.end(), std::invalid_argument
00313 ,"Error, the value \""<<PreconditionerType_name<<"\"=\""<<name<<"\" is not a valid"
00314 " preconditioner type. Valid preconditioning strategy names include "
00315 <<validPreconditioningStrategyNames()<<"!"
00316 );
00317 pf = itr->second->create();
00318 pf->setParameterList(sublist(sublist(paramList_,PreconditionerTypes_name),name));
00319 }
00320 return pf;
00321 }
00322
00323
00324
00325 void DefaultRealLinearSolverBuilder::initializeDefaults()
00326 {
00327 using Teuchos::rcp;
00328 using Teuchos::AbstractFactoryStd;
00329 defaultLOWSF_ = "";
00330 defaultPF_ = "";
00331
00332 #ifdef HAVE_STRATIMIKOS_BELOS_THYRA
00333 setLinearSolveStrategyFactory(
00334 rcp(new AbstractFactoryStd<LinearOpWithSolveFactoryBase<double>,BelosLinearOpWithSolveFactory<double> >())
00335 ,"Belos"
00336 );
00337 #endif
00338 #ifdef HAVE_STRATIMIKOS_AMESOS_THYRA
00339 setLinearSolveStrategyFactory(
00340 rcp(new AbstractFactoryStd<LinearOpWithSolveFactoryBase<double>,AmesosLinearOpWithSolveFactory>())
00341 ,"Amesos"
00342 );
00343 #endif
00344 #ifdef HAVE_STRATIMIKOS_AZTECOO_THYRA
00345 setLinearSolveStrategyFactory(
00346 rcp(new AbstractFactoryStd<LinearOpWithSolveFactoryBase<double>,AztecOOLinearOpWithSolveFactory>())
00347 ,"AztecOO"
00348 );
00349 #endif
00350 #ifdef HAVE_STRATIMIKOS_AMESOS_THYRA
00351 if( Teuchos::GlobalMPISession::getNProc() == 1 ) {
00352 defaultLOWSF_ = "Amesos";
00353 }
00354 #endif
00355
00356 #ifdef HAVE_STRATIMIKOS_IFPACK_THYRA
00357 setPreconditioningStrategyFactory(
00358 rcp(new AbstractFactoryStd<PreconditionerFactoryBase<double>,IfpackPreconditionerFactory>())
00359 ,"Ifpack"
00360 );
00361 #endif
00362 #ifdef HAVE_STRATIMIKOS_ML_THYRA
00363 setPreconditioningStrategyFactory(
00364 rcp(new AbstractFactoryStd<PreconditionerFactoryBase<double>,MLPreconditionerFactory>())
00365 ,"ML"
00366 );
00367 #endif
00368 }
00369
00370 std::string
00371 DefaultRealLinearSolverBuilder::validLinearSolveStrategyNames() const
00372 {
00373 std::ostringstream oss;
00374 oss << "{";
00375 for( int i = 0; i < int(validLowsfNames_.size()); ++i ) {
00376 oss << "\"" << validLowsfNames_[i] << "\"";
00377 if( i != int(validLowsfNames_.size()-1) )
00378 oss << ",";
00379 }
00380 oss << "}";
00381 return oss.str();
00382 }
00383
00384 std::string
00385 DefaultRealLinearSolverBuilder::validPreconditioningStrategyNames() const
00386 {
00387 std::ostringstream oss;
00388 oss << "{";
00389 for( int i = 0; i < int(validPfNames_.size()); ++i ) {
00390 oss << "\"" << validPfNames_[i] << "\"";
00391 if( i != int(validPfNames_.size()-1) )
00392 oss << ",";
00393 }
00394 oss << "}";
00395 return oss.str();
00396 }
00397
00398 }