5#ifndef DUNE_COMMON_PARALLEL_REMOTEINDICES_HH
6#define DUNE_COMMON_PARALLEL_REMOTEINDICES_HH
41 template<
typename TG,
typename TA>
45 inline static MPI_Datatype getType();
47 static MPI_Datatype type;
51 template<
typename T,
typename A>
54 template<
typename T1,
typename T2>
61 template<
typename T1,
typename T2>
65 template<
typename T,
typename A,
bool mode>
72 template<
typename T1,
typename T2>
78 template<
typename T,
typename A,
typename A1>
83 template<
typename T,
typename A,
bool mode>
154 template<
class T,
class A>
159 template<
class T,
class A>
167 template<
typename T1,
typename T2>
187 template<
class T,
class A=std::allocator<
RemoteIndex<
typename T::GlobalIndex,
188 typename T::LocalIndex::Attribute> > >
193 template<
typename T1,
typename A2,
typename A1>
198 template<
class G,
class T1,
class T2>
238 using Allocator =
typename std::allocator_traits<A>::template rebind_alloc<RemoteIndex>;
245 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
248 typedef typename RemoteIndexMap::const_iterator const_iterator;
268 const MPI_Comm& comm,
const std::vector<int>&
neighbours=std::vector<int>(),
bool includeSelf=
false);
298 const MPI_Comm& comm,
const std::vector<int>&
neighbours=std::vector<int>());
303 neighbourIds.clear();
308 const std::set<int>& getNeighbours()
const
327 template<
bool ignorePublic>
360 template<
bool mode,
bool send>
369 inline const_iterator
find(
int proc)
const;
375 inline const_iterator
begin()
const;
381 inline const_iterator
end()
const;
421 std::set<int> neighbourIds;
424 const static int commTag_=333;
478 template<
bool ignorePublic>
479 inline void buildRemote(
bool includeSelf);
499 template<
bool ignorePublic>
501 char* p_out, MPI_Datatype type,
int bufferSize,
502 int* position,
int n);
518 PairType** local,
int localEntries,
char* p_in,
519 MPI_Datatype type,
int* position,
int bufferSize,
523 int remoteEntries,
PairType** localSource,
524 int localSourceEntries,
PairType** localDest,
525 int localDestEntries,
char* p_in,
526 MPI_Datatype type,
int* position,
int bufferSize);
528 void unpackCreateRemote(
char* p_in,
PairType** sourcePairs,
PairType** DestPairs,
529 int remoteProc,
int sourcePublish,
int destPublish,
530 int bufferSize,
bool sendTwo,
bool fromOurSelf=
false);
548 template<
class T,
class A,
bool mode>
552 template<
typename T1,
typename A1>
695 GlobalModifyIterator giter_;
705 template<
class T,
class A>
712 typedef T ParallelIndexSet;
727 typedef typename LocalIndex::Attribute Attribute;
733 using Allocator =
typename std::allocator_traits<A>::template rebind_alloc<RemoteIndex>;
746 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
764 inline void advance(
const GlobalIndex& global);
775 inline void advance(
const GlobalIndex& global,
const Attribute& attribute);
782 inline bool empty()
const;
793 typedef typename Map::iterator RealIterator;
794 typedef typename Map::iterator ConstRealIterator;
798 iterator(
const RealIterator& iter,
const ConstRealIterator& end, GlobalIndex& index)
799 : iter_(iter), end_(end), index_(index), hasAttribute(false)
802 while(iter_!=end_ && iter_->second.first->localIndexPair().global()!=index_)
806 iterator(
const RealIterator& iter,
const ConstRealIterator& end, GlobalIndex index,
808 : iter_(iter), end_(end), index_(index), attribute_(attribute), hasAttribute(true)
811 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_
812 || iter_->second.first->localIndexPair().local().attribute()!=attribute))
817 : iter_(other.iter_), end_(other.end_), index_(other.index_)
825 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_ ||
827 iter_->second.first->localIndexPair().local().attribute()!=attribute_)))
829 assert(iter_==end_ ||
830 (iter_->second.first->localIndexPair().global()==index_));
831 assert(iter_==end_ || !hasAttribute ||
832 (iter_->second.first->localIndexPair().local().attribute()==attribute_));
839 return *(iter_->second.first);
851 return iter_->second.first.operator->();
857 return other.iter_==iter_;
863 return other.iter_!=iter_;
872 Attribute attribute_;
884 Attribute attribute_;
888 template<
typename TG,
typename TA>
889 MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::getType()
891 if(type==MPI_DATATYPE_NULL) {
892 int length[2] = {1, 1};
895 MPI_Datatype types[2] = {MPITraits<TG>::getType(),
896 MPITraits<ParallelLocalIndex<TA> >::getType()};
897 IndexPair<TG,ParallelLocalIndex<TA> > rep;
898 MPI_Get_address(&rep, &base);
899 MPI_Get_address(&(rep.global_), &disp[0]);
900 MPI_Get_address(&(rep.local_), &disp[1]);
901 for (MPI_Aint& d : disp)
905 MPI_Type_create_struct(2, length, disp, types, &tmp);
907 MPI_Type_create_resized(tmp, 0,
sizeof(IndexPair<TG,ParallelLocalIndex<TA> >), &type);
908 MPI_Type_commit(&type);
915 template<
typename TG,
typename TA>
916 MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::type=MPI_DATATYPE_NULL;
918 template<
typename T1,
typename T2>
920 : localIndex_(local), attribute_(static_cast<
std::underlying_type_t<T2>>(attribute))
923 template<
typename T1,
typename T2>
925 : localIndex_(0), attribute_(static_cast<
std::underlying_type_t<T2>>(attribute))
928 template<
typename T1,
typename T2>
930 : localIndex_(0), attribute_()
932 template<
typename T1,
typename T2>
935 return localIndex_==ri.localIndex_ && attribute_==ri.attribute_;
938 template<
typename T1,
typename T2>
939 inline bool RemoteIndex<T1,T2>::operator!=(
const RemoteIndex& ri)
const
941 return localIndex_!=ri.localIndex_ || attribute_!=ri.attribute_;
944 template<
typename T1,
typename T2>
947 return T2(attribute_);
950 template<
typename T1,
typename T2>
956 template<
typename T,
typename A>
959 const MPI_Comm& comm,
960 const std::vector<int>& neighbours,
962 : source_(&source), target_(&destination), comm_(comm),
963 sourceSeqNo_(-1), destSeqNo_(-1), publicIgnored(false), firstBuild(true),
964 includeSelf(includeSelf_)
969 template<
typename T,
typename A>
975 template<
typename T,
typename A>
977 : source_(0), target_(0), sourceSeqNo_(-1),
978 destSeqNo_(-1), publicIgnored(false), firstBuild(true),
982 template<
class T,
typename A>
985 const MPI_Comm& comm,
986 const std::vector<int>& neighbours)
990 target_ = &destination;
993 setNeighbours(neighbours);
996 template<
typename T,
typename A>
1004 template<
typename T,
typename A>
1012 template<
typename T,
typename A>
1018 template<
typename T,
typename A>
1019 template<
bool ignorePublic>
1022 char* p_out, MPI_Datatype type,
1025 [[maybe_unused]]
int n)
1028 const auto end = indexSet.
end();
1032 for(
auto index = indexSet.
begin(); index != end; ++index)
1033 if(ignorePublic || index->local().isPublic()) {
1035 MPI_Pack(
const_cast<PairType*
>(&(*index)), 1,
1037 p_out, bufferSize, position, comm_);
1038 pairs[i++] =
const_cast<PairType*
>(&(*index));
1044 template<
typename T,
typename A>
1045 inline int RemoteIndices<T,A>::noPublic(
const ParallelIndexSet& indexSet)
1050 const auto end=indexSet.end();
1051 for(
auto index=indexSet.begin(); index!=end; ++index)
1052 if(index->local().isPublic())
1060 template<
typename T,
typename A>
1061 inline void RemoteIndices<T,A>::unpackCreateRemote(
char* p_in, PairType** sourcePairs,
1062 PairType** destPairs,
int remoteProc,
1063 int sourcePublish,
int destPublish,
1064 int bufferSize,
bool sendTwo,
1069 int noRemoteSource=-1, noRemoteDest=-1;
1070 char twoIndexSets=0;
1073 MPI_Unpack(p_in, bufferSize, &position, &twoIndexSets, 1, MPI_CHAR, comm_);
1075 MPI_Unpack(p_in, bufferSize, &position, &noRemoteSource, 1, MPI_INT, comm_);
1077 MPI_Unpack(p_in, bufferSize, &position, &noRemoteDest, 1, MPI_INT, comm_);
1081 RemoteIndexList* receive=
new RemoteIndexList();
1083 RemoteIndexList* send=0;
1085 MPI_Datatype type= MPITraits<PairType>::getType();
1089 send =
new RemoteIndexList();
1091 unpackIndices(*send, *receive, noRemoteSource, sourcePairs, sourcePublish,
1092 destPairs, destPublish, p_in, type, &position, bufferSize);
1095 unpackIndices(*receive, noRemoteSource, sourcePairs, sourcePublish,
1096 p_in, type, &position, bufferSize, fromOurSelf);
1101 int oldPos=position;
1103 unpackIndices(*receive, noRemoteSource, destPairs, destPublish,
1104 p_in, type, &position, bufferSize, fromOurSelf);
1109 send =
new RemoteIndexList();
1110 unpackIndices(*send, noRemoteDest, sourcePairs, sourcePublish,
1111 p_in, type, &position, bufferSize, fromOurSelf);
1114 if(receive->empty() && send->empty()) {
1122 remoteIndices_.insert(std::make_pair(remoteProc,
1123 std::make_pair(send,receive)));
1128 template<
typename T,
typename A>
1129 template<
bool ignorePublic>
1130 inline void RemoteIndices<T,A>::buildRemote(
bool includeSelf_)
1134 MPI_Comm_rank(comm_, &rank);
1135 MPI_Comm_size(comm_, &procs);
1139 int sourcePublish, destPublish;
1142 char sendTwo = (source_ != target_);
1144 if(procs==1 && !(sendTwo || includeSelf_))
1148 sourcePublish = (ignorePublic) ? source_->size() : noPublic(*source_);
1151 destPublish = (ignorePublic) ? target_->size() : noPublic(*target_);
1156 int maxPublish, publish=sourcePublish+destPublish;
1159 MPI_Allreduce(&publish, &maxPublish, 1, MPI_INT, MPI_MAX, comm_);
1162 PairType** destPairs;
1163 PairType** sourcePairs =
new PairType*[sourcePublish>0 ? sourcePublish : 1];
1166 destPairs =
new PairType*[destPublish>0 ? destPublish : 1];
1168 destPairs=sourcePairs;
1170 char** buffer =
new char*[2];
1177 MPI_Datatype type = MPITraits<PairType>::getType();
1179 MPI_Pack_size(maxPublish, type, comm_,
1181 MPI_Pack_size(1, MPI_INT, comm_,
1183 MPI_Pack_size(1, MPI_CHAR, comm_,
1189 bufferSize += 2 * intSize + charSize;
1191 if(bufferSize<=0) bufferSize=1;
1193 buffer[0] =
new char[bufferSize];
1194 buffer[1] =
new char[bufferSize];
1198 MPI_Pack(&sendTwo, 1, MPI_CHAR, buffer[0], bufferSize, &position,
1202 MPI_Pack(&sourcePublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1204 MPI_Pack(&destPublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1208 packEntries<ignorePublic>(sourcePairs, *source_, buffer[0], type,
1209 bufferSize, &position, sourcePublish);
1212 packEntries<ignorePublic>(destPairs, *target_, buffer[0], type,
1213 bufferSize, &position, destPublish);
1217 if(sendTwo|| includeSelf_)
1218 unpackCreateRemote(buffer[0], sourcePairs, destPairs, rank, sourcePublish,
1219 destPublish, bufferSize, sendTwo, includeSelf_);
1221 neighbourIds.erase(rank);
1223 if(neighbourIds.size()==0)
1225 Dune::dvverb<<rank<<
": Sending messages in a ring"<<std::endl;
1227 for(
int proc=1; proc<procs; proc++) {
1229 char* p_out = buffer[1-(proc%2)];
1230 char* p_in = buffer[proc%2];
1234 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1236 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1237 commTag_, comm_, &status);
1239 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1240 commTag_, comm_, &status);
1241 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1247 int remoteProc = (rank+procs-proc)%procs;
1249 unpackCreateRemote(p_in, sourcePairs, destPairs, remoteProc, sourcePublish,
1250 destPublish, bufferSize, sendTwo);
1257 MPI_Request* requests=
new MPI_Request[neighbourIds.size()];
1258 MPI_Request* req=requests;
1260 typedef typename std::set<int>::size_type size_type;
1261 size_type noNeighbours=neighbourIds.size();
1264 for(std::set<int>::iterator neighbour=neighbourIds.begin();
1265 neighbour!= neighbourIds.end(); ++neighbour) {
1267 MPI_Issend(buffer[0], position , MPI_PACKED, *neighbour, commTag_, comm_, req++);
1272 for(size_type received=0; received <noNeighbours; ++received)
1276 MPI_Probe(MPI_ANY_SOURCE, commTag_, comm_, &status);
1277 int remoteProc=status.MPI_SOURCE;
1279 MPI_Get_count(&status, MPI_PACKED, &
size);
1281 MPI_Recv(buffer[1],
size, MPI_PACKED, remoteProc,
1282 commTag_, comm_, &status);
1284 unpackCreateRemote(buffer[1], sourcePairs, destPairs, remoteProc, sourcePublish,
1285 destPublish, bufferSize, sendTwo);
1288 MPI_Status* statuses =
new MPI_Status[neighbourIds.size()];
1290 if(
int(MPI_ERR_IN_STATUS)==MPI_Waitall(neighbourIds.size(), requests, statuses)) {
1291 for(size_type i=0; i < neighbourIds.size(); ++i)
1292 if(statuses[i].MPI_ERROR!=MPI_SUCCESS) {
1293 std::cerr<<rank<<
": MPI_Error occurred while receiving message."<<std::endl;
1294 MPI_Abort(comm_, 999);
1303 if(destPairs!=sourcePairs)
1306 delete[] sourcePairs;
1312 template<
typename T,
typename A>
1313 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& remote,
1323 if(remoteEntries==0)
1327 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1329 GlobalIndex oldGlobal=index.global();
1330 int n_in=0, localIndex=0;
1333 while(localIndex<localEntries) {
1334 if(local[localIndex]->global()==index.global()) {
1335 int oldLocalIndex=localIndex;
1337 while(localIndex<localEntries &&
1338 local[localIndex]->global()==index.global()) {
1339 if(!fromOurSelf || index.local().attribute() !=
1340 local[localIndex]->local().attribute())
1342 remote.push_back(RemoteIndex(index.local().attribute(),
1343 local[localIndex]));
1348 if((++n_in) < remoteEntries) {
1349 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1351 if(index.global()==oldGlobal)
1353 localIndex=oldLocalIndex;
1355 oldGlobal=index.global();
1363 if (local[localIndex]->global()<index.global()) {
1368 if((++n_in) < remoteEntries) {
1369 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1371 oldGlobal=index.global();
1379 while(++n_in < remoteEntries)
1380 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1385 template<
typename T,
typename A>
1386 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& send,
1387 RemoteIndexList& receive,
1389 PairType** localSource,
1390 int localSourceEntries,
1391 PairType** localDest,
1392 int localDestEntries,
1398 int n_in=0, sourceIndex=0, destIndex=0;
1401 while(n_in<remoteEntries && (sourceIndex<localSourceEntries || destIndex<localDestEntries)) {
1404 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1409 while(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()<index.global())
1412 while(destIndex<localDestEntries && localDest[destIndex]->global()<index.global())
1416 if(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()==index.global())
1417 send.push_back(RemoteIndex(index.local().attribute(),
1418 localSource[sourceIndex]));
1420 if(destIndex < localDestEntries && localDest[destIndex]->global() == index.global())
1421 receive.push_back(RemoteIndex(index.local().attribute(),
1422 localDest[sourceIndex]));
1427 template<
typename T,
typename A>
1430 auto lend = remoteIndices_.end();
1431 for(
auto lists=remoteIndices_.begin(); lists != lend; ++lists) {
1432 if(lists->second.first==lists->second.second) {
1434 delete lists->second.first;
1436 delete lists->second.first;
1437 delete lists->second.second;
1440 remoteIndices_.clear();
1444 template<
typename T,
typename A>
1447 return remoteIndices_.size();
1450 template<
typename T,
typename A>
1451 template<
bool ignorePublic>
1456 ignorePublic!=publicIgnored || !
1460 buildRemote<ignorePublic>(includeSelf);
1462 sourceSeqNo_ = source_->seqNo();
1463 destSeqNo_ = target_->seqNo();
1465 publicIgnored=ignorePublic;
1471 template<
typename T,
typename A>
1474 return sourceSeqNo_==source_->seqNo() && destSeqNo_ ==target_->seqNo();
1477 template<
typename T,
typename A>
1478 template<
bool mode,
bool send>
1485 sourceSeqNo_ = source_->seqNo();
1486 destSeqNo_ = target_->seqNo();
1488 typename RemoteIndexMap::iterator found = remoteIndices_.find(process);
1490 if(found == remoteIndices_.end())
1492 if(source_ != target_)
1493 found = remoteIndices_.insert(found, std::make_pair(process,
1498 found = remoteIndices_.insert(found,
1499 std::make_pair(process,
1500 std::make_pair(rlist, rlist)));
1512 template<
typename T,
typename A>
1513 inline typename RemoteIndices<T,A>::const_iterator
1516 return remoteIndices_.find(proc);
1519 template<
typename T,
typename A>
1520 inline typename RemoteIndices<T,A>::const_iterator
1523 return remoteIndices_.begin();
1526 template<
typename T,
typename A>
1527 inline typename RemoteIndices<T,A>::const_iterator
1530 return remoteIndices_.end();
1534 template<
typename T,
typename A>
1540 const auto rend = remoteIndices_.
end();
1542 for(
auto rindex = remoteIndices_.begin(), rindex1=ri.remoteIndices_.begin(); rindex!=rend; ++rindex, ++rindex1) {
1543 if(rindex->first != rindex1->first)
1545 if(*(rindex->second.first) != *(rindex1->second.first))
1547 if(*(rindex->second.second) != *(rindex1->second.second))
1553 template<
class T,
class A,
bool mode>
1555 RemoteIndexList& rList)
1556 : rList_(&rList), indexSet_(&indexSet), iter_(rList.beginModify()), end_(rList.end()), first_(true)
1558 if(MODIFYINDEXSET) {
1560 for(ConstIterator iter=iter_; iter != end_; ++iter)
1561 glist_.push_back(iter->localIndexPair().global());
1562 giter_ = glist_.beginModify();
1566 template<
typename T,
typename A,
bool mode>
1568 : rList_(other.rList_), indexSet_(other.indexSet_),
1569 glist_(other.glist_), iter_(other.iter_), giter_(other.giter_), end_(other.end_),
1570 first_(other.first_), last_(other.last_)
1573 template<
typename T,
typename A,
bool mode>
1576 if(MODIFYINDEXSET) {
1578#ifdef DUNE_ISTL_WITH_CHECKING
1579 if(indexSet_->state()!=
GROUND)
1582 auto giter = glist_.begin();
1583 auto index = indexSet_->begin();
1585 for(
auto iter=rList_->begin(); iter != end_; ++iter) {
1586 while(index->global()<*giter) {
1588#ifdef DUNE_ISTL_WITH_CHECKING
1589 if(index == indexSet_->end())
1590 DUNE_THROW(InvalidPosition,
"No such global index in set!");
1594#ifdef DUNE_ISTL_WITH_CHECKING
1595 if(index->global() != *giter)
1596 DUNE_THROW(InvalidPosition,
"No such global index in set!");
1598 iter->localIndex_ = &(*index);
1603 template<
typename T,
typename A,
bool mode>
1606 static_assert(!mode,
"Not allowed if the mode indicates that new indices"
1607 "might be added to the underlying index set. Use "
1608 "insert(const RemoteIndex&, const GlobalIndex&) instead");
1610#ifdef DUNE_ISTL_WITH_CHECKING
1611 if(!first_ && index.localIndexPair().global()<last_)
1612 DUNE_THROW(InvalidPosition,
"Modification of remote indices have to occur with ascending global index.");
1615 while(iter_ != end_ && iter_->localIndexPair().global() < index.localIndexPair().global()) {
1620 assert(iter_==end_ || iter_->localIndexPair().global() != index.localIndexPair().global());
1621 iter_.insert(index);
1622 last_ = index.localIndexPair().global();
1626 template<
typename T,
typename A,
bool mode>
1629 static_assert(mode,
"Not allowed if the mode indicates that no new indices"
1630 "might be added to the underlying index set. Use "
1631 "insert(const RemoteIndex&) instead");
1632#ifdef DUNE_ISTL_WITH_CHECKING
1633 if(!first_ && global<last_)
1634 DUNE_THROW(InvalidPosition,
"Modification of remote indices have to occur with ascending global index.");
1637 while(iter_ != end_ && *giter_ < global) {
1643 assert(iter_->localIndexPair().global() != global);
1644 iter_.insert(index);
1645 giter_.insert(global);
1651 template<
typename T,
typename A,
bool mode>
1654#ifdef DUNE_ISTL_WITH_CHECKING
1655 if(!first_ && global<last_)
1656 DUNE_THROW(InvalidPosition,
"Modification of remote indices have to occur with ascending global index.");
1661 if(MODIFYINDEXSET) {
1663 while(iter_!=end_ && *giter_< global) {
1667 if(*giter_ == global) {
1673 while(iter_!=end_ && iter_->localIndexPair().global() < global)
1676 if(iter_->localIndexPair().global()==global) {
1687 template<
typename T,
typename A>
1694 template<
typename T,
typename A>
1701 template<
typename T,
typename A>
1705 const auto end = pmap.end();
1706 for(
auto process = pmap.begin(); process != end; ++process) {
1707 const RemoteIndexList* list = send ? process->second.first : process->second.second;
1709 map_.insert(std::make_pair(process->first,
1710 std::pair<ri_iterator, const ri_iterator>(list->
begin(), list->
end())));
1714 template<
typename T,
typename A>
1717 const auto end = map_.end();
1719 for(
auto iter = map_.begin(); iter != end;) {
1725 remoteIndex = *current;
1727 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1728 ++(iter->second.first);
1731 if(iter->second.first == iter->second.second)
1741 template<
typename T,
typename A>
1743 const Attribute& attribute)
1745 const auto end = map_.end();
1747 for(
auto iter = map_.begin(); iter != end;) {
1753 remoteIndex = *current;
1756 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1757 ++(iter->second.first);
1760 while(iter->second.first!=iter->second.second
1761 && iter->second.first->localIndexPair().global()==index
1762 && iter->second.first->localIndexPair().local().attribute()<attribute)
1763 ++(iter->second.first);
1766 if(iter->second.first == iter->second.second)
1773 attribute_=attribute;
1777 template<
typename T,
typename A>
1780 const auto end = map_.end();
1782 for(
auto iter = map_.begin(); iter != end;) {
1784 auto current = iter->second.first;
1785 auto rend = iter->second.second;
1788 if(iter->second.first->localIndexPair().global()==index_ &&
1789 (noattribute || iter->second.first->localIndexPair().local().attribute() == attribute_))
1790 ++(iter->second.first);
1793 if(iter->second.first == iter->second.second)
1802 template<
typename T,
typename A>
1805 return map_.empty();
1808 template<
typename T,
typename A>
1813 return iterator(map_.begin(), map_.end(), index_);
1815 return iterator(map_.begin(), map_.end(), index_,
1819 template<
typename T,
typename A>
1820 inline typename CollectiveIterator<T,A>::iterator
1821 CollectiveIterator<T,A>::end()
1823 return iterator(map_.end(), map_.end(), index_);
1826 template<
typename TG,
typename TA>
1827 inline std::ostream& operator<<(std::ostream& os,
const RemoteIndex<TG,TA>& index)
1829 os<<
"[global="<<index.localIndexPair().global()<<
", remote attribute="<<index.attribute()<<
" local attribute="<<index.localIndexPair().local().attribute()<<
"]";
1833 template<
typename T,
typename A>
1834 inline std::ostream& operator<<(std::ostream& os,
const RemoteIndices<T,A>& indices)
1837 MPI_Comm_rank(indices.comm_, &rank);
1838 const auto rend = indices.remoteIndices_.end();
1840 for(
auto rindex = indices.remoteIndices_.begin(); rindex!=rend; ++rindex) {
1841 os<<rank<<
": Process "<<rindex->first<<
":";
1843 if(!rindex->second.first->empty()) {
1846 const auto send= rindex->second.first->end();
1848 for(
auto index = rindex->second.first->begin();
1849 index != send; ++index)
1853 if(!rindex->second.second->empty()) {
1854 os<<rank<<
": Process "<<rindex->first<<
": "<<
"receive: ";
1856 for(
const auto& index : *(rindex->second.second))
1859 os<<std::endl<<std::flush;
Iterator over the valid underlying iterators.
Definition: remoteindices.hh:791
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex &index)
Definition: remoteindices.hh:798
iterator(const iterator &other)
Definition: remoteindices.hh:816
const RemoteIndex & operator*() const
Definition: remoteindices.hh:837
iterator & operator++()
Definition: remoteindices.hh:821
const RemoteIndex * operator->() const
Definition: remoteindices.hh:849
bool operator==(const iterator &other) const
Definition: remoteindices.hh:855
int process() const
Definition: remoteindices.hh:843
bool operator!=(const iterator &other) const
Definition: remoteindices.hh:861
A collective iterator for moving over the remote indices for all processes collectively.
Definition: remoteindices.hh:707
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:747
A pair consisting of a global and local index.
Definition: indexset.hh:85
Class for recomputing missing indices of a distributed index set.
Definition: indicessyncer.hh:45
Base class of all classes representing a communication interface.
Definition: interface.hh:44
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:205
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:174
Manager class for the mapping between local indices and globally unique indices.
Definition: indexset.hh:218
An index present on the local process with an additional attribute flag.
Definition: plocalindex.hh:52
Default exception class for range errors.
Definition: exceptions.hh:254
Modifier for adding and/or deleting remote indices from the remote index list.
Definition: remoteindices.hh:550
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:601
A Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:597
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:577
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:582
RemoteIndexList::const_iterator ConstIterator
The type of the remote index list iterator.
Definition: remoteindices.hh:611
SLListModifyIterator< RemoteIndex, Allocator > ModifyIterator
The type of the modifying iterator of the remote index list.
Definition: remoteindices.hh:606
T ParallelIndexSet
Type of the index set we use.
Definition: remoteindices.hh:572
RemoteIndexListModifier()
Default constructor.
Definition: remoteindices.hh:675
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:587
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:592
static constexpr bool MODIFYINDEXSET
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:567
Information about an index residing on another processor.
Definition: remoteindices.hh:74
T1 GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: remoteindices.hh:91
T2 Attribute
The type of the attributes. Normally this will be an enumeration like.
Definition: remoteindices.hh:100
IndexPair< GlobalIndex, ParallelLocalIndex< Attribute > > PairType
The type of the index pair.
Definition: remoteindices.hh:106
The indices present on remote processes.
Definition: remoteindices.hh:190
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:232
friend void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
Fills the holes in an index set.
Definition: repartition.hh:83
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:216
T ParallelIndexSet
Type of the index set we use, e.g. ParallelLocalIndexSet.
Definition: remoteindices.hh:207
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:227
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:246
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:242
CollectiveIterator< T, A > CollectiveIteratorT
The type of the collective iterator over all remote indices.
Definition: remoteindices.hh:211
typename std::allocator_traits< A >::template rebind_alloc< RemoteIndex > Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:238
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:222
A constant iterator for the SLList.
Definition: sllist.hh:371
A single linked list.
Definition: sllist.hh:44
A few common exception classes.
void repairLocalIndexPointers()
Repair the pointers to the local index pairs.
Definition: remoteindices.hh:1574
const Attribute attribute() const
Get the attribute of the index on the remote process.
Definition: remoteindices.hh:945
void setIndexSets(const ParallelIndexSet &source, const ParallelIndexSet &destination, const MPI_Comm &comm, const std::vector< int > &neighbours=std::vector< int >())
Set the index sets and communicator we work with.
Definition: remoteindices.hh:983
void free()
Free the index lists.
Definition: remoteindices.hh:1428
void insert(const RemoteIndex &index)
Insert an index to the list.
Definition: remoteindices.hh:1604
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1452
void repairLocalIndexPointers(std::map< int, SLList< std::pair< typename T::GlobalIndex, typename T::LocalIndex::Attribute >, A > > &globalMap, RemoteIndices< T, A1 > &remoteIndices, const T &indexSet)
Repair the pointers to the local indices in the remote indices.
Definition: indicessyncer.hh:495
MPI_Comm communicator() const
Get the mpi communicator used.
Definition: remoteindices.hh:1695
CollectiveIteratorT iterator() const
Get an iterator for collectively iterating over the remote indices of all remote processes.
Definition: remoteindices.hh:1689
void setIncludeSelf(bool includeSelf)
Tell whether sending from indices of the processor to other indices on the same processor is enabled ...
Definition: remoteindices.hh:970
CollectiveIterator(const RemoteIndexMap &map_, bool send)
Constructor.
Definition: remoteindices.hh:1702
iterator begin()
Get an iterator over the indices positioned at the first index.
iterator end()
Get an iterator over the indices positioned after the last index.
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1528
bool empty() const
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1803
RemoteIndexListModifier< T, A, mode > getModifier(int process)
Get a modifier for a remote index list.
Definition: remoteindices.hh:1479
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1715
const PairType & localIndexPair() const
Get the corresponding local index pair.
Definition: remoteindices.hh:951
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:998
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1013
TL LocalIndex
The type of the local index, e.g. ParallelLocalIndex.
Definition: indexset.hh:239
bool remove(const GlobalIndex &global)
Remove a remote index.
Definition: remoteindices.hh:1652
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:929
int neighbours() const
Get the number of processors we share indices with.
Definition: remoteindices.hh:1445
TG GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: indexset.hh:226
const ParallelIndexSet & destinationIndexSet() const
Get the index set at destination.
Definition: remoteindices.hh:1006
RemoteIndices(const ParallelIndexSet &source, const ParallelIndexSet &destination, const MPI_Comm &comm, const std::vector< int > &neighbours=std::vector< int >(), bool includeSelf=false)
Constructor.
Definition: remoteindices.hh:957
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1514
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1472
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1521
@ GROUND
The default mode. Indicates that the index set is ready to be used.
Definition: indexset.hh:186
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:774
SLListConstIterator< RemoteIndex, Allocator > const_iterator
The constant iterator of the list.
Definition: sllist.hh:74
SLListModifyIterator< GlobalIndex, Allocator > ModifyIterator
The type of the iterator capable of deletion and insertion.
Definition: sllist.hh:103
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:762
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:96
Provides a map between global and local indices.
Traits classes for mapping types onto MPI_Datatype.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Provides classes for use as the local index in ParallelIndexSet for distributed computing.
Implements a singly linked list together with the necessary iterators.
Standard Dune debug streams.
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: mpitraits.hh:41