60 if (list.isType<std::string>(
"parameterlist: syntax") && list.get<std::string>(
"parameterlist: syntax") ==
"ml") {
61 list.remove(
"parameterlist: syntax");
62 Teuchos::ParameterList newList;
68 newList.sublist(
"maxwell1: 22list").set(
"use kokkos refactor",
false);
70 newList.sublist(
"maxwell1: 11list").set(
"use kokkos refactor",
false);
71 newList.sublist(
"maxwell1: 11list").set(
"tentative: constant column sums",
false);
72 newList.sublist(
"maxwell1: 11list").set(
"tentative: calculate qr",
false);
74 newList.sublist(
"maxwell1: 11list").set(
"aggregation: use ml scaling of drop tol",
true);
75 newList.sublist(
"maxwell1: 22list").set(
"aggregation: use ml scaling of drop tol",
true);
77 newList.sublist(
"maxwell1: 22list").set(
"aggregation: min agg size", 3);
78 newList.sublist(
"maxwell1: 22list").set(
"aggregation: match ML phase1",
true);
79 newList.sublist(
"maxwell1: 22list").set(
"aggregation: match ML phase2a",
true);
80 newList.sublist(
"maxwell1: 22list").set(
"aggregation: match ML phase2b",
true);
82 if (list.isParameter(
"aggregation: damping factor") && list.get<
double>(
"aggregation: damping factor") == 0.0)
83 newList.sublist(
"maxwell1: 11list").set(
"multigrid algorithm",
"unsmoothed reitzinger");
85 newList.sublist(
"maxwell1: 11list").set(
"multigrid algorithm",
"smoothed reitzinger");
86 newList.sublist(
"maxwell1: 11list").set(
"aggregation: type",
"uncoupled");
88 newList.sublist(
"maxwell1: 22list").set(
"multigrid algorithm",
"unsmoothed");
89 newList.sublist(
"maxwell1: 22list").set(
"aggregation: type",
"uncoupled");
91 if (newList.sublist(
"maxwell1: 22list").isType<std::string>(
"verbosity"))
92 newList.set(
"verbosity", newList.sublist(
"maxwell1: 22list").get<std::string>(
"verbosity"));
95 std::vector<std::string> convert = {
"coarse:",
"smoother:",
"smoother: pre",
"smoother: post"};
96 for (
auto it = convert.begin(); it != convert.end(); ++it) {
97 if (newList.sublist(
"maxwell1: 22list").isType<std::string>(*it +
" type")) {
98 newList.sublist(
"maxwell1: 11list").set(*it +
" type", newList.sublist(
"maxwell1: 22list").get<std::string>(*it +
" type"));
99 newList.sublist(
"maxwell1: 22list").remove(*it +
" type");
101 if (newList.sublist(
"maxwell1: 22list").isSublist(*it +
" params")) {
102 newList.sublist(
"maxwell1: 11list").set(*it +
" params", newList.sublist(
"maxwell1: 22list").sublist(*it +
" params"));
103 newList.sublist(
"maxwell1: 22list").remove(*it +
" params");
107 newList.sublist(
"maxwell1: 22list").set(
"smoother: type",
"none");
108 newList.sublist(
"maxwell1: 22list").set(
"coarse: type",
"none");
110 newList.set(
"maxwell1: nodal smoother fix zero diagonal threshold", 1e-10);
111 newList.sublist(
"maxwell1: 22list").set(
"rap: fix zero diagonals",
true);
112 newList.sublist(
"maxwell1: 22list").set(
"rap: fix zero diagonals threshold", 1e-10);
117 std::string mode_string = list.get(
"maxwell1: mode", MasterList::getDefault<std::string>(
"maxwell1: mode"));
118 applyBCsTo22_ = list.get(
"maxwell1: apply BCs to 22",
false);
119 dump_matrices_ = list.get(
"maxwell1: dump matrices", MasterList::getDefault<bool>(
"maxwell1: dump matrices"));
120 check_D0_scaling_ = list.get(
"maxwell1: check and fix D0 scaling", MasterList::getDefault<bool>(
"maxwell1: check and fix D0 scaling"));
123 Teuchos::ParameterList defaultSmootherList;
124 defaultSmootherList.set(
"smoother: type",
"CHEBYSHEV");
125 defaultSmootherList.sublist(
"smoother: params").set(
"chebyshev: degree", 2);
126 defaultSmootherList.sublist(
"smoother: params").set(
"chebyshev: ratio eigenvalue", 7.0);
127 defaultSmootherList.sublist(
"smoother: params").set(
"chebyshev: eigenvalue max iterations", 30);
130 std::string verbosity = list.get(
"verbosity",
"high");
134 if (mode_ != MODE_GMHD_STANDARD) {
135 if (mode_string ==
"standard")
136 mode_ = MODE_STANDARD;
137 else if (mode_string ==
"refmaxwell")
138 mode_ = MODE_REFMAXWELL;
139 else if (mode_string ==
"edge only")
140 mode_ = MODE_EDGE_ONLY;
142 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"Must use mode 'standard', 'refmaxwell', 'edge only', or use the GMHD constructor.");
148 if (list.isSublist(
"maxwell1: 22list"))
149 precList22_ = list.sublist(
"maxwell1: 22list");
150 else if (list.isSublist(
"refmaxwell: 22list"))
151 precList22_ = list.sublist(
"refmaxwell: 22list");
152 if (mode_ == MODE_EDGE_ONLY || mode_ == MODE_STANDARD || mode_ == MODE_GMHD_STANDARD)
153 precList22_.set(
"smoother: pre or post",
"none");
154 else if (!precList22_.isType<std::string>(
"Preconditioner Type") &&
155 !precList22_.isType<std::string>(
"smoother: type") &&
156 !precList22_.isType<std::string>(
"smoother: pre type") &&
157 !precList22_.isType<std::string>(
"smoother: post type")) {
158 precList22_ = defaultSmootherList;
160 precList22_.set(
"verbosity", precList22_.get(
"verbosity", verbosity));
164 if (list.isSublist(
"maxwell1: 11list"))
165 precList11_ = list.sublist(
"maxwell1: 11list");
166 else if (list.isSublist(
"refmaxwell: 11list"))
167 precList11_ = list.sublist(
"refmaxwell: 11list");
169 if (mode_ == MODE_GMHD_STANDARD) {
170 precList11_.set(
"smoother: pre or post",
"none");
171 precList11_.set(
"smoother: type",
"none");
173 if (!precList11_.isType<std::string>(
"Preconditioner Type") &&
174 !precList11_.isType<std::string>(
"smoother: type") &&
175 !precList11_.isType<std::string>(
"smoother: pre type") &&
176 !precList11_.isType<std::string>(
"smoother: post type")) {
177 if (mode_ == MODE_EDGE_ONLY || mode_ == MODE_REFMAXWELL) {
178 precList11_ = defaultSmootherList;
180 if (mode_ == MODE_STANDARD) {
181 precList11_.set(
"smoother: type",
"HIPTMAIR");
182 precList11_.set(
"hiptmair: smoother type 1",
"CHEBYSHEV");
183 precList11_.set(
"hiptmair: smoother type 2",
"CHEBYSHEV");
184 precList11_.sublist(
"hiptmair: smoother list 1") = defaultSmootherList;
185 precList11_.sublist(
"hiptmair: smoother list 2") = defaultSmootherList;
188 precList11_.set(
"verbosity", precList11_.get(
"verbosity", verbosity));
192 !precList11_.isType<std::string>(
"Preconditioner Type") &&
193 !precList11_.isParameter(
"reuse: type"))
194 precList11_.set(
"reuse: type",
"full");
196 !precList22_.isType<std::string>(
"Preconditioner Type") &&
197 !precList22_.isParameter(
"reuse: type"))
198 precList22_.set(
"reuse: type",
"full");
201 useKokkos_ = !Node::is_serial;
202 useKokkos_ = list.get(
"use kokkos refactor", useKokkos_);
204 parameterList_ = list;
240#ifdef HAVE_MUELU_CUDA
241 if (parameterList_.get<
bool>(
"maxwell1: cuda profile setup",
false)) cudaProfilerStart();
244 std::string timerLabel;
246 timerLabel =
"MueLu Maxwell1: compute (reuse)";
248 timerLabel =
"MueLu Maxwell1: compute";
249 RCP<Teuchos::TimeMonitor> tmCompute = getTimer(timerLabel);
253 bool have_generated_Kn =
false;
254 if (Kn_Matrix_.is_null()) {
256 GetOStream(
Runtime0) <<
"Maxwell1::compute(): Kn not provided. Generating." << std::endl;
257 Kn_Matrix_ = generate_kn();
258 have_generated_Kn =
true;
259 }
else if (parameterList_.get<
bool>(
"rap: fix zero diagonals",
true)) {
261 if (parameterList_.isType<
magnitudeType>(
"rap: fix zero diagonals threshold"))
262 threshold = parameterList_.get<
magnitudeType>(
"rap: fix zero diagonals threshold",
263 Teuchos::ScalarTraits<double>::eps());
265 threshold = Teuchos::as<magnitudeType>(parameterList_.get<
double>(
"rap: fix zero diagonals threshold",
266 Teuchos::ScalarTraits<double>::eps()));
267 Scalar replacement = Teuchos::as<Scalar>(parameterList_.get<
double>(
"rap: fix zero diagonals replacement",
268 MasterList::getDefault<double>(
"rap: fix zero diagonals replacement")));
269 Xpetra::MatrixUtils<SC, LO, GO, NO>::CheckRepairMainDiagonal(Kn_Matrix_,
true, GetOStream(
Warnings1), threshold, replacement);
274 Kn_Matrix_->setObjectLabel(
"Maxwell1 (2,2)");
277 if (!Coords_.is_null())
278 precList22_.sublist(
"user data").set(
"Coordinates", Coords_);
279 if (!Material_.is_null())
280 precList22_.sublist(
"user data").set(
"Material", Material_);
284 if (precList22_.isParameter(
"repartition: enable")) {
285 bool repartition = precList22_.get<
bool>(
"repartition: enable");
286 precList11_.set(
"repartition: enable", repartition);
292 precList22_.set(
"repartition: save importer",
true);
294 precList22_.set(
"repartition: rebalance P and R",
true);
297 if (precList22_.isParameter(
"repartition: use subcommunicators")) {
298 precList11_.set(
"repartition: use subcommunicators", precList22_.get<
bool>(
"repartition: use subcommunicators"));
302 if (precList11_.get<
bool>(
"repartition: use subcommunicators") ==
true)
303 precList11_.set(
"repartition: use subcommunicators in place",
true);
306 precList11_.set(
"repartition: use subcommunicators",
true);
307 precList22_.set(
"repartition: use subcommunicators",
true);
311 precList11_.set(
"repartition: use subcommunicators in place",
true);
315 precList11_.remove(
"repartition: enable",
false);
334 magnitudeType rowSumTol = precList11_.get(
"aggregation: row sum drop tol", -1.0);
336 useKokkos_, BCrowsKokkos_, BCcolsKokkos_, BCdomainKokkos_,
337 BCedges_, BCnodes_, BCrows_, BCcols_, BCdomain_,
338 allEdgesBoundary_, allNodesBoundary_);
340 GetOStream(
Statistics2) <<
"MueLu::Maxwell1::compute(): Detected " << BCedges_ <<
" BC rows and " << BCnodes_ <<
" BC columns." << std::endl;
344 if (allEdgesBoundary_) {
347 GetOStream(
Warnings0) <<
"All edges are detected as boundary edges!" << std::endl;
348 mode_ = MODE_EDGE_ONLY;
351 precList22_.set(
"max levels", 1);
354 if (allNodesBoundary_) {
357 GetOStream(
Warnings0) <<
"All nodes are detected as boundary nodes!" << std::endl;
358 mode_ = MODE_EDGE_ONLY;
361 precList22_.set(
"max levels", 1);
371 D0_Matrix_->resumeFill();
372 Scalar replaceWith = Teuchos::ScalarTraits<SC>::zero();
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());
400 RCP<Matrix> Kn_Smoother_0;
401 if (have_generated_Kn) {
402 Kn_Smoother_0 = Kn_Matrix_;
404 Kn_Smoother_0 = generate_kn();
409 Hierarchy11_ = rcp(
new Hierarchy(
"Maxwell1 (1,1)"));
410 RCP<Matrix> OldSmootherMatrix;
411 RCP<Level> OldEdgeLevel;
412 for (
int i = 0; i < Hierarchy22_->GetNumLevels(); i++) {
413 Hierarchy11_->AddNewLevel();
414 RCP<Level> NodeL = Hierarchy22_->GetLevel(i);
415 RCP<Level> EdgeL = Hierarchy11_->GetLevel(i);
416 RCP<Operator> NodeAggOp = NodeL->Get<RCP<Operator> >(
"A");
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;
433 auto NodalP = NodeL->Get<RCP<Matrix> >(
"P");
436 EdgeL->Set(
"Pnodal", NodalP_ones);
439 RCP<const Import> importer;
440 if (NodeL->IsAvailable(
"Importer")) {
441 importer = NodeL->Get<RCP<const Import> >(
"Importer");
442 EdgeL->Set(
"NodeImporter", importer);
447 if (!OldSmootherMatrix.is_null() && !NodalP_ones.is_null()) {
448 EdgeL->Set(
"NodeAggMatrix", NodeAggMatrix);
449 if (!have_generated_Kn) {
459 Teuchos::ParameterList RAPlist;
460 RAPlist.set(
"rap: fix zero diagonals",
false);
464 if (!importer.is_null()) {
465 ParameterList rebAcParams;
466 rebAcParams.set(
"repartition: use subcommunicators",
true);
467 rebAcParams.set(
"repartition: use subcommunicators in place",
true);
469 newAfact->SetParameterList(rebAcParams);
470 RCP<const Map> InPlaceMap = NodeAggMatrix.is_null() ? Teuchos::null : NodeAggMatrix->getRowMap();
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);
479 NewKn = cLevel.
Get<RCP<Matrix> >(
"A", newAfact.get());
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;
489 Scalar replacement = Teuchos::ScalarTraits<Scalar>::one();
490 Xpetra::MatrixUtils<SC, LO, GO, NO>::CheckRepairMainDiagonal(OldSmootherMatrix,
true, GetOStream(
Warnings1), thresh, replacement);
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");
514 SM_Matrix_->setObjectLabel(
"A(1,1)");
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");
526 Teuchos::ParameterList nonSerialList11, processedPrecList11;
529 Hierarchy11_->setlib(SM_Matrix_->getDomainMap()->lib());
530 Hierarchy11_->SetProcRankVerbose(SM_Matrix_->getDomainMap()->getComm()->getRank());
533 if (nonSerialList11.numParams() > 0) {
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) {
550 RCP<Level> EdgeL = Hierarchy11_->GetLevel(1);
551 P11_ = EdgeL->Get<RCP<Matrix> >(
"P");
562#ifdef MUELU_MAXWELL1_DEBUG
563 for (
int i = 0; i < Hierarchy11_->GetNumLevels(); i++) {
564 RCP<Level> L = Hierarchy11_->GetLevel(i);
565 RCP<Matrix> EdgeMatrix = rcp_dynamic_cast<Matrix>(L->Get<RCP<Operator> >(
"A"));
566 RCP<Matrix> NodeMatrix = rcp_dynamic_cast<Matrix>(L->Get<RCP<Operator> >(
"NodeMatrix"));
567 RCP<Matrix> NodeAggMatrix = rcp_dynamic_cast<Matrix>(L->Get<RCP<Operator> >(
"NodeAggMatrix"));
568 RCP<Matrix> D0 = rcp_dynamic_cast<Matrix>(L->Get<RCP<Operator> >(
"D0"));
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;
686 const SC one = Teuchos::ScalarTraits<SC>::one();
687 if (!allEdgesBoundary_ && X.getNumVectors() != residualFine_->getNumVectors())
688 allocateMemory(X.getNumVectors());
690 TEUCHOS_TEST_FOR_EXCEPTION(Hierarchy11_.is_null() || Hierarchy11_->GetNumLevels() == 0,
Exceptions::RuntimeError,
"(1,1) Hiearchy is null.");
693 RCP<Level> Fine = Hierarchy11_->GetLevel(0);
694 if (Fine->IsAvailable(
"PreSmoother")) {
695 RCP<Teuchos::TimeMonitor> tmRes = getTimer(
"MueLu Maxwell1: PreSmoother");
696 RCP<SmootherBase> preSmoo = Fine->Get<RCP<SmootherBase> >(
"PreSmoother");
697 preSmoo->Apply(X, RHS,
true);
702 RCP<Teuchos::TimeMonitor> tmRes = getTimer(
"MueLu Maxwell1: residual calculation");
707 if (!P11_.is_null()) {
708 RCP<Teuchos::TimeMonitor> tmRes = getTimer(
"MueLu Maxwell1: (1,1) correction");
709 P11_->apply(*residualFine_, *residual11c_, Teuchos::TRANS);
710 Hierarchy11_->Iterate(*residual11c_, *update11c_,
true, 1);
714 if (!allNodesBoundary_) {
715 RCP<Teuchos::TimeMonitor> tmRes = getTimer(
"MueLu Maxwell1: (2,2) correction");
716 D0_Matrix_->apply(*residualFine_, *residual22_, Teuchos::TRANS);
717 Hierarchy22_->Iterate(*residual22_, *update22_,
true, 0);
722 RCP<Teuchos::TimeMonitor> tmRes = getTimer(
"MueLu Maxwell1: Orolongation");
724 P11_->apply(*update11c_, X, Teuchos::NO_TRANS, one, one);
725 if (!allNodesBoundary_)
726 D0_Matrix_->apply(*update22_, X, Teuchos::NO_TRANS, one, one);
730 if (Fine->IsAvailable(
"PostSmoother")) {
731 RCP<Teuchos::TimeMonitor> tmRes = getTimer(
"MueLu Maxwell1: PostSmoother");
732 RCP<SmootherBase> postSmoo = Fine->Get<RCP<SmootherBase> >(
"PostSmoother");
733 postSmoo->Apply(X, RHS,
false);
764void scaleD0(Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& D0) {
769 using range_type = Kokkos::RangePolicy<LocalOrdinal, typename Node::execution_space>;
770 using Matrix = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
771 using impl_scalar_type =
typename Matrix::impl_scalar_type;
772 using impl_ATS = KokkosKernels::ArithTraits<impl_scalar_type>;
773 using magnitude_type =
typename impl_ATS::magnitudeType;
774 using MinMax = Kokkos::MinMax<magnitude_type>;
776 typename MinMax::value_type result;
778 auto lclD0 = D0.getLocalMatrixDevice();
779 Kokkos::parallel_reduce(
780 "MueLu::Maxwell1::D0_fixup",
781 range_type(0, lclD0.nnz()),
782 KOKKOS_LAMBDA(
const LocalOrdinal k,
typename MinMax::value_type& res) {
783 auto val = impl_ATS::magnitude(lclD0.values(k));
784 res.min_val = Kokkos::min(res.min_val, val);
785 res.max_val = Kokkos::max(res.max_val, val);
790 TEUCHOS_ASSERT_EQUALITY(result.min_val, result.max_val);
792 if (impl_ATS::magnitude(result.max_val - impl_ATS::one()) > impl_ATS::eps()) {
793 Scalar scaling = impl_ATS::one() / result.max_val;
800 initialize(
const Teuchos::RCP<Matrix>& D0_Matrix,
801 const Teuchos::RCP<Matrix>& Kn_Matrix,
802 const Teuchos::RCP<MultiVector>& Nullspace,
803 const Teuchos::RCP<RealValuedMultiVector>& Coords,
804 const Teuchos::RCP<MultiVector>& Material,
805 Teuchos::ParameterList& List) {
807 TEUCHOS_ASSERT(D0_Matrix != Teuchos::null);
809#ifdef HAVE_MUELU_DEBUG
810 if (!Kn_Matrix.is_null()) {
811 TEUCHOS_ASSERT(Kn_Matrix->getDomainMap()->isSameAs(*D0_Matrix->getDomainMap()));
812 TEUCHOS_ASSERT(Kn_Matrix->getRangeMap()->isSameAs(*D0_Matrix->getDomainMap()));
815 TEUCHOS_ASSERT(D0_Matrix->getRangeMap()->isSameAs(*D0_Matrix->getRowMap()));
818 Hierarchy11_ = Teuchos::null;
819 Hierarchy22_ = Teuchos::null;
820 HierarchyGmhd_ = Teuchos::null;
821 if (mode_ != MODE_GMHD_STANDARD) mode_ = MODE_STANDARD;
825 allEdgesBoundary_ =
false;
826 allNodesBoundary_ =
false;
827 dump_matrices_ =
false;
828 check_D0_scaling_ =
false;
829 enable_reuse_ =
false;
831 applyBCsTo22_ =
false;
836 if (D0_Matrix->getRowMap()->lib() == Xpetra::UseTpetra) {
841 RCP<Matrix> D0copy = MatrixFactory::Build(D0_Matrix->getRowMap(), D0_Matrix->getColMap(), 0);
842 RCP<CrsMatrix> D0copyCrs = toCrsMatrix(D0copy);
843 ArrayRCP<const size_t> D0rowptr_RCP;
844 ArrayRCP<const LO> D0colind_RCP;
845 ArrayRCP<const SC> D0vals_RCP;
846 toCrsMatrix(D0_Matrix)->getAllValues(D0rowptr_RCP, D0colind_RCP, D0vals_RCP);
848 ArrayRCP<size_t> D0copyrowptr_RCP;
849 ArrayRCP<LO> D0copycolind_RCP;
850 ArrayRCP<SC> D0copyvals_RCP;
851 D0copyCrs->allocateAllValues(D0vals_RCP.size(), D0copyrowptr_RCP, D0copycolind_RCP, D0copyvals_RCP);
852 D0copyrowptr_RCP.deepCopy(D0rowptr_RCP());
853 D0copycolind_RCP.deepCopy(D0colind_RCP());
854 D0copyvals_RCP.deepCopy(D0vals_RCP());
855 D0copyCrs->setAllValues(D0copyrowptr_RCP,
858 D0copyCrs->expertStaticFillComplete(D0_Matrix->getDomainMap(), D0_Matrix->getRangeMap(),
859 toCrsMatrix(D0_Matrix)->getCrsGraph()->getImporter(),
860 toCrsMatrix(D0_Matrix)->getCrsGraph()->getExporter());
863 D0_Matrix_ = MatrixFactory::BuildCopy(D0_Matrix);
865 if (check_D0_scaling_)
868 Kn_Matrix_ = Kn_Matrix;
870 Material_ = Material;
871 Nullspace_ = Nullspace;
873 if (!Kn_Matrix_.is_null()) dump(*Kn_Matrix_,
"Kn.m");
874 if (!Nullspace_.is_null()) dump(*Nullspace_,
"nullspace.m");
875 if (!Coords_.is_null()) dumpCoords(*Coords_,
"coords.m");
880 describe(Teuchos::FancyOStream& out,
const Teuchos::EVerbosityLevel )
const {
881 std::ostringstream oss;
883 RCP<const Teuchos::Comm<int> > comm = SM_Matrix_->getDomainMap()->getComm();
887 if (!Kn_Matrix_.is_null())
888 root = comm->getRank();
893 reduceAll(*comm, Teuchos::REDUCE_MAX, root, Teuchos::ptr(&actualRoot));
897 oss <<
"\n--------------------------------------------------------------------------------\n"
898 <<
"--- Maxwell1 Summary ---\n"
899 "--------------------------------------------------------------------------------"
906 SM_Matrix_->getRowMap()->getComm()->barrier();
908 numRows = SM_Matrix_->getGlobalNumRows();
909 nnz = SM_Matrix_->getGlobalNumEntries();
911 Xpetra::global_size_t tt = numRows;
924 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
925 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
927 if (!Kn_Matrix_.is_null()) {
929 numRows = Kn_Matrix_->getGlobalNumRows();
930 nnz = Kn_Matrix_->getGlobalNumEntries();
932 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
937 std::string outstr = oss.str();
940 RCP<const Teuchos::MpiComm<int> > mpiComm = rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm);
941 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
943 int strLength = outstr.size();
944 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
945 if (comm->getRank() != root)
946 outstr.resize(strLength);
947 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
952 if (!Hierarchy11_.is_null())
953 Hierarchy11_->describe(out, GetVerbLevel());
955 if (!Hierarchy22_.is_null())
956 Hierarchy22_->describe(out, GetVerbLevel());
958 if (!HierarchyGmhd_.is_null())
959 HierarchyGmhd_->describe(out, GetVerbLevel());
963 std::ostringstream oss2;
965 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
966 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;
968 int numProcs = comm->getSize();
970 RCP<const Teuchos::MpiComm<int> > tmpic = rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm);
972 RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > rawMpiComm = tmpic->getRawMpiComm();
976 if (!Kn_Matrix_.is_null())
978 std::vector<char> states(numProcs, 0);
980 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
982 states.push_back(status);
985 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
986 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
987 for (
int j = 0; j < rowWidth; j++)
988 if (proc + j < numProcs)
989 if (states[proc + j] == 0)
991 else if (states[proc + j] == 1)
993 else if (states[proc + j] == 2)
1000 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;