46 #ifndef MUELU_BRICKAGGREGATIONFACTORY_DEF_HPP_
47 #define MUELU_BRICKAGGREGATIONFACTORY_DEF_HPP_
52 #include <Teuchos_CommHelpers.hpp>
64 #include "MueLu_Aggregates.hpp"
68 #include "MueLu_Utilities.hpp"
72 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
76 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
80 #undef SET_VALID_ENTRY
85 return validParamList;
88 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
90 Input(currentLevel,
"A");
91 Input(currentLevel,
"Coordinates");
138 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
147 RCP<Matrix> A = Get< RCP<Matrix> > (currentLevel,
"A");
152 int numProcs = comm->getSize();
153 int myRank = comm->getRank();
155 int numPoints = colMap->getNodeNumElements();
157 bx_ = pL.
get<
int>(
"aggregation: brick x size");
158 by_ = pL.
get<
int>(
"aggregation: brick y size");
159 bz_ = pL.
get<
int>(
"aggregation: brick z size");
175 Setup(comm, overlappedCoords, colMap);
177 GetOStream(
Runtime0) <<
"Using brick size: " << bx_
178 << (nDim_ > 1 ?
"x " +
toString(by_) :
"")
179 << (nDim_ > 2 ?
"x " +
toString(bz_) :
"") << std::endl;
183 aggregates->setObjectLabel(
"Brick");
185 ArrayRCP<LO> vertex2AggId = aggregates->GetVertex2AggId()->getDataNonConst(0);
186 ArrayRCP<LO> procWinner = aggregates->GetProcWinner() ->getDataNonConst(0);
195 std::set<GO> myAggGIDs, remoteAggGIDs;
196 for (LO LID = 0; LID < numPoints; LID++) {
197 GO aggGID = getAggGID(LID);
199 if ((revMap_.find(getRoot(LID)) != revMap_.end()) && rowMap->isNodeGlobalElement(colMap->getGlobalElement(revMap_[getRoot(LID)]))) {
201 vertex2AggId[LID] = aggGID;
202 myAggGIDs.insert(aggGID);
205 aggregates->SetIsRoot(LID);
208 remoteAggGIDs.insert(aggGID);
211 size_t numAggregates = myAggGIDs .
size();
212 size_t numRemote = remoteAggGIDs.size();
213 aggregates->SetNumAggregates(numAggregates);
215 std::map<GO,LO> AggG2L;
216 std::map<GO,int> AggG2R;
218 Array<GO> myAggGIDsArray(numAggregates), remoteAggGIDsArray(numRemote);
222 for (
typename std::set<GO>::const_iterator it = myAggGIDs.begin(); it != myAggGIDs.end(); it++) {
224 AggG2R[*it] = myRank;
226 myAggGIDsArray[ind++] = *it;
231 myAggGIDsArray, 0, comm);
234 for (
typename std::set<GO>::const_iterator it = remoteAggGIDs.begin(); it != remoteAggGIDs.end(); it++)
235 remoteAggGIDsArray[ind++] = *it;
240 aggMap->getRemoteIndexList(remoteAggGIDsArray, remoteProcIDs, remoteLIDs);
243 for (
size_t i = 0; i < numRemote; i++) {
244 AggG2L[remoteAggGIDsArray[i]] = remoteLIDs [i];
245 AggG2R[remoteAggGIDsArray[i]] = remoteProcIDs[i];
249 for (LO LID = 0; LID < numPoints; LID++) {
250 if (revMap_.find(getRoot(LID)) != revMap_.end() && rowMap->isNodeGlobalElement(colMap->getGlobalElement(revMap_[getRoot(LID)]))) {
251 GO aggGID = vertex2AggId[LID];
253 vertex2AggId[LID] = AggG2L[aggGID];
254 procWinner [LID] = AggG2R[aggGID];
260 aggregates->AggregatesCrossProcessors(numGlobalRemote);
262 Set(currentLevel,
"Aggregates", aggregates);
264 GetOStream(
Statistics1) << aggregates->description() << std::endl;
267 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
270 nDim_ = coords->getNumVectors();
272 x_ = coords->getData(0);
273 xMap_ = Construct1DMap(comm, x_);
278 y_ = coords->getData(1);
279 yMap_ = Construct1DMap(comm, y_);
285 z_ = coords->getData(2);
286 zMap_ = Construct1DMap(comm, z_);
290 for (
size_t ind = 0; ind < coords->getLocalLength(); ind++) {
291 GO i = (*xMap_)[(coords->getData(0))[ind]], j = 0, k = 0;
293 j = (*yMap_)[(coords->getData(1))[ind]];
295 k = (*zMap_)[(coords->getData(2))[ind]];
297 revMap_[k*ny_*nx_ + j*nx_ + i] = ind;
301 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
311 for (
int i = 0; i < n; i++)
318 int numProcs = comm->getSize();
322 MPI_Comm rawComm = (*dupMpiComm->getRawMpiComm())();
324 int sendCnt = gMap->size(), cnt = 0, recvSize;
325 Array<int> recvCnt(numProcs), Displs(numProcs);
329 for (
typename container::const_iterator cit = gMap->begin(); cit != gMap->end(); cit++)
330 sendBuf[cnt++] = Teuchos::as<double>(STS::real(cit->first));
332 MPI_Allgather(&sendCnt, 1, MPI_INT, recvCnt.getRawPtr(), 1, MPI_INT, rawComm);
334 for (
int i = 0; i < numProcs-1; i++)
335 Displs[i+1] = Displs[i] + recvCnt[i];
336 recvSize = Displs[numProcs-1] + recvCnt[numProcs-1];
338 MPI_Allgatherv(sendBuf.
getRawPtr(), sendCnt, MPI_DOUBLE, recvBuf.
getRawPtr(), recvCnt.getRawPtr(), Displs.getRawPtr(), MPI_DOUBLE, rawComm);
340 for (
int i = 0; i < recvSize; i++)
341 (*gMap)[as<SC>(recvBuf[i])] = 0;
346 for (
typename container::iterator it = gMap->begin(); it != gMap->end(); it++)
352 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
354 int i = (*xMap_)[x_[LID]], j = 0, k = 0;
356 j = (*yMap_)[y_[LID]];
358 k = (*zMap_)[z_[LID]];
360 return (k*ny_*nx_ + j*nx_ + i) == getRoot(LID);
363 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
365 int i = ((*xMap_)[x_[LID]]/bx_)*bx_ + (bx_-1)/2, j = 0, k = 0;
367 j = ((*yMap_)[y_[LID]]/by_)*by_ + (by_-1)/2;
369 k = ((*zMap_)[z_[LID]]/bz_)*bz_ + (bz_-1)/2;
372 if (i > nx_) i = nx_;
373 if (j > ny_) j = ny_;
374 if (k > nz_) k = nz_;
376 return k*ny_*nx_ + j*nx_ + i;
379 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
381 int naggx = nx_/bx_ + (nx_ % bx_ ? 1 : 0), naggy = 1;
382 int i = (*xMap_)[x_[LID]]/bx_, j = 0;
385 naggy = ny_/by_ + (ny_ % by_ ? 1 : 0);
386 j = (*yMap_)[y_[LID]]/by_;
389 k = (*zMap_)[z_[LID]]/bz_;
391 return Teuchos::as<GlobalOrdinal>(k*naggy*naggx) + Teuchos::as<GlobalOrdinal>(j*naggx) + i;
#define MueLu_sumAll(rcpComm, in, out)
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
Container class for aggregation information.
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
One-liner description of what is happening.
void Build(Level ¤tLevel) const
Build aggregates.
GlobalOrdinal getAggGID(LocalOrdinal LID) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
void Setup(const RCP< const Teuchos::Comm< int > > &comm, const RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::magnitudeType, LO, GO, NO > > &coords, const RCP< const Map > &map) const
void resize(size_type new_size, const value_type &x=value_type())
bool isRoot(LocalOrdinal LID) const
RCP< container > Construct1DMap(const RCP< const Teuchos::Comm< int > > &comm, const ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &x) const
std::map< Scalar, GlobalOrdinal, compare > container
GlobalOrdinal getRoot(LocalOrdinal LID) const
void DeclareInput(Level ¤tLevel) const
Input.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
#define SET_VALID_ENTRY(name)