MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Amesos2Smoother_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_AMESOS2SMOOTHER_DEF_HPP
11#define MUELU_AMESOS2SMOOTHER_DEF_HPP
12
13#include <algorithm>
14
15#include "MueLu_ConfigDefs.hpp"
16#include <Xpetra_Matrix.hpp>
17#include <Xpetra_IO.hpp>
18
19#include <Amesos2_config.h>
20#include <Amesos2.hpp>
21
23#include "MueLu_Level.hpp"
24#include "MueLu_Utilities.hpp"
25#include "MueLu_Monitor.hpp"
26
27namespace MueLu {
28
29template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
31 Projection(RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& Nullspace) {
32 localMap_ = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(Nullspace->getMap()->lib(),
33 Nullspace->getNumVectors(),
34 Nullspace->getMap()->getIndexBase(),
35 Nullspace->getMap()->getComm(),
36 Xpetra::LocallyReplicated);
37
38 Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tempMV = Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(localMap_, Nullspace->getNumVectors(), false);
39 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one();
40 const Scalar ZERO = Teuchos::ScalarTraits<Scalar>::zero();
41 tempMV->multiply(Teuchos::CONJ_TRANS, Teuchos::NO_TRANS, ONE, *Nullspace, *Nullspace, ZERO);
42
43 Kokkos::View<Scalar**, Kokkos::LayoutLeft, Kokkos::HostSpace> Q("Q", Nullspace->getNumVectors(), Nullspace->getNumVectors());
44 int LDQ;
45 {
46 auto dots = tempMV->getLocalViewHost(Tpetra::Access::ReadOnly);
47 Kokkos::deep_copy(Q, dots);
48 LDQ = Q.stride(1);
49 }
50
51 Teuchos::LAPACK<LocalOrdinal, Scalar> lapack;
52 int info = 0;
53 lapack.POTRF('L', Nullspace->getNumVectors(), Q.data(), LDQ, &info);
54 TEUCHOS_ASSERT(info == 0);
55 lapack.TRTRI('L', 'N', Nullspace->getNumVectors(), Q.data(), LDQ, &info);
56 TEUCHOS_ASSERT(info == 0);
57
58 Nullspace_ = Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(Nullspace->getMap(), Nullspace->getNumVectors());
59
60 for (size_t i = 0; i < Nullspace->getNumVectors(); i++) {
61 for (size_t j = 0; j <= i; j++) {
62 Nullspace_->getVectorNonConst(i)->update(Q(i, j), *Nullspace->getVector(j), ONE);
63 }
64 }
65}
66
67template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69 projectOut(Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X) {
70 const Scalar ONE = Teuchos::ScalarTraits<Scalar>::one();
71 const Scalar ZERO = Teuchos::ScalarTraits<Scalar>::zero();
72
73 // Project X onto orthonormal nullspace
74 // Nullspace_ ^T * X
75 Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tempMV = Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(localMap_, X.getNumVectors());
76 tempMV->multiply(Teuchos::CONJ_TRANS, Teuchos::NO_TRANS, ONE, *Nullspace_, X, ZERO);
77 auto dots = tempMV->getLocalViewHost(Tpetra::Access::ReadOnly);
78 bool doProject = true;
79 for (size_t i = 0; i < X.getNumVectors(); i++) {
80 for (size_t j = 0; j < Nullspace_->getNumVectors(); j++) {
81 doProject = doProject || (Teuchos::ScalarTraits<Scalar>::magnitude(dots(j, i)) > 100 * Teuchos::ScalarTraits<Scalar>::eps());
82 }
83 }
84 if (doProject) {
85 for (size_t i = 0; i < X.getNumVectors(); i++) {
86 for (size_t j = 0; j < Nullspace_->getNumVectors(); j++) {
87 X.getVectorNonConst(i)->update(-dots(j, i), *Nullspace_->getVector(j), ONE);
88 }
89 }
90 }
91}
92
93template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
94Amesos2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Amesos2Smoother(const std::string& type, const Teuchos::ParameterList& paramList)
95 : type_(type)
96 , useTransformation_(false) {
97 this->SetParameterList(paramList);
98
99 if (!type_.empty()) {
100 // Transform string to "Abcde" notation
101 std::transform(type_.begin(), type_.end(), type_.begin(), ::tolower);
102 std::transform(type_.begin(), ++type_.begin(), type_.begin(), ::toupper);
103 }
104 if (type_ == "Superlu_dist")
105 type_ = "Superludist";
106
107 // Try to come up with something availble
108 // Order corresponds to our preference
109 // TODO: It would be great is Amesos2 provides directly this kind of logic for us
110 if (type_ == "" || Amesos2::query(type_) == false) {
111 std::string oldtype = type_;
112#if defined(HAVE_AMESOS2_KLU2)
113 type_ = "Klu";
114#elif defined(HAVE_AMESOS2_SUPERLU)
115 type_ = "Superlu";
116#elif defined(HAVE_AMESOS2_SUPERLUDIST)
117 type_ = "Superludist";
118#elif defined(HAVE_AMESOS2_BASKER)
119 type_ = "Basker";
120#else
121 this->declareConstructionOutcome(true, std::string("Amesos2 has been compiled without SuperLU_DIST, SuperLU, Klu, or Basker. By default, MueLu tries") +
122 "to use one of these libraries. Amesos2 must be compiled with one of these solvers, " +
123 "or a valid Amesos2 solver has to be specified explicitly.");
124 return;
125#endif
126 if (oldtype != "")
127 this->GetOStream(Warnings0) << "MueLu::Amesos2Smoother: \"" << oldtype << "\" is not available. Using \"" << type_ << "\" instead" << std::endl;
128 else
129 this->GetOStream(Runtime1) << "MueLu::Amesos2Smoother: using \"" << type_ << "\"" << std::endl;
130 }
131
132 // Check the validity of the solver type parameter
133 this->declareConstructionOutcome(Amesos2::query(type_) == false, "The Amesos2 library reported that the solver '" + type_ + "' is not available. " +
134 "Amesos2 has been compiled without the support of this solver, or the solver name is misspelled.");
135}
136
137template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
139
140template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
142 RCP<ParameterList> validParamList = rcp(new ParameterList());
143 validParamList->set<RCP<const FactoryBase> >("A", null, "Factory of the coarse matrix");
144 validParamList->set<RCP<const FactoryBase> >("Nullspace", null, "Factory of the nullspace");
145 validParamList->set<bool>("fix nullspace", false, "Remove zero eigenvalue by adding rank one correction.");
146 ParameterList norecurse;
147 norecurse.disableRecursiveValidation();
148 validParamList->set<ParameterList>("Amesos2", norecurse, "Parameters that are passed to Amesos2");
149 return validParamList;
150}
151
152template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
154 ParameterList pL = this->GetParameterList();
155
156 this->Input(currentLevel, "A");
157 if (pL.get<bool>("fix nullspace"))
158 this->Input(currentLevel, "Nullspace");
159}
160
161template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
163 FactoryMonitor m(*this, "Setup Smoother", currentLevel);
164
165 if (SmootherPrototype::IsSetup() == true)
166 this->GetOStream(Warnings0) << "MueLu::Amesos2Smoother::Setup(): Setup() has already been called" << std::endl;
167
168 RCP<Matrix> A = Factory::Get<RCP<Matrix> >(currentLevel, "A");
169 auto A_block = rcp_dynamic_cast<BlockedCrsMatrix>(A);
170 if (A_block) {
171 A = A_block->Merge();
172 }
173
174 // Do a quick check if we need to modify the matrix
175 RCP<const Map> rowMap = A->getRowMap();
176 RCP<Matrix> factorA;
177 Teuchos::ParameterList pL = this->GetParameterList();
178
179 if (pL.get<bool>("fix nullspace")) {
180 this->GetOStream(Runtime1) << "MueLu::Amesos2Smoother::Setup(): fixing nullspace" << std::endl;
181
182 rowMap = A->getRowMap();
183 size_t gblNumCols = rowMap->getGlobalNumElements();
184
185 RCP<MultiVector> NullspaceOrig = Factory::Get<RCP<MultiVector> >(currentLevel, "Nullspace");
186
187 projection_ = rcp(new Projection<Scalar, LocalOrdinal, GlobalOrdinal, Node>(NullspaceOrig));
188 RCP<MultiVector> Nullspace = projection_->Nullspace_;
189
190 RCP<MultiVector> ghostedNullspace;
191 RCP<const Map> colMap;
192 RCP<const Import> importer;
193 if (rowMap->getComm()->getSize() > 1) {
194 this->GetOStream(Warnings0) << "MueLu::Amesos2Smoother::Setup(): Applying nullspace fix on distributed matrix. Try rebalancing to single rank!" << std::endl;
195 ArrayRCP<GO> elements_RCP;
196 elements_RCP.resize(gblNumCols);
197 ArrayView<GO> elements = elements_RCP();
198 for (size_t k = 0; k < gblNumCols; k++)
199 elements[k] = Teuchos::as<GO>(k);
200 colMap = MapFactory::Build(rowMap->lib(), gblNumCols * rowMap->getComm()->getSize(), elements, Teuchos::ScalarTraits<GO>::zero(), rowMap->getComm());
201 importer = ImportFactory::Build(rowMap, colMap);
202 ghostedNullspace = MultiVectorFactory::Build(colMap, Nullspace->getNumVectors(), false);
203 ghostedNullspace->doImport(*Nullspace, *importer, Xpetra::INSERT);
204 } else {
205 ghostedNullspace = Nullspace;
206 colMap = rowMap;
207 }
208
209 using ATS = KokkosKernels::ArithTraits<SC>;
210 using impl_Scalar = typename ATS::val_type;
211 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
212 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
213
214 typedef typename Matrix::local_matrix_device_type KCRS;
215 typedef typename KCRS::StaticCrsGraphType graph_t;
216 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
217 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
218 typedef typename KCRS::values_type::non_const_type scalar_view_t;
219
220 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
221
222 size_t lclNumRows = rowMap->getLocalNumElements();
223 LocalOrdinal lclNumCols = Teuchos::as<LocalOrdinal>(gblNumCols);
224 lno_view_t newRowPointers("newRowPointers", lclNumRows + 1);
225 lno_nnz_view_t newColIndices("newColIndices", lclNumRows * gblNumCols);
226 scalar_view_t newValues("newValues", lclNumRows * gblNumCols);
227
228 impl_Scalar shift;
229 {
230 RCP<Vector> diag = VectorFactory::Build(A->getRowMap());
231 A->getLocalDiagCopy(*diag);
232 shift = diag->normInf();
233 }
234
235 // form normalization * nullspace * nullspace^T
236 {
237 auto lclNullspace = Nullspace->getLocalViewDevice(Tpetra::Access::ReadOnly);
238 auto lclGhostedNullspace = ghostedNullspace->getLocalViewDevice(Tpetra::Access::ReadOnly);
239 Kokkos::parallel_for(
240 "MueLu:Amesos2Smoother::fixNullspace_1", range_type(0, lclNumRows + 1),
241 KOKKOS_LAMBDA(const size_t i) {
242 if (i < lclNumRows) {
243 newRowPointers(i) = i * gblNumCols;
244 for (LocalOrdinal j = 0; j < lclNumCols; j++) {
245 newColIndices(i * gblNumCols + j) = j;
246 newValues(i * gblNumCols + j) = impl_SC_ZERO;
247 for (size_t I = 0; I < lclNullspace.extent(1); I++)
248 for (size_t J = 0; J < lclGhostedNullspace.extent(1); J++)
249 newValues(i * gblNumCols + j) += shift * lclNullspace(i, I) * impl_ATS::conjugate(lclGhostedNullspace(j, J));
250 }
251 } else
252 newRowPointers(lclNumRows) = lclNumRows * gblNumCols;
253 });
254 }
255
256 // add A
257 if (colMap->lib() == Xpetra::UseTpetra) {
258 auto lclA = A->getLocalMatrixDevice();
259 auto lclColMapA = A->getColMap()->getLocalMap();
260 auto lclColMapANew = colMap->getLocalMap();
261 Kokkos::parallel_for(
262 "MueLu:Amesos2Smoother::fixNullspace_2", range_type(0, lclNumRows),
263 KOKKOS_LAMBDA(const size_t i) {
264 for (size_t jj = lclA.graph.row_map(i); jj < lclA.graph.row_map(i + 1); jj++) {
265 LO j = lclColMapANew.getLocalElement(lclColMapA.getGlobalElement(lclA.graph.entries(jj)));
266 impl_Scalar v = lclA.values(jj);
267 newValues(i * gblNumCols + j) += v;
268 }
269 });
270 } else {
271 auto lclA = A->getLocalMatrixHost();
272 for (size_t i = 0; i < lclNumRows; i++) {
273 for (size_t jj = lclA.graph.row_map(i); jj < lclA.graph.row_map(i + 1); jj++) {
274 LO j = colMap->getLocalElement(A->getColMap()->getGlobalElement(lclA.graph.entries(jj)));
275 SC v = lclA.values(jj);
276 newValues(i * gblNumCols + j) += v;
277 }
278 }
279 }
280
281 RCP<Matrix> newA = rcp(new CrsMatrixWrap(rowMap, colMap, 0));
282 RCP<CrsMatrix> newAcrs = toCrsMatrix(newA);
283 newAcrs->setAllValues(newRowPointers, newColIndices, newValues);
284 newAcrs->expertStaticFillComplete(A->getDomainMap(), A->getRangeMap(),
285 importer, A->getCrsGraph()->getExporter());
286
287 factorA = newA;
288 rowMap = factorA->getRowMap();
289 } else {
290 factorA = A;
291 }
292
293 RCP<const Tpetra_CrsMatrix> tA = toTpetra(factorA);
294
295 prec_ = Amesos2::create<Tpetra_CrsMatrix, Tpetra_MultiVector>(type_, tA);
296 TEUCHOS_TEST_FOR_EXCEPTION(prec_ == Teuchos::null, Exceptions::RuntimeError, "Amesos2::create returns Teuchos::null");
297 RCP<Teuchos::ParameterList> amesos2_params = Teuchos::rcpFromRef(pL.sublist("Amesos2"));
298 amesos2_params->setName("Amesos2");
299 if ((rowMap->getGlobalNumElements() != as<size_t>((rowMap->getMaxAllGlobalIndex() - rowMap->getMinAllGlobalIndex()) + 1)) ||
300 (!rowMap->isContiguous() && (rowMap->getComm()->getSize() == 1))) {
301 if (((type_ != "Cusolver") && (type_ != "Tacho")) && !(amesos2_params->sublist(prec_->name()).template isType<bool>("IsContiguous")))
302 amesos2_params->sublist(prec_->name()).set("IsContiguous", false, "Are GIDs Contiguous");
303 }
304 prec_->setParameters(amesos2_params);
305
306 prec_->numericFactorization();
307
309}
310
311template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
312void Amesos2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool /* InitialGuessIsZero */) const {
313 TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, Exceptions::RuntimeError, "MueLu::Amesos2Smoother::Apply(): Setup() has not been called");
314
315 RCP<BlockedMultiVector> blockedX = rcp_dynamic_cast<BlockedMultiVector>(rcpFromRef(X));
316 bool blocked = blockedX != Teuchos::null;
317 if (blocked) {
318 this->ApplyBlocked(X, B);
319 return;
320 }
321
322 RCP<Tpetra_MultiVector> tX, tB;
323 if (!useTransformation_) {
324 tX = toTpetra(Teuchos::rcpFromRef(X));
325 tB = toTpetra(Teuchos::rcpFromRef(const_cast<MultiVector&>(B)));
326 } else {
327 // Copy data of the original vectors into the transformed ones
328 size_t numVectors = X.getNumVectors();
329 size_t length = X.getLocalLength();
330
331 TEUCHOS_TEST_FOR_EXCEPTION(numVectors > 1, Exceptions::RuntimeError,
332 "MueLu::Amesos2Smoother::Apply: Fixing coarse matrix for Amesos2 for multivectors has not been implemented yet.");
333 ArrayRCP<const SC> Xdata = X.getData(0), Bdata = B.getData(0);
334 ArrayRCP<SC> X_data = X_->getDataNonConst(0), B_data = B_->getDataNonConst(0);
335
336 for (size_t i = 0; i < length; i++) {
337 X_data[i] = Xdata[i];
338 B_data[i] = Bdata[i];
339 }
340
341 tX = toTpetra(X_);
342 tB = toTpetra(B_);
343 }
344
345 prec_->setX(tX);
346 prec_->setB(tB);
347
348 prec_->solve();
349
350 prec_->setX(Teuchos::null);
351 prec_->setB(Teuchos::null);
352
353 if (useTransformation_) {
354 // Copy data from the transformed vectors into the original ones
355 size_t length = X.getLocalLength();
356
357 ArrayRCP<SC> Xdata = X.getDataNonConst(0);
358 ArrayRCP<const SC> X_data = X_->getData(0);
359
360 for (size_t i = 0; i < length; i++)
361 Xdata[i] = X_data[i];
362 }
363
364 {
365 Teuchos::ParameterList pL = this->GetParameterList();
366 if (pL.get<bool>("fix nullspace")) {
367 projection_->projectOut(X);
368 }
369 }
370}
371
372template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
373void Amesos2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ApplyBlocked(MultiVector& X, const MultiVector& B) const {
374 TEUCHOS_TEST_FOR_EXCEPTION(useTransformation_, Exceptions::RuntimeError,
375 "MueLu::Amesos2Smoother::ApplyBlocked: useTransformation_ == true is not supported");
376
377 Teuchos::ParameterList pL = this->GetParameterList();
378 const auto fixNullspace = pL.get<bool>("fix nullspace");
379 TEUCHOS_TEST_FOR_EXCEPTION(fixNullspace, Exceptions::RuntimeError,
380 "MueLu::Amesos2Smoother::ApplyBlocked: \"fix nullspace\" == true is not supported");
381
382 RCP<BlockedMultiVector> blockedX = rcp_dynamic_cast<BlockedMultiVector>(rcpFromRef(X));
383 RCP<const BlockedMultiVector> blockedB = rcp_dynamic_cast<const BlockedMultiVector>(rcpFromRef(B));
384 TEUCHOS_TEST_FOR_EXCEPTION(blockedX == Teuchos::null || blockedB == Teuchos::null, Exceptions::RuntimeError,
385 "MueLu::Amesos2Smoother::ApplyBlocked: Input and/or output vector are not BlockedMultiVector!");
386
387 RCP<MultiVector> mergedX = blockedX->Merge();
388 RCP<MultiVector> mergedB = blockedB->Merge();
389
390 RCP<Tpetra_MultiVector> tX, tB;
391 tX = toTpetra(mergedX);
392 tB = toTpetra(mergedB);
393
394 prec_->setX(tX);
395 prec_->setB(tB);
396
397 prec_->solve();
398
399 prec_->setX(Teuchos::null);
400 prec_->setB(Teuchos::null);
401
402 RCP<MultiVector> xx = Teuchos::rcp(new BlockedMultiVector(blockedX->getBlockedMap(), mergedX));
403 SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
404 X.update(one, *xx, zero);
405}
406
407template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
408RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
413
414template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
416 std::ostringstream out;
417
418 if (SmootherPrototype::IsSetup() == true) {
419 out << prec_->description();
420
421 } else {
423 out << "{type = " << type_ << "}";
424 }
425 return out.str();
426}
427
428template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
429void Amesos2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream& out, const VerbLevel verbLevel) const {
431
432 if (verbLevel & Parameters0)
433 out0 << "Prec. type: " << type_ << std::endl;
434
435 if (verbLevel & Parameters1) {
436 out0 << "Parameter list: " << std::endl;
437 Teuchos::OSTab tab2(out);
438 out << this->GetParameterList();
439 }
440
441 if ((verbLevel & External) && prec_ != Teuchos::null) {
442 Teuchos::OSTab tab2(out);
443 out << *prec_ << std::endl;
444 }
445
446 if (verbLevel & Debug)
447 out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl
448 << "-" << std::endl
449 << "RCP<prec_>: " << prec_ << std::endl;
450}
451
452template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
454 if (!prec_.is_null())
455 return prec_->getStatus().getNnzLU();
456 else
457 return 0.0;
458}
459} // namespace MueLu
460
461#endif // MUELU_AMESOS2SMOOTHER_DEF_HPP
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
Class that encapsulates Amesos2 direct solvers.
void DeclareInput(Level &currentLevel) const
Input.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
std::string type_
amesos2-specific key phrase that denote smoother type
void ApplyBlocked(MultiVector &X, const MultiVector &B) const
RCP< SmootherPrototype > Copy() const
std::string description() const
Return a simple one-line description of this object.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void Setup(Level &currentLevel)
Set up the direct solver. This creates the underlying Amesos2 solver object according to the paramete...
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.
Amesos2Smoother(const std::string &type="", const Teuchos::ParameterList &paramList=Teuchos::ParameterList())
Constructor Creates a MueLu interface to the direct solvers in the Amesos2 package....
virtual std::string description() const
Return a simple one-line description of this object.
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.
virtual void SetParameterList(const Teuchos::ParameterList &paramList)
Set parameters from a parameter list and return with default values.
Projection(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &Nullspace)
void projectOut(Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X)
void declareConstructionOutcome(bool fail, std::string msg)
bool IsSetup() const
Get the state of a smoother prototype.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)
@ Debug
Print additional debugging information.
@ External
Print external lib objects.
@ Runtime1
Description of what is happening (more verbose)
@ Parameters0
Print class parameters.
@ Parameters1
Print class parameters (more parameters, more verbose)