dune-spgrid  2.7
linkage.hh
Go to the documentation of this file.
1 #ifndef DUNE_SPGRID_LINKAGE_HH
2 #define DUNE_SPGRID_LINKAGE_HH
3 
4 #include <vector>
5 
8 
9 namespace Dune
10 {
11 
12  // SPLinkage
13  // ---------
14 
15  template< int dim >
16  class SPLinkage
17  {
18  typedef SPLinkage< dim > This;
19 
20  public:
23 
24  typedef typename PartitionPool::Mesh Mesh;
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 >
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 >
254  {}
255 
256 
257  template< int dim >
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 >
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 >
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 >
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 >
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
Definition: iostream.hh:7
Definition: linkage.hh:17
const Interface & interface(const InterfaceType iftype) const
Definition: linkage.hh:182
SPPartitionList< dim > PartitionList
Definition: linkage.hh:22
PartitionPool::MultiIndex MultiIndex
Definition: linkage.hh:25
SPLinkage(const int localRank, const PartitionPool &localPool, const std::vector< Mesh > &decomposition)
Definition: linkage.hh:155
SPPartitionPool< dim > PartitionPool
Definition: linkage.hh:21
PartitionPool::Mesh Mesh
Definition: linkage.hh:24
Definition: linkage.hh:54
void add(int rank, const PartitionList *sendList, const PartitionList *receiveList)
Definition: linkage.hh:72
NodeContainer::const_iterator Iterator
Definition: linkage.hh:60
~Interface()
Definition: linkage.hh:272
Iterator end() const
Definition: linkage.hh:68
Iterator begin() const
Definition: linkage.hh:67
std::size_t size() const
Definition: linkage.hh:70
Interface()
Definition: linkage.hh:253
Definition: linkage.hh:88
int rank() const
Definition: linkage.hh:296
const PartitionList & receiveList(const CommunicationDirection direction=ForwardCommunication) const
Definition: linkage.hh:314
Node(const int rank, const PartitionList *sendList, const PartitionList *receiveList)
Definition: linkage.hh:287
const PartitionList & sendList(const CommunicationDirection direction=ForwardCommunication) const
Definition: linkage.hh:305
void destroy()
Definition: linkage.hh:323
Definition: linkage.hh:111
Definition: partitionlist.hh:16
Definition: partitionpool.hh:18
const MultiIndex & overlap() const
Definition: partitionpool.hh:42
const Mesh & globalMesh() const
Definition: partitionpool.hh:41
const Topology & topology() const
Definition: partitionpool.hh:43