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 #ifdef TEKO_HAVE_EPETRA
28 #include "Teko_ProbingPreconditionerFactory.hpp"
29 #endif
30 #include "Teko_IdentityPreconditionerFactory.hpp"
31 #include "NS/Teko_LSCPreconditionerFactory.hpp"
32 #include "NS/Teko_SIMPLEPreconditionerFactory.hpp"
33 #include "NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp"
34 
35 #ifdef Teko_ENABLE_ML_SMOOTHERS
36 #include "Teko_SmootherPreconditionerFactory.hpp"
37 #include "Teko_MLPreconditionerFactory.hpp"
38 #endif
39 
40 #include "Thyra_DefaultPreconditioner.hpp"
41 
42 using namespace Thyra;
43 using Teuchos::RCP;
44 
45 namespace Teko {
47 
49 bool PreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &fwdOpSrc) const {
50  RCP<const Thyra::LinearOpBase<double> > A = fwdOpSrc.getOp();
51  return A != Teuchos::null;
52 }
53 
55 RCP<Thyra::PreconditionerBase<double> > PreconditionerFactory::createPrec() const {
56  // build a preconditioner, give it some inital state
57  RCP<Preconditioner> bp = rcp(new Preconditioner());
58  bp->setStateObject(buildPreconditionerState());
59  bp->getStateObject()->setInitialized(false);
60 
61  return bp;
62 }
63 
65 void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > &ASrc,
66  PreconditionerBase<double> *prec,
67  const ESupportSolveUse /* supportSolveUse */) const {
68  // get the blocked linear operator
69  LinearOp A = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(ASrc->getOp());
70 
71  Preconditioner *blkPrec = dynamic_cast<Preconditioner *>(prec);
72  TEUCHOS_ASSERT(blkPrec != 0);
73 
74  // grab the state object
75  RCP<PreconditionerState> state = blkPrec->getStateObject();
76  state->setInitialized(false);
77 
78  // build the preconditioner
79  const RCP<const LinearOpBase<double> > M = buildPreconditionerOperator(A, *state);
80 
81  // set the request handler for the
82  setOpRequestHandler(*this, M);
83 
84  // must first cast that to be initialized
85  DefaultPreconditioner<double> &dPrec = Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
86  dPrec.initializeUnspecified(Teuchos::rcp_const_cast<LinearOpBase<double> >(M));
87 }
88 
90 void PreconditionerFactory::initializePrec(
91  const RCP<const LinearOpSourceBase<double> > &ASrc,
92  const RCP<const Thyra::MultiVectorBase<double> > &solnVec, PreconditionerBase<double> *prec,
93  const ESupportSolveUse supportSolveUse) const {
94  Preconditioner *blkPrec = dynamic_cast<Preconditioner *>(prec);
95  blkPrec->setSourceVector(Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(solnVec));
96 
97  initializePrec(ASrc, prec, supportSolveUse);
98 }
99 
101 void PreconditionerFactory::uninitializePrec(
102  PreconditionerBase<double> * /* prec */,
103  RCP<const LinearOpSourceBase<double> > * /* fwdOpSrc */,
104  ESupportSolveUse * /* supportSolveUse */) const {
105  // Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
106 
107  // what do I do here?
108  TEUCHOS_TEST_FOR_EXCEPT_MSG(true, "\"PreconditionerFactory::uninitializePrec not implemented\"");
109 }
110 
111 // for ParameterListAcceptor
113 
115 void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> &paramList) {
116  paramList_ = paramList;
117 }
118 
120 RCP<Teuchos::ParameterList> PreconditionerFactory::getNonconstParameterList() { return paramList_; }
121 
123 RCP<Teuchos::ParameterList> PreconditionerFactory::unsetParameterList() {
124  RCP<Teuchos::ParameterList> _paramList = paramList_;
125  paramList_ = Teuchos::null;
126  return _paramList;
127 }
128 
130 void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> &il) {
131  inverseLibrary_ = il;
132 }
133 
135 RCP<const InverseLibrary> PreconditionerFactory::getInverseLibrary() const {
136  // lazily build the inverse library only when needed
137  if (inverseLibrary_ == Teuchos::null) return InverseLibrary::buildFromStratimikos();
138 
139  return inverseLibrary_;
140 }
141 
143 // Static members and methods
145 
147 void PreconditionerFactory::setOpRequestHandler(const RequestHandlerContainer &rhc,
148  const LinearOp &op) {
149  ModifiableLinearOp mlo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(op);
150 
151  // conditionally set the request handler
152  RCP<RequestHandlerContainer> reqHandCont =
153  Teuchos::rcp_dynamic_cast<RequestHandlerContainer>(mlo);
154  if (reqHandCont != Teuchos::null) {
155  reqHandCont->setRequestHandler(rhc.getRequestHandler());
156  } else {
157  // is null
158  }
159 }
160 
162 CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_;
163 
178 RCP<PreconditionerFactory> PreconditionerFactory::buildPreconditionerFactory(
179  const std::string &name, const Teuchos::ParameterList &settings,
180  const RCP<const InverseLibrary> &invLib) {
181  Teko_DEBUG_SCOPE("PreconditionerFactory::buildPreconditionerFactory", 10);
182 
183  // initialize the defaults if necessary
184  if (precFactoryBuilder_.cloneCount() == 0) initializePrecFactoryBuilder();
185 
186  // request the preconditioner factory from the CloneFactory
187  RCP<PreconditionerFactory> precFact = precFactoryBuilder_.build(name);
188 
189  Teko_DEBUG_MSG_BEGIN(5);
190  DEBUG_STREAM << "Looked up \"" << name << "\"" << std::endl;
191  DEBUG_STREAM << "Built " << precFact << std::endl;
192  Teko_DEBUG_MSG_END();
193 
194  if (precFact == Teuchos::null) return Teuchos::null;
195 
196  // add in the inverse library
197  if (invLib != Teuchos::null) {
198  precFact->setInverseLibrary(invLib);
199  precFact->setRequestHandler(invLib->getRequestHandler());
200  }
201 
202  // now that inverse library has been set,
203  // pass in the parameter list
204  precFact->initializeFromParameterList(settings);
205 
206  return precFact;
207 }
208 
222 void PreconditionerFactory::addPreconditionerFactory(const std::string &name,
223  const RCP<Cloneable> &clone) {
224  // initialize the defaults if necessary
225  if (precFactoryBuilder_.cloneCount() == 0) initializePrecFactoryBuilder();
226 
227  // add clone to builder
228  precFactoryBuilder_.addClone(name, clone);
229 }
230 
232 void PreconditionerFactory::initializePrecFactoryBuilder() {
233  RCP<Cloneable> clone;
234 
235  // add various preconditioners to factory
236  clone = rcp(new AutoClone<LU2x2PreconditionerFactory>());
237  precFactoryBuilder_.addClone("Block LU2x2", clone);
238 
239  clone = rcp(new AutoClone<JacobiPreconditionerFactory>());
240  precFactoryBuilder_.addClone("Block Jacobi", clone);
241 
243  precFactoryBuilder_.addClone("Block Gauss-Seidel", clone);
244 
246  precFactoryBuilder_.addClone("Hierarchical Block Gauss-Seidel", clone);
247 
248  clone = rcp(new AutoClone<AddPreconditionerFactory>());
249  precFactoryBuilder_.addClone("Block Add", clone);
250 
251  clone = rcp(new AutoClone<MultPreconditionerFactory>());
252  precFactoryBuilder_.addClone("Block Multiply", clone);
253 
254  clone = rcp(new AutoClone<NS::LSCPreconditionerFactory>());
255  precFactoryBuilder_.addClone("NS LSC", clone);
256 
258  precFactoryBuilder_.addClone("NS SIMPLE", clone);
259 
261  precFactoryBuilder_.addClone("NS SIMPLE-Timed", clone);
262 
264  precFactoryBuilder_.addClone("Iterative Preconditioner", clone);
265 
266  clone = rcp(new AutoClone<DiagonalPreconditionerFactory>());
267  precFactoryBuilder_.addClone("Explicit Diagonal Preconditioner", clone);
268 
270  precFactoryBuilder_.addClone("Diagnostic Inverse", clone);
271 
273  precFactoryBuilder_.addClone("Diagonal Scaling", clone);
274 
275  clone = rcp(new AutoClone<IdentityPreconditionerFactory>());
276  precFactoryBuilder_.addClone("Identity", clone);
277 
278 #if defined(Teko_ENABLE_Isorropia) && defined(TEKO_HAVE_EPETRA)
279  clone = rcp(new AutoClone<ProbingPreconditionerFactory>());
280  precFactoryBuilder_.addClone("Probing Preconditioner", clone);
281 #endif
282 
283 #ifdef Teko_ENABLE_ML_SMOOTHERS
284  clone = rcp(new AutoClone<MLPreconditionerFactory>());
285  precFactoryBuilder_.addClone("Blocked ML Preconditioner", clone);
286 #endif
287 }
288 
289 void PreconditionerFactory::getPreconditionerFactoryNames(std::vector<std::string> &names) {
290  // initialize the defaults if necessary
291  if (precFactoryBuilder_.cloneCount() == 0) initializePrecFactoryBuilder();
292  precFactoryBuilder_.getCloneNames(names);
293 }
294 
295 } // 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.