Teko Version of the Day
Loading...
Searching...
No Matches
Teko_PreconditionerFactory.cpp
1// @HEADER
2// *****************************************************************************
3// Teko: A package for block and physics based preconditioning
4//
5// Copyright 2010 NTESS and the Teko contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Teko_Config.h"
11#include "Teko_PreconditionerFactory.hpp"
12
13#include "Teko_InverseLibrary.hpp"
14#include "Teko_Preconditioner.hpp"
15
16// Specific preconditioners included for dynamic creation
17#include "Teko_JacobiPreconditionerFactory.hpp"
18#include "Teko_GaussSeidelPreconditionerFactory.hpp"
19#include "Teko_HierarchicalGaussSeidelPreconditionerFactory.hpp"
20#include "Teko_AddPreconditionerFactory.hpp"
21#include "Teko_MultPreconditionerFactory.hpp"
22#include "Teko_LU2x2PreconditionerFactory.hpp"
23#include "Teko_IterativePreconditionerFactory.hpp"
24#include "Teko_DiagnosticPreconditionerFactory.hpp"
25#include "Teko_DiagonallyScaledPreconditionerFactory.hpp"
26#include "Teko_DiagonalPreconditionerFactory.hpp"
27#include "Teko_AdaptivePreconditionerFactory.hpp"
28#ifdef TEKO_HAVE_EPETRA
29#include "Teko_ProbingPreconditionerFactory.hpp"
30#endif
31#include "Teko_IdentityPreconditionerFactory.hpp"
32#include "NS/Teko_LSCPreconditionerFactory.hpp"
33#include "NS/Teko_SIMPLEPreconditionerFactory.hpp"
34#include "NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp"
35
36#ifdef Teko_ENABLE_ML_SMOOTHERS
37#include "Teko_SmootherPreconditionerFactory.hpp"
38#include "Teko_MLPreconditionerFactory.hpp"
39#endif
40
41#include "Thyra_DefaultPreconditioner.hpp"
42
43using namespace Thyra;
44using Teuchos::RCP;
45
46namespace Teko {
48
50bool PreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &fwdOpSrc) const {
51 RCP<const Thyra::LinearOpBase<double> > A = fwdOpSrc.getOp();
52 return A != Teuchos::null;
53}
54
56RCP<Thyra::PreconditionerBase<double> > PreconditionerFactory::createPrec() const {
57 // build a preconditioner, give it some inital state
58 RCP<Preconditioner> bp = rcp(new Preconditioner());
59 bp->setStateObject(buildPreconditionerState());
60 bp->getStateObject()->setInitialized(false);
61
62 return bp;
63}
64
66void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > &ASrc,
67 PreconditionerBase<double> *prec,
68 const ESupportSolveUse /* supportSolveUse */) const {
69 // get the blocked linear operator
70 LinearOp A = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(ASrc->getOp());
71
72 Preconditioner *blkPrec = dynamic_cast<Preconditioner *>(prec);
73 TEUCHOS_ASSERT(blkPrec != 0);
74
75 // grab the state object
76 RCP<PreconditionerState> state = blkPrec->getStateObject();
77 state->setInitialized(false);
78
79 // build the preconditioner
80 const RCP<const LinearOpBase<double> > M = buildPreconditionerOperator(A, *state);
81
82 // set the request handler for the
83 setOpRequestHandler(*this, M);
84
85 // must first cast that to be initialized
86 DefaultPreconditioner<double> &dPrec = Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
87 dPrec.initializeUnspecified(Teuchos::rcp_const_cast<LinearOpBase<double> >(M));
88}
89
92 const RCP<const LinearOpSourceBase<double> > &ASrc,
93 const RCP<const Thyra::MultiVectorBase<double> > &solnVec, PreconditionerBase<double> *prec,
94 const ESupportSolveUse supportSolveUse) const {
95 Preconditioner *blkPrec = dynamic_cast<Preconditioner *>(prec);
96 blkPrec->setSourceVector(Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(solnVec));
97
98 initializePrec(ASrc, prec, supportSolveUse);
99}
100
103 PreconditionerBase<double> * /* prec */,
104 RCP<const LinearOpSourceBase<double> > * /* fwdOpSrc */,
105 ESupportSolveUse * /* supportSolveUse */) const {
106 // Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
107
108 // what do I do here?
109 TEUCHOS_TEST_FOR_EXCEPT_MSG(true, "\"PreconditionerFactory::uninitializePrec not implemented\"");
110}
111
112// for ParameterListAcceptor
114
116void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> &paramList) {
117 paramList_ = paramList;
118}
119
121RCP<Teuchos::ParameterList> PreconditionerFactory::getNonconstParameterList() { return paramList_; }
122
124RCP<Teuchos::ParameterList> PreconditionerFactory::unsetParameterList() {
125 RCP<Teuchos::ParameterList> _paramList = paramList_;
126 paramList_ = Teuchos::null;
127 return _paramList;
128}
129
131void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> &il) {
132 inverseLibrary_ = il;
133}
134
136RCP<const InverseLibrary> PreconditionerFactory::getInverseLibrary() const {
137 // lazily build the inverse library only when needed
138 if (inverseLibrary_ == Teuchos::null) return InverseLibrary::buildFromStratimikos();
139
140 return inverseLibrary_;
141}
142
144// Static members and methods
146
148void PreconditionerFactory::setOpRequestHandler(const RequestHandlerContainer &rhc,
149 const LinearOp &op) {
150 ModifiableLinearOp mlo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(op);
151
152 // conditionally set the request handler
153 RCP<RequestHandlerContainer> reqHandCont =
154 Teuchos::rcp_dynamic_cast<RequestHandlerContainer>(mlo);
155 if (reqHandCont != Teuchos::null) {
156 reqHandCont->setRequestHandler(rhc.getRequestHandler());
157 } else {
158 // is null
159 }
160}
161
163CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_;
164
180 const std::string &name, const Teuchos::ParameterList &settings,
181 const RCP<const InverseLibrary> &invLib) {
182 Teko_DEBUG_SCOPE("PreconditionerFactory::buildPreconditionerFactory", 10);
183
184 // initialize the defaults if necessary
185 if (precFactoryBuilder_.cloneCount() == 0) initializePrecFactoryBuilder();
186
187 // request the preconditioner factory from the CloneFactory
188 RCP<PreconditionerFactory> precFact = precFactoryBuilder_.build(name);
189
190 Teko_DEBUG_MSG_BEGIN(5);
191 DEBUG_STREAM << "Looked up \"" << name << "\"" << std::endl;
192 DEBUG_STREAM << "Built " << precFact << std::endl;
193 Teko_DEBUG_MSG_END();
194
195 if (precFact == Teuchos::null) return Teuchos::null;
196
197 // add in the inverse library
198 if (invLib != Teuchos::null) {
199 precFact->setInverseLibrary(invLib);
200 precFact->setRequestHandler(invLib->getRequestHandler());
201 }
202
203 // now that inverse library has been set,
204 // pass in the parameter list
205 precFact->initializeFromParameterList(settings);
206
207 return precFact;
208}
209
224 const RCP<Cloneable> &clone) {
225 // initialize the defaults if necessary
226 if (precFactoryBuilder_.cloneCount() == 0) initializePrecFactoryBuilder();
227
228 // add clone to builder
229 precFactoryBuilder_.addClone(name, clone);
230}
231
233void PreconditionerFactory::initializePrecFactoryBuilder() {
234 RCP<Cloneable> clone;
235
236 // add various preconditioners to factory
237 clone = rcp(new AutoClone<LU2x2PreconditionerFactory>());
238 precFactoryBuilder_.addClone("Block LU2x2", clone);
239
241 precFactoryBuilder_.addClone("Block Jacobi", clone);
242
244 precFactoryBuilder_.addClone("Block Gauss-Seidel", clone);
245
247 precFactoryBuilder_.addClone("Hierarchical Block Gauss-Seidel", clone);
248
249 clone = rcp(new AutoClone<AddPreconditionerFactory>());
250 precFactoryBuilder_.addClone("Block Add", clone);
251
252 clone = rcp(new AutoClone<MultPreconditionerFactory>());
253 precFactoryBuilder_.addClone("Block Multiply", clone);
254
256 precFactoryBuilder_.addClone("NS LSC", clone);
257
259 precFactoryBuilder_.addClone("NS SIMPLE", clone);
260
262 precFactoryBuilder_.addClone("NS SIMPLE-Timed", clone);
263
265 precFactoryBuilder_.addClone("Iterative Preconditioner", clone);
266
268 precFactoryBuilder_.addClone("Explicit Diagonal Preconditioner", clone);
269
271 precFactoryBuilder_.addClone("Diagnostic Inverse", clone);
272
274 precFactoryBuilder_.addClone("Diagonal Scaling", clone);
275
277 precFactoryBuilder_.addClone("Identity", clone);
278
280 precFactoryBuilder_.addClone("Adaptive", clone);
281
282#if defined(Teko_ENABLE_Isorropia) && defined(TEKO_HAVE_EPETRA)
284 precFactoryBuilder_.addClone("Probing Preconditioner", clone);
285#endif
286
287#ifdef Teko_ENABLE_ML_SMOOTHERS
288 clone = rcp(new AutoClone<MLPreconditionerFactory>());
289 precFactoryBuilder_.addClone("Blocked ML Preconditioner", clone);
290#endif
291}
292
293void PreconditionerFactory::getPreconditionerFactoryNames(std::vector<std::string> &names) {
294 // initialize the defaults if necessary
295 if (precFactoryBuilder_.cloneCount() == 0) initializePrecFactoryBuilder();
296 precFactoryBuilder_.getCloneNames(names);
297}
298
299} // end namespace Teko
void initializePrec(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOpSrc, const Teuchos::RCP< const Thyra::MultiVectorBase< double > > &solnVec, Thyra::PreconditionerBase< double > *precOp, const Thyra::ESupportSolveUse supportSolveUse) const
initialize a newly created preconditioner object
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Get the parameter list that was set using setParameterList().
void setInverseLibrary(const Teuchos::RCP< const InverseLibrary > &il)
Set the inverse library used by this preconditioner factory.
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).
Teuchos::RCP< Thyra::PreconditionerBase< double > > createPrec() const
create an instance of the preconditioner
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
Set parameters from a parameter list and return with default values.
Teuchos::RCP< Teuchos::ParameterList > paramList_
for ParameterListAcceptor
static void addPreconditionerFactory(const std::string &name, const Teuchos::RCP< Cloneable > &clone)
Add a preconditioner factory to the builder. This is done using the clone pattern.
virtual LinearOp buildPreconditionerOperator(LinearOp &lo, PreconditionerState &state) const =0
Function that is called to build the preconditioner for the linear operator that is passed in.
void uninitializePrec(Thyra::PreconditionerBase< double > *prec, Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > *fwdOpSrc, Thyra::ESupportSolveUse *supportSolveUse) const
wipe clean a already initialized preconditioner object
bool isCompatible(const Thyra::LinearOpSourceBase< double > &fwdOpSrc) const
is this operator compatiable with the preconditioner factory?
static void getPreconditionerFactoryNames(std::vector< std::string > &names)
Get the names of the block preconditioner factories.
virtual Teuchos::RCP< PreconditionerState > buildPreconditionerState() const
Function that permits the construction of an arbitrary PreconditionerState object.
Teuchos::RCP< const InverseLibrary > getInverseLibrary() const
Get the inverse library used by this preconditioner factory.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Unset the parameter list that was set using setParameterList().
An extension of the Thyra::DefaultPreconditioner class with some specializations useful for use withi...
virtual void setSourceVector(const RCP< Thyra::MultiVectorBase< double > > &srcVec)
virtual const RCP< PreconditionerState > getStateObject()
virtual Teuchos::RCP< RequestHandler > getRequestHandler() const =0
Get the request handler with pointers to the appropriate callbacks.