MueLu  Version of the Day
MueLu_BraessSarazinSmoother_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_BraessSarazinSmoother_def.hpp
48  *
49  * Created on: Apr 16, 2012
50  * Author: wiesner
51  */
52 
53 #ifndef MUELU_BRAESSSARAZINSMOOTHER_DEF_HPP_
54 #define MUELU_BRAESSSARAZINSMOOTHER_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>
64 #include <Xpetra_VectorFactory.hpp>
66 
68 #include "MueLu_Level.hpp"
69 #include "MueLu_Utilities.hpp"
70 #include "MueLu_Monitor.hpp"
71 #include "MueLu_HierarchyUtils.hpp"
72 #include "MueLu_SmootherBase.hpp"
73 
74 // include files for default FactoryManager
75 #include "MueLu_SchurComplementFactory.hpp"
76 #include "MueLu_DirectSolver.hpp"
77 #include "MueLu_SmootherFactory.hpp"
78 #include "MueLu_FactoryManager.hpp"
79 
80 namespace MueLu {
81 
82  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
84  : type_("Braess Sarazin"), A_(null)
85  {
86  //Factory::SetParameter("Sweeps", ParameterEntry(sweeps));
87  //Factory::SetParameter("Damping factor",ParameterEntry(omega));
88 
89 #if 0
90  // when declaring default factories without overwriting them leads to a multipleCallCheck exception
91  // TODO: debug into this
92  // workaround: always define your factory managers outside either using the C++ API or the XML files
94  SchurFact->SetParameter("omega",ParameterEntry(omega));
95  SchurFact->SetFactory("A", this->GetFactory("A"));
96 
97  // define smoother/solver for BraessSarazin
98  ParameterList SCparams;
99  std::string SCtype;
100  RCP<SmootherPrototype> smoProtoSC = rcp( new DirectSolver(SCtype,SCparams) );
101  smoProtoSC->SetFactory("A", SchurFact);
102 
103  RCP<SmootherFactory> SmooSCFact = rcp( new SmootherFactory(smoProtoSC) );
104 
105  RCP<FactoryManager> FactManager = rcp(new FactoryManager());
106  FactManager->SetFactory("A", SchurFact);
107  FactManager->SetFactory("Smoother", SmooSCFact);
108  FactManager->SetIgnoreUserData(true);
109 
110  AddFactoryManager(FactManager,0);
111 #endif
112  }
113 
114  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
116 
118  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
120  TEUCHOS_TEST_FOR_EXCEPTION(pos != 0, Exceptions::RuntimeError, "MueLu::BraessSarazinSmoother::AddFactoryManager: parameter \'pos\' must be zero! error.");
121  FactManager_ = FactManager;
122  }
123 
124  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
126  RCP<ParameterList> validParamList = rcp(new ParameterList());
127 
129 
130  validParamList->set<RCP<const FactoryBase> >("A", null, "Generating factory of the matrix A");
131 
132  validParamList->set<bool> ("lumping", false, "Use lumping to construct diag(A(0,0)), i.e. use row sum of the abs values on the diagonal "
133  "as approximation of A00 (and A00^{-1})");
134  validParamList->set<SC> ("Damping factor", one, "Damping/Scaling factor in BraessSarazin (usually has to be chosen > 1, default = 1.0)");
135  validParamList->set<LO> ("Sweeps", 1, "Number of BraessSarazin sweeps (default = 1)");
136  //validParamList->set<ParameterList> ("block1", ParameterList(), "Sublist for parameters for SchurComplement block. At least has to contain some information about a smoother \"Smoother\" for variable \"A\" which is generated by a SchurComplementFactory.");
137  validParamList->set<bool> ("q2q1 mode", false, "Run in the mode matching Q2Q1 matlab code");
138 
139  return validParamList;
140  }
141 
142  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
144  this->Input(currentLevel, "A");
145 
147  "MueLu::BraessSarazinSmoother::DeclareInput: FactManager_ must not be null! "
148  "Introduce a FactoryManager for the SchurComplement equation.");
149 
150  // carefully call DeclareInput after switching to internal FactoryManager
151  {
152  SetFactoryManager currentSFM(rcpFromRef(currentLevel), FactManager_);
153 
154  // request "Smoother" for current subblock row.
155  currentLevel.DeclareInput("PreSmoother", FactManager_->GetFactory("Smoother").get());
156 
157  // request Schur matrix just in case
158  currentLevel.DeclareInput("A", FactManager_->GetFactory("A").get());
159  }
160  }
161 
162  // Setup routine can be summarized in 4 steps:
163  // - set the map extractors
164  // - set the blocks
165  // - create and set the inverse of the diagonal of F
166  // - set the smoother for the Schur Complement
167  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
169  FactoryMonitor m(*this, "Setup Smoother", currentLevel);
170 
171  if (SmootherPrototype::IsSetup() == true)
172  this->GetOStream(Warnings0) << "MueLu::BreaessSarazinSmoother::Setup(): Setup() has already been called";
173 
174  // Extract blocked operator A from current level
175  A_ = Factory::Get<RCP<Matrix> > (currentLevel, "A");
176  RCP<BlockedCrsMatrix> bA = rcp_dynamic_cast<BlockedCrsMatrix>(A_);
178  "MueLu::BraessSarazinSmoother::Setup: input matrix A is not of type BlockedCrsMatrix! error.");
179 
180  // Store map extractors
181  rangeMapExtractor_ = bA->getRangeMapExtractor();
182  domainMapExtractor_ = bA->getDomainMapExtractor();
183 
184  // Store the blocks in local member variables
185  A00_ = bA->getMatrix(0,0);
186  A01_ = bA->getMatrix(0,1);
187  A10_ = bA->getMatrix(1,0);
188  A11_ = bA->getMatrix(1,1);
189 
191  SC omega = pL.get<SC>("Damping factor");
192 
193 #if 0 // old code
194  // Create the inverse of the diagonal of F
195  D_ = VectorFactory::Build(A00_->getRowMap());
196 
197  ArrayRCP<SC> diag;
198  if (pL.get<bool>("lumping") == false)
199  diag = Utilities::GetMatrixDiagonal (*A00_);
200  else
202 
204 
205  ArrayRCP<SC> Ddata = D_->getDataNonConst(0);
206  for (GO row = 0; row < Ddata.size(); row++)
207  Ddata[row] = one / (diag[row]*omega);*/
208 #else
209  // Create the inverse of the diagonal of F
210  // TODO add safety check for zeros on diagonal of F!
211  RCP<Vector> diagFVector = VectorFactory::Build(A00_->getRowMap());
212  if (pL.get<bool>("lumping") == false) {
213  A00_->getLocalDiagCopy(*diagFVector); // extract diagonal of F
214  } else {
215  diagFVector = Utilities::GetLumpedMatrixDiagonal(A00_);
216  }
217  diagFVector->scale(omega);
218  D_ = Utilities::GetInverse(diagFVector);
219 
220  // check whether D_ is a blocked vector with only 1 block
221  RCP<BlockedVector> bD = Teuchos::rcp_dynamic_cast<BlockedVector>(D_);
222  if(bD.is_null() == false && bD->getBlockedMap()->getNumMaps() == 1) {
223  RCP<Vector> nestedVec = bD->getMultiVector(0,bD->getBlockedMap()->getThyraMode())->getVectorNonConst(0);
224  D_.swap(nestedVec);
225  }
226 #endif
227 
228  // Set the Smoother
229  // carefully switch to the SubFactoryManagers (defined by the users)
230  {
231  SetFactoryManager currentSFM(rcpFromRef(currentLevel), FactManager_);
232  smoo_ = currentLevel.Get<RCP<SmootherBase> >("PreSmoother", FactManager_->GetFactory("Smoother").get());
233  S_ = currentLevel.Get<RCP<Matrix> > ("A", FactManager_->GetFactory("A").get());
234  }
235 
237  }
238 
239  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
240  void BraessSarazinSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const {
242  "MueLu::BraessSarazinSmoother::Apply(): Setup() has not been called");
243 
244 #if 0 //def HAVE_MUELU_DEBUG
245  // TODO simplify this debug check
246  RCP<MultiVector> rcpDebugX = Teuchos::rcpFromRef(X);
247  RCP<const MultiVector> rcpDebugB = Teuchos::rcpFromRef(B);
248  RCP<BlockedMultiVector> rcpBDebugX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpDebugX);
249  RCP<const BlockedMultiVector> rcpBDebugB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpDebugB);
250  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
251  if(rcpBDebugB.is_null() == false) {
252  //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.");
253  } else {
254  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.");
255  }
256  if(rcpBDebugX.is_null() == false) {
257  //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.");
258  } else {
259  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.");
260  }
261 #endif
262 
263 
264  RCP<MultiVector> rcpX = rcpFromRef(X);
265  RCP<const MultiVector> rcpB = rcpFromRef(B);
266 
267  // make sure that both rcpX and rcpB are BlockedMultiVector objects
268  bool bCopyResultX = false;
269  RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
270  MUELU_TEST_FOR_EXCEPTION(bA.is_null() == true, Exceptions::RuntimeError, "MueLu::BlockedGaussSeidelSmoother::Apply(): A_ must be a BlockedCrsMatrix");
271  RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
272  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
273 
274  if(bX.is_null() == true) {
275  RCP<MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedDomainMap(),rcpX));
276  rcpX.swap(test);
277  bCopyResultX = true;
278  }
279 
280  if(bB.is_null() == true) {
281  RCP<const MultiVector> test = Teuchos::rcp(new BlockedMultiVector(bA->getBlockedRangeMap(),rcpB));
282  rcpB.swap(test);
283  }
284 
285  // we now can guarantee that X and B are blocked multi vectors
286  bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
287  bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
288 
289  // check the type of operator
291  if(rbA.is_null() == false) {
292  // A is a ReorderedBlockedCrsMatrix
293  Teuchos::RCP<const Xpetra::BlockReorderManager > brm = rbA->getBlockReorderManager();
294 
295  // check type of X vector
296  if(bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps()) {
297  // X is a blocked multi vector but incompatible to the reordered blocked operator A
300  rcpX.swap(test);
301  }
302  if(bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps()) {
303  // B is a blocked multi vector but incompatible to the reordered blocked operator A
306  rcpB.swap(test);
307  }
308  }
309 
310  // use the GIDs of the sub blocks
311  // This is valid as the subblocks actually represent the GIDs (either Thyra, Xpetra or pseudo Xpetra)
312 
313  bool bRangeThyraMode = rangeMapExtractor_->getThyraMode();
314  bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
315 
316  RCP<MultiVector> deltaX = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
317  RCP<BlockedMultiVector> bdeltaX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(deltaX);
318  RCP<MultiVector> deltaX0 = bdeltaX->getMultiVector(0,bDomainThyraMode);
319  RCP<MultiVector> deltaX1 = bdeltaX->getMultiVector(1,bDomainThyraMode);
320 
321  RCP<MultiVector> Rtmp = rangeMapExtractor_->getVector(1, rcpB->getNumVectors(), bRangeThyraMode);
322 
323 
324  typedef Teuchos::ScalarTraits<SC> STS;
325  SC one = STS::one(), zero = STS::zero();
326 
327  // extract parameters from internal parameter list
329  LO nSweeps = pL.get<LO>("Sweeps");
330 
331  RCP<MultiVector> R;// = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());;
332  if (InitialGuessIsZero) {
333  R = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
334  R->update(one, *rcpB, zero);
335  } else {
336  R = Utilities::Residual(*A_, *rcpX, *rcpB);
337  }
338 
339  // extract diagonal of Schur complement operator
340  RCP<Vector> diagSVector = VectorFactory::Build(S_->getRowMap());
341  S_->getLocalDiagCopy(*diagSVector);
342 
343  for (LO run = 0; run < nSweeps; ++run) {
344  // Extract corresponding subvectors from X and R
345  // Automatically detect whether we use Thyra or Xpetra GIDs
346  // The GIDs should be always compatible with the GIDs of A00, A01, etc...
347  RCP<MultiVector> R0 = rangeMapExtractor_ ->ExtractVector(R, 0, bRangeThyraMode);
348  RCP<MultiVector> R1 = rangeMapExtractor_ ->ExtractVector(R, 1, bRangeThyraMode);
349 
350  // Calculate Rtmp = R1 - D * deltaX0 (equation 8.14)
351  deltaX0->putScalar(zero);
352  deltaX0->elementWiseMultiply(one, *D_, *R0, zero); // deltaX0 = D * R0 (equation 8.13)
353  A10_->apply(*deltaX0, *Rtmp); // Rtmp = A10*D*deltaX0 (intermediate step)
354  Rtmp->update(one, *R1, -one); // Rtmp = R1 - A10*D*deltaX0
355 
356  if (!pL.get<bool>("q2q1 mode")) {
357  deltaX1->putScalar(zero);
358  } else {
359  // special code for q2q1
360  if(Teuchos::rcp_dynamic_cast<BlockedVector>(diagSVector) == Teuchos::null) {
361  ArrayRCP<SC> Sdiag = diagSVector->getDataNonConst(0);
362  ArrayRCP<SC> deltaX1data = deltaX1->getDataNonConst(0);
363  ArrayRCP<SC> Rtmpdata = Rtmp->getDataNonConst(0);
364  for (GO row = 0; row < deltaX1data.size(); row++)
365  deltaX1data[row] = 1.1*Rtmpdata[row] / Sdiag[row];
366  } else {
367  TEUCHOS_TEST_FOR_EXCEPTION(true,MueLu::Exceptions::RuntimeError,"MueLu::BraessSarazinSmoother: q2q1 mode only supported for non-blocked operators.")
368  }
369  }
370 
371  smoo_->Apply(*deltaX1,*Rtmp);
372 
373  // Compute deltaX0
374  deltaX0->putScalar(zero); // just for safety
375  A01_->apply(*deltaX1, *deltaX0); // deltaX0 = A01*deltaX1
376  deltaX0->update(one, *R0, -one); // deltaX0 = R0 - A01*deltaX1
377  R0.swap(deltaX0);
378  deltaX0->elementWiseMultiply(one, *D_, *R0, zero); // deltaX0 = D*(R0 - A01*deltaX1)
379 
380  RCP<MultiVector> X0 = domainMapExtractor_->ExtractVector(rcpX, 0, bDomainThyraMode);
381  RCP<MultiVector> X1 = domainMapExtractor_->ExtractVector(rcpX, 1, bDomainThyraMode);
382 
383  // Update solution
384  X0->update(one, *deltaX0, one);
385  X1->update(one, *deltaX1, one);
386 
387  domainMapExtractor_->InsertVector(X0, 0, rcpX, bDomainThyraMode);
388  domainMapExtractor_->InsertVector(X1, 1, rcpX, bDomainThyraMode);
389 
390  if (run < nSweeps-1) {
391  R = Utilities::Residual(*A_, *rcpX, *rcpB);
392  }
393 
394  }
395 
396  if (bCopyResultX == true) {
397  RCP<MultiVector> Xmerged = bX->Merge();
398  X.update(one, *Xmerged, zero);
399  }
400 
401  }
402 
403  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
406  return rcp (new BraessSarazinSmoother (*this));
407  }
408 
409  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
411  description () const {
412  std::ostringstream out;
414  out << "{type = " << type_ << "}";
415  return out.str();
416  }
417 
418  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
421 
422  if (verbLevel & Parameters0) {
423  out0 << "Prec. type: " << type_ << /*" Sweeps: " << nSweeps_ << " damping: " << omega_ <<*/ std::endl;
424  }
425 
426  if (verbLevel & Debug) {
427  out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl;
428  }
429  }
430 
431  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
433  // FIXME: This is a placeholder
435  }
436 
437 
438 } // namespace MueLu
439 
440 #endif /* MUELU_BRAESSSARAZINSMOOTHER_DEF_HPP_ */
static Teuchos::ArrayRCP< Scalar > GetMatrixDiagonal(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
Important warning messages (one line)
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Exception indicating invalid cast attempted.
This class specifies the default factory that should generate some data on a Level if the data does n...
RCP< SmootherPrototype > Copy() const
BraessSarazin smoother for 2x2 block matrices.
size_type size() const
GlobalOrdinal GO
bool IsSetup() const
Get the state of a smoother prototype.
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void swap(RCP< T > &r_ptr)
Print additional debugging information.
static Teuchos::ArrayRCP< Scalar > GetLumpedMatrixDiagonal(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
LocalOrdinal LO
Namespace for MueLu classes and methods.
std::string description() const
Return a simple one-line description of this object.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
bool is_null() 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)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the Braess Sarazin smoother.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
virtual const Teuchos::ParameterList & GetParameterList() const
Print class parameters.
Factory for building the Schur Complement for a 2x2 block matrix.
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())
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager, int pos=0)
Add a factory manager for BraessSarazin internal SchurComplement handling.
void DeclareInput(Level &currentLevel) const
Input.
Scalar SC
void Setup(Level &currentLevel)
Setup routine.
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
Exception throws to report errors in the internal logical of the program.
#define MUELU_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
An exception safe way to call the method &#39;Level::SetFactoryManager()&#39;.
Teuchos::RCP< const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > buildReorderedBlockedMultiVector(Teuchos::RCP< const Xpetra::BlockReorderManager > brm, Teuchos::RCP< const Xpetra::BlockedMultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > bvec)
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
virtual std::string description() const
Return a simple one-line description of this object.
RCP< const ParameterList > GetValidParameterList() const
Input.
std::string toString(const T &t)