10 #ifndef MUELU_REFMAXWELL_DEF_HPP
11 #define MUELU_REFMAXWELL_DEF_HPP
17 #include "Xpetra_Map.hpp"
25 #include "MueLu_AmalgamationFactory.hpp"
26 #include "MueLu_RAPFactory.hpp"
27 #include "MueLu_SmootherFactory.hpp"
29 #include "MueLu_CoalesceDropFactory.hpp"
30 #include "MueLu_CoarseMapFactory.hpp"
31 #include "MueLu_CoordinatesTransferFactory.hpp"
32 #include "MueLu_UncoupledAggregationFactory.hpp"
33 #include "MueLu_TentativePFactory.hpp"
34 #include "MueLu_SaPFactory.hpp"
35 #include "MueLu_AggregationExportFactory.hpp"
36 #include "MueLu_Utilities.hpp"
37 #include "MueLu_Maxwell_Utils.hpp"
39 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
40 #include "MueLu_TentativePFactory_kokkos.hpp"
41 #include <Kokkos_Core.hpp>
42 #include <KokkosSparse_CrsMatrix.hpp>
44 #include "MueLu_ZoltanInterface.hpp"
45 #include "MueLu_Zoltan2Interface.hpp"
46 #include "MueLu_RepartitionHeuristicFactory.hpp"
47 #include "MueLu_RepartitionFactory.hpp"
48 #include "MueLu_RebalanceAcFactory.hpp"
49 #include "MueLu_RebalanceTransferFactory.hpp"
56 #ifdef HAVE_MUELU_CUDA
57 #include "cuda_profiler_api.h"
61 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
69 T result = pl.
get<T>(name_in);
76 T result = pl.
get<T>(name_in, def_value);
81 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
87 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
89 return SM_Matrix_->getDomainMap();
92 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
94 return SM_Matrix_->getRangeMap();
97 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
101 bool useKokkosDefault = !Node::is_serial;
128 params->
set(
"refmaxwell: space number", 1,
"", spaceValidator);
129 params->
set(
"verbosity", MasterList::getDefault<std::string>(
"verbosity"));
130 params->
set(
"use kokkos refactor", useKokkosDefault);
131 params->
set(
"half precision",
false);
132 params->
set(
"parameterlist: syntax", MasterList::getDefault<std::string>(
"parameterlist: syntax"));
133 params->
set(
"output filename", MasterList::getDefault<std::string>(
"output filename"));
134 params->
set(
"print initial parameters", MasterList::getDefault<bool>(
"print initial parameters"));
135 params->
set(
"refmaxwell: disable addon", MasterList::getDefault<bool>(
"refmaxwell: disable addon"));
136 params->
set(
"refmaxwell: disable addon 22",
true);
137 params->
set(
"refmaxwell: mode", MasterList::getDefault<std::string>(
"refmaxwell: mode"));
138 params->
set(
"refmaxwell: use as preconditioner", MasterList::getDefault<bool>(
"refmaxwell: use as preconditioner"));
139 params->
set(
"refmaxwell: dump matrices", MasterList::getDefault<bool>(
"refmaxwell: dump matrices"));
140 params->
set(
"refmaxwell: enable reuse", MasterList::getDefault<bool>(
"refmaxwell: enable reuse"));
141 params->
set(
"refmaxwell: skip first (1,1) level", MasterList::getDefault<bool>(
"refmaxwell: skip first (1,1) level"));
142 params->
set(
"refmaxwell: skip first (2,2) level",
false);
143 params->
set(
"multigrid algorithm",
"Unsmoothed");
144 params->
set(
"transpose: use implicit", MasterList::getDefault<bool>(
"transpose: use implicit"));
145 params->
set(
"rap: triple product", MasterList::getDefault<bool>(
"rap: triple product"));
146 params->
set(
"rap: fix zero diagonals",
true);
147 params->
set(
"rap: fix zero diagonals threshold", MasterList::getDefault<double>(
"rap: fix zero diagonals threshold"));
148 params->
set(
"fuse prolongation and update", MasterList::getDefault<bool>(
"fuse prolongation and update"));
149 params->
set(
"refmaxwell: subsolves on subcommunicators", MasterList::getDefault<bool>(
"refmaxwell: subsolves on subcommunicators"));
150 params->
set(
"refmaxwell: subsolves striding", 1);
151 params->
set(
"refmaxwell: row sum drop tol (1,1)", MasterList::getDefault<double>(
"aggregation: row sum drop tol"));
152 params->
set(
"sync timers",
false);
153 params->
set(
"refmaxwell: num iters coarse 11", 1);
154 params->
set(
"refmaxwell: num iters 22", 1);
155 params->
set(
"refmaxwell: apply BCs to Anodal",
false);
156 params->
set(
"refmaxwell: apply BCs to coarse 11",
true);
157 params->
set(
"refmaxwell: apply BCs to 22",
true);
158 params->
set(
"refmaxwell: max coarse size", 1);
165 params->
set(
"smoother: type",
"CHEBYSHEV");
168 params->
set(
"smoother: pre type",
"NONE");
171 params->
set(
"smoother: post type",
"NONE");
178 params->
set(
"multigrid algorithm",
"unsmoothed");
179 params->
set(
"aggregation: type", MasterList::getDefault<std::string>(
"aggregation: type"));
180 params->
set(
"aggregation: drop tol", MasterList::getDefault<double>(
"aggregation: drop tol"));
181 params->
set(
"aggregation: drop scheme", MasterList::getDefault<std::string>(
"aggregation: drop scheme"));
182 params->
set(
"aggregation: distance laplacian algo", MasterList::getDefault<std::string>(
"aggregation: distance laplacian algo"));
183 params->
set(
"aggregation: min agg size", MasterList::getDefault<int>(
"aggregation: min agg size"));
184 params->
set(
"aggregation: max agg size", MasterList::getDefault<int>(
"aggregation: max agg size"));
185 params->
set(
"aggregation: match ML phase1", MasterList::getDefault<bool>(
"aggregation: match ML phase1"));
186 params->
set(
"aggregation: match ML phase2a", MasterList::getDefault<bool>(
"aggregation: match ML phase2a"));
187 params->
set(
"aggregation: match ML phase2b", MasterList::getDefault<bool>(
"aggregation: match ML phase2b"));
188 params->
set(
"aggregation: export visualization data", MasterList::getDefault<bool>(
"aggregation: export visualization data"));
193 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
195 if (list.
isType<std::string>(
"parameterlist: syntax") && list.
get<std::string>(
"parameterlist: syntax") ==
"ml") {
200 for (
auto it = newList2.
begin(); it != newList2.
end(); ++it) {
201 const std::string &entry_name = it->first;
204 newList.
setEntry(entry_name, theEntry);
211 if (list.
isSublist(
"refmaxwell: 22list"))
216 parameterList_ = list;
218 std::string verbosityLevel = parameterList_.get<std::string>(
"verbosity");
220 std::string outputFilename = parameterList_.get<std::string>(
"output filename");
221 if (outputFilename !=
"")
226 if (parameterList_.get<
bool>(
"print initial parameters"))
227 GetOStream(static_cast<MsgType>(
Runtime1), 0) << parameterList_ << std::endl;
228 disable_addon_ = parameterList_.get<
bool>(
"refmaxwell: disable addon");
229 disable_addon_22_ = parameterList_.get<
bool>(
"refmaxwell: disable addon 22");
230 mode_ = parameterList_.get<std::string>(
"refmaxwell: mode");
231 use_as_preconditioner_ = parameterList_.get<
bool>(
"refmaxwell: use as preconditioner");
232 dump_matrices_ = parameterList_.get<
bool>(
"refmaxwell: dump matrices");
233 enable_reuse_ = parameterList_.get<
bool>(
"refmaxwell: enable reuse");
234 implicitTranspose_ = parameterList_.get<
bool>(
"transpose: use implicit");
235 fuseProlongationAndUpdate_ = parameterList_.get<
bool>(
"fuse prolongation and update");
236 skipFirst11Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (1,1) level");
237 skipFirst22Level_ = parameterList_.get<
bool>(
"refmaxwell: skip first (2,2) level");
238 if (spaceNumber_ == 1)
239 skipFirst22Level_ =
false;
240 syncTimers_ = parameterList_.get<
bool>(
"sync timers");
241 useKokkos_ = parameterList_.get<
bool>(
"use kokkos refactor");
242 numItersCoarse11_ = parameterList_.get<
int>(
"refmaxwell: num iters coarse 11");
243 numIters22_ = parameterList_.get<
int>(
"refmaxwell: num iters 22");
244 applyBCsToAnodal_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to Anodal");
245 applyBCsToCoarse11_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to coarse 11");
246 applyBCsTo22_ = parameterList_.get<
bool>(
"refmaxwell: apply BCs to 22");
248 precList11_ = parameterList_.sublist(
"refmaxwell: 11list");
249 if (!precList11_.isType<std::string>(
"Preconditioner Type") &&
250 !precList11_.isType<std::string>(
"smoother: type") &&
251 !precList11_.isType<std::string>(
"smoother: pre type") &&
252 !precList11_.isType<std::string>(
"smoother: post type")) {
253 precList11_.set(
"smoother: type",
"CHEBYSHEV");
254 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
255 precList11_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 5.4);
256 precList11_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
259 precList22_ = parameterList_.sublist(
"refmaxwell: 22list");
260 if (!precList22_.isType<std::string>(
"Preconditioner Type") &&
261 !precList22_.isType<std::string>(
"smoother: type") &&
262 !precList22_.isType<std::string>(
"smoother: pre type") &&
263 !precList22_.isType<std::string>(
"smoother: post type")) {
264 precList22_.set(
"smoother: type",
"CHEBYSHEV");
265 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
266 precList22_.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
267 precList22_.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
270 if (!parameterList_.isType<std::string>(
"smoother: type") && !parameterList_.isType<std::string>(
"smoother: pre type") && !parameterList_.isType<std::string>(
"smoother: post type")) {
271 list.
set(
"smoother: type",
"CHEBYSHEV");
272 list.
sublist(
"smoother: params").
set(
"chebyshev: degree", 2);
273 list.
sublist(
"smoother: params").
set(
"chebyshev: ratio eigenvalue", 20.0);
274 list.
sublist(
"smoother: params").
set(
"chebyshev: eigenvalue max iterations", 30);
278 !precList11_.isType<std::string>(
"Preconditioner Type") &&
279 !precList11_.isParameter(
"reuse: type"))
280 precList11_.
set(
"reuse: type",
"full");
282 !precList22_.isType<std::string>(
"Preconditioner Type") &&
283 !precList22_.isParameter(
"reuse: type"))
284 precList22_.
set(
"reuse: type",
"full");
289 if (useKokkos_ && precList11_.isParameter(
"aggregation: drop tol") && precList11_.get<
double>(
"aggregation: drop tol") != 0.0) {
290 GetOStream(
Warnings0) << solverName_ +
"::compute(): Setting \"aggregation: drop tol\". to 0.0, since CoalesceDropFactory_kokkos does not "
291 <<
"support BlockSize > 1 and drop tol != 0.0" << std::endl;
292 precList11_.
set(
"aggregation: drop tol", 0.0);
296 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
298 using memory_space =
typename Node::device_type::memory_space;
300 #ifdef HAVE_MUELU_CUDA
301 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
304 std::string timerLabel;
306 timerLabel =
"compute (reuse)";
308 timerLabel =
"compute";
320 params->
set(
"printLoadBalancingInfo",
true);
321 params->
set(
"printCommInfo",
true);
328 magnitudeType rowSumTol = parameterList_.get<
double>(
"refmaxwell: row sum drop tol (1,1)");
330 BCrows11_, BCcols22_, BCdomain22_,
331 globalNumberBoundaryUnknowns11_,
332 globalNumberBoundaryUnknowns22_,
333 onlyBoundary11_, onlyBoundary22_);
334 if (spaceNumber_ == 2) {
335 Kokkos::View<bool *, memory_space> BCcolsEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), Dk_1_->getColMap()->getLocalNumElements());
336 Kokkos::View<bool *, memory_space> BCdomainEdge = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), Dk_1_->getDomainMap()->getLocalNumElements());
339 Kokkos::View<bool *, memory_space> BCcolsNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletCols"), D0_->getColMap()->getLocalNumElements());
340 Kokkos::View<bool *, memory_space> BCdomainNode = Kokkos::View<bool *, memory_space>(Kokkos::ViewAllocateWithoutInitializing(
"dirichletDomains"), D0_->getDomainMap()->getLocalNumElements());
342 BCdomain22_ = BCdomainNode;
345 GetOStream(
Statistics2) << solverName_ +
"::compute(): Detected " << globalNumberBoundaryUnknowns11_ <<
" BC rows and " << globalNumberBoundaryUnknowns22_ <<
" BC columns." << std::endl;
347 dump(BCrows11_,
"BCrows11.m");
348 dump(BCcols22_,
"BCcols22.m");
349 dump(BCdomain22_,
"BCdomain22.m");
352 if (onlyBoundary11_) {
355 GetOStream(
Warnings0) <<
"All unknowns of the (1,1) block have been detected as boundary unknowns!" << std::endl;
357 setFineLevelSmoother11();
363 dim_ = NodalCoords_->getNumVectors();
370 if (Nullspace11_ != null) {
371 TEUCHOS_ASSERT(Nullspace11_->getMap()->isCompatible(*(SM_Matrix_->getRowMap())));
372 }
else if (NodalCoords_ != null) {
373 Nullspace11_ = buildNullspace(spaceNumber_, BCrows11_, skipFirst11Level_);
375 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
381 if (skipFirst11Level_) {
383 std::string label(
"D0^T*M1_beta*D0");
386 if (applyBCsToAnodal_) {
390 A11_nodal->setObjectLabel(solverName_ +
" (1,1) A_nodal");
391 dump(A11_nodal,
"A11_nodal.m");
394 M1_beta_ = Teuchos::null;
397 buildProlongator(spaceNumber_, A11_nodal, Nullspace11_, P11_, NullspaceCoarse11_, CoordsCoarse11_);
404 if (Nullspace22_ != null) {
405 TEUCHOS_ASSERT(Nullspace22_->getMap()->isCompatible(*(Dk_1_->getDomainMap())));
406 }
else if (NodalCoords_ != null)
407 Nullspace22_ = buildNullspace(spaceNumber_ - 1, BCdomain22_, skipFirst22Level_);
409 GetOStream(
Errors) << solverName_ +
"::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
415 if (skipFirst22Level_) {
417 std::string label(
"D0^T*M1_alpha*D0");
420 if (applyBCsToAnodal_) {
424 A22_nodal->setObjectLabel(solverName_ +
" (2,2) A_nodal");
425 dump(A22_nodal,
"A22_nodal.m");
428 M1_alpha_ = Teuchos::null;
431 buildProlongator(spaceNumber_ - 1, A22_nodal, Nullspace22_, P22_, CoarseNullspace22_, Coords22_);
439 buildCoarse11Matrix();
444 int rebalanceStriding, numProcsCoarseA11, numProcsA22;
446 this->determineSubHierarchyCommSizes(doRebalancing, rebalanceStriding, numProcsCoarseA11, numProcsA22);
448 doRebalancing =
false;
451 if (!reuse && doRebalancing)
452 rebalanceCoarse11Matrix(rebalanceStriding, numProcsCoarseA11);
453 if (!coarseA11_.is_null()) {
454 dump(coarseA11_,
"coarseA11.m");
456 dumpCoords(CoordsCoarse11_,
"CoordsCoarse11.m");
457 dump(NullspaceCoarse11_,
"NullspaceCoarse11.m");
462 if (!implicitTranspose_) {
469 if (!coarseA11_.is_null()) {
471 std::string label(
"coarseA11");
472 setupSubSolve(HierarchyCoarse11_, thyraPrecOpH_, coarseA11_, NullspaceCoarse11_, CoordsCoarse11_, precList11_, label, reuse);
478 if (!reuse && applyBCsTo22_) {
479 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC columns of Dk_1" << std::endl;
484 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
489 if (!onlyBoundary22_) {
490 GetOStream(
Runtime0) << solverName_ +
"::compute(): building MG for (2,2)-block" << std::endl;
493 build22Matrix(reuse, doRebalancing, rebalanceStriding, numProcsA22);
495 if (!P22_.is_null()) {
496 std::string label(
"P22^T*A22*P22");
498 coarseA22_->SetFixedBlockSize(A22_->GetFixedBlockSize());
499 coarseA22_->setObjectLabel(solverName_ +
" coarse (2, 2)");
500 dump(coarseA22_,
"coarseA22.m");
503 if (!reuse && !implicitTranspose_) {
509 if (!A22_.is_null()) {
511 std::string label(
"A22");
512 if (!P22_.is_null()) {
513 precList22_.sublist(
"level 1 user data").set(
"A", coarseA22_);
514 precList22_.sublist(
"level 1 user data").set(
"P", P22_);
515 if (!implicitTranspose_)
516 precList22_.sublist(
"level 1 user data").set(
"R", R22_);
517 precList22_.sublist(
"level 1 user data").set(
"Nullspace", CoarseNullspace22_);
518 precList22_.sublist(
"level 1 user data").set(
"Coordinates", Coords22_);
521 int maxCoarseSize = precList22_.get(
"coarse: max size", MasterList::getDefault<int>(
"coarse: max size"));
522 int numRows = Teuchos::as<int>(coarseA22_->getGlobalNumRows());
523 if (maxCoarseSize > numRows)
524 precList22_.set(
"coarse: max size", numRows);
525 int maxLevels = precList22_.get(
"max levels", MasterList::getDefault<int>(
"max levels"));
527 precList22_.set(
"max levels", 2);
528 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, Teuchos::null, Teuchos::null, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
530 setupSubSolve(Hierarchy22_, thyraPrecOp22_, A22_, CoarseNullspace22_, Coords22_, precList22_, label, reuse, globalNumberBoundaryUnknowns11_ == 0);
538 if (!reuse && !onlyBoundary22_ && applyBCsTo22_) {
539 GetOStream(
Runtime0) << solverName_ +
"::compute(): nuking BC rows of Dk_1" << std::endl;
544 Dk_1_->fillComplete(Dk_1_->getDomainMap(), Dk_1_->getRangeMap());
545 dump(Dk_1_,
"Dk_1_nuked.m");
550 setFineLevelSmoother11();
553 if (!ImporterCoarse11_.is_null()) {
554 RCP<const Import> ImporterP11 = ImportFactory::Build(ImporterCoarse11_->getTargetMap(), P11_->getColMap());
555 rcp_dynamic_cast<CrsMatrixWrap>(P11_)->getCrsMatrix()->replaceDomainMapAndImporter(ImporterCoarse11_->getTargetMap(), ImporterP11);
558 if (!Importer22_.is_null()) {
560 DorigDomainMap_ = Dk_1_->getDomainMap();
561 DorigImporter_ = rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->getCrsGraph()->getImporter();
563 RCP<const Import> ImporterD = ImportFactory::Build(Importer22_->getTargetMap(), Dk_1_->getColMap());
564 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->replaceDomainMapAndImporter(Importer22_->getTargetMap(), ImporterD);
567 #ifdef HAVE_MUELU_TPETRA
568 if ((!Dk_1_T_.is_null()) &&
570 (!rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_T_)->getCrsMatrix()->getCrsGraph()->getImporter().is_null()) &&
571 (!rcp_dynamic_cast<CrsMatrixWrap>(R11_)->getCrsMatrix()->getCrsGraph()->getImporter().is_null()) &&
574 Dk_1_T_R11_colMapsMatch_ = Dk_1_T_->getColMap()->isSameAs(*R11_->getColMap());
577 Dk_1_T_R11_colMapsMatch_ =
false;
578 if (Dk_1_T_R11_colMapsMatch_)
579 GetOStream(
Runtime0) << solverName_ +
"::compute(): Dk_1_T and R11 have matching colMaps" << std::endl;
585 if (parameterList_.isSublist(
"matvec params")) {
586 RCP<ParameterList> matvecParams = rcpFromRef(parameterList_.sublist(
"matvec params"));
590 if (!Dk_1_T_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*Dk_1_T_, matvecParams);
591 if (!R11_.is_null()) Maxwell_Utils<SC, LO, GO, NO>::setMatvecParams(*R11_, matvecParams);
592 if (!ImporterCoarse11_.is_null()) ImporterCoarse11_->setDistributorParameters(matvecParams);
593 if (!Importer22_.is_null()) Importer22_->setDistributorParameters(matvecParams);
595 if (!ImporterCoarse11_.is_null() && parameterList_.isSublist(
"refmaxwell: ImporterCoarse11 params")) {
596 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: ImporterCoarse11 params"));
597 ImporterCoarse11_->setDistributorParameters(importerParams);
599 if (!Importer22_.is_null() && parameterList_.isSublist(
"refmaxwell: Importer22 params")) {
600 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: Importer22 params"));
601 Importer22_->setDistributorParameters(importerParams);
607 #ifdef HAVE_MUELU_CUDA
608 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
612 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
615 doRebalancing = parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators");
616 rebalanceStriding = parameterList_.get<
int>(
"refmaxwell: subsolves striding", -1);
617 int numProcs = SM_Matrix_->getDomainMap()->getComm()->getSize();
619 doRebalancing =
false;
631 level.
Set(
"A", coarseA11_);
635 repartheurParams.
set(
"repartition: start level", 0);
637 int defaultTargetRows = 10000;
638 repartheurParams.
set(
"repartition: min rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
639 repartheurParams.
set(
"repartition: target rows per proc", precList11_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
640 repartheurParams.
set(
"repartition: min rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
641 repartheurParams.
set(
"repartition: target rows per thread", precList11_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
642 repartheurParams.
set(
"repartition: max imbalance", precList11_.get<
double>(
"repartition: max imbalance", 1.1));
643 repartheurFactory->SetParameterList(repartheurParams);
645 level.
Request(
"number of partitions", repartheurFactory.get());
646 repartheurFactory->Build(level);
647 numProcsCoarseA11 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
648 numProcsCoarseA11 = std::min(numProcsCoarseA11, numProcs);
658 level.
Set(
"Map", Dk_1_->getDomainMap());
662 repartheurParams.
set(
"repartition: start level", 0);
663 repartheurParams.
set(
"repartition: use map",
true);
665 int defaultTargetRows = 10000;
666 repartheurParams.
set(
"repartition: min rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
667 repartheurParams.
set(
"repartition: target rows per proc", precList22_.get<
int>(
"repartition: target rows per proc", defaultTargetRows));
668 repartheurParams.
set(
"repartition: min rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
669 repartheurParams.
set(
"repartition: target rows per thread", precList22_.get<
int>(
"repartition: target rows per thread", defaultTargetRows));
671 repartheurFactory->SetParameterList(repartheurParams);
673 level.
Request(
"number of partitions", repartheurFactory.get());
674 repartheurFactory->Build(level);
675 numProcsA22 = level.
Get<
int>(
"number of partitions", repartheurFactory.get());
676 numProcsA22 = std::min(numProcsA22, numProcs);
679 if (rebalanceStriding >= 1) {
680 TEUCHOS_ASSERT(rebalanceStriding * numProcsCoarseA11 <= numProcs);
682 if (rebalanceStriding * (numProcsCoarseA11 + numProcsA22) > numProcs) {
683 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling striding = " << rebalanceStriding <<
", since coarseA11 needs " << numProcsCoarseA11
684 <<
" procs and A22 needs " << numProcsA22 <<
" procs." << std::endl;
685 rebalanceStriding = -1;
687 int lclBadMatrixDistribution = (coarseA11_->getLocalNumEntries() == 0) || (Dk_1_->getDomainMap()->getLocalNumElements() == 0);
688 int gblBadMatrixDistribution =
false;
689 MueLu_maxAll(SM_Matrix_->getDomainMap()->getComm(), lclBadMatrixDistribution, gblBadMatrixDistribution);
690 if (gblBadMatrixDistribution) {
691 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;
692 rebalanceStriding = -1;
696 if ((numProcsCoarseA11 < 0) || (numProcsA22 < 0) || (numProcsCoarseA11 + numProcsA22 > numProcs)) {
697 GetOStream(
Warnings0) << solverName_ +
"::compute(): Disabling rebalancing of subsolves, since partition heuristic resulted "
698 <<
"in undesirable number of partitions: " << numProcsCoarseA11 <<
", " << numProcsA22 << std::endl;
699 doRebalancing =
false;
703 doRebalancing =
false;
707 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
710 if (spaceNumber == 0)
711 return Teuchos::null;
713 std::string timerLabel;
714 if (spaceNumber == spaceNumber_) {
715 if (skipFirst11Level_)
716 timerLabel =
"Build coarse addon matrix 11";
718 timerLabel =
"Build addon matrix 11";
720 timerLabel =
"Build addon matrix 22";
727 if (spaceNumber == spaceNumber_) {
731 "::buildCoarse11Matrix(): Inverse of "
732 "lumped mass matrix required for add-on (i.e. invMk_1_invBeta_ is null)");
733 lumpedInverse = invMk_1_invBeta_;
735 if (skipFirst11Level_) {
738 Zaux =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Mk_one_,
false, *P11_,
false, Zaux, GetOStream(
Runtime0),
true,
true);
740 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Zaux,
false, Z, GetOStream(
Runtime0),
true,
true);
743 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *Mk_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
746 }
else if (spaceNumber == spaceNumber_ - 1) {
750 "::buildCoarse11Matrix(): Inverse of "
751 "lumped mass matrix required for add-on (i.e. invMk_2_invAlpha_ is null)");
752 lumpedInverse = invMk_2_invAlpha_;
755 Z =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_2_,
true, *Mk_1_one_,
false, Z, GetOStream(
Runtime0),
true,
true);
759 if (lumpedInverse->getGlobalMaxNumRowEntries() <= 1) {
762 RCP<Vector> diag = VectorFactory::Build(lumpedInverse->getRowMap());
763 lumpedInverse->getLocalDiagCopy(*diag);
766 for (
size_t j = 0; j < diag->getMap()->getLocalNumElements(); j++) {
770 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
773 RCP<Import> importer = ImportFactory::Build(diag->getMap(), Z->getRowMap());
774 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
776 Z->leftScale(*diag2);
778 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *Z,
false, addon, GetOStream(
Runtime0),
true,
true);
779 }
else if (parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
782 C2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*lumpedInverse,
false, *Z,
false, C2, GetOStream(
Runtime0),
true,
true);
784 addon =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Z,
true, *C2,
false, addon, GetOStream(
Runtime0),
true,
true);
786 addon = MatrixFactory::Build(Z->getDomainMap());
789 MultiplyRAP(*Z,
true, *lumpedInverse,
false, *Z,
false, *addon,
true,
true);
794 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
802 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *P11_,
false, temp, GetOStream(
Runtime0),
true,
true);
803 if (ImporterCoarse11_.is_null())
804 coarseA11_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, coarseA11_, GetOStream(
Runtime0),
true,
true);
807 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P11_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
809 RCP<const Map> map = ImporterCoarse11_->getTargetMap()->removeEmptyProcesses();
810 temp2->removeEmptyProcessesInPlace(map);
812 temp2 = Teuchos::null;
816 if (!disable_addon_) {
819 if (!coarseA11_.is_null() && Addon11_.is_null()) {
820 addon = buildAddon(spaceNumber_);
827 if (!coarseA11_.is_null()) {
830 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*coarseA11_,
false, one, *addon,
false, one, newCoarseA11, GetOStream(
Runtime0));
831 newCoarseA11->fillComplete();
832 coarseA11_ = newCoarseA11;
836 if (!coarseA11_.is_null() && !skipFirst11Level_) {
838 coarseA11BCrows.
resize(coarseA11_->getRowMap()->getLocalNumElements());
839 for (
size_t i = 0; i < BCdomain22_.size(); i++)
840 for (
size_t k = 0; k < dim_; k++)
841 coarseA11BCrows[i * dim_ + k] = BCdomain22_(i);
842 magnitudeType rowSumTol = parameterList_.
get<
double>(
"refmaxwell: row sum drop tol (1,1)");
845 if (applyBCsToCoarse11_)
849 if (!coarseA11_.is_null()) {
855 bool fixZeroDiagonal = !applyBCsToAnodal_;
856 if (precList11_.isParameter(
"rap: fix zero diagonals"))
857 fixZeroDiagonal = precList11_.get<
bool>(
"rap: fix zero diagonals");
859 if (fixZeroDiagonal) {
862 if (precList11_.isType<
magnitudeType>(
"rap: fix zero diagonals threshold"))
863 threshold = precList11_.get<
magnitudeType>(
"rap: fix zero diagonals threshold");
864 else if (precList11_.isType<
double>(
"rap: fix zero diagonals threshold"))
865 threshold = Teuchos::as<magnitudeType>(precList11_.get<
double>(
"rap: fix zero diagonals threshold"));
866 if (precList11_.isType<
double>(
"rap: fix zero diagonals replacement"))
867 replacement = Teuchos::as<Scalar>(precList11_.get<
double>(
"rap: fix zero diagonals replacement"));
872 coarseA11_->SetFixedBlockSize(dim_);
873 if (skipFirst11Level_)
874 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
876 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
880 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
887 Level fineLevel, coarseLevel;
893 coarseLevel.
Set(
"A", coarseA11_);
894 coarseLevel.
Set(
"P", P11_);
895 coarseLevel.
Set(
"Coordinates", CoordsCoarse11_);
896 if (!NullspaceCoarse11_.is_null())
897 coarseLevel.
Set(
"Nullspace", NullspaceCoarse11_);
898 coarseLevel.
Set(
"number of partitions", numProcsCoarseA11);
899 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
901 coarseLevel.
setlib(coarseA11_->getDomainMap()->lib());
902 fineLevel.
setlib(coarseA11_->getDomainMap()->lib());
906 std::string partName = precList11_.get<std::string>(
"repartition: partitioner",
"zoltan2");
908 if (partName ==
"zoltan") {
909 #ifdef HAVE_MUELU_ZOLTAN
916 }
else if (partName ==
"zoltan2") {
917 #ifdef HAVE_MUELU_ZOLTAN2
921 partParams.
set(
"ParameterList", partpartParams);
922 partitioner->SetParameterList(partParams);
931 repartParams.
set(
"repartition: print partition distribution", precList11_.get<
bool>(
"repartition: print partition distribution",
false));
932 repartParams.
set(
"repartition: remap parts", precList11_.get<
bool>(
"repartition: remap parts",
true));
933 if (rebalanceStriding >= 1) {
934 bool acceptPart = (SM_Matrix_->getDomainMap()->getComm()->getRank() % rebalanceStriding) == 0;
935 if (SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsCoarseA11 * rebalanceStriding)
937 repartParams.
set(
"repartition: remap accept partition", acceptPart);
939 repartFactory->SetParameterList(repartParams);
941 repartFactory->SetFactory(
"Partition", partitioner);
945 newPparams.
set(
"type",
"Interpolation");
946 newPparams.
set(
"repartition: rebalance P and R", precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
947 newPparams.
set(
"repartition: use subcommunicators",
true);
948 newPparams.
set(
"repartition: rebalance Nullspace", !NullspaceCoarse11_.is_null());
950 if (!NullspaceCoarse11_.is_null())
952 newP->SetParameterList(newPparams);
953 newP->SetFactory(
"Importer", repartFactory);
957 rebAcParams.
set(
"repartition: use subcommunicators",
true);
958 newA->SetParameterList(rebAcParams);
959 newA->SetFactory(
"Importer", repartFactory);
961 coarseLevel.
Request(
"P", newP.get());
962 coarseLevel.
Request(
"Importer", repartFactory.get());
963 coarseLevel.
Request(
"A", newA.get());
964 coarseLevel.
Request(
"Coordinates", newP.get());
965 if (!NullspaceCoarse11_.is_null())
966 coarseLevel.
Request(
"Nullspace", newP.get());
967 repartFactory->Build(coarseLevel);
969 if (!precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
974 if (!NullspaceCoarse11_.is_null())
979 coarseA11_->SetFixedBlockSize(dim_);
980 if (skipFirst11Level_)
981 coarseA11_->setObjectLabel(solverName_ +
" coarse (1,1)");
983 coarseA11_->setObjectLabel(solverName_ +
" (1,1)");
986 coarseA11_AP_reuse_data_ = Teuchos::null;
987 coarseA11_RAP_reuse_data_ = Teuchos::null;
989 if (!disable_addon_ && enable_reuse_) {
994 XpetraList.
set(
"Restrict Communicator",
true);
995 Addon11_ = MatrixFactory::Build(Addon11_, *ImporterCoarse11, *ImporterCoarse11, targetMap, targetMap,
rcp(&XpetraList,
false));
1000 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1005 Level fineLevel, coarseLevel;
1011 fineLevel.
Set(
"A", SM_Matrix_);
1012 coarseLevel.
Set(
"P", Dk_1_);
1013 coarseLevel.
Set(
"Coordinates", Coords22_);
1015 coarseLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1016 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1022 rapList.
set(
"transpose: use implicit",
true);
1023 rapList.
set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1025 rapList.
set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
1028 if (!A22_AP_reuse_data_.is_null()) {
1032 if (!A22_RAP_reuse_data_.is_null()) {
1038 if (doRebalancing) {
1039 coarseLevel.
Set(
"number of partitions", numProcsA22);
1040 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
1042 std::string partName = precList22_.get<std::string>(
"repartition: partitioner",
"zoltan2");
1044 if (partName ==
"zoltan") {
1045 #ifdef HAVE_MUELU_ZOLTAN
1047 partitioner->SetFactory(
"A", rapFact);
1053 }
else if (partName ==
"zoltan2") {
1054 #ifdef HAVE_MUELU_ZOLTAN2
1058 partParams.
set(
"ParameterList", partpartParams);
1059 partitioner->SetParameterList(partParams);
1060 partitioner->SetFactory(
"A", rapFact);
1069 repartParams.
set(
"repartition: print partition distribution", precList22_.get<
bool>(
"repartition: print partition distribution",
false));
1070 repartParams.
set(
"repartition: remap parts", precList22_.get<
bool>(
"repartition: remap parts",
true));
1071 if (rebalanceStriding >= 1) {
1072 bool acceptPart = ((SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank()) % rebalanceStriding) == 0;
1073 if (SM_Matrix_->getDomainMap()->getComm()->getSize() - 1 - SM_Matrix_->getDomainMap()->getComm()->getRank() >= numProcsA22 * rebalanceStriding)
1077 repartParams.
set(
"repartition: remap accept partition", acceptPart);
1079 repartParams.
set(
"repartition: remap accept partition", coarseA11_.is_null());
1080 repartFactory->SetParameterList(repartParams);
1081 repartFactory->SetFactory(
"A", rapFact);
1083 repartFactory->SetFactory(
"Partition", partitioner);
1087 newPparams.
set(
"type",
"Interpolation");
1088 newPparams.
set(
"repartition: rebalance P and R", precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
1089 newPparams.
set(
"repartition: use subcommunicators",
true);
1090 newPparams.
set(
"repartition: rebalance Nullspace",
false);
1092 newP->SetParameterList(newPparams);
1093 newP->SetFactory(
"Importer", repartFactory);
1097 rebAcParams.
set(
"repartition: use subcommunicators",
true);
1098 newA->SetParameterList(rebAcParams);
1099 newA->SetFactory(
"A", rapFact);
1100 newA->SetFactory(
"Importer", repartFactory);
1102 coarseLevel.
Request(
"P", newP.get());
1103 coarseLevel.
Request(
"Importer", repartFactory.get());
1104 coarseLevel.
Request(
"A", newA.get());
1105 coarseLevel.
Request(
"Coordinates", newP.get());
1106 rapFact->
Build(fineLevel, coarseLevel);
1107 repartFactory->Build(coarseLevel);
1109 if (!precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
1115 if (!P22_.is_null()) {
1123 if (enable_reuse_) {
1124 coarseLevel.
Request(
"AP reuse data", rapFact.
get());
1125 coarseLevel.
Request(
"RAP reuse data", rapFact.
get());
1130 if (enable_reuse_) {
1139 if (Importer22_.is_null()) {
1141 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1142 if (!implicitTranspose_)
1143 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1145 A22_ =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, A22_, GetOStream(
Runtime0),
true,
true);
1148 RCP<const Import> Dimporter = rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->getCrsGraph()->getImporter();
1149 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->replaceDomainMapAndImporter(DorigDomainMap_, DorigImporter_);
1152 temp =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*SM_Matrix_,
false, *Dk_1_,
false, temp, GetOStream(
Runtime0),
true,
true);
1153 if (!implicitTranspose_)
1154 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_T_,
false, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1156 temp2 =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Dk_1_,
true, *temp,
false, temp2, GetOStream(
Runtime0),
true,
true);
1159 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_)->getCrsMatrix()->replaceDomainMapAndImporter(Importer22_->getTargetMap(), Dimporter);
1162 XpetraList.
set(
"Restrict Communicator",
true);
1163 XpetraList.
set(
"Timer Label",
"MueLu::RebalanceA22");
1165 A22_ = MatrixFactory::Build(temp2, *Importer22_, *Importer22_, targetMap, targetMap,
rcp(&XpetraList,
false));
1169 if (not A22_.is_null() and not disable_addon_22_ and spaceNumber_ > 1) {
1172 RCP<Matrix> addon22 = buildAddon(spaceNumber_ - 1);
1176 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*A22_,
false, one, *addon22,
false, one, newA22, GetOStream(
Runtime0));
1177 newA22->fillComplete();
1181 if (!A22_.is_null()) {
1182 dump(A22_,
"A22.m");
1183 A22_->setObjectLabel(solverName_ +
" (2,2)");
1185 if (spaceNumber_ - 1 == 0)
1186 A22_->SetFixedBlockSize(1);
1188 A22_->SetFixedBlockSize(dim_);
1192 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1199 level.
Set(
"A", SM_Matrix_);
1200 level.
setlib(SM_Matrix_->getDomainMap()->lib());
1202 level.
Set(
"NodeMatrix", A22_);
1203 level.
Set(
"D0", Dk_1_);
1205 if ((parameterList_.get<std::string>(
"smoother: pre type") !=
"NONE") && (parameterList_.get<std::string>(
"smoother: post type") !=
"NONE")) {
1206 std::string preSmootherType = parameterList_.get<std::string>(
"smoother: pre type");
1207 std::string postSmootherType = parameterList_.get<std::string>(
"smoother: post type");
1210 if (parameterList_.isSublist(
"smoother: pre params"))
1211 preSmootherList = parameterList_.
sublist(
"smoother: pre params");
1212 if (parameterList_.isSublist(
"smoother: post params"))
1213 postSmootherList = parameterList_.
sublist(
"smoother: post params");
1219 level.
Request(
"PreSmoother", smootherFact.
get());
1220 level.
Request(
"PostSmoother", smootherFact.
get());
1221 if (enable_reuse_) {
1223 smootherFactoryParams.
set(
"keep smoother data",
true);
1225 level.
Request(
"PreSmoother data", smootherFact.
get());
1226 level.
Request(
"PostSmoother data", smootherFact.
get());
1227 if (!PreSmootherData11_.is_null())
1228 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1229 if (!PostSmootherData11_.is_null())
1230 level.
Set(
"PostSmoother data", PostSmootherData11_, smootherFact.
get());
1232 smootherFact->
Build(level);
1235 if (enable_reuse_) {
1240 std::string smootherType = parameterList_.
get<std::string>(
"smoother: type");
1243 if (parameterList_.isSublist(
"smoother: params"))
1244 smootherList = parameterList_.
sublist(
"smoother: params");
1248 level.
Request(
"PreSmoother", smootherFact.
get());
1249 if (enable_reuse_) {
1251 smootherFactoryParams.
set(
"keep smoother data",
true);
1253 level.
Request(
"PreSmoother data", smootherFact.
get());
1254 if (!PreSmootherData11_.is_null())
1255 level.
Set(
"PreSmoother data", PreSmootherData11_, smootherFact.
get());
1257 smootherFact->
Build(level);
1259 PostSmoother11_ = PreSmoother11_;
1265 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1270 if (!R11_.is_null())
1271 P11res_ = MultiVectorFactory::Build(R11_->getRangeMap(), numVectors);
1273 P11res_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1274 P11res_->setObjectLabel(
"P11res");
1276 if (Dk_1_T_R11_colMapsMatch_) {
1277 DTR11Tmp_ = MultiVectorFactory::Build(R11_->getColMap(), numVectors);
1278 DTR11Tmp_->setObjectLabel(
"DTR11Tmp");
1280 if (!ImporterCoarse11_.is_null()) {
1281 P11resTmp_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1282 P11resTmp_->setObjectLabel(
"P11resTmp");
1283 P11x_ = MultiVectorFactory::Build(ImporterCoarse11_->getTargetMap(), numVectors);
1285 P11x_ = MultiVectorFactory::Build(P11_->getDomainMap(), numVectors);
1286 P11x_->setObjectLabel(
"P11x");
1289 if (!Dk_1_T_.is_null())
1290 Dres_ = MultiVectorFactory::Build(Dk_1_T_->getRangeMap(), numVectors);
1292 Dres_ = MultiVectorFactory::Build(Dk_1_->getDomainMap(), numVectors);
1293 Dres_->setObjectLabel(
"Dres");
1295 if (!Importer22_.is_null()) {
1296 DresTmp_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1297 DresTmp_->setObjectLabel(
"DresTmp");
1298 Dx_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), numVectors);
1299 }
else if (!onlyBoundary22_)
1300 Dx_ = MultiVectorFactory::Build(A22_->getDomainMap(), numVectors);
1302 Dx_->setObjectLabel(
"Dx");
1304 if (!coarseA11_.is_null()) {
1305 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
1306 P11resSubComm_ = MultiVectorFactory::Build(P11resTmp_,
Teuchos::View);
1308 P11resSubComm_ = MultiVectorFactory::Build(P11res_,
Teuchos::View);
1309 P11resSubComm_->replaceMap(coarseA11_->getRangeMap());
1310 P11resSubComm_->setObjectLabel(
"P11resSubComm");
1312 P11xSubComm_ = MultiVectorFactory::Build(P11x_,
Teuchos::View);
1313 P11xSubComm_->replaceMap(coarseA11_->getDomainMap());
1314 P11xSubComm_->setObjectLabel(
"P11xSubComm");
1317 if (!A22_.is_null()) {
1318 if (!Importer22_.is_null() && !implicitTranspose_)
1319 DresSubComm_ = MultiVectorFactory::Build(DresTmp_,
Teuchos::View);
1321 DresSubComm_ = MultiVectorFactory::Build(Dres_,
Teuchos::View);
1322 DresSubComm_->replaceMap(A22_->getRangeMap());
1323 DresSubComm_->setObjectLabel(
"DresSubComm");
1326 DxSubComm_->replaceMap(A22_->getDomainMap());
1327 DxSubComm_->setObjectLabel(
"DxSubComm");
1330 residual_ = MultiVectorFactory::Build(SM_Matrix_->getDomainMap(), numVectors);
1331 residual_->setObjectLabel(
"residual");
1334 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1336 if (dump_matrices_ && !A.
is_null()) {
1337 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1342 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1344 if (dump_matrices_ && !X.
is_null()) {
1345 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1350 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1352 if (dump_matrices_ && !X.
is_null()) {
1353 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1358 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1360 if (dump_matrices_) {
1361 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1362 std::ofstream out(name);
1363 for (
size_t i = 0; i < Teuchos::as<size_t>(v.
size()); i++)
1364 out << v[i] <<
"\n";
1368 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1370 if (dump_matrices_) {
1371 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
1372 std::ofstream out(name);
1373 auto vH = Kokkos::create_mirror_view(v);
1374 Kokkos::deep_copy(vH, v);
1375 out <<
"%%MatrixMarket matrix array real general\n"
1376 << vH.extent(0) <<
" 1\n";
1377 for (
size_t i = 0; i < vH.size(); i++)
1378 out << vH[i] <<
"\n";
1382 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1394 return Teuchos::null;
1397 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1399 buildNullspace(
const int spaceNumber,
const Kokkos::View<bool *, typename Node::device_type> &bcs,
const bool applyBCs) {
1400 std::string spaceLabel;
1401 if (spaceNumber == 0)
1402 spaceLabel =
"nodal";
1403 else if (spaceNumber == 1)
1404 spaceLabel =
"edge";
1405 else if (spaceNumber == 2)
1406 spaceLabel =
"face";
1411 if (spaceNumber > 0) {
1412 tm = getTimer(
"nullspace " + spaceLabel);
1413 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" nullspace" << std::endl;
1416 if (spaceNumber == 0) {
1417 return Teuchos::null;
1419 }
else if (spaceNumber == 1) {
1422 RCP<MultiVector> Nullspace = MultiVectorFactory::Build(D0_->getRowMap(), NodalCoords_->getNumVectors());
1423 D0_->apply(*CoordsSC, *Nullspace);
1425 bool normalize = parameterList_.
get<
bool>(
"refmaxwell: normalize nullspace", MasterList::getDefault<bool>(
"refmaxwell: normalize nullspace"));
1431 for (
size_t i = 0; i < dim_; i++)
1432 localNullspace[i] = Nullspace->getData(i);
1436 for (
size_t j = 0; j < Nullspace->getMap()->getLocalNumElements(); j++) {
1438 for (
size_t i = 0; i < dim_; i++)
1439 lenSC += localNullspace[i][j] * localNullspace[i][j];
1441 localMinLen = std::min(localMinLen, len);
1442 localMaxLen = std::max(localMaxLen, len);
1443 localMeanLen += len;
1450 meanLen /= Nullspace->getMap()->getGlobalNumElements();
1454 GetOStream(
Statistics2) <<
"Edge length (min/mean/max): " << minLen <<
" / " << meanLen <<
" / " << maxLen << std::endl;
1459 GetOStream(
Runtime0) << solverName_ +
"::compute(): normalizing nullspace" << std::endl;
1463 Array<Scalar> normsSC(NodalCoords_->getNumVectors(), one / Teuchos::as<Scalar>(meanLen));
1464 Nullspace->scale(normsSC());
1471 dump(Nullspace,
"nullspaceEdge.m");
1475 }
else if (spaceNumber == 2) {
1476 using ATS = Kokkos::ArithTraits<Scalar>;
1477 using impl_Scalar =
typename ATS::val_type;
1478 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1479 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1494 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1502 auto importer = facesToNodes->getCrsGraph()->getImporter();
1503 if (!importer.is_null()) {
1505 ghostedNodalCoordinates->doImport(*NodalCoords_, *importer,
Xpetra::INSERT);
1507 ghostedNodalCoordinates = NodalCoords_;
1511 auto facesToNodesLocal = facesToNodes->getLocalMatrixDevice();
1512 auto localNodalCoordinates = ghostedNodalCoordinates->getDeviceLocalView(Xpetra::Access::ReadOnly);
1513 auto localFaceNullspace = Nullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1516 Kokkos::parallel_for(
1517 solverName_ +
"::buildFaceProjection_nullspace",
1518 range_type(0, Nullspace->getMap()->getLocalNumElements()),
1519 KOKKOS_LAMBDA(
const size_t f) {
1520 size_t n0 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f));
1521 size_t n1 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 1);
1522 size_t n2 = facesToNodesLocal.graph.entries(facesToNodesLocal.graph.row_map(f) + 2);
1523 impl_Scalar elementNullspace00 = localNodalCoordinates(n1, 0) - localNodalCoordinates(n0, 0);
1524 impl_Scalar elementNullspace10 = localNodalCoordinates(n2, 0) - localNodalCoordinates(n0, 0);
1525 impl_Scalar elementNullspace01 = localNodalCoordinates(n1, 1) - localNodalCoordinates(n0, 1);
1526 impl_Scalar elementNullspace11 = localNodalCoordinates(n2, 1) - localNodalCoordinates(n0, 1);
1527 impl_Scalar elementNullspace02 = localNodalCoordinates(n1, 2) - localNodalCoordinates(n0, 2);
1528 impl_Scalar elementNullspace12 = localNodalCoordinates(n2, 2) - localNodalCoordinates(n0, 2);
1530 localFaceNullspace(f, 0) = impl_ATS::magnitude(elementNullspace01 * elementNullspace12 - elementNullspace02 * elementNullspace11) / 6.0;
1531 localFaceNullspace(f, 1) = impl_ATS::magnitude(elementNullspace02 * elementNullspace10 - elementNullspace00 * elementNullspace12) / 6.0;
1532 localFaceNullspace(f, 2) = impl_ATS::magnitude(elementNullspace00 * elementNullspace11 - elementNullspace01 * elementNullspace10) / 6.0;
1541 dump(Nullspace,
"nullspaceFace.m");
1549 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1552 using ATS = Kokkos::ArithTraits<Scalar>;
1553 using impl_Scalar =
typename ATS::val_type;
1554 using impl_ATS = Kokkos::ArithTraits<impl_Scalar>;
1555 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1557 typedef typename Matrix::local_matrix_type KCRS;
1558 typedef typename KCRS::StaticCrsGraphType graph_t;
1559 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1560 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1561 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1563 const impl_Scalar impl_SC_ONE = impl_ATS::one();
1564 const impl_Scalar impl_SC_ZERO = impl_ATS::zero();
1565 const impl_Scalar impl_half = impl_SC_ONE / (impl_SC_ONE + impl_SC_ONE);
1567 std::string spaceLabel;
1568 if (spaceNumber == 0)
1569 spaceLabel =
"nodal";
1570 else if (spaceNumber == 1)
1571 spaceLabel =
"edge";
1572 else if (spaceNumber == 2)
1573 spaceLabel =
"face";
1578 if (spaceNumber > 0) {
1579 tm = getTimer(
"projection " + spaceLabel);
1580 GetOStream(
Runtime0) << solverName_ +
"::compute(): building " + spaceLabel +
" projection" << std::endl;
1584 if (spaceNumber == 0) {
1586 return Teuchos::null;
1588 }
else if (spaceNumber == 1) {
1592 }
else if (spaceNumber == 2) {
1602 dump(edgesToNodes,
"edgesToNodes.m");
1608 dump(facesToEdges,
"facesToEdges.m");
1610 facesToNodes =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*facesToEdges,
false, *edgesToNodes,
false, facesToNodes, GetOStream(
Runtime0),
true,
true);
1615 dump(facesToNodes,
"facesToNodes.m");
1617 incidence = facesToNodes;
1626 RCP<const Map> blockColMap = MapFactory::Build(incidence->getColMap(), dim);
1627 RCP<const Map> blockDomainMap = MapFactory::Build(incidence->getDomainMap(), dim);
1629 auto localIncidence = incidence->getLocalMatrixDevice();
1630 size_t numLocalRows = rowMap->getLocalNumElements();
1631 size_t numLocalColumns = dim * incidence->getColMap()->getLocalNumElements();
1632 size_t nnzEstimate = dim * localIncidence.graph.entries.size();
1633 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"projection_rowptr_" + spaceLabel), numLocalRows + 1);
1634 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"projection_colind_" + spaceLabel), nnzEstimate);
1635 scalar_view_t vals(
"projection_vals_" + spaceLabel, nnzEstimate);
1638 Kokkos::parallel_for(
1639 solverName_ +
"::buildProjection_adjustRowptr_" + spaceLabel,
1640 range_type(0, numLocalRows + 1),
1641 KOKKOS_LAMBDA(
const size_t i) {
1642 rowptr(i) = dim * localIncidence.graph.row_map(i);
1645 auto localNullspace = Nullspace->getDeviceLocalView(Xpetra::Access::ReadOnly);
1649 Kokkos::parallel_for(
1650 solverName_ +
"::buildProjection_enterValues_" + spaceLabel,
1651 range_type(0, numLocalRows),
1652 KOKKOS_LAMBDA(
const size_t f) {
1653 for (
size_t jj = localIncidence.graph.row_map(f); jj < localIncidence.graph.row_map(f + 1); jj++) {
1654 for (
size_t k = 0; k < dim; k++) {
1655 colind(dim * jj + k) = dim * localIncidence.graph.entries(jj) + k;
1656 if (impl_ATS::magnitude(localIncidence.values(jj)) > tol)
1657 vals(dim * jj + k) = impl_half * localNullspace(f, k);
1659 vals(dim * jj + k) = impl_SC_ZERO;
1665 typename CrsMatrix::local_matrix_type lclProjection(
"local projection " + spaceLabel,
1666 numLocalRows, numLocalColumns, nnzEstimate,
1667 vals, rowptr, colind);
1668 RCP<Matrix> projection = MatrixFactory::Build(lclProjection,
1669 rowMap, blockColMap,
1670 blockDomainMap, rowMap);
1675 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1681 GetOStream(
Runtime0) << solverName_ +
"::compute(): building nodal prolongator" << std::endl;
1689 Level fineLevel, coarseLevel;
1695 fineLevel.
Set(
"A", A_nodal);
1696 fineLevel.
Set(
"Coordinates", NodalCoords_);
1697 fineLevel.
Set(
"DofsPerNode", 1);
1698 coarseLevel.
setlib(A_nodal->getDomainMap()->lib());
1699 fineLevel.
setlib(A_nodal->getDomainMap()->lib());
1704 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal->getRowMap(), NSdim);
1705 nullSpace->putScalar(SC_ONE);
1706 fineLevel.
Set(
"Nullspace", nullSpace);
1708 std::string algo = parameterList_.get<std::string>(
"multigrid algorithm");
1710 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact, SaPFact;
1724 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1726 double dropTol = parameterList_.get<
double>(
"aggregation: drop tol");
1727 std::string dropScheme = parameterList_.get<std::string>(
"aggregation: drop scheme");
1728 std::string distLaplAlgo = parameterList_.get<std::string>(
"aggregation: distance laplacian algo");
1734 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1735 int minAggSize = parameterList_.get<
int>(
"aggregation: min agg size");
1737 int maxAggSize = parameterList_.get<
int>(
"aggregation: max agg size");
1739 bool matchMLbehavior1 = parameterList_.get<
bool>(
"aggregation: match ML phase1");
1741 bool matchMLbehavior2a = parameterList_.get<
bool>(
"aggregation: match ML phase2a");
1743 bool matchMLbehavior2b = parameterList_.get<
bool>(
"aggregation: match ML phase2b");
1746 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1748 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1749 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1750 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1752 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1753 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1756 SaPFact->SetFactory(
"P", TentativePFact);
1757 coarseLevel.
Request(
"P", SaPFact.get());
1759 coarseLevel.
Request(
"P", TentativePFact.get());
1760 coarseLevel.
Request(
"Nullspace", TentativePFact.get());
1761 coarseLevel.
Request(
"Coordinates", Tfact.get());
1764 bool exportVizData = parameterList_.
get<
bool>(
"aggregation: export visualization data");
1765 if (exportVizData) {
1768 aggExportParams.
set(
"aggregation: output filename",
"aggs.vtk");
1769 aggExportParams.
set(
"aggregation: output file: agg style",
"Jacks");
1772 aggExport->
SetFactory(
"Aggregates", UncoupledAggFact);
1773 aggExport->
SetFactory(
"UnAmalgamationInfo", amalgFact);
1774 fineLevel.
Request(
"Aggregates", UncoupledAggFact.get());
1775 fineLevel.
Request(
"UnAmalgamationInfo", amalgFact.get());
1779 coarseLevel.
Get(
"P", P_nodal, SaPFact.
get());
1781 coarseLevel.
Get(
"P", P_nodal, TentativePFact.
get());
1782 coarseLevel.
Get(
"Nullspace", Nullspace_nodal, TentativePFact.
get());
1783 coarseLevel.
Get(
"Coordinates", CoarseCoords_nodal, Tfact.
get());
1786 aggExport->
Build(fineLevel, coarseLevel);
1790 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1794 GetOStream(
Runtime0) << solverName_ +
"::compute(): building vectorial nodal prolongator" << std::endl;
1796 using range_type = Kokkos::RangePolicy<LO, typename NO::execution_space>;
1798 typedef typename Matrix::local_matrix_type KCRS;
1799 typedef typename KCRS::StaticCrsGraphType graph_t;
1800 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1801 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1802 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1807 RCP<Map> blockRowMap = MapFactory::Build(P_nodal->getRowMap(), dim);
1808 RCP<Map> blockColMap = MapFactory::Build(P_nodal->getColMap(), dim);
1809 RCP<Map> blockDomainMap = MapFactory::Build(P_nodal->getDomainMap(), dim);
1812 auto localP_nodal = P_nodal->getLocalMatrixDevice();
1814 size_t numLocalRows = blockRowMap->getLocalNumElements();
1815 size_t numLocalColumns = blockColMap->getLocalNumElements();
1816 size_t nnzEstimate = dim * localP_nodal.graph.entries.size();
1817 lno_view_t rowptr(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_rowptr"), numLocalRows + 1);
1818 lno_nnz_view_t colind(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_colind"), nnzEstimate);
1819 scalar_view_t vals(Kokkos::ViewAllocateWithoutInitializing(
"vectorPNodal_vals"), nnzEstimate);
1822 Kokkos::parallel_for(
1823 solverName_ +
"::buildVectorNodalProlongator_adjustRowptr",
1824 range_type(0, localP_nodal.numRows() + 1),
1826 if (i < localP_nodal.numRows()) {
1827 for (
size_t k = 0; k < dim; k++) {
1828 rowptr(dim * i + k) = dim * localP_nodal.graph.row_map(i) + k;
1831 rowptr(dim * localP_nodal.numRows()) = dim * localP_nodal.graph.row_map(i);
1835 Kokkos::parallel_for(
1836 solverName_ +
"::buildVectorNodalProlongator_adjustColind",
1837 range_type(0, localP_nodal.graph.entries.size()),
1838 KOKKOS_LAMBDA(
const size_t jj) {
1839 for (
size_t k = 0; k < dim; k++) {
1840 colind(dim * jj + k) = dim * localP_nodal.graph.entries(jj) + k;
1842 vals(dim * jj + k) = 1.;
1846 typename CrsMatrix::local_matrix_type lclVectorNodalP(
"local vector nodal prolongator",
1847 numLocalRows, numLocalColumns, nnzEstimate,
1848 vals, rowptr, colind);
1849 RCP<Matrix> vectorNodalP = MatrixFactory::Build(lclVectorNodalP,
1850 blockRowMap, blockColMap,
1851 blockDomainMap, blockRowMap);
1853 return vectorNodalP;
1856 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1864 using ATS = Kokkos::ArithTraits<Scalar>;
1865 using impl_Scalar =
typename ATS::val_type;
1866 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
1868 std::string typeStr;
1869 switch (spaceNumber) {
1884 const bool skipFirstLevel = !A_nodal.
is_null();
1887 if (spaceNumber > 0) {
1888 tm = getTimer(
"special prolongator " + typeStr);
1889 GetOStream(
Runtime0) << solverName_ +
"::compute(): building special " + typeStr +
" prolongator" << std::endl;
1892 RCP<Matrix> projection = buildProjection(spaceNumber, Nullspace);
1893 dump(projection, typeStr +
"Projection.m");
1895 if (skipFirstLevel) {
1899 buildNodalProlongator(A_nodal, P_nodal, coarseNodalNullspace, coarseNodalCoords);
1901 dump(P_nodal,
"P_nodal_" + typeStr +
".m");
1902 dump(coarseNodalNullspace,
"coarseNullspace_nodal_" + typeStr +
".m");
1904 RCP<Matrix> vectorP_nodal = buildVectorNodalProlongator(P_nodal);
1906 dump(vectorP_nodal,
"vectorP_nodal_" + typeStr +
".m");
1908 Prolongator =
Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*projection,
false, *vectorP_nodal,
false, Prolongator, GetOStream(
Runtime0),
true,
true);
1957 coarseNullspace = MultiVectorFactory::Build(vectorP_nodal->getDomainMap(), dim);
1959 auto localNullspace_nodal = coarseNodalNullspace->getDeviceLocalView(Xpetra::Access::ReadOnly);
1960 auto localNullspace_coarse = coarseNullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1961 Kokkos::parallel_for(
1962 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1963 range_type(0, coarseNodalNullspace->getLocalLength()),
1964 KOKKOS_LAMBDA(
const size_t i) {
1965 impl_Scalar val = localNullspace_nodal(i, 0);
1966 for (
size_t j = 0; j < dim; j++)
1967 localNullspace_coarse(dim * i + j, j) = val;
1971 Prolongator = projection;
1972 coarseNodalCoords = NodalCoords_;
1974 if (spaceNumber == 0) {
1976 }
else if (spaceNumber >= 1) {
1978 coarseNullspace = MultiVectorFactory::Build(projection->getDomainMap(), dim);
1979 auto localNullspace_coarse = coarseNullspace->getDeviceLocalView(Xpetra::Access::ReadWrite);
1980 Kokkos::parallel_for(
1981 solverName_ +
"::buildProlongator_nullspace_" + typeStr,
1982 range_type(0, coarseNullspace->getLocalLength() / dim),
1983 KOKKOS_LAMBDA(
const size_t i) {
1984 for (
size_t j = 0; j < dim; j++)
1985 localNullspace_coarse(dim * i + j, j) = 1.0;
1991 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2000 const bool isSingular) {
2001 int oldRank = SetProcRankVerbose(A->getDomainMap()->getComm()->getRank());
2004 pl->
set(
"printLoadBalancingInfo",
true);
2005 pl->
set(
"printCommInfo",
true);
2008 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2009 if (params.
isType<std::string>(
"Preconditioner Type")) {
2012 if (params.
get<std::string>(
"Preconditioner Type") ==
"MueLu") {
2018 thyraPrecOp =
rcp(
new XpetraThyraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(coarseA11_,
rcp(¶ms,
false)));
2032 std::string coarseType =
"";
2034 coarseType = params.
get<std::string>(
"coarse: type");
2036 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(),
::tolower);
2037 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
2039 if ((coarseType ==
"" ||
2040 coarseType ==
"Klu" ||
2041 coarseType ==
"Klu2" ||
2042 coarseType ==
"Superlu" ||
2043 coarseType ==
"Superlu_dist" ||
2044 coarseType ==
"Superludist" ||
2045 coarseType ==
"Basker" ||
2046 coarseType ==
"Cusolver" ||
2047 coarseType ==
"Tacho") &&
2050 params.
sublist(
"coarse: params").
set(
"fix nullspace",
true);
2056 level0->
Set(
"A", A);
2060 SetProcRankVerbose(oldRank);
2063 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2065 bool reuse = !SM_Matrix_.is_null();
2066 SM_Matrix_ = SM_Matrix_new;
2067 dump(SM_Matrix_,
"SM.m");
2072 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2118 if (implicitTranspose_) {
2123 if (!onlyBoundary22_) {
2128 if (Dk_1_T_R11_colMapsMatch_) {
2132 DTR11Tmp_->doImport(*residual_, *rcp_dynamic_cast<CrsMatrixWrap>(R11_)->getCrsMatrix()->getCrsGraph()->getImporter(),
Xpetra::INSERT);
2134 if (!onlyBoundary22_) {
2136 rcp_dynamic_cast<TpetraCrsMatrix>(rcp_dynamic_cast<CrsMatrixWrap>(Dk_1_T_)->getCrsMatrix())->getTpetra_CrsMatrix()->localApply(
toTpetra(*DTR11Tmp_),
toTpetra(*Dres_),
Teuchos::NO_TRANS);
2140 rcp_dynamic_cast<TpetraCrsMatrix>(rcp_dynamic_cast<CrsMatrixWrap>(R11_)->getCrsMatrix())->getTpetra_CrsMatrix()->localApply(
toTpetra(*DTR11Tmp_),
toTpetra(*P11res_),
Teuchos::NO_TRANS);
2147 if (!onlyBoundary22_) {
2160 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2162 P11resTmp_->beginImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2164 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_) {
2170 if (!coarseA11_.is_null()) {
2171 if (!ImporterCoarse11_.is_null() && !implicitTranspose_)
2172 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2176 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2177 if (!thyraPrecOpH_.is_null()) {
2179 thyraPrecOpH_->apply(*P11resSubComm_, *P11xSubComm_,
Teuchos::NO_TRANS, one, zero);
2182 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2186 if (!A22_.is_null()) {
2187 if (!onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2191 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
2192 if (!thyraPrecOp22_.is_null()) {
2194 thyraPrecOp22_->apply(*DresSubComm_, *DxSubComm_,
Teuchos::NO_TRANS, one, zero);
2197 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2200 if (coarseA11_.is_null() && !ImporterCoarse11_.is_null() && !implicitTranspose_)
2201 P11resTmp_->endImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2202 if (A22_.is_null() && !onlyBoundary22_ && !Importer22_.is_null() && !implicitTranspose_)
2206 if (fuseProlongationAndUpdate_) {
2212 if (!onlyBoundary22_) {
2222 if (!onlyBoundary22_) {
2229 X.update(one, *residual_, one);
2234 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2241 if (implicitTranspose_)
2248 if (!ImporterCoarse11_.is_null() && !implicitTranspose_) {
2250 P11resTmp_->doImport(*P11res_, *ImporterCoarse11_,
Xpetra::INSERT);
2252 if (!coarseA11_.is_null()) {
2254 HierarchyCoarse11_->Iterate(*P11resSubComm_, *P11xSubComm_, numItersCoarse11_,
true);
2261 X.update(one, *residual_, one);
2265 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2267 if (onlyBoundary22_)
2275 if (implicitTranspose_)
2282 if (!Importer22_.is_null() && !implicitTranspose_) {
2286 if (!A22_.is_null()) {
2288 Hierarchy22_->Iterate(*DresSubComm_, *DxSubComm_, numIters22_,
true);
2295 X.update(one, *residual_, one);
2299 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2307 if (!onlyBoundary11_ && X.getNumVectors() != P11res_->getNumVectors())
2308 allocateMemory(X.getNumVectors());
2314 PreSmoother11_->Apply(X, RHS, use_as_preconditioner_);
2318 if (mode_ ==
"additive")
2319 applyInverseAdditive(RHS, X);
2320 else if (mode_ ==
"121") {
2324 }
else if (mode_ ==
"212") {
2328 }
else if (mode_ ==
"1")
2330 else if (mode_ ==
"2")
2332 else if (mode_ ==
"7") {
2338 PreSmoother11_->Apply(X, RHS,
false);
2345 PostSmoother11_->Apply(X, RHS,
false);
2348 }
else if (mode_ ==
"none") {
2351 applyInverseAdditive(RHS, X);
2357 PostSmoother11_->Apply(X, RHS,
false);
2361 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2366 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2371 int spaceNumber = List.
get<
int>(
"refmaxwell: space number", 1);
2380 Dk_1 =
pop(List,
"Dk_1", Dk_1);
2381 Dk_2 = pop<RCP<Matrix> >(List,
"Dk_2", Dk_2);
2382 D0 = pop<RCP<Matrix> >(List,
"D0", D0);
2384 M1_beta = pop<RCP<Matrix> >(List,
"M1_beta", M1_beta);
2385 M1_alpha = pop<RCP<Matrix> >(List,
"M1_alpha", M1_alpha);
2387 Mk_one = pop<RCP<Matrix> >(List,
"Mk_one", Mk_one);
2388 Mk_1_one = pop<RCP<Matrix> >(List,
"Mk_1_one", Mk_1_one);
2390 invMk_1_invBeta = pop<RCP<Matrix> >(List,
"invMk_1_invBeta", invMk_1_invBeta);
2391 invMk_2_invAlpha = pop<RCP<Matrix> >(List,
"invMk_2_invAlpha", invMk_2_invAlpha);
2393 Nullspace11 = pop<RCP<MultiVector> >(List,
"Nullspace11", Nullspace11);
2394 Nullspace22 = pop<RCP<MultiVector> >(List,
"Nullspace22", Nullspace22);
2395 NodalCoords = pop<RCP<RealValuedMultiVector> >(List,
"Coordinates", NodalCoords);
2399 if (M1_beta.is_null())
2405 if (Mk_one.is_null())
2411 if (invMk_1_invBeta.is_null())
2417 if (Nullspace11.is_null())
2423 if (spaceNumber == 1) {
2426 else if (D0.is_null())
2428 if (M1_beta.is_null())
2430 }
else if (spaceNumber == 2) {
2433 else if (D0.is_null())
2441 invMk_1_invBeta, invMk_2_invAlpha,
2442 Nullspace11, Nullspace22,
2446 if (SM_Matrix != Teuchos::null)
2447 resetMatrix(SM_Matrix, ComputePrec);
2450 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2460 D0_Matrix, Teuchos::null, D0_Matrix,
2461 Ms_Matrix, Teuchos::null,
2462 M1_Matrix, Teuchos::null,
2463 M0inv_Matrix, Teuchos::null,
2464 Nullspace11, Teuchos::null,
2469 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2486 if (spaceNumber_ == 1)
2487 solverName_ =
"RefMaxwell";
2488 else if (spaceNumber_ == 2)
2489 solverName_ =
"RefDarcy";
2492 "spaceNumber needs to be 1 (HCurl) or 2 (HDiv)");
2493 HierarchyCoarse11_ = Teuchos::null;
2494 Hierarchy22_ = Teuchos::null;
2495 PreSmoother11_ = Teuchos::null;
2496 PostSmoother11_ = Teuchos::null;
2497 disable_addon_ =
false;
2498 disable_addon_22_ =
true;
2502 setParameters(List);
2517 if (!disable_addon_) {
2523 if ((k >= 2) && !disable_addon_22_) {
2530 #ifdef HAVE_MUELU_DEBUG
2535 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRangeMap()));
2536 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*M1_beta->getRowMap()));
2539 TEUCHOS_ASSERT(M1_beta->getDomainMap()->isSameAs(*D0->getRangeMap()));
2543 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRangeMap()));
2544 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*M1_alpha->getRowMap()));
2547 TEUCHOS_ASSERT(M1_alpha->getDomainMap()->isSameAs(*D0->getRangeMap()))
2550 if (!disable_addon_) {
2552 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRangeMap()));
2553 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Mk_one->getRowMap()));
2556 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2559 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRangeMap()));
2560 TEUCHOS_ASSERT(invMk_1_invBeta->getDomainMap()->isSameAs(*invMk_1_invBeta->getRowMap()));
2563 TEUCHOS_ASSERT(Mk_one->getDomainMap()->isSameAs(*Dk_1->getRangeMap()));
2566 if ((k >= 2) && !disable_addon_22_) {
2568 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRangeMap()));
2569 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Mk_1_one->getRowMap()));
2572 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_1->getDomainMap()));
2575 TEUCHOS_ASSERT(Mk_1_one->getDomainMap()->isSameAs(*Dk_2->getRangeMap()));
2578 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRangeMap()));
2579 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*invMk_2_invAlpha->getRowMap()));
2582 TEUCHOS_ASSERT(invMk_2_invAlpha->getDomainMap()->isSameAs(*Dk_2->getDomainMap()));
2592 RCP<Matrix> Dk_1copy = MatrixFactory::Build(Dk_1->getRowMap(), Dk_1->getColMap(), 0);
2593 RCP<CrsMatrix> Dk_1copyCrs = rcp_dynamic_cast<CrsMatrixWrap>(Dk_1copy,
true)->getCrsMatrix();
2597 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1,
true)->getCrsMatrix()->getAllValues(Dk_1rowptr_RCP, Dk_1colind_RCP, Dk_1vals_RCP);
2602 Dk_1copyCrs->allocateAllValues(Dk_1vals_RCP.
size(), Dk_1copyrowptr_RCP, Dk_1copycolind_RCP, Dk_1copyvals_RCP);
2603 Dk_1copyrowptr_RCP.
deepCopy(Dk_1rowptr_RCP());
2604 Dk_1copycolind_RCP.deepCopy(Dk_1colind_RCP());
2605 Dk_1copyvals_RCP.
deepCopy(Dk_1vals_RCP());
2606 Dk_1copyCrs->setAllValues(Dk_1copyrowptr_RCP,
2609 Dk_1copyCrs->expertStaticFillComplete(Dk_1->getDomainMap(), Dk_1->getRangeMap(),
2610 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1,
true)->getCrsMatrix()->getCrsGraph()->getImporter(),
2611 rcp_dynamic_cast<CrsMatrixWrap>(Dk_1,
true)->getCrsMatrix()->getCrsGraph()->getExporter());
2614 Dk_1_ = MatrixFactory::BuildCopy(Dk_1);
2621 RCP<Matrix> Dk_2copy = MatrixFactory::Build(Dk_2->getRowMap(), Dk_2->getColMap(), 0);
2622 RCP<CrsMatrix> Dk_2copyCrs = rcp_dynamic_cast<CrsMatrixWrap>(Dk_2copy,
true)->getCrsMatrix();
2626 rcp_dynamic_cast<CrsMatrixWrap>(Dk_2,
true)->getCrsMatrix()->getAllValues(Dk_2rowptr_RCP, Dk_2colind_RCP, Dk_2vals_RCP);
2631 Dk_2copyCrs->allocateAllValues(Dk_2vals_RCP.
size(), Dk_2copyrowptr_RCP, Dk_2copycolind_RCP, Dk_2copyvals_RCP);
2632 Dk_2copyrowptr_RCP.
deepCopy(Dk_2rowptr_RCP());
2633 Dk_2copycolind_RCP.deepCopy(Dk_2colind_RCP());
2634 Dk_2copyvals_RCP.
deepCopy(Dk_2vals_RCP());
2635 Dk_2copyCrs->setAllValues(Dk_2copyrowptr_RCP,
2638 Dk_2copyCrs->expertStaticFillComplete(Dk_2->getDomainMap(), Dk_2->getRangeMap(),
2639 rcp_dynamic_cast<CrsMatrixWrap>(Dk_2,
true)->getCrsMatrix()->getCrsGraph()->getImporter(),
2640 rcp_dynamic_cast<CrsMatrixWrap>(Dk_2,
true)->getCrsMatrix()->getCrsGraph()->getExporter());
2643 Dk_2_ = MatrixFactory::BuildCopy(Dk_2);
2646 M1_alpha_ = M1_alpha;
2649 Mk_1_one_ = Mk_1_one;
2651 invMk_1_invBeta_ = invMk_1_invBeta;
2652 invMk_2_invAlpha_ = invMk_2_invAlpha;
2654 NodalCoords_ = NodalCoords;
2655 Nullspace11_ = Nullspace11;
2656 Nullspace22_ = Nullspace22;
2659 dump(Dk_1_,
"Dk_1_clean.m");
2660 dump(Dk_2_,
"Dk_2_clean.m");
2662 dump(M1_beta_,
"M1_beta.m");
2663 dump(M1_alpha_,
"M1_alpha.m");
2665 dump(Mk_one_,
"Mk_one.m");
2666 dump(Mk_1_one_,
"Mk_1_one.m");
2668 dump(invMk_1_invBeta_,
"invMk_1_invBeta.m");
2669 dump(invMk_2_invAlpha_,
"invMk_2_invAlpha.m");
2671 dumpCoords(NodalCoords_,
"coords.m");
2674 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2677 std::ostringstream oss;
2683 if (!coarseA11_.is_null())
2684 root = comm->getRank();
2693 oss <<
"\n--------------------------------------------------------------------------------\n"
2694 <<
"--- " + solverName_ +
2696 "--------------------------------------------------------------------------------"
2703 SM_Matrix_->getRowMap()->getComm()->barrier();
2705 numRows = SM_Matrix_->getGlobalNumRows();
2706 nnz = SM_Matrix_->getGlobalNumEntries();
2721 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2722 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2724 if (!A22_.is_null()) {
2725 numRows = A22_->getGlobalNumRows();
2726 nnz = A22_->getGlobalNumEntries();
2728 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2734 if (PreSmoother11_ != null && PreSmoother11_ == PostSmoother11_)
2735 oss <<
"Smoother 11 both : " << PreSmoother11_->description() << std::endl;
2737 oss <<
"Smoother 11 pre : "
2738 << (PreSmoother11_ != null ? PreSmoother11_->description() :
"no smoother") << std::endl;
2739 oss <<
"Smoother 11 post : "
2740 << (PostSmoother11_ != null ? PostSmoother11_->description() :
"no smoother") << std::endl;
2745 std::string outstr = oss.str();
2749 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2751 int strLength = outstr.size();
2752 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2753 if (comm->getRank() != root)
2754 outstr.resize(strLength);
2755 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2760 if (!HierarchyCoarse11_.is_null())
2761 HierarchyCoarse11_->describe(out, GetVerbLevel());
2763 if (!Hierarchy22_.is_null())
2764 Hierarchy22_->describe(out, GetVerbLevel());
2768 std::ostringstream oss2;
2770 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2771 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;
2773 int numProcs = comm->getSize();
2781 if (!coarseA11_.is_null())
2783 if (!A22_.is_null())
2785 std::vector<char> states(numProcs, 0);
2787 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2789 states.push_back(status);
2792 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2793 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2794 for (
int j = 0; j < rowWidth; j++)
2795 if (proc + j < numProcs)
2796 if (states[proc + j] == 0)
2798 else if (states[proc + j] == 1)
2800 else if (states[proc + j] == 2)
2807 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2816 #define MUELU_REFMAXWELL_SHORT
2817 #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.
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 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)
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.
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.
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)