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>
1393 return Teuchos::null;
1396 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1398 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1399 std::string spaceLabel;
1400 if (spaceNumber == 0)
1401 spaceLabel =
"nodal";
1402 else if (spaceNumber == 1)
1403 spaceLabel =
"edge";
1404 else if (spaceNumber == 2)
1405 spaceLabel =
"face";
1412 if (spaceNumber > 0) {
1413 tm = getTimer(
"nullspace " + spaceLabel);
1414 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" nullspace" << std::endl;
1417 if (spaceNumber == 0) {
1418 return Teuchos::null;
1420 }
else if (spaceNumber == 1) {
1423 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(D0_->getRowMap(), NodalCoords_->getNumVectors());
1424 D0_->apply(*CoordsSC, *Nullspace);
1426 bool normalize = parameterList_.
get<
bool>(
"refmaxwell: normalize nullspace", MasterList::getDefault<bool>(
"refmaxwell: normalize nullspace"));
1432 for (
size_t i = 0; i < dim_; i++)
1433 localNullspace[i] = Nullspace->getData(i);
1437 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1439 for (
size_t i = 0; i < dim_; i++)
1440 lenSC += localNullspace[i][j] * localNullspace[i][j];
1442 localMinLen = std::min(localMinLen, len);
1443 localMaxLen = std::max(localMaxLen, len);
1444 localMeanLen += len;
1451 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1455 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1460 GetOStream(
Runtime0) << solverName_ +
"::compute(): normalizing nullspace" << std::endl;
1464 Array<Scalar> normsSC(NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1465 Nullspace->scale(normsSC());
1472 dump(Nullspace,
"nullspaceEdge.m");
1476 }
else if (spaceNumber == 2) {
1477 using ATS = Kokkos::ArithTraits<Scalar>;
1478 using impl_Scalar =
typename ATS::val_type;
1479 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1480 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1495 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1503 auto importer = facesToNodes->getCrsGraph()->getImporter();
1504 if (!importer.is_null()) {
1506 ghostedNodalCoordinates->doImport(*NodalCoords_, *importer,
Xpetra::INSERT);
1508 ghostedNodalCoordinates = NodalCoords_;
1512 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1513 auto localNodalCoordinates = ghostedNodalCoordinates->getDeviceLocalView(Xpetra::Access::ReadOnly);
1514 auto localFaceNullspace = Nullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1517 Kokkos::parallel_for(
1518 solverName_ +
"::buildFaceProjection_nullspace",
1519 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1520 KOKKOS_LAMBDA(
const size_t f) {
1521 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1522 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1523 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1524 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1525 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1526 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1527 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1528 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1529 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1531 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1532 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1533 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1542 dump(Nullspace,
"nullspaceFace.m");
1552 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1555 using ATS = Kokkos::ArithTraits<Scalar>;
1556 using impl_Scalar =
typename ATS::val_type;
1557 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1558 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1560 typedef typename Matrix::local_matrix_type KCRS;
1561 typedef typename KCRS::StaticCrsGraphType graph_t;
1562 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1563 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1564 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1566 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1567 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1568 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1570 std::string spaceLabel;
1571 if (spaceNumber == 0)
1572 spaceLabel =
"nodal";
1573 else if (spaceNumber == 1)
1574 spaceLabel =
"edge";
1575 else if (spaceNumber == 2)
1576 spaceLabel =
"face";
1581 if (spaceNumber > 0) {
1582 tm = getTimer(
"projection " + spaceLabel);
1583 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" projection" << std::endl;
1587 if (spaceNumber == 0) {
1589 return Teuchos::null;
1591 }
else if (spaceNumber == 1) {
1595 }
else if (spaceNumber == 2) {
1605 dump(edgesToNodes,
"edgesToNodes.m");
1611 dump(facesToEdges,
"facesToEdges.m");
1613 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1618 dump(facesToNodes,
"facesToNodes.m");
1620 incidence = facesToNodes;
1629 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1630 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1632 auto localIncidence = incidence->getLocalMatrixDevice();
1633 size_t numLocalRows = rowMap->getLocalNumElements();
1634 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1635 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1636 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1637 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1638 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1641 Kokkos::parallel_for(
1642 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1643 range_type(0, numLocalRows + 1),
1644 KOKKOS_LAMBDA(
const size_t i) {
1645 rowptr(i) = dim * localIncidence.graph.row_map(i);
1648 auto localNullspace = Nullspace->getDeviceLocalView(Xpetra::Access::ReadOnly);
1652 Kokkos::parallel_for(
1653 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1654 range_type(0, numLocalRows),
1655 KOKKOS_LAMBDA(
const size_t f) {
1656 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1657 for (
size_t k = 0; k < dim; k++) {
1658 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1659 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1660 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1662 vals(dim * jj + k) = impl_SC_ZERO;
1668 typename CrsMatrix::local_matrix_type lclProjection(
"local projection " + spaceLabel,
1669 numLocalRows, numLocalColumns, nnzEstimate,
1670 vals, rowptr, colind);
1671 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1672 rowMap, blockColMap,
1673 blockDomainMap, rowMap);
1678 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1684 GetOStream(
Runtime0) << solverName_ +
"::compute(): building nodal prolongator" << std::endl;
1692 Level fineLevel, coarseLevel;
1698 fineLevel.
Set(
"A", A_nodal);
1699 fineLevel.
Set(
"Coordinates", NodalCoords_);
1700 fineLevel.
Set(
"DofsPerNode", 1);
1701 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1702 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1707 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1708 nullSpace->putScalar(SC_ONE);
1709 fineLevel.
Set(
"Nullspace", nullSpace);
1711 std::string algo = parameterList_.get<std::string>(
"multigrid algorithm");
1713 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1727 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1729 double dropTol = parameterList_.get<
double>(
"aggregation: drop tol");
1730 std::string dropScheme = parameterList_.get<std::string>(
"aggregation: drop scheme");
1731 std::string distLaplAlgo = parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1737 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1738 int minAggSize = parameterList_.get<
int>(
"aggregation: min agg size");
1740 int maxAggSize = parameterList_.get<
int>(
"aggregation: max agg size");
1742 bool matchMLbehavior1 = parameterList_.get<
bool>(
"aggregation: match ML phase1");
1744 bool matchMLbehavior2a = parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1746 bool matchMLbehavior2b = parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1749 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1751 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1752 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1753 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1755 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1756 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1759 SaPFact->SetFactory(
"P", TentativePFact);
1760 coarseLevel.
Request(
"P", SaPFact.get());
1762 coarseLevel.
Request(
"P", TentativePFact.get());
1763 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1764 coarseLevel.
Request(
"Coordinates", Tfact.get());
1767 bool exportVizData = parameterList_.
get<
bool>(
"aggregation: export visualization data");
1768 if (exportVizData) {
1771 aggExportParams.
set(
"aggregation: output filename",
"aggs.vtk");
1772 aggExportParams.
set(
"aggregation: output file: agg style",
"Jacks");
1775 aggExport->
SetFactory(
"Aggregates", UncoupledAggFact);
1776 aggExport->
SetFactory(
"UnAmalgamationInfo", amalgFact);
1777 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1778 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1782 coarseLevel.
Get(
"P", P_nodal, SaPFact.
get());
1784 coarseLevel.
Get(
"P", P_nodal, TentativePFact.
get());
1785 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.
get());
1786 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.
get());
1789 aggExport->
Build(fineLevel, coarseLevel);
1793 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1797 GetOStream(
Runtime0) << solverName_ +
"::compute(): building vectorial nodal prolongator" << std::endl;
1799 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1801 typedef typename Matrix::local_matrix_type KCRS;
1802 typedef typename KCRS::StaticCrsGraphType graph_t;
1803 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1804 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1805 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1810 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1811 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1812 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1815 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1817 size_t numLocalRows = blockRowMap->getLocalNumElements();
1818 size_t numLocalColumns = blockColMap->getLocalNumElements();
1819 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1820 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1821 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1822 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1825 Kokkos::parallel_for(
1826 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1827 range_type(0, localP_nodal.numRows() + 1),
1829 if (i < localP_nodal.numRows()) {
1830 for (
size_t k = 0; k < dim; k++) {
1831 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1834 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1838 Kokkos::parallel_for(
1839 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1840 range_type(0, localP_nodal.graph.entries.size()),
1841 KOKKOS_LAMBDA(
const size_t jj) {
1842 for (
size_t k = 0; k < dim; k++) {
1843 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1845 vals(dim * jj + k) = 1.;
1849 typename CrsMatrix::local_matrix_type lclVectorNodalP(
"local vector nodal prolongator",
1850 numLocalRows, numLocalColumns, nnzEstimate,
1851 vals, rowptr, colind);
1852 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1853 blockRowMap, blockColMap,
1854 blockDomainMap, blockRowMap);
1856 return vectorNodalP;
1859 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1867 using ATS = Kokkos::ArithTraits<Scalar>;
1868 using impl_Scalar =
typename ATS::val_type;
1869 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1871 std::string typeStr;
1872 switch (spaceNumber) {
1887 const bool skipFirstLevel = !A_nodal.
is_null();
1890 if (spaceNumber > 0) {
1891 tm = getTimer(
"special prolongator " + typeStr);
1892 GetOStream(
Runtime0) << solverName_ +
"::compute(): building special " + typeStr +
" prolongator" << std::endl;
1895 RCP<Matrix> projection = buildProjection(spaceNumber, Nullspace);
1896 dump(projection, typeStr +
"Projection.m");
1898 if (skipFirstLevel) {
1902 buildNodalProlongator(A_nodal, P_nodal, coarseNodalNullspace, coarseNodalCoords);
1904 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1905 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1907 RCP<Matrix> vectorP_nodal = buildVectorNodalProlongator(P_nodal);
1909 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1911 Prolongator =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator, GetOStream(
Runtime0),
true,
true);
1960 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
1962 auto localNullspace_nodal = coarseNodalNullspace->getDeviceLocalView(Xpetra::Access::ReadOnly);
1963 auto localNullspace_coarse = coarseNullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1964 Kokkos::parallel_for(
1965 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1966 range_type(0, coarseNodalNullspace->getLocalLength()),
1967 KOKKOS_LAMBDA(
const size_t i) {
1968 impl_Scalar val = localNullspace_nodal(i, 0);
1969 for (
size_t j = 0; j < dim; j++)
1970 localNullspace_coarse(dim * i + j, j) = val;
1974 Prolongator = projection;
1975 coarseNodalCoords = NodalCoords_;
1977 if (spaceNumber == 0) {
1979 }
else if (spaceNumber >= 1) {
1981 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
1982 auto localNullspace_coarse = coarseNullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1983 Kokkos::parallel_for(
1984 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1985 range_type(0, coarseNullspace->getLocalLength() / dim),
1986 KOKKOS_LAMBDA(
const size_t i) {
1987 for (
size_t j = 0; j < dim; j++)
1988 localNullspace_coarse(dim * i + j, j) = 1.0;
1994 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2004 const bool isSingular) {
2005 int oldRank = SetProcRankVerbose(A->getDomainMap()->getComm()->getRank());
2008 pl->
set(
"printLoadBalancingInfo",
true);
2009 pl->
set(
"printCommInfo",
true);
2012 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2013 if (params.
isType<std::string>(
"Preconditioner Type")) {
2016 if (params.
get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2024 thyraPrecOp =
rcp(
new XpetraThyraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(coarseA11_,
rcp(¶ms,
false)));
2040 std::string coarseType =
"";
2042 coarseType = params.
get<std::string>(
"coarse: type");
2044 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(),
::tolower);
2045 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
2047 if ((coarseType ==
"" ||
2048 coarseType ==
"Klu" ||
2049 coarseType ==
"Klu2" ||
2050 coarseType ==
"Superlu" ||
2051 coarseType ==
"Superlu_dist" ||
2052 coarseType ==
"Superludist" ||
2053 coarseType ==
"Basker" ||
2054 coarseType ==
"Cusolver" ||
2055 coarseType ==
"Tacho") &&
2058 params.
sublist(
"coarse: params").
set(
"fix nullspace",
true);
2064 level0->
Set(
"A", A);
2068 SetProcRankVerbose(oldRank);
2071 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2073 bool reuse = !SM_Matrix_.is_null();
2074 SM_Matrix_ = SM_Matrix_new;
2075 dump(SM_Matrix_,
"SM.m");
2080 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2126 if (implicitTranspose_) {
2131 if (!onlyBoundary22_) {
2136 if (Dk_1_T_R11_colMapsMatch_) {
2140 DTR11Tmp_->doImport(*residual_, *toCrsMatrix(R11_)->getCrsGraph()->getImporter(),
Xpetra::INSERT);
2142 if (!onlyBoundary22_) {
2155 if (!onlyBoundary22_) {
2168 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2170 P11resTmp_->beginImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2172 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_) {
2178 if (!coarseA11_.is_null()) {
2179 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
2180 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2184 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2185 if (!thyraPrecOpH_.is_null()) {
2187 thyraPrecOpH_->apply(*P11resSubComm_, *P11xSubComm_,
Teuchos::NO_TRANS, one, zero);
2190 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2194 if (!A22_.is_null()) {
2195 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2199 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2200 if (!thyraPrecOp22_.is_null()) {
2202 thyraPrecOp22_->apply(*DresSubComm_, *DxSubComm_,
Teuchos::NO_TRANS, one, zero);
2205 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2208 if (coarseA11_.is_null() && !ImporterCoarse11_.is_null() && !implicitTranspose_)
2209 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2210 if (A22_.is_null() && !onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2217 if (asyncTransfers_) {
2231 unsigned completedImports = 0;
2232 std::vector<bool> completedImport(2,
false);
2233 auto tpP11importer = tpP11->getCrsGraph()->getImporter();
2234 if (!tpP11importer.is_null()) {
2235 tpP11x_colmap =
toTpetra(P11x_colmap_);
2236 tpP11x_colmap->beginImport(*tpP11x, *tpP11importer,
Tpetra::INSERT);
2240 if (!onlyBoundary22_) {
2241 tpDk_1importer = tpDk_1->getCrsGraph()->getImporter();
2242 if (!tpDk_1importer.
is_null()) {
2243 tpDx_colmap =
toTpetra(Dx_colmap_);
2244 tpDx_colmap->beginImport(*tpDx, *tpDk_1importer,
Tpetra::INSERT);
2247 completedImport[1] =
true;
2251 if (!fuseProlongationAndUpdate_) {
2253 tpResidual->putScalar(zero);
2256 while (completedImports < completedImport.size()) {
2257 for (
unsigned i = 0; i < completedImport.size(); i++) {
2258 if (completedImport[i])
continue;
2261 if (!tpP11importer.is_null()) {
2262 if (tpP11x_colmap->transferArrived()) {
2263 tpP11x_colmap->endImport(*tpP11x, *tpP11importer,
Tpetra::INSERT);
2264 completedImport[i] =
true;
2267 if (fuseProlongationAndUpdate_) {
2276 completedImport[i] =
true;
2279 if (fuseProlongationAndUpdate_) {
2288 if (!tpDk_1importer.
is_null()) {
2289 if (tpDx_colmap->transferArrived()) {
2291 completedImport[i] =
true;
2294 if (fuseProlongationAndUpdate_) {
2303 completedImport[i] =
true;
2306 if (fuseProlongationAndUpdate_) {
2318 if (!fuseProlongationAndUpdate_) {
2320 X.update(one, *residual_, one);
2323 if (fuseProlongationAndUpdate_) {
2329 if (!onlyBoundary22_) {
2339 if (!onlyBoundary22_) {
2346 X.update(one, *residual_, one);
2353 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2360 if (implicitTranspose_)
2367 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2369 P11resTmp_->doImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2371 if (!coarseA11_.is_null()) {
2373 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2380 X.update(one, *residual_, one);
2384 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2386 if (onlyBoundary22_)
2394 if (implicitTranspose_)
2401 if (!Importer22_.is_null() && !implicitTranspose_) {
2405 if (!A22_.is_null()) {
2407 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2414 X.update(one, *residual_, one);
2418 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2426 if (!onlyBoundary11_ && X.getNumVectors() != P11res_->getNumVectors())
2427 allocateMemory(X.getNumVectors());
2433 PreSmoother11_->Apply(X, RHS, use_as_preconditioner_);
2437 if (mode_ ==
"additive")
2438 applyInverseAdditive(RHS, X);
2439 else if (mode_ ==
"121") {
2443 }
else if (mode_ ==
"212") {
2447 }
else if (mode_ ==
"1")
2449 else if (mode_ ==
"2")
2451 else if (mode_ ==
"7") {
2457 PreSmoother11_->Apply(X, RHS,
false);
2464 PostSmoother11_->Apply(X, RHS,
false);
2467 }
else if (mode_ ==
"none") {
2470 applyInverseAdditive(RHS, X);
2476 PostSmoother11_->Apply(X, RHS,
false);
2480 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2485 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2490 int spaceNumber = List.
get<
int>(
"refmaxwell: space number", 1);
2499 Dk_1 =
pop(List,
"Dk_1", Dk_1);
2500 Dk_2 = pop<RCP<Matrix>>(List,
"Dk_2", Dk_2);
2501 D0 = pop<RCP<Matrix>>(List,
"D0", D0);
2503 M1_beta = pop<RCP<Matrix>>(List,
"M1_beta", M1_beta);
2504 M1_alpha = pop<RCP<Matrix>>(List,
"M1_alpha", M1_alpha);
2506 Mk_one = pop<RCP<Matrix>>(List,
"Mk_one", Mk_one);
2507 Mk_1_one = pop<RCP<Matrix>>(List,
"Mk_1_one", Mk_1_one);
2509 invMk_1_invBeta = pop<RCP<Matrix>>(List,
"invMk_1_invBeta", invMk_1_invBeta);
2510 invMk_2_invAlpha = pop<RCP<Matrix>>(List,
"invMk_2_invAlpha", invMk_2_invAlpha);
2512 Nullspace11 = pop<RCP<MultiVector>>(List,
"Nullspace11", Nullspace11);
2513 Nullspace22 = pop<RCP<MultiVector>>(List,
"Nullspace22", Nullspace22);
2514 NodalCoords = pop<RCP<RealValuedMultiVector>>(List,
"Coordinates", NodalCoords);
2518 if (M1_beta.is_null())
2524 if (Mk_one.is_null())
2530 if (invMk_1_invBeta.is_null())
2536 if (Nullspace11.is_null())
2542 if (spaceNumber == 1) {
2545 else if (D0.is_null())
2547 if (M1_beta.is_null())
2549 }
else if (spaceNumber == 2) {
2552 else if (D0.is_null())
2560 invMk_1_invBeta, invMk_2_invAlpha,
2561 Nullspace11, Nullspace22,
2563 Teuchos::null, Teuchos::null,
2566 if (SM_Matrix != Teuchos::null)
2567 resetMatrix(SM_Matrix, ComputePrec);
2570 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2581 D0_Matrix, Teuchos::null, D0_Matrix,
2582 Ms_Matrix, Teuchos::null,
2583 M1_Matrix, Teuchos::null,
2584 M0inv_Matrix, Teuchos::null,
2585 Nullspace11, Teuchos::null,
2587 Teuchos::null, Material,
2591 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2610 if (spaceNumber_ == 1)
2611 solverName_ =
"RefMaxwell";
2612 else if (spaceNumber_ == 2)
2613 solverName_ =
"RefDarcy";
2616 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2617 HierarchyCoarse11_ = Teuchos::null;
2618 Hierarchy22_ = Teuchos::null;
2619 PreSmoother11_ = Teuchos::null;
2620 PostSmoother11_ = Teuchos::null;
2621 disable_addon_ =
false;
2622 disable_addon_22_ =
true;
2626 setParameters(List);
2641 if (!disable_addon_) {
2647 if ((k >= 2) && !disable_addon_22_) {
2654 #ifdef HAVE_MUELU_DEBUG
2659 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2660 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2663 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2667 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2668 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2671 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()))
2674 if (!disable_addon_) {
2676 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2677 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2680 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2683 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2684 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2687 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2690 if ((k >= 2) && !disable_addon_22_) {
2692 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2693 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2696 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2699 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2702 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2703 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2706 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2716 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2721 toCrsMatrix(Dk_1)->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2726 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.
size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2727 Dk_1copyrowptr_RCP.
deepCopy(Dk_1rowptr_RCP());
2728 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2729 Dk_1copyvals_RCP.
deepCopy(Dk_1vals_RCP());
2730 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2733 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2734 toCrsMatrix(Dk_1)->getCrsGraph()->getImporter(),
2735 toCrsMatrix(Dk_1)->getCrsGraph()->getExporter());
2738 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2745 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2750 toCrsMatrix(Dk_2)->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2755 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.
size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2756 Dk_2copyrowptr_RCP.
deepCopy(Dk_2rowptr_RCP());
2757 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2758 Dk_2copyvals_RCP.
deepCopy(Dk_2vals_RCP());
2759 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2762 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2763 toCrsMatrix(Dk_2)->getCrsGraph()->getImporter(),
2764 toCrsMatrix(Dk_2)->getCrsGraph()->getExporter());
2767 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2770 M1_alpha_ = M1_alpha;
2772 Material_beta_ = Material_beta;
2773 Material_alpha_ = Material_alpha;
2776 Mk_1_one_ = Mk_1_one;
2778 invMk_1_invBeta_ = invMk_1_invBeta;
2779 invMk_2_invAlpha_ = invMk_2_invAlpha;
2781 NodalCoords_ = NodalCoords;
2782 Nullspace11_ = Nullspace11;
2783 Nullspace22_ = Nullspace22;
2786 dump(Dk_1_,
"Dk_1_clean.m");
2787 dump(Dk_2_,
"Dk_2_clean.m");
2789 dump(M1_beta_,
"M1_beta.m");
2790 dump(M1_alpha_,
"M1_alpha.m");
2792 dump(Mk_one_,
"Mk_one.m");
2793 dump(Mk_1_one_,
"Mk_1_one.m");
2795 dump(invMk_1_invBeta_,
"invMk_1_invBeta.m");
2796 dump(invMk_2_invAlpha_,
"invMk_2_invAlpha.m");
2798 dumpCoords(NodalCoords_,
"coords.m");
2801 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2804 std::ostringstream oss;
2810 if (!coarseA11_.is_null())
2811 root = comm->getRank();
2820 oss <<
"\n--------------------------------------------------------------------------------\n"
2821 <<
"--- " + solverName_ +
2823 "--------------------------------------------------------------------------------"
2830 SM_Matrix_->getRowMap()->getComm()->barrier();
2832 numRows = SM_Matrix_->getGlobalNumRows();
2833 nnz = SM_Matrix_->getGlobalNumEntries();
2848 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2849 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2851 if (!A22_.is_null()) {
2852 numRows = A22_->getGlobalNumRows();
2853 nnz = A22_->getGlobalNumEntries();
2855 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2861 if (PreSmoother11_ != null && PreSmoother11_ == PostSmoother11_)
2862 oss <<
"Smoother 11 both : " << PreSmoother11_->description() << std::endl;
2864 oss <<
"Smoother 11 pre : "
2865 << (PreSmoother11_ != null ? PreSmoother11_->description() :
"no smoother") << std::endl;
2866 oss <<
"Smoother 11 post : "
2867 << (PostSmoother11_ != null ? PostSmoother11_->description() :
"no smoother") << std::endl;
2872 std::string outstr = oss.str();
2876 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2878 int strLength = outstr.size();
2879 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2880 if (comm->getRank() != root)
2881 outstr.resize(strLength);
2882 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2887 if (!HierarchyCoarse11_.is_null())
2888 HierarchyCoarse11_->describe(out, GetVerbLevel());
2890 if (!Hierarchy22_.is_null())
2891 Hierarchy22_->describe(out, GetVerbLevel());
2895 std::ostringstream oss2;
2897 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2898 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;
2900 int numProcs = comm->getSize();
2908 if (!coarseA11_.is_null())
2910 if (!A22_.is_null())
2912 std::vector<char> states(numProcs, 0);
2914 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2916 states.push_back(status);
2919 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2920 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2921 for (
int j = 0; j < rowWidth; j++)
2922 if (proc + j < numProcs)
2923 if (states[proc + j] == 0)
2925 else if (states[proc + j] == 1)
2927 else if (states[proc + j] == 2)
2934 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2943 #define MUELU_REFMAXWELL_SHORT
2944 #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)
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.
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())
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitudeType
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.
Teuchos::ScalarTraits< Scalar >::coordinateType coordinateType
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)