|
Teko Version of the Day
|
00001 /* 00002 // @HEADER 00003 // 00004 // *********************************************************************** 00005 // 00006 // Teko: A package for block and physics based preconditioning 00007 // Copyright 2010 Sandia Corporation 00008 // 00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00010 // the U.S. Government retains certain rights in this software. 00011 // 00012 // Redistribution and use in source and binary forms, with or without 00013 // modification, are permitted provided that the following conditions are 00014 // met: 00015 // 00016 // 1. Redistributions of source code must retain the above copyright 00017 // notice, this list of conditions and the following disclaimer. 00018 // 00019 // 2. Redistributions in binary form must reproduce the above copyright 00020 // notice, this list of conditions and the following disclaimer in the 00021 // documentation and/or other materials provided with the distribution. 00022 // 00023 // 3. Neither the name of the Corporation nor the names of the 00024 // contributors may be used to endorse or promote products derived from 00025 // this software without specific prior written permission. 00026 // 00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 // 00039 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) 00040 // 00041 // *********************************************************************** 00042 // 00043 // @HEADER 00044 00045 */ 00046 00047 #include "Teko_Config.h" 00048 #include "Teko_PreconditionerFactory.hpp" 00049 00050 #include "Teko_InverseLibrary.hpp" 00051 #include "Teko_Preconditioner.hpp" 00052 00053 // Specific preconditioners included for dynamic creation 00054 #include "Teko_JacobiPreconditionerFactory.hpp" 00055 #include "Teko_GaussSeidelPreconditionerFactory.hpp" 00056 #include "Teko_AddPreconditionerFactory.hpp" 00057 #include "Teko_MultPreconditionerFactory.hpp" 00058 #include "Teko_LU2x2PreconditionerFactory.hpp" 00059 #include "Teko_IterativePreconditionerFactory.hpp" 00060 #include "Teko_DiagnosticPreconditionerFactory.hpp" 00061 #include "Teko_DiagonallyScaledPreconditionerFactory.hpp" 00062 #include "Teko_ProbingPreconditionerFactory.hpp" 00063 #include "NS/Teko_LSCPreconditionerFactory.hpp" 00064 #include "NS/Teko_SIMPLEPreconditionerFactory.hpp" 00065 00066 #ifdef Teko_ENABLE_DEV_MODE 00067 #include "Teko_SmootherPreconditionerFactory.hpp" 00068 #endif 00069 00070 00071 #include "Thyra_DefaultPreconditioner.hpp" 00072 00073 using namespace Thyra; 00074 using Teuchos::RCP; 00075 00076 namespace Teko { 00078 00080 bool PreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &fwdOpSrc) const 00081 { 00082 RCP<const Thyra::LinearOpBase<double> > A = fwdOpSrc.getOp(); 00083 return A!=Teuchos::null; 00084 } 00085 00087 RCP<Thyra::PreconditionerBase<double> > PreconditionerFactory::createPrec() const 00088 { 00089 // build a preconditioner, give it some inital state 00090 RCP<Preconditioner> bp = rcp(new Preconditioner()); 00091 bp->setStateObject(buildPreconditionerState()); 00092 bp->getStateObject()->setInitialized(false); 00093 00094 return bp; 00095 } 00096 00098 void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc, 00099 PreconditionerBase<double> * prec, 00100 const ESupportSolveUse supportSolveUse) const 00101 { 00102 // get the blocked linear operator 00103 LinearOp A = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(ASrc->getOp()); 00104 00105 Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec); 00106 TEUCHOS_ASSERT(blkPrec!=0); 00107 00108 // grab the state object 00109 RCP<PreconditionerState> state = blkPrec->getStateObject(); 00110 state->setInitialized(false); 00111 00112 // build the preconditioner 00113 const RCP<const LinearOpBase<double> > M = buildPreconditionerOperator(A,*state); 00114 00115 // set the request handler for the 00116 setOpRequestHandler(*this,M); 00117 00118 // must first cast that to be initialized 00119 DefaultPreconditioner<double> & dPrec = Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec); 00120 dPrec.initializeUnspecified(Teuchos::rcp_const_cast<LinearOpBase<double> >(M)); 00121 } 00122 00124 void PreconditionerFactory::initializePrec(const RCP<const LinearOpSourceBase<double> > & ASrc, 00125 const RCP<const Thyra::MultiVectorBase<double> > & solnVec, 00126 PreconditionerBase<double> * prec, 00127 const ESupportSolveUse supportSolveUse) const 00128 { 00129 Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec); 00130 blkPrec->setSourceVector(Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(solnVec)); 00131 00132 initializePrec(ASrc,prec,supportSolveUse); 00133 } 00134 00136 void PreconditionerFactory::uninitializePrec(PreconditionerBase<double> * prec, 00137 RCP<const LinearOpSourceBase<double> > * fwdOpSrc, 00138 ESupportSolveUse *supportSolveUse) const 00139 { 00140 // Preconditioner * blkPrec = dynamic_cast<Preconditioner *>(prec); 00141 00142 // what do I do here? 00143 TEST_FOR_EXCEPT_MSG(true,"\"PreconditionerFactory::uninitializePrec not implemented\""); 00144 } 00145 00146 // for ParameterListAcceptor 00148 00150 void PreconditionerFactory::setParameterList(const RCP<Teuchos::ParameterList> & paramList) 00151 { 00152 paramList_ = paramList; 00153 } 00154 00156 RCP< Teuchos::ParameterList > PreconditionerFactory::getNonconstParameterList() 00157 { 00158 return paramList_; 00159 } 00160 00162 RCP< Teuchos::ParameterList > PreconditionerFactory::unsetParameterList() 00163 { 00164 RCP<Teuchos::ParameterList> _paramList = paramList_; 00165 paramList_ = Teuchos::null; 00166 return _paramList; 00167 } 00168 00170 void PreconditionerFactory::setInverseLibrary(const RCP<const InverseLibrary> & il) 00171 { 00172 inverseLibrary_ = il; 00173 } 00174 00176 RCP<const InverseLibrary> PreconditionerFactory::getInverseLibrary() const 00177 { 00178 // lazily build the inverse library only when needed 00179 if(inverseLibrary_==Teuchos::null) 00180 return InverseLibrary::buildFromStratimikos(); 00181 00182 return inverseLibrary_; 00183 } 00184 00186 // Static members and methods 00188 00190 void PreconditionerFactory::setOpRequestHandler(const RequestHandlerContainer & rhc,const LinearOp & op) 00191 { 00192 ModifiableLinearOp mlo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(op); 00193 00194 // conditionally set the request handler 00195 RCP<RequestHandlerContainer> reqHandCont = Teuchos::rcp_dynamic_cast<RequestHandlerContainer>(mlo); 00196 if(reqHandCont!=Teuchos::null) { 00197 reqHandCont->setRequestHandler(rhc.getRequestHandler()); 00198 } 00199 else { 00200 // is null 00201 } 00202 00203 } 00204 00206 CloneFactory<PreconditionerFactory> PreconditionerFactory::precFactoryBuilder_; 00207 00222 RCP<PreconditionerFactory> 00223 PreconditionerFactory::buildPreconditionerFactory(const std::string & name, 00224 const Teuchos::ParameterList & settings, 00225 const RCP<const InverseLibrary> & invLib) 00226 { 00227 Teko_DEBUG_SCOPE("PreconditionerFactory::buildPreconditionerFactory",10); 00228 00229 // initialize the defaults if necessary 00230 if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder(); 00231 00232 // request the preconditioner factory from the CloneFactory 00233 RCP<PreconditionerFactory> precFact = precFactoryBuilder_.build(name); 00234 00235 Teko_DEBUG_MSG_BEGIN(5); 00236 DEBUG_STREAM << "Looked up \"" << name << "\"" << std::endl; 00237 DEBUG_STREAM << "Built " << precFact << std::endl; 00238 Teko_DEBUG_MSG_END(); 00239 00240 if(precFact==Teuchos::null) 00241 return Teuchos::null; 00242 00243 // add in the inverse library 00244 if(invLib!=Teuchos::null) { 00245 precFact->setInverseLibrary(invLib); 00246 precFact->setRequestHandler(invLib->getRequestHandler()); 00247 } 00248 00249 // now that inverse library has been set, 00250 // pass in the parameter list 00251 precFact->initializeFromParameterList(settings); 00252 00253 return precFact; 00254 } 00255 00269 void PreconditionerFactory::addPreconditionerFactory(const std::string & name,const RCP<Cloneable> & clone) 00270 { 00271 // initialize the defaults if necessary 00272 if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder(); 00273 00274 // add clone to builder 00275 precFactoryBuilder_.addClone(name,clone); 00276 } 00277 00279 void PreconditionerFactory::initializePrecFactoryBuilder() 00280 { 00281 RCP<Cloneable> clone; 00282 00283 // add various preconditioners to factory 00284 clone = rcp(new AutoClone<LU2x2PreconditionerFactory>()); 00285 precFactoryBuilder_.addClone("Block LU2x2",clone); 00286 00287 clone = rcp(new AutoClone<JacobiPreconditionerFactory>()); 00288 precFactoryBuilder_.addClone("Block Jacobi",clone); 00289 00290 clone = rcp(new AutoClone<GaussSeidelPreconditionerFactory>()); 00291 precFactoryBuilder_.addClone("Block Gauss-Seidel",clone); 00292 00293 clone = rcp(new AutoClone<AddPreconditionerFactory>()); 00294 precFactoryBuilder_.addClone("Block Add",clone); 00295 00296 clone = rcp(new AutoClone<MultPreconditionerFactory>()); 00297 precFactoryBuilder_.addClone("Block Multiply",clone); 00298 00299 clone = rcp(new AutoClone<NS::LSCPreconditionerFactory>()); 00300 precFactoryBuilder_.addClone("NS LSC",clone); 00301 00302 clone = rcp(new AutoClone<NS::SIMPLEPreconditionerFactory>()); 00303 precFactoryBuilder_.addClone("NS SIMPLE",clone); 00304 00305 clone = rcp(new AutoClone<IterativePreconditionerFactory>()); 00306 precFactoryBuilder_.addClone("Iterative Preconditioner",clone); 00307 00308 clone = rcp(new AutoClone<DiagnosticPreconditionerFactory>()); 00309 precFactoryBuilder_.addClone("Diagnostic Inverse",clone); 00310 00311 clone = rcp(new AutoClone<DiagonallyScaledPreconditionerFactory>()); 00312 precFactoryBuilder_.addClone("Diagonal Scaling",clone); 00313 00314 #ifdef Teko_ENABLE_DEV_MODE 00315 clone = rcp(new AutoClone<SmootherPreconditionerFactory>()); 00316 precFactoryBuilder_.addClone("Smoother",clone); 00317 #endif 00318 00319 #ifdef Teko_ENABLE_Isorropia 00320 clone = rcp(new AutoClone<ProbingPreconditionerFactory>()); 00321 precFactoryBuilder_.addClone("Probing Preconditioner",clone); 00322 #endif 00323 } 00324 00325 void PreconditionerFactory::getPreconditionerFactoryNames(std::vector<std::string> & names) 00326 { 00327 // initialize the defaults if necessary 00328 if(precFactoryBuilder_.cloneCount()==0) initializePrecFactoryBuilder(); 00329 precFactoryBuilder_.getCloneNames(names); 00330 } 00331 00332 } // end namespace Teko
1.7.4