10#ifndef STRATIMIKOS_LINEARSOLVERBUILDER_DEF_HPP
11#define STRATIMIKOS_LINEARSOLVERBUILDER_DEF_HPP
15#include "Stratimikos_InternalConfig.h"
16#include "Thyra_DelayedLinearOpWithSolveFactory.hpp"
17#include "Teuchos_AbstractFactoryStd.hpp"
18#include "Teuchos_CommandLineProcessor.hpp"
19#include "Teuchos_XMLParameterListHelpers.hpp"
20#include "Teuchos_GlobalMPISession.hpp"
22#ifdef HAVE_STRATIMIKOS_AMESOS2
23# include "Thyra_Amesos2LinearOpWithSolveFactory.hpp"
25#ifdef HAVE_STRATIMIKOS_BELOS
26# include "Thyra_BelosLinearOpWithSolveFactory.hpp"
28#if defined(HAVE_STRATIMIKOS_IFPACK2) && defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS)
29# include "Thyra_Ifpack2PreconditionerFactory.hpp"
30# include "Tpetra_CrsMatrix.hpp"
37const std::string LinearSolverType_name =
"Linear Solver Type";
38const std::string LinearSolverTypes_name =
"Linear Solver Types";
39const std::string PreconditionerType_name =
"Preconditioner Type";
40const std::string PreconditionerTypes_name =
"Preconditioner Types";
41const std::string None_name =
"None";
42const std::string EnableDelayedSolverConstruction_name =
"Enable Delayed Solver Construction";
43const bool EnableDelayedSolverConstruction_default =
false;
49namespace Stratimikos {
57 const std::string ¶msXmlFileName_in,
58 const std::string &extraParamsXmlString_in,
59 const std::string ¶msUsedXmlOutFileName_in,
60 const std::string ¶msXmlFileNameOption_in,
61 const std::string &extraParamsXmlStringOption_in,
62 const std::string ¶msUsedXmlOutFileNameOption_in,
63 const bool &replaceDuplicateFactories_in
65 :paramsXmlFileName_(paramsXmlFileName_in)
66 ,extraParamsXmlString_(extraParamsXmlString_in)
67 ,paramsUsedXmlOutFileName_(paramsUsedXmlOutFileName_in)
68 ,paramsXmlFileNameOption_(paramsXmlFileNameOption_in)
69 ,extraParamsXmlStringOption_(extraParamsXmlStringOption_in)
70 ,paramsUsedXmlOutFileNameOption_(paramsUsedXmlOutFileNameOption_in)
71 ,replaceDuplicateFactories_(replaceDuplicateFactories_in)
72 ,enableDelayedSolverConstruction_(EnableDelayedSolverConstruction_default)
74 this->initializeDefaults();
83 if (nonnull(paramList_)) {
84 paramList_->validateParameters(*this->getValidParameters());
92 const RCP<
const AbstractFactory<Thyra::LinearOpWithSolveFactoryBase<Scalar> > >
93 &solveStrategyFactory,
94 const std::string &solveStrategyName,
95 const bool makeDefault
98 const int existingNameIdx =
99 this->getAndAssertExistingFactoryNameIdx(
"setLinearSolveStrategyFactory()",
100 validLowsfNames_(), solveStrategyName);
101 if (existingNameIdx >= 0) {
102 validLowsfNames_[existingNameIdx] = solveStrategyName;
103 lowsfArray_[existingNameIdx] = solveStrategyFactory;
106 validLowsfNames_.push_back(solveStrategyName);
107 lowsfArray_.push_back(solveStrategyFactory);
109 validParamList_ = Teuchos::null;
111 setDefaultLinearSolveStrategyFactoryName(solveStrategyName);
116template<
class Scalar>
118 const std::string &solveStrategyName)
120 defaultLOWSF_ = solveStrategyName;
124template<
class Scalar>
126 const RCP<
const AbstractFactory<Thyra::PreconditionerFactoryBase<Scalar>>>
127 &precStrategyFactory,
128 const std::string &precStrategyName,
129 const bool makeDefault
132 const int existingNameIdx =
133 this->getAndAssertExistingFactoryNameIdx(
"setPreconditioningStrategyFactory()",
134 validPfNames_(), precStrategyName);
135 if (existingNameIdx >= 0) {
136 validPfNames_[existingNameIdx] = precStrategyName;
137 pfArray_[existingNameIdx-1] = precStrategyFactory;
140 validPfNames_.push_back(precStrategyName);
141 pfArray_.push_back(precStrategyFactory);
143 validParamList_ = Teuchos::null;
145 setDefaultPreconditioningStrategyFactoryName(precStrategyName);
150template<
class Scalar>
152 const std::string &precStrategyName)
154 defaultPF_ = precStrategyName;
158template<
class Scalar>
161 TEUCHOS_TEST_FOR_EXCEPT(clp==NULL);
163 paramsXmlFileNameOption().c_str(),¶msXmlFileName_
164 ,
"Name of an XML file containing parameters for linear solver "
165 "options to be appended first."
168 extraParamsXmlStringOption().c_str(),&extraParamsXmlString_
169 ,
"An XML string containing linear solver parameters to be appended second."
172 paramsUsedXmlOutFileNameOption().c_str(),¶msUsedXmlOutFileName_
173 ,
"Name of an XML file that can be written with the parameter list after it "
174 "has been used on completion of this program."
179template<
class Scalar>
182 using Teuchos::parameterList;
184 using Teuchos::updateParametersFromXmlFile;
185 using Teuchos::updateParametersFromXmlString;
188 if (!paramList_.get()) {
189 paramList_ = parameterList(
"LinearSolverBuilder");
191 if (paramsXmlFileName().length()) {
193 *out << endl <<
"Reading parameters from XML file \""
194 << paramsXmlFileName() <<
"\" ..." << endl;
196 updateParametersFromXmlFile (paramsXmlFileName (), paramList_.ptr());
198 if (extraParamsXmlString().length()) {
200 *out << endl <<
"Appending extra parameters from the XML string \""
201 << extraParamsXmlString() <<
"\" ..." << endl;
203 updateParametersFromXmlString (extraParamsXmlString (), paramList_.ptr());
205 setParameterList(paramList_);
209template<
class Scalar>
211 const Thyra::LinearOpWithSolveFactoryBase<Scalar> &,
212 const std::string &outputXmlFileName
215 justInTimeInitialize();
216 const std::string xmlOutputFile =
217 ( outputXmlFileName.length() ? outputXmlFileName : paramsUsedXmlOutFileName() );
218 if (xmlOutputFile.length()) {
219 Teuchos::writeParameterListToXmlFile(*paramList_, xmlOutputFile);
224template<
class Scalar>
228 justInTimeInitialize();
229 return lowsfValidator_->getStringValue(*paramList_, LinearSolverType_name,
234template<
class Scalar>
238 justInTimeInitialize();
239 return pfValidator_->getStringValue(*paramList_, PreconditionerType_name,
247template<
class Scalar>
249 RCP<Teuchos::ParameterList>
const& paramList
252 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
253 paramList->validateParameters(*this->getValidParameters());
254 paramList_ = paramList;
255 enableDelayedSolverConstruction_ = paramList_->get(
256 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default );
260template<
class Scalar>
261RCP<Teuchos::ParameterList>
268template<
class Scalar>
269RCP<Teuchos::ParameterList>
272 RCP<Teuchos::ParameterList> _paramList = paramList_;
273 paramList_ = Teuchos::null;
278template<
class Scalar>
279RCP<const Teuchos::ParameterList>
286template<
class Scalar>
287RCP<const Teuchos::ParameterList>
290 using Teuchos::rcp_implicit_cast;
291 typedef Teuchos::ParameterEntryValidator PEV;
292 if (is_null(validParamList_)) {
293 RCP<Teuchos::ParameterList>
294 validParamList = Teuchos::rcp(
new Teuchos::ParameterList);
296 lowsfValidator_ = Teuchos::rcp(
297 new Teuchos::StringToIntegralParameterEntryValidator<int>(
298 validLowsfNames_,LinearSolverType_name
302 LinearSolverType_name, defaultLOWSF_,
303 (std::string(
"Determines the type of linear solver that will be used.\n")
304 +
"The parameters for each solver type are specified in the sublist \""
305 + LinearSolverTypes_name +
"\"").c_str(),
306 rcp_implicit_cast<const PEV>(lowsfValidator_)
308 Teuchos::ParameterList &linearSolverTypesSL = validParamList->sublist(
309 LinearSolverTypes_name,
false,
310 "Sublists for each of the linear solver types set using the parameter\n"
311 "\"" + LinearSolverType_name +
"\". Note that the options for each\n"
312 "linear solver type given below will only be used if linear solvers\n"
313 "of that type are created. It is fine to list parameter sublists for\n"
314 "linear solver types that are not used."
316 for(
int i = 0; i < static_cast<int>(lowsfArray_.size()); ++i ) {
318 &lsname = validLowsfNames_[i];
319 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
320 lowsf = lowsfArray_[i]->create();
321 linearSolverTypesSL.sublist(lsname).setParameters(*lowsf->getValidParameters()
322 ).disableRecursiveValidation();
325 pfValidator_ = Teuchos::rcp(
326 new Teuchos::StringToIntegralParameterEntryValidator<int>(
327 validPfNames_, PreconditionerType_name ) );
329 PreconditionerType_name, defaultPF_,
330 (std::string(
"Determines the type of preconditioner that will be used.\n")
331 +
"This option is only meaningful for linear solvers that accept preconditioner"
332 +
" factory objects!\n"
333 +
"The parameters for each preconditioner are specified in the sublist \""
334 + PreconditionerTypes_name +
"\"").c_str(),
335 rcp_implicit_cast<const PEV>(pfValidator_)
337 Teuchos::ParameterList &precTypesSL = validParamList->sublist(
338 PreconditionerTypes_name,
false,
339 "Sublists for each of the preconditioner types set using the parameter\n"
340 "\"" + PreconditionerType_name +
"\". Note that the options for each\n"
341 "preconditioner type given below will only be used if preconditioners\n"
342 "of that type are created. It is fine to list parameter sublists for\n"
343 "preconditioner types that are not used."
345 for(
int i = 0; i < static_cast<int>(pfArray_.size()); ++i ) {
347 &pfname = validPfNames_[i+1];
348 const RCP<Thyra::PreconditionerFactoryBase<Scalar> >
349 pf = pfArray_[i]->create();
350 precTypesSL.sublist(pfname).setParameters(*pf->getValidParameters()
351 ).disableRecursiveValidation();
355 EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default,
356 "When this option is set to true, the linear solver factory will be wrapped\n"
357 "in a delayed evaluation Decorator factory object. This results in a delay\n"
358 "in the creation of a linear solver (and the associated preconditioner) until\n"
359 "the first solve is actually performed. This helps in cases where it is not\n"
360 "known a-priori if a linear solve will be needed on a given linear operator and\n"
361 "therefore can significantly improve performance for some types of algorithms\n"
362 "such as NOX and LOCA."
365 validParamList_ = validParamList;
367 return validParamList_;
374template<
class Scalar>
375RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
377 const std::string &linearSolveStrategyName
380 justInTimeInitialize();
383#ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
384 std::cout <<
"\nEntering LinearSolverBuilder"
385 <<
"::createLinearSolveStrategy(...) ...\n";
386 std::cout <<
"\nlinearSolveStrategyName = \""
387 << linearSolveStrategyName <<
"\"\n";
388 std::cout <<
"\nlinearSolveStrategyName.length() = "
389 << linearSolveStrategyName.length() <<
"\n";
390 std::cout <<
"\ndefaultLOWSF_ = \"" << defaultLOWSF_ <<
"\"\n";
391 std::cout <<
"\nthis->getLinearSolveStrategyName() = \""
392 << this->getLinearSolveStrategyName() <<
"\"\n";
395 lsname = ( linearSolveStrategyName.length()
396 ? linearSolveStrategyName
397 : this->getLinearSolveStrategyName() );
398#ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
399 std::cout <<
"\nlsname = \"" << lsname <<
"\"\n";
404 ls_idx = lowsfValidator_->getIntegralValue(lsname, LinearSolverType_name);
407 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
408 lowsf = lowsfArray_[ls_idx]->create();
411 if(lowsf->acceptsPreconditionerFactory()) {
412 const std::string &pfName = this->getPreconditionerStrategyName();
413 RCP<Thyra::PreconditionerFactoryBase<Scalar> >
414 pf = this->createPreconditioningStrategy(pfName);
416 lowsf->setPreconditionerFactory(pf,pfName);
421 lowsf->setParameterList(
422 sublist(sublist(paramList_, LinearSolverTypes_name), lsname));
424 if (enableDelayedSolverConstruction_) {
426 new Thyra::DelayedLinearOpWithSolveFactory<Scalar>(lowsf)
435template<
class Scalar>
436RCP<Thyra::PreconditionerFactoryBase<Scalar> >
438 const std::string &preconditioningStrategyName
441 justInTimeInitialize();
445 pfname = ( preconditioningStrategyName.length()
446 ? preconditioningStrategyName
447 : this->getPreconditionerStrategyName() );
448 RCP<Thyra::PreconditionerFactoryBase<Scalar> >
453 pf_idx = pfValidator_->getIntegralValue(pfname, PreconditionerType_name);
455 pf = pfArray_[pf_idx-1]->create();
456 pf->setParameterList(
457 sublist(sublist(paramList_, PreconditionerTypes_name), pfname));
467template<
class Scalar>
472 using Teuchos::abstractFactoryStd;
475 defaultPF_ = None_name;
476 validLowsfNames_.resize(0);
477 validPfNames_.resize(0);
478 validPfNames_.push_back(None_name);
484#ifdef HAVE_STRATIMIKOS_AMESOS2
485 setLinearSolveStrategyFactory(
486 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
487 Thyra::Amesos2LinearOpWithSolveFactory<Scalar>>(),
492#ifdef HAVE_STRATIMIKOS_BELOS
493 setLinearSolveStrategyFactory(
494 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<Scalar>,
503#ifdef HAVE_STRATIMIKOS_AMESOS2
504 if (Teuchos::GlobalMPISession::getNProc() == 1) {
505 setDefaultLinearSolveStrategyFactoryName(
"Amesos2");
513#if defined(HAVE_STRATIMIKOS_IFPACK2) && defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS)
514 setPreconditioningStrategyFactory(
515 abstractFactoryStd<Thyra::PreconditionerFactoryBase<Scalar>,
516 Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<Scalar>>>(),
526template<
class Scalar>
527void LinearSolverBuilder<Scalar>::justInTimeInitialize()
const
529 paramList_.assert_not_null();
530 if (is_null(validParamList_)) {
532 this->getValidParameters();
537template<
class Scalar>
538int LinearSolverBuilder<Scalar>::getAndAssertExistingFactoryNameIdx(
539 const std::string &setFunctionName,
const Teuchos::ArrayView<std::string> namesArray,
540 const std::string &name)
const
542 const int existingNameIdx =
543 LinearSolverBuilderHelpers::existingNameIndex(namesArray, name);
544 TEUCHOS_TEST_FOR_EXCEPTION(
545 (!replaceDuplicateFactories_ && existingNameIdx >= 0), std::logic_error,
546 "ERROR: "<<setFunctionName<<
": the name='"<<name<<
"' already exists"
547 <<
" at index="<<existingNameIdx<<
"!\n"
549 <<
"TIP: To allow duplicates, change the property replaceDuplicateFactories from"
550 <<
" false to true by calling <thisObject>.replaceDuplicateFactories(true)"
551 <<
" where <thisObject> is of type Stratimikos::LinearSolverBuilder<Scalar>!");
552 return existingNameIdx;
563#define STRATIMIKOS_LINEARSOLVERBUILDER_INSTANT(SCALAR) \
565 template class LinearSolverBuilder<SCALAR >;
Concrete subclass of Thyra::LinearSolverBuilderBase for creating Thyra::LinearOpWithSolveFactoryBase ...
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...
LinearOpWithSolveFactoryBase subclass implemented in terms of Belos.