Stratimikos Version of the Day
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
72namespace {
73
74
75const std::string LinearSolverType_name = "Linear Solver Type";
76const std::string LinearSolverTypes_name = "Linear Solver Types";
77const std::string PreconditionerType_name = "Preconditioner Type";
78const std::string PreconditionerTypes_name = "Preconditioner Types";
79const std::string None_name = "None";
80const std::string EnableDelayedSolverConstruction_name = "Enable Delayed Solver Construction";
81const bool EnableDelayedSolverConstruction_default = false;
82
83
84} // namespace
85
86
87namespace 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
125 const RCP<const AbstractFactory<Thyra::LinearOpWithSolveFactoryBase<double> > >
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) {
136 }
137}
138
139
141 const std::string &solveStrategyName)
142{
143 defaultLOWSF_ = solveStrategyName;
144}
145
146
148 const RCP<const AbstractFactory<Thyra::PreconditionerFactoryBase<double> > >
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
170void DefaultLinearSolverBuilder::setupCLP( Teuchos::CommandLineProcessor *clp )
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
233std::string
235{
236 justInTimeInitialize();
237 return lowsfValidator_->getStringValue(*paramList_, LinearSolverType_name,
238 defaultLOWSF_);
239}
240
241
242std::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
266RCP<Teuchos::ParameterList>
268{
269 return paramList_;
270}
271
272
273RCP<Teuchos::ParameterList>
275{
276 RCP<Teuchos::ParameterList> _paramList = paramList_;
277 paramList_ = Teuchos::null;
278 return _paramList;
279}
280
281
282RCP<const Teuchos::ParameterList>
284{
285 return paramList_;
286}
287
288
289RCP<const Teuchos::ParameterList>
291{
292 using Teuchos::rcp_implicit_cast;
293 typedef Teuchos::ParameterEntryValidator PEV;
294 if (is_null(validParamList_)) {
295 RCP<Teuchos::ParameterList>
296 validParamList = Teuchos::rcp(new Teuchos::ParameterList);
297 // Linear Solver Types
298 lowsfValidator_ = Teuchos::rcp(
299 new Teuchos::StringToIntegralParameterEntryValidator<int>(
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];
321 const RCP<Thyra::LinearOpWithSolveFactoryBase<double> >
322 lowsf = lowsfArray_[i]->create();
323 linearSolverTypesSL.sublist(lsname).setParameters(*lowsf->getValidParameters()
324 ).disableRecursiveValidation();
325 }
326 // Preconditioner Type
327 pfValidator_ = Teuchos::rcp(
328 new Teuchos::StringToIntegralParameterEntryValidator<int>(
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!
350 const RCP<Thyra::PreconditionerFactoryBase<double> >
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
376RCP<Thyra::LinearOpWithSolveFactoryBase<double> >
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
408 RCP<Thyra::LinearOpWithSolveFactoryBase<double> >
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();
414 RCP<Thyra::PreconditionerFactoryBase<double> >
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(
427 new Thyra::DelayedLinearOpWithSolveFactory<double>(lowsf)
428 );
429 }
430
431 return lowsf;
432
433}
434
435
436RCP<Thyra::PreconditionerFactoryBase<double> >
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
448 RCP<Thyra::PreconditionerFactoryBase<double> >
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
468void 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
486 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>,
487 Thyra::Amesos2LinearOpWithSolveFactory<double>>(),
488 "Amesos2", true
489 );
490#endif
491
492#ifdef HAVE_STRATIMIKOS_BELOS
494 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>,
496 "Belos", true
497 );
498#endif
499
500#ifdef HAVE_STRATIMIKOS_AMESOS
502 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>,
504 "Amesos", true
505 );
506#endif
507
508#if defined(HAVE_STRATIMIKOS_EPETRAEXT) && defined(HAVE_STRATIMIKOS_AZTECOO)
510 abstractFactoryStd<Thyra::LinearOpWithSolveFactoryBase<double>,
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
520 if (Teuchos::GlobalMPISession::getNProc() == 1) {
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
550void 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
void setupCLP(Teuchos::CommandLineProcessor *clp)
Setup the command-line processor to read in the needed data to extra the parameters from.
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...
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.
RCP< Thyra::LinearOpWithSolveFactoryBase< double > > createLinearSolveStrategy(const std::string &linearSolveStrategyName) const
void setDefaultPreconditioningStrategyFactoryName(const std::string &precStrategyName)
Set the default linear solver factory name.
RCP< Thyra::PreconditionerFactoryBase< double > > createPreconditioningStrategy(const std::string &preconditioningStrategyName) const
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.
std::string getLinearSolveStrategyName() const
Get the name of the linear solver strategy that will be created on the next call to this->createLinea...
std::string getPreconditionerStrategyName() const
Get the name of the preconditioner strategy that will be created on the next call to this->createPrec...
void setDefaultLinearSolveStrategyFactoryName(const std::string &solveStrategyName)
Set the default linear solver factory name.
void readParameters(std::ostream *out)
Force the parameters to be read from a file and/or an extra XML string.
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 setParameterList(RCP< ParameterList > const &paramList)
Concrete LinearOpWithSolveFactoryBase adapter subclass that uses Amesos direct solvers.
LinearOpWithSolveFactoryBase subclass implemented in terms of AztecOO.
LinearOpWithSolveFactoryBase subclass implemented in terms of Belos.
Concrete preconditioner factory subclass based on Ifpack.
Concrete preconditioner factory subclass based on ML.

Generated on Fri Mar 10 2023 07:13:22 for Stratimikos by doxygen 1.9.4