47 #include "NS/Teko_InvLSCStrategy.hpp"
49 #include "Thyra_DefaultDiagonalLinearOp.hpp"
50 #include "Thyra_EpetraThyraWrappers.hpp"
51 #include "Thyra_get_Epetra_Operator.hpp"
52 #include "Thyra_EpetraLinearOp.hpp"
53 #include "Thyra_VectorStdOps.hpp"
55 #include "Epetra_Vector.h"
56 #include "Epetra_Map.h"
58 #include "EpetraExt_RowMatrixOut.h"
59 #include "EpetraExt_MultiVectorOut.h"
60 #include "EpetraExt_VectorOut.h"
62 #include "Teuchos_Time.hpp"
63 #include "Teuchos_TimeMonitor.hpp"
67 #include "NS/Teko_LSCPreconditionerFactory.hpp"
68 #include "Teko_EpetraHelpers.hpp"
69 #include "Teko_EpetraOperatorWrapper.hpp"
70 #include "Teko_TpetraHelpers.hpp"
72 #include "Thyra_TpetraLinearOp.hpp"
75 using Teuchos::rcp_dynamic_cast;
76 using Teuchos::rcp_const_cast;
87 InvLSCStrategy::InvLSCStrategy()
88 : massMatrix_(Teuchos::null), invFactoryF_(Teuchos::null), invFactoryS_(Teuchos::null), eigSolveParam_(5)
89 , rowZeroingNeeded_(false), useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal)
90 , isSymmetric_(true), assumeStable_(false)
93 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & factory,
bool rzn)
94 : massMatrix_(Teuchos::null), invFactoryF_(factory), invFactoryS_(factory), eigSolveParam_(5), rowZeroingNeeded_(rzn)
95 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal)
96 , isSymmetric_(true), assumeStable_(false)
99 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & invFactF,
100 const Teuchos::RCP<InverseFactory> & invFactS,
102 : massMatrix_(Teuchos::null), invFactoryF_(invFactF), invFactoryS_(invFactS), eigSolveParam_(5), rowZeroingNeeded_(rzn)
103 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal)
104 , isSymmetric_(true), assumeStable_(false)
107 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & factory,LinearOp & mass,
bool rzn)
108 : massMatrix_(mass), invFactoryF_(factory), invFactoryS_(factory), eigSolveParam_(5), rowZeroingNeeded_(rzn)
109 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal)
110 , isSymmetric_(true), assumeStable_(false)
113 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & invFactF,
114 const Teuchos::RCP<InverseFactory> & invFactS,
115 LinearOp & mass,
bool rzn)
116 : massMatrix_(mass), invFactoryF_(invFactF), invFactoryS_(invFactS), eigSolveParam_(5), rowZeroingNeeded_(rzn)
117 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal)
118 , isSymmetric_(true), assumeStable_(false)
125 Teko_DEBUG_SCOPE(
"InvLSCStrategy::buildState",10);
128 TEUCHOS_ASSERT(lscState!=0);
132 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
136 Teko_DEBUG_SCOPE(
"LSC::buildState constructing operators",1);
137 Teko_DEBUG_EXPR(timer.start(
true));
139 initializeState(A,lscState);
141 Teko_DEBUG_EXPR(timer.stop());
142 Teko_DEBUG_MSG(
"LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1);
147 Teko_DEBUG_SCOPE(
"LSC::buildState calculating inverses",1);
148 Teko_DEBUG_EXPR(timer.start(
true));
150 computeInverses(A,lscState);
152 Teko_DEBUG_EXPR(timer.stop());
153 Teko_DEBUG_MSG(
"LSC::buildState BuildInvTime = " << timer.totalElapsedTime(),1);
177 TEUCHOS_ASSERT(lscState!=0);
180 return lscState->
aiD_;
186 TEUCHOS_ASSERT(lscState!=0);
194 if(hScaling_!=Teuchos::null)
return hScaling_;
195 return getInvMass(A,state);
199 void InvLSCStrategy::initializeState(
const BlockedLinearOp & A,
LSCPrecondState * state)
const
201 Teko_DEBUG_SCOPE(
"InvLSCStrategy::initializeState",10);
203 const LinearOp F = getBlock(0,0,A);
204 const LinearOp Bt = getBlock(0,1,A);
205 const LinearOp B = getBlock(1,0,A);
206 const LinearOp C = getBlock(1,1,A);
209 LinearOp G = isSymmetric_ ? Bt : adjoint(D);
211 bool isStabilized = assumeStable_ ?
false : (not isZeroOp(C));
219 if(massMatrix_==Teuchos::null) {
220 Teko_DEBUG_MSG(
"LSC::initializeState Build Scaling <F> type \""
221 << getDiagonalName(scaleType_) <<
"\"" ,1);
222 state->
invMass_ = getInvDiagonalOp(F,scaleType_);
224 else if(state->
invMass_==Teuchos::null) {
225 Teko_DEBUG_MSG(
"LSC::initializeState Build Scaling <mass> type \""
226 << getDiagonalName(scaleType_) <<
"\"" ,1);
227 state->
invMass_ = getInvDiagonalOp(massMatrix_,scaleType_);
233 Teko_DEBUG_MSG(
"Computed BQBt",10);
236 if(wScaling_!=Teuchos::null && hScaling_==Teuchos::null) {
238 RCP<const Thyra::VectorBase<double> > w = wScaling_->col(0);
239 RCP<const Thyra::VectorBase<double> > iQu
240 = rcp_dynamic_cast<
const Thyra::DiagonalLinearOpBase<double> >(state->
invMass_)->getDiag();
241 RCP<Thyra::VectorBase<double> > h = Thyra::createMember(iQu->space());
243 Thyra::put_scalar(0.0,h.ptr());
244 Thyra::ele_wise_prod(1.0,*w,*iQu,h.ptr());
245 hScaling_ = Teuchos::rcp(
new Thyra::DefaultDiagonalLinearOp<double>(h));
248 LinearOp H = hScaling_;
249 if(H==Teuchos::null && not isSymmetric_)
256 RCP<Teuchos::Time> time = Teuchos::TimeMonitor::getNewTimer(
"InvLSCStrategy::initializeState Build BHBt");
257 Teuchos::TimeMonitor timer(*time);
260 state->
BHBt_ = explicitMultiply(D,H,G,state->
BHBt_);
264 if(not isStabilized) {
269 state->
aiD_ = Teuchos::null;
278 if(!Teko::TpetraHelpers::isTpetraLinearOp(F)){
279 const RCP<const Epetra_Operator> epF = Thyra::get_Epetra_Operator(*F);
280 if(epF!=Teuchos::null && rowZeroingNeeded_) {
282 const RCP<const Epetra_CrsMatrix> crsF = rcp_dynamic_cast<
const Epetra_CrsMatrix>(epF);
285 if(crsF!=Teuchos::null) {
286 std::vector<int> zeroIndices;
289 Teko::Epetra::identityRowIndices(crsF->RowMap(), *crsF,zeroIndices);
298 RCP<const Tpetra::CrsMatrix<ST,LO,GO,NT> > crsF = Teko::TpetraHelpers::getTpetraCrsMatrix(F, &scalar, &transp);
300 std::vector<GO> zeroIndices;
303 Teko::TpetraHelpers::identityRowIndices(*crsF->getRowMap(), *crsF,zeroIndices);
306 modF = Thyra::tpetraLinearOp<ST,LO,GO,NT>(Thyra::tpetraVectorSpace<ST,LO,GO,NT>(crsF->getDomainMap()),Thyra::tpetraVectorSpace<ST,LO,GO,NT>(crsF->getRangeMap()),rcp(
new Teko::TpetraHelpers::ZeroedOperator(zeroIndices,crsF)));
310 Teko_DEBUG_MSG(
"Calculating gamma",10);
311 LinearOp iQuF = multiply(state->
invMass_,modF);
314 Teko::LinearOp stabMatrix;
315 state->
gamma_ = std::fabs(Teko::computeSpectralRad(iQuF,5e-2,
false,eigSolveParam_))/3.0;
316 Teko_DEBUG_MSG(
"Calculated gamma",10);
317 if(userPresStabMat_!=Teuchos::null) {
318 Teko::LinearOp invDGl = Teko::getInvDiagonalOp(userPresStabMat_);
319 Teko::LinearOp gammaOp = multiply(invDGl,C);
320 state->
gamma_ *= std::fabs(Teko::computeSpectralRad(gammaOp,5e-2,
false,eigSolveParam_));
321 stabMatrix = userPresStabMat_;
327 LinearOp invDiagF = getInvDiagonalOp(F);
328 Teko::ModifiableLinearOp modB_idF_Bt = state->
getInverse(
"BidFBt");
329 modB_idF_Bt = explicitMultiply(B,invDiagF,Bt,modB_idF_Bt);
331 const LinearOp B_idF_Bt = modB_idF_Bt;
333 MultiVector vec_D = getDiagonal(B_idF_Bt);
334 update(-1.0,getDiagonal(C),1.0,vec_D);
335 const LinearOp invD = buildInvDiagonal(vec_D,
"inv(D)");
337 Teko_DEBUG_MSG(
"Calculating alpha",10);
338 const LinearOp BidFBtidD = multiply<double>(B_idF_Bt,invD);
339 double num = std::fabs(Teko::computeSpectralRad(BidFBtidD,5e-2,
false,eigSolveParam_));
340 Teko_DEBUG_MSG(
"Calculated alpha",10);
342 state->
aiD_ = Thyra::scale(state->
alpha_,invD);
345 Teko::ModifiableLinearOp BQBtmC = state->
getInverse(
"BQBtmC");
346 BQBtmC = explicitAdd(state->
BQBt_,scale(-state->
gamma_,stabMatrix),BQBtmC);
350 Teko::ModifiableLinearOp BHBtmC = state->
getInverse(
"BHBtmC");
354 BHBtmC = explicitAdd(state->
BHBt_,scale(-state->
gamma_,stabMatrix),BHBtmC);
358 Teko_DEBUG_MSG_BEGIN(5)
359 DEBUG_STREAM <<
"LSC Gamma Parameter = " << state->
gamma_ << std::endl;
360 DEBUG_STREAM <<
"LSC Alpha Parameter = " << state->
alpha_ << std::endl;
371 void InvLSCStrategy::computeInverses(
const BlockedLinearOp & A,
LSCPrecondState * state)
const
373 Teko_DEBUG_SCOPE(
"InvLSCStrategy::computeInverses",10);
374 Teko_DEBUG_EXPR(Teuchos::Time invTimer(
""));
376 const LinearOp F = getBlock(0,0,A);
381 Teko_DEBUG_MSG(
"LSC::computeInverses Building inv(F)",1);
382 Teko_DEBUG_EXPR(invTimer.start(
true));
383 InverseLinearOp invF = state->
getInverse(
"invF");
384 if(invF==Teuchos::null) {
390 Teko_DEBUG_EXPR(invTimer.stop());
391 Teko_DEBUG_MSG(
"LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1);
396 Teko_DEBUG_MSG(
"LSC::computeInverses Building inv(BQBtmC)",1);
397 Teko_DEBUG_EXPR(invTimer.start(
true));
398 const LinearOp BQBt = state->
getInverse(
"BQBtmC");
399 InverseLinearOp invBQBt = state->
getInverse(
"invBQBtmC");
400 if(invBQBt==Teuchos::null) {
406 Teko_DEBUG_EXPR(invTimer.stop());
407 Teko_DEBUG_MSG(
"LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1);
412 ModifiableLinearOp invBHBt = state->
getInverse(
"invBHBtmC");
413 if(hScaling_!=Teuchos::null || not isSymmetric_) {
415 Teko_DEBUG_MSG(
"LSC::computeInverses Building inv(BHBtmC)",1);
416 Teko_DEBUG_EXPR(invTimer.start(
true));
417 const LinearOp BHBt = state->
getInverse(
"BHBtmC");
418 if(invBHBt==Teuchos::null) {
424 Teko_DEBUG_EXPR(invTimer.stop());
425 Teko_DEBUG_MSG(
"LSC::computeInverses GetInvBHBt = " << invTimer.totalElapsedTime(),1);
427 else if(invBHBt==Teuchos::null) {
434 void InvLSCStrategy::initializeFromParameterList(
const Teuchos::ParameterList & pl,
const InverseLibrary & invLib)
437 std::string invStr=
"", invVStr=
"", invPStr=
"";
438 bool rowZeroing =
true;
440 scaleType_ = Diagonal;
443 if(pl.isParameter(
"Inverse Type"))
444 invStr = pl.get<std::string>(
"Inverse Type");
445 if(pl.isParameter(
"Inverse Velocity Type"))
446 invVStr = pl.get<std::string>(
"Inverse Velocity Type");
447 if(pl.isParameter(
"Inverse Pressure Type"))
448 invPStr = pl.get<std::string>(
"Inverse Pressure Type");
449 if(pl.isParameter(
"Ignore Boundary Rows"))
450 rowZeroing = pl.get<
bool>(
"Ignore Boundary Rows");
451 if(pl.isParameter(
"Use LDU"))
452 useLDU = pl.get<
bool>(
"Use LDU");
453 if(pl.isParameter(
"Use Mass Scaling"))
454 useMass_ = pl.get<
bool>(
"Use Mass Scaling");
457 if(pl.isParameter(
"Use W-Scaling"))
458 useWScaling_ = pl.get<
bool>(
"Use W-Scaling");
459 if(pl.isParameter(
"Eigen Solver Iterations"))
460 eigSolveParam_ = pl.get<
int>(
"Eigen Solver Iterations");
461 if(pl.isParameter(
"Scaling Type")) {
462 scaleType_ = getDiagonalType(pl.get<std::string>(
"Scaling Type"));
463 TEUCHOS_TEST_FOR_EXCEPT(scaleType_==NotDiag);
465 if(pl.isParameter(
"Assume Stable Discretization"))
466 assumeStable_ = pl.get<
bool>(
"Assume Stable Discretization");
468 Teko_DEBUG_MSG_BEGIN(5)
469 DEBUG_STREAM <<
"LSC Inverse Strategy Parameters: " << std::endl;
470 DEBUG_STREAM <<
" inv type = \"" << invStr <<
"\"" << std::endl;
471 DEBUG_STREAM <<
" inv v type = \"" << invVStr <<
"\"" << std::endl;
472 DEBUG_STREAM <<
" inv p type = \"" << invPStr <<
"\"" << std::endl;
473 DEBUG_STREAM <<
" bndry rows = " << rowZeroing << std::endl;
474 DEBUG_STREAM <<
" use ldu = " << useLDU << std::endl;
475 DEBUG_STREAM <<
" use mass = " << useMass_ << std::endl;
476 DEBUG_STREAM <<
" use w-scaling = " << useWScaling_ << std::endl;
477 DEBUG_STREAM <<
" assume stable = " << assumeStable_ << std::endl;
478 DEBUG_STREAM <<
" scale type = " << getDiagonalName(scaleType_) << std::endl;
479 DEBUG_STREAM <<
"LSC Inverse Strategy Parameter list: " << std::endl;
480 pl.print(DEBUG_STREAM);
484 if(invStr==
"") invStr =
"Amesos";
485 if(invVStr==
"") invVStr = invStr;
486 if(invPStr==
"") invPStr = invStr;
489 invFactoryF_ = invLib.getInverseFactory(invVStr);
490 invFactoryS_ = invFactoryF_;
492 invFactoryS_ = invLib.getInverseFactory(invPStr);
495 setUseFullLDU(useLDU);
496 setRowZeroing(rowZeroing);
499 Teuchos::RCP<Teko::RequestHandler> rh = getRequestHandler();
500 rh->preRequest<Teko::LinearOp>(Teko::RequestMesg(
"Velocity Mass Matrix"));
502 = rh->request<Teko::LinearOp>(Teko::RequestMesg(
"Velocity Mass Matrix"));
509 Teuchos::RCP<Teuchos::ParameterList> InvLSCStrategy::getRequestedParameters()
const
511 Teuchos::RCP<Teuchos::ParameterList> result;
512 Teuchos::RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList());
515 RCP<Teuchos::ParameterList> fList = invFactoryF_->getRequestedParameters();
516 if(fList!=Teuchos::null) {
517 Teuchos::ParameterList::ConstIterator itr;
518 for(itr=fList->begin();itr!=fList->end();++itr)
519 pl->setEntry(itr->first,itr->second);
524 RCP<Teuchos::ParameterList> sList = invFactoryS_->getRequestedParameters();
525 if(sList!=Teuchos::null) {
526 Teuchos::ParameterList::ConstIterator itr;
527 for(itr=sList->begin();itr!=sList->end();++itr)
528 pl->setEntry(itr->first,itr->second);
534 pl->set<Teko::LinearOp>(
"W-Scaling Vector", Teuchos::null,
"W-Scaling Vector");
542 bool InvLSCStrategy::updateRequestedParameters(
const Teuchos::ParameterList & pl)
544 Teko_DEBUG_SCOPE(
"InvLSCStrategy::updateRequestedParameters",10);
548 result &= invFactoryF_->updateRequestedParameters(pl);
549 result &= invFactoryS_->updateRequestedParameters(pl);
553 Teko::MultiVector wScale = pl.get<Teko::MultiVector>(
"W-Scaling Vector");
555 if(wScale==Teuchos::null)
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
virtual Teko::InverseLinearOp getInverse(const std::string &name) const
Get a named inverse from the state object.
An implementation of a state object for block preconditioners.
virtual bool isInitialized() const
virtual void addInverse(const std::string &name, const Teko::InverseLinearOp &ilo)
Add a named inverse to the state object.
LinearOp invMass_
Inverse mass operator ( )
Preconditioner state for the LSC factory.
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
virtual void setInitialized(bool init=true)