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"
53 #include "Thyra_get_Epetra_Operator.hpp"
57 #include "Teko_BlockUpperTriInverseOp.hpp"
58 #include "Teko_StaticLSCStrategy.hpp"
59 #include "Teko_InvLSCStrategy.hpp"
60 #include "Teko_PresLaplaceLSCStrategy.hpp"
61 #include "Teko_LSCSIMPLECStrategy.hpp"
63 #include "EpetraExt_RowMatrixOut.h"
65 #include "Teuchos_Time.hpp"
71 using Teuchos::rcp_dynamic_cast;
74 using Thyra::multiply;
76 using Thyra::identity;
79 LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp & invF,
const LinearOp & invBQBtmC,
80 const LinearOp & invD,
const LinearOp & invMass)
81 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF,invBQBtmC,invD,invMass))), isSymmetric_(true)
85 LSCPreconditionerFactory::LSCPreconditionerFactory(
const LinearOp & invF,
const LinearOp & invBQBtmC,
86 const LinearOp & invMass)
87 : invOpsStrategy_(rcp(new StaticLSCStrategy(invF,invBQBtmC,invMass))), isSymmetric_(true)
91 LSCPreconditionerFactory::LSCPreconditionerFactory(
const RCP<LSCStrategy> & strategy)
92 : invOpsStrategy_(strategy), isSymmetric_(true)
95 LSCPreconditionerFactory::LSCPreconditionerFactory() : isSymmetric_(true)
102 LinearOp LSCPreconditionerFactory::buildPreconditionerOperator(BlockedLinearOp & blockOp,BlockPreconditionerState & state)
const
104 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildPreconditionerOperator",10);
105 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
106 Teko_DEBUG_EXPR(Teuchos::Time totalTimer(
""));
107 Teko_DEBUG_EXPR(totalTimer.start());
110 LinearOp F = blockOp->getBlock(0,0);
111 LinearOp B = blockOp->getBlock(1,0);
112 LinearOp Bt = blockOp->getBlock(0,1);
115 Bt = scale(-1.0,adjoint(B));
118 Teko_DEBUG_EXPR(timer.start(
true));
119 invOpsStrategy_->buildState(blockOp,state);
120 Teko_DEBUG_EXPR(timer.stop());
121 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO BuildStateTime = " << timer.totalElapsedTime(),2);
124 Teko_DEBUG_EXPR(timer.start(
true));
125 LinearOp invF = invOpsStrategy_->getInvF(blockOp,state);
126 LinearOp invBQBtmC = invOpsStrategy_->getInvBQBt(blockOp,state);
127 LinearOp invBHBtmC = invOpsStrategy_->getInvBHBt(blockOp,state);
128 LinearOp outerStab = invOpsStrategy_->getOuterStabilization(blockOp,state);
129 LinearOp innerStab = invOpsStrategy_->getInnerStabilization(blockOp,state);
132 LinearOp invMass = invOpsStrategy_->getInvMass(blockOp,state);
133 LinearOp HScaling = invOpsStrategy_->getHScaling(blockOp,state);
134 if(invMass==Teuchos::null) invMass = identity<double>(F->range());
135 if(HScaling==Teuchos::null) HScaling = identity<double>(F->range());
136 Teko_DEBUG_EXPR(timer.stop());
137 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO GetInvTime = " << timer.totalElapsedTime(),2);
144 multiply( multiply(B,invMass), F , multiply(HScaling,Bt));
145 if(innerStab!=Teuchos::null)
146 M = add(M, innerStab);
150 if(outerStab!=Teuchos::null)
151 invPschur = add(multiply(invBQBtmC, M , invBHBtmC), outerStab);
153 invPschur = multiply(invBQBtmC, M , invBHBtmC);
156 if(invOpsStrategy_->useFullLDU()) {
157 Teko_DEBUG_EXPR(totalTimer.stop());
158 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(),2);
161 return createLU2x2InverseOp(blockOp,invF,invPschur,
"LSC-LDU");
164 std::vector<LinearOp> invDiag(2);
166 invDiag[1] = Thyra::scale(-1.0,invPschur);
169 BlockedLinearOp U = getUpperTriBlocks(blockOp);
171 Teko_DEBUG_EXPR(totalTimer.stop());
172 Teko_DEBUG_MSG(
"LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(),2);
175 return createBlockUpperTriInverseOp(U,invDiag,
"LSC-Upper");
180 void LSCPreconditionerFactory::initializeFromParameterList(
const Teuchos::ParameterList & pl)
182 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::initializeFromParameterList",10);
184 RCP<const InverseLibrary> invLib = getInverseLibrary();
186 if(pl.isParameter(
"Is Symmetric"))
187 isSymmetric_ = pl.get<
bool>(
"Is Symmetric");
189 std::string name =
"Basic Inverse";
190 if(pl.isParameter(
"Strategy Name"))
191 name = pl.get<std::string>(
"Strategy Name");
192 const Teuchos::ParameterEntry * pe = pl.getEntryPtr(
"Strategy Settings");
195 if(name!=
"Basic Inverse" && pe==0) {
196 RCP<Teuchos::FancyOStream> out = getOutputStream();
197 *out <<
"LSC Construction failed: ";
198 *out <<
"Strategy \"" << name <<
"\" requires a \"Strategy Settings\" sublist" << std::endl;
199 throw std::runtime_error(
"LSC Construction failed: Strategy Settings not set");
203 Teuchos::RCP<const Teuchos::ParameterList> stratPL = Teuchos::rcpFromRef(pl);
205 stratPL = Teuchos::rcpFromRef(pl.sublist(
"Strategy Settings"));
208 RCP<LSCStrategy> strategy = buildStrategy(name,*stratPL,invLib,getRequestHandler());
211 if(strategy==Teuchos::null) {
212 RCP<Teuchos::FancyOStream> out = getOutputStream();
213 *out <<
"LSC Construction failed: ";
214 *out <<
"Strategy \"" << name <<
"\" could not be constructed" << std::endl;
215 throw std::runtime_error(
"LSC Construction failed: Strategy could not be constructed");
218 strategy->setSymmetric(isSymmetric_);
219 invOpsStrategy_ = strategy;
223 Teuchos::RCP<Teuchos::ParameterList> LSCPreconditionerFactory::getRequestedParameters()
const
225 return invOpsStrategy_->getRequestedParameters();
229 bool LSCPreconditionerFactory::updateRequestedParameters(
const Teuchos::ParameterList & pl)
231 return invOpsStrategy_->updateRequestedParameters(pl);
239 CloneFactory<LSCStrategy> LSCPreconditionerFactory::strategyBuilder_;
253 RCP<LSCStrategy> LSCPreconditionerFactory::buildStrategy(
const std::string & name,
254 const Teuchos::ParameterList & settings,
255 const RCP<const InverseLibrary> & invLib,
256 const RCP<RequestHandler> & rh)
258 Teko_DEBUG_SCOPE(
"LSCPreconditionerFactory::buildStrategy",10);
261 if(strategyBuilder_.cloneCount()==0) initializeStrategyBuilder();
264 Teko_DEBUG_MSG(
"Building LSC strategy \"" << name <<
"\"",1);
265 RCP<LSCStrategy> strategy = strategyBuilder_.build(name);
267 if(strategy==Teuchos::null)
return Teuchos::null;
271 strategy->setRequestHandler(rh);
272 strategy->initializeFromParameterList(settings,*invLib);
290 void LSCPreconditionerFactory::addStrategy(
const std::string & name,
const RCP<Cloneable> & clone)
293 if(strategyBuilder_.cloneCount()==0) initializeStrategyBuilder();
296 strategyBuilder_.addClone(name,clone);
300 void LSCPreconditionerFactory::initializeStrategyBuilder()
302 RCP<Cloneable> clone;
305 clone = rcp(
new AutoClone<InvLSCStrategy>());
306 strategyBuilder_.addClone(
"Basic Inverse",clone);
309 clone = rcp(
new AutoClone<PresLaplaceLSCStrategy>());
310 strategyBuilder_.addClone(
"Pressure Laplace",clone);
313 clone = rcp(
new AutoClone<LSCSIMPLECStrategy>());
314 strategyBuilder_.addClone(
"SIMPLEC",clone);