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 
 1612      DUNE_THROW(InvalidPosition, 
"Modification of remote indices have to occur with ascending global index.");
 
 1621    iter_.insert(index);
 
 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:348
 
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.
 
Provides a map between global and local indices.
 
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
 
const GlobalIndex & global() const
Get the global index.
 
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
 
RemoteIndex(const T2 &attribute, const PairType *local)
Constructor.
Definition: remoteindices.hh:919
 
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
 
RemoteIndex(const T2 &attribute)
Constructor. Private as it should only be called from within Indexset.
Definition: remoteindices.hh:924
 
@ 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,...)
Definition: exceptions.hh:314
 
constexpr 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
 
constexpr 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
 
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