3#ifndef DUNE_REMOTEINDICES_HH
4#define DUNE_REMOTEINDICES_HH
38 template<
typename TG,
typename TA>
42 inline static MPI_Datatype getType();
44 static MPI_Datatype type;
48 template<
typename T,
typename A>
51 template<
typename T1,
typename T2>
58 template<
typename T1,
typename T2>
62 template<
typename T,
typename A,
bool mode>
69 template<
typename T1,
typename T2>
75 template<
typename T,
typename A,
typename A1>
80 template<
typename T,
typename A,
bool mode>
151 template<
class T,
class A>
156 template<
class T,
class A>
164 template<
typename T1,
typename T2>
184 template<
class T,
class A=std::allocator<
RemoteIndex<
typename T::GlobalIndex,
185 typename T::LocalIndex::Attribute> > >
190 template<
typename T1,
typename A2,
typename A1>
195 template<
class G,
class T1,
class T2>
235 using Allocator =
typename std::allocator_traits<A>::template rebind_alloc<RemoteIndex>;
242 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
245 typedef typename RemoteIndexMap::const_iterator const_iterator;
265 const MPI_Comm& comm,
const std::vector<int>&
neighbours=std::vector<int>(),
bool includeSelf=
false);
295 const MPI_Comm& comm,
const std::vector<int>&
neighbours=std::vector<int>());
300 neighbourIds.clear();
305 const std::set<int>& getNeighbours()
const
324 template<
bool ignorePublic>
357 template<
bool mode,
bool send>
366 inline const_iterator
find(
int proc)
const;
372 inline const_iterator
begin()
const;
378 inline const_iterator
end()
const;
418 std::set<int> neighbourIds;
421 const static int commTag_=333;
475 template<
bool ignorePublic>
476 inline void buildRemote(
bool includeSelf);
496 template<
bool ignorePublic>
498 char* p_out, MPI_Datatype type,
int bufferSize,
499 int* position,
int n);
515 PairType** local,
int localEntries,
char* p_in,
516 MPI_Datatype type,
int* position,
int bufferSize,
520 int remoteEntries,
PairType** localSource,
521 int localSourceEntries,
PairType** localDest,
522 int localDestEntries,
char* p_in,
523 MPI_Datatype type,
int* position,
int bufferSize);
525 void unpackCreateRemote(
char* p_in,
PairType** sourcePairs,
PairType** DestPairs,
526 int remoteProc,
int sourcePublish,
int destPublish,
527 int bufferSize,
bool sendTwo,
bool fromOurSelf=
false);
547 template<
class T,
class A,
bool mode>
551 template<
typename T1,
typename A1>
696 GlobalModifyIterator giter_;
706 template<
class T,
class A>
713 typedef T ParallelIndexSet;
728 typedef typename LocalIndex::Attribute Attribute;
734 using Allocator =
typename std::allocator_traits<A>::template rebind_alloc<RemoteIndex>;
747 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
765 inline void advance(
const GlobalIndex& global);
776 inline void advance(
const GlobalIndex& global,
const Attribute& attribute);
783 inline bool empty()
const;
794 typedef typename Map::iterator RealIterator;
795 typedef typename Map::iterator ConstRealIterator;
799 iterator(
const RealIterator& iter,
const ConstRealIterator& end, GlobalIndex& index)
800 : iter_(iter), end_(end), index_(index), hasAttribute(false)
803 while(iter_!=end_ && iter_->second.first->localIndexPair().global()!=index_)
807 iterator(
const RealIterator& iter,
const ConstRealIterator& end, GlobalIndex index,
809 : iter_(iter), end_(end), index_(index), attribute_(attribute), hasAttribute(true)
812 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_
813 || iter_->second.first->localIndexPair().local().attribute()!=attribute))
818 : iter_(other.iter_), end_(other.end_), index_(other.index_)
826 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_ ||
828 iter_->second.first->localIndexPair().local().attribute()!=attribute_)))
830 assert(iter_==end_ ||
831 (iter_->second.first->localIndexPair().global()==index_));
832 assert(iter_==end_ || !hasAttribute ||
833 (iter_->second.first->localIndexPair().local().attribute()==attribute_));
840 return *(iter_->second.first);
852 return iter_->second.first.operator->();
858 return other.iter_==iter_;
864 return other.iter_!=iter_;
873 Attribute attribute_;
885 Attribute attribute_;
889 template<
typename TG,
typename TA>
890 MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::getType()
892 if(type==MPI_DATATYPE_NULL) {
893 int length[2] = {1, 1};
896 MPI_Datatype types[2] = {MPITraits<TG>::getType(),
897 MPITraits<ParallelLocalIndex<TA> >::getType()};
898 IndexPair<TG,ParallelLocalIndex<TA> > rep;
899 MPI_Get_address(&rep, &base);
900 MPI_Get_address(&(rep.global_), &disp[0]);
901 MPI_Get_address(&(rep.local_), &disp[1]);
902 for (MPI_Aint& d : disp)
906 MPI_Type_create_struct(2, length, disp, types, &tmp);
908 MPI_Type_create_resized(tmp, 0,
sizeof(IndexPair<TG,ParallelLocalIndex<TA> >), &type);
909 MPI_Type_commit(&type);
916 template<
typename TG,
typename TA>
917 MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::type=MPI_DATATYPE_NULL;
919 template<
typename T1,
typename T2>
921 : localIndex_(local), attribute_(static_cast<
std::underlying_type_t<T2>>(attribute))
924 template<
typename T1,
typename T2>
926 : localIndex_(0), attribute_(static_cast<
std::underlying_type_t<T2>>(attribute))
929 template<
typename T1,
typename T2>
931 : localIndex_(0), attribute_()
933 template<
typename T1,
typename T2>
936 return localIndex_==ri.localIndex_ && attribute_==ri.
attribute;
939 template<
typename T1,
typename T2>
940 inline bool RemoteIndex<T1,T2>::operator!=(
const RemoteIndex& ri)
const
942 return localIndex_!=ri.localIndex_ || attribute_!=ri.attribute_;
945 template<
typename T1,
typename T2>
948 return T2(attribute_);
951 template<
typename T1,
typename T2>
957 template<
typename T,
typename A>
960 const MPI_Comm& comm,
961 const std::vector<int>& neighbours,
963 : source_(&source), target_(&destination), comm_(comm),
964 sourceSeqNo_(-1), destSeqNo_(-1), publicIgnored(false), firstBuild(true),
965 includeSelf(includeSelf_)
970 template<
typename T,
typename A>
976 template<
typename T,
typename A>
978 : source_(0), target_(0), sourceSeqNo_(-1),
979 destSeqNo_(-1), publicIgnored(false), firstBuild(true),
983 template<
class T,
typename A>
986 const MPI_Comm& comm,
987 const std::vector<int>& neighbours)
991 target_ = &destination;
994 setNeighbours(neighbours);
997 template<
typename T,
typename A>
1005 template<
typename T,
typename A>
1013 template<
typename T,
typename A>
1019 template<
typename T,
typename A>
1020 template<
bool ignorePublic>
1023 char* p_out, MPI_Datatype type,
1026 [[maybe_unused]]
int n)
1029 const auto end = indexSet.
end();
1033 for(
auto index = indexSet.
begin(); index != end; ++index)
1034 if(ignorePublic || index->local().isPublic()) {
1036 MPI_Pack(
const_cast<PairType*
>(&(*index)), 1,
1038 p_out, bufferSize, position, comm_);
1039 pairs[i++] =
const_cast<PairType*
>(&(*index));
1045 template<
typename T,
typename A>
1046 inline int RemoteIndices<T,A>::noPublic(
const ParallelIndexSet& indexSet)
1051 const auto end=indexSet.end();
1052 for(
auto index=indexSet.begin(); index!=end; ++index)
1053 if(index->local().isPublic())
1061 template<
typename T,
typename A>
1062 inline void RemoteIndices<T,A>::unpackCreateRemote(
char* p_in, PairType** sourcePairs,
1063 PairType** destPairs,
int remoteProc,
1064 int sourcePublish,
int destPublish,
1065 int bufferSize,
bool sendTwo,
1070 int noRemoteSource=-1, noRemoteDest=-1;
1071 char twoIndexSets=0;
1074 MPI_Unpack(p_in, bufferSize, &position, &twoIndexSets, 1, MPI_CHAR, comm_);
1076 MPI_Unpack(p_in, bufferSize, &position, &noRemoteSource, 1, MPI_INT, comm_);
1078 MPI_Unpack(p_in, bufferSize, &position, &noRemoteDest, 1, MPI_INT, comm_);
1082 RemoteIndexList* receive=
new RemoteIndexList();
1084 RemoteIndexList* send=0;
1086 MPI_Datatype type= MPITraits<PairType>::getType();
1090 send =
new RemoteIndexList();
1092 unpackIndices(*send, *receive, noRemoteSource, sourcePairs, sourcePublish,
1093 destPairs, destPublish, p_in, type, &position, bufferSize);
1096 unpackIndices(*receive, noRemoteSource, sourcePairs, sourcePublish,
1097 p_in, type, &position, bufferSize, fromOurSelf);
1102 int oldPos=position;
1104 unpackIndices(*receive, noRemoteSource, destPairs, destPublish,
1105 p_in, type, &position, bufferSize, fromOurSelf);
1110 send =
new RemoteIndexList();
1111 unpackIndices(*send, noRemoteDest, sourcePairs, sourcePublish,
1112 p_in, type, &position, bufferSize, fromOurSelf);
1115 if(receive->empty() && send->empty()) {
1123 remoteIndices_.insert(std::make_pair(remoteProc,
1124 std::make_pair(send,receive)));
1129 template<
typename T,
typename A>
1130 template<
bool ignorePublic>
1131 inline void RemoteIndices<T,A>::buildRemote(
bool includeSelf_)
1135 MPI_Comm_rank(comm_, &rank);
1136 MPI_Comm_size(comm_, &procs);
1140 int sourcePublish, destPublish;
1143 char sendTwo = (source_ != target_);
1145 if(procs==1 && !(sendTwo || includeSelf_))
1149 sourcePublish = (ignorePublic) ? source_->size() : noPublic(*source_);
1152 destPublish = (ignorePublic) ? target_->size() : noPublic(*target_);
1157 int maxPublish, publish=sourcePublish+destPublish;
1160 MPI_Allreduce(&publish, &maxPublish, 1, MPI_INT, MPI_MAX, comm_);
1163 PairType** destPairs;
1164 PairType** sourcePairs =
new PairType*[sourcePublish>0 ? sourcePublish : 1];
1167 destPairs =
new PairType*[destPublish>0 ? destPublish : 1];
1169 destPairs=sourcePairs;
1171 char** buffer =
new char*[2];
1178 MPI_Datatype type = MPITraits<PairType>::getType();
1180 MPI_Pack_size(maxPublish, type, comm_,
1182 MPI_Pack_size(1, MPI_INT, comm_,
1184 MPI_Pack_size(1, MPI_CHAR, comm_,
1190 bufferSize += 2 * intSize + charSize;
1192 if(bufferSize<=0) bufferSize=1;
1194 buffer[0] =
new char[bufferSize];
1195 buffer[1] =
new char[bufferSize];
1199 MPI_Pack(&sendTwo, 1, MPI_CHAR, buffer[0], bufferSize, &position,
1203 MPI_Pack(&sourcePublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1205 MPI_Pack(&destPublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1209 packEntries<ignorePublic>(sourcePairs, *source_, buffer[0], type,
1210 bufferSize, &position, sourcePublish);
1213 packEntries<ignorePublic>(destPairs, *target_, buffer[0], type,
1214 bufferSize, &position, destPublish);
1218 if(sendTwo|| includeSelf_)
1219 unpackCreateRemote(buffer[0], sourcePairs, destPairs, rank, sourcePublish,
1220 destPublish, bufferSize, sendTwo, includeSelf_);
1222 neighbourIds.erase(rank);
1224 if(neighbourIds.size()==0)
1226 Dune::dvverb<<rank<<
": Sending messages in a ring"<<std::endl;
1228 for(
int proc=1; proc<procs; proc++) {
1230 char* p_out = buffer[1-(proc%2)];
1231 char* p_in = buffer[proc%2];
1235 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1237 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1238 commTag_, comm_, &status);
1240 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1241 commTag_, comm_, &status);
1242 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1248 int remoteProc = (rank+procs-proc)%procs;
1250 unpackCreateRemote(p_in, sourcePairs, destPairs, remoteProc, sourcePublish,
1251 destPublish, bufferSize, sendTwo);
1258 MPI_Request* requests=
new MPI_Request[neighbourIds.size()];
1259 MPI_Request* req=requests;
1261 typedef typename std::set<int>::size_type size_type;
1262 size_type noNeighbours=neighbourIds.size();
1265 for(std::set<int>::iterator neighbour=neighbourIds.begin();
1266 neighbour!= neighbourIds.end(); ++neighbour) {
1268 MPI_Issend(buffer[0], position , MPI_PACKED, *neighbour, commTag_, comm_, req++);
1273 for(size_type received=0; received <noNeighbours; ++received)
1277 MPI_Probe(MPI_ANY_SOURCE, commTag_, comm_, &status);
1278 int remoteProc=status.MPI_SOURCE;
1280 MPI_Get_count(&status, MPI_PACKED, &size);
1282 MPI_Recv(buffer[1], size, MPI_PACKED, remoteProc,
1283 commTag_, comm_, &status);
1285 unpackCreateRemote(buffer[1], sourcePairs, destPairs, remoteProc, sourcePublish,
1286 destPublish, bufferSize, sendTwo);
1289 MPI_Status* statuses =
new MPI_Status[neighbourIds.size()];
1291 if(MPI_ERR_IN_STATUS==MPI_Waitall(neighbourIds.size(), requests, statuses)) {
1292 for(size_type i=0; i < neighbourIds.size(); ++i)
1293 if(statuses[i].MPI_ERROR!=MPI_SUCCESS) {
1294 std::cerr<<rank<<
": MPI_Error occurred while receiving message."<<std::endl;
1295 MPI_Abort(comm_, 999);
1304 if(destPairs!=sourcePairs)
1307 delete[] sourcePairs;
1313 template<
typename T,
typename A>
1314 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& remote,
1324 if(remoteEntries==0)
1328 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1330 GlobalIndex oldGlobal=index.global();
1331 int n_in=0, localIndex=0;
1334 while(localIndex<localEntries) {
1335 if(local[localIndex]->global()==index.global()) {
1336 int oldLocalIndex=localIndex;
1338 while(localIndex<localEntries &&
1339 local[localIndex]->global()==index.global()) {
1340 if(!fromOurSelf || index.local().attribute() !=
1341 local[localIndex]->local().attribute())
1343 remote.push_back(RemoteIndex(index.local().attribute(),
1344 local[localIndex]));
1349 if((++n_in) < remoteEntries) {
1350 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1352 if(index.global()==oldGlobal)
1354 localIndex=oldLocalIndex;
1356 oldGlobal=index.global();
1364 if (local[localIndex]->global()<index.global()) {
1369 if((++n_in) < remoteEntries) {
1370 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1372 oldGlobal=index.global();
1380 while(++n_in < remoteEntries)
1381 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1386 template<
typename T,
typename A>
1387 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& send,
1388 RemoteIndexList& receive,
1390 PairType** localSource,
1391 int localSourceEntries,
1392 PairType** localDest,
1393 int localDestEntries,
1399 int n_in=0, sourceIndex=0, destIndex=0;
1402 while(n_in<remoteEntries && (sourceIndex<localSourceEntries || destIndex<localDestEntries)) {
1405 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1410 while(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()<index.global())
1413 while(destIndex<localDestEntries && localDest[destIndex]->global()<index.global())
1417 if(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()==index.global())
1418 send.push_back(RemoteIndex(index.local().attribute(),
1419 localSource[sourceIndex]));
1421 if(destIndex < localDestEntries && localDest[destIndex]->global() == index.global())
1422 receive.push_back(RemoteIndex(index.local().attribute(),
1423 localDest[sourceIndex]));
1428 template<
typename T,
typename A>
1431 auto lend = remoteIndices_.end();
1432 for(
auto lists=remoteIndices_.begin(); lists != lend; ++lists) {
1433 if(lists->second.first==lists->second.second) {
1435 delete lists->second.first;
1437 delete lists->second.first;
1438 delete lists->second.second;
1441 remoteIndices_.clear();
1445 template<
typename T,
typename A>
1448 return remoteIndices_.size();
1451 template<
typename T,
typename A>
1452 template<
bool ignorePublic>
1457 ignorePublic!=publicIgnored || !
1461 buildRemote<ignorePublic>(includeSelf);
1463 sourceSeqNo_ = source_->seqNo();
1464 destSeqNo_ = target_->seqNo();
1466 publicIgnored=ignorePublic;
1472 template<
typename T,
typename A>
1475 return sourceSeqNo_==source_->seqNo() && destSeqNo_ ==target_->seqNo();
1478 template<
typename T,
typename A>
1479 template<
bool mode,
bool send>
1486 sourceSeqNo_ = source_->seqNo();
1487 destSeqNo_ = target_->seqNo();
1489 typename RemoteIndexMap::iterator found = remoteIndices_.find(process);
1491 if(found == remoteIndices_.end())
1493 if(source_ != target_)
1494 found = remoteIndices_.insert(found, std::make_pair(process,
1499 found = remoteIndices_.insert(found,
1500 std::make_pair(process,
1501 std::make_pair(rlist, rlist)));
1513 template<
typename T,
typename A>
1514 inline typename RemoteIndices<T,A>::const_iterator
1517 return remoteIndices_.find(proc);
1520 template<
typename T,
typename A>
1521 inline typename RemoteIndices<T,A>::const_iterator
1524 return remoteIndices_.begin();
1527 template<
typename T,
typename A>
1528 inline typename RemoteIndices<T,A>::const_iterator
1531 return remoteIndices_.end();
1535 template<
typename T,
typename A>
1541 const auto rend = remoteIndices_.
end();
1543 for(
auto rindex = remoteIndices_.begin(), rindex1=ri.remoteIndices_.begin(); rindex!=rend; ++rindex, ++rindex1) {
1544 if(rindex->first != rindex1->first)
1546 if(*(rindex->second.first) != *(rindex1->second.first))
1548 if(*(rindex->second.second) != *(rindex1->second.second))
1554 template<
class T,
class A,
bool mode>
1556 RemoteIndexList& rList)
1557 : rList_(&rList), indexSet_(&indexSet), iter_(rList.beginModify()), end_(rList.end()), first_(true)
1559 if(MODIFYINDEXSET) {
1561 for(ConstIterator iter=iter_; iter != end_; ++iter)
1562 glist_.push_back(iter->localIndexPair().global());
1563 giter_ = glist_.beginModify();
1567 template<
typename T,
typename A,
bool mode>
1569 : rList_(other.rList_), indexSet_(other.indexSet_),
1570 glist_(other.glist_), iter_(other.iter_), giter_(other.giter_), end_(other.end_),
1571 first_(other.first_), last_(other.last_)
1574 template<
typename T,
typename A,
bool mode>
1577 if(MODIFYINDEXSET) {
1579#ifdef DUNE_ISTL_WITH_CHECKING
1580 if(indexSet_->state()!=
GROUND)
1583 auto giter = glist_.begin();
1584 auto index = indexSet_->begin();
1586 for(
auto iter=rList_->begin(); iter != end_; ++iter) {
1587 while(index->global()<*giter) {
1589#ifdef DUNE_ISTL_WITH_CHECKING
1590 if(index == indexSet_->end())
1591 DUNE_THROW(InvalidPosition,
"No such global index in set!");
1595#ifdef DUNE_ISTL_WITH_CHECKING
1596 if(index->global() != *giter)
1597 DUNE_THROW(InvalidPosition,
"No such global index in set!");
1599 iter->localIndex_ = &(*index);
1604 template<
typename T,
typename A,
bool mode>
1607 static_assert(!mode,
"Not allowed if the mode indicates that new indices"
1608 "might be added to the underlying index set. Use "
1609 "insert(const RemoteIndex&, const GlobalIndex&) instead");
1611#ifdef DUNE_ISTL_WITH_CHECKING
1612 if(!first_ && index.localIndexPair().global()<last_)
1613 DUNE_THROW(InvalidPosition,
"Modifcation of remote indices have to occur with ascending global index.");
1616 while(iter_ != end_ && iter_->localIndexPair().global() < index.localIndexPair().global()) {
1621 assert(iter_==end_ || iter_->localIndexPair().global() != index.localIndexPair().global());
1622 iter_.insert(index);
1623 last_ = index.localIndexPair().global();
1627 template<
typename T,
typename A,
bool mode>
1630 static_assert(mode,
"Not allowed if the mode indicates that no new indices"
1631 "might be added to the underlying index set. Use "
1632 "insert(const RemoteIndex&) instead");
1633#ifdef DUNE_ISTL_WITH_CHECKING
1634 if(!first_ && global<last_)
1635 DUNE_THROW(InvalidPosition,
"Modification of remote indices have to occur with ascending global index.");
1638 while(iter_ != end_ && *giter_ < global) {
1644 assert(iter_->localIndexPair().global() != global);
1645 iter_.insert(index);
1646 giter_.insert(global);
1652 template<
typename T,
typename A,
bool mode>
1655#ifdef DUNE_ISTL_WITH_CHECKING
1656 if(!first_ && global<last_)
1657 DUNE_THROW(InvalidPosition,
"Modifcation of remote indices have to occur with ascending global index.");
1662 if(MODIFYINDEXSET) {
1664 while(iter_!=end_ && *giter_< global) {
1668 if(*giter_ == global) {
1674 while(iter_!=end_ && iter_->localIndexPair().global() < global)
1677 if(iter_->localIndexPair().global()==global) {
1688 template<
typename T,
typename A>
1695 template<
typename T,
typename A>
1702 template<
typename T,
typename A>
1706 const auto end = pmap.end();
1707 for(
auto process = pmap.begin(); process != end; ++process) {
1708 const RemoteIndexList* list = send ? process->second.first : process->second.second;
1710 map_.insert(std::make_pair(process->first,
1711 std::pair<ri_iterator, const ri_iterator>(list->
begin(), list->
end())));
1715 template<
typename T,
typename A>
1718 const auto end = map_.end();
1720 for(
auto iter = map_.begin(); iter != end;) {
1726 remoteIndex = *current;
1728 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1729 ++(iter->second.first);
1732 if(iter->second.first == iter->second.second)
1742 template<
typename T,
typename A>
1744 const Attribute& attribute)
1746 const auto end = map_.end();
1748 for(
auto iter = map_.begin(); iter != end;) {
1754 remoteIndex = *current;
1757 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1758 ++(iter->second.first);
1761 while(iter->second.first!=iter->second.second
1762 && iter->second.first->localIndexPair().global()==index
1763 && iter->second.first->localIndexPair().local().attribute()<attribute)
1764 ++(iter->second.first);
1767 if(iter->second.first == iter->second.second)
1774 attribute_=attribute;
1778 template<
typename T,
typename A>
1781 const auto end = map_.end();
1783 for(
auto iter = map_.begin(); iter != end;) {
1785 auto current = iter->second.first;
1786 auto rend = iter->second.second;
1789 if(iter->second.first->localIndexPair().global()==index_ &&
1790 (noattribute || iter->second.first->localIndexPair().local().attribute() == attribute_))
1791 ++(iter->second.first);
1794 if(iter->second.first == iter->second.second)
1803 template<
typename T,
typename A>
1806 return map_.empty();
1809 template<
typename T,
typename A>
1814 return iterator(map_.begin(), map_.end(), index_);
1816 return iterator(map_.begin(), map_.end(), index_,
1820 template<
typename T,
typename A>
1821 inline typename CollectiveIterator<T,A>::iterator
1822 CollectiveIterator<T,A>::end()
1824 return iterator(map_.end(), map_.end(), index_);
1827 template<
typename TG,
typename TA>
1828 inline std::ostream& operator<<(std::ostream& os,
const RemoteIndex<TG,TA>& index)
1830 os<<
"[global="<<index.localIndexPair().global()<<
", remote attribute="<<index.attribute()<<
" local attribute="<<index.localIndexPair().local().attribute()<<
"]";
1834 template<
typename T,
typename A>
1835 inline std::ostream& operator<<(std::ostream& os,
const RemoteIndices<T,A>& indices)
1838 MPI_Comm_rank(indices.comm_, &rank);
1839 const auto rend = indices.remoteIndices_.end();
1841 for(
auto rindex = indices.remoteIndices_.begin(); rindex!=rend; ++rindex) {
1842 os<<rank<<
": Prozess "<<rindex->first<<
":";
1844 if(!rindex->second.first->empty()) {
1847 const auto send= rindex->second.first->end();
1849 for(
auto index = rindex->second.first->begin();
1850 index != send; ++index)
1854 if(!rindex->second.second->empty()) {
1855 os<<rank<<
": Prozess "<<rindex->first<<
": "<<
"receive: ";
1857 for(
const auto& index : *(rindex->second.second))
1860 os<<std::endl<<std::flush;
Iterator over the valid underlying iterators.
Definition: remoteindices.hh:792
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex &index)
Definition: remoteindices.hh:799
iterator(const iterator &other)
Definition: remoteindices.hh:817
const RemoteIndex & operator*() const
Definition: remoteindices.hh:838
iterator & operator++()
Definition: remoteindices.hh:822
const RemoteIndex * operator->() const
Definition: remoteindices.hh:850
bool operator==(const iterator &other) const
Definition: remoteindices.hh:856
int process() const
Definition: remoteindices.hh:844
bool operator!=(const iterator &other) const
Definition: remoteindices.hh:862
A collective iterator for moving over the remote indices for all processes collectively.
Definition: remoteindices.hh:708
CollectiveIterator(const RemoteIndexMap &map_, bool send)
Constructor.
Definition: remoteindices.hh:1703
bool empty() const
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1804
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1716
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:748
A pair consisting of a global and local index.
Definition: indexset.hh:83
Class for recomputing missing indices of a distributed index set.
Definition: indicessyncer.hh:39
Base class of all classes representing a communication interface.
Definition: interface.hh:33
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:203
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:172
Manager class for the mapping between local indices and globally unique indices.
Definition: indexset.hh:216
An index present on the local process with an additional attribute flag.
Definition: plocalindex.hh:47
Default exception class for range errors.
Definition: exceptions.hh:252
Modifier for adding and/or deleting remote indices from the remote index list.
Definition: remoteindices.hh:549
void repairLocalIndexPointers()
Repair the pointers to the local index pairs.
Definition: remoteindices.hh:1575
@ MODIFYINDEXSET
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:567
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:602
A Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:598
void insert(const RemoteIndex &index)
Insert an index to the list.
Definition: remoteindices.hh:1605
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:578
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:583
RemoteIndexList::const_iterator ConstIterator
The type of the remote index list iterator.
Definition: remoteindices.hh:612
SLListModifyIterator< RemoteIndex, Allocator > ModifyIterator
The type of the modifying iterator of the remote index list.
Definition: remoteindices.hh:607
bool remove(const GlobalIndex &global)
Remove a remote index.
Definition: remoteindices.hh:1653
T ParallelIndexSet
Type of the index set we use.
Definition: remoteindices.hh:573
RemoteIndexListModifier()
Default constructor.
Definition: remoteindices.hh:676
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:588
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:593
Information about an index residing on another processor.
Definition: remoteindices.hh:71
const Attribute attribute() const
Get the attribute of the index on the remote process.
Definition: remoteindices.hh:946
T1 GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: remoteindices.hh:88
T2 Attribute
The type of the attributes. Normally this will be an enumeration like.
Definition: remoteindices.hh:97
IndexPair< GlobalIndex, ParallelLocalIndex< Attribute > > PairType
The type of the index pair.
Definition: remoteindices.hh:103
const PairType & localIndexPair() const
Get the corresponding local index pair.
Definition: remoteindices.hh:952
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:930
The indices present on remote processes.
Definition: remoteindices.hh:187
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:229
friend void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
Fills the holes in an index set.
Definition: repartition.hh:81
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:984
void free()
Free the index lists.
Definition: remoteindices.hh:1429
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:213
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1453
T ParallelIndexSet
Type of the index set we use, e.g. ParallelLocalIndexSet.
Definition: remoteindices.hh:204
MPI_Comm communicator() const
Get the mpi communicator used.
Definition: remoteindices.hh:1696
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:224
CollectiveIteratorT iterator() const
Get an iterator for colletively iterating over the remote indices of all remote processes.
Definition: remoteindices.hh:1690
void setIncludeSelf(bool includeSelf)
Tell whether sending from indices of the processor to other indices on the same processor is enabled ...
Definition: remoteindices.hh:971
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1529
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:243
RemoteIndexListModifier< T, A, mode > getModifier(int process)
Get a modifier for a remote index list.
Definition: remoteindices.hh:1480
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:999
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1014
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:239
int neighbours() const
Get the number of processors we share indices with.
Definition: remoteindices.hh:1446
CollectiveIterator< T, A > CollectiveIteratorT
The type of the collective iterator over all remote indices.
Definition: remoteindices.hh:208
const ParallelIndexSet & destinationIndexSet() const
Get the index set at destination.
Definition: remoteindices.hh:1007
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:958
typename std::allocator_traits< A >::template rebind_alloc< RemoteIndex > Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:235
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1515
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1473
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1522
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:219
A constant iterator for the SLList.
Definition: sllist.hh:369
A single linked list.
Definition: sllist.hh:42
A few common exception classes.
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:485
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.
TL LocalIndex
The type of the local index, e.g. ParallelLocalIndex.
Definition: indexset.hh:237
TG GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: indexset.hh:224
@ GROUND
The default mode. Indicates that the index set is ready to be used.
Definition: indexset.hh:184
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:780
SLListConstIterator< RemoteIndex, Allocator > const_iterator
The constant iterator of the list.
Definition: sllist.hh:72
SLListModifyIterator< GlobalIndex, Allocator > ModifyIterator
The type of the iterator capable of deletion and insertion.
Definition: sllist.hh:101
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:768
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
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:235
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:257
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:93
Provides a map between global and local indices.
Traits classes for mapping types onto MPI_Datatype.
Dune namespace.
Definition: alignedallocator.hh:11
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:39