MueLu  Version of the Day
MueLu_SimpleSmoother_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 /*
47  * MueLu_SimpleSmoother_def.hpp
48  *
49  * Created on: 19.03.2013
50  * Author: wiesner
51  */
52 
53 #ifndef MUELU_SIMPLESMOOTHER_DEF_HPP_
54 #define MUELU_SIMPLESMOOTHER_DEF_HPP_
55 
56 #include "Teuchos_ArrayViewDecl.hpp"
57 #include "Teuchos_ScalarTraits.hpp"
58 
59 #include "MueLu_ConfigDefs.hpp"
60 
61 #include <Xpetra_Matrix.hpp>
62 #include <Xpetra_CrsMatrixWrap.hpp>
63 #include <Xpetra_BlockedCrsMatrix.hpp>
64 #include <Xpetra_MultiVectorFactory.hpp>
65 #include <Xpetra_VectorFactory.hpp>
66 #include <Xpetra_ReorderedBlockedCrsMatrix.hpp>
67 
69 #include "MueLu_Level.hpp"
70 #include "MueLu_Utilities.hpp"
71 #include "MueLu_Monitor.hpp"
72 #include "MueLu_HierarchyUtils.hpp"
73 #include "MueLu_SmootherBase.hpp"
74 #include "MueLu_SubBlockAFactory.hpp"
75 
76 // include files for default FactoryManager
77 #include "MueLu_SchurComplementFactory.hpp"
78 #include "MueLu_DirectSolver.hpp"
79 #include "MueLu_SmootherFactory.hpp"
80 #include "MueLu_FactoryManager.hpp"
81 
82 namespace MueLu {
83 
84  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
86  : type_("SIMPLE"), A_(Teuchos::null)
87  {
88  //Factory::SetParameter("Sweeps", Teuchos::ParameterEntry(sweeps));
89  //Factory::SetParameter("Damping factor",Teuchos::ParameterEntry(omega));
90  //Factory::SetParameter("UseSIMPLEC", Teuchos::ParameterEntry(SIMPLEC));
91 
92 #if 0
93  // when declaring default factories without overwriting them leads to a multipleCallCheck exception
94  // TODO: debug into this
95  // workaround: always define your factory managers outside either using the C++ API or the XML files
96  RCP<SchurComplementFactory> SchurFact = Teuchos::rcp(new SchurComplementFactory());
97  SchurFact->SetParameter("omega",Teuchos::ParameterEntry(omega));
98  SchurFact->SetParameter("lumping",Teuchos::ParameterEntry(SIMPLEC));
99  SchurFact->SetFactory("A", this->GetFactory("A"));
100 
101  // define smoother/solver for SchurComplement equation
102  Teuchos::ParameterList SCparams;
103  std::string SCtype;
104  RCP<SmootherPrototype> smoProtoSC = rcp( new DirectSolver(SCtype,SCparams) );
105  smoProtoSC->SetFactory("A", SchurFact);
106 
107  RCP<SmootherFactory> SmooSCFact = rcp( new SmootherFactory(smoProtoSC) );
108 
109  RCP<FactoryManager> schurFactManager = rcp(new FactoryManager());
110  schurFactManager->SetFactory("A", SchurFact);
111  schurFactManager->SetFactory("Smoother", SmooSCFact);
112  schurFactManager->SetIgnoreUserData(true);
113 
114  // define smoother/solver for velocity prediction
115  RCP<SubBlockAFactory> A00Fact = Teuchos::rcp(new SubBlockAFactory(/*this->GetFactory("A"), 0, 0*/));
116  A00Fact->SetFactory("A",this->GetFactory("A"));
117  A00Fact->SetParameter("block row",ParameterEntry(0));
118  A00Fact->SetParameter("block col",ParameterEntry(0));
119  Teuchos::ParameterList velpredictParams;
120  std::string velpredictType;
121  RCP<SmootherPrototype> smoProtoPredict = rcp( new DirectSolver(velpredictType,velpredictParams) );
122  smoProtoPredict->SetFactory("A", A00Fact);
123  RCP<SmootherFactory> SmooPredictFact = rcp( new SmootherFactory(smoProtoPredict) );
124 
125  RCP<FactoryManager> velpredictFactManager = rcp(new FactoryManager());
126  velpredictFactManager->SetFactory("A", A00Fact);
127  velpredictFactManager->SetFactory("Smoother", SmooPredictFact);
128  velpredictFactManager->SetIgnoreUserData(true);
129 
130  AddFactoryManager(velpredictFactManager, 0);
131  AddFactoryManager(schurFactManager, 1);
132 #endif
133  }
134 
135  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
137 
138  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
140  RCP<ParameterList> validParamList = rcp(new ParameterList());
141 
142  validParamList->set< RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A");
143  validParamList->set< Scalar > ("Damping factor", 1.0, "Damping/Scaling factor in SIMPLE");
144  validParamList->set< LocalOrdinal > ("Sweeps", 1, "Number of SIMPLE sweeps (default = 1)");
145  validParamList->set< bool > ("UseSIMPLEC", false, "Use SIMPLEC instead of SIMPLE (default = false)");
146 
147  return validParamList;
148  }
149 
151  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
152  void SimpleSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::AddFactoryManager(RCP<const FactoryManagerBase> FactManager, int pos) {
153  TEUCHOS_TEST_FOR_EXCEPTION(pos < 0, Exceptions::RuntimeError, "MueLu::SimpleSmoother::AddFactoryManager: parameter \'pos\' must not be negative! error.");
154 
155  size_t myPos = Teuchos::as<size_t>(pos);
156 
157  if (myPos < FactManager_.size()) {
158  // replace existing entris in FactManager_ vector
159  FactManager_.at(myPos) = FactManager;
160  } else if( myPos == FactManager_.size()) {
161  // add new Factory manager in the end of the vector
162  FactManager_.push_back(FactManager);
163  } else { // if(myPos > FactManager_.size())
164  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
165  *out << "Warning: cannot add new FactoryManager at proper position " << pos << ". The FactoryManager is just appended to the end. Check this!" << std::endl;
166 
167  // add new Factory manager in the end of the vector
168  FactManager_.push_back(FactManager);
169  }
170 
171  }
172 
173 
174  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
176  AddFactoryManager(FactManager, 0); // overwrite factory manager for predicting the primary variable
177  }
178 
179  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
181  AddFactoryManager(FactManager, 1); // overwrite factory manager for SchurComplement
182  }
183 
184  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
186  currentLevel.DeclareInput("A",this->GetFactory("A").get());
187 
188  TEUCHOS_TEST_FOR_EXCEPTION(FactManager_.size() != 2, Exceptions::RuntimeError,"MueLu::SimpleSmoother::DeclareInput: You have to declare two FactoryManagers with a \"Smoother\" object: One for predicting the primary variable and one for the SchurComplement system. The smoother for the SchurComplement system needs a SchurComplementFactory as input for variable \"A\". make sure that you use the same proper damping factors for omega both in the SchurComplementFactory and in the SIMPLE smoother!");
189 
190  // loop over all factory managers for the subblocks of blocked operator A
191  std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
192  for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
193  SetFactoryManager currentSFM (rcpFromRef(currentLevel), *it);
194 
195  // request "Smoother" for current subblock row.
196  currentLevel.DeclareInput("PreSmoother",(*it)->GetFactory("Smoother").get());
197  }
198  }
199 
200  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
202  //*********************************************
203  // Setup routine can be summarized in 4 steps:
204  // - Set the map extractors
205  // - Set the blocks
206  // - Create and set the inverse of the diagonal of F
207  // - Set the smoother for the Schur Complement
208 
209  FactoryMonitor m(*this, "Setup blocked SIMPLE Smoother", currentLevel);
210 
211  if (SmootherPrototype::IsSetup() == true)
212  this->GetOStream(Warnings0) << "MueLu::SimpleSmoother::Setup(): Setup() has already been called";
213 
214  // extract blocked operator A from current level
215  A_ = Factory::Get<RCP<Matrix> > (currentLevel, "A");
216 
217  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
218  TEUCHOS_TEST_FOR_EXCEPTION(bA == Teuchos::null, Exceptions::BadCast, "MueLu::SimpleSmoother::Setup: input matrix A is not of type BlockedCrsMatrix! error.");
219 
220  // store map extractors
221  rangeMapExtractor_ = bA->getRangeMapExtractor();
222  domainMapExtractor_ = bA->getDomainMapExtractor();
223 
224  // Store the blocks in local member variables
225  F_ = bA->getMatrix(0, 0);
226  G_ = bA->getMatrix(0, 1);
227  D_ = bA->getMatrix(1, 0);
228  Z_ = bA->getMatrix(1, 1);
229 
230  const ParameterList & pL = Factory::GetParameterList();
231  bool bSIMPLEC = pL.get<bool>("UseSIMPLEC");
232 
233  // Create the inverse of the diagonal of F
234  // TODO add safety check for zeros on diagonal of F!
235  RCP<Vector> diagFVector = VectorFactory::Build(F_->getRowMap());
236  if(!bSIMPLEC) {
237  F_->getLocalDiagCopy(*diagFVector); // extract diagonal of F
238  } else {
239  /*const RCP<const Map> rowmap = F_->getRowMap();
240  size_t locSize = rowmap->getNodeNumElements();
241  Teuchos::ArrayRCP<SC> diag = diagFVector->getDataNonConst(0);
242  Teuchos::ArrayView<const LO> cols;
243  Teuchos::ArrayView<const SC> vals;
244  for (size_t i=0; i<locSize; ++i) { // loop over rows
245  F_->getLocalRowView(i,cols,vals);
246  Scalar absRowSum = Teuchos::ScalarTraits<Scalar>::zero();
247  for (LO j=0; j<cols.size(); ++j) { // loop over cols
248  absRowSum += Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
249  }
250  diag[i] = absRowSum;
251  }*/
252  // TODO this does not work if F_ is nested!
253  diagFVector = Utilities::GetLumpedMatrixDiagonal(F_);
254  }
255  diagFinv_ = Utilities::GetInverse(diagFVector);
256 
257  // check whether diagFinv_ is a blocked vector with only 1 block
258  RCP<BlockedVector> bdiagFinv = Teuchos::rcp_dynamic_cast<BlockedVector>(diagFinv_);
259  if(bdiagFinv.is_null() == false && bdiagFinv->getBlockedMap()->getNumMaps() == 1) {
260  RCP<Vector> nestedVec = bdiagFinv->getMultiVector(0,bdiagFinv->getBlockedMap()->getThyraMode())->getVectorNonConst(0);
261  diagFinv_.swap(nestedVec);
262  }
263 
264  // Set the Smoother
265  // carefully switch to the SubFactoryManagers (defined by the users)
266  {
267  RCP<const FactoryManagerBase> velpredictFactManager = FactManager_.at(0);
268  SetFactoryManager currentSFM (rcpFromRef(currentLevel), velpredictFactManager);
269  velPredictSmoo_ = currentLevel.Get< RCP<SmootherBase> >("PreSmoother",velpredictFactManager->GetFactory("Smoother").get());
270  }
271  {
272  RCP<const FactoryManagerBase> schurFactManager = FactManager_.at(1);
273  SetFactoryManager currentSFM (rcpFromRef(currentLevel), schurFactManager);
274  schurCompSmoo_ = currentLevel.Get< RCP<SmootherBase> >("PreSmoother", schurFactManager->GetFactory("Smoother").get());
275  }
276 
278  }
279 
280  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
281  void SimpleSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const
282  {
283  TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, Exceptions::RuntimeError, "MueLu::SimpleSmoother::Apply(): Setup() has not been called");
284 #if 0
285  // TODO simplify this debug check
286  RCP<MultiVector> rcpDebugX = Teuchos::rcpFromRef(X);
287  RCP<const MultiVector> rcpDebugB = Teuchos::rcpFromRef(B);
288  RCP<BlockedMultiVector> rcpBDebugX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpDebugX);
289  RCP<const BlockedMultiVector> rcpBDebugB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpDebugB);
290  if(rcpBDebugB.is_null() == false) {
291  //TEUCHOS_TEST_FOR_EXCEPTION(A_->getRangeMap()->isSameAs(*(B.getMap())) == false, Exceptions::RuntimeError, "MueLu::SimpleSmoother::Apply(): The map of RHS vector B is not the same as range map of the blocked operator A. Please check the map of B and A.");
292  } else {
293  //TEUCHOS_TEST_FOR_EXCEPTION(bA->getFullRangeMap()->isSameAs(*(B.getMap())) == false, Exceptions::RuntimeError, "MueLu::SimpleSmoother::Apply(): The map of RHS vector B is not the same as range map of the blocked operator A. Please check the map of B and A.");
294  }
295  if(rcpBDebugX.is_null() == false) {
296  //TEUCHOS_TEST_FOR_EXCEPTION(A_->getDomainMap()->isSameAs(*(X.getMap())) == false, Exceptions::RuntimeError, "MueLu::SimpleSmoother::Apply(): The map of the solution vector X is not the same as domain map of the blocked operator A. Please check the map of X and A.");
297  } else {
298  //TEUCHOS_TEST_FOR_EXCEPTION(bA->getFullDomainMap()->isSameAs(*(X.getMap())) == false, Exceptions::RuntimeError, "MueLu::SimpleSmoother::Apply(): The map of the solution vector X is not the same as domain map of the blocked operator A. Please check the map of X and A.");
299  }
300 #endif
301 
302  Teuchos::RCP<Teuchos::FancyOStream> fos = Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cout));
303 
304  SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
305 
306  // extract parameters from internal parameter list
307  const ParameterList & pL = Factory::GetParameterList();
308  LocalOrdinal nSweeps = pL.get<LocalOrdinal>("Sweeps");
309  Scalar omega = pL.get<Scalar>("Damping factor");
310 
311  // The boolean flags check whether we use Thyra or Xpetra style GIDs
312  bool bRangeThyraMode = rangeMapExtractor_->getThyraMode(); // && (Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(F_) == Teuchos::null);
313  bool bDomainThyraMode = domainMapExtractor_->getThyraMode(); // && (Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(F_) == Teuchos::null);
314 
315  //RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
316 
317  // wrap current solution vector in RCP
318  RCP<MultiVector> rcpX = Teuchos::rcpFromRef(X);
319  RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
320 
321  // make sure that both rcpX and rcpB are BlockedMultiVector objects
322  bool bCopyResultX = false;
323  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
324  MUELU_TEST_FOR_EXCEPTION(bA.is_null() == true, Exceptions::RuntimeError, "MueLu::BlockedGaussSeidelSmoother::Apply(): A_ must be a BlockedCrsMatrix");
325  RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
326  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
327 
328  if(bX.is_null() == true) {
329  RCP<MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedDomainMap(),rcpX));
330  rcpX.swap(test);
331  bCopyResultX = true;
332  }
333 
334  if(bB.is_null() == true) {
335  RCP<const MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedRangeMap(),rcpB));
336  rcpB.swap(test);
337  }
338 
339  // we now can guarantee that X and B are blocked multi vectors
340  bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
341  bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
342 
343  // check the type of operator
344  RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rbA = Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(bA);
345  if(rbA.is_null() == false) {
346  // A is a ReorderedBlockedCrsMatrix
347  Teuchos::RCP<const Xpetra::BlockReorderManager > brm = rbA->getBlockReorderManager();
348 
349  // check type of X vector
350  if(bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps()) {
351  // X is a blocked multi vector but incompatible to the reordered blocked operator A
352  Teuchos::RCP<MultiVector> test =
353  buildReorderedBlockedMultiVector(brm, bX);
354  rcpX.swap(test);
355  }
356  if(bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps()) {
357  // B is a blocked multi vector but incompatible to the reordered blocked operator A
358  Teuchos::RCP<const MultiVector> test =
359  buildReorderedBlockedMultiVector(brm, bB);
360  rcpB.swap(test);
361  }
362  }
363 
364  // Throughout the rest of the algorithm rcpX and rcpB are used for solution vector and RHS
365 
366  // create residual vector
367  // contains current residual of current solution X with rhs B
368  RCP<MultiVector> residual = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
369  RCP<BlockedMultiVector> bresidual = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(residual);
370  Teuchos::RCP<MultiVector> r1 = bresidual->getMultiVector(0,bRangeThyraMode);
371  Teuchos::RCP<MultiVector> r2 = bresidual->getMultiVector(1,bRangeThyraMode);
372 
373  // helper vector 1
374  RCP<MultiVector> xtilde = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
375  RCP<BlockedMultiVector> bxtilde = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xtilde);
376  RCP<MultiVector> xtilde1 = bxtilde->getMultiVector(0,bDomainThyraMode);
377  RCP<MultiVector> xtilde2 = bxtilde->getMultiVector(1,bDomainThyraMode);
378 
379  // helper vector 2
380  RCP<MultiVector> xhat = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
381  RCP<BlockedMultiVector> bxhat = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xhat);
382  RCP<MultiVector> xhat1 = bxhat->getMultiVector(0,bDomainThyraMode);
383  RCP<MultiVector> xhat2 = bxhat->getMultiVector(1,bDomainThyraMode);
384 
385 
386  // incrementally improve solution vector X
387  for (LocalOrdinal run = 0; run < nSweeps; ++run) {
388  // 1) calculate current residual
389  residual->update(one,*rcpB,zero); // residual = B
390  if(InitialGuessIsZero == false || run > 0)
391  A_->apply(*rcpX, *residual, Teuchos::NO_TRANS, -one, one);
392 
393  // 2) solve F * \Delta \tilde{x}_1 = r_1
394  // start with zero guess \Delta \tilde{x}_1
395  xtilde1->putScalar(zero);
396  xtilde2->putScalar(zero);
397  velPredictSmoo_->Apply(*xtilde1,*r1);
398 
399  // 3) calculate rhs for SchurComp equation
400  // r_2 - D \Delta \tilde{x}_1
401  RCP<MultiVector> schurCompRHS = rangeMapExtractor_->getVector(1, rcpB->getNumVectors(), bRangeThyraMode);
402  D_->apply(*xtilde1,*schurCompRHS);
403 
404  schurCompRHS->update(one,*r2,-one);
405 
406  // 4) solve SchurComp equation
407  // start with zero guess \Delta \tilde{x}_2
408  schurCompSmoo_->Apply(*xtilde2,*schurCompRHS);
409 
410  // 5) scale xtilde2 with omega
411  // store this in xhat2
412  xhat2->update(omega,*xtilde2,zero);
413 
414  // 6) calculate xhat1
415  RCP<MultiVector> xhat1_temp = domainMapExtractor_->getVector(0, rcpX->getNumVectors(), bDomainThyraMode);
416  G_->apply(*xhat2,*xhat1_temp); // store result temporarely in xtilde1_temp
417 
418  xhat1->elementWiseMultiply(one/*/omega*/,*diagFinv_,*xhat1_temp,zero);
419  xhat1->update(one,*xtilde1,-one);
420 
421  rcpX->update(one,*bxhat,one);
422  }
423 
424  if (bCopyResultX == true) {
425  RCP<MultiVector> Xmerged = bX->Merge();
426  X.update(one, *Xmerged, zero);
427  }
428 
429  }
430 
431  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
432  RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
434  return rcp( new SimpleSmoother(*this) );
435  }
436 
437  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
439  std::ostringstream out;
441  out << "{type = " << type_ << "}";
442  return out.str();
443  }
444 
445  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
446  void SimpleSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
448 
449  if (verbLevel & Parameters0) {
450  out0 << "Prec. type: " << type_ << /*" Sweeps: " << nSweeps_ << " damping: " << omega_ <<*/ std::endl;
451  }
452 
453  if (verbLevel & Debug) {
454  out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl;
455  }
456  }
457 
458  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
460  // FIXME: This is a placeholder
461  return Teuchos::OrdinalTraits<size_t>::invalid();
462  }
463 
464 
465 } // namespace MueLu
466 
467 
468 #endif /* MUELU_SIMPLESMOOTHER_DEF_HPP_ */
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
#define MUELU_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
virtual std::string description() const
Return a simple one-line description of this object.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Exception indicating invalid cast attempted.
Exception throws to report errors in the internal logical of the program.
This class specifies the default factory that should generate some data on a Level if the data does n...
Timer to be used in factories. Similar to Monitor but with additional timers.
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
virtual const Teuchos::ParameterList & GetParameterList() const
Factory for building the Schur Complement for a 2x2 block matrix.
An exception safe way to call the method 'Level::SetFactoryManager()'.
SIMPLE smoother for 2x2 block matrices.
void SetVelocityPredictionFactoryManager(RCP< FactoryManager > FactManager)
void Setup(Level &currentLevel)
Setup routine.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
std::string description() const
Return a simple one-line description of this object.
void DeclareInput(Level &currentLevel) const
Input.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
RCP< const ParameterList > GetValidParameterList() const
Input.
virtual ~SimpleSmoother()
Destructor.
RCP< SmootherPrototype > Copy() const
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager, int pos)
Add a factory manager at a specific position.
void Apply(MultiVector &X, MultiVector const &B, bool InitialGuessIsZero=false) const
Apply the Braess Sarazin smoother.
void SetSchurCompFactoryManager(RCP< FactoryManager > FactManager)
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
bool IsSetup() const
Get the state of a smoother prototype.
Factory for building a thresholded operator.
static Teuchos::ArrayRCP< Scalar > GetLumpedMatrixDiagonal(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
static Teuchos::RCP< Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > GetInverse(Teuchos::RCP< const Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > v, Magnitude tol=Teuchos::ScalarTraits< Scalar >::eps() *100, Scalar tolReplacement=Teuchos::ScalarTraits< Scalar >::zero())
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)
@ Debug
Print additional debugging information.
@ Parameters0
Print class parameters.
std::string toString(const T &what)
Little helper function to convert non-string types to strings.