46 #ifndef MUELU_REFMAXWELL_DEF_HPP
47 #define MUELU_REFMAXWELL_DEF_HPP
53 #include "Xpetra_Map.hpp"
54 #include "Xpetra_MatrixMatrix.hpp"
55 #include "Xpetra_TripleMatrixMultiply.hpp"
56 #include "Xpetra_CrsMatrixUtils.hpp"
57 #include "Xpetra_MatrixUtils.hpp"
61 #include "MueLu_AmalgamationFactory.hpp"
62 #include "MueLu_RAPFactory.hpp"
63 #include "MueLu_ThresholdAFilterFactory.hpp"
64 #include "MueLu_TransPFactory.hpp"
65 #include "MueLu_SmootherFactory.hpp"
67 #include "MueLu_CoalesceDropFactory.hpp"
68 #include "MueLu_CoarseMapFactory.hpp"
69 #include "MueLu_CoordinatesTransferFactory.hpp"
70 #include "MueLu_UncoupledAggregationFactory.hpp"
71 #include "MueLu_TentativePFactory.hpp"
72 #include "MueLu_AggregationExportFactory.hpp"
73 #include "MueLu_Utilities.hpp"
75 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
76 #include "MueLu_AmalgamationFactory_kokkos.hpp"
77 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
78 #include "MueLu_CoarseMapFactory_kokkos.hpp"
79 #include "MueLu_CoordinatesTransferFactory_kokkos.hpp"
80 #include "MueLu_UncoupledAggregationFactory_kokkos.hpp"
81 #include "MueLu_TentativePFactory_kokkos.hpp"
82 #include "MueLu_Utilities_kokkos.hpp"
83 #include <Kokkos_Core.hpp>
84 #include <KokkosSparse_CrsMatrix.hpp>
87 #include "MueLu_ZoltanInterface.hpp"
88 #include "MueLu_Zoltan2Interface.hpp"
89 #include "MueLu_RepartitionHeuristicFactory.hpp"
90 #include "MueLu_RepartitionFactory.hpp"
91 #include "MueLu_RebalanceAcFactory.hpp"
92 #include "MueLu_RebalanceTransferFactory.hpp"
99 #ifdef HAVE_MUELU_CUDA
100 #include "cuda_profiler_api.h"
106 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
108 return SM_Matrix_->getDomainMap();
112 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
114 return SM_Matrix_->getRangeMap();
118 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
121 if (list.isType<
std::string>(
"parameterlist: syntax") && list.get<
std::string>(
"parameterlist: syntax") ==
"ml") {
123 if(list.isSublist(
"refmaxwell: 11list") && list.sublist(
"refmaxwell: 11list").isSublist(
"edge matrix free: coarse"))
125 if(list.isSublist(
"refmaxwell: 22list"))
130 parameterList_ = list;
131 disable_addon_ = list.get(
"refmaxwell: disable addon",MasterList::getDefault<bool>(
"refmaxwell: disable addon"));
132 mode_ = list.get(
"refmaxwell: mode",MasterList::getDefault<std::string>(
"refmaxwell: mode"));
133 use_as_preconditioner_ = list.get(
"refmaxwell: use as preconditioner",MasterList::getDefault<bool>(
"refmaxwell: use as preconditioner"));
134 dump_matrices_ = list.get(
"refmaxwell: dump matrices",MasterList::getDefault<bool>(
"refmaxwell: dump matrices"));
135 implicitTranspose_ = list.get(
"transpose: use implicit",MasterList::getDefault<bool>(
"transpose: use implicit"));
137 if(list.isSublist(
"refmaxwell: 11list"))
138 precList11_ = list.sublist(
"refmaxwell: 11list");
139 if(!precList11_.isType<
std::string>(
"smoother: type") && !precList11_.isType<
std::string>(
"smoother: pre type") && !precList11_.isType<
std::string>(
"smoother: post type")) {
140 precList11_.set(
"smoother: type",
"CHEBYSHEV");
141 precList11_.sublist(
"smoother: params").set(
"chebyshev: degree",2);
144 if(list.isSublist(
"refmaxwell: 22list"))
145 precList22_ = list.sublist(
"refmaxwell: 22list");
146 if(!precList22_.isType<
std::string>(
"smoother: type") && !precList22_.isType<
std::string>(
"smoother: pre type") && !precList22_.isType<
std::string>(
"smoother: post type")) {
147 precList22_.set(
"smoother: type",
"CHEBYSHEV");
148 precList22_.sublist(
"smoother: params").set(
"chebyshev: degree",2);
152 list.set(
"smoother: type",
"CHEBYSHEV");
153 list.sublist(
"smoother: params").set(
"chebyshev: degree",2);
156 if(list.isSublist(
"smoother: params")) {
157 smootherList_ = list.sublist(
"smoother: params");
160 #if !defined(HAVE_MUELU_KOKKOS_REFACTOR)
162 #elif defined(HAVE_MUELU_KOKKOS_REFACTOR_USE_BY_DEFAULT)
163 useKokkos_ = list.get(
"use kokkos refactor",
true);
165 useKokkos_ = list.get(
"use kokkos refactor",
false);
171 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
175 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType realType;
177 #ifdef HAVE_MUELU_CUDA
178 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStart();
183 timerLabel =
"MueLu RefMaxwell: compute (reuse)";
185 timerLabel =
"MueLu RefMaxwell: compute";
186 Teuchos::TimeMonitor tmCompute(*Teuchos::TimeMonitor::getNewTimer(timerLabel));
188 std::map<std::string, MsgType> verbMap;
189 verbMap[
"none"] =
None;
190 verbMap[
"low"] =
Low;
191 verbMap[
"medium"] =
Medium;
192 verbMap[
"high"] =
High;
194 verbMap[
"test"] =
Test;
200 "Invalid verbosity level: \"" << verbosityLevel <<
"\"");
204 bool defaultFilter =
false;
209 if (parameterList_.get<
bool>(
"refmaxwell: filter D0",
true) && D0_Matrix_->getNodeMaxNumRowEntries()>2) {
213 fineLevel.
Set(
"A",D0_Matrix_);
214 fineLevel.
setlib(D0_Matrix_->getDomainMap()->lib());
217 fineLevel.
Request(
"A",ThreshFact.get());
218 ThreshFact->Build(fineLevel);
219 D0_Matrix_ = fineLevel.
Get< RCP<Matrix> >(
"A",ThreshFact.get());
222 defaultFilter =
true;
225 if (parameterList_.get<
bool>(
"refmaxwell: filter SM", defaultFilter)) {
226 RCP<Vector> diag = VectorFactory::Build(SM_Matrix_->getRowMap());
228 SM_Matrix_->getLocalDiagCopy(*diag);
234 fineLevel.
Set(
"A",SM_Matrix_);
235 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
237 fineLevel.
Request(
"A",ThreshFact.get());
238 ThreshFact->Build(fineLevel);
239 SM_Matrix_ = fineLevel.
Get< RCP<Matrix> >(
"A",ThreshFact.get());
242 if (parameterList_.get<
bool>(
"refmaxwell: filter M1", defaultFilter)) {
243 RCP<Vector> diag = VectorFactory::Build(M1_Matrix_->getRowMap());
245 M1_Matrix_->getLocalDiagCopy(*diag);
251 fineLevel.
Set(
"A",M1_Matrix_);
252 fineLevel.
setlib(M1_Matrix_->getDomainMap()->lib());
254 fineLevel.
Request(
"A",ThreshFact.get());
255 ThreshFact->Build(fineLevel);
256 M1_Matrix_ = fineLevel.
Get< RCP<Matrix> >(
"A",ThreshFact.get());
264 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
269 int BCrowcountLocal = 0;
270 for (
size_t i = 0; i<BCrowsKokkos_.size(); i++)
271 if (BCrowsKokkos_(i))
272 BCrowcountLocal += 1;
274 MueLu_sumAll(SM_Matrix_->getRowMap()->getComm(), BCrowcountLocal, BCrowcount_);
276 BCrowcount_ = BCrowcountLocal;
278 int BCcolcountLocal = 0;
279 for (
size_t i = 0; i<BCcolsKokkos_.size(); i++)
280 if (BCcolsKokkos_(i))
281 BCcolcountLocal += 1;
283 MueLu_sumAll(SM_Matrix_->getRowMap()->getComm(), BCcolcountLocal, BCcolcount_);
285 BCcolcount_ = BCcolcountLocal;
288 GetOStream(
Statistics2) <<
"MueLu::RefMaxwell::compute(): Detected " << BCrowcount_ <<
" BC rows and " << BCcolcount_ <<
" BC columns." << std::endl;
295 int BCrowcountLocal = 0;
296 for (
auto it = BCrows_.begin(); it != BCrows_.end(); ++it)
298 BCrowcountLocal += 1;
300 MueLu_sumAll(SM_Matrix_->getRowMap()->getComm(), BCrowcountLocal, BCrowcount_);
302 BCrowcount_ = BCrowcountLocal;
304 int BCcolcountLocal = 0;
305 for (
auto it = BCcols_.begin(); it != BCcols_.end(); ++it)
307 BCcolcountLocal += 1;
309 MueLu_sumAll(SM_Matrix_->getRowMap()->getComm(), BCcolcountLocal, BCcolcount_);
311 BCcolcount_ = BCcolcountLocal;
314 GetOStream(
Statistics2) <<
"MueLu::RefMaxwell::compute(): Detected " << BCrowcount_ <<
" BC rows and " << BCcolcount_ <<
" BC columns." << std::endl;
320 if(Nullspace_ !=
null) {
322 TEUCHOS_ASSERT(Nullspace_->getMap()->isCompatible(*(SM_Matrix_->getRowMap())));
324 else if(Nullspace_ ==
null && Coords_ !=
null) {
326 typedef typename RealValuedMultiVector::scalar_type realScalarType;
327 typedef typename Teuchos::ScalarTraits<realScalarType>::magnitudeType realMagnitudeType;
328 Array<realMagnitudeType> norms(Coords_->getNumVectors());
329 Coords_->norm2(norms);
330 for (
size_t i=0;i<Coords_->getNumVectors();i++)
331 norms[i] = ((realMagnitudeType)1.0)/norms[i];
332 Nullspace_ = MultiVectorFactory::Build(SM_Matrix_->getRowMap(),Coords_->getNumVectors());
335 Array<Scalar> normsSC(Coords_->getNumVectors());
336 for (
size_t i=0;i<Coords_->getNumVectors();i++)
337 normsSC[i] = (SC) norms[i];
338 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
339 RCP<MultiVector> CoordsSC;
341 CoordsSC = Utilities_kokkos::RealValuedToScalarMultiVector(Coords_);
347 D0_Matrix_->apply(*CoordsSC,*Nullspace_);
348 Nullspace_->scale(normsSC());
351 GetOStream(
Errors) <<
"MueLu::RefMaxwell::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
356 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
367 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"D0_clean.mat"), *D0_Matrix_);
372 Level fineLevel, coarseLevel;
378 fineLevel.
Set(
"A",Ms_Matrix_);
379 coarseLevel.
Set(
"P",D0_Matrix_);
380 coarseLevel.
setlib(M1_Matrix_->getDomainMap()->lib());
381 fineLevel.
setlib(M1_Matrix_->getDomainMap()->lib());
382 coarseLevel.setObjectLabel(
"RefMaxwell (1,1) A_nodal");
383 fineLevel.setObjectLabel(
"RefMaxwell (1,1) A_nodal");
385 RCP<RAPFactory> rapFact = rcp(
new RAPFactory());
386 ParameterList rapList = *(rapFact->GetValidParameterList());
387 rapList.set(
"transpose: use implicit", parameterList_.get<
bool>(
"transpose: use implicit",
false));
388 rapList.set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
389 rapList.set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
390 rapFact->SetParameterList(rapList);
392 RCP<TransPFactory> transPFactory;
393 if (!parameterList_.get<
bool>(
"transpose: use implicit",
false)) {
395 rapFact->SetFactory(
"R", transPFactory);
398 coarseLevel.
Request(
"A", rapFact.get());
400 A_nodal_Matrix_ = coarseLevel.
Get< RCP<Matrix> >(
"A", rapFact.get());
403 GetOStream(
Runtime0) <<
"RefMaxwell::compute(): building special prolongator" << std::endl;
406 if (!implicitTranspose_) {
407 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
409 R11_ = Utilities_kokkos::Transpose(*P11_);
418 bool doRebalancing =
false;
420 doRebalancing = parameterList_.get<
bool>(
"refmaxwell: subsolves on subcommunicators", MasterList::getDefault<bool>(
"refmaxwell: subsolves on subcommunicators"));
421 int numProcsAH, numProcsA22;
428 int numProcs = SM_Matrix_->getDomainMap()->getComm()->getSize();
429 if (doRebalancing && numProcs > 1) {
430 GlobalOrdinal globalNumRowsAH = AH_->getRowMap()->getGlobalNumElements();
431 GlobalOrdinal globalNumRowsA22 = D0_Matrix_->getDomainMap()->getGlobalNumElements();
432 double ratio = parameterList_.get<
double>(
"refmaxwell: ratio AH / A22 subcommunicators", MasterList::getDefault<double>(
"refmaxwell: ratio AH / A22 subcommunicators"));
433 numProcsAH = numProcs * globalNumRowsAH / (globalNumRowsAH + ratio*globalNumRowsA22);
434 numProcsA22 = numProcs * ratio * globalNumRowsA22 / (globalNumRowsAH + ratio*globalNumRowsA22);
435 if (numProcsAH + numProcsA22 < numProcs)
437 if (numProcsAH + numProcsA22 < numProcs)
439 numProcsAH = std::max(numProcsAH, 1);
440 numProcsA22 = std::max(numProcsA22, 1);
442 doRebalancing =
false;
446 Teuchos::TimeMonitor tm(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: Rebalance AH"));
448 Level fineLevel, coarseLevel;
454 coarseLevel.
Set(
"A",AH_);
455 coarseLevel.
Set(
"P",P11_);
456 if (!implicitTranspose_)
457 coarseLevel.
Set(
"R",R11_);
458 coarseLevel.
Set(
"Coordinates",CoordsH_);
459 coarseLevel.
Set(
"number of partitions", numProcsAH);
460 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
462 coarseLevel.
setlib(AH_->getDomainMap()->lib());
463 fineLevel.
setlib(AH_->getDomainMap()->lib());
464 coarseLevel.setObjectLabel(
"RefMaxwell (1,1)");
465 fineLevel.setObjectLabel(
"RefMaxwell (1,1)");
476 RCP<Factory> partitioner;
477 if (partName ==
"zoltan") {
478 #ifdef HAVE_MUELU_ZOLTAN
485 }
else if (partName ==
"zoltan2") {
486 #ifdef HAVE_MUELU_ZOLTAN2
488 ParameterList partParams;
489 RCP<const ParameterList> partpartParams = rcp(
new ParameterList(precList11_.sublist(
"repartition: params",
false)));
490 partParams.set(
"ParameterList", partpartParams);
491 partitioner->SetParameterList(partParams);
499 ParameterList repartParams;
500 repartParams.set(
"repartition: print partition distribution", precList11_.get<
bool>(
"repartition: print partition distribution",
false));
501 repartParams.set(
"repartition: remap parts", precList11_.get<
bool>(
"repartition: remap parts",
true));
502 repartFactory->SetParameterList(repartParams);
504 repartFactory->SetFactory(
"Partition", partitioner);
507 ParameterList newPparams;
508 newPparams.set(
"type",
"Interpolation");
509 newPparams.set(
"repartition: rebalance P and R", precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
510 newPparams.set(
"repartition: use subcommunicators",
true);
511 newPparams.set(
"repartition: rebalance Nullspace",
false);
513 newP->SetParameterList(newPparams);
514 newP->SetFactory(
"Importer", repartFactory);
517 RCP<RebalanceTransferFactory> newR;
518 if (!implicitTranspose_) {
520 ParameterList newRparams;
521 newRparams.set(
"type",
"Restriction");
522 newRparams.set(
"repartition: rebalance P and R", precList11_.get<
bool>(
"repartition: rebalance P and R",
false));
523 newRparams.set(
"repartition: use subcommunicators",
true);
524 newR->SetParameterList(newRparams);
525 newR->SetFactory(
"Importer", repartFactory);
529 ParameterList rebAcParams;
530 rebAcParams.set(
"repartition: use subcommunicators",
true);
531 newA->SetParameterList(rebAcParams);
532 newA->SetFactory(
"Importer", repartFactory);
534 coarseLevel.
Request(
"R", newR.get());
535 coarseLevel.
Request(
"P", newP.get());
536 coarseLevel.
Request(
"Importer", repartFactory.get());
537 coarseLevel.
Request(
"A", newA.get());
538 coarseLevel.
Request(
"Coordinates", newP.get());
539 repartFactory->Build(coarseLevel);
541 if (!precList11_.get<
bool>(
"repartition: rebalance P and R",
false))
542 ImporterH_ = coarseLevel.
Get< RCP<const Import> >(
"Importer", repartFactory.get());
543 P11_ = coarseLevel.
Get< RCP<Matrix> >(
"P", newP.get());
544 if (!implicitTranspose_)
545 R11_ = coarseLevel.
Get< RCP<Matrix> >(
"R", newR.get());
546 AH_ = coarseLevel.
Get< RCP<Matrix> >(
"A", newA.get());
547 CoordsH_ = coarseLevel.
Get< RCP<RealValuedMultiVector> >(
"Coordinates", newP.get());
550 ParameterList XpetraList;
551 XpetraList.set(
"Restrict Communicator",
true);
552 XpetraList.set(
"Timer Label",
"MueLu RefMaxwell::RebalanceAH");
553 RCP<const Map> targetMap = ImporterH_->getTargetMap();
554 AH_ = MatrixFactory::Build(AH_, *ImporterH_, *ImporterH_, targetMap, targetMap, rcp(&XpetraList,
false));
557 AH_->setObjectLabel(
"RefMaxwell (1,1)");
561 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
565 if (useKokkos_ && precList11_.isParameter(
"aggregation: drop tol") && precList11_.get<
double>(
"aggregation: drop tol") != 0.0) {
566 GetOStream(
Warnings0) <<
"RefMaxwell::compute(): Setting \"aggregation: drop tol\". to 0.0, since CoalesceDropFactory_kokkos does not "
567 <<
"support BlockSize > 1 and drop tol != 0.0" << std::endl;
568 precList11_.set(
"aggregation: drop tol", 0.0);
571 if (!AH_.is_null()) {
572 int oldRank = SetProcRankVerbose(AH_->getDomainMap()->getComm()->getRank());
574 ParameterList& userParamList = precList11_.sublist(
"user data");
575 userParamList.set<RCP<RealValuedMultiVector> >(
"Coordinates", CoordsH_);
578 RCP<MueLu::Level> level0 = HierarchyH_->GetLevel(0);
579 level0->Set(
"A", AH_);
580 HierarchyH_->SetupRe();
582 SetProcRankVerbose(oldRank);
589 GetOStream(
Runtime0) <<
"RefMaxwell::compute(): nuking BC edges of D0" << std::endl;
591 D0_Matrix_->resumeFill();
593 Scalar replaceWith = Teuchos::ScalarTraits<SC>::zero();
594 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
606 D0_Matrix_->fillComplete(D0_Matrix_->getDomainMap(),D0_Matrix_->getRangeMap());
610 GetOStream(
Runtime0) <<
"RefMaxwell::compute(): building MG for (2,2)-block" << std::endl;
613 Teuchos::TimeMonitor tm(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: Build A22"));
615 Level fineLevel, coarseLevel;
621 fineLevel.
Set(
"A",SM_Matrix_);
622 coarseLevel.
Set(
"P",D0_Matrix_);
623 coarseLevel.
Set(
"Coordinates",Coords_);
625 coarseLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
626 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
627 coarseLevel.setObjectLabel(
"RefMaxwell (2,2)");
628 fineLevel.setObjectLabel(
"RefMaxwell (2,2)");
630 RCP<RAPFactory> rapFact = rcp(
new RAPFactory());
631 ParameterList rapList = *(rapFact->GetValidParameterList());
632 rapList.set(
"transpose: use implicit", implicitTranspose_);
633 rapList.set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
634 rapList.set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
635 rapFact->SetParameterList(rapList);
637 if (!A22_AP_reuse_data_.is_null()) {
638 coarseLevel.
AddKeepFlag(
"AP reuse data", rapFact.get());
639 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList> >(
"AP reuse data", A22_AP_reuse_data_, rapFact.get());
641 if (!A22_RAP_reuse_data_.is_null()) {
642 coarseLevel.
AddKeepFlag(
"RAP reuse data", rapFact.get());
643 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList> >(
"RAP reuse data", A22_RAP_reuse_data_, rapFact.get());
646 RCP<TransPFactory> transPFactory;
647 if (!implicitTranspose_) {
649 rapFact->SetFactory(
"R", transPFactory);
657 coarseLevel.
Set(
"number of partitions", numProcsA22);
658 coarseLevel.
Set(
"repartition: heuristic target rows per process", 1000);
670 RCP<Factory> partitioner;
671 if (partName ==
"zoltan") {
672 #ifdef HAVE_MUELU_ZOLTAN
674 partitioner->SetFactory(
"A", rapFact);
680 }
else if (partName ==
"zoltan2") {
681 #ifdef HAVE_MUELU_ZOLTAN2
683 ParameterList partParams;
684 RCP<const ParameterList> partpartParams = rcp(
new ParameterList(precList22_.sublist(
"repartition: params",
false)));
685 partParams.set(
"ParameterList", partpartParams);
686 partitioner->SetParameterList(partParams);
687 partitioner->SetFactory(
"A", rapFact);
695 ParameterList repartParams;
696 repartParams.set(
"repartition: print partition distribution", precList22_.get<
bool>(
"repartition: print partition distribution",
false));
697 repartParams.set(
"repartition: remap parts", precList22_.get<
bool>(
"repartition: remap parts",
true));
698 repartParams.set(
"repartition: remap accept partition", AH_.is_null());
699 repartFactory->SetParameterList(repartParams);
700 repartFactory->SetFactory(
"A", rapFact);
702 repartFactory->SetFactory(
"Partition", partitioner);
705 ParameterList newPparams;
706 newPparams.set(
"type",
"Interpolation");
707 newPparams.set(
"repartition: rebalance P and R", precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
708 newPparams.set(
"repartition: use subcommunicators",
true);
709 newPparams.set(
"repartition: rebalance Nullspace",
false);
711 newP->SetParameterList(newPparams);
712 newP->SetFactory(
"Importer", repartFactory);
714 RCP<RebalanceTransferFactory> newR;
715 if (!implicitTranspose_) {
718 ParameterList newRparams;
719 newRparams.set(
"type",
"Restriction");
720 newRparams.set(
"repartition: rebalance P and R", precList22_.get<
bool>(
"repartition: rebalance P and R",
false));
721 newRparams.set(
"repartition: use subcommunicators",
true);
722 newR->SetParameterList(newRparams);
723 newR->SetFactory(
"Importer", repartFactory);
724 newR->SetFactory(
"R", transPFactory);
728 ParameterList rebAcParams;
729 rebAcParams.set(
"repartition: use subcommunicators",
true);
730 newA->SetParameterList(rebAcParams);
731 newA->SetFactory(
"A", rapFact);
732 newA->SetFactory(
"Importer", repartFactory);
734 if (!implicitTranspose_)
735 coarseLevel.
Request(
"R", newR.get());
736 coarseLevel.
Request(
"P", newP.get());
737 coarseLevel.
Request(
"Importer", repartFactory.get());
738 coarseLevel.
Request(
"A", newA.get());
739 if (precList22_.isType<
std::string>(
"reuse: type") && precList22_.get<
std::string>(
"reuse: type") !=
"none") {
740 if (!parameterList_.get<
bool>(
"rap: triple product",
false))
741 coarseLevel.
Request(
"AP reuse data", rapFact.get());
742 coarseLevel.
Request(
"RAP reuse data", rapFact.get());
744 coarseLevel.
Request(
"Coordinates", newP.get());
745 rapFact->Build(fineLevel,coarseLevel);
746 repartFactory->Build(coarseLevel);
748 if (!precList22_.get<
bool>(
"repartition: rebalance P and R",
false))
749 Importer22_ = coarseLevel.
Get< RCP<const Import> >(
"Importer", repartFactory.get());
750 D0_Matrix_ = coarseLevel.
Get< RCP<Matrix> >(
"P", newP.get());
751 if (!implicitTranspose_)
752 D0_T_Matrix_ = coarseLevel.
Get< RCP<Matrix> >(
"R", newR.get());
753 A22_ = coarseLevel.
Get< RCP<Matrix> >(
"A", newA.get());
754 if (precList22_.isType<
std::string>(
"reuse: type") && precList22_.get<
std::string>(
"reuse: type") !=
"none") {
755 if (!parameterList_.get<
bool>(
"rap: triple product",
false))
756 A22_AP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"AP reuse data", rapFact.get());
757 A22_RAP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"RAP reuse data", rapFact.get());
759 Coords_ = coarseLevel.
Get< RCP<RealValuedMultiVector> >(
"Coordinates", newP.get());
761 coarseLevel.
Request(
"A", rapFact.get());
762 if (precList22_.isType<
std::string>(
"reuse: type") && precList22_.get<
std::string>(
"reuse: type") !=
"none") {
763 coarseLevel.
Request(
"AP reuse data", rapFact.get());
764 coarseLevel.
Request(
"RAP reuse data", rapFact.get());
766 if (!implicitTranspose_)
767 coarseLevel.
Request(
"R", transPFactory.get());
769 A22_ = coarseLevel.
Get< RCP<Matrix> >(
"A", rapFact.get());
770 if (!implicitTranspose_)
771 D0_T_Matrix_ = coarseLevel.
Get< RCP<Matrix> >(
"R", transPFactory.get());
772 if (precList22_.isType<
std::string>(
"reuse: type") && precList22_.get<
std::string>(
"reuse: type") !=
"none") {
773 if (!parameterList_.get<
bool>(
"rap: triple product",
false))
774 A22_AP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"AP reuse data", rapFact.get());
775 A22_RAP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"RAP reuse data", rapFact.get());
778 ParameterList XpetraList;
779 XpetraList.set(
"Restrict Communicator",
true);
780 XpetraList.set(
"Timer Label",
"MueLu RefMaxwell::RebalanceA22");
781 RCP<const Map> targetMap = Importer22_->getTargetMap();
782 A22_ = MatrixFactory::Build(A22_, *Importer22_, *Importer22_, targetMap, targetMap, rcp(&XpetraList,
false));
787 coarseLevel.
Request(
"A", rapFact.get());
788 if (precList22_.isType<
std::string>(
"reuse: type") && precList22_.get<
std::string>(
"reuse: type") !=
"none") {
789 coarseLevel.
Request(
"AP reuse data", rapFact.get());
790 coarseLevel.
Request(
"RAP reuse data", rapFact.get());
792 coarseLevel.
Request(
"R", transPFactory.get());
794 A22_ = coarseLevel.
Get< RCP<Matrix> >(
"A", rapFact.get());
795 if (!implicitTranspose_)
796 D0_T_Matrix_ = coarseLevel.
Get< RCP<Matrix> >(
"R", transPFactory.get());
797 if (precList22_.isType<
std::string>(
"reuse: type") && precList22_.get<
std::string>(
"reuse: type") !=
"none") {
798 if (!parameterList_.get<
bool>(
"rap: triple product",
false))
799 A22_AP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"AP reuse data", rapFact.get());
800 A22_RAP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"RAP reuse data", rapFact.get());
805 if (!A22_.is_null()) {
806 A22_->setObjectLabel(
"RefMaxwell (2,2)");
807 int oldRank = SetProcRankVerbose(A22_->getDomainMap()->getComm()->getRank());
809 ParameterList& userParamList = precList22_.sublist(
"user data");
810 userParamList.set<RCP<RealValuedMultiVector> >(
"Coordinates", Coords_);
814 if (precList22_.isParameter(
"coarse: type")) {
815 coarseType = precList22_.get<
std::string>(
"coarse: type");
817 std::transform(coarseType.begin(), coarseType.end(), coarseType.begin(), ::
tolower);
818 std::transform(coarseType.begin(), ++coarseType.begin(), coarseType.begin(), ::toupper);
820 if (BCrowcount_ == 0 &&
822 coarseType ==
"Klu" ||
823 coarseType ==
"Klu2") &&
824 (!precList22_.isSublist(
"coarse: params") ||
825 !precList22_.sublist(
"coarse: params").isParameter(
"fix nullspace")))
826 precList22_.sublist(
"coarse: params").set(
"fix nullspace",
true);
829 RCP<MueLu::Level> level0 = Hierarchy22_->GetLevel(0);
830 level0->Set(
"A", A22_);
831 Hierarchy22_->SetupRe();
833 SetProcRankVerbose(oldRank);
840 if (parameterList_.isType<
std::string>(
"smoother: type") &&
841 parameterList_.get<
std::string>(
"smoother: type") ==
"hiptmair" &&
842 SM_Matrix_->getDomainMap()->lib() == Xpetra::UseTpetra &&
843 A22_->getDomainMap()->lib() == Xpetra::UseTpetra &&
844 D0_Matrix_->getDomainMap()->lib() == Xpetra::UseTpetra) {
845 #if defined(HAVE_MUELU_IFPACK2) && (!defined(HAVE_MUELU_EPETRA) || (defined(HAVE_MUELU_INST_DOUBLE_INT_INT)))
846 ParameterList hiptmairPreList, hiptmairPostList, smootherPreList, smootherPostList;
848 if (smootherList_.isSublist(
"smoother: pre params"))
849 smootherPreList = smootherList_.sublist(
"smoother: pre params");
850 else if (smootherList_.isSublist(
"smoother: params"))
851 smootherPreList = smootherList_.sublist(
"smoother: params");
852 hiptmairPreList.set(
"hiptmair: smoother type 1",
853 smootherPreList.get<
std::string>(
"hiptmair: smoother type 1",
"CHEBYSHEV"));
854 hiptmairPreList.set(
"hiptmair: smoother type 2",
855 smootherPreList.get<
std::string>(
"hiptmair: smoother type 2",
"CHEBYSHEV"));
856 if(smootherPreList.isSublist(
"hiptmair: smoother list 1"))
857 hiptmairPreList.set(
"hiptmair: smoother list 1", smootherPreList.sublist(
"hiptmair: smoother list 1"));
858 if(smootherPreList.isSublist(
"hiptmair: smoother list 2"))
859 hiptmairPreList.set(
"hiptmair: smoother list 2", smootherPreList.sublist(
"hiptmair: smoother list 2"));
860 hiptmairPreList.set(
"hiptmair: pre or post",
861 smootherPreList.get<
std::string>(
"hiptmair: pre or post",
"pre"));
862 hiptmairPreList.set(
"hiptmair: zero starting solution",
863 smootherPreList.get<
bool>(
"hiptmair: zero starting solution",
true));
865 if (smootherList_.isSublist(
"smoother: post params"))
866 smootherPostList = smootherList_.sublist(
"smoother: post params");
867 else if (smootherList_.isSublist(
"smoother: params"))
868 smootherPostList = smootherList_.sublist(
"smoother: params");
869 hiptmairPostList.set(
"hiptmair: smoother type 1",
870 smootherPostList.get<
std::string>(
"hiptmair: smoother type 1",
"CHEBYSHEV"));
871 hiptmairPostList.set(
"hiptmair: smoother type 2",
872 smootherPostList.get<
std::string>(
"hiptmair: smoother type 2",
"CHEBYSHEV"));
873 if(smootherPostList.isSublist(
"hiptmair: smoother list 1"))
874 hiptmairPostList.set(
"hiptmair: smoother list 1", smootherPostList.sublist(
"hiptmair: smoother list 1"));
875 if(smootherPostList.isSublist(
"hiptmair: smoother list 2"))
876 hiptmairPostList.set(
"hiptmair: smoother list 2", smootherPostList.sublist(
"hiptmair: smoother list 2"));
877 hiptmairPostList.set(
"hiptmair: pre or post",
878 smootherPostList.get<
std::string>(
"hiptmair: pre or post",
"post"));
879 hiptmairPostList.set(
"hiptmair: zero starting solution",
880 smootherPostList.get<
bool>(
"hiptmair: zero starting solution",
false));
882 typedef Tpetra::RowMatrix<SC, LO, GO, NO> TROW;
888 hiptmairPreSmoother_ -> setParameters(hiptmairPreList);
889 hiptmairPreSmoother_ -> initialize();
890 hiptmairPreSmoother_ -> compute();
892 hiptmairPostSmoother_ -> setParameters(hiptmairPostList);
893 hiptmairPostSmoother_ -> initialize();
894 hiptmairPostSmoother_ -> compute();
895 useHiptmairSmoothing_ =
true;
897 throw(Xpetra::Exceptions::RuntimeError(
"MueLu must be compiled with Ifpack2 for Hiptmair smoothing."));
898 #endif // defined(HAVE_MUELU_IFPACK2) && (!defined(HAVE_MUELU_EPETRA) || defined(HAVE_MUELU_INST_DOUBLE_INT_INT))
900 if (parameterList_.isType<
std::string>(
"smoother: pre type") && parameterList_.isType<
std::string>(
"smoother: post type")) {
904 ParameterList preSmootherList, postSmootherList;
905 if (parameterList_.isSublist(
"smoother: pre params"))
906 preSmootherList = parameterList_.sublist(
"smoother: pre params");
907 if (parameterList_.isSublist(
"smoother: post params"))
908 postSmootherList = parameterList_.sublist(
"smoother: post params");
911 RCP<MueLu::FactoryManagerBase> factoryHandler = rcp(
new FactoryManager());
914 level.setObjectLabel(
"RefMaxwell (1,1)");
915 level.
Set(
"A",SM_Matrix_);
916 level.
setlib(SM_Matrix_->getDomainMap()->lib());
918 RCP<SmootherPrototype> preSmootherPrototype = rcp(
new TrilinosSmoother(preSmootherType, preSmootherList));
919 RCP<SmootherFactory> preSmootherFact = rcp(
new SmootherFactory(preSmootherPrototype));
921 RCP<SmootherPrototype> postSmootherPrototype = rcp(
new TrilinosSmoother(postSmootherType, postSmootherList));
922 RCP<SmootherFactory> postSmootherFact = rcp(
new SmootherFactory(postSmootherPrototype));
924 level.
Request(
"PreSmoother",preSmootherFact.get());
925 preSmootherFact->Build(level);
926 PreSmoother_ = level.
Get<RCP<SmootherBase> >(
"PreSmoother",preSmootherFact.get());
928 level.
Request(
"PostSmoother",postSmootherFact.get());
929 postSmootherFact->Build(level);
930 PostSmoother_ = level.
Get<RCP<SmootherBase> >(
"PostSmoother",postSmootherFact.get());
934 RCP<MueLu::FactoryManagerBase> factoryHandler = rcp(
new FactoryManager());
935 level.SetFactoryManager(factoryHandler);
937 level.setObjectLabel(
"RefMaxwell (1,1)");
938 level.Set(
"A",SM_Matrix_);
939 level.setlib(SM_Matrix_->getDomainMap()->lib());
940 RCP<SmootherPrototype> smootherPrototype = rcp(
new TrilinosSmoother(smootherType, smootherList_));
941 RCP<SmootherFactory> SmootherFact = rcp(
new SmootherFactory(smootherPrototype));
942 level.Request(
"PreSmoother",SmootherFact.get());
943 SmootherFact->Build(level);
944 PreSmoother_ = level.Get<RCP<SmootherBase> >(
"PreSmoother",SmootherFact.get());
945 PostSmoother_ = PreSmoother_;
947 useHiptmairSmoothing_ =
false;
952 P11res_ = MultiVectorFactory::Build(P11_->getDomainMap(), 1);
953 if (!ImporterH_.is_null()) {
954 P11resTmp_ = MultiVectorFactory::Build(ImporterH_->getTargetMap(), 1);
955 P11xTmp_ = MultiVectorFactory::Build(ImporterH_->getSourceMap(), 1);
956 P11x_ = MultiVectorFactory::Build(ImporterH_->getTargetMap(), 1);
958 P11x_ = MultiVectorFactory::Build(P11_->getDomainMap(), 1);
959 D0res_ = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(), 1);
960 if (!Importer22_.is_null()) {
961 D0resTmp_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), 1);
962 D0xTmp_ = MultiVectorFactory::Build(Importer22_->getSourceMap(), 1);
963 D0x_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), 1);
965 D0x_ = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(), 1);
966 residual_ = MultiVectorFactory::Build(SM_Matrix_->getDomainMap(), 1);
968 if (!ImporterH_.is_null() && parameterList_.isSublist(
"refmaxwell: ImporterH params")){
969 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: ImporterH params"));
970 ImporterH_->setDistributorParameters(importerParams);
972 if (!Importer22_.is_null() && parameterList_.isSublist(
"refmaxwell: Importer22 params")){
973 RCP<ParameterList> importerParams = rcpFromRef(parameterList_.sublist(
"refmaxwell: Importer22 params"));
974 Importer22_->setDistributorParameters(importerParams);
977 #ifdef HAVE_MUELU_CUDA
978 if (parameterList_.get<
bool>(
"refmaxwell: cuda profile setup",
false)) cudaProfilerStop();
983 if (dump_matrices_) {
984 GetOStream(
Runtime0) <<
"RefMaxwell::compute(): dumping data" << std::endl;
985 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"SM.mat"), *SM_Matrix_);
986 if(!Ms_Matrix_.is_null()) Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"Ms.mat"), *Ms_Matrix_);
987 if(!M1_Matrix_.is_null()) Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"M1.mat"), *M1_Matrix_);
988 if(!M0inv_Matrix_.is_null()) Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"M0inv.mat"), *M0inv_Matrix_);
989 #ifndef HAVE_MUELU_KOKKOS_REFACTOR
990 std::ofstream outBCrows(
"BCrows.mat");
991 std::copy(BCrows_.begin(), BCrows_.end(), std::ostream_iterator<LO>(outBCrows,
"\n"));
992 std::ofstream outBCcols(
"BCcols.mat");
993 std::copy(BCcols_.begin(), BCcols_.end(), std::ostream_iterator<LO>(outBCcols,
"\n"));
996 std::ofstream outBCrows(
"BCrows.mat");
997 auto BCrows = Kokkos::create_mirror_view (BCrowsKokkos_);
999 for (
size_t i = 0; i < BCrows.size(); i++)
1000 outBCrows << BCrows[i] <<
"\n";
1002 std::ofstream outBCcols(
"BCcols.mat");
1003 auto BCcols = Kokkos::create_mirror_view (BCcolsKokkos_);
1005 for (
size_t i = 0; i < BCcols.size(); i++)
1006 outBCcols << BCcols[i] <<
"\n";
1008 std::ofstream outBCrows(
"BCrows.mat");
1009 std::copy(BCrows_.begin(), BCrows_.end(), std::ostream_iterator<LO>(outBCrows,
"\n"));
1010 std::ofstream outBCcols(
"BCcols.mat");
1011 std::copy(BCcols_.begin(), BCcols_.end(), std::ostream_iterator<LO>(outBCcols,
"\n"));
1014 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"nullspace.mat"), *Nullspace_);
1015 if (Coords_ !=
null)
1016 Xpetra::IO<realType, LO, GlobalOrdinal, Node>::Write(
std::string(
"coords.mat"), *Coords_);
1017 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"D0_nuked.mat"), *D0_Matrix_);
1018 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"A_nodal.mat"), *A_nodal_Matrix_);
1019 Xpetra::IO<SC, LO, GO, NO>::Write(
std::string(
"P11.mat"), *P11_);
1021 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"AH.mat"), *AH_);
1022 if (!A22_.is_null())
1023 Xpetra::IO<SC, LO, GlobalOrdinal, Node>::Write(
std::string(
"A22.mat"), *A22_);
1026 if (parameterList_.isSublist(
"matvec params"))
1028 RCP<ParameterList> matvecParams = rcpFromRef(parameterList_.sublist(
"matvec params"));
1031 RCP<const Import> xpImporter = SM_Matrix_->getCrsGraph()->getImporter();
1032 if (!xpImporter.is_null())
1033 xpImporter->setDistributorParameters(matvecParams);
1034 RCP<const Export> xpExporter = SM_Matrix_->getCrsGraph()->getExporter();
1035 if (!xpExporter.is_null())
1036 xpExporter->setDistributorParameters(matvecParams);
1039 RCP<const Import> xpImporter = D0_Matrix_->getCrsGraph()->getImporter();
1040 if (!xpImporter.is_null())
1041 xpImporter->setDistributorParameters(matvecParams);
1042 RCP<const Export> xpExporter = D0_Matrix_->getCrsGraph()->getExporter();
1043 if (!xpExporter.is_null())
1044 xpExporter->setDistributorParameters(matvecParams);
1047 RCP<const Import> xpImporter = D0_T_Matrix_->getCrsGraph()->getImporter();
1048 if (!xpImporter.is_null())
1049 xpImporter->setDistributorParameters(matvecParams);
1050 RCP<const Export> xpExporter = D0_T_Matrix_->getCrsGraph()->getExporter();
1051 if (!xpExporter.is_null())
1052 xpExporter->setDistributorParameters(matvecParams);
1055 RCP<const Import> xpImporter = R11_->getCrsGraph()->getImporter();
1056 if (!xpImporter.is_null())
1057 xpImporter->setDistributorParameters(matvecParams);
1058 RCP<const Export> xpExporter = R11_->getCrsGraph()->getExporter();
1059 if (!xpExporter.is_null())
1060 xpExporter->setDistributorParameters(matvecParams);
1063 RCP<const Import> xpImporter = P11_->getCrsGraph()->getImporter();
1064 if (!xpImporter.is_null())
1065 xpImporter->setDistributorParameters(matvecParams);
1066 RCP<const Export> xpExporter = P11_->getCrsGraph()->getExporter();
1067 if (!xpExporter.is_null())
1068 xpExporter->setDistributorParameters(matvecParams);
1070 if (!ImporterH_.is_null())
1071 ImporterH_->setDistributorParameters(matvecParams);
1072 if (!Importer22_.is_null())
1073 Importer22_->setDistributorParameters(matvecParams);
1081 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1094 const SC SC_ZERO = Teuchos::ScalarTraits<SC>::zero();
1095 const SC SC_ONE = Teuchos::ScalarTraits<SC>::one();
1096 const Scalar half = SC_ONE / (SC_ONE + SC_ONE);
1097 size_t dim = Nullspace_->getNumVectors();
1098 size_t numLocalRows = SM_Matrix_->getNodeNumRows();
1102 RCP<Matrix> P_nodal;
1103 bool read_P_from_file = parameterList_.get(
"refmaxwell: read_P_from_file",
false);
1104 if (read_P_from_file) {
1108 P_nodal = Xpetra::IO<SC, LO, GO, NO>::Read(P_filename, A_nodal_Matrix_->getDomainMap());
1110 Level fineLevel, coarseLevel;
1116 fineLevel.
Set(
"A",A_nodal_Matrix_);
1117 fineLevel.
Set(
"Coordinates",Coords_);
1118 fineLevel.
Set(
"DofsPerNode",1);
1119 coarseLevel.
setlib(A_nodal_Matrix_->getDomainMap()->lib());
1120 fineLevel.
setlib(A_nodal_Matrix_->getDomainMap()->lib());
1121 coarseLevel.setObjectLabel(
"RefMaxwell (1,1)");
1122 fineLevel.setObjectLabel(
"RefMaxwell (1,1)");
1125 RCP<MultiVector> nullSpace = MultiVectorFactory::Build(A_nodal_Matrix_->getRowMap(),NSdim);
1126 nullSpace->putScalar(SC_ONE);
1127 fineLevel.
Set(
"Nullspace",nullSpace);
1129 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
1130 RCP<Factory> amalgFact, dropFact, UncoupledAggFact, coarseMapFact, TentativePFact, Tfact;
1132 amalgFact = rcp(
new AmalgamationFactory_kokkos());
1133 dropFact = rcp(
new CoalesceDropFactory_kokkos());
1134 UncoupledAggFact = rcp(
new UncoupledAggregationFactory_kokkos());
1135 coarseMapFact = rcp(
new CoarseMapFactory_kokkos());
1136 TentativePFact = rcp(
new TentativePFactory_kokkos());
1137 Tfact = rcp(
new CoordinatesTransferFactory_kokkos());
1154 dropFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1155 double dropTol = parameterList_.get(
"aggregation: drop tol",0.0);
1156 dropFact->SetParameter(
"aggregation: drop tol",Teuchos::ParameterEntry(dropTol));
1158 UncoupledAggFact->SetFactory(
"Graph", dropFact);
1160 coarseMapFact->SetFactory(
"Aggregates", UncoupledAggFact);
1162 TentativePFact->SetFactory(
"Aggregates", UncoupledAggFact);
1163 TentativePFact->SetFactory(
"UnAmalgamationInfo", amalgFact);
1164 TentativePFact->SetFactory(
"CoarseMap", coarseMapFact);
1166 Tfact->SetFactory(
"Aggregates", UncoupledAggFact);
1167 Tfact->SetFactory(
"CoarseMap", coarseMapFact);
1169 coarseLevel.
Request(
"P",TentativePFact.get());
1170 coarseLevel.
Request(
"Coordinates",Tfact.get());
1172 RCP<AggregationExportFactory> aggExport;
1173 if (parameterList_.get(
"aggregation: export visualization data",
false)) {
1175 ParameterList aggExportParams;
1176 aggExportParams.set(
"aggregation: output filename",
"aggs.vtk");
1177 aggExportParams.set(
"aggregation: output file: agg style",
"Jacks");
1178 aggExport->SetParameterList(aggExportParams);
1180 aggExport->SetFactory(
"Aggregates", UncoupledAggFact);
1181 aggExport->SetFactory(
"UnAmalgamationInfo", amalgFact);
1182 fineLevel.
Request(
"Aggregates",UncoupledAggFact.get());
1183 fineLevel.
Request(
"UnAmalgamationInfo",amalgFact.get());
1186 coarseLevel.
Get(
"P",P_nodal,TentativePFact.get());
1187 coarseLevel.
Get(
"Coordinates",CoordsH_,Tfact.get());
1189 if (parameterList_.get(
"aggregation: export visualization data",
false))
1190 aggExport->Build(fineLevel, coarseLevel);
1193 Xpetra::IO<SC, LO, GO, NO>::Write(
std::string(
"P_nodal.mat"), *P_nodal);
1195 RCP<CrsMatrix> D0Crs = rcp_dynamic_cast<CrsMatrixWrap>(D0_Matrix_)->getCrsMatrix();
1198 RCP<CrsMatrix> P_nodal_imported;
1199 int numProcs = P_nodal->getDomainMap()->getComm()->getSize();
1201 RCP<CrsMatrixWrap> P_nodal_temp;
1202 RCP<const Map> targetMap = D0Crs->getColMap();
1203 P_nodal_temp = rcp(
new CrsMatrixWrap(targetMap, 0));
1204 RCP<const Import> importer = D0Crs->getCrsGraph()->getImporter();
1205 P_nodal_temp->doImport(*P_nodal, *importer, Xpetra::INSERT);
1206 P_nodal_temp->fillComplete(rcp_dynamic_cast<CrsMatrixWrap>(P_nodal)->getCrsMatrix()->getDomainMap(),
1207 rcp_dynamic_cast<CrsMatrixWrap>(P_nodal)->getCrsMatrix()->getRangeMap());
1208 P_nodal_imported = P_nodal_temp->getCrsMatrix();
1210 Xpetra::IO<SC, LO, GO, NO>::Write(
std::string(
"P_nodal_imported.mat"), *P_nodal_temp);
1212 P_nodal_imported = rcp_dynamic_cast<CrsMatrixWrap>(P_nodal)->getCrsMatrix();
1214 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
1217 using ATS = Kokkos::ArithTraits<SC>;
1220 typedef typename Matrix::local_matrix_type KCRS;
1221 typedef typename KCRS::device_type device_t;
1222 typedef typename KCRS::StaticCrsGraphType graph_t;
1223 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
1224 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1225 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1228 auto localP = P_nodal_imported->getLocalMatrix();
1229 auto localD0 = D0_Matrix_->getLocalMatrix();
1235 std::string algo = parameterList_.get(
"refmaxwell: prolongator compute algorithm",defaultAlgo);
1237 if (algo ==
"mat-mat") {
1238 RCP<Matrix> D0_P_nodal = MatrixFactory::Build(SM_Matrix_->getRowMap(),0);
1239 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_,
false,*P_nodal,
false,*D0_P_nodal,
true,
true);
1242 auto localD0P = D0_P_nodal->getLocalMatrix();
1245 RCP<Map> blockColMap = Xpetra::MapFactory<LO,GO,NO>::Build(P_nodal_imported->getColMap(), dim);
1246 RCP<Map> blockDomainMap = Xpetra::MapFactory<LO,GO,NO>::Build(P_nodal->getDomainMap(), dim);
1248 lno_view_t P11rowptr(
"P11_rowptr", numLocalRows+1);
1249 lno_nnz_view_t P11colind(
"P11_colind",dim*localD0P.graph.entries.size());
1250 scalar_view_t P11vals(
"P11_vals",dim*localD0P.graph.entries.size());
1253 Kokkos::parallel_for(
"MueLu:RefMaxwell::buildProlongator_adjustRowptr", range_type(0,numLocalRows+1),
1254 KOKKOS_LAMBDA(
const size_t i) {
1255 P11rowptr(i) = dim*localD0P.graph.row_map(i);
1259 Kokkos::parallel_for(
"MueLu:RefMaxwell::buildProlongator_adjustColind", range_type(0,localD0P.graph.entries.size()),
1260 KOKKOS_LAMBDA(
const size_t jj) {
1261 for (
size_t k = 0; k < dim; k++) {
1262 P11colind(dim*jj+k) = dim*localD0P.graph.entries(jj)+k;
1263 P11vals(dim*jj+k) = SC_ZERO;
1267 auto localNullspace = Nullspace_->template getLocalView<device_t>();
1270 if (D0_Matrix_->getNodeMaxNumRowEntries()>2) {
1274 GetOStream(
Warnings0) <<
"RefMaxwell::buildProlongator(): D0 matrix has more than 2 entries per row. Taking inefficient code path." << std::endl;
1276 magnitudeType tol = Teuchos::ScalarTraits<magnitudeType>::eps();
1278 Kokkos::parallel_for(
"MueLu:RefMaxwell::buildProlongator_enterValues_D0wZeros", range_type(0,numLocalRows),
1279 KOKKOS_LAMBDA(
const size_t i) {
1280 for (
size_t ll = localD0.graph.row_map(i); ll < localD0.graph.row_map(i+1); ll++) {
1281 LO l = localD0.graph.entries(ll);
1282 SC p = localD0.values(ll);
1283 if (ATS::magnitude(p) < tol)
1285 for (size_t jj = localP.graph.row_map(l); jj < localP.graph.row_map(l+1); jj++) {
1286 LO j = localP.graph.entries(jj);
1287 SC v = localP.values(jj);
1288 for (size_t k = 0; k < dim; k++) {
1290 SC n = localNullspace(i,k);
1292 for (m = P11rowptr(i); m < P11rowptr(i+1); m++)
1293 if (P11colind(m) == jNew)
1295 #if defined(HAVE_MUELU_DEBUG) && !defined(HAVE_MUELU_CUDA)
1296 TEUCHOS_ASSERT_EQUALITY(P11colind(m),jNew);
1298 P11vals(m) += half * v * n;
1305 Kokkos::parallel_for(
"MueLu:RefMaxwell::buildProlongator_enterValues", range_type(0,numLocalRows),
1306 KOKKOS_LAMBDA(
const size_t i) {
1307 for (
size_t ll = localD0.graph.row_map(i); ll < localD0.graph.row_map(i+1); ll++) {
1308 LO l = localD0.graph.entries(ll);
1309 for (size_t jj = localP.graph.row_map(l); jj < localP.graph.row_map(l+1); jj++) {
1310 LO j = localP.graph.entries(jj);
1311 SC v = localP.values(jj);
1312 for (size_t k = 0; k < dim; k++) {
1314 SC n = localNullspace(i,k);
1316 for (m = P11rowptr(i); m < P11rowptr(i+1); m++)
1317 if (P11colind(m) == jNew)
1319 #if defined(HAVE_MUELU_DEBUG) && !defined(HAVE_MUELU_CUDA)
1320 TEUCHOS_ASSERT_EQUALITY(P11colind(m),jNew);
1322 P11vals(m) += half * v * n;
1329 P11_ = rcp(
new CrsMatrixWrap(SM_Matrix_->getRowMap(), blockColMap, 0, Xpetra::StaticProfile));
1330 RCP<CrsMatrix> P11Crs = rcp_dynamic_cast<CrsMatrixWrap>(P11_)->getCrsMatrix();
1331 P11Crs->setAllValues(P11rowptr, P11colind, P11vals);
1332 P11Crs->expertStaticFillComplete(blockDomainMap, SM_Matrix_->getRangeMap());
1335 TEUCHOS_TEST_FOR_EXCEPTION(
false,std::invalid_argument,algo <<
" is not a valid option for \"refmaxwell: prolongator compute algorithm\"");
1337 #endif // ifdef(HAVE_MUELU_KOKKOS_REFACTOR)
1340 ArrayRCP<ArrayRCP<const SC> > nullspaceRCP(dim);
1341 ArrayRCP<ArrayView<const SC> > nullspace(dim);
1342 for(
size_t i=0; i<dim; i++) {
1343 nullspaceRCP[i] = Nullspace_->getData(i);
1344 nullspace[i] = nullspaceRCP[i]();
1348 ArrayRCP<const size_t> Prowptr_RCP, D0rowptr_RCP;
1349 ArrayRCP<const LO> Pcolind_RCP, D0colind_RCP;
1350 ArrayRCP<const SC> Pvals_RCP, D0vals_RCP;
1351 ArrayRCP<size_t> P11rowptr_RCP;
1352 ArrayRCP<LO> P11colind_RCP;
1353 ArrayRCP<SC> P11vals_RCP;
1355 P_nodal_imported->getAllValues(Prowptr_RCP, Pcolind_RCP, Pvals_RCP);
1356 rcp_dynamic_cast<CrsMatrixWrap>(D0_Matrix_)->getCrsMatrix()->getAllValues(D0rowptr_RCP, D0colind_RCP, D0vals_RCP);
1361 ArrayView<const size_t> Prowptr, D0rowptr;
1362 ArrayView<const LO> Pcolind, D0colind;
1363 ArrayView<const SC> Pvals, D0vals;
1364 Prowptr = Prowptr_RCP(); Pcolind = Pcolind_RCP(); Pvals = Pvals_RCP();
1365 D0rowptr = D0rowptr_RCP(); D0colind = D0colind_RCP(); D0vals = D0vals_RCP();
1374 std::string algo = parameterList_.get(
"refmaxwell: prolongator compute algorithm",defaultAlgo);
1376 if (algo ==
"mat-mat") {
1377 RCP<Matrix> D0_P_nodal = MatrixFactory::Build(SM_Matrix_->getRowMap(),0);
1378 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_,
false,*P_nodal,
false,*D0_P_nodal,
true,
true);
1381 ArrayRCP<const size_t> D0Prowptr_RCP;
1382 ArrayRCP<const LO> D0Pcolind_RCP;
1383 ArrayRCP<const SC> D0Pvals_RCP;
1384 rcp_dynamic_cast<CrsMatrixWrap>(D0_P_nodal)->getCrsMatrix()->getAllValues(D0Prowptr_RCP, D0Pcolind_RCP, D0Pvals_RCP);
1389 ArrayView<const size_t> D0Prowptr;
1390 ArrayView<const LO> D0Pcolind;
1391 D0Prowptr = D0Prowptr_RCP(); D0Pcolind = D0Pcolind_RCP();
1394 RCP<Map> blockColMap = Xpetra::MapFactory<LO,GO,NO>::Build(P_nodal_imported->getColMap(), dim);
1395 RCP<Map> blockDomainMap = Xpetra::MapFactory<LO,GO,NO>::Build(P_nodal->getDomainMap(), dim);
1396 P11_ = rcp(
new CrsMatrixWrap(SM_Matrix_->getRowMap(), blockColMap, 0, Xpetra::StaticProfile));
1397 RCP<CrsMatrix> P11Crs = rcp_dynamic_cast<CrsMatrixWrap>(P11_)->getCrsMatrix();
1398 P11Crs->allocateAllValues(dim*D0Pcolind.size(), P11rowptr_RCP, P11colind_RCP, P11vals_RCP);
1400 ArrayView<size_t> P11rowptr = P11rowptr_RCP();
1401 ArrayView<LO> P11colind = P11colind_RCP();
1402 ArrayView<SC> P11vals = P11vals_RCP();
1405 for (
size_t i = 0; i < numLocalRows+1; i++) {
1406 P11rowptr[i] = dim*D0Prowptr[i];
1411 for (
size_t jj = 0; jj < (size_t) D0Pcolind.size(); jj++)
1412 for (
size_t k = 0; k < dim; k++) {
1413 P11colind[nnz] = dim*D0Pcolind[jj]+k;
1414 P11vals[nnz] = SC_ZERO;
1419 if (D0_Matrix_->getNodeMaxNumRowEntries()>2) {
1423 GetOStream(
Warnings0) <<
"RefMaxwell::buildProlongator(): D0 matrix has more than 2 entries per row. Taking inefficient code path." << std::endl;
1425 magnitudeType tol = Teuchos::ScalarTraits<magnitudeType>::eps();
1426 for (
size_t i = 0; i < numLocalRows; i++) {
1427 for (
size_t ll = D0rowptr[i]; ll < D0rowptr[i+1]; ll++) {
1428 LO l = D0colind[ll];
1430 if (Teuchos::ScalarTraits<Scalar>::magnitude(p) < tol)
1432 for (
size_t jj = Prowptr[l]; jj < Prowptr[l+1]; jj++) {
1435 for (
size_t k = 0; k < dim; k++) {
1437 SC n = nullspace[k][i];
1439 for (m = P11rowptr[i]; m < P11rowptr[i+1]; m++)
1440 if (P11colind[m] == jNew)
1442 #ifdef HAVE_MUELU_DEBUG
1443 TEUCHOS_ASSERT_EQUALITY(P11colind[m],jNew);
1445 P11vals[m] += half * v * n;
1452 for (
size_t i = 0; i < numLocalRows; i++) {
1453 for (
size_t ll = D0rowptr[i]; ll < D0rowptr[i+1]; ll++) {
1454 LO l = D0colind[ll];
1455 for (
size_t jj = Prowptr[l]; jj < Prowptr[l+1]; jj++) {
1458 for (
size_t k = 0; k < dim; k++) {
1460 SC n = nullspace[k][i];
1462 for (m = P11rowptr[i]; m < P11rowptr[i+1]; m++)
1463 if (P11colind[m] == jNew)
1465 #ifdef HAVE_MUELU_DEBUG
1466 TEUCHOS_ASSERT_EQUALITY(P11colind[m],jNew);
1468 P11vals[m] += half * v * n;
1475 P11Crs->setAllValues(P11rowptr_RCP, P11colind_RCP, P11vals_RCP);
1476 P11Crs->expertStaticFillComplete(blockDomainMap, SM_Matrix_->getRangeMap());
1478 }
else if (algo ==
"gustavson") {
1480 LO maxP11col = dim * P_nodal_imported->getColMap()->getMaxLocalIndex();
1481 const size_t ST_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
1482 Array<size_t> P11_status(dim*maxP11col, ST_INVALID);
1484 size_t nnz_alloc = dim*D0vals_RCP.size();
1487 RCP<Map> blockColMap = Xpetra::MapFactory<LO,GO,NO>::Build(P_nodal_imported->getColMap(), dim);
1488 RCP<Map> blockDomainMap = Xpetra::MapFactory<LO,GO,NO>::Build(P_nodal->getDomainMap(), dim);
1489 P11_ = rcp(
new CrsMatrixWrap(SM_Matrix_->getRowMap(), blockColMap, 0, Xpetra::StaticProfile));
1490 RCP<CrsMatrix> P11Crs = rcp_dynamic_cast<CrsMatrixWrap>(P11_)->getCrsMatrix();
1491 P11Crs->allocateAllValues(nnz_alloc, P11rowptr_RCP, P11colind_RCP, P11vals_RCP);
1493 ArrayView<size_t> P11rowptr = P11rowptr_RCP();
1494 ArrayView<LO> P11colind = P11colind_RCP();
1495 ArrayView<SC> P11vals = P11vals_RCP();
1498 if (D0_Matrix_->getNodeMaxNumRowEntries()>2) {
1502 GetOStream(
Warnings0) <<
"RefMaxwell::buildProlongator(): D0 matrix has more than 2 entries per row. Taking inefficient code path." << std::endl;
1504 magnitudeType tol = Teuchos::ScalarTraits<magnitudeType>::eps();
1507 for (
size_t i = 0; i < numLocalRows; i++) {
1509 for (
size_t ll = D0rowptr[i]; ll < D0rowptr[i+1]; ll++) {
1510 LO l = D0colind[ll];
1512 if (Teuchos::ScalarTraits<Scalar>::magnitude(p) < tol)
1514 for (
size_t jj = Prowptr[l]; jj < Prowptr[l+1]; jj++) {
1517 for (
size_t k = 0; k < dim; k++) {
1519 SC n = nullspace[k][i];
1521 if (P11_status[jNew] == ST_INVALID || P11_status[jNew] < nnz_old) {
1522 P11_status[jNew] = nnz;
1523 P11colind[nnz] = jNew;
1524 P11vals[nnz] = half * v * n;
1529 P11vals[P11_status[jNew]] += half * v * n;
1538 P11rowptr[numLocalRows] = nnz;
1542 for (
size_t i = 0; i < numLocalRows; i++) {
1544 for (
size_t ll = D0rowptr[i]; ll < D0rowptr[i+1]; ll++) {
1545 LO l = D0colind[ll];
1546 for (
size_t jj = Prowptr[l]; jj < Prowptr[l+1]; jj++) {
1549 for (
size_t k = 0; k < dim; k++) {
1551 SC n = nullspace[k][i];
1553 if (P11_status[jNew] == ST_INVALID || P11_status[jNew] < nnz_old) {
1554 P11_status[jNew] = nnz;
1555 P11colind[nnz] = jNew;
1556 P11vals[nnz] = half * v * n;
1561 P11vals[P11_status[jNew]] += half * v * n;
1570 P11rowptr[numLocalRows] = nnz;
1573 if (blockDomainMap->lib() == Xpetra::UseTpetra) {
1577 P11vals_RCP.resize(nnz);
1578 P11colind_RCP.resize(nnz);
1581 P11Crs->setAllValues(P11rowptr_RCP, P11colind_RCP, P11vals_RCP);
1582 P11Crs->expertStaticFillComplete(blockDomainMap, SM_Matrix_->getRangeMap());
1584 TEUCHOS_TEST_FOR_EXCEPTION(
false,std::invalid_argument,algo <<
" is not a valid option for \"refmaxwell: prolongator compute algorithm\"");
1585 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
1590 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1592 Teuchos::TimeMonitor tm(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: Build coarse (1,1) matrix"));
1595 RCP<Matrix> Matrix1;
1597 Level fineLevel, coarseLevel;
1603 fineLevel.
Set(
"A",SM_Matrix_);
1604 coarseLevel.
Set(
"P",P11_);
1605 if (!implicitTranspose_)
1606 coarseLevel.
Set(
"R",R11_);
1608 coarseLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1609 fineLevel.
setlib(SM_Matrix_->getDomainMap()->lib());
1610 coarseLevel.setObjectLabel(
"RefMaxwell (1,1)");
1611 fineLevel.setObjectLabel(
"RefMaxwell (1,1)");
1613 RCP<RAPFactory> rapFact = rcp(
new RAPFactory());
1614 ParameterList rapList = *(rapFact->GetValidParameterList());
1615 rapList.set(
"transpose: use implicit", implicitTranspose_);
1616 rapList.set(
"rap: fix zero diagonals", parameterList_.get<
bool>(
"rap: fix zero diagonals",
true));
1617 rapList.set(
"rap: triple product", parameterList_.get<
bool>(
"rap: triple product",
false));
1618 rapFact->SetParameterList(rapList);
1620 if (precList11_.isType<
std::string>(
"reuse: type") && precList11_.get<
std::string>(
"reuse: type") !=
"none") {
1621 if (!parameterList_.get<
bool>(
"rap: triple product",
false))
1622 coarseLevel.
Request(
"AP reuse data", rapFact.get());
1623 coarseLevel.
Request(
"RAP reuse data", rapFact.get());
1626 if (!AH_AP_reuse_data_.is_null()) {
1627 coarseLevel.
AddKeepFlag(
"AP reuse data", rapFact.get());
1628 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList> >(
"AP reuse data", AH_AP_reuse_data_, rapFact.get());
1630 if (!AH_RAP_reuse_data_.is_null()) {
1631 coarseLevel.
AddKeepFlag(
"RAP reuse data", rapFact.get());
1632 coarseLevel.
Set<Teuchos::RCP<Teuchos::ParameterList> >(
"RAP reuse data", AH_RAP_reuse_data_, rapFact.get());
1635 coarseLevel.
Request(
"A", rapFact.get());
1637 Matrix1 = coarseLevel.
Get< RCP<Matrix> >(
"A", rapFact.get());
1638 if (precList11_.isType<
std::string>(
"reuse: type") && precList11_.get<
std::string>(
"reuse: type") !=
"none") {
1639 if (!parameterList_.get<
bool>(
"rap: triple product",
false))
1640 AH_AP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"AP reuse data", rapFact.get());
1641 AH_RAP_reuse_data_ = coarseLevel.
Get< RCP<ParameterList> >(
"RAP reuse data", rapFact.get());
1646 AH_ = Teuchos::null;
1648 if(disable_addon_==
true) {
1653 if (Addon_Matrix_.is_null()) {
1654 Teuchos::TimeMonitor tmAddon(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: Build coarse addon matrix"));
1656 TEUCHOS_TEST_FOR_EXCEPTION(M0inv_Matrix_==Teuchos::null,std::invalid_argument,
1657 "MueLu::RefMaxwell::formCoarseMatrix(): Inverse of "
1658 "lumped mass matrix required for add-on (i.e. M0inv_Matrix is null)");
1661 RCP<Matrix> Zaux = MatrixFactory::Build(M1_Matrix_->getRowMap(),0);
1662 RCP<Matrix> Z = MatrixFactory::Build(D0_Matrix_->getDomainMap(),0);
1665 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*M1_Matrix_,
false,*P11_,
false,*Zaux,
true,
true);
1667 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_,
true,*Zaux,
false,*Z,
true,
true);
1670 RCP<Matrix> Matrix2 = MatrixFactory::Build(Z->getDomainMap(),0);
1671 if (M0inv_Matrix_->getGlobalMaxNumRowEntries()<=1) {
1674 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
1677 ZT = Utilities_kokkos::Transpose(*Z);
1679 ZT = Utilities::Transpose(*Z);
1681 RCP<Matrix> ZT = Utilities::Transpose(*Z);
1683 RCP<Vector> diag = VectorFactory::Build(M0inv_Matrix_->getRowMap());
1684 M0inv_Matrix_->getLocalDiagCopy(*diag);
1685 if (Z->getRowMap()->isSameAs(*(diag->getMap())))
1686 Z->leftScale(*diag);
1688 RCP<Import> importer = ImportFactory::Build(diag->getMap(),Z->getRowMap());
1689 RCP<Vector> diag2 = VectorFactory::Build(Z->getRowMap());
1690 diag2->doImport(*diag,*importer,Xpetra::INSERT);
1691 Z->leftScale(*diag2);
1693 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*ZT,
false,*Z,
false,*Matrix2,
true,
true);
1694 }
else if (parameterList_.get<
bool>(
"rap: triple product",
false) ==
false) {
1695 RCP<Matrix> C2 = MatrixFactory::Build(M0inv_Matrix_->getRowMap(),0);
1697 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*M0inv_Matrix_,
false,*Z,
false,*C2,
true,
true);
1699 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*Z,
true,*C2,
false,*Matrix2,
true,
true);
1702 Xpetra::TripleMatrixMultiply<Scalar,LocalOrdinal,GlobalOrdinal,Node>::
1703 MultiplyRAP(*Z,
true, *M0inv_Matrix_,
false, *Z,
false, *Matrix2,
true,
true);
1706 if (precList11_.isType<
std::string>(
"reuse: type") && precList11_.get<
std::string>(
"reuse: type") !=
"none")
1707 Addon_Matrix_ = Matrix2;
1710 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::TwoMatrixAdd(*Matrix1,
false,(
Scalar)1.0,*Matrix2,
false,(
Scalar)1.0,AH_,GetOStream(
Runtime0));
1711 AH_->fillComplete();
1714 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::TwoMatrixAdd(*Matrix1,
false,(
Scalar)1.0,*Addon_Matrix_,
false,(
Scalar)1.0,AH_,GetOStream(
Runtime0));
1715 AH_->fillComplete();
1720 size_t dim = Nullspace_->getNumVectors();
1721 AH_->SetFixedBlockSize(dim);
1722 AH_->setObjectLabel(
"RefMaxwell (1,1)");
1727 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1729 bool reuse = !SM_Matrix_.is_null();
1730 SM_Matrix_ = SM_Matrix_new;
1736 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1739 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1743 Teuchos::TimeMonitor tmRes(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: residual calculation"));
1744 Utilities::Residual(*SM_Matrix_, X, RHS, *residual_);
1745 if (implicitTranspose_) {
1746 P11_->apply(*residual_,*P11res_,Teuchos::TRANS);
1747 D0_Matrix_->apply(*residual_,*D0res_,Teuchos::TRANS);
1749 R11_->apply(*residual_,*P11res_,Teuchos::NO_TRANS);
1750 D0_T_Matrix_->apply(*residual_,*D0res_,Teuchos::NO_TRANS);
1756 if (!ImporterH_.is_null()) {
1757 Teuchos::TimeMonitor tmH(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: import coarse (1,1)"));
1758 P11resTmp_->doImport(*P11res_, *ImporterH_, Xpetra::INSERT);
1759 P11res_.swap(P11resTmp_);
1761 if (!Importer22_.is_null()) {
1762 Teuchos::TimeMonitor tm22(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: import (2,2)"));
1763 D0resTmp_->doImport(*D0res_, *Importer22_, Xpetra::INSERT);
1764 D0res_.swap(D0resTmp_);
1768 if (!AH_.is_null()) {
1769 Teuchos::TimeMonitor tmH(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: solve coarse (1,1)"));
1771 RCP<const Map> origXMap = P11x_->getMap();
1772 RCP<const Map> origRhsMap = P11res_->getMap();
1775 P11res_->replaceMap(AH_->getRangeMap());
1776 P11x_ ->replaceMap(AH_->getDomainMap());
1777 HierarchyH_->Iterate(*P11res_, *P11x_, 1,
true);
1778 P11x_ ->replaceMap(origXMap);
1779 P11res_->replaceMap(origRhsMap);
1783 if (!A22_.is_null()) {
1784 Teuchos::TimeMonitor tm22(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: solve (2,2)"));
1786 RCP<const Map> origXMap = D0x_->getMap();
1787 RCP<const Map> origRhsMap = D0res_->getMap();
1790 D0res_->replaceMap(A22_->getRangeMap());
1791 D0x_ ->replaceMap(A22_->getDomainMap());
1792 Hierarchy22_->Iterate(*D0res_, *D0x_, 1,
true);
1793 D0x_ ->replaceMap(origXMap);
1794 D0res_->replaceMap(origRhsMap);
1797 if (!Importer22_.is_null()) {
1798 Teuchos::TimeMonitor tm22(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: export (2,2)"));
1799 D0xTmp_->doExport(*D0x_, *Importer22_, Xpetra::INSERT);
1803 if (!ImporterH_.is_null()) {
1804 Teuchos::TimeMonitor tmH(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: export coarse (1,1)"));
1805 P11xTmp_->doExport(*P11x_, *ImporterH_, Xpetra::INSERT);
1806 P11x_.swap(P11xTmp_);
1810 Teuchos::TimeMonitor tmUp(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: update"));
1811 P11_->apply(*P11x_,*residual_,Teuchos::NO_TRANS);
1812 D0_Matrix_->apply(*D0x_,*residual_,Teuchos::NO_TRANS,one,one);
1813 X.update(one, *residual_, one);
1815 if (!ImporterH_.is_null()) {
1816 P11res_.swap(P11resTmp_);
1817 P11x_.swap(P11xTmp_);
1819 if (!Importer22_.is_null()) {
1820 D0res_.swap(D0resTmp_);
1828 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1841 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1853 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1856 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1859 Teuchos::TimeMonitor tmRes(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: residual calculation"));
1860 Utilities::Residual(*SM_Matrix_, X, RHS,*residual_);
1861 if (implicitTranspose_)
1862 P11_->apply(*residual_,*P11res_,Teuchos::TRANS);
1864 R11_->apply(*residual_,*P11res_,Teuchos::NO_TRANS);
1868 if (!ImporterH_.is_null()) {
1869 Teuchos::TimeMonitor tmH(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: import coarse (1,1)"));
1870 P11resTmp_->doImport(*P11res_, *ImporterH_, Xpetra::INSERT);
1871 P11res_.swap(P11resTmp_);
1873 if (!AH_.is_null()) {
1874 Teuchos::TimeMonitor tmH(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: solve coarse (1,1)"));
1876 RCP<const Map> origXMap = P11x_->getMap();
1877 RCP<const Map> origRhsMap = P11res_->getMap();
1880 P11res_->replaceMap(AH_->getRangeMap());
1881 P11x_ ->replaceMap(AH_->getDomainMap());
1882 HierarchyH_->Iterate(*P11res_, *P11x_, 1,
true);
1883 P11x_ ->replaceMap(origXMap);
1884 P11res_->replaceMap(origRhsMap);
1886 if (!ImporterH_.is_null()) {
1887 Teuchos::TimeMonitor tmH(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: export coarse (1,1)"));
1888 P11xTmp_->doExport(*P11x_, *ImporterH_, Xpetra::INSERT);
1889 P11x_.swap(P11xTmp_);
1894 Teuchos::TimeMonitor tmUp(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: update"));
1895 P11_->apply(*P11x_,*residual_,Teuchos::NO_TRANS);
1896 X.update(one, *residual_, one);
1902 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1905 Scalar one = Teuchos::ScalarTraits<Scalar>::one();
1908 Teuchos::TimeMonitor tmRes(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: residual calculation"));
1909 Utilities::Residual(*SM_Matrix_, X, RHS, *residual_);
1910 if (implicitTranspose_)
1911 D0_Matrix_->apply(*residual_,*D0res_,Teuchos::TRANS);
1913 D0_T_Matrix_->apply(*residual_,*D0res_,Teuchos::NO_TRANS);
1917 if (!Importer22_.is_null()) {
1918 Teuchos::TimeMonitor tm22(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: import (2,2)"));
1919 D0resTmp_->doImport(*D0res_, *Importer22_, Xpetra::INSERT);
1920 D0res_.swap(D0resTmp_);
1922 if (!A22_.is_null()) {
1923 Teuchos::TimeMonitor tm22(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: solve (2,2)"));
1925 RCP<const Map> origXMap = D0x_->getMap();
1926 RCP<const Map> origRhsMap = D0res_->getMap();
1929 D0res_->replaceMap(A22_->getRangeMap());
1930 D0x_ ->replaceMap(A22_->getDomainMap());
1931 Hierarchy22_->Iterate(*D0res_, *D0x_, 1,
true);
1932 D0x_ ->replaceMap(origXMap);
1933 D0res_->replaceMap(origRhsMap);
1935 if (!Importer22_.is_null()) {
1936 Teuchos::TimeMonitor tm22(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: export (2,2)"));
1937 D0xTmp_->doExport(*D0x_, *Importer22_, Xpetra::INSERT);
1943 Teuchos::TimeMonitor tmUp(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: update"));
1944 D0_Matrix_->apply(*D0x_,*residual_,Teuchos::NO_TRANS);
1945 X.update(one, *residual_, one);
1951 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1957 Teuchos::TimeMonitor tm(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: solve"));
1960 if (X.getNumVectors() != P11res_->getNumVectors()) {
1961 P11res_ = MultiVectorFactory::Build(P11_->getDomainMap(), X.getNumVectors());
1962 if (!ImporterH_.is_null()) {
1963 P11resTmp_ = MultiVectorFactory::Build(ImporterH_->getTargetMap(), X.getNumVectors());
1964 P11xTmp_ = MultiVectorFactory::Build(ImporterH_->getSourceMap(), X.getNumVectors());
1965 P11x_ = MultiVectorFactory::Build(ImporterH_->getTargetMap(), X.getNumVectors());
1967 P11x_ = MultiVectorFactory::Build(P11_->getDomainMap(), X.getNumVectors());
1968 if (!Importer22_.is_null()) {
1969 D0resTmp_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), X.getNumVectors());
1970 D0xTmp_ = MultiVectorFactory::Build(Importer22_->getSourceMap(), X.getNumVectors());
1971 D0x_ = MultiVectorFactory::Build(Importer22_->getTargetMap(), X.getNumVectors());
1973 D0x_ = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(), X.getNumVectors());
1974 residual_ = MultiVectorFactory::Build(SM_Matrix_->getDomainMap(), X.getNumVectors());
1980 Teuchos::TimeMonitor tmSm(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: smoothing"));
1982 #if defined(HAVE_MUELU_IFPACK2) && (!defined(HAVE_MUELU_EPETRA) || defined(HAVE_MUELU_INST_DOUBLE_INT_INT))
1983 if (useHiptmairSmoothing_) {
1984 Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> tX = Utilities::MV2NonConstTpetraMV(X);
1985 Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> tRHS = Utilities::MV2TpetraMV(RHS);
1986 hiptmairPreSmoother_->apply(tRHS, tX);
1990 PreSmoother_->Apply(X, RHS, use_as_preconditioner_);
1994 if(mode_==
"additive")
1995 applyInverseAdditive(RHS,X);
1996 else if(mode_==
"121")
1997 applyInverse121(RHS,X);
1998 else if(mode_==
"212")
1999 applyInverse212(RHS,X);
2004 else if(mode_==
"none") {
2008 applyInverseAdditive(RHS,X);
2012 Teuchos::TimeMonitor tmSm(*Teuchos::TimeMonitor::getNewTimer(
"MueLu RefMaxwell: smoothing"));
2014 #if defined(HAVE_MUELU_IFPACK2) && (!defined(HAVE_MUELU_EPETRA) || defined(HAVE_MUELU_INST_DOUBLE_INT_INT))
2015 if (useHiptmairSmoothing_)
2017 Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> tX = Utilities::MV2NonConstTpetraMV(X);
2018 Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> tRHS = Utilities::MV2TpetraMV(RHS);
2019 hiptmairPostSmoother_->apply(tRHS, tX);
2023 PostSmoother_->Apply(X, RHS,
false);
2029 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2035 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2037 initialize(
const Teuchos::RCP<Matrix> & D0_Matrix,
2038 const Teuchos::RCP<Matrix> & Ms_Matrix,
2039 const Teuchos::RCP<Matrix> & M0inv_Matrix,
2040 const Teuchos::RCP<Matrix> & M1_Matrix,
2041 const Teuchos::RCP<MultiVector> & Nullspace,
2042 const Teuchos::RCP<RealValuedMultiVector> & Coords,
2043 Teuchos::ParameterList& List)
2046 TEUCHOS_ASSERT(D0_Matrix!=Teuchos::null);
2047 TEUCHOS_ASSERT(Ms_Matrix!=Teuchos::null);
2048 TEUCHOS_ASSERT(M1_Matrix!=Teuchos::null);
2050 HierarchyH_ = Teuchos::null;
2051 Hierarchy22_ = Teuchos::null;
2052 PreSmoother_ = Teuchos::null;
2053 PostSmoother_ = Teuchos::null;
2054 disable_addon_ =
false;
2058 setParameters(List);
2060 D0_Matrix_ = D0_Matrix;
2061 M0inv_Matrix_ = M0inv_Matrix;
2062 Ms_Matrix_ = Ms_Matrix;
2063 M1_Matrix_ = M1_Matrix;
2065 Nullspace_ = Nullspace;
2068 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2070 describe(Teuchos::FancyOStream& out,
const Teuchos::EVerbosityLevel )
const {
2072 std::ostringstream oss;
2074 RCP<const Teuchos::Comm<int> > comm = SM_Matrix_->
getDomainMap()->getComm();
2078 if (!A22_.is_null())
2079 root = comm->getRank();
2084 reduceAll(*comm, Teuchos::REDUCE_MAX, root, Teuchos::ptr(&actualRoot));
2089 oss <<
"\n--------------------------------------------------------------------------------\n" <<
2090 "--- RefMaxwell Summary ---\n"
2091 "--------------------------------------------------------------------------------" << std::endl;
2097 SM_Matrix_->getRowMap()->getComm()->barrier();
2099 numRows = SM_Matrix_->getGlobalNumRows();
2100 nnz = SM_Matrix_->getGlobalNumEntries();
2102 Xpetra::global_size_t tt = numRows;
2103 int rowspacer = 3;
while (tt != 0) { tt /= 10; rowspacer++; }
2105 int nnzspacer = 2;
while (tt != 0) { tt /= 10; nnzspacer++; }
2107 oss <<
"block " << std::setw(rowspacer) <<
" rows " << std::setw(nnzspacer) <<
" nnz " << std::setw(9) <<
" nnz/row" << std::endl;
2108 oss <<
"(1, 1)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2110 if (!A22_.is_null()) {
2112 numRows = A22_->getGlobalNumRows();
2113 nnz = A22_->getGlobalNumEntries();
2115 oss <<
"(2, 2)" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
2123 RCP<const Teuchos::MpiComm<int> > mpiComm = rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm);
2124 MPI_Comm rawComm = (*mpiComm->getRawMpiComm())();
2126 int strLength = outstr.size();
2127 MPI_Bcast(&strLength, 1, MPI_INT, root, rawComm);
2128 if (comm->getRank() != root)
2129 outstr.resize(strLength);
2130 MPI_Bcast(&outstr[0], strLength, MPI_CHAR, root, rawComm);
2137 std::ostringstream oss2;
2139 oss2 <<
"Sub-solver distribution over ranks" << std::endl;
2140 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;
2142 int numProcs = comm->getSize();
2144 RCP<const Teuchos::MpiComm<int> > tmpic = rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm);
2145 TEUCHOS_TEST_FOR_EXCEPTION(tmpic == Teuchos::null,
Exceptions::RuntimeError,
"Cannot cast base Teuchos::Comm to Teuchos::MpiComm object.");
2146 RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > rawMpiComm = tmpic->getRawMpiComm();
2152 if (!A22_.is_null())
2154 std::vector<char> states(numProcs, 0);
2156 MPI_Gather(&status, 1, MPI_CHAR, &states[0], 1, MPI_CHAR, 0, *rawMpiComm);
2158 states.push_back(status);
2161 int rowWidth = std::min(Teuchos::as<int>(ceil(sqrt(numProcs))), 100);
2162 for (
int proc = 0; proc < numProcs; proc += rowWidth) {
2163 for (
int j = 0; j < rowWidth; j++)
2164 if (proc + j < numProcs)
2165 if (states[proc+j] == 0)
2167 else if (states[proc+j] == 1)
2169 else if (states[proc+j] == 2)
2176 oss2 <<
" " << proc <<
":" << std::min(proc + rowWidth, numProcs) - 1 << std::endl;
2187 #define MUELU_REFMAXWELL_SHORT
2188 #endif //ifdef MUELU_REFMAXWELL_DEF_HPP