dune-common  2.4.1-rc2
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>
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 
449  typedef IndexPair<GlobalIndex, LocalIndex>
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* positon, 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>
543  class RemoteIndexListModifier
544  {
545 
546  template<typename T1, typename A1>
547  friend class RemoteIndices;
548 
549  public:
551  {};
552 
553  enum {
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 
683  RemoteIndexList& rList);
684 
685  typedef SLList<GlobalIndex,Allocator> GlobalList;
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 
732  typedef Dune::SLList<RemoteIndex,Allocator> RemoteIndexList;
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 
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[4];
889  MPI_Aint disp[4];
890  MPI_Datatype types[4] = {MPI_LB, MPITraits<TG>::getType(),
891  MPITraits<ParallelLocalIndex<TA> >::getType(), MPI_UB};
893  length[0]=length[1]=length[2]=length[3]=1;
894  MPI_Get_address(rep, disp); // lower bound of the datatype
895  MPI_Get_address(&(rep[0].global_), disp+1);
896  MPI_Get_address(&(rep[0].local_), disp+2);
897  MPI_Get_address(rep+1, disp+3); // upper bound of the datatype
898  for(int i=3; i >= 0; --i)
899  disp[i] -= disp[0];
900  MPI_Type_create_struct(4, length, disp, types, &type);
901  MPI_Type_commit(&type);
902  }
903  return type;
904  }
905 
906  template<typename TG, typename TA>
907  MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::type=MPI_DATATYPE_NULL;
908 
909  template<typename T1, typename T2>
910  RemoteIndex<T1,T2>::RemoteIndex(const T2& attribute, const PairType* local)
911  : localIndex_(local), attribute_(attribute)
912  {}
913 
914  template<typename T1, typename T2>
915  RemoteIndex<T1,T2>::RemoteIndex(const T2& attribute)
916  : localIndex_(0), attribute_(attribute)
917  {}
918 
919  template<typename T1, typename T2>
921  : localIndex_(0), attribute_()
922  {}
923  template<typename T1, typename T2>
924  inline bool RemoteIndex<T1,T2>::operator==(const RemoteIndex& ri) const
925  {
926  return localIndex_==ri.localIndex_ && attribute_==ri.attribute;
927  }
928 
929  template<typename T1, typename T2>
930  inline bool RemoteIndex<T1,T2>::operator!=(const RemoteIndex& ri) const
931  {
932  return localIndex_!=ri.localIndex_ || attribute_!=ri.attribute_;
933  }
934 
935  template<typename T1, typename T2>
936  inline const T2 RemoteIndex<T1,T2>::attribute() const
937  {
938  return T2(attribute_);
939  }
940 
941  template<typename T1, typename T2>
943  {
944  return *localIndex_;
945  }
946 
947  template<typename T, typename A>
949  const ParallelIndexSet& destination,
950  const MPI_Comm& comm,
951  const std::vector<int>& neighbours,
952  bool includeSelf_)
953  : source_(&source), target_(&destination), comm_(comm),
954  sourceSeqNo_(-1), destSeqNo_(-1), publicIgnored(false), firstBuild(true),
955  includeSelf(includeSelf_)
956  {
957  setNeighbours(neighbours);
958  }
959 
960  template<typename T, typename A>
962  {
963  includeSelf=b;
964  }
965 
966  template<typename T, typename A>
968  : source_(0), target_(0), sourceSeqNo_(-1),
969  destSeqNo_(-1), publicIgnored(false), firstBuild(true)
970  {}
971 
972  template<class T, typename A>
974  const ParallelIndexSet& destination,
975  const MPI_Comm& comm,
976  const std::vector<int>& neighbours)
977  {
978  free();
979  source_ = &source;
980  target_ = &destination;
981  comm_ = comm;
982  firstBuild = true;
983  setNeighbours(neighbours);
984  }
985 
986  template<typename T, typename A>
989  {
990  return *source_;
991  }
992 
993 
994  template<typename T, typename A>
997  {
998  return *target_;
999  }
1000 
1001 
1002  template<typename T, typename A>
1004  {
1005  free();
1006  }
1007 
1008  template<typename T, typename A>
1009  template<bool ignorePublic>
1011  const ParallelIndexSet& indexSet,
1012  char* p_out, MPI_Datatype type,
1013  int bufferSize,
1014  int *position, int n)
1015  {
1017  // fill with own indices
1020  const const_iterator end = indexSet.end();
1021 
1022  //Now pack the source indices
1023  int i=0;
1024  for(const_iterator index = indexSet.begin(); index != end; ++index)
1025  if(ignorePublic || index->local().isPublic()) {
1026 
1027  MPI_Pack(const_cast<PairType*>(&(*index)), 1,
1028  type,
1029  p_out, bufferSize, position, comm_);
1030  pairs[i++] = const_cast<PairType*>(&(*index));
1031 
1032  }
1033  assert(i==n);
1034  }
1035 
1036  template<typename T, typename A>
1037  inline int RemoteIndices<T,A>::noPublic(const ParallelIndexSet& indexSet)
1038  {
1039  typedef typename ParallelIndexSet::const_iterator const_iterator;
1040 
1041  int noPublic=0;
1042 
1043  const const_iterator end=indexSet.end();
1044  for(const_iterator index=indexSet.begin(); index!=end; ++index)
1045  if(index->local().isPublic())
1046  noPublic++;
1047 
1048  return noPublic;
1049 
1050  }
1051 
1052 
1053  template<typename T, typename A>
1054  inline void RemoteIndices<T,A>::unpackCreateRemote(char* p_in, PairType** sourcePairs,
1055  PairType** destPairs, int remoteProc,
1056  int sourcePublish, int destPublish,
1057  int bufferSize, bool sendTwo,
1058  bool fromOurSelf)
1059  {
1060 
1061  // unpack the number of indices we received
1062  int noRemoteSource=-1, noRemoteDest=-1;
1063  char twoIndexSets=0;
1064  int position=0;
1065  // Did we receive two index sets?
1066  MPI_Unpack(p_in, bufferSize, &position, &twoIndexSets, 1, MPI_CHAR, comm_);
1067  // The number of source indices received
1068  MPI_Unpack(p_in, bufferSize, &position, &noRemoteSource, 1, MPI_INT, comm_);
1069  // The number of destination indices received
1070  MPI_Unpack(p_in, bufferSize, &position, &noRemoteDest, 1, MPI_INT, comm_);
1071 
1072 
1073  // Indices for which we receive
1074  RemoteIndexList* receive= new RemoteIndexList();
1075  // Indices for which we send
1076  RemoteIndexList* send=0;
1077 
1078  MPI_Datatype type= MPITraits<PairType>::getType();
1079 
1080  if(!twoIndexSets) {
1081  if(sendTwo) {
1082  send = new RemoteIndexList();
1083  // Create both remote index sets simultaneously
1084  unpackIndices(*send, *receive, noRemoteSource, sourcePairs, sourcePublish,
1085  destPairs, destPublish, p_in, type, &position, bufferSize);
1086  }else{
1087  // we only need one list
1088  unpackIndices(*receive, noRemoteSource, sourcePairs, sourcePublish,
1089  p_in, type, &position, bufferSize, fromOurSelf);
1090  send=receive;
1091  }
1092  }else{
1093 
1094  int oldPos=position;
1095  // Two index sets received
1096  unpackIndices(*receive, noRemoteSource, destPairs, destPublish,
1097  p_in, type, &position, bufferSize, fromOurSelf);
1098  if(!sendTwo)
1099  //unpack source entries again as destination entries
1100  position=oldPos;
1101 
1102  send = new RemoteIndexList();
1103  unpackIndices(*send, noRemoteDest, sourcePairs, sourcePublish,
1104  p_in, type, &position, bufferSize, fromOurSelf);
1105  }
1106 
1107  if(receive->empty() && send->empty()) {
1108  if(send==receive) {
1109  delete send;
1110  }else{
1111  delete send;
1112  delete receive;
1113  }
1114  }else{
1115  remoteIndices_.insert(std::make_pair(remoteProc,
1116  std::make_pair(send,receive)));
1117  }
1118  }
1119 
1120 
1121  template<typename T, typename A>
1122  template<bool ignorePublic>
1123  inline void RemoteIndices<T,A>::buildRemote(bool includeSelf_)
1124  {
1125  // Processor configuration
1126  int rank, procs;
1127  MPI_Comm_rank(comm_, &rank);
1128  MPI_Comm_size(comm_, &procs);
1129 
1130  // number of local indices to publish
1131  // The indices of the destination will be send.
1132  int sourcePublish, destPublish;
1133 
1134  // Do we need to send two index sets?
1135  char sendTwo = (source_ != target_);
1136 
1137  if(procs==1 && !(sendTwo || includeSelf_))
1138  // Nothing to communicate
1139  return;
1140 
1141  sourcePublish = (ignorePublic) ? source_->size() : noPublic(*source_);
1142 
1143  if(sendTwo)
1144  destPublish = (ignorePublic) ? target_->size() : noPublic(*target_);
1145  else
1146  // we only need to send one set of indices
1147  destPublish = 0;
1148 
1149  int maxPublish, publish=sourcePublish+destPublish;
1150 
1151  // Calucate maximum number of indices send
1152  MPI_Allreduce(&publish, &maxPublish, 1, MPI_INT, MPI_MAX, comm_);
1153 
1154  // allocate buffers
1155  typedef IndexPair<GlobalIndex,LocalIndex> PairType;
1156 
1157  PairType** destPairs;
1158  PairType** sourcePairs = new PairType*[sourcePublish>0 ? sourcePublish : 1];
1159 
1160  if(sendTwo)
1161  destPairs = new PairType*[destPublish>0 ? destPublish : 1];
1162  else
1163  destPairs=sourcePairs;
1164 
1165  char** buffer = new char*[2];
1166  int bufferSize;
1167  int position=0;
1168  int intSize;
1169  int charSize;
1170 
1171  // calculate buffer size
1172  MPI_Datatype type = MPITraits<PairType>::getType();
1173 
1174  MPI_Pack_size(maxPublish, type, comm_,
1175  &bufferSize);
1176  MPI_Pack_size(1, MPI_INT, comm_,
1177  &intSize);
1178  MPI_Pack_size(1, MPI_CHAR, comm_,
1179  &charSize);
1180  // Our message will contain the following:
1181  // a bool wether two index sets where sent
1182  // the size of the source and the dest indexset,
1183  // then the source and destination indices
1184  bufferSize += 2 * intSize + charSize;
1185 
1186  if(bufferSize<=0) bufferSize=1;
1187 
1188  buffer[0] = new char[bufferSize];
1189  buffer[1] = new char[bufferSize];
1190 
1191 
1192  // pack entries into buffer[0], p_out below!
1193  MPI_Pack(&sendTwo, 1, MPI_CHAR, buffer[0], bufferSize, &position,
1194  comm_);
1195 
1196  // The number of indices we send for each index set
1197  MPI_Pack(&sourcePublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1198  comm_);
1199  MPI_Pack(&destPublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1200  comm_);
1201 
1202  // Now pack the source indices and setup the destination pairs
1203  packEntries<ignorePublic>(sourcePairs, *source_, buffer[0], type,
1204  bufferSize, &position, sourcePublish);
1205  // If necessary send the dest indices and setup the source pairs
1206  if(sendTwo)
1207  packEntries<ignorePublic>(destPairs, *target_, buffer[0], type,
1208  bufferSize, &position, destPublish);
1209 
1210 
1211  // Update remote indices for ourself
1212  if(sendTwo|| includeSelf_)
1213  unpackCreateRemote(buffer[0], sourcePairs, destPairs, rank, sourcePublish,
1214  destPublish, bufferSize, sendTwo, includeSelf_);
1215 
1216  neighbourIds.erase(rank);
1217 
1218  if(neighbourIds.size()==0)
1219  {
1220  Dune::dvverb<<rank<<": Sending messages in a ring"<<std::endl;
1221  // send messages in ring
1222  for(int proc=1; proc<procs; proc++) {
1223  // pointers to the current input and output buffers
1224  char* p_out = buffer[1-(proc%2)];
1225  char* p_in = buffer[proc%2];
1226 
1227  MPI_Status status;
1228  if(rank%2==0) {
1229  MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1230  commTag_, comm_);
1231  MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1232  commTag_, comm_, &status);
1233  }else{
1234  MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1235  commTag_, comm_, &status);
1236  MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1237  commTag_, comm_);
1238  }
1239 
1240 
1241  // The process these indices are from
1242  int remoteProc = (rank+procs-proc)%procs;
1243 
1244  unpackCreateRemote(p_in, sourcePairs, destPairs, remoteProc, sourcePublish,
1245  destPublish, bufferSize, sendTwo);
1246 
1247  }
1248 
1249  }
1250  else
1251  {
1252  MPI_Request* requests=new MPI_Request[neighbourIds.size()];
1253  MPI_Request* req=requests;
1254 
1255  typedef typename std::set<int>::size_type size_type;
1256  size_type noNeighbours=neighbourIds.size();
1257 
1258  // setup sends
1259  for(std::set<int>::iterator neighbour=neighbourIds.begin();
1260  neighbour!= neighbourIds.end(); ++neighbour) {
1261  // Only send the information to the neighbouring processors
1262  MPI_Issend(buffer[0], position , MPI_PACKED, *neighbour, commTag_, comm_, req++);
1263  }
1264 
1265  //Test for received messages
1266 
1267  for(size_type received=0; received <noNeighbours; ++received)
1268  {
1269  MPI_Status status;
1270  // probe for next message
1271  MPI_Probe(MPI_ANY_SOURCE, commTag_, comm_, &status);
1272  int remoteProc=status.MPI_SOURCE;
1273  int size;
1274  MPI_Get_count(&status, MPI_PACKED, &size);
1275  // receive message
1276  MPI_Recv(buffer[1], size, MPI_PACKED, remoteProc,
1277  commTag_, comm_, &status);
1278 
1279  unpackCreateRemote(buffer[1], sourcePairs, destPairs, remoteProc, sourcePublish,
1280  destPublish, bufferSize, sendTwo);
1281  }
1282  // wait for completion of pending requests
1283  MPI_Status* statuses = new MPI_Status[neighbourIds.size()];
1284 
1285  if(MPI_ERR_IN_STATUS==MPI_Waitall(neighbourIds.size(), requests, statuses)) {
1286  for(size_type i=0; i < neighbourIds.size(); ++i)
1287  if(statuses[i].MPI_ERROR!=MPI_SUCCESS) {
1288  std::cerr<<rank<<": MPI_Error occurred while receiving message."<<std::endl;
1289  MPI_Abort(comm_, 999);
1290  }
1291  }
1292  delete[] requests;
1293  delete[] statuses;
1294  }
1295 
1296 
1297  // delete allocated memory
1298  if(destPairs!=sourcePairs)
1299  delete[] destPairs;
1300 
1301  delete[] sourcePairs;
1302  delete[] buffer[0];
1303  delete[] buffer[1];
1304  delete[] buffer;
1305  }
1306 
1307  template<typename T, typename A>
1308  inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& remote,
1309  int remoteEntries,
1310  PairType** local,
1311  int localEntries,
1312  char* p_in,
1313  MPI_Datatype type,
1314  int* position,
1315  int bufferSize,
1316  bool fromOurSelf)
1317  {
1318  if(remoteEntries==0)
1319  return;
1320 
1321  PairType index(1);
1322  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1323  type, comm_);
1324  GlobalIndex oldGlobal=index.global();
1325  int n_in=0, localIndex=0;
1326 
1327  //Check if we know the global index
1328  while(localIndex<localEntries) {
1329  if(local[localIndex]->global()==index.global()) {
1330  int oldLocalIndex=localIndex;
1331 
1332  while(localIndex<localEntries &&
1333  local[localIndex]->global()==index.global()) {
1334  if(!fromOurSelf || index.local().attribute() !=
1335  local[localIndex]->local().attribute())
1336  // if index is from us it has to have a different attribute
1337  remote.push_back(RemoteIndex(index.local().attribute(),
1338  local[localIndex]));
1339  localIndex++;
1340  }
1341 
1342  // unpack next remote index
1343  if((++n_in) < remoteEntries) {
1344  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1345  type, comm_);
1346  if(index.global()==oldGlobal)
1347  // Restart comparison for the same global indices
1348  localIndex=oldLocalIndex;
1349  else
1350  oldGlobal=index.global();
1351  }else{
1352  // No more received indices
1353  break;
1354  }
1355  continue;
1356  }
1357 
1358  if (local[localIndex]->global()<index.global()) {
1359  // compare with next entry in our list
1360  ++localIndex;
1361  }else{
1362  // We do not know the index, unpack next
1363  if((++n_in) < remoteEntries) {
1364  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1365  type, comm_);
1366  oldGlobal=index.global();
1367  }else
1368  // No more received indices
1369  break;
1370  }
1371  }
1372 
1373  // Unpack the other received indices without doing anything
1374  while(++n_in < remoteEntries)
1375  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1376  type, comm_);
1377  }
1378 
1379 
1380  template<typename T, typename A>
1381  inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& send,
1382  RemoteIndexList& receive,
1383  int remoteEntries,
1384  PairType** localSource,
1385  int localSourceEntries,
1386  PairType** localDest,
1387  int localDestEntries,
1388  char* p_in,
1389  MPI_Datatype type,
1390  int* position,
1391  int bufferSize)
1392  {
1393  int n_in=0, sourceIndex=0, destIndex=0;
1394 
1395  //Check if we know the global index
1396  while(n_in<remoteEntries && (sourceIndex<localSourceEntries || destIndex<localDestEntries)) {
1397  // Unpack next index
1398  PairType index;
1399  MPI_Unpack(p_in, bufferSize, position, &index, 1,
1400  type, comm_);
1401  n_in++;
1402 
1403  // Advance until global index in localSource and localDest are >= than the one in the unpacked index
1404  while(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()<index.global())
1405  sourceIndex++;
1406 
1407  while(destIndex<localDestEntries && localDest[destIndex]->global()<index.global())
1408  destIndex++;
1409 
1410  // Add a remote index if we found the global index.
1411  if(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()==index.global())
1412  send.push_back(RemoteIndex(index.local().attribute(),
1413  localSource[sourceIndex]));
1414 
1415  if(destIndex < localDestEntries && localDest[destIndex]->global() == index.global())
1416  receive.push_back(RemoteIndex(index.local().attribute(),
1417  localDest[sourceIndex]));
1418  }
1419 
1420  }
1421 
1422  template<typename T, typename A>
1424  {
1425  typedef typename RemoteIndexMap::iterator Iterator;
1426  Iterator lend = remoteIndices_.end();
1427  for(Iterator lists=remoteIndices_.begin(); lists != lend; ++lists) {
1428  if(lists->second.first==lists->second.second) {
1429  // there is only one remote index list.
1430  delete lists->second.first;
1431  }else{
1432  delete lists->second.first;
1433  delete lists->second.second;
1434  }
1435  }
1436  remoteIndices_.clear();
1437  firstBuild=true;
1438  }
1439 
1440  template<typename T, typename A>
1442  {
1443  return remoteIndices_.size();
1444  }
1445 
1446  template<typename T, typename A>
1447  template<bool ignorePublic>
1449  {
1450  // Test wether a rebuild is Needed.
1451  if(firstBuild ||
1452  ignorePublic!=publicIgnored || !
1453  isSynced()) {
1454  free();
1455 
1456  buildRemote<ignorePublic>(includeSelf);
1457 
1458  sourceSeqNo_ = source_->seqNo();
1459  destSeqNo_ = target_->seqNo();
1460  firstBuild=false;
1461  publicIgnored=ignorePublic;
1462  }
1463 
1464 
1465  }
1466 
1467  template<typename T, typename A>
1468  inline bool RemoteIndices<T,A>::isSynced() const
1469  {
1470  return sourceSeqNo_==source_->seqNo() && destSeqNo_ ==target_->seqNo();
1471  }
1472 
1473  template<typename T, typename A>
1474  template<bool mode, bool send>
1476  {
1477 
1478  // The user are on their own now!
1479  // We assume they know what they are doing and just set the
1480  // remote indices to synced status.
1481  sourceSeqNo_ = source_->seqNo();
1482  destSeqNo_ = target_->seqNo();
1483 
1484  typename RemoteIndexMap::iterator found = remoteIndices_.find(process);
1485 
1486  if(found == remoteIndices_.end())
1487  {
1488  if(source_ != target_)
1489  found = remoteIndices_.insert(found, std::make_pair(process,
1490  std::make_pair(new RemoteIndexList(),
1491  new RemoteIndexList())));
1492  else{
1493  RemoteIndexList* rlist = new RemoteIndexList();
1494  found = remoteIndices_.insert(found,
1495  std::make_pair(process,
1496  std::make_pair(rlist, rlist)));
1497  }
1498  }
1499 
1500  firstBuild = false;
1501 
1502  if(send)
1503  return RemoteIndexListModifier<T,A,mode>(*source_, *(found->second.first));
1504  else
1505  return RemoteIndexListModifier<T,A,mode>(*target_, *(found->second.second));
1506  }
1507 
1508  template<typename T, typename A>
1509  inline typename RemoteIndices<T,A>::const_iterator
1511  {
1512  return remoteIndices_.find(proc);
1513  }
1514 
1515  template<typename T, typename A>
1516  inline typename RemoteIndices<T,A>::const_iterator
1518  {
1519  return remoteIndices_.begin();
1520  }
1521 
1522  template<typename T, typename A>
1523  inline typename RemoteIndices<T,A>::const_iterator
1525  {
1526  return remoteIndices_.end();
1527  }
1528 
1529 
1530  template<typename T, typename A>
1532  {
1533  if(neighbours()!=ri.neighbours())
1534  return false;
1535 
1536  typedef RemoteIndexList RList;
1537  typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1538 
1539  const const_iterator rend = remoteIndices_.end();
1540 
1541  for(const_iterator rindex = remoteIndices_.begin(), rindex1=ri.remoteIndices_.begin(); rindex!=rend; ++rindex, ++rindex1) {
1542  if(rindex->first != rindex1->first)
1543  return false;
1544  if(*(rindex->second.first) != *(rindex1->second.first))
1545  return false;
1546  if(*(rindex->second.second) != *(rindex1->second.second))
1547  return false;
1548  }
1549  return true;
1550  }
1551 
1552  template<class T, class A, bool mode>
1554  RemoteIndexList& rList)
1555  : rList_(&rList), indexSet_(&indexSet), iter_(rList.beginModify()), end_(rList.end()), first_(true)
1556  {
1557  if(MODIFYINDEXSET) {
1558  assert(indexSet_);
1559  for(ConstIterator iter=iter_; iter != end_; ++iter)
1560  glist_.push_back(iter->localIndexPair().global());
1561  giter_ = glist_.beginModify();
1562  }
1563  }
1564 
1565  template<typename T, typename A, bool mode>
1567  : rList_(other.rList_), indexSet_(other.indexSet_),
1568  glist_(other.glist_), iter_(other.iter_), giter_(other.giter_), end_(other.end_),
1569  first_(other.first_), last_(other.last_)
1570  {}
1571 
1572  template<typename T, typename A, bool mode>
1574  {
1575  if(MODIFYINDEXSET) {
1576  // repair pointers to local index set.
1577 #ifdef DUNE_ISTL_WITH_CHECKING
1578  if(indexSet_->state()!=GROUND)
1579  DUNE_THROW(InvalidIndexSetState, "Index has to be in ground mode for repairing pointers to indices");
1580 #endif
1581  typedef typename ParallelIndexSet::const_iterator IndexIterator;
1582  typedef typename GlobalList::const_iterator GlobalIterator;
1583  typedef typename RemoteIndexList::iterator Iterator;
1584  GlobalIterator giter = glist_.begin();
1585  IndexIterator index = indexSet_->begin();
1586 
1587  for(Iterator iter=rList_->begin(); iter != end_; ++iter) {
1588  while(index->global()<*giter) {
1589  ++index;
1590 #ifdef DUNE_ISTL_WITH_CHECKING
1591  if(index == indexSet_->end())
1592  DUNE_THROW(InvalidPosition, "No such global index in set!");
1593 #endif
1594  }
1595 
1596 #ifdef DUNE_ISTL_WITH_CHECKING
1597  if(index->global() != *giter)
1598  DUNE_THROW(InvalidPosition, "No such global index in set!");
1599 #endif
1600  iter->localIndex_ = &(*index);
1601  }
1602  }
1603  }
1604 
1605  template<typename T, typename A, bool mode>
1607  {
1608  static_assert(!mode,"Not allowed if the mode indicates that new indices"
1609  "might be added to the underlying index set. Use "
1610  "insert(const RemoteIndex&, const GlobalIndex&) instead");
1611 
1612 #ifdef DUNE_ISTL_WITH_CHECKING
1613  if(!first_ && index.localIndexPair().global()<last_)
1614  DUNE_THROW(InvalidPosition, "Modifcation of remote indices have to occur with ascending global index.");
1615 #endif
1616  // Move to the correct position
1617  while(iter_ != end_ && iter_->localIndexPair().global() < index.localIndexPair().global()) {
1618  ++iter_;
1619  }
1620 
1621  // No duplicate entries allowed
1622  assert(iter_==end_ || iter_->localIndexPair().global() != index.localIndexPair().global());
1623  iter_.insert(index);
1624  last_ = index.localIndexPair().global();
1625  first_ = false;
1626  }
1627 
1628  template<typename T, typename A, bool mode>
1630  {
1631  static_assert(mode,"Not allowed if the mode indicates that no new indices"
1632  "might be added to the underlying index set. Use "
1633  "insert(const RemoteIndex&) instead");
1634 #ifdef DUNE_ISTL_WITH_CHECKING
1635  if(!first_ && global<last_)
1636  DUNE_THROW(InvalidPosition, "Modification of remote indices have to occur with ascending global index.");
1637 #endif
1638  // Move to the correct position
1639  while(iter_ != end_ && *giter_ < global) {
1640  ++giter_;
1641  ++iter_;
1642  }
1643 
1644  // No duplicate entries allowed
1645  assert(iter_->localIndexPair().global() != global);
1646  iter_.insert(index);
1647  giter_.insert(global);
1648 
1649  last_ = global;
1650  first_ = false;
1651  }
1652 
1653  template<typename T, typename A, bool mode>
1655  {
1656 #ifdef DUNE_ISTL_WITH_CHECKING
1657  if(!first_ && global<last_)
1658  DUNE_THROW(InvalidPosition, "Modifcation of remote indices have to occur with ascending global index.");
1659 #endif
1660 
1661  bool found= false;
1662 
1663  if(MODIFYINDEXSET) {
1664  // Move to the correct position
1665  while(iter_!=end_ && *giter_< global) {
1666  ++giter_;
1667  ++iter_;
1668  }
1669  if(*giter_ == global) {
1670  giter_.remove();
1671  iter_.remove();
1672  found=true;
1673  }
1674  }else{
1675  while(iter_!=end_ && iter_->localIndexPair().global() < global)
1676  ++iter_;
1677 
1678  if(iter_->localIndexPair().global()==global) {
1679  iter_.remove();
1680  found = true;
1681  }
1682  }
1683 
1684  last_ = global;
1685  first_ = false;
1686  return found;
1687  }
1688 
1689  template<typename T, typename A>
1690  template<bool send>
1692  {
1693  return CollectiveIterator<T,A>(remoteIndices_, send);
1694  }
1695 
1696  template<typename T, typename A>
1697  inline MPI_Comm RemoteIndices<T,A>::communicator() const
1698  {
1699  return comm_;
1700 
1701  }
1702 
1703  template<typename T, typename A>
1705  {
1706  typedef typename RemoteIndexMap::const_iterator const_iterator;
1707 
1708  const const_iterator end=pmap.end();
1709  for(const_iterator process=pmap.begin(); process != end; ++process) {
1710  const RemoteIndexList* list = send ? process->second.first : process->second.second;
1711  typedef typename RemoteIndexList::const_iterator iterator;
1712  map_.insert(std::make_pair(process->first,
1713  std::pair<iterator, const iterator>(list->begin(), list->end())));
1714  }
1715  }
1716 
1717  template<typename T, typename A>
1718  inline void CollectiveIterator<T,A>::advance(const GlobalIndex& index)
1719  {
1720  typedef typename Map::iterator iterator;
1721  typedef typename Map::const_iterator const_iterator;
1722  const const_iterator end = map_.end();
1723 
1724  for(iterator iter = map_.begin(); iter != end;) {
1725  // Step the iterator until we are >= index
1726  typename RemoteIndexList::const_iterator current = iter->second.first;
1727  typename RemoteIndexList::const_iterator rend = iter->second.second;
1728  RemoteIndex remoteIndex;
1729  if(current != rend)
1730  remoteIndex = *current;
1731 
1732  while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1733  ++(iter->second.first);
1734 
1735  // erase from the map if there are no more entries.
1736  if(iter->second.first == iter->second.second)
1737  map_.erase(iter++);
1738  else{
1739  ++iter;
1740  }
1741  }
1742  index_=index;
1743  noattribute=true;
1744  }
1745 
1746  template<typename T, typename A>
1747  inline void CollectiveIterator<T,A>::advance(const GlobalIndex& index,
1748  const Attribute& attribute)
1749  {
1750  typedef typename Map::iterator iterator;
1751  typedef typename Map::const_iterator const_iterator;
1752  const const_iterator end = map_.end();
1753 
1754  for(iterator iter = map_.begin(); iter != end;) {
1755  // Step the iterator until we are >= index
1756  typename RemoteIndexList::const_iterator current = iter->second.first;
1757  typename RemoteIndexList::const_iterator rend = iter->second.second;
1758  RemoteIndex remoteIndex;
1759  if(current != rend)
1760  remoteIndex = *current;
1761 
1762  // Move to global index or bigger
1763  while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1764  ++(iter->second.first);
1765 
1766  // move to attribute or bigger
1767  while(iter->second.first!=iter->second.second
1768  && iter->second.first->localIndexPair().global()==index
1769  && iter->second.first->localIndexPair().local().attribute()<attribute)
1770  ++(iter->second.first);
1771 
1772  // erase from the map if there are no more entries.
1773  if(iter->second.first == iter->second.second)
1774  map_.erase(iter++);
1775  else{
1776  ++iter;
1777  }
1778  }
1779  index_=index;
1780  attribute_=attribute;
1781  noattribute=false;
1782  }
1783 
1784  template<typename T, typename A>
1786  {
1787  typedef typename Map::iterator iterator;
1788  typedef typename Map::const_iterator const_iterator;
1789  const const_iterator end = map_.end();
1790 
1791  for(iterator iter = map_.begin(); iter != end;) {
1792  // Step the iterator until we are >= index
1793  typename RemoteIndexList::const_iterator current = iter->second.first;
1794  typename RemoteIndexList::const_iterator rend = iter->second.second;
1795 
1796  // move all iterators pointing to the current global index to next value
1797  if(iter->second.first->localIndexPair().global()==index_ &&
1798  (noattribute || iter->second.first->localIndexPair().local().attribute() == attribute_))
1799  ++(iter->second.first);
1800 
1801  // erase from the map if there are no more entries.
1802  if(iter->second.first == iter->second.second)
1803  map_.erase(iter++);
1804  else{
1805  ++iter;
1806  }
1807  }
1808  return *this;
1809  }
1810 
1811  template<typename T, typename A>
1813  {
1814  return map_.empty();
1815  }
1816 
1817  template<typename T, typename A>
1818  inline typename CollectiveIterator<T,A>::iterator
1820  {
1821  if(noattribute)
1822  return iterator(map_.begin(), map_.end(), index_);
1823  else
1824  return iterator(map_.begin(), map_.end(), index_,
1825  attribute_);
1826  }
1827 
1828  template<typename T, typename A>
1829  inline typename CollectiveIterator<T,A>::iterator
1831  {
1832  return iterator(map_.end(), map_.end(), index_);
1833  }
1834 
1835  template<typename TG, typename TA>
1836  inline std::ostream& operator<<(std::ostream& os, const RemoteIndex<TG,TA>& index)
1837  {
1838  os<<"[global="<<index.localIndexPair().global()<<", remote attribute="<<index.attribute()<<" local attribute="<<index.localIndexPair().local().attribute()<<"]";
1839  return os;
1840  }
1841 
1842  template<typename T, typename A>
1843  inline std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices)
1844  {
1845  int rank;
1846  MPI_Comm_rank(indices.comm_, &rank);
1847 
1848  typedef typename RemoteIndices<T,A>::RemoteIndexList RList;
1849  typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1850 
1851  const const_iterator rend = indices.remoteIndices_.end();
1852 
1853  for(const_iterator rindex = indices.remoteIndices_.begin(); rindex!=rend; ++rindex) {
1854  os<<rank<<": Prozess "<<rindex->first<<":";
1855 
1856  if(!rindex->second.first->empty()) {
1857  os<<" send:";
1858 
1859  const typename RList::const_iterator send= rindex->second.first->end();
1860 
1861  for(typename RList::const_iterator index = rindex->second.first->begin();
1862  index != send; ++index)
1863  os<<*index<<" ";
1864  os<<std::endl;
1865  }
1866  if(!rindex->second.second->empty()) {
1867  os<<rank<<": Prozess "<<rindex->first<<": "<<"receive: ";
1868 
1869  const typename RList::const_iterator rend= rindex->second.second->end();
1870 
1871  for(typename RList::const_iterator index = rindex->second.second->begin();
1872  index != rend; ++index)
1873  os << *index << " ";
1874  }
1875  os<<std::endl<<std::flush;
1876  }
1877  return os;
1878  }
1880 }
1881 
1882 #endif
1883 #endif
CollectiveIterator< T, A > CollectiveIteratorT
The type of the collective iterator over all remote indices.
Definition: remoteindices.hh:202
A Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:593
friend void repairLocalIndexPointers(std::map< int, SLList< std::pair< typename T::GlobalIndex, typename T::LocalIndex::Attribute >, A > > &, RemoteIndices< T, A1 > &, const T &)
bool operator==(const RemoteIndex &ri) const
Definition: remoteindices.hh:924
RemoteIndexList::const_iterator ConstIterator
The type of the remote index list iterator.
Definition: remoteindices.hh:607
SLListModifyIterator< RemoteIndex, Allocator > ModifyIterator
The type of the modifying iterator of the remote index list.
Definition: remoteindices.hh:602
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:93
The indices present on remote processes.
Definition: remoteindices.hh:45
CollectiveIterator & operator++()
Definition: remoteindices.hh:1785
const std::set< int > & getNeighbours() const
Definition: remoteindices.hh:299
iterator end()
Definition: remoteindices.hh:1830
Information about an index residing on another processor.
Definition: remoteindices.hh:48
Class for recomputing missing indices of a distributed index set.
Definition: indicessyncer.hh:39
SLListConstIterator< RemoteIndex, Allocator > const_iterator
The constant iterator of the list.
Definition: sllist.hh:72
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:597
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:743
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:204
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex index, Attribute attribute)
Definition: remoteindices.hh:802
TG GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: indexset.hh:225
Traits classes for mapping types onto MPI_Datatype.
A constant iterator for the SLList.
Definition: sllist.hh:28
A few common exception classes.
void setNeighbours(const C &neighbours)
Definition: remoteindices.hh:292
SLListModifyIterator< GlobalIndex, Allocator > ModifyIterator
The type of the iterator capable of deletion and insertion.
Definition: sllist.hh:101
T ParallelIndexSet
Type of the index set we use.
Definition: remoteindices.hh:568
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:776
T ParallelIndexSet
Type of the index set we use, e.g. ParallelLocalIndexSet.
Definition: remoteindices.hh:198
Modifier for adding and/or deleting remote indices from the remote index list.
Definition: remoteindices.hh:58
iterator & operator++()
Definition: remoteindices.hh:817
TL LocalIndex
The type of the local index, e.g. ParallelLocalIndex.
Definition: indexset.hh:238
Provides a map between global and local indices.
bool empty()
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1812
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: bigunsignedint.hh:30
MPI_Comm communicator() const
Get the mpi communicator used.
Definition: remoteindices.hh:1697
void repairLocalIndexPointers()
Repair the pointers to the local index pairs.
Definition: remoteindices.hh:1573
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1517
Map::iterator RealIterator
Definition: remoteindices.hh:789
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:583
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:573
A single linked list.
Definition: sllist.hh:41
CollectiveIteratorT iterator() const
Get an iterator for colletively iterating over the remote indices of all remote processes.
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:920
const RemoteIndex & operator*() const
Definition: remoteindices.hh:833
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1448
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1524
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1468
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:973
iterator begin()
Definition: remoteindices.hh:1819
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:223
Implements a singly linked list together with the necessary iterators.
std::size_t index_
The other rank that this interface communcates with.
Definition: variablesizecommunicator.hh:257
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:788
void insert(const RemoteIndex &index)
Insert an index to the list.
Definition: remoteindices.hh:1606
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex &index)
Definition: remoteindices.hh:794
bool remove(const GlobalIndex &global)
Remove a remote index.
Definition: remoteindices.hh:1654
Definition: remoteindices.hh:159
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:213
The default mode. Indicates that the index set is ready to be used.
Definition: indexset.hh:185
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:233
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:207
A constant random access iterator for the Dune::ArrayList class.
Definition: arraylist.hh:20
friend void repairLocalIndexPointers(std::map< int, SLList< std::pair< typename T1::GlobalIndex, typename T1::LocalIndex::Attribute >, A2 > > &, RemoteIndices< T1, A1 > &, const T1 &)
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:237
friend void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
Iterator over the valid underlying iterators.
Definition: remoteindices.hh:786
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:218
iterator(const iterator &other)
Definition: remoteindices.hh:812
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:578
const Attribute attribute() const
Get the attribute of the index on the remote process.
Definition: remoteindices.hh:936
bool operator!=(const iterator &other)
Definition: remoteindices.hh:857
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional unused function parameters with.
Definition: unused.hh:18
A pair consisting of a global and local index.
Definition: indexset.hh:30
T2 Attribute
The type of the attributes. Normally this will be an enumeration like.
Definition: remoteindices.hh:92
int process() const
Definition: remoteindices.hh:839
bool operator!=(const RemoteIndex &ri) const
Definition: remoteindices.hh:930
Standard Dune debug streams.
const RemoteIndex * operator->() const
Definition: remoteindices.hh:845
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:562
Map::iterator ConstRealIterator
Definition: remoteindices.hh:790
const ParallelIndexSet & destinationIndexSet() const
Get the index set at destination.
Definition: remoteindices.hh:996
Base class of all classes representing a communication interface.
Definition: interface.hh:32
An stl-compliant pool allocator.
An index present on the local process with an additional attribute flag.
Definition: plocalindex.hh:27
iterator end()
Get an iterator over the indices positioned after the last index.
A collective iterator for moving over the remote indices for all processes collectively.
Definition: remoteindices.hh:152
Default exception class for range errors.
Definition: exceptions.hh:279
CollectiveIterator(const RemoteIndexMap &map_, bool send)
Constructor.
Definition: remoteindices.hh:1704
RemoteIndexMap::const_iterator const_iterator
Definition: remoteindices.hh:239
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:988
bool operator==(const iterator &other)
Definition: remoteindices.hh:851
RemoteIndexListModifier()
Default constructor.
Definition: remoteindices.hh:671
A::template rebind< RemoteIndex >::other Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:229
iterator begin()
Get an iterator over the indices positioned at the first index.
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1510
void free()
Free the index lists.
Definition: remoteindices.hh:1423
T1 GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: remoteindices.hh:83
RemoteIndices()
Definition: remoteindices.hh:967
static MPI_Datatype getType()
Definition: mpitraits.hh:44
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
RemoteIndexListModifier< T, A, mode > getModifier(int process)
Get a modifier for a remote index list.
Definition: remoteindices.hh:1475
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1718
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1003
int neighbours() const
Get the number of processors we share indices with.
Definition: remoteindices.hh:1441
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:588
IndexPair< GlobalIndex, ParallelLocalIndex< Attribute > > PairType
The type of the index pair.
Definition: remoteindices.hh:98
bool operator==(const RemoteIndices &ri)
Definition: remoteindices.hh:1531
Definition: remoteindices.hh:550
const PairType & localIndexPair() const
Get the corresponding local index pair.
Definition: remoteindices.hh:942
void setIncludeSelf(bool includeSelf)
Tell whether sending from indices of the processor to other indices on the same processor is enabled ...
Definition: remoteindices.hh:961
Provides classes for use as the local index in ParallelIndexSet for distributed computing.
Manager class for the mapping between local indices and globally unique indices.
Definition: indexset.hh:216