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"
67 void addToStratimikosBuilder(
const RCP<Stratimikos::DefaultLinearSolverBuilder>& builder) {
68 typedef Thyra::PreconditionerFactoryBase<double> PrecFactory;
70 RCP<const Teuchos::ParameterList> parameters = builder->getValidParameters();
72 if (!parameters->sublist(
"Preconditioner Types").isSublist(
"Neumann Series")) {
73 RCP<const Teuchos::AbstractFactory<Thyra::PreconditionerFactoryBase<double> > > factory;
75 factory = Teuchos::abstractFactoryStd<PrecFactory,
76 Teko::NeumannSeriesPreconditionerFactory<double> >();
77 builder->setPreconditioningStrategyFactory(factory,
"Neumann Series");
81 InverseLibrary::InverseLibrary() {
82 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
84 defaultBuilder_ = Teuchos::rcp(
new Stratimikos::DefaultLinearSolverBuilder());
85 addToStratimikosBuilder(defaultBuilder_);
91 stratValidSolver_.push_back(
"Belos");
92 stratValidSolver_.push_back(
"Amesos");
93 stratValidSolver_.push_back(
"Amesos2");
94 stratValidSolver_.push_back(
"AztecOO");
97 stratValidPrecond_.push_back(
"ML");
98 stratValidPrecond_.push_back(
"Ifpack");
99 stratValidPrecond_.push_back(
"Neumann Series");
100 stratValidPrecond_.push_back(
"MueLu");
101 stratValidPrecond_.push_back(
"Ifpack2");
106 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
107 for (std::
size_t i = 0; i < blockValidPrecond_.size(); i++)
108 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
109 DEBUG_STREAM << std::endl;
113 InverseLibrary::InverseLibrary(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder>& strat)
114 : defaultBuilder_(strat) {
115 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
117 RCP<Teuchos::ParameterList> pl =
118 rcp(
new Teuchos::ParameterList(*defaultBuilder_->getValidParameters()));
119 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
120 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
122 Teuchos::ParameterList::ConstIterator itr;
125 for (itr = lst.begin(); itr != lst.end(); ++itr) stratValidSolver_.push_back(itr->first);
127 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"Stratimikos\" solvers = ";
128 for (std::
size_t i = 0; i < stratValidSolver_.size(); i++)
129 DEBUG_STREAM << stratValidSolver_[i] << ", ";
130 DEBUG_STREAM << std::endl;
134 for (itr = pft.begin(); itr != pft.end(); ++itr) stratValidPrecond_.push_back(itr->first);
136 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"Stratimikos\" preconditioners = ";
137 for (std::
size_t i = 0; i < stratValidPrecond_.size(); i++)
138 DEBUG_STREAM << stratValidPrecond_[i] << ", ";
139 DEBUG_STREAM << std::endl;
143 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
145 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
146 for (std::
size_t i = 0; i < blockValidPrecond_.size(); i++)
147 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
148 DEBUG_STREAM << std::endl;
153 void InverseLibrary::addInverse(const std::
string& label, const Teuchos::ParameterList& pl) {
155 const std::string type = pl.get<std::string>(
"Type");
158 Teuchos::ParameterList settingsList;
159 settingsList.set(type, pl);
160 settingsList.sublist(type).remove(
"Type");
163 if (std::find(stratValidPrecond_.begin(), stratValidPrecond_.end(), type) !=
164 stratValidPrecond_.end()) {
166 addStratPrecond(label, type, settingsList);
167 }
else if (std::find(stratValidSolver_.begin(), stratValidSolver_.end(), type) !=
168 stratValidSolver_.end()) {
170 addStratSolver(label, type, settingsList);
171 }
else if (std::find(blockValidPrecond_.begin(), blockValidPrecond_.end(), type) !=
172 blockValidPrecond_.end()) {
174 addBlockPrecond(label, type, settingsList);
176 Teuchos::FancyOStream& os = *Teko::getOutputStream();
177 os <<
"ERROR: Could not find inverse type \"" << type <<
"\" required by inverse name \""
178 << label <<
"\"" << std::endl;
179 TEUCHOS_ASSERT(
false);
184 void InverseLibrary::addStratSolver(
const std::string& label,
const std::string& type,
185 const Teuchos::ParameterList& pl) {
187 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
188 stratList->set(
"Linear Solver Type", type);
189 stratList->set(
"Linear Solver Types", pl);
190 stratList->set(
"Preconditioner Type",
"None");
192 stratSolver_[label] = stratList;
196 void InverseLibrary::addStratPrecond(
const std::string& label,
const std::string& type,
197 const Teuchos::ParameterList& pl) {
199 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
200 stratList->set(
"Preconditioner Type", type);
201 stratList->set(
"Preconditioner Types", pl);
203 stratPrecond_[label] = stratList;
207 void InverseLibrary::addBlockPrecond(
const std::string& label,
const std::string& type,
208 const Teuchos::ParameterList& pl) {
210 RCP<Teuchos::ParameterList> blockList = rcp(
new Teuchos::ParameterList());
211 blockList->set(
"Preconditioner Type", type);
212 blockList->set(
"Preconditioner Settings", pl.sublist(type));
215 blockPrecond_[label] = blockList;
225 Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(
226 const std::string& label)
const {
227 std::map<std::string, RCP<const Teuchos::ParameterList> >::const_iterator itr;
230 itr = stratPrecond_.find(label);
231 if (itr != stratPrecond_.end())
return itr->second;
234 itr = stratSolver_.find(label);
235 if (itr != stratSolver_.end())
return itr->second;
238 itr = blockPrecond_.find(label);
239 if (itr != blockPrecond_.end())
return itr->second;
241 return Teuchos::null;
245 Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(
const std::string& label)
const {
246 Teko_DEBUG_SCOPE(
"InverseLibrary::getInverseFactory", 10);
248 std::map<std::string, RCP<const Teuchos::ParameterList> >::const_iterator itr;
250 bool isStratSolver =
false, isStratPrecond =
false, isBlockPrecond =
false;
253 itr = stratPrecond_.find(label);
254 isStratPrecond = itr != stratPrecond_.end();
257 if (not isStratPrecond) {
258 itr = stratSolver_.find(label);
259 isStratSolver = itr != stratSolver_.end();
263 if (not(isStratSolver || isStratPrecond)) {
264 itr = blockPrecond_.find(label);
265 isBlockPrecond = itr != blockPrecond_.end();
268 Teko_DEBUG_MSG(
"Inverse \"" << label <<
"\" is of type "
269 <<
"strat prec = " << isStratPrecond <<
", "
270 <<
"strat solv = " << isStratSolver <<
", "
271 <<
"block prec = " << isBlockPrecond,
275 if (not(isStratSolver || isStratPrecond || isBlockPrecond)) {
276 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
278 *out <<
"InverseLibrary::getInverseFactory could not find \"" << label <<
"\" ... aborting\n";
279 *out <<
"Choose one of: " << std::endl;
281 *out <<
" Stratimikos preconditioners = ";
282 for (itr = stratPrecond_.begin(); itr != stratPrecond_.end(); ++itr)
283 *out <<
" \"" << itr->first <<
"\"\n";
286 *out <<
" Stratimikos solvers = ";
287 for (itr = stratSolver_.begin(); itr != stratSolver_.end(); ++itr)
288 *out <<
" \"" << itr->first <<
"\"\n";
291 *out <<
" Block preconditioners = ";
292 for (itr = blockPrecond_.begin(); itr != blockPrecond_.end(); ++itr)
293 *out <<
" \"" << itr->first <<
"\"\n";
296 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
299 RCP<const Teuchos::ParameterList> pl = itr->second;
302 if (isStratPrecond) {
304 RCP<Teuchos::ParameterList> plCopy = rcp(
new Teuchos::ParameterList(*pl));
305 std::string type = plCopy->get<std::string>(
"Preconditioner Type");
306 RCP<Teuchos::ParameterList> xtraParams;
307 if (plCopy->sublist(
"Preconditioner Types").sublist(type).isParameter(
"Required Parameters")) {
308 xtraParams = rcp(
new Teuchos::ParameterList(
309 plCopy->sublist(
"Preconditioner Types").sublist(type).sublist(
"Required Parameters")));
310 plCopy->sublist(
"Preconditioner Types").sublist(type).remove(
"Required Parameters");
314 Teko_DEBUG_MSG_BEGIN(10);
315 DEBUG_STREAM <<
"Printing parameter list: " << std::endl;
316 Teko_DEBUG_PUSHTAB();
317 plCopy->print(DEBUG_STREAM);
320 if (xtraParams != Teuchos::null) {
321 DEBUG_STREAM <<
"Printing extra parameters: " << std::endl;
322 Teko_DEBUG_PUSHTAB();
323 xtraParams->print(DEBUG_STREAM);
326 Teko_DEBUG_MSG_END();
330 defaultBuilder_->setParameterList(plCopy);
333 RCP<Thyra::PreconditionerFactoryBase<double> > precFact =
334 defaultBuilder_->createPreconditioningStrategy(type);
337 RCP<Teko::PreconditionerInverseFactory> precInvFact =
338 rcp(
new PreconditionerInverseFactory(precFact, xtraParams, getRequestHandler()));
339 precInvFact->setupParameterListFromRequestHandler();
341 }
else if (isStratSolver) {
342 RCP<Teuchos::ParameterList> solveList = rcp(
new Teuchos::ParameterList(*pl));
343 std::string type = solveList->get<std::string>(
"Linear Solver Type");
346 Teuchos::ParameterList& solveSettings = solveList->sublist(
"Linear Solver Types").sublist(type);
347 std::string precKeyWord =
"Use Preconditioner";
348 std::string precName =
"None";
349 if (solveSettings.isParameter(precKeyWord)) {
350 precName = solveSettings.get<std::string>(precKeyWord);
351 solveSettings.remove(precKeyWord);
355 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
356 if (precName !=
"None") {
358 solveList->set<std::string>(
"Preconditioner Type",
"None");
361 RCP<PreconditionerInverseFactory> precInvFactory =
362 Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
365 precFactory = precInvFactory->getPrecFactory();
370 defaultBuilder_->setParameterList(solveList);
373 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact =
374 defaultBuilder_->createLinearSolveStrategy(type);
375 if (precFactory != Teuchos::null) solveFact->setPreconditionerFactory(precFactory, precName);
378 return rcp(
new SolveInverseFactory(solveFact));
379 }
else if (isBlockPrecond) {
381 std::string type = pl->get<std::string>(
"Preconditioner Type");
382 const Teuchos::ParameterList& settings = pl->sublist(
"Preconditioner Settings");
386 type, settings, Teuchos::rcpFromRef(*
this));
388 TEUCHOS_ASSERT(precFact != Teuchos::null);
391 return rcp(
new PreconditionerInverseFactory(precFact, getRequestHandler()));
392 }
catch (std::exception& e) {
393 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
395 *out <<
"Teko: \"getInverseFactory\" failed, Parameter List =\n";
398 *out <<
"*** THROWN EXCEPTION ***\n";
399 *out << e.what() << std::endl;
400 *out <<
"************************\n";
406 TEUCHOS_ASSERT(
false);
410 void InverseLibrary::PrintAvailableInverses(std::ostream& os)
const {
411 std::map<std::string, Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
413 os <<
"Stratimikos Solvers: " << std::endl;
414 os <<
"********************************" << std::endl;
415 for (itr = stratSolver_.begin(); itr != stratSolver_.end(); ++itr) {
416 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
417 itr->second->print(os);
421 os <<
"Stratimikos Preconditioners: " << std::endl;
422 os <<
"********************************" << std::endl;
423 for (itr = stratPrecond_.begin(); itr != stratPrecond_.end(); ++itr) {
424 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
425 itr->second->print(os);
429 os <<
"Teko Preconditioners: " << std::endl;
430 os <<
"********************************" << std::endl;
431 for (itr = blockPrecond_.begin(); itr != blockPrecond_.end(); ++itr) {
432 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
433 itr->second->print(os);
447 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList& pl,
448 bool useStratDefaults) {
450 RCP<InverseLibrary> invLib;
451 if (useStratDefaults)
452 invLib = InverseLibrary::buildFromStratimikos();
454 invLib = rcp(
new InverseLibrary());
457 Teuchos::ParameterList* temp = 0;
460 Teuchos::ParameterList::ConstIterator itr;
461 for (itr = pl.begin(); itr != pl.end(); ++itr) {
463 std::string label = itr->first;
464 Teuchos::ParameterList& list = itr->second.getValue(temp);
467 invLib->addInverse(label, list);
483 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
484 const Teuchos::ParameterList& pl,
485 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder>& strat) {
487 if (strat == Teuchos::null)
return buildFromParameterList(pl,
true);
490 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
493 Teuchos::ParameterList* temp = 0;
496 Teuchos::ParameterList::ConstIterator itr;
497 for (itr = pl.begin(); itr != pl.end(); ++itr) {
499 std::string label = itr->first;
500 Teuchos::ParameterList& list = itr->second.getValue(temp);
503 invLib->addInverse(label, list);
517 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos() {
518 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
521 RCP<Stratimikos::DefaultLinearSolverBuilder> strat = invLib->defaultBuilder_;
522 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
523 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
524 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
526 Teuchos::ParameterList::ConstIterator itr;
527 Teuchos::ParameterList* temp = 0;
530 for (itr = lst.begin(); itr != lst.end(); ++itr) {
532 std::string label = itr->first;
533 Teuchos::ParameterList& list = itr->second.getValue(temp);
534 list.set(
"Type", label);
537 invLib->addInverse(label, list);
541 for (itr = pft.begin(); itr != pft.end(); ++itr) {
543 std::string label = itr->first;
544 Teuchos::ParameterList& list = itr->second.getValue(temp);
545 list.set(
"Type", label);
548 invLib->addInverse(label, list);
563 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
564 const Stratimikos::DefaultLinearSolverBuilder& strat) {
565 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
568 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat.getValidParameters()));
569 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
570 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
572 Teuchos::ParameterList::ConstIterator itr;
573 Teuchos::ParameterList* temp = 0;
576 for (itr = lst.begin(); itr != lst.end(); ++itr) {
578 std::string label = itr->first;
579 Teuchos::ParameterList& list = itr->second.getValue(temp);
580 list.set(
"Type", label);
583 invLib->addInverse(label, list);
587 for (itr = pft.begin(); itr != pft.end(); ++itr) {
589 std::string label = itr->first;
590 Teuchos::ParameterList& list = itr->second.getValue(temp);
591 list.set(
"Type", label);
594 invLib->addInverse(label, list);
609 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
610 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder>& strat) {
611 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary(strat));
614 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
615 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
616 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
618 Teuchos::ParameterList::ConstIterator itr;
619 Teuchos::ParameterList* temp = 0;
622 for (itr = lst.begin(); itr != lst.end(); ++itr) {
624 std::string label = itr->first;
625 Teuchos::ParameterList& list = itr->second.getValue(temp);
626 list.set(
"Type", label);
629 invLib->addInverse(label, list);
633 for (itr = pft.begin(); itr != pft.end(); ++itr) {
635 std::string label = itr->first;
636 Teuchos::ParameterList& list = itr->second.getValue(temp);
637 list.set(
"Type", label);
640 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).