Dune Core Modules (2.9.0)

linkage.hh
1#ifndef DUNE_SPGRID_LINKAGE_HH
2#define DUNE_SPGRID_LINKAGE_HH
3
4#include <vector>
5
6#include <dune/grid/spgrid/partitionlist.hh>
7#include <dune/grid/spgrid/partitionpool.hh>
8
9namespace Dune
10{
11
12 // SPLinkage
13 // ---------
14
15 template< int dim >
16 class SPLinkage
17 {
18 typedef SPLinkage< dim > This;
19
20 public:
21 typedef SPPartitionPool< dim > PartitionPool;
22 typedef SPPartitionList< dim > PartitionList;
23
24 typedef typename PartitionPool::Mesh Mesh;
25 typedef typename PartitionPool::MultiIndex MultiIndex;
26
27 class Interface;
28
29 SPLinkage ( const int localRank,
30 const PartitionPool &localPool,
31 const std::vector< Mesh > &decomposition );
32
33 const Interface &interface ( const InterfaceType iftype ) const;
34
35 private:
36 template< InterfaceType iftype >
37 bool build ( const int localRank, const PartitionPool &localPool,
38 const int remoteRank, const PartitionPool &remotePool );
39
40 const PartitionList *
41 intersect ( const bool order, const PartitionList &local, const PartitionList &remote ) const;
42
43 // note: We use the knowledge that interfaces are numbered 0, ..., 4.
44 Interface interface_[ 5 ];
45 };
46
47
48
49 // SPLinkage::Interface
50 // --------------------
51
52 template< int dim >
53 class SPLinkage< dim >::Interface
54 {
55 struct Node;
56
57 typedef std::vector< Node > NodeContainer;
58
59 public:
60 typedef typename NodeContainer::const_iterator Iterator;
61
62 Interface ();
63 Interface ( const This &other );
64
65 ~Interface ();
66
67 Iterator begin () const { return nodes_.begin(); }
68 Iterator end () const { return nodes_.end(); }
69
70 std::size_t size () const { return nodes_.size(); }
71
72 void add ( int rank, const PartitionList *sendList, const PartitionList *receiveList )
73 {
74 nodes_.emplace_back( rank, sendList, receiveList );
75 }
76
77 private:
78 NodeContainer nodes_;
79 };
80
81
82
83 // SPLinkage::Interface::Node
84 // --------------------------
85
86 template< int dim >
87 struct SPLinkage< dim >::Interface::Node
88 {
89 static_assert( (int( ForwardCommunication ) == 0) && (int( BackwardCommunication ) == 1),
90 "enumeration CommunicationDirection has changed." );
91
92 Node ( const int rank, const PartitionList *sendList, const PartitionList *receiveList );
93
94 int rank () const;
95 const PartitionList &sendList ( const CommunicationDirection direction = ForwardCommunication ) const;
96 const PartitionList &receiveList ( const CommunicationDirection direction = ForwardCommunication ) const;
97
98 void destroy ();
99
100 private:
101 int rank_;
102 const PartitionList *partitionList_[ 2 ];
103 };
104
105
106
107 // SPCommunicationInterface
108 // ------------------------
109
110 template< InterfaceType iftype >
111 struct SPCommunicationInterface;
112
113 template<>
114 struct SPCommunicationInterface< InteriorBorder_InteriorBorder_Interface >
115 {
116 static const PartitionIteratorType sendPartition = InteriorBorder_Partition;
117 static const PartitionIteratorType receivePartition = InteriorBorder_Partition;
118 };
119
120 template<>
121 struct SPCommunicationInterface< InteriorBorder_All_Interface >
122 {
123 static const PartitionIteratorType sendPartition = InteriorBorder_Partition;
124 static const PartitionIteratorType receivePartition = All_Partition;
125 };
126
127 template<>
128 struct SPCommunicationInterface< Overlap_OverlapFront_Interface >
129 {
130 static const PartitionIteratorType sendPartition = Overlap_Partition;
131 static const PartitionIteratorType receivePartition = OverlapFront_Partition;
132 };
133
134 template<>
135 struct SPCommunicationInterface< Overlap_All_Interface >
136 {
137 static const PartitionIteratorType sendPartition = Overlap_Partition;
138 static const PartitionIteratorType receivePartition = All_Partition;
139 };
140
141 template<>
142 struct SPCommunicationInterface< All_All_Interface >
143 {
144 static const PartitionIteratorType sendPartition = All_Partition;
145 static const PartitionIteratorType receivePartition = All_Partition;
146 };
147
148
149
150 // Implementation of SPLinkage
151 // ---------------------------
152
153 template< int dim >
154 inline SPLinkage< dim >
155 ::SPLinkage ( const int localRank,
156 const PartitionPool &localPool,
157 const std::vector< Mesh > &decomposition )
158 {
159 const int size = decomposition.size();
160
161 const Mesh &globalMesh = localPool.globalMesh();
162 const MultiIndex &overlap = localPool.overlap();
163
164 for( int remoteRank = 0; remoteRank < size; ++remoteRank )
165 {
166 if( remoteRank == localRank )
167 continue;
168 PartitionPool remotePool( decomposition[ remoteRank ], globalMesh, overlap, localPool.topology() );
169 if( build< All_All_Interface >( localRank, localPool, remoteRank, remotePool ) )
170 {
171 build< InteriorBorder_InteriorBorder_Interface >( localRank, localPool, remoteRank, remotePool );
172 build< InteriorBorder_All_Interface >( localRank, localPool, remoteRank, remotePool );
173 build< Overlap_OverlapFront_Interface >( localRank, localPool, remoteRank, remotePool );
174 build< Overlap_All_Interface >( localRank, localPool, remoteRank, remotePool );
175 }
176 }
177 }
178
179
180 template< int dim >
181 inline const typename SPLinkage< dim >::Interface &
182 SPLinkage< dim >::interface ( const InterfaceType iftype ) const
183 {
184 assert( (int( iftype ) >= 0) && (int( iftype ) < 5) );
185 return interface_[ int( iftype ) ];
186 }
187
188
189 template< int dim >
190 template< InterfaceType iftype >
191 inline bool SPLinkage< dim >
192 ::build ( const int localRank, const PartitionPool &localPool,
193 const int remoteRank, const PartitionPool &remotePool )
194 {
195 const PartitionIteratorType piSend = SPCommunicationInterface< iftype >::sendPartition;
196 const PartitionIteratorType piReceive = SPCommunicationInterface< iftype >::receivePartition;
197
198 const bool order = (localRank < remoteRank);
199
200 // build intersection lists
201 const PartitionList *sendList, *receiveList;
202 sendList = intersect( order, localPool.template get< piSend >(), remotePool.template get< piReceive >() );
203 if( piSend != piReceive )
204 receiveList = intersect( order, localPool.template get< piReceive >(), remotePool.template get< piSend >() );
205 else
206 receiveList = sendList;
207
208 // if both lists are empty, no communication is necessary
209 if( sendList->empty() && receiveList->empty() )
210 {
211 if( sendList != receiveList )
212 delete receiveList;
213 delete sendList;
214 return false;
215 }
216
217 assert( (iftype >= 0) && (iftype < 5) );
218 interface_[ iftype ].add( remoteRank, sendList, receiveList );
219 return true;
220 }
221
222
223 template< int dim >
224 inline const typename SPLinkage< dim >::PartitionList *
225 SPLinkage< dim >::intersect ( const bool order, const PartitionList &local, const PartitionList &remote ) const
226 {
227 typedef SPBasicPartition< dim > Intersection;
228 typedef typename PartitionList::Iterator Iterator;
229 typedef typename PartitionList::Partition Partition;
230
231 // order = true <=> pit local iterator, qit remote iterator
232
233 PartitionList *link = new PartitionList;
234 for( Iterator pit = (order ? local.begin() : remote.begin()); pit; ++pit )
235 {
236 for( Iterator qit = (order ? remote.begin() : local.begin()); qit; ++qit )
237 {
238 const int number = (order ? pit->number() : qit->number());
239 Intersection intersection = pit->intersect( *qit );
240 if( !intersection.empty() )
241 *link += Partition( intersection, number );
242 }
243 }
244 return link;
245 }
246
247
248
249 // Implementation of SPLinkage::Interface
250 // --------------------------------------
251
252 template< int dim >
253 inline SPLinkage< dim >::Interface::Interface ()
254 {}
255
256
257 template< int dim >
258 inline SPLinkage< dim >::Interface::Interface ( const This &other )
259 {
260 nodes_.reserve( other.nodes_.size() );
261 const Iterator end = other.end();
262 for( Iterator it = other.begin(); it != end; ++it )
263 {
264 const PartitionList *sendList = new PartitionList( it->sendList() );
265 const PartitionList *receiveList = new PartitionList( it->receiveList() );
266 nodes_->push_back( it->rank(), sendList, receiveList );
267 }
268 }
269
270
271 template< int dim >
272 inline SPLinkage< dim >::Interface::~Interface ()
273 {
274 typedef typename NodeContainer::iterator Iterator;
275 const Iterator end = nodes_.end();
276 for( Iterator it = nodes_.begin(); it != end; ++it )
277 it->destroy();
278 }
279
280
281
282 // Implementation of SPLinkage::Interface
283 // --------------------------------------
284
285 template< int dim >
286 inline SPLinkage< dim >::Interface::Node
287 ::Node ( const int rank, const PartitionList *sendList, const PartitionList *receiveList )
288 : rank_( rank )
289 {
290 partitionList_[ 0 ] = sendList;
291 partitionList_[ 1 ] = receiveList;
292 }
293
294
295 template< int dim >
296 inline int SPLinkage< dim >::Interface::Node::rank () const
297 {
298 assert( rank_ >= 0 );
299 return rank_;
300 }
301
302
303 template< int dim >
304 inline const typename SPLinkage< dim >::PartitionList &
305 SPLinkage< dim >::Interface::Node::sendList ( const CommunicationDirection direction ) const
306 {
307 assert( (int( direction ) >= 0) && (int( direction ) <= 1) );
308 assert( partitionList_[ direction ] != 0 );
309 return *partitionList_[ direction ];
310 }
311
312 template< int dim >
313 inline const typename SPLinkage< dim >::PartitionList &
314 SPLinkage< dim >::Interface::Node::receiveList ( const CommunicationDirection direction ) const
315 {
316 assert( (int( direction ) >= 0) && (int( direction ) <= 1) );
317 assert( partitionList_[ 1 - direction ] != 0 );
318 return *partitionList_[ 1 - direction ];
319 }
320
321
322 template< int dim >
323 inline void SPLinkage< dim >::Interface::Node::destroy ()
324 {
325 rank_ = -1;
326 if( partitionList_[ 0 ] != partitionList_[ 1 ] )
327 delete partitionList_[ 1 ];
328 delete partitionList_[ 0 ];
329 partitionList_[ 0 ] = partitionList_[ 1 ] = 0;
330 }
331
332} // namespace Dune
333
334#endif // #ifndef DUNE_SPGRID_LINKAGE_HH
void add(std::size_t index)
Add a new index to the interface.
Definition: interface.hh:154
PartitionIteratorType
Parameter to be used for the parallel level- and leaf iterators.
Definition: gridenums.hh:136
CommunicationDirection
Define a type for communication direction parameter.
Definition: gridenums.hh:170
InterfaceType
Parameter to be used for the communication functions.
Definition: gridenums.hh:86
@ All_Partition
all entities
Definition: gridenums.hh:141
@ OverlapFront_Partition
interior, border, overlap and front entities
Definition: gridenums.hh:140
@ InteriorBorder_Partition
interior and border entities
Definition: gridenums.hh:138
@ Overlap_Partition
interior, border, and overlap entities
Definition: gridenums.hh:139
@ BackwardCommunication
reverse communication direction
Definition: gridenums.hh:172
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
@ InteriorBorder_All_Interface
send interior and border, receive all entities
Definition: gridenums.hh:88
@ All_All_Interface
send all and receive all entities
Definition: gridenums.hh:91
@ Overlap_All_Interface
send overlap, receive all entities
Definition: gridenums.hh:90
@ Overlap_OverlapFront_Interface
send overlap, receive overlap and front entities
Definition: gridenums.hh:89
@ InteriorBorder_InteriorBorder_Interface
send/receive interior and border entities
Definition: gridenums.hh:87
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)