Teko  Version of the Day
All Classes Files Functions Variables Pages
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 
43 using namespace Thyra;
44 using Teuchos::RCP;
45 
46 namespace Teko {
48 
50 bool PreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &fwdOpSrc) const {
51  RCP<const Thyra::LinearOpBase<double> > A = fwdOpSrc.getOp();
52  return A != Teuchos::null;
53 }
54 
56 RCP<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 
66 void 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 
91 void PreconditionerFactory::initializePrec(
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 
102 void PreconditionerFactory::uninitializePrec(
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 
116 void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> &paramList) {
117  paramList_ = paramList;
118 }
119 
121 RCP<Teuchos::ParameterList> PreconditionerFactory::getNonconstParameterList() { return paramList_; }
122 
124 RCP<Teuchos::ParameterList> PreconditionerFactory::unsetParameterList() {
125  RCP<Teuchos::ParameterList> _paramList = paramList_;
126  paramList_ = Teuchos::null;
127  return _paramList;
128 }
129 
131 void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> &il) {
132  inverseLibrary_ = il;
133 }
134 
136 RCP<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 
148 void 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 
163 CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_;
164 
179 RCP<PreconditionerFactory> PreconditionerFactory::buildPreconditionerFactory(
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 
223 void PreconditionerFactory::addPreconditionerFactory(const std::string &name,
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 
233 void 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 
240  clone = rcp(new AutoClone<JacobiPreconditionerFactory>());
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 
255  clone = rcp(new AutoClone<NS::LSCPreconditionerFactory>());
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 
267  clone = rcp(new AutoClone<DiagonalPreconditionerFactory>());
268  precFactoryBuilder_.addClone("Explicit Diagonal Preconditioner", clone);
269 
271  precFactoryBuilder_.addClone("Diagnostic Inverse", clone);
272 
274  precFactoryBuilder_.addClone("Diagonal Scaling", clone);
275 
276  clone = rcp(new AutoClone<IdentityPreconditionerFactory>());
277  precFactoryBuilder_.addClone("Identity", clone);
278 
279  clone = rcp(new AutoClone<AdaptivePreconditionerFactory>());
280  precFactoryBuilder_.addClone("Adaptive", clone);
281 
282 #if defined(Teko_ENABLE_Isorropia) && defined(TEKO_HAVE_EPETRA)
283  clone = rcp(new AutoClone<ProbingPreconditionerFactory>());
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 
293 void 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
virtual void setRequestHandler(const Teuchos::RCP< RequestHandler > &rh)=0
Set the request handler with pointers to the appropriate callbacks.
An extension of the Thyra::DefaultPreconditioner class with some specializations useful for use withi...
virtual Teuchos::RCP< RequestHandler > getRequestHandler() const =0
Get the request handler with pointers to the appropriate callbacks.