dune-grid  2.2.0
geometrygrid/iterator.hh
Go to the documentation of this file.
1 #ifndef DUNE_GEOGRID_ITERATOR_HH
2 #define DUNE_GEOGRID_ITERATOR_HH
3 
4 #include <dune/geometry/referenceelements.hh>
5 
8 
9 namespace Dune
10 {
11 
12  namespace GeoGrid
13  {
14 
15  // Internal Forward Declarations
16  // -----------------------------
17 
18  template< class Traits, bool fake = Traits::fake >
19  class Iterator;
20 
21  template< class Grid >
22  class HierarchicIterator;
23 
24 
25 
26  // PartitionIteratorFilter
27  // -----------------------
28 
29  template< int codim, PartitionIteratorType pitype, class Grid >
30  struct PartitionIteratorFilter;
31 
32  template< int codim, class Grid >
33  struct PartitionIteratorFilter< codim, Interior_Partition, Grid >
34  {
35  static const int dimension = remove_const< Grid >::type::dimension;
36  static const int codimension = codim;
37 
38  static const PartitionIteratorType Element_Partition = Interior_Partition;
39 
40  typedef typename remove_const< Grid >::type::ctype ctype;
41  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
42  typedef GenericReferenceElement< ctype, dimension > ReferenceElement;
43 
44  static bool apply ( const ReferenceElement &refElement,
45  const Element &element, int subEntity )
46  {
47  const int size = refElement.size( subEntity, codim, dimension );
48  for( int i = 0; i < size; ++i )
49  {
50  const int j = refElement.subEntity( subEntity, codim, i, dimension );
51  PartitionType type = element.template subEntity< dimension >( j )->partitionType();
52  if( type == InteriorEntity )
53  return true;
54  }
55  return false;
56  }
57  };
58 
59  template< int codim, class Grid >
60  struct PartitionIteratorFilter< codim, InteriorBorder_Partition, Grid >
61  {
62  static const int dimension = remove_const< Grid >::type::dimension;
63  static const int codimension = codim;
64 
65  static const PartitionIteratorType Element_Partition = Interior_Partition;
66 
67  typedef typename remove_const< Grid >::type::ctype ctype;
68  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
69  typedef GenericReferenceElement< ctype, dimension > ReferenceElement;
70 
71  static bool apply ( const ReferenceElement &refElement,
72  const Element &element, int subEntity )
73  {
74  return true;
75  }
76  };
77 
78  template< int codim, class Grid >
79  struct PartitionIteratorFilter< codim, Overlap_Partition, Grid >
80  {
81  static const int dimension = remove_const< Grid >::type::dimension;
82  static const int codimension = codim;
83 
84  static const PartitionIteratorType Element_Partition = Overlap_Partition;
85 
86  typedef typename remove_const< Grid >::type::ctype ctype;
87  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
88  typedef GenericReferenceElement< ctype, dimension > ReferenceElement;
89 
90  static bool apply ( const ReferenceElement &refElement,
91  const Element &element, int subEntity )
92  {
93  if( element.partitionType() == InteriorEntity )
94  return true;
95 
96  const int size = refElement.size( subEntity, codim, dimension );
97  for( int i = 0; i < size; ++i )
98  {
99  const int j = refElement.subEntity( subEntity, codim, i, dimension );
100  PartitionType type = element.template subEntity< dimension >( j )->partitionType();
101  if( (type == OverlapEntity) || (type == BorderEntity) )
102  return true;
103  }
104  return false;
105  }
106  };
107 
108  template< int codim, class Grid >
109  struct PartitionIteratorFilter< codim, OverlapFront_Partition, Grid >
110  {
111  static const int dimension = remove_const< Grid >::type::dimension;
112  static const int codimension = codim;
113 
114  static const PartitionIteratorType Element_Partition = Overlap_Partition;
115 
116  typedef typename remove_const< Grid >::type::ctype ctype;
117  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
118  typedef GenericReferenceElement< ctype, dimension > ReferenceElement;
119 
120  static bool apply ( const ReferenceElement &refElement,
121  const Element &element, int subEntity )
122  {
123  return true;
124  }
125  };
126 
127  template< int codim, class Grid >
128  struct PartitionIteratorFilter< codim, All_Partition, Grid >
129  {
130  static const int dimension = remove_const< Grid >::type::dimension;
131  static const int codimension = codim;
132 
133  static const PartitionIteratorType Element_Partition = All_Partition;
134 
135  typedef typename remove_const< Grid >::type::ctype ctype;
136  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
137  typedef GenericReferenceElement< ctype, dimension > ReferenceElement;
138 
139  static bool apply ( const ReferenceElement &refElement,
140  const Element &element, int subEntity )
141  {
142  return true;
143  }
144  };
145 
146  template< int codim, class Grid >
147  struct PartitionIteratorFilter< codim, Ghost_Partition, Grid >
148  {
149  static const int dimension = remove_const< Grid >::type::dimension;
150  static const int codimension = codim;
151 
152  static const PartitionIteratorType Element_Partition = Ghost_Partition;
153 
154  typedef typename remove_const< Grid >::type::ctype ctype;
155  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
156  typedef GenericReferenceElement< ctype, dimension > ReferenceElement;
157 
158  static bool apply ( const ReferenceElement &refElement,
159  const Element &element, int subEntity )
160  {
161  const int size = refElement.size( subEntity, codim, dimension );
162  for( int i = 0; i < size; ++i )
163  {
164  const int j = refElement.subEntity( subEntity, codim, i, dimension );
165  PartitionType type = element.template subEntity< dimension >( j )->partitionType();
166  if( type == GhostEntity )
167  return true;
168  }
169  return false;
170  }
171  };
172 
173 
174 
175  // Iterator (real)
176  // ---------------
177 
178  template< class Traits >
179  class Iterator< Traits, false >
180  : public EntityPointer< Traits, false >
181  {
183 
184  typedef typename Traits::Grid Grid;
185 
186  public:
187  typedef typename Traits::IteratorType IteratorType;
188 
189  protected:
190  typedef typename Base::EntityImpl EntityImpl;
191 
192  using Base::hostEntityIterator_;
193  using Base::entityImpl;
194  using Base::grid;
195 
196  public:
197  Iterator ( const Grid &grid, int level, IteratorType type )
198  : Base( grid, Traits::getHostEntityIterator( grid.hostGrid(), level, type ) )
199  {}
200 
201  void increment ()
202  {
203  ++hostEntityIterator_;
204  entityImpl() = EntityImpl( grid() );
205  }
206  };
207 
208 
209 
210  // Iterator (fake)
211  // ---------------
212 
213  template< class Traits >
214  class Iterator< Traits, true >
215  : public EntityPointer< Traits, true >
216  {
218 
219  typedef typename Traits::Grid Grid;
220 
221  public:
222  static const int dimension = Traits::dimension;
223  static const int codimension = Traits::codimension;
224 
225  typedef typename Traits::IteratorType IteratorType;
226 
227  private:
228  typedef typename Traits::Filter Filter;
229 
230  typedef typename Traits::HostElement HostElement;
231  typedef typename Traits::HostElementIterator HostElementIterator;
232  typedef typename Traits::HostIndexSet HostIndexSet;
233 
234  protected:
235  typedef typename Base::EntityImpl EntityImpl;
236 
237  using Base::hostElementIterator_;
238  using Base::entityImpl;
239  using Base::grid;
240 
241  public:
242  Iterator ( const Grid &grid, int level, IteratorType type )
243  : Base( grid, Traits::getHostElementIterator( grid.hostGrid(), level, type ), -1 ),
244  hostEnd_( Traits::getHostElementIterator( grid.hostGrid(), level, Traits::end ) ),
245  hostIndexSet_( &Traits::getHostIndexSet( grid.hostGrid(), level ) )
246  {
247  if( hostElementIterator_ != hostEnd_ )
248  {
249  visited_.resize( hostIndexSet_->size( codimension ), false );
250  increment();
251  }
252  }
253 
254  void increment ()
255  {
256  typedef typename Traits::ctype ctype;
257 
258  int subEntity = this->subEntity();
259  while( hostElementIterator_ != hostEnd_ )
260  {
261  const HostElement &hostElement = *hostElementIterator_;
262 
263  const GenericReferenceElement< ctype, dimension > &refElement
264  = GenericReferenceElements< ctype, dimension >::general( hostElement.type() );
265 
266  ++subEntity;
267  const int count = refElement.size( codimension );
268  for( ; subEntity < count; ++subEntity )
269  {
270  if( !Filter::apply( refElement, hostElement, subEntity ) )
271  continue;
272 
273  const size_t index = hostIndexSet_->subIndex( hostElement, subEntity, codimension );
274  if( !visited_[ index ] )
275  {
276  visited_[ index ] = true;
277  entityImpl() = EntityImpl( grid(), subEntity );
278  return;
279  }
280  }
281  ++hostElementIterator_;
282  subEntity = -1;
283  }
284  entityImpl() = EntityImpl( grid(), subEntity );
285  }
286 
287  private:
288  HostElementIterator hostEnd_;
289  const HostIndexSet *hostIndexSet_;
290  std::vector< bool > visited_;
291  };
292 
293 
294 
295  // LeafIteratorTraits
296  // ------------------
297 
298  template< int codim, PartitionIteratorType pitype, class Grid >
300  : public EntityPointerTraits< codim, Grid >
301  {
302  typedef typename EntityPointerTraits< codim, Grid >::HostGrid HostGrid;
303 
304  typedef PartitionIteratorFilter< codim, pitype, HostGrid > Filter;
305 
308 
309  typedef typename HostGrid::template Codim< codim >
310  ::template Partition< Entity_Partition >::LeafIterator
312  typedef typename HostGrid::template Codim< 0 >
313  ::template Partition< Element_Partition >::LeafIterator
315 
316  typedef typename HostGrid::LeafIndexSet HostIndexSet;
317 
318  enum IteratorType { begin, end };
319 
320  static HostEntityIterator
321  getHostEntityIterator ( const HostGrid &hostGrid, int level, IteratorType type )
322  {
323  if( type == begin )
324  return hostGrid.template leafbegin< codim, Entity_Partition >();
325  else
326  return hostGrid.template leafend< codim, Entity_Partition >();
327  }
328 
329  static HostElementIterator
330  getHostElementIterator ( const HostGrid &hostGrid, int level, IteratorType type )
331  {
332  if( type == begin )
333  return hostGrid.template leafbegin< 0, Element_Partition >();
334  else
335  return hostGrid.template leafend< 0, Element_Partition >();
336  }
337 
338  static const HostIndexSet &getHostIndexSet ( const HostGrid &hostGrid, int level )
339  {
340  return hostGrid.leafIndexSet();
341  }
342  };
343 
344 
345 
346  // LevelIteratorTraits
347  // -------------------
348 
349  template< int codim, PartitionIteratorType pitype, class Grid >
351  : public EntityPointerTraits< codim, Grid >
352  {
353  typedef typename EntityPointerTraits< codim, Grid >::HostGrid HostGrid;
354 
355  typedef PartitionIteratorFilter< codim, pitype, HostGrid > Filter;
356 
359 
360  typedef typename HostGrid::template Codim< codim >
361  ::template Partition< Entity_Partition >::LevelIterator
363  typedef typename HostGrid::template Codim< 0 >
364  ::template Partition< Element_Partition >::LevelIterator
366 
367  typedef typename HostGrid::LevelIndexSet HostIndexSet;
368 
369  enum IteratorType { begin, end };
370 
371  static HostEntityIterator
372  getHostEntityIterator ( const HostGrid &hostGrid, int level, IteratorType type )
373  {
374  if( type == begin )
375  return hostGrid.template lbegin< codim, Entity_Partition >( level );
376  else
377  return hostGrid.template lend< codim, Entity_Partition >( level );
378  }
379 
380  static HostElementIterator
381  getHostElementIterator ( const HostGrid &hostGrid, int level, IteratorType type )
382  {
383  if( type == begin )
384  return hostGrid.template lbegin< 0, Element_Partition >( level );
385  else
386  return hostGrid.template lend< 0, Element_Partition >( level );
387  }
388 
389  static const HostIndexSet &getHostIndexSet ( const HostGrid &hostGrid, int level )
390  {
391  return hostGrid.levelIndexSet( level );
392  }
393  };
394 
395 
396 
397  // HierarchicIteratorTraits
398  // ------------------------
399 
400  template< class Grid >
402  : public EntityPointerTraits< 0, Grid >
403  {
404  typedef typename remove_const< Grid >::type::Traits Traits;
405 
406  typedef typename Traits::HostGrid::Traits::HierarchicIterator HostEntityIterator;
407  typedef typename Traits::HostGrid::Traits::HierarchicIterator HostElementIterator;
408  };
409 
410 
411 
412  // HierarchicIterator
413  // ------------------
414 
415  template< class Grid >
417  : public EntityPointer< HierarchicIteratorTraits< Grid > >
418  {
420 
422 
423  protected:
424  typedef typename Base::EntityImpl EntityImpl;
426 
427  using Base::hostEntityIterator_;
428  using Base::entityImpl;
429  using Base::grid;
430 
431  public:
432  HierarchicIterator ( const Grid &grid,
433  const HostEntityIterator &hostEntityIterator )
434  : Base( grid, hostEntityIterator )
435  {}
436 
437  void increment ()
438  {
439  ++hostEntityIterator_;
440  entityImpl() = EntityImpl( grid() );
441  }
442  };
443 
444  } // namespace GeoGrid
445 
446 } // namespace Dune
447 
448 #endif // #ifndef DUNE_GEOGRID_ITERATOR_HH