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" 57 #ifdef HAVE_Teko_ENABLE_Ifpack2 58 #include "Thyra_Ifpack2PreconditionerFactory.hpp" 59 #include "Tpetra_CrsMatrix.hpp" 72 void addToStratimikosBuilder(
const RCP<Stratimikos::DefaultLinearSolverBuilder> & builder)
74 typedef Thyra::PreconditionerFactoryBase<double> PrecFactory;
76 RCP<const Teuchos::ParameterList> parameters = builder->getValidParameters();
78 if(!parameters->sublist(
"Preconditioner Types").isSublist(
"Neumann Series")) {
79 RCP<const Teuchos::AbstractFactory<Thyra::PreconditionerFactoryBase<double> > > factory;
81 factory = Teuchos::abstractFactoryStd<PrecFactory,Teko::NeumannSeriesPreconditionerFactory<double> >();
82 builder->setPreconditioningStrategyFactory(factory,
"Neumann Series");
84 #ifdef HAVE_Teko_ENABLE_Ifpack2 86 typedef Thyra::PreconditionerFactoryBase<ST> Base;
87 typedef Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<ST,LO,GO,NT> > Impl;
88 builder->setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, Impl>(),
"Ifpack2");
94 InverseLibrary::InverseLibrary()
96 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
98 defaultBuilder_ = Teuchos::rcp(
new Stratimikos::DefaultLinearSolverBuilder());
99 addToStratimikosBuilder(defaultBuilder_);
105 stratValidSolver_.push_back(
"Belos");
106 stratValidSolver_.push_back(
"Amesos");
107 stratValidSolver_.push_back(
"AztecOO");
110 stratValidPrecond_.push_back(
"ML");
111 stratValidPrecond_.push_back(
"Ifpack");
112 stratValidPrecond_.push_back(
"Neumann Series");
113 stratValidPrecond_.push_back(
"MueLu");
114 stratValidPrecond_.push_back(
"Ifpack2");
119 Teko_DEBUG_MSG_BEGIN(10)
120 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
121 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
122 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
123 DEBUG_STREAM << std::endl;
127 InverseLibrary::InverseLibrary(const
Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
128 : defaultBuilder_(strat)
130 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
132 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*defaultBuilder_->getValidParameters()));
133 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
134 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
136 Teuchos::ParameterList::ConstIterator itr;
139 for(itr=lst.begin();itr!=lst.end();++itr)
140 stratValidSolver_.push_back(itr->first);
142 Teko_DEBUG_MSG_BEGIN(10)
143 DEBUG_STREAM << "Loaded \"Stratimikos\" solvers = ";
144 for(std::
size_t i=0;i<stratValidSolver_.size();i++)
145 DEBUG_STREAM << stratValidSolver_[i] << ", ";
146 DEBUG_STREAM << std::endl;
150 for(itr=pft.begin();itr!=pft.end();++itr)
151 stratValidPrecond_.push_back(itr->first);
153 Teko_DEBUG_MSG_BEGIN(10)
154 DEBUG_STREAM << "Loaded \"Stratimikos\" preconditioners = ";
155 for(std::
size_t i=0;i<stratValidPrecond_.size();i++)
156 DEBUG_STREAM << stratValidPrecond_[i] << ", ";
157 DEBUG_STREAM << std::endl;
161 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
163 Teko_DEBUG_MSG_BEGIN(10)
164 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
165 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
166 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
167 DEBUG_STREAM << std::endl;
172 void InverseLibrary::addInverse(const std::
string & label,const
Teuchos::ParameterList & pl)
175 const std::string type = pl.get<std::string>(
"Type");
178 Teuchos::ParameterList settingsList;
179 settingsList.set(type,pl);
180 settingsList.sublist(type).remove(
"Type");
183 if(std::find(stratValidPrecond_.begin(),stratValidPrecond_.end(),type)!=stratValidPrecond_.end()) {
185 addStratPrecond(label,type,settingsList);
187 else if(std::find(stratValidSolver_.begin(),stratValidSolver_.end(),type)!=stratValidSolver_.end()) {
189 addStratSolver(label,type,settingsList);
191 else if(std::find(blockValidPrecond_.begin(),blockValidPrecond_.end(),type)!=blockValidPrecond_.end()) {
193 addBlockPrecond(label,type,settingsList);
196 Teuchos::FancyOStream & os = *Teko::getOutputStream();
197 os <<
"ERROR: Could not find inverse type \"" << type
198 <<
"\" required by inverse name \"" << label <<
"\"" << std::endl;
199 TEUCHOS_ASSERT(
false);
204 void InverseLibrary::addStratSolver(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
207 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
208 stratList->set(
"Linear Solver Type",type);
209 stratList->set(
"Linear Solver Types",pl);
210 stratList->set(
"Preconditioner Type",
"None");
212 stratSolver_[label] = stratList;
216 void InverseLibrary::addStratPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
219 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
220 stratList->set(
"Preconditioner Type",type);
221 stratList->set(
"Preconditioner Types",pl);
223 stratPrecond_[label] = stratList;
227 void InverseLibrary::addBlockPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
230 RCP<Teuchos::ParameterList> blockList = rcp(
new Teuchos::ParameterList());
231 blockList->set(
"Preconditioner Type",type);
232 blockList->set(
"Preconditioner Settings",pl.sublist(type));
235 blockPrecond_[label] = blockList;
245 Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(
const std::string & label)
const 247 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
250 itr = stratPrecond_.find(label);
251 if(itr!=stratPrecond_.end())
return itr->second;
254 itr = stratSolver_.find(label);
255 if(itr!=stratSolver_.end())
return itr->second;
258 itr = blockPrecond_.find(label);
259 if(itr!=blockPrecond_.end())
return itr->second;
261 return Teuchos::null;
265 Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(
const std::string & label)
const 267 Teko_DEBUG_SCOPE(
"InverseLibrary::getInverseFactory",10);
269 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
271 bool isStratSolver=
false,isStratPrecond=
false,isBlockPrecond=
false;
274 itr = stratPrecond_.find(label);
275 isStratPrecond = itr!=stratPrecond_.end();
278 if(not isStratPrecond) {
279 itr = stratSolver_.find(label);
280 isStratSolver = itr!=stratSolver_.end();
284 if(not (isStratSolver || isStratPrecond)) {
285 itr = blockPrecond_.find(label);
286 isBlockPrecond = itr!=blockPrecond_.end();
289 Teko_DEBUG_MSG(
"Inverse \"" << label <<
"\" is of type " 290 <<
"strat prec = " << isStratPrecond <<
", " 291 <<
"strat solv = " << isStratSolver <<
", " 292 <<
"block prec = " << isBlockPrecond,3);
295 if(not (isStratSolver || isStratPrecond || isBlockPrecond)) {
296 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
298 *out <<
"InverseLibrary::getInverseFactory could not find \"" << label <<
"\" ... aborting\n";
299 *out <<
"Choose one of: " << std::endl;
301 *out <<
" Stratimikos preconditioners = ";
302 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr)
303 *out <<
" \"" << itr->first <<
"\"\n";
306 *out <<
" Stratimikos solvers = ";
307 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr)
308 *out <<
" \"" << itr->first <<
"\"\n";
311 *out <<
" Block preconditioners = ";
312 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr)
313 *out <<
" \"" << itr->first <<
"\"\n";
316 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
319 RCP<const Teuchos::ParameterList> pl = itr->second;
324 RCP<Teuchos::ParameterList> plCopy = rcp(
new Teuchos::ParameterList(*pl));
325 std::string type = plCopy->get<std::string>(
"Preconditioner Type");
326 RCP<Teuchos::ParameterList> xtraParams;
327 if(plCopy->sublist(
"Preconditioner Types").sublist(type).isParameter(
"Required Parameters")) {
328 xtraParams = rcp(
new Teuchos::ParameterList(
329 plCopy->sublist(
"Preconditioner Types").sublist(type).sublist(
"Required Parameters")));
330 plCopy->sublist(
"Preconditioner Types").sublist(type).remove(
"Required Parameters");
334 Teko_DEBUG_MSG_BEGIN(10);
335 DEBUG_STREAM <<
"Printing parameter list: " << std::endl;
336 Teko_DEBUG_PUSHTAB(); plCopy->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
338 if(xtraParams!=Teuchos::null) {
339 DEBUG_STREAM <<
"Printing extra parameters: " << std::endl;
340 Teko_DEBUG_PUSHTAB(); xtraParams->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
342 Teko_DEBUG_MSG_END();
346 defaultBuilder_->setParameterList(plCopy);
349 RCP<Thyra::PreconditionerFactoryBase<double> > precFact = defaultBuilder_->createPreconditioningStrategy(type);
352 RCP<Teko::PreconditionerInverseFactory> precInvFact
353 = rcp(
new PreconditionerInverseFactory(precFact,xtraParams,getRequestHandler()));
354 precInvFact->setupParameterListFromRequestHandler();
357 else if(isStratSolver) {
358 RCP<Teuchos::ParameterList> solveList = rcp(
new Teuchos::ParameterList(*pl));
359 std::string type = solveList->get<std::string>(
"Linear Solver Type");
362 Teuchos::ParameterList & solveSettings = solveList->sublist(
"Linear Solver Types").sublist(type);
363 std::string precKeyWord =
"Use Preconditioner";
364 std::string precName =
"None";
365 if(solveSettings.isParameter(precKeyWord)) {
366 precName = solveSettings.get<std::string>(precKeyWord);
367 solveSettings.remove(precKeyWord);
371 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
372 if(precName!=
"None") {
374 solveList->set<std::string>(
"Preconditioner Type",
"None");
377 RCP<PreconditionerInverseFactory> precInvFactory
378 = Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
381 precFactory = precInvFactory->getPrecFactory();
386 defaultBuilder_->setParameterList(solveList);
389 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact = defaultBuilder_->createLinearSolveStrategy(type);
390 if(precFactory!=Teuchos::null)
391 solveFact->setPreconditionerFactory(precFactory,precName);
394 return rcp(
new SolveInverseFactory(solveFact));
396 else if(isBlockPrecond) {
398 std::string type = pl->get<std::string>(
"Preconditioner Type");
399 const Teuchos::ParameterList & settings = pl->sublist(
"Preconditioner Settings");
402 RCP<PreconditionerFactory> precFact
405 TEUCHOS_ASSERT(precFact!=Teuchos::null);
408 return rcp(
new PreconditionerInverseFactory(precFact,getRequestHandler()));
410 catch(std::exception & e) {
411 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
413 *out <<
"Teko: \"getInverseFactory\" failed, Parameter List =\n";
416 *out <<
"*** THROWN EXCEPTION ***\n";
417 *out << e.what() << std::endl;
418 *out <<
"************************\n";
424 TEUCHOS_ASSERT(
false);
428 void InverseLibrary::PrintAvailableInverses(std::ostream & os)
const 430 std::map<std::string,Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
432 os <<
"Stratimikos Solvers: " << std::endl;
433 os <<
"********************************" << std::endl;
434 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr) {
435 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
436 itr->second->print(os);
440 os <<
"Stratimikos Preconditioners: " << std::endl;
441 os <<
"********************************" << std::endl;
442 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr) {
443 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
444 itr->second->print(os);
448 os <<
"Teko Preconditioners: " << std::endl;
449 os <<
"********************************" << std::endl;
450 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr) {
451 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
452 itr->second->print(os);
466 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
bool useStratDefaults)
469 RCP<InverseLibrary> invLib;
471 invLib = InverseLibrary::buildFromStratimikos();
473 invLib = rcp(
new InverseLibrary());
476 Teuchos::ParameterList * temp = 0;
479 Teuchos::ParameterList::ConstIterator itr;
480 for(itr=pl.begin();itr!=pl.end();++itr) {
482 std::string label = itr->first;
483 Teuchos::ParameterList & list = itr->second.getValue(temp);
486 invLib->addInverse(label,list);
502 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
503 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
506 if(strat==Teuchos::null)
507 return buildFromParameterList(pl,
true);
510 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
513 Teuchos::ParameterList * temp = 0;
516 Teuchos::ParameterList::ConstIterator itr;
517 for(itr=pl.begin();itr!=pl.end();++itr) {
519 std::string label = itr->first;
520 Teuchos::ParameterList & list = itr->second.getValue(temp);
523 invLib->addInverse(label,list);
537 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos()
539 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
542 RCP<Stratimikos::DefaultLinearSolverBuilder> strat = invLib->defaultBuilder_;
543 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
544 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
545 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
547 Teuchos::ParameterList::ConstIterator itr;
548 Teuchos::ParameterList * temp = 0;
551 for(itr=lst.begin();itr!=lst.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);
562 for(itr=pft.begin();itr!=pft.end();++itr) {
564 std::string label = itr->first;
565 Teuchos::ParameterList & list = itr->second.getValue(temp);
566 list.set(
"Type",label);
569 invLib->addInverse(label,list);
584 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Stratimikos::DefaultLinearSolverBuilder & strat)
586 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
589 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat.getValidParameters()));
590 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
591 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
593 Teuchos::ParameterList::ConstIterator itr;
594 Teuchos::ParameterList * temp = 0;
597 for(itr=lst.begin();itr!=lst.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);
608 for(itr=pft.begin();itr!=pft.end();++itr) {
610 std::string label = itr->first;
611 Teuchos::ParameterList & list = itr->second.getValue(temp);
612 list.set(
"Type",label);
615 invLib->addInverse(label,list);
630 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
632 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary(strat));
635 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
636 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
637 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
639 Teuchos::ParameterList::ConstIterator itr;
640 Teuchos::ParameterList * temp = 0;
643 for(itr=lst.begin();itr!=lst.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);
654 for(itr=pft.begin();itr!=pft.end();++itr) {
656 std::string label = itr->first;
657 Teuchos::ParameterList & list = itr->second.getValue(temp);
658 list.set(
"Type",label);
661 invLib->addInverse(label,list);
static void getPreconditionerFactoryNames(std::vector< std::string > &names)
Get the names of the block preconditioner factories.
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).