10#ifndef MUELU_CONSTRAINT_DEF_HPP
11#define MUELU_CONSTRAINT_DEF_HPP
13#include <Xpetra_Map.hpp>
14#include <Xpetra_MultiVector.hpp>
15#include <Xpetra_Matrix.hpp>
16#include "KokkosBatched_Copy_Internal.hpp"
17#include "Teuchos_Assert.hpp"
18#include "Xpetra_MatrixFactory.hpp"
19#include "Xpetra_MatrixMatrix.hpp"
22#include "MueLu_ProductOperator.hpp"
24#include "MueLu_Utilities.hpp"
27#include "KokkosBlas1_set.hpp"
28#include "KokkosBatched_QR_FormQ_TeamVector_Internal.hpp"
29#include "KokkosBatched_ApplyQ_Decl.hpp"
30#include "KokkosBatched_SetIdentity_Decl.hpp"
31#include "KokkosBatched_SetIdentity_Impl.hpp"
32#include "Kokkos_DualView.hpp"
33#include "Kokkos_Pair.hpp"
34#include "Kokkos_UnorderedMap.hpp"
35#include "KokkosBatched_QR_Decl.hpp"
36#include "KokkosBatched_QR_Serial_Impl.hpp"
37#include "KokkosBatched_QR_TeamVector_Impl.hpp"
38#include "KokkosBatched_LU_Decl.hpp"
39#include "KokkosBatched_LU_Team_Impl.hpp"
40#include "KokkosBatched_Trsv_Decl.hpp"
41#include "KokkosBatched_Trsv_TeamVector_Impl.hpp"
42#include "KokkosBatched_Gemm_Decl.hpp"
43#include "KokkosBatched_Gemm_Team_Impl.hpp"
44#include "KokkosBatched_Gemv_Decl.hpp"
45#include "KokkosBatched_Gemv_Team_Impl.hpp"
46#include "KokkosBatched_Copy_Decl.hpp"
47#include "KokkosBatched_Copy_Impl.hpp"
51template <
class LocalGraph,
class LocalVector>
63 MinSpmMV(LocalGraph lclGraph_, LocalVector lhs_, LocalVector rhs_)
68 KOKKOS_INLINE_FUNCTION
73 KOKKOS_INLINE_FUNCTION
74 void join(
bool& dst,
const bool& src) {
78 KOKKOS_INLINE_FUNCTION
83 val = Kokkos::min(val,
lhs(j));
87 changed = changed || (prev != val);
91template <
class LocalGraph,
class LocalVector>
103 MinSpmMVT(LocalGraph lclGraph_, LocalVector lhs_, LocalVector rhs_)
110 KOKKOS_INLINE_FUNCTION
115 Kokkos::atomic_min(&
rhs(j), val);
120template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
123 using CrsGraph =
typename Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
124 using CrsMatrix =
typename Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
128 using ATS = KokkosKernels::ArithTraits<scalar_type>;
130 using magATS = KokkosKernels::ArithTraits<magnitude_type>;
133 using shared_matrix = Kokkos::View<scalar_type**, typename Node::execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
134 using shared_vector = Kokkos::View<scalar_type*, typename Node::execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged>;
159 KOKKOS_INLINE_FUNCTION
161 using member_type =
typename Kokkos::TeamPolicy<typename Node::execution_space>::member_type;
163 auto blockId = thread.league_rank();
164 auto blockRow =
blocks.rowConst(blockId);
165 auto blockSize = blockRow.length;
167 shared_matrix lclA(thread.team_shmem(), blockSize, blockSize);
172 KokkosBlas::TeamSet<member_type>::invoke(thread,
zero, lclA);
173 KokkosBlas::TeamSet<member_type>::invoke(thread,
one, lclConst);
174 thread.team_barrier();
178 auto i = blockRow.colidx(ii);
179 auto row =
A.rowConst(i);
181 auto j = row.colidx(jj);
182 auto d = row.value(jj);
184 if (blockRow.colidx(kk) == j) {
192 KokkosBlas::TeamGemv<member_type, KokkosBlas::Trans::NoTranspose, KokkosBlas::Algo::Gemv::Unblocked>::invoke(thread,
one, lclA, lclConst,
zero, lclAConst);
193 thread.team_barrier();
197 norm2 += ATS::magnitude(lclAConst(i) * lclAConst(i));
200 singular(blockId) = (ATS::magnitude(norm2) < ATS::epsilon());
203 KOKKOS_INLINE_FUNCTION
205 auto blockId = thread.league_rank();
210 KOKKOS_INLINE_FUNCTION
211 void operator()(
TagApply,
const typename Kokkos::TeamPolicy<typename Node::execution_space>::member_type& thread)
const {
212 using member_type =
typename Kokkos::TeamPolicy<typename Node::execution_space>::member_type;
214 auto blockId = thread.league_rank();
215 auto blockRow =
blocks.rowConst(blockId);
216 auto blockSize = blockRow.length;
218 shared_matrix lclA(thread.team_shmem(), blockSize, blockSize);
219 shared_matrix lclInvA(thread.team_shmem(), blockSize, blockSize);
221 const bool PseudoInverse = (!(
singular.extent(0) == 0)) &&
singular(blockId);
225 KokkosBlas::TeamSet<member_type>::invoke(thread, PseudoInverse ?
one :
zero, lclA);
226 thread.team_barrier();
230 auto i = blockRow.colidx(ii);
231 auto row =
A.rowConst(i);
233 auto j = row.colidx(jj);
234 auto d = row.value(jj);
236 if (blockRow.colidx(kk) == j) {
246 KokkosBatched::TeamLU<member_type, KokkosBlas::Algo::QR::Unblocked>::invoke(thread, lclA);
249 KokkosBatched::TeamSetIdentity<member_type>::invoke(thread, lclInvA);
250 thread.team_barrier();
254 KokkosBatched::TeamVectorTrsv<member_type, KokkosBatched::Uplo::Lower, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::Unit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(thread,
one, lclA, Kokkos::subview(lclInvA, Kokkos::ALL(), j));
255 thread.team_barrier();
259 KokkosBatched::TeamVectorTrsv<member_type, KokkosBatched::Uplo::Upper, KokkosBatched::Trans::NoTranspose, KokkosBatched::Diag::NonUnit, KokkosBatched::Algo::Trsv::Unblocked>::invoke(thread,
one, lclA, Kokkos::subview(lclInvA, Kokkos::ALL(), j));
260 thread.team_barrier();
302 shared_matrix temp(thread.team_shmem(), blockSize, blockSize);
303 KokkosBatched::TeamCopy<member_type, KokkosBatched::Trans::NoTranspose>::invoke(thread, lclInvA, temp);
304 thread.team_barrier();
307 KokkosBatched::TeamGemm<member_type, KokkosBatched::Trans::NoTranspose, KokkosBatched::Trans::NoTranspose, KokkosBatched::Algo::Gemm::Unblocked>::invoke(thread,
one, lclA, temp,
zero, lclInvA);
308 thread.team_barrier();
313 auto i = blockRow.colidx(ii);
314 auto row =
invA.row(i);
316 auto j = row.colidx(jj);
318 if (blockRow.colidx(kk) == j) {
319 row.value(jj) = lclInvA(ii, kk);
332template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
334 return X_->getDomainMap();
337template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
339 return X_->getDomainMap();
342template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
344#ifdef HAVE_MUELU_BELOS
345 Monitor m(*
this,
"PrepareLeastSquaresSolveBelos");
347 TEUCHOS_TEST_FOR_EXCEPTION(!detect_singular_blocks,
Exceptions::RuntimeError,
"The option \"emin: least squares solver type\" = \"Belos\" is currently only implemented for non-singular constraint solves");
349 problem_ = rcp(
new Belos::LinearProblem<Scalar, MV, OP>());
351 std::vector<RCP<Operator>> ops = {X_, X_};
352 std::vector<Teuchos::ETransp> modes = {Teuchos::NO_TRANS, Teuchos::TRANS};
354 auto belosXXt = rcp(
new Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(XXt));
356 problem_->setOperator(belosXXt);
357 problem_->setLabel(
"LeastSquares");
359 auto belosList = rcp(
new Teuchos::ParameterList());
360 belosList->set(
"Implicit Residual Scaling",
"None");
361 belosList->set(
"Convergence Tolerance", 1e-16);
362 auto out = GetMueLuOStream();
363 belosList->set(
"Output Stream", out->getOStream());
368 Belos::SolverFactory<Scalar, MV, OP> solverFactory;
369 solver_ = solverFactory.create(
"Pseudo Block CG", belosList);
371 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"Energy minimization multigrid requires Belos to be enabled.");
375template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
376Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
378 const typename Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>::local_graph_type blocks) {
379 using graph_type =
typename Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>::local_graph_type;
380 using matrix_type =
typename Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_matrix_type;
381 using execution_space =
typename Node::execution_space;
383 auto numRows = map->getLocalNumElements();
384 auto numBlocks = blocks.numRows();
385 typename graph_type::row_map_type::non_const_type rowptr(
"rowptr", numRows + 1);
388 Kokkos::parallel_reduce(
389 "MueLu::Constraint::allocateBlockDiagonalMatrix::1", Kokkos::RangePolicy<execution_space>(0, numBlocks), KOKKOS_LAMBDA(
const LocalOrdinal blockId,
LocalOrdinal& count) {
390 auto blockRow = blocks.rowConst(blockId);
391 auto blockSize = blockRow.length;
394 auto rowId = blockRow.colidx(k);
395 if ((
decltype(numRows))rowId+2<numRows+1)
396 Kokkos::atomic_add(&rowptr(rowId+2), blockSize);
400 Kokkos::parallel_scan(
401 "MueLu::Constraint::allocateBlockDiagonalMatrix::3", Kokkos::RangePolicy<execution_space>(0, numRows), KOKKOS_LAMBDA(
const LocalOrdinal rowId,
LocalOrdinal& sum,
const bool is_final) {
402 sum += rowptr(rowId+1);
404 rowptr(rowId+1) = sum;
407 typename graph_type::entries_type::non_const_type indices(
"lclInvXXt_indices", nnz);
409 Kokkos::parallel_for(
410 "MueLu::Constraint::allocateBlockDiagonalMatrix::3", Kokkos::RangePolicy<execution_space>(0, numBlocks), KOKKOS_LAMBDA(
const LocalOrdinal blockId) {
411 auto blockRow = blocks.rowConst(blockId);
412 auto blockSize = blockRow.length;
415 auto rowId = blockRow.colidx(k);
417 auto j = blockRow.colidx(jj);
418 auto l = Kokkos::atomic_fetch_inc(&rowptr(rowId + 1));
424 auto lclInvXXtGraph = graph_type(indices, rowptr);
425 typename matrix_type::values_type::non_const_type values(
"lclInvXXt_values", nnz);
426 auto lclInvXXt = matrix_type(
"lclInvXXt", numRows, values, lclInvXXtGraph);
427 return Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclInvXXt, map, map, map, map);
430template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
432 using execution_space =
typename Node::execution_space;
433 using memory_space =
typename Node::memory_space;
434 using range_type = Kokkos::RangePolicy<LocalOrdinal, execution_space>;
440 auto numConstraints = XXt->getRowMap()->getLocalNumElements();
442 Kokkos::View<LocalOrdinal*, memory_space> blockIds(
"blockIds", numConstraints);
443 Kokkos::View<LocalOrdinal*, memory_space> blockIds2(
"blockIds2", numConstraints);
445 auto lclGraph = XXt->getLocalGraphDevice();
447 auto constraint_range = range_type(0, numConstraints);
450 Kokkos::parallel_for(
451 "MueLu::Constraint::FindBlocks::init_blockIds", constraint_range,
453 blockIds(contraintId) = contraintId;
459 bool resultsIn2 =
false;
463 MinSpmMV functor(lclGraph, blockIds, blockIds2);
464 Kokkos::parallel_reduce(
"MueLu::Constraint::FindBlocks::minSpmv1", constraint_range, functor, changed);
467 MinSpmMV functor(lclGraph, blockIds2, blockIds);
468 Kokkos::parallel_reduce(
"MueLu::Constraint::FindBlocks::minSpmv2", constraint_range, functor, changed);
473 Kokkos::deep_copy(blockIds, blockIds2);
476 Kokkos::View<bool*, memory_space> blockStatus(
"blockStatus", numConstraints);
477 Kokkos::parallel_for(
478 "MueLu::Constraint::FindBlocks::set_blockstatus", constraint_range,
480 Kokkos::atomic_store(&blockStatus(blockIds(contraintId)),
true);
485 Kokkos::View<LocalOrdinal*, memory_space> newBlockIds(
"newBlockIds", numConstraints);
487 Kokkos::parallel_scan(
488 "MueLu::Constraint::FindBlocks::compute_blockIds", constraint_range,
491 newBlockIds(contraintId) = blockId;
492 if (blockStatus(contraintId))
498 using graph_type =
typename Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>::local_graph_type;
499 typename graph_type::row_map_type::non_const_type rowptr(
"blocks_rowptr", numBlocks + 1);
500 typename graph_type::entries_type::non_const_type indices(
"blocks_indices", numConstraints);
502 Kokkos::parallel_for(
503 "MueLu::Constraint::FindBlocks::count_entries_per_block", constraint_range, KOKKOS_LAMBDA(
const LocalOrdinal constraintId) {
504 auto blockId = newBlockIds(blockIds(constraintId));
505 if (blockId + 2 < numBlocks + 1)
506 Kokkos::atomic_inc(&rowptr(blockId + 2));
510 auto block_range = range_type(0, numBlocks);
513 Kokkos::parallel_scan(
514 "MueLu::Constraint::FindBlocks::prefix_sum", block_range, KOKKOS_LAMBDA(
const LocalOrdinal blockId,
LocalOrdinal& sum,
const bool final) {
515 sum += rowptr(blockId+1);
517 rowptr(blockId+1) = sum;
520 Kokkos::parallel_for(
521 "MueLu::Constraint::FindBlocks::fill", constraint_range, KOKKOS_LAMBDA(
const LocalOrdinal contraintId) {
522 auto blockId = newBlockIds(blockIds(contraintId));
523 auto offset = Kokkos::atomic_fetch_inc(&rowptr(blockId + 1));
524 indices(offset) = contraintId;
527 graph_type blocks(indices, rowptr);
532template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
534 using memory_space =
typename Node::memory_space;
535 Monitor m(*
this,
"PrepareLeastSquaresSolveDirect");
537 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> XXt;
540 XXt = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*X_,
false, *X_,
true, XXt, GetOStream(
Runtime0),
true,
true);
543 auto XXtgraph = XXt->getCrsGraph();
544 auto blocks = this->FindBlocks(XXtgraph);
545 invXXt_ = allocateBlockDiagonalMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(XXt->getRowMap(), blocks);
548 LocalOrdinal maxBlocksize = invXXt_->getLocalMaxNumRowEntries();
551 Kokkos::View<bool*, memory_space> block_is_singular;
553 if (detect_singular_blocks)
554 block_is_singular = Kokkos::View<bool*, memory_space>(
"block_is_singular", numBlocks);
557 functor_type functor(XXt->getLocalMatrixDevice(), blocks, maxBlocksize, invXXt_->getLocalMatrixDevice(), block_is_singular);
559 if (detect_singular_blocks) {
560 SubMonitor m2(*
this,
"singular block detection");
561 Kokkos::parallel_for(
"MueLu::Constraint::findSingularBlocks", Kokkos::TeamPolicy<typename Node::execution_space, typename functor_type::TagFindSingularBlocks>(numBlocks, 1), functor);
564 Kokkos::parallel_reduce(
"MueLu::Constraint::countSingularBlocks", Kokkos::TeamPolicy<typename Node::execution_space, typename functor_type::TagCountSingularBlocks>(numBlocks, 1), functor, numSingularBlocks);
570 Kokkos::parallel_for(
"MueLu::Constraint::invertBlocks", Kokkos::TeamPolicy<typename Node::execution_space, typename functor_type::TagApply>(numBlocks, 1), functor);
576 auto comm = invXXt_->getRowMap()->getComm();
582 GetOStream(
Statistics0) <<
"Least-squares problem:\n maximum block size: " << invXXt_->getGlobalMaxNumRowEntries() <<
"\n Number of blocks: " << globalNumBlocks <<
"\n Number of singular blocks: " << globalNumSingularBlocks << std::endl;
586template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
588 if (solverType ==
"Belos")
589 PrepareLeastSquaresSolveBelos(detect_singular_blocks);
590 else if (solverType ==
"direct")
591 PrepareLeastSquaresSolveDirect(detect_singular_blocks);
593 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"solverType must be one of (Belos|direct), not \"" << solverType <<
"\".");
594 solverType_ = solverType;
597template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
600#ifdef HAVE_MUELU_BELOS
601 problem_->setLHS(rcpFromRef(C));
602 problem_->setRHS(rcpFromRef(B));
603 TEUCHOS_ASSERT(problem_->setProblem());
605 solver_->setProblem(problem_);
610template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
613 invXXt_->apply(B, C);
616template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
618 if (solverType_ ==
"Belos")
619 LeastSquaresSolveBelos(B, C);
620 else if (solverType_ ==
"direct")
621 LeastSquaresSolveDirect(B, C);
623 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"solverType must be one of (Belos|direct), not \"" << solverType_ <<
"\".");
626template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
628 MultiVector& Projected,
629 Teuchos::ETransp mode,
632 const auto one = Teuchos::ScalarTraits<Scalar>::one();
633 const auto zero = Teuchos::ScalarTraits<Scalar>::zero();
635 TEUCHOS_ASSERT(mode == Teuchos::NO_TRANS);
636 TEUCHOS_ASSERT(alpha == one);
637 TEUCHOS_ASSERT(beta == zero);
641 X_->apply(P, *temp1_, Teuchos::NO_TRANS);
642 LeastSquaresSolve(*temp1_, *temp2_);
643 X_->apply(*temp2_, *temp3_, Teuchos::TRANS);
644 Projected.update(-one, *temp3_, one);
647template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
649 const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& B,
650 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& R)
const {
651 const auto one = Teuchos::ScalarTraits<Scalar>::one();
652 const auto zero = Teuchos::ScalarTraits<Scalar>::zero();
654 apply(X, R, Teuchos::NO_TRANS, one, zero);
655 R.update(one, B, -one);
658template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
663template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
665 Ppattern_ = Ppattern;
668template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
673 temp1_ = MultiVectorFactory::Build(X_->getRangeMap(), 1);
674 temp2_ = MultiVectorFactory::Build(X_->getRangeMap(), 1);
675 temp3_ = MultiVectorFactory::Build(X_->getDomainMap(), 1);
678template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
683template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
685 const RCP<const CrsGraph>& pattern,
686 MultiVector& vecP)
const {
687 auto lclPattern = pattern->getLocalGraphDevice();
688 auto lclPatternRowMap = pattern->getRowMap()->getLocalMap();
689 auto lclPatternColMap = pattern->getColMap()->getLocalMap();
691 auto lclMat = P.getLocalMatrixDevice();
692 auto lclMatRowMap = P.getRowMap()->getLocalMap();
693 auto lclMatColMap = P.getColMap()->getLocalMap();
695 auto lclVec = vecP.getLocalViewDevice(Tpetra::Access::OverwriteAll);
696 TEUCHOS_ASSERT(lclPattern.numRows() == (
typename decltype(lclPattern)::size_type)lclMat.numRows());
697 TEUCHOS_ASSERT(lclPattern.entries.extent(0) == lclVec.extent(0));
698 Kokkos::deep_copy(lclVec, 0.);
700 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
701 Kokkos::parallel_for(
702 "MueLu::Constraint::AssignMatrixEntriesToVector::filter", range_type(0, lclPattern.numRows()), KOKKOS_LAMBDA(
const size_t i) {
703 auto grid = lclPatternRowMap.getGlobalElement(i);
704 auto row_mat = lclMat.rowConst(lclMatRowMap.getLocalElement(grid));
706 if (row_mat.length == 0)
709 for (
size_t jj = lclPattern.row_map(i); jj < lclPattern.row_map(i + 1); ++jj) {
710 auto clid_pattern = lclPattern.entries(jj);
711 auto cgid = lclPatternColMap.getGlobalElement(clid_pattern);
712 auto clid_mat = lclMatColMap.getLocalElement(cgid);
715 while ((kk + 1 < row_mat.length) && (row_mat.colidx(kk) != clid_mat))
717 if (row_mat.colidx(kk) == clid_mat) {
718 lclVec(jj, 0) = row_mat.value(kk);
724template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
726 MultiVector& vecP)
const {
727 AssignMatrixEntriesToVector(P, GetPattern(), vecP);
730template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
733 auto Ppattern = GetPattern();
734 RCP<Matrix> P = MatrixFactory::Build(Ppattern);
736 auto lclMat = P->getLocalMatrixDevice();
737 auto lclVec = vecP.getLocalViewDevice(Tpetra::Access::ReadOnly);
738 TEUCHOS_ASSERT(lclMat.values.extent(0) == lclVec.extent(0));
739 Kokkos::deep_copy(lclMat.values, Kokkos::subview(lclVec, Kokkos::ALL(), 0));
741 P->fillComplete(Ppattern->getDomainMap(), Ppattern->getRowMap());
#define MueLu_sumAll(rcpComm, in, out)
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
typename CrsGraph::local_graph_type local_graph_type
KokkosKernels::ArithTraits< magnitude_type > magATS
BlockInverseFunctor(local_matrix_type A_, local_graph_type blocks_, LocalOrdinal maxBlocksize_, local_matrix_type invA_, Kokkos::View< bool *, memory_space > singular_)
size_t team_shmem_size(int) const
Kokkos::View< scalar_type **, typename Node::execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged > shared_matrix
Kokkos::View< scalar_type *, typename Node::execution_space::scratch_memory_space, Kokkos::MemoryUnmanaged > shared_vector
typename Xpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > CrsGraph
typename local_matrix_type::value_type scalar_type
const magnitude_type mag_zero
KOKKOS_INLINE_FUNCTION void operator()(TagApply, const typename Kokkos::TeamPolicy< typename Node::execution_space >::member_type &thread) const
typename ATS::magnitudeType magnitude_type
typename Xpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > CrsMatrix
typename Node::memory_space memory_space
LocalOrdinal maxBlocksize
KOKKOS_INLINE_FUNCTION void operator()(TagFindSingularBlocks, const typename Kokkos::TeamPolicy< typename Node::execution_space >::member_type &thread) const
KokkosKernels::ArithTraits< scalar_type > ATS
Kokkos::View< bool *, memory_space > singular
KOKKOS_INLINE_FUNCTION void operator()(TagCountSingularBlocks, const typename Kokkos::TeamPolicy< typename Node::execution_space >::member_type &thread, LocalOrdinal &numSingularBlocks) const
typename CrsMatrix::local_matrix_type local_matrix_type
void LeastSquaresSolveDirect(const MultiVector &B, MultiVector &C) const
Direct solve of least-squares problem.
RCP< Matrix > GetConstraintMatrix()
virtual const RCP< const Map > getDomainMap() const
The Map associated with the domain of this operator, which must be compatible with X....
void PrepareLeastSquaresSolveDirect(bool detect_singular_blocks)
Prepare direct solution of least-squares problem.
virtual void apply(const MultiVector &P, MultiVector &Projected, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Apply constraint.
void PrepareLeastSquaresSolveBelos(bool detect_singular_blocks)
Prepare least-squares solve using Belos.
virtual CrsGraph::local_graph_type FindBlocks(RCP< const CrsGraph > &XXt)
void PrepareLeastSquaresSolve(const std::string &solverType, bool detect_singular_blocks=false)
void residual(const MultiVector &X, const MultiVector &B, MultiVector &R) const
Compute a residual R = B - (*this) * X.
void LeastSquaresSolve(const MultiVector &B, MultiVector &C) const
void SetConstraintsMatrix(RCP< Matrix > &X)
void LeastSquaresSolveBelos(const MultiVector &B, MultiVector &C) const
Perform least-squares solve using Belos.
RCP< Matrix > GetMatrixWithEntriesFromVector(MultiVector &vecP) const
RCP< const CrsGraph > GetPattern() const
void SetPattern(RCP< const CrsGraph > &Ppattern)
virtual const RCP< const Map > getRangeMap() const
The Map associated with the range of this operator, which must be compatible with Y....
void AssignMatrixEntriesToVector(const Matrix &P, const RCP< const CrsGraph > &pattern, MultiVector &vecP) const
Exception throws to report errors in the internal logical of the program.
MinSpmMV(LocalGraph lclGraph_, LocalVector lhs_, LocalVector rhs_)
typename LocalVector::value_type local_ordinal_type
const local_ordinal_type MAX_VAL
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type i, bool &changed) const
KOKKOS_INLINE_FUNCTION void init(bool &dst)
KOKKOS_INLINE_FUNCTION void join(bool &dst, const bool &src)
typename LocalVector::value_type local_ordinal_type
const local_ordinal_type MAX_VAL
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type i) const
MinSpmMVT(LocalGraph lclGraph_, LocalVector lhs_, LocalVector rhs_)
Timer to be used in non-factories.
Takes a sequence of operators and applies their product.
Timer to be used in non-factories. Similar to Monitor, but doesn't print object description.
Namespace for MueLu classes and methods.
@ Runtime0
One-liner description of what is happening.
@ Statistics0
Print statistics that do not involve significant additional computation.
Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > allocateBlockDiagonalMatrix(RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > map, const typename Xpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node >::local_graph_type blocks)