45 auto D = Get<RCP<Matrix> >(fineLevel,
"D0",
"FineD0");
46 auto Dc = Get<RCP<Matrix> >(coarseLevel,
"D0",
"CoarseD0");
47 auto Pn = Get<RCP<Matrix> >(coarseLevel,
"PnodalEmin");
49 const auto one = Teuchos::ScalarTraits<Scalar>::one();
53 RCP<Matrix> absD_absPn_absDcT;
58 auto absD = MatrixFactory::BuildCopy(D);
59 absD->setAllToScalar(one);
61 auto absPn = MatrixFactory::BuildCopy(Pn);
62 absPn->setAllToScalar(one);
64 RCP<Matrix> absD_absPn = MatrixMatrix::Multiply(*absD,
false, *absPn,
false, GetOStream(
Statistics2),
true,
true);
65 absD_absPn->setAllToScalar(one);
69 auto comm = absD_absPn->getRowMap()->getComm();
70 if (Dc.is_null() || Dc->getRowMap()->getComm()->getSize() < comm->getSize()) {
71 auto lib = absD_absPn->getRowMap()->lib();
73 Kokkos::View<GlobalOrdinal*, typename Node::memory_space> dummy(
"", 0);
74 auto big_coarse_nodal_map = MapFactory::Build(lib, -1, dummy, 0, comm);
75 auto big_coarse_edge_map = MapFactory::Build(lib, -1, dummy, 0, comm);
76 auto big_coarse_nodal_colmap = MapFactory::Build(lib, -1, dummy, 0, comm);
78 typename Matrix::local_matrix_device_type dummyLocalMatrix;
79 Dc = MatrixFactory::Build(dummyLocalMatrix, big_coarse_edge_map, big_coarse_nodal_colmap, big_coarse_nodal_map, big_coarse_edge_map);
82 auto big_coarse_nodal_map = MapFactory::Build(lib, -1, Dc->getDomainMap()->getMyGlobalIndicesDevice(), 0, comm);
83 auto big_coarse_edge_map = MapFactory::Build(lib, -1, Dc->getRangeMap()->getMyGlobalIndicesDevice(), 0, comm);
84 auto big_coarse_nodal_colmap = MapFactory::Build(lib, -1, Dc->getColMap()->getMyGlobalIndicesDevice(), 0, comm);
86 Dc = MatrixFactory::Build(Dc->getLocalMatrixDevice(), big_coarse_edge_map, big_coarse_nodal_colmap, big_coarse_nodal_map, big_coarse_edge_map);
89 absDc = MatrixFactory::BuildCopy(Dc);
90 absDc->setAllToScalar(one);
92 absD_absPn_absDcT = MatrixMatrix::Multiply(*absD_absPn,
false, *absDc,
true, GetOStream(
Statistics2),
true,
true);
98 using ATS = KokkosKernels::ArithTraits<typename Matrix::impl_scalar_type>;
99 using magnitudeType =
typename ATS::magnitudeType;
100 using magATS = KokkosKernels::ArithTraits<magnitudeType>;
101 auto eps = magATS::epsilon();
103 RCP<MultiVector> oneVec = MultiVectorFactory::Build(absDc->getDomainMap(), 1);
104 oneVec->putScalar(one);
105 RCP<MultiVector> singleParent = MultiVectorFactory::Build(absDc->getRowMap(), 1);
106 absDc->apply(*oneVec, *singleParent, Teuchos::NO_TRANS);
108 RCP<MultiVector> singleParentGhosted;
109 auto importer = absD_absPn_absDcT->getCrsGraph()->getImporter();
110 if (importer.is_null()) {
111 singleParentGhosted = singleParent;
113 singleParentGhosted = MultiVectorFactory::Build(importer->getTargetMap(), 1);
114 singleParentGhosted->doImport(*singleParent, *importer, Xpetra::INSERT);
117 auto lclSingleParent = singleParentGhosted->getLocalViewDevice(Tpetra::Access::ReadOnly);
120 filtered = Xpetra::applyFilter_LID(
124 const typename Matrix::impl_scalar_type val) {
125 return ((ATS::magnitude(val - 2.0) < eps) || ((lclSingleParent(col, 0) == 1.0) && (ATS::magnitude(val - 1.0) < eps)));
129 auto numEntriesBeforeFiltering = absD_absPn_absDcT->getGlobalNumEntries();
130 auto numEntriesAfterFiltering = filtered->getGlobalNumEntries();
131 GetOStream(
Statistics1) <<
"Number of kept entries in filtered pattern for P: " << numEntriesAfterFiltering <<
"/" << numEntriesBeforeFiltering << std::endl;
135 auto Ppattern = filtered->getCrsGraph();
137 Set(coarseLevel,
"Ppattern", Ppattern);