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"
69 using Teuchos::rcp_dynamic_cast;
72 using Thyra::identity;
73 using Thyra::multiply;
76 LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp& invF,
const LinearOp& invBQBtmC,
77 const LinearOp& invD,
const LinearOp& invMass)
78 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF, invBQBtmC, invD, invMass))),
82 LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp& invF,
const LinearOp& invBQBtmC,
83 const LinearOp& invMass)
84 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF, invBQBtmC, invMass))), isSymmetric_(true) {}
87 LSCPreconditionerFactory::LSCPreconditionerFactory(
const RCP<LSCStrategy>& strategy)
88 : invOpsStrategy_(strategy), isSymmetric_(true) {}
90 LSCPreconditionerFactory::LSCPreconditionerFactory() : isSymmetric_(true) {}
96 LinearOp LSCPreconditionerFactory::buildPreconditionerOperator(
97 BlockedLinearOp& blockOp, BlockPreconditionerState& state)
const {
98 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildPreconditionerOperator", 10);
99 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
100 Teko_DEBUG_EXPR(Teuchos::Time totalTimer(
""));
101 Teko_DEBUG_EXPR(totalTimer.start());
104 LinearOp F = blockOp->getBlock(0, 0);
105 LinearOp B = blockOp->getBlock(1, 0);
106 LinearOp Bt = blockOp->getBlock(0, 1);
108 if (not isSymmetric_) Bt = scale(-1.0, adjoint(B));
111 Teko_DEBUG_EXPR(timer.start(
true));
112 invOpsStrategy_->buildState(blockOp, state);
113 Teko_DEBUG_EXPR(timer.stop());
114 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO BuildStateTime = " << timer.totalElapsedTime(), 2);
117 Teko_DEBUG_EXPR(timer.start(
true));
118 LinearOp invF = invOpsStrategy_->getInvF(blockOp, state);
119 LinearOp invBQBtmC = invOpsStrategy_->getInvBQBt(blockOp, state);
120 LinearOp invBHBtmC = invOpsStrategy_->getInvBHBt(blockOp, state);
121 LinearOp outerStab = invOpsStrategy_->getOuterStabilization(blockOp, state);
122 LinearOp innerStab = invOpsStrategy_->getInnerStabilization(blockOp, state);
125 LinearOp invMass = invOpsStrategy_->getInvMass(blockOp, state);
126 LinearOp HScaling = invOpsStrategy_->getHScaling(blockOp, state);
127 if (invMass == Teuchos::null) invMass = identity<double>(F->range());
128 if (HScaling == Teuchos::null) HScaling = identity<double>(F->range());
129 Teko_DEBUG_EXPR(timer.stop());
130 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO GetInvTime = " << timer.totalElapsedTime(), 2);
137 multiply(multiply(B, invMass), F, multiply(HScaling, Bt));
138 if (innerStab != Teuchos::null)
139 M = add(M, innerStab);
143 if (outerStab != Teuchos::null)
144 invPschur = add(multiply(invBQBtmC, M, invBHBtmC), outerStab);
146 invPschur = multiply(invBQBtmC, M, invBHBtmC);
149 if (invOpsStrategy_->useFullLDU()) {
150 Teko_DEBUG_EXPR(totalTimer.stop());
151 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(), 2);
154 return createLU2x2InverseOp(blockOp, invF, invPschur,
"LSC-LDU");
157 std::vector<LinearOp> invDiag(2);
159 invDiag[1] = Thyra::scale(-1.0, invPschur);
162 BlockedLinearOp U = getUpperTriBlocks(blockOp);
164 Teko_DEBUG_EXPR(totalTimer.stop());
165 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(), 2);
168 return createBlockUpperTriInverseOp(U, invDiag,
"LSC-Upper");
173 void LSCPreconditionerFactory::initializeFromParameterList(
const Teuchos::ParameterList& pl) {
174 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::initializeFromParameterList", 10);
176 RCP<const InverseLibrary> invLib = getInverseLibrary();
178 if (pl.isParameter(
"Is Symmetric")) isSymmetric_ = pl.get<
bool>(
"Is Symmetric");
180 std::string name =
"Basic Inverse";
181 if (pl.isParameter(
"Strategy Name")) name = pl.get<std::string>(
"Strategy Name");
182 const Teuchos::ParameterEntry* pe = pl.getEntryPtr(
"Strategy Settings");
185 if (name !=
"Basic Inverse" && pe == 0) {
186 RCP<Teuchos::FancyOStream> out = getOutputStream();
187 *out <<
"LSC Construction failed: ";
188 *out <<
"Strategy \"" << name <<
"\" requires a \"Strategy Settings\" sublist" << std::endl;
189 throw std::runtime_error(
"LSC Construction failed: Strategy Settings not set");
193 Teuchos::RCP<const Teuchos::ParameterList> stratPL = Teuchos::rcpFromRef(pl);
194 if (pe != 0) stratPL = Teuchos::rcpFromRef(pl.sublist(
"Strategy Settings"));
197 RCP<LSCStrategy> strategy = buildStrategy(name, *stratPL, invLib, getRequestHandler());
200 if (strategy == Teuchos::null) {
201 RCP<Teuchos::FancyOStream> out = getOutputStream();
202 *out <<
"LSC Construction failed: ";
203 *out <<
"Strategy \"" << name <<
"\" could not be constructed" << std::endl;
204 throw std::runtime_error(
"LSC Construction failed: Strategy could not be constructed");
207 strategy->setSymmetric(isSymmetric_);
208 invOpsStrategy_ = strategy;
212 Teuchos::RCP<Teuchos::ParameterList> LSCPreconditionerFactory::getRequestedParameters()
const {
213 return invOpsStrategy_->getRequestedParameters();
217 bool LSCPreconditionerFactory::updateRequestedParameters(
const Teuchos::ParameterList& pl) {
218 return invOpsStrategy_->updateRequestedParameters(pl);
226 CloneFactory<LSCStrategy> LSCPreconditionerFactory::strategyBuilder_;
240 RCP<LSCStrategy> LSCPreconditionerFactory::buildStrategy(
const std::string& name,
241 const Teuchos::ParameterList& settings,
242 const RCP<const InverseLibrary>& invLib,
243 const RCP<RequestHandler>& rh) {
244 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildStrategy", 10);
247 if (strategyBuilder_.cloneCount() == 0) initializeStrategyBuilder();
250 Teko_DEBUG_MSG(
"Building LSC strategy \"" << name <<
"\"", 1);
251 RCP<LSCStrategy> strategy = strategyBuilder_.build(name);
253 if (strategy == Teuchos::null)
return Teuchos::null;
257 strategy->setRequestHandler(rh);
258 strategy->initializeFromParameterList(settings, *invLib);
276 void LSCPreconditionerFactory::addStrategy(
const std::string& name,
const RCP<Cloneable>& clone) {
278 if (strategyBuilder_.cloneCount() == 0) initializeStrategyBuilder();
281 strategyBuilder_.addClone(name, clone);
285 void LSCPreconditionerFactory::initializeStrategyBuilder() {
286 RCP<Cloneable> clone;
289 clone = rcp(
new AutoClone<InvLSCStrategy>());
290 strategyBuilder_.addClone(
"Basic Inverse", clone);
293 clone = rcp(
new AutoClone<PresLaplaceLSCStrategy>());
294 strategyBuilder_.addClone(
"Pressure Laplace", clone);
297 clone = rcp(
new AutoClone<LSCSIMPLECStrategy>());
298 strategyBuilder_.addClone(
"SIMPLEC", clone);