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" 66 void addToStratimikosBuilder(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,Teko::NeumannSeriesPreconditionerFactory<double> >();
76 builder.setPreconditioningStrategyFactory(factory,
"Neumann Series");
80 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(
"AztecOO");
96 stratValidPrecond_.push_back(
"ML");
97 stratValidPrecond_.push_back(
"Ifpack");
98 stratValidPrecond_.push_back(
"Neumann Series");
103 Teko_DEBUG_MSG_BEGIN(10)
104 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
105 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
106 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
107 DEBUG_STREAM << std::endl;
111 InverseLibrary::InverseLibrary(const
Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
112 : defaultBuilder_(strat)
114 Teko_DEBUG_SCOPE(
"InverseLibrary::InverseLibrary", 10);
116 addToStratimikosBuilder(*defaultBuilder_);
118 RCP<Teuchos::ParameterList> pl = 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)
126 stratValidSolver_.push_back(itr->first);
128 Teko_DEBUG_MSG_BEGIN(10)
129 DEBUG_STREAM << "Loaded \"Stratimikos\" solvers = ";
130 for(std::
size_t i=0;i<stratValidSolver_.size();i++)
131 DEBUG_STREAM << stratValidSolver_[i] << ", ";
132 DEBUG_STREAM << std::endl;
136 for(itr=pft.begin();itr!=pft.end();++itr)
137 stratValidPrecond_.push_back(itr->first);
139 Teko_DEBUG_MSG_BEGIN(10)
140 DEBUG_STREAM << "Loaded \"Stratimikos\" preconditioners = ";
141 for(std::
size_t i=0;i<stratValidPrecond_.size();i++)
142 DEBUG_STREAM << stratValidPrecond_[i] << ", ";
143 DEBUG_STREAM << std::endl;
147 PreconditionerFactory::getPreconditionerFactoryNames(blockValidPrecond_);
149 Teko_DEBUG_MSG_BEGIN(10)
150 DEBUG_STREAM << "Loaded \"block\" preconditioners = ";
151 for(std::
size_t i=0;i<blockValidPrecond_.size();i++)
152 DEBUG_STREAM << blockValidPrecond_[i] << ", ";
153 DEBUG_STREAM << std::endl;
158 void InverseLibrary::addInverse(const std::
string & label,const
Teuchos::ParameterList & pl)
161 const std::string type = pl.get<std::string>(
"Type");
164 Teuchos::ParameterList settingsList;
165 settingsList.set(type,pl);
166 settingsList.sublist(type).remove(
"Type");
169 if(std::find(stratValidPrecond_.begin(),stratValidPrecond_.end(),type)!=stratValidPrecond_.end()) {
171 addStratPrecond(label,type,settingsList);
173 else if(std::find(stratValidSolver_.begin(),stratValidSolver_.end(),type)!=stratValidSolver_.end()) {
175 addStratSolver(label,type,settingsList);
177 else if(std::find(blockValidPrecond_.begin(),blockValidPrecond_.end(),type)!=blockValidPrecond_.end()) {
179 addBlockPrecond(label,type,settingsList);
182 Teuchos::FancyOStream & os = *Teko::getOutputStream();
183 os <<
"ERROR: Could not find inverse type \"" << type
184 <<
"\" required by inverse name \"" << label <<
"\"" << std::endl;
185 TEUCHOS_ASSERT(
false);
190 void InverseLibrary::addStratSolver(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
193 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
194 stratList->set(
"Linear Solver Type",type);
195 stratList->set(
"Linear Solver Types",pl);
196 stratList->set(
"Preconditioner Type",
"None");
198 stratSolver_[label] = stratList;
202 void InverseLibrary::addStratPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
205 RCP<Teuchos::ParameterList> stratList = rcp(
new Teuchos::ParameterList());
206 stratList->set(
"Preconditioner Type",type);
207 stratList->set(
"Preconditioner Types",pl);
209 stratPrecond_[label] = stratList;
213 void InverseLibrary::addBlockPrecond(
const std::string & label,
const std::string & type,
const Teuchos::ParameterList & pl)
216 RCP<Teuchos::ParameterList> blockList = rcp(
new Teuchos::ParameterList());
217 blockList->set(
"Preconditioner Type",type);
218 blockList->set(
"Preconditioner Settings",pl.sublist(type));
221 blockPrecond_[label] = blockList;
231 Teuchos::RCP<const Teuchos::ParameterList> InverseLibrary::getParameterList(
const std::string & label)
const 233 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
236 itr = stratPrecond_.find(label);
237 if(itr!=stratPrecond_.end())
return itr->second;
240 itr = stratSolver_.find(label);
241 if(itr!=stratSolver_.end())
return itr->second;
244 itr = blockPrecond_.find(label);
245 if(itr!=blockPrecond_.end())
return itr->second;
247 return Teuchos::null;
251 Teuchos::RCP<InverseFactory> InverseLibrary::getInverseFactory(
const std::string & label)
const 253 Teko_DEBUG_SCOPE(
"InverseLibrary::getInverseFactory",10);
255 std::map<std::string,RCP<const Teuchos::ParameterList> >::const_iterator itr;
257 bool isStratSolver=
false,isStratPrecond=
false,isBlockPrecond=
false;
260 itr = stratPrecond_.find(label);
261 isStratPrecond = itr!=stratPrecond_.end();
264 if(not isStratPrecond) {
265 itr = stratSolver_.find(label);
266 isStratSolver = itr!=stratSolver_.end();
270 if(not (isStratSolver || isStratPrecond)) {
271 itr = blockPrecond_.find(label);
272 isBlockPrecond = itr!=blockPrecond_.end();
275 Teko_DEBUG_MSG(
"Inverse \"" << label <<
"\" is of type " 276 <<
"strat prec = " << isStratPrecond <<
", " 277 <<
"strat solv = " << isStratSolver <<
", " 278 <<
"block prec = " << isBlockPrecond,3);
281 if(not (isStratSolver || isStratPrecond || isBlockPrecond)) {
282 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
284 *out <<
"InverseLibrary::getInverseFactory could not find \"" << label <<
"\" ... aborting\n";
285 *out <<
"Choose one of: " << std::endl;
287 *out <<
" Stratimikos preconditioners = ";
288 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr)
289 *out <<
" \"" << itr->first <<
"\"\n";
292 *out <<
" Stratimikos solvers = ";
293 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr)
294 *out <<
" \"" << itr->first <<
"\"\n";
297 *out <<
" Block preconditioners = ";
298 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr)
299 *out <<
" \"" << itr->first <<
"\"\n";
302 TEUCHOS_ASSERT(isStratSolver || isStratPrecond || isBlockPrecond);
305 RCP<const Teuchos::ParameterList> pl = itr->second;
310 RCP<Teuchos::ParameterList> plCopy = rcp(
new Teuchos::ParameterList(*pl));
311 std::string type = plCopy->get<std::string>(
"Preconditioner Type");
312 RCP<Teuchos::ParameterList> xtraParams;
313 if(plCopy->sublist(
"Preconditioner Types").sublist(type).isParameter(
"Required Parameters")) {
314 xtraParams = rcp(
new Teuchos::ParameterList(
315 plCopy->sublist(
"Preconditioner Types").sublist(type).sublist(
"Required Parameters")));
316 plCopy->sublist(
"Preconditioner Types").sublist(type).remove(
"Required Parameters");
320 Teko_DEBUG_MSG_BEGIN(10);
321 DEBUG_STREAM <<
"Printing parameter list: " << std::endl;
322 Teko_DEBUG_PUSHTAB(); plCopy->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
324 if(xtraParams!=Teuchos::null) {
325 DEBUG_STREAM <<
"Printing extra parameters: " << std::endl;
326 Teko_DEBUG_PUSHTAB(); xtraParams->print(DEBUG_STREAM); Teko_DEBUG_POPTAB();
328 Teko_DEBUG_MSG_END();
332 defaultBuilder_->setParameterList(plCopy);
335 RCP<Thyra::PreconditionerFactoryBase<double> > precFact = defaultBuilder_->createPreconditioningStrategy(type);
338 RCP<Teko::PreconditionerInverseFactory> precInvFact
339 = rcp(
new PreconditionerInverseFactory(precFact,xtraParams,getRequestHandler()));
340 precInvFact->setupParameterListFromRequestHandler();
343 else if(isStratSolver) {
344 RCP<Teuchos::ParameterList> solveList = rcp(
new Teuchos::ParameterList(*pl));
345 std::string type = solveList->get<std::string>(
"Linear Solver Type");
348 Teuchos::ParameterList & solveSettings = solveList->sublist(
"Linear Solver Types").sublist(type);
349 std::string precKeyWord =
"Use Preconditioner";
350 std::string precName =
"None";
351 if(solveSettings.isParameter(precKeyWord)) {
352 precName = solveSettings.get<std::string>(precKeyWord);
353 solveSettings.remove(precKeyWord);
357 RCP<Thyra::PreconditionerFactoryBase<double> > precFactory;
358 if(precName!=
"None") {
360 solveList->set<std::string>(
"Preconditioner Type",
"None");
363 RCP<PreconditionerInverseFactory> precInvFactory
364 = Teuchos::rcp_dynamic_cast<PreconditionerInverseFactory>(getInverseFactory(precName));
367 precFactory = precInvFactory->getPrecFactory();
372 defaultBuilder_->setParameterList(solveList);
375 RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFact = defaultBuilder_->createLinearSolveStrategy(type);
376 if(precFactory!=Teuchos::null)
377 solveFact->setPreconditionerFactory(precFactory,precName);
380 return rcp(
new SolveInverseFactory(solveFact));
382 else if(isBlockPrecond) {
384 std::string type = pl->get<std::string>(
"Preconditioner Type");
385 const Teuchos::ParameterList & settings = pl->sublist(
"Preconditioner Settings");
388 RCP<PreconditionerFactory> precFact
391 TEUCHOS_ASSERT(precFact!=Teuchos::null);
394 return rcp(
new PreconditionerInverseFactory(precFact,getRequestHandler()));
396 catch(std::exception & e) {
397 RCP<Teuchos::FancyOStream> out = Teko::getOutputStream();
399 *out <<
"Teko: \"getInverseFactory\" failed, Parameter List =\n";
402 *out <<
"*** THROWN EXCEPTION ***\n";
403 *out << e.what() << std::endl;
404 *out <<
"************************\n";
410 TEUCHOS_ASSERT(
false);
414 void InverseLibrary::PrintAvailableInverses(std::ostream & os)
const 416 std::map<std::string,Teuchos::RCP<const Teuchos::ParameterList> >::const_iterator itr;
418 os <<
"Stratimikos Solvers: " << std::endl;
419 os <<
"********************************" << std::endl;
420 for(itr=stratSolver_.begin();itr!=stratSolver_.end();++itr) {
421 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
422 itr->second->print(os);
426 os <<
"Stratimikos Preconditioners: " << std::endl;
427 os <<
"********************************" << std::endl;
428 for(itr=stratPrecond_.begin();itr!=stratPrecond_.end();++itr) {
429 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
430 itr->second->print(os);
434 os <<
"Teko Preconditioners: " << std::endl;
435 os <<
"********************************" << std::endl;
436 for(itr=blockPrecond_.begin();itr!=blockPrecond_.end();++itr) {
437 os <<
"name = \"" << itr->first <<
"\"" << std::endl;
438 itr->second->print(os);
452 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
bool useStratDefaults)
455 RCP<InverseLibrary> invLib;
457 invLib = InverseLibrary::buildFromStratimikos();
459 invLib = rcp(
new InverseLibrary());
462 Teuchos::ParameterList * temp = 0;
465 Teuchos::ParameterList::ConstIterator itr;
466 for(itr=pl.begin();itr!=pl.end();++itr) {
468 std::string label = itr->first;
469 Teuchos::ParameterList & list = itr->second.getValue(temp);
472 invLib->addInverse(label,list);
488 RCP<InverseLibrary> InverseLibrary::buildFromParameterList(
const Teuchos::ParameterList & pl,
489 const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
492 if(strat==Teuchos::null)
493 return buildFromParameterList(pl,
true);
496 RCP<InverseLibrary> invLib = InverseLibrary::buildFromStratimikos(strat);
499 Teuchos::ParameterList * temp = 0;
502 Teuchos::ParameterList::ConstIterator itr;
503 for(itr=pl.begin();itr!=pl.end();++itr) {
505 std::string label = itr->first;
506 Teuchos::ParameterList & list = itr->second.getValue(temp);
509 invLib->addInverse(label,list);
524 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Stratimikos::DefaultLinearSolverBuilder & strat)
526 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary());
529 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat.getValidParameters()));
530 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
531 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
533 Teuchos::ParameterList::ConstIterator itr;
534 Teuchos::ParameterList * temp = 0;
537 for(itr=lst.begin();itr!=lst.end();++itr) {
539 std::string label = itr->first;
540 Teuchos::ParameterList & list = itr->second.getValue(temp);
541 list.set(
"Type",label);
544 invLib->addInverse(label,list);
548 for(itr=pft.begin();itr!=pft.end();++itr) {
550 std::string label = itr->first;
551 Teuchos::ParameterList & list = itr->second.getValue(temp);
552 list.set(
"Type",label);
555 invLib->addInverse(label,list);
570 Teuchos::RCP<InverseLibrary> InverseLibrary::buildFromStratimikos(
const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & strat)
572 RCP<InverseLibrary> invLib = rcp(
new InverseLibrary(strat));
575 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList(*strat->getValidParameters()));
576 Teuchos::ParameterList lst(pl->sublist(
"Linear Solver Types"));
577 Teuchos::ParameterList pft(pl->sublist(
"Preconditioner Types"));
579 Teuchos::ParameterList::ConstIterator itr;
580 Teuchos::ParameterList * temp = 0;
583 for(itr=lst.begin();itr!=lst.end();++itr) {
585 std::string label = itr->first;
586 Teuchos::ParameterList & list = itr->second.getValue(temp);
587 list.set(
"Type",label);
590 invLib->addInverse(label,list);
594 for(itr=pft.begin();itr!=pft.end();++itr) {
596 std::string label = itr->first;
597 Teuchos::ParameterList & list = itr->second.getValue(temp);
598 list.set(
"Type",label);
601 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).