109 typedef Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO> MultiVector_d;
114 RCP<const Map> rowMap = A->getRowMap();
115 RCP<const Map> colMap = A->getColMap();
116 GO GO_INVALID = Teuchos::OrdinalTraits<GO>::invalid();
118 RCP<const Teuchos::Comm<int> > comm = rowMap->getComm();
119 int numProcs = comm->getSize();
120 int myRank = comm->getRank();
122 int numPoints = colMap->getLocalNumElements();
124 bx_ = pL.get<
int>(
"aggregation: brick x size");
125 by_ = pL.get<
int>(
"aggregation: brick y size");
126 bz_ = pL.get<
int>(
"aggregation: brick z size");
128 dirichletX_ = pL.get<
bool>(
"aggregation: brick x Dirichlet");
129 dirichletY_ = pL.get<
bool>(
"aggregation: brick y Dirichlet");
130 dirichletZ_ = pL.get<
bool>(
"aggregation: brick z Dirichlet");
140 RCP<MultiVector_d> overlappedCoords = coords;
141 RCP<const Import> importer = ImportFactory::Build(coords->getMap(), colMap);
142 if (!importer.is_null()) {
143 overlappedCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>
::Build(colMap, coords->getNumVectors());
144 overlappedCoords->doImport(*coords, *importer, Xpetra::INSERT);
149 Setup(comm, overlappedCoords, colMap);
159 RCP<Aggregates> aggregates = rcp(
new Aggregates(colMap));
160 aggregates->setObjectLabel(
"Brick");
162 ArrayRCP<LO> vertex2AggId = aggregates->GetVertex2AggId()->getDataNonConst(0);
163 ArrayRCP<LO> procWinner = aggregates->GetProcWinner()->getDataNonConst(0);
172 std::set<GO> myAggGIDs, remoteAggGIDs;
173 for (LO LID = 0; LID < numPoints; LID++) {
176 if (aggGID == GO_INVALID)
continue;
181 vertex2AggId[LID] = aggGID;
182 myAggGIDs.insert(aggGID);
185 aggregates->SetIsRoot(LID);
188 remoteAggGIDs.insert(aggGID);
191 size_t numAggregates = myAggGIDs.size();
192 size_t numRemote = remoteAggGIDs.size();
193 aggregates->SetNumAggregates(numAggregates);
195 std::map<GO, LO> AggG2L;
196 std::map<GO, int> AggG2R;
198 Array<GO> myAggGIDsArray(numAggregates), remoteAggGIDsArray(numRemote);
202 for (
typename std::set<GO>::const_iterator it = myAggGIDs.begin(); it != myAggGIDs.end(); it++) {
204 AggG2R[*it] = myRank;
206 myAggGIDsArray[ind++] = *it;
210 RCP<Map> aggMap = MapFactory::Build(rowMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
211 myAggGIDsArray, 0, comm);
214 for (
typename std::set<GO>::const_iterator it = remoteAggGIDs.begin(); it != remoteAggGIDs.end(); it++)
215 remoteAggGIDsArray[ind++] = *it;
218 Array<int> remoteProcIDs(numRemote);
219 Array<LO> remoteLIDs(numRemote);
220 aggMap->getRemoteIndexList(remoteAggGIDsArray, remoteProcIDs, remoteLIDs);
223 for (
size_t i = 0; i < numRemote; i++) {
224 AggG2L[remoteAggGIDsArray[i]] = remoteLIDs[i];
225 AggG2R[remoteAggGIDsArray[i]] = remoteProcIDs[i];
229 for (LO LID = 0; LID < numPoints; LID++) {
231 GO aggGID = vertex2AggId[LID];
233 vertex2AggId[LID] = AggG2L[aggGID];
234 procWinner[LID] = AggG2R[aggGID];
241 aggregates->AggregatesCrossProcessors(numGlobalRemote);
243 Set(currentLevel,
"Aggregates", aggregates);
302 const ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& x)
const {
306 RCP<container> gMap = rcp(
new container);
307 for (
int i = 0; i < n; i++)
314 int numProcs = comm->getSize();
316 RCP<const Teuchos::MpiComm<int> > dupMpiComm = rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm->duplicate());
318 MPI_Comm rawComm = (*dupMpiComm->getRawMpiComm())();
320 int sendCnt = gMap->size(), cnt = 0, recvSize;
321 Array<int> recvCnt(numProcs), Displs(numProcs);
322 Array<double> sendBuf, recvBuf;
324 sendBuf.resize(sendCnt);
325 for (
typename container::const_iterator cit = gMap->begin(); cit != gMap->end(); cit++)
326 sendBuf[cnt++] = Teuchos::as<double>(STS::real(cit->first));
328 MPI_Allgather(&sendCnt, 1, MPI_INT, recvCnt.getRawPtr(), 1, MPI_INT, rawComm);
330 for (
int i = 0; i < numProcs - 1; i++)
331 Displs[i + 1] = Displs[i] + recvCnt[i];
332 recvSize = Displs[numProcs - 1] + recvCnt[numProcs - 1];
333 recvBuf.resize(recvSize);
334 MPI_Allgatherv(sendBuf.getRawPtr(), sendCnt, MPI_DOUBLE, recvBuf.getRawPtr(), recvCnt.getRawPtr(), Displs.getRawPtr(), MPI_DOUBLE, rawComm);
336 for (
int i = 0; i < recvSize; i++)
337 (*gMap)[as<SC>(recvBuf[i])] = 0;
342 for (
typename container::iterator it = gMap->begin(); it != gMap->end(); it++)
445 double dirichletThreshold = 0.0;
447 if (
bx_ > 1 && (nDim_ <= 1 || by_ > 1) && (nDim_ <= 2 || bz_ > 1)) {
448 FactoryMonitor m(*
this,
"Generating Graph (trivial)", currentLevel);
451 RCP<LWGraph> graph = rcp(
new LWGraph(A->getCrsGraph(),
"graph of A"));
453 graph->SetBoundaryNodeMap(boundaryNodes);
456 GO numLocalBoundaryNodes = 0;
457 GO numGlobalBoundaryNodes = 0;
458 for (
size_t i = 0; i < boundaryNodes.size(); ++i)
459 if (boundaryNodes(i))
460 numLocalBoundaryNodes++;
461 RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
462 MueLu_sumAll(comm, numLocalBoundaryNodes, numGlobalBoundaryNodes);
465 Set(currentLevel,
"DofsPerNode", 1);
466 Set(currentLevel,
"Graph", graph);
467 Set(currentLevel,
"Filtering",
false);
473 bool drop_x = (
bx_ == 1);
474 bool drop_y = (
nDim_ > 1 &&
by_ == 1);
475 bool drop_z = (
nDim_ > 2 &&
bz_ == 1);
477 typename LWGraph::row_type::non_const_type rows(
"rows", A->getLocalNumRows() + 1);
478 typename LWGraph::entries_type::non_const_type columns(
"columns", A->getLocalNumEntries());
480 size_t N = A->getRowMap()->getLocalNumElements();
483 auto G = A->getLocalMatrixHost().graph;
484 auto rowptr = G.row_map;
485 auto colind = G.entries;
489 for (
size_t row = 0; row < N; row++) {
492 LO row2 = A->getColMap()->getLocalElement(A->getRowMap()->getGlobalElement(row));
495 for (
size_t cidx = rowptr[row]; cidx < rowptr[row + 1]; cidx++) {
497 LO col = colind[cidx];
500 if ((row2 != col) && ((drop_x && ir != ic) || (drop_y && jr != jc) || (drop_z && kr != kc))) {
513 RCP<LWGraph> graph = rcp(
new LWGraph(rows, columns, A->getRowMap(), A->getColMap(),
"thresholded graph of A"));
516 graph->SetBoundaryNodeMap(boundaryNodes);
519 GO numLocalBoundaryNodes = 0;
520 GO numGlobalBoundaryNodes = 0;
521 for (
size_t i = 0; i < boundaryNodes.size(); ++i)
522 if (boundaryNodes(i))
523 numLocalBoundaryNodes++;
524 RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
525 MueLu_sumAll(comm, numLocalBoundaryNodes, numGlobalBoundaryNodes);
528 Set(currentLevel,
"DofsPerNode", 1);
529 Set(currentLevel,
"Graph", graph);
530 Set(currentLevel,
"Filtering",
true);