10 #include "Teko_LSCPreconditionerFactory.hpp"
12 #include "Thyra_DefaultMultipliedLinearOp.hpp"
13 #include "Thyra_DefaultAddedLinearOp.hpp"
14 #include "Thyra_DefaultIdentityLinearOp.hpp"
15 #include "Thyra_DefaultZeroLinearOp.hpp"
19 #include "Teko_BlockUpperTriInverseOp.hpp"
20 #include "Teko_StaticLSCStrategy.hpp"
21 #include "Teko_InvLSCStrategy.hpp"
22 #include "Teko_PresLaplaceLSCStrategy.hpp"
23 #include "Teko_LSCSIMPLECStrategy.hpp"
25 #include "Teuchos_Time.hpp"
32 using Teuchos::rcp_dynamic_cast;
35 using Thyra::identity;
36 using Thyra::multiply;
39 LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp& invF,
const LinearOp& invBQBtmC,
40 const LinearOp& invD,
const LinearOp& invMass)
41 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF, invBQBtmC, invD, invMass))),
45 LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp& invF,
const LinearOp& invBQBtmC,
46 const LinearOp& invMass)
47 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF, invBQBtmC, invMass))), isSymmetric_(true) {}
50 LSCPreconditionerFactory::LSCPreconditionerFactory(
const RCP<LSCStrategy>& strategy)
51 : invOpsStrategy_(strategy), isSymmetric_(true) {}
53 LSCPreconditionerFactory::LSCPreconditionerFactory() : isSymmetric_(true) {}
59 LinearOp LSCPreconditionerFactory::buildPreconditionerOperator(
60 BlockedLinearOp& blockOp, BlockPreconditionerState& state)
const {
61 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildPreconditionerOperator", 10);
62 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
63 Teko_DEBUG_EXPR(Teuchos::Time totalTimer(
""));
64 Teko_DEBUG_EXPR(totalTimer.start());
67 LinearOp F = blockOp->getBlock(0, 0);
68 LinearOp B = blockOp->getBlock(1, 0);
69 LinearOp Bt = blockOp->getBlock(0, 1);
71 if (not isSymmetric_) Bt = scale(-1.0, adjoint(B));
74 Teko_DEBUG_EXPR(timer.start(
true));
75 invOpsStrategy_->buildState(blockOp, state);
76 Teko_DEBUG_EXPR(timer.stop());
77 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO BuildStateTime = " << timer.totalElapsedTime(), 2);
80 Teko_DEBUG_EXPR(timer.start(
true));
81 LinearOp invF = invOpsStrategy_->getInvF(blockOp, state);
82 LinearOp invBQBtmC = invOpsStrategy_->getInvBQBt(blockOp, state);
83 LinearOp invBHBtmC = invOpsStrategy_->getInvBHBt(blockOp, state);
84 LinearOp outerStab = invOpsStrategy_->getOuterStabilization(blockOp, state);
85 LinearOp innerStab = invOpsStrategy_->getInnerStabilization(blockOp, state);
88 LinearOp invMass = invOpsStrategy_->getInvMass(blockOp, state);
89 LinearOp HScaling = invOpsStrategy_->getHScaling(blockOp, state);
90 if (invMass == Teuchos::null) invMass = identity<double>(F->range());
91 if (HScaling == Teuchos::null) HScaling = identity<double>(F->range());
92 Teko_DEBUG_EXPR(timer.stop());
93 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO GetInvTime = " << timer.totalElapsedTime(), 2);
100 multiply(multiply(B, invMass), F, multiply(HScaling, Bt));
101 if (innerStab != Teuchos::null)
102 M = add(M, innerStab);
106 if (outerStab != Teuchos::null)
107 invPschur = add(multiply(invBQBtmC, M, invBHBtmC), outerStab);
109 invPschur = multiply(invBQBtmC, M, invBHBtmC);
112 if (invOpsStrategy_->useFullLDU()) {
113 Teko_DEBUG_EXPR(totalTimer.stop());
114 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(), 2);
117 return createLU2x2InverseOp(blockOp, invF, invPschur,
"LSC-LDU");
120 std::vector<LinearOp> invDiag(2);
122 invDiag[1] = Thyra::scale(-1.0, invPschur);
125 BlockedLinearOp U = getUpperTriBlocks(blockOp);
127 Teko_DEBUG_EXPR(totalTimer.stop());
128 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(), 2);
131 return createBlockUpperTriInverseOp(U, invDiag,
"LSC-Upper");
136 void LSCPreconditionerFactory::initializeFromParameterList(
const Teuchos::ParameterList& pl) {
137 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::initializeFromParameterList", 10);
139 RCP<const InverseLibrary> invLib = getInverseLibrary();
141 if (pl.isParameter(
"Is Symmetric")) isSymmetric_ = pl.get<
bool>(
"Is Symmetric");
143 std::string name =
"Basic Inverse";
144 if (pl.isParameter(
"Strategy Name")) name = pl.get<std::string>(
"Strategy Name");
145 const Teuchos::ParameterEntry* pe = pl.getEntryPtr(
"Strategy Settings");
148 if (name !=
"Basic Inverse" && pe == 0) {
149 RCP<Teuchos::FancyOStream> out = getOutputStream();
150 *out <<
"LSC Construction failed: ";
151 *out <<
"Strategy \"" << name <<
"\" requires a \"Strategy Settings\" sublist" << std::endl;
152 throw std::runtime_error(
"LSC Construction failed: Strategy Settings not set");
156 Teuchos::RCP<const Teuchos::ParameterList> stratPL = Teuchos::rcpFromRef(pl);
157 if (pe != 0) stratPL = Teuchos::rcpFromRef(pl.sublist(
"Strategy Settings"));
160 RCP<LSCStrategy> strategy = buildStrategy(name, *stratPL, invLib, getRequestHandler());
163 if (strategy == Teuchos::null) {
164 RCP<Teuchos::FancyOStream> out = getOutputStream();
165 *out <<
"LSC Construction failed: ";
166 *out <<
"Strategy \"" << name <<
"\" could not be constructed" << std::endl;
167 throw std::runtime_error(
"LSC Construction failed: Strategy could not be constructed");
170 strategy->setSymmetric(isSymmetric_);
171 invOpsStrategy_ = strategy;
175 Teuchos::RCP<Teuchos::ParameterList> LSCPreconditionerFactory::getRequestedParameters()
const {
176 return invOpsStrategy_->getRequestedParameters();
180 bool LSCPreconditionerFactory::updateRequestedParameters(
const Teuchos::ParameterList& pl) {
181 return invOpsStrategy_->updateRequestedParameters(pl);
189 CloneFactory<LSCStrategy> LSCPreconditionerFactory::strategyBuilder_;
203 RCP<LSCStrategy> LSCPreconditionerFactory::buildStrategy(
const std::string& name,
204 const Teuchos::ParameterList& settings,
205 const RCP<const InverseLibrary>& invLib,
206 const RCP<RequestHandler>& rh) {
207 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildStrategy", 10);
210 if (strategyBuilder_.cloneCount() == 0) initializeStrategyBuilder();
213 Teko_DEBUG_MSG(
"Building LSC strategy \"" << name <<
"\"", 1);
214 RCP<LSCStrategy> strategy = strategyBuilder_.build(name);
216 if (strategy == Teuchos::null)
return Teuchos::null;
220 strategy->setRequestHandler(rh);
221 strategy->initializeFromParameterList(settings, *invLib);
239 void LSCPreconditionerFactory::addStrategy(
const std::string& name,
const RCP<Cloneable>& clone) {
241 if (strategyBuilder_.cloneCount() == 0) initializeStrategyBuilder();
244 strategyBuilder_.addClone(name, clone);
248 void LSCPreconditionerFactory::initializeStrategyBuilder() {
249 RCP<Cloneable> clone;
252 clone = rcp(
new AutoClone<InvLSCStrategy>());
253 strategyBuilder_.addClone(
"Basic Inverse", clone);
256 clone = rcp(
new AutoClone<PresLaplaceLSCStrategy>());
257 strategyBuilder_.addClone(
"Pressure Laplace", clone);
260 clone = rcp(
new AutoClone<LSCSIMPLECStrategy>());
261 strategyBuilder_.addClone(
"SIMPLEC", clone);