10 #ifndef MUELU_REFMAXWELL_DEF_HPP
11 #define MUELU_REFMAXWELL_DEF_HPP
17 #include "Teuchos_CompilerCodeTweakMacros.hpp"
18 #include "Tpetra_CrsMatrix.hpp"
20 #include "Xpetra_Map.hpp"
29 #include "MueLu_AmalgamationFactory.hpp"
30 #include "MueLu_RAPFactory.hpp"
31 #include "MueLu_SmootherFactory.hpp"
33 #include "MueLu_CoalesceDropFactory.hpp"
34 #include "MueLu_CoarseMapFactory.hpp"
35 #include "MueLu_CoordinatesTransferFactory.hpp"
36 #include "MueLu_UncoupledAggregationFactory.hpp"
37 #include "MueLu_TentativePFactory.hpp"
38 #include "MueLu_SaPFactory.hpp"
39 #include "MueLu_AggregationExportFactory.hpp"
40 #include "MueLu_Utilities.hpp"
41 #include "MueLu_Maxwell_Utils.hpp"
43 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
44 #include "MueLu_TentativePFactory_kokkos.hpp"
45 #include <Kokkos_Core.hpp>
46 #include <KokkosSparse_CrsMatrix.hpp>
48 #include "MueLu_ZoltanInterface.hpp"
49 #include "MueLu_Zoltan2Interface.hpp"
50 #include "MueLu_RepartitionHeuristicFactory.hpp"
51 #include "MueLu_RepartitionFactory.hpp"
52 #include "MueLu_RebalanceAcFactory.hpp"
53 #include "MueLu_RebalanceTransferFactory.hpp"
60 #ifdef HAVE_MUELU_CUDA
61 #include "cuda_profiler_api.h"
65 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
73 T result = pl.
get<T>(name_in);
80 T result = pl.
get<T>(name_in, def_value);
85 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
87 return SM_Matrix_->getDomainMap();
90 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
92 return SM_Matrix_->getRangeMap();
95 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
99 bool useKokkosDefault = !Node::is_serial;
126 params->
set(
"refmaxwell: space number", 1,
"", spaceValidator);
127 params->
set(
"verbosity", MasterList::getDefault<std::string>(
"verbosity"));
128 params->
set(
"use kokkos refactor", useKokkosDefault);
129 params->
set(
"half precision",
false);
130 params->
set(
"parameterlist: syntax", MasterList::getDefault<std::string>(
"parameterlist: syntax"));
131 params->
set(
"output filename", MasterList::getDefault<std::string>(
"output filename"));
132 params->
set(
"print initial parameters", MasterList::getDefault<bool>(
"print initial parameters"));
133 params->
set(
"refmaxwell: disable addon", MasterList::getDefault<bool>(
"refmaxwell: disable addon"));
134 params->
set(
"refmaxwell: disable addon 22",
true);
135 params->
set(
"refmaxwell: mode", MasterList::getDefault<std::string>(
"refmaxwell: mode"));
136 params->
set(
"refmaxwell: use as preconditioner", MasterList::getDefault<bool>(
"refmaxwell: use as preconditioner"));
137 params->
set(
"refmaxwell: dump matrices", MasterList::getDefault<bool>(
"refmaxwell: dump matrices"));
138 params->
set(
"refmaxwell: enable reuse", MasterList::getDefault<bool>(
"refmaxwell: enable reuse"));
139 params->
set(
"refmaxwell: skip first (1,1) level", MasterList::getDefault<bool>(
"refmaxwell: skip first (1,1) level"));
140 params->
set(
"refmaxwell: skip first (2,2) level",
false);
141 params->
set(
"multigrid algorithm",
"Unsmoothed");
142 params->
set(
"transpose: use implicit", MasterList::getDefault<bool>(
"transpose: use implicit"));
143 params->
set(
"rap: triple product", MasterList::getDefault<bool>(
"rap: triple product"));
144 params->
set(
"rap: fix zero diagonals",
true);
145 params->
set(
"rap: fix zero diagonals threshold", MasterList::getDefault<double>(
"rap: fix zero diagonals threshold"));
146 params->
set(
"fuse prolongation and update", MasterList::getDefault<bool>(
"fuse prolongation and update"));
147 params->
set(
"refmaxwell: async transfers", Node::is_gpu);
148 params->
set(
"refmaxwell: subsolves on subcommunicators", MasterList::getDefault<bool>(
"refmaxwell: subsolves on subcommunicators"));
149 params->
set(
"refmaxwell: subsolves striding", 1);
150 params->
set(
"refmaxwell: row sum drop tol (1,1)", MasterList::getDefault<double>(
"aggregation: row sum drop tol"));
151 params->
set(
"sync timers",
false);
152 params->
set(
"refmaxwell: num iters coarse 11", 1);
153 params->
set(
"refmaxwell: num iters 22", 1);
154 params->
set(
"refmaxwell: apply BCs to Anodal",
false);
155 params->
set(
"refmaxwell: apply BCs to coarse 11",
true);
156 params->
set(
"refmaxwell: apply BCs to 22",
true);
157 params->
set(
"refmaxwell: max coarse size", 1);
164 params->
set(
"smoother: type",
"CHEBYSHEV");
167 params->
set(
"smoother: pre type",
"NONE");
170 params->
set(
"smoother: post type",
"NONE");
183 params->
set(
"multigrid algorithm",
"unsmoothed");
184 params->
set(
"aggregation: type", MasterList::getDefault<std::string>(
"aggregation: type"));
185 params->
set(
"aggregation: drop tol", MasterList::getDefault<double>(
"aggregation: drop tol"));
186 params->
set(
"aggregation: drop scheme", MasterList::getDefault<std::string>(
"aggregation: drop scheme"));
187 params->
set(
"aggregation: distance laplacian algo", MasterList::getDefault<std::string>(
"aggregation: distance laplacian algo"));
188 params->
set(
"aggregation: min agg size", MasterList::getDefault<int>(
"aggregation: min agg size"));
189 params->
set(
"aggregation: max agg size", MasterList::getDefault<int>(
"aggregation: max agg size"));
190 params->
set(
"aggregation: match ML phase1", MasterList::getDefault<bool>(
"aggregation: match ML phase1"));
191 params->
set(
"aggregation: match ML phase2a", MasterList::getDefault<bool>(
"aggregation: match ML phase2a"));
192 params->
set(
"aggregation: match ML phase2b", MasterList::getDefault<bool>(
"aggregation: match ML phase2b"));
193 params->
set(
"aggregation: export visualization data", MasterList::getDefault<bool>(
"aggregation: export visualization data"));
198 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
200 if (list.
isType<std::string>(
"parameterlist: syntax") && list.
get<std::string>(
"parameterlist: syntax") ==
"ml") {
205 for (
auto it = newList2.
begin(); it != newList2.
end(); ++it) {
206 const std::string &entry_name = it->first;
209 newList.
setEntry(entry_name, theEntry);
216 if (list.
isSublist(
"refmaxwell: 22list"))
221 parameterList_ = list;
223 std::string verbosityLevel = parameterList_.get<std::string>(
"verbosity");
225 std::string outputFilename = parameterList_.get<std::string>(
"output filename");
226 if (outputFilename !=
"")
231 if (parameterList_.get<
bool>(
"print initial parameters"))
232 GetOStream(static_cast<MsgType>(
Runtime1), 0) << parameterList_ << std::endl;
233 disable_addon_ = parameterList_.get<
bool>(
"refmaxwell: disable addon");
234 disable_addon_22_ = parameterList_.get<
bool>(
"refmaxwell: disable addon 22");
235 mode_ = parameterList_.get<std::string>(
"refmaxwell: mode");
236 use_as_preconditioner_ = parameterList_.get<
bool>(
"refmaxwell: use as preconditioner");
237 dump_matrices_ = parameterList_.get<
bool>(
"refmaxwell: dump matrices");
238 enable_reuse_ = parameterList_.get<
bool>(
"refmaxwell: enable reuse");
239 implicitTranspose_ = parameterList_.get<
bool>(
"transpose: use implicit");
240 fuseProlongationAndUpdate_ = parameterList_.get<
bool>(
"fuse prolongation and update");
241 skipFirst11Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (1,1) level");
242 skipFirst22Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (2,2) level");
243 if (spaceNumber_ == 1)
244 skipFirst22Level_ =
false;
245 syncTimers_ = parameterList_.get<
bool>(
"sync timers");
246 useKokkos_ = parameterList_.get<
bool>(
"use kokkos refactor");
247 numItersCoarse11_ = parameterList_.get<
int>(
"refmaxwell: num iters coarse 11");
248 numIters22_ = parameterList_.get<
int>(
"refmaxwell: num iters 22");
249 applyBCsToAnodal_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to Anodal");
250 applyBCsToCoarse11_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to coarse 11");
251 applyBCsTo22_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to 22");
253 precList11_ = parameterList_.sublist(
"refmaxwell: 11list");
254 if (!precList11_.isType<std::string>(
"Preconditioner Type") &&
255 !precList11_.isType<std::string>(
"smoother: type") &&
256 !precList11_.isType<std::string>(
"smoother: pre type") &&
257 !precList11_.isType<std::string>(
"smoother: post type")) {
258 precList11_.set(
"smoother: type",
"CHEBYSHEV");
259 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
260 precList11_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 5.4);
261 precList11_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
264 precList22_ = parameterList_.sublist(
"refmaxwell: 22list");
265 if (!precList22_.isType<std::string>(
"Preconditioner Type") &&
266 !precList22_.isType<std::string>(
"smoother: type") &&
267 !precList22_.isType<std::string>(
"smoother: pre type") &&
268 !precList22_.isType<std::string>(
"smoother: post type")) {
269 precList22_.set(
"smoother: type",
"CHEBYSHEV");
270 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
271 precList22_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
272 precList22_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
275 if (!parameterList_.isType<std::string>(
"smoother: type") && !parameterList_.isType<std::string>(
"smoother: pre type") && !parameterList_.isType<std::string>(
"smoother: post type")) {
276 list.
set(
"smoother: type",
"CHEBYSHEV");
277 list.
sublist(
"smoother: params").
set(
"chebyshev: degree", 2);
278 list.
sublist(
"smoother: params").
set(
"chebyshev: ratio eigenvalue", 20.0);
279 list.
sublist(
"smoother: params").
set(
"chebyshev: eigenvalue max iterations", 30);
283 !precList11_.isType<std::string>(
"Preconditioner Type") &&
284 !precList11_.isParameter(
"reuse: type"))
285 precList11_.
set(
"reuse: type",
"full");
287 !precList22_.isType<std::string>(
"Preconditioner Type") &&
288 !precList22_.isParameter(
"reuse: type"))
289 precList22_.
set(
"reuse: type",
"full");
292 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
294 using memory_space =
typename Node::device_type::memory_space;
296 #ifdef HAVE_MUELU_CUDA
297 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
300 std::string timerLabel;
302 timerLabel =
"compute (reuse)";
304 timerLabel =
"compute";
316 params->
set(
"printLoadBalancingInfo",
true);
317 params->
set(
"printCommInfo",
true);
324 magnitudeType rowSumTol = parameterList_.get<
double>(
"refmaxwell: row sum drop tol (1,1)");
326 BCrows11_, BCcols22_, BCdomain22_,
327 globalNumberBoundaryUnknowns11_,
328 globalNumberBoundaryUnknowns22_,
329 onlyBoundary11_, onlyBoundary22_);
330 if (spaceNumber_ == 2) {
331 Kokkos::View<bool *, memory_space> BCcolsEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), Dk_1_->getColMap()->getLocalNumElements());
332 Kokkos::View<bool *, memory_space> BCdomainEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), Dk_1_->getDomainMap()->getLocalNumElements());
335 Kokkos::View<bool *, memory_space> BCcolsNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), D0_->getColMap()->getLocalNumElements());
336 Kokkos::View<bool *, memory_space> BCdomainNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), D0_->getDomainMap()->getLocalNumElements());
338 BCdomain22_ = BCdomainNode;
341 GetOStream(
Statistics2) << solverName_ +
"::compute(): Detected " << globalNumberBoundaryUnknowns11_ <<
" BC rows and " << globalNumberBoundaryUnknowns22_ <<
" BC columns." << std::endl;
343 dump(BCrows11_,
"BCrows11.m");
344 dump(BCcols22_,
"BCcols22.m");
345 dump(BCdomain22_,
"BCdomain22.m");
348 if (onlyBoundary11_) {
351 GetOStream(
Warnings0) <<
"All unknowns of the (1,1) block have been detected as boundary unknowns!" << std::endl;
353 setFineLevelSmoother11();
359 dim_ = NodalCoords_->getNumVectors();
366 if (Nullspace11_ != null) {
367 TEUCHOS_ASSERT(Nullspace11_->getMap()->isCompatible(*(SM_Matrix_->getRowMap())));
368 }
else if (NodalCoords_ != null) {
369 Nullspace11_ = buildNullspace(spaceNumber_, BCrows11_, skipFirst11Level_);
371 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
377 if (skipFirst11Level_) {
379 std::string label(
"D0^T*M1_beta*D0");
382 if (applyBCsToAnodal_) {
386 A11_nodal->setObjectLabel(solverName_ +
" (1,1) A_nodal");
387 dump(A11_nodal,
"A11_nodal.m");
390 M1_beta_ = Teuchos::null;
393 buildProlongator(spaceNumber_, A11_nodal, Nullspace11_, P11_, NullspaceCoarse11_, CoordsCoarse11_);
400 if (Nullspace22_ != null) {
401 TEUCHOS_ASSERT(Nullspace22_->getMap()->isCompatible(*(Dk_1_->getDomainMap())));
402 }
else if (NodalCoords_ != null)
403 Nullspace22_ = buildNullspace(spaceNumber_ - 1, BCdomain22_, skipFirst22Level_);
405 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
411 if (skipFirst22Level_) {
413 std::string label(
"D0^T*M1_alpha*D0");
416 if (applyBCsToAnodal_) {
420 A22_nodal->setObjectLabel(solverName_ +
" (2,2) A_nodal");
421 dump(A22_nodal,
"A22_nodal.m");
424 M1_alpha_ = Teuchos::null;
427 buildProlongator(spaceNumber_ - 1, A22_nodal, Nullspace22_, P22_, CoarseNullspace22_, Coords22_);
435 buildCoarse11Matrix();
440 int rebalanceStriding, numProcsCoarseA11, numProcsA22;
442 this->determineSubHierarchyCommSizes(doRebalancing, rebalanceStriding, numProcsCoarseA11, numProcsA22);
444 doRebalancing =
false;
447 if (!reuse && doRebalancing)
448 rebalanceCoarse11Matrix(rebalanceStriding, numProcsCoarseA11);
449 if (!coarseA11_.is_null()) {
450 dump(coarseA11_,
"coarseA11.m");
452 dumpCoords(CoordsCoarse11_,
"CoordsCoarse11.m");
453 dump(NullspaceCoarse11_,
"NullspaceCoarse11.m");
458 if (!implicitTranspose_) {
465 if (!coarseA11_.is_null()) {
467 std::string label(
"coarseA11");
468 setupSubSolve(HierarchyCoarse11_, thyraPrecOpH_, coarseA11_, NullspaceCoarse11_, CoordsCoarse11_, Material_beta_, precList11_, label, reuse);
474 if (!reuse && applyBCsTo22_) {
475 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC columns of Dk_1" << std::endl;
480 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
485 if (!onlyBoundary22_) {
486 GetOStream(
Runtime0) << solverName_ +
"::compute(): building MG for (2,2)-block" << std::endl;
489 build22Matrix(reuse, doRebalancing, rebalanceStriding, numProcsA22);
491 if (!P22_.is_null()) {
492 std::string label(
"P22^T*A22*P22");
494 coarseA22_->SetFixedBlockSize(A22_->GetFixedBlockSize());
495 coarseA22_->setObjectLabel(solverName_ +
" coarse (2, 2)");
496 dump(coarseA22_,
"coarseA22.m");
499 if (!reuse && !implicitTranspose_) {
505 if (!A22_.is_null()) {
507 std::string label(
"A22");
508 if (!P22_.is_null()) {
509 precList22_.sublist(
"level 1 user data").set(
"A", coarseA22_);
510 precList22_.sublist(
"level 1 user data").set(
"P", P22_);
511 if (!implicitTranspose_)
512 precList22_.sublist(
"level 1 user data").set(
"R", R22_);
513 precList22_.sublist(
"level 1 user data").set(
"Nullspace", CoarseNullspace22_);
514 precList22_.sublist(
"level 1 user data").set(
"Coordinates", Coords22_);
517 int maxCoarseSize = precList22_.get(
"coarse: max size", MasterList::getDefault<int>(
"coarse: max size"));
518 int numRows = Teuchos::as<int>(coarseA22_->getGlobalNumRows());
519 if (maxCoarseSize > numRows)
520 precList22_.set(
"coarse: max size", numRows);
521 int maxLevels = precList22_.get(
"max levels", MasterList::getDefault<int>(
"max levels"));
523 precList22_.set(
"max levels", 2);
524 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, Teuchos::null, Teuchos::null, Material_alpha_, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
526 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, CoarseNullspace22_, Coords22_, Material_alpha_, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
534 if (!reuse && !onlyBoundary22_ && applyBCsTo22_) {
535 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC rows of Dk_1" << std::endl;
540 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
541 dump(Dk_1_,
"Dk_1_nuked.m");
546 setFineLevelSmoother11();
549 if (!ImporterCoarse11_.is_null()) {
550 RCP<const Import> ImporterP11 = ImportFactory::Build(ImporterCoarse11_->getTargetMap(), P11_->getColMap());
551 toCrsMatrix(P11_)->replaceDomainMapAndImporter(ImporterCoarse11_->getTargetMap(), ImporterP11);
554 if (!Importer22_.is_null()) {
556 DorigDomainMap_ = Dk_1_->getDomainMap();
557 DorigImporter_ = toCrsMatrix(Dk_1_)->getCrsGraph()->getImporter();
559 RCP<const Import> ImporterD = ImportFactory::Build(Importer22_->getTargetMap(), Dk_1_->getColMap());
560 toCrsMatrix(Dk_1_)->replaceDomainMapAndImporter(Importer22_->getTargetMap(), ImporterD);
563 #ifdef HAVE_MUELU_TPETRA
564 if ((!Dk_1_T_.is_null()) &&
566 (!toCrsMatrix(Dk_1_T_)->getCrsGraph()->getImporter().is_null()) &&
567 (!toCrsMatrix(R11_)->getCrsGraph()->getImporter().is_null()) &&
570 Dk_1_T_R11_colMapsMatch_ = Dk_1_T_->getColMap()->isSameAs(*R11_->getColMap());
573 Dk_1_T_R11_colMapsMatch_ =
false;
574 if (Dk_1_T_R11_colMapsMatch_)
575 GetOStream(
Runtime0) << solverName_ +
"::compute(): Dk_1_T and R11 have matching colMaps" << std::endl;
577 asyncTransfers_ = parameterList_.
get<
bool>(
"refmaxwell: async transfers");
583 if (parameterList_.isSublist(
"matvec params")) {
584 RCP<ParameterList> matvecParams = rcpFromRef(parameterList_.sublist(
"matvec params"));
588 if (!Dk_1_T_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*Dk_1_T_, matvecParams);
589 if (!R11_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*R11_, matvecParams);
590 if (!ImporterCoarse11_.is_null()) ImporterCoarse11_->setDistributorParameters(matvecParams);
591 if (!Importer22_.is_null()) Importer22_->setDistributorParameters(matvecParams);
593 if (!ImporterCoarse11_.is_null() && parameterList_.isSublist(
"refmaxwell: ImporterCoarse11 params")) {
594 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: ImporterCoarse11 params"));
595 ImporterCoarse11_->setDistributorParameters(importerParams);
597 if (!Importer22_.is_null() && parameterList_.isSublist(
"refmaxwell: Importer22 params")) {
598 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: Importer22 params"));
599 Importer22_->setDistributorParameters(importerParams);
605 #ifdef HAVE_MUELU_CUDA
606 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
610 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
613 doRebalancing = parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators");
614 rebalanceStriding = parameterList_.get<
int>(
"refmaxwell: subsolves striding", -1);
615 int numProcs = SM_Matrix_->getDomainMap()->getComm()->getSize();
617 doRebalancing =
false;
629 level.
Set(
"A", coarseA11_);
633 repartheurParams.
set(
"repartition: start level", 0);
635 int defaultTargetRows = 10000;
636 repartheurParams.
set(
"repartition: min rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
637 repartheurParams.
set(
"repartition: target rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
638 repartheurParams.
set(
"repartition: min rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
639 repartheurParams.
set(
"repartition: target rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
640 repartheurParams.
set(
"repartition: max imbalance", precList11_.get<
double>(
"repartition: max imbalance", 1.1));
641 repartheurFactory->SetParameterList(repartheurParams);
643 level.
Request(
"number of partitions", repartheurFactory.get());
644 repartheurFactory->Build(level);
645 numProcsCoarseA11 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
646 numProcsCoarseA11 = std::min(numProcsCoarseA11, numProcs);
656 level.
Set(
"Map", Dk_1_->getDomainMap());
660 repartheurParams.
set(
"repartition: start level", 0);
661 repartheurParams.
set(
"repartition: use map",
true);
663 int defaultTargetRows = 10000;
664 repartheurParams.
set(
"repartition: min rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
665 repartheurParams.
set(
"repartition: target rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
666 repartheurParams.
set(
"repartition: min rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
667 repartheurParams.
set(
"repartition: target rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
669 repartheurFactory->SetParameterList(repartheurParams);
671 level.
Request(
"number of partitions", repartheurFactory.get());
672 repartheurFactory->Build(level);
673 numProcsA22 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
674 numProcsA22 = std::min(numProcsA22, numProcs);
677 if (rebalanceStriding >= 1) {
678 TEUCHOS_ASSERT(rebalanceStriding * numProcsCoarseA11 <= numProcs);
680 if (rebalanceStriding * (numProcsCoarseA11 + numProcsA22) > numProcs) {
681 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 needs " << numProcsCoarseA11
682 <<
" procs and A22 needs " << numProcsA22 <<
" procs." << std::endl;
683 rebalanceStriding = -1;
685 int lclBadMatrixDistribution = (coarseA11_->getLocalNumEntries() == 0) || (Dk_1_->getDomainMap()->getLocalNumElements() == 0);
686 int gblBadMatrixDistribution =
false;
687 MueLu_maxAll(SM_Matrix_->getDomainMap()->getComm(), lclBadMatrixDistribution, gblBadMatrixDistribution);
688 if (gblBadMatrixDistribution) {
689 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;
690 rebalanceStriding = -1;
694 if ((numProcsCoarseA11 < 0) || (numProcsA22 < 0) || (numProcsCoarseA11 + numProcsA22 > numProcs)) {
695 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling rebalancing of subsolves, since partition heuristic resulted "
696 <<
"in undesirable number of partitions: " << numProcsCoarseA11 <<
", " << numProcsA22 << std::endl;
697 doRebalancing =
false;
701 doRebalancing =
false;
705 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
708 if (spaceNumber == 0)
709 return Teuchos::null;
711 std::string timerLabel;
712 if (spaceNumber == spaceNumber_) {
713 if (skipFirst11Level_)
714 timerLabel =
"Build coarse addon matrix 11";
716 timerLabel =
"Build addon matrix 11";
718 timerLabel =
"Build addon matrix 22";
725 if (spaceNumber == spaceNumber_) {
729 "::buildCoarse11Matrix(): Inverse of "
730 "lumped mass matrix required for add-on (i.e. invMk_1_invBeta_ is null)");
731 lumpedInverse = invMk_1_invBeta_;
733 if (skipFirst11Level_) {
736 Zaux =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Mk_one_,
false, *P11_,
false, Zaux, GetOStream(
Runtime0),
true,
true);
738 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Zaux,
false, Z, GetOStream(
Runtime0),
true,
true);
741 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Mk_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
744 }
else if (spaceNumber == spaceNumber_ - 1) {
748 "::buildCoarse11Matrix(): Inverse of "
749 "lumped mass matrix required for add-on (i.e. invMk_2_invAlpha_ is null)");
750 lumpedInverse = invMk_2_invAlpha_;
753 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_2_,
true, *Mk_1_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
757 if (lumpedInverse->getGlobalMaxNumRowEntries() <= 1) {
760 RCP<Vector> diag = VectorFactory::Build(lumpedInverse->getRowMap());
761 lumpedInverse->getLocalDiagCopy(*diag);
764 for (
size_t j = 0; j < diag->getMap()->getLocalNumElements(); j++) {
768 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
771 RCP<Import> importer = ImportFactory::Build(diag->getMap(), Z->getRowMap());
772 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
774 Z->leftScale(*diag2);
776 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *Z,
false, addon, GetOStream(
Runtime0),
true,
true);
777 }
else if (parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
780 C2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*lumpedInverse,
false, *Z,
false, C2, GetOStream(
Runtime0),
true,
true);
782 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *C2,
false, addon, GetOStream(
Runtime0),
true,
true);
784 addon = MatrixFactory::Build(Z->getDomainMap());
787 MultiplyRAP(*Z,
true, *lumpedInverse,
false, *Z,
false, *addon,
true,
true);
792 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
800 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *P11_,
false, temp, GetOStream(
Runtime0),
true,
true);
801 if (ImporterCoarse11_.is_null())
802 coarseA11_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, coarseA11_, GetOStream(
Runtime0),
true,
true);
805 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
807 RCP<const Map> map = ImporterCoarse11_->getTargetMap()->removeEmptyProcesses();
808 temp2->removeEmptyProcessesInPlace(map);
810 temp2 = Teuchos::null;
814 if (!disable_addon_) {
817 if (!coarseA11_.is_null() && Addon11_.is_null()) {
818 addon = buildAddon(spaceNumber_);
825 if (!coarseA11_.is_null()) {
828 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*coarseA11_,
false, one, *addon,
false, one, newCoarseA11, GetOStream(
Runtime0));
829 newCoarseA11->fillComplete();
830 coarseA11_ = newCoarseA11;
834 if (!coarseA11_.is_null() && !skipFirst11Level_) {
836 coarseA11BCrows.
resize(coarseA11_->getRowMap()->getLocalNumElements());
837 for (
size_t i = 0; i < BCdomain22_.size(); i++)
838 for (
size_t k = 0; k < dim_; k++)
839 coarseA11BCrows[i * dim_ + k] = BCdomain22_(i);
840 magnitudeType rowSumTol = parameterList_.
get<
double>(
"refmaxwell: row sum drop tol (1,1)");
843 if (applyBCsToCoarse11_)
847 if (!coarseA11_.is_null()) {
853 bool fixZeroDiagonal = !applyBCsToAnodal_;
854 if (precList11_.isParameter(
"rap: fix zero diagonals"))
855 fixZeroDiagonal = precList11_.get<
bool>(
"rap: fix zero diagonals");
857 if (fixZeroDiagonal) {
860 if (precList11_.isType<
magnitudeType>(
"rap: fix zero diagonals threshold"))
861 threshold = precList11_.get<
magnitudeType>(
"rap: fix zero diagonals threshold");
862 else if (precList11_.isType<
double>(
"rap: fix zero diagonals threshold"))
863 threshold = Teuchos::as<magnitudeType>(precList11_.get<
double>(
"rap: fix zero diagonals threshold"));
864 if (precList11_.isType<
double>(
"rap: fix zero diagonals replacement"))
865 replacement = Teuchos::as<Scalar>(precList11_.get<
double>(
"rap: fix zero diagonals replacement"));
870 coarseA11_->SetFixedBlockSize(dim_);
871 if (skipFirst11Level_)
872 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
874 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
878 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
885 Level fineLevel, coarseLevel;
891 coarseLevel.
Set(
"A", coarseA11_);
892 coarseLevel.
Set(
"P", P11_);
893 coarseLevel.
Set(
"Coordinates", CoordsCoarse11_);
894 if (!NullspaceCoarse11_.is_null())
895 coarseLevel.
Set(
"Nullspace", NullspaceCoarse11_);
896 coarseLevel.
Set(
"number of partitions", numProcsCoarseA11);
897 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
899 coarseLevel.
setlib(coarseA11_->getDomainMap()->lib());
900 fineLevel.
setlib(coarseA11_->getDomainMap()->lib());
904 std::string partName = precList11_.get<std::string>(
"repartition: partitioner",
"zoltan2");
906 if (partName ==
"zoltan") {
907 #ifdef HAVE_MUELU_ZOLTAN
914 }
else if (partName ==
"zoltan2") {
915 #ifdef HAVE_MUELU_ZOLTAN2
919 partParams.
set(
"ParameterList", partpartParams);
920 partitioner->SetParameterList(partParams);
929 repartParams.
set(
"repartition: print partition distribution", precList11_.get<
bool>(
"repartition: print partition distribution",
false));
930 repartParams.
set(
"repartition: remap parts", precList11_.get<
bool>(
"repartition: remap parts",
true));
931 if (rebalanceStriding >= 1) {
932 bool acceptPart = (SM_Matrix_->getDomainMap()->getComm()->getRank() % rebalanceStriding) == 0;
933 if (SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsCoarseA11 * rebalanceStriding)
935 repartParams.
set(
"repartition: remap accept partition", acceptPart);
937 repartFactory->SetParameterList(repartParams);
939 repartFactory->SetFactory(
"Partition", partitioner);
943 newPparams.
set(
"type",
"Interpolation");
944 newPparams.
set(
"repartition: rebalance P and R", precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
945 newPparams.
set(
"repartition: use subcommunicators",
true);
946 newPparams.
set(
"repartition: rebalance Nullspace", !NullspaceCoarse11_.is_null());
948 if (!NullspaceCoarse11_.is_null())
950 newP->SetParameterList(newPparams);
951 newP->SetFactory(
"Importer", repartFactory);
955 rebAcParams.
set(
"repartition: use subcommunicators",
true);
956 newA->SetParameterList(rebAcParams);
957 newA->SetFactory(
"Importer", repartFactory);
959 coarseLevel.
Request(
"P", newP.get());
960 coarseLevel.
Request(
"Importer", repartFactory.get());
961 coarseLevel.
Request(
"A", newA.get());
962 coarseLevel.
Request(
"Coordinates", newP.get());
963 if (!NullspaceCoarse11_.is_null())
964 coarseLevel.
Request(
"Nullspace", newP.get());
965 repartFactory->Build(coarseLevel);
967 if (!precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
972 if (!NullspaceCoarse11_.is_null())
977 coarseA11_->SetFixedBlockSize(dim_);
978 if (skipFirst11Level_)
979 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
981 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
984 coarseA11_AP_reuse_data_ = Teuchos::null;
985 coarseA11_RAP_reuse_data_ = Teuchos::null;
987 if (!disable_addon_ && enable_reuse_) {
992 XpetraList.
set(
"Restrict Communicator",
true);
993 Addon11_ = MatrixFactory::Build(Addon11_, *ImporterCoarse11, *ImporterCoarse11, targetMap, targetMap,
rcp(&XpetraList,
false));
998 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1003 Level fineLevel, coarseLevel;
1009 fineLevel.
Set(
"A", SM_Matrix_);
1010 coarseLevel.
Set(
"P", Dk_1_);
1011 coarseLevel.
Set(
"Coordinates", Coords22_);
1013 coarseLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1014 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1020 rapList.
set(
"transpose: use implicit",
true);
1021 rapList.
set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1023 rapList.
set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
1026 if (!A22_AP_reuse_data_.is_null()) {
1030 if (!A22_RAP_reuse_data_.is_null()) {
1036 if (doRebalancing) {
1037 coarseLevel.
Set(
"number of partitions", numProcsA22);
1038 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
1040 std::string partName = precList22_.get<std::string>(
"repartition: partitioner",
"zoltan2");
1042 if (partName ==
"zoltan") {
1043 #ifdef HAVE_MUELU_ZOLTAN
1045 partitioner->SetFactory(
"A", rapFact);
1051 }
else if (partName ==
"zoltan2") {
1052 #ifdef HAVE_MUELU_ZOLTAN2
1056 partParams.
set(
"ParameterList", partpartParams);
1057 partitioner->SetParameterList(partParams);
1058 partitioner->SetFactory(
"A", rapFact);
1067 repartParams.
set(
"repartition: print partition distribution", precList22_.get<
bool>(
"repartition: print partition distribution",
false));
1068 repartParams.
set(
"repartition: remap parts", precList22_.get<
bool>(
"repartition: remap parts",
true));
1069 if (rebalanceStriding >= 1) {
1070 bool acceptPart = ((SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank()) % rebalanceStriding) == 0;
1071 if (SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsA22 * rebalanceStriding)
1075 repartParams.
set(
"repartition: remap accept partition", acceptPart);
1077 repartParams.
set(
"repartition: remap accept partition", coarseA11_.is_null());
1078 repartFactory->SetParameterList(repartParams);
1079 repartFactory->SetFactory(
"A", rapFact);
1081 repartFactory->SetFactory(
"Partition", partitioner);
1085 newPparams.
set(
"type",
"Interpolation");
1086 newPparams.
set(
"repartition: rebalance P and R", precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
1087 newPparams.
set(
"repartition: use subcommunicators",
true);
1088 newPparams.
set(
"repartition: rebalance Nullspace",
false);
1090 newP->SetParameterList(newPparams);
1091 newP->SetFactory(
"Importer", repartFactory);
1095 rebAcParams.
set(
"repartition: use subcommunicators",
true);
1096 newA->SetParameterList(rebAcParams);
1097 newA->SetFactory(
"A", rapFact);
1098 newA->SetFactory(
"Importer", repartFactory);
1100 coarseLevel.
Request(
"P", newP.get());
1101 coarseLevel.
Request(
"Importer", repartFactory.get());
1102 coarseLevel.
Request(
"A", newA.get());
1103 coarseLevel.
Request(
"Coordinates", newP.get());
1104 rapFact->
Build(fineLevel, coarseLevel);
1105 repartFactory->Build(coarseLevel);
1107 if (!precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
1113 if (!P22_.is_null()) {
1121 if (enable_reuse_) {
1122 coarseLevel.
Request(
"AP reuse data", rapFact.
get());
1123 coarseLevel.
Request(
"RAP reuse data", rapFact.
get());
1128 if (enable_reuse_) {
1137 if (Importer22_.is_null()) {
1139 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1140 if (!implicitTranspose_)
1141 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1143 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1147 toCrsMatrix(Dk_1_)->replaceDomainMapAndImporter(DorigDomainMap_, DorigImporter_);
1150 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1151 if (!implicitTranspose_)
1152 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1154 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1157 toCrsMatrix(Dk_1_)->replaceDomainMapAndImporter(Importer22_->getTargetMap(), Dimporter);
1160 XpetraList.
set(
"Restrict Communicator",
true);
1161 XpetraList.
set(
"Timer Label",
"MueLu::RebalanceA22");
1163 A22_ = MatrixFactory::Build(temp2, *Importer22_, *Importer22_, targetMap, targetMap,
rcp(&XpetraList,
false));
1167 if (not A22_.is_null() and not disable_addon_22_ and spaceNumber_ > 1) {
1170 RCP<Matrix> addon22 = buildAddon(spaceNumber_ - 1);
1174 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*A22_,
false, one, *addon22,
false, one, newA22, GetOStream(
Runtime0));
1175 newA22->fillComplete();
1179 if (!A22_.is_null()) {
1180 dump(A22_,
"A22.m");
1181 A22_->setObjectLabel(solverName_ +
" (2,2)");
1183 if (spaceNumber_ - 1 == 0)
1184 A22_->SetFixedBlockSize(1);
1186 A22_->SetFixedBlockSize(dim_);
1190 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1197 level.
Set(
"A", SM_Matrix_);
1198 level.
setlib(SM_Matrix_->getDomainMap()->lib());
1200 level.
Set(
"NodeMatrix", A22_);
1201 level.
Set(
"D0", Dk_1_);
1203 if ((parameterList_.get<std::string>(
"smoother: pre type") !=
"NONE") && (parameterList_.get<std::string>(
"smoother: post type") !=
"NONE")) {
1204 std::string preSmootherType = parameterList_.get<std::string>(
"smoother: pre type");
1205 std::string postSmootherType = parameterList_.get<std::string>(
"smoother: post type");
1208 if (parameterList_.isSublist(
"smoother: pre params"))
1209 preSmootherList = parameterList_.
sublist(
"smoother: pre params");
1210 if (parameterList_.isSublist(
"smoother: post params"))
1211 postSmootherList = parameterList_.
sublist(
"smoother: post params");
1217 level.
Request(
"PreSmoother", smootherFact.
get());
1218 level.
Request(
"PostSmoother", smootherFact.
get());
1219 if (enable_reuse_) {
1221 smootherFactoryParams.
set(
"keep smoother data",
true);
1223 level.
Request(
"PreSmoother data", smootherFact.
get());
1224 level.
Request(
"PostSmoother data", smootherFact.
get());
1225 if (!PreSmootherData11_.is_null())
1226 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1227 if (!PostSmootherData11_.is_null())
1228 level.
Set(
"PostSmoother data", PostSmootherData11_, smootherFact.
get());
1230 smootherFact->
Build(level);
1233 if (enable_reuse_) {
1238 std::string smootherType = parameterList_.
get<std::string>(
"smoother: type");
1241 if (parameterList_.isSublist(
"smoother: params"))
1242 smootherList = parameterList_.
sublist(
"smoother: params");
1246 level.
Request(
"PreSmoother", smootherFact.
get());
1247 if (enable_reuse_) {
1249 smootherFactoryParams.
set(
"keep smoother data",
true);
1251 level.
Request(
"PreSmoother data", smootherFact.
get());
1252 if (!PreSmootherData11_.is_null())
1253 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1255 smootherFact->
Build(level);
1257 PostSmoother11_ = PreSmoother11_;
1263 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1268 if (!R11_.is_null())
1269 P11res_ = MultiVectorFactory::Build(R11_->getRangeMap(), numVectors);
1271 P11res_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1272 P11res_->setObjectLabel(
"P11res");
1274 if (Dk_1_T_R11_colMapsMatch_) {
1275 DTR11Tmp_ = MultiVectorFactory::Build(R11_->getColMap(), numVectors);
1276 DTR11Tmp_->setObjectLabel(
"DTR11Tmp");
1278 if (!ImporterCoarse11_.is_null()) {
1279 P11resTmp_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1280 P11resTmp_->setObjectLabel(
"P11resTmp");
1281 P11x_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1283 P11x_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1284 P11x_->setObjectLabel(
"P11x");
1287 if (!Dk_1_T_.is_null())
1288 Dres_ = MultiVectorFactory::Build(Dk_1_T_->getRangeMap(), numVectors);
1290 Dres_ = MultiVectorFactory::Build(Dk_1_->getDomainMap(), numVectors);
1291 Dres_->setObjectLabel(
"Dres");
1293 if (!Importer22_.is_null()) {
1294 DresTmp_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1295 DresTmp_->setObjectLabel(
"DresTmp");
1296 Dx_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1297 }
else if (!onlyBoundary22_)
1298 Dx_ = MultiVectorFactory::Build(A22_->getDomainMap(), numVectors);
1300 Dx_->setObjectLabel(
"Dx");
1302 if (!coarseA11_.is_null()) {
1303 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
1304 P11resSubComm_ = MultiVectorFactory::Build(P11resTmp_,
Teuchos::View);
1306 P11resSubComm_ = MultiVectorFactory::Build(P11res_,
Teuchos::View);
1307 P11resSubComm_->replaceMap(coarseA11_->getRangeMap());
1308 P11resSubComm_->setObjectLabel(
"P11resSubComm");
1310 P11xSubComm_ = MultiVectorFactory::Build(P11x_,
Teuchos::View);
1311 P11xSubComm_->replaceMap(coarseA11_->getDomainMap());
1312 P11xSubComm_->setObjectLabel(
"P11xSubComm");
1315 if (!A22_.is_null()) {
1316 if (!Importer22_.is_null() && !implicitTranspose_)
1317 DresSubComm_ = MultiVectorFactory::Build(DresTmp_,
Teuchos::View);
1319 DresSubComm_ = MultiVectorFactory::Build(Dres_,
Teuchos::View);
1320 DresSubComm_->replaceMap(A22_->getRangeMap());
1321 DresSubComm_->setObjectLabel(
"DresSubComm");
1324 DxSubComm_->replaceMap(A22_->getDomainMap());
1325 DxSubComm_->setObjectLabel(
"DxSubComm");
1328 if (asyncTransfers_) {
1329 if (!toCrsMatrix(P11_)->getCrsGraph()->getImporter().
is_null())
1330 P11x_colmap_ = MultiVectorFactory::Build(P11_->getColMap(), numVectors);
1331 if (!toCrsMatrix(Dk_1_)->getCrsGraph()->getImporter().is_null())
1332 Dx_colmap_ = MultiVectorFactory::Build(Dk_1_->getColMap(), numVectors);
1335 residual_ = MultiVectorFactory::Build(SM_Matrix_->getDomainMap(), numVectors);
1336 residual_->setObjectLabel(
"residual");
1339 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1341 if (dump_matrices_ && !A.
is_null()) {
1342 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1347 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1349 if (dump_matrices_ && !X.
is_null()) {
1350 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1355 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1357 if (dump_matrices_ && !X.
is_null()) {
1358 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1363 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1365 if (dump_matrices_) {
1366 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1367 std::ofstream out(name);
1368 for (
size_t i = 0; i < Teuchos::as<size_t>(v.
size()); i++)
1369 out << v[i] <<
"\n";
1373 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1375 if (dump_matrices_) {
1376 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1377 std::ofstream out(name);
1378 auto vH = Kokkos::create_mirror_view(v);
1379 Kokkos::deep_copy(vH, v);
1380 out <<
"%%MatrixMarket matrix array real general\n"
1381 << vH.extent(0) <<
" 1\n";
1382 for (
size_t i = 0; i < vH.size(); i++)
1383 out << vH[i] <<
"\n";
1387 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1393 if (comm.is_null()) {
1396 SM_Matrix_->getRowMap()->getComm()->barrier();
1408 return Teuchos::null;
1411 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1413 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1414 std::string spaceLabel;
1415 if (spaceNumber == 0)
1416 spaceLabel =
"nodal";
1417 else if (spaceNumber == 1)
1418 spaceLabel =
"edge";
1419 else if (spaceNumber == 2)
1420 spaceLabel =
"face";
1427 if (spaceNumber > 0) {
1428 tm = getTimer(
"nullspace " + spaceLabel);
1429 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" nullspace" << std::endl;
1432 if (spaceNumber == 0) {
1433 return Teuchos::null;
1435 }
else if (spaceNumber == 1) {
1438 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(D0_->getRowMap(), NodalCoords_->getNumVectors());
1439 D0_->apply(*CoordsSC, *Nullspace);
1441 bool normalize = parameterList_.
get<
bool>(
"refmaxwell: normalize nullspace", MasterList::getDefault<bool>(
"refmaxwell: normalize nullspace"));
1447 for (
size_t i = 0; i < dim_; i++)
1448 localNullspace[i] = Nullspace->getData(i);
1452 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1454 for (
size_t i = 0; i < dim_; i++)
1455 lenSC += localNullspace[i][j] * localNullspace[i][j];
1457 localMinLen = std::min(localMinLen, len);
1458 localMaxLen = std::max(localMaxLen, len);
1459 localMeanLen += len;
1466 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1470 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1475 GetOStream(
Runtime0) << solverName_ +
"::compute(): normalizing nullspace" << std::endl;
1479 Array<Scalar> normsSC(NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1480 Nullspace->scale(normsSC());
1487 dump(Nullspace,
"nullspaceEdge.m");
1491 }
else if (spaceNumber == 2) {
1492 #if KOKKOS_VERSION >= 40799
1493 using ATS = KokkosKernels::ArithTraits<Scalar>;
1495 using ATS = Kokkos::ArithTraits<Scalar>;
1497 using impl_Scalar =
typename ATS::val_type;
1498 #if KOKKOS_VERSION >= 40799
1499 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1501 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1503 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1518 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1526 auto importer = facesToNodes->getCrsGraph()->getImporter();
1527 if (!importer.is_null()) {
1529 ghostedNodalCoordinates->doImport(*NodalCoords_, *importer,
Xpetra::INSERT);
1531 ghostedNodalCoordinates = NodalCoords_;
1535 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1536 auto localNodalCoordinates = ghostedNodalCoordinates->getLocalViewDevice(Xpetra::Access::ReadOnly);
1537 auto localFaceNullspace = Nullspace->getLocalViewDevice(Xpetra::Access::ReadWrite);
1540 Kokkos::parallel_for(
1541 solverName_ +
"::buildFaceProjection_nullspace",
1542 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1543 KOKKOS_LAMBDA(
const size_t f) {
1544 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1545 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1546 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1547 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1548 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1549 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1550 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1551 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1552 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1554 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1555 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1556 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1565 dump(Nullspace,
"nullspaceFace.m");
1575 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1578 #if KOKKOS_VERSION >= 40799
1579 using ATS = KokkosKernels::ArithTraits<Scalar>;
1581 using ATS = Kokkos::ArithTraits<Scalar>;
1583 using impl_Scalar =
typename ATS::val_type;
1584 #if KOKKOS_VERSION >= 40799
1585 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1587 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1589 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1591 typedef typename Matrix::local_matrix_type KCRS;
1592 typedef typename KCRS::StaticCrsGraphType graph_t;
1593 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1594 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1595 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1597 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1598 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1599 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1601 std::string spaceLabel;
1602 if (spaceNumber == 0)
1603 spaceLabel =
"nodal";
1604 else if (spaceNumber == 1)
1605 spaceLabel =
"edge";
1606 else if (spaceNumber == 2)
1607 spaceLabel =
"face";
1612 if (spaceNumber > 0) {
1613 tm = getTimer(
"projection " + spaceLabel);
1614 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" projection" << std::endl;
1618 if (spaceNumber == 0) {
1620 return Teuchos::null;
1622 }
else if (spaceNumber == 1) {
1626 }
else if (spaceNumber == 2) {
1636 dump(edgesToNodes,
"edgesToNodes.m");
1642 dump(facesToEdges,
"facesToEdges.m");
1644 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1649 dump(facesToNodes,
"facesToNodes.m");
1651 incidence = facesToNodes;
1660 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1661 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1663 auto localIncidence = incidence->getLocalMatrixDevice();
1664 size_t numLocalRows = rowMap->getLocalNumElements();
1665 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1666 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1667 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1668 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1669 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1672 Kokkos::parallel_for(
1673 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1674 range_type(0, numLocalRows + 1),
1675 KOKKOS_LAMBDA(
const size_t i) {
1676 rowptr(i) = dim * localIncidence.graph.row_map(i);
1679 auto localNullspace = Nullspace->getLocalViewDevice(Xpetra::Access::ReadOnly);
1683 Kokkos::parallel_for(
1684 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1685 range_type(0, numLocalRows),
1686 KOKKOS_LAMBDA(
const size_t f) {
1687 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1688 for (
size_t k = 0; k < dim; k++) {
1689 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1690 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1691 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1693 vals(dim * jj + k) = impl_SC_ZERO;
1699 typename CrsMatrix::local_matrix_type lclProjection(
"local projection " + spaceLabel,
1700 numLocalRows, numLocalColumns, nnzEstimate,
1701 vals, rowptr, colind);
1702 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1703 rowMap, blockColMap,
1704 blockDomainMap, rowMap);
1709 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1715 GetOStream(
Runtime0) << solverName_ +
"::compute(): building nodal prolongator" << std::endl;
1723 Level fineLevel, coarseLevel;
1729 fineLevel.
Set(
"A", A_nodal);
1730 fineLevel.
Set(
"Coordinates", NodalCoords_);
1731 fineLevel.
Set(
"DofsPerNode", 1);
1732 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1733 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1738 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1739 nullSpace->putScalar(SC_ONE);
1740 fineLevel.
Set(
"Nullspace", nullSpace);
1742 std::string algo = parameterList_.get<std::string>(
"multigrid algorithm");
1744 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1758 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1760 double dropTol = parameterList_.get<
double>(
"aggregation: drop tol");
1761 std::string dropScheme = parameterList_.get<std::string>(
"aggregation: drop scheme");
1762 std::string distLaplAlgo = parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1767 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1768 int minAggSize = parameterList_.get<
int>(
"aggregation: min agg size");
1770 int maxAggSize = parameterList_.get<
int>(
"aggregation: max agg size");
1772 bool matchMLbehavior1 = parameterList_.get<
bool>(
"aggregation: match ML phase1");
1774 bool matchMLbehavior2a = parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1776 bool matchMLbehavior2b = parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1779 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1781 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1782 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1783 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1785 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1786 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1789 SaPFact->SetFactory(
"P", TentativePFact);
1790 coarseLevel.
Request(
"P", SaPFact.get());
1792 coarseLevel.
Request(
"P", TentativePFact.get());
1793 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1794 coarseLevel.
Request(
"Coordinates", Tfact.get());
1797 bool exportVizData = parameterList_.
get<
bool>(
"aggregation: export visualization data");
1798 if (exportVizData) {
1801 aggExportParams.
set(
"aggregation: output filename",
"aggs.vtk");
1802 aggExportParams.
set(
"aggregation: output file: agg style",
"Jacks");
1805 aggExport->
SetFactory(
"Aggregates", UncoupledAggFact);
1806 aggExport->
SetFactory(
"UnAmalgamationInfo", amalgFact);
1807 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1808 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1812 coarseLevel.
Get(
"P", P_nodal, SaPFact.
get());
1814 coarseLevel.
Get(
"P", P_nodal, TentativePFact.
get());
1815 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.
get());
1816 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.
get());
1819 aggExport->
Build(fineLevel, coarseLevel);
1823 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1827 GetOStream(
Runtime0) << solverName_ +
"::compute(): building vectorial nodal prolongator" << std::endl;
1829 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1831 typedef typename Matrix::local_matrix_type KCRS;
1832 typedef typename KCRS::StaticCrsGraphType graph_t;
1833 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1834 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1835 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1840 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1841 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1842 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1845 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1847 size_t numLocalRows = blockRowMap->getLocalNumElements();
1848 size_t numLocalColumns = blockColMap->getLocalNumElements();
1849 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1850 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1851 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1852 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1855 Kokkos::parallel_for(
1856 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1857 range_type(0, localP_nodal.numRows() + 1),
1859 if (i < localP_nodal.numRows()) {
1860 for (
size_t k = 0; k < dim; k++) {
1861 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1864 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1868 Kokkos::parallel_for(
1869 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1870 range_type(0, localP_nodal.graph.entries.size()),
1871 KOKKOS_LAMBDA(
const size_t jj) {
1872 for (
size_t k = 0; k < dim; k++) {
1873 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1875 vals(dim * jj + k) = 1.;
1879 typename CrsMatrix::local_matrix_type lclVectorNodalP(
"local vector nodal prolongator",
1880 numLocalRows, numLocalColumns, nnzEstimate,
1881 vals, rowptr, colind);
1882 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1883 blockRowMap, blockColMap,
1884 blockDomainMap, blockRowMap);
1886 return vectorNodalP;
1889 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1897 #if KOKKOS_VERSION >= 40799
1898 using ATS = KokkosKernels::ArithTraits<Scalar>;
1900 using ATS = Kokkos::ArithTraits<Scalar>;
1902 using impl_Scalar =
typename ATS::val_type;
1903 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1905 std::string typeStr;
1906 switch (spaceNumber) {
1921 const bool skipFirstLevel = !A_nodal.
is_null();
1924 if (spaceNumber > 0) {
1925 tm = getTimer(
"special prolongator " + typeStr);
1926 GetOStream(
Runtime0) << solverName_ +
"::compute(): building special " + typeStr +
" prolongator" << std::endl;
1929 RCP<Matrix> projection = buildProjection(spaceNumber, Nullspace);
1930 dump(projection, typeStr +
"Projection.m");
1932 if (skipFirstLevel) {
1936 buildNodalProlongator(A_nodal, P_nodal, coarseNodalNullspace, coarseNodalCoords);
1938 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1939 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1941 RCP<Matrix> vectorP_nodal = buildVectorNodalProlongator(P_nodal);
1943 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1945 Prolongator =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator, GetOStream(
Runtime0),
true,
true);
1994 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
1996 auto localNullspace_nodal = coarseNodalNullspace->getLocalViewDevice(Xpetra::Access::ReadOnly);
1997 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Xpetra::Access::ReadWrite);
1998 Kokkos::parallel_for(
1999 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2000 range_type(0, coarseNodalNullspace->getLocalLength()),
2001 KOKKOS_LAMBDA(
const size_t i) {
2002 impl_Scalar val = localNullspace_nodal(i, 0);
2003 for (
size_t j = 0; j < dim; j++)
2004 localNullspace_coarse(dim * i + j, j) = val;
2008 Prolongator = projection;
2009 coarseNodalCoords = NodalCoords_;
2011 if (spaceNumber == 0) {
2013 }
else if (spaceNumber >= 1) {
2015 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
2016 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Xpetra::Access::ReadWrite);
2017 Kokkos::parallel_for(
2018 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2019 range_type(0, coarseNullspace->getLocalLength() / dim),
2020 KOKKOS_LAMBDA(
const size_t i) {
2021 for (
size_t j = 0; j < dim; j++)
2022 localNullspace_coarse(dim * i + j, j) = 1.0;
2028 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2038 const bool isSingular) {
2039 int oldRank = SetProcRankVerbose(A->getDomainMap()->getComm()->getRank());
2042 pl->
set(
"printLoadBalancingInfo",
true);
2043 pl->
set(
"printCommInfo",
true);
2046 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2047 if (params.
isType<std::string>(
"Preconditioner Type")) {
2050 if (params.
get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2058 thyraPrecOp =
rcp(
new XpetraThyraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(coarseA11_,
rcp(¶ms,
false)));
2074 std::string coarseType =
"";
2076 coarseType = params.
get<std::string>(
"coarse: type");
2078 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(),
::tolower);
2079 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
2081 if ((coarseType ==
"" ||
2082 coarseType ==
"Klu" ||
2083 coarseType ==
"Klu2" ||
2084 coarseType ==
"Superlu" ||
2085 coarseType ==
"Superlu_dist" ||
2086 coarseType ==
"Superludist" ||
2087 coarseType ==
"Basker" ||
2088 coarseType ==
"Cusolver" ||
2089 coarseType ==
"Tacho") &&
2092 params.
sublist(
"coarse: params").
set(
"fix nullspace",
true);
2098 level0->
Set(
"A", A);
2102 SetProcRankVerbose(oldRank);
2105 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2107 bool reuse = !SM_Matrix_.is_null();
2108 SM_Matrix_ = SM_Matrix_new;
2109 dump(SM_Matrix_,
"SM.m");
2114 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2160 if (implicitTranspose_) {
2165 if (!onlyBoundary22_) {
2170 if (Dk_1_T_R11_colMapsMatch_) {
2174 DTR11Tmp_->doImport(*residual_, *toCrsMatrix(R11_)->getCrsGraph()->getImporter(),
Xpetra::INSERT);
2176 if (!onlyBoundary22_) {
2189 if (!onlyBoundary22_) {
2202 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2204 P11resTmp_->beginImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2206 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_) {
2212 if (!coarseA11_.is_null()) {
2213 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
2214 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2218 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2219 if (!thyraPrecOpH_.is_null()) {
2221 thyraPrecOpH_->apply(*P11resSubComm_, *P11xSubComm_,
Teuchos::NO_TRANS, one, zero);
2224 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2228 if (!A22_.is_null()) {
2229 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2233 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2234 if (!thyraPrecOp22_.is_null()) {
2236 thyraPrecOp22_->apply(*DresSubComm_, *DxSubComm_,
Teuchos::NO_TRANS, one, zero);
2239 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2242 if (coarseA11_.is_null() && !ImporterCoarse11_.is_null() && !implicitTranspose_)
2243 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2244 if (A22_.is_null() && !onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2251 if (asyncTransfers_) {
2265 unsigned completedImports = 0;
2266 std::vector<bool> completedImport(2,
false);
2267 auto tpP11importer = tpP11->getCrsGraph()->getImporter();
2268 if (!tpP11importer.is_null()) {
2269 tpP11x_colmap =
toTpetra(P11x_colmap_);
2270 tpP11x_colmap->beginImport(*tpP11x, *tpP11importer,
Tpetra::INSERT);
2274 if (!onlyBoundary22_) {
2275 tpDk_1importer = tpDk_1->getCrsGraph()->getImporter();
2276 if (!tpDk_1importer.
is_null()) {
2277 tpDx_colmap =
toTpetra(Dx_colmap_);
2278 tpDx_colmap->beginImport(*tpDx, *tpDk_1importer,
Tpetra::INSERT);
2281 completedImport[1] =
true;
2285 if (!fuseProlongationAndUpdate_) {
2287 tpResidual->putScalar(zero);
2290 while (completedImports < completedImport.size()) {
2291 for (
unsigned i = 0; i < completedImport.size(); i++) {
2292 if (completedImport[i])
continue;
2295 if (!tpP11importer.is_null()) {
2296 if (tpP11x_colmap->transferArrived()) {
2297 tpP11x_colmap->endImport(*tpP11x, *tpP11importer,
Tpetra::INSERT);
2298 completedImport[i] =
true;
2301 if (fuseProlongationAndUpdate_) {
2310 completedImport[i] =
true;
2313 if (fuseProlongationAndUpdate_) {
2322 if (!tpDk_1importer.
is_null()) {
2323 if (tpDx_colmap->transferArrived()) {
2325 completedImport[i] =
true;
2328 if (fuseProlongationAndUpdate_) {
2337 completedImport[i] =
true;
2340 if (fuseProlongationAndUpdate_) {
2352 if (!fuseProlongationAndUpdate_) {
2354 X.update(one, *residual_, one);
2357 if (fuseProlongationAndUpdate_) {
2363 if (!onlyBoundary22_) {
2373 if (!onlyBoundary22_) {
2380 X.update(one, *residual_, one);
2387 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2394 if (implicitTranspose_)
2401 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2403 P11resTmp_->doImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2405 if (!coarseA11_.is_null()) {
2407 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2414 X.update(one, *residual_, one);
2418 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2420 if (onlyBoundary22_)
2428 if (implicitTranspose_)
2435 if (!Importer22_.is_null() && !implicitTranspose_) {
2439 if (!A22_.is_null()) {
2441 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2448 X.update(one, *residual_, one);
2452 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2460 if (!onlyBoundary11_ && X.getNumVectors() != P11res_->getNumVectors())
2461 allocateMemory(X.getNumVectors());
2467 PreSmoother11_->Apply(X, RHS, use_as_preconditioner_);
2471 if (mode_ ==
"additive")
2472 applyInverseAdditive(RHS, X);
2473 else if (mode_ ==
"121") {
2477 }
else if (mode_ ==
"212") {
2481 }
else if (mode_ ==
"1")
2483 else if (mode_ ==
"2")
2485 else if (mode_ ==
"7") {
2491 PreSmoother11_->Apply(X, RHS,
false);
2498 PostSmoother11_->Apply(X, RHS,
false);
2501 }
else if (mode_ ==
"none") {
2504 applyInverseAdditive(RHS, X);
2510 PostSmoother11_->Apply(X, RHS,
false);
2514 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2519 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2524 int spaceNumber = List.
get<
int>(
"refmaxwell: space number", 1);
2533 Dk_1 =
pop(List,
"Dk_1", Dk_1);
2534 Dk_2 = pop<RCP<Matrix>>(List,
"Dk_2", Dk_2);
2535 D0 = pop<RCP<Matrix>>(List,
"D0", D0);
2537 M1_beta = pop<RCP<Matrix>>(List,
"M1_beta", M1_beta);
2538 M1_alpha = pop<RCP<Matrix>>(List,
"M1_alpha", M1_alpha);
2540 Mk_one = pop<RCP<Matrix>>(List,
"Mk_one", Mk_one);
2541 Mk_1_one = pop<RCP<Matrix>>(List,
"Mk_1_one", Mk_1_one);
2543 invMk_1_invBeta = pop<RCP<Matrix>>(List,
"invMk_1_invBeta", invMk_1_invBeta);
2544 invMk_2_invAlpha = pop<RCP<Matrix>>(List,
"invMk_2_invAlpha", invMk_2_invAlpha);
2546 Nullspace11 = pop<RCP<MultiVector>>(List,
"Nullspace11", Nullspace11);
2547 Nullspace22 = pop<RCP<MultiVector>>(List,
"Nullspace22", Nullspace22);
2548 NodalCoords = pop<RCP<RealValuedMultiVector>>(List,
"Coordinates", NodalCoords);
2552 if (M1_beta.is_null())
2558 if (Mk_one.is_null())
2564 if (invMk_1_invBeta.is_null())
2570 if (Nullspace11.is_null())
2576 if (spaceNumber == 1) {
2579 else if (D0.is_null())
2581 if (M1_beta.is_null())
2583 }
else if (spaceNumber == 2) {
2586 else if (D0.is_null())
2594 invMk_1_invBeta, invMk_2_invAlpha,
2595 Nullspace11, Nullspace22,
2597 Teuchos::null, Teuchos::null,
2600 if (SM_Matrix != Teuchos::null)
2601 resetMatrix(SM_Matrix, ComputePrec);
2604 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2615 D0_Matrix, Teuchos::null, D0_Matrix,
2616 Ms_Matrix, Teuchos::null,
2617 M1_Matrix, Teuchos::null,
2618 M0inv_Matrix, Teuchos::null,
2619 Nullspace11, Teuchos::null,
2621 Teuchos::null, Material,
2625 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2644 if (spaceNumber_ == 1)
2645 solverName_ =
"RefMaxwell";
2646 else if (spaceNumber_ == 2)
2647 solverName_ =
"RefDarcy";
2650 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2651 HierarchyCoarse11_ = Teuchos::null;
2652 Hierarchy22_ = Teuchos::null;
2653 PreSmoother11_ = Teuchos::null;
2654 PostSmoother11_ = Teuchos::null;
2655 disable_addon_ =
false;
2656 disable_addon_22_ =
true;
2660 setParameters(List);
2675 if (!disable_addon_) {
2681 if ((k >= 2) && !disable_addon_22_) {
2688 #ifdef HAVE_MUELU_DEBUG
2693 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2694 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2697 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2701 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2702 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2705 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()))
2708 if (!disable_addon_) {
2710 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2711 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2714 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2717 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2718 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2721 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2724 if ((k >= 2) && !disable_addon_22_) {
2726 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2727 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2730 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2733 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2736 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2737 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2740 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2750 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2755 toCrsMatrix(Dk_1)->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2760 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.
size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2761 Dk_1copyrowptr_RCP.
deepCopy(Dk_1rowptr_RCP());
2762 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2763 Dk_1copyvals_RCP.
deepCopy(Dk_1vals_RCP());
2764 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2767 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2768 toCrsMatrix(Dk_1)->getCrsGraph()->getImporter(),
2769 toCrsMatrix(Dk_1)->getCrsGraph()->getExporter());
2772 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2779 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2784 toCrsMatrix(Dk_2)->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2789 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.
size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2790 Dk_2copyrowptr_RCP.
deepCopy(Dk_2rowptr_RCP());
2791 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2792 Dk_2copyvals_RCP.
deepCopy(Dk_2vals_RCP());
2793 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2796 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2797 toCrsMatrix(Dk_2)->getCrsGraph()->getImporter(),
2798 toCrsMatrix(Dk_2)->getCrsGraph()->getExporter());
2801 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2804 M1_alpha_ = M1_alpha;
2806 Material_beta_ = Material_beta;
2807 Material_alpha_ = Material_alpha;
2810 Mk_1_one_ = Mk_1_one;
2812 invMk_1_invBeta_ = invMk_1_invBeta;
2813 invMk_2_invAlpha_ = invMk_2_invAlpha;
2815 NodalCoords_ = NodalCoords;
2816 Nullspace11_ = Nullspace11;
2817 Nullspace22_ = Nullspace22;
2820 dump(Dk_1_,
"Dk_1_clean.m");
2821 dump(Dk_2_,
"Dk_2_clean.m");
2823 dump(M1_beta_,
"M1_beta.m");
2824 dump(M1_alpha_,
"M1_alpha.m");
2826 dump(Mk_one_,
"Mk_one.m");
2827 dump(Mk_1_one_,
"Mk_1_one.m");
2829 dump(invMk_1_invBeta_,
"invMk_1_invBeta.m");
2830 dump(invMk_2_invAlpha_,
"invMk_2_invAlpha.m");
2832 dumpCoords(NodalCoords_,
"coords.m");
2835 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2838 std::ostringstream oss;
2844 if (!coarseA11_.is_null())
2845 root = comm->getRank();
2854 oss <<
"\n--------------------------------------------------------------------------------\n"
2855 <<
"--- " + solverName_ +
2857 "--------------------------------------------------------------------------------"
2864 SM_Matrix_->getRowMap()->getComm()->barrier();
2866 numRows = SM_Matrix_->getGlobalNumRows();
2867 nnz = SM_Matrix_->getGlobalNumEntries();
2882 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2883 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2885 if (!A22_.is_null()) {
2886 numRows = A22_->getGlobalNumRows();
2887 nnz = A22_->getGlobalNumEntries();
2889 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2895 if (PreSmoother11_ != null && PreSmoother11_ == PostSmoother11_)
2896 oss <<
"Smoother 11 both : " << PreSmoother11_->description() << std::endl;
2898 oss <<
"Smoother 11 pre : "
2899 << (PreSmoother11_ != null ? PreSmoother11_->description() :
"no smoother") << std::endl;
2900 oss <<
"Smoother 11 post : "
2901 << (PostSmoother11_ != null ? PostSmoother11_->description() :
"no smoother") << std::endl;
2906 std::string outstr = oss.str();
2910 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2912 int strLength = outstr.size();
2913 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2914 if (comm->getRank() != root)
2915 outstr.resize(strLength);
2916 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2921 if (!HierarchyCoarse11_.is_null())
2922 HierarchyCoarse11_->describe(out, GetVerbLevel());
2924 if (!Hierarchy22_.is_null())
2925 Hierarchy22_->describe(out, GetVerbLevel());
2929 std::ostringstream oss2;
2931 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2932 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;
2934 int numProcs = comm->getSize();
2942 if (!coarseA11_.is_null())
2944 if (!A22_.is_null())
2946 std::vector<char> states(numProcs, 0);
2948 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2950 states.push_back(status);
2953 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2954 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2955 for (
int j = 0; j < rowWidth; j++)
2956 if (proc + j < numProcs)
2957 if (states[proc + j] == 0)
2959 else if (states[proc + j] == 1)
2961 else if (states[proc + j] == 2)
2968 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2977 #define MUELU_REFMAXWELL_SHORT
2978 #endif // ifdef MUELU_REFMAXWELL_DEF_HPP
Important warning messages (one line)
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
RCP< Matrix > buildAddon(const int spaceNumber)
void initialize(int *argc, char ***argv)
static void ApplyOAZToMatrixRows(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >> &A, const std::vector< LocalOrdinal > &dirichletRows)
static void ZeroDirichletCols(Teuchos::RCP< Matrix > &A, const Teuchos::ArrayRCP< const bool > &dirichletCols, Scalar replaceWith=Teuchos::ScalarTraits< Scalar >::zero())
This class specifies the default factory that should generate some data on a Level if the data does n...
static void DetectDirichletColsAndDomains(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Teuchos::ArrayRCP< bool > &dirichletRows, Teuchos::ArrayRCP< bool > dirichletCols, Teuchos::ArrayRCP< bool > dirichletDomain)
Detects Dirichlet columns & domains from a list of Dirichlet rows.
#define MueLu_sumAll(rcpComm, in, out)
ParameterList & setEntry(const std::string &name, U &&entry)
static VerbLevel GetDefaultVerbLevel()
Get the default (global) verbosity level.
Various adapters that will create a MueLu preconditioner that is an Xpetra::Matrix.
ConstIterator end() const
MueLu::DefaultLocalOrdinal LocalOrdinal
Factory for determing the number of partitions for rebalancing.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level->Get< RCP<Matrix> >("A", factory) if factory == NULL => use default factory.
void solve22(const MultiVector &RHS, MultiVector &X) const
apply solve to 2-2 block only
Factory for generating coarse level map. Used by TentativePFactory.
bool is_null(const boost::shared_ptr< T > &p)
RCP< Level > & GetLevel(const int levelID=0)
Retrieve a certain level from hierarchy.
void dumpCoords(const RCP< RealValuedMultiVector > &X, std::string name) const
dump out real-valued multivector
const Teuchos::RCP< const Map > getRangeMap() const
Returns the Xpetra::Map object associated with the range of this operator.
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Configuration.
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map, size_t NumVectors, bool zeroOut=true)
ParameterList & disableRecursiveValidation()
#define MueLu_maxAll(rcpComm, in, out)
static RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > RealValuedToScalarMultiVector(RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::coordinateType, LocalOrdinal, GlobalOrdinal, Node >> X)
typename Teuchos::ScalarTraits< Scalar >::magnitudeType magnitudeType
T & get(const std::string &name, T def_value)
void setFineLevelSmoother11()
Set the fine level smoother.
Class that encapsulates external library smoothers.
static void MultiplyRAP(const Matrix &R, bool transposeR, const Matrix &A, bool transposeA, const Matrix &P, bool transposeP, Matrix &Ac, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
static void ApplyRowSumCriterion(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Magnitude rowSumTol, Teuchos::ArrayRCP< bool > &dirichletRows)
Apply Rowsum Criterion.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static void Write(const std::string &fileName, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &M)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
static magnitudeType real(T a)
Factory for building permutation matrix that can be be used to shuffle data (matrices, vectors) among processes.
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.
typename Teuchos::ScalarTraits< Scalar >::coordinateType coordinateType
void buildNodalProlongator(const Teuchos::RCP< Matrix > &A_nodal, Teuchos::RCP< Matrix > &P_nodal, Teuchos::RCP< MultiVector > &Nullspace_nodal, Teuchos::RCP< RealValuedMultiVector > &Coords_nodal) const
One-liner description of what is happening.
void determineSubHierarchyCommSizes(bool &doRebalancing, int &rebalanceStriding, int &numProcsCoarseA11, int &numProcsA22)
Determine how large the sub-communicators for the two hierarchies should be.
static void ZeroDirichletRows(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >> &A, const std::vector< LocalOrdinal > &dirichletRows, Scalar replaceWith=Teuchos::ScalarTraits< Scalar >::zero())
std::string tolower(const std::string &str)
void solveH(const MultiVector &RHS, MultiVector &X) const
apply solve to 1-1 block only
void SetPreviousLevel(const RCP< Level > &previousLevel)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Interface to Zoltan library.This interface provides access to partitioning methods in Zoltan...
void SetFactoryManager(const RCP< const FactoryManagerBase > &factoryManager)
Set default factories (used internally by Hierarchy::SetLevel()).
void setParameters(Teuchos::ParameterList &list)
Set parameters.
#define MueLu_minAll(rcpComm, in, out)
static void CheckRepairMainDiagonal(RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >> &Ac, bool const &repairZeroDiagonals, Teuchos::FancyOStream &fos, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType threshold=Teuchos::ScalarTraits< typename Teuchos::ScalarTraits< Scalar >::magnitudeType >::zero())
RCP< MultiVector > buildNullspace(const int spaceNumber, const Kokkos::View< bool *, typename Node::device_type > &bcs, const bool applyBCs)
Builds a nullspace.
static magnitudeType rmax()
Factory for building tentative prolongator.
static void SetMueLuOFileStream(const std::string &filename)
MsgType toVerbLevel(const std::string &verbLevelStr)
Print even more statistics.
void setlib(Xpetra::UnderlyingLib lib2)
static RCP< Time > getNewTimer(const std::string &name)
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...
void resize(const size_type n, const T &val=T())
void Build(Level ¤tLevel) const
Creates pre and post smoothers.
void allocateMemory(int numVectors) const
allocate multivectors for solve
bool isParameter(const std::string &name) const
bool remove(std::string const &name, bool throwIfNotExists=true)
static RCP< MultiVector > Residual(const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, const MultiVector &X, const MultiVector &RHS)
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 applyInverseAdditive(const MultiVector &RHS, MultiVector &X) const
apply additive algorithm for 2x2 solve
static void SetDefaultVerbLevel(const VerbLevel defaultVerbLevel)
Set the default (global) verbosity level.
virtual void SetParameterList(const Teuchos::ParameterList ¶mList)
Set parameters from a parameter list and return with default values.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
void resetMatrix(Teuchos::RCP< Matrix > SM_Matrix_new, bool ComputePrec=true)
Reset system matrix.
MueLu::DefaultGlobalOrdinal GlobalOrdinal
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > BuildCopy(const RCP< const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > A)
void rebalanceCoarse11Matrix(const int rebalanceStriding, const int numProcsCoarseA11)
rebalance the coarse A11 matrix, as well as P11, CoordsCoarse11 and Addon11
Class that holds all level-specific information.
bool isSublist(const std::string &name) const
static void setMatvecParams(Matrix &A, RCP< ParameterList > matvecParams)
Sets matvec params on a matrix.
RCP< Matrix > buildVectorNodalProlongator(const Teuchos::RCP< Matrix > &P_nodal) const
void dump(const RCP< Matrix > &A, std::string name) const
dump out matrix
void buildCoarse11Matrix()
Compute coarseA11 = P11^{T}*SM*P11 + addon efficiently.
Factory to export aggregation info or visualize aggregates using VTK.
Interface to Zoltan2 library.This interface provides access to partitioning methods in Zoltan2...
void deepCopy(const ArrayView< const T > &av)
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::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.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
virtual void setObjectLabel(const std::string &objectLabel)
AmalgamationFactory for subblocks of strided map based amalgamation data.
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_.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
void AddKeepFlag(const std::string &ename, const FactoryBase *factory=NoFactory::get(), KeepType keep=MueLu::Keep)
ConstIterator begin() const
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.
Teuchos::RCP< Teuchos::TimeMonitor > getTimer(std::string name, RCP< const Teuchos::Comm< int > > comm=Teuchos::null) const
get a (synced) timer
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
void compute(bool reuse=false)
Setup the preconditioner.
Applies permutation to grid transfer operators.
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
Teuchos::RCP< Teuchos::ParameterList > getValidParamterList()
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_HIGH) const
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Print all timing information.
RCP< const Tpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > toTpetra(const RCP< const CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > &graph)
Factory for creating a graph based on a given matrix.
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
static void Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Matrix &C, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
void SetLevelID(int levelID)
Set level number.
bool isType(const std::string &name) const
Class for transferring coordinates from a finer level to a coarser one.
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
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.
const Teuchos::RCP< const Map > getDomainMap() const
Returns the Xpetra::Map object associated with the domain of this operator.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Factory for creating a graph based on a given matrix.
Factory for building coarse matrices.
Exception throws to report errors in the internal logical of the program.
#define TEUCHOS_ASSERT(assertion_test)
Description of what is happening (more verbose)
Factory for building coarse matrices.
ParameterEntry & getEntry(const std::string &name)
Factory for building Smoothed Aggregation prolongators.Input/output of SaPFactory
Factory for building uncoupled aggregates.
static void thresholdedAbs(const RCP< Matrix > &A, const magnitudeType thresholded)
static std::string translate(Teuchos::ParameterList ¶mList, const std::string &defaultVals="")
: Translate ML parameters to MueLu parameter XML string
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
static void SetMueLuOStream(const Teuchos::RCP< Teuchos::FancyOStream > &mueluOStream)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
static RCP< Matrix > removeExplicitZeros(const RCP< Matrix > &A, const magnitudeType tolerance, const bool keepDiagonal=true, const size_t expectedNNZperRow=0)
Remove explicit zeros.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void Request(const FactoryBase &factory)
Increment the storage counter for all the inputs of a factory.
bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
T pop(Teuchos::ParameterList &pl, std::string const &name_in)