MueLu  Version of the Day
MueLu_BlockedGaussSeidelSmoother_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_BLOCKEDGAUSSSEIDELSMOOTHER_DEF_HPP_
48 #define MUELU_BLOCKEDGAUSSSEIDELSMOOTHER_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 GaussSeidel"), 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 BGS");
87  validParamList->set< LocalOrdinal > ("Sweeps", 1, "Number of BGS sweeps (default = 1)");
88 
89  return validParamList;
90  }
91 
92  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
93  void BlockedGaussSeidelSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::AddFactoryManager(RCP<const FactoryManagerBase> FactManager, int pos) {
94  TEUCHOS_TEST_FOR_EXCEPTION(pos < 0, Exceptions::RuntimeError, "MueLu::BlockedGaussSeidelSmoother::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 entries in FactManager_ vector
100  FactManager_.at(myPos) = FactManager;
101  } else if(myPos == FactManager_.size()) {
102  // append new Factory manager at 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 Gauss-Seidel Smoother", currentLevel);
138  if (SmootherPrototype::IsSetup() == true) this->GetOStream(Warnings0) << "MueLu::BlockedGaussSeidelSmoother::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::BlockedGaussSeidelSmoother::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::BlockedGaussSeidelSmoother::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 (BGS ordering)
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 BlockedGaussSeidelSmoother<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::BlockedGaussSeidelSmoother::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) << "BlockedGaussSeidel: 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::BlockedGaussSeidelSmoother::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) << "BlockedGaussSeidel: 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::BlockedGaussSeidelSmoother::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) << "BlockedGaussSeidel: 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::BlockedGaussSeidelSmoother::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) << "BlockedGaussSeidel: 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::BlockedGaussSeidelSmoother::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 #endif
197  SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
198 
199  // Input variables used for the rest of the algorithm
200  RCP<MultiVector> rcpX = Teuchos::rcpFromRef(X);
201  RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
202 
203  // make sure that both rcpX and rcpB are BlockedMultiVector objects
204  bool bCopyResultX = false;
205  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
206  MUELU_TEST_FOR_EXCEPTION(bA.is_null() == true, Exceptions::RuntimeError, "MueLu::BlockedGaussSeidelSmoother::Apply(): A_ must be a BlockedCrsMatrix");
207  RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
208  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
209 
210  if(bX.is_null() == true) {
211  RCP<MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedDomainMap(),rcpX));
212  rcpX.swap(test);
213  bCopyResultX = true;
214  }
215 
216  if(bB.is_null() == true) {
217  RCP<const MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedRangeMap(),rcpB));
218  rcpB.swap(test);
219  }
220 
221  // we now can guarantee that X and B are blocked multi vectors
222  bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
223  bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
224 
225  // check the type of operator
226  RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rbA = Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(bA);
227  if(rbA.is_null() == false) {
228  // A is a ReorderedBlockedCrsMatrix
229  Teuchos::RCP<const Xpetra::BlockReorderManager > brm = rbA->getBlockReorderManager();
230 
231  // check type of X vector
232  if(bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps()) {
233  // X is a blocked multi vector but incompatible to the reordered blocked operator A
234  Teuchos::RCP<MultiVector> test =
235  buildReorderedBlockedMultiVector(brm, bX);
236  rcpX.swap(test);
237  }
238  if(bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps()) {
239  // B is a blocked multi vector but incompatible to the reordered blocked operator A
240  Teuchos::RCP<const MultiVector> test =
241  buildReorderedBlockedMultiVector(brm, bB);
242  rcpB.swap(test);
243  }
244  }
245 
246 
247  // check the type of operator
248  /*RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
249  MUELU_TEST_FOR_EXCEPTION(bA.is_null() == true, Exceptions::RuntimeError, "MueLu::BlockedGaussSeidelSmoother::Apply(): A_ must be a BlockedCrsMatrix");
250  RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rbA = Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(bA);
251  if(rbA.is_null() == false) {
252  // A is a ReorderedBlockedCrsMatrix
253  Teuchos::RCP<const Xpetra::BlockReorderManager > brm = rbA->getBlockReorderManager();
254 
255  // check type of vectors
256  RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
257  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
258 
259  // check type of X vector
260  if(bX.is_null() == false && bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps()) {
261  RCP<ReorderedBlockedMultiVector> rbX = Teuchos::rcp_dynamic_cast<ReorderedBlockedMultiVector>(bX);
262  if(rbX.is_null() == true) {
263  // X is a blocked multi vector but not reordered
264  // However, A is a reordered blocked operator
265  // We have to make sure, that A and X use compatible maps
266  Teuchos::RCP<MultiVector> test =
267  buildReorderedBlockedMultiVector(brm, bX);
268  rcpX.swap(test);
269  }
270  }
271  if(bB.is_null() == false && bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps()) {
272  RCP<const ReorderedBlockedMultiVector> rbB = Teuchos::rcp_dynamic_cast<const ReorderedBlockedMultiVector>(bB);
273  if(rbB.is_null() == true) {
274  // B is a blocked multi vector but not reordered
275  // However, A is a reordered blocked operator
276  // We have to make sure, that A and X use compatible maps
277  Teuchos::RCP<const MultiVector> test =
278  buildReorderedBlockedMultiVector(brm, bB);
279  rcpB.swap(test);
280  }
281  }
282  }*/
283 
284  // Throughout the rest of the algorithm rcpX and rcpB are used for solution vector and RHS
285 
286  RCP<MultiVector> residual = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
287  RCP<MultiVector> tempres = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
288 
289  // extract parameters from internal parameter list
290  const ParameterList & pL = Factory::GetParameterList();
291  LocalOrdinal nSweeps = pL.get<LocalOrdinal>("Sweeps");
292  Scalar omega = pL.get<Scalar>("Damping factor");
293 
294 
295  // Clear solution from previos V cycles in case it is still stored
296  if( InitialGuessIsZero==true )
297  rcpX->putScalar(Teuchos::ScalarTraits<Scalar>::zero());
298 
299 
300  // outer Richardson loop
301  for (LocalOrdinal run = 0; run < nSweeps; ++run) {
302  // one BGS sweep
303  // loop over all block rows
304  for(size_t i = 0; i<Inverse_.size(); i++) {
305 
306  // calculate block residual r = B-A*X
307  // note: A_ is the full blocked operator
308  residual->update(1.0,*rcpB,0.0); // r = B
309  if(InitialGuessIsZero == false || i > 0 || run > 0)
310  bA->bgs_apply(*rcpX, *residual, i, Teuchos::NO_TRANS, -1.0, 1.0);
311 
312  // extract corresponding subvectors from X and residual
313  bool bRangeThyraMode = rangeMapExtractor_->getThyraMode();
314  bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
315  Teuchos::RCP<MultiVector> Xi = domainMapExtractor_->ExtractVector(rcpX, i, bDomainThyraMode);
316  Teuchos::RCP<MultiVector> ri = rangeMapExtractor_->ExtractVector(residual, i, bRangeThyraMode);
317  Teuchos::RCP<MultiVector> tXi = domainMapExtractor_->getVector(i, X.getNumVectors(), bDomainThyraMode);
318 
319  // apply solver/smoother
320  Inverse_.at(i)->Apply(*tXi, *ri, false);
321 
322  // update vector
323  Xi->update(omega,*tXi,1.0); // X_{i+1} = X_i + omega \Delta X_i
324 
325  }
326  }
327 
328  if (bCopyResultX == true) {
329  RCP<MultiVector> Xmerged = bX->Merge();
330  X.update(one, *Xmerged, zero);
331  }
332  }
333 
334  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
335  RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> > BlockedGaussSeidelSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Copy() const {
336  return rcp( new BlockedGaussSeidelSmoother(*this) );
337  }
338 
339  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
341  std::ostringstream out;
343  out << "{type = " << type_ << "}";
344  return out.str();
345  }
346 
347  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
348  void BlockedGaussSeidelSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
350 
351  // extract parameters from internal parameter list
352  const ParameterList & pL = Factory::GetParameterList();
353  LocalOrdinal nSweeps = pL.get<LocalOrdinal>("Sweeps");
354  Scalar omega = pL.get<Scalar>("Damping factor");
355 
356  if (verbLevel & Parameters0) {
357  out0 << "Prec. type: " << type_ << " Sweeps: " << nSweeps << " damping: " << omega << std::endl;
358  }
359 
360  if (verbLevel & Debug) {
361  out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl;
362  }
363  }
364  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
366  // FIXME: This is a placeholder
367  return Teuchos::OrdinalTraits<size_t>::invalid();
368  }
369 
370 } // namespace MueLu
371 
372 #endif /* MUELU_BLOCKEDGAUSSSEIDELSMOOTHER_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 Gauss-Seidel method for blocked matrices
void DeclareInput(Level &currentLevel) const
Input.
std::vector< Teuchos::RCP< const FactoryManagerBase > > FactManager_
vector of factory managers
std::string description() const
Return a simple one-line description of this object.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager, int pos)
Add a factory manager.
RCP< const ParameterList > GetValidParameterList() const
Input.
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the direct solver. Solves the linear system AX=B using the constructed solver.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level verbLevel to an FancyOStream object out.
void Setup(Level &currentLevel)
Setup routine In the Setup method the Inverse_ vector is filled with the corresponding SmootherBase o...
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.