Teko Version of the Day
Loading...
Searching...
No Matches
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#ifdef TEKO_HAVE_EPETRA
63#include "Teko_DiagonalPreconditionerFactory.hpp"
64#endif
65#include "Teko_ProbingPreconditionerFactory.hpp"
66#include "Teko_IdentityPreconditionerFactory.hpp"
67#include "NS/Teko_LSCPreconditionerFactory.hpp"
68#include "NS/Teko_SIMPLEPreconditionerFactory.hpp"
69#include "NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp"
70
71#ifdef Teko_ENABLE_ML_SMOOTHERS
72#include "Teko_SmootherPreconditionerFactory.hpp"
73#include "Teko_MLPreconditionerFactory.hpp"
74#endif
75
76
77#include "Thyra_DefaultPreconditioner.hpp"
78
79using namespace Thyra;
80using Teuchos::RCP;
81
82namespace Teko {
84
86bool PreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &fwdOpSrc) const
87{
88 RCP<const Thyra::LinearOpBase<double> > A = fwdOpSrc.getOp();
89 return A!=Teuchos::null;
90}
91
93RCP<Thyra::PreconditionerBase<double> > PreconditionerFactory::createPrec() const
94{
95 // build a preconditioner, give it some inital state
96 RCP<Preconditioner> bp = rcp(new Preconditioner());
97 bp->setStateObject(buildPreconditionerState());
98 bp->getStateObject()->setInitialized(false);
99
100 return bp;
101}
102
104void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc,
105 PreconditionerBase<double> * prec,
106 const ESupportSolveUse /* supportSolveUse */) const
107{
108 // get the blocked linear operator
109 LinearOp A = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(ASrc->getOp());
110
111 Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
112 TEUCHOS_ASSERT(blkPrec!=0);
113
114 // grab the state object
115 RCP<PreconditionerState> state = blkPrec->getStateObject();
116 state->setInitialized(false);
117
118 // build the preconditioner
119 const RCP<const LinearOpBase<double> > M = buildPreconditionerOperator(A,*state);
120
121 // set the request handler for the
122 setOpRequestHandler(*this,M);
123
124 // must first cast that to be initialized
125 DefaultPreconditioner<double> & dPrec = Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
126 dPrec.initializeUnspecified(Teuchos::rcp_const_cast<LinearOpBase<double> >(M));
127}
128
130void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc,
131 const RCP<const Thyra::MultiVectorBase<double> > & solnVec,
132 PreconditionerBase<double> * prec,
133 const ESupportSolveUse supportSolveUse) const
134{
135 Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
136 blkPrec->setSourceVector(Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(solnVec));
137
138 initializePrec(ASrc,prec,supportSolveUse);
139}
140
142void PreconditionerFactory::uninitializePrec(PreconditionerBase<double> * /* prec */,
143 RCP<const LinearOpSourceBase<double> > * /* fwdOpSrc */,
144 ESupportSolveUse * /* supportSolveUse */) const
145{
146 // Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec);
147
148 // what do I do here?
149 TEUCHOS_TEST_FOR_EXCEPT_MSG(true,"\"PreconditionerFactory::uninitializePrec not implemented\"");
150}
151
152// for ParameterListAcceptor
154
156void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> & paramList)
157{
158 paramList_ = paramList;
159}
160
163{
164 return paramList_;
165}
166
168RCP< Teuchos::ParameterList > PreconditionerFactory::unsetParameterList()
169{
170 RCP<Teuchos::ParameterList> _paramList = paramList_;
171 paramList_ = Teuchos::null;
172 return _paramList;
173}
174
176void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> & il)
177{
178 inverseLibrary_ = il;
179}
180
182RCP<const InverseLibrary> PreconditionerFactory::getInverseLibrary() const
183{
184 // lazily build the inverse library only when needed
185 if(inverseLibrary_==Teuchos::null)
186 return InverseLibrary::buildFromStratimikos();
187
188 return inverseLibrary_;
189}
190
192// Static members and methods
194
196void PreconditionerFactory::setOpRequestHandler(const RequestHandlerContainer & rhc,const LinearOp & op)
197{
198 ModifiableLinearOp mlo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(op);
199
200 // conditionally set the request handler
201 RCP<RequestHandlerContainer> reqHandCont = Teuchos::rcp_dynamic_cast<RequestHandlerContainer>(mlo);
202 if(reqHandCont!=Teuchos::null) {
203 reqHandCont->setRequestHandler(rhc.getRequestHandler());
204 }
205 else {
206 // is null
207 }
208
209}
210
212CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_;
213
228RCP<PreconditionerFactory>
230 const Teuchos::ParameterList & settings,
231 const RCP<const InverseLibrary> & invLib)
232{
233 Teko_DEBUG_SCOPE("PreconditionerFactory::buildPreconditionerFactory",10);
234
235 // initialize the defaults if necessary
236 if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder();
237
238 // request the preconditioner factory from the CloneFactory
239 RCP<PreconditionerFactory> precFact = precFactoryBuilder_.build(name);
240
241 Teko_DEBUG_MSG_BEGIN(5);
242 DEBUG_STREAM << "Looked up \"" << name << "\"" << std::endl;
243 DEBUG_STREAM << "Built " << precFact << std::endl;
244 Teko_DEBUG_MSG_END();
245
246 if(precFact==Teuchos::null)
247 return Teuchos::null;
248
249 // add in the inverse library
250 if(invLib!=Teuchos::null) {
251 precFact->setInverseLibrary(invLib);
252 precFact->setRequestHandler(invLib->getRequestHandler());
253 }
254
255 // now that inverse library has been set,
256 // pass in the parameter list
257 precFact->initializeFromParameterList(settings);
258
259 return precFact;
260}
261
275void PreconditionerFactory::addPreconditionerFactory(const std::string & name,const RCP<Cloneable> & clone)
276{
277 // initialize the defaults if necessary
278 if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder();
279
280 // add clone to builder
281 precFactoryBuilder_.addClone(name,clone);
282}
283
285void PreconditionerFactory::initializePrecFactoryBuilder()
286{
287 RCP<Cloneable> clone;
288
289 // add various preconditioners to factory
290 clone = rcp(new AutoClone<LU2x2PreconditionerFactory>());
291 precFactoryBuilder_.addClone("Block LU2x2",clone);
292
294 precFactoryBuilder_.addClone("Block Jacobi",clone);
295
297 precFactoryBuilder_.addClone("Block Gauss-Seidel",clone);
298
299 clone = rcp(new AutoClone<AddPreconditionerFactory>());
300 precFactoryBuilder_.addClone("Block Add",clone);
301
302 clone = rcp(new AutoClone<MultPreconditionerFactory>());
303 precFactoryBuilder_.addClone("Block Multiply",clone);
304
306 precFactoryBuilder_.addClone("NS LSC",clone);
307
309 precFactoryBuilder_.addClone("NS SIMPLE",clone);
310
312 precFactoryBuilder_.addClone("NS SIMPLE-Timed",clone);
313
315 precFactoryBuilder_.addClone("Iterative Preconditioner",clone);
316
317#ifdef TEKO_HAVE_EPETRA
319 precFactoryBuilder_.addClone("Explicit Diagonal Preconditioner",clone);
320#endif
321
323 precFactoryBuilder_.addClone("Diagnostic Inverse",clone);
324
326 precFactoryBuilder_.addClone("Diagonal Scaling",clone);
327
329 precFactoryBuilder_.addClone("Identity",clone);
330
331#ifdef Teko_ENABLE_Isorropia
333 precFactoryBuilder_.addClone("Probing Preconditioner",clone);
334#endif
335
336#ifdef Teko_ENABLE_ML_SMOOTHERS
337 clone = rcp(new AutoClone<MLPreconditionerFactory>());
338 precFactoryBuilder_.addClone("Blocked ML Preconditioner",clone);
339#endif
340}
341
342void PreconditionerFactory::getPreconditionerFactoryNames(std::vector<std::string> & names)
343{
344 // initialize the defaults if necessary
345 if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder();
346 precFactoryBuilder_.getCloneNames(names);
347}
348
349} // 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.