Stratimikos  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Stratimikos_DefaultLinearSolverBuilder.cpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stratimikos: Thyra-based strategies for linear solvers
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 //#define THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
43 
44 #include "Stratimikos_InternalConfig.h"
45 #include "Stratimikos_DefaultLinearSolverBuilder.hpp"
46 #include "Thyra_DelayedLinearOpWithSolveFactory.hpp"
47 #include "Teuchos_AbstractFactoryStd.hpp"
48 #include "Teuchos_CommandLineProcessor.hpp"
49 #include "Teuchos_XMLParameterListHelpers.hpp"
50 #include "Teuchos_GlobalMPISession.hpp"
51 
52 #ifdef HAVE_STRATIMIKOS_AMESOS
53 # include "Thyra_AmesosLinearOpWithSolveFactory.hpp"
54 #endif
55 #ifdef HAVE_STRATIMIKOS_AMESOS2
56 # include "Thyra_Amesos2LinearOpWithSolveFactory.hpp"
57 #endif
58 #if defined(HAVE_STRATIMIKOS_EPETRAEXT) && defined(HAVE_STRATIMIKOS_AZTECOO)
59 # include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
60 #endif
61 #ifdef HAVE_STRATIMIKOS_BELOS
62 # include "Thyra_BelosLinearOpWithSolveFactory.hpp"
63 #endif
64 #ifdef HAVE_STRATIMIKOS_IFPACK
65 # include "Thyra_IfpackPreconditionerFactory.hpp"
66 #endif
67 #ifdef HAVE_STRATIMIKOS_ML
68 # include "Thyra_MLPreconditionerFactory.hpp"
69 #endif
70 
71 
72 namespace {
73 
74 
75 const std::string LinearSolverType_name = "Linear Solver Type";
76 const std::string LinearSolverTypes_name = "Linear Solver Types";
77 const std::string PreconditionerType_name = "Preconditioner Type";
78 const std::string PreconditionerTypes_name = "Preconditioner Types";
79 const std::string None_name = "None";
80 const std::string EnableDelayedSolverConstruction_name = "Enable Delayed Solver Construction";
81 const bool EnableDelayedSolverConstruction_default = false;
82 
83 
84 } // namespace
85 
86 
87 namespace Stratimikos {
88 
89 
90 // Constructors/Initializers/Accessors
91 
92 
94  const std::string &paramsXmlFileName_in
95  ,const std::string &extraParamsXmlString_in
96  ,const std::string &paramsUsedXmlOutFileName_in
97  ,const std::string &paramsXmlFileNameOption_in
98  ,const std::string &extraParamsXmlStringOption_in
99  ,const std::string &paramsUsedXmlOutFileNameOption_in
100  )
101  :paramsXmlFileName_(paramsXmlFileName_in)
102  ,extraParamsXmlString_(extraParamsXmlString_in)
103  ,paramsUsedXmlOutFileName_(paramsUsedXmlOutFileName_in)
104  ,paramsXmlFileNameOption_(paramsXmlFileNameOption_in)
105  ,extraParamsXmlStringOption_(extraParamsXmlStringOption_in)
106  ,paramsUsedXmlOutFileNameOption_(paramsUsedXmlOutFileNameOption_in)
107  ,enableDelayedSolverConstruction_(EnableDelayedSolverConstruction_default)
108 {
109  this->initializeDefaults();
110 }
111 
112 
114 {
115 #ifdef TEUCHOS_DEBUG
116  // Validate that we read the parameters correctly!
117  if (nonnull(paramList_)) {
118  paramList_->validateParameters(*this->getValidParameters());
119  }
120 #endif
121 }
122 
123 
126  &solveStrategyFactory,
127  const std::string &solveStrategyName,
128  const bool makeDefault
129  )
130 {
131  validLowsfNames_.push_back(solveStrategyName);
132  lowsfArray_.push_back(solveStrategyFactory);
133  validParamList_ = Teuchos::null;
134  if (makeDefault) {
135  setDefaultLinearSolveStrategyFactoryName(solveStrategyName);
136  }
137 }
138 
139 
141  const std::string &solveStrategyName)
142 {
143  defaultLOWSF_ = solveStrategyName;
144 }
145 
146 
149  &precStrategyFactory,
150  const std::string &precStrategyName,
151  const bool makeDefault
152  )
153 {
154  validPfNames_.push_back(precStrategyName);
155  pfArray_.push_back(precStrategyFactory);
156  validParamList_ = Teuchos::null;
157  if (makeDefault) {
159  }
160 }
161 
162 
164  const std::string &precStrategyName)
165 {
166  defaultPF_ = precStrategyName;
167 }
168 
169 
171 {
172  TEUCHOS_TEST_FOR_EXCEPT(clp==NULL);
173  clp->setOption(
174  paramsXmlFileNameOption().c_str(),&paramsXmlFileName_
175  ,"Name of an XML file containing parameters for linear solver "
176  "options to be appended first."
177  );
178  clp->setOption(
179  extraParamsXmlStringOption().c_str(),&extraParamsXmlString_
180  ,"An XML string containing linear solver parameters to be appended second."
181  );
182  clp->setOption(
183  paramsUsedXmlOutFileNameOption().c_str(),&paramsUsedXmlOutFileName_
184  ,"Name of an XML file that can be written with the parameter list after it "
185  "has been used on completion of this program."
186  );
187 }
188 
189 
191 {
192  using Teuchos::parameterList;
193  using Teuchos::ptr;
194  using Teuchos::updateParametersFromXmlFile;
195  using Teuchos::updateParametersFromXmlString;
196  using std::endl;
197 
198  if (!paramList_.get()) {
199  paramList_ = parameterList("DefaultLinearSolverBuilder");
200  }
201  if (paramsXmlFileName().length()) {
202  if (out) {
203  *out << endl << "Reading parameters from XML file \""
204  << paramsXmlFileName() << "\" ..." << endl;
205  }
206  updateParametersFromXmlFile (paramsXmlFileName (), paramList_.ptr());
207  }
208  if (extraParamsXmlString().length()) {
209  if (out) {
210  *out << endl << "Appending extra parameters from the XML string \""
211  << extraParamsXmlString() << "\" ..." << endl;
212  }
213  updateParametersFromXmlString (extraParamsXmlString (), paramList_.ptr());
214  }
215  setParameterList(paramList_);
216 }
217 
218 
220  const Thyra::LinearOpWithSolveFactoryBase<double> &/* lowsFactory */,
221  const std::string &outputXmlFileName
222  ) const
223 {
224  justInTimeInitialize();
225  const std::string xmlOutputFile =
226  ( outputXmlFileName.length() ? outputXmlFileName : paramsUsedXmlOutFileName() );
227  if (xmlOutputFile.length()) {
228  Teuchos::writeParameterListToXmlFile(*paramList_, xmlOutputFile);
229  }
230 }
231 
232 
233 std::string
235 {
236  justInTimeInitialize();
237  return lowsfValidator_->getStringValue(*paramList_, LinearSolverType_name,
238  defaultLOWSF_);
239 }
240 
241 
242 std::string
244 {
245  justInTimeInitialize();
246  return pfValidator_->getStringValue(*paramList_, PreconditionerType_name,
247  defaultPF_);
248 }
249 
250 
251 // Overridden from ParameterListAcceptor
252 
253 
255  RCP<Teuchos::ParameterList> const& paramList
256  )
257 {
258  TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
259  paramList->validateParameters(*this->getValidParameters());
260  paramList_ = paramList;
261  enableDelayedSolverConstruction_ = paramList_->get(
262  EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default );
263 }
264 
265 
268 {
269  return paramList_;
270 }
271 
272 
275 {
276  RCP<Teuchos::ParameterList> _paramList = paramList_;
277  paramList_ = Teuchos::null;
278  return _paramList;
279 }
280 
281 
284 {
285  return paramList_;
286 }
287 
288 
291 {
292  using Teuchos::rcp_implicit_cast;
294  if (is_null(validParamList_)) {
296  validParamList = Teuchos::rcp(new Teuchos::ParameterList);
297  // Linear Solver Types
298  lowsfValidator_ = Teuchos::rcp(
300  validLowsfNames_,LinearSolverType_name
301  )
302  );
303  validParamList->set(
304  LinearSolverType_name, defaultLOWSF_,
305  (std::string("Determines the type of linear solver that will be used.\n")
306  + "The parameters for each solver type are specified in the sublist \""
307  + LinearSolverTypes_name + "\"").c_str(),
308  rcp_implicit_cast<const PEV>(lowsfValidator_)
309  );
310  Teuchos::ParameterList &linearSolverTypesSL = validParamList->sublist(
311  LinearSolverTypes_name,false,
312  "Sublists for each of the linear solver types set using the parameter\n"
313  "\"" + LinearSolverType_name + "\". Note that the options for each\n"
314  "linear solver type given below will only be used if linear solvers\n"
315  "of that type are created. It is fine to list parameter sublists for\n"
316  "linear solver types that are not used."
317  );
318  for( int i = 0; i < static_cast<int>(lowsfArray_.size()); ++i ) {
319  const std::string
320  &lsname = validLowsfNames_[i];
322  lowsf = lowsfArray_[i]->create();
323  linearSolverTypesSL.sublist(lsname).setParameters(*lowsf->getValidParameters()
324  ).disableRecursiveValidation();
325  }
326  // Preconditioner Type
327  pfValidator_ = Teuchos::rcp(
329  validPfNames_, PreconditionerType_name ) );
330  validParamList->set(
331  PreconditionerType_name, defaultPF_,
332  (std::string("Determines the type of preconditioner that will be used.\n")
333  + "This option is only meaningful for linear solvers that accept preconditioner"
334  + " factory objects!\n"
335  + "The parameters for each preconditioner are specified in the sublist \""
336  + PreconditionerTypes_name + "\"").c_str(),
337  rcp_implicit_cast<const PEV>(pfValidator_)
338  );
339  Teuchos::ParameterList &precTypesSL = validParamList->sublist(
340  PreconditionerTypes_name,false,
341  "Sublists for each of the preconditioner types set using the parameter\n"
342  "\"" + PreconditionerType_name + "\". Note that the options for each\n"
343  "preconditioner type given below will only be used if preconditioners\n"
344  "of that type are created. It is fine to list parameter sublists for\n"
345  "preconditioner types that are not used."
346  );
347  for( int i = 0; i < static_cast<int>(pfArray_.size()); ++i ) {
348  const std::string
349  &pfname = validPfNames_[i+1]; // "None" is the 0th entry!
351  pf = pfArray_[i]->create();
352  precTypesSL.sublist(pfname).setParameters(*pf->getValidParameters()
353  ).disableRecursiveValidation();
354  }
355  //
356  validParamList->set(
357  EnableDelayedSolverConstruction_name, EnableDelayedSolverConstruction_default,
358  "When this option is set to true, the linear solver factory will be wrapped\n"
359  "in a delayed evaluation Decorator factory object. This results in a delay\n"
360  "in the creation of a linear solver (and the associated preconditioner) until\n"
361  "the first solve is actually performed. This helps in cases where it is not\n"
362  "known a-priori if a linear solve will be needed on a given linear operator and\n"
363  "therefore can significantly improve performance for some types of algorithms\n"
364  "such as NOX and LOCA."
365  );
366  //
367  validParamList_ = validParamList;
368  }
369  return validParamList_;
370 }
371 
372 
373 // Overridden from LinearSolverBuilderBase.
374 
375 
378  const std::string &linearSolveStrategyName
379  ) const
380 {
381  justInTimeInitialize();
382 
383  // Get the name of the linear solve strategy
384 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
385  std::cout << "\nEntering DefaultLinearSolverBuilder"
386  << "::createLinearSolveStrategy(...) ...\n";
387  std::cout << "\nlinearSolveStrategyName = \""
388  << linearSolveStrategyName << "\"\n";
389  std::cout << "\nlinearSolveStrategyName.length() = "
390  << linearSolveStrategyName.length() << "\n";
391  std::cout << "\ndefaultLOWSF_ = \"" << defaultLOWSF_ << "\"\n";
392  std::cout << "\nthis->getLinearSolveStrategyName() = \""
393  << this->getLinearSolveStrategyName() << "\"\n";
394 #endif
395  const std::string
396  lsname = ( linearSolveStrategyName.length()
397  ? linearSolveStrategyName
398  : this->getLinearSolveStrategyName() );
399 #ifdef THYRA_DEFAULT_REAL_LINEAR_SOLVER_BUILDER_DUMP
400  std::cout << "\nlsname = \"" << lsname << "\"\n";
401 #endif
402 
403  // Get the index of this linear solver strategy (this will validate!)
404  const int
405  ls_idx = lowsfValidator_->getIntegralValue(lsname, LinearSolverType_name);
406 
407  // Create the uninitialized LOWSFB object
409  lowsf = lowsfArray_[ls_idx]->create();
410 
411  // First, set the preconditioner factory and its parameters
412  if(lowsf->acceptsPreconditionerFactory()) {
413  const std::string &pfName = this->getPreconditionerStrategyName();
415  pf = this->createPreconditioningStrategy(pfName);
416  if(pf.get())
417  lowsf->setPreconditionerFactory(pf,pfName);
418  }
419 
420  // Now set the parameters for the linear solver (some of which might
421  // override some preconditioner factory parameters).
422  lowsf->setParameterList(
423  sublist(sublist(paramList_, LinearSolverTypes_name), lsname));
424  //
425  if (enableDelayedSolverConstruction_) {
426  return Teuchos::rcp(
428  );
429  }
430 
431  return lowsf;
432 
433 }
434 
435 
438  const std::string &preconditioningStrategyName
439  ) const
440 {
441  justInTimeInitialize();
442 
443  // Get the name of the preconditioning strategy
444  const std::string
445  pfname = ( preconditioningStrategyName.length()
446  ? preconditioningStrategyName
447  : this->getPreconditionerStrategyName() );
449  pf = Teuchos::null;
450 
451  // Get the index of this preconditioning strategy (this will validate!)
452  const int
453  pf_idx = pfValidator_->getIntegralValue(pfname, PreconditionerType_name);
454  if( pf_idx != 0 ) {
455  pf = pfArray_[pf_idx-1]->create(); // We offset by -1 since "None" is first!
456  pf->setParameterList(
457  sublist(sublist(paramList_, PreconditionerTypes_name), pfname));
458  }
459 
460  return pf;
461 
462 }
463 
464 
465 // private
466 
467 
468 void DefaultLinearSolverBuilder::initializeDefaults()
469 {
470 
471  using Teuchos::rcp;
472  using Teuchos::abstractFactoryStd;
473 
474  defaultLOWSF_ = "";
475  defaultPF_ = None_name;
476  validLowsfNames_.resize(0);
477  validPfNames_.resize(0);
478  validPfNames_.push_back(None_name); // This will offset everything!
479 
480  //
481  // Linear Solvers
482  //
483 
484 #ifdef HAVE_STRATIMIKOS_AMESOS2
487  Thyra::Amesos2LinearOpWithSolveFactory<double>>(),
488  "Amesos2", true
489  );
490 #endif
491 
492 #ifdef HAVE_STRATIMIKOS_BELOS
496  "Belos", true
497  );
498 #endif
499 
500 #ifdef HAVE_STRATIMIKOS_AMESOS
504  "Amesos", true
505  );
506 #endif
507 
508 #if defined(HAVE_STRATIMIKOS_EPETRAEXT) && defined(HAVE_STRATIMIKOS_AZTECOO)
512  "AztecOO", true
513  );
514 #endif
515 
516  // Note: Above, the last LOWSF object set will be the default!
517  // (unless we have only one processor, see below:)
518 
519 #ifdef HAVE_STRATIMIKOS_AMESOS
522  }
523 #endif
524 
525  //
526  // Preconditioners
527  //
528 
529 #ifdef HAVE_STRATIMIKOS_ML
531  abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>,
533  "ML", true
534  );
535 #endif
536 
537 #ifdef HAVE_STRATIMIKOS_IFPACK
539  abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>,
541  "Ifpack", true
542  );
543 #endif
544 
545  // Note: Above, the last PF object set will be the default!
546 
547 }
548 
549 
550 void DefaultLinearSolverBuilder::justInTimeInitialize() const
551 {
552  paramList_.assert_not_null();
553  if (is_null(validParamList_)) {
554  // Create the validators
555  this->getValidParameters();
556  }
557 }
558 
559 
560 
561 } // namespace Stratimikos
Concrete LinearOpWithSolveFactoryBase adapter subclass that uses Amesos direct solvers.
std::string getPreconditionerStrategyName() const
Get the name of the preconditioner strategy that will be created on the next call to this-&gt;createPrec...
void setPreconditioningStrategyFactory(const RCP< const AbstractFactory< Thyra::PreconditionerFactoryBase< double > > > &precStrategyFactory, const std::string &precStrategyName, const bool makeDefault=false)
Set a new preconditioner strategy factory object.
Concrete preconditioner factory subclass based on Ifpack.
LinearOpWithSolveFactoryBase subclass implemented in terms of AztecOO.
bool is_null(const boost::shared_ptr< T > &p)
void setupCLP(Teuchos::CommandLineProcessor *clp)
Setup the command-line processor to read in the needed data to extra the parameters from...
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void setDefaultLinearSolveStrategyFactoryName(const std::string &solveStrategyName)
Set the default linear solver factory name.
T * get() const
Concrete preconditioner factory subclass based on ML.
void setParameterList(RCP< ParameterList > const &paramList)
void readParameters(std::ostream *out)
Force the parameters to be read from a file and/or an extra XML string.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
RCP< Thyra::LinearOpWithSolveFactoryBase< double > > createLinearSolveStrategy(const std::string &linearSolveStrategyName) const
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
void writeParamsFile(const Thyra::LinearOpWithSolveFactoryBase< double > &lowsFactory, const std::string &outputXmlFileName="") const
Write the parameters list for a LinearOpWithSolveFactoryBase object to a file after the parameters ar...
std::string getLinearSolveStrategyName() const
Get the name of the linear solver strategy that will be created on the next call to this-&gt;createLinea...
void resize(size_type new_size, const value_type &x=value_type())
LinearOpWithSolveFactoryBase subclass implemented in terms of Belos.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
ParameterList & setParameters(const ParameterList &source)
bool nonnull(const boost::shared_ptr< T > &p)
void push_back(const value_type &x)
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
DefaultLinearSolverBuilder(const std::string &paramsXmlFileName="", const std::string &extraParamsXmlString="", const std::string &paramsUsedXmlOutFileName="", const std::string &paramsXmlFileNameOption="linear-solver-params-file", const std::string &extraParamsXmlStringOption="extra-linear-solver-params", const std::string &paramsUsedXmlOutFileNameOption="linear-solver-params-used-file")
Construct with default parameters.
void setLinearSolveStrategyFactory(const RCP< const AbstractFactory< Thyra::LinearOpWithSolveFactoryBase< double > > > &solveStrategyFactory, const std::string &solveStrategyName, const bool makeDefault=false)
Set a new linear solver strategy factory object.
void setDefaultPreconditioningStrategyFactoryName(const std::string &precStrategyName)
Set the default linear solver factory name.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
RCP< Thyra::PreconditionerFactoryBase< double > > createPreconditioningStrategy(const std::string &preconditioningStrategyName) const

Generated on Fri Jun 17 2022 11:27:39 for Stratimikos by doxygen 1.8.5