Teko  Version of the Day
 All Classes Files Functions Variables Pages
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_VectorStdOps.hpp"
51 
52 #include "Teko_ConfigDefs.hpp"
53 
54 #ifdef TEKO_HAVE_EPETRA
55 #include "Thyra_EpetraThyraWrappers.hpp"
56 #include "Thyra_get_Epetra_Operator.hpp"
57 #include "Thyra_EpetraLinearOp.hpp"
58 #include "Epetra_Vector.h"
59 #include "Epetra_Map.h"
60 #include "EpetraExt_RowMatrixOut.h"
61 #include "EpetraExt_MultiVectorOut.h"
62 #include "EpetraExt_VectorOut.h"
63 #include "Teko_EpetraHelpers.hpp"
64 #include "Teko_EpetraOperatorWrapper.hpp"
65 #endif
66 
67 #include "Teuchos_Time.hpp"
68 #include "Teuchos_TimeMonitor.hpp"
69 
70 // Teko includes
71 #include "Teko_Utilities.hpp"
72 #include "NS/Teko_LSCPreconditionerFactory.hpp"
73 
74 #include "Teko_TpetraHelpers.hpp"
75 
76 #include "Thyra_TpetraLinearOp.hpp"
77 
78 using Teuchos::RCP;
79 using Teuchos::rcp_const_cast;
80 using Teuchos::rcp_dynamic_cast;
81 
82 namespace Teko {
83 namespace NS {
84 
86 // InvLSCStrategy Implementation
88 
89 // constructors
91 InvLSCStrategy::InvLSCStrategy()
92  : massMatrix_(Teuchos::null),
93  invFactoryF_(Teuchos::null),
94  invFactoryS_(Teuchos::null),
95  eigSolveParam_(5),
96  rowZeroingNeeded_(false),
97  useFullLDU_(false),
98  useMass_(false),
99  useLumping_(false),
100  useWScaling_(false),
101  scaleType_(Diagonal),
102  isSymmetric_(true),
103  assumeStable_(false) {}
104 
105 InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP<InverseFactory>& factory, bool rzn)
106  : massMatrix_(Teuchos::null),
107  invFactoryF_(factory),
108  invFactoryS_(factory),
109  eigSolveParam_(5),
110  rowZeroingNeeded_(rzn),
111  useFullLDU_(false),
112  useMass_(false),
113  useLumping_(false),
114  useWScaling_(false),
115  scaleType_(Diagonal),
116  isSymmetric_(true),
117  assumeStable_(false) {}
118 
119 InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP<InverseFactory>& invFactF,
120  const Teuchos::RCP<InverseFactory>& invFactS, bool rzn)
121  : massMatrix_(Teuchos::null),
122  invFactoryF_(invFactF),
123  invFactoryS_(invFactS),
124  eigSolveParam_(5),
125  rowZeroingNeeded_(rzn),
126  useFullLDU_(false),
127  useMass_(false),
128  useLumping_(false),
129  useWScaling_(false),
130  scaleType_(Diagonal),
131  isSymmetric_(true),
132  assumeStable_(false) {}
133 
134 InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP<InverseFactory>& factory, LinearOp& mass,
135  bool rzn)
136  : massMatrix_(mass),
137  invFactoryF_(factory),
138  invFactoryS_(factory),
139  eigSolveParam_(5),
140  rowZeroingNeeded_(rzn),
141  useFullLDU_(false),
142  useMass_(false),
143  useLumping_(false),
144  useWScaling_(false),
145  scaleType_(Diagonal),
146  isSymmetric_(true),
147  assumeStable_(false) {}
148 
149 InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP<InverseFactory>& invFactF,
150  const Teuchos::RCP<InverseFactory>& invFactS, LinearOp& mass,
151  bool rzn)
152  : massMatrix_(mass),
153  invFactoryF_(invFactF),
154  invFactoryS_(invFactS),
155  eigSolveParam_(5),
156  rowZeroingNeeded_(rzn),
157  useFullLDU_(false),
158  useMass_(false),
159  useLumping_(false),
160  useWScaling_(false),
161  scaleType_(Diagonal),
162  isSymmetric_(true),
163  assumeStable_(false) {}
164 
166 
167 void InvLSCStrategy::buildState(BlockedLinearOp& A, BlockPreconditionerState& state) const {
168  Teko_DEBUG_SCOPE("InvLSCStrategy::buildState", 10);
169 
170  LSCPrecondState* lscState = dynamic_cast<LSCPrecondState*>(&state);
171  TEUCHOS_ASSERT(lscState != 0);
172 
173  // if neccessary save state information
174  if (not lscState->isInitialized()) {
175  Teko_DEBUG_EXPR(Teuchos::Time timer(""));
176 
177  // construct operators
178  {
179  Teko_DEBUG_SCOPE("LSC::buildState constructing operators", 1);
180  Teko_DEBUG_EXPR(timer.start(true));
181 
182  initializeState(A, lscState);
183 
184  Teko_DEBUG_EXPR(timer.stop());
185  Teko_DEBUG_MSG("LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(), 1);
186  }
187 
188  // Build the inverses
189  {
190  Teko_DEBUG_SCOPE("LSC::buildState calculating inverses", 1);
191  Teko_DEBUG_EXPR(timer.start(true));
192 
193  computeInverses(A, lscState);
194 
195  Teko_DEBUG_EXPR(timer.stop());
196  Teko_DEBUG_MSG("LSC::buildState BuildInvTime = " << timer.totalElapsedTime(), 1);
197  }
198  }
199 }
200 
201 // functions inherited from LSCStrategy
202 LinearOp InvLSCStrategy::getInvBQBt(const BlockedLinearOp& /* A */,
203  BlockPreconditionerState& state) const {
204  return state.getInverse("invBQBtmC");
205 }
206 
207 LinearOp InvLSCStrategy::getInvBHBt(const BlockedLinearOp& /* A */,
208  BlockPreconditionerState& state) const {
209  return state.getInverse("invBHBtmC");
210 }
211 
212 LinearOp InvLSCStrategy::getInvF(const BlockedLinearOp& /* A */,
213  BlockPreconditionerState& state) const {
214  return state.getInverse("invF");
215 }
216 
217 LinearOp InvLSCStrategy::getOuterStabilization(const BlockedLinearOp& /* A */,
218  BlockPreconditionerState& state) const {
219  LSCPrecondState* lscState = dynamic_cast<LSCPrecondState*>(&state);
220  TEUCHOS_ASSERT(lscState != 0);
221  TEUCHOS_ASSERT(lscState->isInitialized())
222 
223  return lscState->aiD_;
224 }
225 
226 LinearOp InvLSCStrategy::getInvMass(const BlockedLinearOp& /* A */,
227  BlockPreconditionerState& state) const {
228  LSCPrecondState* lscState = dynamic_cast<LSCPrecondState*>(&state);
229  TEUCHOS_ASSERT(lscState != 0);
230  TEUCHOS_ASSERT(lscState->isInitialized())
231 
232  return lscState->invMass_;
233 }
234 
235 LinearOp InvLSCStrategy::getHScaling(const BlockedLinearOp& A,
236  BlockPreconditionerState& state) const {
237  if (hScaling_ != Teuchos::null) return hScaling_;
238  return getInvMass(A, state);
239 }
240 
242 void InvLSCStrategy::initializeState(const BlockedLinearOp& A, LSCPrecondState* state) const {
243  Teko_DEBUG_SCOPE("InvLSCStrategy::initializeState", 10);
244 
245  const LinearOp F = getBlock(0, 0, A);
246  const LinearOp Bt = getBlock(0, 1, A);
247  const LinearOp B = getBlock(1, 0, A);
248  const LinearOp C = getBlock(1, 1, A);
249 
250  LinearOp D = B;
251  LinearOp G = isSymmetric_ ? Bt : adjoint(D);
252 
253  bool isStabilized = assumeStable_ ? false : (not isZeroOp(C));
254 
255  // The logic follows like this
256  // if there is no mass matrix available --> build from F
257  // if there is a mass matrix and the inverse hasn't yet been built
258  // --> build from the mass matrix
259  // otherwise, there is already an invMass_ matrix that is appropriate
260  // --> use that one
261  if (massMatrix_ == Teuchos::null) {
262  Teko_DEBUG_MSG(
263  "LSC::initializeState Build Scaling <F> type \"" << getDiagonalName(scaleType_) << "\"", 1);
264  state->invMass_ = getInvDiagonalOp(F, scaleType_);
265  } else if (state->invMass_ == Teuchos::null) {
266  Teko_DEBUG_MSG(
267  "LSC::initializeState Build Scaling <mass> type \"" << getDiagonalName(scaleType_) << "\"",
268  1);
269  state->invMass_ = getInvDiagonalOp(massMatrix_, scaleType_);
270  }
271  // else "invMass_" should be set and there is no reason to rebuild it
272 
273  // compute BQBt
274  state->BQBt_ = explicitMultiply(B, state->invMass_, Bt, state->BQBt_);
275  Teko_DEBUG_MSG("Computed BQBt", 10);
276 
277  // if there is no H-Scaling
278  if (wScaling_ != Teuchos::null && hScaling_ == Teuchos::null) {
279  // from W vector build H operator scaling
280  RCP<const Thyra::VectorBase<double> > w = wScaling_->col(0);
281  RCP<const Thyra::VectorBase<double> > iQu =
282  rcp_dynamic_cast<const Thyra::DiagonalLinearOpBase<double> >(state->invMass_)->getDiag();
283  RCP<Thyra::VectorBase<double> > h = Thyra::createMember(iQu->space());
284 
285  Thyra::put_scalar(0.0, h.ptr());
286  Thyra::ele_wise_prod(1.0, *w, *iQu, h.ptr());
287  hScaling_ = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp<double>(h));
288  }
289 
290  LinearOp H = hScaling_;
291  if (H == Teuchos::null && not isSymmetric_) H = state->invMass_;
292 
293  // setup the scaling operator
294  if (H == Teuchos::null)
295  state->BHBt_ = state->BQBt_;
296  else {
297  RCP<Teuchos::Time> time =
298  Teuchos::TimeMonitor::getNewTimer("InvLSCStrategy::initializeState Build BHBt");
299  Teuchos::TimeMonitor timer(*time);
300 
301  // compute BHBt
302  state->BHBt_ = explicitMultiply(D, H, G, state->BHBt_);
303  }
304 
305  // if this is a stable discretization...we are done!
306  if (not isStabilized) {
307  state->addInverse("BQBtmC", state->BQBt_);
308  state->addInverse("BHBtmC", state->BHBt_);
309  state->gamma_ = 0.0;
310  state->alpha_ = 0.0;
311  state->aiD_ = Teuchos::null;
312 
313  state->setInitialized(true);
314 
315  return;
316  }
317 
318  // for Epetra_CrsMatrix...zero out certain rows: this ensures spectral radius is correct
319  LinearOp modF = F;
320  if (!Teko::TpetraHelpers::isTpetraLinearOp(F)) { // Epetra
321 #ifdef TEKO_HAVE_EPETRA
322  const RCP<const Epetra_Operator> epF = Thyra::get_Epetra_Operator(*F);
323  if (epF != Teuchos::null && rowZeroingNeeded_) {
324  // try to get a CRS matrix
325  const RCP<const Epetra_CrsMatrix> crsF = rcp_dynamic_cast<const Epetra_CrsMatrix>(epF);
326 
327  // if it is a CRS matrix get rows that need to be zeroed
328  if (crsF != Teuchos::null) {
329  std::vector<int> zeroIndices;
330 
331  // get rows in need of zeroing
332  Teko::Epetra::identityRowIndices(crsF->RowMap(), *crsF, zeroIndices);
333 
334  // build an operator that zeros those rows
335  modF = Thyra::epetraLinearOp(rcp(new Teko::Epetra::ZeroedOperator(zeroIndices, crsF)));
336  }
337  }
338 #else
339  throw std::logic_error(
340  "InvLSCStrategy::initializeState is trying to use "
341  "Epetra code, but TEKO is not built with Epetra!");
342 #endif
343  } else { // Tpetra
344  ST scalar = 0.0;
345  bool transp = false;
346  RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > crsF =
347  Teko::TpetraHelpers::getTpetraCrsMatrix(F, &scalar, &transp);
348 
349  std::vector<GO> zeroIndices;
350 
351  // get rows in need of zeroing
352  Teko::TpetraHelpers::identityRowIndices(*crsF->getRowMap(), *crsF, zeroIndices);
353 
354  // build an operator that zeros those rows
355  modF = Thyra::tpetraLinearOp<ST, LO, GO, NT>(
356  Thyra::tpetraVectorSpace<ST, LO, GO, NT>(crsF->getDomainMap()),
357  Thyra::tpetraVectorSpace<ST, LO, GO, NT>(crsF->getRangeMap()),
358  rcp(new Teko::TpetraHelpers::ZeroedOperator(zeroIndices, crsF)));
359  }
360 
361  // compute gamma
362  Teko_DEBUG_MSG("Calculating gamma", 10);
363  LinearOp iQuF = multiply(state->invMass_, modF);
364 
365  // do 6 power iterations to compute spectral radius: EHSST2007 Eq. 4.28
366  Teko::LinearOp stabMatrix; // this is the pressure stabilization matrix to use
367  state->gamma_ = std::fabs(Teko::computeSpectralRad(iQuF, 5e-2, false, eigSolveParam_)) / 3.0;
368  Teko_DEBUG_MSG("Calculated gamma", 10);
369  if (userPresStabMat_ != Teuchos::null) {
370  Teko::LinearOp invDGl = Teko::getInvDiagonalOp(userPresStabMat_);
371  Teko::LinearOp gammaOp = multiply(invDGl, C);
372  state->gamma_ *= std::fabs(Teko::computeSpectralRad(gammaOp, 5e-2, false, eigSolveParam_));
373  stabMatrix = userPresStabMat_;
374  } else
375  stabMatrix = C;
376 
377  // compute alpha scaled inv(D): EHSST2007 Eq. 4.29
378  // construct B_idF_Bt and save it for refilling later: This could reuse BQBt graph
379  LinearOp invDiagF = getInvDiagonalOp(F);
380  Teko::ModifiableLinearOp modB_idF_Bt = state->getInverse("BidFBt");
381  modB_idF_Bt = explicitMultiply(B, invDiagF, Bt, modB_idF_Bt);
382  state->addInverse("BidFBt", modB_idF_Bt);
383  const LinearOp B_idF_Bt = modB_idF_Bt;
384 
385  MultiVector vec_D = getDiagonal(B_idF_Bt); // this memory could be reused
386  update(-1.0, getDiagonal(C), 1.0, vec_D); // vec_D = diag(B*inv(diag(F))*Bt)-diag(C)
387  const LinearOp invD = buildInvDiagonal(vec_D, "inv(D)");
388 
389  Teko_DEBUG_MSG("Calculating alpha", 10);
390  const LinearOp BidFBtidD = multiply<double>(B_idF_Bt, invD);
391  double num = std::fabs(Teko::computeSpectralRad(BidFBtidD, 5e-2, false, eigSolveParam_));
392  Teko_DEBUG_MSG("Calculated alpha", 10);
393  state->alpha_ = 1.0 / num;
394  state->aiD_ = Thyra::scale(state->alpha_, invD);
395 
396  // now build B*Q*Bt-gamma*C
397  Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC");
398  BQBtmC = explicitAdd(state->BQBt_, scale(-state->gamma_, stabMatrix), BQBtmC);
399  state->addInverse("BQBtmC", BQBtmC);
400 
401  // now build B*H*Bt-gamma*C
402  Teko::ModifiableLinearOp BHBtmC = state->getInverse("BHBtmC");
403  if (H == Teuchos::null)
404  BHBtmC = BQBtmC;
405  else {
406  BHBtmC = explicitAdd(state->BHBt_, scale(-state->gamma_, stabMatrix), BHBtmC);
407  }
408  state->addInverse("BHBtmC", BHBtmC);
409 
410  Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "LSC Gamma Parameter = " << state->gamma_ << std::endl;
411  DEBUG_STREAM << "LSC Alpha Parameter = " << state->alpha_ << std::endl;
412  Teko_DEBUG_MSG_END()
413 
414  state->setInitialized(true);
415 }
416 
422 void InvLSCStrategy::computeInverses(const BlockedLinearOp& A, LSCPrecondState* state) const {
423  Teko_DEBUG_SCOPE("InvLSCStrategy::computeInverses", 10);
424  Teko_DEBUG_EXPR(Teuchos::Time invTimer(""));
425 
426  const LinearOp F = getBlock(0, 0, A);
427 
429 
430  // (re)build the inverse of F
431  Teko_DEBUG_MSG("LSC::computeInverses Building inv(F)", 1);
432  Teko_DEBUG_EXPR(invTimer.start(true));
433  InverseLinearOp invF = state->getInverse("invF");
434  if (invF == Teuchos::null) {
435  invF = buildInverse(*invFactoryF_, F);
436  state->addInverse("invF", invF);
437  } else {
438  rebuildInverse(*invFactoryF_, F, invF);
439  }
440  Teko_DEBUG_EXPR(invTimer.stop());
441  Teko_DEBUG_MSG("LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(), 1);
442 
444 
445  // (re)build the inverse of BQBt
446  Teko_DEBUG_MSG("LSC::computeInverses Building inv(BQBtmC)", 1);
447  Teko_DEBUG_EXPR(invTimer.start(true));
448  const LinearOp BQBt = state->getInverse("BQBtmC");
449  InverseLinearOp invBQBt = state->getInverse("invBQBtmC");
450  if (invBQBt == Teuchos::null) {
451  invBQBt = buildInverse(*invFactoryS_, BQBt);
452  state->addInverse("invBQBtmC", invBQBt);
453  } else {
454  rebuildInverse(*invFactoryS_, BQBt, invBQBt);
455  }
456  Teko_DEBUG_EXPR(invTimer.stop());
457  Teko_DEBUG_MSG("LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(), 1);
458 
460 
461  // Compute the inverse of BHBt or just use BQBt
462  ModifiableLinearOp invBHBt = state->getInverse("invBHBtmC");
463  if (hScaling_ != Teuchos::null || not isSymmetric_) {
464  // (re)build the inverse of BHBt
465  Teko_DEBUG_MSG("LSC::computeInverses Building inv(BHBtmC)", 1);
466  Teko_DEBUG_EXPR(invTimer.start(true));
467  const LinearOp BHBt = state->getInverse("BHBtmC");
468  if (invBHBt == Teuchos::null) {
469  invBHBt = buildInverse(*invFactoryS_, BHBt);
470  state->addInverse("invBHBtmC", invBHBt);
471  } else {
472  rebuildInverse(*invFactoryS_, BHBt, invBHBt);
473  }
474  Teko_DEBUG_EXPR(invTimer.stop());
475  Teko_DEBUG_MSG("LSC::computeInverses GetInvBHBt = " << invTimer.totalElapsedTime(), 1);
476  } else if (invBHBt == Teuchos::null) {
477  // just use the Q version
478  state->addInverse("invBHBtmC", invBQBt);
479  }
480 }
481 
483 void InvLSCStrategy::initializeFromParameterList(const Teuchos::ParameterList& pl,
484  const InverseLibrary& invLib) {
485  // get string specifying inverse
486  std::string invStr = "", invVStr = "", invPStr = "";
487  bool rowZeroing = true;
488  bool useLDU = false;
489  scaleType_ = Diagonal;
490 
491  // "parse" the parameter list
492  if (pl.isParameter("Inverse Type")) invStr = pl.get<std::string>("Inverse Type");
493  if (pl.isParameter("Inverse Velocity Type"))
494  invVStr = pl.get<std::string>("Inverse Velocity Type");
495  if (pl.isParameter("Inverse Pressure Type"))
496  invPStr = pl.get<std::string>("Inverse Pressure Type");
497  if (pl.isParameter("Ignore Boundary Rows")) rowZeroing = pl.get<bool>("Ignore Boundary Rows");
498  if (pl.isParameter("Use LDU")) useLDU = pl.get<bool>("Use LDU");
499  if (pl.isParameter("Use Mass Scaling")) useMass_ = pl.get<bool>("Use Mass Scaling");
500  // if(pl.isParameter("Use Lumping"))
501  // useLumping_ = pl.get<bool>("Use Lumping");
502  if (pl.isParameter("Use W-Scaling")) useWScaling_ = pl.get<bool>("Use W-Scaling");
503  if (pl.isParameter("Eigen Solver Iterations"))
504  eigSolveParam_ = pl.get<int>("Eigen Solver Iterations");
505  if (pl.isParameter("Scaling Type")) {
506  scaleType_ = getDiagonalType(pl.get<std::string>("Scaling Type"));
507  TEUCHOS_TEST_FOR_EXCEPT(scaleType_ == NotDiag);
508  }
509  if (pl.isParameter("Assume Stable Discretization"))
510  assumeStable_ = pl.get<bool>("Assume Stable Discretization");
511 
512  Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl;
513  DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl;
514  DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl;
515  DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl;
516  DEBUG_STREAM << " bndry rows = " << rowZeroing << std::endl;
517  DEBUG_STREAM << " use ldu = " << useLDU << std::endl;
518  DEBUG_STREAM << " use mass = " << useMass_ << std::endl;
519  DEBUG_STREAM << " use w-scaling = " << useWScaling_ << std::endl;
520  DEBUG_STREAM << " assume stable = " << assumeStable_ << std::endl;
521  DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl;
522  DEBUG_STREAM << "LSC Inverse Strategy Parameter list: " << std::endl;
523  pl.print(DEBUG_STREAM);
524  Teko_DEBUG_MSG_END()
525 
526  // set defaults as needed
527 #if defined(Teko_ENABLE_Amesos)
528  if (invStr == "") invStr = "Amesos";
529 #elif defined(Teko_ENABLE_Amesos2)
530  if (invStr == "") invStr = "Amesos2";
531 #endif
532  if (invVStr == "") invVStr = invStr;
533  if (invPStr == "") invPStr = invStr;
534 
535  // build velocity inverse factory
536  invFactoryF_ = invLib.getInverseFactory(invVStr);
537  invFactoryS_ = invFactoryF_; // by default these are the same
538  if (invVStr != invPStr) // if different, build pressure inverse factory
539  invFactoryS_ = invLib.getInverseFactory(invPStr);
540 
541  // set other parameters
542  setUseFullLDU(useLDU);
543  setRowZeroing(rowZeroing);
544 
545  if (useMass_) {
546  Teuchos::RCP<Teko::RequestHandler> rh = getRequestHandler();
547  rh->preRequest<Teko::LinearOp>(Teko::RequestMesg("Velocity Mass Matrix"));
548  Teko::LinearOp mass = rh->request<Teko::LinearOp>(Teko::RequestMesg("Velocity Mass Matrix"));
549  setMassMatrix(mass);
550  }
551 }
552 
554 Teuchos::RCP<Teuchos::ParameterList> InvLSCStrategy::getRequestedParameters() const {
555  Teuchos::RCP<Teuchos::ParameterList> result;
556  Teuchos::RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList());
557 
558  // grab parameters from F solver
559  RCP<Teuchos::ParameterList> fList = invFactoryF_->getRequestedParameters();
560  if (fList != Teuchos::null) {
561  Teuchos::ParameterList::ConstIterator itr;
562  for (itr = fList->begin(); itr != fList->end(); ++itr) pl->setEntry(itr->first, itr->second);
563  result = pl;
564  }
565 
566  // grab parameters from S solver
567  RCP<Teuchos::ParameterList> sList = invFactoryS_->getRequestedParameters();
568  if (sList != Teuchos::null) {
569  Teuchos::ParameterList::ConstIterator itr;
570  for (itr = sList->begin(); itr != sList->end(); ++itr) pl->setEntry(itr->first, itr->second);
571  result = pl;
572  }
573 
574  // use the mass matrix
575  if (useWScaling_) {
576  pl->set<Teko::LinearOp>("W-Scaling Vector", Teuchos::null, "W-Scaling Vector");
577  result = pl;
578  }
579 
580  return result;
581 }
582 
584 bool InvLSCStrategy::updateRequestedParameters(const Teuchos::ParameterList& pl) {
585  Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters", 10);
586  bool result = true;
587 
588  // update requested parameters in solvers
589  result &= invFactoryF_->updateRequestedParameters(pl);
590  result &= invFactoryS_->updateRequestedParameters(pl);
591 
592  // use W scaling matrix
593  if (useWScaling_) {
594  Teko::MultiVector wScale = pl.get<Teko::MultiVector>("W-Scaling Vector");
595 
596  if (wScale == Teuchos::null)
597  result &= false;
598  else
599  setWScaling(wScale);
600  }
601 
602  return result;
603 }
604 
605 } // end namespace NS
606 } // end namespace Teko
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 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)