10#ifndef MUELU_REFMAXWELL_DEF_HPP
11#define MUELU_REFMAXWELL_DEF_HPP
17#include "Teuchos_Assert.hpp"
18#include "Teuchos_CompilerCodeTweakMacros.hpp"
19#include "Tpetra_CrsMatrix.hpp"
20#include "Xpetra_CrsMatrix.hpp"
21#include "Xpetra_Map.hpp"
22#include "Xpetra_MatrixMatrix.hpp"
23#include "Xpetra_MultiVector.hpp"
24#include "Xpetra_TripleMatrixMultiply.hpp"
26#include "Xpetra_MatrixUtils.hpp"
30#include "MueLu_AmalgamationFactory.hpp"
31#include "MueLu_RAPFactory.hpp"
32#include "MueLu_SmootherFactory.hpp"
34#include "MueLu_CoalesceDropFactory.hpp"
35#include "MueLu_CoarseMapFactory.hpp"
36#include "MueLu_CoordinatesTransferFactory.hpp"
37#include "MueLu_UncoupledAggregationFactory.hpp"
38#include "MueLu_TentativePFactory.hpp"
39#include "MueLu_SaPFactory.hpp"
40#include "MueLu_AggregationExportFactory.hpp"
41#include "MueLu_Utilities.hpp"
42#include "MueLu_Maxwell_Utils.hpp"
44#include "MueLu_CoalesceDropFactory_kokkos.hpp"
45#include "MueLu_TentativePFactory_kokkos.hpp"
46#include <Kokkos_Core.hpp>
47#include <KokkosSparse_CrsMatrix.hpp>
49#include "MueLu_ZoltanInterface.hpp"
50#include "MueLu_Zoltan2Interface.hpp"
51#include "MueLu_RepartitionHeuristicFactory.hpp"
52#include "MueLu_RepartitionFactory.hpp"
53#include "MueLu_RebalanceAcFactory.hpp"
54#include "MueLu_RebalanceTransferFactory.hpp"
63#include "cuda_profiler_api.h"
67#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
74T
pop(Teuchos::ParameterList &pl, std::string
const &name_in) {
75 T result = pl.get<T>(name_in);
76 pl.remove(name_in,
true);
81T
pop(Teuchos::ParameterList &pl, std::string
const &name_in, T def_value) {
82 T result = pl.get<T>(name_in, def_value);
83 pl.remove(name_in,
false);
88T
pop(Teuchos::ParameterList &pl1, Teuchos::ParameterList &pl2, std::string
const &name_in, T def_value) {
89 return pop(pl2, name_in,
pop(pl1, name_in, def_value));
92template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
97template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
102template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
103Teuchos::RCP<Teuchos::ParameterList>
106 bool useKokkosDefault = !Node::is_serial;
108 RCP<ParameterList> params = rcp(
new ParameterList(
"RefMaxwell"));
110 params->set<RCP<Matrix>>(
"Dk_1", Teuchos::null);
111 params->set<RCP<Matrix>>(
"Dk_2", Teuchos::null);
112 params->set<RCP<Matrix>>(
"D0", Teuchos::null);
114 params->set<RCP<Matrix>>(
"M1_beta", Teuchos::null);
115 params->set<RCP<Matrix>>(
"M1_alpha", Teuchos::null);
117 params->set<RCP<Matrix>>(
"Ms", Teuchos::null);
119 params->set<RCP<Matrix>>(
"Mk_one", Teuchos::null);
120 params->set<RCP<Matrix>>(
"Mk_1_one", Teuchos::null);
122 params->set<RCP<Matrix>>(
"M1", Teuchos::null);
124 params->set<RCP<Matrix>>(
"invMk_1_invBeta", Teuchos::null);
125 params->set<RCP<Matrix>>(
"invMk_2_invAlpha", Teuchos::null);
127 params->set<RCP<Matrix>>(
"M0inv", Teuchos::null);
129 params->set<RCP<MultiVector>>(
"Nullspace", Teuchos::null);
130 params->set<RCP<RealValuedMultiVector>>(
"Coordinates", Teuchos::null);
132 auto spaceValidator = rcp(
new Teuchos::EnhancedNumberValidator<int>(1, 2));
133 params->set(
"refmaxwell: space number", 1,
"", spaceValidator);
135 params->set(
"use kokkos refactor", useKokkosDefault);
136 params->set(
"half precision",
false);
141 params->set(
"refmaxwell: disable addon 22",
true);
147 params->set(
"refmaxwell: skip first (2,2) level",
false);
148 params->set(
"multigrid algorithm",
"Unsmoothed");
151 params->set(
"rap: fix zero diagonals",
true);
154 params->set(
"refmaxwell: async transfers", Node::is_gpu);
156 params->set(
"refmaxwell: subsolves striding", 1);
158 params->set(
"sync timers",
false);
159 params->set(
"refmaxwell: num iters coarse 11", 1);
160 params->set(
"refmaxwell: num iters 22", 1);
161 params->set(
"refmaxwell: apply BCs to Anodal",
false);
162 params->set(
"refmaxwell: apply BCs to coarse 11",
true);
163 params->set(
"refmaxwell: apply BCs to 22",
true);
164 params->set(
"refmaxwell: max coarse size", 1);
166 ParameterList &precList11 = params->sublist(
"refmaxwell: 11list");
167 precList11.disableRecursiveValidation();
168 ParameterList &precList22 = params->sublist(
"refmaxwell: 22list");
169 precList22.disableRecursiveValidation();
170 ParameterList &userData = params->sublist(
"user data");
171 userData.disableRecursiveValidation();
173 params->set(
"smoother: type",
"CHEBYSHEV");
174 ParameterList &smootherList = params->sublist(
"smoother: params");
175 smootherList.disableRecursiveValidation();
176 params->set(
"smoother: pre type",
"NONE");
177 ParameterList &preSmootherList = params->sublist(
"smoother: pre params");
178 preSmootherList.disableRecursiveValidation();
179 params->set(
"smoother: post type",
"NONE");
180 ParameterList &postSmootherList = params->sublist(
"smoother: post params");
181 postSmootherList.disableRecursiveValidation();
183 ParameterList &matvecParams = params->sublist(
"matvec params");
184 matvecParams.disableRecursiveValidation();
186 ParameterList &importerCoarse11Params = params->sublist(
"refmaxwell: ImporterCoarse11 params");
187 importerCoarse11Params.disableRecursiveValidation();
189 ParameterList &importer22Params = params->sublist(
"refmaxwell: Importer22 params");
190 importer22Params.disableRecursiveValidation();
192 params->set(
"multigrid algorithm",
"unsmoothed");
207template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
209 if (list.isType<std::string>(
"parameterlist: syntax") && list.get<std::string>(
"parameterlist: syntax") ==
"ml") {
210 Teuchos::ParameterList newList;
214 for (
auto it = newList2.begin(); it != newList2.end(); ++it) {
215 const std::string &entry_name = it->first;
216 if (validateParameters->isParameter(entry_name)) {
217 ParameterEntry theEntry = newList2.getEntry(entry_name);
218 newList.setEntry(entry_name, theEntry);
223 if (list.isSublist(
"refmaxwell: 11list") && list.sublist(
"refmaxwell: 11list").isSublist(
"edge matrix free: coarse"))
225 if (list.isSublist(
"refmaxwell: 22list"))
232 std::string verbosityLevel =
parameterList_.get<std::string>(
"verbosity");
234 std::string outputFilename =
parameterList_.get<std::string>(
"output filename");
235 if (outputFilename !=
"")
237 if (
parameterList_.isType<Teuchos::RCP<Teuchos::FancyOStream>>(
"output stream"))
263 if (!
precList11_.isType<std::string>(
"Preconditioner Type") &&
264 !
precList11_.isType<std::string>(
"smoother: type") &&
265 !
precList11_.isType<std::string>(
"smoother: pre type") &&
266 !
precList11_.isType<std::string>(
"smoother: post type")) {
268 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
269 precList11_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 5.4);
270 precList11_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
274 if (!
precList22_.isType<std::string>(
"Preconditioner Type") &&
275 !
precList22_.isType<std::string>(
"smoother: type") &&
276 !
precList22_.isType<std::string>(
"smoother: pre type") &&
277 !
precList22_.isType<std::string>(
"smoother: post type")) {
279 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
280 precList22_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
281 precList22_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
285 list.set(
"smoother: type",
"CHEBYSHEV");
286 list.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
287 list.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 20.0);
288 list.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
292 !
precList11_.isType<std::string>(
"Preconditioner Type") &&
296 !
precList22_.isType<std::string>(
"Preconditioner Type") &&
301template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
303 using memory_space =
typename Node::device_type::memory_space;
305#ifdef HAVE_MUELU_CUDA
306 if (
parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
309 std::string timerLabel;
311 timerLabel =
"compute (reuse)";
313 timerLabel =
"compute";
314 RCP<Teuchos::TimeMonitor> tmCompute =
getTimer(timerLabel);
324 RCP<ParameterList> params = rcp(
new ParameterList());
325 params->set(
"printLoadBalancingInfo",
true);
326 params->set(
"printCommInfo",
true);
340 Kokkos::View<bool *, memory_space> BCcolsEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"),
Dk_1_->getColMap()->getLocalNumElements());
341 Kokkos::View<bool *, memory_space> BCdomainEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"),
Dk_1_->getDomainMap()->getLocalNumElements());
344 Kokkos::View<bool *, memory_space> BCcolsNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"),
D0_->getColMap()->getLocalNumElements());
345 Kokkos::View<bool *, memory_space> BCdomainNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"),
D0_->getDomainMap()->getLocalNumElements());
360 GetOStream(
Warnings0) <<
"All unknowns of the (1,1) block have been detected as boundary unknowns!" << std::endl;
385 RCP<Matrix> A11_nodal;
388 std::string label(
"D0^T*M1_beta*D0");
395 A11_nodal->setObjectLabel(
solverName_ +
" (1,1) A_nodal");
396 dump(A11_nodal,
"A11_nodal.m");
419 RCP<Matrix> A22_nodal;
422 std::string label(
"D0^T*M1_alpha*D0");
429 A22_nodal->setObjectLabel(
solverName_ +
" (2,2) A_nodal");
430 dump(A22_nodal,
"A22_nodal.m");
449 int rebalanceStriding, numProcsCoarseA11, numProcsA22;
453 doRebalancing =
false;
456 if (!reuse && doRebalancing)
476 std::string label(
"coarseA11");
477 if (!
precList11_.isType<std::string>(
"hierarchy label"))
489 Scalar replaceWith = Teuchos::ScalarTraits<SC>::zero();
500 build22Matrix(reuse, doRebalancing, rebalanceStriding, numProcsA22);
502 if (!
P22_.is_null()) {
503 std::string label(
"P22^T*A22*P22");
516 if (!
A22_.is_null()) {
518 std::string label(
"A22");
519 if (!
precList22_.isType<std::string>(
"hierarchy label"))
521 if (!
P22_.is_null()) {
531 int numRows = Teuchos::as<int>(
coarseA22_->getGlobalNumRows());
532 if (maxCoarseSize > numRows)
551 Scalar replaceWith = Teuchos::ScalarTraits<SC>::zero();
563 RCP<const Import> ImporterP11 = ImportFactory::Build(
ImporterCoarse11_->getTargetMap(),
P11_->getColMap());
572 RCP<const Import> ImporterD = ImportFactory::Build(
Importer22_->getTargetMap(),
Dk_1_->getColMap());
573 toCrsMatrix(
Dk_1_)->replaceDomainMapAndImporter(
Importer22_->getTargetMap(), ImporterD);
578 (!toCrsMatrix(
Dk_1_T_)->getCrsGraph()->getImporter().is_null()) &&
579 (!toCrsMatrix(
R11_)->getCrsGraph()->getImporter().is_null()) &&
580 (
Dk_1_T_->getColMap()->lib() == Xpetra::UseTpetra) &&
581 (
R11_->getColMap()->lib() == Xpetra::UseTpetra))
595 RCP<ParameterList> matvecParams = rcpFromRef(
parameterList_.sublist(
"matvec params"));
605 RCP<ParameterList> importerParams = rcpFromRef(
parameterList_.sublist(
"refmaxwell: ImporterCoarse11 params"));
609 RCP<ParameterList> importerParams = rcpFromRef(
parameterList_.sublist(
"refmaxwell: Importer22 params"));
610 Importer22_->setDistributorParameters(importerParams);
617#ifdef HAVE_MUELU_CUDA
618 if (
parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
622template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
625 doRebalancing =
parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators");
626 rebalanceStriding =
parameterList_.get<
int>(
"refmaxwell: subsolves striding", -1);
627 int numProcs =
SM_Matrix_->getDomainMap()->getComm()->getSize();
629 doRebalancing =
false;
644 ParameterList repartheurParams;
645 repartheurParams.set(
"repartition: start level", 0);
647 int defaultTargetRows = 10000;
648 repartheurParams.set(
"repartition: min rows per proc",
precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
649 repartheurParams.set(
"repartition: target rows per proc",
precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
650 repartheurParams.set(
"repartition: min rows per thread",
precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
651 repartheurParams.set(
"repartition: target rows per thread",
precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
652 repartheurParams.set(
"repartition: max imbalance",
precList11_.get<
double>(
"repartition: max imbalance", 1.1));
653 repartheurFactory->SetParameterList(repartheurParams);
655 level.
Request(
"number of partitions", repartheurFactory.get());
656 repartheurFactory->Build(level);
657 numProcsCoarseA11 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
658 numProcsCoarseA11 = std::min(numProcsCoarseA11, numProcs);
668 level.
Set(
"Map",
Dk_1_->getDomainMap());
671 ParameterList repartheurParams;
672 repartheurParams.set(
"repartition: start level", 0);
673 repartheurParams.set(
"repartition: use map",
true);
675 int defaultTargetRows = 10000;
676 repartheurParams.set(
"repartition: min rows per proc",
precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
677 repartheurParams.set(
"repartition: target rows per proc",
precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
678 repartheurParams.set(
"repartition: min rows per thread",
precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
679 repartheurParams.set(
"repartition: target rows per thread",
precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
681 repartheurFactory->SetParameterList(repartheurParams);
683 level.
Request(
"number of partitions", repartheurFactory.get());
684 repartheurFactory->Build(level);
685 numProcsA22 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
686 numProcsA22 = std::min(numProcsA22, numProcs);
689 if (rebalanceStriding >= 1) {
690 TEUCHOS_ASSERT(rebalanceStriding * numProcsCoarseA11 <= numProcs);
691 TEUCHOS_ASSERT(rebalanceStriding * numProcsA22 <= numProcs);
692 if (rebalanceStriding * (numProcsCoarseA11 + numProcsA22) > numProcs) {
693 GetOStream(
Warnings0) <<
solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 needs " << numProcsCoarseA11
694 <<
" procs and A22 needs " << numProcsA22 <<
" procs." << std::endl;
695 rebalanceStriding = -1;
697 int lclBadMatrixDistribution = (
coarseA11_->getLocalNumEntries() == 0) || (
Dk_1_->getDomainMap()->getLocalNumElements() == 0);
698 int gblBadMatrixDistribution =
false;
700 if (gblBadMatrixDistribution) {
701 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;
702 rebalanceStriding = -1;
706 if ((numProcsCoarseA11 < 0) || (numProcsA22 < 0) || (numProcsCoarseA11 + numProcsA22 > numProcs)) {
707 std::stringstream ss;
708 ss <<
solverName_ +
"::compute(): Partition heuristic resulted "
709 <<
"in undesirable number of partitions: " << numProcsCoarseA11 <<
", " << numProcsA22 <<
".";
711 if (numProcsCoarseA11 < 0)
712 numProcsCoarseA11 = numProcs;
714 numProcsA22 = numProcs;
716 double ratioCoarseA11 = ((double)numProcsCoarseA11) / ((
double)(numProcsCoarseA11 + numProcsA22));
717 double ratioA22 = ((double)numProcsA22) / ((
double)(numProcsCoarseA11 + numProcsA22));
718 numProcsCoarseA11 = std::round(ratioCoarseA11 * numProcs);
719 numProcsA22 = std::round(ratioA22 * numProcs);
721 if (numProcsCoarseA11 == 0) {
722 numProcsCoarseA11 = 1;
723 numProcsA22 = numProcs - 1;
725 if (numProcsA22 == 0) {
726 numProcsCoarseA11 = numProcs - 1;
730 ss <<
". Adjusting to fit: " << numProcsCoarseA11 <<
", " << numProcsA22 << std::endl;
733 TEUCHOS_ASSERT_INEQUALITY(numProcsCoarseA11, >, 0);
734 TEUCHOS_ASSERT_INEQUALITY(numProcsA22, >, 0);
735 TEUCHOS_ASSERT_EQUALITY(numProcsCoarseA11 + numProcsA22, numProcs);
739 doRebalancing =
false;
743template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
746 if (spaceNumber == 0)
747 return Teuchos::null;
749 std::string timerLabel;
752 timerLabel =
"Build coarse addon matrix 11";
754 timerLabel =
"Build addon matrix 11";
756 timerLabel =
"Build addon matrix 22";
758 RCP<Teuchos::TimeMonitor> tmAddon =
getTimer(timerLabel);
762 RCP<Matrix> lumpedInverse;
765 TEUCHOS_TEST_FOR_EXCEPTION(
invMk_1_invBeta_ == Teuchos::null, std::invalid_argument,
767 "::buildCoarse11Matrix(): Inverse of "
768 "lumped mass matrix required for add-on (i.e. invMk_1_invBeta_ is null)");
774 Zaux = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Mk_one_,
false, *
P11_,
false, Zaux,
GetOStream(
Runtime0),
true,
true);
776 Z = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *Zaux,
false, Z,
GetOStream(
Runtime0),
true,
true);
779 Z = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *
Mk_one_,
false, Z,
GetOStream(
Runtime0),
true,
true);
784 TEUCHOS_TEST_FOR_EXCEPTION(
invMk_2_invAlpha_ == Teuchos::null, std::invalid_argument,
786 "::buildCoarse11Matrix(): Inverse of "
787 "lumped mass matrix required for add-on (i.e. invMk_2_invAlpha_ is null)");
791 Z = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_2_,
true, *
Mk_1_one_,
false, Z,
GetOStream(
Runtime0),
true,
true);
795 if (lumpedInverse->getGlobalMaxNumRowEntries() <= 1) {
798 RCP<Vector> diag = VectorFactory::Build(lumpedInverse->getRowMap());
799 lumpedInverse->getLocalDiagCopy(*diag);
801 ArrayRCP<Scalar> diagVals = diag->getDataNonConst(0);
802 for (
size_t j = 0; j < diag->getMap()->getLocalNumElements(); j++) {
803 diagVals[j] = Teuchos::ScalarTraits<Scalar>::squareroot(diagVals[j]);
806 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
809 RCP<Import> importer = ImportFactory::Build(diag->getMap(), Z->getRowMap());
810 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
811 diag2->doImport(*diag, *importer, Xpetra::INSERT);
812 Z->leftScale(*diag2);
814 addon = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *Z,
false, addon,
GetOStream(
Runtime0),
true,
true);
815 }
else if (
parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
818 C2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*lumpedInverse,
false, *Z,
false, C2,
GetOStream(
Runtime0),
true,
true);
820 addon = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *C2,
false, addon,
GetOStream(
Runtime0),
true,
true);
822 addon = MatrixFactory::Build(Z->getDomainMap());
824 Xpetra::TripleMatrixMultiply<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
825 MultiplyRAP(*Z,
true, *lumpedInverse,
false, *Z,
false, *addon,
true,
true);
830template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
832 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Build coarse (1,1) matrix");
834 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
838 temp = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
SM_Matrix_,
false, *
P11_,
false, temp,
GetOStream(
Runtime0),
true,
true);
840 coarseA11_ = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
P11_,
true, *temp,
false,
coarseA11_,
GetOStream(
Runtime0),
true,
true);
843 temp2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
P11_,
true, *temp,
false, temp2,
GetOStream(
Runtime0),
true,
true);
846 temp2->removeEmptyProcessesInPlace(map);
847 if (!temp2.is_null() && temp2->getRowMap().is_null())
848 temp2 = Teuchos::null;
865 RCP<Matrix> newCoarseA11;
866 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*
coarseA11_,
false, one, *addon,
false, one, newCoarseA11,
GetOStream(
Runtime0));
867 newCoarseA11->fillComplete();
873 ArrayRCP<bool> coarseA11BCrows;
874 coarseA11BCrows.resize(
coarseA11_->getRowMap()->getLocalNumElements());
876 for (
size_t k = 0; k <
dim_; k++)
892 if (
precList11_.isParameter(
"rap: fix zero diagonals"))
893 fixZeroDiagonal =
precList11_.get<
bool>(
"rap: fix zero diagonals");
895 if (fixZeroDiagonal) {
900 else if (
precList11_.isType<
double>(
"rap: fix zero diagonals threshold"))
901 threshold = Teuchos::as<magnitudeType>(
precList11_.get<
double>(
"rap: fix zero diagonals threshold"));
902 if (
precList11_.isType<
double>(
"rap: fix zero diagonals replacement"))
903 replacement = Teuchos::as<Scalar>(
precList11_.get<
double>(
"rap: fix zero diagonals replacement"));
916template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
921 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Rebalance coarseA11");
923 Level fineLevel, coarseLevel;
934 coarseLevel.
Set(
"number of partitions", numProcsCoarseA11);
935 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
939 coarseLevel.setObjectLabel(
solverName_ +
" coarse (1,1)");
940 fineLevel.setObjectLabel(
solverName_ +
" coarse (1,1)");
942 std::string partName =
precList11_.get<std::string>(
"repartition: partitioner",
"zoltan2");
943 RCP<Factory> partitioner;
944 if (partName ==
"zoltan") {
945#ifdef HAVE_MUELU_ZOLTAN
952 }
else if (partName ==
"zoltan2") {
953#ifdef HAVE_MUELU_ZOLTAN2
955 ParameterList partParams;
956 RCP<const ParameterList> partpartParams = rcp(
new ParameterList(
precList11_.sublist(
"repartition: params",
false)));
957 partParams.set(
"ParameterList", partpartParams);
958 partitioner->SetParameterList(partParams);
966 ParameterList repartParams;
967 repartParams.set(
"repartition: print partition distribution",
precList11_.get<
bool>(
"repartition: print partition distribution",
false));
968 repartParams.set(
"repartition: remap parts",
precList11_.get<
bool>(
"repartition: remap parts",
true));
969 if (rebalanceStriding >= 1) {
970 bool acceptPart = (
SM_Matrix_->getDomainMap()->getComm()->getRank() % rebalanceStriding) == 0;
971 if (
SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsCoarseA11 * rebalanceStriding)
973 repartParams.set(
"repartition: remap accept partition", acceptPart);
975 repartFactory->SetParameterList(repartParams);
977 repartFactory->SetFactory(
"Partition", partitioner);
980 ParameterList newPparams;
981 newPparams.set(
"type",
"Interpolation");
982 newPparams.set(
"repartition: rebalance P and R",
precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
983 newPparams.set(
"repartition: use subcommunicators",
true);
988 newP->SetParameterList(newPparams);
989 newP->SetFactory(
"Importer", repartFactory);
992 ParameterList rebAcParams;
993 rebAcParams.set(
"repartition: use subcommunicators",
true);
994 newA->SetParameterList(rebAcParams);
995 newA->SetFactory(
"Importer", repartFactory);
997 coarseLevel.
Request(
"P", newP.get());
998 coarseLevel.
Request(
"Importer", repartFactory.get());
999 coarseLevel.
Request(
"A", newA.get());
1000 coarseLevel.
Request(
"Coordinates", newP.get());
1002 coarseLevel.
Request(
"Nullspace", newP.get());
1003 repartFactory->Build(coarseLevel);
1005 if (!
precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
1007 P11_ = coarseLevel.
Get<RCP<Matrix>>(
"P", newP.get());
1009 CoordsCoarse11_ = coarseLevel.
Get<RCP<RealValuedMultiVector>>(
"Coordinates", newP.get());
1027 RCP<const Import> ImporterCoarse11 = coarseLevel.
Get<RCP<const Import>>(
"Importer", repartFactory.get());
1028 RCP<const Map> targetMap = ImporterCoarse11->getTargetMap();
1029 ParameterList XpetraList;
1030 XpetraList.set(
"Restrict Communicator",
true);
1031 Addon11_ = MatrixFactory::Build(
Addon11_, *ImporterCoarse11, *ImporterCoarse11, targetMap, targetMap, rcp(&XpetraList,
false));
1036template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1039 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Build A22");
1041 Level fineLevel, coarseLevel;
1053 coarseLevel.setObjectLabel(
solverName_ +
" (2,2)");
1056 RCP<RAPFactory> rapFact = rcp(
new RAPFactory());
1057 ParameterList rapList = *(rapFact->GetValidParameterList());
1058 rapList.set(
"transpose: use implicit",
true);
1059 rapList.set(
"rap: fix zero diagonals",
parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1060 rapList.set(
"rap: fix zero diagonals threshold",
parameterList_.get<
double>(
"rap: fix zero diagonals threshold", Teuchos::ScalarTraits<double>::eps()));
1061 rapList.set(
"rap: triple product",
parameterList_.get<
bool>(
"rap: triple product",
false));
1062 rapFact->SetParameterList(rapList);
1065 coarseLevel.
AddKeepFlag(
"AP reuse data", rapFact.get());
1066 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList>>(
"AP reuse data",
A22_AP_reuse_data_, rapFact.get());
1069 coarseLevel.
AddKeepFlag(
"RAP reuse data", rapFact.get());
1070 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList>>(
"RAP reuse data",
A22_RAP_reuse_data_, rapFact.get());
1074 if (doRebalancing) {
1075 coarseLevel.
Set(
"number of partitions", numProcsA22);
1076 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
1078 std::string partName =
precList22_.get<std::string>(
"repartition: partitioner",
"zoltan2");
1079 RCP<Factory> partitioner;
1080 if (partName ==
"zoltan") {
1081#ifdef HAVE_MUELU_ZOLTAN
1083 partitioner->SetFactory(
"A", rapFact);
1089 }
else if (partName ==
"zoltan2") {
1090#ifdef HAVE_MUELU_ZOLTAN2
1092 ParameterList partParams;
1093 RCP<const ParameterList> partpartParams = rcp(
new ParameterList(
precList22_.sublist(
"repartition: params",
false)));
1094 partParams.set(
"ParameterList", partpartParams);
1095 partitioner->SetParameterList(partParams);
1096 partitioner->SetFactory(
"A", rapFact);
1104 ParameterList repartParams;
1105 repartParams.set(
"repartition: print partition distribution",
precList22_.get<
bool>(
"repartition: print partition distribution",
false));
1106 repartParams.set(
"repartition: remap parts",
precList22_.get<
bool>(
"repartition: remap parts",
true));
1107 if (rebalanceStriding >= 1) {
1108 bool acceptPart = ((
SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 -
SM_Matrix_->getDomainMap()->getComm()->getRank()) % rebalanceStriding) == 0;
1109 if (
SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 -
SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsA22 * rebalanceStriding)
1113 repartParams.set(
"repartition: remap accept partition", acceptPart);
1115 repartParams.set(
"repartition: remap accept partition",
coarseA11_.is_null());
1116 repartFactory->SetParameterList(repartParams);
1117 repartFactory->SetFactory(
"A", rapFact);
1119 repartFactory->SetFactory(
"Partition", partitioner);
1122 ParameterList newPparams;
1123 newPparams.set(
"type",
"Interpolation");
1124 newPparams.set(
"repartition: rebalance P and R",
precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
1125 newPparams.set(
"repartition: use subcommunicators",
true);
1126 newPparams.set(
"repartition: rebalance Nullspace",
false);
1128 newP->SetParameterList(newPparams);
1129 newP->SetFactory(
"Importer", repartFactory);
1132 ParameterList rebAcParams;
1133 rebAcParams.set(
"repartition: use subcommunicators",
true);
1134 newA->SetParameterList(rebAcParams);
1135 newA->SetFactory(
"A", rapFact);
1136 newA->SetFactory(
"Importer", repartFactory);
1138 coarseLevel.
Request(
"P", newP.get());
1139 coarseLevel.
Request(
"Importer", repartFactory.get());
1140 coarseLevel.
Request(
"A", newA.get());
1141 coarseLevel.
Request(
"Coordinates", newP.get());
1142 rapFact->Build(fineLevel, coarseLevel);
1143 repartFactory->Build(coarseLevel);
1145 if (!
precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
1146 Importer22_ = coarseLevel.
Get<RCP<const Import>>(
"Importer", repartFactory.get());
1147 Dk_1_ = coarseLevel.
Get<RCP<Matrix>>(
"P", newP.get());
1148 A22_ = coarseLevel.
Get<RCP<Matrix>>(
"A", newA.get());
1149 Coords22_ = coarseLevel.
Get<RCP<RealValuedMultiVector>>(
"Coordinates", newP.get());
1151 if (!
P22_.is_null()) {
1158 coarseLevel.
Request(
"A", rapFact.get());
1160 coarseLevel.
Request(
"AP reuse data", rapFact.get());
1161 coarseLevel.
Request(
"RAP reuse data", rapFact.get());
1164 A22_ = coarseLevel.
Get<RCP<Matrix>>(
"A", rapFact.get());
1167 if (coarseLevel.
IsAvailable(
"AP reuse data", rapFact.get()))
1169 if (coarseLevel.
IsAvailable(
"RAP reuse data", rapFact.get()))
1174 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"Build A22");
1177 temp = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
SM_Matrix_,
false, *
Dk_1_,
false, temp,
GetOStream(
Runtime0),
true,
true);
1179 A22_ = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_T_,
false, *temp,
false,
A22_,
GetOStream(
Runtime0),
true,
true);
1181 A22_ = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *temp,
false,
A22_,
GetOStream(
Runtime0),
true,
true);
1184 RCP<const Import> Dimporter = toCrsMatrix(
Dk_1_)->getCrsGraph()->getImporter();
1187 RCP<Matrix> temp, temp2;
1188 temp = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
SM_Matrix_,
false, *
Dk_1_,
false, temp,
GetOStream(
Runtime0),
true,
true);
1190 temp2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_T_,
false, *temp,
false, temp2,
GetOStream(
Runtime0),
true,
true);
1192 temp2 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*
Dk_1_,
true, *temp,
false, temp2,
GetOStream(
Runtime0),
true,
true);
1195 toCrsMatrix(
Dk_1_)->replaceDomainMapAndImporter(
Importer22_->getTargetMap(), Dimporter);
1197 ParameterList XpetraList;
1198 XpetraList.set(
"Restrict Communicator",
true);
1199 XpetraList.set(
"Timer Label",
"MueLu::RebalanceA22");
1200 RCP<const Map> targetMap =
Importer22_->getTargetMap();
1206 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1212 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*
A22_,
false, one, *addon22,
false, one, newA22,
GetOStream(
Runtime0));
1213 newA22->fillComplete();
1217 if (!
A22_.is_null()) {
1222 A22_->SetFixedBlockSize(1);
1228template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1231 RCP<MueLu::FactoryManagerBase> factoryHandler = rcp(
new FactoryManager());
1238 level.
Set(
"NodeMatrix",
A22_);
1241 if ((
parameterList_.get<std::string>(
"smoother: pre type") !=
"NONE") && (
parameterList_.get<std::string>(
"smoother: post type") !=
"NONE")) {
1242 std::string preSmootherType =
parameterList_.get<std::string>(
"smoother: pre type");
1243 std::string postSmootherType =
parameterList_.get<std::string>(
"smoother: post type");
1245 ParameterList preSmootherList, postSmootherList;
1247 preSmootherList =
parameterList_.sublist(
"smoother: pre params");
1249 postSmootherList =
parameterList_.sublist(
"smoother: post params");
1251 RCP<SmootherPrototype> preSmootherPrototype = rcp(
new TrilinosSmoother(preSmootherType, preSmootherList));
1252 RCP<SmootherPrototype> postSmootherPrototype = rcp(
new TrilinosSmoother(postSmootherType, postSmootherList));
1253 RCP<SmootherFactory> smootherFact = rcp(
new SmootherFactory(preSmootherPrototype, postSmootherPrototype));
1255 level.
Request(
"PreSmoother", smootherFact.get());
1256 level.
Request(
"PostSmoother", smootherFact.get());
1258 ParameterList smootherFactoryParams;
1259 smootherFactoryParams.set(
"keep smoother data",
true);
1260 smootherFact->SetParameterList(smootherFactoryParams);
1261 level.
Request(
"PreSmoother data", smootherFact.get());
1262 level.
Request(
"PostSmoother data", smootherFact.get());
1268 smootherFact->Build(level);
1269 PreSmoother11_ = level.
Get<RCP<SmootherBase>>(
"PreSmoother", smootherFact.get());
1276 std::string smootherType =
parameterList_.get<std::string>(
"smoother: type");
1278 ParameterList smootherList;
1282 RCP<SmootherPrototype> smootherPrototype = rcp(
new TrilinosSmoother(smootherType, smootherList));
1283 RCP<SmootherFactory> smootherFact = rcp(
new SmootherFactory(smootherPrototype));
1284 level.
Request(
"PreSmoother", smootherFact.get());
1286 ParameterList smootherFactoryParams;
1287 smootherFactoryParams.set(
"keep smoother data",
true);
1288 smootherFact->SetParameterList(smootherFactoryParams);
1289 level.
Request(
"PreSmoother data", smootherFact.get());
1293 smootherFact->Build(level);
1294 PreSmoother11_ = level.
Get<RCP<SmootherBase>>(
"PreSmoother", smootherFact.get());
1301template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1303 RCP<Teuchos::TimeMonitor> tmAlloc =
getTimer(
"Allocate MVs");
1306 if (!
R11_.is_null())
1307 P11res_ = MultiVectorFactory::Build(
R11_->getRangeMap(), numVectors);
1309 P11res_ = MultiVectorFactory::Build(
P11_->getDomainMap(), numVectors);
1310 P11res_->setObjectLabel(
"P11res");
1313 DTR11Tmp_ = MultiVectorFactory::Build(
R11_->getColMap(), numVectors);
1321 P11x_ = MultiVectorFactory::Build(
P11_->getDomainMap(), numVectors);
1322 P11x_->setObjectLabel(
"P11x");
1326 Dres_ = MultiVectorFactory::Build(
Dk_1_T_->getRangeMap(), numVectors);
1328 Dres_ = MultiVectorFactory::Build(
Dk_1_->getDomainMap(), numVectors);
1329 Dres_->setObjectLabel(
"Dres");
1333 DresTmp_->setObjectLabel(
"DresTmp");
1334 Dx_ = MultiVectorFactory::Build(
Importer22_->getTargetMap(), numVectors);
1336 Dx_ = MultiVectorFactory::Build(
A22_->getDomainMap(), numVectors);
1338 Dx_->setObjectLabel(
"Dx");
1353 if (!
A22_.is_null()) {
1367 if (!toCrsMatrix(
P11_)->getCrsGraph()->getImporter().is_null())
1369 if (!toCrsMatrix(
Dk_1_)->getCrsGraph()->getImporter().is_null())
1370 Dx_colmap_ = MultiVectorFactory::Build(
Dk_1_->getColMap(), numVectors);
1377template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1381 Xpetra::IO<SC, LO, GO, NO>::Write(name, *A);
1385template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1389 Xpetra::IO<SC, LO, GO, NO>::Write(name, *X);
1393template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1397 Xpetra::IO<coordinateType, LO, GO, NO>::Write(name, *X);
1401template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1405 std::ofstream out(name);
1406 for (
size_t i = 0; i < Teuchos::as<size_t>(v.size()); i++)
1407 out << v[i] <<
"\n";
1411template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1415 std::ofstream out(name);
1416 auto vH = Kokkos::create_mirror_view(v);
1417 Kokkos::deep_copy(vH, v);
1418 out <<
"%%MatrixMarket matrix array real general\n"
1419 << vH.extent(0) <<
" 1\n";
1420 for (
size_t i = 0; i < vH.size(); i++)
1421 out << vH[i] <<
"\n";
1425template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1429 return Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name)));
1431 if (comm.is_null()) {
1433 Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name +
"_barrier")));
1434 SM_Matrix_->getRowMap()->getComm()->barrier();
1436 return Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name)));
1439 Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name +
"_barrier")));
1442 return Teuchos::rcp(
new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(
"MueLu " +
solverName_ +
": " + name)));
1446 return Teuchos::null;
1449template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1451 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1452 std::string spaceLabel;
1453 if (spaceNumber == 0)
1454 spaceLabel =
"nodal";
1455 else if (spaceNumber == 1)
1456 spaceLabel =
"edge";
1457 else if (spaceNumber == 2)
1458 spaceLabel =
"face";
1460 TEUCHOS_ASSERT(
false);
1461 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
1464 RCP<Teuchos::TimeMonitor> tm;
1465 if (spaceNumber > 0) {
1466 tm =
getTimer(
"nullspace " + spaceLabel);
1470 if (spaceNumber == 0) {
1471 return Teuchos::null;
1473 }
else if (spaceNumber == 1) {
1474 RCP<MultiVector> CoordsSC;
1476 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(
D0_->getRowMap(),
NodalCoords_->getNumVectors());
1477 D0_->apply(*CoordsSC, *Nullspace);
1484 ArrayRCP<ArrayRCP<const Scalar>> localNullspace(
dim_);
1485 for (
size_t i = 0; i <
dim_; i++)
1486 localNullspace[i] = Nullspace->getData(i);
1487 coordinateType localMinLen = Teuchos::ScalarTraits<coordinateType>::rmax();
1488 coordinateType localMeanLen = Teuchos::ScalarTraits<coordinateType>::zero();
1489 coordinateType localMaxLen = Teuchos::ScalarTraits<coordinateType>::zero();
1490 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1491 Scalar lenSC = Teuchos::ScalarTraits<Scalar>::zero();
1492 for (
size_t i = 0; i <
dim_; i++)
1493 lenSC += localNullspace[i][j] * localNullspace[i][j];
1494 coordinateType len = Teuchos::as<coordinateType>(Teuchos::ScalarTraits<Scalar>::real(Teuchos::ScalarTraits<Scalar>::squareroot(lenSC)));
1495 localMinLen = std::min(localMinLen, len);
1496 localMaxLen = std::max(localMaxLen, len);
1497 localMeanLen += len;
1500 RCP<const Teuchos::Comm<int>> comm = Nullspace->getMap()->getComm();
1504 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1508 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1515 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1517 Array<Scalar> normsSC(
NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1518 Nullspace->scale(normsSC());
1525 dump(Nullspace,
"nullspaceEdge.m");
1529 }
else if (spaceNumber == 2) {
1530 using ATS = KokkosKernels::ArithTraits<Scalar>;
1531 using impl_Scalar =
typename ATS::val_type;
1532 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1533 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1535 RCP<Matrix> facesToNodes;
1537 RCP<Matrix> edgesToNodes = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
D0_);
1542 RCP<Matrix> facesToEdges = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
Dk_1_);
1548 facesToNodes = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes,
GetOStream(
Runtime0),
true,
true);
1555 RCP<RealValuedMultiVector> ghostedNodalCoordinates;
1556 auto importer = facesToNodes->getCrsGraph()->getImporter();
1557 if (!importer.is_null()) {
1558 ghostedNodalCoordinates = Xpetra::MultiVectorFactory<coordinateType, LocalOrdinal, GlobalOrdinal, Node>::Build(importer->getTargetMap(),
dim_);
1559 ghostedNodalCoordinates->doImport(*
NodalCoords_, *importer, Xpetra::INSERT);
1563 RCP<MultiVector> Nullspace = Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(facesToNodes->getRangeMap(),
dim_);
1565 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1566 auto localNodalCoordinates = ghostedNodalCoordinates->getLocalViewDevice(Tpetra::Access::ReadOnly);
1567 auto localFaceNullspace = Nullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
1570 Kokkos::parallel_for(
1572 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1573 KOKKOS_LAMBDA(
const size_t f) {
1574 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1575 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1576 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1577 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1578 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1579 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1580 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1581 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1582 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1584 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1585 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1586 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1595 dump(Nullspace,
"nullspaceFace.m");
1600 TEUCHOS_ASSERT(
false);
1601 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
1605template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1606Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1608 using ATS = KokkosKernels::ArithTraits<Scalar>;
1609 using impl_Scalar =
typename ATS::val_type;
1610 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1611 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1613 typedef typename Matrix::local_matrix_device_type KCRS;
1614 typedef typename KCRS::StaticCrsGraphType graph_t;
1615 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1616 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1617 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1619 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1620 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1621 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1623 std::string spaceLabel;
1624 if (spaceNumber == 0)
1625 spaceLabel =
"nodal";
1626 else if (spaceNumber == 1)
1627 spaceLabel =
"edge";
1628 else if (spaceNumber == 2)
1629 spaceLabel =
"face";
1631 TEUCHOS_ASSERT(
false);
1633 RCP<Teuchos::TimeMonitor> tm;
1634 if (spaceNumber > 0) {
1635 tm =
getTimer(
"projection " + spaceLabel);
1639 RCP<Matrix> incidence;
1640 if (spaceNumber == 0) {
1642 return Teuchos::null;
1644 }
else if (spaceNumber == 1) {
1648 }
else if (spaceNumber == 2) {
1653 RCP<Matrix> facesToNodes;
1655 RCP<Matrix> edgesToNodes = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
D0_);
1658 dump(edgesToNodes,
"edgesToNodes.m");
1660 RCP<Matrix> facesToEdges = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(
Dk_1_);
1664 dump(facesToEdges,
"facesToEdges.m");
1666 facesToNodes = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes,
GetOStream(
Runtime0),
true,
true);
1671 dump(facesToNodes,
"facesToNodes.m");
1673 incidence = facesToNodes;
1676 TEUCHOS_ASSERT(
false);
1681 RCP<const Map> rowMap = incidence->getRowMap();
1682 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1683 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1685 auto localIncidence = incidence->getLocalMatrixDevice();
1686 size_t numLocalRows = rowMap->getLocalNumElements();
1687 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1688 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1689 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1690 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1691 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1694 Kokkos::parallel_for(
1695 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1696 range_type(0, numLocalRows + 1),
1697 KOKKOS_LAMBDA(
const size_t i) {
1698 rowptr(i) = dim * localIncidence.graph.row_map(i);
1701 auto localNullspace = Nullspace->getLocalViewDevice(Tpetra::Access::ReadOnly);
1705 Kokkos::parallel_for(
1706 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1707 range_type(0, numLocalRows),
1708 KOKKOS_LAMBDA(
const size_t f) {
1709 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1710 for (
size_t k = 0; k < dim; k++) {
1711 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1712 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1713 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1715 vals(dim * jj + k) = impl_SC_ZERO;
1721 typename CrsMatrix::local_matrix_device_type lclProjection(
"local projection " + spaceLabel,
1722 numLocalRows, numLocalColumns, nnzEstimate,
1723 vals, rowptr, colind);
1724 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1725 rowMap, blockColMap,
1726 blockDomainMap, rowMap);
1731template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1733 Teuchos::RCP<Matrix> &P_nodal,
1734 Teuchos::RCP<MultiVector> &Nullspace_nodal,
1735 Teuchos::RCP<RealValuedMultiVector> &CoarseCoords_nodal)
const {
1736 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"nodal prolongator");
1742 const SC SC_ONE = Teuchos::ScalarTraits<SC>::one();
1745 Level fineLevel, coarseLevel;
1751 fineLevel.
Set(
"A", A_nodal);
1753 fineLevel.
Set(
"DofsPerNode", 1);
1754 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1755 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1756 coarseLevel.setObjectLabel(A_nodal->getObjectLabel());
1757 fineLevel.setObjectLabel(A_nodal->getObjectLabel());
1760 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1761 nullSpace->putScalar(SC_ONE);
1762 fineLevel.
Set(
"Nullspace", nullSpace);
1764 std::string algo =
parameterList_.get<std::string>(
"multigrid algorithm");
1766 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1780 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1782 double dropTol =
parameterList_.get<
double>(
"aggregation: drop tol");
1783 std::string dropScheme =
parameterList_.get<std::string>(
"aggregation: drop scheme");
1784 std::string distLaplAlgo =
parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1785 dropFact->SetParameter(
"aggregation: drop tol", Teuchos::ParameterEntry(dropTol));
1786 dropFact->SetParameter(
"aggregation: drop scheme", Teuchos::ParameterEntry(dropScheme));
1787 dropFact->SetParameter(
"aggregation: distance laplacian algo", Teuchos::ParameterEntry(distLaplAlgo));
1789 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1790 int minAggSize =
parameterList_.get<
int>(
"aggregation: min agg size");
1791 UncoupledAggFact->SetParameter(
"aggregation: min agg size", Teuchos::ParameterEntry(minAggSize));
1792 int maxAggSize =
parameterList_.get<
int>(
"aggregation: max agg size");
1793 UncoupledAggFact->SetParameter(
"aggregation: max agg size", Teuchos::ParameterEntry(maxAggSize));
1794 bool matchMLbehavior1 =
parameterList_.get<
bool>(
"aggregation: match ML phase1");
1795 UncoupledAggFact->SetParameter(
"aggregation: match ML phase1", Teuchos::ParameterEntry(matchMLbehavior1));
1796 bool matchMLbehavior2a =
parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1797 UncoupledAggFact->SetParameter(
"aggregation: match ML phase2a", Teuchos::ParameterEntry(matchMLbehavior2a));
1798 bool matchMLbehavior2b =
parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1799 UncoupledAggFact->SetParameter(
"aggregation: match ML phase2b", Teuchos::ParameterEntry(matchMLbehavior2b));
1801 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1803 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1804 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1805 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1807 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1808 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1811 SaPFact->SetFactory(
"P", TentativePFact);
1812 coarseLevel.
Request(
"P", SaPFact.get());
1814 coarseLevel.
Request(
"P", TentativePFact.get());
1815 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1816 coarseLevel.
Request(
"Coordinates", Tfact.get());
1818 RCP<AggregationExportFactory> aggExport;
1819 bool exportVizData =
parameterList_.get<
bool>(
"aggregation: export visualization data");
1820 if (exportVizData) {
1822 ParameterList aggExportParams;
1823 aggExportParams.set(
"aggregation: output filename",
"aggs.vtk");
1824 aggExportParams.set(
"aggregation: output file: agg style",
"Jacks");
1825 aggExport->SetParameterList(aggExportParams);
1827 aggExport->SetFactory(
"Aggregates", UncoupledAggFact);
1828 aggExport->SetFactory(
"UnAmalgamationInfo", amalgFact);
1829 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1830 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1834 coarseLevel.
Get(
"P", P_nodal, SaPFact.get());
1836 coarseLevel.
Get(
"P", P_nodal, TentativePFact.get());
1837 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.get());
1838 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.get());
1841 aggExport->Build(fineLevel, coarseLevel);
1845template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1846Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1848 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"vectorial nodal prolongator");
1851 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1853 typedef typename Matrix::local_matrix_device_type KCRS;
1854 typedef typename KCRS::StaticCrsGraphType graph_t;
1855 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1856 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1857 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1862 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1863 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1864 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1867 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1869 size_t numLocalRows = blockRowMap->getLocalNumElements();
1870 size_t numLocalColumns = blockColMap->getLocalNumElements();
1871 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1872 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1873 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1874 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1877 Kokkos::parallel_for(
1878 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1879 range_type(0, localP_nodal.numRows() + 1),
1881 if (i < localP_nodal.numRows()) {
1882 for (
size_t k = 0; k < dim; k++) {
1883 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1886 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1890 Kokkos::parallel_for(
1891 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1892 range_type(0, localP_nodal.graph.entries.size()),
1893 KOKKOS_LAMBDA(
const size_t jj) {
1894 for (
size_t k = 0; k < dim; k++) {
1895 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1897 vals(dim * jj + k) = 1.;
1901 typename CrsMatrix::local_matrix_device_type lclVectorNodalP(
"local vector nodal prolongator",
1902 numLocalRows, numLocalColumns, nnzEstimate,
1903 vals, rowptr, colind);
1904 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1905 blockRowMap, blockColMap,
1906 blockDomainMap, blockRowMap);
1908 return vectorNodalP;
1911template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1914 const Teuchos::RCP<Matrix> &A_nodal,
1915 const Teuchos::RCP<MultiVector> &Nullspace,
1916 Teuchos::RCP<Matrix> &Prolongator,
1917 Teuchos::RCP<MultiVector> &coarseNullspace,
1918 Teuchos::RCP<RealValuedMultiVector> &coarseNodalCoords)
const {
1919 using ATS = KokkosKernels::ArithTraits<Scalar>;
1920 using impl_Scalar =
typename ATS::val_type;
1921 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1923 std::string typeStr;
1924 switch (spaceNumber) {
1927 TEUCHOS_ASSERT(A_nodal.is_null());
1936 TEUCHOS_ASSERT(
false);
1939 const bool skipFirstLevel = !A_nodal.is_null();
1941 RCP<Teuchos::TimeMonitor> tm;
1942 if (spaceNumber > 0) {
1943 tm =
getTimer(
"special prolongator " + typeStr);
1948 dump(projection, typeStr +
"Projection.m");
1950 if (skipFirstLevel) {
1951 RCP<Matrix> P_nodal;
1952 RCP<MultiVector> coarseNodalNullspace;
1956 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1957 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1961 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1963 Prolongator = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator,
GetOStream(
Runtime0),
true,
true);
2012 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
2014 auto localNullspace_nodal = coarseNodalNullspace->getLocalViewDevice(Tpetra::Access::ReadOnly);
2015 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
2016 Kokkos::parallel_for(
2017 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2018 range_type(0, coarseNodalNullspace->getLocalLength()),
2019 KOKKOS_LAMBDA(
const size_t i) {
2020 impl_Scalar val = localNullspace_nodal(i, 0);
2021 for (
size_t j = 0; j < dim; j++)
2022 localNullspace_coarse(dim * i + j, j) = val;
2026 Prolongator = projection;
2029 if (spaceNumber == 0) {
2031 }
else if (spaceNumber >= 1) {
2033 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
2034 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Tpetra::Access::ReadWrite);
2035 Kokkos::parallel_for(
2036 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2037 range_type(0, coarseNullspace->getLocalLength() / dim),
2038 KOKKOS_LAMBDA(
const size_t i) {
2039 for (
size_t j = 0; j < dim; j++)
2040 localNullspace_coarse(dim * i + j, j) = 1.0;
2046template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2048 Teuchos::RCP<Operator> &thyraPrecOp,
2049 const Teuchos::RCP<Matrix> &A,
2050 const Teuchos::RCP<MultiVector> &Nullspace,
2051 const Teuchos::RCP<RealValuedMultiVector> &Coords,
2052 const Teuchos::RCP<MultiVector> &Material,
2053 Teuchos::ParameterList ¶ms,
2056 const bool isSingular) {
2059 RCP<ParameterList> pl = rcp(
new ParameterList());
2060 pl->set(
"printLoadBalancingInfo",
true);
2061 pl->set(
"printCommInfo",
true);
2064#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2065 if (params.isType<std::string>(
"Preconditioner Type")) {
2066 TEUCHOS_ASSERT(!reuse);
2068 if (params.get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2069 ParameterList &userParamList = params.sublist(
"Preconditioner Types").sublist(
"MueLu").sublist(
"user data");
2070 if (!Nullspace.is_null())
2071 userParamList.set<RCP<MultiVector>>(
"Nullspace", Nullspace);
2072 if (!Material.is_null())
2073 userParamList.set<RCP<MultiVector>>(
"Material", Material);
2074 userParamList.set<RCP<RealValuedMultiVector>>(
"Coordinates", Coords);
2076 thyraPrecOp = rcp(
new XpetraThyraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(
coarseA11_, rcp(¶ms,
false)));
2083 ParameterList &userParamList = params.sublist(
"user data");
2084 if (!Coords.is_null())
2085 userParamList.set<RCP<RealValuedMultiVector>>(
"Coordinates", Coords);
2086 if (!Nullspace.is_null())
2087 userParamList.set<RCP<MultiVector>>(
"Nullspace", Nullspace);
2088 if (!Material.is_null())
2089 userParamList.set<RCP<MultiVector>>(
"Material", Material);
2092 std::string coarseType =
"";
2093 if (params.isParameter(
"coarse: type")) {
2094 coarseType = params.get<std::string>(
"coarse: type");
2096 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(), ::tolower);
2097 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
2099 if ((coarseType ==
"" ||
2100 coarseType ==
"Klu" ||
2101 coarseType ==
"Klu2" ||
2102 coarseType ==
"Superlu" ||
2103 coarseType ==
"Superlu_dist" ||
2104 coarseType ==
"Superludist" ||
2105 coarseType ==
"Basker" ||
2106 coarseType ==
"Cusolver" ||
2107 coarseType ==
"Tacho") &&
2108 (!params.isSublist(
"coarse: params") ||
2109 !params.sublist(
"coarse: params").isParameter(
"fix nullspace")))
2110 params.sublist(
"coarse: params").set(
"fix nullspace",
true);
2115 RCP<MueLu::Level> level0 = hierarchy->GetLevel(0);
2116 level0->Set(
"A", A);
2117 hierarchy->SetupRe();
2123template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2132template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2168 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
2172 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"residual calculation");
2180 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"restriction coarse (1,1) (implicit)");
2184 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restriction (2,2) (implicit)");
2191 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restrictions import");
2195 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restriction (2,2) (explicit)");
2199 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"restriction coarse (1,1) (explicit)");
2204 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"restriction coarse (1,1) (explicit)");
2208 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"restriction (2,2) (explicit)");
2216 RCP<Teuchos::TimeMonitor> tmSubSolves =
getTimer(
"subsolves");
2221 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"import coarse (1,1)");
2225 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"import (2,2)");
2234 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"solve coarse (1,1)",
coarseA11_->getRowMap()->getComm());
2236#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2238 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
2246 if (!
A22_.is_null()) {
2250 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"solve (2,2)",
A22_->getRowMap()->getComm());
2251#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2253 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
2267 RCP<Teuchos::TimeMonitor> tmProlongations =
getTimer(
"prolongations");
2270 using Tpetra_Multivector = Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
2271 using Tpetra_Import = Tpetra::Import<LocalOrdinal, GlobalOrdinal, Node>;
2273 auto tpP11 = toTpetra(
P11_);
2274 auto tpDk_1 = toTpetra(
Dk_1_);
2276 RCP<Tpetra_Multivector> tpP11x = toTpetra(
P11x_);
2277 RCP<Tpetra_Multivector> tpP11x_colmap;
2278 RCP<Tpetra_Multivector> tpX = toTpetra(Teuchos::rcpFromRef(X));
2279 RCP<Tpetra_Multivector> tpResidual = toTpetra(
residual_);
2280 RCP<Tpetra_Multivector> tpDx = toTpetra(
Dx_);
2281 RCP<Tpetra_Multivector> tpDx_colmap;
2283 unsigned completedImports = 0;
2284 std::vector<bool> completedImport(2,
false);
2285 auto tpP11importer = tpP11->getCrsGraph()->getImporter();
2286 if (!tpP11importer.is_null()) {
2288 tpP11x_colmap->beginImport(*tpP11x, *tpP11importer, Tpetra::INSERT);
2291 RCP<const Tpetra_Import> tpDk_1importer;
2293 tpDk_1importer = tpDk_1->getCrsGraph()->getImporter();
2294 if (!tpDk_1importer.is_null()) {
2296 tpDx_colmap->beginImport(*tpDx, *tpDk_1importer, Tpetra::INSERT);
2299 completedImport[1] =
true;
2304 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
2305 tpResidual->putScalar(zero);
2308 while (completedImports < completedImport.size()) {
2309 for (
unsigned i = 0; i < completedImport.size(); i++) {
2310 if (completedImport[i])
continue;
2313 if (!tpP11importer.is_null()) {
2314 if (tpP11x_colmap->transferArrived()) {
2315 tpP11x_colmap->endImport(*tpP11x, *tpP11importer, Tpetra::INSERT);
2316 completedImport[i] =
true;
2320 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (fused, local)");
2321 tpP11->localApply(*tpP11x_colmap, *tpX, Teuchos::NO_TRANS, one, one);
2323 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (unfused, local)");
2324 tpP11->localApply(*tpP11x_colmap, *tpResidual, Teuchos::NO_TRANS, one, one);
2328 completedImport[i] =
true;
2332 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (fused, local)");
2333 tpP11->localApply(*tpP11x, *tpX, Teuchos::NO_TRANS, one, one);
2335 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (unfused, local)");
2336 tpP11->localApply(*tpP11x, *tpResidual, Teuchos::NO_TRANS, one, one);
2340 if (!tpDk_1importer.is_null()) {
2341 if (tpDx_colmap->transferArrived()) {
2342 tpDx_colmap->endImport(*tpDx, *tpDk_1importer, Tpetra::INSERT);
2343 completedImport[i] =
true;
2347 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (fused, local)");
2348 tpDk_1->localApply(*tpDx_colmap, *tpX, Teuchos::NO_TRANS, one, one);
2350 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (unfused, local)");
2351 tpDk_1->localApply(*tpDx_colmap, *tpResidual, Teuchos::NO_TRANS, one, one);
2355 completedImport[i] =
true;
2359 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (fused, local)");
2360 tpDk_1->localApply(*tpDx, *tpX, Teuchos::NO_TRANS, one, one);
2362 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (unfused, local)");
2363 tpDk_1->localApply(*tpDx, *tpResidual, Teuchos::NO_TRANS, one, one);
2371 RCP<Teuchos::TimeMonitor> tmUpdate =
getTimer(
"update");
2377 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (fused)");
2378 P11_->apply(*
P11x_, X, Teuchos::NO_TRANS, one, one);
2382 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (fused)");
2383 Dk_1_->apply(*
Dx_, X, Teuchos::NO_TRANS, one, one);
2387 RCP<Teuchos::TimeMonitor> tmP11 =
getTimer(
"prolongation coarse (1,1) (unfused)");
2392 RCP<Teuchos::TimeMonitor> tmD =
getTimer(
"prolongation (2,2) (unfused)");
2397 RCP<Teuchos::TimeMonitor> tmUpdate =
getTimer(
"update");
2405template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2407 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
2410 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"residual calculation");
2420 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"import coarse (1,1)");
2424 RCP<Teuchos::TimeMonitor> tmH =
getTimer(
"solve coarse (1,1)",
coarseA11_->getRowMap()->getComm());
2430 RCP<Teuchos::TimeMonitor> tmUp =
getTimer(
"update");
2436template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2441 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
2444 RCP<Teuchos::TimeMonitor> tmRes =
getTimer(
"residual calculation");
2454 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"import (2,2)");
2457 if (!
A22_.is_null()) {
2458 RCP<Teuchos::TimeMonitor> tm22 =
getTimer(
"solve (2,2)",
A22_->getRowMap()->getComm());
2464 RCP<Teuchos::TimeMonitor> tmUp =
getTimer(
"update");
2470template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2475 RCP<Teuchos::TimeMonitor> tm =
getTimer(
"solve");
2483 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2489 if (
mode_ ==
"additive")
2491 else if (
mode_ ==
"121") {
2495 }
else if (
mode_ ==
"212") {
2499 }
else if (
mode_ ==
"1")
2501 else if (
mode_ ==
"2")
2503 else if (
mode_ ==
"7") {
2507 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2514 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2519 }
else if (
mode_ ==
"none") {
2526 RCP<Teuchos::TimeMonitor> tmSm =
getTimer(
"smoothing");
2532template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2537template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2538std::pair<std::set<std::string>, std::set<std::string>>
2541 std::set<std::string> requiredUserData;
2542 int spaceNumber = 1;
2543 if (params.isType<
int>(
"refmaxwell: space number"))
2544 spaceNumber = params.get<
int>(
"refmaxwell: space number");
2546 if (params.isType<
bool>(
"refmaxwell: disable addon"))
2547 disable_addon = params.get<
bool>(
"refmaxwell: disable addon");
2548 bool disable_addon22 =
true;
2549 if (params.isType<
bool>(
"refmaxwell: disable addon 22"))
2550 disable_addon22 = params.get<
bool>(
"refmaxwell: disable addon 22");
2552 requiredUserData.insert(
"Coordinates");
2553 requiredUserData.insert(
"Dk_1");
2555 requiredUserData.insert(
"M1_beta");
2556 if (spaceNumber >= 2)
2557 requiredUserData.insert(
"M1_alpha");
2559 if (!disable_addon) {
2560 requiredUserData.insert(
"Mk_one");
2561 requiredUserData.insert(
"invMk_1_invBeta");
2564 if ((spaceNumber >= 2) && (!disable_addon22)) {
2565 requiredUserData.insert(
"Dk_2");
2566 requiredUserData.insert(
"Mk_1_one");
2567 requiredUserData.insert(
"invMk_2_invAlpha");
2573 if (requiredUserData11.contains(
"Material") || requiredUserData22.contains(
"Material"))
2574 requiredUserData.insert(
"Material");
2576 std::set<std::string> optionalUserData;
2577 optionalUserData.insert(
"Nullspace11");
2578 optionalUserData.insert(
"Nullspace22");
2580 return std::make_pair(requiredUserData, optionalUserData);
2583template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2585 RefMaxwell(
const Teuchos::RCP<Matrix> &SM_Matrix,
2586 Teuchos::ParameterList &List,
2588 int spaceNumber = List.get<
int>(
"refmaxwell: space number", 1);
2590 RCP<Matrix> Dk_1, Dk_2, D0;
2591 RCP<Matrix> M1_beta, M1_alpha;
2592 RCP<Matrix> Mk_one, Mk_1_one;
2593 RCP<Matrix> invMk_1_invBeta, invMk_2_invAlpha;
2594 RCP<MultiVector> Nullspace11, Nullspace22;
2595 RCP<RealValuedMultiVector> NodalCoords;
2597 auto &userData = List.sublist(
"user data");
2599 Dk_1 =
pop(List, userData,
"Dk_1", Dk_1);
2600 Dk_2 =
pop(List, userData,
"Dk_2", Dk_2);
2601 D0 =
pop(List, userData,
"D0", D0);
2603 M1_beta =
pop(List, userData,
"M1_beta", M1_beta);
2604 M1_alpha =
pop(List, userData,
"M1_alpha", M1_alpha);
2606 Mk_one =
pop(List, userData,
"Mk_one", Mk_one);
2607 Mk_1_one =
pop(List, userData,
"Mk_1_one", Mk_1_one);
2609 invMk_1_invBeta =
pop(List, userData,
"invMk_1_invBeta", invMk_1_invBeta);
2610 invMk_2_invAlpha =
pop(List, userData,
"invMk_2_invAlpha", invMk_2_invAlpha);
2612 Nullspace11 =
pop(List, userData,
"Nullspace11", Nullspace11);
2613 Nullspace22 =
pop(List, userData,
"Nullspace22", Nullspace22);
2614 NodalCoords =
pop(List, userData,
"Coordinates", NodalCoords);
2617 if (List.isType<RCP<Matrix>>(
"Ms")) {
2618 if (M1_beta.is_null())
2621 TEUCHOS_ASSERT(
false);
2623 if (List.isType<RCP<Matrix>>(
"M1")) {
2624 if (Mk_one.is_null())
2627 TEUCHOS_ASSERT(
false);
2629 if (List.isType<RCP<Matrix>>(
"M0inv")) {
2630 if (invMk_1_invBeta.is_null())
2633 TEUCHOS_ASSERT(
false);
2635 if (List.isType<RCP<MultiVector>>(
"Nullspace")) {
2636 if (Nullspace11.is_null())
2639 TEUCHOS_ASSERT(
false);
2642 if (spaceNumber == 1) {
2645 else if (D0.is_null())
2647 if (M1_beta.is_null())
2649 }
else if (spaceNumber == 2) {
2652 else if (D0.is_null())
2660 invMk_1_invBeta, invMk_2_invAlpha,
2661 Nullspace11, Nullspace22,
2663 Teuchos::null, Teuchos::null,
2666 if (SM_Matrix != Teuchos::null)
2670template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2672 initialize(
const Teuchos::RCP<Matrix> &D0_Matrix,
2673 const Teuchos::RCP<Matrix> &Ms_Matrix,
2674 const Teuchos::RCP<Matrix> &M0inv_Matrix,
2675 const Teuchos::RCP<Matrix> &M1_Matrix,
2676 const Teuchos::RCP<MultiVector> &Nullspace11,
2677 const Teuchos::RCP<RealValuedMultiVector> &NodalCoords,
2678 const Teuchos::RCP<MultiVector> &Material,
2679 Teuchos::ParameterList &List) {
2681 D0_Matrix, Teuchos::null, D0_Matrix,
2682 Ms_Matrix, Teuchos::null,
2683 M1_Matrix, Teuchos::null,
2684 M0inv_Matrix, Teuchos::null,
2685 Nullspace11, Teuchos::null,
2687 Teuchos::null, Material,
2691template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2694 const Teuchos::RCP<Matrix> &Dk_1,
2695 const Teuchos::RCP<Matrix> &Dk_2,
2696 const Teuchos::RCP<Matrix> &D0,
2697 const Teuchos::RCP<Matrix> &M1_beta,
2698 const Teuchos::RCP<Matrix> &M1_alpha,
2699 const Teuchos::RCP<Matrix> &Mk_one,
2700 const Teuchos::RCP<Matrix> &Mk_1_one,
2701 const Teuchos::RCP<Matrix> &invMk_1_invBeta,
2702 const Teuchos::RCP<Matrix> &invMk_2_invAlpha,
2703 const Teuchos::RCP<MultiVector> &Nullspace11,
2704 const Teuchos::RCP<MultiVector> &Nullspace22,
2705 const Teuchos::RCP<RealValuedMultiVector> &NodalCoords,
2706 const Teuchos::RCP<MultiVector> &Material_beta,
2707 const Teuchos::RCP<MultiVector> &Material_alpha,
2708 Teuchos::ParameterList &List) {
2715 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
2716 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2729 TEUCHOS_ASSERT((k == 1) || (k == 2));
2731 TEUCHOS_ASSERT(Dk_1 != Teuchos::null);
2733 TEUCHOS_ASSERT(D0 != Teuchos::null);
2736 TEUCHOS_ASSERT(M1_beta != Teuchos::null);
2739 TEUCHOS_ASSERT(M1_alpha != Teuchos::null);
2743 TEUCHOS_ASSERT(Mk_one != Teuchos::null);
2744 TEUCHOS_ASSERT(invMk_1_invBeta != Teuchos::null);
2749 TEUCHOS_ASSERT(Dk_2 != Teuchos::null);
2750 TEUCHOS_ASSERT(Mk_1_one != Teuchos::null);
2751 TEUCHOS_ASSERT(invMk_2_invAlpha != Teuchos::null);
2755 TEUCHOS_ASSERT(D0->getRangeMap()->isSameAs(*D0->getRowMap()));
2758 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2759 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2762 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2766 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2767 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2770 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()));
2775 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2776 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2779 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2782 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2783 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2786 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2791 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2792 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2795 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2798 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2801 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2802 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2805 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2810 if (Dk_1->getRowMap()->lib() == Xpetra::UseTpetra) {
2815 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2816 RCP<CrsMatrix> Dk_1copyCrs = toCrsMatrix(Dk_1copy);
2817 ArrayRCP<const size_t> Dk_1rowptr_RCP;
2818 ArrayRCP<const LO> Dk_1colind_RCP;
2819 ArrayRCP<const SC> Dk_1vals_RCP;
2820 toCrsMatrix(Dk_1)->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2822 ArrayRCP<size_t> Dk_1copyrowptr_RCP;
2823 ArrayRCP<LO> Dk_1copycolind_RCP;
2824 ArrayRCP<SC> Dk_1copyvals_RCP;
2825 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2826 Dk_1copyrowptr_RCP.deepCopy(Dk_1rowptr_RCP());
2827 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2828 Dk_1copyvals_RCP.deepCopy(Dk_1vals_RCP());
2829 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2832 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2833 toCrsMatrix(Dk_1)->getCrsGraph()->getImporter(),
2834 toCrsMatrix(Dk_1)->getCrsGraph()->getExporter());
2837 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2839 if ((!Dk_2.is_null()) && (Dk_2->getRowMap()->lib() == Xpetra::UseTpetra)) {
2844 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2845 RCP<CrsMatrix> Dk_2copyCrs = toCrsMatrix(Dk_2copy);
2846 ArrayRCP<const size_t> Dk_2rowptr_RCP;
2847 ArrayRCP<const LO> Dk_2colind_RCP;
2848 ArrayRCP<const SC> Dk_2vals_RCP;
2849 toCrsMatrix(Dk_2)->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2851 ArrayRCP<size_t> Dk_2copyrowptr_RCP;
2852 ArrayRCP<LO> Dk_2copycolind_RCP;
2853 ArrayRCP<SC> Dk_2copyvals_RCP;
2854 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2855 Dk_2copyrowptr_RCP.deepCopy(Dk_2rowptr_RCP());
2856 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2857 Dk_2copyvals_RCP.deepCopy(Dk_2vals_RCP());
2858 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2861 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2862 toCrsMatrix(Dk_2)->getCrsGraph()->getImporter(),
2863 toCrsMatrix(Dk_2)->getCrsGraph()->getExporter());
2865 }
else if (!Dk_2.is_null())
2866 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2900template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2902 describe(Teuchos::FancyOStream &out,
const Teuchos::EVerbosityLevel )
const {
2903 std::ostringstream oss;
2905 RCP<const Teuchos::Comm<int>> comm =
SM_Matrix_->getDomainMap()->getComm();
2910 root = comm->getRank();
2915 reduceAll(*comm, Teuchos::REDUCE_MAX, root, Teuchos::ptr(&actualRoot));
2919 oss <<
"\n--------------------------------------------------------------------------------\n"
2922 "--------------------------------------------------------------------------------"
2929 SM_Matrix_->getRowMap()->getComm()->barrier();
2934 Xpetra::global_size_t tt = numRows;
2947 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2948 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2954 if (!
A22_.is_null()) {
2955 numRows =
A22_->getGlobalNumRows();
2956 if (Xpetra::toTpetra(
A22_)->haveGlobalConstants())
2957 nnz =
A22_->getGlobalNumEntries();
2959 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, numRows, Teuchos::ptr(&numRowsGlobal));
2960 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, nnz, Teuchos::ptr(&numNNZGlobal));
2962 if (numRowsGlobal > 0)
2963 oss <<
"(2, 2)" << std::setw(rowspacer) << numRowsGlobal << std::setw(nnzspacer) << numNNZGlobal << std::setw(9) << as<double>(numNNZGlobal) / numRowsGlobal << std::endl;
2965 oss <<
"(2, 2)" << std::setw(rowspacer) << numRowsGlobal << std::setw(nnzspacer) << numNNZGlobal << std::endl;
2971 oss <<
"Smoother 11 both : " <<
PreSmoother11_->description() << std::endl;
2973 oss <<
"Smoother 11 pre : "
2975 oss <<
"Smoother 11 post : "
2981 std::string outstr = oss.str();
2984 RCP<const Teuchos::MpiComm<int>> mpiComm = rcp_dynamic_cast<const Teuchos::MpiComm<int>>(comm);
2985 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2987 int strLength = outstr.size();
2988 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2989 if (comm->getRank() != root)
2990 outstr.resize(strLength);
2991 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
3004 std::ostringstream oss2;
3006 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
3007 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;
3009 int numProcs = comm->getSize();
3011 RCP<const Teuchos::MpiComm<int>> tmpic = rcp_dynamic_cast<const Teuchos::MpiComm<int>>(comm);
3012 TEUCHOS_TEST_FOR_EXCEPTION(tmpic == Teuchos::null,
Exceptions::RuntimeError,
"Cannot cast base Teuchos::Comm to Teuchos::MpiComm object.");
3013 RCP<const Teuchos::OpaqueWrapper<MPI_Comm>> rawMpiComm = tmpic->getRawMpiComm();
3019 if (!
A22_.is_null())
3021 std::vector<char> states(numProcs, 0);
3023 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
3025 states.push_back(status);
3028 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
3029 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
3030 for (
int j = 0; j < rowWidth; j++)
3031 if (proc + j < numProcs)
3032 if (states[proc + j] == 0)
3034 else if (states[proc + j] == 1)
3036 else if (states[proc + j] == 2)
3043 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
3052#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.
static bool debug()
Whether MueLu is in debug mode.
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 Teuchos::RCP< Teuchos::ParameterList > translate(const 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)
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::pair< std::set< std::string >, std::set< std::string > > requiredAndOptionalUserData(const Teuchos::ParameterList ¶mList, Teuchos::RCP< const Teuchos::ParameterList > defaultList=Teuchos::null, int maxLevel=0)
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_
static std::pair< std::set< std::string >, std::set< std::string > > requiredAndOptionalUserData(const Teuchos::ParameterList ¶ms)
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,...