Teko Version of the Day
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
77using namespace Thyra;
78using Teuchos::RCP;
79
80namespace Teko {
82
84bool 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
91RCP<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
102void 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
128void 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
140void 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
154void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> & paramList)
155{
156 paramList_ = paramList;
157}
158
161{
162 return paramList_;
163}
164
166RCP< Teuchos::ParameterList > PreconditionerFactory::unsetParameterList()
167{
168 RCP<Teuchos::ParameterList> _paramList = paramList_;
169 paramList_ = Teuchos::null;
170 return _paramList;
171}
172
174void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> & il)
175{
176 inverseLibrary_ = il;
177}
178
180RCP<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
194void 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
210CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_;
211
226RCP<PreconditionerFactory>
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
273void 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
283void 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
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
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
316 precFactoryBuilder_.addClone("Explicit Diagonal Preconditioner",clone);
317
319 precFactoryBuilder_.addClone("Diagnostic Inverse",clone);
320
322 precFactoryBuilder_.addClone("Diagonal Scaling",clone);
323
325 precFactoryBuilder_.addClone("Identity",clone);
326
327#ifdef Teko_ENABLE_Isorropia
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
338void 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
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 Teuchos::RCP< RequestHandler > getRequestHandler() const =0
Get the request handler with pointers to the appropriate callbacks.