42#ifndef STRATIMIKOS_LINEARSOLVERBUILDER_DEF_HPP
43#define STRATIMIKOS_LINEARSOLVERBUILDER_DEF_HPP
47#include "Stratimikos_InternalConfig.h"
48#include "Thyra_DelayedLinearOpWithSolveFactory.hpp"
49#include "Teuchos_AbstractFactoryStd.hpp"
50#include "Teuchos_CommandLineProcessor.hpp"
51#include "Teuchos_XMLParameterListHelpers.hpp"
52#include "Teuchos_GlobalMPISession.hpp"
54#ifdef HAVE_STRATIMIKOS_AMESOS
55# include "Thyra_AmesosLinearOpWithSolveFactory.hpp"
57#ifdef HAVE_STRATIMIKOS_AMESOS2
58# include "Thyra_Amesos2LinearOpWithSolveFactory.hpp"
60#if defined(HAVE_STRATIMIKOS_EPETRAEXT) && defined(HAVE_STRATIMIKOS_AZTECOO)
61# include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
63#ifdef HAVE_STRATIMIKOS_BELOS
64# include "Thyra_BelosLinearOpWithSolveFactory.hpp"
66#ifdef HAVE_STRATIMIKOS_IFPACK
67# include "Thyra_IfpackPreconditionerFactory.hpp"
69#ifdef HAVE_STRATIMIKOS_IFPACK2
70# include "Thyra_Ifpack2PreconditionerFactory.hpp"
71# include "Tpetra_CrsMatrix.hpp"
73#ifdef HAVE_STRATIMIKOS_ML
74# include "Thyra_MLPreconditionerFactory.hpp"
81const std::string LinearSolverType_name =
"Linear Solver Type";
82const std::string LinearSolverTypes_name =
"Linear Solver Types";
83const std::string PreconditionerType_name =
"Preconditioner Type";
84const std::string PreconditionerTypes_name =
"Preconditioner Types";
85const std::string None_name =
"None";
86const std::string EnableDelayedSolverConstruction_name =
"Enable Delayed Solver Construction";
87const bool EnableDelayedSolverConstruction_default =
false;
93namespace Stratimikos {
101 const std::string ¶msXmlFileName_in,
102 const std::string &extraParamsXmlString_in,
103 const std::string ¶msUsedXmlOutFileName_in,
104 const std::string ¶msXmlFileNameOption_in,
105 const std::string &extraParamsXmlStringOption_in,
106 const std::string ¶msUsedXmlOutFileNameOption_in,
107 const bool &replaceDuplicateFactories_in
109 :paramsXmlFileName_(paramsXmlFileName_in)
110 ,extraParamsXmlString_(extraParamsXmlString_in)
111 ,paramsUsedXmlOutFileName_(paramsUsedXmlOutFileName_in)
112 ,paramsXmlFileNameOption_(paramsXmlFileNameOption_in)
113 ,extraParamsXmlStringOption_(extraParamsXmlStringOption_in)
114 ,paramsUsedXmlOutFileNameOption_(paramsUsedXmlOutFileNameOption_in)
115 ,replaceDuplicateFactories_(replaceDuplicateFactories_in)
116 ,enableDelayedSolverConstruction_(EnableDelayedSolverConstruction_default)
118 this->initializeDefaults();
122template<
class Scalar>
127 if (nonnull(paramList_)) {
128 paramList_->validateParameters(*this->getValidParameters());
134template<
class Scalar>
136 const RCP<
const AbstractFactory<Thyra::LinearOpWithSolveFactoryBase<Scalar> > >
137 &solveStrategyFactory,
138 const std::string &solveStrategyName,
139 const bool makeDefault
142 const int existingNameIdx =
143 this->getAndAssertExistingFactoryNameIdx(
"setLinearSolveStrategyFactory()",
144 validLowsfNames_(), solveStrategyName);
145 if (existingNameIdx >= 0) {
146 validLowsfNames_[existingNameIdx] = solveStrategyName;
147 lowsfArray_[existingNameIdx] = solveStrategyFactory;
150 validLowsfNames_.push_back(solveStrategyName);
151 lowsfArray_.push_back(solveStrategyFactory);
153 validParamList_ = Teuchos::null;
160template<
class Scalar>
162 const std::string &solveStrategyName)
164 defaultLOWSF_ = solveStrategyName;
168template<
class Scalar>
170 const RCP<
const AbstractFactory<Thyra::PreconditionerFactoryBase<Scalar>>>
171 &precStrategyFactory,
172 const std::string &precStrategyName,
173 const bool makeDefault
176 const int existingNameIdx =
177 this->getAndAssertExistingFactoryNameIdx(
"setPreconditioningStrategyFactory()",
178 validPfNames_(), precStrategyName);
179 if (existingNameIdx >= 0) {
180 validPfNames_[existingNameIdx] = precStrategyName;
181 pfArray_[existingNameIdx-1] = precStrategyFactory;
184 validPfNames_.push_back(precStrategyName);
185 pfArray_.push_back(precStrategyFactory);
187 validParamList_ = Teuchos::null;
194template<
class Scalar>
196 const std::string &precStrategyName)
198 defaultPF_ = precStrategyName;
202template<
class Scalar>
205 TEUCHOS_TEST_FOR_EXCEPT(clp==NULL);
207 paramsXmlFileNameOption().c_str(),¶msXmlFileName_
208 ,
"Name of an XML file containing parameters for linear solver "
209 "options to be appended first."
212 extraParamsXmlStringOption().c_str(),&extraParamsXmlString_
213 ,
"An XML string containing linear solver parameters to be appended second."
216 paramsUsedXmlOutFileNameOption().c_str(),¶msUsedXmlOutFileName_
217 ,
"Name of an XML file that can be written with the parameter list after it "
218 "has been used on completion of this program."
223template<
class Scalar>
226 using Teuchos::parameterList;
228 using Teuchos::updateParametersFromXmlFile;
229 using Teuchos::updateParametersFromXmlString;
232 if (!paramList_.get()) {
233 paramList_ = parameterList(
"LinearSolverBuilder");
235 if (paramsXmlFileName().length()) {
237 *out << endl <<
"Reading parameters from XML file \""
238 << paramsXmlFileName() <<
"\" ..." << endl;
240 updateParametersFromXmlFile (paramsXmlFileName (), paramList_.ptr());
242 if (extraParamsXmlString().length()) {
244 *out << endl <<
"Appending extra parameters from the XML string \""
245 << extraParamsXmlString() <<
"\" ..." << endl;
247 updateParametersFromXmlString (extraParamsXmlString (), paramList_.ptr());
253template<
class Scalar>
255 const Thyra::LinearOpWithSolveFactoryBase<Scalar> &,
256 const std::string &outputXmlFileName
259 justInTimeInitialize();
260 const std::string xmlOutputFile =
261 ( outputXmlFileName.length() ? outputXmlFileName : paramsUsedXmlOutFileName() );
262 if (xmlOutputFile.length()) {
263 Teuchos::writeParameterListToXmlFile(*paramList_, xmlOutputFile);
268template<
class Scalar>
272 justInTimeInitialize();
273 return lowsfValidator_->getStringValue(*paramList_, LinearSolverType_name,
278template<
class Scalar>
282 justInTimeInitialize();
283 return pfValidator_->getStringValue(*paramList_, PreconditionerType_name,
291template<
class Scalar>
293 RCP<Teuchos::ParameterList>
const& paramList
296 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
298 paramList_ = paramList;
299 enableDelayedSolverConstruction_ = paramList_->get(
300 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default );
304template<
class Scalar>
305RCP<Teuchos::ParameterList>
312template<
class Scalar>
313RCP<Teuchos::ParameterList>
316 RCP<Teuchos::ParameterList> _paramList = paramList_;
317 paramList_ = Teuchos::null;
322template<
class Scalar>
323RCP<const Teuchos::ParameterList>
330template<
class Scalar>
331RCP<const Teuchos::ParameterList>
334 using Teuchos::rcp_implicit_cast;
335 typedef Teuchos::ParameterEntryValidator PEV;
336 if (is_null(validParamList_)) {
337 RCP<Teuchos::ParameterList>
338 validParamList = Teuchos::rcp(
new Teuchos::ParameterList);
340 lowsfValidator_ = Teuchos::rcp(
341 new Teuchos::StringToIntegralParameterEntryValidator<int>(
342 validLowsfNames_,LinearSolverType_name
346 LinearSolverType_name, defaultLOWSF_,
347 (std::string(
"Determines the type of linear solver that will be used.\n")
348 +
"The parameters for each solver type are specified in the sublist \""
349 + LinearSolverTypes_name +
"\"").c_str(),
350 rcp_implicit_cast<const PEV>(lowsfValidator_)
352 Teuchos::ParameterList &linearSolverTypesSL = validParamList->sublist(
353 LinearSolverTypes_name,
false,
354 "Sublists for each of the linear solver types set using the parameter\n"
355 "\"" + LinearSolverType_name +
"\". Note that the options for each\n"
356 "linear solver type given below will only be used if linear solvers\n"
357 "of that type are created. It is fine to list parameter sublists for\n"
358 "linear solver types that are not used."
360 for(
int i = 0; i < static_cast<int>(lowsfArray_.size()); ++i ) {
362 &lsname = validLowsfNames_[i];
363 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
364 lowsf = lowsfArray_[i]->create();
365 linearSolverTypesSL.sublist(lsname).setParameters(*lowsf->getValidParameters()
366 ).disableRecursiveValidation();
369 pfValidator_ = Teuchos::rcp(
370 new Teuchos::StringToIntegralParameterEntryValidator<int>(
371 validPfNames_, PreconditionerType_name ) );
373 PreconditionerType_name, defaultPF_,
374 (std::string(
"Determines the type of preconditioner that will be used.\n")
375 +
"This option is only meaningful for linear solvers that accept preconditioner"
376 +
" factory objects!\n"
377 +
"The parameters for each preconditioner are specified in the sublist \""
378 + PreconditionerTypes_name +
"\"").c_str(),
379 rcp_implicit_cast<const PEV>(pfValidator_)
381 Teuchos::ParameterList &precTypesSL = validParamList->sublist(
382 PreconditionerTypes_name,
false,
383 "Sublists for each of the preconditioner types set using the parameter\n"
384 "\"" + PreconditionerType_name +
"\". Note that the options for each\n"
385 "preconditioner type given below will only be used if preconditioners\n"
386 "of that type are created. It is fine to list parameter sublists for\n"
387 "preconditioner types that are not used."
389 for(
int i = 0; i < static_cast<int>(pfArray_.size()); ++i ) {
391 &pfname = validPfNames_[i+1];
392 const RCP<Thyra::PreconditionerFactoryBase<Scalar> >
393 pf = pfArray_[i]->create();
394 precTypesSL.sublist(pfname).setParameters(*pf->getValidParameters()
395 ).disableRecursiveValidation();
399 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default,
400 "When this option is set to true, the linear solver factory will be wrapped\n"
401 "in a delayed evaluation Decorator factory object. This results in a delay\n"
402 "in the creation of a linear solver (and the associated preconditioner) until\n"
403 "the first solve is actually performed. This helps in cases where it is not\n"
404 "known a-priori if a linear solve will be needed on a given linear operator and\n"
405 "therefore can significantly improve performance for some types of algorithms\n"
406 "such as NOX and LOCA."
409 validParamList_ = validParamList;
411 return validParamList_;
418template<
class Scalar>
419RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
421 const std::string &linearSolveStrategyName
424 justInTimeInitialize();
427#ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
428 std::cout <<
"\nEntering LinearSolverBuilder"
429 <<
"::createLinearSolveStrategy(...) ...\n";
430 std::cout <<
"\nlinearSolveStrategyName = \""
431 << linearSolveStrategyName <<
"\"\n";
432 std::cout <<
"\nlinearSolveStrategyName.length() = "
433 << linearSolveStrategyName.length() <<
"\n";
434 std::cout <<
"\ndefaultLOWSF_ = \"" << defaultLOWSF_ <<
"\"\n";
435 std::cout <<
"\nthis->getLinearSolveStrategyName() = \""
439 lsname = ( linearSolveStrategyName.length()
440 ? linearSolveStrategyName
442#ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
443 std::cout <<
"\nlsname = \"" << lsname <<
"\"\n";
448 ls_idx = lowsfValidator_->getIntegralValue(lsname, LinearSolverType_name);
451 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
452 lowsf = lowsfArray_[ls_idx]->create();
455 if(lowsf->acceptsPreconditionerFactory()) {
457 RCP<Thyra::PreconditionerFactoryBase<Scalar> >
460 lowsf->setPreconditionerFactory(pf,pfName);
465 lowsf->setParameterList(
466 sublist(sublist(paramList_, LinearSolverTypes_name), lsname));
468 if (enableDelayedSolverConstruction_) {
470 new Thyra::DelayedLinearOpWithSolveFactory<Scalar>(lowsf)
479template<
class Scalar>
480RCP<Thyra::PreconditionerFactoryBase<Scalar> >
482 const std::string &preconditioningStrategyName
485 justInTimeInitialize();
489 pfname = ( preconditioningStrategyName.length()
490 ? preconditioningStrategyName
492 RCP<Thyra::PreconditionerFactoryBase<Scalar> >
497 pf_idx = pfValidator_->getIntegralValue(pfname, PreconditionerType_name);
499 pf = pfArray_[pf_idx-1]->create();
500 pf->setParameterList(
501 sublist(sublist(paramList_, PreconditionerTypes_name), pfname));
511template<
class Scalar>
512void LinearSolverBuilder<Scalar>::initializeDefaults()
516 using Teuchos::abstractFactoryStd;
519 defaultPF_ = None_name;
520 validLowsfNames_.resize(0);
521 validPfNames_.resize(0);
522 validPfNames_.push_back(None_name);
528#ifdef HAVE_STRATIMIKOS_AMESOS2
529 setLinearSolveStrategyFactory(
530 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
531 Thyra::Amesos2LinearOpWithSolveFactory<Scalar>>(),
536#ifdef HAVE_STRATIMIKOS_BELOS
537 setLinearSolveStrategyFactory(
538 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
544#ifdef HAVE_STRATIMIKOS_IFPACK2
545 setPreconditioningStrategyFactory(
546 abstractFactoryStd<Thyra::PreconditionerFactoryBase<Scalar>,
547 Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<Scalar>>>(),
558void LinearSolverBuilder<double>::initializeDefaults()
560 using Scalar = double;
562 using Teuchos::abstractFactoryStd;
565 defaultPF_ = None_name;
566 validLowsfNames_.resize(0);
567 validPfNames_.resize(0);
568 validPfNames_.push_back(None_name);
574#ifdef HAVE_STRATIMIKOS_AMESOS2
575 setLinearSolveStrategyFactory(
576 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
577 Thyra::Amesos2LinearOpWithSolveFactory<Scalar>>(),
582#ifdef HAVE_STRATIMIKOS_BELOS
583 setLinearSolveStrategyFactory(
584 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
590#ifdef HAVE_STRATIMIKOS_AMESOS
591 setLinearSolveStrategyFactory(
592 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
598#if defined(HAVE_STRATIMIKOS_EPETRAEXT) && defined(HAVE_STRATIMIKOS_AZTECOO)
599 setLinearSolveStrategyFactory(
600 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
609#ifdef HAVE_STRATIMIKOS_AMESOS
610 if (Teuchos::GlobalMPISession::getNProc() == 1) {
611 setDefaultLinearSolveStrategyFactoryName(
"Amesos");
619#ifdef HAVE_STRATIMIKOS_ML
620 setPreconditioningStrategyFactory(
621 abstractFactoryStd<Thyra::PreconditionerFactoryBase<Scalar>,
622 Thyra::MLPreconditionerFactory>(),
627#ifdef HAVE_STRATIMIKOS_IFPACK2
628 setPreconditioningStrategyFactory(
629 abstractFactoryStd<Thyra::PreconditionerFactoryBase<Scalar>,
630 Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<Scalar>>>(),
635#ifdef HAVE_STRATIMIKOS_IFPACK
636 setPreconditioningStrategyFactory(
637 abstractFactoryStd<Thyra::PreconditionerFactoryBase<Scalar>,
638 Thyra::IfpackPreconditionerFactory>(),
648template<
class Scalar>
649void LinearSolverBuilder<Scalar>::justInTimeInitialize()
const
651 paramList_.assert_not_null();
652 if (is_null(validParamList_)) {
654 this->getValidParameters();
659template<
class Scalar>
660int LinearSolverBuilder<Scalar>::getAndAssertExistingFactoryNameIdx(
661 const std::string &setFunctionName,
const Teuchos::ArrayView<std::string> namesArray,
662 const std::string &name)
const
664 const int existingNameIdx =
665 LinearSolverBuilderHelpers::existingNameIndex(namesArray, name);
666 TEUCHOS_TEST_FOR_EXCEPTION(
667 (!replaceDuplicateFactories_ && existingNameIdx >= 0), std::logic_error,
668 "ERROR: "<<setFunctionName<<
": the name='"<<name<<
"' already exists"
669 <<
" at index="<<existingNameIdx<<
"!\n"
671 <<
"TIP: To allow duplicates, change the property replaceDuplicateFactories from"
672 <<
" false to true by calling <thisObject>.replaceDuplicateFactories(true)"
673 <<
" where <thisObject> is of type Stratimikos::LinearSolverBuilder<Scalar>!");
674 return existingNameIdx;
685#define STRATIMIKOS_LINEARSOLVERBUILDER_INSTANT(SCALAR) \
687 template class LinearSolverBuilder<SCALAR >;
void setLinearSolveStrategyFactory(const RCP< const AbstractFactory< Thyra::LinearOpWithSolveFactoryBase< Scalar > > > &solveStrategyFactory, const std::string &solveStrategyName, const bool makeDefault=false)
Set a new linear solver strategy factory object.
RCP< Thyra::PreconditionerFactoryBase< Scalar > > createPreconditioningStrategy(const std::string &preconditioningStrategyName) const
RCP< const ParameterList > getParameterList() const
std::string getLinearSolveStrategyName() const
Get the name of the linear solver strategy that will be created on the next call to this->createLinea...
void setDefaultPreconditioningStrategyFactoryName(const std::string &precStrategyName)
Set the default linear solver factory name.
RCP< const ParameterList > getValidParameters() const
LinearSolverBuilder(const std::string ¶msXmlFileName="", const std::string &extraParamsXmlString="", const std::string ¶msUsedXmlOutFileName="", const std::string ¶msXmlFileNameOption="linear-solver-params-file", const std::string &extraParamsXmlStringOption="extra-linear-solver-params", const std::string ¶msUsedXmlOutFileNameOption="linear-solver-params-used-file", const bool &replaceDuplicateFactories=true)
Construct with default parameters.
RCP< Thyra::LinearOpWithSolveFactoryBase< Scalar > > createLinearSolveStrategy(const std::string &linearSolveStrategyName) const
std::string getPreconditionerStrategyName() const
Get the name of the preconditioner strategy that will be created on the next call to this->createPrec...
void setParameterList(RCP< ParameterList > const ¶mList)
void setDefaultLinearSolveStrategyFactoryName(const std::string &solveStrategyName)
Set the default linear solver factory name.
void setupCLP(Teuchos::CommandLineProcessor *clp)
Setup the command-line processor to read in the needed data to extra the parameters from.
RCP< ParameterList > getNonconstParameterList()
void readParameters(std::ostream *out)
Force the parameters to be read from a file and/or an extra XML string.
void setPreconditioningStrategyFactory(const RCP< const AbstractFactory< Thyra::PreconditionerFactoryBase< Scalar > > > &precStrategyFactory, const std::string &precStrategyName, const bool makeDefault=false)
Set a new preconditioner strategy factory object.
RCP< ParameterList > unsetParameterList()
void writeParamsFile(const Thyra::LinearOpWithSolveFactoryBase< Scalar > &lowsFactory, const std::string &outputXmlFileName="") const
Write the parameters list for a LinearOpWithSolveFactoryBase object to a file after the parameters ar...
Concrete LinearOpWithSolveFactoryBase adapter subclass that uses Amesos direct solvers.
LinearOpWithSolveFactoryBase subclass implemented in terms of AztecOO.
LinearOpWithSolveFactoryBase subclass implemented in terms of Belos.