10#ifndef MUELU_INVERSEAPPROXIMATIONFACTORY_DEF_HPP_
11#define MUELU_INVERSEAPPROXIMATIONFACTORY_DEF_HPP_
13#include <Xpetra_BlockedCrsMatrix.hpp>
14#include <Xpetra_CrsGraph.hpp>
15#include <Xpetra_CrsMatrixWrap.hpp>
16#include <Xpetra_CrsMatrix.hpp>
17#include <Xpetra_VectorFactory.hpp>
18#include <Xpetra_MatrixFactory.hpp>
19#include <Xpetra_Matrix.hpp>
21#include "Kokkos_Sort.hpp"
22#include "KokkosBlas1_set.hpp"
23#include "KokkosBatched_QR_Decl.hpp"
24#include "KokkosBatched_ApplyQ_Decl.hpp"
25#include "KokkosBatched_Trsv_Decl.hpp"
26#include "KokkosBatched_Util.hpp"
27#include <KokkosKernels_SimpleUtils.hpp>
31#include "MueLu_Utilities.hpp"
34#if KOKKOSKERNELS_VERSION < 50102
35#include "Teuchos_SerialDenseVector.hpp"
36#include "Teuchos_SerialDenseMatrix.hpp"
37#include "Teuchos_SerialQRDenseSolver.hpp"
42template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
44 RCP<ParameterList> validParamList = rcp(
new ParameterList());
45 using Magnitude =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
47 validParamList->set<RCP<const FactoryBase>>(
"A",
NoFactory::getRCP(),
"Matrix to build the approximate inverse on.\n");
49 validParamList->set<std::string>(
"inverse: approximation type",
"diagonal",
"Method used to approximate the inverse.");
50 validParamList->set<Magnitude>(
"inverse: drop tolerance", 0.0,
"Values below this threshold are dropped from the matrix (or fixed if diagonal fixing is active).");
51 validParamList->set<
bool>(
"inverse: fixing",
false,
"Keep diagonal and fix small entries with 1.0");
53 return validParamList;
56template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
58 Input(currentLevel,
"A");
61template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
65 using STS = Teuchos::ScalarTraits<SC>;
66 const SC one = STS::one();
67 using Magnitude =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
69 const ParameterList& pL = GetParameterList();
70 const bool fixing = pL.get<
bool>(
"inverse: fixing");
73 const std::string method = pL.get<std::string>(
"inverse: approximation type");
74 TEUCHOS_TEST_FOR_EXCEPTION(method !=
"diagonal" && method !=
"lumping" && method !=
"sparseapproxinverse" && method !=
"factoredsparseapproxinverse",
Exceptions::RuntimeError,
75 "MueLu::InverseApproximationFactory::Build: Approximation type can be 'diagonal' or 'lumping' or "
76 "'sparseapproxinverse' or 'factoredsparseapproxinverse'.");
78 RCP<Matrix> A = Get<RCP<Matrix>>(currentLevel,
"A");
79 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A);
80 const bool isBlocked = (bA == Teuchos::null ? false :
true);
83 if (isBlocked) A = bA->getMatrix(0, 0);
85 Magnitude tol = pL.get<Magnitude>(
"inverse: drop tolerance");
86 RCP<Matrix> Ainv = Teuchos::null;
88 if (method ==
"diagonal") {
89 const auto diag = VectorFactory::Build(A->getRangeMap(),
true);
90 A->getLocalDiagCopy(*diag);
92 Ainv = MatrixFactory::Build(D);
93 }
else if (method ==
"lumping") {
96 Ainv = MatrixFactory::Build(D);
97 }
else if (method ==
"sparseapproxinverse") {
100 sparsityPattern->computeGlobalConstants();
101 GetOStream(
Statistics1) <<
"NNZ Graph(A): " << A->getCrsGraph()->getGlobalNumEntries() <<
" , NNZ Tresholded Graph(A): " << sparsityPattern->getGlobalNumEntries() << std::endl;
103 RCP<Matrix> pAinv = GetSparseInverse(A, sparsityPattern);
106 rcp_const_cast<CrsGraph>(Ainv->getCrsGraph())->computeGlobalConstants();
107 GetOStream(
Statistics1) <<
"NNZ Ainv: " << pAinv->getGlobalNumEntries() <<
", NNZ Tresholded Ainv (parameter: " << tol <<
"): " << Ainv->getGlobalNumEntries() << std::endl;
109 }
else if (method ==
"factoredsparseapproxinverse") {
112 sparsityPattern->computeGlobalConstants();
113 GetOStream(
Statistics1) <<
"NNZ Graph(A): " << A->getCrsGraph()->getGlobalNumEntries() <<
" , NNZ Tresholded Graph(triLower(A)): " << sparsityPattern->getGlobalNumEntries() << std::endl;
115 RCP<Matrix> pLinvFactor = GetFactoredSparseInverse(A, sparsityPattern);
124 Ainv = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*LinvTrans,
false, *LinvFactor,
false, GetOStream(
Statistics2),
true,
true, std::string(
"Ainv"));
127 rcp_const_cast<CrsGraph>(Ainv->getCrsGraph())->computeGlobalConstants();
128 GetOStream(
Statistics1) <<
"NNZ Linv: " << LinvFactor->getGlobalNumEntries() <<
", NNZ Tresholded Linv (parameter: " << tol <<
"): " << pLinvFactor->getGlobalNumEntries() << std::endl;
132 GetOStream(
Statistics1) <<
"Approximate inverse calculated by: " << method <<
"." << std::endl;
133 GetOStream(
Statistics1) <<
"Ainv has " << Ainv->getGlobalNumRows() <<
"x" << Ainv->getGlobalNumCols() <<
" rows and columns." << std::endl;
135 Set(currentLevel,
"Ainv", Ainv);
138#if KOKKOSKERNELS_VERSION >= 50102
140template <
class local_matrix_type>
141class LocalSPAIFunctor {
143 using scalar_type =
typename local_matrix_type::value_type;
144 using local_ordinal_type =
typename local_matrix_type::ordinal_type;
145 using execution_space =
typename local_matrix_type::execution_space;
146 using impl_scalar_type =
typename KokkosKernels::ArithTraits<scalar_type>::val_type;
147 using impl_ATS = KokkosKernels::ArithTraits<impl_scalar_type>;
150 using shared_matrix = Kokkos::View<impl_scalar_type**, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
151 using shared_vector = Kokkos::View<impl_scalar_type*, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
152 using shared_lo_vector = Kokkos::View<local_ordinal_type*, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
155 const local_matrix_type lclA;
156 local_matrix_type lclAinv;
157 const local_ordinal_type maxUniqueColEntries;
158 const int scratchLevel;
161 LocalSPAIFunctor(
const local_matrix_type& lclA_, local_matrix_type& lclAinv_, local_ordinal_type maxUniqueColEntries_,
int scratchLevel_)
164 , maxUniqueColEntries(maxUniqueColEntries_)
165 , scratchLevel(scratchLevel_) {}
167 KOKKOS_INLINE_FUNCTION
168 void operator()(
const typename Kokkos::TeamPolicy<execution_space>::member_type& thread)
const {
169 auto rlid = thread.league_rank();
170 auto rowAinv = lclAinv.row(rlid);
173 shared_lo_vector column_indices(thread.team_scratch(scratchLevel), maxUniqueColEntries);
174 local_ordinal_type numColEntries = 0;
175 for (local_ordinal_type ii = 0; ii < rowAinv.length; ++ii) {
176 auto i = rowAinv.colidx(ii);
177 auto rowA = lclA.rowConst(i);
178 for (local_ordinal_type jj = 0; jj < rowA.length; ++jj) {
179 auto j = rowA.colidx(jj);
180 column_indices(numColEntries) = j;
186 local_ordinal_type numUniqeColEntries = 0;
187 local_ordinal_type diagOffset = 0;
190 Kokkos::Experimental::sort_thread(thread, Kokkos::subview(column_indices, Kokkos::make_pair(0, numColEntries)));
192 if (numColEntries > 0)
193 ++numUniqeColEntries;
194 local_ordinal_type pos = 0;
195 for (local_ordinal_type m = 1; m < numColEntries; ++m) {
196 if (column_indices(pos) != column_indices(m)) {
197 column_indices(pos + 1) = column_indices(m);
199 ++numUniqeColEntries;
200 if (column_indices(pos) == rlid)
208 shared_lo_vector uniqueColIndicies(thread.team_scratch(scratchLevel), numUniqeColEntries);
209 for (local_ordinal_type m = 0; m < numUniqeColEntries; ++m) {
210 uniqueColIndicies(m) = column_indices(m);
214 shared_matrix localA(thread.team_scratch(scratchLevel), numUniqeColEntries, rowAinv.length);
215 KokkosBlas::SerialSet::invoke(impl_ATS::zero(), localA);
218 for (local_ordinal_type ii = 0; ii < rowAinv.length; ++ii) {
219 auto i = rowAinv.colidx(ii);
220 auto rowA = lclA.rowConst(i);
221 for (local_ordinal_type jj = 0; jj < rowA.length; ++jj) {
222 auto j = rowA.colidx(jj);
223 auto v = rowA.value(jj);
226 auto it = KokkosKernels::lower_bound_thread(uniqueColIndicies, j);
231 shared_matrix ek(thread.team_scratch(scratchLevel), numUniqeColEntries, 1);
233 for (local_ordinal_type i = 0; i < numUniqeColEntries; ++i) {
234 ek(i, 0) = (i == diagOffset) ? impl_ATS::one() : impl_ATS::zero();
238 shared_vector tau(thread.team_scratch(scratchLevel), rowAinv.length);
239 shared_vector work(thread.team_scratch(scratchLevel), numUniqeColEntries);
241 KokkosBatched::SerialQR<KokkosBatched::Algo::QR::Unblocked>::invoke(localA, tau, work);
243 KokkosBatched::SerialApplyQ<KokkosBatched::Side::Left, KokkosBatched::Trans::Transpose, KokkosBatched::Algo::ApplyQ::Unblocked>::invoke(localA, tau, ek, work);
245 auto sub_A = Kokkos::subview(localA, Kokkos::make_pair(0, rowAinv.length), Kokkos::ALL());
246 auto sub_ek = Kokkos::subview(ek, Kokkos::make_pair(0, rowAinv.length), 0);
247 KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Upper, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(impl_ATS::one(), sub_A, sub_ek);
250 for (local_ordinal_type i = 0; i < rowAinv.length; ++i) {
251 rowAinv.value(i) = sub_ek(i);
256template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
257RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
259 using execution_space =
typename Node::execution_space;
262 RCP<Matrix> Ainv = MatrixFactory::Build(sparsityPattern);
266 RCP<Import> rowImport = ImportFactory::Build(sparsityPattern->getRowMap(), sparsityPattern->getColMap());
267 RCP<Matrix> A = MatrixFactory::Build(Aorg, *rowImport);
269 auto maxRowEntriesAinv = Ainv->getLocalMaxNumRowEntries();
270 auto maxRowEntriesA = A->getLocalMaxNumRowEntries();
271 auto maxUniqueColEntries = maxRowEntriesAinv * maxRowEntriesA;
273 auto lclA = A->getLocalMatrixDevice();
274 auto lclAinv = Ainv->getLocalMatrixDevice();
276 Kokkos::TeamPolicy<execution_space> policy(lclAinv.numRows(), 1);
278 using spai_functor_type = LocalSPAIFunctor<
decltype(lclAinv)>;
279 using shared_matrix =
typename spai_functor_type::shared_matrix;
280 using shared_vector =
typename spai_functor_type::shared_vector;
281 using shared_lo_vector =
typename spai_functor_type::shared_lo_vector;
283 int size = shared_matrix::shmem_size(maxUniqueColEntries, maxRowEntriesAinv) + shared_matrix::shmem_size(maxUniqueColEntries, 1) + shared_vector::shmem_size(3 * maxUniqueColEntries) + shared_vector::shmem_size(maxRowEntriesAinv) + shared_lo_vector::shmem_size(maxUniqueColEntries);
285 int scratchLevel = -1;
286 if (size < policy.scratch_size_max((
int)0)) {
287 policy.set_scratch_size((
int)0, Kokkos::PerTeam(size));
289 }
else if (size < policy.scratch_size_max((
int)1)) {
290 policy.set_scratch_size((
int)1, Kokkos::PerTeam(size));
293 throw Exceptions::RuntimeError(
"Neither L0 scratch memory (max size " + std::to_string(policy.scratch_size_max((
int)0)) +
294 "), nor L1 scratch memory (max size " + std::to_string(policy.scratch_size_max((
int)1)) +
295 ") is large enough for requested allocation of size " + std::to_string(size));
297 LocalSPAIFunctor spaiFunctor(lclA, lclAinv, maxUniqueColEntries, scratchLevel);
299 Kokkos::parallel_for(
"MueLu::InverseFactory::LocalSpai", policy, spaiFunctor);
302 Ainv->fillComplete();
313template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
314RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
317 RCP<Matrix> Ainv = MatrixFactory::Build(sparsityPattern);
321 RCP<Import> rowImport = ImportFactory::Build(sparsityPattern->getRowMap(), sparsityPattern->getColMap());
322 RCP<Matrix> A = MatrixFactory::Build(Aorg, *rowImport);
325 for (
size_t k = 0; k < sparsityPattern->getLocalNumRows(); k++) {
327 ArrayView<const LO> Ik;
328 sparsityPattern->getLocalRowView(k, Ik);
331 Array<ArrayView<const LO>> J(Ik.size());
332 Array<ArrayView<const SC>> Ak(Ik.size());
334 for (LO i = 0; i < Ik.size(); i++) {
335 A->getLocalRowView(Ik[i], J[i], Ak[i]);
336 for (LO j = 0; j < J[i].size(); j++)
340 std::sort(Jk.begin(), Jk.end());
341 Jk.erase(std::unique(Jk.begin(), Jk.end()), Jk.end());
344 for (LO i = 0; i < Jk.size(); i++) G.insert(std::pair<LO, LO>(Jk[i], i));
347 Teuchos::SerialDenseMatrix<LO, SC> localA(Jk.size(), Ik.size(),
true);
348 for (LO i = 0; i < Ik.size(); i++) {
349 for (LO j = 0; j < J[i].size(); j++) {
350 localA(G.at(J[i][j]), i) = Ak[i][j];
356 Teuchos::SerialDenseVector<LO, SC> ek(Jk.size(),
true);
357 ek[std::find(Jk.begin(), Jk.end(), k) - Jk.begin()] = Teuchos::ScalarTraits<Scalar>::one();
361 Teuchos::SerialDenseVector<LO, SC> localX(Ik.size());
362 Teuchos::SerialQRDenseSolver<LO, SC> qrSolver;
363 qrSolver.setMatrix(Teuchos::rcp(&localA,
false));
364 qrSolver.setVectors(Teuchos::rcp(&localX,
false), Teuchos::rcp(&ek,
false));
365 const int err = qrSolver.solve();
367 "MueLu::InverseApproximationFactory::GetSparseInverse: Error in serial QR solve.");
370 ArrayView<const SC> Mk(localX.values(), localX.length());
371 Ainv->replaceLocalValues(k, Ik, Mk);
373 Ainv->fillComplete();
384template <
class local_matrix_type,
typename global_ordinal_type>
391 using impl_ATS = KokkosKernels::ArithTraits<impl_scalar_type>;
393 using local_map_type = Tpetra::Details::LocalMap<local_ordinal_type, global_ordinal_type, device_type>;
396 using shared_matrix = Kokkos::View<impl_scalar_type**, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
397 using shared_vector = Kokkos::View<impl_scalar_type*, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
398 using shared_lo_vector = Kokkos::View<local_ordinal_type*, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
420 KOKKOS_INLINE_FUNCTION
421 void operator()(
const typename Kokkos::TeamPolicy<execution_space>::member_type& thread)
const {
422 auto rlid = thread.league_rank();
423 auto rowAinv =
lclAinv.row(rlid);
446 auto A_rowGid =
lclARowMap.getGlobalElement(rlid);
448 auto numRowEntries = rowAinv.length;
457 auto i = rowAinv.colidx(ii);
461 column_indices(ii) = A_lclColInd;
462 if (A_rowGid == Ainv_colGid) {
463 A_lclRowIndForDiag = A_lclRowInd;
466#ifdef HAVE_MUELU_DEBUG
467 KOKKOS_ASSERT(A_lclRowIndForDiag != -1 &&
"MueLu::InverseApproximationFactory::GetSparseInverse: no diagonal entry found in A.");
470 Kokkos::Experimental::sort_thread(thread, column_indices);
471 for (
int kkk = 0; kkk < numColEntries; kkk++) {
472 if (column_indices(kkk) == A_lclRowIndForDiag) diagOffset = kkk;
474#ifdef HAVE_MUELU_DEBUG
475 KOKKOS_ASSERT(diagOffset != -1 &&
"MueLu::InverseApproximationFactory::GetSparseInverse: no diagonal entry offset found in A.");
480 KokkosBlas::SerialSet::invoke(impl_ATS::zero(), localA);
484 auto i = rowAinv.colidx(ii);
487#ifdef HAVE_MUELU_DEBUG
488 KOKKOS_ASSERT(A_lclRowInd != -1 &&
"MueLu::InverseApproximationFactory: Column global ID in Ainv not found in A rowmap");
490 auto rowA =
lclA.rowConst(A_lclRowInd);
493 auto j = rowA.colidx(jj);
496 auto A_colGid =
lclAColMap.getGlobalElement(j);
497 if (A_colGid <= A_rowGid) {
498 auto newIndex = KokkosKernels::lower_bound_thread(column_indices, j);
499 if ((newIndex < column_indices.extent(0)) && (column_indices(newIndex) == j))
500 localA(newIndex, ii) = rowA.value(jj);
507 ek(i, 0) = (i == diagOffset) ? impl_ATS::one() : impl_ATS::zero();
516 KokkosBatched::SerialQR<KokkosBatched::Algo::QR::Unblocked>::invoke(localA, tau, work);
518 KokkosBatched::SerialCholesky<KokkosBatched::Uplo::Lower, KokkosBatched::Algo::Cholesky::Unblocked>::invoke(localA);
522 KokkosBatched::SerialApplyQ<KokkosBatched::Side::Left, KokkosBatched::Trans::Transpose, KokkosBatched::Algo::ApplyQ::Unblocked>::invoke(localA, tau, ek, work);
524 auto sub_A = Kokkos::subview(localA, Kokkos::make_pair(0, rowAinv.length), Kokkos::ALL());
526 auto sub_A = Kokkos::subview(localA, Kokkos::make_pair(0, rowAinv.length), Kokkos::make_pair(0, rowAinv.length));
528 auto sub_ek = Kokkos::subview(ek, Kokkos::make_pair(0, rowAinv.length), 0);
530 KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Upper, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(impl_ATS::one(), sub_A, sub_ek);
532 KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Lower, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(impl_ATS::one(), sub_A, sub_ek);
533 KokkosBatched::SerialTrsv<KokkosBatched::Uplo::Lower, KokkosBatched::Trans::Transpose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(impl_ATS::one(), sub_A, sub_ek);
538 diagValue = sub_ek(diagOffset);
539#ifdef HAVE_MUELU_DEBUG
540 KOKKOS_ASSERT(impl_ATS::real(diagValue) > 0.0 &&
"MueLu::InverseApproximationFactory::GetSparseInverse: non positive diagonal entry.");
542 auto scale_factor = impl_ATS::one() / impl_ATS::sqrt(diagValue);
544 typename KokkosKernels::ArithTraits<
decltype(diagValue)>::val_type thevalue = sub_ek(i) * scale_factor;
546 if (thevalue == impl_ATS::zero()) thevalue = impl_ATS::eps();
547 rowAinv.value(i) = thevalue;
552template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
553RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
555 using execution_space =
typename Node::execution_space;
558 RCP<Matrix> Ainv = MatrixFactory::Build(sparsityPattern);
562 RCP<Import> rowImport = ImportFactory::Build(sparsityPattern->getRowMap(), sparsityPattern->getColMap());
563 RCP<Matrix> A = MatrixFactory::Build(Aorg, *rowImport);
565 auto maxRowEntriesAinv = Ainv->getLocalMaxNumRowEntries();
567 auto lclA = A->getLocalMatrixDevice();
568 auto lclAinv = Ainv->getLocalMatrixDevice();
569 auto lclARowmap = A->getRowMap()->getLocalMap();
570 auto lclAColmap = A->getColMap()->getLocalMap();
571 auto lclAinvRowmap = Ainv->getRowMap()->getLocalMap();
572 auto lclAinvColmap = Ainv->getColMap()->getLocalMap();
573 auto lclAorgRowmap = Aorg->getRowMap()->getLocalMap();
575 Kokkos::TeamPolicy<execution_space> policy(lclAinv.numRows(), 1);
578 using shared_matrix =
typename fsai_functor_type::shared_matrix;
579 using shared_vector =
typename fsai_functor_type::shared_vector;
580 using shared_lo_vector =
typename fsai_functor_type::shared_lo_vector;
582 int size = shared_matrix::shmem_size(maxRowEntriesAinv, maxRowEntriesAinv) + shared_matrix::shmem_size(maxRowEntriesAinv, 1) + shared_vector::shmem_size(3 * maxRowEntriesAinv) + shared_vector::shmem_size(maxRowEntriesAinv) + shared_lo_vector::shmem_size(maxRowEntriesAinv);
584 int scratchLevel = -1;
585 if (size < policy.scratch_size_max((
int)0)) {
586 policy.set_scratch_size((
int)0, Kokkos::PerTeam(size));
588 }
else if (size < policy.scratch_size_max((
int)1)) {
589 policy.set_scratch_size((
int)1, Kokkos::PerTeam(size));
592 throw Exceptions::RuntimeError(
"Neither L0 scratch memory (max size " + std::to_string(policy.scratch_size_max((
int)0)) +
593 "), nor L1 scratch memory (max size " + std::to_string(policy.scratch_size_max((
int)1)) +
594 ") is large enough for requested allocation of size " + std::to_string(size));
596 LocalFSAIFunctor fsaiFunctor(lclA, lclAinv, lclARowmap, lclAColmap, lclAinvRowmap, lclAinvColmap, scratchLevel);
598 Kokkos::parallel_for(
"MueLu::InverseFactory::LocalSpai", policy, fsaiFunctor);
601 Ainv->fillComplete();
MueLu::DefaultGlobalOrdinal GlobalOrdinal
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.
RCP< Matrix > GetFactoredSparseInverse(const RCP< Matrix > &A, const RCP< const CrsGraph > &sparsityPattern) const
Sparse factor inverse calculation method.
void Build(Level ¤tLevel) const
Build an object with this factory.
void DeclareInput(Level ¤tLevel) const
Input.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
RCP< Matrix > GetSparseInverse(const RCP< Matrix > &A, const RCP< const CrsGraph > &sparsityPattern) const
Sparse inverse calculation method.
Class that holds all level-specific information.
local_map_type lclAinvRowMap
KokkosKernels::ArithTraits< impl_scalar_type > impl_ATS
typename KokkosKernels::ArithTraits< scalar_type >::val_type impl_scalar_type
local_map_type lclARowMap
Kokkos::View< local_ordinal_type *, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged > shared_lo_vector
Tpetra::Details::LocalMap< local_ordinal_type, global_ordinal_type, device_type > local_map_type
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::execution_space execution_space
Kokkos::View< impl_scalar_type *, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged > shared_vector
local_map_type lclAColMap
typename local_matrix_type::device_type device_type
typename local_matrix_type::ordinal_type local_ordinal_type
local_map_type lclAinvColMap
Kokkos::View< impl_scalar_type **, typename execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged > shared_matrix
LocalFSAIFunctor(const local_matrix_type &lclA_, local_matrix_type &lclAinv_, const local_map_type &lclARowMap_, const local_map_type &lclAColMap_, const local_map_type &lclAinvRowMap_, const local_map_type &lclAinvColMap_, int scratchLevel_)
KOKKOS_INLINE_FUNCTION void operator()(const typename Kokkos::TeamPolicy< execution_space >::member_type &thread) const
local_matrix_type lclAinv
const local_matrix_type lclA
static const RCP< const NoFactory > getRCP()
Static Get() functions.
static Teuchos::RCP< Vector > GetInverse(Teuchos::RCP< const Vector > v, Magnitude tol=Teuchos::ScalarTraits< Scalar >::eps() *100, Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero())
Return vector containing inverse of input vector.
static RCP< Xpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > GetThresholdedLowerTriangularGraph(const RCP< Matrix > &A, const Magnitude threshold)
Threshold a graph.
static RCP< Xpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > GetThresholdedGraph(const RCP< Matrix > &A, const Magnitude threshold)
Threshold a graph.
static RCP< Matrix > GetThresholdedMatrix(const RCP< Matrix > &Ain, const Magnitude threshold, const bool keepDiagonal=true)
Threshold a matrix.
static Teuchos::RCP< Vector > GetLumpedMatrixDiagonal(Matrix const &A, const bool doReciprocal=false, Magnitude tol=Teuchos::ScalarTraits< Scalar >::magnitude(Teuchos::ScalarTraits< Scalar >::zero()), Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero(), const bool replaceSingleEntryRowWithZero=false, const bool useAverageAbsDiagVal=false)
Extract Matrix Diagonal of lumped matrix.
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Transpose(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, bool optimizeTranspose=false, const std::string &label=std::string(), const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.
@ Statistics1
Print more statistics.