Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_Details_Amesos2Wrapper_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4 //
5 // Copyright 2009 NTESS and the Ifpack2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef IFPACK2_DETAILS_AMESOS2WRAPPER_DEF_HPP
11 #define IFPACK2_DETAILS_AMESOS2WRAPPER_DEF_HPP
12 
13 #ifdef HAVE_IFPACK2_AMESOS2
14 
15 #include "Ifpack2_LocalFilter.hpp"
18 #include "Teuchos_TimeMonitor.hpp"
20 
21 // FIXME (mfh 25 Aug 2015) Work-around for Bug 6392. This doesn't
22 // need to be a weak symbol as long as the Ifpack2 package depends on
23 // Amesos2.
24 namespace Amesos2 {
25 namespace Details {
26 extern void registerLinearSolverFactory();
27 } // namespace Details
28 } // namespace Amesos2
29 
30 namespace Ifpack2 {
31 namespace Details {
32 
33 template <class MatrixType>
36  : A_(A)
37  , InitializeTime_(0.0)
38  , ComputeTime_(0.0)
39  , ApplyTime_(0.0)
40  , NumInitialize_(0)
41  , NumCompute_(0)
42  , NumApply_(0)
43  , IsInitialized_(false)
44  , IsComputed_(false)
45  , SolverName_("") {}
46 
47 template <class MatrixType>
49 
50 template <class MatrixType>
53  using Teuchos::RCP;
54  using Teuchos::rcp;
55 
56  // FIXME (mfh 12 Sep 2014) Why does this code make a deep copy of
57  // the input ParameterList? Does Amesos2 want a deep copy?
58 
59  // Extract the list called "Amesos2" that contains the Amesos2
60  // solver's options.
61  RCP<ParameterList> theList;
62  if (params.name() == "Amesos2") {
63  theList = rcp(new ParameterList(params));
64  } else if (params.isSublist("Amesos2")) {
65  // FIXME (mfh 12 Sep 2014) This code actually makes _two_ deep copies.
66  ParameterList subpl = params.sublist("Amesos2");
67  theList = rcp(new ParameterList(subpl));
68  theList->setName("Amesos2"); // FIXME hack until Teuchos sublist name bug is fixed
69  if (params.isParameter("Amesos2 solver name")) {
70  SolverName_ = params.get<std::string>("Amesos2 solver name");
71  }
72  } else {
73  // Amesos2 silently ignores any list not called "Amesos2". We'll
74  // throw an exception.
76  true, std::runtime_error,
77  "The ParameterList passed to Amesos2 must be "
78  "called \"Amesos2\".");
79  }
80 
81  // If solver_ hasn't been allocated yet, cache the parameters and set them
82  // once the concrete solver does exist.
83  if (solver_.is_null()) {
84  parameterList_ = theList;
85  return;
86  }
87  // FIXME (mfh 25 Aug 2015) Why doesn't this code set parameterList_
88  // when the solver is NOT null?
89 
90  solver_->setParameters(theList);
91 }
92 
93 template <class MatrixType>
97  A_.is_null(), std::runtime_error,
98  "Ifpack2::Amesos2Wrapper::getComm: "
99  "The matrix is null. Please call setMatrix() with a nonnull input "
100  "before calling this method.");
101  return A_->getComm();
102 }
103 
104 template <class MatrixType>
107  return A_;
108 }
109 
110 template <class MatrixType>
114  A_.is_null(), std::runtime_error,
115  "Ifpack2::Amesos2Wrapper::getDomainMap: "
116  "The matrix is null. Please call setMatrix() with a nonnull input "
117  "before calling this method.");
118  return A_->getDomainMap();
119 }
120 
121 template <class MatrixType>
125  A_.is_null(), std::runtime_error,
126  "Ifpack2::Amesos2Wrapper::getRangeMap: "
127  "The matrix is null. Please call setMatrix() with a nonnull input "
128  "before calling this method.");
129  return A_->getRangeMap();
130 }
131 
132 template <class MatrixType>
134  return true;
135 }
136 
137 template <class MatrixType>
139  return NumInitialize_;
140 }
141 
142 template <class MatrixType>
144  return NumCompute_;
145 }
146 
147 template <class MatrixType>
149  return NumApply_;
150 }
151 
152 template <class MatrixType>
154  return InitializeTime_;
155 }
156 
157 template <class MatrixType>
159  return ComputeTime_;
160 }
161 
162 template <class MatrixType>
164  return ApplyTime_;
165 }
166 
167 template <class MatrixType>
169  // It's legal for A to be null; in that case, you may not call
170  // initialize() until calling setMatrix() with a nonnull input.
171  // Regardless, setting the matrix invalidates any previous
172  // factorization.
173  IsInitialized_ = false;
174  IsComputed_ = false;
175 
176  if (A.is_null()) {
177  A_ = Teuchos::null;
178  } else {
179  A_ = A;
180  }
181 
182  // FIXME (mfh 10 Dec 2013) Currently, initialize() recreates
183  // solver_ unconditionally, so this code won't have any
184  // effect. Once we fix initialize() so that it keeps
185  // solver_, the code below will be effective.
186  // if (! solver_.is_null ()) {
187  // solver_->setA (A_);
188  //}
189  // FIXME JJH 2014-July18 A_ might not be a locally filtered CRS matrix, which
190  // means we have to do that dance all over again before calling solver_->setA ....
191 }
192 
193 template <class MatrixType>
196  using Teuchos::RCP;
197  using Teuchos::rcp;
198  using Teuchos::rcp_dynamic_cast;
199  using Teuchos::rcp_implicit_cast;
200 
201  // If A_'s communicator only has one process, or if its column and
202  // row Maps are the same, then it is already local, so use it
203  // directly.
204  if (A->getRowMap()->getComm()->getSize() == 1 ||
205  A->getRowMap()->isSameAs(*(A->getColMap()))) {
206  return A;
207  }
208 
209  // If A_ is already a LocalFilter, then use it directly. This
210  // should be the case if RILUK is being used through
211  // AdditiveSchwarz, for example.
212  RCP<const LocalFilter<row_matrix_type> > A_lf_r =
213  rcp_dynamic_cast<const LocalFilter<row_matrix_type> >(A);
214  if (!A_lf_r.is_null()) {
215  return rcp_implicit_cast<const row_matrix_type>(A_lf_r);
216  } else {
217  // A_'s communicator has more than one process, its row Map and
218  // its column Map differ, and A_ is not a LocalFilter. Thus, we
219  // have to wrap it in a LocalFilter.
220  return rcp(new LocalFilter<row_matrix_type>(A));
221  }
222 }
223 
224 template <class MatrixType>
226  using Teuchos::Array;
227  using Teuchos::ArrayView;
228  using Teuchos::RCP;
229  using Teuchos::rcp;
230  using Teuchos::rcp_const_cast;
231  using Teuchos::rcp_dynamic_cast;
232  using Teuchos::Time;
233  using Teuchos::TimeMonitor;
234 
235  const std::string timerName("Ifpack2::Amesos2Wrapper::initialize");
236  RCP<Time> timer = TimeMonitor::lookupCounter(timerName);
237  if (timer.is_null()) {
238  timer = TimeMonitor::getNewCounter(timerName);
239  }
240 
241  double startTime = timer->wallTime();
242 
243  { // Start timing here.
244  TimeMonitor timeMon(*timer);
245 
246  // Check that the matrix is nonnull.
248  A_.is_null(), std::runtime_error,
249  "Ifpack2::Amesos2Wrapper::initialize: "
250  "The matrix to precondition is null. Please call setMatrix() with a "
251  "nonnull input before calling this method.");
252 
253  // Clear any previous computations.
254  IsInitialized_ = false;
255  IsComputed_ = false;
256 
257  RCP<const row_matrix_type> A_local = makeLocalFilter(A_);
259  A_local.is_null(), std::logic_error,
260  "Ifpack2::AmesosWrapper::initialize: "
261  "makeLocalFilter returned null; it failed to compute A_local. "
262  "Please report this bug to the Ifpack2 developers.");
263 
264  {
265  // The matrix that Amesos2 will build the preconditioner on must be a Tpetra::Crs matrix.
266  // If A_local isn't, then we build one.
267  A_local_crs_ = rcp_dynamic_cast<const crs_matrix_type>(A_local);
268 
269  if (A_local_crs_.is_null()) {
270  local_ordinal_type numRows = A_local->getLocalNumRows();
271  Array<size_t> entriesPerRow(numRows);
272  for (local_ordinal_type i = 0; i < numRows; i++) {
273  entriesPerRow[i] = A_local->getNumEntriesInLocalRow(i);
274  }
275  RCP<crs_matrix_type> A_local_crs_nc =
276  rcp(new crs_matrix_type(A_local->getRowMap(),
277  A_local->getColMap(),
278  entriesPerRow()));
279  // copy entries into A_local_crs
280  typename crs_matrix_type::nonconst_local_inds_host_view_type indices("Indices", A_local->getLocalMaxNumRowEntries());
281  typename crs_matrix_type::nonconst_values_host_view_type values("Values", A_local->getLocalMaxNumRowEntries());
282  for (local_ordinal_type i = 0; i < numRows; i++) {
283  size_t numEntries = 0;
284  A_local->getLocalRowCopy(i, indices, values, numEntries);
285  ArrayView<const local_ordinal_type> indicesInsert(indices.data(), numEntries);
286  ArrayView<const scalar_type> valuesInsert((const scalar_type*)values.data(), numEntries);
287  A_local_crs_nc->insertLocalValues(i, indicesInsert, valuesInsert);
288  }
289  A_local_crs_nc->fillComplete(A_local->getDomainMap(), A_local->getRangeMap());
290  A_local_crs_ = rcp_const_cast<const crs_matrix_type>(A_local_crs_nc);
291  }
292  }
293 
294  // FIXME (10 Dec 2013, 25 Aug 2015) It shouldn't be necessary to
295  // recreate the solver each time, since
296  // Trilinos::Details::LinearSolver has a setA() method. See the
297  // implementation of setMatrix(). I don't want to break anything
298  // so I will leave the code as it is, possibly inefficient.
299 
300  // FIXME (mfh 25 Aug 2015) This is a work-around for Bug 6392.
302  Amesos2::Details::registerLinearSolverFactory();
303  }
304 
305  solver_ = Trilinos::Details::getLinearSolver<MV, OP, typename MV::mag_type>("Amesos2", SolverName_);
306  TEUCHOS_TEST_FOR_EXCEPTION(solver_.is_null(), std::runtime_error,
307  "Ifpack2::Details::"
308  "Amesos2Wrapper::initialize: Failed to create Amesos2 solver!");
309 
310  solver_->setMatrix(A_local_crs_);
311  // If parameters have been already been cached via setParameters, set them now.
312  if (parameterList_ != Teuchos::null) {
313  setParameters(*parameterList_);
314  parameterList_ = Teuchos::null;
315  }
316  // The symbolic factorization properly belongs to initialize(),
317  // since initialize() is concerned with the matrix's structure
318  // (and compute() with the matrix's values).
319  solver_->symbolic();
320  } // Stop timing here.
321 
322  IsInitialized_ = true;
323  ++NumInitialize_;
324 
325  InitializeTime_ += (timer->wallTime() - startTime);
326 }
327 
328 template <class MatrixType>
330  using Teuchos::RCP;
331  using Teuchos::Time;
332  using Teuchos::TimeMonitor;
333 
334  // Don't count initialization in the compute() time.
335  if (!isInitialized()) {
336  initialize();
337  }
338 
339  const std::string timerName("Ifpack2::Details::Amesos2Wrapper::compute");
340  RCP<Time> timer = TimeMonitor::lookupCounter(timerName);
341  if (timer.is_null()) {
342  timer = TimeMonitor::getNewCounter(timerName);
343  }
344 
345  double startTime = timer->wallTime();
346 
347  { // Start timing here.
348  TimeMonitor timeMon(*timer);
349  solver_->numeric();
350  } // Stop timing here.
351 
352  IsComputed_ = true;
353  ++NumCompute_;
354 
355  ComputeTime_ += (timer->wallTime() - startTime);
356 }
357 
358 template <class MatrixType>
360  apply(const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
361  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
362  Teuchos::ETransp mode,
363  scalar_type alpha,
364  scalar_type beta) const {
365  using Teuchos::ArrayView;
366  using Teuchos::RCP;
367  using Teuchos::rcp;
368  using Teuchos::rcpFromRef;
369  using Teuchos::Time;
370  using Teuchos::TimeMonitor;
371 
372  // X = RHS
373  // Y = solution
374 
375  const std::string timerName("Ifpack2::Amesos2Wrapper::apply");
376  RCP<Time> timer = TimeMonitor::lookupCounter(timerName);
377  if (timer.is_null()) {
378  timer = TimeMonitor::getNewCounter(timerName);
379  }
380 
381  double startTime = timer->wallTime();
382 
383  { // Start timing here.
384  TimeMonitor timeMon(*timer);
385 
387  !isComputed(), std::runtime_error,
388  "Ifpack2::Amesos2Wrapper::apply: You must call compute() to compute the "
389  "incomplete factorization, before calling apply().");
390 
392  X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
393  "Ifpack2::Amesos2Wrapper::apply: X and Y must have the same number of columns. "
394  "X has "
395  << X.getNumVectors() << " columns, but Y has "
396  << Y.getNumVectors() << " columns.");
397 
399  mode != Teuchos::NO_TRANS, std::logic_error,
400  "Ifpack2::Amesos2Wrapper::apply: Solving with the transpose (mode == "
401  "Teuchos::TRANS) or conjugate transpose (Teuchos::CONJ_TRANS) is not "
402  "implemented.");
403 
404  // If alpha != 1 or beta != 0, create a temporary multivector
405  // Y_temp to hold the contents of alpha*M^{-1}*X. Otherwise,
406  // alias Y_temp to Y.
407  RCP<MV> Y_temp = (alpha != STS::one() || beta != STS::zero()) ? rcp(new MV(Y.getMap(), Y.getNumVectors())) : rcpFromRef(Y);
408 
409  // If X and Y are pointing to the same memory location, create an
410  // auxiliary vector, X_temp, so that we don't clobber the input
411  // when computing the output. Otherwise, alias X_temp to X.
412  RCP<const MV> X_temp;
413  {
414  if (X.aliases(Y)) {
415  X_temp = rcp(new MV(X, Teuchos::Copy));
416  } else {
417  X_temp = rcpFromRef(X);
418  }
419  }
420 
421  // Set up "local" views of X and Y.
422  RCP<const MV> X_local;
423  RCP<MV> Y_local;
424  // JJH 15-Apr-2016 I changed this from ">=" to ">". Otherwise the else block
425  // is never hit.
426  // bmk 6-19-17: previously, the next line only set multipleProcs if A_ was distributed
427  // This doesn't work if A_ is local but X/Y are distributed, as in AdditiveSchwarz.
428  const bool multipleProcs = (A_->getRowMap()->getComm()->getSize() > 1) || (X.getMap()->getComm()->getSize() > 1);
429  if (multipleProcs) {
430  // Interpret X and Y as "local" multivectors, that is, in the
431  // local filter's domain resp. range Maps. "Interpret" means that
432  // we create views with different Maps; we don't have to copy.
433  X_local = X_temp->offsetView(A_local_crs_->getDomainMap(), 0);
434  Y_local = Y_temp->offsetViewNonConst(A_local_crs_->getRangeMap(), 0);
435  } else { // only one process in A_'s communicator
436  // X and Y are already "local"; no need to set up local views.
437  X_local = X_temp;
438  Y_local = Y_temp;
439  }
440 
441  // Use the precomputed factorization to solve.
442  solver_->solve(*Y_local, *X_local);
443 
444  if (alpha != STS::one() || beta != STS::zero()) {
445  Y.update(alpha, *Y_temp, beta);
446  }
447  } // Stop timing here.
448 
449  ++NumApply_;
450 
451  ApplyTime_ += (timer->wallTime() - startTime);
452 }
453 
454 template <class MatrixType>
457  std::ostringstream os;
458 
459  // Output is a valid YAML dictionary in flow style. If you don't
460  // like everything on a single line, you should call describe()
461  // instead.
462  os << "\"Ifpack2::Amesos2Wrapper\": {";
463  if (this->getObjectLabel() != "") {
464  os << "Label: \"" << this->getObjectLabel() << "\", ";
465  }
466  os << "Initialized: " << (isInitialized() ? "true" : "false")
467  << ", Computed: " << (isComputed() ? "true" : "false");
468 
469  if (A_local_crs_.is_null()) {
470  os << ", Matrix: null";
471  } else {
472  os << ", Global matrix dimensions: ["
473  << A_local_crs_->getGlobalNumRows() << ", " << A_local_crs_->getGlobalNumCols() << "]";
474  }
475 
476  // If the actual solver happens to implement Describable, have it
477  // describe itself. Otherwise, don't print anything.
478  if (!solver_.is_null()) {
479  Teuchos::Describable* d = dynamic_cast<Teuchos::Describable*>(solver_.getRawPtr());
480  if (d != NULL) {
481  os << ", {";
482  os << d->description();
483  os << "}";
484  }
485  }
486  os << "}";
487  return os.str();
488 }
489 
490 template <class MatrixType>
493  const Teuchos::EVerbosityLevel verbLevel) const {
494  using std::endl;
495  using Teuchos::Comm;
496  using Teuchos::OSTab;
497  using Teuchos::RCP;
499 
500  const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
501 
502  // describe() starts, by convention, with a tab before it prints anything.
503  OSTab tab0(out);
504  if (vl > Teuchos::VERB_NONE) {
505  out << "\"Ifpack2::Amesos2Wrapper\":" << endl;
506  OSTab tab1(out);
507  out << "MatrixType: \"" << TypeNameTraits<MatrixType>::name()
508  << "\"" << endl;
509 
510  if (this->getObjectLabel() != "") {
511  out << "Label: \"" << this->getObjectLabel() << "\"" << endl;
512  }
513 
514  out << "Initialized: " << (isInitialized() ? "true" : "false") << endl;
515  out << "Computed: " << (isComputed() ? "true" : "false") << endl;
516  out << "Number of initialize calls: " << getNumInitialize() << endl;
517  out << "Number of compute calls: " << getNumCompute() << endl;
518  out << "Number of apply calls: " << getNumApply() << endl;
519  out << "Total time in seconds for initialize: " << getInitializeTime() << endl;
520  out << "Total time in seconds for compute: " << getComputeTime() << endl;
521  out << "Total time in seconds for apply: " << getApplyTime() << endl;
522 
523  if (vl > Teuchos::VERB_LOW) {
524  out << "Matrix:" << endl;
525  A_local_crs_->describe(out, vl);
526  }
527  }
528 }
529 
530 } // namespace Details
531 } // namespace Ifpack2
532 
533 // There's no need to instantiate for CrsMatrix too. All Ifpack2
534 // preconditioners can and should do dynamic casts if they need a type
535 // more specific than RowMatrix.
536 
537 #define IFPACK2_DETAILS_AMESOS2WRAPPER_INSTANT(S, LO, GO, N) \
538  template class Ifpack2::Details::Amesos2Wrapper<Tpetra::RowMatrix<S, LO, GO, N> >;
539 
540 #else
541 
542 #define IFPACK2_DETAILS_AMESOS2WRAPPER_INSTANT(S, LO, GO, N)
543 
544 #endif // HAVE_IFPACK2_AMESOS2
545 #endif // IFPACK2_DETAILS_AMESOS2WRAPPER_DEF_HPP
double getInitializeTime() const
The total time in seconds spent in successful calls to initialize().
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:153
const std::string & name() const
double getApplyTime() const
The total time in seconds spent in successful calls to apply().
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:163
basic_OSTab< char > OSTab
void setParameters(const Teuchos::ParameterList &params)
Set parameters.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:51
T & get(const std::string &name, T def_value)
bool rememberRegisteredSomeLinearSolverFactory(const std::string &packageName)
bool hasTransposeApply() const
Whether this object&#39;s apply() method can apply the transpose (or conjugate transpose, if applicable).
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:133
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
int getNumApply() const
The total number of successful calls to apply().
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:148
void initialize()
Compute the preordering and symbolic factorization of the matrix.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:225
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The input matrix&#39;s communicator.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:95
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to the given output stream.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:492
int getNumInitialize() const
The total number of successful calls to initialize().
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:138
bool isParameter(const std::string &name) const
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_Details_Amesos2Wrapper_decl.hpp:81
Teuchos::RCP< const map_type > getDomainMap() const
Tpetra::Map representing the domain of this operator.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:112
Tpetra::CrsMatrix< scalar_type, local_ordinal_type, global_ordinal_type, node_type > crs_matrix_type
Type of the Tpetra::CrsMatrix specialization that this class uses.
Definition: Ifpack2_Details_Amesos2Wrapper_decl.hpp:116
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Wrapper class for direct solvers in Amesos2.
Definition: Ifpack2_Details_Amesos2Wrapper_decl.hpp:68
Teuchos::RCP< const map_type > getRangeMap() const
Tpetra::Map representing the range of this operator.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:123
bool isSublist(const std::string &name) const
virtual std::string description() const
virtual ~Amesos2Wrapper()
Destructor.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:48
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_Details_Amesos2Wrapper_decl.hpp:84
Amesos2Wrapper(const Teuchos::RCP< const row_matrix_type > &A)
Constructor.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:35
Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix; the matrix to be preconditioned.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:106
double getComputeTime() const
The total time in seconds spent in successful calls to compute().
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:158
int getNumCompute() const
The total number of successful calls to compute().
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:143
void apply(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &X, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, scalar_type alpha=Teuchos::ScalarTraits< scalar_type >::one(), scalar_type beta=Teuchos::ScalarTraits< scalar_type >::zero()) const
Apply the preconditioner to X, resulting in Y.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:360
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
void compute()
Compute the numeric factorization of the matrix.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:329
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:127
void registerLinearSolverFactory()
std::string description() const
A one-line description of this object.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:455
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_Details_Amesos2Wrapper_def.hpp:168
bool is_null() const