10 #ifndef MUELU_MAXWELL1_DEF_HPP
11 #define MUELU_MAXWELL1_DEF_HPP
18 #include "Xpetra_Map.hpp"
23 #include "MueLu_Maxwell_Utils.hpp"
25 #include "MueLu_ReitzingerPFactory.hpp"
26 #include "MueLu_Utilities.hpp"
28 #include "MueLu_Hierarchy.hpp"
29 #include "MueLu_RAPFactory.hpp"
30 #include "MueLu_RebalanceAcFactory.hpp"
32 #include "MueLu_PerfUtils.hpp"
33 #include "MueLu_ParameterListInterpreter.hpp"
35 #include <MueLu_HierarchyUtils.hpp>
39 #include <MueLu_RefMaxwellSmoother.hpp>
41 #ifdef HAVE_MUELU_CUDA
42 #include "cuda_profiler_api.h"
47 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
49 return SM_Matrix_->getDomainMap();
52 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
54 return SM_Matrix_->getRangeMap();
57 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
59 if (list.
isType<std::string>(
"parameterlist: syntax") && list.
get<std::string>(
"parameterlist: syntax") ==
"ml") {
60 list.
remove(
"parameterlist: syntax");
67 newList.
sublist(
"maxwell1: 22list").
set(
"use kokkos refactor",
false);
69 newList.
sublist(
"maxwell1: 11list").
set(
"use kokkos refactor",
false);
70 newList.
sublist(
"maxwell1: 11list").
set(
"tentative: constant column sums",
false);
71 newList.
sublist(
"maxwell1: 11list").
set(
"tentative: calculate qr",
false);
73 newList.
sublist(
"maxwell1: 11list").
set(
"aggregation: use ml scaling of drop tol",
true);
74 newList.
sublist(
"maxwell1: 22list").
set(
"aggregation: use ml scaling of drop tol",
true);
76 newList.
sublist(
"maxwell1: 22list").
set(
"aggregation: min agg size", 3);
77 newList.
sublist(
"maxwell1: 22list").
set(
"aggregation: match ML phase1",
true);
78 newList.
sublist(
"maxwell1: 22list").
set(
"aggregation: match ML phase2a",
true);
79 newList.
sublist(
"maxwell1: 22list").
set(
"aggregation: match ML phase2b",
true);
81 if (list.
isParameter(
"aggregation: damping factor") && list.
get<
double>(
"aggregation: damping factor") == 0.0)
82 newList.
sublist(
"maxwell1: 11list").
set(
"multigrid algorithm",
"unsmoothed reitzinger");
84 newList.
sublist(
"maxwell1: 11list").
set(
"multigrid algorithm",
"smoothed reitzinger");
85 newList.
sublist(
"maxwell1: 11list").
set(
"aggregation: type",
"uncoupled");
87 newList.
sublist(
"maxwell1: 22list").
set(
"multigrid algorithm",
"unsmoothed");
88 newList.
sublist(
"maxwell1: 22list").
set(
"aggregation: type",
"uncoupled");
90 if (newList.
sublist(
"maxwell1: 22list").
isType<std::string>(
"verbosity"))
91 newList.
set(
"verbosity", newList.
sublist(
"maxwell1: 22list").
get<std::string>(
"verbosity"));
94 std::vector<std::string> convert = {
"coarse:",
"smoother:",
"smoother: pre",
"smoother: post"};
95 for (
auto it = convert.begin(); it != convert.end(); ++it) {
96 if (newList.
sublist(
"maxwell1: 22list").
isType<std::string>(*it +
" type")) {
97 newList.
sublist(
"maxwell1: 11list").
set(*it +
" type", newList.
sublist(
"maxwell1: 22list").
get<std::string>(*it +
" type"));
101 newList.
sublist(
"maxwell1: 11list").
set(*it +
" params", newList.
sublist(
"maxwell1: 22list").
sublist(*it +
" params"));
106 newList.
sublist(
"maxwell1: 22list").
set(
"smoother: type",
"none");
107 newList.
sublist(
"maxwell1: 22list").
set(
"coarse: type",
"none");
109 newList.
set(
"maxwell1: nodal smoother fix zero diagonal threshold", 1e-10);
110 newList.
sublist(
"maxwell1: 22list").
set(
"rap: fix zero diagonals",
true);
111 newList.
sublist(
"maxwell1: 22list").
set(
"rap: fix zero diagonals threshold", 1e-10);
116 std::string mode_string = list.
get(
"maxwell1: mode", MasterList::getDefault<std::string>(
"maxwell1: mode"));
117 applyBCsTo22_ = list.
get(
"maxwell1: apply BCs to 22",
false);
118 dump_matrices_ = list.
get(
"maxwell1: dump matrices", MasterList::getDefault<bool>(
"maxwell1: dump matrices"));
122 defaultSmootherList.
set(
"smoother: type",
"CHEBYSHEV");
123 defaultSmootherList.
sublist(
"smoother: params").
set(
"chebyshev: degree", 2);
124 defaultSmootherList.
sublist(
"smoother: params").
set(
"chebyshev: ratio eigenvalue", 7.0);
125 defaultSmootherList.
sublist(
"smoother: params").
set(
"chebyshev: eigenvalue max iterations", 30);
128 std::string verbosity = list.
get(
"verbosity",
"high");
132 if (mode_ != MODE_GMHD_STANDARD) {
133 if (mode_string ==
"standard")
134 mode_ = MODE_STANDARD;
135 else if (mode_string ==
"refmaxwell")
136 mode_ = MODE_REFMAXWELL;
137 else if (mode_string ==
"edge only")
138 mode_ = MODE_EDGE_ONLY;
147 precList22_ = list.
sublist(
"maxwell1: 22list");
148 else if (list.
isSublist(
"refmaxwell: 22list"))
149 precList22_ = list.
sublist(
"refmaxwell: 22list");
150 if (mode_ == MODE_EDGE_ONLY || mode_ == MODE_STANDARD || mode_ == MODE_GMHD_STANDARD)
151 precList22_.
set(
"smoother: pre or post",
"none");
152 else if (!precList22_.isType<std::string>(
"Preconditioner Type") &&
153 !precList22_.isType<std::string>(
"smoother: type") &&
154 !precList22_.isType<std::string>(
"smoother: pre type") &&
155 !precList22_.isType<std::string>(
"smoother: post type")) {
156 precList22_ = defaultSmootherList;
158 precList22_.
set(
"verbosity", precList22_.get(
"verbosity", verbosity));
163 precList11_ = list.
sublist(
"maxwell1: 11list");
164 else if (list.
isSublist(
"refmaxwell: 11list"))
165 precList11_ = list.
sublist(
"refmaxwell: 11list");
167 if (mode_ == MODE_GMHD_STANDARD) {
168 precList11_.
set(
"smoother: pre or post",
"none");
169 precList11_.
set(
"smoother: type",
"none");
171 if (!precList11_.isType<std::string>(
"Preconditioner Type") &&
172 !precList11_.isType<std::string>(
"smoother: type") &&
173 !precList11_.isType<std::string>(
"smoother: pre type") &&
174 !precList11_.isType<std::string>(
"smoother: post type")) {
175 if (mode_ == MODE_EDGE_ONLY || mode_ == MODE_REFMAXWELL) {
176 precList11_ = defaultSmootherList;
178 if (mode_ == MODE_STANDARD) {
179 precList11_.
set(
"smoother: type",
"HIPTMAIR");
180 precList11_.
set(
"hiptmair: smoother type 1",
"CHEBYSHEV");
181 precList11_.
set(
"hiptmair: smoother type 2",
"CHEBYSHEV");
182 precList11_.
sublist(
"hiptmair: smoother list 1") = defaultSmootherList;
183 precList11_.
sublist(
"hiptmair: smoother list 2") = defaultSmootherList;
186 precList11_.
set(
"verbosity", precList11_.get(
"verbosity", verbosity));
190 !precList11_.isType<std::string>(
"Preconditioner Type") &&
191 !precList11_.isParameter(
"reuse: type"))
192 precList11_.
set(
"reuse: type",
"full");
194 !precList22_.isType<std::string>(
"Preconditioner Type") &&
195 !precList22_.isParameter(
"reuse: type"))
196 precList22_.
set(
"reuse: type",
"full");
199 useKokkos_ = !Node::is_serial;
200 useKokkos_ = list.
get(
"use kokkos refactor", useKokkos_);
202 parameterList_ = list;
205 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
211 HierarchyGmhd_->GetLevel(0)->Set(
"A", GmhdA_Matrix_);
212 GmhdA_Matrix_->setObjectLabel(
"GmhdA");
215 precListGmhd = List.
sublist(
"maxwell1: Gmhdlist");
216 precListGmhd.
set(
"coarse: max size", 1);
217 precListGmhd.
set(
"max levels", HierarchyGmhd_->GetNumLevels());
219 HierarchyGmhd_->setlib(GmhdA_Matrix_->getDomainMap()->lib());
220 HierarchyGmhd_->SetProcRankVerbose(GmhdA_Matrix_->getDomainMap()->getComm()->getRank());
221 mueLuFactory->SetupHierarchy(*HierarchyGmhd_);
224 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
238 #ifdef HAVE_MUELU_CUDA
239 if (parameterList_.get<
bool>(
"maxwell1: cuda profile setup",
false)) cudaProfilerStart();
242 std::string timerLabel;
244 timerLabel =
"MueLu Maxwell1: compute (reuse)";
246 timerLabel =
"MueLu Maxwell1: compute";
251 bool have_generated_Kn =
false;
252 if (Kn_Matrix_.is_null()) {
254 GetOStream(
Runtime0) <<
"Maxwell1::compute(): Kn not provided. Generating." << std::endl;
255 Kn_Matrix_ = generate_kn();
256 have_generated_Kn =
true;
257 }
else if (parameterList_.get<
bool>(
"rap: fix zero diagonals",
true)) {
259 if (parameterList_.isType<
magnitudeType>(
"rap: fix zero diagonals threshold"))
260 threshold = parameterList_.get<
magnitudeType>(
"rap: fix zero diagonals threshold",
263 threshold = Teuchos::as<magnitudeType>(parameterList_.get<
double>(
"rap: fix zero diagonals threshold",
265 Scalar replacement = Teuchos::as<Scalar>(parameterList_.get<
double>(
"rap: fix zero diagonals replacement",
266 MasterList::getDefault<double>(
"rap: fix zero diagonals replacement")));
272 Kn_Matrix_->setObjectLabel(
"Maxwell1 (2,2)");
275 if (!Coords_.is_null())
276 precList22_.sublist(
"user data").set(
"Coordinates", Coords_);
280 if (precList22_.isParameter(
"repartition: enable")) {
281 bool repartition = precList22_.get<
bool>(
"repartition: enable");
282 precList11_.set(
"repartition: enable", repartition);
288 precList22_.set(
"repartition: save importer",
true);
290 precList22_.set(
"repartition: rebalance P and R",
true);
293 if (precList22_.isParameter(
"repartition: use subcommunicators")) {
294 precList11_.set(
"repartition: use subcommunicators", precList22_.get<
bool>(
"repartition: use subcommunicators"));
298 if (precList11_.get<
bool>(
"repartition: use subcommunicators") ==
true)
299 precList11_.set(
"repartition: use subcommunicators in place",
true);
302 precList11_.set(
"repartition: use subcommunicators",
true);
303 precList22_.set(
"repartition: use subcommunicators",
true);
307 precList11_.set(
"repartition: use subcommunicators in place",
true);
311 precList11_.remove(
"repartition: enable",
false);
330 magnitudeType rowSumTol = precList11_.get(
"aggregation: row sum drop tol", -1.0);
332 useKokkos_, BCrowsKokkos_, BCcolsKokkos_, BCdomainKokkos_,
333 BCedges_, BCnodes_, BCrows_, BCcols_, BCdomain_,
334 allEdgesBoundary_, allNodesBoundary_);
336 GetOStream(
Statistics2) <<
"MueLu::Maxwell1::compute(): Detected " << BCedges_ <<
" BC rows and " << BCnodes_ <<
" BC columns." << std::endl;
340 if (allEdgesBoundary_) {
343 GetOStream(
Warnings0) <<
"All edges are detected as boundary edges!" << std::endl;
344 mode_ = MODE_EDGE_ONLY;
347 precList22_.set(
"max levels", 1);
350 if (allNodesBoundary_) {
353 GetOStream(
Warnings0) <<
"All nodes are detected as boundary nodes!" << std::endl;
354 mode_ = MODE_EDGE_ONLY;
357 precList22_.set(
"max levels", 1);
367 D0_Matrix_->resumeFill();
375 GetOStream(
Runtime0) <<
"Maxwell1::compute(): nuking BC rows/cols of D0" << std::endl;
382 GetOStream(
Runtime0) <<
"Maxwell1::compute(): nuking BC rows of D0" << std::endl;
390 D0_Matrix_->fillComplete(D0_Matrix_->getDomainMap(), D0_Matrix_->getRangeMap());
401 if (have_generated_Kn) {
402 Kn_Smoother_0 = Kn_Matrix_;
404 Kn_Smoother_0 = generate_kn();
412 for (
int i = 0; i < Hierarchy22_->GetNumLevels(); i++) {
413 Hierarchy11_->AddNewLevel();
417 RCP<Matrix> NodeAggMatrix = rcp_dynamic_cast<Matrix>(NodeAggOp);
421 EdgeL->
Set(
"A", SM_Matrix_);
422 EdgeL->
Set(
"D0", D0_Matrix_);
424 EdgeL->
Set(
"NodeAggMatrix", NodeAggMatrix);
425 EdgeL->
Set(
"NodeMatrix", Kn_Smoother_0);
426 OldSmootherMatrix = Kn_Smoother_0;
427 OldEdgeLevel = EdgeL;
436 EdgeL->
Set(
"Pnodal", NodalP_ones);
442 EdgeL->
Set(
"NodeImporter", importer);
448 EdgeL->
Set(
"NodeAggMatrix", NodeAggMatrix);
449 if (!have_generated_Kn) {
460 RAPlist.
set(
"rap: fix zero diagonals",
false);
466 rebAcParams.
set(
"repartition: use subcommunicators",
true);
467 rebAcParams.
set(
"repartition: use subcommunicators in place",
true);
469 newAfact->SetParameterList(rebAcParams);
472 Level fLevel, cLevel;
474 cLevel.
Set(
"InPlaceMap", InPlaceMap);
475 cLevel.
Set(
"A", NewKn);
476 cLevel.
Request(
"A", newAfact.get());
477 newAfact->Build(fLevel, cLevel);
480 EdgeL->
Set(
"NodeMatrix", NewKn);
482 EdgeL->
Set(
"NodeMatrix", NewKn);
486 double thresh = parameterList_.get(
"maxwell1: nodal smoother fix zero diagonal threshold", 1e-10);
488 GetOStream(
Runtime0) <<
"Maxwell1::compute(): Fixing zero diagonal for nodal smoother matrix" << std::endl;
492 OldEdgeLevel->
Set(
"NodeMatrix", OldSmootherMatrix);
494 OldSmootherMatrix = NewKn;
497 EdgeL->
Set(
"NodeMatrix", NodeAggMatrix);
501 EdgeL->
Set(
"NodeMatrix", NodeAggOp);
502 EdgeL->
Set(
"NodeAggMatrix", NodeAggOp);
505 OldEdgeLevel = EdgeL;
512 std::string fine_smoother = precList11_.
get<std::string>(
"smoother: type");
515 precList11_.set(
"coarse: max size", 1);
516 precList11_.set(
"max levels", Hierarchy22_->GetNumLevels());
518 const bool refmaxwellCoarseSolve = (precList11_.get<std::string>(
"coarse: type",
519 MasterList::getDefault<std::string>(
"coarse: type")) ==
"RefMaxwell");
520 if (refmaxwellCoarseSolve) {
521 GetOStream(
Runtime0) <<
"Maxwell1::compute(): Will set up RefMaxwell coarse solver" << std::endl;
522 precList11_.set(
"coarse: type",
"none");
529 Hierarchy11_->setlib(SM_Matrix_->getDomainMap()->lib());
530 Hierarchy11_->SetProcRankVerbose(SM_Matrix_->getDomainMap()->getComm()->getRank());
536 mueLuFactory->SetupHierarchy(*Hierarchy11_);
538 if (refmaxwellCoarseSolve) {
539 GetOStream(
Runtime0) <<
"Maxwell1::compute(): Setting up RefMaxwell coarse solver" << std::endl;
540 auto coarseLvl = Hierarchy11_->GetLevel(Hierarchy11_->GetNumLevels() - 1);
542 precList11_.sublist(
"coarse: params")));
543 coarseSolver->Setup(*coarseLvl);
544 coarseLvl->Set(
"PreSmoother",
545 rcp_dynamic_cast<SmootherBase>(coarseSolver,
true));
548 if (mode_ == MODE_REFMAXWELL) {
549 if (Hierarchy11_->GetNumLevels() > 1) {
562 #ifdef MUELU_MAXWELL1_DEBUG
563 for (
int i = 0; i < Hierarchy11_->GetNumLevels(); i++) {
570 auto nrmE = EdgeMatrix->getFrobeniusNorm();
571 auto nrmN = NodeMatrix->getFrobeniusNorm();
572 auto nrmNa = NodeAggMatrix->getFrobeniusNorm();
573 auto nrmD0 = D0->getFrobeniusNorm();
575 std::cout <<
"DEBUG: Norms on Level " << i <<
" E/N/NA/D0 = " << nrmE <<
" / " << nrmN <<
" / " << nrmNa <<
" / " << nrmD0 << std::endl;
576 std::cout <<
"DEBUG: NNZ on Level " << i <<
" E/N/NA/D0 = " << EdgeMatrix->getGlobalNumEntries() <<
" / " << NodeMatrix->getGlobalNumEntries() <<
" / " << NodeAggMatrix->getGlobalNumEntries() <<
" / " << D0->getGlobalNumEntries() << std::endl;
581 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
585 RAPlist.
set(
"rap: fix zero diagonals",
false);
587 std::string labelstr =
"NodeMatrix (Level 0)";
592 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
594 if (mode_ == MODE_REFMAXWELL) {
597 residualFine_ = MultiVectorFactory::Build(SM_Matrix_->getRangeMap(), numVectors);
599 if (!Hierarchy11_.is_null() && Hierarchy11_->GetNumLevels() > 1) {
602 residual11c_ = MultiVectorFactory::Build(A->getRangeMap(), numVectors);
603 update11c_ = MultiVectorFactory::Build(A->getDomainMap(), numVectors);
606 if (!Hierarchy22_.is_null()) {
607 residual22_ = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(), numVectors);
608 update22_ = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(), numVectors);
613 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
615 if (dump_matrices_) {
616 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
621 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
623 if (dump_matrices_) {
624 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
629 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
631 if (dump_matrices_) {
632 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
637 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
639 if (dump_matrices_) {
640 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
641 std::ofstream out(name);
642 for (
size_t i = 0; i < Teuchos::as<size_t>(v.
size()); i++)
647 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
649 if (dump_matrices_) {
650 GetOStream(
Runtime0) <<
"Dumping to " << name << std::endl;
651 std::ofstream out(name);
652 auto vH = Kokkos::create_mirror_view(v);
653 Kokkos::deep_copy(vH, v);
654 for (
size_t i = 0; i < vH.size(); i++)
655 out << vH[i] <<
"\n";
659 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
671 return Teuchos::null;
674 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
676 bool reuse = !SM_Matrix_.is_null();
677 SM_Matrix_ = SM_Matrix_new;
678 dump(*SM_Matrix_,
"SM.m");
683 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
687 if (!allEdgesBoundary_ && X.
getNumVectors() != residualFine_->getNumVectors())
694 if (Fine->IsAvailable(
"PreSmoother")) {
697 preSmoo->
Apply(X, RHS,
true);
707 if (!P11_.is_null()) {
710 Hierarchy11_->Iterate(*residual11c_, *update11c_,
true, 1);
714 if (!allNodesBoundary_) {
717 Hierarchy22_->Iterate(*residual22_, *update22_,
true, 0);
725 if (!allNodesBoundary_)
730 if (Fine->IsAvailable(
"PostSmoother")) {
733 postSmoo->
Apply(X, RHS,
false);
737 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
739 Hierarchy11_->Iterate(RHS, X, 1,
true);
742 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
748 if (mode_ == MODE_GMHD_STANDARD)
749 HierarchyGmhd_->Iterate(RHS, X, 1,
true);
750 else if (mode_ == MODE_STANDARD || mode_ == MODE_EDGE_ONLY)
751 applyInverseStandard(RHS, X);
752 else if (mode_ == MODE_REFMAXWELL)
753 applyInverseRefMaxwellAdditive(RHS, X);
758 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
763 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
773 #ifdef HAVE_MUELU_DEBUG
775 TEUCHOS_ASSERT(Kn_Matrix->getDomainMap()->isSameAs(*D0_Matrix->getDomainMap()));
776 TEUCHOS_ASSERT(Kn_Matrix->getRangeMap()->isSameAs(*D0_Matrix->getDomainMap()));
779 TEUCHOS_ASSERT(D0_Matrix->getRangeMap()->isSameAs(*D0_Matrix->getRowMap()));
782 Hierarchy11_ = Teuchos::null;
783 Hierarchy22_ = Teuchos::null;
784 HierarchyGmhd_ = Teuchos::null;
785 if (mode_ != MODE_GMHD_STANDARD) mode_ = MODE_STANDARD;
789 allEdgesBoundary_ =
false;
790 allNodesBoundary_ =
false;
791 dump_matrices_ =
false;
792 enable_reuse_ =
false;
794 applyBCsTo22_ =
false;
804 RCP<Matrix> D0copy = MatrixFactory::Build(D0_Matrix->getRowMap(), D0_Matrix->getColMap(), 0);
805 RCP<CrsMatrix> D0copyCrs = rcp_dynamic_cast<CrsMatrixWrap>(D0copy,
true)->getCrsMatrix();
809 rcp_dynamic_cast<CrsMatrixWrap>(D0_Matrix,
true)->getCrsMatrix()->getAllValues(D0rowptr_RCP, D0colind_RCP, D0vals_RCP);
814 D0copyCrs->allocateAllValues(D0vals_RCP.
size(), D0copyrowptr_RCP, D0copycolind_RCP, D0copyvals_RCP);
815 D0copyrowptr_RCP.
deepCopy(D0rowptr_RCP());
816 D0copycolind_RCP.deepCopy(D0colind_RCP());
817 D0copyvals_RCP.
deepCopy(D0vals_RCP());
818 D0copyCrs->setAllValues(D0copyrowptr_RCP,
821 D0copyCrs->expertStaticFillComplete(D0_Matrix->getDomainMap(), D0_Matrix->getRangeMap(),
822 rcp_dynamic_cast<CrsMatrixWrap>(D0_Matrix,
true)->getCrsMatrix()->getCrsGraph()->getImporter(),
823 rcp_dynamic_cast<CrsMatrixWrap>(D0_Matrix,
true)->getCrsMatrix()->getCrsGraph()->getExporter());
826 D0_Matrix_ = MatrixFactory::BuildCopy(D0_Matrix);
828 Kn_Matrix_ = Kn_Matrix;
830 Nullspace_ = Nullspace;
832 if (!Kn_Matrix_.is_null()) dump(*Kn_Matrix_,
"Kn.m");
833 if (!Nullspace_.is_null()) dump(*Nullspace_,
"nullspace.m");
834 if (!Coords_.is_null()) dumpCoords(*Coords_,
"coords.m");
837 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
840 std::ostringstream oss;
846 if (!Kn_Matrix_.is_null())
847 root = comm->getRank();
856 oss <<
"\n--------------------------------------------------------------------------------\n"
857 <<
"--- Maxwell1 Summary ---\n"
858 "--------------------------------------------------------------------------------"
865 SM_Matrix_->getRowMap()->getComm()->barrier();
867 numRows = SM_Matrix_->getGlobalNumRows();
868 nnz = SM_Matrix_->getGlobalNumEntries();
883 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
884 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
886 if (!Kn_Matrix_.is_null()) {
888 numRows = Kn_Matrix_->getGlobalNumRows();
889 nnz = Kn_Matrix_->getGlobalNumEntries();
891 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
896 std::string outstr = oss.str();
900 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
902 int strLength = outstr.size();
903 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
904 if (comm->getRank() != root)
905 outstr.resize(strLength);
906 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
911 if (!Hierarchy11_.is_null())
912 Hierarchy11_->describe(out, GetVerbLevel());
914 if (!Hierarchy22_.is_null())
915 Hierarchy22_->describe(out, GetVerbLevel());
917 if (!HierarchyGmhd_.is_null())
918 HierarchyGmhd_->describe(out, GetVerbLevel());
922 std::ostringstream oss2;
924 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
925 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;
927 int numProcs = comm->getSize();
935 if (!Kn_Matrix_.is_null())
937 std::vector<char> states(numProcs, 0);
939 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
941 states.push_back(status);
944 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
945 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
946 for (
int j = 0; j < rowWidth; j++)
947 if (proc + j < numProcs)
948 if (states[proc + j] == 0)
950 else if (states[proc + j] == 1)
952 else if (states[proc + j] == 2)
959 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
968 #define MUELU_MAXWELL1_SHORT
969 #endif // ifdef MUELU_MAXWELL1_DEF_HPP
Important warning messages (one line)
static void ZeroDirichletCols(Teuchos::RCP< Matrix > &A, const Teuchos::ArrayRCP< const bool > &dirichletCols, Scalar replaceWith=Teuchos::ScalarTraits< Scalar >::zero())
const Teuchos::RCP< const Map > getDomainMap() const
Returns the Xpetra::Map object associated with the domain of this operator.
Various adapters that will create a MueLu preconditioner that is an Xpetra::Matrix.
virtual std::string getObjectLabel() const
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 dump(const Matrix &A, std::string name) const
dump out matrix
static magnitudeType eps()
static void AddNonSerializableDataToHierarchy(HierarchyManager &HM, Hierarchy &H, const ParameterList &nonSerialList)
Add non-serializable data to Hierarchy.
T & get(const std::string &name, T def_value)
void resetMatrix(Teuchos::RCP< Matrix > SM_Matrix_new, bool ComputePrec=true)
Reset system matrix.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static void Write(const std::string &fileName, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &M)
void GMHDSetupHierarchy(Teuchos::ParameterList &List) const
Sets up hiearchy for GMHD matrices that include generalized Ohms law equations.
void initialize(const Teuchos::RCP< Matrix > &D0_Matrix, const Teuchos::RCP< Matrix > &Kn_Matrix, const Teuchos::RCP< MultiVector > &Nullspace, const Teuchos::RCP< RealValuedMultiVector > &Coords, Teuchos::ParameterList &List)
bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
One-liner description of what is happening.
static void ZeroDirichletRows(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >> &A, const std::vector< LocalOrdinal > &dirichletRows, Scalar replaceWith=Teuchos::ScalarTraits< Scalar >::zero())
Ordinal numParams() const
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > ReplaceNonZerosWithOnes(const RCP< Matrix > &original)
Creates a copy of a matrix where the non-zero entries are replaced by ones.
void SetPreviousLevel(const RCP< Level > &previousLevel)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_HIGH) const
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())
MsgType toVerbLevel(const std::string &verbLevelStr)
Print even more statistics.
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...
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitudeType
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 setParameters(Teuchos::ParameterList &list)
Set parameters.
static void SetDefaultVerbLevel(const VerbLevel defaultVerbLevel)
Set the default (global) verbosity level.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Class that holds all level-specific information.
bool isSublist(const std::string &name) const
Teuchos::RCP< Teuchos::TimeMonitor > getTimer(std::string name, RCP< const Teuchos::Comm< int > > comm=Teuchos::null) const
get a (synced) timer
void deepCopy(const ArrayView< const T > &av)
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.
virtual void setObjectLabel(const std::string &objectLabel)
Class that encapsulates Operator smoothers.
void applyInverseRefMaxwellAdditive(const MultiVector &RHS, MultiVector &X) const
apply RefMaxwell additive 2x2 style cycle
void allocateMemory(int numVectors) const
allocate multivectors for solve
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.
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
Print all timing information.
void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
void applyInverseStandard(const MultiVector &RHS, MultiVector &X) const
apply standard Maxwell1 cycle
const Teuchos::RCP< const Map > getRangeMap() const
Returns the Xpetra::Map object associated with the range of this operator.
void compute(bool reuse=false)
Setup the preconditioner.
bool isType(const std::string &name) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Factory for building coarse matrices.
Exception throws to report errors in the internal logical of the program.
#define TEUCHOS_ASSERT(assertion_test)
virtual size_t getNumVectors() const =0
Teuchos::RCP< Matrix > generate_kn() const
Generates the Kn matrix.
static std::string translate(Teuchos::ParameterList ¶mList, const std::string &defaultVals="")
: Translate ML parameters to MueLu parameter XML string
void dumpCoords(const RealValuedMultiVector &X, std::string name) const
dump out real-valued multivector
virtual void Apply(MultiVector &x, const MultiVector &rhs, bool InitialGuessIsZero=false) const =0
Apply smoother.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
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.
long ExtractNonSerializableData(const Teuchos::ParameterList &inList, Teuchos::ParameterList &serialList, Teuchos::ParameterList &nonSerialList)
Extract non-serializable data from level-specific sublists and move it to a separate parameter list...
static void CopyBetweenHierarchies(Hierarchy &fromHierarchy, Hierarchy &toHierarchy, const std::string fromLabel, const std::string toLabel, const std::string dataType)