59 using GlobalToDomesticMap = std::map<Index, Index>;
60 using DomesticToGlobalMap = std::map<Index, Index>;
64 : foreignOverlap_(foreignOverlap)
72 MPI_Comm_rank(MPI_COMM_WORLD, &tmp);
74 MPI_Comm_size(MPI_COMM_WORLD, &tmp);
75 mpiSize_ =
static_cast<size_t>(tmp);
82 buildGlobalIndices_();
90 assert(domesticToGlobal_.find(domesticIdx) != domesticToGlobal_.end());
92 return domesticToGlobal_.find(domesticIdx)->second;
100 const auto& tmp = globalToDomestic_.find(globalIdx);
102 if (tmp == globalToDomestic_.end())
113 {
return foreignOverlap_.numLocal(); }
122 {
return numDomestic_; }
129 domesticToGlobal_[domesticIdx] = globalIdx;
130 globalToDomestic_[globalIdx] = domesticIdx;
131 numDomestic_ = domesticToGlobal_.size();
133 assert(domesticToGlobal_.size() == globalToDomestic_.size());
140 [[maybe_unused]]
Index domesticIdx,
141 [[maybe_unused]]
Index peerLocalIdx)
145 sendBuf.peerIdx = peerLocalIdx;
150 static_cast<int>(peerRank),
167 static_cast<int>(peerRank),
172 Index domesticIdx = foreignOverlap_.nativeToLocal(recvBuf.peerIdx);
173 if (domesticIdx >= 0) {
174 Index globalIdx = recvBuf.globalIdx;
184 {
return globalToDomestic_.find(globalIdx) != globalToDomestic_.end(); }
192 std::cout <<
"(domestic index, global index, domestic->global->domestic)"
193 <<
" list for rank " << myRank_ <<
"\n";
195 for (
size_t domIdx = 0; domIdx < domesticToGlobal_.size(); ++domIdx)
198 std::cout <<
"\n" << std::flush;
204 void buildGlobalIndices_()
209 numDomestic_ = foreignOverlap_.numLocal();
220 MPI_Recv(&domesticOffset_,
223 static_cast<int>(myRank_ - 1),
232 for (
unsigned i = 0; i < foreignOverlap_.numLocal(); ++i) {
233 if (!foreignOverlap_.iAmMasterOf(
static_cast<Index
>(i)))
237 static_cast<Index
>(domesticOffset_ + numMaster));
241 if (myRank_ < mpiSize_ - 1) {
244 int tmp = domesticOffset_ + numMaster;
248 static_cast<int>(myRank_ + 1),
253 typename PeerSet::const_iterator peerIt;
254 typename PeerSet::const_iterator peerEndIt = peerSet_().end();
256 peerIt = peerSet_().begin();
257 for (; peerIt != peerEndIt; ++peerIt) {
258 if (*peerIt < myRank_)
259 receiveBorderFrom_(*peerIt);
263 peerIt = peerSet_().begin();
264 for (; peerIt != peerEndIt; ++peerIt) {
265 if (*peerIt > myRank_)
266 sendBorderTo_(*peerIt);
270 peerIt = peerSet_().begin();
271 for (; peerIt != peerEndIt; ++peerIt) {
272 if (*peerIt > myRank_)
273 receiveBorderFrom_(*peerIt);
277 peerIt = peerSet_().begin();
278 for (; peerIt != peerEndIt; ++peerIt) {
279 if (*peerIt < myRank_)
280 sendBorderTo_(*peerIt);
285 void sendBorderTo_([[maybe_unused]] ProcessRank peerRank)
290 BorderList::const_iterator borderIt = borderList_().begin();
291 BorderList::const_iterator borderEndIt = borderList_().end();
292 for (; borderIt != borderEndIt; ++borderIt) {
295 if (borderPeer != peerRank || borderDistance != 0)
298 Index localIdx = foreignOverlap_.nativeToLocal(borderIt->localIdx);
299 Index peerIdx = borderIt->peerIdx;
300 assert(localIdx >= 0);
301 if (foreignOverlap_.iAmMasterOf(localIdx)) {
308 void receiveBorderFrom_([[maybe_unused]] ProcessRank peerRank)
313 BorderList::const_iterator borderIt = borderList_().begin();
314 BorderList::const_iterator borderEndIt = borderList_().end();
315 for (; borderIt != borderEndIt; ++borderIt) {
318 if (borderPeer != peerRank || borderDistance != 0)
321 Index nativeIdx = borderIt->localIdx;
322 Index localIdx = foreignOverlap_.nativeToLocal(nativeIdx);
323 if (localIdx >= 0 && foreignOverlap_.masterRank(localIdx) == borderPeer)
329 const PeerSet& peerSet_()
const
330 {
return foreignOverlap_.peerSet(); }
333 {
return foreignOverlap_.borderList(); }
340 const ForeignOverlap& foreignOverlap_;
342 GlobalToDomesticMap globalToDomestic_;
343 DomesticToGlobalMap domesticToGlobal_;