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