Dune Core Modules (2.4.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* 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>
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[4];
889  MPI_Aint disp[4];
890  MPI_Datatype types[4] = {MPI_LB, MPITraits<TG>::getType(),
891  MPITraits<ParallelLocalIndex<TA> >::getType(), MPI_UB};
892  IndexPair<TG,ParallelLocalIndex<TA> > rep[2];
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
1018  typedef typename ParallelIndexSet::const_iterator const_iterator;
1019  typedef IndexPair<GlobalIndex,LocalIndex> PairType;
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>
1553  RemoteIndexListModifier<T,A,mode>::RemoteIndexListModifier(const ParallelIndexSet& indexSet,
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>
1566  RemoteIndexListModifier<T,A,mode>::RemoteIndexListModifier(const RemoteIndexListModifier<T,A,mode>& other)
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>
1606  inline void RemoteIndexListModifier<T,A,mode>::insert(const RemoteIndex& index) throw(InvalidPosition)
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>
1629  inline void RemoteIndexListModifier<T,A,mode>::insert(const RemoteIndex& index, const GlobalIndex& global) throw(InvalidPosition)
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>
1654  bool RemoteIndexListModifier<T,A,mode>::remove(const GlobalIndex& global) throw(InvalidPosition)
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
1830  CollectiveIterator<T,A>::end()
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
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:1704
bool empty()
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1812
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1718
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:173
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:279
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:1573
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:597
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:1606
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
@ MODIFYINDEXSET
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:562
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:1654
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:936
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:942
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:920
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:973
void free()
Free the index lists.
Definition: remoteindices.hh:1423
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:207
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1448
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:1697
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:1691
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
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1524
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:1475
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:988
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1003
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:1441
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:996
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:948
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1510
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1468
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1517
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
std::ostream & operator<<(std::ostream &s, const array< T, N > &e)
Output operator for array.
Definition: array.hh:26
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:243
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:252
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:230
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:10
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:37
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional 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 13, 22:30, 2024)