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 "Epetra/Teko_EpetraHelpers.hpp" 69 #include "Epetra/Teko_EpetraOperatorWrapper.hpp" 72 using Teuchos::rcp_dynamic_cast;
73 using Teuchos::rcp_const_cast;
84 InvLSCStrategy::InvLSCStrategy()
85 : massMatrix_(
Teuchos::null), invFactoryF_(
Teuchos::null), invFactoryS_(
Teuchos::null), eigSolveParam_(5)
86 , rowZeroingNeeded_(false), useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(
Diagonal)
87 , isSymmetric_(true), assumeStable_(false)
90 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & factory,
bool rzn)
91 : massMatrix_(
Teuchos::null), invFactoryF_(factory), invFactoryS_(factory), eigSolveParam_(5), rowZeroingNeeded_(rzn)
92 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(
Diagonal)
93 , isSymmetric_(true), assumeStable_(false)
96 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & invFactF,
97 const Teuchos::RCP<InverseFactory> & invFactS,
99 : massMatrix_(
Teuchos::null), invFactoryF_(invFactF), invFactoryS_(invFactS), eigSolveParam_(5), rowZeroingNeeded_(rzn)
100 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(
Diagonal)
101 , isSymmetric_(true), assumeStable_(false)
104 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & factory,LinearOp & mass,
bool rzn)
105 : massMatrix_(mass), invFactoryF_(factory), invFactoryS_(factory), eigSolveParam_(5), rowZeroingNeeded_(rzn)
106 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(
Diagonal)
107 , isSymmetric_(true), assumeStable_(false)
110 InvLSCStrategy::InvLSCStrategy(
const Teuchos::RCP<InverseFactory> & invFactF,
111 const Teuchos::RCP<InverseFactory> & invFactS,
112 LinearOp & mass,
bool rzn)
113 : massMatrix_(mass), invFactoryF_(invFactF), invFactoryS_(invFactS), eigSolveParam_(5), rowZeroingNeeded_(rzn)
114 , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(
Diagonal)
115 , isSymmetric_(true), assumeStable_(false)
122 Teko_DEBUG_SCOPE(
"InvLSCStrategy::buildState",10);
125 TEUCHOS_ASSERT(lscState!=0);
129 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
133 Teko_DEBUG_SCOPE(
"LSC::buildState constructing operators",1);
134 Teko_DEBUG_EXPR(timer.start(
true));
136 initializeState(A,lscState);
138 Teko_DEBUG_EXPR(timer.stop());
139 Teko_DEBUG_MSG(
"LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1);
144 Teko_DEBUG_SCOPE(
"LSC::buildState calculating inverses",1);
145 Teko_DEBUG_EXPR(timer.start(
true));
147 computeInverses(A,lscState);
149 Teko_DEBUG_EXPR(timer.stop());
150 Teko_DEBUG_MSG(
"LSC::buildState BuildInvTime = " << timer.totalElapsedTime(),1);
174 TEUCHOS_ASSERT(lscState!=0);
177 return lscState->
aiD_;
183 TEUCHOS_ASSERT(lscState!=0);
191 if(hScaling_!=Teuchos::null)
return hScaling_;
192 return getInvMass(A,state);
196 void InvLSCStrategy::initializeState(
const BlockedLinearOp & A,
LSCPrecondState * state)
const 198 Teko_DEBUG_SCOPE(
"InvLSCStrategy::initializeState",10);
201 const LinearOp Bt =
getBlock(0,1,A);
206 LinearOp G = isSymmetric_ ? Bt :
adjoint(D);
208 bool isStabilized = assumeStable_ ?
false : (not isZeroOp(C));
216 if(massMatrix_==Teuchos::null) {
217 Teko_DEBUG_MSG(
"LSC::initializeState Build Scaling <F> type \"" 218 << getDiagonalName(scaleType_) <<
"\"" ,1);
219 state->
invMass_ = getInvDiagonalOp(F,scaleType_);
221 else if(state->
invMass_==Teuchos::null) {
222 Teko_DEBUG_MSG(
"LSC::initializeState Build Scaling <mass> type \"" 223 << getDiagonalName(scaleType_) <<
"\"" ,1);
224 state->
invMass_ = getInvDiagonalOp(massMatrix_,scaleType_);
230 Teko_DEBUG_MSG(
"Computed BQBt",10);
233 if(wScaling_!=Teuchos::null && hScaling_==Teuchos::null) {
235 RCP<const Thyra::VectorBase<double> > w = wScaling_->col(0);
236 RCP<const Thyra::VectorBase<double> > iQu
237 = rcp_dynamic_cast<
const Thyra::DiagonalLinearOpBase<double> >(state->
invMass_)->getDiag();
238 RCP<Thyra::VectorBase<double> > h = Thyra::createMember(iQu->space());
240 Thyra::put_scalar(0.0,h.ptr());
241 Thyra::ele_wise_prod(1.0,*w,*iQu,h.ptr());
242 hScaling_ = Teuchos::rcp(
new Thyra::DefaultDiagonalLinearOp<double>(h));
245 LinearOp H = hScaling_;
246 if(H==Teuchos::null && not isSymmetric_)
253 RCP<Teuchos::Time> time = Teuchos::TimeMonitor::getNewTimer(
"InvLSCStrategy::initializeState Build BHBt");
254 Teuchos::TimeMonitor timer(*time);
257 state->
BHBt_ = explicitMultiply(D,H,G,state->
BHBt_);
261 if(not isStabilized) {
266 state->
aiD_ = Teuchos::null;
275 const RCP<const Epetra_Operator> epF = Thyra::get_Epetra_Operator(*F);
276 if(epF!=Teuchos::null && rowZeroingNeeded_) {
278 const RCP<const Epetra_CrsMatrix> crsF = rcp_dynamic_cast<
const Epetra_CrsMatrix>(epF);
281 if(crsF!=Teuchos::null) {
282 std::vector<int> zeroIndices;
285 Teko::Epetra::identityRowIndices(crsF->RowMap(), *crsF,zeroIndices);
293 Teko_DEBUG_MSG(
"Calculating gamma",10);
294 LinearOp iQuF = multiply(state->
invMass_,modF);
297 Teko::LinearOp stabMatrix;
299 Teko_DEBUG_MSG(
"Calculated gamma",10);
300 if(userPresStabMat_!=Teuchos::null) {
301 Teko::LinearOp invDGl = Teko::getInvDiagonalOp(userPresStabMat_);
302 Teko::LinearOp gammaOp = multiply(invDGl,C);
304 stabMatrix = userPresStabMat_;
310 LinearOp invDiagF = getInvDiagonalOp(F);
311 Teko::ModifiableLinearOp modB_idF_Bt = state->
getInverse(
"BidFBt");
312 modB_idF_Bt = explicitMultiply(B,invDiagF,Bt,modB_idF_Bt);
314 const LinearOp B_idF_Bt = modB_idF_Bt;
316 MultiVector vec_D = getDiagonal(B_idF_Bt);
317 update(-1.0,getDiagonal(C),1.0,vec_D);
318 const LinearOp invD = buildInvDiagonal(vec_D,
"inv(D)");
320 Teko_DEBUG_MSG(
"Calculating alpha",10);
321 const LinearOp BidFBtidD = multiply<double>(B_idF_Bt,invD);
323 Teko_DEBUG_MSG(
"Calculated alpha",10);
325 state->
aiD_ = Thyra::scale(state->
alpha_,invD);
328 Teko::ModifiableLinearOp BQBtmC = state->
getInverse(
"BQBtmC");
333 Teko::ModifiableLinearOp BHBtmC = state->
getInverse(
"BHBtmC");
341 Teko_DEBUG_MSG_BEGIN(5)
342 DEBUG_STREAM <<
"LSC Gamma Parameter = " << state->
gamma_ << std::endl;
343 DEBUG_STREAM <<
"LSC Alpha Parameter = " << state->
alpha_ << std::endl;
354 void InvLSCStrategy::computeInverses(
const BlockedLinearOp & A,
LSCPrecondState * state)
const 356 Teko_DEBUG_SCOPE(
"InvLSCStrategy::computeInverses",10);
357 Teko_DEBUG_EXPR(Teuchos::Time invTimer(
""));
364 Teko_DEBUG_MSG(
"LSC::computeInverses Building inv(F)",1);
365 Teko_DEBUG_EXPR(invTimer.start(
true));
366 InverseLinearOp invF = state->
getInverse(
"invF");
367 if(invF==Teuchos::null) {
373 Teko_DEBUG_EXPR(invTimer.stop());
374 Teko_DEBUG_MSG(
"LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1);
379 Teko_DEBUG_MSG(
"LSC::computeInverses Building inv(BQBtmC)",1);
380 Teko_DEBUG_EXPR(invTimer.start(
true));
381 const LinearOp BQBt = state->
getInverse(
"BQBtmC");
382 InverseLinearOp invBQBt = state->
getInverse(
"invBQBtmC");
383 if(invBQBt==Teuchos::null) {
389 Teko_DEBUG_EXPR(invTimer.stop());
390 Teko_DEBUG_MSG(
"LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1);
395 ModifiableLinearOp invBHBt = state->
getInverse(
"invBHBtmC");
396 if(hScaling_!=Teuchos::null || not isSymmetric_) {
398 Teko_DEBUG_MSG(
"LSC::computeInverses Building inv(BHBtmC)",1);
399 Teko_DEBUG_EXPR(invTimer.start(
true));
400 const LinearOp BHBt = state->
getInverse(
"BHBtmC");
401 if(invBHBt==Teuchos::null) {
407 Teko_DEBUG_EXPR(invTimer.stop());
408 Teko_DEBUG_MSG(
"LSC::computeInverses GetInvBHBt = " << invTimer.totalElapsedTime(),1);
410 else if(invBHBt==Teuchos::null) {
417 void InvLSCStrategy::initializeFromParameterList(
const Teuchos::ParameterList & pl,
const InverseLibrary & invLib)
420 std::string invStr=
"", invVStr=
"", invPStr=
"";
421 bool rowZeroing =
true;
426 if(pl.isParameter(
"Inverse Type"))
427 invStr = pl.get<std::string>(
"Inverse Type");
428 if(pl.isParameter(
"Inverse Velocity Type"))
429 invVStr = pl.get<std::string>(
"Inverse Velocity Type");
430 if(pl.isParameter(
"Inverse Pressure Type"))
431 invPStr = pl.get<std::string>(
"Inverse Pressure Type");
432 if(pl.isParameter(
"Ignore Boundary Rows"))
433 rowZeroing = pl.get<
bool>(
"Ignore Boundary Rows");
434 if(pl.isParameter(
"Use LDU"))
435 useLDU = pl.get<
bool>(
"Use LDU");
436 if(pl.isParameter(
"Use Mass Scaling"))
437 useMass_ = pl.get<
bool>(
"Use Mass Scaling");
440 if(pl.isParameter(
"Use W-Scaling"))
441 useWScaling_ = pl.get<
bool>(
"Use W-Scaling");
442 if(pl.isParameter(
"Eigen Solver Iterations"))
443 eigSolveParam_ = pl.get<
int>(
"Eigen Solver Iterations");
444 if(pl.isParameter(
"Scaling Type")) {
445 scaleType_ = getDiagonalType(pl.get<std::string>(
"Scaling Type"));
446 TEUCHOS_TEST_FOR_EXCEPT(scaleType_==
NotDiag);
448 if(pl.isParameter(
"Assume Stable Discretization"))
449 assumeStable_ = pl.get<
bool>(
"Assume Stable Discretization");
451 Teko_DEBUG_MSG_BEGIN(5)
452 DEBUG_STREAM <<
"LSC Inverse Strategy Parameters: " << std::endl;
453 DEBUG_STREAM <<
" inv type = \"" << invStr <<
"\"" << std::endl;
454 DEBUG_STREAM <<
" inv v type = \"" << invVStr <<
"\"" << std::endl;
455 DEBUG_STREAM <<
" inv p type = \"" << invPStr <<
"\"" << std::endl;
456 DEBUG_STREAM <<
" bndry rows = " << rowZeroing << std::endl;
457 DEBUG_STREAM <<
" use ldu = " << useLDU << std::endl;
458 DEBUG_STREAM <<
" use mass = " << useMass_ << std::endl;
459 DEBUG_STREAM <<
" use w-scaling = " << useWScaling_ << std::endl;
460 DEBUG_STREAM <<
" assume stable = " << assumeStable_ << std::endl;
461 DEBUG_STREAM <<
" scale type = " << getDiagonalName(scaleType_) << std::endl;
462 DEBUG_STREAM <<
"LSC Inverse Strategy Parameter list: " << std::endl;
463 pl.print(DEBUG_STREAM);
467 if(invStr==
"") invStr =
"Amesos";
468 if(invVStr==
"") invVStr = invStr;
469 if(invPStr==
"") invPStr = invStr;
472 invFactoryF_ = invLib.getInverseFactory(invVStr);
473 invFactoryS_ = invFactoryF_;
475 invFactoryS_ = invLib.getInverseFactory(invPStr);
478 setUseFullLDU(useLDU);
479 setRowZeroing(rowZeroing);
482 Teuchos::RCP<Teko::RequestHandler> rh = getRequestHandler();
483 rh->preRequest<Teko::LinearOp>(Teko::RequestMesg(
"Velocity Mass Matrix"));
485 = rh->request<Teko::LinearOp>(Teko::RequestMesg(
"Velocity Mass Matrix"));
492 Teuchos::RCP<Teuchos::ParameterList> InvLSCStrategy::getRequestedParameters()
const 494 Teuchos::RCP<Teuchos::ParameterList> result;
495 Teuchos::RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList());
498 RCP<Teuchos::ParameterList> fList = invFactoryF_->getRequestedParameters();
499 if(fList!=Teuchos::null) {
500 Teuchos::ParameterList::ConstIterator itr;
501 for(itr=fList->begin();itr!=fList->end();++itr)
502 pl->setEntry(itr->first,itr->second);
507 RCP<Teuchos::ParameterList> sList = invFactoryS_->getRequestedParameters();
508 if(sList!=Teuchos::null) {
509 Teuchos::ParameterList::ConstIterator itr;
510 for(itr=sList->begin();itr!=sList->end();++itr)
511 pl->setEntry(itr->first,itr->second);
517 pl->set<Teko::LinearOp>(
"W-Scaling Vector", Teuchos::null,
"W-Scaling Vector");
525 bool InvLSCStrategy::updateRequestedParameters(
const Teuchos::ParameterList & pl)
527 Teko_DEBUG_SCOPE(
"InvLSCStrategy::updateRequestedParameters",10);
531 result &= invFactoryF_->updateRequestedParameters(pl);
532 result &= invFactoryS_->updateRequestedParameters(pl);
536 Teko::MultiVector wScale = pl.get<Teko::MultiVector>(
"W-Scaling Vector");
538 if(wScale==Teuchos::null)
LinearOp adjoint(ModifiableLinearOp &a)
Construct an implicit adjoint of the linear operators.
virtual Teko::InverseLinearOp getInverse(const std::string &name) const
Get a named inverse from the state object.
Specifies that just the diagonal is used.
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
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.
double computeSpectralRad(const Teuchos::RCP< const Thyra::LinearOpBase< double > > &A, double tol, bool isHermitian=false, int numBlocks=5, int restart=0, int verbosity=0)
Compute the spectral radius of a matrix.
LinearOp invMass_
Inverse mass operator ( )
Preconditioner state for the LSC factory.
MultiVector getBlock(int i, const BlockedMultiVector &bmv)
Get the ith block from a BlockedMultiVector object.
For user convenience, if Teko recieves this value, exceptions will be thrown.
virtual void setInitialized(bool init=true)