dune-common  2.5.0
remoteindices.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_REMOTEINDICES_HH
4 #define DUNE_REMOTEINDICES_HH
5 
6 #include "indexset.hh"
7 #include "plocalindex.hh"
10 #include <dune/common/sllist.hh>
12 #include <map>
13 #include <set>
14 #include <utility>
15 #include <iostream>
16 #include <algorithm>
17 #include <iterator>
18 #if HAVE_MPI
19 #include "mpitraits.hh"
20 #include <mpi.h>
21 
22 namespace Dune {
33  template<typename TG, typename TA>
36  {
37  public:
38  inline static MPI_Datatype getType();
39  private:
40  static MPI_Datatype type;
41  };
42 
43 
44  template<typename T, typename A>
46 
47  template<typename T1, typename T2>
48  class RemoteIndex;
49 
50  template<typename T>
51  class IndicesSyncer;
52 
53  template<typename T1, typename T2>
54  std::ostream& operator<<(std::ostream& os, const RemoteIndex<T1,T2>& index);
55 
56 
57  template<typename T, typename A, bool mode>
59 
60 
64  template<typename T1, typename T2>
65  class RemoteIndex
66  {
67  template<typename T>
68  friend class IndicesSyncer;
69 
70  template<typename T, typename A, typename A1>
71  friend void repairLocalIndexPointers(std::map<int,SLList<std::pair<typename T::GlobalIndex, typename T::LocalIndex::Attribute>,A> >&,
73  const T&);
74 
75  template<typename T, typename A, bool mode>
77 
78  public:
83  typedef T1 GlobalIndex;
92  typedef T2 Attribute;
93 
99 
104  const Attribute attribute() const;
105 
111  const PairType& localIndexPair() const;
112 
116  RemoteIndex();
117 
118 
124  RemoteIndex(const T2& attribute,
125  const PairType* local);
126 
127 
133  RemoteIndex(const T2& attribute);
134 
135  bool operator==(const RemoteIndex& ri) const;
136 
137  bool operator!=(const RemoteIndex& ri) const;
138  private:
140  const PairType* localIndex_;
141 
143  char attribute_;
144  };
145 
146  template<class T, class A>
147  std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices);
148 
149  class InterfaceBuilder;
150 
151  template<class T, class A>
153 
154  template<class T>
155  class IndicesSyncer;
156 
157  // forward declaration needed for friend declaration.
158  template<typename T1, typename T2>
160 
161 
178  template<class T, class A=std::allocator<RemoteIndex<typename T::GlobalIndex,
179  typename T::LocalIndex::Attribute> > >
180  class RemoteIndices
181  {
182  friend class InterfaceBuilder;
183  friend class IndicesSyncer<T>;
184  template<typename T1, typename A2, typename A1>
185  friend void repairLocalIndexPointers(std::map<int,SLList<std::pair<typename T1::GlobalIndex, typename T1::LocalIndex::Attribute>,A2> >&,
187  const T1&);
188 
189  template<class G, class T1, class T2>
190  friend void fillIndexSetHoles(const G& graph, Dune::OwnerOverlapCopyCommunication<T1,T2>& oocomm);
191  friend std::ostream& operator<<<>(std::ostream&, const RemoteIndices<T>&);
192 
193  public:
194 
198  typedef T ParallelIndexSet;
199 
203 
208 
209 
214 
218  typedef typename LocalIndex::Attribute Attribute;
219 
224 
225 
229  typedef typename A::template rebind<RemoteIndex>::other Allocator;
230 
234 
236  typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
238 
239  typedef typename RemoteIndexMap::const_iterator const_iterator;
240 
258  inline RemoteIndices(const ParallelIndexSet& source, const ParallelIndexSet& destination,
259  const MPI_Comm& comm, const std::vector<int>& neighbours=std::vector<int>(), bool includeSelf=false);
260 
261  RemoteIndices();
262 
270  void setIncludeSelf(bool includeSelf);
271 
288  void setIndexSets(const ParallelIndexSet& source, const ParallelIndexSet& destination,
289  const MPI_Comm& comm, const std::vector<int>& neighbours=std::vector<int>());
290 
291  template<typename C>
292  void setNeighbours(const C& neighbours)
293  {
294  neighbourIds.clear();
295  neighbourIds.insert(neighbours.begin(), neighbours.end());
296 
297  }
298 
299  const std::set<int>& getNeighbours() const
300  {
301  return neighbourIds;
302  }
303 
307  ~RemoteIndices();
308 
318  template<bool ignorePublic>
319  void rebuild();
320 
321  bool operator==(const RemoteIndices& ri);
322 
330  inline bool isSynced() const;
331 
335  inline MPI_Comm communicator() const;
336 
351  template<bool mode, bool send>
352  inline RemoteIndexListModifier<T,A,mode> getModifier(int process);
353 
360  inline const_iterator find(int proc) const;
361 
366  inline const_iterator begin() const;
367 
372  inline const_iterator end() const;
373 
377  template<bool send>
378  inline CollectiveIteratorT iterator() const;
379 
383  inline void free();
384 
389  inline int neighbours() const;
390 
392  inline const ParallelIndexSet& sourceIndexSet() const;
393 
395  inline const ParallelIndexSet& destinationIndexSet() const;
396 
397  private:
400  {}
401 
403  const ParallelIndexSet* source_;
404 
406  const ParallelIndexSet* target_;
407 
409  MPI_Comm comm_;
410 
413  std::set<int> neighbourIds;
414 
416  const static int commTag_=333;
417 
422  int sourceSeqNo_;
423 
428  int destSeqNo_;
429 
433  bool publicIgnored;
434 
438  bool firstBuild;
439 
440  /*
441  * @brief If true, sending from indices of the processor to other
442  * indices on the same processor is enabled even if the same indexset is used
443  * on both the
444  * sending and receiving side.
445  */
446  bool includeSelf;
447 
450  PairType;
451 
458  RemoteIndexMap remoteIndices_;
459 
470  template<bool ignorePublic>
471  inline void buildRemote(bool includeSelf);
472 
478  inline int noPublic(const ParallelIndexSet& indexSet);
479 
491  template<bool ignorePublic>
492  inline void packEntries(PairType** myPairs, const ParallelIndexSet& indexSet,
493  char* p_out, MPI_Datatype type, int bufferSize,
494  int* position, int n);
495 
509  inline void unpackIndices(RemoteIndexList& remote, int remoteEntries,
510  PairType** local, int localEntries, char* p_in,
511  MPI_Datatype type, int* position, int bufferSize,
512  bool fromOurself);
513 
514  inline void unpackIndices(RemoteIndexList& send, RemoteIndexList& receive,
515  int remoteEntries, PairType** localSource,
516  int localSourceEntries, PairType** localDest,
517  int localDestEntries, char* p_in,
518  MPI_Datatype type, int* position, int bufferSize);
519 
520  void unpackCreateRemote(char* p_in, PairType** sourcePairs, PairType** DestPairs,
521  int remoteProc, int sourcePublish, int destPublish,
522  int bufferSize, bool sendTwo, bool fromOurSelf=false);
523  };
524 
542  template<class T, class A, bool mode>
544  {
545 
546  template<typename T1, typename A1>
547  friend class RemoteIndices;
548 
549  public:
551  {};
552 
553  enum {
562  MODIFYINDEXSET=mode
563  };
564 
568  typedef T ParallelIndexSet;
569 
574 
579 
583  typedef typename LocalIndex::Attribute Attribute;
584 
589 
593  typedef A Allocator;
594 
598 
603 
608 
622  void insert(const RemoteIndex& index) throw(InvalidPosition);
623 
624 
639  void insert(const RemoteIndex& index, const GlobalIndex& global) throw(InvalidPosition);
640 
648  bool remove(const GlobalIndex& global) throw(InvalidPosition);
649 
663 
664 
666 
671  RemoteIndexListModifier()
672  : glist_()
673  {}
674 
675  private:
676 
682  RemoteIndexListModifier(const ParallelIndexSet& indexSet,
683  RemoteIndexList& rList);
684 
686  typedef typename GlobalList::ModifyIterator GlobalModifyIterator;
687  RemoteIndexList* rList_;
688  const ParallelIndexSet* indexSet_;
689  GlobalList glist_;
690  ModifyIterator iter_;
691  GlobalModifyIterator giter_;
692  ConstIterator end_;
693  bool first_;
694  GlobalIndex last_;
695  };
696 
701  template<class T, class A>
702  class CollectiveIterator
703  {
704 
708  typedef T ParallelIndexSet;
709 
713  typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
714 
718  typedef typename ParallelIndexSet::LocalIndex LocalIndex;
719 
723  typedef typename LocalIndex::Attribute Attribute;
724 
726  typedef Dune::RemoteIndex<GlobalIndex,Attribute> RemoteIndex;
727 
729  typedef typename A::template rebind<RemoteIndex>::other Allocator;
730 
733 
735  typedef std::map<int,std::pair<typename RemoteIndexList::const_iterator,
736  const typename RemoteIndexList::const_iterator> >
737  Map;
738 
739  public:
740 
742  typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
744 
750  inline CollectiveIterator(const RemoteIndexMap& map_, bool send);
751 
760  inline void advance(const GlobalIndex& global);
761 
771  inline void advance(const GlobalIndex& global, const Attribute& attribute);
772 
773  CollectiveIterator& operator++();
774 
778  inline bool empty();
779 
786  class iterator
787  {
788  public:
789  typedef typename Map::iterator RealIterator;
790  typedef typename Map::iterator ConstRealIterator;
791 
792 
794  iterator(const RealIterator& iter, const ConstRealIterator& end, GlobalIndex& index)
795  : iter_(iter), end_(end), index_(index), hasAttribute(false)
796  {
797  // Move to the first valid entry
798  while(iter_!=end_ && iter_->second.first->localIndexPair().global()!=index_)
799  ++iter_;
800  }
801 
802  iterator(const RealIterator& iter, const ConstRealIterator& end, GlobalIndex index,
803  Attribute attribute)
804  : iter_(iter), end_(end), index_(index), attribute_(attribute), hasAttribute(true)
805  {
806  // Move to the first valid entry or the end
807  while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_
808  || iter_->second.first->localIndexPair().local().attribute()!=attribute))
809  ++iter_;
810  }
812  iterator(const iterator& other)
813  : iter_(other.iter_), end_(other.end_), index_(other.index_)
814  { }
815 
818  {
819  ++iter_;
820  // If entry is not valid move on
821  while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_ ||
822  (hasAttribute &&
823  iter_->second.first->localIndexPair().local().attribute()!=attribute_)))
824  ++iter_;
825  assert(iter_==end_ ||
826  (iter_->second.first->localIndexPair().global()==index_));
827  assert(iter_==end_ || !hasAttribute ||
828  (iter_->second.first->localIndexPair().local().attribute()==attribute_));
829  return *this;
830  }
831 
833  const RemoteIndex& operator*() const
834  {
835  return *(iter_->second.first);
836  }
837 
839  int process() const
840  {
841  return iter_->first;
842  }
843 
845  const RemoteIndex* operator->() const
846  {
847  return iter_->second.first.operator->();
848  }
849 
851  bool operator==(const iterator& other)
852  {
853  return other.iter_==iter_;
854  }
855 
857  bool operator!=(const iterator& other)
858  {
859  return other.iter_!=iter_;
860  }
861 
862  private:
863  iterator();
864 
865  RealIterator iter_;
866  RealIterator end_;
867  GlobalIndex index_;
868  Attribute attribute_;
869  bool hasAttribute;
870  };
871 
872  iterator begin();
873 
874  iterator end();
875 
876  private:
877 
878  Map map_;
879  GlobalIndex index_;
880  Attribute attribute_;
881  bool noattribute;
882  };
883 
884  template<typename TG, typename TA>
886  {
887  if(type==MPI_DATATYPE_NULL) {
888  int length[2] = {1, 1};
889  MPI_Aint base;
890  MPI_Aint disp[2];
891  MPI_Datatype types[2] = {MPITraits<TG>::getType(),
894  MPI_Get_address(&rep, &base); // lower bound of the datatype
895  MPI_Get_address(&(rep.global_), &disp[0]);
896  MPI_Get_address(&(rep.local_), &disp[1]);
897  for (MPI_Aint& d : disp)
898  d -= base;
899 
900  MPI_Datatype tmp;
901  MPI_Type_create_struct(2, length, disp, types, &tmp);
902 
903  MPI_Type_create_resized(tmp, 0, sizeof(IndexPair<TG,ParallelLocalIndex<TA> >), &type);
904  MPI_Type_commit(&type);
905 
906  MPI_Type_free(&tmp);
907  }
908  return type;
909  }
910 
911  template<typename TG, typename TA>
912  MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::type=MPI_DATATYPE_NULL;
913 
914  template<typename T1, typename T2>
915  RemoteIndex<T1,T2>::RemoteIndex(const T2& attribute, const PairType* local)
916  : localIndex_(local), attribute_(attribute)
917  {}
918 
919  template<typename T1, typename T2>
921  : localIndex_(0), attribute_(attribute)
922  {}
923 
924  template<typename T1, typename T2>
926  : localIndex_(0), attribute_()
927  {}
928  template<typename T1, typename T2>
929  inline bool RemoteIndex<T1,T2>::operator==(const RemoteIndex& ri) const
930  {
931  return localIndex_==ri.localIndex_ && attribute_==ri.attribute;
932  }
933 
934  template<typename T1, typename T2>
935  inline bool RemoteIndex<T1,T2>::operator!=(const RemoteIndex& ri) const
936  {
937  return localIndex_!=ri.localIndex_ || attribute_!=ri.attribute_;
938  }
939 
940  template<typename T1, typename T2>
941  inline const T2 RemoteIndex<T1,T2>::attribute() const
942  {
943  return T2(attribute_);
944  }
945 
946  template<typename T1, typename T2>
948  {
949  return *localIndex_;
950  }
951 
952  template<typename T, typename A>
953  inline RemoteIndices<T,A>::RemoteIndices(const ParallelIndexSet& source,
954  const ParallelIndexSet& destination,
955  const MPI_Comm& comm,
956  const std::vector<int>& neighbours,
957  bool includeSelf_)
958  : source_(&source), target_(&destination), comm_(comm),
959  sourceSeqNo_(-1), destSeqNo_(-1), publicIgnored(false), firstBuild(true),
960  includeSelf(includeSelf_)
961  {
962  setNeighbours(neighbours);
963  }
964 
965  template<typename T, typename A>
967  {
968  includeSelf=b;
969  }
970 
971  template<typename T, typename A>
973  : source_(0), target_(0), sourceSeqNo_(-1),
974  destSeqNo_(-1), publicIgnored(false), firstBuild(true),
975  includeSelf(false)
976  {}
977 
978  template<class T, typename A>
979  void RemoteIndices<T,A>::setIndexSets(const ParallelIndexSet& source,
980  const ParallelIndexSet& destination,
981  const MPI_Comm& comm,
982  const std::vector<int>& neighbours)
983  {
984  free();
985  source_ = &source;
986  target_ = &destination;
987  comm_ = comm;
988  firstBuild = true;
989  setNeighbours(neighbours);
990  }
991 
992  template<typename T, typename A>
995  {
996  return *source_;
997  }
998 
999 
1000  template<typename T, typename A>
1001  const typename RemoteIndices<T,A>::ParallelIndexSet&
1003  {
1004  return *target_;
1005  }
1006 
1007 
1008  template<typename T, typename A>
1010  {
1011  free();
1012  }
1013 
1014  template<typename T, typename A>
1015  template<bool ignorePublic>
1017  const ParallelIndexSet& indexSet,
1018  char* p_out, MPI_Datatype type,
1019  int bufferSize,
1020  int *position, int n)
1021  {
1023  // fill with own indices
1026  const const_iterator end = indexSet.end();
1027 
1028  //Now pack the source indices
1029  int i=0;
1030  for(const_iterator index = indexSet.begin(); index != end; ++index)
1031  if(ignorePublic || index->local().isPublic()) {
1032 
1033  MPI_Pack(const_cast<PairType*>(&(*index)), 1,
1034  type,
1035  p_out, bufferSize, position, comm_);
1036  pairs[i++] = const_cast<PairType*>(&(*index));
1037 
1038  }
1039  assert(i==n);
1040  }
1041 
1042  template<typename T, typename A>
1043  inline int RemoteIndices<T,A>::noPublic(const ParallelIndexSet& indexSet)
1044  {
1046 
1047  int noPublic=0;
1048 
1049  const const_iterator end=indexSet.end();
1050  for(const_iterator index=indexSet.begin(); index!=end; ++index)
1051  if(index->local().isPublic())
1052  noPublic++;
1053 
1054  return noPublic;
1055 
1056  }
1057 
1058 
1059  template<typename T, typename A>
1060  inline void RemoteIndices<T,A>::unpackCreateRemote(char* p_in, PairType** sourcePairs,
1061  PairType** destPairs, int remoteProc,
1062  int sourcePublish, int destPublish,
1063  int bufferSize, bool sendTwo,
1064  bool fromOurSelf)
1065  {
1066 
1067  // unpack the number of indices we received
1068  int noRemoteSource=-1, noRemoteDest=-1;
1069  char twoIndexSets=0;
1070  int position=0;
1071  // Did we receive two index sets?
1072  MPI_Unpack(p_in, bufferSize, &position, &twoIndexSets, 1, MPI_CHAR, comm_);
1073  // The number of source indices received
1074  MPI_Unpack(p_in, bufferSize, &position, &noRemoteSource, 1, MPI_INT, comm_);
1075  // The number of destination indices received
1076  MPI_Unpack(p_in, bufferSize, &position, &noRemoteDest, 1, MPI_INT, comm_);
1077 
1078 
1079  // Indices for which we receive
1080  RemoteIndexList* receive= new RemoteIndexList();
1081  // Indices for which we send
1082  RemoteIndexList* send=0;
1083 
1084  MPI_Datatype type= MPITraits<PairType>::getType();
1085 
1086  if(!twoIndexSets) {
1087  if(sendTwo) {
1088  send = new RemoteIndexList();
1089  // Create both remote index sets simultaneously
1090  unpackIndices(*send, *receive, noRemoteSource, sourcePairs, sourcePublish,
1091  destPairs, destPublish, p_in, type, &position, bufferSize);
1092  }else{
1093  // we only need one list
1094  unpackIndices(*receive, noRemoteSource, sourcePairs, sourcePublish,
1095  p_in, type, &position, bufferSize, fromOurSelf);
1096  send=receive;
1097  }
1098  }else{
1099 
1100  int oldPos=position;
1101  // Two index sets received
1102  unpackIndices(*receive, noRemoteSource, destPairs, destPublish,
1103  p_in, type, &position, bufferSize, fromOurSelf);
1104  if(!sendTwo)
1105  //unpack source entries again as destination entries
1106  position=oldPos;
1107 
1108  send = new RemoteIndexList();
1109  unpackIndices(*send, noRemoteDest, sourcePairs, sourcePublish,
1110  p_in, type, &position, bufferSize, fromOurSelf);
1111  }
1112 
1113  if(receive->empty() && send->empty()) {
1114  if(send==receive) {
1115  delete send;
1116  }else{
1117  delete send;
1118  delete receive;
1119  }
1120  }else{
1121  remoteIndices_.insert(std::make_pair(remoteProc,
1122  std::make_pair(send,receive)));
1123  }
1124  }
1125 
1126 
1127  template<typename T, typename A>
1128  template<bool ignorePublic>
1129  inline void RemoteIndices<T,A>::buildRemote(bool includeSelf_)
1130  {
1131  // Processor configuration
1132  int rank, procs;
1133  MPI_Comm_rank(comm_, &rank);
1134  MPI_Comm_size(comm_, &procs);
1135 
1136  // number of local indices to publish
1137  // The indices of the destination will be send.
1138  int sourcePublish, destPublish;
1139 
1140  // Do we need to send two index sets?
1141  char sendTwo = (source_ != target_);
1142 
1143  if(procs==1 && !(sendTwo || includeSelf_))
1144  // Nothing to communicate
1145  return;
1146 
1147  sourcePublish = (ignorePublic) ? source_->size() : noPublic(*source_);
1148 
1149  if(sendTwo)
1150  destPublish = (ignorePublic) ? target_->size() : noPublic(*target_);
1151  else
1152  // we only need to send one set of indices
1153  destPublish = 0;
1154 
1155  int maxPublish, publish=sourcePublish+destPublish;
1156 
1157  // Calucate maximum number of indices send
1158  MPI_Allreduce(&publish, &maxPublish, 1, MPI_INT, MPI_MAX, comm_);
1159 
1160  // allocate buffers
1162 
1163  PairType** destPairs;
1164  PairType** sourcePairs = new PairType*[sourcePublish>0 ? sourcePublish : 1];
1165 
1166  if(sendTwo)
1167  destPairs = new PairType*[destPublish>0 ? destPublish : 1];
1168  else
1169  destPairs=sourcePairs;
1170 
1171  char** buffer = new char*[2];
1172  int bufferSize;
1173  int position=0;
1174  int intSize;
1175  int charSize;
1176 
1177  // calculate buffer size
1178  MPI_Datatype type = MPITraits<PairType>::getType();
1179 
1180  MPI_Pack_size(maxPublish, type, comm_,
1181  &bufferSize);
1182  MPI_Pack_size(1, MPI_INT, comm_,
1183  &intSize);
1184  MPI_Pack_size(1, MPI_CHAR, comm_,
1185  &charSize);
1186  // Our message will contain the following:
1187  // a bool whether two index sets where sent
1188  // the size of the source and the dest indexset,
1189  // then the source and destination indices
1190  bufferSize += 2 * intSize + charSize;
1191 
1192  if(bufferSize<=0) bufferSize=1;
1193 
1194  buffer[0] = new char[bufferSize];
1195  buffer[1] = new char[bufferSize];
1196 
1197 
1198  // pack entries into buffer[0], p_out below!
1199  MPI_Pack(&sendTwo, 1, MPI_CHAR, buffer[0], bufferSize, &position,
1200  comm_);
1201 
1202  // The number of indices we send for each index set
1203  MPI_Pack(&sourcePublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1204  comm_);
1205  MPI_Pack(&destPublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1206  comm_);
1207 
1208  // Now pack the source indices and setup the destination pairs
1209  packEntries<ignorePublic>(sourcePairs, *source_, buffer[0], type,
1210  bufferSize, &position, sourcePublish);
1211  // If necessary send the dest indices and setup the source pairs
1212  if(sendTwo)
1213  packEntries<ignorePublic>(destPairs, *target_, buffer[0], type,
1214  bufferSize, &position, destPublish);
1215 
1216 
1217  // Update remote indices for ourself
1218  if(sendTwo|| includeSelf_)
1219  unpackCreateRemote(buffer[0], sourcePairs, destPairs, rank, sourcePublish,
1220  destPublish, bufferSize, sendTwo, includeSelf_);
1221 
1222  neighbourIds.erase(rank);
1223 
1224  if(neighbourIds.size()==0)
1225  {
1226  Dune::dvverb<<rank<<": Sending messages in a ring"<<std::endl;
1227  // send messages in ring
1228  for(int proc=1; proc<procs; proc++) {
1229  // pointers to the current input and output buffers
1230  char* p_out = buffer[1-(proc%2)];
1231  char* p_in = buffer[proc%2];
1232 
1233  MPI_Status status;
1234  if(rank%2==0) {
1235  MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1236  commTag_, comm_);
1237  MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1238  commTag_, comm_, &status);
1239  }else{
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,
1243  commTag_, comm_);
1244  }
1245 
1246 
1247  // The process these indices are from
1248  int remoteProc = (rank+procs-proc)%procs;
1249 
1250  unpackCreateRemote(p_in, sourcePairs, destPairs, remoteProc, sourcePublish,
1251  destPublish, bufferSize, sendTwo);
1252 
1253  }
1254 
1255  }
1256  else
1257  {
1258  MPI_Request* requests=new MPI_Request[neighbourIds.size()];
1259  MPI_Request* req=requests;
1260 
1261  typedef typename std::set<int>::size_type size_type;
1262  size_type noNeighbours=neighbourIds.size();
1263 
1264  // setup sends
1265  for(std::set<int>::iterator neighbour=neighbourIds.begin();
1266  neighbour!= neighbourIds.end(); ++neighbour) {
1267  // Only send the information to the neighbouring processors
1268  MPI_Issend(buffer[0], position , MPI_PACKED, *neighbour, commTag_, comm_, req++);
1269  }
1270 
1271  //Test for received messages
1272 
1273  for(size_type received=0; received <noNeighbours; ++received)
1274  {
1275  MPI_Status status;
1276  // probe for next message
1277  MPI_Probe(MPI_ANY_SOURCE, commTag_, comm_, &status);
1278  int remoteProc=status.MPI_SOURCE;
1279  int size;
1280  MPI_Get_count(&status, MPI_PACKED, &size);
1281  // receive message
1282  MPI_Recv(buffer[1], size, MPI_PACKED, remoteProc,
1283  commTag_, comm_, &status);
1284 
1285  unpackCreateRemote(buffer[1], sourcePairs, destPairs, remoteProc, sourcePublish,
1286  destPublish, bufferSize, sendTwo);
1287  }
1288  // wait for completion of pending requests
1289  MPI_Status* statuses = new MPI_Status[neighbourIds.size()];
1290 
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);
1296  }
1297  }
1298  delete[] requests;
1299  delete[] statuses;
1300  }
1301 
1302 
1303  // delete allocated memory
1304  if(destPairs!=sourcePairs)
1305  delete[] destPairs;
1306 
1307  delete[] sourcePairs;
1308  delete[] buffer[0];
1309  delete[] buffer[1];
1310  delete[] buffer;
1311  }
1312 
1313  template<typename T, typename A>
1315  int remoteEntries,
1316  PairType** local,
1317  int localEntries,
1318  char* p_in,
1319  MPI_Datatype type,
1320  int* position,
1321  int bufferSize,
1322  bool fromOurSelf)
1323  {
1324  if(remoteEntries==0)
1325  return;
1326 
1327  PairType index(1);
1328  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1329  type, comm_);
1330  GlobalIndex oldGlobal=index.global();
1331  int n_in=0, localIndex=0;
1332 
1333  //Check if we know the global index
1334  while(localIndex<localEntries) {
1335  if(local[localIndex]->global()==index.global()) {
1336  int oldLocalIndex=localIndex;
1337 
1338  while(localIndex<localEntries &&
1339  local[localIndex]->global()==index.global()) {
1340  if(!fromOurSelf || index.local().attribute() !=
1341  local[localIndex]->local().attribute())
1342  // if index is from us it has to have a different attribute
1343  remote.push_back(RemoteIndex(index.local().attribute(),
1344  local[localIndex]));
1345  localIndex++;
1346  }
1347 
1348  // unpack next remote index
1349  if((++n_in) < remoteEntries) {
1350  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1351  type, comm_);
1352  if(index.global()==oldGlobal)
1353  // Restart comparison for the same global indices
1354  localIndex=oldLocalIndex;
1355  else
1356  oldGlobal=index.global();
1357  }else{
1358  // No more received indices
1359  break;
1360  }
1361  continue;
1362  }
1363 
1364  if (local[localIndex]->global()<index.global()) {
1365  // compare with next entry in our list
1366  ++localIndex;
1367  }else{
1368  // We do not know the index, unpack next
1369  if((++n_in) < remoteEntries) {
1370  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1371  type, comm_);
1372  oldGlobal=index.global();
1373  }else
1374  // No more received indices
1375  break;
1376  }
1377  }
1378 
1379  // Unpack the other received indices without doing anything
1380  while(++n_in < remoteEntries)
1381  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1382  type, comm_);
1383  }
1384 
1385 
1386  template<typename T, typename A>
1388  RemoteIndexList& receive,
1389  int remoteEntries,
1390  PairType** localSource,
1391  int localSourceEntries,
1392  PairType** localDest,
1393  int localDestEntries,
1394  char* p_in,
1395  MPI_Datatype type,
1396  int* position,
1397  int bufferSize)
1398  {
1399  int n_in=0, sourceIndex=0, destIndex=0;
1400 
1401  //Check if we know the global index
1402  while(n_in<remoteEntries && (sourceIndex<localSourceEntries || destIndex<localDestEntries)) {
1403  // Unpack next index
1404  PairType index;
1405  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1406  type, comm_);
1407  n_in++;
1408 
1409  // Advance until global index in localSource and localDest are >= than the one in the unpacked index
1410  while(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()<index.global())
1411  sourceIndex++;
1412 
1413  while(destIndex<localDestEntries && localDest[destIndex]->global()<index.global())
1414  destIndex++;
1415 
1416  // Add a remote index if we found the global index.
1417  if(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()==index.global())
1418  send.push_back(RemoteIndex(index.local().attribute(),
1419  localSource[sourceIndex]));
1420 
1421  if(destIndex < localDestEntries && localDest[destIndex]->global() == index.global())
1422  receive.push_back(RemoteIndex(index.local().attribute(),
1423  localDest[sourceIndex]));
1424  }
1425 
1426  }
1427 
1428  template<typename T, typename A>
1430  {
1431  typedef typename RemoteIndexMap::iterator Iterator;
1432  Iterator lend = remoteIndices_.end();
1433  for(Iterator lists=remoteIndices_.begin(); lists != lend; ++lists) {
1434  if(lists->second.first==lists->second.second) {
1435  // there is only one remote index list.
1436  delete lists->second.first;
1437  }else{
1438  delete lists->second.first;
1439  delete lists->second.second;
1440  }
1441  }
1442  remoteIndices_.clear();
1443  firstBuild=true;
1444  }
1445 
1446  template<typename T, typename A>
1448  {
1449  return remoteIndices_.size();
1450  }
1451 
1452  template<typename T, typename A>
1453  template<bool ignorePublic>
1455  {
1456  // Test whether a rebuild is Needed.
1457  if(firstBuild ||
1458  ignorePublic!=publicIgnored || !
1459  isSynced()) {
1460  free();
1461 
1462  buildRemote<ignorePublic>(includeSelf);
1463 
1464  sourceSeqNo_ = source_->seqNo();
1465  destSeqNo_ = target_->seqNo();
1466  firstBuild=false;
1467  publicIgnored=ignorePublic;
1468  }
1469 
1470 
1471  }
1472 
1473  template<typename T, typename A>
1474  inline bool RemoteIndices<T,A>::isSynced() const
1475  {
1476  return sourceSeqNo_==source_->seqNo() && destSeqNo_ ==target_->seqNo();
1477  }
1478 
1479  template<typename T, typename A>
1480  template<bool mode, bool send>
1482  {
1483 
1484  // The user are on their own now!
1485  // We assume they know what they are doing and just set the
1486  // remote indices to synced status.
1487  sourceSeqNo_ = source_->seqNo();
1488  destSeqNo_ = target_->seqNo();
1489 
1490  typename RemoteIndexMap::iterator found = remoteIndices_.find(process);
1491 
1492  if(found == remoteIndices_.end())
1493  {
1494  if(source_ != target_)
1495  found = remoteIndices_.insert(found, std::make_pair(process,
1496  std::make_pair(new RemoteIndexList(),
1497  new RemoteIndexList())));
1498  else{
1499  RemoteIndexList* rlist = new RemoteIndexList();
1500  found = remoteIndices_.insert(found,
1501  std::make_pair(process,
1502  std::make_pair(rlist, rlist)));
1503  }
1504  }
1505 
1506  firstBuild = false;
1507 
1508  if(send)
1509  return RemoteIndexListModifier<T,A,mode>(*source_, *(found->second.first));
1510  else
1511  return RemoteIndexListModifier<T,A,mode>(*target_, *(found->second.second));
1512  }
1513 
1514  template<typename T, typename A>
1515  inline typename RemoteIndices<T,A>::const_iterator
1517  {
1518  return remoteIndices_.find(proc);
1519  }
1520 
1521  template<typename T, typename A>
1522  inline typename RemoteIndices<T,A>::const_iterator
1524  {
1525  return remoteIndices_.begin();
1526  }
1527 
1528  template<typename T, typename A>
1529  inline typename RemoteIndices<T,A>::const_iterator
1531  {
1532  return remoteIndices_.end();
1533  }
1534 
1535 
1536  template<typename T, typename A>
1538  {
1539  if(neighbours()!=ri.neighbours())
1540  return false;
1541 
1542  typedef RemoteIndexList RList;
1543  typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1544 
1545  const const_iterator rend = remoteIndices_.end();
1546 
1547  for(const_iterator rindex = remoteIndices_.begin(), rindex1=ri.remoteIndices_.begin(); rindex!=rend; ++rindex, ++rindex1) {
1548  if(rindex->first != rindex1->first)
1549  return false;
1550  if(*(rindex->second.first) != *(rindex1->second.first))
1551  return false;
1552  if(*(rindex->second.second) != *(rindex1->second.second))
1553  return false;
1554  }
1555  return true;
1556  }
1557 
1558  template<class T, class A, bool mode>
1559  RemoteIndexListModifier<T,A,mode>::RemoteIndexListModifier(const ParallelIndexSet& indexSet,
1560  RemoteIndexList& rList)
1561  : rList_(&rList), indexSet_(&indexSet), iter_(rList.beginModify()), end_(rList.end()), first_(true)
1562  {
1563  if(MODIFYINDEXSET) {
1564  assert(indexSet_);
1565  for(ConstIterator iter=iter_; iter != end_; ++iter)
1566  glist_.push_back(iter->localIndexPair().global());
1567  giter_ = glist_.beginModify();
1568  }
1569  }
1570 
1571  template<typename T, typename A, bool mode>
1573  : rList_(other.rList_), indexSet_(other.indexSet_),
1574  glist_(other.glist_), iter_(other.iter_), giter_(other.giter_), end_(other.end_),
1575  first_(other.first_), last_(other.last_)
1576  {}
1577 
1578  template<typename T, typename A, bool mode>
1580  {
1581  if(MODIFYINDEXSET) {
1582  // repair pointers to local index set.
1583 #ifdef DUNE_ISTL_WITH_CHECKING
1584  if(indexSet_->state()!=GROUND)
1585  DUNE_THROW(InvalidIndexSetState, "Index has to be in ground mode for repairing pointers to indices");
1586 #endif
1587  typedef typename ParallelIndexSet::const_iterator IndexIterator;
1588  typedef typename GlobalList::const_iterator GlobalIterator;
1589  typedef typename RemoteIndexList::iterator Iterator;
1590  GlobalIterator giter = glist_.begin();
1591  IndexIterator index = indexSet_->begin();
1592 
1593  for(Iterator iter=rList_->begin(); iter != end_; ++iter) {
1594  while(index->global()<*giter) {
1595  ++index;
1596 #ifdef DUNE_ISTL_WITH_CHECKING
1597  if(index == indexSet_->end())
1598  DUNE_THROW(InvalidPosition, "No such global index in set!");
1599 #endif
1600  }
1601 
1602 #ifdef DUNE_ISTL_WITH_CHECKING
1603  if(index->global() != *giter)
1604  DUNE_THROW(InvalidPosition, "No such global index in set!");
1605 #endif
1606  iter->localIndex_ = &(*index);
1607  }
1608  }
1609  }
1610 
1611  template<typename T, typename A, bool mode>
1612  inline void RemoteIndexListModifier<T,A,mode>::insert(const RemoteIndex& index) throw(InvalidPosition)
1613  {
1614  static_assert(!mode,"Not allowed if the mode indicates that new indices"
1615  "might be added to the underlying index set. Use "
1616  "insert(const RemoteIndex&, const GlobalIndex&) instead");
1617 
1618 #ifdef DUNE_ISTL_WITH_CHECKING
1619  if(!first_ && index.localIndexPair().global()<last_)
1620  DUNE_THROW(InvalidPosition, "Modifcation of remote indices have to occur with ascending global index.");
1621 #endif
1622  // Move to the correct position
1623  while(iter_ != end_ && iter_->localIndexPair().global() < index.localIndexPair().global()) {
1624  ++iter_;
1625  }
1626 
1627  // No duplicate entries allowed
1628  assert(iter_==end_ || iter_->localIndexPair().global() != index.localIndexPair().global());
1629  iter_.insert(index);
1630  last_ = index.localIndexPair().global();
1631  first_ = false;
1632  }
1633 
1634  template<typename T, typename A, bool mode>
1635  inline void RemoteIndexListModifier<T,A,mode>::insert(const RemoteIndex& index, const GlobalIndex& global) throw(InvalidPosition)
1636  {
1637  static_assert(mode,"Not allowed if the mode indicates that no new indices"
1638  "might be added to the underlying index set. Use "
1639  "insert(const RemoteIndex&) instead");
1640 #ifdef DUNE_ISTL_WITH_CHECKING
1641  if(!first_ && global<last_)
1642  DUNE_THROW(InvalidPosition, "Modification of remote indices have to occur with ascending global index.");
1643 #endif
1644  // Move to the correct position
1645  while(iter_ != end_ && *giter_ < global) {
1646  ++giter_;
1647  ++iter_;
1648  }
1649 
1650  // No duplicate entries allowed
1651  assert(iter_->localIndexPair().global() != global);
1652  iter_.insert(index);
1653  giter_.insert(global);
1654 
1655  last_ = global;
1656  first_ = false;
1657  }
1658 
1659  template<typename T, typename A, bool mode>
1660  bool RemoteIndexListModifier<T,A,mode>::remove(const GlobalIndex& global) throw(InvalidPosition)
1661  {
1662 #ifdef DUNE_ISTL_WITH_CHECKING
1663  if(!first_ && global<last_)
1664  DUNE_THROW(InvalidPosition, "Modifcation of remote indices have to occur with ascending global index.");
1665 #endif
1666 
1667  bool found= false;
1668 
1669  if(MODIFYINDEXSET) {
1670  // Move to the correct position
1671  while(iter_!=end_ && *giter_< global) {
1672  ++giter_;
1673  ++iter_;
1674  }
1675  if(*giter_ == global) {
1676  giter_.remove();
1677  iter_.remove();
1678  found=true;
1679  }
1680  }else{
1681  while(iter_!=end_ && iter_->localIndexPair().global() < global)
1682  ++iter_;
1683 
1684  if(iter_->localIndexPair().global()==global) {
1685  iter_.remove();
1686  found = true;
1687  }
1688  }
1689 
1690  last_ = global;
1691  first_ = false;
1692  return found;
1693  }
1694 
1695  template<typename T, typename A>
1696  template<bool send>
1698  {
1699  return CollectiveIterator<T,A>(remoteIndices_, send);
1700  }
1701 
1702  template<typename T, typename A>
1703  inline MPI_Comm RemoteIndices<T,A>::communicator() const
1704  {
1705  return comm_;
1706 
1707  }
1708 
1709  template<typename T, typename A>
1711  {
1712  typedef typename RemoteIndexMap::const_iterator const_iterator;
1713 
1714  const const_iterator end=pmap.end();
1715  for(const_iterator process=pmap.begin(); process != end; ++process) {
1716  const RemoteIndexList* list = send ? process->second.first : process->second.second;
1717  typedef typename RemoteIndexList::const_iterator iterator;
1718  map_.insert(std::make_pair(process->first,
1719  std::pair<iterator, const iterator>(list->begin(), list->end())));
1720  }
1721  }
1722 
1723  template<typename T, typename A>
1724  inline void CollectiveIterator<T,A>::advance(const GlobalIndex& index)
1725  {
1726  typedef typename Map::iterator iterator;
1727  typedef typename Map::const_iterator const_iterator;
1728  const const_iterator end = map_.end();
1729 
1730  for(iterator iter = map_.begin(); iter != end;) {
1731  // Step the iterator until we are >= index
1732  typename RemoteIndexList::const_iterator current = iter->second.first;
1733  typename RemoteIndexList::const_iterator rend = iter->second.second;
1734  RemoteIndex remoteIndex;
1735  if(current != rend)
1736  remoteIndex = *current;
1737 
1738  while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1739  ++(iter->second.first);
1740 
1741  // erase from the map if there are no more entries.
1742  if(iter->second.first == iter->second.second)
1743  map_.erase(iter++);
1744  else{
1745  ++iter;
1746  }
1747  }
1748  index_=index;
1749  noattribute=true;
1750  }
1751 
1752  template<typename T, typename A>
1753  inline void CollectiveIterator<T,A>::advance(const GlobalIndex& index,
1754  const Attribute& attribute)
1755  {
1756  typedef typename Map::iterator iterator;
1757  typedef typename Map::const_iterator const_iterator;
1758  const const_iterator end = map_.end();
1759 
1760  for(iterator iter = map_.begin(); iter != end;) {
1761  // Step the iterator until we are >= index
1762  typename RemoteIndexList::const_iterator current = iter->second.first;
1763  typename RemoteIndexList::const_iterator rend = iter->second.second;
1764  RemoteIndex remoteIndex;
1765  if(current != rend)
1766  remoteIndex = *current;
1767 
1768  // Move to global index or bigger
1769  while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1770  ++(iter->second.first);
1771 
1772  // move to attribute or bigger
1773  while(iter->second.first!=iter->second.second
1774  && iter->second.first->localIndexPair().global()==index
1775  && iter->second.first->localIndexPair().local().attribute()<attribute)
1776  ++(iter->second.first);
1777 
1778  // erase from the map if there are no more entries.
1779  if(iter->second.first == iter->second.second)
1780  map_.erase(iter++);
1781  else{
1782  ++iter;
1783  }
1784  }
1785  index_=index;
1786  attribute_=attribute;
1787  noattribute=false;
1788  }
1789 
1790  template<typename T, typename A>
1792  {
1793  typedef typename Map::iterator iterator;
1794  typedef typename Map::const_iterator const_iterator;
1795  const const_iterator end = map_.end();
1796 
1797  for(iterator iter = map_.begin(); iter != end;) {
1798  // Step the iterator until we are >= index
1799  typename RemoteIndexList::const_iterator current = iter->second.first;
1800  typename RemoteIndexList::const_iterator rend = iter->second.second;
1801 
1802  // move all iterators pointing to the current global index to next value
1803  if(iter->second.first->localIndexPair().global()==index_ &&
1804  (noattribute || iter->second.first->localIndexPair().local().attribute() == attribute_))
1805  ++(iter->second.first);
1806 
1807  // erase from the map if there are no more entries.
1808  if(iter->second.first == iter->second.second)
1809  map_.erase(iter++);
1810  else{
1811  ++iter;
1812  }
1813  }
1814  return *this;
1815  }
1816 
1817  template<typename T, typename A>
1819  {
1820  return map_.empty();
1821  }
1822 
1823  template<typename T, typename A>
1824  inline typename CollectiveIterator<T,A>::iterator
1826  {
1827  if(noattribute)
1828  return iterator(map_.begin(), map_.end(), index_);
1829  else
1830  return iterator(map_.begin(), map_.end(), index_,
1831  attribute_);
1832  }
1833 
1834  template<typename T, typename A>
1835  inline typename CollectiveIterator<T,A>::iterator
1837  {
1838  return iterator(map_.end(), map_.end(), index_);
1839  }
1840 
1841  template<typename TG, typename TA>
1842  inline std::ostream& operator<<(std::ostream& os, const RemoteIndex<TG,TA>& index)
1843  {
1844  os<<"[global="<<index.localIndexPair().global()<<", remote attribute="<<index.attribute()<<" local attribute="<<index.localIndexPair().local().attribute()<<"]";
1845  return os;
1846  }
1847 
1848  template<typename T, typename A>
1849  inline std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices)
1850  {
1851  int rank;
1852  MPI_Comm_rank(indices.comm_, &rank);
1853 
1854  typedef typename RemoteIndices<T,A>::RemoteIndexList RList;
1855  typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1856 
1857  const const_iterator rend = indices.remoteIndices_.end();
1858 
1859  for(const_iterator rindex = indices.remoteIndices_.begin(); rindex!=rend; ++rindex) {
1860  os<<rank<<": Prozess "<<rindex->first<<":";
1861 
1862  if(!rindex->second.first->empty()) {
1863  os<<" send:";
1864 
1865  const typename RList::const_iterator send= rindex->second.first->end();
1866 
1867  for(typename RList::const_iterator index = rindex->second.first->begin();
1868  index != send; ++index)
1869  os<<*index<<" ";
1870  os<<std::endl;
1871  }
1872  if(!rindex->second.second->empty()) {
1873  os<<rank<<": Prozess "<<rindex->first<<": "<<"receive: ";
1874 
1875  for(const auto& index : *(rindex->second.second))
1876  os << index << " ";
1877  }
1878  os<<std::endl<<std::flush;
1879  }
1880  return os;
1881  }
1883 }
1884 
1885 #endif
1886 #endif
void setIncludeSelf(bool includeSelf)
Tell whether sending from indices of the processor to other indices on the same processor is enabled ...
Definition: remoteindices.hh:966
RemoteIndexList::const_iterator ConstIterator
The type of the remote index list iterator.
Definition: remoteindices.hh:607
CollectiveIterator(const RemoteIndexMap &map_, bool send)
Constructor.
Definition: remoteindices.hh:1710
iterator end()
Definition: remoteindices.hh:1836
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:233
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:979
MPI_Comm communicator() const
Get the mpi communicator used.
Definition: remoteindices.hh:1703
TL LocalIndex
The type of the local index, e.g. ParallelLocalIndex.
Definition: indexset.hh:238
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:743
void push_back(const MemberType &item)
Add a new entry to the end of the list.
Definition: sllist.hh:657
T1 GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: remoteindices.hh:83
const GlobalIndex & global() const
Get the global index.
void insert(const RemoteIndex &index)
Insert an index to the list.
Definition: remoteindices.hh:1612
Provides classes for use as the local index in ParallelIndexSet for distributed computing.
A constant random access iterator for the Dune::ArrayList class.
Definition: arraylist.hh:20
The default mode. Indicates that the index set is ready to be used.
Definition: indexset.hh:185
static MPI_Datatype getType()
Definition: mpitraits.hh:46
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:490
bool empty() const
Check whether the list is empty.
Definition: sllist.hh:764
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:223
LocalIndex & local()
Get the local index.
RemoteIndexListModifier< T, A, mode > getModifier(int process)
Get a modifier for a remote index list.
Definition: remoteindices.hh:1481
bool operator==(const RemoteIndices &ri)
Definition: remoteindices.hh:1537
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: bigunsignedint.hh:25
bool operator==(const RemoteIndex &ri) const
Definition: remoteindices.hh:929
Provides a map between global and local indices.
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:573
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex index, Attribute attribute)
Definition: remoteindices.hh:802
A single linked list.
Definition: sllist.hh:41
SLListModifyIterator< RemoteIndex, Allocator > ModifyIterator
The type of the modifying iterator of the remote index list.
Definition: remoteindices.hh:602
Standard Dune debug streams.
bool remove(const GlobalIndex &global)
Remove a remote index.
Definition: remoteindices.hh:1660
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:597
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:207
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:994
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1009
const PairType & localIndexPair() const
Get the corresponding local index pair.
Definition: remoteindices.hh:947
T ParallelIndexSet
Type of the index set we use.
Definition: remoteindices.hh:568
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:578
Map::iterator RealIterator
Definition: remoteindices.hh:789
CollectiveIterator< T, A > CollectiveIteratorT
The type of the collective iterator over all remote indices.
Definition: remoteindices.hh:202
A pair consisting of a global and local index.
Definition: indexset.hh:30
const ParallelIndexSet & destinationIndexSet() const
Get the index set at destination.
Definition: remoteindices.hh:1002
Map::iterator ConstRealIterator
Definition: remoteindices.hh:790
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:93
iterator & operator++()
Definition: remoteindices.hh:817
Dune namespace.
Definition: alignment.hh:10
void setNeighbours(const C &neighbours)
Definition: remoteindices.hh:292
A Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:593
bool operator!=(const iterator &other)
Definition: remoteindices.hh:857
TG GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: indexset.hh:225
A collective iterator for moving over the remote indices for all processes collectively.
Definition: remoteindices.hh:152
T2 Attribute
The type of the attributes. Normally this will be an enumeration like.
Definition: remoteindices.hh:92
int neighbours() const
Get the number of processors we share indices with.
Definition: remoteindices.hh:1447
bool operator==(const iterator &other)
Definition: remoteindices.hh:851
ModifyIterator beginModify()
Get an iterator capable of deleting and inserting elements.
Definition: sllist.hh:801
The indices present on remote processes.
Definition: remoteindices.hh:45
Base class of all classes representing a communication interface.
Definition: interface.hh:32
void insert(const T &v)
Insert an element at the current position.
Definition: sllist.hh:511
const std::set< int > & getNeighbours() const
Definition: remoteindices.hh:299
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1724
Traits classes for mapping types onto MPI_Datatype.
A few common exception classes.
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:776
const RemoteIndex * operator->() const
Definition: remoteindices.hh:845
RemoteIndexListModifier()
Default constructor.
Definition: remoteindices.hh:671
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:562
void repairLocalIndexPointers()
Repair the pointers to the local index pairs.
Definition: remoteindices.hh:1579
A::template rebind< RemoteIndex >::other Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:229
int process() const
Definition: remoteindices.hh:839
Definition: remoteindices.hh:550
Default exception class for range errors.
Definition: exceptions.hh:252
Class for recomputing missing indices of a distributed index set.
Definition: indicessyncer.hh:39
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
RemoteIndexMap::const_iterator const_iterator
Definition: remoteindices.hh:239
CollectiveIteratorT iterator() const
Get an iterator for colletively iterating over the remote indices of all remote processes.
Definition: remoteindices.hh:1697
T ParallelIndexSet
Type of the index set we use, e.g. ParallelLocalIndexSet.
Definition: remoteindices.hh:198
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1523
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1516
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:925
bool operator!=(const RemoteIndex &ri) const
Definition: remoteindices.hh:935
iterator begin()
Definition: remoteindices.hh:1825
Implements a singly linked list together with the necessary iterators.
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:788
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:218
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:213
A constant iterator for the SLList.
Definition: sllist.hh:28
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:255
void remove()
Delete the entry at the current position.
Definition: sllist.hh:524
void free()
Free the index lists.
Definition: remoteindices.hh:1429
Modifier for adding and/or deleting remote indices from the remote index list.
Definition: remoteindices.hh:58
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:204
An stl-compliant pool allocator.
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:237
An index present on the local process with an additional attribute flag.
Definition: plocalindex.hh:27
iterator(const iterator &other)
Definition: remoteindices.hh:812
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1454
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:583
const RemoteIndex & operator*() const
Definition: remoteindices.hh:833
const Attribute attribute() const
Get the attribute of the index on the remote process.
Definition: remoteindices.hh:941
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1474
IndexPair< GlobalIndex, ParallelLocalIndex< Attribute > > PairType
The type of the index pair.
Definition: remoteindices.hh:98
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:18
RemoteIndices()
Definition: remoteindices.hh:972
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1530
Definition: remoteindices.hh:159
bool empty()
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1818
constexpr auto size(const Dune::FieldVector< T, i > *, const PriorityTag< 5 > &) -> decltype(std::integral_constant< std::size_t, i >())
Definition: hybridutilities.hh:22
Information about an index residing on another processor.
Definition: remoteindices.hh:48
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:588
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:233
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex &index)
Definition: remoteindices.hh:794
CollectiveIterator & operator++()
Definition: remoteindices.hh:1791
Iterator over the valid underlying iterators.
Definition: remoteindices.hh:786