MueLu  Version of the Day
MueLu_Ifpack2Smoother_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 #ifndef MUELU_IFPACK2SMOOTHER_DEF_HPP
47 #define MUELU_IFPACK2SMOOTHER_DEF_HPP
48 
49 #include "MueLu_ConfigDefs.hpp"
50 
51 #if defined(HAVE_MUELU_TPETRA) && defined(HAVE_MUELU_IFPACK2)
52 
53 #include <Teuchos_ParameterList.hpp>
54 
55 #include <Tpetra_RowMatrix.hpp>
56 
57 #include <Ifpack2_Chebyshev.hpp>
58 #include <Ifpack2_Factory.hpp>
59 #include <Ifpack2_Parameters.hpp>
60 
61 #include <Xpetra_BlockedCrsMatrix.hpp>
62 #include <Xpetra_CrsMatrix.hpp>
63 #include <Xpetra_CrsMatrixWrap.hpp>
64 #include <Xpetra_Matrix.hpp>
65 #include <Xpetra_MultiVectorFactory.hpp>
66 
68 #include "MueLu_Level.hpp"
70 #include "MueLu_Utilities.hpp"
71 #include "MueLu_Monitor.hpp"
72 
73 namespace MueLu {
74 
75  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
76  Ifpack2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Ifpack2Smoother(const std::string& type, const Teuchos::ParameterList& paramList, const LO& overlap)
77  : type_(type), overlap_(overlap)
78  {
79  SetParameterList(paramList);
80  }
81 
82  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
84  Factory::SetParameterList(paramList);
85 
87  // It might be invalid to change parameters after the setup, but it depends entirely on Ifpack implementation.
88  // TODO: I don't know if Ifpack returns an error code or exception or ignore parameters modification in this case...
90  }
91  }
92 
93  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
95  ParameterList& paramList = const_cast<ParameterList&>(this->GetParameterList());
96  paramList.setParameters(list);
97 
98  RCP<ParameterList> precList = this->RemoveFactoriesFromList(this->GetParameterList());
99 
100  prec_->setParameters(*precList);
101 
102  paramList.setParameters(*precList); // what about that??
103  }
104 
105  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
107  this->Input(currentLevel, "A");
108 
109  if (type_ == "LINESMOOTHING_BANDED_RELAXATION" ||
110  type_ == "LINESMOOTHING_BANDED RELAXATION" ||
111  type_ == "LINESMOOTHING_BANDEDRELAXATION" ||
112  type_ == "LINESMOOTHING_BLOCK_RELAXATION" ||
113  type_ == "LINESMOOTHING_BLOCK RELAXATION" ||
114  type_ == "LINESMOOTHING_BLOCKRELAXATION") {
115  this->Input(currentLevel, "CoarseNumZLayers"); // necessary for fallback criterion
116  this->Input(currentLevel, "LineDetection_VertLineIds"); // necessary to feed block smoother
117  } // if (type_ == "LINESMOOTHING_BANDEDRELAXATION")
118  }
119 
120  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
122  FactoryMonitor m(*this, "Setup Smoother", currentLevel);
123 
124  if (this->IsSetup() == true)
125  this->GetOStream(Warnings0) << "MueLu::Ifpack2Smoother::Setup(): Setup() has already been called";
126 
127  A_ = Factory::Get< RCP<Matrix> >(currentLevel, "A");
128 
129  typedef Teuchos::ScalarTraits<SC> STS;
130  SC negone = -STS::one();
131 
132  SC lambdaMax = negone;
133 
134  // If we are doing "user" partitioning, we assume that what the user
135  // really wants to do is make tiny little subdomains with one row
136  // asssigned to each subdomain. The rows used for these little
137  // subdomains correspond to those in the 2nd block row. Then,
138  // if we overlap these mini-subdomains, we will do something that
139  // looks like Vanka (grabbing all velocities associated with each
140  // each pressure unknown). In addition, we put all Dirichlet points
141  // as a little mini-domain.
142 
143  bool isBlockedMatrix = false;
144  RCP<Matrix> merged2Mat;
145  if (type_ == "SCHWARZ") {
146  ParameterList& paramList = const_cast<ParameterList&>(this->GetParameterList());
147 
148  std::string sublistName = "subdomain solver parameters";
149  if (paramList.isSublist(sublistName)) {
150  ParameterList& subList = paramList.sublist(sublistName);
151 
152  std::string partName = "partitioner: type";
153  if (subList.isParameter(partName) && subList.get<std::string>(partName) == "user") {
154  isBlockedMatrix = true;
155 
156  RCP<BlockedCrsMatrix> bA = rcp_dynamic_cast<BlockedCrsMatrix>(A_);
157  TEUCHOS_TEST_FOR_EXCEPTION(bA.is_null(), Exceptions::BadCast,
158  "Matrix A must be of type BlockedCrsMatrix.");
159 
160  size_t numVels = bA->getMatrix(0,0)->getNodeNumRows();
161  size_t numPres = bA->getMatrix(1,0)->getNodeNumRows();
162  size_t numRows = A_->getNodeNumRows();
163 
164  ArrayRCP<LocalOrdinal> blockSeeds(numRows, Teuchos::OrdinalTraits<LocalOrdinal>::invalid());
165 
166  size_t numBlocks = 0;
167  for (size_t rowOfB = numVels; rowOfB < numVels+numPres; ++rowOfB)
168  blockSeeds[rowOfB] = numBlocks++;
169 
170  RCP<BlockedCrsMatrix> bA2 = rcp_dynamic_cast<BlockedCrsMatrix>(A_);
171  TEUCHOS_TEST_FOR_EXCEPTION(bA2.is_null(), Exceptions::BadCast,
172  "Matrix A must be of type BlockedCrsMatrix.");
173 
174  RCP<CrsMatrix> mergedMat = bA2->Merge();
175  merged2Mat = rcp(new CrsMatrixWrap(mergedMat));
176 
177  // Add Dirichlet rows to the list of seeds
178  ArrayRCP<const bool> boundaryNodes;
179  boundaryNodes = Utilities::DetectDirichletRows(*merged2Mat, 0.0);
180  bool haveBoundary = false;
181  for (LO i = 0; i < boundaryNodes.size(); i++)
182  if (boundaryNodes[i]) {
183  // FIXME:
184  // 1. would not this [] overlap with some in the previos blockSeed loop?
185  // 2. do we need to distinguish between pressure and velocity Dirichlet b.c.
186  blockSeeds[i] = numBlocks;
187  haveBoundary = true;
188  }
189  if (haveBoundary)
190  numBlocks++;
191 
192  subList.set("partitioner: map", blockSeeds);
193  subList.set("partitioner: local parts", as<int>(numBlocks));
194  }
195  }
196  } // if (type_ == "SCHWARZ")
197 
198  if (type_ == "LINESMOOTHING_BANDED_RELAXATION" ||
199  type_ == "LINESMOOTHING_BANDED RELAXATION" ||
200  type_ == "LINESMOOTHING_BANDEDRELAXATION" ||
201  type_ == "LINESMOOTHING_BLOCK_RELAXATION" ||
202  type_ == "LINESMOOTHING_BLOCK RELAXATION" ||
203  type_ == "LINESMOOTHING_BLOCKRELAXATION" ) {
204  ParameterList& myparamList = const_cast<ParameterList&>(this->GetParameterList());
205 
206  LO CoarseNumZLayers = Factory::Get<LO>(currentLevel,"CoarseNumZLayers");
207  if (CoarseNumZLayers > 0) {
208  Teuchos::ArrayRCP<LO> TVertLineIdSmoo = Factory::Get< Teuchos::ArrayRCP<LO> >(currentLevel, "LineDetection_VertLineIds");
209 
210  // determine number of local parts
211  LO maxPart = 0;
212  for(size_t k = 0; k < Teuchos::as<size_t>(TVertLineIdSmoo.size()); k++) {
213  if(maxPart < TVertLineIdSmoo[k]) maxPart = TVertLineIdSmoo[k];
214  }
215 
216  size_t numLocalRows = A_->getNodeNumRows();
217  TEUCHOS_TEST_FOR_EXCEPTION(numLocalRows % TVertLineIdSmoo.size() != 0, Exceptions::RuntimeError, "MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the TVertLineIdsSmoo.");
218 
219  if (numLocalRows == Teuchos::as<size_t>(TVertLineIdSmoo.size())) {
220  myparamList.set("partitioner: type","user");
221  myparamList.set("partitioner: map",TVertLineIdSmoo);
222  myparamList.set("partitioner: local parts",maxPart+1);
223  } else {
224  // we assume a constant number of DOFs per node
225  size_t numDofsPerNode = numLocalRows / TVertLineIdSmoo.size();
226 
227  // Create a new Teuchos::ArrayRCP<LO> of size numLocalRows and fill it with the corresponding information
228  Teuchos::ArrayRCP<LO> partitionerMap(numLocalRows, Teuchos::OrdinalTraits<LocalOrdinal>::invalid());
229  for (size_t blockRow = 0; blockRow < Teuchos::as<size_t>(TVertLineIdSmoo.size()); ++blockRow)
230  for (size_t dof = 0; dof < numDofsPerNode; dof++)
231  partitionerMap[blockRow * numDofsPerNode + dof] = TVertLineIdSmoo[blockRow];
232  myparamList.set("partitioner: type","user");
233  myparamList.set("partitioner: map",partitionerMap);
234  myparamList.set("partitioner: local parts",maxPart + 1);
235  }
236 
237  if (type_ == "LINESMOOTHING_BANDED_RELAXATION" ||
238  type_ == "LINESMOOTHING_BANDED RELAXATION" ||
239  type_ == "LINESMOOTHING_BANDEDRELAXATION")
240  type_ = "BANDEDRELAXATION";
241  else
242  type_ = "BLOCKRELAXATION";
243  } else {
244  // line detection failed -> fallback to point-wise relaxation
245  this->GetOStream(Runtime0) << "Line detection failed: fall back to point-wise relaxation" << std::endl;
246  myparamList.remove("partitioner: type",false);
247  myparamList.remove("partitioner: map", false);
248  myparamList.remove("partitioner: local parts",false);
249  type_ = "RELAXATION";
250  }
251 
252  } // if (type_ == "LINESMOOTHING_BANDEDRELAXATION")
253 
254  if (type_ == "CHEBYSHEV") {
255  std::string maxEigString = "chebyshev: max eigenvalue";
256  std::string eigRatioString = "chebyshev: ratio eigenvalue";
257 
258  ParameterList& paramList = const_cast<ParameterList&>(this->GetParameterList());
259 
260  // Get/calculate the maximum eigenvalue
261  if (paramList.isParameter(maxEigString)) {
262  if (paramList.isType<double>(maxEigString))
263  lambdaMax = paramList.get<double>(maxEigString);
264  else
265  lambdaMax = paramList.get<SC>(maxEigString);
266  this->GetOStream(Statistics1) << maxEigString << " (cached with smoother parameter list) = " << lambdaMax << std::endl;
267 
268  } else {
269  lambdaMax = A_->GetMaxEigenvalueEstimate();
270  if (lambdaMax != negone) {
271  this->GetOStream(Statistics1) << maxEigString << " (cached with matrix) = " << lambdaMax << std::endl;
272  paramList.set(maxEigString, lambdaMax);
273  }
274  }
275 
276  // Calculate the eigenvalue ratio
277  const SC defaultEigRatio = 20;
278 
279  SC ratio = defaultEigRatio;
280  if (paramList.isParameter(eigRatioString)) {
281  if (paramList.isType<double>(eigRatioString))
282  ratio = paramList.get<double>(eigRatioString);
283  else
284  ratio = paramList.get<SC>(eigRatioString);
285  }
286  if (currentLevel.GetLevelID()) {
287  // Update ratio to be
288  // ratio = max(number of fine DOFs / number of coarse DOFs, defaultValue)
289  //
290  // NOTE: We don't need to request previous level matrix as we know for sure it was constructed
291  RCP<const Matrix> fineA = currentLevel.GetPreviousLevel()->Get<RCP<Matrix> >("A");
292  size_t nRowsFine = fineA->getGlobalNumRows();
293  size_t nRowsCoarse = A_->getGlobalNumRows();
294 
295  SC levelRatio = as<SC>(as<float>(nRowsFine)/nRowsCoarse);
296  if (STS::magnitude(levelRatio) > STS::magnitude(ratio))
297  ratio = levelRatio;
298  }
299 
300  this->GetOStream(Statistics1) << eigRatioString << " (computed) = " << ratio << std::endl;
301  paramList.set(eigRatioString, ratio);
302  }
303 
304  RCP<const Tpetra::RowMatrix<SC, LO, GO, NO> > tpA;
305  if (isBlockedMatrix == true) tpA = Utilities::Op2NonConstTpetraRow(merged2Mat);
309  prec_->initialize();
310  prec_->compute();
311 
313 
314  if (type_ == "CHEBYSHEV" && lambdaMax == negone) {
315  typedef Tpetra::RowMatrix<SC, LO, GO, NO> MatrixType;
316 
317  Teuchos::RCP<Ifpack2::Chebyshev<MatrixType> > chebyPrec = rcp_dynamic_cast<Ifpack2::Chebyshev<MatrixType> >(prec_);
318  if (chebyPrec != Teuchos::null) {
319  lambdaMax = chebyPrec->getLambdaMaxForApply();
320  A_->SetMaxEigenvalueEstimate(lambdaMax);
321  this->GetOStream(Statistics1) << "chebyshev: max eigenvalue (calculated by Ifpack2)" << " = " << lambdaMax << std::endl;
322  }
323  TEUCHOS_TEST_FOR_EXCEPTION(lambdaMax == negone, Exceptions::RuntimeError, "MueLu::IfpackSmoother::Setup(): no maximum eigenvalue estimate");
324  }
325 
326  this->GetOStream(Statistics0) << description() << std::endl;
327  }
328 
329  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
330  void Ifpack2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const {
331  TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, Exceptions::RuntimeError, "MueLu::IfpackSmoother::Apply(): Setup() has not been called");
332 
333  // Forward the InitialGuessIsZero option to Ifpack2
334  // TODO: It might be nice to switch back the internal
335  // "zero starting solution" option of the ifpack2 object prec_ to his
336  // initial value at the end but there is no way right now to get
337  // the current value of the "zero starting solution" in ifpack2.
338  // It's not really an issue, as prec_ can only be used by this method.
339  // TODO: When https://software.sandia.gov/bugzilla/show_bug.cgi?id=5283#c2 is done
340  // we should remove the if/else/elseif and just test if this
341  // option is supported by current ifpack2 preconditioner
342  Teuchos::ParameterList paramList;
343  bool supportInitialGuess = false;
344  if (type_ == "CHEBYSHEV") {
345  paramList.set("chebyshev: zero starting solution", InitialGuessIsZero);
346  SetPrecParameters(paramList);
347  supportInitialGuess = true;
348 
349  } else if (type_ == "RELAXATION") {
350  paramList.set("relaxation: zero starting solution", InitialGuessIsZero);
351  SetPrecParameters(paramList);
352  supportInitialGuess = true;
353 
354  } else if (type_ == "KRYLOV") {
355  paramList.set("krylov: zero starting solution", InitialGuessIsZero);
356  SetPrecParameters(paramList);
357  supportInitialGuess = true;
358 
359  } else if (type_ == "SCHWARZ") {
360  paramList.set("schwarz: zero starting solution", InitialGuessIsZero);
361  //Because additive Schwarz has "delta" semantics, it's sufficient to
362  //toggle only the zero initial guess flag, and not pass in already
363  //set parameters. If we call SetPrecParameters, the subdomain solver
364  //will be destroyed.
365  prec_->setParameters(paramList);
366  supportInitialGuess = true;
367  }
368 
369  //TODO JJH 30Apr2014 Calling SetPrecParameters(paramList) when the smoother
370  //is Ifpack2::AdditiveSchwarz::setParameterList() will destroy the subdomain
371  //(aka inner) solver. This behavior is documented but a departure from what
372  //it previously did, and what other Ifpack2 solvers currently do. So I have
373  //moved SetPrecParameters(paramList) into the if-else block above.
374 
375  // Apply
376  if (InitialGuessIsZero || supportInitialGuess) {
377  Tpetra::MultiVector<SC,LO,GO,NO>& tpX = Utilities::MV2NonConstTpetraMV(X);
378  const Tpetra::MultiVector<SC,LO,GO,NO>& tpB = Utilities::MV2TpetraMV(B);
379  prec_->apply(tpB, tpX);
380  } else {
381  typedef Teuchos::ScalarTraits<Scalar> TST;
382  RCP<MultiVector> Residual = Utilities::Residual(*A_, X, B);
383  RCP<MultiVector> Correction = MultiVectorFactory::Build(A_->getDomainMap(), X.getNumVectors());
384 
385  Tpetra::MultiVector<SC,LO,GO,NO>& tpX = Utilities::MV2NonConstTpetraMV(*Correction);
386  const Tpetra::MultiVector<SC,LO,GO,NO>& tpB = Utilities::MV2TpetraMV(*Residual);
387 
388  prec_->apply(tpB, tpX);
389 
390  X.update(TST::one(), *Correction, TST::one());
391  }
392  }
393 
394  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
395  RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Ifpack2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Copy() const {
396  RCP<Ifpack2Smoother> smoother = rcp(new Ifpack2Smoother(*this) );
397  smoother->SetParameterList(this->GetParameterList());
398  return smoother;
399  }
400 
401  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
403  std::ostringstream out;
405  out << prec_->description();
406  } else {
408  out << "{type = " << type_ << "}";
409  }
410  return out.str();
411  }
412 
413  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
414  void Ifpack2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
416 
417  if (verbLevel & Parameters0)
418  out0 << "Prec. type: " << type_ << std::endl;
419 
420  if (verbLevel & Parameters1) {
421  out0 << "Parameter list: " << std::endl;
422  Teuchos::OSTab tab2(out);
423  out << this->GetParameterList();
424  out0 << "Overlap: " << overlap_ << std::endl;
425  }
426 
427  if (verbLevel & External)
428  if (prec_ != Teuchos::null) {
429  Teuchos::OSTab tab2(out);
430  out << *prec_ << std::endl;
431  }
432 
433  if (verbLevel & Debug) {
434  out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl
435  << "-" << std::endl
436  << "RCP<prec_>: " << prec_ << std::endl;
437  }
438  }
439 
440 } // namespace MueLu
441 
442 #endif // HAVE_MUELU_TPETRA && HAVE_MUELU_IFPACK2
443 #endif // MUELU_IFPACK2SMOOTHER_DEF_HPP
void DeclareInput(Level &currentLevel) const
Input.
Important warning messages (one line)
Exception indicating invalid cast attempted.
static RCP< const Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > MV2TpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > const vec)
Helper utility to pull out the underlying Tpetra objects from an Xpetra object.
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
Print external lib objects.
friend class Ifpack2Smoother
Constructor.
Timer to be used in factories. Similar to Monitor but with additional timers.
RCP< Matrix > A_
matrix, used in apply if solving residual equation
Print more statistics.
Print additional debugging information.
One-liner description of what is happening.
void SetParameterList(const Teuchos::ParameterList &paramList)
Namespace for MueLu classes and methods.
virtual const Teuchos::ParameterList & GetParameterList() const
LO overlap_
overlap when using the smoother in additive Schwarz mode
static RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > MV2NonConstTpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > vec)
std::string type_
ifpack2-specific key phrase that denote smoother type
Print statistics that do not involve significant additional computation.
RCP< ParameterList > RemoveFactoriesFromList(const ParameterList &list) const
static RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Residual(const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &RHS)
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
virtual void SetParameterList(const ParameterList &paramList)
Set parameters from a parameter list and return with default values.
RCP< SmootherPrototype > Copy() const
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
void Setup(Level &currentLevel)
Set up the smoother.
std::string description() const
Return a simple one-line description of this object.
bool IsSetup() const
Get the state of a smoother prototype.
static Teuchos::RCP< Preconditioner< typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > > create(const std::string &precType, const Teuchos::RCP< const MatrixType > &matrix)
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Print class parameters.
void SetPrecParameters(const Teuchos::ParameterList &list=Teuchos::ParameterList()) const
MatrixType::scalar_type getLambdaMaxForApply() const
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the preconditioner.
static Teuchos::ArrayRCP< const bool > DetectDirichletRows(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Magnitude &tol=Teuchos::ScalarTraits< Scalar >::magnitude(0.))
Print class parameters (more parameters, more verbose)
Exception throws to report errors in the internal logical of the program.
static RCP< Tpetra::RowMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Op2NonConstTpetraRow(RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Op)
void Input(Level &level, const std::string &varName) const
RCP< Ifpack2::Preconditioner< Scalar, LocalOrdinal, GlobalOrdinal, Node > > prec_
pointer to Ifpack2 preconditioner object
virtual std::string description() const
Return a simple one-line description of this object.