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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "Teko_InverseLibrary.hpp"
00048
00049 #include "Teko_SolveInverseFactory.hpp"
00050 #include "Teko_PreconditionerInverseFactory.hpp"
00051 #include "Teko_BlockPreconditionerFactory.hpp"
00052
00053 #include "Teko_NeumannSeriesPreconditionerFactory.hpp"
00054 #include "Teuchos_AbstractFactoryStd.hpp"
00055
00056 #include <algorithm>
00057
00058 using Teuchos::RCP;
00059 using Teuchos::rcp;
00060
00061 namespace Teko {
00062
00066 void addToStratimikosBuilder(Stratimikos::DefaultLinearSolverBuilder & builder)
00067 {
00068 typedef Thyra::PreconditionerFactoryBase<double> PrecFactory;
00069
00070 RCP<const Teuchos::AbstractFactory<Thyra::PreconditionerFactoryBase<double> > > factory;
00071
00072 factory = Teuchos::abstractFactoryStd<PrecFactory,Teko::NeumannSeriesPreconditionerFactory<double> >();
00073 builder.setPreconditioningStrategyFactory(factory,"Neumann Series");
00074 }
00075
00076 InverseLibrary::InverseLibrary()
00077 {
00078 Teko_DEBUG_SCOPE("InverseLibrary::InverseLibrary", 10);
00079
00080 defaultBuilder_ = Teuchos::rcp(new Stratimikos::DefaultLinearSolverBuilder());
00081 addToStratimikosBuilder(*defaultBuilder_);
00082
00083
00085
00086
00087 stratValidSolver_.push_back("Belos");
00088 stratValidSolver_.push_back("Amesos");
00089 stratValidSolver_.push_back("AztecOO");
00090
00091
00092 stratValidPrecond_.push_back("ML");
00093 stratValidPrecond_.push_back("Ifpack");
00094 stratValidPrecond_.push_back("Neumann Series");
00095
00096
00097 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
00098
00099 Teko_DEBUG_MSG_BEGIN(10)
00100 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
00101 for(std::size_t i=0;i<blockValidPrecond_.size();i++)
00102 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
00103 DEBUG_STREAM << std::endl;
00104 Teko_DEBUG_MSG_END()
00105 }
00106
00107 InverseLibrary::InverseLibrary(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
00108 : defaultBuilder_(strat)
00109 {
00110 Teko_DEBUG_SCOPE("InverseLibrary::InverseLibrary", 10);
00111
00112 addToStratimikosBuilder(*defaultBuilder_);
00113
00114 RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList(*defaultBuilder_->getValidParameters()));
00115 Teuchos::ParameterList lst(pl->sublist("Linear Solver Types"));
00116 Teuchos::ParameterList pft(pl->sublist("Preconditioner Types"));
00117
00118 Teuchos::ParameterList::ConstIterator itr;
00119
00120
00121 for(itr=lst.begin();itr!=lst.end();++itr)
00122 stratValidSolver_.push_back(itr->first);
00123
00124 Teko_DEBUG_MSG_BEGIN(10)
00125 DEBUG_STREAM << "Loaded \"Stratimikos\" solvers = ";
00126 for(std::size_t i=0;i<stratValidSolver_.size();i++)
00127 DEBUG_STREAM << stratValidSolver_[i] << ", ";
00128 DEBUG_STREAM << std::endl;
00129 Teko_DEBUG_MSG_END()
00130
00131
00132 for(itr=pft.begin();itr!=pft.end();++itr)
00133 stratValidPrecond_.push_back(itr->first);
00134
00135 Teko_DEBUG_MSG_BEGIN(10)
00136 DEBUG_STREAM << "Loaded \"Stratimikos\" preconditioners = ";
00137 for(std::size_t i=0;i<stratValidPrecond_.size();i++)
00138 DEBUG_STREAM << stratValidPrecond_[i] << ", ";
00139 DEBUG_STREAM << std::endl;
00140 Teko_DEBUG_MSG_END()
00141
00142
00143 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
00144
00145 Teko_DEBUG_MSG_BEGIN(10)
00146 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
00147 for(std::size_t i=0;i<blockValidPrecond_.size();i++)
00148 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
00149 DEBUG_STREAM << std::endl;
00150 Teko_DEBUG_MSG_END()
00151 }
00152
00154 void InverseLibrary::addInverse(const std::string & label,const Teuchos::ParameterList & pl)
00155 {
00156
00157 const std::string type = pl.get<std::string>("Type");
00158
00159
00160 Teuchos::ParameterList settingsList;
00161 settingsList.set(type,pl);
00162 settingsList.sublist(type).remove("Type");
00163
00164
00165 if(std::find(stratValidPrecond_.begin(),stratValidPrecond_.end(),type)!=stratValidPrecond_.end()) {
00166
00167 addStratPrecond(label,type,settingsList);
00168 }
00169 else if(std::find(stratValidSolver_.begin(),stratValidSolver_.end(),type)!=stratValidSolver_.end()) {
00170
00171 addStratSolver(label,type,settingsList);
00172 }
00173 else if(std::find(blockValidPrecond_.begin(),blockValidPrecond_.end(),type)!=blockValidPrecond_.end()) {
00174
00175 addBlockPrecond(label,type,settingsList);
00176 }
00177 else {
00178 Teuchos::FancyOStream & os = *Teko::getOutputStream();
00179 os << "ERROR: Could not find inverse type \"" << type
00180 << "\" required by inverse name \"" << label << "\"" << std::endl;
00181 TEUCHOS_ASSERT(false);
00182 }
00183 }
00184
00186 void InverseLibrary::addStratSolver(const std::string & label,const std::string & type,const Teuchos::ParameterList & pl)
00187 {
00188
00189 RCP<Teuchos::ParameterList> stratList = rcp(new Teuchos::ParameterList());
00190 stratList->set("Linear Solver Type",type);
00191 stratList->set("Linear Solver Types",pl);
00192 stratList->set("Preconditioner Type","None");
00193
00194 stratSolver_[label] = stratList;
00195 }
00196
00198 void InverseLibrary::addStratPrecond(const std::string & label,const std::string & type,const Teuchos::ParameterList & pl)
00199 {
00200
00201 RCP<Teuchos::ParameterList> stratList = rcp(new Teuchos::ParameterList());
00202 stratList->set("Preconditioner Type",type);
00203 stratList->set("Preconditioner Types",pl);
00204
00205 stratPrecond_[label] = stratList;
00206 }
00207
00209 void InverseLibrary::addBlockPrecond(const std::string & label,const std::string & type,const Teuchos::ParameterList & pl)
00210 {
00211
00212 RCP<Teuchos::ParameterList> blockList = rcp(new Teuchos::ParameterList());
00213 blockList->set("Preconditioner Type",type);
00214 blockList->set("Preconditioner Settings",pl.sublist(type));
00215
00216
00217 blockPrecond_[label] = blockList;
00218 }
00219
00227 Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(const std::string & label) const
00228 {
00229 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
00230
00231
00232 itr = stratPrecond_.find(label);
00233 if(itr!=stratPrecond_.end()) return itr->second;
00234
00235
00236 itr = stratSolver_.find(label);
00237 if(itr!=stratSolver_.end()) return itr->second;
00238
00239
00240 itr = blockPrecond_.find(label);
00241 if(itr!=blockPrecond_.end()) return itr->second;
00242
00243 return Teuchos::null;
00244 }
00245
00247 Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(const std::string & label) const
00248 {
00249 Teko_DEBUG_SCOPE("InverseLibrary::getInverseFactory",10);
00250
00251 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
00252
00253 bool isStratSolver=false,isStratPrecond=false,isBlockPrecond=false;
00254
00255
00256 itr = stratPrecond_.find(label);
00257 isStratPrecond = itr!=stratPrecond_.end();
00258
00259
00260 if(not isStratPrecond) {
00261 itr = stratSolver_.find(label);
00262 isStratSolver = itr!=stratSolver_.end();
00263 }
00264
00265
00266 if(not (isStratSolver || isStratPrecond)) {
00267 itr = blockPrecond_.find(label);
00268 isBlockPrecond = itr!=blockPrecond_.end();
00269 }
00270
00271 Teko_DEBUG_MSG("Inverse \"" << label << "\" is of type "
00272 << "strat prec = " << isStratPrecond << ", "
00273 << "strat solv = " << isStratSolver << ", "
00274 << "block prec = " << isBlockPrecond,3);
00275
00276
00277 if(not (isStratSolver || isStratPrecond || isBlockPrecond)) {
00278 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
00279
00280 *out << "InverseLibrary::getInverseFactory could not find \"" << label << "\" ... aborting\n";
00281 *out << "Choose one of: " << std::endl;
00282
00283 *out << " Stratimikos preconditioners = ";
00284 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr)
00285 *out << " \"" << itr->first << "\"\n";
00286 *out << std::endl;
00287
00288 *out << " Stratimikos solvers = ";
00289 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr)
00290 *out << " \"" << itr->first << "\"\n";
00291 *out << std::endl;
00292
00293 *out << " Block preconditioners = ";
00294 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr)
00295 *out << " \"" << itr->first << "\"\n";
00296 *out << std::endl;
00297
00298 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
00299 }
00300
00301 RCP<const Teuchos::ParameterList> pl = itr->second;
00302
00303
00304 if(isStratPrecond) {
00305
00306 RCP<Teuchos::ParameterList> plCopy = rcp(new Teuchos::ParameterList(*pl));
00307 std::string type = plCopy->get<std::string>("Preconditioner Type");
00308 RCP<Teuchos::ParameterList> xtraParams;
00309 if(plCopy->sublist("Preconditioner Types").sublist(type).isParameter("Required Parameters")) {
00310 xtraParams = rcp(new Teuchos::ParameterList(
00311 plCopy->sublist("Preconditioner Types").sublist(type).sublist("Required Parameters")));
00312 plCopy->sublist("Preconditioner Types").sublist(type).remove("Required Parameters");
00313 }
00314
00315
00316 Teko_DEBUG_MSG_BEGIN(10);
00317 DEBUG_STREAM << "Printing parameter list: " << std::endl;
00318 Teko_DEBUG_PUSHTAB(); plCopy->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
00319
00320 if(xtraParams!=Teuchos::null) {
00321 DEBUG_STREAM << "Printing extra parameters: " << std::endl;
00322 Teko_DEBUG_PUSHTAB(); xtraParams->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
00323 }
00324 Teko_DEBUG_MSG_END();
00325
00326
00327
00328 defaultBuilder_->setParameterList(plCopy);
00329
00330
00331 RCP<Thyra::PreconditionerFactoryBase<double> > precFact = defaultBuilder_->createPreconditioningStrategy(type);
00332
00333
00334 RCP<Teko::PreconditionerInverseFactory> precInvFact
00335 = rcp(new PreconditionerInverseFactory(precFact,xtraParams,getRequestHandler()));
00336 precInvFact->setupParameterListFromRequestHandler();
00337 return precInvFact;
00338 }
00339 else if(isStratSolver) {
00340 RCP<Teuchos::ParameterList> solveList = rcp(new Teuchos::ParameterList(*pl));
00341 std::string type = solveList->get<std::string>("Linear Solver Type");
00342
00343
00344 Teuchos::ParameterList & solveSettings = solveList->sublist("Linear Solver Types").sublist(type);
00345 std::string precKeyWord = "Use Preconditioner";
00346 std::string precName = "None";
00347 if(solveSettings.isParameter(precKeyWord)) {
00348 precName = solveSettings.get<std::string>(precKeyWord);
00349 solveSettings.remove(precKeyWord);
00350 }
00351
00352
00353 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
00354 if(precName!="None") {
00355
00356 solveList->set<std::string>("Preconditioner Type","None");
00357
00358
00359 RCP<PreconditionerInverseFactory> precInvFactory
00360 = Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
00361
00362
00363 precFactory = precInvFactory->getPrecFactory();
00364 }
00365
00366
00367
00368 defaultBuilder_->setParameterList(solveList);
00369
00370
00371 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact = defaultBuilder_->createLinearSolveStrategy(type);
00372 if(precFactory!=Teuchos::null)
00373 solveFact->setPreconditionerFactory(precFactory,precName);
00374
00375
00376 return rcp(new SolveInverseFactory(solveFact));
00377 }
00378 else if(isBlockPrecond) {
00379 try {
00380 std::string type = pl->get<std::string>("Preconditioner Type");
00381 const Teuchos::ParameterList & settings = pl->sublist("Preconditioner Settings");
00382
00383
00384 RCP<PreconditionerFactory> precFact
00385 = PreconditionerFactory::buildPreconditionerFactory(type,settings,Teuchos::rcpFromRef(*this));
00386
00387 TEUCHOS_ASSERT(precFact!=Teuchos::null);
00388
00389
00390 return rcp(new PreconditionerInverseFactory(precFact,getRequestHandler()));
00391 }
00392 catch(std::exception & e) {
00393 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
00394
00395 *out << "Teko: \"getInverseFactory\" failed, Parameter List =\n";
00396 pl->print(*out);
00397
00398 *out << "*** THROWN EXCEPTION ***\n";
00399 *out << e.what() << std::endl;
00400 *out << "************************\n";
00401
00402 throw e;
00403 }
00404 }
00405
00406 TEUCHOS_ASSERT(false);
00407 }
00408
00410 void InverseLibrary::PrintAvailableInverses(std::ostream & os) const
00411 {
00412 std::map<std::string,Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
00413
00414 os << "Stratimikos Solvers: " << std::endl;
00415 os << "********************************" << std::endl;
00416 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr) {
00417 os << "name = \"" << itr->first << "\"" << std::endl;
00418 itr->second->print(os);
00419 os << std::endl;
00420 }
00421
00422 os << "Stratimikos Preconditioners: " << std::endl;
00423 os << "********************************" << std::endl;
00424 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr) {
00425 os << "name = \"" << itr->first << "\"" << std::endl;
00426 itr->second->print(os);
00427 os << std::endl;
00428 }
00429
00430 os << "Teko Preconditioners: " << std::endl;
00431 os << "********************************" << std::endl;
00432 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr) {
00433 os << "name = \"" << itr->first << "\"" << std::endl;
00434 itr->second->print(os);
00435 os << std::endl;
00436 }
00437 }
00438
00448 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(const Teuchos::ParameterList & pl,bool useStratDefaults)
00449 {
00450
00451 RCP<InverseLibrary> invLib;
00452 if(useStratDefaults)
00453 invLib = InverseLibrary::buildFromStratimikos();
00454 else
00455 invLib = rcp(new InverseLibrary());
00456
00457
00458 Teuchos::ParameterList * temp = 0;
00459
00460
00461 Teuchos::ParameterList::ConstIterator itr;
00462 for(itr=pl.begin();itr!=pl.end();++itr) {
00463
00464 std::string label = itr->first;
00465 Teuchos::ParameterList & list = itr->second.getValue(temp);
00466
00467
00468 invLib->addInverse(label,list);
00469 }
00470
00471 return invLib;
00472 }
00473
00484 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(const Teuchos::ParameterList & pl,
00485 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
00486 {
00487
00488 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
00489
00490
00491 Teuchos::ParameterList * temp = 0;
00492
00493
00494 Teuchos::ParameterList::ConstIterator itr;
00495 for(itr=pl.begin();itr!=pl.end();++itr) {
00496
00497 std::string label = itr->first;
00498 Teuchos::ParameterList & list = itr->second.getValue(temp);
00499
00500
00501 invLib->addInverse(label,list);
00502 }
00503
00504 return invLib;
00505 }
00506
00516 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(const Stratimikos::DefaultLinearSolverBuilder & strat)
00517 {
00518 RCP<InverseLibrary> invLib = rcp(new InverseLibrary());
00519
00520
00521 RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList(*strat.getValidParameters()));
00522 Teuchos::ParameterList lst(pl->sublist("Linear Solver Types"));
00523 Teuchos::ParameterList pft(pl->sublist("Preconditioner Types"));
00524
00525 Teuchos::ParameterList::ConstIterator itr;
00526 Teuchos::ParameterList * temp = 0;
00527
00528
00529 for(itr=lst.begin();itr!=lst.end();++itr) {
00530
00531 std::string label = itr->first;
00532 Teuchos::ParameterList & list = itr->second.getValue(temp);
00533 list.set("Type",label);
00534
00535
00536 invLib->addInverse(label,list);
00537 }
00538
00539
00540 for(itr=pft.begin();itr!=pft.end();++itr) {
00541
00542 std::string label = itr->first;
00543 Teuchos::ParameterList & list = itr->second.getValue(temp);
00544 list.set("Type",label);
00545
00546
00547 invLib->addInverse(label,list);
00548 }
00549
00550 return invLib;
00551 }
00552
00562 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
00563 {
00564 RCP<InverseLibrary> invLib = rcp(new InverseLibrary(strat));
00565
00566
00567 RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList(*strat->getValidParameters()));
00568 Teuchos::ParameterList lst(pl->sublist("Linear Solver Types"));
00569 Teuchos::ParameterList pft(pl->sublist("Preconditioner Types"));
00570
00571 Teuchos::ParameterList::ConstIterator itr;
00572 Teuchos::ParameterList * temp = 0;
00573
00574
00575 for(itr=lst.begin();itr!=lst.end();++itr) {
00576
00577 std::string label = itr->first;
00578 Teuchos::ParameterList & list = itr->second.getValue(temp);
00579 list.set("Type",label);
00580
00581
00582 invLib->addInverse(label,list);
00583 }
00584
00585
00586 for(itr=pft.begin();itr!=pft.end();++itr) {
00587
00588 std::string label = itr->first;
00589 Teuchos::ParameterList & list = itr->second.getValue(temp);
00590 list.set("Type",label);
00591
00592
00593 invLib->addInverse(label,list);
00594 }
00595
00596 return invLib;
00597 }
00598
00599 }