47#include "Teko_LSCPreconditionerFactory.hpp"
49#include "Thyra_DefaultMultipliedLinearOp.hpp"
50#include "Thyra_DefaultAddedLinearOp.hpp"
51#include "Thyra_DefaultIdentityLinearOp.hpp"
52#include "Thyra_DefaultZeroLinearOp.hpp"
56#include "Teko_BlockUpperTriInverseOp.hpp"
57#include "Teko_StaticLSCStrategy.hpp"
58#include "Teko_InvLSCStrategy.hpp"
59#include "Teko_PresLaplaceLSCStrategy.hpp"
60#include "Teko_LSCSIMPLECStrategy.hpp"
62#include "Teuchos_Time.hpp"
68using Teuchos::rcp_dynamic_cast;
76LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp & invF,
const LinearOp & invBQBtmC,
77 const LinearOp & invD,
const LinearOp & invMass)
78 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF,invBQBtmC,invD,invMass))), isSymmetric_(true)
82LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp & invF,
const LinearOp & invBQBtmC,
83 const LinearOp & invMass)
84 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF,invBQBtmC,invMass))), isSymmetric_(true)
88LSCPreconditionerFactory::LSCPreconditionerFactory(
const RCP<LSCStrategy> & strategy)
89 : invOpsStrategy_(strategy), isSymmetric_(true)
92LSCPreconditionerFactory::LSCPreconditionerFactory() : isSymmetric_(true)
99LinearOp LSCPreconditionerFactory::buildPreconditionerOperator(BlockedLinearOp & blockOp,BlockPreconditionerState & state)
const
101 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildPreconditionerOperator",10);
102 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
103 Teko_DEBUG_EXPR(Teuchos::Time totalTimer(
""));
104 Teko_DEBUG_EXPR(totalTimer.start());
107 LinearOp F = blockOp->getBlock(0,0);
108 LinearOp B = blockOp->getBlock(1,0);
109 LinearOp Bt = blockOp->getBlock(0,1);
115 Teko_DEBUG_EXPR(timer.start(
true));
116 invOpsStrategy_->buildState(blockOp,state);
117 Teko_DEBUG_EXPR(timer.stop());
118 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO BuildStateTime = " << timer.totalElapsedTime(),2);
121 Teko_DEBUG_EXPR(timer.start(
true));
122 LinearOp invF = invOpsStrategy_->getInvF(blockOp,state);
123 LinearOp invBQBtmC = invOpsStrategy_->getInvBQBt(blockOp,state);
124 LinearOp invBHBtmC = invOpsStrategy_->getInvBHBt(blockOp,state);
125 LinearOp outerStab = invOpsStrategy_->getOuterStabilization(blockOp,state);
126 LinearOp innerStab = invOpsStrategy_->getInnerStabilization(blockOp,state);
129 LinearOp invMass = invOpsStrategy_->getInvMass(blockOp,state);
130 LinearOp HScaling = invOpsStrategy_->getHScaling(blockOp,state);
131 if(invMass==Teuchos::null) invMass = identity<double>(F->range());
132 if(HScaling==Teuchos::null) HScaling = identity<double>(F->range());
133 Teko_DEBUG_EXPR(timer.stop());
134 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO GetInvTime = " << timer.totalElapsedTime(),2);
141 multiply( multiply(B,invMass), F , multiply(HScaling,Bt));
142 if(innerStab!=Teuchos::null)
143 M = add(M, innerStab);
147 if(outerStab!=Teuchos::null)
148 invPschur = add(multiply(invBQBtmC, M , invBHBtmC), outerStab);
150 invPschur = multiply(invBQBtmC, M , invBHBtmC);
153 if(invOpsStrategy_->useFullLDU()) {
154 Teko_DEBUG_EXPR(totalTimer.stop());
155 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(),2);
158 return createLU2x2InverseOp(blockOp,invF,invPschur,
"LSC-LDU");
161 std::vector<LinearOp> invDiag(2);
163 invDiag[1] = Thyra::scale(-1.0,invPschur);
166 BlockedLinearOp U = getUpperTriBlocks(blockOp);
168 Teko_DEBUG_EXPR(totalTimer.stop());
169 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(),2);
172 return createBlockUpperTriInverseOp(U,invDiag,
"LSC-Upper");
177void LSCPreconditionerFactory::initializeFromParameterList(
const Teuchos::ParameterList & pl)
179 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::initializeFromParameterList",10);
181 RCP<const InverseLibrary> invLib = getInverseLibrary();
183 if(pl.isParameter(
"Is Symmetric"))
184 isSymmetric_ = pl.get<
bool>(
"Is Symmetric");
186 std::string name =
"Basic Inverse";
187 if(pl.isParameter(
"Strategy Name"))
188 name = pl.get<std::string>(
"Strategy Name");
189 const Teuchos::ParameterEntry * pe = pl.getEntryPtr(
"Strategy Settings");
192 if(name!=
"Basic Inverse" && pe==0) {
193 RCP<Teuchos::FancyOStream> out = getOutputStream();
194 *out <<
"LSC Construction failed: ";
195 *out <<
"Strategy \"" << name <<
"\" requires a \"Strategy Settings\" sublist" << std::endl;
196 throw std::runtime_error(
"LSC Construction failed: Strategy Settings not set");
200 Teuchos::RCP<const Teuchos::ParameterList> stratPL = Teuchos::rcpFromRef(pl);
202 stratPL = Teuchos::rcpFromRef(pl.sublist(
"Strategy Settings"));
205 RCP<LSCStrategy> strategy = buildStrategy(name,*stratPL,invLib,getRequestHandler());
208 if(strategy==Teuchos::null) {
209 RCP<Teuchos::FancyOStream> out = getOutputStream();
210 *out <<
"LSC Construction failed: ";
211 *out <<
"Strategy \"" << name <<
"\" could not be constructed" << std::endl;
212 throw std::runtime_error(
"LSC Construction failed: Strategy could not be constructed");
215 strategy->setSymmetric(isSymmetric_);
216 invOpsStrategy_ = strategy;
220Teuchos::RCP<Teuchos::ParameterList> LSCPreconditionerFactory::getRequestedParameters()
const
222 return invOpsStrategy_->getRequestedParameters();
226bool LSCPreconditionerFactory::updateRequestedParameters(
const Teuchos::ParameterList & pl)
228 return invOpsStrategy_->updateRequestedParameters(pl);
236CloneFactory<LSCStrategy> LSCPreconditionerFactory::strategyBuilder_;
250RCP<LSCStrategy> LSCPreconditionerFactory::buildStrategy(
const std::string & name,
251 const Teuchos::ParameterList & settings,
252 const RCP<const InverseLibrary> & invLib,
253 const RCP<RequestHandler> & rh)
255 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildStrategy",10);
258 if(strategyBuilder_.cloneCount()==0) initializeStrategyBuilder();
261 Teko_DEBUG_MSG(
"Building LSC strategy \"" << name <<
"\"",1);
262 RCP<LSCStrategy> strategy = strategyBuilder_.build(name);
264 if(strategy==Teuchos::null)
return Teuchos::null;
268 strategy->setRequestHandler(rh);
269 strategy->initializeFromParameterList(settings,*invLib);
287void LSCPreconditionerFactory::addStrategy(
const std::string & name,
const RCP<Cloneable> & clone)
290 if(strategyBuilder_.cloneCount()==0) initializeStrategyBuilder();
293 strategyBuilder_.addClone(name,clone);
297void LSCPreconditionerFactory::initializeStrategyBuilder()
299 RCP<Cloneable> clone;
302 clone = rcp(
new AutoClone<InvLSCStrategy>());
303 strategyBuilder_.addClone(
"Basic Inverse",clone);
306 clone = rcp(
new AutoClone<PresLaplaceLSCStrategy>());
307 strategyBuilder_.addClone(
"Pressure Laplace",clone);
310 clone = rcp(
new AutoClone<LSCSIMPLECStrategy>());
311 strategyBuilder_.addClone(
"SIMPLEC",clone);
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
LinearOp adjoint(ModifiableLinearOp &a)
Construct an implicit adjoint of the linear operators.