10#ifndef MUELU_REFMAXWELL_DEF_HPP
11#define MUELU_REFMAXWELL_DEF_HPP
17#include "Teuchos_CompilerCodeTweakMacros.hpp"
18#include "Tpetra_CrsMatrix.hpp"
19#include "Xpetra_CrsMatrix.hpp"
20#include "Xpetra_Map.hpp"
21#include "Xpetra_MatrixMatrix.hpp"
22#include "Xpetra_MultiVector.hpp"
23#include "Xpetra_TripleMatrixMultiply.hpp"
25#include "Xpetra_MatrixUtils.hpp"
29#include "MueLu_AmalgamationFactory.hpp"
30#include "MueLu_RAPFactory.hpp"
31#include "MueLu_SmootherFactory.hpp"
33#include "MueLu_CoalesceDropFactory.hpp"
34#include "MueLu_CoarseMapFactory.hpp"
35#include "MueLu_CoordinatesTransferFactory.hpp"
36#include "MueLu_UncoupledAggregationFactory.hpp"
37#include "MueLu_TentativePFactory.hpp"
38#include "MueLu_SaPFactory.hpp"
39#include "MueLu_AggregationExportFactory.hpp"
40#include "MueLu_Utilities.hpp"
41#include "MueLu_Maxwell_Utils.hpp"
43#include "MueLu_CoalesceDropFactory_kokkos.hpp"
44#include "MueLu_TentativePFactory_kokkos.hpp"
45#include <Kokkos_Core.hpp>
46#include <KokkosSparse_CrsMatrix.hpp>
48#include "MueLu_ZoltanInterface.hpp"
49#include "MueLu_Zoltan2Interface.hpp"
50#include "MueLu_RepartitionHeuristicFactory.hpp"
51#include "MueLu_RepartitionFactory.hpp"
52#include "MueLu_RebalanceAcFactory.hpp"
53#include "MueLu_RebalanceTransferFactory.hpp"
61#include "cuda_profiler_api.h"
65#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
72T
pop(Teuchos::ParameterList &pl, std::string
const &name_in) {
73 T result = pl.get<T>(name_in);
74 pl.remove(name_in,
true);
79T
pop(Teuchos::ParameterList &pl, std::string
const &name_in, T def_value) {
80 T result = pl.get<T>(name_in, def_value);
81 pl.remove(name_in,
false);
85template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
90template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
95template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
96Teuchos::RCP<Teuchos::ParameterList>
99 bool useKokkosDefault = !Node::is_serial;
101 RCP<ParameterList> params = rcp(
new ParameterList(
"RefMaxwell"));
103 params->set<RCP<Matrix>>(
"Dk_1", Teuchos::null);
104 params->set<RCP<Matrix>>(
"Dk_2", Teuchos::null);
105 params->set<RCP<Matrix>>(
"D0", Teuchos::null);
107 params->set<RCP<Matrix>>(
"M1_beta", Teuchos::null);
108 params->set<RCP<Matrix>>(
"M1_alpha", Teuchos::null);
110 params->set<RCP<Matrix>>(
"Ms", Teuchos::null);
112 params->set<RCP<Matrix>>(
"Mk_one", Teuchos::null);
113 params->set<RCP<Matrix>>(
"Mk_1_one", Teuchos::null);
115 params->set<RCP<Matrix>>(
"M1", Teuchos::null);
117 params->set<RCP<Matrix>>(
"invMk_1_invBeta", Teuchos::null);
118 params->set<RCP<Matrix>>(
"invMk_2_invAlpha", Teuchos::null);
120 params->set<RCP<Matrix>>(
"M0inv", Teuchos::null);
122 params->set<RCP<MultiVector>>(
"Nullspace", Teuchos::null);
123 params->set<RCP<RealValuedMultiVector>>(
"Coordinates", Teuchos::null);
125 auto spaceValidator = rcp(
new Teuchos::EnhancedNumberValidator<int>(1, 2));
126 params->set(
"refmaxwell: space number", 1,
"", spaceValidator);
128 params->set(
"use kokkos refactor", useKokkosDefault);
129 params->set(
"half precision",
false);
134 params->set(
"refmaxwell: disable addon 22",
true);
140 params->set(
"refmaxwell: skip first (2,2) level",
false);
141 params->set(
"multigrid algorithm",
"Unsmoothed");
144 params->set(
"rap: fix zero diagonals",
true);
147 params->set(
"refmaxwell: async transfers", Node::is_gpu);
149 params->set(
"refmaxwell: subsolves striding", 1);
151 params->set(
"sync timers",
false);
152 params->set(
"refmaxwell: num iters coarse 11", 1);
153 params->set(
"refmaxwell: num iters 22", 1);
154 params->set(
"refmaxwell: apply BCs to Anodal",
false);
155 params->set(
"refmaxwell: apply BCs to coarse 11",
true);
156 params->set(
"refmaxwell: apply BCs to 22",
true);
157 params->set(
"refmaxwell: max coarse size", 1);
159 ParameterList &precList11 = params->sublist(
"refmaxwell: 11list");
160 precList11.disableRecursiveValidation();
161 ParameterList &precList22 = params->sublist(
"refmaxwell: 22list");
162 precList22.disableRecursiveValidation();
164 params->set(
"smoother: type",
"CHEBYSHEV");
165 ParameterList &smootherList = params->sublist(
"smoother: params");
166 smootherList.disableRecursiveValidation();
167 params->set(
"smoother: pre type",
"NONE");
168 ParameterList &preSmootherList = params->sublist(
"smoother: pre params");
169 preSmootherList.disableRecursiveValidation();
170 params->set(
"smoother: post type",
"NONE");
171 ParameterList &postSmootherList = params->sublist(
"smoother: post params");
172 postSmootherList.disableRecursiveValidation();
174 ParameterList &matvecParams = params->sublist(
"matvec params");
175 matvecParams.disableRecursiveValidation();
177 ParameterList &importerCoarse11Params = params->sublist(
"refmaxwell: ImporterCoarse11 params");
178 importerCoarse11Params.disableRecursiveValidation();
180 ParameterList &importer22Params = params->sublist(
"refmaxwell: Importer22 params");
181 importer22Params.disableRecursiveValidation();
183 params->set(
"multigrid algorithm",
"unsmoothed");
198template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
200 if (list.isType<std::string>(
"parameterlist: syntax") && list.get<std::string>(
"parameterlist: syntax") ==
"ml") {
201 Teuchos::ParameterList newList;
205 for (
auto it = newList2.begin(); it != newList2.end(); ++it) {
206 const std::string &entry_name = it->first;
207 if (validateParameters->isParameter(entry_name)) {
208 ParameterEntry theEntry = newList2.getEntry(entry_name);
209 newList.setEntry(entry_name, theEntry);
214 if (list.isSublist(
"refmaxwell: 11list") && list.sublist(
"refmaxwell: 11list").isSublist(
"edge matrix free: coarse"))
216 if (list.isSublist(
"refmaxwell: 22list"))
223 std::string verbosityLevel =
parameterList_.get<std::string>(
"verbosity");
225 std::string outputFilename =
parameterList_.get<std::string>(
"output filename");
226 if (outputFilename !=
"")
228 if (
parameterList_.isType<Teuchos::RCP<Teuchos::FancyOStream>>(
"output stream"))
254 if (!
precList11_.isType<std::string>(
"Preconditioner Type") &&
255 !
precList11_.isType<std::string>(
"smoother: type") &&
256 !
precList11_.isType<std::string>(
"smoother: pre type") &&
257 !
precList11_.isType<std::string>(
"smoother: post type")) {
259 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
260 precList11_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 5.4);
261 precList11_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
265 if (!
precList22_.isType<std::string>(
"Preconditioner Type") &&
266 !
precList22_.isType<std::string>(
"smoother: type") &&
267 !
precList22_.isType<std::string>(
"smoother: pre type") &&
268 !
precList22_.isType<std::string>(
"smoother: post type")) {
270 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
271 precList22_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
272 precList22_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
276 list.set(
"smoother: type",
"CHEBYSHEV");
277 list.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
278 list.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 20.0);
279 list.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
283 !
precList11_.isType<std::string>(
"Preconditioner Type") &&
287 !
precList22_.isType<std::string>(
"Preconditioner Type") &&
292template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
294 using memory_space =
typename Node::device_type::memory_space;
296#ifdef HAVE_MUELU_CUDA
297 if (
parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
300 std::string timerLabel;
302 timerLabel =
"compute (reuse)";
304 timerLabel =
"compute";
305 RCP<Teuchos::TimeMonitor> tmCompute =
getTimer(timerLabel);
315 RCP<ParameterList> params = rcp(
new ParameterList());
316 params->set(
"printLoadBalancingInfo",
true);
317 params->set(
"printCommInfo",
true);
331 Kokkos::View<bool *, memory_space> BCcolsEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"),
Dk_1_->getColMap()->getLocalNumElements());
332 Kokkos::View<bool *, memory_space> BCdomainEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"),
Dk_1_->getDomainMap()->getLocalNumElements());
335 Kokkos::View<bool *, memory_space> BCcolsNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"),
D0_->getColMap()->getLocalNumElements());
336 Kokkos::View<bool *, memory_space> BCdomainNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"),
D0_->getDomainMap()->getLocalNumElements());
351 GetOStream(
Warnings0) <<
"All unknowns of the (1,1) block have been detected as boundary unknowns!" << std::endl;
376 RCP<Matrix> A11_nodal;
379 std::string label(
"D0^T*M1_beta*D0");
386 A11_nodal->setObjectLabel(
solverName_ +
" (1,1) A_nodal");
387 dump(A11_nodal,
"A11_nodal.m");
410 RCP<Matrix> A22_nodal;
413 std::string label(
"D0^T*M1_alpha*D0");
420 A22_nodal->setObjectLabel(
solverName_ +
" (2,2) A_nodal");
421 dump(A22_nodal,
"A22_nodal.m");
440 int rebalanceStriding, numProcsCoarseA11, numProcsA22;
444 doRebalancing =
false;
447 if (!reuse && doRebalancing)
467 std::string label(
"coarseA11");
478 Scalar replaceWith = Teuchos::ScalarTraits<SC>::zero();
489 build22Matrix(reuse, doRebalancing, rebalanceStriding, numProcsA22);
491 if (!
P22_.is_null()) {
492 std::string label(
"P22^T*A22*P22");
505 if (!
A22_.is_null()) {
507 std::string label(
"A22");
508 if (!
P22_.is_null()) {
518 int numRows = Teuchos::as<int>(
coarseA22_->getGlobalNumRows());
519 if (maxCoarseSize > numRows)
538 Scalar replaceWith = Teuchos::ScalarTraits<SC>::zero();
550 RCP<const Import> ImporterP11 = ImportFactory::Build(
ImporterCoarse11_->getTargetMap(),
P11_->getColMap());
559 RCP<const Import> ImporterD = ImportFactory::Build(
Importer22_->getTargetMap(),
Dk_1_->getColMap());
560 toCrsMatrix(
Dk_1_)->replaceDomainMapAndImporter(
Importer22_->getTargetMap(), ImporterD);
565 (!toCrsMatrix(
Dk_1_T_)->getCrsGraph()->getImporter().is_null()) &&
566 (!toCrsMatrix(
R11_)->getCrsGraph()->getImporter().is_null()) &&
567 (
Dk_1_T_->getColMap()->lib() == Xpetra::UseTpetra) &&
568 (
R11_->getColMap()->lib() == Xpetra::UseTpetra))
582 RCP<ParameterList> matvecParams = rcpFromRef(
parameterList_.sublist(
"matvec params"));
592 RCP<ParameterList> importerParams = rcpFromRef(
parameterList_.sublist(
"refmaxwell: ImporterCoarse11 params"));
596 RCP<ParameterList> importerParams = rcpFromRef(
parameterList_.sublist(
"refmaxwell: Importer22 params"));
597 Importer22_->setDistributorParameters(importerParams);
603#ifdef HAVE_MUELU_CUDA
604 if (
parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
608template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
611 doRebalancing =
parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators");
612 rebalanceStriding =
parameterList_.get<
int>(
"refmaxwell: subsolves striding", -1);
613 int numProcs =
SM_Matrix_->getDomainMap()->getComm()->getSize();
615 doRebalancing =
false;
630 ParameterList repartheurParams;
631 repartheurParams.set(
"repartition: start level", 0);
633 int defaultTargetRows = 10000;
634 repartheurParams.set(
"repartition: min rows per proc",
precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
635 repartheurParams.set(
"repartition: target rows per proc",
precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
636 repartheurParams.set(
"repartition: min rows per thread",
precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
637 repartheurParams.set(
"repartition: target rows per thread",
precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
638 repartheurParams.set(
"repartition: max imbalance",
precList11_.get<
double>(
"repartition: max imbalance", 1.1));
639 repartheurFactory->SetParameterList(repartheurParams);
641 level.
Request(
"number of partitions", repartheurFactory.get());
642 repartheurFactory->Build(level);
643 numProcsCoarseA11 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
644 numProcsCoarseA11 = std::min(numProcsCoarseA11, numProcs);
654 level.
Set(
"Map",
Dk_1_->getDomainMap());
657 ParameterList repartheurParams;
658 repartheurParams.set(
"repartition: start level", 0);
659 repartheurParams.set(
"repartition: use map",
true);
661 int defaultTargetRows = 10000;
662 repartheurParams.set(
"repartition: min rows per proc",
precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
663 repartheurParams.set(
"repartition: target rows per proc",
precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
664 repartheurParams.set(
"repartition: min rows per thread",
precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
665 repartheurParams.set(
"repartition: target rows per thread",
precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
667 repartheurFactory->SetParameterList(repartheurParams);
669 level.
Request(
"number of partitions", repartheurFactory.get());
670 repartheurFactory->Build(level);
671 numProcsA22 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
672 numProcsA22 = std::min(numProcsA22, numProcs);
675 if (rebalanceStriding >= 1) {
676 TEUCHOS_ASSERT(rebalanceStriding * numProcsCoarseA11 <= numProcs);
677 TEUCHOS_ASSERT(rebalanceStriding * numProcsA22 <= numProcs);
678 if (rebalanceStriding * (numProcsCoarseA11 + numProcsA22) > numProcs) {
679 GetOStream(
Warnings0) <<
solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 needs " << numProcsCoarseA11
680 <<
" procs and A22 needs " << numProcsA22 <<
" procs." << std::endl;
681 rebalanceStriding = -1;
683 int lclBadMatrixDistribution = (
coarseA11_->getLocalNumEntries() == 0) || (
Dk_1_->getDomainMap()->getLocalNumElements() == 0);
684 int gblBadMatrixDistribution =
false;
686 if (gblBadMatrixDistribution) {
687 GetOStream(
Warnings0) <<
solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 has no entries on at least one rank or Dk_1's domain map has no entries on at least one rank." << std::endl;
688 rebalanceStriding = -1;
692 if ((numProcsCoarseA11 < 0) || (numProcsA22 < 0) || (numProcsCoarseA11 + numProcsA22 > numProcs)) {
694 <<
"in undesirable number of partitions: " << numProcsCoarseA11 <<
", " << numProcsA22 << std::endl;
695 doRebalancing =
false;
699 doRebalancing =
false;
703template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
706 if (spaceNumber == 0)
707 return Teuchos::null;
709 std::string timerLabel;
712 timerLabel =
"Build coarse addon matrix 11";
714 timerLabel =
"Build addon matrix 11";
716 timerLabel =
"Build addon matrix 22";
718 RCP<Teuchos::TimeMonitor> tmAddon =
getTimer(timerLabel);
722 RCP<Matrix> lumpedInverse;
725 TEUCHOS_TEST_FOR_EXCEPTION(
invMk_1_invBeta_ == Teuchos::null, std::invalid_argument,
727 "::buildCoarse11Matrix(): Inverse of "
728 "lumped mass matrix required for add-on (i.e. invMk_1_invBeta_ is null)");
734 Zaux = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Mk_one_,
false, *
P11_,
false, Zaux,
GetOStream(
Runtime0),
true,
true);
736 Z = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *Zaux,
false, Z,
GetOStream(
Runtime0),
true,
true);
739 Z = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *
Mk_one_,
false, Z,
GetOStream(
Runtime0),
true,
true);
744 TEUCHOS_TEST_FOR_EXCEPTION(
invMk_2_invAlpha_ == Teuchos::null, std::invalid_argument,
746 "::buildCoarse11Matrix(): Inverse of "
747 "lumped mass matrix required for add-on (i.e. invMk_2_invAlpha_ is null)");
751 Z = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_2_,
true, *
Mk_1_one_,
false, Z,
GetOStream(
Runtime0),
true,
true);
755 if (lumpedInverse->getGlobalMaxNumRowEntries() <= 1) {
758 RCP<Vector> diag = VectorFactory::Build(lumpedInverse->getRowMap());
759 lumpedInverse->getLocalDiagCopy(*diag);
761 ArrayRCP<Scalar> diagVals = diag->getDataNonConst(0);
762 for (
size_t j = 0; j < diag->getMap()->getLocalNumElements(); j++) {
763 diagVals[j] = Teuchos::ScalarTraits<Scalar>::squareroot(diagVals[j]);
766 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
769 RCP<Import> importer = ImportFactory::Build(diag->getMap(), Z->getRowMap());
770 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
771 diag2->doImport(*diag, *importer, Xpetra::INSERT);
772 Z->leftScale(*diag2);
774 addon = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *Z,
false, addon,
GetOStream(
Runtime0),
true,
true);
775 }
else if (
parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
778 C2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*lumpedInverse,
false, *Z,
false, C2,
GetOStream(
Runtime0),
true,
true);
780 addon = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *C2,
false, addon,
GetOStream(
Runtime0),
true,
true);
782 addon = MatrixFactory::Build(Z->getDomainMap());
784 Xpetra::TripleMatrixMultiply<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
785 MultiplyRAP(*Z,
true, *lumpedInverse,
false, *Z,
false, *addon,
true,
true);
790template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
792 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Build coarse (1,1) matrix");
794 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
798 temp = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
SM_Matrix_,
false, *
P11_,
false, temp,
GetOStream(
Runtime0),
true,
true);
800 coarseA11_ = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
P11_,
true, *temp,
false,
coarseA11_,
GetOStream(
Runtime0),
true,
true);
803 temp2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
P11_,
true, *temp,
false, temp2,
GetOStream(
Runtime0),
true,
true);
806 temp2->removeEmptyProcessesInPlace(map);
807 if (!temp2.is_null() && temp2->getRowMap().is_null())
808 temp2 = Teuchos::null;
825 RCP<Matrix> newCoarseA11;
826 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*
coarseA11_,
false, one, *addon,
false, one, newCoarseA11,
GetOStream(
Runtime0));
827 newCoarseA11->fillComplete();
833 ArrayRCP<bool> coarseA11BCrows;
834 coarseA11BCrows.resize(
coarseA11_->getRowMap()->getLocalNumElements());
836 for (
size_t k = 0; k <
dim_; k++)
852 if (
precList11_.isParameter(
"rap: fix zero diagonals"))
853 fixZeroDiagonal =
precList11_.get<
bool>(
"rap: fix zero diagonals");
855 if (fixZeroDiagonal) {
860 else if (
precList11_.isType<
double>(
"rap: fix zero diagonals threshold"))
861 threshold = Teuchos::as<magnitudeType>(
precList11_.get<
double>(
"rap: fix zero diagonals threshold"));
862 if (
precList11_.isType<
double>(
"rap: fix zero diagonals replacement"))
863 replacement = Teuchos::as<Scalar>(
precList11_.get<
double>(
"rap: fix zero diagonals replacement"));
876template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
881 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Rebalance coarseA11");
883 Level fineLevel, coarseLevel;
894 coarseLevel.
Set(
"number of partitions", numProcsCoarseA11);
895 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
899 coarseLevel.setObjectLabel(
solverName_ +
" coarse (1,1)");
900 fineLevel.setObjectLabel(
solverName_ +
" coarse (1,1)");
902 std::string partName =
precList11_.get<std::string>(
"repartition: partitioner",
"zoltan2");
903 RCP<Factory> partitioner;
904 if (partName ==
"zoltan") {
905#ifdef HAVE_MUELU_ZOLTAN
912 }
else if (partName ==
"zoltan2") {
913#ifdef HAVE_MUELU_ZOLTAN2
915 ParameterList partParams;
916 RCP<const ParameterList> partpartParams = rcp(
new ParameterList(
precList11_.sublist(
"repartition: params",
false)));
917 partParams.set(
"ParameterList", partpartParams);
918 partitioner->SetParameterList(partParams);
926 ParameterList repartParams;
927 repartParams.set(
"repartition: print partition distribution",
precList11_.get<
bool>(
"repartition: print partition distribution",
false));
928 repartParams.set(
"repartition: remap parts",
precList11_.get<
bool>(
"repartition: remap parts",
true));
929 if (rebalanceStriding >= 1) {
930 bool acceptPart = (
SM_Matrix_->getDomainMap()->getComm()->getRank() % rebalanceStriding) == 0;
931 if (
SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsCoarseA11 * rebalanceStriding)
933 repartParams.set(
"repartition: remap accept partition", acceptPart);
935 repartFactory->SetParameterList(repartParams);
937 repartFactory->SetFactory(
"Partition", partitioner);
940 ParameterList newPparams;
941 newPparams.set(
"type",
"Interpolation");
942 newPparams.set(
"repartition: rebalance P and R",
precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
943 newPparams.set(
"repartition: use subcommunicators",
true);
948 newP->SetParameterList(newPparams);
949 newP->SetFactory(
"Importer", repartFactory);
952 ParameterList rebAcParams;
953 rebAcParams.set(
"repartition: use subcommunicators",
true);
954 newA->SetParameterList(rebAcParams);
955 newA->SetFactory(
"Importer", repartFactory);
957 coarseLevel.
Request(
"P", newP.get());
958 coarseLevel.
Request(
"Importer", repartFactory.get());
959 coarseLevel.
Request(
"A", newA.get());
960 coarseLevel.
Request(
"Coordinates", newP.get());
962 coarseLevel.
Request(
"Nullspace", newP.get());
963 repartFactory->Build(coarseLevel);
965 if (!
precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
967 P11_ = coarseLevel.
Get<RCP<Matrix>>(
"P", newP.get());
969 CoordsCoarse11_ = coarseLevel.
Get<RCP<RealValuedMultiVector>>(
"Coordinates", newP.get());
987 RCP<const Import> ImporterCoarse11 = coarseLevel.
Get<RCP<const Import>>(
"Importer", repartFactory.get());
988 RCP<const Map> targetMap = ImporterCoarse11->getTargetMap();
989 ParameterList XpetraList;
990 XpetraList.set(
"Restrict Communicator",
true);
991 Addon11_ = MatrixFactory::Build(
Addon11_, *ImporterCoarse11, *ImporterCoarse11, targetMap, targetMap, rcp(&XpetraList,
false));
996template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
999 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Build A22");
1001 Level fineLevel, coarseLevel;
1013 coarseLevel.setObjectLabel(
solverName_ +
" (2,2)");
1016 RCP<RAPFactory> rapFact = rcp(
new RAPFactory());
1017 ParameterList rapList = *(rapFact->GetValidParameterList());
1018 rapList.set(
"transpose: use implicit",
true);
1019 rapList.set(
"rap: fix zero diagonals",
parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1020 rapList.set(
"rap: fix zero diagonals threshold",
parameterList_.get<
double>(
"rap: fix zero diagonals threshold", Teuchos::ScalarTraits<double>::eps()));
1021 rapList.set(
"rap: triple product",
parameterList_.get<
bool>(
"rap: triple product",
false));
1022 rapFact->SetParameterList(rapList);
1025 coarseLevel.
AddKeepFlag(
"AP reuse data", rapFact.get());
1026 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList>>(
"AP reuse data",
A22_AP_reuse_data_, rapFact.get());
1029 coarseLevel.
AddKeepFlag(
"RAP reuse data", rapFact.get());
1030 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList>>(
"RAP reuse data",
A22_RAP_reuse_data_, rapFact.get());
1034 if (doRebalancing) {
1035 coarseLevel.
Set(
"number of partitions", numProcsA22);
1036 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
1038 std::string partName =
precList22_.get<std::string>(
"repartition: partitioner",
"zoltan2");
1039 RCP<Factory> partitioner;
1040 if (partName ==
"zoltan") {
1041#ifdef HAVE_MUELU_ZOLTAN
1043 partitioner->SetFactory(
"A", rapFact);
1049 }
else if (partName ==
"zoltan2") {
1050#ifdef HAVE_MUELU_ZOLTAN2
1052 ParameterList partParams;
1053 RCP<const ParameterList> partpartParams = rcp(
new ParameterList(
precList22_.sublist(
"repartition: params",
false)));
1054 partParams.set(
"ParameterList", partpartParams);
1055 partitioner->SetParameterList(partParams);
1056 partitioner->SetFactory(
"A", rapFact);
1064 ParameterList repartParams;
1065 repartParams.set(
"repartition: print partition distribution",
precList22_.get<
bool>(
"repartition: print partition distribution",
false));
1066 repartParams.set(
"repartition: remap parts",
precList22_.get<
bool>(
"repartition: remap parts",
true));
1067 if (rebalanceStriding >= 1) {
1068 bool acceptPart = ((
SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 -
SM_Matrix_->getDomainMap()->getComm()->getRank()) % rebalanceStriding) == 0;
1069 if (
SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 -
SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsA22 * rebalanceStriding)
1073 repartParams.set(
"repartition: remap accept partition", acceptPart);
1075 repartParams.set(
"repartition: remap accept partition",
coarseA11_.is_null());
1076 repartFactory->SetParameterList(repartParams);
1077 repartFactory->SetFactory(
"A", rapFact);
1079 repartFactory->SetFactory(
"Partition", partitioner);
1082 ParameterList newPparams;
1083 newPparams.set(
"type",
"Interpolation");
1084 newPparams.set(
"repartition: rebalance P and R",
precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
1085 newPparams.set(
"repartition: use subcommunicators",
true);
1086 newPparams.set(
"repartition: rebalance Nullspace",
false);
1088 newP->SetParameterList(newPparams);
1089 newP->SetFactory(
"Importer", repartFactory);
1092 ParameterList rebAcParams;
1093 rebAcParams.set(
"repartition: use subcommunicators",
true);
1094 newA->SetParameterList(rebAcParams);
1095 newA->SetFactory(
"A", rapFact);
1096 newA->SetFactory(
"Importer", repartFactory);
1098 coarseLevel.
Request(
"P", newP.get());
1099 coarseLevel.
Request(
"Importer", repartFactory.get());
1100 coarseLevel.
Request(
"A", newA.get());
1101 coarseLevel.
Request(
"Coordinates", newP.get());
1102 rapFact->Build(fineLevel, coarseLevel);
1103 repartFactory->Build(coarseLevel);
1105 if (!
precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
1106 Importer22_ = coarseLevel.
Get<RCP<const Import>>(
"Importer", repartFactory.get());
1107 Dk_1_ = coarseLevel.
Get<RCP<Matrix>>(
"P", newP.get());
1108 A22_ = coarseLevel.
Get<RCP<Matrix>>(
"A", newA.get());
1109 Coords22_ = coarseLevel.
Get<RCP<RealValuedMultiVector>>(
"Coordinates", newP.get());
1111 if (!
P22_.is_null()) {
1118 coarseLevel.
Request(
"A", rapFact.get());
1120 coarseLevel.
Request(
"AP reuse data", rapFact.get());
1121 coarseLevel.
Request(
"RAP reuse data", rapFact.get());
1124 A22_ = coarseLevel.
Get<RCP<Matrix>>(
"A", rapFact.get());
1127 if (coarseLevel.
IsAvailable(
"AP reuse data", rapFact.get()))
1129 if (coarseLevel.
IsAvailable(
"RAP reuse data", rapFact.get()))
1134 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Build A22");
1137 temp = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
SM_Matrix_,
false, *
Dk_1_,
false, temp,
GetOStream(
Runtime0),
true,
true);
1139 A22_ = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_T_,
false, *temp,
false,
A22_,
GetOStream(
Runtime0),
true,
true);
1141 A22_ = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *temp,
false,
A22_,
GetOStream(
Runtime0),
true,
true);
1144 RCP<const Import> Dimporter = toCrsMatrix(
Dk_1_)->getCrsGraph()->getImporter();
1147 RCP<Matrix> temp, temp2;
1148 temp = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
SM_Matrix_,
false, *
Dk_1_,
false, temp,
GetOStream(
Runtime0),
true,
true);
1150 temp2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_T_,
false, *temp,
false, temp2,
GetOStream(
Runtime0),
true,
true);
1152 temp2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *temp,
false, temp2,
GetOStream(
Runtime0),
true,
true);
1155 toCrsMatrix(
Dk_1_)->replaceDomainMapAndImporter(
Importer22_->getTargetMap(), Dimporter);
1157 ParameterList XpetraList;
1158 XpetraList.set(
"Restrict Communicator",
true);
1159 XpetraList.set(
"Timer Label",
"MueLu::RebalanceA22");
1160 RCP<const Map> targetMap =
Importer22_->getTargetMap();
1166 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1172 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*
A22_,
false, one, *addon22,
false, one, newA22,
GetOStream(
Runtime0));
1173 newA22->fillComplete();
1177 if (!
A22_.is_null()) {
1182 A22_->SetFixedBlockSize(1);
1188template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1191 RCP<MueLu::FactoryManagerBase> factoryHandler = rcp(
new FactoryManager());
1198 level.
Set(
"NodeMatrix",
A22_);
1201 if ((
parameterList_.get<std::string>(
"smoother: pre type") !=
"NONE") && (
parameterList_.get<std::string>(
"smoother: post type") !=
"NONE")) {
1202 std::string preSmootherType =
parameterList_.get<std::string>(
"smoother: pre type");
1203 std::string postSmootherType =
parameterList_.get<std::string>(
"smoother: post type");
1205 ParameterList preSmootherList, postSmootherList;
1207 preSmootherList =
parameterList_.sublist(
"smoother: pre params");
1209 postSmootherList =
parameterList_.sublist(
"smoother: post params");
1211 RCP<SmootherPrototype> preSmootherPrototype = rcp(
new TrilinosSmoother(preSmootherType, preSmootherList));
1212 RCP<SmootherPrototype> postSmootherPrototype = rcp(
new TrilinosSmoother(postSmootherType, postSmootherList));
1213 RCP<SmootherFactory> smootherFact = rcp(
new SmootherFactory(preSmootherPrototype, postSmootherPrototype));
1215 level.
Request(
"PreSmoother", smootherFact.get());
1216 level.
Request(
"PostSmoother", smootherFact.get());
1218 ParameterList smootherFactoryParams;
1219 smootherFactoryParams.set(
"keep smoother data",
true);
1220 smootherFact->SetParameterList(smootherFactoryParams);
1221 level.
Request(
"PreSmoother data", smootherFact.get());
1222 level.
Request(
"PostSmoother data", smootherFact.get());
1228 smootherFact->Build(level);
1229 PreSmoother11_ = level.
Get<RCP<SmootherBase>>(
"PreSmoother", smootherFact.get());
1236 std::string smootherType =
parameterList_.get<std::string>(
"smoother: type");
1238 ParameterList smootherList;
1242 RCP<SmootherPrototype> smootherPrototype = rcp(
new TrilinosSmoother(smootherType, smootherList));
1243 RCP<SmootherFactory> smootherFact = rcp(
new SmootherFactory(smootherPrototype));
1244 level.
Request(
"PreSmoother", smootherFact.get());
1246 ParameterList smootherFactoryParams;
1247 smootherFactoryParams.set(
"keep smoother data",
true);
1248 smootherFact->SetParameterList(smootherFactoryParams);
1249 level.
Request(
"PreSmoother data", smootherFact.get());
1253 smootherFact->Build(level);
1254 PreSmoother11_ = level.
Get<RCP<SmootherBase>>(
"PreSmoother", smootherFact.get());
1261template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1263 RCP<Teuchos::TimeMonitor> tmAlloc =
getTimer(
"Allocate MVs");
1266 if (!
R11_.is_null())
1267 P11res_ = MultiVectorFactory::Build(
R11_->getRangeMap(), numVectors);
1269 P11res_ = MultiVectorFactory::Build(
P11_->getDomainMap(), numVectors);
1270 P11res_->setObjectLabel(
"P11res");
1273 DTR11Tmp_ = MultiVectorFactory::Build(
R11_->getColMap(), numVectors);
1281 P11x_ = MultiVectorFactory::Build(
P11_->getDomainMap(), numVectors);
1282 P11x_->setObjectLabel(
"P11x");
1286 Dres_ = MultiVectorFactory::Build(
Dk_1_T_->getRangeMap(), numVectors);
1288 Dres_ = MultiVectorFactory::Build(
Dk_1_->getDomainMap(), numVectors);
1289 Dres_->setObjectLabel(
"Dres");
1293 DresTmp_->setObjectLabel(
"DresTmp");
1294 Dx_ = MultiVectorFactory::Build(
Importer22_->getTargetMap(), numVectors);
1296 Dx_ = MultiVectorFactory::Build(
A22_->getDomainMap(), numVectors);
1298 Dx_->setObjectLabel(
"Dx");
1313 if (!
A22_.is_null()) {
1327 if (!toCrsMatrix(
P11_)->getCrsGraph()->getImporter().is_null())
1329 if (!toCrsMatrix(
Dk_1_)->getCrsGraph()->getImporter().is_null())
1330 Dx_colmap_ = MultiVectorFactory::Build(
Dk_1_->getColMap(), numVectors);
1337template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1341 Xpetra::IO<SC, LO, GO, NO>::Write(name, *A);
1345template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1349 Xpetra::IO<SC, LO, GO, NO>::Write(name, *X);
1353template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1357 Xpetra::IO<coordinateType, LO, GO, NO>::Write(name, *X);
1361template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1365 std::ofstream out(name);
1366 for (
size_t i = 0; i < Teuchos::as<size_t>(v.size()); i++)
1367 out << v[i] <<
"\n";
1371template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1375 std::ofstream out(name);
1376 auto vH = Kokkos::create_mirror_view(v);
1377 Kokkos::deep_copy(vH, v);
1378 out <<
"%%MatrixMarket matrix array real general\n"
1379 << vH.extent(0) <<
" 1\n";
1380 for (
size_t i = 0; i < vH.size(); i++)
1381 out << vH[i] <<
"\n";
1385template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1389 return Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name)));
1391 if (comm.is_null()) {
1393 Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name +
"_barrier")));
1394 SM_Matrix_->getRowMap()->getComm()->barrier();
1396 return Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name)));
1399 Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name +
"_barrier")));
1402 return Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name)));
1406 return Teuchos::null;
1409template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1411 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1412 std::string spaceLabel;
1413 if (spaceNumber == 0)
1414 spaceLabel =
"nodal";
1415 else if (spaceNumber == 1)
1416 spaceLabel =
"edge";
1417 else if (spaceNumber == 2)
1418 spaceLabel =
"face";
1420 TEUCHOS_ASSERT(
false);
1421 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
1424 RCP<Teuchos::TimeMonitor> tm;
1425 if (spaceNumber > 0) {
1426 tm =
getTimer(
"nullspace " + spaceLabel);
1430 if (spaceNumber == 0) {
1431 return Teuchos::null;
1433 }
else if (spaceNumber == 1) {
1434 RCP<MultiVector> CoordsSC;
1436 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(
D0_->getRowMap(),
NodalCoords_->getNumVectors());
1437 D0_->apply(*CoordsSC, *Nullspace);
1444 ArrayRCP<ArrayRCP<const Scalar>> localNullspace(
dim_);
1445 for (
size_t i = 0; i <
dim_; i++)
1446 localNullspace[i] = Nullspace->getData(i);
1447 coordinateType localMinLen = Teuchos::ScalarTraits<coordinateType>::rmax();
1448 coordinateType localMeanLen = Teuchos::ScalarTraits<coordinateType>::zero();
1449 coordinateType localMaxLen = Teuchos::ScalarTraits<coordinateType>::zero();
1450 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1451 Scalar lenSC = Teuchos::ScalarTraits<Scalar>::zero();
1452 for (
size_t i = 0; i <
dim_; i++)
1453 lenSC += localNullspace[i][j] * localNullspace[i][j];
1454 coordinateType len = Teuchos::as<coordinateType>(Teuchos::ScalarTraits<Scalar>::real(Teuchos::ScalarTraits<Scalar>::squareroot(lenSC)));
1455 localMinLen = std::min(localMinLen, len);
1456 localMaxLen = std::max(localMaxLen, len);
1457 localMeanLen += len;
1460 RCP<const Teuchos::Comm<int>> comm = Nullspace->getMap()->getComm();
1464 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1468 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1475 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1477 Array<Scalar> normsSC(
NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1478 Nullspace->scale(normsSC());
1485 dump(Nullspace,
"nullspaceEdge.m");
1489 }
else if (spaceNumber == 2) {
1490#if KOKKOS_VERSION >= 40799
1491 using ATS = KokkosKernels::ArithTraits<Scalar>;
1493 using ATS = Kokkos::ArithTraits<Scalar>;
1495 using impl_Scalar =
typename ATS::val_type;
1496#if KOKKOS_VERSION >= 40799
1497 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1499 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1501 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1503 RCP<Matrix> facesToNodes;
1505 RCP<Matrix> edgesToNodes = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
D0_);
1510 RCP<Matrix> facesToEdges = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
Dk_1_);
1516 facesToNodes = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes,
GetOStream(
Runtime0),
true,
true);
1523 RCP<RealValuedMultiVector> ghostedNodalCoordinates;
1524 auto importer = facesToNodes->getCrsGraph()->getImporter();
1525 if (!importer.is_null()) {
1526 ghostedNodalCoordinates = Xpetra::MultiVectorFactory<coordinateType, LocalOrdinal, GlobalOrdinal, Node>::Build(importer->getTargetMap(),
dim_);
1527 ghostedNodalCoordinates->doImport(*
NodalCoords_, *importer, Xpetra::INSERT);
1531 RCP<MultiVector> Nullspace = Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(facesToNodes->getRangeMap(),
dim_);
1533 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1534 auto localNodalCoordinates = ghostedNodalCoordinates->getLocalViewDevice(Tpetra::Access::ReadOnly);
1535 auto localFaceNullspace = Nullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
1538 Kokkos::parallel_for(
1540 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1541 KOKKOS_LAMBDA(
const size_t f) {
1542 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1543 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1544 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1545 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1546 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1547 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1548 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1549 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1550 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1552 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1553 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1554 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1563 dump(Nullspace,
"nullspaceFace.m");
1568 TEUCHOS_ASSERT(
false);
1569 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
1573template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1574Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1576#if KOKKOS_VERSION >= 40799
1577 using ATS = KokkosKernels::ArithTraits<Scalar>;
1579 using ATS = Kokkos::ArithTraits<Scalar>;
1581 using impl_Scalar =
typename ATS::val_type;
1582#if KOKKOS_VERSION >= 40799
1583 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1585 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1587 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1589 typedef typename Matrix::local_matrix_device_type KCRS;
1590 typedef typename KCRS::StaticCrsGraphType graph_t;
1591 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1592 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1593 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1595 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1596 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1597 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1599 std::string spaceLabel;
1600 if (spaceNumber == 0)
1601 spaceLabel =
"nodal";
1602 else if (spaceNumber == 1)
1603 spaceLabel =
"edge";
1604 else if (spaceNumber == 2)
1605 spaceLabel =
"face";
1607 TEUCHOS_ASSERT(
false);
1609 RCP<Teuchos::TimeMonitor> tm;
1610 if (spaceNumber > 0) {
1611 tm =
getTimer(
"projection " + spaceLabel);
1615 RCP<Matrix> incidence;
1616 if (spaceNumber == 0) {
1618 return Teuchos::null;
1620 }
else if (spaceNumber == 1) {
1624 }
else if (spaceNumber == 2) {
1629 RCP<Matrix> facesToNodes;
1631 RCP<Matrix> edgesToNodes = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
D0_);
1634 dump(edgesToNodes,
"edgesToNodes.m");
1636 RCP<Matrix> facesToEdges = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
Dk_1_);
1640 dump(facesToEdges,
"facesToEdges.m");
1642 facesToNodes = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes,
GetOStream(
Runtime0),
true,
true);
1647 dump(facesToNodes,
"facesToNodes.m");
1649 incidence = facesToNodes;
1652 TEUCHOS_ASSERT(
false);
1657 RCP<const Map> rowMap = incidence->getRowMap();
1658 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1659 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1661 auto localIncidence = incidence->getLocalMatrixDevice();
1662 size_t numLocalRows = rowMap->getLocalNumElements();
1663 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1664 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1665 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1666 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1667 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1670 Kokkos::parallel_for(
1671 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1672 range_type(0, numLocalRows + 1),
1673 KOKKOS_LAMBDA(
const size_t i) {
1674 rowptr(i) = dim * localIncidence.graph.row_map(i);
1677 auto localNullspace = Nullspace->getLocalViewDevice(Tpetra::Access::ReadOnly);
1681 Kokkos::parallel_for(
1682 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1683 range_type(0, numLocalRows),
1684 KOKKOS_LAMBDA(
const size_t f) {
1685 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1686 for (
size_t k = 0; k < dim; k++) {
1687 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1688 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1689 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1691 vals(dim * jj + k) = impl_SC_ZERO;
1697 typename CrsMatrix::local_matrix_device_type lclProjection(
"local projection " + spaceLabel,
1698 numLocalRows, numLocalColumns, nnzEstimate,
1699 vals, rowptr, colind);
1700 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1701 rowMap, blockColMap,
1702 blockDomainMap, rowMap);
1707template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1709 Teuchos::RCP<Matrix> &P_nodal,
1710 Teuchos::RCP<MultiVector> &Nullspace_nodal,
1711 Teuchos::RCP<RealValuedMultiVector> &CoarseCoords_nodal)
const {
1712 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"nodal prolongator");
1718 const SC SC_ONE = Teuchos::ScalarTraits<SC>::one();
1721 Level fineLevel, coarseLevel;
1727 fineLevel.
Set(
"A", A_nodal);
1729 fineLevel.
Set(
"DofsPerNode", 1);
1730 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1731 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1732 coarseLevel.setObjectLabel(A_nodal->getObjectLabel());
1733 fineLevel.setObjectLabel(A_nodal->getObjectLabel());
1736 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1737 nullSpace->putScalar(SC_ONE);
1738 fineLevel.
Set(
"Nullspace", nullSpace);
1740 std::string algo =
parameterList_.get<std::string>(
"multigrid algorithm");
1742 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1756 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1758 double dropTol =
parameterList_.get<
double>(
"aggregation: drop tol");
1759 std::string dropScheme =
parameterList_.get<std::string>(
"aggregation: drop scheme");
1760 std::string distLaplAlgo =
parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1761 dropFact->SetParameter(
"aggregation: drop tol", Teuchos::ParameterEntry(dropTol));
1762 dropFact->SetParameter(
"aggregation: drop scheme", Teuchos::ParameterEntry(dropScheme));
1763 dropFact->SetParameter(
"aggregation: distance laplacian algo", Teuchos::ParameterEntry(distLaplAlgo));
1765 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1766 int minAggSize =
parameterList_.get<
int>(
"aggregation: min agg size");
1767 UncoupledAggFact->SetParameter(
"aggregation: min agg size", Teuchos::ParameterEntry(minAggSize));
1768 int maxAggSize =
parameterList_.get<
int>(
"aggregation: max agg size");
1769 UncoupledAggFact->SetParameter(
"aggregation: max agg size", Teuchos::ParameterEntry(maxAggSize));
1770 bool matchMLbehavior1 =
parameterList_.get<
bool>(
"aggregation: match ML phase1");
1771 UncoupledAggFact->SetParameter(
"aggregation: match ML phase1", Teuchos::ParameterEntry(matchMLbehavior1));
1772 bool matchMLbehavior2a =
parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1773 UncoupledAggFact->SetParameter(
"aggregation: match ML phase2a", Teuchos::ParameterEntry(matchMLbehavior2a));
1774 bool matchMLbehavior2b =
parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1775 UncoupledAggFact->SetParameter(
"aggregation: match ML phase2b", Teuchos::ParameterEntry(matchMLbehavior2b));
1777 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1779 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1780 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1781 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1783 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1784 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1787 SaPFact->SetFactory(
"P", TentativePFact);
1788 coarseLevel.
Request(
"P", SaPFact.get());
1790 coarseLevel.
Request(
"P", TentativePFact.get());
1791 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1792 coarseLevel.
Request(
"Coordinates", Tfact.get());
1794 RCP<AggregationExportFactory> aggExport;
1795 bool exportVizData =
parameterList_.get<
bool>(
"aggregation: export visualization data");
1796 if (exportVizData) {
1798 ParameterList aggExportParams;
1799 aggExportParams.set(
"aggregation: output filename",
"aggs.vtk");
1800 aggExportParams.set(
"aggregation: output file: agg style",
"Jacks");
1801 aggExport->SetParameterList(aggExportParams);
1803 aggExport->SetFactory(
"Aggregates", UncoupledAggFact);
1804 aggExport->SetFactory(
"UnAmalgamationInfo", amalgFact);
1805 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1806 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1810 coarseLevel.
Get(
"P", P_nodal, SaPFact.get());
1812 coarseLevel.
Get(
"P", P_nodal, TentativePFact.get());
1813 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.get());
1814 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.get());
1817 aggExport->Build(fineLevel, coarseLevel);
1821template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1822Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1824 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"vectorial nodal prolongator");
1827 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1829 typedef typename Matrix::local_matrix_device_type KCRS;
1830 typedef typename KCRS::StaticCrsGraphType graph_t;
1831 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1832 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1833 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1838 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1839 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1840 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1843 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1845 size_t numLocalRows = blockRowMap->getLocalNumElements();
1846 size_t numLocalColumns = blockColMap->getLocalNumElements();
1847 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1848 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1849 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1850 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1853 Kokkos::parallel_for(
1854 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1855 range_type(0, localP_nodal.numRows() + 1),
1857 if (i < localP_nodal.numRows()) {
1858 for (
size_t k = 0; k < dim; k++) {
1859 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1862 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1866 Kokkos::parallel_for(
1867 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1868 range_type(0, localP_nodal.graph.entries.size()),
1869 KOKKOS_LAMBDA(
const size_t jj) {
1870 for (
size_t k = 0; k < dim; k++) {
1871 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1873 vals(dim * jj + k) = 1.;
1877 typename CrsMatrix::local_matrix_device_type lclVectorNodalP(
"local vector nodal prolongator",
1878 numLocalRows, numLocalColumns, nnzEstimate,
1879 vals, rowptr, colind);
1880 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1881 blockRowMap, blockColMap,
1882 blockDomainMap, blockRowMap);
1884 return vectorNodalP;
1887template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1890 const Teuchos::RCP<Matrix> &A_nodal,
1891 const Teuchos::RCP<MultiVector> &Nullspace,
1892 Teuchos::RCP<Matrix> &Prolongator,
1893 Teuchos::RCP<MultiVector> &coarseNullspace,
1894 Teuchos::RCP<RealValuedMultiVector> &coarseNodalCoords)
const {
1895#if KOKKOS_VERSION >= 40799
1896 using ATS = KokkosKernels::ArithTraits<Scalar>;
1898 using ATS = Kokkos::ArithTraits<Scalar>;
1900 using impl_Scalar =
typename ATS::val_type;
1901 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1903 std::string typeStr;
1904 switch (spaceNumber) {
1907 TEUCHOS_ASSERT(A_nodal.is_null());
1916 TEUCHOS_ASSERT(
false);
1919 const bool skipFirstLevel = !A_nodal.is_null();
1921 RCP<Teuchos::TimeMonitor> tm;
1922 if (spaceNumber > 0) {
1923 tm =
getTimer(
"special prolongator " + typeStr);
1928 dump(projection, typeStr +
"Projection.m");
1930 if (skipFirstLevel) {
1931 RCP<Matrix> P_nodal;
1932 RCP<MultiVector> coarseNodalNullspace;
1936 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1937 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1941 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1943 Prolongator = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator,
GetOStream(
Runtime0),
true,
true);
1992 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
1994 auto localNullspace_nodal = coarseNodalNullspace->getLocalViewDevice(Tpetra::Access::ReadOnly);
1995 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
1996 Kokkos::parallel_for(
1997 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1998 range_type(0, coarseNodalNullspace->getLocalLength()),
1999 KOKKOS_LAMBDA(
const size_t i) {
2000 impl_Scalar val = localNullspace_nodal(i, 0);
2001 for (
size_t j = 0; j < dim; j++)
2002 localNullspace_coarse(dim * i + j, j) = val;
2006 Prolongator = projection;
2009 if (spaceNumber == 0) {
2011 }
else if (spaceNumber >= 1) {
2013 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
2014 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
2015 Kokkos::parallel_for(
2016 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2017 range_type(0, coarseNullspace->getLocalLength() / dim),
2018 KOKKOS_LAMBDA(
const size_t i) {
2019 for (
size_t j = 0; j < dim; j++)
2020 localNullspace_coarse(dim * i + j, j) = 1.0;
2026template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2028 Teuchos::RCP<Operator> &thyraPrecOp,
2029 const Teuchos::RCP<Matrix> &A,
2030 const Teuchos::RCP<MultiVector> &Nullspace,
2031 const Teuchos::RCP<RealValuedMultiVector> &Coords,
2032 const Teuchos::RCP<MultiVector> &Material,
2033 Teuchos::ParameterList ¶ms,
2036 const bool isSingular) {
2039 RCP<ParameterList> pl = rcp(
new ParameterList());
2040 pl->set(
"printLoadBalancingInfo",
true);
2041 pl->set(
"printCommInfo",
true);
2044#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2045 if (params.isType<std::string>(
"Preconditioner Type")) {
2046 TEUCHOS_ASSERT(!reuse);
2048 if (params.get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2049 ParameterList &userParamList = params.sublist(
"Preconditioner Types").sublist(
"MueLu").sublist(
"user data");
2050 if (!Nullspace.is_null())
2051 userParamList.set<RCP<MultiVector>>(
"Nullspace", Nullspace);
2052 if (!Material.is_null())
2053 userParamList.set<RCP<MultiVector>>(
"Material", Material);
2054 userParamList.set<RCP<RealValuedMultiVector>>(
"Coordinates", Coords);
2056 thyraPrecOp = rcp(
new XpetraThyraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(
coarseA11_, rcp(¶ms,
false)));
2063 ParameterList &userParamList = params.sublist(
"user data");
2064 if (!Coords.is_null())
2065 userParamList.set<RCP<RealValuedMultiVector>>(
"Coordinates", Coords);
2066 if (!Nullspace.is_null())
2067 userParamList.set<RCP<MultiVector>>(
"Nullspace", Nullspace);
2068 if (!Material.is_null())
2069 userParamList.set<RCP<MultiVector>>(
"Material", Material);
2072 std::string coarseType =
"";
2073 if (params.isParameter(
"coarse: type")) {
2074 coarseType = params.get<std::string>(
"coarse: type");
2076 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(), ::tolower);
2077 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
2079 if ((coarseType ==
"" ||
2080 coarseType ==
"Klu" ||
2081 coarseType ==
"Klu2" ||
2082 coarseType ==
"Superlu" ||
2083 coarseType ==
"Superlu_dist" ||
2084 coarseType ==
"Superludist" ||
2085 coarseType ==
"Basker" ||
2086 coarseType ==
"Cusolver" ||
2087 coarseType ==
"Tacho") &&
2088 (!params.isSublist(
"coarse: params") ||
2089 !params.sublist(
"coarse: params").isParameter(
"fix nullspace")))
2090 params.sublist(
"coarse: params").set(
"fix nullspace",
true);
2095 RCP<MueLu::Level> level0 = hierarchy->GetLevel(0);
2096 level0->Set(
"A", A);
2097 hierarchy->SetupRe();
2103template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2112template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2148 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
2152 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"residual calculation");
2160 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"restriction coarse (1,1) (implicit)");
2164 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restriction (2,2) (implicit)");
2171 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restrictions import");
2175 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restriction (2,2) (explicit)");
2179 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"restriction coarse (1,1) (explicit)");
2184 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"restriction coarse (1,1) (explicit)");
2188 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restriction (2,2) (explicit)");
2196 RCP<Teuchos::TimeMonitor> tmSubSolves =
getTimer(
"subsolves");
2201 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"import coarse (1,1)");
2205 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"import (2,2)");
2214 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"solve coarse (1,1)",
coarseA11_->getRowMap()->getComm());
2216#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2218 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
2226 if (!
A22_.is_null()) {
2230 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"solve (2,2)",
A22_->getRowMap()->getComm());
2231#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2233 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
2247 RCP<Teuchos::TimeMonitor> tmProlongations =
getTimer(
"prolongations");
2250 using Tpetra_Multivector = Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
2251 using Tpetra_Import = Tpetra::Import<LocalOrdinal, GlobalOrdinal, Node>;
2253 auto tpP11 = toTpetra(
P11_);
2254 auto tpDk_1 = toTpetra(
Dk_1_);
2256 RCP<Tpetra_Multivector> tpP11x = toTpetra(
P11x_);
2257 RCP<Tpetra_Multivector> tpP11x_colmap;
2258 RCP<Tpetra_Multivector> tpX = toTpetra(Teuchos::rcpFromRef(X));
2259 RCP<Tpetra_Multivector> tpResidual = toTpetra(
residual_);
2260 RCP<Tpetra_Multivector> tpDx = toTpetra(
Dx_);
2261 RCP<Tpetra_Multivector> tpDx_colmap;
2263 unsigned completedImports = 0;
2264 std::vector<bool> completedImport(2,
false);
2265 auto tpP11importer = tpP11->getCrsGraph()->getImporter();
2266 if (!tpP11importer.is_null()) {
2268 tpP11x_colmap->beginImport(*tpP11x, *tpP11importer, Tpetra::INSERT);
2271 RCP<const Tpetra_Import> tpDk_1importer;
2273 tpDk_1importer = tpDk_1->getCrsGraph()->getImporter();
2274 if (!tpDk_1importer.is_null()) {
2276 tpDx_colmap->beginImport(*tpDx, *tpDk_1importer, Tpetra::INSERT);
2279 completedImport[1] =
true;
2284 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
2285 tpResidual->putScalar(zero);
2288 while (completedImports < completedImport.size()) {
2289 for (
unsigned i = 0; i < completedImport.size(); i++) {
2290 if (completedImport[i])
continue;
2293 if (!tpP11importer.is_null()) {
2294 if (tpP11x_colmap->transferArrived()) {
2295 tpP11x_colmap->endImport(*tpP11x, *tpP11importer, Tpetra::INSERT);
2296 completedImport[i] =
true;
2300 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (fused, local)");
2301 tpP11->localApply(*tpP11x_colmap, *tpX, Teuchos::NO_TRANS, one, one);
2303 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (unfused, local)");
2304 tpP11->localApply(*tpP11x_colmap, *tpResidual, Teuchos::NO_TRANS, one, one);
2308 completedImport[i] =
true;
2312 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (fused, local)");
2313 tpP11->localApply(*tpP11x, *tpX, Teuchos::NO_TRANS, one, one);
2315 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (unfused, local)");
2316 tpP11->localApply(*tpP11x, *tpResidual, Teuchos::NO_TRANS, one, one);
2320 if (!tpDk_1importer.is_null()) {
2321 if (tpDx_colmap->transferArrived()) {
2322 tpDx_colmap->endImport(*tpDx, *tpDk_1importer, Tpetra::INSERT);
2323 completedImport[i] =
true;
2327 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (fused, local)");
2328 tpDk_1->localApply(*tpDx_colmap, *tpX, Teuchos::NO_TRANS, one, one);
2330 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (unfused, local)");
2331 tpDk_1->localApply(*tpDx_colmap, *tpResidual, Teuchos::NO_TRANS, one, one);
2335 completedImport[i] =
true;
2339 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (fused, local)");
2340 tpDk_1->localApply(*tpDx, *tpX, Teuchos::NO_TRANS, one, one);
2342 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (unfused, local)");
2343 tpDk_1->localApply(*tpDx, *tpResidual, Teuchos::NO_TRANS, one, one);
2351 RCP<Teuchos::TimeMonitor> tmUpdate =
getTimer(
"update");
2357 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (fused)");
2358 P11_->apply(*
P11x_, X, Teuchos::NO_TRANS, one, one);
2362 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (fused)");
2363 Dk_1_->apply(*
Dx_, X, Teuchos::NO_TRANS, one, one);
2367 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (unfused)");
2372 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (unfused)");
2377 RCP<Teuchos::TimeMonitor> tmUpdate =
getTimer(
"update");
2385template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2387 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
2390 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"residual calculation");
2400 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"import coarse (1,1)");
2404 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"solve coarse (1,1)",
coarseA11_->getRowMap()->getComm());
2410 RCP<Teuchos::TimeMonitor> tmUp =
getTimer(
"update");
2416template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2421 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
2424 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"residual calculation");
2434 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"import (2,2)");
2437 if (!
A22_.is_null()) {
2438 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"solve (2,2)",
A22_->getRowMap()->getComm());
2444 RCP<Teuchos::TimeMonitor> tmUp =
getTimer(
"update");
2450template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2455 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"solve");
2463 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2469 if (
mode_ ==
"additive")
2471 else if (
mode_ ==
"121") {
2475 }
else if (
mode_ ==
"212") {
2479 }
else if (
mode_ ==
"1")
2481 else if (
mode_ ==
"2")
2483 else if (
mode_ ==
"7") {
2487 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2494 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2499 }
else if (
mode_ ==
"none") {
2506 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2512template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2517template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2519 RefMaxwell(
const Teuchos::RCP<Matrix> &SM_Matrix,
2520 Teuchos::ParameterList &List,
2522 int spaceNumber = List.get<
int>(
"refmaxwell: space number", 1);
2524 RCP<Matrix> Dk_1, Dk_2, D0;
2525 RCP<Matrix> M1_beta, M1_alpha;
2526 RCP<Matrix> Mk_one, Mk_1_one;
2527 RCP<Matrix> invMk_1_invBeta, invMk_2_invAlpha;
2528 RCP<MultiVector> Nullspace11, Nullspace22;
2529 RCP<RealValuedMultiVector> NodalCoords;
2531 Dk_1 =
pop(List,
"Dk_1", Dk_1);
2541 invMk_1_invBeta =
pop<RCP<Matrix>>(List,
"invMk_1_invBeta", invMk_1_invBeta);
2542 invMk_2_invAlpha =
pop<RCP<Matrix>>(List,
"invMk_2_invAlpha", invMk_2_invAlpha);
2549 if (List.isType<RCP<Matrix>>(
"Ms")) {
2550 if (M1_beta.is_null())
2553 TEUCHOS_ASSERT(
false);
2555 if (List.isType<RCP<Matrix>>(
"M1")) {
2556 if (Mk_one.is_null())
2559 TEUCHOS_ASSERT(
false);
2561 if (List.isType<RCP<Matrix>>(
"M0inv")) {
2562 if (invMk_1_invBeta.is_null())
2565 TEUCHOS_ASSERT(
false);
2567 if (List.isType<RCP<MultiVector>>(
"Nullspace")) {
2568 if (Nullspace11.is_null())
2571 TEUCHOS_ASSERT(
false);
2574 if (spaceNumber == 1) {
2577 else if (D0.is_null())
2579 if (M1_beta.is_null())
2581 }
else if (spaceNumber == 2) {
2584 else if (D0.is_null())
2592 invMk_1_invBeta, invMk_2_invAlpha,
2593 Nullspace11, Nullspace22,
2595 Teuchos::null, Teuchos::null,
2598 if (SM_Matrix != Teuchos::null)
2602template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2604 initialize(
const Teuchos::RCP<Matrix> &D0_Matrix,
2605 const Teuchos::RCP<Matrix> &Ms_Matrix,
2606 const Teuchos::RCP<Matrix> &M0inv_Matrix,
2607 const Teuchos::RCP<Matrix> &M1_Matrix,
2608 const Teuchos::RCP<MultiVector> &Nullspace11,
2609 const Teuchos::RCP<RealValuedMultiVector> &NodalCoords,
2610 const Teuchos::RCP<MultiVector> &Material,
2611 Teuchos::ParameterList &List) {
2613 D0_Matrix, Teuchos::null, D0_Matrix,
2614 Ms_Matrix, Teuchos::null,
2615 M1_Matrix, Teuchos::null,
2616 M0inv_Matrix, Teuchos::null,
2617 Nullspace11, Teuchos::null,
2619 Teuchos::null, Material,
2623template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2626 const Teuchos::RCP<Matrix> &Dk_1,
2627 const Teuchos::RCP<Matrix> &Dk_2,
2628 const Teuchos::RCP<Matrix> &D0,
2629 const Teuchos::RCP<Matrix> &M1_beta,
2630 const Teuchos::RCP<Matrix> &M1_alpha,
2631 const Teuchos::RCP<Matrix> &Mk_one,
2632 const Teuchos::RCP<Matrix> &Mk_1_one,
2633 const Teuchos::RCP<Matrix> &invMk_1_invBeta,
2634 const Teuchos::RCP<Matrix> &invMk_2_invAlpha,
2635 const Teuchos::RCP<MultiVector> &Nullspace11,
2636 const Teuchos::RCP<MultiVector> &Nullspace22,
2637 const Teuchos::RCP<RealValuedMultiVector> &NodalCoords,
2638 const Teuchos::RCP<MultiVector> &Material_beta,
2639 const Teuchos::RCP<MultiVector> &Material_alpha,
2640 Teuchos::ParameterList &List) {
2647 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
2648 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2661 TEUCHOS_ASSERT((k == 1) || (k == 2));
2663 TEUCHOS_ASSERT(Dk_1 != Teuchos::null);
2665 TEUCHOS_ASSERT(D0 != Teuchos::null);
2668 TEUCHOS_ASSERT(M1_beta != Teuchos::null);
2671 TEUCHOS_ASSERT(M1_alpha != Teuchos::null);
2675 TEUCHOS_ASSERT(Mk_one != Teuchos::null);
2676 TEUCHOS_ASSERT(invMk_1_invBeta != Teuchos::null);
2681 TEUCHOS_ASSERT(Dk_2 != Teuchos::null);
2682 TEUCHOS_ASSERT(Mk_1_one != Teuchos::null);
2683 TEUCHOS_ASSERT(invMk_2_invAlpha != Teuchos::null);
2686#ifdef HAVE_MUELU_DEBUG
2688 TEUCHOS_ASSERT(D0->getRangeMap()->isSameAs(*D0->getRowMap()));
2691 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2692 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2695 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2699 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2700 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2703 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()))
2708 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2709 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2712 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2715 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2716 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2719 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2724 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2725 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2728 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2731 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2734 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2735 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2738 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2743 if (Dk_1->getRowMap()->lib() == Xpetra::UseTpetra) {
2748 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2749 RCP<CrsMatrix> Dk_1copyCrs = toCrsMatrix(Dk_1copy);
2750 ArrayRCP<const size_t> Dk_1rowptr_RCP;
2751 ArrayRCP<const LO> Dk_1colind_RCP;
2752 ArrayRCP<const SC> Dk_1vals_RCP;
2753 toCrsMatrix(Dk_1)->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2755 ArrayRCP<size_t> Dk_1copyrowptr_RCP;
2756 ArrayRCP<LO> Dk_1copycolind_RCP;
2757 ArrayRCP<SC> Dk_1copyvals_RCP;
2758 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2759 Dk_1copyrowptr_RCP.deepCopy(Dk_1rowptr_RCP());
2760 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2761 Dk_1copyvals_RCP.deepCopy(Dk_1vals_RCP());
2762 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2765 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2766 toCrsMatrix(Dk_1)->getCrsGraph()->getImporter(),
2767 toCrsMatrix(Dk_1)->getCrsGraph()->getExporter());
2770 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2772 if ((!Dk_2.is_null()) && (Dk_2->getRowMap()->lib() == Xpetra::UseTpetra)) {
2777 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2778 RCP<CrsMatrix> Dk_2copyCrs = toCrsMatrix(Dk_2copy);
2779 ArrayRCP<const size_t> Dk_2rowptr_RCP;
2780 ArrayRCP<const LO> Dk_2colind_RCP;
2781 ArrayRCP<const SC> Dk_2vals_RCP;
2782 toCrsMatrix(Dk_2)->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2784 ArrayRCP<size_t> Dk_2copyrowptr_RCP;
2785 ArrayRCP<LO> Dk_2copycolind_RCP;
2786 ArrayRCP<SC> Dk_2copyvals_RCP;
2787 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2788 Dk_2copyrowptr_RCP.deepCopy(Dk_2rowptr_RCP());
2789 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2790 Dk_2copyvals_RCP.deepCopy(Dk_2vals_RCP());
2791 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2794 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2795 toCrsMatrix(Dk_2)->getCrsGraph()->getImporter(),
2796 toCrsMatrix(Dk_2)->getCrsGraph()->getExporter());
2798 }
else if (!Dk_2.is_null())
2799 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2833template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2835 describe(Teuchos::FancyOStream &out,
const Teuchos::EVerbosityLevel )
const {
2836 std::ostringstream oss;
2838 RCP<const Teuchos::Comm<int>> comm =
SM_Matrix_->getDomainMap()->getComm();
2843 root = comm->getRank();
2848 reduceAll(*comm, Teuchos::REDUCE_MAX, root, Teuchos::ptr(&actualRoot));
2852 oss <<
"\n--------------------------------------------------------------------------------\n"
2855 "--------------------------------------------------------------------------------"
2862 SM_Matrix_->getRowMap()->getComm()->barrier();
2867 Xpetra::global_size_t tt = numRows;
2880 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2881 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2883 if (!
A22_.is_null()) {
2884 numRows =
A22_->getGlobalNumRows();
2885 nnz =
A22_->getGlobalNumEntries();
2887 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2894 oss <<
"Smoother 11 both : " <<
PreSmoother11_->description() << std::endl;
2896 oss <<
"Smoother 11 pre : "
2898 oss <<
"Smoother 11 post : "
2904 std::string outstr = oss.str();
2907 RCP<const Teuchos::MpiComm<int>> mpiComm = rcp_dynamic_cast<const Teuchos::MpiComm<int>>(comm);
2908 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2910 int strLength = outstr.size();
2911 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2912 if (comm->getRank() != root)
2913 outstr.resize(strLength);
2914 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2927 std::ostringstream oss2;
2929 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2930 oss2 <<
"( (1,1) block only is indicated by '1', (2,2) block only by '2', and both blocks by 'B' and none by '.')" << std::endl;
2932 int numProcs = comm->getSize();
2934 RCP<const Teuchos::MpiComm<int>> tmpic = rcp_dynamic_cast<const Teuchos::MpiComm<int>>(comm);
2935 TEUCHOS_TEST_FOR_EXCEPTION(tmpic == Teuchos::null,
Exceptions::RuntimeError,
"Cannot cast base Teuchos::Comm to Teuchos::MpiComm object.");
2936 RCP<const Teuchos::OpaqueWrapper<MPI_Comm>> rawMpiComm = tmpic->getRawMpiComm();
2942 if (!
A22_.is_null())
2944 std::vector<char> states(numProcs, 0);
2946 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2948 states.push_back(status);
2951 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2952 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2953 for (
int j = 0; j < rowWidth; j++)
2954 if (proc + j < numProcs)
2955 if (states[proc + j] == 0)
2957 else if (states[proc + j] == 1)
2959 else if (states[proc + j] == 2)
2966 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2975#define MUELU_REFMAXWELL_SHORT
Various adapters that will create a MueLu preconditioner that is an Xpetra::Matrix.
#define MueLu_maxAll(rcpComm, in, out)
#define MueLu_sumAll(rcpComm, in, out)
#define MueLu_minAll(rcpComm, in, out)
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Factory to export aggregation info or visualize aggregates using VTK.
AmalgamationFactory for subblocks of strided map based amalgamation data.
Factory for creating a graph based on a given matrix.
Factory for creating a graph based on a given matrix.
Factory for generating coarse level map. Used by TentativePFactory.
Class for transferring coordinates from a finer level to a coarser one.
Exception throws to report errors in the internal logical of the program.
This class specifies the default factory that should generate some data on a Level if the data does n...
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void setlib(Xpetra::UnderlyingLib lib2)
void SetLevelID(int levelID)
Set level number.
void AddKeepFlag(const std::string &ename, const FactoryBase *factory=NoFactory::get(), KeepType keep=MueLu::Keep)
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
void Request(const FactoryBase &factory)
Increment the storage counter for all the inputs of a factory.
void SetPreviousLevel(const RCP< Level > &previousLevel)
void SetFactoryManager(const RCP< const FactoryManagerBase > &factoryManager)
Set default factories (used internally by Hierarchy::SetLevel()).
static std::string translate(Teuchos::ParameterList ¶mList, const std::string &defaultVals="")
: Translate ML parameters to MueLu parameter XML string
static const T & getDefault(const std::string &name)
Returns default value on the "master" list for a parameter with the specified name and type.
static void detectBoundaryConditionsSM(RCP< Matrix > &SM_Matrix, RCP< Matrix > &D0_Matrix, magnitudeType rowSumTol, bool useKokkos_, Kokkos::View< bool *, typename Node::device_type::memory_space > &BCrowsKokkos, Kokkos::View< bool *, typename Node::device_type::memory_space > &BCcolsKokkos, Kokkos::View< bool *, typename Node::device_type::memory_space > &BCdomainKokkos, int &BCedges, int &BCnodes, Teuchos::ArrayRCP< bool > &BCrows, Teuchos::ArrayRCP< bool > &BCcols, Teuchos::ArrayRCP< bool > &BCdomain, bool &allEdgesBoundary, bool &allNodesBoundary)
Detect Dirichlet boundary conditions.
static void thresholdedAbs(const RCP< Matrix > &A, const magnitudeType thresholded)
static RCP< Matrix > removeExplicitZeros(const RCP< Matrix > &A, const magnitudeType tolerance, const bool keepDiagonal=true, const size_t expectedNNZperRow=0)
Remove explicit zeros.
static void setMatvecParams(Matrix &A, RCP< ParameterList > matvecParams)
Sets matvec params on a matrix.
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > PtAPWrapper(const RCP< Matrix > &A, const RCP< Matrix > &P, Teuchos::ParameterList ¶ms, const std::string &label)
Performs an P^T AP.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
Factory for building coarse matrices.
Factory for building coarse matrices.
Applies permutation to grid transfer operators.
Teuchos::RCP< MultiVector > P11resTmp_
Teuchos::RCP< Matrix > Mk_1_one_
Teuchos::RCP< RealValuedMultiVector > NodalCoords_
Coordinates.
Teuchos::RCP< MultiVector > Material_beta_
material for first space
Teuchos::RCP< MultiVector > P11x_
Teuchos::RCP< MultiVector > Nullspace22_
Teuchos::RCP< MultiVector > residual_
Teuchos::RCP< Matrix > M1_beta_
mass matrices on first space with weights beta and alpha respectively
Teuchos::RCP< MultiVector > Dx_colmap_
Teuchos::RCP< Teuchos::ParameterList > coarseA11_AP_reuse_data_
Kokkos::View< bool *, typename Node::device_type::memory_space > BCrows11_
Vectors for BCs.
void setupSubSolve(Teuchos::RCP< Hierarchy > &hierarchy, Teuchos::RCP< Operator > &thyraPrecOp, const Teuchos::RCP< Matrix > &A, const Teuchos::RCP< MultiVector > &Nullspace, const Teuchos::RCP< RealValuedMultiVector > &Coords, const Teuchos::RCP< MultiVector > &Material, Teuchos::ParameterList ¶ms, std::string &label, const bool reuse, const bool isSingular=false)
Setup a subsolve.
int globalNumberBoundaryUnknowns22_
Teuchos::RCP< Teuchos::ParameterList > A22_AP_reuse_data_
Teuchos::RCP< Matrix > coarseA22_
Teuchos::RCP< MultiVector > P11res_
Temporary memory.
Teuchos::RCP< Matrix > coarseA11_
coarse 11, 22 and coarse 22 blocks
Teuchos::RCP< Matrix > Mk_one_
mass matrices with unit weight on k-th and (k-1)-th spaces
Teuchos::RCP< Matrix > Dk_1_T_
Teuchos::RCP< Teuchos::TimeMonitor > getTimer(std::string name, RCP< const Teuchos::Comm< int > > comm=Teuchos::null) const
get a (synced) timer
void allocateMemory(int numVectors) const
allocate multivectors for solve
RCP< Matrix > buildVectorNodalProlongator(const Teuchos::RCP< Matrix > &P_nodal) const
Teuchos::RCP< const Map > DorigDomainMap_
Teuchos::RCP< Matrix > SM_Matrix_
The system that is getting preconditioned.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_HIGH) const
Teuchos::RCP< Matrix > invMk_1_invBeta_
inverse of mass matrices on (k-1)-th and (k-2)-th space with weights 1/beta and 1/alpha respectively
Kokkos::View< bool *, typename Node::device_type::memory_space > BCcols22_
void build22Matrix(const bool reuse, const bool doRebalancing, const int rebalanceStriding, const int numProcsA22)
Setup A22 = D0^T SM D0 and rebalance it, as well as D0 and Coords_.
void buildCoarse11Matrix()
Compute coarseA11 = P11^{T}*SM*P11 + addon efficiently.
void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Teuchos::RCP< SmootherPrototype > PostSmootherData11_
Teuchos::RCP< Teuchos::ParameterList > A22_RAP_reuse_data_
RCP< MultiVector > buildNullspace(const int spaceNumber, const Kokkos::View< bool *, typename Node::device_type > &bcs, const bool applyBCs)
Builds a nullspace.
bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
void determineSubHierarchyCommSizes(bool &doRebalancing, int &rebalanceStriding, int &numProcsCoarseA11, int &numProcsA22)
Determine how large the sub-communicators for the two hierarchies should be.
Teuchos::RCP< RealValuedMultiVector > Coords22_
bool disable_addon_
Some options.
Kokkos::View< bool *, typename Node::device_type::memory_space > BCdomain22_
void solveH(const MultiVector &RHS, MultiVector &X) const
apply solve to 1-1 block only
Teuchos::ParameterList precList22_
Teuchos::RCP< Matrix > A22_
typename Teuchos::ScalarTraits< Scalar >::coordinateType coordinateType
Teuchos::RCP< SmootherBase > PostSmoother11_
Teuchos::RCP< MultiVector > NullspaceCoarse11_
Nullspace for coarse (1,1) problem.
Teuchos::RCP< Matrix > Dk_2_
D_{k-2} matrix.
void setFineLevelSmoother11()
Set the fine level smoother.
Teuchos::RCP< Matrix > R11_
std::string solverName_
The name of the solver.
void dumpCoords(const RCP< RealValuedMultiVector > &X, std::string name) const
dump out real-valued multivector
Teuchos::RCP< Matrix > D0_
D_0 matrix.
Teuchos::RCP< const Import > Importer22_
const Teuchos::RCP< const Map > getDomainMap() const
Returns the Xpetra::Map object associated with the domain of this operator.
Teuchos::RCP< MultiVector > Dx_
Teuchos::RCP< Matrix > M1_alpha_
Teuchos::RCP< Matrix > P11_
special prolongator for 11 block and its transpose
Teuchos::RCP< MultiVector > DresTmp_
bool use_as_preconditioner_
Teuchos::RCP< MultiVector > P11resSubComm_
Teuchos::RCP< MultiVector > P11xSubComm_
Teuchos::RCP< Hierarchy > Hierarchy22_
Teuchos::RCP< Teuchos::ParameterList > getValidParamterList()
Teuchos::RCP< Matrix > P22_
special prolongator for 22 block and its transpose
Teuchos::RCP< Hierarchy > HierarchyCoarse11_
Two hierarchies: one for the coarse (1,1)-block, another for the (2,2)-block.
Teuchos::RCP< MultiVector > CoarseNullspace22_
Nullspace for coarse (2,2) problem.
Teuchos::RCP< MultiVector > DTR11Tmp_
Teuchos::RCP< SmootherPrototype > PreSmootherData11_
int spaceNumber_
The number of the space in the deRham complex.
Teuchos::RCP< MultiVector > Dres_
void applyInverseAdditive(const MultiVector &RHS, MultiVector &X) const
apply additive algorithm for 2x2 solve
bool fuseProlongationAndUpdate_
RCP< Operator > thyraPrecOpH_
int globalNumberBoundaryUnknowns11_
Teuchos::RCP< RealValuedMultiVector > CoordsCoarse11_
Teuchos::RCP< const Import > DorigImporter_
bool Dk_1_T_R11_colMapsMatch_
void buildProlongator(const int spaceNumber, const Teuchos::RCP< Matrix > &A_nodal_Matrix, const RCP< MultiVector > &EdgeNullspace, Teuchos::RCP< Matrix > &edgeProlongator, Teuchos::RCP< MultiVector > &coarseEdgeNullspace, Teuchos::RCP< RealValuedMultiVector > &coarseNodalCoords) const
const Teuchos::RCP< const Map > getRangeMap() const
Returns the Xpetra::Map object associated with the range of this operator.
void compute(bool reuse=false)
Setup the preconditioner.
Teuchos::ParameterList precList11_
Teuchos::RCP< Matrix > Dk_1_
D_{k-1} matrix and its transpose.
Teuchos::RCP< Teuchos::ParameterList > coarseA11_RAP_reuse_data_
void initialize(const Teuchos::RCP< Matrix > &D0_Matrix, const Teuchos::RCP< Matrix > &Ms_Matrix, const Teuchos::RCP< Matrix > &M0inv_Matrix, const Teuchos::RCP< Matrix > &M1_Matrix, const Teuchos::RCP< MultiVector > &Nullspace11, const Teuchos::RCP< RealValuedMultiVector > &NodalCoords, const Teuchos::RCP< MultiVector > &Material, Teuchos::ParameterList &List)
void buildNodalProlongator(const Teuchos::RCP< Matrix > &A_nodal, Teuchos::RCP< Matrix > &P_nodal, Teuchos::RCP< MultiVector > &Nullspace_nodal, Teuchos::RCP< RealValuedMultiVector > &Coords_nodal) const
Teuchos::RCP< Matrix > Addon11_
the addon for the 11 block
Teuchos::RCP< Matrix > buildProjection(const int spaceNumber, const RCP< MultiVector > &EdgeNullspace) const
Builds a projection from a vector values space into a vector valued nodal space.
Teuchos::ParameterList parameterList_
Parameter lists.
void dump(const RCP< Matrix > &A, std::string name) const
dump out matrix
void rebalanceCoarse11Matrix(const int rebalanceStriding, const int numProcsCoarseA11)
rebalance the coarse A11 matrix, as well as P11, CoordsCoarse11 and Addon11
Teuchos::RCP< MultiVector > Nullspace11_
Nullspace for (1.1) block.
size_t dim_
The spatial dimension.
Teuchos::RCP< MultiVector > P11x_colmap_
Teuchos::RCP< MultiVector > DresSubComm_
void resetMatrix(Teuchos::RCP< Matrix > SM_Matrix_new, bool ComputePrec=true)
Reset system matrix.
void setParameters(Teuchos::ParameterList &list)
Set parameters.
typename Teuchos::ScalarTraits< Scalar >::magnitudeType magnitudeType
Teuchos::RCP< SmootherBase > PreSmoother11_
Teuchos::RCP< MultiVector > Material_alpha_
Teuchos::RCP< const Import > ImporterCoarse11_
Importer to coarse (1,1) hierarchy.
Teuchos::RCP< Matrix > R22_
RCP< Matrix > buildAddon(const int spaceNumber)
void solve22(const MultiVector &RHS, MultiVector &X) const
apply solve to 2-2 block only
Teuchos::RCP< Matrix > invMk_2_invAlpha_
RCP< Operator > thyraPrecOp22_
Teuchos::RCP< MultiVector > DxSubComm_
Factory for building permutation matrix that can be be used to shuffle data (matrices,...
Factory for determing the number of partitions for rebalancing.
Factory for building Smoothed Aggregation prolongators.
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Factory for building tentative prolongator.
Class that encapsulates external library smoothers.
Factory for building uncoupled aggregates.
static void ZeroDirichletRows(Teuchos::RCP< Xpetra::Matrix< Scalar, DefaultLocalOrdinal, DefaultGlobalOrdinal, DefaultNode > > &A, const std::vector< DefaultLocalOrdinal > &dirichletRows, Scalar replaceWith=Teuchos::ScalarTraits< Scalar >::zero())
static void ZeroDirichletCols(Teuchos::RCP< Matrix > &A, const Teuchos::ArrayRCP< const bool > &dirichletCols, Scalar replaceWith=Teuchos::ScalarTraits< Scalar >::zero())
static void ApplyRowSumCriterion(const Xpetra::Matrix< Scalar, DefaultLocalOrdinal, DefaultGlobalOrdinal, DefaultNode > &A, const Magnitude rowSumTol, Teuchos::ArrayRCP< bool > &dirichletRows)
static void ApplyOAZToMatrixRows(Teuchos::RCP< Xpetra::Matrix< Scalar, DefaultLocalOrdinal, DefaultGlobalOrdinal, DefaultNode > > &A, const std::vector< DefaultLocalOrdinal > &dirichletRows)
static void DetectDirichletColsAndDomains(const Xpetra::Matrix< Scalar, DefaultLocalOrdinal, DefaultGlobalOrdinal, DefaultNode > &A, const Teuchos::ArrayRCP< bool > &dirichletRows, Teuchos::ArrayRCP< bool > dirichletCols, Teuchos::ArrayRCP< bool > dirichletDomain)
static RCP< MultiVector > Residual(const Xpetra::Operator< Scalar, DefaultLocalOrdinal, DefaultGlobalOrdinal, DefaultNode > &Op, const MultiVector &X, const MultiVector &RHS)
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)
static RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > RealValuedToScalarMultiVector(RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::coordinateType, LocalOrdinal, GlobalOrdinal, Node > > X)
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
VerbLevel GetVerbLevel() const
Get the verbosity level.
int SetProcRankVerbose(int procRank) const
Set proc rank used for printing.
static VerbLevel GetDefaultVerbLevel()
Get the default (global) verbosity level.
bool IsPrint(MsgType type, int thisProcRankOnly=-1) const
Find out whether we need to print out information for a specific message type.
static void SetMueLuOStream(const Teuchos::RCP< Teuchos::FancyOStream > &mueluOStream)
static void SetDefaultVerbLevel(const VerbLevel defaultVerbLevel)
Set the default (global) verbosity level.
static void SetMueLuOFileStream(const std::string &filename)
Interface to Zoltan2 library.
Interface to Zoltan library.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line).
@ Statistics2
Print even more statistics.
@ Runtime0
One-liner description of what is happening.
@ Runtime1
Description of what is happening (more verbose).
@ Warnings1
Additional warnings.
@ Timings
Print all timing information.
MsgType toVerbLevel(const std::string &verbLevelStr)
T pop(Teuchos::ParameterList &pl, std::string const &name_in)
Teuchos::RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateXpetraPreconditioner(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > op, const Teuchos::ParameterList &inParamList)
Helper function to create a MueLu preconditioner that can be used by Xpetra.Given an Xpetra::Matrix,...