Dune Core Modules (2.5.2)

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 {
34  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>
45  class RemoteIndices;
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>
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>
76  friend class RemoteIndexListModifier;
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>
152  class CollectiveIterator;
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> > >
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 
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>
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:
550  class InvalidPosition : public RangeError
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 
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>
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 
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>
885  MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::getType()
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(),
892  MPITraits<ParallelLocalIndex<TA> >::getType()};
893  IndexPair<TG,ParallelLocalIndex<TA> > rep;
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>
920  RemoteIndex<T1,T2>::RemoteIndex(const T2& attribute)
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>
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>
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
1024  typedef typename ParallelIndexSet::const_iterator const_iterator;
1025  typedef IndexPair<GlobalIndex,LocalIndex> PairType;
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  {
1045  typedef typename ParallelIndexSet::const_iterator const_iterator;
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
1161  typedef IndexPair<GlobalIndex,LocalIndex> PairType;
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>
1314  inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& remote,
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>
1387  inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& send,
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>
1572  RemoteIndexListModifier<T,A,mode>::RemoteIndexListModifier(const RemoteIndexListModifier<T,A,mode>& other)
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
1836  CollectiveIterator<T,A>::end()
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
Iterator over the valid underlying iterators.
Definition: remoteindices.hh:787
const RemoteIndex * operator->() const
Definition: remoteindices.hh:845
iterator & operator++()
Definition: remoteindices.hh:817
bool operator==(const iterator &other)
Definition: remoteindices.hh:851
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex &index)
Definition: remoteindices.hh:794
bool operator!=(const iterator &other)
Definition: remoteindices.hh:857
iterator(const iterator &other)
Definition: remoteindices.hh:812
const RemoteIndex & operator*() const
Definition: remoteindices.hh:833
int process() const
Definition: remoteindices.hh:839
A collective iterator for moving over the remote indices for all processes collectively.
Definition: remoteindices.hh:703
CollectiveIterator(const RemoteIndexMap &map_, bool send)
Constructor.
Definition: remoteindices.hh:1710
bool empty()
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1818
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1724
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:743
A constant random access iterator for the Dune::ArrayList class.
Definition: arraylist.hh:379
A pair consisting of a global and local index.
Definition: indexset.hh:84
Class for recomputing missing indices of a distributed index set.
Definition: indicessyncer.hh:40
Base class of all classes representing a communication interface.
Definition: interface.hh:33
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:204
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:172
Manager class for the mapping between local indices and globally unique indices.
Definition: indexset.hh:217
An index present on the local process with an additional attribute flag.
Definition: plocalindex.hh:47
Default exception class for range errors.
Definition: exceptions.hh:252
Modifier for adding and/or deleting remote indices from the remote index list.
Definition: remoteindices.hh:544
void repairLocalIndexPointers()
Repair the pointers to the local index pairs.
Definition: remoteindices.hh:1579
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:597
@ MODIFYINDEXSET
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:562
A Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:593
void insert(const RemoteIndex &index)
Insert an index to the list.
Definition: remoteindices.hh:1612
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:573
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:578
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
bool remove(const GlobalIndex &global)
Remove a remote index.
Definition: remoteindices.hh:1660
T ParallelIndexSet
Type of the index set we use.
Definition: remoteindices.hh:568
RemoteIndexListModifier()
Default constructor.
Definition: remoteindices.hh:671
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:583
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:588
Information about an index residing on another processor.
Definition: remoteindices.hh:66
const Attribute attribute() const
Get the attribute of the index on the remote process.
Definition: remoteindices.hh:941
T1 GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: remoteindices.hh:83
T2 Attribute
The type of the attributes. Normally this will be an enumeration like.
Definition: remoteindices.hh:92
IndexPair< GlobalIndex, ParallelLocalIndex< Attribute > > PairType
The type of the index pair.
Definition: remoteindices.hh:98
const PairType & localIndexPair() const
Get the corresponding local index pair.
Definition: remoteindices.hh:947
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:925
The indices present on remote processes.
Definition: remoteindices.hh:181
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:223
friend void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
Fills the holes in an index set.
Definition: repartition.hh:58
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
void free()
Free the index lists.
Definition: remoteindices.hh:1429
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:207
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1454
T ParallelIndexSet
Type of the index set we use, e.g. ParallelLocalIndexSet.
Definition: remoteindices.hh:198
MPI_Comm communicator() const
Get the mpi communicator used.
Definition: remoteindices.hh:1703
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:218
CollectiveIteratorT iterator() const
Get an iterator for colletively iterating over the remote indices of all remote processes.
Definition: remoteindices.hh:1697
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
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1530
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:237
RemoteIndexListModifier< T, A, mode > getModifier(int process)
Get a modifier for a remote index list.
Definition: remoteindices.hh:1481
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:994
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1009
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:233
int neighbours() const
Get the number of processors we share indices with.
Definition: remoteindices.hh:1447
CollectiveIterator< T, A > CollectiveIteratorT
The type of the collective iterator over all remote indices.
Definition: remoteindices.hh:202
const ParallelIndexSet & destinationIndexSet() const
Get the index set at destination.
Definition: remoteindices.hh:1002
RemoteIndices(const ParallelIndexSet &source, const ParallelIndexSet &destination, const MPI_Comm &comm, const std::vector< int > &neighbours=std::vector< int >(), bool includeSelf=false)
Constructor.
Definition: remoteindices.hh:953
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1516
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1474
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1523
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:213
A::template rebind< RemoteIndex >::other Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:229
A constant iterator for the SLList.
Definition: sllist.hh:369
A mutable iterator for the SLList.
Definition: sllist.hh:269
A single linked list.
Definition: sllist.hh:42
A few common exception classes.
ArrayList< IndexPair, N >::const_iterator const_iterator
The constant iterator over the pairs.
Definition: indexset.hh:305
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
iterator begin()
Get an iterator over the indices positioned at the first index.
iterator end()
Get an iterator over the indices positioned after the last index.
TL LocalIndex
The type of the local index, e.g. ParallelLocalIndex.
Definition: indexset.hh:238
TG GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: indexset.hh:225
@ GROUND
The default mode. Indicates that the index set is ready to be used.
Definition: indexset.hh:185
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:788
SLListConstIterator< T, A > const_iterator
The constant iterator of the list.
Definition: sllist.hh:72
SLListModifyIterator< GlobalIndex, Allocator > ModifyIterator
The type of the iterator capable of deletion and insertion.
Definition: sllist.hh:101
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:776
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:255
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
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:93
Provides a map between global and local indices.
Traits classes for mapping types onto MPI_Datatype.
Dune namespace.
Definition: alignment.hh:11
Provides classes for use as the local index in ParallelIndexSet for distributed computing.
An stl-compliant pool allocator.
Implements a singly linked list together with the necessary iterators.
Standard Dune debug streams.
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: mpitraits.hh:39
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:18
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 9, 22:29, 2024)