Teko  Version of the Day
Teko_InvLSCStrategy.cpp
1 /*
2 // @HEADER
3 //
4 // ***********************************************************************
5 //
6 // Teko: A package for block and physics based preconditioning
7 // Copyright 2010 Sandia Corporation
8 //
9 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
40 //
41 // ***********************************************************************
42 //
43 // @HEADER
44 
45 */
46 
47 #include "NS/Teko_InvLSCStrategy.hpp"
48 
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"
54 
55 #include "Epetra_Vector.h"
56 #include "Epetra_Map.h"
57 
58 #include "EpetraExt_RowMatrixOut.h"
59 #include "EpetraExt_MultiVectorOut.h"
60 #include "EpetraExt_VectorOut.h"
61 
62 #include "Teuchos_Time.hpp"
63 #include "Teuchos_TimeMonitor.hpp"
64 
65 // Teko includes
66 #include "Teko_Utilities.hpp"
67 #include "NS/Teko_LSCPreconditionerFactory.hpp"
68 #include "Epetra/Teko_EpetraHelpers.hpp"
69 #include "Epetra/Teko_EpetraOperatorWrapper.hpp"
70 
71 using Teuchos::RCP;
72 using Teuchos::rcp_dynamic_cast;
73 using Teuchos::rcp_const_cast;
74 
75 namespace Teko {
76 namespace NS {
77 
79 // InvLSCStrategy Implementation
81 
82 // constructors
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)
88 { }
89 
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)
94 { }
95 
96 InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP<InverseFactory> & invFactF,
97  const Teuchos::RCP<InverseFactory> & invFactS,
98  bool rzn)
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)
102 { }
103 
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)
108 { }
109 
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)
116 { }
117 
119 
120 void InvLSCStrategy::buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const
121 {
122  Teko_DEBUG_SCOPE("InvLSCStrategy::buildState",10);
123 
124  LSCPrecondState * lscState = dynamic_cast<LSCPrecondState*>(&state);
125  TEUCHOS_ASSERT(lscState!=0);
126 
127  // if neccessary save state information
128  if(not lscState->isInitialized()) {
129  Teko_DEBUG_EXPR(Teuchos::Time timer(""));
130 
131  // construct operators
132  {
133  Teko_DEBUG_SCOPE("LSC::buildState constructing operators",1);
134  Teko_DEBUG_EXPR(timer.start(true));
135 
136  initializeState(A,lscState);
137 
138  Teko_DEBUG_EXPR(timer.stop());
139  Teko_DEBUG_MSG("LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1);
140  }
141 
142  // Build the inverses
143  {
144  Teko_DEBUG_SCOPE("LSC::buildState calculating inverses",1);
145  Teko_DEBUG_EXPR(timer.start(true));
146 
147  computeInverses(A,lscState);
148 
149  Teko_DEBUG_EXPR(timer.stop());
150  Teko_DEBUG_MSG("LSC::buildState BuildInvTime = " << timer.totalElapsedTime(),1);
151  }
152  }
153 }
154 
155 // functions inherited from LSCStrategy
156 LinearOp InvLSCStrategy::getInvBQBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const
157 {
158  return state.getInverse("invBQBtmC");
159 }
160 
161 LinearOp InvLSCStrategy::getInvBHBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const
162 {
163  return state.getInverse("invBHBtmC");
164 }
165 
166 LinearOp InvLSCStrategy::getInvF(const BlockedLinearOp & A,BlockPreconditionerState & state) const
167 {
168  return state.getInverse("invF");
169 }
170 
171 LinearOp InvLSCStrategy::getOuterStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const
172 {
173  LSCPrecondState * lscState = dynamic_cast<LSCPrecondState*>(&state);
174  TEUCHOS_ASSERT(lscState!=0);
175  TEUCHOS_ASSERT(lscState->isInitialized())
176 
177  return lscState->aiD_;
178 }
179 
180 LinearOp InvLSCStrategy::getInvMass(const BlockedLinearOp & A,BlockPreconditionerState & state) const
181 {
182  LSCPrecondState * lscState = dynamic_cast<LSCPrecondState*>(&state);
183  TEUCHOS_ASSERT(lscState!=0);
184  TEUCHOS_ASSERT(lscState->isInitialized())
185 
186  return lscState->invMass_;
187 }
188 
189 LinearOp InvLSCStrategy::getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const
190 {
191  if(hScaling_!=Teuchos::null) return hScaling_;
192  return getInvMass(A,state);
193 }
194 
196 void InvLSCStrategy::initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const
197 {
198  Teko_DEBUG_SCOPE("InvLSCStrategy::initializeState",10);
199 
200  const LinearOp F = getBlock(0,0,A);
201  const LinearOp Bt = getBlock(0,1,A);
202  const LinearOp B = getBlock(1,0,A);
203  const LinearOp C = getBlock(1,1,A);
204 
205  LinearOp D = B;
206  LinearOp G = isSymmetric_ ? Bt : adjoint(D);
207 
208  bool isStabilized = assumeStable_ ? false : (not isZeroOp(C));
209 
210  // The logic follows like this
211  // if there is no mass matrix available --> build from F
212  // if there is a mass matrix and the inverse hasn't yet been built
213  // --> build from the mass matrix
214  // otherwise, there is already an invMass_ matrix that is appropriate
215  // --> use that one
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_);
220  }
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_);
225  }
226  // else "invMass_" should be set and there is no reason to rebuild it
227 
228  // compute BQBt
229  state->BQBt_ = explicitMultiply(B,state->invMass_,Bt,state->BQBt_);
230  Teko_DEBUG_MSG("Computed BQBt",10);
231 
232  // if there is no H-Scaling
233  if(wScaling_!=Teuchos::null && hScaling_==Teuchos::null) {
234  // from W vector build H operator scaling
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());
239 
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));
243  }
244 
245  LinearOp H = hScaling_;
246  if(H==Teuchos::null && not isSymmetric_)
247  H = state->invMass_;
248 
249  // setup the scaling operator
250  if(H==Teuchos::null)
251  state->BHBt_ = state->BQBt_;
252  else {
253  RCP<Teuchos::Time> time = Teuchos::TimeMonitor::getNewTimer("InvLSCStrategy::initializeState Build BHBt");
254  Teuchos::TimeMonitor timer(*time);
255 
256  // compute BHBt
257  state->BHBt_ = explicitMultiply(D,H,G,state->BHBt_);
258  }
259 
260  // if this is a stable discretization...we are done!
261  if(not isStabilized) {
262  state->addInverse("BQBtmC",state->BQBt_);
263  state->addInverse("BHBtmC",state->BHBt_);
264  state->gamma_ = 0.0;
265  state->alpha_ = 0.0;
266  state->aiD_ = Teuchos::null;
267 
268  state->setInitialized(true);
269 
270  return;
271  }
272 
273  // for Epetra_CrsMatrix...zero out certain rows: this ensures spectral radius is correct
274  LinearOp modF = F;
275  const RCP<const Epetra_Operator> epF = Thyra::get_Epetra_Operator(*F);
276  if(epF!=Teuchos::null && rowZeroingNeeded_) {
277  // try to get a CRS matrix
278  const RCP<const Epetra_CrsMatrix> crsF = rcp_dynamic_cast<const Epetra_CrsMatrix>(epF);
279 
280  // if it is a CRS matrix get rows that need to be zeroed
281  if(crsF!=Teuchos::null) {
282  std::vector<int> zeroIndices;
283 
284  // get rows in need of zeroing
285  Teko::Epetra::identityRowIndices(crsF->RowMap(), *crsF,zeroIndices);
286 
287  // build an operator that zeros those rows
288  modF = Thyra::epetraLinearOp(rcp(new Teko::Epetra::ZeroedOperator(zeroIndices,crsF)));
289  }
290  }
291 
292  // compute gamma
293  Teko_DEBUG_MSG("Calculating gamma",10);
294  LinearOp iQuF = multiply(state->invMass_,modF);
295 
296  // do 6 power iterations to compute spectral radius: EHSST2007 Eq. 4.28
297  Teko::LinearOp stabMatrix; // this is the pressure stabilization matrix to use
298  state->gamma_ = std::fabs(Teko::computeSpectralRad(iQuF,5e-2,false,eigSolveParam_))/3.0;
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);
303  state->gamma_ *= std::fabs(Teko::computeSpectralRad(gammaOp,5e-2,false,eigSolveParam_));
304  stabMatrix = userPresStabMat_;
305  } else
306  stabMatrix = C;
307 
308  // compute alpha scaled inv(D): EHSST2007 Eq. 4.29
309  // construct B_idF_Bt and save it for refilling later: This could reuse BQBt graph
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);
313  state->addInverse("BidFBt",modB_idF_Bt);
314  const LinearOp B_idF_Bt = modB_idF_Bt;
315 
316  MultiVector vec_D = getDiagonal(B_idF_Bt); // this memory could be reused
317  update(-1.0,getDiagonal(C),1.0,vec_D); // vec_D = diag(B*inv(diag(F))*Bt)-diag(C)
318  const LinearOp invD = buildInvDiagonal(vec_D,"inv(D)");
319 
320  Teko_DEBUG_MSG("Calculating alpha",10);
321  const LinearOp BidFBtidD = multiply<double>(B_idF_Bt,invD);
322  double num = std::fabs(Teko::computeSpectralRad(BidFBtidD,5e-2,false,eigSolveParam_));
323  Teko_DEBUG_MSG("Calculated alpha",10);
324  state->alpha_ = 1.0/num;
325  state->aiD_ = Thyra::scale(state->alpha_,invD);
326 
327  // now build B*Q*Bt-gamma*C
328  Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC");
329  BQBtmC = explicitAdd(state->BQBt_,scale(-state->gamma_,stabMatrix),BQBtmC);
330  state->addInverse("BQBtmC",BQBtmC);
331 
332  // now build B*H*Bt-gamma*C
333  Teko::ModifiableLinearOp BHBtmC = state->getInverse("BHBtmC");
334  if(H==Teuchos::null)
335  BHBtmC = BQBtmC;
336  else {
337  BHBtmC = explicitAdd(state->BHBt_,scale(-state->gamma_,stabMatrix),BHBtmC);
338  }
339  state->addInverse("BHBtmC",BHBtmC);
340 
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;
344  Teko_DEBUG_MSG_END()
345 
346  state->setInitialized(true);
347 }
348 
354 void InvLSCStrategy::computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const
355 {
356  Teko_DEBUG_SCOPE("InvLSCStrategy::computeInverses",10);
357  Teko_DEBUG_EXPR(Teuchos::Time invTimer(""));
358 
359  const LinearOp F = getBlock(0,0,A);
360 
362 
363  // (re)build the inverse of F
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) {
368  invF = buildInverse(*invFactoryF_,F);
369  state->addInverse("invF",invF);
370  } else {
371  rebuildInverse(*invFactoryF_,F,invF);
372  }
373  Teko_DEBUG_EXPR(invTimer.stop());
374  Teko_DEBUG_MSG("LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1);
375 
377 
378  // (re)build the inverse of BQBt
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) {
384  invBQBt = buildInverse(*invFactoryS_,BQBt);
385  state->addInverse("invBQBtmC",invBQBt);
386  } else {
387  rebuildInverse(*invFactoryS_,BQBt,invBQBt);
388  }
389  Teko_DEBUG_EXPR(invTimer.stop());
390  Teko_DEBUG_MSG("LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1);
391 
393 
394  // Compute the inverse of BHBt or just use BQBt
395  ModifiableLinearOp invBHBt = state->getInverse("invBHBtmC");
396  if(hScaling_!=Teuchos::null || not isSymmetric_) {
397  // (re)build the inverse of BHBt
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) {
402  invBHBt = buildInverse(*invFactoryS_,BHBt);
403  state->addInverse("invBHBtmC",invBHBt);
404  } else {
405  rebuildInverse(*invFactoryS_,BHBt,invBHBt);
406  }
407  Teko_DEBUG_EXPR(invTimer.stop());
408  Teko_DEBUG_MSG("LSC::computeInverses GetInvBHBt = " << invTimer.totalElapsedTime(),1);
409  }
410  else if(invBHBt==Teuchos::null) {
411  // just use the Q version
412  state->addInverse("invBHBtmC",invBQBt);
413  }
414 }
415 
417 void InvLSCStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl,const InverseLibrary & invLib)
418 {
419  // get string specifying inverse
420  std::string invStr="", invVStr="", invPStr="";
421  bool rowZeroing = true;
422  bool useLDU = false;
423  scaleType_ = Diagonal;
424 
425  // "parse" the parameter list
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");
438  // if(pl.isParameter("Use Lumping"))
439  // useLumping_ = pl.get<bool>("Use Lumping");
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);
447  }
448  if(pl.isParameter("Assume Stable Discretization"))
449  assumeStable_ = pl.get<bool>("Assume Stable Discretization");
450 
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);
464  Teko_DEBUG_MSG_END()
465 
466  // set defaults as needed
467  if(invStr=="") invStr = "Amesos";
468  if(invVStr=="") invVStr = invStr;
469  if(invPStr=="") invPStr = invStr;
470 
471  // build velocity inverse factory
472  invFactoryF_ = invLib.getInverseFactory(invVStr);
473  invFactoryS_ = invFactoryF_; // by default these are the same
474  if(invVStr!=invPStr) // if different, build pressure inverse factory
475  invFactoryS_ = invLib.getInverseFactory(invPStr);
476 
477  // set other parameters
478  setUseFullLDU(useLDU);
479  setRowZeroing(rowZeroing);
480 
481  if(useMass_) {
482  Teuchos::RCP<Teko::RequestHandler> rh = getRequestHandler();
483  rh->preRequest<Teko::LinearOp>(Teko::RequestMesg("Velocity Mass Matrix"));
484  Teko::LinearOp mass
485  = rh->request<Teko::LinearOp>(Teko::RequestMesg("Velocity Mass Matrix"));
486  setMassMatrix(mass);
487  }
488 
489 }
490 
492 Teuchos::RCP<Teuchos::ParameterList> InvLSCStrategy::getRequestedParameters() const
493 {
494  Teuchos::RCP<Teuchos::ParameterList> result;
495  Teuchos::RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList());
496 
497  // grab parameters from F solver
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);
503  result = pl;
504  }
505 
506  // grab parameters from S solver
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);
512  result = pl;
513  }
514 
515  // use the mass matrix
516  if(useWScaling_) {
517  pl->set<Teko::LinearOp>("W-Scaling Vector", Teuchos::null,"W-Scaling Vector");
518  result = pl;
519  }
520 
521  return result;
522 }
523 
525 bool InvLSCStrategy::updateRequestedParameters(const Teuchos::ParameterList & pl)
526 {
527  Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters",10);
528  bool result = true;
529 
530  // update requested parameters in solvers
531  result &= invFactoryF_->updateRequestedParameters(pl);
532  result &= invFactoryS_->updateRequestedParameters(pl);
533 
534  // use W scaling matrix
535  if(useWScaling_) {
536  Teko::MultiVector wScale = pl.get<Teko::MultiVector>("W-Scaling Vector");
537 
538  if(wScale==Teuchos::null)
539  result &= false;
540  else
541  setWScaling(wScale);
542  }
543 
544  return result;
545 }
546 
547 } // end namespace NS
548 } // end namespace Teko
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 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)