Dune Core Modules (2.3.1)

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// $Id$
4#ifndef DUNE_REMOTEINDICES_HH
5#define DUNE_REMOTEINDICES_HH
6
7#include "indexset.hh"
8#include "plocalindex.hh"
11#include <dune/common/sllist.hh>
14#include <map>
15#include <set>
16#include <utility>
17#include <iostream>
18#include <algorithm>
19#include <iterator>
20#if HAVE_MPI
21#include "mpitraits.hh"
22#include <mpi.h>
23
24namespace Dune {
36 template<typename TG, typename TA>
38 {
39 public:
40 inline static MPI_Datatype getType();
41 private:
42 static MPI_Datatype type;
43 };
44
45
46 template<typename T, typename A>
47 class RemoteIndices;
48
49 template<typename T1, typename T2>
50 class RemoteIndex;
51
52 template<typename T>
53 class IndicesSyncer;
54
55 template<typename T1, typename T2>
56 std::ostream& operator<<(std::ostream& os, const RemoteIndex<T1,T2>& index);
57
58
59 template<typename T, typename A, bool mode>
61
62
66 template<typename T1, typename T2>
68 {
69 template<typename T>
70 friend class IndicesSyncer;
71
72 template<typename T, typename A, typename A1>
73 friend void repairLocalIndexPointers(std::map<int,SLList<std::pair<typename T::GlobalIndex, typename T::LocalIndex::Attribute>,A> >&,
75 const T&);
76
77 template<typename T, typename A, bool mode>
78 friend class RemoteIndexListModifier;
79
80 public:
85 typedef T1 GlobalIndex;
94 typedef T2 Attribute;
95
101
106 const Attribute attribute() const;
107
113 const PairType& localIndexPair() const;
114
118 RemoteIndex();
119
120
126 RemoteIndex(const T2& attribute,
127 const PairType* local);
128
129
135 RemoteIndex(const T2& attribute);
136
137 bool operator==(const RemoteIndex& ri) const;
138
139 bool operator!=(const RemoteIndex& ri) const;
140 private:
142 const PairType* localIndex_;
143
145 char attribute_;
146 };
147
148 template<class T, class A>
149 std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices);
150
151 class InterfaceBuilder;
152
153 template<class T, class A>
154 class CollectiveIterator;
155
156 template<class T>
157 class IndicesSyncer;
158
159 // forward declaration needed for friend declaration.
160 template<typename T1, typename T2>
162
163
180 template<class T, class A=std::allocator<RemoteIndex<typename T::GlobalIndex,
181 typename T::LocalIndex::Attribute> > >
183 {
184 friend class InterfaceBuilder;
185 friend class IndicesSyncer<T>;
186 template<typename T1, typename A2, typename A1>
187 friend void repairLocalIndexPointers(std::map<int,SLList<std::pair<typename T1::GlobalIndex, typename T1::LocalIndex::Attribute>,A2> >&,
189 const T1&);
190
191 template<class G, class T1, class T2>
192 friend void fillIndexSetHoles(const G& graph, Dune::OwnerOverlapCopyCommunication<T1,T2>& oocomm);
193 friend std::ostream& operator<<<>(std::ostream&, const RemoteIndices<T>&);
194
195 public:
196
201
205
210
211
216
220 typedef typename LocalIndex::Attribute Attribute;
221
226
227
231 typedef typename A::template rebind<RemoteIndex>::other Allocator;
232
236
238 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
240
241 typedef typename RemoteIndexMap::const_iterator const_iterator;
242
260 inline RemoteIndices(const ParallelIndexSet& source, const ParallelIndexSet& destination,
261 const MPI_Comm& comm, const std::vector<int>& neighbours=std::vector<int>(), bool includeSelf=false);
262
264
272 void setIncludeSelf(bool includeSelf);
273
290 void setIndexSets(const ParallelIndexSet& source, const ParallelIndexSet& destination,
291 const MPI_Comm& comm, const std::vector<int>& neighbours=std::vector<int>());
292
293 template<typename C>
294 void setNeighbours(const C& neighbours)
295 {
296 neighbourIds.clear();
297 neighbourIds.insert(neighbours.begin(), neighbours.end());
298
299 }
300
301 const std::set<int>& getNeighbours() const
302 {
303 return neighbourIds;
304 }
305
310
320 template<bool ignorePublic>
321 void rebuild();
322
323 bool operator==(const RemoteIndices& ri);
324
332 inline bool isSynced() const;
333
337 inline MPI_Comm communicator() const;
338
353 template<bool mode, bool send>
355
362 inline const_iterator find(int proc) const;
363
368 inline const_iterator begin() const;
369
374 inline const_iterator end() const;
375
379 template<bool send>
381
385 inline void free();
386
391 inline int neighbours() const;
392
394 inline const ParallelIndexSet& sourceIndexSet() const;
395
398
399 private:
402 {}
403
405 const ParallelIndexSet* source_;
406
408 const ParallelIndexSet* target_;
409
411 MPI_Comm comm_;
412
415 std::set<int> neighbourIds;
416
418 const static int commTag_=333;
419
424 int sourceSeqNo_;
425
430 int destSeqNo_;
431
435 bool publicIgnored;
436
440 bool firstBuild;
441
442 /*
443 * @brief If true, sending from indices of the processor to other
444 * indices on the same processor is enabled even if the same indexset is used
445 * on both the
446 * sending and receiving side.
447 */
448 bool includeSelf;
449
452 PairType;
453
460 RemoteIndexMap remoteIndices_;
461
472 template<bool ignorePublic>
473 inline void buildRemote(bool includeSelf);
474
480 inline int noPublic(const ParallelIndexSet& indexSet);
481
493 template<bool ignorePublic>
494 inline void packEntries(PairType** myPairs, const ParallelIndexSet& indexSet,
495 char* p_out, MPI_Datatype type, int bufferSize,
496 int* position, int n);
497
511 inline void unpackIndices(RemoteIndexList& remote, int remoteEntries,
512 PairType** local, int localEntries, char* p_in,
513 MPI_Datatype type, int* positon, int bufferSize,
514 bool fromOurself);
515
516 inline void unpackIndices(RemoteIndexList& send, RemoteIndexList& receive,
517 int remoteEntries, PairType** localSource,
518 int localSourceEntries, PairType** localDest,
519 int localDestEntries, char* p_in,
520 MPI_Datatype type, int* position, int bufferSize);
521
522 void unpackCreateRemote(char* p_in, PairType** sourcePairs, PairType** DestPairs,
523 int remoteProc, int sourcePublish, int destPublish,
524 int bufferSize, bool sendTwo, bool fromOurSelf=false);
525 };
526
544 template<class T, class A, bool mode>
546 {
547
548 template<typename T1, typename A1>
549 friend class RemoteIndices;
550
551 public:
552 class InvalidPosition : public RangeError
553 {};
554
555 enum {
564 MODIFYINDEXSET=mode
565 };
566
571
576
581
585 typedef typename LocalIndex::Attribute Attribute;
586
591
595 typedef A Allocator;
596
600
605
610
624 void insert(const RemoteIndex& index) throw(InvalidPosition);
625
626
641 void insert(const RemoteIndex& index, const GlobalIndex& global) throw(InvalidPosition);
642
650 bool remove(const GlobalIndex& global) throw(InvalidPosition);
651
665
666
668
674 : glist_()
675 {}
676
677 private:
678
685 RemoteIndexList& rList);
686
687 typedef SLList<GlobalIndex,Allocator> GlobalList;
688 typedef typename GlobalList::ModifyIterator GlobalModifyIterator;
689 RemoteIndexList* rList_;
690 const ParallelIndexSet* indexSet_;
691 GlobalList glist_;
692 ModifyIterator iter_;
693 GlobalModifyIterator giter_;
694 ConstIterator end_;
695 bool first_;
696 GlobalIndex last_;
697 };
698
703 template<class T, class A>
705 {
706
710 typedef T ParallelIndexSet;
711
715 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
716
720 typedef typename ParallelIndexSet::LocalIndex LocalIndex;
721
725 typedef typename LocalIndex::Attribute Attribute;
726
729
731 typedef typename A::template rebind<RemoteIndex>::other Allocator;
732
735
737 typedef std::map<int,std::pair<typename RemoteIndexList::const_iterator,
738 const typename RemoteIndexList::const_iterator> >
739 Map;
740
741 public:
742
744 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
746
752 inline CollectiveIterator(const RemoteIndexMap& map_, bool send);
753
762 inline void advance(const GlobalIndex& global);
763
773 inline void advance(const GlobalIndex& global, const Attribute& attribute);
774
775 CollectiveIterator& operator++();
776
780 inline bool empty();
781
789 {
790 public:
791 typedef typename Map::iterator RealIterator;
792 typedef typename Map::iterator ConstRealIterator;
793
794
796 iterator(const RealIterator& iter, const ConstRealIterator& end, GlobalIndex& index)
797 : iter_(iter), end_(end), index_(index), hasAttribute(false)
798 {
799 // Move to the first valid entry
800 while(iter_!=end_ && iter_->second.first->localIndexPair().global()!=index_)
801 ++iter_;
802 }
803
804 iterator(const RealIterator& iter, const ConstRealIterator& end, GlobalIndex index,
805 Attribute attribute)
806 : iter_(iter), end_(end), index_(index), attribute_(attribute), hasAttribute(true)
807 {
808 // Move to the first valid entry or the end
809 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_
810 || iter_->second.first->localIndexPair().local().attribute()!=attribute))
811 ++iter_;
812 }
814 iterator(const iterator& other)
815 : iter_(other.iter_), end_(other.end_), index_(other.index_)
816 { }
817
820 {
821 ++iter_;
822 // If entry is not valid move on
823 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_ ||
824 (hasAttribute &&
825 iter_->second.first->localIndexPair().local().attribute()!=attribute_)))
826 ++iter_;
827 assert(iter_==end_ ||
828 (iter_->second.first->localIndexPair().global()==index_));
829 assert(iter_==end_ || !hasAttribute ||
830 (iter_->second.first->localIndexPair().local().attribute()==attribute_));
831 return *this;
832 }
833
835 const RemoteIndex& operator*() const
836 {
837 return *(iter_->second.first);
838 }
839
841 int process() const
842 {
843 return iter_->first;
844 }
845
847 const RemoteIndex* operator->() const
848 {
849 return iter_->second.first.operator->();
850 }
851
853 bool operator==(const iterator& other)
854 {
855 return other.iter_==iter_;
856 }
857
859 bool operator!=(const iterator& other)
860 {
861 return other.iter_!=iter_;
862 }
863
864 private:
865 iterator();
866
867 RealIterator iter_;
868 RealIterator end_;
869 GlobalIndex index_;
870 Attribute attribute_;
871 bool hasAttribute;
872 };
873
874 iterator begin();
875
876 iterator end();
877
878 private:
879
880 Map map_;
881 GlobalIndex index_;
882 Attribute attribute_;
883 bool noattribute;
884 };
885
886 template<typename TG, typename TA>
887 MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::getType()
888 {
889 if(type==MPI_DATATYPE_NULL) {
890 int length[4];
891 MPI_Aint disp[4];
892 MPI_Datatype types[4] = {MPI_LB, MPITraits<TG>::getType(),
893 MPITraits<ParallelLocalIndex<TA> >::getType(), MPI_UB};
894 IndexPair<TG,ParallelLocalIndex<TA> > rep[2];
895 length[0]=length[1]=length[2]=length[3]=1;
896 MPI_Address(rep, disp); // lower bound of the datatype
897 MPI_Address(&(rep[0].global_), disp+1);
898 MPI_Address(&(rep[0].local_), disp+2);
899 MPI_Address(rep+1, disp+3); // upper bound of the datatype
900 for(int i=3; i >= 0; --i)
901 disp[i] -= disp[0];
902 MPI_Type_struct(4, length, disp, types, &type);
903 MPI_Type_commit(&type);
904 }
905 return type;
906 }
907
908 template<typename TG, typename TA>
909 MPI_Datatype MPITraits<IndexPair<TG,ParallelLocalIndex<TA> > >::type=MPI_DATATYPE_NULL;
910
911 template<typename T1, typename T2>
912 RemoteIndex<T1,T2>::RemoteIndex(const T2& attribute, const PairType* local)
913 : localIndex_(local), attribute_(attribute)
914 {}
915
916 template<typename T1, typename T2>
918 : localIndex_(0), attribute_(attribute)
919 {}
920
921 template<typename T1, typename T2>
923 : localIndex_(0), attribute_()
924 {}
925 template<typename T1, typename T2>
926 inline bool RemoteIndex<T1,T2>::operator==(const RemoteIndex& ri) const
927 {
928 return localIndex_==ri.localIndex_ && attribute_==ri.attribute;
929 }
930
931 template<typename T1, typename T2>
932 inline bool RemoteIndex<T1,T2>::operator!=(const RemoteIndex& ri) const
933 {
934 return localIndex_!=ri.localIndex_ || attribute_!=ri.attribute_;
935 }
936
937 template<typename T1, typename T2>
938 inline const T2 RemoteIndex<T1,T2>::attribute() const
939 {
940 return T2(attribute_);
941 }
942
943 template<typename T1, typename T2>
945 {
946 return *localIndex_;
947 }
948
949 template<typename T, typename A>
951 const ParallelIndexSet& destination,
952 const MPI_Comm& comm,
953 const std::vector<int>& neighbours,
954 bool includeSelf_)
955 : source_(&source), target_(&destination), comm_(comm),
956 sourceSeqNo_(-1), destSeqNo_(-1), publicIgnored(false), firstBuild(true),
957 includeSelf(includeSelf_)
958 {
959 setNeighbours(neighbours);
960 }
961
962 template<typename T, typename A>
964 {
965 includeSelf=b;
966 }
967
968 template<typename T, typename A>
970 : source_(0), target_(0), sourceSeqNo_(-1),
971 destSeqNo_(-1), publicIgnored(false), firstBuild(true)
972 {}
973
974 template<class T, typename A>
976 const ParallelIndexSet& destination,
977 const MPI_Comm& comm,
978 const std::vector<int>& neighbours)
979 {
980 free();
981 source_ = &source;
982 target_ = &destination;
983 comm_ = comm;
984 firstBuild = true;
985 setNeighbours(neighbours);
986 }
987
988 template<typename T, typename A>
991 {
992 return *source_;
993 }
994
995
996 template<typename T, typename A>
999 {
1000 return *target_;
1001 }
1002
1003
1004 template<typename T, typename A>
1006 {
1007 free();
1008 }
1009
1010 template<typename T, typename A>
1011 template<bool ignorePublic>
1013 const ParallelIndexSet& indexSet,
1014 char* p_out, MPI_Datatype type,
1015 int bufferSize,
1016 int *position, int n)
1017 {
1018 // fill with own indices
1019 typedef typename ParallelIndexSet::const_iterator const_iterator;
1020 typedef IndexPair<GlobalIndex,LocalIndex> PairType;
1021 const const_iterator end = indexSet.end();
1022
1023 //Now pack the source indices
1024 int i=0;
1025 for(const_iterator index = indexSet.begin(); index != end; ++index)
1026 if(ignorePublic || index->local().isPublic()) {
1027
1028 MPI_Pack(const_cast<PairType*>(&(*index)), 1,
1029 type,
1030 p_out, bufferSize, position, comm_);
1031 pairs[i++] = const_cast<PairType*>(&(*index));
1032
1033 }
1034 assert(i==n);
1035 }
1036
1037 template<typename T, typename A>
1038 inline int RemoteIndices<T,A>::noPublic(const ParallelIndexSet& indexSet)
1039 {
1040 typedef typename ParallelIndexSet::const_iterator const_iterator;
1041
1042 int noPublic=0;
1043
1044 const const_iterator end=indexSet.end();
1045 for(const_iterator index=indexSet.begin(); index!=end; ++index)
1046 if(index->local().isPublic())
1047 noPublic++;
1048
1049 return noPublic;
1050
1051 }
1052
1053
1054 template<typename T, typename A>
1055 inline void RemoteIndices<T,A>::unpackCreateRemote(char* p_in, PairType** sourcePairs,
1056 PairType** destPairs, int remoteProc,
1057 int sourcePublish, int destPublish,
1058 int bufferSize, bool sendTwo,
1059 bool fromOurSelf)
1060 {
1061
1062 // unpack the number of indices we received
1063 int noRemoteSource=-1, noRemoteDest=-1;
1064 char twoIndexSets=0;
1065 int position=0;
1066 // Did we receive two index sets?
1067 MPI_Unpack(p_in, bufferSize, &position, &twoIndexSets, 1, MPI_CHAR, comm_);
1068 // The number of source indices received
1069 MPI_Unpack(p_in, bufferSize, &position, &noRemoteSource, 1, MPI_INT, comm_);
1070 // The number of destination indices received
1071 MPI_Unpack(p_in, bufferSize, &position, &noRemoteDest, 1, MPI_INT, comm_);
1072
1073
1074 // Indices for which we receive
1075 RemoteIndexList* receive= new RemoteIndexList();
1076 // Indices for which we send
1077 RemoteIndexList* send=0;
1078
1079 MPI_Datatype type= MPITraits<PairType>::getType();
1080
1081 if(!twoIndexSets) {
1082 if(sendTwo) {
1083 send = new RemoteIndexList();
1084 // Create both remote index sets simultaneously
1085 unpackIndices(*send, *receive, noRemoteSource, sourcePairs, sourcePublish,
1086 destPairs, destPublish, p_in, type, &position, bufferSize);
1087 }else{
1088 // we only need one list
1089 unpackIndices(*receive, noRemoteSource, sourcePairs, sourcePublish,
1090 p_in, type, &position, bufferSize, fromOurSelf);
1091 send=receive;
1092 }
1093 }else{
1094
1095 int oldPos=position;
1096 // Two index sets received
1097 unpackIndices(*receive, noRemoteSource, destPairs, destPublish,
1098 p_in, type, &position, bufferSize, fromOurSelf);
1099 if(!sendTwo)
1100 //unpack source entries again as destination entries
1101 position=oldPos;
1102
1103 send = new RemoteIndexList();
1104 unpackIndices(*send, noRemoteDest, sourcePairs, sourcePublish,
1105 p_in, type, &position, bufferSize, fromOurSelf);
1106 }
1107
1108 if(receive->empty() && send->empty()) {
1109 if(send==receive) {
1110 delete send;
1111 }else{
1112 delete send;
1113 delete receive;
1114 }
1115 }else{
1116 remoteIndices_.insert(std::make_pair(remoteProc,
1117 std::make_pair(send,receive)));
1118 }
1119 }
1120
1121
1122 template<typename T, typename A>
1123 template<bool ignorePublic>
1124 inline void RemoteIndices<T,A>::buildRemote(bool includeSelf)
1125 {
1126 // Processor configuration
1127 int rank, procs;
1128 MPI_Comm_rank(comm_, &rank);
1129 MPI_Comm_size(comm_, &procs);
1130
1131 // number of local indices to publish
1132 // The indices of the destination will be send.
1133 int sourcePublish, destPublish;
1134
1135 // Do we need to send two index sets?
1136 char sendTwo = (source_ != target_);
1137
1138 if(procs==1 && !(sendTwo || includeSelf))
1139 // Nothing to communicate
1140 return;
1141
1142 sourcePublish = (ignorePublic) ? source_->size() : noPublic(*source_);
1143
1144 if(sendTwo)
1145 destPublish = (ignorePublic) ? target_->size() : noPublic(*target_);
1146 else
1147 // we only need to send one set of indices
1148 destPublish = 0;
1149
1150 int maxPublish, publish=sourcePublish+destPublish;
1151
1152 // Calucate maximum number of indices send
1153 MPI_Allreduce(&publish, &maxPublish, 1, MPI_INT, MPI_MAX, comm_);
1154
1155 // allocate buffers
1156 typedef IndexPair<GlobalIndex,LocalIndex> PairType;
1157
1158 PairType** destPairs;
1159 PairType** sourcePairs = new PairType*[sourcePublish>0 ? sourcePublish : 1];
1160
1161 if(sendTwo)
1162 destPairs = new PairType*[destPublish>0 ? destPublish : 1];
1163 else
1164 destPairs=sourcePairs;
1165
1166 char** buffer = new char*[2];
1167 int bufferSize;
1168 int position=0;
1169 int intSize;
1170 int charSize;
1171
1172 // calculate buffer size
1173 MPI_Datatype type = MPITraits<PairType>::getType();
1174
1175 MPI_Pack_size(maxPublish, type, comm_,
1176 &bufferSize);
1177 MPI_Pack_size(1, MPI_INT, comm_,
1178 &intSize);
1179 MPI_Pack_size(1, MPI_CHAR, comm_,
1180 &charSize);
1181 // Our message will contain the following:
1182 // a bool wether two index sets where sent
1183 // the size of the source and the dest indexset,
1184 // then the source and destination indices
1185 bufferSize += 2 * intSize + charSize;
1186
1187 if(bufferSize<=0) bufferSize=1;
1188
1189 buffer[0] = new char[bufferSize];
1190 buffer[1] = new char[bufferSize];
1191
1192
1193 // pack entries into buffer[0], p_out below!
1194 MPI_Pack(&sendTwo, 1, MPI_CHAR, buffer[0], bufferSize, &position,
1195 comm_);
1196
1197 // The number of indices we send for each index set
1198 MPI_Pack(&sourcePublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1199 comm_);
1200 MPI_Pack(&destPublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1201 comm_);
1202
1203 // Now pack the source indices and setup the destination pairs
1204 packEntries<ignorePublic>(sourcePairs, *source_, buffer[0], type,
1205 bufferSize, &position, sourcePublish);
1206 // If necessary send the dest indices and setup the source pairs
1207 if(sendTwo)
1208 packEntries<ignorePublic>(destPairs, *target_, buffer[0], type,
1209 bufferSize, &position, destPublish);
1210
1211
1212 // Update remote indices for ourself
1213 if(sendTwo|| includeSelf)
1214 unpackCreateRemote(buffer[0], sourcePairs, destPairs, rank, sourcePublish,
1215 destPublish, bufferSize, sendTwo, includeSelf);
1216
1217 neighbourIds.erase(rank);
1218
1219 if(neighbourIds.size()==0)
1220 {
1221 Dune::dvverb<<rank<<": Sending messages in a ring"<<std::endl;
1222 // send messages in ring
1223 for(int proc=1; proc<procs; proc++) {
1224 // pointers to the current input and output buffers
1225 char* p_out = buffer[1-(proc%2)];
1226 char* p_in = buffer[proc%2];
1227
1228 MPI_Status status;
1229 if(rank%2==0) {
1230 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1231 commTag_, comm_);
1232 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1233 commTag_, comm_, &status);
1234 }else{
1235 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1236 commTag_, comm_, &status);
1237 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1238 commTag_, comm_);
1239 }
1240
1241
1242 // The process these indices are from
1243 int remoteProc = (rank+procs-proc)%procs;
1244
1245 unpackCreateRemote(p_in, sourcePairs, destPairs, remoteProc, sourcePublish,
1246 destPublish, bufferSize, sendTwo);
1247
1248 }
1249
1250 }
1251 else
1252 {
1253 MPI_Request* requests=new MPI_Request[neighbourIds.size()];
1254 MPI_Request* req=requests;
1255
1256 typedef typename std::set<int>::size_type size_type;
1257 size_type noNeighbours=neighbourIds.size();
1258
1259 // setup sends
1260 for(std::set<int>::iterator neighbour=neighbourIds.begin();
1261 neighbour!= neighbourIds.end(); ++neighbour) {
1262 // Only send the information to the neighbouring processors
1263 MPI_Issend(buffer[0], position , MPI_PACKED, *neighbour, commTag_, comm_, req++);
1264 }
1265
1266 //Test for received messages
1267
1268 for(size_type received=0; received <noNeighbours; ++received)
1269 {
1270 MPI_Status status;
1271 // probe for next message
1272 MPI_Probe(MPI_ANY_SOURCE, commTag_, comm_, &status);
1273 int remoteProc=status.MPI_SOURCE;
1274 int size;
1275 MPI_Get_count(&status, MPI_PACKED, &size);
1276 // receive message
1277 MPI_Recv(buffer[1], size, MPI_PACKED, remoteProc,
1278 commTag_, comm_, &status);
1279
1280 unpackCreateRemote(buffer[1], sourcePairs, destPairs, remoteProc, sourcePublish,
1281 destPublish, bufferSize, sendTwo);
1282 }
1283 // wait for completion of pending requests
1284 MPI_Status* statuses = new MPI_Status[neighbourIds.size()];
1285
1286 if(MPI_ERR_IN_STATUS==MPI_Waitall(neighbourIds.size(), requests, statuses)) {
1287 for(size_type i=0; i < neighbourIds.size(); ++i)
1288 if(statuses[i].MPI_ERROR!=MPI_SUCCESS) {
1289 std::cerr<<rank<<": MPI_Error occurred while receiving message."<<std::endl;
1290 MPI_Abort(comm_, 999);
1291 }
1292 }
1293 delete[] requests;
1294 delete[] statuses;
1295 }
1296
1297
1298 // delete allocated memory
1299 if(destPairs!=sourcePairs)
1300 delete[] destPairs;
1301
1302 delete[] sourcePairs;
1303 delete[] buffer[0];
1304 delete[] buffer[1];
1305 delete[] buffer;
1306 }
1307
1308 template<typename T, typename A>
1309 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& remote,
1310 int remoteEntries,
1311 PairType** local,
1312 int localEntries,
1313 char* p_in,
1314 MPI_Datatype type,
1315 int* position,
1316 int bufferSize,
1317 bool fromOurSelf)
1318 {
1319 if(remoteEntries==0)
1320 return;
1321
1322 PairType index(-1);
1323 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1324 type, comm_);
1325 GlobalIndex oldGlobal=index.global();
1326 int n_in=0, localIndex=0;
1327
1328 //Check if we know the global index
1329 while(localIndex<localEntries) {
1330 if(local[localIndex]->global()==index.global()) {
1331 int oldLocalIndex=localIndex;
1332
1333 while(localIndex<localEntries &&
1334 local[localIndex]->global()==index.global()) {
1335 if(!fromOurSelf || index.local().attribute() !=
1336 local[localIndex]->local().attribute())
1337 // if index is from us it has to have a different attribute
1338 remote.push_back(RemoteIndex(index.local().attribute(),
1339 local[localIndex]));
1340 localIndex++;
1341 }
1342
1343 // unpack next remote index
1344 if((++n_in) < remoteEntries) {
1345 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1346 type, comm_);
1347 if(index.global()==oldGlobal)
1348 // Restart comparison for the same global indices
1349 localIndex=oldLocalIndex;
1350 else
1351 oldGlobal=index.global();
1352 }else{
1353 // No more received indices
1354 break;
1355 }
1356 continue;
1357 }
1358
1359 if (local[localIndex]->global()<index.global()) {
1360 // compare with next entry in our list
1361 ++localIndex;
1362 }else{
1363 // We do not know the index, unpack next
1364 if((++n_in) < remoteEntries) {
1365 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1366 type, comm_);
1367 oldGlobal=index.global();
1368 }else
1369 // No more received indices
1370 break;
1371 }
1372 }
1373
1374 // Unpack the other received indices without doing anything
1375 while(++n_in < remoteEntries)
1376 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1377 type, comm_);
1378 }
1379
1380
1381 template<typename T, typename A>
1382 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& send,
1383 RemoteIndexList& receive,
1384 int remoteEntries,
1385 PairType** localSource,
1386 int localSourceEntries,
1387 PairType** localDest,
1388 int localDestEntries,
1389 char* p_in,
1390 MPI_Datatype type,
1391 int* position,
1392 int bufferSize)
1393 {
1394 int n_in=0, sourceIndex=0, destIndex=0;
1395
1396 //Check if we know the global index
1397 while(n_in<remoteEntries && (sourceIndex<localSourceEntries || destIndex<localDestEntries)) {
1398 // Unpack next index
1399 PairType index;
1400 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1401 type, comm_);
1402 n_in++;
1403
1404 // Advance until global index in localSource and localDest are >= than the one in the unpacked index
1405 while(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()<index.global())
1406 sourceIndex++;
1407
1408 while(destIndex<localDestEntries && localDest[destIndex]->global()<index.global())
1409 destIndex++;
1410
1411 // Add a remote index if we found the global index.
1412 if(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()==index.global())
1413 send.push_back(RemoteIndex(index.local().attribute(),
1414 localSource[sourceIndex]));
1415
1416 if(destIndex < localDestEntries && localDest[destIndex]->global() == index.global())
1417 receive.push_back(RemoteIndex(index.local().attribute(),
1418 localDest[sourceIndex]));
1419 }
1420
1421 }
1422
1423 template<typename T, typename A>
1425 {
1426 typedef typename RemoteIndexMap::iterator Iterator;
1427 Iterator lend = remoteIndices_.end();
1428 for(Iterator lists=remoteIndices_.begin(); lists != lend; ++lists) {
1429 if(lists->second.first==lists->second.second) {
1430 // there is only one remote index list.
1431 delete lists->second.first;
1432 }else{
1433 delete lists->second.first;
1434 delete lists->second.second;
1435 }
1436 }
1437 remoteIndices_.clear();
1438 firstBuild=true;
1439 }
1440
1441 template<typename T, typename A>
1443 {
1444 return remoteIndices_.size();
1445 }
1446
1447 template<typename T, typename A>
1448 template<bool ignorePublic>
1450 {
1451 // Test wether a rebuild is Needed.
1452 if(firstBuild ||
1453 ignorePublic!=publicIgnored || !
1454 isSynced()) {
1455 free();
1456
1457 buildRemote<ignorePublic>(includeSelf);
1458
1459 sourceSeqNo_ = source_->seqNo();
1460 destSeqNo_ = target_->seqNo();
1461 firstBuild=false;
1462 publicIgnored=ignorePublic;
1463 }
1464
1465
1466 }
1467
1468 template<typename T, typename A>
1470 {
1471 return sourceSeqNo_==source_->seqNo() && destSeqNo_ ==target_->seqNo();
1472 }
1473
1474 template<typename T, typename A>
1475 template<bool mode, bool send>
1477 {
1478
1479 // The user are on their own now!
1480 // We assume they know what they are doing and just set the
1481 // remote indices to synced status.
1482 sourceSeqNo_ = source_->seqNo();
1483 destSeqNo_ = target_->seqNo();
1484
1485 typename RemoteIndexMap::iterator found = remoteIndices_.find(process);
1486
1487 if(found == remoteIndices_.end())
1488 {
1489 if(source_ != target_)
1490 found = remoteIndices_.insert(found, std::make_pair(process,
1491 std::make_pair(new RemoteIndexList(),
1492 new RemoteIndexList())));
1493 else{
1494 RemoteIndexList* rlist = new RemoteIndexList();
1495 found = remoteIndices_.insert(found,
1496 std::make_pair(process,
1497 std::make_pair(rlist, rlist)));
1498 }
1499 }
1500
1501 firstBuild = false;
1502
1503 if(send)
1504 return RemoteIndexListModifier<T,A,mode>(*source_, *(found->second.first));
1505 else
1506 return RemoteIndexListModifier<T,A,mode>(*target_, *(found->second.second));
1507 }
1508
1509 template<typename T, typename A>
1510 inline typename RemoteIndices<T,A>::const_iterator
1512 {
1513 return remoteIndices_.find(proc);
1514 }
1515
1516 template<typename T, typename A>
1517 inline typename RemoteIndices<T,A>::const_iterator
1519 {
1520 return remoteIndices_.begin();
1521 }
1522
1523 template<typename T, typename A>
1524 inline typename RemoteIndices<T,A>::const_iterator
1526 {
1527 return remoteIndices_.end();
1528 }
1529
1530
1531 template<typename T, typename A>
1533 {
1534 if(neighbours()!=ri.neighbours())
1535 return false;
1536
1537 typedef RemoteIndexList RList;
1538 typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1539
1540 const const_iterator rend = remoteIndices_.end();
1541
1542 for(const_iterator rindex = remoteIndices_.begin(), rindex1=ri.remoteIndices_.begin(); rindex!=rend; ++rindex, ++rindex1) {
1543 if(rindex->first != rindex1->first)
1544 return false;
1545 if(*(rindex->second.first) != *(rindex1->second.first))
1546 return false;
1547 if(*(rindex->second.second) != *(rindex1->second.second))
1548 return false;
1549 }
1550 return true;
1551 }
1552
1553 template<class T, class A, bool mode>
1554 RemoteIndexListModifier<T,A,mode>::RemoteIndexListModifier(const ParallelIndexSet& indexSet,
1555 RemoteIndexList& rList)
1556 : rList_(&rList), indexSet_(&indexSet), iter_(rList.beginModify()), end_(rList.end()), first_(true)
1557 {
1558 if(MODIFYINDEXSET) {
1559 assert(indexSet_);
1560 for(ConstIterator iter=iter_; iter != end_; ++iter)
1561 glist_.push_back(iter->localIndexPair().global());
1562 giter_ = glist_.beginModify();
1563 }
1564 }
1565
1566 template<typename T, typename A, bool mode>
1567 RemoteIndexListModifier<T,A,mode>::RemoteIndexListModifier(const RemoteIndexListModifier<T,A,mode>& other)
1568 : rList_(other.rList_), indexSet_(other.indexSet_),
1569 glist_(other.glist_), iter_(other.iter_), giter_(other.giter_), end_(other.end_),
1570 first_(other.first_), last_(other.last_)
1571 {}
1572
1573 template<typename T, typename A, bool mode>
1575 {
1576 if(MODIFYINDEXSET) {
1577 // repair pointers to local index set.
1578#ifdef DUNE_ISTL_WITH_CHECKING
1579 if(indexSet_->state()!=GROUND)
1580 DUNE_THROW(InvalidIndexSetState, "Index has to be in ground mode for repairing pointers to indices");
1581#endif
1582 typedef typename ParallelIndexSet::const_iterator IndexIterator;
1583 typedef typename GlobalList::const_iterator GlobalIterator;
1584 typedef typename RemoteIndexList::iterator Iterator;
1585 GlobalIterator giter = glist_.begin();
1586 IndexIterator index = indexSet_->begin();
1587
1588 for(Iterator iter=rList_->begin(); iter != end_; ++iter) {
1589 while(index->global()<*giter) {
1590 ++index;
1591#ifdef DUNE_ISTL_WITH_CHECKING
1592 if(index == indexSet_->end())
1593 DUNE_THROW(InvalidPosition, "No such global index in set!");
1594#endif
1595 }
1596
1597#ifdef DUNE_ISTL_WITH_CHECKING
1598 if(index->global() != *giter)
1599 DUNE_THROW(InvalidPosition, "No such global index in set!");
1600#endif
1601 iter->localIndex_ = &(*index);
1602 }
1603 }
1604 }
1605
1606 template<typename T, typename A, bool mode>
1607 inline void RemoteIndexListModifier<T,A,mode>::insert(const RemoteIndex& index) throw(InvalidPosition)
1608 {
1609 dune_static_assert(!mode,"Not allowed if the mode indicates that new indices"
1610 "might be added to the underlying index set. Use "
1611 "insert(const RemoteIndex&, const GlobalIndex&) instead");
1612
1613#ifdef DUNE_ISTL_WITH_CHECKING
1614 if(!first_ && index.localIndexPair().global()<last_)
1615 DUNE_THROW(InvalidPosition, "Modifcation of remote indices have to occur with ascending global index.");
1616#endif
1617 // Move to the correct position
1618 while(iter_ != end_ && iter_->localIndexPair().global() < index.localIndexPair().global()) {
1619 ++iter_;
1620 }
1621
1622 // No duplicate entries allowed
1623 assert(iter_==end_ || iter_->localIndexPair().global() != index.localIndexPair().global());
1624 iter_.insert(index);
1625 last_ = index.localIndexPair().global();
1626 first_ = false;
1627 }
1628
1629 template<typename T, typename A, bool mode>
1630 inline void RemoteIndexListModifier<T,A,mode>::insert(const RemoteIndex& index, const GlobalIndex& global) throw(InvalidPosition)
1631 {
1632 dune_static_assert(mode,"Not allowed if the mode indicates that no new indices"
1633 "might be added to the underlying index set. Use "
1634 "insert(const RemoteIndex&) instead");
1635#ifdef DUNE_ISTL_WITH_CHECKING
1636 if(!first_ && global<last_)
1637 DUNE_THROW(InvalidPosition, "Modification of remote indices have to occur with ascending global index.");
1638#endif
1639 // Move to the correct position
1640 while(iter_ != end_ && *giter_ < global) {
1641 ++giter_;
1642 ++iter_;
1643 }
1644
1645 // No duplicate entries allowed
1646 assert(iter_->localIndexPair().global() != global);
1647 iter_.insert(index);
1648 giter_.insert(global);
1649
1650 last_ = global;
1651 first_ = false;
1652 }
1653
1654 template<typename T, typename A, bool mode>
1655 bool RemoteIndexListModifier<T,A,mode>::remove(const GlobalIndex& global) throw(InvalidPosition)
1656 {
1657#ifdef DUNE_ISTL_WITH_CHECKING
1658 if(!first_ && global<last_)
1659 DUNE_THROW(InvalidPosition, "Modifcation of remote indices have to occur with ascending global index.");
1660#endif
1661
1662 bool found= false;
1663
1664 if(MODIFYINDEXSET) {
1665 // Move to the correct position
1666 while(iter_!=end_ && *giter_< global) {
1667 ++giter_;
1668 ++iter_;
1669 }
1670 if(*giter_ == global) {
1671 giter_.remove();
1672 iter_.remove();
1673 found=true;
1674 }
1675 }else{
1676 while(iter_!=end_ && iter_->localIndexPair().global() < global)
1677 ++iter_;
1678
1679 if(iter_->localIndexPair().global()==global) {
1680 iter_.remove();
1681 found = true;
1682 }
1683 }
1684
1685 last_ = global;
1686 first_ = false;
1687 return found;
1688 }
1689
1690 template<typename T, typename A>
1691 template<bool send>
1693 {
1694 return CollectiveIterator<T,A>(remoteIndices_, send);
1695 }
1696
1697 template<typename T, typename A>
1698 inline MPI_Comm RemoteIndices<T,A>::communicator() const
1699 {
1700 return comm_;
1701
1702 }
1703
1704 template<typename T, typename A>
1706 {
1707 typedef typename RemoteIndexMap::const_iterator const_iterator;
1708
1709 const const_iterator end=pmap.end();
1710 for(const_iterator process=pmap.begin(); process != end; ++process) {
1711 const RemoteIndexList* list = send ? process->second.first : process->second.second;
1713 map_.insert(std::make_pair(process->first,
1714 std::pair<iterator, const iterator>(list->begin(), list->end())));
1715 }
1716 }
1717
1718 template<typename T, typename A>
1719 inline void CollectiveIterator<T,A>::advance(const GlobalIndex& index)
1720 {
1721 typedef typename Map::iterator iterator;
1722 typedef typename Map::const_iterator const_iterator;
1723 const const_iterator end = map_.end();
1724
1725 for(iterator iter = map_.begin(); iter != end;) {
1726 // Step the iterator until we are >= index
1727 typename RemoteIndexList::const_iterator current = iter->second.first;
1728 typename RemoteIndexList::const_iterator rend = iter->second.second;
1729 RemoteIndex remoteIndex;
1730 if(current != rend)
1731 remoteIndex = *current;
1732
1733 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1734 ++(iter->second.first);
1735
1736 // erase from the map if there are no more entries.
1737 if(iter->second.first == iter->second.second)
1738 map_.erase(iter++);
1739 else{
1740 ++iter;
1741 }
1742 }
1743 index_=index;
1744 noattribute=true;
1745 }
1746
1747 template<typename T, typename A>
1748 inline void CollectiveIterator<T,A>::advance(const GlobalIndex& index,
1749 const Attribute& attribute)
1750 {
1751 typedef typename Map::iterator iterator;
1752 typedef typename Map::const_iterator const_iterator;
1753 const const_iterator end = map_.end();
1754
1755 for(iterator iter = map_.begin(); iter != end;) {
1756 // Step the iterator until we are >= index
1757 typename RemoteIndexList::const_iterator current = iter->second.first;
1758 typename RemoteIndexList::const_iterator rend = iter->second.second;
1759 RemoteIndex remoteIndex;
1760 if(current != rend)
1761 remoteIndex = *current;
1762
1763 // Move to global index or bigger
1764 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1765 ++(iter->second.first);
1766
1767 // move to attribute or bigger
1768 while(iter->second.first!=iter->second.second
1769 && iter->second.first->localIndexPair().global()==index
1770 && iter->second.first->localIndexPair().local().attribute()<attribute)
1771 ++(iter->second.first);
1772
1773 // erase from the map if there are no more entries.
1774 if(iter->second.first == iter->second.second)
1775 map_.erase(iter++);
1776 else{
1777 ++iter;
1778 }
1779 }
1780 index_=index;
1781 attribute_=attribute;
1782 noattribute=false;
1783 }
1784
1785 template<typename T, typename A>
1787 {
1788 typedef typename Map::iterator iterator;
1789 typedef typename Map::const_iterator const_iterator;
1790 const const_iterator end = map_.end();
1791
1792 for(iterator iter = map_.begin(); iter != end;) {
1793 // Step the iterator until we are >= index
1794 typename RemoteIndexList::const_iterator current = iter->second.first;
1795 typename RemoteIndexList::const_iterator rend = iter->second.second;
1796
1797 // move all iterators pointing to the current global index to next value
1798 if(iter->second.first->localIndexPair().global()==index_ &&
1799 (noattribute || iter->second.first->localIndexPair().local().attribute() == attribute_))
1800 ++(iter->second.first);
1801
1802 // erase from the map if there are no more entries.
1803 if(iter->second.first == iter->second.second)
1804 map_.erase(iter++);
1805 else{
1806 ++iter;
1807 }
1808 }
1809 return *this;
1810 }
1811
1812 template<typename T, typename A>
1814 {
1815 return map_.empty();
1816 }
1817
1818 template<typename T, typename A>
1819 inline typename CollectiveIterator<T,A>::iterator
1821 {
1822 if(noattribute)
1823 return iterator(map_.begin(), map_.end(), index_);
1824 else
1825 return iterator(map_.begin(), map_.end(), index_,
1826 attribute_);
1827 }
1828
1829 template<typename T, typename A>
1830 inline typename CollectiveIterator<T,A>::iterator
1831 CollectiveIterator<T,A>::end()
1832 {
1833 return iterator(map_.end(), map_.end(), index_);
1834 }
1835
1836 template<typename TG, typename TA>
1837 inline std::ostream& operator<<(std::ostream& os, const RemoteIndex<TG,TA>& index)
1838 {
1839 os<<"[global="<<index.localIndexPair().global()<<", remote attribute="<<index.attribute()<<" local attribute="<<index.localIndexPair().local().attribute()<<"]";
1840 return os;
1841 }
1842
1843 template<typename T, typename A>
1844 inline std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices)
1845 {
1846 int rank;
1847 MPI_Comm_rank(indices.comm_, &rank);
1848
1849 typedef typename RemoteIndices<T,A>::RemoteIndexList RList;
1850 typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1851
1852 const const_iterator rend = indices.remoteIndices_.end();
1853
1854 for(const_iterator rindex = indices.remoteIndices_.begin(); rindex!=rend; ++rindex) {
1855 os<<rank<<": Prozess "<<rindex->first<<":";
1856
1857 if(!rindex->second.first->empty()) {
1858 os<<" send:";
1859
1860 const typename RList::const_iterator send= rindex->second.first->end();
1861
1862 for(typename RList::const_iterator index = rindex->second.first->begin();
1863 index != send; ++index)
1864 os<<*index<<" ";
1865 os<<std::endl;
1866 }
1867 if(!rindex->second.second->empty()) {
1868 os<<rank<<": Prozess "<<rindex->first<<": "<<"receive: ";
1869
1870 const typename RList::const_iterator rend= rindex->second.second->end();
1871
1872 for(typename RList::const_iterator index = rindex->second.second->begin();
1873 index != rend; ++index)
1874 os<<*index<<" ";
1875 }
1876 os<<std::endl<<std::flush;
1877 }
1878 return os;
1879 }
1881}
1882
1883#endif
1884#endif
Iterator over the valid underlying iterators.
Definition: remoteindices.hh:789
bool operator==(const iterator &other)
Definition: remoteindices.hh:853
iterator(const RealIterator &iter, const ConstRealIterator &end, GlobalIndex &index)
Definition: remoteindices.hh:796
bool operator!=(const iterator &other)
Definition: remoteindices.hh:859
iterator(const iterator &other)
Definition: remoteindices.hh:814
const RemoteIndex & operator*() const
Definition: remoteindices.hh:835
iterator & operator++()
Definition: remoteindices.hh:819
const RemoteIndex * operator->() const
Definition: remoteindices.hh:847
int process() const
Definition: remoteindices.hh:841
A collective iterator for moving over the remote indices for all processes collectively.
Definition: remoteindices.hh:705
CollectiveIterator(const RemoteIndexMap &map_, bool send)
Constructor.
Definition: remoteindices.hh:1705
bool empty()
Checks whether there are still iterators in the map.
Definition: remoteindices.hh:1813
void advance(const GlobalIndex &global)
Advances all underlying iterators.
Definition: remoteindices.hh:1719
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:745
A constant random access iterator for the Dune::ArrayList class.
Definition: arraylist.hh:380
A pair consisting of a global and local index.
Definition: indexset.hh:85
Class for recomputing missing indices of a distributed index set.
Definition: indicessyncer.hh:41
Base class of all classes representing a communication interface.
Definition: interface.hh:34
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:205
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:173
Manager class for the mapping between local indices and globally unique indices.
Definition: indexset.hh:218
An index present on the local process with an additional attribute flag.
Definition: plocalindex.hh:48
Default exception class for range errors.
Definition: exceptions.hh:280
Modifier for adding and/or deleting remote indices from the remote index list.
Definition: remoteindices.hh:546
void repairLocalIndexPointers()
Repair the pointers to the local index pairs.
Definition: remoteindices.hh:1574
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:599
A Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:595
void insert(const RemoteIndex &index)
Insert an index to the list.
Definition: remoteindices.hh:1607
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:575
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:580
@ MODIFYINDEXSET
If true the index set corresponding to the remote indices might get modified.
Definition: remoteindices.hh:564
RemoteIndexList::const_iterator ConstIterator
The type of the remote index list iterator.
Definition: remoteindices.hh:609
SLListModifyIterator< RemoteIndex, Allocator > ModifyIterator
The type of the modifying iterator of the remote index list.
Definition: remoteindices.hh:604
bool remove(const GlobalIndex &global)
Remove a remote index.
Definition: remoteindices.hh:1655
T ParallelIndexSet
Type of the index set we use.
Definition: remoteindices.hh:570
RemoteIndexListModifier()
Default constructor.
Definition: remoteindices.hh:673
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:585
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:590
Information about an index residing on another processor.
Definition: remoteindices.hh:68
const Attribute attribute() const
Get the attribute of the index on the remote process.
Definition: remoteindices.hh:938
T1 GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: remoteindices.hh:85
T2 Attribute
The type of the attributes. Normally this will be an enumeration like.
Definition: remoteindices.hh:94
IndexPair< GlobalIndex, ParallelLocalIndex< Attribute > > PairType
The type of the index pair.
Definition: remoteindices.hh:100
const PairType & localIndexPair() const
Get the corresponding local index pair.
Definition: remoteindices.hh:944
RemoteIndex()
Parameterless Constructor.
Definition: remoteindices.hh:922
The indices present on remote processes.
Definition: remoteindices.hh:183
Dune::RemoteIndex< GlobalIndex, Attribute > RemoteIndex
Type of the remote indices we manage.
Definition: remoteindices.hh:225
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:975
void free()
Free the index lists.
Definition: remoteindices.hh:1424
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: remoteindices.hh:209
void rebuild()
Rebuilds the set of remote indices.
Definition: remoteindices.hh:1449
T ParallelIndexSet
Type of the index set we use, e.g. ParallelLocalIndexSet.
Definition: remoteindices.hh:200
MPI_Comm communicator() const
Get the mpi communicator used.
Definition: remoteindices.hh:1698
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: remoteindices.hh:220
CollectiveIteratorT iterator() const
Get an iterator for colletively iterating over the remote indices of all remote processes.
Definition: remoteindices.hh:1692
void setIncludeSelf(bool includeSelf)
Tell whether sending from indices of the processor to other indices on the same processor is enabled ...
Definition: remoteindices.hh:963
const_iterator end() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1525
std::map< int, std::pair< RemoteIndexList *, RemoteIndexList * > > RemoteIndexMap
The type of the map from rank to remote index list.
Definition: remoteindices.hh:239
RemoteIndexListModifier< T, A, mode > getModifier(int process)
Get a modifier for a remote index list.
Definition: remoteindices.hh:1476
const ParallelIndexSet & sourceIndexSet() const
Get the index set at the source.
Definition: remoteindices.hh:990
~RemoteIndices()
Destructor.
Definition: remoteindices.hh:1005
Dune::SLList< RemoteIndex, Allocator > RemoteIndexList
The type of the remote index list.
Definition: remoteindices.hh:235
int neighbours() const
Get the number of processors we share indices with.
Definition: remoteindices.hh:1442
CollectiveIterator< T, A > CollectiveIteratorT
The type of the collective iterator over all remote indices.
Definition: remoteindices.hh:204
const ParallelIndexSet & destinationIndexSet() const
Get the index set at destination.
Definition: remoteindices.hh:998
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:950
const_iterator find(int proc) const
Find an iterator over the remote index lists of a specific process.
Definition: remoteindices.hh:1511
bool isSynced() const
Checks whether the remote indices are synced with the indexsets.
Definition: remoteindices.hh:1469
const_iterator begin() const
Get an iterator over all remote index lists.
Definition: remoteindices.hh:1518
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: remoteindices.hh:215
A::template rebind< RemoteIndex >::other Allocator
The type of the allocator for the remote index list.
Definition: remoteindices.hh:231
A constant iterator for the SLList.
Definition: sllist.hh:370
A single linked list.
Definition: sllist.hh:43
A few common exception classes.
ArrayList< IndexPair, N >::const_iterator const_iterator
The constant iterator over the pairs.
Definition: indexset.hh:306
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:492
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:239
TG GlobalIndex
the type of the global index. This type has to provide at least a operator< for sorting.
Definition: indexset.hh:226
@ GROUND
The default mode. Indicates that the index set is ready to be used.
Definition: indexset.hh:186
#define dune_static_assert(COND, MSG)
Helper template so that compilation fails if condition is not true.
Definition: static_assert.hh:79
std::ostream & operator<<(std::ostream &s, const array< T, N > &e)
Output operator for array.
Definition: array.hh:159
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:789
SLListConstIterator< RemoteIndex, Allocator > const_iterator
The constant iterator of the list.
Definition: sllist.hh:73
SLListModifyIterator< GlobalIndex, Allocator > ModifyIterator
The type of the iterator capable of deletion and insertion.
Definition: sllist.hh:102
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:777
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
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:231
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:253
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:94
Provides a map between global and local indices.
Dune namespace.
Definition: alignment.hh:14
Traits classes for mapping types onto MPI_Datatype.
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.
Fallback implementation of the C++0x static_assert feature.
Standard Dune debug streams.
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: mpitraits.hh:37
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)