|
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_PCDStrategy.hpp" 00048 00049 #include "Teuchos_TimeMonitor.hpp" 00050 #include "Teko_Utilities.hpp" 00051 00052 namespace Teko { 00053 namespace NS { 00054 00055 using Teuchos::TimeMonitor; 00056 00057 Teuchos::RCP<Teuchos::Time> PCDStrategy::initTimer_; 00058 Teuchos::RCP<Teuchos::Time> PCDStrategy::invSTimer_; 00059 Teuchos::RCP<Teuchos::Time> PCDStrategy::invFTimer_; 00060 Teuchos::RCP<Teuchos::Time> PCDStrategy::opsTimer_; 00061 00062 void PCDStrategy::buildTimers() 00063 { 00064 if(initTimer_==Teuchos::null) 00065 initTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec"); 00066 00067 if(invSTimer_==Teuchos::null) 00068 invSTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invS"); 00069 00070 if(invFTimer_==Teuchos::null) 00071 invFTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invF"); 00072 00073 if(opsTimer_==Teuchos::null) 00074 opsTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec buildOps"); 00075 } 00076 00077 PCDStrategy::PCDStrategy() : massInverseType_(Diagonal) 00078 { 00079 buildTimers(); 00080 } 00081 00083 PCDStrategy::PCDStrategy(const Teuchos::RCP<InverseFactory> & invFA, 00084 const Teuchos::RCP<InverseFactory> & invS) 00085 : invFactoryF_(invFA), invFactoryS_(invS), massInverseType_(Diagonal) 00086 { 00087 buildTimers(); 00088 } 00089 00091 const Teko::LinearOp 00092 PCDStrategy::getHatInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const 00093 { 00094 initializeState(A,state); 00095 00096 return state.getModifiableOp("invF"); 00097 } 00098 00100 const Teko::LinearOp 00101 PCDStrategy::getTildeInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const 00102 { 00103 initializeState(A,state); 00104 00105 return state.getModifiableOp("invF"); 00106 } 00107 00109 const Teko::LinearOp 00110 PCDStrategy::getInvS(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const 00111 { 00112 initializeState(A,state); 00113 00114 return state.getLinearOp("invS"); 00115 } 00116 00117 void PCDStrategy::initializeState(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const 00118 { 00119 Teko_DEBUG_SCOPE("PCDStrategy::initializeState",10); 00120 TEUCHOS_ASSERT(getRequestHandler()!=Teuchos::null); 00121 00122 std::string pcdStr = getPCDString(); 00123 std::string presLapStr = getPressureLaplaceString(); 00124 std::string presMassStr = getPressureMassString(); 00125 00126 // no work to be done 00127 if(state.isInitialized()) 00128 return; 00129 00130 Teuchos::TimeMonitor timer(*initTimer_,true); 00131 00132 // extract sub blocks 00133 LinearOp F = Teko::getBlock(0,0,A); 00134 LinearOp Bt = Teko::getBlock(0,1,A); 00135 LinearOp B = Teko::getBlock(1,0,A); 00136 LinearOp C = Teko::getBlock(1,1,A); 00137 00138 LinearOp Qp = getRequestHandler()->request<LinearOp>(presMassStr); 00139 TEUCHOS_ASSERT(Qp!=Teuchos::null); 00140 00141 // build the inverse Laplacian complement 00143 LinearOp iQp; 00144 if(massInverseType_==NotDiag) { 00145 ModifiableLinearOp & invMass = state.getModifiableOp("invMass"); 00146 Teko_DEBUG_SCOPE("Building inv(Mass)",10); 00147 00148 if(invMass==Teuchos::null) 00149 invMass = buildInverse(*invFactoryS_,Qp); 00150 else 00151 rebuildInverse(*invFactoryS_,Qp,invMass); 00152 00153 iQp = invMass; 00154 } 00155 else { 00156 Teko_DEBUG_MSG("Building inverse mass of type \"" << Teko::getDiagonalName(massInverseType_) << "\"",10); 00157 iQp = getInvDiagonalOp(Qp,massInverseType_); 00158 } 00159 00160 // build the inverse Laplacian complement 00162 ModifiableLinearOp & invLaplace = state.getModifiableOp("invLaplace"); 00163 { 00164 Teuchos::TimeMonitor timer(*invSTimer_,true); 00165 00166 LinearOp laplace = getRequestHandler()->request<Teko::LinearOp>(presLapStr); 00167 TEUCHOS_ASSERT(laplace!=Teuchos::null); 00168 if(invLaplace==Teuchos::null) 00169 invLaplace = buildInverse(*invFactoryS_,laplace); 00170 else 00171 rebuildInverse(*invFactoryS_,laplace,invLaplace); 00172 } 00173 00174 // build the inverse Schur complement 00176 { 00177 Teko_DEBUG_SCOPE("Building S",10); 00178 Teuchos::TimeMonitor timer(*opsTimer_,true); 00179 00180 // build Schur-complement 00181 LinearOp pcd = getRequestHandler()->request<Teko::LinearOp>(pcdStr); 00182 TEUCHOS_ASSERT(pcd!=Teuchos::null); 00183 LinearOp invL = invLaplace; 00184 LinearOp invS = multiply(iQp,pcd,invL); 00185 00186 state.addLinearOp("invS",invS); 00187 } 00188 00189 // build inverse F 00191 { 00192 Teko_DEBUG_SCOPE("Building inv(F)",10); 00193 Teuchos::TimeMonitor timer(*invFTimer_,true); 00194 00195 ModifiableLinearOp & invF = state.getModifiableOp("invF"); 00196 if(invF==Teuchos::null) 00197 invF = buildInverse(*invFactoryF_,F); 00198 else 00199 rebuildInverse(*invFactoryF_,F,invF); 00200 } 00201 00202 // mark state as initialized 00203 state.setInitialized(true); 00204 } 00205 00217 void PCDStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl, 00218 const InverseLibrary & invLib) 00219 { 00220 Teko_DEBUG_SCOPE("PCDStrategy::initializeFromParameterList",10); 00221 00222 std::string invStr="Amesos", invFStr="", invSStr=""; 00223 massInverseType_ = Diagonal; 00224 00225 // "parse" the parameter list 00226 if(pl.isParameter("Inverse Type")) 00227 invStr = pl.get<std::string>("Inverse Type"); 00228 if(pl.isParameter("Inverse F Type")) 00229 invFStr = pl.get<std::string>("Inverse F Type"); 00230 if(pl.isParameter("Inverse Laplace Type")) 00231 invSStr = pl.get<std::string>("Inverse Laplace Type"); 00232 if(pl.isParameter("Inverse Mass Type")) { 00233 std::string massInverseStr = pl.get<std::string>("Inverse Mass Type"); 00234 00235 // build inverse types 00236 massInverseType_ = getDiagonalType(massInverseStr); 00237 } 00238 00239 // set defaults as needed 00240 if(invFStr=="") invFStr = invStr; 00241 if(invSStr=="") invSStr = invStr; 00242 00243 Teko_DEBUG_MSG_BEGIN(5) 00244 DEBUG_STREAM << "PCD Strategy Parameters: " << std::endl; 00245 DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; 00246 DEBUG_STREAM << " inv F type = \"" << invFStr << "\"" << std::endl; 00247 DEBUG_STREAM << " inv Laplace type = \"" << invSStr << "\"" << std::endl; 00248 DEBUG_STREAM << " inv Mass type = \"" << Teko::getDiagonalName(massInverseType_) << "\"" << std::endl; 00249 DEBUG_STREAM << "PCD Strategy Parameter list: " << std::endl; 00250 pl.print(DEBUG_STREAM); 00251 Teko_DEBUG_MSG_END() 00252 00253 // build velocity inverse factory 00254 invFactoryF_ = invLib.getInverseFactory(invFStr); 00255 00256 if(invFStr==invSStr) 00257 invFactoryS_ = invFactoryF_; 00258 else 00259 invFactoryS_ = invLib.getInverseFactory(invSStr); 00260 00261 // setup a request for required operators 00262 getRequestHandler()->preRequest<Teko::LinearOp>(getPressureMassString()); 00263 getRequestHandler()->preRequest<Teko::LinearOp>(getPCDString()); 00264 getRequestHandler()->preRequest<Teko::LinearOp>(getPressureLaplaceString()); 00265 } 00266 00268 Teuchos::RCP<Teuchos::ParameterList> PCDStrategy::getRequestedParameters() const 00269 { 00270 Teko_DEBUG_SCOPE("PCDStrategy::getRequestedParameters",10); 00271 Teuchos::RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList()); 00272 00273 // grab parameters from F solver 00274 RCP<Teuchos::ParameterList> fList = invFactoryF_->getRequestedParameters(); 00275 if(fList!=Teuchos::null) { 00276 Teuchos::ParameterList::ConstIterator itr; 00277 for(itr=fList->begin();itr!=fList->end();++itr) 00278 pl->setEntry(itr->first,itr->second); 00279 } 00280 00281 // grab parameters from S solver 00282 RCP<Teuchos::ParameterList> sList = invFactoryS_->getRequestedParameters(); 00283 if(sList!=Teuchos::null) { 00284 Teuchos::ParameterList::ConstIterator itr; 00285 for(itr=sList->begin();itr!=sList->end();++itr) 00286 pl->setEntry(itr->first,itr->second); 00287 } 00288 00289 return pl; 00290 } 00291 00293 bool PCDStrategy::updateRequestedParameters(const Teuchos::ParameterList & pl) 00294 { 00295 Teko_DEBUG_SCOPE("PCDStrategy::updateRequestedParameters",10); 00296 bool result = true; 00297 00298 // update requested parameters in solvers 00299 result &= invFactoryF_->updateRequestedParameters(pl); 00300 result &= invFactoryS_->updateRequestedParameters(pl); 00301 00302 return result; 00303 } 00304 00305 } // end namespace NS 00306 } // end namespace Teko
1.7.4