47#include "Teko_InverseLibrary.hpp"
49#include "Teko_SolveInverseFactory.hpp"
50#include "Teko_PreconditionerInverseFactory.hpp"
51#include "Teko_BlockPreconditionerFactory.hpp"
53#include "Teko_NeumannSeriesPreconditionerFactory.hpp"
54#include "Teuchos_AbstractFactoryStd.hpp"
67void addToStratimikosBuilder(
const RCP<Stratimikos::DefaultLinearSolverBuilder> & builder)
69 typedef Thyra::PreconditionerFactoryBase<double> PrecFactory;
71 RCP<const Teuchos::ParameterList> parameters = builder->getValidParameters();
73 if(!parameters->sublist(
"Preconditioner Types").isSublist(
"Neumann Series")) {
74 RCP<const Teuchos::AbstractFactory<Thyra::PreconditionerFactoryBase<double> > > factory;
76 factory = Teuchos::abstractFactoryStd<PrecFactory,Teko::NeumannSeriesPreconditionerFactory<double> >();
77 builder->setPreconditioningStrategyFactory(factory,
"Neumann Series");
82InverseLibrary::InverseLibrary()
84 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
86 defaultBuilder_ = Teuchos::rcp(
new Stratimikos::DefaultLinearSolverBuilder());
87 addToStratimikosBuilder(defaultBuilder_);
93 stratValidSolver_.push_back(
"Belos");
94 stratValidSolver_.push_back(
"Amesos");
95 stratValidSolver_.push_back(
"Amesos2");
96 stratValidSolver_.push_back(
"AztecOO");
99 stratValidPrecond_.push_back(
"ML");
100 stratValidPrecond_.push_back(
"Ifpack");
101 stratValidPrecond_.push_back(
"Neumann Series");
102 stratValidPrecond_.push_back(
"MueLu");
103 stratValidPrecond_.push_back(
"Ifpack2");
108 Teko_DEBUG_MSG_BEGIN(10)
109 DEBUG_STREAM <<
"Loaded \"block\" preconditioners = ";
110 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
111 DEBUG_STREAM << blockValidPrecond_[i] <<
", ";
112 DEBUG_STREAM << std::endl;
116InverseLibrary::InverseLibrary(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
117 : defaultBuilder_(strat)
119 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
121 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*defaultBuilder_->getValidParameters()));
122 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
123 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
125 Teuchos::ParameterList::ConstIterator itr;
128 for(itr=lst.begin();itr!=lst.end();++itr)
129 stratValidSolver_.push_back(itr->first);
131 Teko_DEBUG_MSG_BEGIN(10)
132 DEBUG_STREAM <<
"Loaded \"Stratimikos\" solvers = ";
133 for(std::
size_t i=0;i<stratValidSolver_.size();i++)
134 DEBUG_STREAM << stratValidSolver_[i] <<
", ";
135 DEBUG_STREAM << std::endl;
139 for(itr=pft.begin();itr!=pft.end();++itr)
140 stratValidPrecond_.push_back(itr->first);
142 Teko_DEBUG_MSG_BEGIN(10)
143 DEBUG_STREAM <<
"Loaded \"Stratimikos\" preconditioners = ";
144 for(std::
size_t i=0;i<stratValidPrecond_.size();i++)
145 DEBUG_STREAM << stratValidPrecond_[i] <<
", ";
146 DEBUG_STREAM << std::endl;
150 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
152 Teko_DEBUG_MSG_BEGIN(10)
153 DEBUG_STREAM <<
"Loaded \"block\" preconditioners = ";
154 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
155 DEBUG_STREAM << blockValidPrecond_[i] <<
", ";
156 DEBUG_STREAM << std::endl;
161void InverseLibrary::addInverse(const std::
string & label,const Teuchos::ParameterList & pl)
164 const std::string type = pl.get<std::string>(
"Type");
167 Teuchos::ParameterList settingsList;
168 settingsList.set(type,pl);
169 settingsList.sublist(type).remove(
"Type");
172 if(std::find(stratValidPrecond_.begin(),stratValidPrecond_.end(),type)!=stratValidPrecond_.end()) {
174 addStratPrecond(label,type,settingsList);
176 else if(std::find(stratValidSolver_.begin(),stratValidSolver_.end(),type)!=stratValidSolver_.end()) {
178 addStratSolver(label,type,settingsList);
180 else if(std::find(blockValidPrecond_.begin(),blockValidPrecond_.end(),type)!=blockValidPrecond_.end()) {
182 addBlockPrecond(label,type,settingsList);
185 Teuchos::FancyOStream & os = *Teko::getOutputStream();
186 os <<
"ERROR: Could not find inverse type \"" << type
187 <<
"\" required by inverse name \"" << label <<
"\"" << std::endl;
188 TEUCHOS_ASSERT(false);
193void InverseLibrary::addStratSolver(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
196 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
197 stratList->set(
"Linear Solver Type",type);
198 stratList->set(
"Linear Solver Types",pl);
199 stratList->set(
"Preconditioner Type",
"None");
201 stratSolver_[label] = stratList;
205void InverseLibrary::addStratPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
208 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
209 stratList->set(
"Preconditioner Type",type);
210 stratList->set(
"Preconditioner Types",pl);
212 stratPrecond_[label] = stratList;
216void InverseLibrary::addBlockPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
219 RCP<Teuchos::ParameterList> blockList = rcp(
new Teuchos::ParameterList());
220 blockList->set(
"Preconditioner Type",type);
221 blockList->set(
"Preconditioner Settings",pl.sublist(type));
224 blockPrecond_[label] = blockList;
234Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(
const std::string & label)
const
236 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
239 itr = stratPrecond_.find(label);
240 if(itr!=stratPrecond_.end())
return itr->second;
243 itr = stratSolver_.find(label);
244 if(itr!=stratSolver_.end())
return itr->second;
247 itr = blockPrecond_.find(label);
248 if(itr!=blockPrecond_.end())
return itr->second;
250 return Teuchos::null;
254Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(
const std::string & label)
const
256 Teko_DEBUG_SCOPE(
"InverseLibrary::getInverseFactory",10);
258 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
260 bool isStratSolver=
false,isStratPrecond=
false,isBlockPrecond=
false;
263 itr = stratPrecond_.find(label);
264 isStratPrecond = itr!=stratPrecond_.end();
267 if(not isStratPrecond) {
268 itr = stratSolver_.find(label);
269 isStratSolver = itr!=stratSolver_.end();
273 if(not (isStratSolver || isStratPrecond)) {
274 itr = blockPrecond_.find(label);
275 isBlockPrecond = itr!=blockPrecond_.end();
278 Teko_DEBUG_MSG(
"Inverse \"" << label <<
"\" is of type "
279 <<
"strat prec = " << isStratPrecond <<
", "
280 <<
"strat solv = " << isStratSolver <<
", "
281 <<
"block prec = " << isBlockPrecond,3);
284 if(not (isStratSolver || isStratPrecond || isBlockPrecond)) {
285 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
287 *out <<
"InverseLibrary::getInverseFactory could not find \"" << label <<
"\" ... aborting\n";
288 *out <<
"Choose one of: " << std::endl;
290 *out <<
" Stratimikos preconditioners = ";
291 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr)
292 *out <<
" \"" << itr->first <<
"\"\n";
295 *out <<
" Stratimikos solvers = ";
296 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr)
297 *out <<
" \"" << itr->first <<
"\"\n";
300 *out <<
" Block preconditioners = ";
301 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr)
302 *out <<
" \"" << itr->first <<
"\"\n";
305 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
308 RCP<const Teuchos::ParameterList> pl = itr->second;
313 RCP<Teuchos::ParameterList> plCopy = rcp(
new Teuchos::ParameterList(*pl));
314 std::string type = plCopy->get<std::string>(
"Preconditioner Type");
315 RCP<Teuchos::ParameterList> xtraParams;
316 if(plCopy->sublist(
"Preconditioner Types").sublist(type).isParameter(
"Required Parameters")) {
317 xtraParams = rcp(
new Teuchos::ParameterList(
318 plCopy->sublist(
"Preconditioner Types").sublist(type).sublist(
"Required Parameters")));
319 plCopy->sublist(
"Preconditioner Types").sublist(type).remove(
"Required Parameters");
323 Teko_DEBUG_MSG_BEGIN(10);
324 DEBUG_STREAM <<
"Printing parameter list: " << std::endl;
325 Teko_DEBUG_PUSHTAB(); plCopy->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
327 if(xtraParams!=Teuchos::null) {
328 DEBUG_STREAM <<
"Printing extra parameters: " << std::endl;
329 Teko_DEBUG_PUSHTAB(); xtraParams->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
331 Teko_DEBUG_MSG_END();
335 defaultBuilder_->setParameterList(plCopy);
338 RCP<Thyra::PreconditionerFactoryBase<double> > precFact = defaultBuilder_->createPreconditioningStrategy(type);
341 RCP<Teko::PreconditionerInverseFactory> precInvFact
342 = rcp(
new PreconditionerInverseFactory(precFact,xtraParams,
getRequestHandler()));
343 precInvFact->setupParameterListFromRequestHandler();
346 else if(isStratSolver) {
347 RCP<Teuchos::ParameterList> solveList = rcp(
new Teuchos::ParameterList(*pl));
348 std::string type = solveList->get<std::string>(
"Linear Solver Type");
351 Teuchos::ParameterList & solveSettings = solveList->sublist(
"Linear Solver Types").sublist(type);
352 std::string precKeyWord =
"Use Preconditioner";
353 std::string precName =
"None";
354 if(solveSettings.isParameter(precKeyWord)) {
355 precName = solveSettings.get<std::string>(precKeyWord);
356 solveSettings.remove(precKeyWord);
360 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
361 if(precName!=
"None") {
363 solveList->set<std::string>(
"Preconditioner Type",
"None");
366 RCP<PreconditionerInverseFactory> precInvFactory
367 = Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
370 precFactory = precInvFactory->getPrecFactory();
375 defaultBuilder_->setParameterList(solveList);
378 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact = defaultBuilder_->createLinearSolveStrategy(type);
379 if(precFactory!=Teuchos::null)
380 solveFact->setPreconditionerFactory(precFactory,precName);
383 return rcp(
new SolveInverseFactory(solveFact));
385 else if(isBlockPrecond) {
387 std::string type = pl->get<std::string>(
"Preconditioner Type");
388 const Teuchos::ParameterList & settings = pl->sublist(
"Preconditioner Settings");
391 RCP<PreconditionerFactory> precFact
394 TEUCHOS_ASSERT(precFact!=Teuchos::null);
399 catch(std::exception & e) {
400 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
402 *out <<
"Teko: \"getInverseFactory\" failed, Parameter List =\n";
405 *out <<
"*** THROWN EXCEPTION ***\n";
406 *out << e.what() << std::endl;
407 *out <<
"************************\n";
413 TEUCHOS_ASSERT(
false);
417void InverseLibrary::PrintAvailableInverses(std::ostream & os)
const
419 std::map<std::string,Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
421 os <<
"Stratimikos Solvers: " << std::endl;
422 os <<
"********************************" << std::endl;
423 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr) {
424 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
425 itr->second->print(os);
429 os <<
"Stratimikos Preconditioners: " << std::endl;
430 os <<
"********************************" << std::endl;
431 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr) {
432 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
433 itr->second->print(os);
437 os <<
"Teko Preconditioners: " << std::endl;
438 os <<
"********************************" << std::endl;
439 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr) {
440 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
441 itr->second->print(os);
455RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
bool useStratDefaults)
458 RCP<InverseLibrary> invLib;
460 invLib = InverseLibrary::buildFromStratimikos();
462 invLib = rcp(
new InverseLibrary());
465 Teuchos::ParameterList * temp = 0;
468 Teuchos::ParameterList::ConstIterator itr;
469 for(itr=pl.begin();itr!=pl.end();++itr) {
471 std::string label = itr->first;
472 Teuchos::ParameterList & list = itr->second.getValue(temp);
475 invLib->addInverse(label,list);
491RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
492 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
495 if(strat==Teuchos::null)
496 return buildFromParameterList(pl,
true);
499 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
502 Teuchos::ParameterList * temp = 0;
505 Teuchos::ParameterList::ConstIterator itr;
506 for(itr=pl.begin();itr!=pl.end();++itr) {
508 std::string label = itr->first;
509 Teuchos::ParameterList & list = itr->second.getValue(temp);
512 invLib->addInverse(label,list);
526Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos()
528 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
531 RCP<Stratimikos::DefaultLinearSolverBuilder> strat = invLib->defaultBuilder_;
532 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
533 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
534 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
536 Teuchos::ParameterList::ConstIterator itr;
537 Teuchos::ParameterList * temp = 0;
540 for(itr=lst.begin();itr!=lst.end();++itr) {
542 std::string label = itr->first;
543 Teuchos::ParameterList & list = itr->second.getValue(temp);
544 list.set(
"Type",label);
547 invLib->addInverse(label,list);
551 for(itr=pft.begin();itr!=pft.end();++itr) {
553 std::string label = itr->first;
554 Teuchos::ParameterList & list = itr->second.getValue(temp);
555 list.set(
"Type",label);
558 invLib->addInverse(label,list);
573Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Stratimikos::DefaultLinearSolverBuilder & strat)
575 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
578 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat.getValidParameters()));
579 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
580 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
582 Teuchos::ParameterList::ConstIterator itr;
583 Teuchos::ParameterList * temp = 0;
586 for(itr=lst.begin();itr!=lst.end();++itr) {
588 std::string label = itr->first;
589 Teuchos::ParameterList & list = itr->second.getValue(temp);
590 list.set(
"Type",label);
593 invLib->addInverse(label,list);
597 for(itr=pft.begin();itr!=pft.end();++itr) {
599 std::string label = itr->first;
600 Teuchos::ParameterList & list = itr->second.getValue(temp);
601 list.set(
"Type",label);
604 invLib->addInverse(label,list);
619Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
621 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary(strat));
624 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
625 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
626 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
628 Teuchos::ParameterList::ConstIterator itr;
629 Teuchos::ParameterList * temp = 0;
632 for(itr=lst.begin();itr!=lst.end();++itr) {
634 std::string label = itr->first;
635 Teuchos::ParameterList & list = itr->second.getValue(temp);
636 list.set(
"Type",label);
639 invLib->addInverse(label,list);
643 for(itr=pft.begin();itr!=pft.end();++itr) {
645 std::string label = itr->first;
646 Teuchos::ParameterList & list = itr->second.getValue(temp);
647 list.set(
"Type",label);
650 invLib->addInverse(label,list);
static Teuchos::RCP< PreconditionerFactory > buildPreconditionerFactory(const std::string &name, const Teuchos::ParameterList &settings, const Teuchos::RCP< const InverseLibrary > &invLib=Teuchos::null)
Builder function for creating preconditioner factories (yes this is a factory factory).
static void getPreconditionerFactoryNames(std::vector< std::string > &names)
Get the names of the block preconditioner factories.
virtual Teuchos::RCP< RequestHandler > getRequestHandler() const =0
Get the request handler with pointers to the appropriate callbacks.