43 #ifndef IFPACK2_ILUT_DEF_HPP
44 #define IFPACK2_ILUT_DEF_HPP
47 #if defined (__clang__) && !defined (__INTEL_COMPILER)
48 #pragma clang system_header
51 #include "Ifpack2_Heap.hpp"
52 #include "Ifpack2_LocalFilter.hpp"
53 #include "Ifpack2_LocalSparseTriangularSolver.hpp"
54 #include "Ifpack2_Parameters.hpp"
55 #include "Tpetra_CrsMatrix.hpp"
58 #include <type_traits>
88 template<
class ScalarType>
90 ilutDefaultDropTolerance () {
93 typedef typename STS::magnitudeType magnitude_type;
97 const magnitude_type oneHalf = STM::one() / (STM::one() + STM::one());
102 return std::min (as<magnitude_type> (1000) * STS::magnitude (STS::eps ()), oneHalf);
109 ilutDefaultDropTolerance<double> () {
116 template <
class MatrixType>
119 Athresh_ (Teuchos::ScalarTraits<magnitude_type>::zero ()),
120 Rthresh_ (Teuchos::ScalarTraits<magnitude_type>::one ()),
121 RelaxValue_ (Teuchos::ScalarTraits<magnitude_type>::zero ()),
123 DropTolerance_ (ilutDefaultDropTolerance<
scalar_type> ()),
124 InitializeTime_ (0.0),
130 IsInitialized_ (false),
136 template <
class MatrixType>
140 template<
class MatrixType>
149 template<
class MagnitudeType>
150 std::pair<MagnitudeType, bool>
152 const char parameterName[],
153 const MagnitudeType& currentValue)
155 const std::string pname (parameterName);
157 if (params.
isType<MagnitudeType> (pname)) {
158 const MagnitudeType value = params.
get<MagnitudeType> (pname);
159 return {value,
true};
161 else if (! std::is_same<MagnitudeType, double>::value &&
162 params.
isType<
double> (pname)) {
163 const MagnitudeType value = params.
get<
double> (pname);
164 return {value,
true};
167 return {currentValue,
false};
174 template <
class MatrixType>
183 double fillLevel = LevelOfFill_;
184 bool gotFillLevel =
false;
186 const std::string fillLevelParamName (
"fact: ilut level-of-fill");
187 if (params.
isType<
double> (fillLevelParamName)) {
188 fillLevel = params.
get<
double> (fillLevelParamName);
191 else if (! std::is_same<magnitude_type, double>::value &&
192 params.
isType<
double> (fillLevelParamName)) {
193 fillLevel = params.
get<
double> (fillLevelParamName);
197 (gotFillLevel && fillLevel < 1.0, std::runtime_error,
198 "Ifpack2::ILUT: The \"fact: ilut level-of-fill\" parameter must be >= "
199 "1.0, but you set it to " << fillLevel <<
". For ILUT, the fill level "
200 "means something different than it does for ILU(k). ILU(0) produces "
201 "factors with the same sparsity structure as the input matrix A. For "
202 "ILUT, level-of-fill = 1.0 will produce factors with nonzeros matching "
203 "the sparsity structure of A. level-of-fill > 1.0 allows for additional "
207 const auto absThreshResult =
208 getMagnitudeOrDoubleParameterAsMagnitude (params,
"fact: absolute threshold", Athresh_);
209 const auto relThreshResult =
210 getMagnitudeOrDoubleParameterAsMagnitude (params,
"fact: relative threshold", Rthresh_);
211 const auto relaxResult =
212 getMagnitudeOrDoubleParameterAsMagnitude (params,
"fact: relax value", RelaxValue_);
213 const auto dropResult =
214 getMagnitudeOrDoubleParameterAsMagnitude (params,
"fact: drop tolerance", DropTolerance_);
217 L_solver_->setParameters(params);
218 U_solver_->setParameters(params);
221 LevelOfFill_ = fillLevel;
223 if (absThreshResult.second) {
224 Athresh_ = absThreshResult.first;
226 if (relThreshResult.second) {
227 Rthresh_ = relThreshResult.first;
229 if (relaxResult.second) {
230 RelaxValue_ = relaxResult.first;
232 if (dropResult.second) {
233 DropTolerance_ = dropResult.first;
238 template <
class MatrixType>
242 A_.is_null (), std::runtime_error,
"Ifpack2::ILUT::getComm: "
243 "The matrix is null. Please call setMatrix() with a nonnull input "
244 "before calling this method.");
245 return A_->getComm ();
249 template <
class MatrixType>
256 template <
class MatrixType>
261 A_.is_null (), std::runtime_error,
"Ifpack2::ILUT::getDomainMap: "
262 "The matrix is null. Please call setMatrix() with a nonnull input "
263 "before calling this method.");
264 return A_->getDomainMap ();
268 template <
class MatrixType>
273 A_.is_null (), std::runtime_error,
"Ifpack2::ILUT::getRangeMap: "
274 "The matrix is null. Please call setMatrix() with a nonnull input "
275 "before calling this method.");
276 return A_->getRangeMap ();
280 template <
class MatrixType>
286 template <
class MatrixType>
288 return NumInitialize_;
292 template <
class MatrixType>
298 template <
class MatrixType>
304 template <
class MatrixType>
306 return InitializeTime_;
310 template<
class MatrixType>
316 template<
class MatrixType>
322 template<
class MatrixType>
325 A_.is_null (), std::runtime_error,
"Ifpack2::ILUT::getNodeSmootherComplexity: "
326 "The input matrix A is null. Please call setMatrix() with a nonnull "
327 "input matrix, then call compute(), before calling this method.");
329 return A_->getNodeNumEntries() + getNodeNumEntries();
333 template<
class MatrixType>
335 return L_->getGlobalNumEntries () + U_->getGlobalNumEntries ();
339 template<
class MatrixType>
341 return L_->getNodeNumEntries () + U_->getNodeNumEntries ();
345 template<
class MatrixType>
351 ! A.
is_null () && A->getComm ()->getSize () == 1 &&
352 A->getNodeNumRows () != A->getNodeNumCols (),
353 std::runtime_error,
"Ifpack2::ILUT::setMatrix: If A's communicator only "
354 "contains one process, then A must be square. Instead, you provided a "
355 "matrix A with " << A->getNodeNumRows () <<
" rows and "
356 << A->getNodeNumCols () <<
" columns.");
362 IsInitialized_ =
false;
364 A_local_ = Teuchos::null;
371 if (! L_solver_.is_null ()) {
372 L_solver_->setMatrix (Teuchos::null);
374 if (! U_solver_.is_null ()) {
375 U_solver_->setMatrix (Teuchos::null);
385 template<
class MatrixType>
394 A_.is_null (), std::runtime_error,
"Ifpack2::ILUT::initialize: "
395 "The matrix to precondition is null. Please call setMatrix() with a "
396 "nonnull input before calling this method.");
399 IsInitialized_ =
false;
401 A_local_ = Teuchos::null;
405 A_local_ = makeLocalFilter (A_);
407 IsInitialized_ =
true;
414 template<
typename ScalarType>
416 scalar_mag (
const ScalarType& s)
422 template<
class MatrixType>
456 if (! isInitialized ()) {
474 Array<ArrayView<const local_ordinal_type> > Uindices (myNumRows);
475 Array<ArrayView<const scalar_type> > Ucoefs (myNumRows);
480 #ifdef IFPACK2_WRITE_FACTORS
481 std::ofstream ofsL(
"L.tif.mtx", std::ios::out);
482 std::ofstream ofsU(
"U.tif.mtx", std::ios::out);
487 double local_nnz =
static_cast<double> (A_local_->getNodeNumEntries ());
488 double fill = ((getLevelOfFill () - 1.0) * local_nnz) / (2 * myNumRows);
493 double fill_ceil=std::ceil(fill);
497 size_type fillL =
static_cast<size_type
>(fill_ceil);
498 size_type fillU =
static_cast<size_type
>(fill_ceil);
500 Array<scalar_type> InvDiagU (myNumRows, zero);
502 Array<local_ordinal_type> tmp_idx;
503 Array<scalar_type> tmpv;
505 enum { UNUSED, ORIG, FILL };
508 Array<int> pattern(max_col, UNUSED);
509 Array<scalar_type> cur_row(max_col, zero);
510 Array<magnitude_type> unorm(max_col);
511 magnitude_type rownorm;
512 Array<local_ordinal_type> L_cols_heap;
513 Array<local_ordinal_type> U_cols;
514 Array<local_ordinal_type> L_vals_heap;
515 Array<local_ordinal_type> U_vals_heap;
520 greater_indirect<scalar_type,local_ordinal_type> vals_comp(cur_row);
526 ArrayRCP<local_ordinal_type> ColIndicesARCP;
527 ArrayRCP<scalar_type> ColValuesARCP;
528 if (! A_local_->supportsRowViews ()) {
529 const size_t maxnz = A_local_->getNodeMaxNumRowEntries ();
530 ColIndicesARCP.resize (maxnz);
531 ColValuesARCP.resize (maxnz);
535 ArrayView<const local_ordinal_type> ColIndicesA;
536 ArrayView<const scalar_type> ColValuesA;
539 if (A_local_->supportsRowViews ()) {
540 A_local_->getLocalRowView (row_i, ColIndicesA, ColValuesA);
541 RowNnz = ColIndicesA.size ();
544 A_local_->getLocalRowCopy (row_i, ColIndicesARCP (), ColValuesARCP (), RowNnz);
545 ColIndicesA = ColIndicesARCP (0, RowNnz);
546 ColValuesA = ColValuesARCP (0, RowNnz);
551 U_cols.push_back(row_i);
552 cur_row[row_i] = zero;
553 pattern[row_i] = ORIG;
555 size_type L_cols_heaplen = 0;
556 rownorm = STM::zero ();
557 for (
size_t i = 0; i < RowNnz; ++i) {
558 if (ColIndicesA[i] < myNumRows) {
559 if (ColIndicesA[i] < row_i) {
560 add_to_heap(ColIndicesA[i], L_cols_heap, L_cols_heaplen);
562 else if (ColIndicesA[i] > row_i) {
563 U_cols.push_back(ColIndicesA[i]);
566 cur_row[ColIndicesA[i]] = ColValuesA[i];
567 pattern[ColIndicesA[i]] = ORIG;
568 rownorm += scalar_mag(ColValuesA[i]);
575 const magnitude_type rthresh = getRelativeThreshold();
577 cur_row[row_i] = as<scalar_type> (getAbsoluteThreshold() * IFPACK2_SGN(v)) + rthresh*v;
579 size_type orig_U_len = U_cols.size();
580 RowNnz = L_cols_heap.size() + orig_U_len;
581 rownorm = getDropTolerance() * rownorm/RowNnz;
584 size_type L_vals_heaplen = 0;
585 while (L_cols_heaplen > 0) {
588 scalar_type multiplier = cur_row[row_k] * InvDiagU[row_k];
589 cur_row[row_k] = multiplier;
590 magnitude_type mag_mult = scalar_mag(multiplier);
591 if (mag_mult*unorm[row_k] < rownorm) {
592 pattern[row_k] = UNUSED;
596 if (pattern[row_k] != ORIG) {
597 if (L_vals_heaplen < fillL) {
598 add_to_heap(row_k, L_vals_heap, L_vals_heaplen, vals_comp);
600 else if (L_vals_heaplen==0 ||
601 mag_mult < scalar_mag(cur_row[L_vals_heap.front()])) {
602 pattern[row_k] = UNUSED;
607 pattern[L_vals_heap.front()] = UNUSED;
609 add_to_heap(row_k, L_vals_heap, L_vals_heaplen, vals_comp);
615 ArrayView<const local_ordinal_type>& ColIndicesU = Uindices[row_k];
616 ArrayView<const scalar_type>& ColValuesU = Ucoefs[row_k];
617 size_type ColNnzU = ColIndicesU.size();
619 for(size_type j=0; j<ColNnzU; ++j) {
620 if (ColIndicesU[j] > row_k) {
623 if (pattern[col_j] != UNUSED) {
624 cur_row[col_j] -= tmp;
626 else if (scalar_mag(tmp) > rownorm) {
627 cur_row[col_j] = -tmp;
628 pattern[col_j] = FILL;
630 U_cols.push_back(col_j);
646 for (size_type i = 0; i < ColIndicesA.size (); ++i) {
647 if (ColIndicesA[i] < row_i) {
648 tmp_idx.push_back(ColIndicesA[i]);
649 tmpv.push_back(cur_row[ColIndicesA[i]]);
650 pattern[ColIndicesA[i]] = UNUSED;
655 for (size_type j = 0; j < L_vals_heaplen; ++j) {
656 tmp_idx.push_back(L_vals_heap[j]);
657 tmpv.push_back(cur_row[L_vals_heap[j]]);
658 pattern[L_vals_heap[j]] = UNUSED;
666 L_->insertLocalValues (row_i, tmp_idx (), tmpv ());
667 #ifdef IFPACK2_WRITE_FACTORS
668 for (size_type ii = 0; ii < tmp_idx.size (); ++ii) {
669 ofsL << row_i <<
" " << tmp_idx[ii] <<
" " << tmpv[ii] << std::endl;
677 if (cur_row[row_i] == zero) {
678 std::cerr <<
"Ifpack2::ILUT::Compute: zero pivot encountered! Replacing with rownorm and continuing...(You may need to set the parameter 'fact: absolute threshold'.)" << std::endl;
679 cur_row[row_i] = rownorm;
681 InvDiagU[row_i] = one / cur_row[row_i];
684 tmp_idx.push_back(row_i);
685 tmpv.push_back(cur_row[row_i]);
686 unorm[row_i] = scalar_mag(cur_row[row_i]);
687 pattern[row_i] = UNUSED;
693 size_type U_vals_heaplen = 0;
694 for(size_type j=1; j<U_cols.size(); ++j) {
696 if (pattern[col] != ORIG) {
697 if (U_vals_heaplen < fillU) {
698 add_to_heap(col, U_vals_heap, U_vals_heaplen, vals_comp);
700 else if (U_vals_heaplen!=0 && scalar_mag(cur_row[col]) >
701 scalar_mag(cur_row[U_vals_heap.front()])) {
703 add_to_heap(col, U_vals_heap, U_vals_heaplen, vals_comp);
707 tmp_idx.push_back(col);
708 tmpv.push_back(cur_row[col]);
709 unorm[row_i] += scalar_mag(cur_row[col]);
711 pattern[col] = UNUSED;
714 for(size_type j=0; j<U_vals_heaplen; ++j) {
715 tmp_idx.push_back(U_vals_heap[j]);
716 tmpv.push_back(cur_row[U_vals_heap[j]]);
717 unorm[row_i] += scalar_mag(cur_row[U_vals_heap[j]]);
720 unorm[row_i] /= (orig_U_len + U_vals_heaplen);
722 U_->insertLocalValues(row_i, tmp_idx(), tmpv() );
723 #ifdef IFPACK2_WRITE_FACTORS
724 for(
int ii=0; ii<tmp_idx.size(); ++ii) {
725 ofsU <<row_i<<
" " <<tmp_idx[ii]<<
" " <<tmpv[ii]<< std::endl;
731 U_->getLocalRowView(row_i, Uindices[row_i], Ucoefs[row_i] );
743 L_solver_->setMatrix(L_);
744 L_solver_->initialize ();
745 L_solver_->compute ();
747 U_solver_->setMatrix(U_);
748 U_solver_->initialize ();
749 U_solver_->compute ();
757 template <
class MatrixType>
759 apply (
const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
760 Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
767 using Teuchos::rcpFromRef;
771 ! isComputed (), std::runtime_error,
772 "Ifpack2::ILUT::apply: You must call compute() to compute the incomplete "
773 "factorization, before calling apply().");
776 X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
777 "Ifpack2::ILUT::apply: X and Y must have the same number of columns. "
778 "X has " << X.getNumVectors () <<
" columns, but Y has "
779 << Y.getNumVectors () <<
" columns.");
788 if (alpha == one && beta == zero) {
791 L_solver_->apply (X, Y, mode);
794 U_solver_->apply (Y, Y, mode);
799 U_solver_->apply (X, Y, mode);
802 L_solver_->apply (Y, Y, mode);
816 MV Y_tmp (Y.getMap (), Y.getNumVectors ());
817 apply (X, Y_tmp, mode);
818 Y.update (alpha, Y_tmp, beta);
828 template <
class MatrixType>
831 std::ostringstream os;
836 os <<
"\"Ifpack2::ILUT\": {";
837 os <<
"Initialized: " << (isInitialized () ?
"true" :
"false") <<
", "
838 <<
"Computed: " << (isComputed () ?
"true" :
"false") <<
", ";
840 os <<
"Level-of-fill: " << getLevelOfFill() <<
", "
841 <<
"absolute threshold: " << getAbsoluteThreshold() <<
", "
842 <<
"relative threshold: " << getRelativeThreshold() <<
", "
843 <<
"relaxation value: " << getRelaxValue() <<
", ";
846 os <<
"Matrix: null";
849 os <<
"Global matrix dimensions: ["
850 << A_->getGlobalNumRows () <<
", " << A_->getGlobalNumCols () <<
"]"
851 <<
", Global nnz: " << A_->getGlobalNumEntries();
859 template <
class MatrixType>
882 out <<
"\"Ifpack2::ILUT\":" << endl;
884 out <<
"MatrixType: " << TypeNameTraits<MatrixType>::name () << endl;
885 if (this->getObjectLabel () !=
"") {
886 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
888 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false")
890 <<
"Computed: " << (isComputed () ?
"true" :
"false")
892 <<
"Level of fill: " << getLevelOfFill () << endl
893 <<
"Absolute threshold: " << getAbsoluteThreshold () << endl
894 <<
"Relative threshold: " << getRelativeThreshold () << endl
895 <<
"Relax value: " << getRelaxValue () << endl;
898 const double fillFraction =
899 (double) getGlobalNumEntries () / (double) A_->getGlobalNumEntries ();
900 const double nnzToRows =
901 (double) getGlobalNumEntries () / (double) U_->getGlobalNumRows ();
903 out <<
"Dimensions of L: [" << L_->getGlobalNumRows () <<
", "
904 << L_->getGlobalNumRows () <<
"]" << endl
905 <<
"Dimensions of U: [" << U_->getGlobalNumRows () <<
", "
906 << U_->getGlobalNumRows () <<
"]" << endl
907 <<
"Number of nonzeros in factors: " << getGlobalNumEntries () << endl
908 <<
"Fill fraction of factors over A: " << fillFraction << endl
909 <<
"Ratio of nonzeros to rows: " << nnzToRows << endl;
912 out <<
"Number of initialize calls: " << getNumInitialize () << endl
913 <<
"Number of compute calls: " << getNumCompute () << endl
914 <<
"Number of apply calls: " << getNumApply () << endl
915 <<
"Total time in seconds for initialize: " << getInitializeTime () << endl
916 <<
"Total time in seconds for compute: " << getComputeTime () << endl
917 <<
"Total time in seconds for apply: " << getApplyTime () << endl;
919 out <<
"Local matrix:" << endl;
920 A_local_->describe (out, vl);
924 template <
class MatrixType>
928 if (A->getComm ()->getSize () > 1) {
943 #define IFPACK2_ILUT_INSTANT(S,LO,GO,N) \
944 template class Ifpack2::ILUT< Tpetra::RowMatrix<S, LO, GO, N> >;
ILUT(const Teuchos::RCP< const row_matrix_type > &A)
Constructor.
Definition: Ifpack2_ILUT_def.hpp:117
bool hasTransposeApply() const
Whether this object's apply() method can apply the transpose (or conjugate transpose, if applicable).
Definition: Ifpack2_ILUT_def.hpp:281
virtual ~ILUT()
Destructor.
Definition: Ifpack2_ILUT_def.hpp:137
basic_OSTab< char > OSTab
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
global_size_t getGlobalNumEntries() const
Returns the number of nonzero entries in the global graph.
Definition: Ifpack2_ILUT_def.hpp:334
void initialize()
Clear any previously computed factors.
Definition: Ifpack2_ILUT_def.hpp:386
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
Definition: Ifpack2_ILUT_def.hpp:862
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_ILUT_def.hpp:829
ILUT (incomplete LU factorization with threshold) of a Tpetra sparse matrix.
Definition: Ifpack2_ILUT_decl.hpp:91
size_t getNodeNumEntries() const
Returns the number of nonzero entries in the local graph.
Definition: Ifpack2_ILUT_def.hpp:340
void rm_heap_root(Teuchos::Array< Ordinal > &heap, SizeType &heap_len)
Definition: Ifpack2_Heap.hpp:92
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< const map_type > getRangeMap() const
Tpetra::Map representing the range of this operator.
Definition: Ifpack2_ILUT_def.hpp:270
"Preconditioner" that solves local sparse triangular systems.
Definition: Ifpack2_LocalSparseTriangularSolver_decl.hpp:77
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_ILUT_decl.hpp:106
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
void compute()
Compute factors L and U using the specified diagonal perturbation thresholds and relaxation parameter...
Definition: Ifpack2_ILUT_def.hpp:423
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_ILUT_def.hpp:346
static magnitudeType magnitude(T a)
int getNumInitialize() const
Returns the number of calls to Initialize().
Definition: Ifpack2_ILUT_def.hpp:287
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_ILUT_def.hpp:317
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the input matrix's communicator.
Definition: Ifpack2_ILUT_def.hpp:240
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 for the L and U factors...
Definition: Ifpack2_ILUT_decl.hpp:126
TypeTo as(const TypeFrom &t)
Teuchos::RCP< const map_type > getDomainMap() const
Tpetra::Map representing the domain of this operator.
Definition: Ifpack2_ILUT_def.hpp:258
bool isType(const std::string &name) const
double totalElapsedTime(bool readCurrentTime=false) const
void add_to_heap(const Ordinal &idx, Teuchos::Array< Ordinal > &heap, SizeType &heap_len)
Definition: Ifpack2_Heap.hpp:70
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
Definition: Ifpack2_ILUT_def.hpp:323
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:160
double getInitializeTime() const
Returns the time spent in Initialize().
Definition: Ifpack2_ILUT_def.hpp:305
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_ILUT_def.hpp:299
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 ILUT preconditioner to X, resulting in Y.
Definition: Ifpack2_ILUT_def.hpp:759
double getComputeTime() const
Returns the time spent in Compute().
Definition: Ifpack2_ILUT_def.hpp:311
void setParameters(const Teuchos::ParameterList ¶ms)
Set preconditioner parameters.
Definition: Ifpack2_ILUT_def.hpp:175
int getNumCompute() const
Returns the number of calls to Compute().
Definition: Ifpack2_ILUT_def.hpp:293
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_ILUT_decl.hpp:109
Teuchos::RCP< const row_matrix_type > getMatrix() const
Returns a reference to the matrix to be preconditioned.
Definition: Ifpack2_ILUT_def.hpp:251