Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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"
16#include "Trilinos_Details_LinearSolverFactory.hpp"
17#include "Trilinos_Details_LinearSolver.hpp"
18#include "Teuchos_TimeMonitor.hpp"
19#include "Teuchos_TypeNameTraits.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.
24namespace Amesos2 {
25namespace Details {
26extern void registerLinearSolverFactory();
27} // namespace Details
28} // namespace Amesos2
29
30namespace Ifpack2 {
31namespace Details {
32
33template <class MatrixType>
35 Amesos2Wrapper(const Teuchos::RCP<const row_matrix_type>& A)
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
47template <class MatrixType>
49
50template <class MatrixType>
51void Amesos2Wrapper<MatrixType>::setParameters(const Teuchos::ParameterList& params) {
52 using Teuchos::ParameterList;
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.
62 if (params.name() == "Amesos2") {
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");
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
93template <class MatrixType>
94Teuchos::RCP<const Teuchos::Comm<int> >
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
104template <class MatrixType>
105Teuchos::RCP<const typename Amesos2Wrapper<MatrixType>::row_matrix_type>
107 return A_;
108}
109
110template <class MatrixType>
111Teuchos::RCP<const typename Amesos2Wrapper<MatrixType>::map_type>
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
121template <class MatrixType>
122Teuchos::RCP<const typename Amesos2Wrapper<MatrixType>::map_type>
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
132template <class MatrixType>
134 return true;
135}
136
137template <class MatrixType>
139 return NumInitialize_;
140}
141
142template <class MatrixType>
144 return NumCompute_;
145}
146
147template <class MatrixType>
149 return NumApply_;
150}
151
152template <class MatrixType>
154 return InitializeTime_;
155}
156
157template <class MatrixType>
159 return ComputeTime_;
160}
161
162template <class MatrixType>
164 return ApplyTime_;
165}
166
167template <class MatrixType>
168void Amesos2Wrapper<MatrixType>::setMatrix(const Teuchos::RCP<const row_matrix_type>& A) {
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
193template <class MatrixType>
194Teuchos::RCP<const typename Amesos2Wrapper<MatrixType>::row_matrix_type>
195Amesos2Wrapper<MatrixType>::makeLocalFilter(const Teuchos::RCP<const row_matrix_type>& A) {
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
224template <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.
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.
268
269 if (A_local_crs_.is_null()) {
270 local_ordinal_type numRows = A_local->getLocalNumRows();
272 for (local_ordinal_type i = 0; i < numRows; i++) {
273 entriesPerRow[i] = A_local->getNumEntriesInLocalRow(i);
274 }
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);
287 A_local_crs_nc->insertLocalValues(i, indicesInsert, valuesInsert);
288 }
289 A_local_crs_nc->fillComplete(A_local->getDomainMap(), A_local->getRangeMap());
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.
301 if (!Trilinos::Details::Impl::rememberRegisteredSomeLinearSolverFactory("Amesos2")) {
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
328template <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.
349 solver_->numeric();
350 } // Stop timing here.
351
352 IsComputed_ = true;
353 ++NumCompute_;
354
355 ComputeTime_ += (timer->wallTime() - startTime);
356}
357
358template <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.
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.
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.
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
454template <class MatrixType>
456 using Teuchos::TypeNameTraits;
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
490template <class MatrixType>
492 describe(Teuchos::FancyOStream& out,
493 const Teuchos::EVerbosityLevel verbLevel) const {
494 using std::endl;
495 using Teuchos::Comm;
496 using Teuchos::OSTab;
497 using Teuchos::RCP;
498 using Teuchos::TypeNameTraits;
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
Wrapper class for direct solvers in Amesos2.
Definition Ifpack2_Details_Amesos2Wrapper_decl.hpp:75
double getComputeTime() const
The total time in seconds spent in successful calls to compute().
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:158
Teuchos::RCP< const map_type > getRangeMap() const
Tpetra::Map representing the range of this operator.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:123
Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix; the matrix to be preconditioned.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:106
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition Ifpack2_Details_Amesos2Wrapper_decl.hpp:81
int getNumInitialize() const
The total number of successful calls to initialize().
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:138
double getApplyTime() const
The total time in seconds spent in successful calls to apply().
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:163
int getNumApply() const
The total number of successful calls to apply().
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:148
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition Ifpack2_Details_Amesos2Wrapper_decl.hpp:84
virtual ~Amesos2Wrapper()
Destructor.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:48
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
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
std::string description() const
A one-line description of this object.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:455
void initialize()
Compute the preordering and symbolic factorization of the matrix.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:225
int getNumCompute() const
The total number of successful calls to compute().
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:143
void setParameters(const Teuchos::ParameterList &params)
Set parameters.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:51
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::RCP< const map_type > getDomainMap() const
Tpetra::Map representing the domain of this operator.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:112
void compute()
Compute the numeric factorization of the matrix.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:329
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The input matrix's communicator.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:95
Amesos2Wrapper(const Teuchos::RCP< const row_matrix_type > &A)
Constructor.
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:35
double getInitializeTime() const
The total time in seconds spent in successful calls to initialize().
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:153
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 hasTransposeApply() const
Whether this object's apply() method can apply the transpose (or conjugate transpose,...
Definition Ifpack2_Details_Amesos2Wrapper_def.hpp:133
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition Ifpack2_Details_LinearSolver_decl.hpp:75
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params)
Set the solver's parameters.
Definition Ifpack2_Details_LinearSolver_def.hpp:135
std::string description() const
Implementation of Teuchos::Describable::description.
Definition Ifpack2_Details_LinearSolver_def.hpp:168
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of Teuchos::Describable::describe.
Definition Ifpack2_Details_LinearSolver_def.hpp:178
void registerLinearSolverFactory()
Ifpack2 implementation details.
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40