10 #include "Teko_InverseLibrary.hpp"
12 #include "Teko_SolveInverseFactory.hpp"
13 #include "Teko_PreconditionerInverseFactory.hpp"
14 #include "Teko_BlockPreconditionerFactory.hpp"
16 #include "Teko_NeumannSeriesPreconditionerFactory.hpp"
17 #include "Teuchos_AbstractFactoryStd.hpp"
30 void addToStratimikosBuilder(
const RCP<Stratimikos::DefaultLinearSolverBuilder>& builder) {
31 typedef Thyra::PreconditionerFactoryBase<double> PrecFactory;
33 RCP<const Teuchos::ParameterList> parameters = builder->getValidParameters();
35 if (!parameters->sublist(
"Preconditioner Types").isSublist(
"Neumann Series")) {
36 RCP<const Teuchos::AbstractFactory<Thyra::PreconditionerFactoryBase<double> > > factory;
38 factory = Teuchos::abstractFactoryStd<PrecFactory,
39 Teko::NeumannSeriesPreconditionerFactory<double> >();
40 builder->setPreconditioningStrategyFactory(factory,
"Neumann Series");
44 InverseLibrary::InverseLibrary() {
45 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
47 defaultBuilder_ = Teuchos::rcp(
new Stratimikos::DefaultLinearSolverBuilder());
48 addToStratimikosBuilder(defaultBuilder_);
54 stratValidSolver_.push_back(
"Belos");
55 stratValidSolver_.push_back(
"Amesos");
56 stratValidSolver_.push_back(
"Amesos2");
57 stratValidSolver_.push_back(
"AztecOO");
60 stratValidPrecond_.push_back(
"ML");
61 stratValidPrecond_.push_back(
"Ifpack");
62 stratValidPrecond_.push_back(
"Neumann Series");
63 stratValidPrecond_.push_back(
"MueLu");
64 stratValidPrecond_.push_back(
"Ifpack2");
69 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
70 for (std::
size_t i = 0; i < blockValidPrecond_.size(); i++)
71 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
72 DEBUG_STREAM << std::endl;
76 InverseLibrary::InverseLibrary(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder>& strat)
77 : defaultBuilder_(strat) {
78 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
80 RCP<Teuchos::ParameterList> pl =
81 rcp(
new Teuchos::ParameterList(*defaultBuilder_->getValidParameters()));
82 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
83 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
85 Teuchos::ParameterList::ConstIterator itr;
88 for (itr = lst.begin(); itr != lst.end(); ++itr) stratValidSolver_.push_back(itr->first);
90 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"Stratimikos\" solvers = ";
91 for (std::
size_t i = 0; i < stratValidSolver_.size(); i++)
92 DEBUG_STREAM << stratValidSolver_[i] << ", ";
93 DEBUG_STREAM << std::endl;
97 for (itr = pft.begin(); itr != pft.end(); ++itr) stratValidPrecond_.push_back(itr->first);
99 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"Stratimikos\" preconditioners = ";
100 for (std::
size_t i = 0; i < stratValidPrecond_.size(); i++)
101 DEBUG_STREAM << stratValidPrecond_[i] << ", ";
102 DEBUG_STREAM << std::endl;
106 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
108 Teko_DEBUG_MSG_BEGIN(10) DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
109 for (std::
size_t i = 0; i < blockValidPrecond_.size(); i++)
110 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
111 DEBUG_STREAM << std::endl;
116 void InverseLibrary::addInverse(const std::
string& label, const Teuchos::ParameterList& pl) {
118 const std::string type = pl.get<std::string>(
"Type");
121 Teuchos::ParameterList settingsList;
122 settingsList.set(type, pl);
123 settingsList.sublist(type).remove(
"Type");
126 if (std::find(stratValidPrecond_.begin(), stratValidPrecond_.end(), type) !=
127 stratValidPrecond_.end()) {
129 addStratPrecond(label, type, settingsList);
130 }
else if (std::find(stratValidSolver_.begin(), stratValidSolver_.end(), type) !=
131 stratValidSolver_.end()) {
133 addStratSolver(label, type, settingsList);
134 }
else if (std::find(blockValidPrecond_.begin(), blockValidPrecond_.end(), type) !=
135 blockValidPrecond_.end()) {
137 addBlockPrecond(label, type, settingsList);
139 Teuchos::FancyOStream& os = *Teko::getOutputStream();
140 os <<
"ERROR: Could not find inverse type \"" << type <<
"\" required by inverse name \""
141 << label <<
"\"" << std::endl;
142 TEUCHOS_ASSERT(
false);
147 void InverseLibrary::addStratSolver(
const std::string& label,
const std::string& type,
148 const Teuchos::ParameterList& pl) {
150 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
151 stratList->set(
"Linear Solver Type", type);
152 stratList->set(
"Linear Solver Types", pl);
153 stratList->set(
"Preconditioner Type",
"None");
155 stratSolver_[label] = stratList;
159 void InverseLibrary::addStratPrecond(
const std::string& label,
const std::string& type,
160 const Teuchos::ParameterList& pl) {
162 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
163 stratList->set(
"Preconditioner Type", type);
164 stratList->set(
"Preconditioner Types", pl);
166 stratPrecond_[label] = stratList;
170 void InverseLibrary::addBlockPrecond(
const std::string& label,
const std::string& type,
171 const Teuchos::ParameterList& pl) {
173 RCP<Teuchos::ParameterList> blockList = rcp(
new Teuchos::ParameterList());
174 blockList->set(
"Preconditioner Type", type);
175 blockList->set(
"Preconditioner Settings", pl.sublist(type));
178 blockPrecond_[label] = blockList;
188 Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(
189 const std::string& label)
const {
190 std::map<std::string, RCP<const Teuchos::ParameterList> >::const_iterator itr;
193 itr = stratPrecond_.find(label);
194 if (itr != stratPrecond_.end())
return itr->second;
197 itr = stratSolver_.find(label);
198 if (itr != stratSolver_.end())
return itr->second;
201 itr = blockPrecond_.find(label);
202 if (itr != blockPrecond_.end())
return itr->second;
204 return Teuchos::null;
208 Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(
const std::string& label)
const {
209 Teko_DEBUG_SCOPE(
"InverseLibrary::getInverseFactory", 10);
211 std::map<std::string, RCP<const Teuchos::ParameterList> >::const_iterator itr;
213 bool isStratSolver =
false, isStratPrecond =
false, isBlockPrecond =
false;
216 itr = stratPrecond_.find(label);
217 isStratPrecond = itr != stratPrecond_.end();
220 if (not isStratPrecond) {
221 itr = stratSolver_.find(label);
222 isStratSolver = itr != stratSolver_.end();
226 if (not(isStratSolver || isStratPrecond)) {
227 itr = blockPrecond_.find(label);
228 isBlockPrecond = itr != blockPrecond_.end();
231 Teko_DEBUG_MSG(
"Inverse \"" << label <<
"\" is of type "
232 <<
"strat prec = " << isStratPrecond <<
", "
233 <<
"strat solv = " << isStratSolver <<
", "
234 <<
"block prec = " << isBlockPrecond,
238 if (not(isStratSolver || isStratPrecond || isBlockPrecond)) {
239 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
241 *out <<
"InverseLibrary::getInverseFactory could not find \"" << label <<
"\" ... aborting\n";
242 *out <<
"Choose one of: " << std::endl;
244 *out <<
" Stratimikos preconditioners = ";
245 for (itr = stratPrecond_.begin(); itr != stratPrecond_.end(); ++itr)
246 *out <<
" \"" << itr->first <<
"\"\n";
249 *out <<
" Stratimikos solvers = ";
250 for (itr = stratSolver_.begin(); itr != stratSolver_.end(); ++itr)
251 *out <<
" \"" << itr->first <<
"\"\n";
254 *out <<
" Block preconditioners = ";
255 for (itr = blockPrecond_.begin(); itr != blockPrecond_.end(); ++itr)
256 *out <<
" \"" << itr->first <<
"\"\n";
259 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
262 RCP<const Teuchos::ParameterList> pl = itr->second;
265 if (isStratPrecond) {
267 RCP<Teuchos::ParameterList> plCopy = rcp(
new Teuchos::ParameterList(*pl));
268 std::string type = plCopy->get<std::string>(
"Preconditioner Type");
269 RCP<Teuchos::ParameterList> xtraParams;
270 if (plCopy->sublist(
"Preconditioner Types").sublist(type).isParameter(
"Required Parameters")) {
271 xtraParams = rcp(
new Teuchos::ParameterList(
272 plCopy->sublist(
"Preconditioner Types").sublist(type).sublist(
"Required Parameters")));
273 plCopy->sublist(
"Preconditioner Types").sublist(type).remove(
"Required Parameters");
277 Teko_DEBUG_MSG_BEGIN(10);
278 DEBUG_STREAM <<
"Printing parameter list: " << std::endl;
279 Teko_DEBUG_PUSHTAB();
280 plCopy->print(DEBUG_STREAM);
283 if (xtraParams != Teuchos::null) {
284 DEBUG_STREAM <<
"Printing extra parameters: " << std::endl;
285 Teko_DEBUG_PUSHTAB();
286 xtraParams->print(DEBUG_STREAM);
289 Teko_DEBUG_MSG_END();
293 defaultBuilder_->setParameterList(plCopy);
296 RCP<Thyra::PreconditionerFactoryBase<double> > precFact =
297 defaultBuilder_->createPreconditioningStrategy(type);
300 RCP<Teko::PreconditionerInverseFactory> precInvFact =
301 rcp(
new PreconditionerInverseFactory(precFact, xtraParams, getRequestHandler()));
302 precInvFact->setupParameterListFromRequestHandler();
304 }
else if (isStratSolver) {
305 RCP<Teuchos::ParameterList> solveList = rcp(
new Teuchos::ParameterList(*pl));
306 std::string type = solveList->get<std::string>(
"Linear Solver Type");
309 Teuchos::ParameterList& solveSettings = solveList->sublist(
"Linear Solver Types").sublist(type);
310 std::string precKeyWord =
"Use Preconditioner";
311 std::string precName =
"None";
312 if (solveSettings.isParameter(precKeyWord)) {
313 precName = solveSettings.get<std::string>(precKeyWord);
314 solveSettings.remove(precKeyWord);
318 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
319 if (precName !=
"None") {
321 solveList->set<std::string>(
"Preconditioner Type",
"None");
324 RCP<PreconditionerInverseFactory> precInvFactory =
325 Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
328 precFactory = precInvFactory->getPrecFactory();
333 defaultBuilder_->setParameterList(solveList);
336 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact =
337 defaultBuilder_->createLinearSolveStrategy(type);
338 if (precFactory != Teuchos::null) solveFact->setPreconditionerFactory(precFactory, precName);
341 return rcp(
new SolveInverseFactory(solveFact));
342 }
else if (isBlockPrecond) {
344 std::string type = pl->get<std::string>(
"Preconditioner Type");
345 const Teuchos::ParameterList& settings = pl->sublist(
"Preconditioner Settings");
349 type, settings, Teuchos::rcpFromRef(*
this));
351 TEUCHOS_ASSERT(precFact != Teuchos::null);
354 return rcp(
new PreconditionerInverseFactory(precFact, getRequestHandler()));
355 }
catch (std::exception& e) {
356 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
358 *out <<
"Teko: \"getInverseFactory\" failed, Parameter List =\n";
361 *out <<
"*** THROWN EXCEPTION ***\n";
362 *out << e.what() << std::endl;
363 *out <<
"************************\n";
369 TEUCHOS_ASSERT(
false);
373 void InverseLibrary::PrintAvailableInverses(std::ostream& os)
const {
374 std::map<std::string, Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
376 os <<
"Stratimikos Solvers: " << std::endl;
377 os <<
"********************************" << std::endl;
378 for (itr = stratSolver_.begin(); itr != stratSolver_.end(); ++itr) {
379 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
380 itr->second->print(os);
384 os <<
"Stratimikos Preconditioners: " << std::endl;
385 os <<
"********************************" << std::endl;
386 for (itr = stratPrecond_.begin(); itr != stratPrecond_.end(); ++itr) {
387 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
388 itr->second->print(os);
392 os <<
"Teko Preconditioners: " << std::endl;
393 os <<
"********************************" << std::endl;
394 for (itr = blockPrecond_.begin(); itr != blockPrecond_.end(); ++itr) {
395 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
396 itr->second->print(os);
410 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList& pl,
411 bool useStratDefaults) {
413 RCP<InverseLibrary> invLib;
414 if (useStratDefaults)
415 invLib = InverseLibrary::buildFromStratimikos();
417 invLib = rcp(
new InverseLibrary());
420 Teuchos::ParameterList* temp = 0;
423 Teuchos::ParameterList::ConstIterator itr;
424 for (itr = pl.begin(); itr != pl.end(); ++itr) {
426 std::string label = itr->first;
427 Teuchos::ParameterList& list = itr->second.getValue(temp);
430 invLib->addInverse(label, list);
446 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
447 const Teuchos::ParameterList& pl,
448 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder>& strat) {
450 if (strat == Teuchos::null)
return buildFromParameterList(pl,
true);
453 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
456 Teuchos::ParameterList* temp = 0;
459 Teuchos::ParameterList::ConstIterator itr;
460 for (itr = pl.begin(); itr != pl.end(); ++itr) {
462 std::string label = itr->first;
463 Teuchos::ParameterList& list = itr->second.getValue(temp);
466 invLib->addInverse(label, list);
480 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos() {
481 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
484 RCP<Stratimikos::DefaultLinearSolverBuilder> strat = invLib->defaultBuilder_;
485 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
486 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
487 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
489 Teuchos::ParameterList::ConstIterator itr;
490 Teuchos::ParameterList* temp = 0;
493 for (itr = lst.begin(); itr != lst.end(); ++itr) {
495 std::string label = itr->first;
496 Teuchos::ParameterList& list = itr->second.getValue(temp);
497 list.set(
"Type", label);
500 invLib->addInverse(label, list);
504 for (itr = pft.begin(); itr != pft.end(); ++itr) {
506 std::string label = itr->first;
507 Teuchos::ParameterList& list = itr->second.getValue(temp);
508 list.set(
"Type", label);
511 invLib->addInverse(label, list);
526 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
527 const Stratimikos::DefaultLinearSolverBuilder& strat) {
528 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
531 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat.getValidParameters()));
532 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
533 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
535 Teuchos::ParameterList::ConstIterator itr;
536 Teuchos::ParameterList* temp = 0;
539 for (itr = lst.begin(); itr != lst.end(); ++itr) {
541 std::string label = itr->first;
542 Teuchos::ParameterList& list = itr->second.getValue(temp);
543 list.set(
"Type", label);
546 invLib->addInverse(label, list);
550 for (itr = pft.begin(); itr != pft.end(); ++itr) {
552 std::string label = itr->first;
553 Teuchos::ParameterList& list = itr->second.getValue(temp);
554 list.set(
"Type", label);
557 invLib->addInverse(label, list);
572 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
573 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder>& strat) {
574 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary(strat));
577 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
578 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
579 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
581 Teuchos::ParameterList::ConstIterator itr;
582 Teuchos::ParameterList* temp = 0;
585 for (itr = lst.begin(); itr != lst.end(); ++itr) {
587 std::string label = itr->first;
588 Teuchos::ParameterList& list = itr->second.getValue(temp);
589 list.set(
"Type", label);
592 invLib->addInverse(label, list);
596 for (itr = pft.begin(); itr != pft.end(); ++itr) {
598 std::string label = itr->first;
599 Teuchos::ParameterList& list = itr->second.getValue(temp);
600 list.set(
"Type", label);
603 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).