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");
177 params->
set(
"multigrid algorithm",
"unsmoothed");
178 params->
set(
"aggregation: type", MasterList::getDefault<std::string>(
"aggregation: type"));
179 params->
set(
"aggregation: drop tol", MasterList::getDefault<double>(
"aggregation: drop tol"));
180 params->
set(
"aggregation: drop scheme", MasterList::getDefault<std::string>(
"aggregation: drop scheme"));
181 params->
set(
"aggregation: distance laplacian algo", MasterList::getDefault<std::string>(
"aggregation: distance laplacian algo"));
182 params->
set(
"aggregation: min agg size", MasterList::getDefault<int>(
"aggregation: min agg size"));
183 params->
set(
"aggregation: max agg size", MasterList::getDefault<int>(
"aggregation: max agg size"));
184 params->
set(
"aggregation: match ML phase1", MasterList::getDefault<bool>(
"aggregation: match ML phase1"));
185 params->
set(
"aggregation: match ML phase2a", MasterList::getDefault<bool>(
"aggregation: match ML phase2a"));
186 params->
set(
"aggregation: match ML phase2b", MasterList::getDefault<bool>(
"aggregation: match ML phase2b"));
187 params->
set(
"aggregation: export visualization data", MasterList::getDefault<bool>(
"aggregation: export visualization data"));
192 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
194 if (list.
isType<std::string>(
"parameterlist: syntax") && list.
get<std::string>(
"parameterlist: syntax") ==
"ml") {
199 for (
auto it = newList2.
begin(); it != newList2.
end(); ++it) {
200 const std::string &entry_name = it->first;
203 newList.
setEntry(entry_name, theEntry);
210 if (list.
isSublist(
"refmaxwell: 22list"))
215 parameterList_ = list;
217 std::string verbosityLevel = parameterList_.get<std::string>(
"verbosity");
219 std::string outputFilename = parameterList_.get<std::string>(
"output filename");
220 if (outputFilename !=
"")
225 if (parameterList_.get<
bool>(
"print initial parameters"))
226 GetOStream(static_cast<MsgType>(
Runtime1), 0) << parameterList_ << std::endl;
227 disable_addon_ = parameterList_.get<
bool>(
"refmaxwell: disable addon");
228 disable_addon_22_ = parameterList_.get<
bool>(
"refmaxwell: disable addon 22");
229 mode_ = parameterList_.get<std::string>(
"refmaxwell: mode");
230 use_as_preconditioner_ = parameterList_.get<
bool>(
"refmaxwell: use as preconditioner");
231 dump_matrices_ = parameterList_.get<
bool>(
"refmaxwell: dump matrices");
232 enable_reuse_ = parameterList_.get<
bool>(
"refmaxwell: enable reuse");
233 implicitTranspose_ = parameterList_.get<
bool>(
"transpose: use implicit");
234 fuseProlongationAndUpdate_ = parameterList_.get<
bool>(
"fuse prolongation and update");
235 skipFirst11Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (1,1) level");
236 skipFirst22Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (2,2) level");
237 if (spaceNumber_ == 1)
238 skipFirst22Level_ =
false;
239 syncTimers_ = parameterList_.get<
bool>(
"sync timers");
240 useKokkos_ = parameterList_.get<
bool>(
"use kokkos refactor");
241 numItersCoarse11_ = parameterList_.get<
int>(
"refmaxwell: num iters coarse 11");
242 numIters22_ = parameterList_.get<
int>(
"refmaxwell: num iters 22");
243 applyBCsToAnodal_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to Anodal");
244 applyBCsToCoarse11_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to coarse 11");
245 applyBCsTo22_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to 22");
247 precList11_ = parameterList_.sublist(
"refmaxwell: 11list");
248 if (!precList11_.isType<std::string>(
"Preconditioner Type") &&
249 !precList11_.isType<std::string>(
"smoother: type") &&
250 !precList11_.isType<std::string>(
"smoother: pre type") &&
251 !precList11_.isType<std::string>(
"smoother: post type")) {
252 precList11_.set(
"smoother: type",
"CHEBYSHEV");
253 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
254 precList11_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 5.4);
255 precList11_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
258 precList22_ = parameterList_.sublist(
"refmaxwell: 22list");
259 if (!precList22_.isType<std::string>(
"Preconditioner Type") &&
260 !precList22_.isType<std::string>(
"smoother: type") &&
261 !precList22_.isType<std::string>(
"smoother: pre type") &&
262 !precList22_.isType<std::string>(
"smoother: post type")) {
263 precList22_.set(
"smoother: type",
"CHEBYSHEV");
264 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
265 precList22_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
266 precList22_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
269 if (!parameterList_.isType<std::string>(
"smoother: type") && !parameterList_.isType<std::string>(
"smoother: pre type") && !parameterList_.isType<std::string>(
"smoother: post type")) {
270 list.
set(
"smoother: type",
"CHEBYSHEV");
271 list.
sublist(
"smoother: params").
set(
"chebyshev: degree", 2);
272 list.
sublist(
"smoother: params").
set(
"chebyshev: ratio eigenvalue", 20.0);
273 list.
sublist(
"smoother: params").
set(
"chebyshev: eigenvalue max iterations", 30);
277 !precList11_.isType<std::string>(
"Preconditioner Type") &&
278 !precList11_.isParameter(
"reuse: type"))
279 precList11_.
set(
"reuse: type",
"full");
281 !precList22_.isType<std::string>(
"Preconditioner Type") &&
282 !precList22_.isParameter(
"reuse: type"))
283 precList22_.
set(
"reuse: type",
"full");
286 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
288 using memory_space =
typename Node::device_type::memory_space;
290 #ifdef HAVE_MUELU_CUDA
291 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
294 std::string timerLabel;
296 timerLabel =
"compute (reuse)";
298 timerLabel =
"compute";
310 params->
set(
"printLoadBalancingInfo",
true);
311 params->
set(
"printCommInfo",
true);
318 magnitudeType rowSumTol = parameterList_.get<
double>(
"refmaxwell: row sum drop tol (1,1)");
320 BCrows11_, BCcols22_, BCdomain22_,
321 globalNumberBoundaryUnknowns11_,
322 globalNumberBoundaryUnknowns22_,
323 onlyBoundary11_, onlyBoundary22_);
324 if (spaceNumber_ == 2) {
325 Kokkos::View<bool *, memory_space> BCcolsEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), Dk_1_->getColMap()->getLocalNumElements());
326 Kokkos::View<bool *, memory_space> BCdomainEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), Dk_1_->getDomainMap()->getLocalNumElements());
329 Kokkos::View<bool *, memory_space> BCcolsNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), D0_->getColMap()->getLocalNumElements());
330 Kokkos::View<bool *, memory_space> BCdomainNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), D0_->getDomainMap()->getLocalNumElements());
332 BCdomain22_ = BCdomainNode;
335 GetOStream(
Statistics2) << solverName_ +
"::compute(): Detected " << globalNumberBoundaryUnknowns11_ <<
" BC rows and " << globalNumberBoundaryUnknowns22_ <<
" BC columns." << std::endl;
337 dump(BCrows11_,
"BCrows11.m");
338 dump(BCcols22_,
"BCcols22.m");
339 dump(BCdomain22_,
"BCdomain22.m");
342 if (onlyBoundary11_) {
345 GetOStream(
Warnings0) <<
"All unknowns of the (1,1) block have been detected as boundary unknowns!" << std::endl;
347 setFineLevelSmoother11();
353 dim_ = NodalCoords_->getNumVectors();
360 if (Nullspace11_ != null) {
361 TEUCHOS_ASSERT(Nullspace11_->getMap()->isCompatible(*(SM_Matrix_->getRowMap())));
362 }
else if (NodalCoords_ != null) {
363 Nullspace11_ = buildNullspace(spaceNumber_, BCrows11_, skipFirst11Level_);
365 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
371 if (skipFirst11Level_) {
373 std::string label(
"D0^T*M1_beta*D0");
376 if (applyBCsToAnodal_) {
380 A11_nodal->setObjectLabel(solverName_ +
" (1,1) A_nodal");
381 dump(A11_nodal,
"A11_nodal.m");
384 M1_beta_ = Teuchos::null;
387 buildProlongator(spaceNumber_, A11_nodal, Nullspace11_, P11_, NullspaceCoarse11_, CoordsCoarse11_);
394 if (Nullspace22_ != null) {
395 TEUCHOS_ASSERT(Nullspace22_->getMap()->isCompatible(*(Dk_1_->getDomainMap())));
396 }
else if (NodalCoords_ != null)
397 Nullspace22_ = buildNullspace(spaceNumber_ - 1, BCdomain22_, skipFirst22Level_);
399 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
405 if (skipFirst22Level_) {
407 std::string label(
"D0^T*M1_alpha*D0");
410 if (applyBCsToAnodal_) {
414 A22_nodal->setObjectLabel(solverName_ +
" (2,2) A_nodal");
415 dump(A22_nodal,
"A22_nodal.m");
418 M1_alpha_ = Teuchos::null;
421 buildProlongator(spaceNumber_ - 1, A22_nodal, Nullspace22_, P22_, CoarseNullspace22_, Coords22_);
429 buildCoarse11Matrix();
434 int rebalanceStriding, numProcsCoarseA11, numProcsA22;
436 this->determineSubHierarchyCommSizes(doRebalancing, rebalanceStriding, numProcsCoarseA11, numProcsA22);
438 doRebalancing =
false;
441 if (!reuse && doRebalancing)
442 rebalanceCoarse11Matrix(rebalanceStriding, numProcsCoarseA11);
443 if (!coarseA11_.is_null()) {
444 dump(coarseA11_,
"coarseA11.m");
446 dumpCoords(CoordsCoarse11_,
"CoordsCoarse11.m");
447 dump(NullspaceCoarse11_,
"NullspaceCoarse11.m");
452 if (!implicitTranspose_) {
459 if (!coarseA11_.is_null()) {
461 std::string label(
"coarseA11");
462 setupSubSolve(HierarchyCoarse11_, thyraPrecOpH_, coarseA11_, NullspaceCoarse11_, CoordsCoarse11_, Material_beta_, precList11_, label, reuse);
468 if (!reuse && applyBCsTo22_) {
469 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC columns of Dk_1" << std::endl;
474 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
479 if (!onlyBoundary22_) {
480 GetOStream(
Runtime0) << solverName_ +
"::compute(): building MG for (2,2)-block" << std::endl;
483 build22Matrix(reuse, doRebalancing, rebalanceStriding, numProcsA22);
485 if (!P22_.is_null()) {
486 std::string label(
"P22^T*A22*P22");
488 coarseA22_->SetFixedBlockSize(A22_->GetFixedBlockSize());
489 coarseA22_->setObjectLabel(solverName_ +
" coarse (2, 2)");
490 dump(coarseA22_,
"coarseA22.m");
493 if (!reuse && !implicitTranspose_) {
499 if (!A22_.is_null()) {
501 std::string label(
"A22");
502 if (!P22_.is_null()) {
503 precList22_.sublist(
"level 1 user data").set(
"A", coarseA22_);
504 precList22_.sublist(
"level 1 user data").set(
"P", P22_);
505 if (!implicitTranspose_)
506 precList22_.sublist(
"level 1 user data").set(
"R", R22_);
507 precList22_.sublist(
"level 1 user data").set(
"Nullspace", CoarseNullspace22_);
508 precList22_.sublist(
"level 1 user data").set(
"Coordinates", Coords22_);
511 int maxCoarseSize = precList22_.get(
"coarse: max size", MasterList::getDefault<int>(
"coarse: max size"));
512 int numRows = Teuchos::as<int>(coarseA22_->getGlobalNumRows());
513 if (maxCoarseSize > numRows)
514 precList22_.set(
"coarse: max size", numRows);
515 int maxLevels = precList22_.get(
"max levels", MasterList::getDefault<int>(
"max levels"));
517 precList22_.set(
"max levels", 2);
518 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, Teuchos::null, Teuchos::null, Material_alpha_, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
520 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, CoarseNullspace22_, Coords22_, Material_alpha_, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
528 if (!reuse && !onlyBoundary22_ && applyBCsTo22_) {
529 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC rows of Dk_1" << std::endl;
534 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
535 dump(Dk_1_,
"Dk_1_nuked.m");
540 setFineLevelSmoother11();
543 if (!ImporterCoarse11_.is_null()) {
544 RCP<const Import> ImporterP11 = ImportFactory::Build(ImporterCoarse11_->getTargetMap(), P11_->getColMap());
545 toCrsMatrix(P11_)->replaceDomainMapAndImporter(ImporterCoarse11_->getTargetMap(), ImporterP11);
548 if (!Importer22_.is_null()) {
550 DorigDomainMap_ = Dk_1_->getDomainMap();
551 DorigImporter_ = toCrsMatrix(Dk_1_)->getCrsGraph()->getImporter();
553 RCP<const Import> ImporterD = ImportFactory::Build(Importer22_->getTargetMap(), Dk_1_->getColMap());
554 toCrsMatrix(Dk_1_)->replaceDomainMapAndImporter(Importer22_->getTargetMap(), ImporterD);
557 #ifdef HAVE_MUELU_TPETRA
558 if ((!Dk_1_T_.is_null()) &&
560 (!toCrsMatrix(Dk_1_T_)->getCrsGraph()->getImporter().is_null()) &&
561 (!toCrsMatrix(R11_)->getCrsGraph()->getImporter().is_null()) &&
564 Dk_1_T_R11_colMapsMatch_ = Dk_1_T_->getColMap()->isSameAs(*R11_->getColMap());
567 Dk_1_T_R11_colMapsMatch_ =
false;
568 if (Dk_1_T_R11_colMapsMatch_)
569 GetOStream(
Runtime0) << solverName_ +
"::compute(): Dk_1_T and R11 have matching colMaps" << std::endl;
571 asyncTransfers_ = parameterList_.
get<
bool>(
"refmaxwell: async transfers");
577 if (parameterList_.isSublist(
"matvec params")) {
578 RCP<ParameterList> matvecParams = rcpFromRef(parameterList_.sublist(
"matvec params"));
582 if (!Dk_1_T_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*Dk_1_T_, matvecParams);
583 if (!R11_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*R11_, matvecParams);
584 if (!ImporterCoarse11_.is_null()) ImporterCoarse11_->setDistributorParameters(matvecParams);
585 if (!Importer22_.is_null()) Importer22_->setDistributorParameters(matvecParams);
587 if (!ImporterCoarse11_.is_null() && parameterList_.isSublist(
"refmaxwell: ImporterCoarse11 params")) {
588 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: ImporterCoarse11 params"));
589 ImporterCoarse11_->setDistributorParameters(importerParams);
591 if (!Importer22_.is_null() && parameterList_.isSublist(
"refmaxwell: Importer22 params")) {
592 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: Importer22 params"));
593 Importer22_->setDistributorParameters(importerParams);
599 #ifdef HAVE_MUELU_CUDA
600 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
604 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
607 doRebalancing = parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators");
608 rebalanceStriding = parameterList_.get<
int>(
"refmaxwell: subsolves striding", -1);
609 int numProcs = SM_Matrix_->getDomainMap()->getComm()->getSize();
611 doRebalancing =
false;
623 level.
Set(
"A", coarseA11_);
627 repartheurParams.
set(
"repartition: start level", 0);
629 int defaultTargetRows = 10000;
630 repartheurParams.
set(
"repartition: min rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
631 repartheurParams.
set(
"repartition: target rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
632 repartheurParams.
set(
"repartition: min rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
633 repartheurParams.
set(
"repartition: target rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
634 repartheurParams.
set(
"repartition: max imbalance", precList11_.get<
double>(
"repartition: max imbalance", 1.1));
635 repartheurFactory->SetParameterList(repartheurParams);
637 level.
Request(
"number of partitions", repartheurFactory.get());
638 repartheurFactory->Build(level);
639 numProcsCoarseA11 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
640 numProcsCoarseA11 = std::min(numProcsCoarseA11, numProcs);
650 level.
Set(
"Map", Dk_1_->getDomainMap());
654 repartheurParams.
set(
"repartition: start level", 0);
655 repartheurParams.
set(
"repartition: use map",
true);
657 int defaultTargetRows = 10000;
658 repartheurParams.
set(
"repartition: min rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
659 repartheurParams.
set(
"repartition: target rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
660 repartheurParams.
set(
"repartition: min rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
661 repartheurParams.
set(
"repartition: target rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
663 repartheurFactory->SetParameterList(repartheurParams);
665 level.
Request(
"number of partitions", repartheurFactory.get());
666 repartheurFactory->Build(level);
667 numProcsA22 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
668 numProcsA22 = std::min(numProcsA22, numProcs);
671 if (rebalanceStriding >= 1) {
672 TEUCHOS_ASSERT(rebalanceStriding * numProcsCoarseA11 <= numProcs);
674 if (rebalanceStriding * (numProcsCoarseA11 + numProcsA22) > numProcs) {
675 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 needs " << numProcsCoarseA11
676 <<
" procs and A22 needs " << numProcsA22 <<
" procs." << std::endl;
677 rebalanceStriding = -1;
679 int lclBadMatrixDistribution = (coarseA11_->getLocalNumEntries() == 0) || (Dk_1_->getDomainMap()->getLocalNumElements() == 0);
680 int gblBadMatrixDistribution =
false;
681 MueLu_maxAll(SM_Matrix_->getDomainMap()->getComm(), lclBadMatrixDistribution, gblBadMatrixDistribution);
682 if (gblBadMatrixDistribution) {
683 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;
684 rebalanceStriding = -1;
688 if ((numProcsCoarseA11 < 0) || (numProcsA22 < 0) || (numProcsCoarseA11 + numProcsA22 > numProcs)) {
689 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling rebalancing of subsolves, since partition heuristic resulted "
690 <<
"in undesirable number of partitions: " << numProcsCoarseA11 <<
", " << numProcsA22 << std::endl;
691 doRebalancing =
false;
695 doRebalancing =
false;
699 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
702 if (spaceNumber == 0)
703 return Teuchos::null;
705 std::string timerLabel;
706 if (spaceNumber == spaceNumber_) {
707 if (skipFirst11Level_)
708 timerLabel =
"Build coarse addon matrix 11";
710 timerLabel =
"Build addon matrix 11";
712 timerLabel =
"Build addon matrix 22";
719 if (spaceNumber == spaceNumber_) {
723 "::buildCoarse11Matrix(): Inverse of "
724 "lumped mass matrix required for add-on (i.e. invMk_1_invBeta_ is null)");
725 lumpedInverse = invMk_1_invBeta_;
727 if (skipFirst11Level_) {
730 Zaux =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Mk_one_,
false, *P11_,
false, Zaux, GetOStream(
Runtime0),
true,
true);
732 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Zaux,
false, Z, GetOStream(
Runtime0),
true,
true);
735 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Mk_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
738 }
else if (spaceNumber == spaceNumber_ - 1) {
742 "::buildCoarse11Matrix(): Inverse of "
743 "lumped mass matrix required for add-on (i.e. invMk_2_invAlpha_ is null)");
744 lumpedInverse = invMk_2_invAlpha_;
747 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_2_,
true, *Mk_1_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
751 if (lumpedInverse->getGlobalMaxNumRowEntries() <= 1) {
754 RCP<Vector> diag = VectorFactory::Build(lumpedInverse->getRowMap());
755 lumpedInverse->getLocalDiagCopy(*diag);
758 for (
size_t j = 0; j < diag->getMap()->getLocalNumElements(); j++) {
762 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
765 RCP<Import> importer = ImportFactory::Build(diag->getMap(), Z->getRowMap());
766 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
768 Z->leftScale(*diag2);
770 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *Z,
false, addon, GetOStream(
Runtime0),
true,
true);
771 }
else if (parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
774 C2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*lumpedInverse,
false, *Z,
false, C2, GetOStream(
Runtime0),
true,
true);
776 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *C2,
false, addon, GetOStream(
Runtime0),
true,
true);
778 addon = MatrixFactory::Build(Z->getDomainMap());
781 MultiplyRAP(*Z,
true, *lumpedInverse,
false, *Z,
false, *addon,
true,
true);
786 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
794 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *P11_,
false, temp, GetOStream(
Runtime0),
true,
true);
795 if (ImporterCoarse11_.is_null())
796 coarseA11_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, coarseA11_, GetOStream(
Runtime0),
true,
true);
799 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
801 RCP<const Map> map = ImporterCoarse11_->getTargetMap()->removeEmptyProcesses();
802 temp2->removeEmptyProcessesInPlace(map);
804 temp2 = Teuchos::null;
808 if (!disable_addon_) {
811 if (!coarseA11_.is_null() && Addon11_.is_null()) {
812 addon = buildAddon(spaceNumber_);
819 if (!coarseA11_.is_null()) {
822 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*coarseA11_,
false, one, *addon,
false, one, newCoarseA11, GetOStream(
Runtime0));
823 newCoarseA11->fillComplete();
824 coarseA11_ = newCoarseA11;
828 if (!coarseA11_.is_null() && !skipFirst11Level_) {
830 coarseA11BCrows.
resize(coarseA11_->getRowMap()->getLocalNumElements());
831 for (
size_t i = 0; i < BCdomain22_.size(); i++)
832 for (
size_t k = 0; k < dim_; k++)
833 coarseA11BCrows[i * dim_ + k] = BCdomain22_(i);
834 magnitudeType rowSumTol = parameterList_.
get<
double>(
"refmaxwell: row sum drop tol (1,1)");
837 if (applyBCsToCoarse11_)
841 if (!coarseA11_.is_null()) {
847 bool fixZeroDiagonal = !applyBCsToAnodal_;
848 if (precList11_.isParameter(
"rap: fix zero diagonals"))
849 fixZeroDiagonal = precList11_.get<
bool>(
"rap: fix zero diagonals");
851 if (fixZeroDiagonal) {
854 if (precList11_.isType<
magnitudeType>(
"rap: fix zero diagonals threshold"))
855 threshold = precList11_.get<
magnitudeType>(
"rap: fix zero diagonals threshold");
856 else if (precList11_.isType<
double>(
"rap: fix zero diagonals threshold"))
857 threshold = Teuchos::as<magnitudeType>(precList11_.get<
double>(
"rap: fix zero diagonals threshold"));
858 if (precList11_.isType<
double>(
"rap: fix zero diagonals replacement"))
859 replacement = Teuchos::as<Scalar>(precList11_.get<
double>(
"rap: fix zero diagonals replacement"));
864 coarseA11_->SetFixedBlockSize(dim_);
865 if (skipFirst11Level_)
866 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
868 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
872 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
879 Level fineLevel, coarseLevel;
885 coarseLevel.
Set(
"A", coarseA11_);
886 coarseLevel.
Set(
"P", P11_);
887 coarseLevel.
Set(
"Coordinates", CoordsCoarse11_);
888 if (!NullspaceCoarse11_.is_null())
889 coarseLevel.
Set(
"Nullspace", NullspaceCoarse11_);
890 coarseLevel.
Set(
"number of partitions", numProcsCoarseA11);
891 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
893 coarseLevel.
setlib(coarseA11_->getDomainMap()->lib());
894 fineLevel.
setlib(coarseA11_->getDomainMap()->lib());
898 std::string partName = precList11_.get<std::string>(
"repartition: partitioner",
"zoltan2");
900 if (partName ==
"zoltan") {
901 #ifdef HAVE_MUELU_ZOLTAN
908 }
else if (partName ==
"zoltan2") {
909 #ifdef HAVE_MUELU_ZOLTAN2
913 partParams.
set(
"ParameterList", partpartParams);
914 partitioner->SetParameterList(partParams);
923 repartParams.
set(
"repartition: print partition distribution", precList11_.get<
bool>(
"repartition: print partition distribution",
false));
924 repartParams.
set(
"repartition: remap parts", precList11_.get<
bool>(
"repartition: remap parts",
true));
925 if (rebalanceStriding >= 1) {
926 bool acceptPart = (SM_Matrix_->getDomainMap()->getComm()->getRank() % rebalanceStriding) == 0;
927 if (SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsCoarseA11 * rebalanceStriding)
929 repartParams.
set(
"repartition: remap accept partition", acceptPart);
931 repartFactory->SetParameterList(repartParams);
933 repartFactory->SetFactory(
"Partition", partitioner);
937 newPparams.
set(
"type",
"Interpolation");
938 newPparams.
set(
"repartition: rebalance P and R", precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
939 newPparams.
set(
"repartition: use subcommunicators",
true);
940 newPparams.
set(
"repartition: rebalance Nullspace", !NullspaceCoarse11_.is_null());
942 if (!NullspaceCoarse11_.is_null())
944 newP->SetParameterList(newPparams);
945 newP->SetFactory(
"Importer", repartFactory);
949 rebAcParams.
set(
"repartition: use subcommunicators",
true);
950 newA->SetParameterList(rebAcParams);
951 newA->SetFactory(
"Importer", repartFactory);
953 coarseLevel.
Request(
"P", newP.get());
954 coarseLevel.
Request(
"Importer", repartFactory.get());
955 coarseLevel.
Request(
"A", newA.get());
956 coarseLevel.
Request(
"Coordinates", newP.get());
957 if (!NullspaceCoarse11_.is_null())
958 coarseLevel.
Request(
"Nullspace", newP.get());
959 repartFactory->Build(coarseLevel);
961 if (!precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
966 if (!NullspaceCoarse11_.is_null())
971 coarseA11_->SetFixedBlockSize(dim_);
972 if (skipFirst11Level_)
973 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
975 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
978 coarseA11_AP_reuse_data_ = Teuchos::null;
979 coarseA11_RAP_reuse_data_ = Teuchos::null;
981 if (!disable_addon_ && enable_reuse_) {
986 XpetraList.
set(
"Restrict Communicator",
true);
987 Addon11_ = MatrixFactory::Build(Addon11_, *ImporterCoarse11, *ImporterCoarse11, targetMap, targetMap,
rcp(&XpetraList,
false));
992 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
997 Level fineLevel, coarseLevel;
1003 fineLevel.
Set(
"A", SM_Matrix_);
1004 coarseLevel.
Set(
"P", Dk_1_);
1005 coarseLevel.
Set(
"Coordinates", Coords22_);
1007 coarseLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1008 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1014 rapList.
set(
"transpose: use implicit",
true);
1015 rapList.
set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1017 rapList.
set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
1020 if (!A22_AP_reuse_data_.is_null()) {
1024 if (!A22_RAP_reuse_data_.is_null()) {
1030 if (doRebalancing) {
1031 coarseLevel.
Set(
"number of partitions", numProcsA22);
1032 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
1034 std::string partName = precList22_.get<std::string>(
"repartition: partitioner",
"zoltan2");
1036 if (partName ==
"zoltan") {
1037 #ifdef HAVE_MUELU_ZOLTAN
1039 partitioner->SetFactory(
"A", rapFact);
1045 }
else if (partName ==
"zoltan2") {
1046 #ifdef HAVE_MUELU_ZOLTAN2
1050 partParams.
set(
"ParameterList", partpartParams);
1051 partitioner->SetParameterList(partParams);
1052 partitioner->SetFactory(
"A", rapFact);
1061 repartParams.
set(
"repartition: print partition distribution", precList22_.get<
bool>(
"repartition: print partition distribution",
false));
1062 repartParams.
set(
"repartition: remap parts", precList22_.get<
bool>(
"repartition: remap parts",
true));
1063 if (rebalanceStriding >= 1) {
1064 bool acceptPart = ((SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank()) % rebalanceStriding) == 0;
1065 if (SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsA22 * rebalanceStriding)
1069 repartParams.
set(
"repartition: remap accept partition", acceptPart);
1071 repartParams.
set(
"repartition: remap accept partition", coarseA11_.is_null());
1072 repartFactory->SetParameterList(repartParams);
1073 repartFactory->SetFactory(
"A", rapFact);
1075 repartFactory->SetFactory(
"Partition", partitioner);
1079 newPparams.
set(
"type",
"Interpolation");
1080 newPparams.
set(
"repartition: rebalance P and R", precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
1081 newPparams.
set(
"repartition: use subcommunicators",
true);
1082 newPparams.
set(
"repartition: rebalance Nullspace",
false);
1084 newP->SetParameterList(newPparams);
1085 newP->SetFactory(
"Importer", repartFactory);
1089 rebAcParams.
set(
"repartition: use subcommunicators",
true);
1090 newA->SetParameterList(rebAcParams);
1091 newA->SetFactory(
"A", rapFact);
1092 newA->SetFactory(
"Importer", repartFactory);
1094 coarseLevel.
Request(
"P", newP.get());
1095 coarseLevel.
Request(
"Importer", repartFactory.get());
1096 coarseLevel.
Request(
"A", newA.get());
1097 coarseLevel.
Request(
"Coordinates", newP.get());
1098 rapFact->
Build(fineLevel, coarseLevel);
1099 repartFactory->Build(coarseLevel);
1101 if (!precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
1107 if (!P22_.is_null()) {
1115 if (enable_reuse_) {
1116 coarseLevel.
Request(
"AP reuse data", rapFact.
get());
1117 coarseLevel.
Request(
"RAP reuse data", rapFact.
get());
1122 if (enable_reuse_) {
1131 if (Importer22_.is_null()) {
1133 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1134 if (!implicitTranspose_)
1135 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1137 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1141 toCrsMatrix(Dk_1_)->replaceDomainMapAndImporter(DorigDomainMap_, DorigImporter_);
1144 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1145 if (!implicitTranspose_)
1146 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1148 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1151 toCrsMatrix(Dk_1_)->replaceDomainMapAndImporter(Importer22_->getTargetMap(), Dimporter);
1154 XpetraList.
set(
"Restrict Communicator",
true);
1155 XpetraList.
set(
"Timer Label",
"MueLu::RebalanceA22");
1157 A22_ = MatrixFactory::Build(temp2, *Importer22_, *Importer22_, targetMap, targetMap,
rcp(&XpetraList,
false));
1161 if (not A22_.is_null() and not disable_addon_22_ and spaceNumber_ > 1) {
1164 RCP<Matrix> addon22 = buildAddon(spaceNumber_ - 1);
1168 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*A22_,
false, one, *addon22,
false, one, newA22, GetOStream(
Runtime0));
1169 newA22->fillComplete();
1173 if (!A22_.is_null()) {
1174 dump(A22_,
"A22.m");
1175 A22_->setObjectLabel(solverName_ +
" (2,2)");
1177 if (spaceNumber_ - 1 == 0)
1178 A22_->SetFixedBlockSize(1);
1180 A22_->SetFixedBlockSize(dim_);
1184 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1191 level.
Set(
"A", SM_Matrix_);
1192 level.
setlib(SM_Matrix_->getDomainMap()->lib());
1194 level.
Set(
"NodeMatrix", A22_);
1195 level.
Set(
"D0", Dk_1_);
1197 if ((parameterList_.get<std::string>(
"smoother: pre type") !=
"NONE") && (parameterList_.get<std::string>(
"smoother: post type") !=
"NONE")) {
1198 std::string preSmootherType = parameterList_.get<std::string>(
"smoother: pre type");
1199 std::string postSmootherType = parameterList_.get<std::string>(
"smoother: post type");
1202 if (parameterList_.isSublist(
"smoother: pre params"))
1203 preSmootherList = parameterList_.
sublist(
"smoother: pre params");
1204 if (parameterList_.isSublist(
"smoother: post params"))
1205 postSmootherList = parameterList_.
sublist(
"smoother: post params");
1211 level.
Request(
"PreSmoother", smootherFact.
get());
1212 level.
Request(
"PostSmoother", smootherFact.
get());
1213 if (enable_reuse_) {
1215 smootherFactoryParams.
set(
"keep smoother data",
true);
1217 level.
Request(
"PreSmoother data", smootherFact.
get());
1218 level.
Request(
"PostSmoother data", smootherFact.
get());
1219 if (!PreSmootherData11_.is_null())
1220 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1221 if (!PostSmootherData11_.is_null())
1222 level.
Set(
"PostSmoother data", PostSmootherData11_, smootherFact.
get());
1224 smootherFact->
Build(level);
1227 if (enable_reuse_) {
1232 std::string smootherType = parameterList_.
get<std::string>(
"smoother: type");
1235 if (parameterList_.isSublist(
"smoother: params"))
1236 smootherList = parameterList_.
sublist(
"smoother: params");
1240 level.
Request(
"PreSmoother", smootherFact.
get());
1241 if (enable_reuse_) {
1243 smootherFactoryParams.
set(
"keep smoother data",
true);
1245 level.
Request(
"PreSmoother data", smootherFact.
get());
1246 if (!PreSmootherData11_.is_null())
1247 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1249 smootherFact->
Build(level);
1251 PostSmoother11_ = PreSmoother11_;
1257 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1262 if (!R11_.is_null())
1263 P11res_ = MultiVectorFactory::Build(R11_->getRangeMap(), numVectors);
1265 P11res_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1266 P11res_->setObjectLabel(
"P11res");
1268 if (Dk_1_T_R11_colMapsMatch_) {
1269 DTR11Tmp_ = MultiVectorFactory::Build(R11_->getColMap(), numVectors);
1270 DTR11Tmp_->setObjectLabel(
"DTR11Tmp");
1272 if (!ImporterCoarse11_.is_null()) {
1273 P11resTmp_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1274 P11resTmp_->setObjectLabel(
"P11resTmp");
1275 P11x_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1277 P11x_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1278 P11x_->setObjectLabel(
"P11x");
1281 if (!Dk_1_T_.is_null())
1282 Dres_ = MultiVectorFactory::Build(Dk_1_T_->getRangeMap(), numVectors);
1284 Dres_ = MultiVectorFactory::Build(Dk_1_->getDomainMap(), numVectors);
1285 Dres_->setObjectLabel(
"Dres");
1287 if (!Importer22_.is_null()) {
1288 DresTmp_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1289 DresTmp_->setObjectLabel(
"DresTmp");
1290 Dx_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1291 }
else if (!onlyBoundary22_)
1292 Dx_ = MultiVectorFactory::Build(A22_->getDomainMap(), numVectors);
1294 Dx_->setObjectLabel(
"Dx");
1296 if (!coarseA11_.is_null()) {
1297 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
1298 P11resSubComm_ = MultiVectorFactory::Build(P11resTmp_,
Teuchos::View);
1300 P11resSubComm_ = MultiVectorFactory::Build(P11res_,
Teuchos::View);
1301 P11resSubComm_->replaceMap(coarseA11_->getRangeMap());
1302 P11resSubComm_->setObjectLabel(
"P11resSubComm");
1304 P11xSubComm_ = MultiVectorFactory::Build(P11x_,
Teuchos::View);
1305 P11xSubComm_->replaceMap(coarseA11_->getDomainMap());
1306 P11xSubComm_->setObjectLabel(
"P11xSubComm");
1309 if (!A22_.is_null()) {
1310 if (!Importer22_.is_null() && !implicitTranspose_)
1311 DresSubComm_ = MultiVectorFactory::Build(DresTmp_,
Teuchos::View);
1313 DresSubComm_ = MultiVectorFactory::Build(Dres_,
Teuchos::View);
1314 DresSubComm_->replaceMap(A22_->getRangeMap());
1315 DresSubComm_->setObjectLabel(
"DresSubComm");
1318 DxSubComm_->replaceMap(A22_->getDomainMap());
1319 DxSubComm_->setObjectLabel(
"DxSubComm");
1322 if (asyncTransfers_) {
1323 if (!toCrsMatrix(P11_)->getCrsGraph()->getImporter().
is_null())
1324 P11x_colmap_ = MultiVectorFactory::Build(P11_->getColMap(), numVectors);
1325 if (!toCrsMatrix(Dk_1_)->getCrsGraph()->getImporter().is_null())
1326 Dx_colmap_ = MultiVectorFactory::Build(Dk_1_->getColMap(), numVectors);
1329 residual_ = MultiVectorFactory::Build(SM_Matrix_->getDomainMap(), numVectors);
1330 residual_->setObjectLabel(
"residual");
1333 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1335 if (dump_matrices_ && !A.
is_null()) {
1336 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1341 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1343 if (dump_matrices_ && !X.
is_null()) {
1344 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1349 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1351 if (dump_matrices_ && !X.
is_null()) {
1352 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1357 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1359 if (dump_matrices_) {
1360 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1361 std::ofstream out(name);
1362 for (
size_t i = 0; i < Teuchos::as<size_t>(v.
size()); i++)
1363 out << v[i] <<
"\n";
1367 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1369 if (dump_matrices_) {
1370 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1371 std::ofstream out(name);
1372 auto vH = Kokkos::create_mirror_view(v);
1373 Kokkos::deep_copy(vH, v);
1374 out <<
"%%MatrixMarket matrix array real general\n"
1375 << vH.extent(0) <<
" 1\n";
1376 for (
size_t i = 0; i < vH.size(); i++)
1377 out << vH[i] <<
"\n";
1381 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1387 if (comm.is_null()) {
1390 SM_Matrix_->getRowMap()->getComm()->barrier();
1402 return Teuchos::null;
1405 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1407 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1408 std::string spaceLabel;
1409 if (spaceNumber == 0)
1410 spaceLabel =
"nodal";
1411 else if (spaceNumber == 1)
1412 spaceLabel =
"edge";
1413 else if (spaceNumber == 2)
1414 spaceLabel =
"face";
1421 if (spaceNumber > 0) {
1422 tm = getTimer(
"nullspace " + spaceLabel);
1423 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" nullspace" << std::endl;
1426 if (spaceNumber == 0) {
1427 return Teuchos::null;
1429 }
else if (spaceNumber == 1) {
1432 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(D0_->getRowMap(), NodalCoords_->getNumVectors());
1433 D0_->apply(*CoordsSC, *Nullspace);
1435 bool normalize = parameterList_.
get<
bool>(
"refmaxwell: normalize nullspace", MasterList::getDefault<bool>(
"refmaxwell: normalize nullspace"));
1441 for (
size_t i = 0; i < dim_; i++)
1442 localNullspace[i] = Nullspace->getData(i);
1446 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1448 for (
size_t i = 0; i < dim_; i++)
1449 lenSC += localNullspace[i][j] * localNullspace[i][j];
1451 localMinLen = std::min(localMinLen, len);
1452 localMaxLen = std::max(localMaxLen, len);
1453 localMeanLen += len;
1460 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1464 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1469 GetOStream(
Runtime0) << solverName_ +
"::compute(): normalizing nullspace" << std::endl;
1473 Array<Scalar> normsSC(NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1474 Nullspace->scale(normsSC());
1481 dump(Nullspace,
"nullspaceEdge.m");
1485 }
else if (spaceNumber == 2) {
1486 #if KOKKOS_VERSION >= 40799
1487 using ATS = KokkosKernels::ArithTraits<Scalar>;
1489 using ATS = Kokkos::ArithTraits<Scalar>;
1491 using impl_Scalar =
typename ATS::val_type;
1492 #if KOKKOS_VERSION >= 40799
1493 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1495 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1497 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1512 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1520 auto importer = facesToNodes->getCrsGraph()->getImporter();
1521 if (!importer.is_null()) {
1523 ghostedNodalCoordinates->doImport(*NodalCoords_, *importer,
Xpetra::INSERT);
1525 ghostedNodalCoordinates = NodalCoords_;
1529 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1530 auto localNodalCoordinates = ghostedNodalCoordinates->getLocalViewDevice(Xpetra::Access::ReadOnly);
1531 auto localFaceNullspace = Nullspace->getLocalViewDevice(Xpetra::Access::ReadWrite);
1534 Kokkos::parallel_for(
1535 solverName_ +
"::buildFaceProjection_nullspace",
1536 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1537 KOKKOS_LAMBDA(
const size_t f) {
1538 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1539 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1540 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1541 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1542 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1543 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1544 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1545 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1546 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1548 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1549 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1550 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1559 dump(Nullspace,
"nullspaceFace.m");
1569 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1572 #if KOKKOS_VERSION >= 40799
1573 using ATS = KokkosKernels::ArithTraits<Scalar>;
1575 using ATS = Kokkos::ArithTraits<Scalar>;
1577 using impl_Scalar =
typename ATS::val_type;
1578 #if KOKKOS_VERSION >= 40799
1579 using impl_ATS = KokkosKernels::ArithTraits<impl_Scalar>;
1581 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1583 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1585 typedef typename Matrix::local_matrix_type KCRS;
1586 typedef typename KCRS::StaticCrsGraphType graph_t;
1587 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1588 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1589 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1591 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1592 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1593 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1595 std::string spaceLabel;
1596 if (spaceNumber == 0)
1597 spaceLabel =
"nodal";
1598 else if (spaceNumber == 1)
1599 spaceLabel =
"edge";
1600 else if (spaceNumber == 2)
1601 spaceLabel =
"face";
1606 if (spaceNumber > 0) {
1607 tm = getTimer(
"projection " + spaceLabel);
1608 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" projection" << std::endl;
1612 if (spaceNumber == 0) {
1614 return Teuchos::null;
1616 }
else if (spaceNumber == 1) {
1620 }
else if (spaceNumber == 2) {
1630 dump(edgesToNodes,
"edgesToNodes.m");
1636 dump(facesToEdges,
"facesToEdges.m");
1638 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1643 dump(facesToNodes,
"facesToNodes.m");
1645 incidence = facesToNodes;
1654 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1655 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1657 auto localIncidence = incidence->getLocalMatrixDevice();
1658 size_t numLocalRows = rowMap->getLocalNumElements();
1659 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1660 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1661 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1662 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1663 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1666 Kokkos::parallel_for(
1667 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1668 range_type(0, numLocalRows + 1),
1669 KOKKOS_LAMBDA(
const size_t i) {
1670 rowptr(i) = dim * localIncidence.graph.row_map(i);
1673 auto localNullspace = Nullspace->getLocalViewDevice(Xpetra::Access::ReadOnly);
1677 Kokkos::parallel_for(
1678 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1679 range_type(0, numLocalRows),
1680 KOKKOS_LAMBDA(
const size_t f) {
1681 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1682 for (
size_t k = 0; k < dim; k++) {
1683 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1684 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1685 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1687 vals(dim * jj + k) = impl_SC_ZERO;
1693 typename CrsMatrix::local_matrix_type lclProjection(
"local projection " + spaceLabel,
1694 numLocalRows, numLocalColumns, nnzEstimate,
1695 vals, rowptr, colind);
1696 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1697 rowMap, blockColMap,
1698 blockDomainMap, rowMap);
1703 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1709 GetOStream(
Runtime0) << solverName_ +
"::compute(): building nodal prolongator" << std::endl;
1717 Level fineLevel, coarseLevel;
1723 fineLevel.
Set(
"A", A_nodal);
1724 fineLevel.
Set(
"Coordinates", NodalCoords_);
1725 fineLevel.
Set(
"DofsPerNode", 1);
1726 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1727 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1732 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1733 nullSpace->putScalar(SC_ONE);
1734 fineLevel.
Set(
"Nullspace", nullSpace);
1736 std::string algo = parameterList_.get<std::string>(
"multigrid algorithm");
1738 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1752 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1754 double dropTol = parameterList_.get<
double>(
"aggregation: drop tol");
1755 std::string dropScheme = parameterList_.get<std::string>(
"aggregation: drop scheme");
1756 std::string distLaplAlgo = parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1761 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1762 int minAggSize = parameterList_.get<
int>(
"aggregation: min agg size");
1764 int maxAggSize = parameterList_.get<
int>(
"aggregation: max agg size");
1766 bool matchMLbehavior1 = parameterList_.get<
bool>(
"aggregation: match ML phase1");
1768 bool matchMLbehavior2a = parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1770 bool matchMLbehavior2b = parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1773 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1775 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1776 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1777 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1779 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1780 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1783 SaPFact->SetFactory(
"P", TentativePFact);
1784 coarseLevel.
Request(
"P", SaPFact.get());
1786 coarseLevel.
Request(
"P", TentativePFact.get());
1787 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1788 coarseLevel.
Request(
"Coordinates", Tfact.get());
1791 bool exportVizData = parameterList_.
get<
bool>(
"aggregation: export visualization data");
1792 if (exportVizData) {
1795 aggExportParams.
set(
"aggregation: output filename",
"aggs.vtk");
1796 aggExportParams.
set(
"aggregation: output file: agg style",
"Jacks");
1799 aggExport->
SetFactory(
"Aggregates", UncoupledAggFact);
1800 aggExport->
SetFactory(
"UnAmalgamationInfo", amalgFact);
1801 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1802 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1806 coarseLevel.
Get(
"P", P_nodal, SaPFact.
get());
1808 coarseLevel.
Get(
"P", P_nodal, TentativePFact.
get());
1809 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.
get());
1810 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.
get());
1813 aggExport->
Build(fineLevel, coarseLevel);
1817 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1821 GetOStream(
Runtime0) << solverName_ +
"::compute(): building vectorial nodal prolongator" << std::endl;
1823 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1825 typedef typename Matrix::local_matrix_type KCRS;
1826 typedef typename KCRS::StaticCrsGraphType graph_t;
1827 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1828 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1829 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1834 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1835 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1836 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1839 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1841 size_t numLocalRows = blockRowMap->getLocalNumElements();
1842 size_t numLocalColumns = blockColMap->getLocalNumElements();
1843 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1844 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1845 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1846 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1849 Kokkos::parallel_for(
1850 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1851 range_type(0, localP_nodal.numRows() + 1),
1853 if (i < localP_nodal.numRows()) {
1854 for (
size_t k = 0; k < dim; k++) {
1855 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1858 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1862 Kokkos::parallel_for(
1863 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1864 range_type(0, localP_nodal.graph.entries.size()),
1865 KOKKOS_LAMBDA(
const size_t jj) {
1866 for (
size_t k = 0; k < dim; k++) {
1867 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1869 vals(dim * jj + k) = 1.;
1873 typename CrsMatrix::local_matrix_type lclVectorNodalP(
"local vector nodal prolongator",
1874 numLocalRows, numLocalColumns, nnzEstimate,
1875 vals, rowptr, colind);
1876 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1877 blockRowMap, blockColMap,
1878 blockDomainMap, blockRowMap);
1880 return vectorNodalP;
1883 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1891 #if KOKKOS_VERSION >= 40799
1892 using ATS = KokkosKernels::ArithTraits<Scalar>;
1894 using ATS = Kokkos::ArithTraits<Scalar>;
1896 using impl_Scalar =
typename ATS::val_type;
1897 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1899 std::string typeStr;
1900 switch (spaceNumber) {
1915 const bool skipFirstLevel = !A_nodal.
is_null();
1918 if (spaceNumber > 0) {
1919 tm = getTimer(
"special prolongator " + typeStr);
1920 GetOStream(
Runtime0) << solverName_ +
"::compute(): building special " + typeStr +
" prolongator" << std::endl;
1923 RCP<Matrix> projection = buildProjection(spaceNumber, Nullspace);
1924 dump(projection, typeStr +
"Projection.m");
1926 if (skipFirstLevel) {
1930 buildNodalProlongator(A_nodal, P_nodal, coarseNodalNullspace, coarseNodalCoords);
1932 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1933 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1935 RCP<Matrix> vectorP_nodal = buildVectorNodalProlongator(P_nodal);
1937 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1939 Prolongator =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator, GetOStream(
Runtime0),
true,
true);
1988 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
1990 auto localNullspace_nodal = coarseNodalNullspace->getLocalViewDevice(Xpetra::Access::ReadOnly);
1991 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Xpetra::Access::ReadWrite);
1992 Kokkos::parallel_for(
1993 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1994 range_type(0, coarseNodalNullspace->getLocalLength()),
1995 KOKKOS_LAMBDA(
const size_t i) {
1996 impl_Scalar val = localNullspace_nodal(i, 0);
1997 for (
size_t j = 0; j < dim; j++)
1998 localNullspace_coarse(dim * i + j, j) = val;
2002 Prolongator = projection;
2003 coarseNodalCoords = NodalCoords_;
2005 if (spaceNumber == 0) {
2007 }
else if (spaceNumber >= 1) {
2009 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
2010 auto localNullspace_coarse = coarseNullspace->getLocalViewDevice(Xpetra::Access::ReadWrite);
2011 Kokkos::parallel_for(
2012 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2013 range_type(0, coarseNullspace->getLocalLength() / dim),
2014 KOKKOS_LAMBDA(
const size_t i) {
2015 for (
size_t j = 0; j < dim; j++)
2016 localNullspace_coarse(dim * i + j, j) = 1.0;
2022 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2032 const bool isSingular) {
2033 int oldRank = SetProcRankVerbose(A->getDomainMap()->getComm()->getRank());
2036 pl->
set(
"printLoadBalancingInfo",
true);
2037 pl->
set(
"printCommInfo",
true);
2040 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2041 if (params.
isType<std::string>(
"Preconditioner Type")) {
2044 if (params.
get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2052 thyraPrecOp =
rcp(
new XpetraThyraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(coarseA11_,
rcp(¶ms,
false)));
2068 std::string coarseType =
"";
2070 coarseType = params.
get<std::string>(
"coarse: type");
2072 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(),
::tolower);
2073 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
2075 if ((coarseType ==
"" ||
2076 coarseType ==
"Klu" ||
2077 coarseType ==
"Klu2" ||
2078 coarseType ==
"Superlu" ||
2079 coarseType ==
"Superlu_dist" ||
2080 coarseType ==
"Superludist" ||
2081 coarseType ==
"Basker" ||
2082 coarseType ==
"Cusolver" ||
2083 coarseType ==
"Tacho") &&
2086 params.
sublist(
"coarse: params").
set(
"fix nullspace",
true);
2092 level0->
Set(
"A", A);
2096 SetProcRankVerbose(oldRank);
2099 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2101 bool reuse = !SM_Matrix_.is_null();
2102 SM_Matrix_ = SM_Matrix_new;
2103 dump(SM_Matrix_,
"SM.m");
2108 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2154 if (implicitTranspose_) {
2159 if (!onlyBoundary22_) {
2164 if (Dk_1_T_R11_colMapsMatch_) {
2168 DTR11Tmp_->doImport(*residual_, *toCrsMatrix(R11_)->getCrsGraph()->getImporter(),
Xpetra::INSERT);
2170 if (!onlyBoundary22_) {
2183 if (!onlyBoundary22_) {
2196 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2198 P11resTmp_->beginImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2200 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_) {
2206 if (!coarseA11_.is_null()) {
2207 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
2208 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2212 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2213 if (!thyraPrecOpH_.is_null()) {
2215 thyraPrecOpH_->apply(*P11resSubComm_, *P11xSubComm_,
Teuchos::NO_TRANS, one, zero);
2218 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2222 if (!A22_.is_null()) {
2223 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2227 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2228 if (!thyraPrecOp22_.is_null()) {
2230 thyraPrecOp22_->apply(*DresSubComm_, *DxSubComm_,
Teuchos::NO_TRANS, one, zero);
2233 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2236 if (coarseA11_.is_null() && !ImporterCoarse11_.is_null() && !implicitTranspose_)
2237 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2238 if (A22_.is_null() && !onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2245 if (asyncTransfers_) {
2259 unsigned completedImports = 0;
2260 std::vector<bool> completedImport(2,
false);
2261 auto tpP11importer = tpP11->getCrsGraph()->getImporter();
2262 if (!tpP11importer.is_null()) {
2263 tpP11x_colmap =
toTpetra(P11x_colmap_);
2264 tpP11x_colmap->beginImport(*tpP11x, *tpP11importer,
Tpetra::INSERT);
2268 if (!onlyBoundary22_) {
2269 tpDk_1importer = tpDk_1->getCrsGraph()->getImporter();
2270 if (!tpDk_1importer.
is_null()) {
2271 tpDx_colmap =
toTpetra(Dx_colmap_);
2272 tpDx_colmap->beginImport(*tpDx, *tpDk_1importer,
Tpetra::INSERT);
2275 completedImport[1] =
true;
2279 if (!fuseProlongationAndUpdate_) {
2281 tpResidual->putScalar(zero);
2284 while (completedImports < completedImport.size()) {
2285 for (
unsigned i = 0; i < completedImport.size(); i++) {
2286 if (completedImport[i])
continue;
2289 if (!tpP11importer.is_null()) {
2290 if (tpP11x_colmap->transferArrived()) {
2291 tpP11x_colmap->endImport(*tpP11x, *tpP11importer,
Tpetra::INSERT);
2292 completedImport[i] =
true;
2295 if (fuseProlongationAndUpdate_) {
2304 completedImport[i] =
true;
2307 if (fuseProlongationAndUpdate_) {
2316 if (!tpDk_1importer.
is_null()) {
2317 if (tpDx_colmap->transferArrived()) {
2319 completedImport[i] =
true;
2322 if (fuseProlongationAndUpdate_) {
2331 completedImport[i] =
true;
2334 if (fuseProlongationAndUpdate_) {
2346 if (!fuseProlongationAndUpdate_) {
2348 X.update(one, *residual_, one);
2351 if (fuseProlongationAndUpdate_) {
2357 if (!onlyBoundary22_) {
2367 if (!onlyBoundary22_) {
2374 X.update(one, *residual_, one);
2381 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2388 if (implicitTranspose_)
2395 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2397 P11resTmp_->doImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2399 if (!coarseA11_.is_null()) {
2401 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2408 X.update(one, *residual_, one);
2412 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2414 if (onlyBoundary22_)
2422 if (implicitTranspose_)
2429 if (!Importer22_.is_null() && !implicitTranspose_) {
2433 if (!A22_.is_null()) {
2435 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2442 X.update(one, *residual_, one);
2446 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2454 if (!onlyBoundary11_ && X.getNumVectors() != P11res_->getNumVectors())
2455 allocateMemory(X.getNumVectors());
2461 PreSmoother11_->Apply(X, RHS, use_as_preconditioner_);
2465 if (mode_ ==
"additive")
2466 applyInverseAdditive(RHS, X);
2467 else if (mode_ ==
"121") {
2471 }
else if (mode_ ==
"212") {
2475 }
else if (mode_ ==
"1")
2477 else if (mode_ ==
"2")
2479 else if (mode_ ==
"7") {
2485 PreSmoother11_->Apply(X, RHS,
false);
2492 PostSmoother11_->Apply(X, RHS,
false);
2495 }
else if (mode_ ==
"none") {
2498 applyInverseAdditive(RHS, X);
2504 PostSmoother11_->Apply(X, RHS,
false);
2508 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2513 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2518 int spaceNumber = List.
get<
int>(
"refmaxwell: space number", 1);
2527 Dk_1 =
pop(List,
"Dk_1", Dk_1);
2528 Dk_2 = pop<RCP<Matrix>>(List,
"Dk_2", Dk_2);
2529 D0 = pop<RCP<Matrix>>(List,
"D0", D0);
2531 M1_beta = pop<RCP<Matrix>>(List,
"M1_beta", M1_beta);
2532 M1_alpha = pop<RCP<Matrix>>(List,
"M1_alpha", M1_alpha);
2534 Mk_one = pop<RCP<Matrix>>(List,
"Mk_one", Mk_one);
2535 Mk_1_one = pop<RCP<Matrix>>(List,
"Mk_1_one", Mk_1_one);
2537 invMk_1_invBeta = pop<RCP<Matrix>>(List,
"invMk_1_invBeta", invMk_1_invBeta);
2538 invMk_2_invAlpha = pop<RCP<Matrix>>(List,
"invMk_2_invAlpha", invMk_2_invAlpha);
2540 Nullspace11 = pop<RCP<MultiVector>>(List,
"Nullspace11", Nullspace11);
2541 Nullspace22 = pop<RCP<MultiVector>>(List,
"Nullspace22", Nullspace22);
2542 NodalCoords = pop<RCP<RealValuedMultiVector>>(List,
"Coordinates", NodalCoords);
2546 if (M1_beta.is_null())
2552 if (Mk_one.is_null())
2558 if (invMk_1_invBeta.is_null())
2564 if (Nullspace11.is_null())
2570 if (spaceNumber == 1) {
2573 else if (D0.is_null())
2575 if (M1_beta.is_null())
2577 }
else if (spaceNumber == 2) {
2580 else if (D0.is_null())
2588 invMk_1_invBeta, invMk_2_invAlpha,
2589 Nullspace11, Nullspace22,
2591 Teuchos::null, Teuchos::null,
2594 if (SM_Matrix != Teuchos::null)
2595 resetMatrix(SM_Matrix, ComputePrec);
2598 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2609 D0_Matrix, Teuchos::null, D0_Matrix,
2610 Ms_Matrix, Teuchos::null,
2611 M1_Matrix, Teuchos::null,
2612 M0inv_Matrix, Teuchos::null,
2613 Nullspace11, Teuchos::null,
2615 Teuchos::null, Material,
2619 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2638 if (spaceNumber_ == 1)
2639 solverName_ =
"RefMaxwell";
2640 else if (spaceNumber_ == 2)
2641 solverName_ =
"RefDarcy";
2644 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2645 HierarchyCoarse11_ = Teuchos::null;
2646 Hierarchy22_ = Teuchos::null;
2647 PreSmoother11_ = Teuchos::null;
2648 PostSmoother11_ = Teuchos::null;
2649 disable_addon_ =
false;
2650 disable_addon_22_ =
true;
2654 setParameters(List);
2669 if (!disable_addon_) {
2675 if ((k >= 2) && !disable_addon_22_) {
2682 #ifdef HAVE_MUELU_DEBUG
2687 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2688 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2691 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2695 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2696 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2699 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()))
2702 if (!disable_addon_) {
2704 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2705 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2708 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2711 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2712 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2715 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2718 if ((k >= 2) && !disable_addon_22_) {
2720 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2721 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2724 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2727 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2730 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2731 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2734 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2744 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2749 toCrsMatrix(Dk_1)->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2754 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.
size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2755 Dk_1copyrowptr_RCP.
deepCopy(Dk_1rowptr_RCP());
2756 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2757 Dk_1copyvals_RCP.
deepCopy(Dk_1vals_RCP());
2758 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2761 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2762 toCrsMatrix(Dk_1)->getCrsGraph()->getImporter(),
2763 toCrsMatrix(Dk_1)->getCrsGraph()->getExporter());
2766 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2773 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2778 toCrsMatrix(Dk_2)->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2783 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.
size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2784 Dk_2copyrowptr_RCP.
deepCopy(Dk_2rowptr_RCP());
2785 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2786 Dk_2copyvals_RCP.
deepCopy(Dk_2vals_RCP());
2787 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2790 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2791 toCrsMatrix(Dk_2)->getCrsGraph()->getImporter(),
2792 toCrsMatrix(Dk_2)->getCrsGraph()->getExporter());
2795 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2798 M1_alpha_ = M1_alpha;
2800 Material_beta_ = Material_beta;
2801 Material_alpha_ = Material_alpha;
2804 Mk_1_one_ = Mk_1_one;
2806 invMk_1_invBeta_ = invMk_1_invBeta;
2807 invMk_2_invAlpha_ = invMk_2_invAlpha;
2809 NodalCoords_ = NodalCoords;
2810 Nullspace11_ = Nullspace11;
2811 Nullspace22_ = Nullspace22;
2814 dump(Dk_1_,
"Dk_1_clean.m");
2815 dump(Dk_2_,
"Dk_2_clean.m");
2817 dump(M1_beta_,
"M1_beta.m");
2818 dump(M1_alpha_,
"M1_alpha.m");
2820 dump(Mk_one_,
"Mk_one.m");
2821 dump(Mk_1_one_,
"Mk_1_one.m");
2823 dump(invMk_1_invBeta_,
"invMk_1_invBeta.m");
2824 dump(invMk_2_invAlpha_,
"invMk_2_invAlpha.m");
2826 dumpCoords(NodalCoords_,
"coords.m");
2829 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2832 std::ostringstream oss;
2838 if (!coarseA11_.is_null())
2839 root = comm->getRank();
2848 oss <<
"\n--------------------------------------------------------------------------------\n"
2849 <<
"--- " + solverName_ +
2851 "--------------------------------------------------------------------------------"
2858 SM_Matrix_->getRowMap()->getComm()->barrier();
2860 numRows = SM_Matrix_->getGlobalNumRows();
2861 nnz = SM_Matrix_->getGlobalNumEntries();
2876 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2877 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2879 if (!A22_.is_null()) {
2880 numRows = A22_->getGlobalNumRows();
2881 nnz = A22_->getGlobalNumEntries();
2883 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2889 if (PreSmoother11_ != null && PreSmoother11_ == PostSmoother11_)
2890 oss <<
"Smoother 11 both : " << PreSmoother11_->description() << std::endl;
2892 oss <<
"Smoother 11 pre : "
2893 << (PreSmoother11_ != null ? PreSmoother11_->description() :
"no smoother") << std::endl;
2894 oss <<
"Smoother 11 post : "
2895 << (PostSmoother11_ != null ? PostSmoother11_->description() :
"no smoother") << std::endl;
2900 std::string outstr = oss.str();
2904 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2906 int strLength = outstr.size();
2907 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2908 if (comm->getRank() != root)
2909 outstr.resize(strLength);
2910 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2915 if (!HierarchyCoarse11_.is_null())
2916 HierarchyCoarse11_->describe(out, GetVerbLevel());
2918 if (!Hierarchy22_.is_null())
2919 Hierarchy22_->describe(out, GetVerbLevel());
2923 std::ostringstream oss2;
2925 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2926 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;
2928 int numProcs = comm->getSize();
2936 if (!coarseA11_.is_null())
2938 if (!A22_.is_null())
2940 std::vector<char> states(numProcs, 0);
2942 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2944 states.push_back(status);
2947 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2948 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2949 for (
int j = 0; j < rowWidth; j++)
2950 if (proc + j < numProcs)
2951 if (states[proc + j] == 0)
2953 else if (states[proc + j] == 1)
2955 else if (states[proc + j] == 2)
2962 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2971 #define MUELU_REFMAXWELL_SHORT
2972 #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)