46 #ifndef MUELU_REFMAXWELL_DEF_HPP
47 #define MUELU_REFMAXWELL_DEF_HPP
53 #include "Xpetra_Map.hpp"
61 #include "MueLu_AmalgamationFactory.hpp"
62 #include "MueLu_RAPFactory.hpp"
63 #include "MueLu_SmootherFactory.hpp"
65 #include "MueLu_CoalesceDropFactory.hpp"
66 #include "MueLu_CoarseMapFactory.hpp"
67 #include "MueLu_CoordinatesTransferFactory.hpp"
68 #include "MueLu_UncoupledAggregationFactory.hpp"
69 #include "MueLu_TentativePFactory.hpp"
70 #include "MueLu_SaPFactory.hpp"
71 #include "MueLu_AggregationExportFactory.hpp"
72 #include "MueLu_Utilities.hpp"
73 #include "MueLu_Maxwell_Utils.hpp"
75 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
76 #include "MueLu_TentativePFactory_kokkos.hpp"
77 #include <Kokkos_Core.hpp>
78 #include <KokkosSparse_CrsMatrix.hpp>
80 #include "MueLu_ZoltanInterface.hpp"
81 #include "MueLu_Zoltan2Interface.hpp"
82 #include "MueLu_RepartitionHeuristicFactory.hpp"
83 #include "MueLu_RepartitionFactory.hpp"
84 #include "MueLu_RebalanceAcFactory.hpp"
85 #include "MueLu_RebalanceTransferFactory.hpp"
92 #ifdef HAVE_MUELU_CUDA
93 #include "cuda_profiler_api.h"
97 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
103 template <
typename T>
105 T result = pl.
get<T>(name_in);
110 template <
typename T>
112 T result = pl.
get<T>(name_in, def_value);
113 pl.
remove(name_in,
false);
117 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
123 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
125 return SM_Matrix_->getDomainMap();
128 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
130 return SM_Matrix_->getRangeMap();
133 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
137 bool useKokkosDefault = !Node::is_serial;
164 params->
set(
"refmaxwell: space number", 1,
"", spaceValidator);
165 params->
set(
"verbosity", MasterList::getDefault<std::string>(
"verbosity"));
166 params->
set(
"use kokkos refactor", useKokkosDefault);
167 params->
set(
"half precision",
false);
168 params->
set(
"parameterlist: syntax", MasterList::getDefault<std::string>(
"parameterlist: syntax"));
169 params->
set(
"output filename", MasterList::getDefault<std::string>(
"output filename"));
170 params->
set(
"print initial parameters", MasterList::getDefault<bool>(
"print initial parameters"));
171 params->
set(
"refmaxwell: disable addon", MasterList::getDefault<bool>(
"refmaxwell: disable addon"));
172 params->
set(
"refmaxwell: disable addon 22",
true);
173 params->
set(
"refmaxwell: mode", MasterList::getDefault<std::string>(
"refmaxwell: mode"));
174 params->
set(
"refmaxwell: use as preconditioner", MasterList::getDefault<bool>(
"refmaxwell: use as preconditioner"));
175 params->
set(
"refmaxwell: dump matrices", MasterList::getDefault<bool>(
"refmaxwell: dump matrices"));
176 params->
set(
"refmaxwell: enable reuse", MasterList::getDefault<bool>(
"refmaxwell: enable reuse"));
177 params->
set(
"refmaxwell: skip first (1,1) level", MasterList::getDefault<bool>(
"refmaxwell: skip first (1,1) level"));
178 params->
set(
"refmaxwell: skip first (2,2) level",
false);
179 params->
set(
"multigrid algorithm",
"Unsmoothed");
180 params->
set(
"transpose: use implicit", MasterList::getDefault<bool>(
"transpose: use implicit"));
181 params->
set(
"rap: triple product", MasterList::getDefault<bool>(
"rap: triple product"));
182 params->
set(
"rap: fix zero diagonals",
true);
183 params->
set(
"rap: fix zero diagonals threshold", MasterList::getDefault<double>(
"rap: fix zero diagonals threshold"));
184 params->
set(
"fuse prolongation and update", MasterList::getDefault<bool>(
"fuse prolongation and update"));
185 params->
set(
"refmaxwell: subsolves on subcommunicators", MasterList::getDefault<bool>(
"refmaxwell: subsolves on subcommunicators"));
186 params->
set(
"refmaxwell: subsolves striding", 1);
187 params->
set(
"refmaxwell: row sum drop tol (1,1)", MasterList::getDefault<double>(
"aggregation: row sum drop tol"));
188 params->
set(
"sync timers",
false);
189 params->
set(
"refmaxwell: num iters coarse 11", 1);
190 params->
set(
"refmaxwell: num iters 22", 1);
191 params->
set(
"refmaxwell: apply BCs to Anodal",
false);
192 params->
set(
"refmaxwell: apply BCs to coarse 11",
true);
193 params->
set(
"refmaxwell: apply BCs to 22",
true);
194 params->
set(
"refmaxwell: max coarse size", 1);
201 params->
set(
"smoother: type",
"CHEBYSHEV");
204 params->
set(
"smoother: pre type",
"NONE");
207 params->
set(
"smoother: post type",
"NONE");
214 params->
set(
"multigrid algorithm",
"unsmoothed");
215 params->
set(
"aggregation: type", MasterList::getDefault<std::string>(
"aggregation: type"));
216 params->
set(
"aggregation: drop tol", MasterList::getDefault<double>(
"aggregation: drop tol"));
217 params->
set(
"aggregation: drop scheme", MasterList::getDefault<std::string>(
"aggregation: drop scheme"));
218 params->
set(
"aggregation: distance laplacian algo", MasterList::getDefault<std::string>(
"aggregation: distance laplacian algo"));
219 params->
set(
"aggregation: min agg size", MasterList::getDefault<int>(
"aggregation: min agg size"));
220 params->
set(
"aggregation: max agg size", MasterList::getDefault<int>(
"aggregation: max agg size"));
221 params->
set(
"aggregation: match ML phase1", MasterList::getDefault<bool>(
"aggregation: match ML phase1"));
222 params->
set(
"aggregation: match ML phase2a", MasterList::getDefault<bool>(
"aggregation: match ML phase2a"));
223 params->
set(
"aggregation: match ML phase2b", MasterList::getDefault<bool>(
"aggregation: match ML phase2b"));
224 params->
set(
"aggregation: export visualization data", MasterList::getDefault<bool>(
"aggregation: export visualization data"));
229 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
231 if (list.
isType<std::string>(
"parameterlist: syntax") && list.
get<std::string>(
"parameterlist: syntax") ==
"ml") {
236 for (
auto it = newList2.
begin(); it != newList2.
end(); ++it) {
237 const std::string &entry_name = it->first;
240 newList.
setEntry(entry_name, theEntry);
247 if (list.
isSublist(
"refmaxwell: 22list"))
252 parameterList_ = list;
254 std::string verbosityLevel = parameterList_.get<std::string>(
"verbosity");
256 std::string outputFilename = parameterList_.get<std::string>(
"output filename");
257 if (outputFilename !=
"")
262 if (parameterList_.get<
bool>(
"print initial parameters"))
263 GetOStream(static_cast<MsgType>(
Runtime1), 0) << parameterList_ << std::endl;
264 disable_addon_ = parameterList_.get<
bool>(
"refmaxwell: disable addon");
265 disable_addon_22_ = parameterList_.get<
bool>(
"refmaxwell: disable addon 22");
266 mode_ = parameterList_.get<std::string>(
"refmaxwell: mode");
267 use_as_preconditioner_ = parameterList_.get<
bool>(
"refmaxwell: use as preconditioner");
268 dump_matrices_ = parameterList_.get<
bool>(
"refmaxwell: dump matrices");
269 enable_reuse_ = parameterList_.get<
bool>(
"refmaxwell: enable reuse");
270 implicitTranspose_ = parameterList_.get<
bool>(
"transpose: use implicit");
271 fuseProlongationAndUpdate_ = parameterList_.get<
bool>(
"fuse prolongation and update");
272 skipFirst11Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (1,1) level");
273 skipFirst22Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (2,2) level");
274 if (spaceNumber_ == 1)
275 skipFirst22Level_ =
false;
276 syncTimers_ = parameterList_.get<
bool>(
"sync timers");
277 useKokkos_ = parameterList_.get<
bool>(
"use kokkos refactor");
278 numItersCoarse11_ = parameterList_.get<
int>(
"refmaxwell: num iters coarse 11");
279 numIters22_ = parameterList_.get<
int>(
"refmaxwell: num iters 22");
280 applyBCsToAnodal_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to Anodal");
281 applyBCsToCoarse11_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to coarse 11");
282 applyBCsTo22_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to 22");
284 precList11_ = parameterList_.sublist(
"refmaxwell: 11list");
285 if (!precList11_.isType<std::string>(
"Preconditioner Type") &&
286 !precList11_.isType<std::string>(
"smoother: type") &&
287 !precList11_.isType<std::string>(
"smoother: pre type") &&
288 !precList11_.isType<std::string>(
"smoother: post type")) {
289 precList11_.set(
"smoother: type",
"CHEBYSHEV");
290 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
291 precList11_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 5.4);
292 precList11_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
295 precList22_ = parameterList_.sublist(
"refmaxwell: 22list");
296 if (!precList22_.isType<std::string>(
"Preconditioner Type") &&
297 !precList22_.isType<std::string>(
"smoother: type") &&
298 !precList22_.isType<std::string>(
"smoother: pre type") &&
299 !precList22_.isType<std::string>(
"smoother: post type")) {
300 precList22_.set(
"smoother: type",
"CHEBYSHEV");
301 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
302 precList22_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
303 precList22_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
306 if (!parameterList_.isType<std::string>(
"smoother: type") && !parameterList_.isType<std::string>(
"smoother: pre type") && !parameterList_.isType<std::string>(
"smoother: post type")) {
307 list.
set(
"smoother: type",
"CHEBYSHEV");
308 list.
sublist(
"smoother: params").
set(
"chebyshev: degree", 2);
309 list.
sublist(
"smoother: params").
set(
"chebyshev: ratio eigenvalue", 20.0);
310 list.
sublist(
"smoother: params").
set(
"chebyshev: eigenvalue max iterations", 30);
314 !precList11_.isType<std::string>(
"Preconditioner Type") &&
315 !precList11_.isParameter(
"reuse: type"))
316 precList11_.
set(
"reuse: type",
"full");
318 !precList22_.isType<std::string>(
"Preconditioner Type") &&
319 !precList22_.isParameter(
"reuse: type"))
320 precList22_.
set(
"reuse: type",
"full");
325 if (useKokkos_ && precList11_.isParameter(
"aggregation: drop tol") && precList11_.get<
double>(
"aggregation: drop tol") != 0.0) {
326 GetOStream(
Warnings0) << solverName_ +
"::compute(): Setting \"aggregation: drop tol\". to 0.0, since CoalesceDropFactory_kokkos does not "
327 <<
"support BlockSize > 1 and drop tol != 0.0" << std::endl;
328 precList11_.
set(
"aggregation: drop tol", 0.0);
332 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
334 using memory_space =
typename Node::device_type::memory_space;
336 #ifdef HAVE_MUELU_CUDA
337 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
340 std::string timerLabel;
342 timerLabel =
"compute (reuse)";
344 timerLabel =
"compute";
356 params->
set(
"printLoadBalancingInfo",
true);
357 params->
set(
"printCommInfo",
true);
364 magnitudeType rowSumTol = parameterList_.get<
double>(
"refmaxwell: row sum drop tol (1,1)");
366 BCrows11_, BCcols22_, BCdomain22_,
367 globalNumberBoundaryUnknowns11_,
368 globalNumberBoundaryUnknowns22_,
369 onlyBoundary11_, onlyBoundary22_);
370 if (spaceNumber_ == 2) {
371 Kokkos::View<bool *, memory_space> BCcolsEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), Dk_1_->getColMap()->getLocalNumElements());
372 Kokkos::View<bool *, memory_space> BCdomainEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), Dk_1_->getDomainMap()->getLocalNumElements());
375 Kokkos::View<bool *, memory_space> BCcolsNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), D0_->getColMap()->getLocalNumElements());
376 Kokkos::View<bool *, memory_space> BCdomainNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), D0_->getDomainMap()->getLocalNumElements());
378 BCdomain22_ = BCdomainNode;
381 GetOStream(
Statistics2) << solverName_ +
"::compute(): Detected " << globalNumberBoundaryUnknowns11_ <<
" BC rows and " << globalNumberBoundaryUnknowns22_ <<
" BC columns." << std::endl;
383 dump(BCrows11_,
"BCrows11.m");
384 dump(BCcols22_,
"BCcols22.m");
385 dump(BCdomain22_,
"BCdomain22.m");
388 if (onlyBoundary11_) {
391 GetOStream(
Warnings0) <<
"All unknowns of the (1,1) block have been detected as boundary unknowns!" << std::endl;
393 setFineLevelSmoother11();
399 dim_ = NodalCoords_->getNumVectors();
406 if (Nullspace11_ != null) {
407 TEUCHOS_ASSERT(Nullspace11_->getMap()->isCompatible(*(SM_Matrix_->getRowMap())));
408 }
else if (NodalCoords_ != null) {
409 Nullspace11_ = buildNullspace(spaceNumber_, BCrows11_, skipFirst11Level_);
411 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
417 if (skipFirst11Level_) {
419 std::string label(
"D0^T*M1_beta*D0");
422 if (applyBCsToAnodal_) {
426 A11_nodal->setObjectLabel(solverName_ +
" (1,1) A_nodal");
427 dump(A11_nodal,
"A11_nodal.m");
430 M1_beta_ = Teuchos::null;
433 buildProlongator(spaceNumber_, A11_nodal, Nullspace11_, P11_, NullspaceCoarse11_, CoordsCoarse11_);
440 if (Nullspace22_ != null) {
441 TEUCHOS_ASSERT(Nullspace22_->getMap()->isCompatible(*(Dk_1_->getDomainMap())));
442 }
else if (NodalCoords_ != null)
443 Nullspace22_ = buildNullspace(spaceNumber_ - 1, BCdomain22_, skipFirst22Level_);
445 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
451 if (skipFirst22Level_) {
453 std::string label(
"D0^T*M1_alpha*D0");
456 if (applyBCsToAnodal_) {
460 A22_nodal->setObjectLabel(solverName_ +
" (2,2) A_nodal");
461 dump(A22_nodal,
"A22_nodal.m");
464 M1_alpha_ = Teuchos::null;
467 buildProlongator(spaceNumber_ - 1, A22_nodal, Nullspace22_, P22_, CoarseNullspace22_, Coords22_);
475 buildCoarse11Matrix();
480 int rebalanceStriding, numProcsCoarseA11, numProcsA22;
482 this->determineSubHierarchyCommSizes(doRebalancing, rebalanceStriding, numProcsCoarseA11, numProcsA22);
484 doRebalancing =
false;
487 if (!reuse && doRebalancing)
488 rebalanceCoarse11Matrix(rebalanceStriding, numProcsCoarseA11);
489 if (!coarseA11_.is_null()) {
490 dump(coarseA11_,
"coarseA11.m");
492 dumpCoords(CoordsCoarse11_,
"CoordsCoarse11.m");
493 dump(NullspaceCoarse11_,
"NullspaceCoarse11.m");
498 if (!implicitTranspose_) {
505 if (!coarseA11_.is_null()) {
507 std::string label(
"coarseA11");
508 setupSubSolve(HierarchyCoarse11_, thyraPrecOpH_, coarseA11_, NullspaceCoarse11_, CoordsCoarse11_, precList11_, label, reuse);
514 if (!reuse && applyBCsTo22_) {
515 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC columns of Dk_1" << std::endl;
520 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
525 if (!onlyBoundary22_) {
526 GetOStream(
Runtime0) << solverName_ +
"::compute(): building MG for (2,2)-block" << std::endl;
529 build22Matrix(reuse, doRebalancing, rebalanceStriding, numProcsA22);
531 if (!P22_.is_null()) {
532 std::string label(
"P22^T*A22*P22");
534 coarseA22_->SetFixedBlockSize(A22_->GetFixedBlockSize());
535 coarseA22_->setObjectLabel(solverName_ +
" coarse (2, 2)");
536 dump(coarseA22_,
"coarseA22.m");
539 if (!reuse && !implicitTranspose_) {
545 if (!A22_.is_null()) {
547 std::string label(
"A22");
548 if (!P22_.is_null()) {
549 precList22_.sublist(
"level 1 user data").set(
"A", coarseA22_);
550 precList22_.sublist(
"level 1 user data").set(
"P", P22_);
551 if (!implicitTranspose_)
552 precList22_.sublist(
"level 1 user data").set(
"R", R22_);
553 precList22_.sublist(
"level 1 user data").set(
"Nullspace", CoarseNullspace22_);
554 precList22_.sublist(
"level 1 user data").set(
"Coordinates", Coords22_);
557 int maxCoarseSize = precList22_.get(
"coarse: max size", MasterList::getDefault<int>(
"coarse: max size"));
558 int numRows = Teuchos::as<int>(coarseA22_->getGlobalNumRows());
559 if (maxCoarseSize > numRows)
560 precList22_.set(
"coarse: max size", numRows);
561 int maxLevels = precList22_.get(
"max levels", MasterList::getDefault<int>(
"max levels"));
563 precList22_.set(
"max levels", 2);
564 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, Teuchos::null, Teuchos::null, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
566 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, CoarseNullspace22_, Coords22_, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
574 if (!reuse && !onlyBoundary22_ && applyBCsTo22_) {
575 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC rows of Dk_1" << std::endl;
580 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
581 dump(Dk_1_,
"Dk_1_nuked.m");
586 setFineLevelSmoother11();
589 if (!ImporterCoarse11_.is_null()) {
590 RCP<const Import> ImporterP11 = ImportFactory::Build(ImporterCoarse11_->getTargetMap(), P11_->getColMap());
591 rcp_dynamic_cast<CrsMatrixWrap>(P11_)->getCrsMatrix()->replaceDomainMapAndImporter(ImporterCoarse11_->getTargetMap(), ImporterP11);
594 if (!Importer22_.is_null()) {
596 DorigDomainMap_ = Dk_1_->getDomainMap();
597 DorigImporter_ = rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->getCrsGraph()->getImporter();
599 RCP<const Import> ImporterD = ImportFactory::Build(Importer22_->getTargetMap(), Dk_1_->getColMap());
600 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->replaceDomainMapAndImporter(Importer22_->getTargetMap(), ImporterD);
603 #ifdef HAVE_MUELU_TPETRA
604 if ((!Dk_1_T_.is_null()) &&
606 (!rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_T_)->getCrsMatrix()->getCrsGraph()->getImporter().is_null()) &&
607 (!rcp_dynamic_cast<CrsMatrixWrap>(R11_)->getCrsMatrix()->getCrsGraph()->getImporter().is_null()) &&
610 Dk_1_T_R11_colMapsMatch_ = Dk_1_T_->getColMap()->isSameAs(*R11_->getColMap());
613 Dk_1_T_R11_colMapsMatch_ =
false;
614 if (Dk_1_T_R11_colMapsMatch_)
615 GetOStream(
Runtime0) << solverName_ +
"::compute(): Dk_1_T and R11 have matching colMaps" << std::endl;
621 if (parameterList_.isSublist(
"matvec params")) {
622 RCP<ParameterList> matvecParams = rcpFromRef(parameterList_.sublist(
"matvec params"));
626 if (!Dk_1_T_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*Dk_1_T_, matvecParams);
627 if (!R11_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*R11_, matvecParams);
628 if (!ImporterCoarse11_.is_null()) ImporterCoarse11_->setDistributorParameters(matvecParams);
629 if (!Importer22_.is_null()) Importer22_->setDistributorParameters(matvecParams);
631 if (!ImporterCoarse11_.is_null() && parameterList_.isSublist(
"refmaxwell: ImporterCoarse11 params")) {
632 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: ImporterCoarse11 params"));
633 ImporterCoarse11_->setDistributorParameters(importerParams);
635 if (!Importer22_.is_null() && parameterList_.isSublist(
"refmaxwell: Importer22 params")) {
636 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: Importer22 params"));
637 Importer22_->setDistributorParameters(importerParams);
643 #ifdef HAVE_MUELU_CUDA
644 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
648 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
651 doRebalancing = parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators");
652 rebalanceStriding = parameterList_.get<
int>(
"refmaxwell: subsolves striding", -1);
653 int numProcs = SM_Matrix_->getDomainMap()->getComm()->getSize();
655 doRebalancing =
false;
667 level.
Set(
"A", coarseA11_);
671 repartheurParams.
set(
"repartition: start level", 0);
673 int defaultTargetRows = 10000;
674 repartheurParams.
set(
"repartition: min rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
675 repartheurParams.
set(
"repartition: target rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
676 repartheurParams.
set(
"repartition: min rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
677 repartheurParams.
set(
"repartition: target rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
678 repartheurParams.
set(
"repartition: max imbalance", precList11_.get<
double>(
"repartition: max imbalance", 1.1));
679 repartheurFactory->SetParameterList(repartheurParams);
681 level.
Request(
"number of partitions", repartheurFactory.get());
682 repartheurFactory->Build(level);
683 numProcsCoarseA11 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
684 numProcsCoarseA11 = std::min(numProcsCoarseA11, numProcs);
694 level.
Set(
"Map", Dk_1_->getDomainMap());
698 repartheurParams.
set(
"repartition: start level", 0);
699 repartheurParams.
set(
"repartition: use map",
true);
701 int defaultTargetRows = 10000;
702 repartheurParams.
set(
"repartition: min rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
703 repartheurParams.
set(
"repartition: target rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
704 repartheurParams.
set(
"repartition: min rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
705 repartheurParams.
set(
"repartition: target rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
707 repartheurFactory->SetParameterList(repartheurParams);
709 level.
Request(
"number of partitions", repartheurFactory.get());
710 repartheurFactory->Build(level);
711 numProcsA22 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
712 numProcsA22 = std::min(numProcsA22, numProcs);
715 if (rebalanceStriding >= 1) {
716 TEUCHOS_ASSERT(rebalanceStriding * numProcsCoarseA11 <= numProcs);
718 if (rebalanceStriding * (numProcsCoarseA11 + numProcsA22) > numProcs) {
719 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 needs " << numProcsCoarseA11
720 <<
" procs and A22 needs " << numProcsA22 <<
" procs." << std::endl;
721 rebalanceStriding = -1;
723 int lclBadMatrixDistribution = (coarseA11_->getLocalNumEntries() == 0) || (Dk_1_->getDomainMap()->getLocalNumElements() == 0);
724 int gblBadMatrixDistribution =
false;
725 MueLu_maxAll(SM_Matrix_->getDomainMap()->getComm(), lclBadMatrixDistribution, gblBadMatrixDistribution);
726 if (gblBadMatrixDistribution) {
727 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;
728 rebalanceStriding = -1;
732 if ((numProcsCoarseA11 < 0) || (numProcsA22 < 0) || (numProcsCoarseA11 + numProcsA22 > numProcs)) {
733 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling rebalancing of subsolves, since partition heuristic resulted "
734 <<
"in undesirable number of partitions: " << numProcsCoarseA11 <<
", " << numProcsA22 << std::endl;
735 doRebalancing =
false;
739 doRebalancing =
false;
743 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
746 if (spaceNumber == 0)
747 return Teuchos::null;
749 std::string timerLabel;
750 if (spaceNumber == spaceNumber_) {
751 if (skipFirst11Level_)
752 timerLabel =
"Build coarse addon matrix 11";
754 timerLabel =
"Build addon matrix 11";
756 timerLabel =
"Build addon matrix 22";
763 if (spaceNumber == spaceNumber_) {
767 "::buildCoarse11Matrix(): Inverse of "
768 "lumped mass matrix required for add-on (i.e. invMk_1_invBeta_ is null)");
769 lumpedInverse = invMk_1_invBeta_;
771 if (skipFirst11Level_) {
774 Zaux =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Mk_one_,
false, *P11_,
false, Zaux, GetOStream(
Runtime0),
true,
true);
776 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Zaux,
false, Z, GetOStream(
Runtime0),
true,
true);
779 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Mk_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
782 }
else if (spaceNumber == spaceNumber_ - 1) {
786 "::buildCoarse11Matrix(): Inverse of "
787 "lumped mass matrix required for add-on (i.e. invMk_2_invAlpha_ is null)");
788 lumpedInverse = invMk_2_invAlpha_;
791 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_2_,
true, *Mk_1_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
795 if (lumpedInverse->getGlobalMaxNumRowEntries() <= 1) {
798 RCP<Vector> diag = VectorFactory::Build(lumpedInverse->getRowMap());
799 lumpedInverse->getLocalDiagCopy(*diag);
802 for (
size_t j = 0; j < diag->getMap()->getLocalNumElements(); j++) {
806 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
809 RCP<Import> importer = ImportFactory::Build(diag->getMap(), Z->getRowMap());
810 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
812 Z->leftScale(*diag2);
814 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *Z,
false, addon, GetOStream(
Runtime0),
true,
true);
815 }
else if (parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
818 C2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*lumpedInverse,
false, *Z,
false, C2, GetOStream(
Runtime0),
true,
true);
820 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *C2,
false, addon, GetOStream(
Runtime0),
true,
true);
822 addon = MatrixFactory::Build(Z->getDomainMap());
825 MultiplyRAP(*Z,
true, *lumpedInverse,
false, *Z,
false, *addon,
true,
true);
830 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
838 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *P11_,
false, temp, GetOStream(
Runtime0),
true,
true);
839 if (ImporterCoarse11_.is_null())
840 coarseA11_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, coarseA11_, GetOStream(
Runtime0),
true,
true);
843 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
845 RCP<const Map> map = ImporterCoarse11_->getTargetMap()->removeEmptyProcesses();
846 temp2->removeEmptyProcessesInPlace(map);
848 temp2 = Teuchos::null;
852 if (!disable_addon_) {
855 if (!coarseA11_.is_null() && Addon11_.is_null()) {
856 addon = buildAddon(spaceNumber_);
863 if (!coarseA11_.is_null()) {
866 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*coarseA11_,
false, one, *addon,
false, one, newCoarseA11, GetOStream(
Runtime0));
867 newCoarseA11->fillComplete();
868 coarseA11_ = newCoarseA11;
872 if (!coarseA11_.is_null() && !skipFirst11Level_) {
874 coarseA11BCrows.
resize(coarseA11_->getRowMap()->getLocalNumElements());
875 for (
size_t i = 0; i < BCdomain22_.size(); i++)
876 for (
size_t k = 0; k < dim_; k++)
877 coarseA11BCrows[i * dim_ + k] = BCdomain22_(i);
878 magnitudeType rowSumTol = parameterList_.
get<
double>(
"refmaxwell: row sum drop tol (1,1)");
881 if (applyBCsToCoarse11_)
885 if (!coarseA11_.is_null()) {
891 bool fixZeroDiagonal = !applyBCsToAnodal_;
892 if (precList11_.isParameter(
"rap: fix zero diagonals"))
893 fixZeroDiagonal = precList11_.get<
bool>(
"rap: fix zero diagonals");
895 if (fixZeroDiagonal) {
898 if (precList11_.isType<
magnitudeType>(
"rap: fix zero diagonals threshold"))
899 threshold = precList11_.get<
magnitudeType>(
"rap: fix zero diagonals threshold");
900 else if (precList11_.isType<
double>(
"rap: fix zero diagonals threshold"))
901 threshold = Teuchos::as<magnitudeType>(precList11_.get<
double>(
"rap: fix zero diagonals threshold"));
902 if (precList11_.isType<
double>(
"rap: fix zero diagonals replacement"))
903 replacement = Teuchos::as<Scalar>(precList11_.get<
double>(
"rap: fix zero diagonals replacement"));
908 coarseA11_->SetFixedBlockSize(dim_);
909 if (skipFirst11Level_)
910 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
912 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
916 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
923 Level fineLevel, coarseLevel;
929 coarseLevel.
Set(
"A", coarseA11_);
930 coarseLevel.
Set(
"P", P11_);
931 coarseLevel.
Set(
"Coordinates", CoordsCoarse11_);
932 if (!NullspaceCoarse11_.is_null())
933 coarseLevel.
Set(
"Nullspace", NullspaceCoarse11_);
934 coarseLevel.
Set(
"number of partitions", numProcsCoarseA11);
935 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
937 coarseLevel.
setlib(coarseA11_->getDomainMap()->lib());
938 fineLevel.
setlib(coarseA11_->getDomainMap()->lib());
942 std::string partName = precList11_.get<std::string>(
"repartition: partitioner",
"zoltan2");
944 if (partName ==
"zoltan") {
945 #ifdef HAVE_MUELU_ZOLTAN
952 }
else if (partName ==
"zoltan2") {
953 #ifdef HAVE_MUELU_ZOLTAN2
957 partParams.
set(
"ParameterList", partpartParams);
958 partitioner->SetParameterList(partParams);
967 repartParams.
set(
"repartition: print partition distribution", precList11_.get<
bool>(
"repartition: print partition distribution",
false));
968 repartParams.
set(
"repartition: remap parts", precList11_.get<
bool>(
"repartition: remap parts",
true));
969 if (rebalanceStriding >= 1) {
970 bool acceptPart = (SM_Matrix_->getDomainMap()->getComm()->getRank() % rebalanceStriding) == 0;
971 if (SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsCoarseA11 * rebalanceStriding)
973 repartParams.
set(
"repartition: remap accept partition", acceptPart);
975 repartFactory->SetParameterList(repartParams);
977 repartFactory->SetFactory(
"Partition", partitioner);
981 newPparams.
set(
"type",
"Interpolation");
982 newPparams.
set(
"repartition: rebalance P and R", precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
983 newPparams.
set(
"repartition: use subcommunicators",
true);
984 newPparams.
set(
"repartition: rebalance Nullspace", !NullspaceCoarse11_.is_null());
986 if (!NullspaceCoarse11_.is_null())
988 newP->SetParameterList(newPparams);
989 newP->SetFactory(
"Importer", repartFactory);
993 rebAcParams.
set(
"repartition: use subcommunicators",
true);
994 newA->SetParameterList(rebAcParams);
995 newA->SetFactory(
"Importer", repartFactory);
997 coarseLevel.
Request(
"P", newP.get());
998 coarseLevel.
Request(
"Importer", repartFactory.get());
999 coarseLevel.
Request(
"A", newA.get());
1000 coarseLevel.
Request(
"Coordinates", newP.get());
1001 if (!NullspaceCoarse11_.is_null())
1002 coarseLevel.
Request(
"Nullspace", newP.get());
1003 repartFactory->Build(coarseLevel);
1005 if (!precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
1010 if (!NullspaceCoarse11_.is_null())
1015 coarseA11_->SetFixedBlockSize(dim_);
1016 if (skipFirst11Level_)
1017 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
1019 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
1022 coarseA11_AP_reuse_data_ = Teuchos::null;
1023 coarseA11_RAP_reuse_data_ = Teuchos::null;
1025 if (!disable_addon_ && enable_reuse_) {
1030 XpetraList.
set(
"Restrict Communicator",
true);
1031 Addon11_ = MatrixFactory::Build(Addon11_, *ImporterCoarse11, *ImporterCoarse11, targetMap, targetMap,
rcp(&XpetraList,
false));
1036 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1041 Level fineLevel, coarseLevel;
1047 fineLevel.
Set(
"A", SM_Matrix_);
1048 coarseLevel.
Set(
"P", Dk_1_);
1049 coarseLevel.
Set(
"Coordinates", Coords22_);
1051 coarseLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1052 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1058 rapList.
set(
"transpose: use implicit",
true);
1059 rapList.
set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1061 rapList.
set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
1064 if (!A22_AP_reuse_data_.is_null()) {
1068 if (!A22_RAP_reuse_data_.is_null()) {
1074 if (doRebalancing) {
1075 coarseLevel.
Set(
"number of partitions", numProcsA22);
1076 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
1078 std::string partName = precList22_.get<std::string>(
"repartition: partitioner",
"zoltan2");
1080 if (partName ==
"zoltan") {
1081 #ifdef HAVE_MUELU_ZOLTAN
1083 partitioner->SetFactory(
"A", rapFact);
1089 }
else if (partName ==
"zoltan2") {
1090 #ifdef HAVE_MUELU_ZOLTAN2
1094 partParams.
set(
"ParameterList", partpartParams);
1095 partitioner->SetParameterList(partParams);
1096 partitioner->SetFactory(
"A", rapFact);
1105 repartParams.
set(
"repartition: print partition distribution", precList22_.get<
bool>(
"repartition: print partition distribution",
false));
1106 repartParams.
set(
"repartition: remap parts", precList22_.get<
bool>(
"repartition: remap parts",
true));
1107 if (rebalanceStriding >= 1) {
1108 bool acceptPart = ((SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank()) % rebalanceStriding) == 0;
1109 if (SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsA22 * rebalanceStriding)
1113 repartParams.
set(
"repartition: remap accept partition", acceptPart);
1115 repartParams.
set(
"repartition: remap accept partition", coarseA11_.is_null());
1116 repartFactory->SetParameterList(repartParams);
1117 repartFactory->SetFactory(
"A", rapFact);
1119 repartFactory->SetFactory(
"Partition", partitioner);
1123 newPparams.
set(
"type",
"Interpolation");
1124 newPparams.
set(
"repartition: rebalance P and R", precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
1125 newPparams.
set(
"repartition: use subcommunicators",
true);
1126 newPparams.
set(
"repartition: rebalance Nullspace",
false);
1128 newP->SetParameterList(newPparams);
1129 newP->SetFactory(
"Importer", repartFactory);
1133 rebAcParams.
set(
"repartition: use subcommunicators",
true);
1134 newA->SetParameterList(rebAcParams);
1135 newA->SetFactory(
"A", rapFact);
1136 newA->SetFactory(
"Importer", repartFactory);
1138 coarseLevel.
Request(
"P", newP.get());
1139 coarseLevel.
Request(
"Importer", repartFactory.get());
1140 coarseLevel.
Request(
"A", newA.get());
1141 coarseLevel.
Request(
"Coordinates", newP.get());
1142 rapFact->
Build(fineLevel, coarseLevel);
1143 repartFactory->Build(coarseLevel);
1145 if (!precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
1151 if (!P22_.is_null()) {
1159 if (enable_reuse_) {
1160 coarseLevel.
Request(
"AP reuse data", rapFact.
get());
1161 coarseLevel.
Request(
"RAP reuse data", rapFact.
get());
1166 if (enable_reuse_) {
1175 if (Importer22_.is_null()) {
1177 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1178 if (!implicitTranspose_)
1179 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1181 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1184 RCP<const Import> Dimporter = rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->getCrsGraph()->getImporter();
1185 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->replaceDomainMapAndImporter(DorigDomainMap_, DorigImporter_);
1188 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1189 if (!implicitTranspose_)
1190 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1192 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1195 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->replaceDomainMapAndImporter(Importer22_->getTargetMap(), Dimporter);
1198 XpetraList.
set(
"Restrict Communicator",
true);
1199 XpetraList.
set(
"Timer Label",
"MueLu::RebalanceA22");
1201 A22_ = MatrixFactory::Build(temp2, *Importer22_, *Importer22_, targetMap, targetMap,
rcp(&XpetraList,
false));
1205 if (not A22_.is_null() and not disable_addon_22_ and spaceNumber_ > 1) {
1208 RCP<Matrix> addon22 = buildAddon(spaceNumber_ - 1);
1212 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*A22_,
false, one, *addon22,
false, one, newA22, GetOStream(
Runtime0));
1213 newA22->fillComplete();
1217 if (!A22_.is_null()) {
1218 dump(A22_,
"A22.m");
1219 A22_->setObjectLabel(solverName_ +
" (2,2)");
1221 if (spaceNumber_ - 1 == 0)
1222 A22_->SetFixedBlockSize(1);
1224 A22_->SetFixedBlockSize(dim_);
1228 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1235 level.
Set(
"A", SM_Matrix_);
1236 level.
setlib(SM_Matrix_->getDomainMap()->lib());
1238 level.
Set(
"NodeMatrix", A22_);
1239 level.
Set(
"D0", Dk_1_);
1241 if ((parameterList_.get<std::string>(
"smoother: pre type") !=
"NONE") && (parameterList_.get<std::string>(
"smoother: post type") !=
"NONE")) {
1242 std::string preSmootherType = parameterList_.get<std::string>(
"smoother: pre type");
1243 std::string postSmootherType = parameterList_.get<std::string>(
"smoother: post type");
1246 if (parameterList_.isSublist(
"smoother: pre params"))
1247 preSmootherList = parameterList_.
sublist(
"smoother: pre params");
1248 if (parameterList_.isSublist(
"smoother: post params"))
1249 postSmootherList = parameterList_.
sublist(
"smoother: post params");
1255 level.
Request(
"PreSmoother", smootherFact.
get());
1256 level.
Request(
"PostSmoother", smootherFact.
get());
1257 if (enable_reuse_) {
1259 smootherFactoryParams.
set(
"keep smoother data",
true);
1261 level.
Request(
"PreSmoother data", smootherFact.
get());
1262 level.
Request(
"PostSmoother data", smootherFact.
get());
1263 if (!PreSmootherData11_.is_null())
1264 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1265 if (!PostSmootherData11_.is_null())
1266 level.
Set(
"PostSmoother data", PostSmootherData11_, smootherFact.
get());
1268 smootherFact->
Build(level);
1271 if (enable_reuse_) {
1276 std::string smootherType = parameterList_.
get<std::string>(
"smoother: type");
1279 if (parameterList_.isSublist(
"smoother: params"))
1280 smootherList = parameterList_.
sublist(
"smoother: params");
1284 level.
Request(
"PreSmoother", smootherFact.
get());
1285 if (enable_reuse_) {
1287 smootherFactoryParams.
set(
"keep smoother data",
true);
1289 level.
Request(
"PreSmoother data", smootherFact.
get());
1290 if (!PreSmootherData11_.is_null())
1291 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1293 smootherFact->
Build(level);
1295 PostSmoother11_ = PreSmoother11_;
1301 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1306 if (!R11_.is_null())
1307 P11res_ = MultiVectorFactory::Build(R11_->getRangeMap(), numVectors);
1309 P11res_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1310 P11res_->setObjectLabel(
"P11res");
1312 if (Dk_1_T_R11_colMapsMatch_) {
1313 DTR11Tmp_ = MultiVectorFactory::Build(R11_->getColMap(), numVectors);
1314 DTR11Tmp_->setObjectLabel(
"DTR11Tmp");
1316 if (!ImporterCoarse11_.is_null()) {
1317 P11resTmp_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1318 P11resTmp_->setObjectLabel(
"P11resTmp");
1319 P11x_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1321 P11x_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1322 P11x_->setObjectLabel(
"P11x");
1325 if (!Dk_1_T_.is_null())
1326 Dres_ = MultiVectorFactory::Build(Dk_1_T_->getRangeMap(), numVectors);
1328 Dres_ = MultiVectorFactory::Build(Dk_1_->getDomainMap(), numVectors);
1329 Dres_->setObjectLabel(
"Dres");
1331 if (!Importer22_.is_null()) {
1332 DresTmp_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1333 DresTmp_->setObjectLabel(
"DresTmp");
1334 Dx_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1335 }
else if (!onlyBoundary22_)
1336 Dx_ = MultiVectorFactory::Build(A22_->getDomainMap(), numVectors);
1338 Dx_->setObjectLabel(
"Dx");
1340 if (!coarseA11_.is_null()) {
1341 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
1342 P11resSubComm_ = MultiVectorFactory::Build(P11resTmp_,
Teuchos::View);
1344 P11resSubComm_ = MultiVectorFactory::Build(P11res_,
Teuchos::View);
1345 P11resSubComm_->replaceMap(coarseA11_->getRangeMap());
1346 P11resSubComm_->setObjectLabel(
"P11resSubComm");
1348 P11xSubComm_ = MultiVectorFactory::Build(P11x_,
Teuchos::View);
1349 P11xSubComm_->replaceMap(coarseA11_->getDomainMap());
1350 P11xSubComm_->setObjectLabel(
"P11xSubComm");
1353 if (!A22_.is_null()) {
1354 if (!Importer22_.is_null() && !implicitTranspose_)
1355 DresSubComm_ = MultiVectorFactory::Build(DresTmp_,
Teuchos::View);
1357 DresSubComm_ = MultiVectorFactory::Build(Dres_,
Teuchos::View);
1358 DresSubComm_->replaceMap(A22_->getRangeMap());
1359 DresSubComm_->setObjectLabel(
"DresSubComm");
1362 DxSubComm_->replaceMap(A22_->getDomainMap());
1363 DxSubComm_->setObjectLabel(
"DxSubComm");
1366 residual_ = MultiVectorFactory::Build(SM_Matrix_->getDomainMap(), numVectors);
1367 residual_->setObjectLabel(
"residual");
1370 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1372 if (dump_matrices_ && !A.
is_null()) {
1373 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1378 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1380 if (dump_matrices_ && !X.
is_null()) {
1381 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1386 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1388 if (dump_matrices_ && !X.
is_null()) {
1389 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1394 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1396 if (dump_matrices_) {
1397 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1398 std::ofstream out(name);
1399 for (
size_t i = 0; i < Teuchos::as<size_t>(v.
size()); i++)
1400 out << v[i] <<
"\n";
1404 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1406 if (dump_matrices_) {
1407 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1408 std::ofstream out(name);
1409 auto vH = Kokkos::create_mirror_view(v);
1410 Kokkos::deep_copy(vH, v);
1411 out <<
"%%MatrixMarket matrix array real general\n"
1412 << vH.extent(0) <<
" 1\n";
1413 for (
size_t i = 0; i < vH.size(); i++)
1414 out << vH[i] <<
"\n";
1418 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1430 return Teuchos::null;
1433 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1435 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1436 std::string spaceLabel;
1437 if (spaceNumber == 0)
1438 spaceLabel =
"nodal";
1439 else if (spaceNumber == 1)
1440 spaceLabel =
"edge";
1441 else if (spaceNumber == 2)
1442 spaceLabel =
"face";
1447 if (spaceNumber > 0) {
1448 tm = getTimer(
"nullspace " + spaceLabel);
1449 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" nullspace" << std::endl;
1452 if (spaceNumber == 0) {
1453 return Teuchos::null;
1455 }
else if (spaceNumber == 1) {
1458 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(D0_->getRowMap(), NodalCoords_->getNumVectors());
1459 D0_->apply(*CoordsSC, *Nullspace);
1461 bool normalize = parameterList_.
get<
bool>(
"refmaxwell: normalize nullspace", MasterList::getDefault<bool>(
"refmaxwell: normalize nullspace"));
1467 for (
size_t i = 0; i < dim_; i++)
1468 localNullspace[i] = Nullspace->getData(i);
1472 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1474 for (
size_t i = 0; i < dim_; i++)
1475 lenSC += localNullspace[i][j] * localNullspace[i][j];
1477 localMinLen = std::min(localMinLen, len);
1478 localMaxLen = std::max(localMaxLen, len);
1479 localMeanLen += len;
1486 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1490 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1495 GetOStream(
Runtime0) << solverName_ +
"::compute(): normalizing nullspace" << std::endl;
1499 Array<Scalar> normsSC(NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1500 Nullspace->scale(normsSC());
1507 dump(Nullspace,
"nullspaceEdge.m");
1511 }
else if (spaceNumber == 2) {
1512 using ATS = Kokkos::ArithTraits<Scalar>;
1513 using impl_Scalar =
typename ATS::val_type;
1514 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1515 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1530 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1538 auto importer = facesToNodes->getCrsGraph()->getImporter();
1539 if (!importer.is_null()) {
1541 ghostedNodalCoordinates->doImport(*NodalCoords_, *importer,
Xpetra::INSERT);
1543 ghostedNodalCoordinates = NodalCoords_;
1547 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1548 auto localNodalCoordinates = ghostedNodalCoordinates->getDeviceLocalView(Xpetra::Access::ReadOnly);
1549 auto localFaceNullspace = Nullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1552 Kokkos::parallel_for(
1553 solverName_ +
"::buildFaceProjection_nullspace",
1554 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1555 KOKKOS_LAMBDA(
const size_t f) {
1556 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1557 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1558 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1559 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1560 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1561 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1562 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1563 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1564 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1566 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1567 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1568 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1577 dump(Nullspace,
"nullspaceFace.m");
1585 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1588 using ATS = Kokkos::ArithTraits<Scalar>;
1589 using impl_Scalar =
typename ATS::val_type;
1590 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1591 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1593 typedef typename Matrix::local_matrix_type KCRS;
1594 typedef typename KCRS::StaticCrsGraphType graph_t;
1595 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1596 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1597 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1599 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1600 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1601 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1603 std::string spaceLabel;
1604 if (spaceNumber == 0)
1605 spaceLabel =
"nodal";
1606 else if (spaceNumber == 1)
1607 spaceLabel =
"edge";
1608 else if (spaceNumber == 2)
1609 spaceLabel =
"face";
1614 if (spaceNumber > 0) {
1615 tm = getTimer(
"projection " + spaceLabel);
1616 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" projection" << std::endl;
1620 if (spaceNumber == 0) {
1622 return Teuchos::null;
1624 }
else if (spaceNumber == 1) {
1628 }
else if (spaceNumber == 2) {
1638 dump(edgesToNodes,
"edgesToNodes.m");
1644 dump(facesToEdges,
"facesToEdges.m");
1646 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1651 dump(facesToNodes,
"facesToNodes.m");
1653 incidence = facesToNodes;
1662 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1663 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1665 auto localIncidence = incidence->getLocalMatrixDevice();
1666 size_t numLocalRows = rowMap->getLocalNumElements();
1667 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1668 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1669 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1670 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1671 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1674 Kokkos::parallel_for(
1675 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1676 range_type(0, numLocalRows + 1),
1677 KOKKOS_LAMBDA(
const size_t i) {
1678 rowptr(i) = dim * localIncidence.graph.row_map(i);
1681 auto localNullspace = Nullspace->getDeviceLocalView(Xpetra::Access::ReadOnly);
1685 Kokkos::parallel_for(
1686 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1687 range_type(0, numLocalRows),
1688 KOKKOS_LAMBDA(
const size_t f) {
1689 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1690 for (
size_t k = 0; k < dim; k++) {
1691 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1692 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1693 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1695 vals(dim * jj + k) = impl_SC_ZERO;
1701 typename CrsMatrix::local_matrix_type lclProjection(
"local projection " + spaceLabel,
1702 numLocalRows, numLocalColumns, nnzEstimate,
1703 vals, rowptr, colind);
1704 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1705 rowMap, blockColMap,
1706 blockDomainMap, rowMap);
1711 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1717 GetOStream(
Runtime0) << solverName_ +
"::compute(): building nodal prolongator" << std::endl;
1725 Level fineLevel, coarseLevel;
1731 fineLevel.
Set(
"A", A_nodal);
1732 fineLevel.
Set(
"Coordinates", NodalCoords_);
1733 fineLevel.
Set(
"DofsPerNode", 1);
1734 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1735 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1740 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1741 nullSpace->putScalar(SC_ONE);
1742 fineLevel.
Set(
"Nullspace", nullSpace);
1744 std::string algo = parameterList_.get<std::string>(
"multigrid algorithm");
1746 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1760 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1762 double dropTol = parameterList_.get<
double>(
"aggregation: drop tol");
1763 std::string dropScheme = parameterList_.get<std::string>(
"aggregation: drop scheme");
1764 std::string distLaplAlgo = parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1770 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1771 int minAggSize = parameterList_.get<
int>(
"aggregation: min agg size");
1773 int maxAggSize = parameterList_.get<
int>(
"aggregation: max agg size");
1775 bool matchMLbehavior1 = parameterList_.get<
bool>(
"aggregation: match ML phase1");
1777 bool matchMLbehavior2a = parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1779 bool matchMLbehavior2b = parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1782 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1784 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1785 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1786 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1788 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1789 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1792 SaPFact->SetFactory(
"P", TentativePFact);
1793 coarseLevel.
Request(
"P", SaPFact.get());
1795 coarseLevel.
Request(
"P", TentativePFact.get());
1796 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1797 coarseLevel.
Request(
"Coordinates", Tfact.get());
1800 bool exportVizData = parameterList_.
get<
bool>(
"aggregation: export visualization data");
1801 if (exportVizData) {
1804 aggExportParams.
set(
"aggregation: output filename",
"aggs.vtk");
1805 aggExportParams.
set(
"aggregation: output file: agg style",
"Jacks");
1808 aggExport->
SetFactory(
"Aggregates", UncoupledAggFact);
1809 aggExport->
SetFactory(
"UnAmalgamationInfo", amalgFact);
1810 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1811 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1815 coarseLevel.
Get(
"P", P_nodal, SaPFact.
get());
1817 coarseLevel.
Get(
"P", P_nodal, TentativePFact.
get());
1818 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.
get());
1819 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.
get());
1822 aggExport->
Build(fineLevel, coarseLevel);
1826 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1830 GetOStream(
Runtime0) << solverName_ +
"::compute(): building vectorial nodal prolongator" << std::endl;
1832 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1834 typedef typename Matrix::local_matrix_type KCRS;
1835 typedef typename KCRS::StaticCrsGraphType graph_t;
1836 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1837 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1838 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1843 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1844 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1845 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1848 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1850 size_t numLocalRows = blockRowMap->getLocalNumElements();
1851 size_t numLocalColumns = blockColMap->getLocalNumElements();
1852 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1853 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1854 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1855 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1858 Kokkos::parallel_for(
1859 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1860 range_type(0, localP_nodal.numRows() + 1),
1862 if (i < localP_nodal.numRows()) {
1863 for (
size_t k = 0; k < dim; k++) {
1864 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1867 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1871 Kokkos::parallel_for(
1872 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1873 range_type(0, localP_nodal.graph.entries.size()),
1874 KOKKOS_LAMBDA(
const size_t jj) {
1875 for (
size_t k = 0; k < dim; k++) {
1876 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1878 vals(dim * jj + k) = 1.;
1882 typename CrsMatrix::local_matrix_type lclVectorNodalP(
"local vector nodal prolongator",
1883 numLocalRows, numLocalColumns, nnzEstimate,
1884 vals, rowptr, colind);
1885 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1886 blockRowMap, blockColMap,
1887 blockDomainMap, blockRowMap);
1889 return vectorNodalP;
1892 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1900 using ATS = Kokkos::ArithTraits<Scalar>;
1901 using impl_Scalar =
typename ATS::val_type;
1902 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1904 std::string typeStr;
1905 switch (spaceNumber) {
1920 const bool skipFirstLevel = !A_nodal.
is_null();
1923 if (spaceNumber > 0) {
1924 tm = getTimer(
"special prolongator " + typeStr);
1925 GetOStream(
Runtime0) << solverName_ +
"::compute(): building special " + typeStr +
" prolongator" << std::endl;
1928 RCP<Matrix> projection = buildProjection(spaceNumber, Nullspace);
1929 dump(projection, typeStr +
"Projection.m");
1931 if (skipFirstLevel) {
1935 buildNodalProlongator(A_nodal, P_nodal, coarseNodalNullspace, coarseNodalCoords);
1937 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1938 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1940 RCP<Matrix> vectorP_nodal = buildVectorNodalProlongator(P_nodal);
1942 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1944 Prolongator =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator, GetOStream(
Runtime0),
true,
true);
1993 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
1995 auto localNullspace_nodal = coarseNodalNullspace->getDeviceLocalView(Xpetra::Access::ReadOnly);
1996 auto localNullspace_coarse = coarseNullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1997 Kokkos::parallel_for(
1998 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1999 range_type(0, coarseNodalNullspace->getLocalLength()),
2000 KOKKOS_LAMBDA(
const size_t i) {
2001 impl_Scalar val = localNullspace_nodal(i, 0);
2002 for (
size_t j = 0; j < dim; j++)
2003 localNullspace_coarse(dim * i + j, j) = val;
2007 Prolongator = projection;
2008 coarseNodalCoords = NodalCoords_;
2010 if (spaceNumber == 0) {
2012 }
else if (spaceNumber >= 1) {
2014 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
2015 auto localNullspace_coarse = coarseNullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
2016 Kokkos::parallel_for(
2017 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
2018 range_type(0, coarseNullspace->getLocalLength() / dim),
2019 KOKKOS_LAMBDA(
const size_t i) {
2020 for (
size_t j = 0; j < dim; j++)
2021 localNullspace_coarse(dim * i + j, j) = 1.0;
2027 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2036 const bool isSingular) {
2037 int oldRank = SetProcRankVerbose(A->getDomainMap()->getComm()->getRank());
2040 pl->
set(
"printLoadBalancingInfo",
true);
2041 pl->
set(
"printCommInfo",
true);
2044 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2045 if (params.
isType<std::string>(
"Preconditioner Type")) {
2048 if (params.
get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2054 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") &&
2080 params.
sublist(
"coarse: params").
set(
"fix nullspace",
true);
2086 level0->
Set(
"A", A);
2090 SetProcRankVerbose(oldRank);
2093 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2095 bool reuse = !SM_Matrix_.is_null();
2096 SM_Matrix_ = SM_Matrix_new;
2097 dump(SM_Matrix_,
"SM.m");
2102 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2148 if (implicitTranspose_) {
2153 if (!onlyBoundary22_) {
2158 if (Dk_1_T_R11_colMapsMatch_) {
2162 DTR11Tmp_->doImport(*residual_, *rcp_dynamic_cast<CrsMatrixWrap>(R11_)->getCrsMatrix()->getCrsGraph()->getImporter(),
Xpetra::INSERT);
2164 if (!onlyBoundary22_) {
2166 rcp_dynamic_cast<TpetraCrsMatrix>(rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_T_)->getCrsMatrix())->getTpetra_CrsMatrix()->localApply(
toTpetra(*DTR11Tmp_),
toTpetra(*Dres_),
Teuchos::NO_TRANS);
2170 rcp_dynamic_cast<TpetraCrsMatrix>(rcp_dynamic_cast<CrsMatrixWrap>(R11_)->getCrsMatrix())->getTpetra_CrsMatrix()->localApply(
toTpetra(*DTR11Tmp_),
toTpetra(*P11res_),
Teuchos::NO_TRANS);
2177 if (!onlyBoundary22_) {
2190 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2192 P11resTmp_->beginImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2194 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_) {
2200 if (!coarseA11_.is_null()) {
2201 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
2202 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2206 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2207 if (!thyraPrecOpH_.is_null()) {
2209 thyraPrecOpH_->apply(*P11resSubComm_, *P11xSubComm_,
Teuchos::NO_TRANS, one, zero);
2212 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2216 if (!A22_.is_null()) {
2217 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2221 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2222 if (!thyraPrecOp22_.is_null()) {
2224 thyraPrecOp22_->apply(*DresSubComm_, *DxSubComm_,
Teuchos::NO_TRANS, one, zero);
2227 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2230 if (coarseA11_.is_null() && !ImporterCoarse11_.is_null() && !implicitTranspose_)
2231 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2232 if (A22_.is_null() && !onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2236 if (fuseProlongationAndUpdate_) {
2242 if (!onlyBoundary22_) {
2252 if (!onlyBoundary22_) {
2259 X.update(one, *residual_, one);
2264 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2271 if (implicitTranspose_)
2278 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2280 P11resTmp_->doImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2282 if (!coarseA11_.is_null()) {
2284 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2291 X.update(one, *residual_, one);
2295 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2297 if (onlyBoundary22_)
2305 if (implicitTranspose_)
2312 if (!Importer22_.is_null() && !implicitTranspose_) {
2316 if (!A22_.is_null()) {
2318 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2325 X.update(one, *residual_, one);
2329 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2337 if (!onlyBoundary11_ && X.getNumVectors() != P11res_->getNumVectors())
2338 allocateMemory(X.getNumVectors());
2344 PreSmoother11_->Apply(X, RHS, use_as_preconditioner_);
2348 if (mode_ ==
"additive")
2349 applyInverseAdditive(RHS, X);
2350 else if (mode_ ==
"121") {
2354 }
else if (mode_ ==
"212") {
2358 }
else if (mode_ ==
"1")
2360 else if (mode_ ==
"2")
2362 else if (mode_ ==
"7") {
2368 PreSmoother11_->Apply(X, RHS,
false);
2375 PostSmoother11_->Apply(X, RHS,
false);
2378 }
else if (mode_ ==
"none") {
2381 applyInverseAdditive(RHS, X);
2387 PostSmoother11_->Apply(X, RHS,
false);
2391 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2396 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2401 int spaceNumber = List.
get<
int>(
"refmaxwell: space number", 1);
2410 Dk_1 =
pop(List,
"Dk_1", Dk_1);
2411 Dk_2 = pop<RCP<Matrix> >(List,
"Dk_2", Dk_2);
2412 D0 = pop<RCP<Matrix> >(List,
"D0", D0);
2414 M1_beta = pop<RCP<Matrix> >(List,
"M1_beta", M1_beta);
2415 M1_alpha = pop<RCP<Matrix> >(List,
"M1_alpha", M1_alpha);
2417 Mk_one = pop<RCP<Matrix> >(List,
"Mk_one", Mk_one);
2418 Mk_1_one = pop<RCP<Matrix> >(List,
"Mk_1_one", Mk_1_one);
2420 invMk_1_invBeta = pop<RCP<Matrix> >(List,
"invMk_1_invBeta", invMk_1_invBeta);
2421 invMk_2_invAlpha = pop<RCP<Matrix> >(List,
"invMk_2_invAlpha", invMk_2_invAlpha);
2423 Nullspace11 = pop<RCP<MultiVector> >(List,
"Nullspace11", Nullspace11);
2424 Nullspace22 = pop<RCP<MultiVector> >(List,
"Nullspace22", Nullspace22);
2425 NodalCoords = pop<RCP<RealValuedMultiVector> >(List,
"Coordinates", NodalCoords);
2429 if (M1_beta.is_null())
2435 if (Mk_one.is_null())
2441 if (invMk_1_invBeta.is_null())
2447 if (Nullspace11.is_null())
2453 if (spaceNumber == 1) {
2456 else if (D0.is_null())
2458 if (M1_beta.is_null())
2460 }
else if (spaceNumber == 2) {
2463 else if (D0.is_null())
2471 invMk_1_invBeta, invMk_2_invAlpha,
2472 Nullspace11, Nullspace22,
2476 if (SM_Matrix != Teuchos::null)
2477 resetMatrix(SM_Matrix, ComputePrec);
2480 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2490 D0_Matrix, Teuchos::null, D0_Matrix,
2491 Ms_Matrix, Teuchos::null,
2492 M1_Matrix, Teuchos::null,
2493 M0inv_Matrix, Teuchos::null,
2494 Nullspace11, Teuchos::null,
2499 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2516 if (spaceNumber_ == 1)
2517 solverName_ =
"RefMaxwell";
2518 else if (spaceNumber_ == 2)
2519 solverName_ =
"RefDarcy";
2522 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2523 HierarchyCoarse11_ = Teuchos::null;
2524 Hierarchy22_ = Teuchos::null;
2525 PreSmoother11_ = Teuchos::null;
2526 PostSmoother11_ = Teuchos::null;
2527 disable_addon_ =
false;
2528 disable_addon_22_ =
true;
2532 setParameters(List);
2547 if (!disable_addon_) {
2553 if ((k >= 2) && !disable_addon_22_) {
2560 #ifdef HAVE_MUELU_DEBUG
2565 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2566 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2569 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2573 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2574 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2577 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()))
2580 if (!disable_addon_) {
2582 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2583 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2586 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2589 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2590 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2593 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2596 if ((k >= 2) && !disable_addon_22_) {
2598 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2599 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2602 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2605 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2608 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2609 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2612 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2622 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2623 RCP<CrsMatrix> Dk_1copyCrs = rcp_dynamic_cast<CrsMatrixWrap>(Dk_1copy,
true)->getCrsMatrix();
2627 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1,
true)->getCrsMatrix()->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2632 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.
size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2633 Dk_1copyrowptr_RCP.
deepCopy(Dk_1rowptr_RCP());
2634 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2635 Dk_1copyvals_RCP.
deepCopy(Dk_1vals_RCP());
2636 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2639 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2640 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1,
true)->getCrsMatrix()->getCrsGraph()->getImporter(),
2641 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1,
true)->getCrsMatrix()->getCrsGraph()->getExporter());
2644 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2651 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2652 RCP<CrsMatrix> Dk_2copyCrs = rcp_dynamic_cast<CrsMatrixWrap>(Dk_2copy,
true)->getCrsMatrix();
2656 rcp_dynamic_cast<CrsMatrixWrap>(Dk_2,
true)->getCrsMatrix()->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2661 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.
size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2662 Dk_2copyrowptr_RCP.
deepCopy(Dk_2rowptr_RCP());
2663 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2664 Dk_2copyvals_RCP.
deepCopy(Dk_2vals_RCP());
2665 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2668 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2669 rcp_dynamic_cast<CrsMatrixWrap>(Dk_2,
true)->getCrsMatrix()->getCrsGraph()->getImporter(),
2670 rcp_dynamic_cast<CrsMatrixWrap>(Dk_2,
true)->getCrsMatrix()->getCrsGraph()->getExporter());
2673 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2676 M1_alpha_ = M1_alpha;
2679 Mk_1_one_ = Mk_1_one;
2681 invMk_1_invBeta_ = invMk_1_invBeta;
2682 invMk_2_invAlpha_ = invMk_2_invAlpha;
2684 NodalCoords_ = NodalCoords;
2685 Nullspace11_ = Nullspace11;
2686 Nullspace22_ = Nullspace22;
2689 dump(Dk_1_,
"Dk_1_clean.m");
2690 dump(Dk_2_,
"Dk_2_clean.m");
2692 dump(M1_beta_,
"M1_beta.m");
2693 dump(M1_alpha_,
"M1_alpha.m");
2695 dump(Mk_one_,
"Mk_one.m");
2696 dump(Mk_1_one_,
"Mk_1_one.m");
2698 dump(invMk_1_invBeta_,
"invMk_1_invBeta.m");
2699 dump(invMk_2_invAlpha_,
"invMk_2_invAlpha.m");
2701 dumpCoords(NodalCoords_,
"coords.m");
2704 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2707 std::ostringstream oss;
2713 if (!coarseA11_.is_null())
2714 root = comm->getRank();
2723 oss <<
"\n--------------------------------------------------------------------------------\n"
2724 <<
"--- " + solverName_ +
2726 "--------------------------------------------------------------------------------"
2733 SM_Matrix_->getRowMap()->getComm()->barrier();
2735 numRows = SM_Matrix_->getGlobalNumRows();
2736 nnz = SM_Matrix_->getGlobalNumEntries();
2751 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2752 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2754 if (!A22_.is_null()) {
2755 numRows = A22_->getGlobalNumRows();
2756 nnz = A22_->getGlobalNumEntries();
2758 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2764 if (PreSmoother11_ != null && PreSmoother11_ == PostSmoother11_)
2765 oss <<
"Smoother 11 both : " << PreSmoother11_->description() << std::endl;
2767 oss <<
"Smoother 11 pre : "
2768 << (PreSmoother11_ != null ? PreSmoother11_->description() :
"no smoother") << std::endl;
2769 oss <<
"Smoother 11 post : "
2770 << (PostSmoother11_ != null ? PostSmoother11_->description() :
"no smoother") << std::endl;
2775 std::string outstr = oss.str();
2779 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2781 int strLength = outstr.size();
2782 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2783 if (comm->getRank() != root)
2784 outstr.resize(strLength);
2785 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2790 if (!HierarchyCoarse11_.is_null())
2791 HierarchyCoarse11_->describe(out, GetVerbLevel());
2793 if (!Hierarchy22_.is_null())
2794 Hierarchy22_->describe(out, GetVerbLevel());
2798 std::ostringstream oss2;
2800 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2801 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;
2803 int numProcs = comm->getSize();
2811 if (!coarseA11_.is_null())
2813 if (!A22_.is_null())
2815 std::vector<char> states(numProcs, 0);
2817 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2819 states.push_back(status);
2822 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2823 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2824 for (
int j = 0; j < rowWidth; j++)
2825 if (proc + j < numProcs)
2826 if (states[proc + j] == 0)
2828 else if (states[proc + j] == 1)
2830 else if (states[proc + j] == 2)
2837 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2846 #define MUELU_REFMAXWELL_SHORT
2847 #endif // ifdef MUELU_REFMAXWELL_DEF_HPP
Important warning messages (one line)
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > PtAPWrapper(const RCP< Matrix > &A, const RCP< Matrix > &P, Teuchos::ParameterList ¶ms, std::string &label)
Performs an P^T AP.
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.
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.
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.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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)
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 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.
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, Teuchos::ParameterList &List)
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)
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_.
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.
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, Teuchos::ParameterList ¶ms, std::string &label, const bool reuse, const bool isSingular=false)
Setup a subsolve.
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.
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.
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)=0
Configuration.
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
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)
Teuchos::RCP< Xpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Matrix2CrsMatrix(Teuchos::RCP< Xpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &matrix)
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)
static const RCP< const NoFactory > getRCP()
Static Get() functions.