176 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
177 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
178 using local_matrix_type =
typename MatrixType::local_matrix_type;
179 using local_graph_type =
typename GraphType::local_graph_type;
180 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
181 using entries_type =
typename local_graph_type::entries_type::non_const_type;
182 using values_type =
typename local_matrix_type::values_type::non_const_type;
183 using device_type =
typename Node::device_type;
184 using memory_space =
typename device_type::memory_space;
186 typedef Teuchos::ScalarTraits<SC> STS;
187 typedef typename STS::magnitudeType MT;
188 const MT zero = Teuchos::ScalarTraits<MT>::zero();
197 const typename STS::magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
198 const typename STS::magnitudeType rowSumTol = as<typename STS::magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
202 const std::string algo = pL.get<std::string>(
"aggregation: drop scheme");
203 std::string classicalAlgoStr = pL.get<std::string>(
"aggregation: classical algo");
204 std::string distanceLaplacianAlgoStr = pL.get<std::string>(
"aggregation: distance laplacian algo");
205 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
208 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
209 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
211 threshold = as<MT>(pL.get<
double>(
"aggregation: drop tol"));
212 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
215 const bool lumping = pL.get<
bool>(
"filtered matrix: use lumping");
216 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
217 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
219 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
220 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
222 const MT filteringDirichletThreshold = as<MT>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
223 TEUCHOS_ASSERT(!useRootStencil);
224 TEUCHOS_ASSERT(!useSpreadLumping);
226 if (algo ==
"classical")
227 GetOStream(
Runtime0) <<
"algorithm = \"" << algo <<
"\" classical algorithm = \"" << classicalAlgoStr <<
"\": threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() << std::endl;
228 else if (algo ==
"distance laplacian")
229 GetOStream(
Runtime0) <<
"algorithm = \"" << algo <<
"\" distance laplacian algorithm = \"" << distanceLaplacianAlgoStr <<
"\" distance laplacian metric = \"" << distanceLaplacianMetric <<
"\": threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() << std::endl;
231 GetOStream(
Runtime0) <<
"algorithm = \"" << algo <<
"\": threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() << std::endl;
233 if (((algo ==
"classical") && (classicalAlgoStr.find(
"scaled") != std::string::npos)) || ((algo ==
"distance laplacian") && (distanceLaplacianAlgoStr.find(
"scaled") != std::string::npos)))
234 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
247 auto crsA = toCrsMatrix(A);
248 auto lclA = crsA->getLocalMatrixDevice();
266#define MueLu_runBoundaryFunctors(...) \
268 auto boundaries = BoundaryDetection::BoundaryFunctor(lclA, __VA_ARGS__); \
269 Kokkos::parallel_for("CoalesceDrop::BoundaryDetection", range, boundaries); \
274 if (rowSumTol <= 0.) {
281#undef MueLu_runBoundaryFunctors
313 auto filtered_rowptr = rowptr_type(
"filtered_rowptr", lclA.numRows() + 1);
317 auto results = Kokkos::View<DecisionType*, memory_space>(
"results", lclA.nnz());
321 std::string functorLabel =
"MueLu::CoalesceDrop::CountEntries";
324#if !defined(HAVE_MUELU_DEBUG)
325#define MueLu_runDroppingFunctors(...) \
327 auto countingFunctor = MatrixConstruction::PointwiseCountingFunctor(lclA, results, filtered_rowptr, __VA_ARGS__); \
328 Kokkos::parallel_scan(functorLabel, range, countingFunctor, nnz_filtered); \
331#define MueLu_runDroppingFunctors(...) \
333 auto debug = Misc::DebugFunctor(lclA, results); \
334 auto countingFunctor = MatrixConstruction::PointwiseCountingFunctor(lclA, results, filtered_rowptr, __VA_ARGS__, debug); \
335 Kokkos::parallel_scan(functorLabel, range, countingFunctor, nnz_filtered); \
341 if (threshold != zero) {
345 if (algo ==
"classical" || algo ==
"block diagonal classical") {
346 if (algo ==
"block diagonal classical") {
350 if (classicalAlgoStr ==
"default") {
353 if (aggregationMayCreateDirichlet) {
358 mark_singletons_as_boundary);
365 }
else if (classicalAlgoStr ==
"unscaled cut") {
373 }
else if (classicalAlgoStr ==
"scaled cut") {
381 }
else if (classicalAlgoStr ==
"scaled cut symmetric") {
395 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: classical algo\" must be one of (default|unscaled cut|scaled cut|scaled cut symmetric), not \"" << classicalAlgoStr <<
"\"");
398 if (classicalAlgoStr ==
"default") {
401 if (aggregationMayCreateDirichlet) {
405 mark_singletons_as_boundary);
411 }
else if (classicalAlgoStr ==
"unscaled cut") {
418 }
else if (classicalAlgoStr ==
"scaled cut") {
425 }
else if (classicalAlgoStr ==
"scaled cut symmetric") {
438 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: classical algo\" must be one of (default|unscaled cut|scaled cut|scaled cut symmetric), not \"" << classicalAlgoStr <<
"\"");
441 }
else if (algo ==
"signed classical" || algo ==
"block diagonal signed classical" || algo ==
"block diagonal colored signed classical") {
444 if (algo ==
"block diagonal signed classical" || algo ==
"block diagonal colored signed classical") {
448 if (classicalAlgoStr ==
"default") {
449 if (aggregationMayCreateDirichlet) {
451 signed_classical_rs_dropping,
454 mark_singletons_as_boundary);
458 signed_classical_rs_dropping,
463 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: classical algo\" must be default, not \"" << classicalAlgoStr <<
"\"");
466 if (classicalAlgoStr ==
"default") {
467 if (aggregationMayCreateDirichlet) {
471 mark_singletons_as_boundary);
479 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: classical algo\" must be default, not \"" << classicalAlgoStr <<
"\"");
482 }
else if (algo ==
"signed classical sa") {
483 if (classicalAlgoStr ==
"default") {
486 if (aggregationMayCreateDirichlet) {
490 mark_singletons_as_boundary);
498 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: classical algo\" must be default, not \"" << classicalAlgoStr <<
"\"");
500 }
else if (algo ==
"distance laplacian" || algo ==
"block diagonal distance laplacian") {
501 using doubleMultiVector = Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>;
504 if (algo ==
"block diagonal distance laplacian") {
510 if (distanceLaplacianAlgoStr ==
"default") {
513 if (aggregationMayCreateDirichlet) {
515 dist_laplacian_dropping,
518 mark_singletons_as_boundary);
521 dist_laplacian_dropping,
525 }
else if (distanceLaplacianAlgoStr ==
"unscaled cut") {
533 }
else if (distanceLaplacianAlgoStr ==
"scaled cut") {
541 }
else if (distanceLaplacianAlgoStr ==
"scaled cut symmetric") {
554 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: distance laplacian algo\" must be one of (default|unscaled cut|scaled cut|scaled cut symmetric), not \"" << distanceLaplacianAlgoStr <<
"\"");
557 if (distanceLaplacianAlgoStr ==
"default") {
558 if (distanceLaplacianMetric ==
"unweighted") {
562 if (aggregationMayCreateDirichlet) {
566 mark_singletons_as_boundary);
572 }
else if (distanceLaplacianMetric ==
"material") {
574 if (material->getNumVectors() == 1) {
575 GetOStream(
Runtime0) <<
"material scalar mean = " << material->getVector(0)->meanValue() << std::endl;
580 if (aggregationMayCreateDirichlet) {
584 mark_singletons_as_boundary);
591 TEUCHOS_TEST_FOR_EXCEPTION(coords->getNumVectors() * coords->getNumVectors() != material->getNumVectors(),
Exceptions::RuntimeError,
"Need \"Material\" to have spatialDim^2 vectors.");
594 std::stringstream ss;
595 ss <<
"material tensor mean =" << std::endl;
597 for (
size_t i = 0; i < coords->getNumVectors(); ++i) {
599 for (
size_t j = 0; j < coords->getNumVectors(); ++j) {
600 ss << material->getVector(k)->meanValue() <<
" ";
611 if (aggregationMayCreateDirichlet) {
615 mark_singletons_as_boundary);
624 }
else if (distanceLaplacianAlgoStr ==
"unscaled cut") {
625 if (distanceLaplacianMetric ==
"unweighted") {
633 }
else if (distanceLaplacianMetric ==
"material") {
635 if (material->getNumVectors() == 1) {
636 GetOStream(
Runtime0) <<
"material scalar mean = " << material->getVector(0)->meanValue() << std::endl;
646 TEUCHOS_TEST_FOR_EXCEPTION(coords->getNumVectors() * coords->getNumVectors() != material->getNumVectors(),
Exceptions::RuntimeError,
"Need \"Material\" to have spatialDim^2 vectors.");
649 std::stringstream ss;
650 ss <<
"material tensor mean =" << std::endl;
652 for (
size_t i = 0; i < coords->getNumVectors(); ++i) {
654 for (
size_t j = 0; j < coords->getNumVectors(); ++j) {
655 ss << material->getVector(k)->meanValue() <<
" ";
672 }
else if (distanceLaplacianAlgoStr ==
"scaled cut") {
673 if (distanceLaplacianMetric ==
"unweighted") {
681 }
else if (distanceLaplacianMetric ==
"material") {
683 if (material->getNumVectors() == 1) {
684 GetOStream(
Runtime0) <<
"material scalar mean = " << material->getVector(0)->meanValue() << std::endl;
694 TEUCHOS_TEST_FOR_EXCEPTION(coords->getNumVectors() * coords->getNumVectors() != material->getNumVectors(),
Exceptions::RuntimeError,
"Need \"Material\" to have spatialDim^2 vectors.");
697 std::stringstream ss;
698 ss <<
"material tensor mean =" << std::endl;
700 for (
size_t i = 0; i < coords->getNumVectors(); ++i) {
702 for (
size_t j = 0; j < coords->getNumVectors(); ++j) {
703 ss << material->getVector(k)->meanValue() <<
" ";
720 }
else if (distanceLaplacianAlgoStr ==
"scaled cut symmetric") {
721 if (distanceLaplacianMetric ==
"unweighted") {
729 }
else if (distanceLaplacianMetric ==
"material") {
731 if (material->getNumVectors() == 1) {
732 GetOStream(
Runtime0) <<
"material scalar mean = " << material->getVector(0)->meanValue() << std::endl;
742 TEUCHOS_TEST_FOR_EXCEPTION(coords->getNumVectors() * coords->getNumVectors() != material->getNumVectors(),
Exceptions::RuntimeError,
"Need \"Material\" to have spatialDim^2 vectors.");
745 std::stringstream ss;
746 ss <<
"material tensor mean =" << std::endl;
748 for (
size_t i = 0; i < coords->getNumVectors(); ++i) {
750 for (
size_t j = 0; j < coords->getNumVectors(); ++j) {
751 ss << material->getVector(k)->meanValue() <<
" ";
773 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: distance laplacian algo\" must be one of (default|unscaled cut|scaled cut|scaled cut symmetric), not \"" << distanceLaplacianAlgoStr <<
"\"");
776 }
else if (algo ==
"block diagonal") {
782 TEUCHOS_ASSERT(
false);
785 Kokkos::deep_copy(results,
KEEP);
791#undef MueLu_runDroppingFunctors
793 GO numDropped = lclA.nnz() - nnz_filtered;
801 RCP<Matrix> filteredA;
802 RCP<LWGraph_kokkos> graph;
806 local_matrix_type lclFilteredA;
807 local_graph_type lclGraph;
809 filteredA = MatrixFactory::BuildCopy(A);
810 lclFilteredA = filteredA->getLocalMatrixDevice();
812 auto colidx = entries_type(
"entries", nnz_filtered);
813 lclGraph = local_graph_type(colidx, filtered_rowptr);
815 auto colidx = entries_type(
"entries", nnz_filtered);
816 auto values = values_type(
"values", nnz_filtered);
817 lclFilteredA = local_matrix_type(
"filteredA",
818 lclA.numRows(), lclA.numCols(),
820 values, filtered_rowptr, colidx);
826 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
829 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
834 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
837 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
842 filteredA = MatrixFactory::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
843 filteredA->SetFixedBlockSize(A->GetFixedBlockSize());
845 if (reuseEigenvalue) {
850 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
852 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
857 lclGraph = filteredA->getCrsGraph()->getLocalGraphDevice();
859 graph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
860 graph->SetBoundaryNodeMap(boundaryNodes);
864 Set(currentLevel,
"DofsPerNode", dofsPerNode);
865 Set(currentLevel,
"Graph", graph);
866 Set(currentLevel,
"A", filteredA);
868 return std::make_tuple(numDropped, boundaryNodes);
876 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
877 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
878 using local_matrix_type =
typename MatrixType::local_matrix_type;
879 using local_graph_type =
typename GraphType::local_graph_type;
880 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
881 using entries_type =
typename local_graph_type::entries_type::non_const_type;
882 using values_type =
typename local_matrix_type::values_type::non_const_type;
883 using device_type =
typename Node::device_type;
884 using memory_space =
typename device_type::memory_space;
886 typedef Teuchos::ScalarTraits<SC> STS;
887 typedef typename STS::magnitudeType MT;
888 const MT zero = Teuchos::ScalarTraits<MT>::zero();
909 TEUCHOS_TEST_FOR_EXCEPTION(A->GetFixedBlockSize() % A->GetStorageBlockSize() != 0,
Exceptions::RuntimeError,
"A->GetFixedBlockSize() needs to be a multiple of A->GetStorageBlockSize()");
910 LO blkSize = A->GetFixedBlockSize() / A->GetStorageBlockSize();
914 const RCP<const Map> rowMap = A->getRowMap();
915 const RCP<const Map> colMap = A->getColMap();
922 const RCP<const Map> uniqueMap = amalInfo->getNodeRowMap();
923 const RCP<const Map> nonUniqueMap = amalInfo->getNodeColMap();
924 Array<LO> rowTranslationArray = *(amalInfo->getRowTranslation());
925 Array<LO> colTranslationArray = *(amalInfo->getColTranslation());
927 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
928 rowTranslationView(rowTranslationArray.getRawPtr(), rowTranslationArray.size());
929 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
930 colTranslationView(colTranslationArray.getRawPtr(), colTranslationArray.size());
933 LO numNodes = Teuchos::as<LocalOrdinal>(uniqueMap->getLocalNumElements());
934 typedef typename Kokkos::View<LocalOrdinal*, typename Node::device_type> id_translation_type;
935 id_translation_type rowTranslation(
"dofId2nodeId", rowTranslationArray.size());
936 id_translation_type colTranslation(
"ov_dofId2nodeId", colTranslationArray.size());
937 Kokkos::deep_copy(rowTranslation, rowTranslationView);
938 Kokkos::deep_copy(colTranslation, colTranslationView);
941 blkSize = A->GetFixedBlockSize();
944 if (A->IsView(
"stridedMaps") ==
true) {
945 const RCP<const Map> myMap = A->getRowMap(
"stridedMaps");
946 const RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(myMap);
948 blkSize = Teuchos::as<const LocalOrdinal>(strMap->getFixedBlockSize());
949 blkId = strMap->getStridedBlockId();
951 blkPartSize = Teuchos::as<LocalOrdinal>(strMap->getStridingData()[blkId]);
954 TEUCHOS_TEST_FOR_EXCEPTION(A->getRowMap()->getLocalNumElements() % blkPartSize != 0,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: Number of local elements is " << A->getRowMap()->getLocalNumElements() <<
" but should be a multiple of " << blkPartSize);
961 const typename STS::magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
962 const typename STS::magnitudeType rowSumTol = as<typename STS::magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
964 const bool useGreedyDirichlet = pL.get<
bool>(
"aggregation: greedy Dirichlet");
965 TEUCHOS_TEST_FOR_EXCEPTION(rowSumTol > zero,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: RowSum is not implemented for vectorial problems.");
968 const std::string algo = pL.get<std::string>(
"aggregation: drop scheme");
969 std::string classicalAlgoStr = pL.get<std::string>(
"aggregation: classical algo");
970 std::string distanceLaplacianAlgoStr = pL.get<std::string>(
"aggregation: distance laplacian algo");
971 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
974 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
975 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
977 threshold = as<MT>(pL.get<
double>(
"aggregation: drop tol"));
978 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
981 const bool lumping = pL.get<
bool>(
"filtered matrix: use lumping");
982 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
983 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
985 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
986 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
988 const MT filteringDirichletThreshold = as<MT>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
990 TEUCHOS_ASSERT(!useRootStencil);
991 TEUCHOS_ASSERT(!useSpreadLumping);
993 if (algo ==
"classical") {
994 GetOStream(
Runtime0) <<
"algorithm = \"" << algo <<
"\" classical algorithm = \"" << classicalAlgoStr <<
"\": threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() << std::endl;
995 }
else if (algo ==
"distance laplacian") {
996 GetOStream(
Runtime0) <<
"algorithm = \"" << algo <<
"\" distance laplacian algorithm = \"" << distanceLaplacianAlgoStr <<
"\" distance laplacian metric = \"" << distanceLaplacianMetric <<
"\": threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() << std::endl;
998 GetOStream(
Runtime0) <<
"algorithm = \"" << algo <<
"\": threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() << std::endl;
1011 auto crsA = toCrsMatrix(A);
1012 auto lclA = crsA->getLocalMatrixDevice();
1027#define MueLu_runBoundaryFunctors(...) \
1029 auto boundaries = BoundaryDetection::BoundaryFunctor(lclA, __VA_ARGS__); \
1030 Kokkos::parallel_for("CoalesceDrop::BoundaryDetection", range, boundaries); \
1033 if (useGreedyDirichlet) {
1040#undef MueLu_runBoundaryFunctors
1068 auto filtered_rowptr = rowptr_type(
"rowptr", lclA.numRows() + 1);
1069 auto graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
1071 Kokkos::pair<LocalOrdinal, LocalOrdinal> nnz = {0, 0};
1074 auto results = Kokkos::View<DecisionType*, memory_space>(
"results", lclA.nnz());
1078 std::string functorLabel =
"MueLu::CoalesceDrop::CountEntries";
1080#if !defined(HAVE_MUELU_DEBUG)
1081#define MueLu_runDroppingFunctors(...) \
1083 auto countingFunctor = MatrixConstruction::VectorCountingFunctor(lclA, blkPartSize, colTranslation, results, filtered_rowptr, graph_rowptr, __VA_ARGS__); \
1084 Kokkos::parallel_scan(functorLabel, range, countingFunctor, nnz); \
1087#define MueLu_runDroppingFunctors(...) \
1089 auto debug = Misc::DebugFunctor(lclA, results); \
1090 auto countingFunctor = MatrixConstruction::VectorCountingFunctor(lclA, blkPartSize, colTranslation, results, filtered_rowptr, graph_rowptr, __VA_ARGS__, debug); \
1091 Kokkos::parallel_scan(functorLabel, range, countingFunctor, nnz); \
1097 if (threshold != zero) {
1101 if (algo ==
"classical") {
1102 if (classicalAlgoStr ==
"default") {
1105 if (aggregationMayCreateDirichlet) {
1109 mark_singletons_as_boundary);
1113 preserve_diagonals);
1115 }
else if (classicalAlgoStr ==
"unscaled cut") {
1116 TEUCHOS_ASSERT(
false);
1117 }
else if (classicalAlgoStr ==
"scaled cut") {
1118 TEUCHOS_ASSERT(
false);
1119 }
else if (classicalAlgoStr ==
"scaled cut symmetric") {
1120 TEUCHOS_ASSERT(
false);
1122 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: classical algo\" must be one of (default|unscaled cut|scaled cut|scaled cut symmetric), not \"" << classicalAlgoStr <<
"\"");
1124 }
else if (algo ==
"signed classical" || algo ==
"block diagonal colored signed classical" || algo ==
"block diagonal signed classical") {
1127 if (aggregationMayCreateDirichlet) {
1131 mark_singletons_as_boundary);
1136 preserve_diagonals);
1138 }
else if (algo ==
"signed classical sa") {
1141 if (aggregationMayCreateDirichlet) {
1145 mark_singletons_as_boundary);
1150 preserve_diagonals);
1152 }
else if (algo ==
"distance laplacian") {
1153 using doubleMultiVector = Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>;
1158 if (distanceLaplacianAlgoStr ==
"default") {
1161 if (aggregationMayCreateDirichlet) {
1165 mark_singletons_as_boundary);
1169 preserve_diagonals);
1171 }
else if (distanceLaplacianAlgoStr ==
"unscaled cut") {
1172 TEUCHOS_ASSERT(
false);
1173 }
else if (distanceLaplacianAlgoStr ==
"scaled cut") {
1174 TEUCHOS_ASSERT(
false);
1175 }
else if (distanceLaplacianAlgoStr ==
"scaled cut symmetric") {
1176 TEUCHOS_ASSERT(
false);
1178 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"\"aggregation: distance laplacian algo\" must be one of (default|unscaled cut|scaled cut|scaled cut symmetric), not \"" << distanceLaplacianAlgoStr <<
"\"");
1181 TEUCHOS_ASSERT(
false);
1184 Kokkos::deep_copy(results,
KEEP);
1189#undef MueLu_runDroppingFunctors
1193 GO numTotal = lclA.nnz();
1194 GO numDropped = numTotal - nnz_filtered;
1202 RCP<Matrix> filteredA;
1203 RCP<LWGraph_kokkos> graph;
1207 local_matrix_type lclFilteredA;
1209 lclFilteredA = local_matrix_type(
"filteredA", lclA.graph, lclA.numCols());
1211 auto colidx = entries_type(
"entries", nnz_filtered);
1212 auto values = values_type(
"values", nnz_filtered);
1213 lclFilteredA = local_matrix_type(
"filteredA",
1214 lclA.numRows(), lclA.numCols(),
1216 values, filtered_rowptr, colidx);
1219 local_graph_type lclGraph;
1221 auto colidx = entries_type(
"entries", nnz_graph);
1222 lclGraph = local_graph_type(colidx, graph_rowptr);
1228 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
1231 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
1236 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
1239 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
1243 filteredA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
1244 filteredA->SetFixedBlockSize(blkSize);
1246 if (reuseEigenvalue) {
1251 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
1253 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
1256 graph = rcp(
new LWGraph_kokkos(lclGraph, uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1257 graph->SetBoundaryNodeMap(boundaryNodes);
1260 LO dofsPerNode = blkSize;
1262 Set(currentLevel,
"DofsPerNode", dofsPerNode);
1263 Set(currentLevel,
"Graph", graph);
1264 Set(currentLevel,
"A", filteredA);
1266 return std::make_tuple(numDropped, boundaryNodes);