MueLu  Version of the Day
MueLu_BlockedJacobiSmoother_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 #ifndef MUELU_BLOCKEDJACOBISMOOTHER_DEF_HPP_
48 #define MUELU_BLOCKEDJACOBISMOOTHER_DEF_HPP_
49 
50 #include "Teuchos_ArrayViewDecl.hpp"
51 #include "Teuchos_ScalarTraits.hpp"
52 
53 #include "MueLu_ConfigDefs.hpp"
54 
55 #include <Xpetra_BlockReorderManager.hpp>
56 #include <Xpetra_Matrix.hpp>
57 #include <Xpetra_BlockedCrsMatrix.hpp>
58 #include <Xpetra_ReorderedBlockedCrsMatrix.hpp>
59 #include <Xpetra_ReorderedBlockedMultiVector.hpp>
60 #include <Xpetra_MultiVectorFactory.hpp>
61 
63 #include "MueLu_Level.hpp"
64 #include "MueLu_Utilities.hpp"
65 #include "MueLu_Monitor.hpp"
66 #include "MueLu_HierarchyUtils.hpp"
67 #include "MueLu_SmootherBase.hpp"
68 
69 namespace MueLu {
70 
71  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
73  : type_("blocked Jacobi"), A_(Teuchos::null)
74  {
75  FactManager_.reserve(10); // TODO fix me!
76  }
77 
78  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
80 
81  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
83  RCP<ParameterList> validParamList = rcp(new ParameterList());
84 
85  validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A");
86  validParamList->set<Scalar>("Damping factor", 1.0, "Damping/Scaling factor in Jacobi");
87  validParamList->set<LocalOrdinal>("Sweeps", 1, "Number of sweeps (default = 1)");
88 
89  return validParamList;
90  }
91 
92  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
93  void BlockedJacobiSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::AddFactoryManager(RCP<const FactoryManagerBase> FactManager, int pos) {
94  TEUCHOS_TEST_FOR_EXCEPTION(pos < 0, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::AddFactoryManager: parameter \'pos\' must not be negative! error.");
95 
96  size_t myPos = Teuchos::as<size_t>(pos);
97 
98  if (myPos < FactManager_.size()) {
99  // replace existing entris in FactManager_ vector
100  FactManager_.at(myPos) = FactManager;
101  } else if( myPos == FactManager_.size()) {
102  // add new Factory manager in the end of the vector
103  FactManager_.push_back(FactManager);
104  } else { // if(myPos > FactManager_.size())
105  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
106  *out << "Warning: cannot add new FactoryManager at proper position " << pos << ". The FactoryManager is just appended to the end. Check this!" << std::endl;
107 
108  // add new Factory manager in the end of the vector
109  FactManager_.push_back(FactManager);
110  }
111  }
112 
113  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
115  //this->Input(currentLevel, "A");
116  // TODO: check me: why is this->Input not freeing properly A in release mode?
117  currentLevel.DeclareInput("A",this->GetFactory("A").get());
118 
119  // loop over all factory managers for the subblocks of blocked operator A
120  std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
121  for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
122  SetFactoryManager currentSFM (rcpFromRef(currentLevel), *it);
123 
124  // request "Smoother" for current subblock row.
125  currentLevel.DeclareInput("PreSmoother",(*it)->GetFactory("Smoother").get());
126 
127  // request "A" for current subblock row (only needed for Thyra mode)
128  currentLevel.DeclareInput("A",(*it)->GetFactory("A").get());
129  }
130  }
131 
132  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
134 
135  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
136 
137  FactoryMonitor m(*this, "Setup blocked Jacobi Smoother", currentLevel);
138  if (SmootherPrototype::IsSetup() == true) this->GetOStream(Warnings0) << "MueLu::BlockedJacobiSmoother::Setup(): Setup() has already been called";
139 
140  // extract blocked operator A from current level
141  A_ = Factory::Get< RCP<Matrix> >(currentLevel, "A"); // A needed for extracting map extractors
142  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
143  TEUCHOS_TEST_FOR_EXCEPTION(bA==Teuchos::null, Exceptions::BadCast, "MueLu::BlockedPFactory::Build: input matrix A is not of type BlockedCrsMatrix! error.");
144 
145  // plausibility check
146  TEUCHOS_TEST_FOR_EXCEPTION(bA->Rows() != FactManager_.size(), Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::Setup: number of block rows of A is " << bA->Rows() << " and does not match number of SubFactoryManagers " << FactManager_.size() << ". error.");
147  TEUCHOS_TEST_FOR_EXCEPTION(bA->Cols() != FactManager_.size(), Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::Setup: number of block cols of A is " << bA->Cols() << " and does not match number of SubFactoryManagers " << FactManager_.size() << ". error.");
148 
149  // store map extractors
150  rangeMapExtractor_ = bA->getRangeMapExtractor();
151  domainMapExtractor_ = bA->getDomainMapExtractor();
152 
153  // loop over all factory managers for the subblocks of blocked operator A
154  std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
155  for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
156  SetFactoryManager currentSFM (rcpFromRef(currentLevel), *it);
157 
158  // extract Smoother for current block row
159  RCP<const SmootherBase> Smoo = currentLevel.Get< RCP<SmootherBase> >("PreSmoother",(*it)->GetFactory("Smoother").get());
160  Inverse_.push_back(Smoo);
161 
162  // store whether subblock matrix is blocked or not!
163  RCP<Matrix> Aii = currentLevel.Get< RCP<Matrix> >("A",(*it)->GetFactory("A").get());
164  bIsBlockedOperator_.push_back(Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Aii)!=Teuchos::null);
165  }
166 
168  }
169 
170  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
171  void BlockedJacobiSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector &X, const MultiVector& B, bool InitialGuessIsZero) const
172  {
173  TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::Apply(): Setup() has not been called");
174 
175 #if 0 // def HAVE_MUELU_DEBUG
176  // TODO simplify this debug check
177  RCP<MultiVector> rcpDebugX = Teuchos::rcpFromRef(X);
178  RCP<const MultiVector> rcpDebugB = Teuchos::rcpFromRef(B);
179  RCP<BlockedMultiVector> rcpBDebugX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpDebugX);
180  RCP<const BlockedMultiVector> rcpBDebugB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpDebugB);
181  //RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
182  if(rcpBDebugB.is_null() == false) {
183  //this->GetOStream(Runtime1) << "BlockedJacobi: B is a BlockedMultiVector of size " << B.getMap()->getGlobalNumElements() << " with " << rcpBDebugB->getBlockedMap()->getNumMaps() << " blocks." << std::endl;
184  //TEUCHOS_TEST_FOR_EXCEPTION(A_->getRangeMap()->isSameAs(*(B.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::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.");
185  } else {
186  //this->GetOStream(Runtime1) << "BlockedJacobi: B is a MultiVector of size " << B.getMap()->getGlobalNumElements() << std::endl;
187  //TEUCHOS_TEST_FOR_EXCEPTION(bA->getFullRangeMap()->isSameAs(*(B.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::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.");
188  }
189  if(rcpBDebugX.is_null() == false) {
190  //this->GetOStream(Runtime1) << "BlockedJacobi: X is a BlockedMultiVector of size " << X.getMap()->getGlobalNumElements() << " with " << rcpBDebugX->getBlockedMap()->getNumMaps() << " blocks." << std::endl;
191  //TEUCHOS_TEST_FOR_EXCEPTION(A_->getDomainMap()->isSameAs(*(X.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::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.");
192  } else {
193  //this->GetOStream(Runtime1) << "BlockedJacobi: X is a MultiVector of size " << X.getMap()->getGlobalNumElements() << std::endl;
194  //TEUCHOS_TEST_FOR_EXCEPTION(bA->getFullDomainMap()->isSameAs(*(X.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::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.");
195  }
196 
197 
198 #endif
199  SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
200 
201  // Input variables used for the rest of the algorithm
202  RCP<MultiVector> rcpX = Teuchos::rcpFromRef(X);
203  RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
204 
205  // make sure that both rcpX and rcpB are BlockedMultiVector objects
206  bool bCopyResultX = false;
207  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
208  MUELU_TEST_FOR_EXCEPTION(bA.is_null() == true, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::Apply(): A_ must be a BlockedCrsMatrix");
209  RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
210  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
211 
212  if(bX.is_null() == true) {
213  RCP<MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedDomainMap(),rcpX));
214  rcpX.swap(test);
215  bCopyResultX = true;
216  }
217 
218  if(bB.is_null() == true) {
219  RCP<const MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedRangeMap(),rcpB));
220  rcpB.swap(test);
221  }
222 
223  // we now can guarantee that X and B are blocked multi vectors
224  bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
225  bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
226 
227  // check the type of operator
228  RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rbA = Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(bA);
229  if(rbA.is_null() == false) {
230  // A is a ReorderedBlockedCrsMatrix
231  Teuchos::RCP<const Xpetra::BlockReorderManager > brm = rbA->getBlockReorderManager();
232 
233  // check type of X vector
234  if(bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps()) {
235  // X is a blocked multi vector but incompatible to the reordered blocked operator A
236  Teuchos::RCP<MultiVector> test =
237  buildReorderedBlockedMultiVector(brm, bX);
238  rcpX.swap(test);
239  }
240  if(bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps()) {
241  // B is a blocked multi vector but incompatible to the reordered blocked operator A
242  Teuchos::RCP<const MultiVector> test =
243  buildReorderedBlockedMultiVector(brm, bB);
244  rcpB.swap(test);
245  }
246  }
247 
248 
249  // check the type of operator
250  /*RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
251  MUELU_TEST_FOR_EXCEPTION(bA.is_null() == true, Exceptions::RuntimeError, "MueLu::BlockedJacobiSmoother::Apply(): A_ must be a BlockedCrsMatrix");
252  RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rbA = Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(bA);
253  if(rbA.is_null() == false) {
254  // A is a ReorderedBlockedCrsMatrix
255  Teuchos::RCP<const Xpetra::BlockReorderManager > brm = rbA->getBlockReorderManager();
256 
257  // check type of vectors
258  RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
259  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
260 
261  // check type of X vector
262  if(bX.is_null() == false && bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps()) {
263  RCP<ReorderedBlockedMultiVector> rbX = Teuchos::rcp_dynamic_cast<ReorderedBlockedMultiVector>(bX);
264  if(rbX.is_null() == true) {
265  // X is a blocked multi vector but not reordered
266  // However, A is a reordered blocked operator
267  // We have to make sure, that A and X use compatible maps
268  Teuchos::RCP<MultiVector> test =
269  buildReorderedBlockedMultiVector(brm, bX);
270  rcpX.swap(test);
271  }
272  }
273  if(bB.is_null() == false && bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps()) {
274  RCP<const ReorderedBlockedMultiVector> rbB = Teuchos::rcp_dynamic_cast<const ReorderedBlockedMultiVector>(bB);
275  if(rbB.is_null() == true) {
276  // B is a blocked multi vector but not reordered
277  // However, A is a reordered blocked operator
278  // We have to make sure, that A and X use compatible maps
279  Teuchos::RCP<const MultiVector> test =
280  buildReorderedBlockedMultiVector(brm, bB);
281  rcpB.swap(test);
282  }
283  }
284  }*/
285 
286  // Throughout the rest of the algorithm rcpX and rcpB are used for solution vector and RHS
287 
288  RCP<MultiVector> residual = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
289  RCP<MultiVector> tempres = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
290 
291  // extract parameters from internal parameter list
292  const ParameterList & pL = Factory::GetParameterList();
293  LocalOrdinal nSweeps = pL.get<LocalOrdinal>("Sweeps");
294  Scalar omega = pL.get<Scalar>("Damping factor");
295 
296  // outer Richardson loop
297  for (LocalOrdinal run = 0; run < nSweeps; ++run) {
298  residual->update(1.0,*rcpB,0.0); // r = B
299  if(InitialGuessIsZero == false || run > 0){
300  bA->apply(*rcpX, *residual, Teuchos::NO_TRANS, -1.0, 1.0);
301  }
302  // one sweep of Jacobi: loop over all block rows
303  for(size_t i = 0; i<Inverse_.size(); i++) {
304 
305  // extract corresponding subvectors from X and residual
306  bool bRangeThyraMode = rangeMapExtractor_->getThyraMode();
307  bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
308  Teuchos::RCP<MultiVector> Xi = domainMapExtractor_->ExtractVector(rcpX, i, bDomainThyraMode);
309  Teuchos::RCP<MultiVector> ri = rangeMapExtractor_->ExtractVector(residual, i, bRangeThyraMode);
310  Teuchos::RCP<MultiVector> tXi = domainMapExtractor_->getVector(i, X.getNumVectors(), bDomainThyraMode);
311 
312  // apply solver/smoother
313  Inverse_.at(i)->Apply(*tXi, *ri, false);
314 
315  // update vector
316  if( InitialGuessIsZero && run == 0 ){
317  Xi->update(omega,*tXi,0.0); // X_{i+1} = X_i + omega \Delta X_i
318  } else {
319  Xi->update(omega,*tXi,1.0); // X_{i+1} = X_i + omega \Delta X_i
320  }
321 
322  }
323  }
324 
325  if (bCopyResultX == true) {
326  RCP<MultiVector> Xmerged = bX->Merge();
327  X.update(one, *Xmerged, zero);
328  }
329  }
330 
331  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
332  RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> > BlockedJacobiSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Copy() const {
333  return rcp( new BlockedJacobiSmoother(*this) );
334  }
335 
336  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
338  std::ostringstream out;
340  out << "{type = " << type_ << "}";
341  return out.str();
342  }
343 
344  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
345  void BlockedJacobiSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
347 
348  // extract parameters from internal parameter list
349  const ParameterList & pL = Factory::GetParameterList();
350  LocalOrdinal nSweeps = pL.get<LocalOrdinal>("Sweeps");
351  Scalar omega = pL.get<Scalar>("Damping factor");
352 
353  if (verbLevel & Parameters0) {
354  out0 << "Prec. type: " << type_ << " Sweeps: " << nSweeps << " damping: " << omega << std::endl;
355  }
356 
357  if (verbLevel & Debug) {
358  out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl;
359  }
360  }
361 
362  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
364  // FIXME: This is a placeholder
365  return Teuchos::OrdinalTraits<size_t>::invalid();
366  }
367 
368 } // namespace MueLu
369 
370 #endif /* MUELU_BLOCKEDJACOBISMOOTHER_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
block Jacobi method for blocked matrices
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the direct solver.
RCP< const ParameterList > GetValidParameterList() const
Input.
void Setup(Level &currentLevel)
Setup routine In the Setup method the Inverse_ vector is filled with the corresponding SmootherBase o...
std::string description() const
Return a simple one-line description of this object.
void DeclareInput(Level &currentLevel) const
Input.
RCP< SmootherPrototype > Copy() const
std::vector< Teuchos::RCP< const FactoryManagerBase > > FactManager_
vector of factory managers
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager, int pos)
Add a factory manager.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
virtual std::string description() const
Return a simple one-line description of this object.
Exception indicating invalid cast attempted.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
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
An exception safe way to call the method 'Level::SetFactoryManager()'.
bool IsSetup() const
Get the state of a smoother prototype.
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.