Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_PreconditionerFactory.cpp
1 /*
2 // @HEADER
3 //
4 // ***********************************************************************
5 //
6 // Teko: A package for block and physics based preconditioning
7 // Copyright 2010 Sandia Corporation
8 //
9 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
40 //
41 // ***********************************************************************
42 //
43 // @HEADER
44 
45 */
46 
47 #include "Teko_Config.h"
48 #include "Teko_PreconditionerFactory.hpp"
49 
50 #include "Teko_InverseLibrary.hpp"
51 #include "Teko_Preconditioner.hpp"
52 
53 // Specific preconditioners included for dynamic creation
54 #include "Teko_JacobiPreconditionerFactory.hpp"
55 #include "Teko_GaussSeidelPreconditionerFactory.hpp"
56 #include "Teko_AddPreconditionerFactory.hpp"
57 #include "Teko_MultPreconditionerFactory.hpp"
58 #include "Teko_LU2x2PreconditionerFactory.hpp"
59 #include "Teko_IterativePreconditionerFactory.hpp"
60 #include "Teko_DiagnosticPreconditionerFactory.hpp"
61 #include "Teko_DiagonallyScaledPreconditionerFactory.hpp"
62 #include "Teko_DiagonalPreconditionerFactory.hpp"
63 #include "Teko_ProbingPreconditionerFactory.hpp"
64 #include "Teko_IdentityPreconditionerFactory.hpp"
65 #include "NS/Teko_LSCPreconditionerFactory.hpp"
66 #include "NS/Teko_SIMPLEPreconditionerFactory.hpp"
67 #include "NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp"
68 
69 #ifdef Teko_ENABLE_ML_SMOOTHERS
70 #include "Teko_SmootherPreconditionerFactory.hpp"
71 #include "Teko_MLPreconditionerFactory.hpp"
72 #endif
73 
74 
75 #include "Thyra_DefaultPreconditioner.hpp"
76 
77 using namespace Thyra;
78 using Teuchos::RCP;
79 
80 namespace Teko {
82 
84 bool PreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &fwdOpSrc) const
85 {
86  RCP<const Thyra::LinearOpBase<double> > A = fwdOpSrc.getOp();
87  return A!=Teuchos::null;
88 }
89 
91 RCP<Thyra::PreconditionerBase<double> > PreconditionerFactory::createPrec() const
92 {
93  // build a preconditioner, give it some inital state
94  RCP<Preconditioner> bp = rcp(new Preconditioner());
95  bp->setStateObject(buildPreconditionerState());
96  bp->getStateObject()->setInitialized(false);
97 
98  return bp;
99 }
100 
102 void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc,
103  PreconditionerBase<double> * prec,
104  const ESupportSolveUse /* supportSolveUse */) const
105 {
106  // get the blocked linear operator
107  LinearOp A = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(ASrc->getOp());
108 
109  Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
110  TEUCHOS_ASSERT(blkPrec!=0);
111 
112  // grab the state object
113  RCP<PreconditionerState> state = blkPrec->getStateObject();
114  state->setInitialized(false);
115 
116  // build the preconditioner
117  const RCP<const LinearOpBase<double> > M = buildPreconditionerOperator(A,*state);
118 
119  // set the request handler for the
120  setOpRequestHandler(*this,M);
121 
122  // must first cast that to be initialized
123  DefaultPreconditioner<double> & dPrec = Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
124  dPrec.initializeUnspecified(Teuchos::rcp_const_cast<LinearOpBase<double> >(M));
125 }
126 
128 void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc,
129  const RCP<const Thyra::MultiVectorBase<double> > & solnVec,
130  PreconditionerBase<double> * prec,
131  const ESupportSolveUse supportSolveUse) const
132 {
133  Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
134  blkPrec->setSourceVector(Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(solnVec));
135 
136  initializePrec(ASrc,prec,supportSolveUse);
137 }
138 
140 void PreconditionerFactory::uninitializePrec(PreconditionerBase<double> * /* prec */,
141  RCP<const LinearOpSourceBase<double> > * /* fwdOpSrc */,
142  ESupportSolveUse * /* supportSolveUse */) const
143 {
144  // Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
145 
146  // what do I do here?
147  TEUCHOS_TEST_FOR_EXCEPT_MSG(true,"\"PreconditionerFactory::uninitializePrec not implemented\"");
148 }
149 
150 // for ParameterListAcceptor
152 
154 void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> & paramList)
155 {
156  paramList_ = paramList;
157 }
158 
160 RCP< Teuchos::ParameterList > PreconditionerFactory::getNonconstParameterList()
161 {
162  return paramList_;
163 }
164 
166 RCP< Teuchos::ParameterList > PreconditionerFactory::unsetParameterList()
167 {
168  RCP<Teuchos::ParameterList> _paramList = paramList_;
169  paramList_ = Teuchos::null;
170  return _paramList;
171 }
172 
174 void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> & il)
175 {
176  inverseLibrary_ = il;
177 }
178 
180 RCP<const InverseLibrary> PreconditionerFactory::getInverseLibrary() const
181 {
182  // lazily build the inverse library only when needed
183  if(inverseLibrary_==Teuchos::null)
184  return InverseLibrary::buildFromStratimikos();
185 
186  return inverseLibrary_;
187 }
188 
190 // Static members and methods
192 
194 void PreconditionerFactory::setOpRequestHandler(const RequestHandlerContainer & rhc,const LinearOp & op)
195 {
196  ModifiableLinearOp mlo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(op);
197 
198  // conditionally set the request handler
199  RCP<RequestHandlerContainer> reqHandCont = Teuchos::rcp_dynamic_cast<RequestHandlerContainer>(mlo);
200  if(reqHandCont!=Teuchos::null) {
201  reqHandCont->setRequestHandler(rhc.getRequestHandler());
202  }
203  else {
204  // is null
205  }
206 
207 }
208 
210 CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_;
211 
226 RCP<PreconditionerFactory>
227 PreconditionerFactory::buildPreconditionerFactory(const std::string & name,
228  const Teuchos::ParameterList & settings,
229  const RCP<const InverseLibrary> & invLib)
230 {
231  Teko_DEBUG_SCOPE("PreconditionerFactory::buildPreconditionerFactory",10);
232 
233  // initialize the defaults if necessary
234  if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder();
235 
236  // request the preconditioner factory from the CloneFactory
237  RCP<PreconditionerFactory> precFact = precFactoryBuilder_.build(name);
238 
239  Teko_DEBUG_MSG_BEGIN(5);
240  DEBUG_STREAM << "Looked up \"" << name << "\"" << std::endl;
241  DEBUG_STREAM << "Built " << precFact << std::endl;
242  Teko_DEBUG_MSG_END();
243 
244  if(precFact==Teuchos::null)
245  return Teuchos::null;
246 
247  // add in the inverse library
248  if(invLib!=Teuchos::null) {
249  precFact->setInverseLibrary(invLib);
250  precFact->setRequestHandler(invLib->getRequestHandler());
251  }
252 
253  // now that inverse library has been set,
254  // pass in the parameter list
255  precFact->initializeFromParameterList(settings);
256 
257  return precFact;
258 }
259 
273 void PreconditionerFactory::addPreconditionerFactory(const std::string & name,const RCP<Cloneable> & clone)
274 {
275  // initialize the defaults if necessary
276  if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder();
277 
278  // add clone to builder
279  precFactoryBuilder_.addClone(name,clone);
280 }
281 
283 void PreconditionerFactory::initializePrecFactoryBuilder()
284 {
285  RCP<Cloneable> clone;
286 
287  // add various preconditioners to factory
288  clone = rcp(new AutoClone<LU2x2PreconditionerFactory>());
289  precFactoryBuilder_.addClone("Block LU2x2",clone);
290 
291  clone = rcp(new AutoClone<JacobiPreconditionerFactory>());
292  precFactoryBuilder_.addClone("Block Jacobi",clone);
293 
295  precFactoryBuilder_.addClone("Block Gauss-Seidel",clone);
296 
297  clone = rcp(new AutoClone<AddPreconditionerFactory>());
298  precFactoryBuilder_.addClone("Block Add",clone);
299 
300  clone = rcp(new AutoClone<MultPreconditionerFactory>());
301  precFactoryBuilder_.addClone("Block Multiply",clone);
302 
303  clone = rcp(new AutoClone<NS::LSCPreconditionerFactory>());
304  precFactoryBuilder_.addClone("NS LSC",clone);
305 
307  precFactoryBuilder_.addClone("NS SIMPLE",clone);
308 
310  precFactoryBuilder_.addClone("NS SIMPLE-Timed",clone);
311 
313  precFactoryBuilder_.addClone("Iterative Preconditioner",clone);
314 
315  clone = rcp(new AutoClone<DiagonalPreconditionerFactory>());
316  precFactoryBuilder_.addClone("Explicit Diagonal Preconditioner",clone);
317 
319  precFactoryBuilder_.addClone("Diagnostic Inverse",clone);
320 
322  precFactoryBuilder_.addClone("Diagonal Scaling",clone);
323 
324  clone = rcp(new AutoClone<IdentityPreconditionerFactory>());
325  precFactoryBuilder_.addClone("Identity",clone);
326 
327 #ifdef Teko_ENABLE_Isorropia
328  clone = rcp(new AutoClone<ProbingPreconditionerFactory>());
329  precFactoryBuilder_.addClone("Probing Preconditioner",clone);
330 #endif
331 
332 #ifdef Teko_ENABLE_ML_SMOOTHERS
333  clone = rcp(new AutoClone<MLPreconditionerFactory>());
334  precFactoryBuilder_.addClone("Blocked ML Preconditioner",clone);
335 #endif
336 }
337 
338 void PreconditionerFactory::getPreconditionerFactoryNames(std::vector<std::string> & names)
339 {
340  // initialize the defaults if necessary
341  if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder();
342  precFactoryBuilder_.getCloneNames(names);
343 }
344 
345 } // 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.