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();
50 const auto invalid = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
54 RCP<Matrix> absD_absPn_absDcT;
59 auto absD = MatrixFactory::BuildCopy(D);
60 absD->setAllToScalar(one);
62 auto absPn = MatrixFactory::BuildCopy(Pn);
63 absPn->setAllToScalar(one);
65 RCP<Matrix> absD_absPn = MatrixMatrix::Multiply(*absD,
false, *absPn,
false, GetOStream(
Statistics2),
true,
true);
66 absD_absPn->setAllToScalar(one);
70 auto comm = absD_absPn->getRowMap()->getComm();
71 if (Dc.is_null() || Dc->getRowMap()->getComm()->getSize() < comm->getSize()) {
72 auto lib = absD_absPn->getRowMap()->lib();
74 Kokkos::View<GlobalOrdinal*, typename Node::memory_space> dummy(
"", 0);
75 auto big_coarse_nodal_map = MapFactory::Build(lib, invalid, dummy, 0, comm);
76 auto big_coarse_edge_map = MapFactory::Build(lib, invalid, dummy, 0, comm);
77 auto big_coarse_nodal_colmap = MapFactory::Build(lib, invalid, dummy, 0, comm);
79 typename Matrix::local_matrix_device_type dummyLocalMatrix;
80 Dc = MatrixFactory::Build(dummyLocalMatrix, big_coarse_edge_map, big_coarse_nodal_colmap, big_coarse_nodal_map, big_coarse_edge_map);
83 auto big_coarse_nodal_map = MapFactory::Build(lib, invalid, Dc->getDomainMap()->getMyGlobalIndicesDevice(), 0, comm);
84 auto big_coarse_edge_map = MapFactory::Build(lib, invalid, Dc->getRangeMap()->getMyGlobalIndicesDevice(), 0, comm);
85 auto big_coarse_nodal_colmap = MapFactory::Build(lib, invalid, Dc->getColMap()->getMyGlobalIndicesDevice(), 0, comm);
87 Dc = MatrixFactory::Build(Dc->getLocalMatrixDevice(), big_coarse_edge_map, big_coarse_nodal_colmap, big_coarse_nodal_map, big_coarse_edge_map);
90 absDc = MatrixFactory::BuildCopy(Dc);
91 absDc->setAllToScalar(one);
93 absD_absPn_absDcT = MatrixMatrix::Multiply(*absD_absPn,
false, *absDc,
true, GetOStream(
Statistics2),
true,
true);
99 using ATS = KokkosKernels::ArithTraits<typename Matrix::impl_scalar_type>;
100 using magnitudeType =
typename ATS::magnitudeType;
101 using magATS = KokkosKernels::ArithTraits<magnitudeType>;
102 auto eps = magATS::epsilon();
104 RCP<MultiVector> oneVec = MultiVectorFactory::Build(absDc->getDomainMap(), 1);
105 oneVec->putScalar(one);
106 RCP<MultiVector> singleParent = MultiVectorFactory::Build(absDc->getRowMap(), 1);
107 absDc->apply(*oneVec, *singleParent, Teuchos::NO_TRANS);
109 RCP<MultiVector> singleParentGhosted;
110 auto importer = absD_absPn_absDcT->getCrsGraph()->getImporter();
111 if (importer.is_null()) {
112 singleParentGhosted = singleParent;
114 singleParentGhosted = MultiVectorFactory::Build(importer->getTargetMap(), 1);
115 singleParentGhosted->doImport(*singleParent, *importer, Xpetra::INSERT);
118 auto lclSingleParent = singleParentGhosted->getLocalViewDevice(Tpetra::Access::ReadOnly);
121 filtered = Xpetra::applyFilter_LID(
125 const typename Matrix::impl_scalar_type val) {
126 return ((ATS::magnitude(val - 2.0) < eps) || ((lclSingleParent(col, 0) == 1.0) && (ATS::magnitude(val - 1.0) < eps)));
130 auto numEntriesBeforeFiltering = absD_absPn_absDcT->getGlobalNumEntries();
131 auto numEntriesAfterFiltering = filtered->getGlobalNumEntries();
132 GetOStream(
Statistics1) <<
"Number of kept entries in filtered pattern for P: " << numEntriesAfterFiltering <<
"/" << numEntriesBeforeFiltering << std::endl;
136 auto Ppattern = filtered->getCrsGraph();
138 Set(coarseLevel,
"Ppattern", Ppattern);