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(
"Amesos2");
108 stratValidSolver_.push_back(
"AztecOO");
111 stratValidPrecond_.push_back(
"ML");
112 stratValidPrecond_.push_back(
"Ifpack");
113 stratValidPrecond_.push_back(
"Neumann Series");
114 stratValidPrecond_.push_back(
"MueLu");
115 stratValidPrecond_.push_back(
"Ifpack2");
120 Teko_DEBUG_MSG_BEGIN(10)
121 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
122 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
123 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
124 DEBUG_STREAM << std::endl;
128 InverseLibrary::InverseLibrary(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
129 : defaultBuilder_(strat)
131 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
133 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*defaultBuilder_->getValidParameters()));
134 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
135 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
137 Teuchos::ParameterList::ConstIterator itr;
140 for(itr=lst.begin();itr!=lst.end();++itr)
141 stratValidSolver_.push_back(itr->first);
143 Teko_DEBUG_MSG_BEGIN(10)
144 DEBUG_STREAM << "Loaded \"Stratimikos\" solvers = ";
145 for(std::
size_t i=0;i<stratValidSolver_.size();i++)
146 DEBUG_STREAM << stratValidSolver_[i] << ", ";
147 DEBUG_STREAM << std::endl;
151 for(itr=pft.begin();itr!=pft.end();++itr)
152 stratValidPrecond_.push_back(itr->first);
154 Teko_DEBUG_MSG_BEGIN(10)
155 DEBUG_STREAM << "Loaded \"Stratimikos\" preconditioners = ";
156 for(std::
size_t i=0;i<stratValidPrecond_.size();i++)
157 DEBUG_STREAM << stratValidPrecond_[i] << ", ";
158 DEBUG_STREAM << std::endl;
162 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
164 Teko_DEBUG_MSG_BEGIN(10)
165 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
166 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
167 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
168 DEBUG_STREAM << std::endl;
173 void InverseLibrary::addInverse(const std::
string & label,const Teuchos::ParameterList & pl)
176 const std::string type = pl.get<std::string>(
"Type");
179 Teuchos::ParameterList settingsList;
180 settingsList.set(type,pl);
181 settingsList.sublist(type).remove(
"Type");
184 if(std::find(stratValidPrecond_.begin(),stratValidPrecond_.end(),type)!=stratValidPrecond_.end()) {
186 addStratPrecond(label,type,settingsList);
188 else if(std::find(stratValidSolver_.begin(),stratValidSolver_.end(),type)!=stratValidSolver_.end()) {
190 addStratSolver(label,type,settingsList);
192 else if(std::find(blockValidPrecond_.begin(),blockValidPrecond_.end(),type)!=blockValidPrecond_.end()) {
194 addBlockPrecond(label,type,settingsList);
197 Teuchos::FancyOStream & os = *Teko::getOutputStream();
198 os <<
"ERROR: Could not find inverse type \"" << type
199 <<
"\" required by inverse name \"" << label <<
"\"" << std::endl;
200 TEUCHOS_ASSERT(
false);
205 void InverseLibrary::addStratSolver(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
208 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
209 stratList->set(
"Linear Solver Type",type);
210 stratList->set(
"Linear Solver Types",pl);
211 stratList->set(
"Preconditioner Type",
"None");
213 stratSolver_[label] = stratList;
217 void InverseLibrary::addStratPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
220 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
221 stratList->set(
"Preconditioner Type",type);
222 stratList->set(
"Preconditioner Types",pl);
224 stratPrecond_[label] = stratList;
228 void InverseLibrary::addBlockPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
231 RCP<Teuchos::ParameterList> blockList = rcp(
new Teuchos::ParameterList());
232 blockList->set(
"Preconditioner Type",type);
233 blockList->set(
"Preconditioner Settings",pl.sublist(type));
236 blockPrecond_[label] = blockList;
246 Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(
const std::string & label)
const
248 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
251 itr = stratPrecond_.find(label);
252 if(itr!=stratPrecond_.end())
return itr->second;
255 itr = stratSolver_.find(label);
256 if(itr!=stratSolver_.end())
return itr->second;
259 itr = blockPrecond_.find(label);
260 if(itr!=blockPrecond_.end())
return itr->second;
262 return Teuchos::null;
266 Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(
const std::string & label)
const
268 Teko_DEBUG_SCOPE(
"InverseLibrary::getInverseFactory",10);
270 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
272 bool isStratSolver=
false,isStratPrecond=
false,isBlockPrecond=
false;
275 itr = stratPrecond_.find(label);
276 isStratPrecond = itr!=stratPrecond_.end();
279 if(not isStratPrecond) {
280 itr = stratSolver_.find(label);
281 isStratSolver = itr!=stratSolver_.end();
285 if(not (isStratSolver || isStratPrecond)) {
286 itr = blockPrecond_.find(label);
287 isBlockPrecond = itr!=blockPrecond_.end();
290 Teko_DEBUG_MSG(
"Inverse \"" << label <<
"\" is of type "
291 <<
"strat prec = " << isStratPrecond <<
", "
292 <<
"strat solv = " << isStratSolver <<
", "
293 <<
"block prec = " << isBlockPrecond,3);
296 if(not (isStratSolver || isStratPrecond || isBlockPrecond)) {
297 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
299 *out <<
"InverseLibrary::getInverseFactory could not find \"" << label <<
"\" ... aborting\n";
300 *out <<
"Choose one of: " << std::endl;
302 *out <<
" Stratimikos preconditioners = ";
303 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr)
304 *out <<
" \"" << itr->first <<
"\"\n";
307 *out <<
" Stratimikos solvers = ";
308 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr)
309 *out <<
" \"" << itr->first <<
"\"\n";
312 *out <<
" Block preconditioners = ";
313 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr)
314 *out <<
" \"" << itr->first <<
"\"\n";
317 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
320 RCP<const Teuchos::ParameterList> pl = itr->second;
325 RCP<Teuchos::ParameterList> plCopy = rcp(
new Teuchos::ParameterList(*pl));
326 std::string type = plCopy->get<std::string>(
"Preconditioner Type");
327 RCP<Teuchos::ParameterList> xtraParams;
328 if(plCopy->sublist(
"Preconditioner Types").sublist(type).isParameter(
"Required Parameters")) {
329 xtraParams = rcp(
new Teuchos::ParameterList(
330 plCopy->sublist(
"Preconditioner Types").sublist(type).sublist(
"Required Parameters")));
331 plCopy->sublist(
"Preconditioner Types").sublist(type).remove(
"Required Parameters");
335 Teko_DEBUG_MSG_BEGIN(10);
336 DEBUG_STREAM <<
"Printing parameter list: " << std::endl;
337 Teko_DEBUG_PUSHTAB(); plCopy->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
339 if(xtraParams!=Teuchos::null) {
340 DEBUG_STREAM <<
"Printing extra parameters: " << std::endl;
341 Teko_DEBUG_PUSHTAB(); xtraParams->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
343 Teko_DEBUG_MSG_END();
347 defaultBuilder_->setParameterList(plCopy);
350 RCP<Thyra::PreconditionerFactoryBase<double> > precFact = defaultBuilder_->createPreconditioningStrategy(type);
353 RCP<Teko::PreconditionerInverseFactory> precInvFact
354 = rcp(
new PreconditionerInverseFactory(precFact,xtraParams,getRequestHandler()));
355 precInvFact->setupParameterListFromRequestHandler();
358 else if(isStratSolver) {
359 RCP<Teuchos::ParameterList> solveList = rcp(
new Teuchos::ParameterList(*pl));
360 std::string type = solveList->get<std::string>(
"Linear Solver Type");
363 Teuchos::ParameterList & solveSettings = solveList->sublist(
"Linear Solver Types").sublist(type);
364 std::string precKeyWord =
"Use Preconditioner";
365 std::string precName =
"None";
366 if(solveSettings.isParameter(precKeyWord)) {
367 precName = solveSettings.get<std::string>(precKeyWord);
368 solveSettings.remove(precKeyWord);
372 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
373 if(precName!=
"None") {
375 solveList->set<std::string>(
"Preconditioner Type",
"None");
378 RCP<PreconditionerInverseFactory> precInvFactory
379 = Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
382 precFactory = precInvFactory->getPrecFactory();
387 defaultBuilder_->setParameterList(solveList);
390 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact = defaultBuilder_->createLinearSolveStrategy(type);
391 if(precFactory!=Teuchos::null)
392 solveFact->setPreconditionerFactory(precFactory,precName);
395 return rcp(
new SolveInverseFactory(solveFact));
397 else if(isBlockPrecond) {
399 std::string type = pl->get<std::string>(
"Preconditioner Type");
400 const Teuchos::ParameterList & settings = pl->sublist(
"Preconditioner Settings");
403 RCP<PreconditionerFactory> precFact
406 TEUCHOS_ASSERT(precFact!=Teuchos::null);
409 return rcp(
new PreconditionerInverseFactory(precFact,getRequestHandler()));
411 catch(std::exception & e) {
412 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
414 *out <<
"Teko: \"getInverseFactory\" failed, Parameter List =\n";
417 *out <<
"*** THROWN EXCEPTION ***\n";
418 *out << e.what() << std::endl;
419 *out <<
"************************\n";
425 TEUCHOS_ASSERT(
false);
429 void InverseLibrary::PrintAvailableInverses(std::ostream & os)
const
431 std::map<std::string,Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
433 os <<
"Stratimikos Solvers: " << std::endl;
434 os <<
"********************************" << std::endl;
435 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr) {
436 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
437 itr->second->print(os);
441 os <<
"Stratimikos Preconditioners: " << std::endl;
442 os <<
"********************************" << std::endl;
443 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr) {
444 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
445 itr->second->print(os);
449 os <<
"Teko Preconditioners: " << std::endl;
450 os <<
"********************************" << std::endl;
451 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr) {
452 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
453 itr->second->print(os);
467 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
bool useStratDefaults)
470 RCP<InverseLibrary> invLib;
472 invLib = InverseLibrary::buildFromStratimikos();
474 invLib = rcp(
new InverseLibrary());
477 Teuchos::ParameterList * temp = 0;
480 Teuchos::ParameterList::ConstIterator itr;
481 for(itr=pl.begin();itr!=pl.end();++itr) {
483 std::string label = itr->first;
484 Teuchos::ParameterList & list = itr->second.getValue(temp);
487 invLib->addInverse(label,list);
503 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
504 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
507 if(strat==Teuchos::null)
508 return buildFromParameterList(pl,
true);
511 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
514 Teuchos::ParameterList * temp = 0;
517 Teuchos::ParameterList::ConstIterator itr;
518 for(itr=pl.begin();itr!=pl.end();++itr) {
520 std::string label = itr->first;
521 Teuchos::ParameterList & list = itr->second.getValue(temp);
524 invLib->addInverse(label,list);
538 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos()
540 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
543 RCP<Stratimikos::DefaultLinearSolverBuilder> strat = invLib->defaultBuilder_;
544 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
545 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
546 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
548 Teuchos::ParameterList::ConstIterator itr;
549 Teuchos::ParameterList * temp = 0;
552 for(itr=lst.begin();itr!=lst.end();++itr) {
554 std::string label = itr->first;
555 Teuchos::ParameterList & list = itr->second.getValue(temp);
556 list.set(
"Type",label);
559 invLib->addInverse(label,list);
563 for(itr=pft.begin();itr!=pft.end();++itr) {
565 std::string label = itr->first;
566 Teuchos::ParameterList & list = itr->second.getValue(temp);
567 list.set(
"Type",label);
570 invLib->addInverse(label,list);
585 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Stratimikos::DefaultLinearSolverBuilder & strat)
587 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
590 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat.getValidParameters()));
591 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
592 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
594 Teuchos::ParameterList::ConstIterator itr;
595 Teuchos::ParameterList * temp = 0;
598 for(itr=lst.begin();itr!=lst.end();++itr) {
600 std::string label = itr->first;
601 Teuchos::ParameterList & list = itr->second.getValue(temp);
602 list.set(
"Type",label);
605 invLib->addInverse(label,list);
609 for(itr=pft.begin();itr!=pft.end();++itr) {
611 std::string label = itr->first;
612 Teuchos::ParameterList & list = itr->second.getValue(temp);
613 list.set(
"Type",label);
616 invLib->addInverse(label,list);
631 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
633 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary(strat));
636 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
637 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
638 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
640 Teuchos::ParameterList::ConstIterator itr;
641 Teuchos::ParameterList * temp = 0;
644 for(itr=lst.begin();itr!=lst.end();++itr) {
646 std::string label = itr->first;
647 Teuchos::ParameterList & list = itr->second.getValue(temp);
648 list.set(
"Type",label);
651 invLib->addInverse(label,list);
655 for(itr=pft.begin();itr!=pft.end();++itr) {
657 std::string label = itr->first;
658 Teuchos::ParameterList & list = itr->second.getValue(temp);
659 list.set(
"Type",label);
662 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).