dune-grid  2.3.1
geometrygrid/iterator.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_GEOGRID_ITERATOR_HH
4 #define DUNE_GEOGRID_ITERATOR_HH
5 
6 #include <dune/geometry/referenceelements.hh>
7 
10 
11 namespace Dune
12 {
13 
14  namespace GeoGrid
15  {
16 
17  // Internal Forward Declarations
18  // -----------------------------
19 
20  template< class Traits, bool fake = Traits::fake >
21  class Iterator;
22 
23  template< class Grid >
24  class HierarchicIterator;
25 
26 
27 
28  // PartitionIteratorFilter
29  // -----------------------
30 
31  template< int codim, PartitionIteratorType pitype, class Grid >
32  struct PartitionIteratorFilter;
33 
34  template< int codim, class Grid >
35  struct PartitionIteratorFilter< codim, Interior_Partition, Grid >
36  {
37  static const int dimension = remove_const< Grid >::type::dimension;
38  static const int codimension = codim;
39 
40  static const PartitionIteratorType Element_Partition = Interior_Partition;
41 
42  typedef typename remove_const< Grid >::type::ctype ctype;
43  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
44  typedef ReferenceElement< ctype, dimension > RefElement;
45 
46  static bool apply ( const RefElement &refElement,
47  const Element &element, int subEntity )
48  {
49  const int size = refElement.size( subEntity, codim, dimension );
50  for( int i = 0; i < size; ++i )
51  {
52  const int j = refElement.subEntity( subEntity, codim, i, dimension );
53  PartitionType type = element.template subEntity< dimension >( j )->partitionType();
54  if( type == InteriorEntity )
55  return true;
56  }
57  return false;
58  }
59  };
60 
61  template< int codim, class Grid >
62  struct PartitionIteratorFilter< codim, InteriorBorder_Partition, Grid >
63  {
64  static const int dimension = remove_const< Grid >::type::dimension;
65  static const int codimension = codim;
66 
67  static const PartitionIteratorType Element_Partition = Interior_Partition;
68 
69  typedef typename remove_const< Grid >::type::ctype ctype;
70  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
71  typedef ReferenceElement< ctype, dimension > RefElement;
72 
73  static bool apply ( const RefElement &refElement,
74  const Element &element, int subEntity )
75  {
76  return true;
77  }
78  };
79 
80  template< int codim, class Grid >
81  struct PartitionIteratorFilter< codim, Overlap_Partition, Grid >
82  {
83  static const int dimension = remove_const< Grid >::type::dimension;
84  static const int codimension = codim;
85 
86  static const PartitionIteratorType Element_Partition = Overlap_Partition;
87 
88  typedef typename remove_const< Grid >::type::ctype ctype;
89  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
90  typedef ReferenceElement< ctype, dimension > RefElement;
91 
92  static bool apply ( const RefElement &refElement,
93  const Element &element, int subEntity )
94  {
95  if( element.partitionType() == InteriorEntity )
96  return true;
97 
98  const int size = refElement.size( subEntity, codim, dimension );
99  for( int i = 0; i < size; ++i )
100  {
101  const int j = refElement.subEntity( subEntity, codim, i, dimension );
102  PartitionType type = element.template subEntity< dimension >( j )->partitionType();
103  if( (type == OverlapEntity) || (type == BorderEntity) )
104  return true;
105  }
106  return false;
107  }
108  };
109 
110  template< int codim, class Grid >
111  struct PartitionIteratorFilter< codim, OverlapFront_Partition, Grid >
112  {
113  static const int dimension = remove_const< Grid >::type::dimension;
114  static const int codimension = codim;
115 
116  static const PartitionIteratorType Element_Partition = Overlap_Partition;
117 
118  typedef typename remove_const< Grid >::type::ctype ctype;
119  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
120  typedef ReferenceElement< ctype, dimension > RefElement;
121 
122  static bool apply ( const RefElement &refElement,
123  const Element &element, int subEntity )
124  {
125  return true;
126  }
127  };
128 
129  template< int codim, class Grid >
130  struct PartitionIteratorFilter< codim, All_Partition, Grid >
131  {
132  static const int dimension = remove_const< Grid >::type::dimension;
133  static const int codimension = codim;
134 
135  static const PartitionIteratorType Element_Partition = All_Partition;
136 
137  typedef typename remove_const< Grid >::type::ctype ctype;
138  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
139  typedef ReferenceElement< ctype, dimension > RefElement;
140 
141  static bool apply ( const RefElement &refElement,
142  const Element &element, int subEntity )
143  {
144  return true;
145  }
146  };
147 
148  template< int codim, class Grid >
149  struct PartitionIteratorFilter< codim, Ghost_Partition, Grid >
150  {
151  static const int dimension = remove_const< Grid >::type::dimension;
152  static const int codimension = codim;
153 
154  static const PartitionIteratorType Element_Partition = Ghost_Partition;
155 
156  typedef typename remove_const< Grid >::type::ctype ctype;
157  typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element;
158  typedef ReferenceElement< ctype, dimension > RefElement;
159 
160  static bool apply ( const RefElement &refElement,
161  const Element &element, int subEntity )
162  {
163  const int size = refElement.size( subEntity, codim, dimension );
164  for( int i = 0; i < size; ++i )
165  {
166  const int j = refElement.subEntity( subEntity, codim, i, dimension );
167  PartitionType type = element.template subEntity< dimension >( j )->partitionType();
168  if( type == GhostEntity )
169  return true;
170  }
171  return false;
172  }
173  };
174 
175 
176 
177  // IteratorTraits
178  // --------------
179 
180  template< class HostGridView, int codim, PartitionIteratorType pitype, class Grid >
182  : public EntityPointerTraits< codim, Grid >
183  {
184  typedef typename EntityPointerTraits< codim, Grid >::HostGrid HostGrid;
185 
186  typedef PartitionIteratorFilter< codim, pitype, HostGrid > Filter;
187 
190 
191  typedef typename HostGridView::template Codim< codim >
192  ::template Partition< Entity_Partition >::Iterator
194  typedef typename HostGridView::template Codim< 0 >
195  ::template Partition< Element_Partition >::Iterator
197 
198  typedef typename HostGridView::IndexSet HostIndexSet;
199 
200  enum IteratorType { begin, end };
201  };
202 
203 
204 
205  // Iterator (real)
206  // ---------------
207 
208  template< class Traits >
209  class Iterator< Traits, false >
210  : public EntityPointer< Traits, false >
211  {
213 
214  typedef typename Traits::Grid Grid;
215 
216  public:
217  typedef typename Traits::IteratorType IteratorType;
218 
219  using Base::codimension;
220 
221  protected:
222  typedef typename Base::EntityImpl EntityImpl;
223 
224  using Base::hostEntityIterator_;
225  using Base::entityImpl;
226  using Base::grid;
227 
228  public:
229  template< class HostGridView >
230  Iterator ( const Grid &grid, const HostGridView &hostGridView, IteratorType type )
231  : Base( grid, (type == Traits::begin ? hostGridView.template begin< codimension, Traits::Entity_Partition >()
232  : hostGridView.template end< codimension, Traits::Entity_Partition >()) )
233  {}
234 
235  void increment ()
236  {
237  ++hostEntityIterator_;
238  entityImpl() = EntityImpl( grid() );
239  }
240  };
241 
242 
243 
244  // Iterator (fake)
245  // ---------------
246 
247  template< class Traits >
248  class Iterator< Traits, true >
249  : public EntityPointer< Traits, true >
250  {
252 
253  typedef typename Traits::Grid Grid;
254 
255  public:
256  static const int dimension = Traits::dimension;
257  static const int codimension = Traits::codimension;
258 
259  typedef typename Traits::IteratorType IteratorType;
260 
261  private:
262  typedef typename Traits::Filter Filter;
263 
264  typedef typename Traits::HostElement HostElement;
265  typedef typename Traits::HostElementIterator HostElementIterator;
266  typedef typename Traits::HostIndexSet HostIndexSet;
267 
268  protected:
269  typedef typename Base::EntityImpl EntityImpl;
270 
271  using Base::hostElementIterator_;
272  using Base::entityImpl;
273  using Base::grid;
274 
275  public:
276  template< class HostGridView >
277  Iterator ( const Grid &grid, const HostGridView &hostGridView, IteratorType type )
278  : Base( grid, (type == Traits::begin ? hostGridView.template begin< 0, Traits::Element_Partition >()
279  : hostGridView.template end< 0, Traits::Element_Partition >()), -1 ),
280  hostEnd_( hostGridView.template end< 0, Traits::Element_Partition >() ),
281  hostIndexSet_( &hostGridView.indexSet() )
282  {
283  if( hostElementIterator_ != hostEnd_ )
284  {
285  visited_.resize( hostIndexSet_->size( codimension ), false );
286  increment();
287  }
288  }
289 
290  void increment ()
291  {
292  typedef typename Traits::ctype ctype;
293 
294  int subEntity = this->subEntity();
295  while( hostElementIterator_ != hostEnd_ )
296  {
297  const HostElement &hostElement = *hostElementIterator_;
298 
299  const ReferenceElement< ctype, dimension > &refElement
300  = ReferenceElements< ctype, dimension >::general( hostElement.type() );
301 
302  ++subEntity;
303  const int count = refElement.size( codimension );
304  for( ; subEntity < count; ++subEntity )
305  {
306  if( !Filter::apply( refElement, hostElement, subEntity ) )
307  continue;
308 
309  const size_t index = hostIndexSet_->subIndex( hostElement, subEntity, codimension );
310  if( !visited_[ index ] )
311  {
312  visited_[ index ] = true;
313  entityImpl() = EntityImpl( grid(), subEntity );
314  return;
315  }
316  }
317  ++hostElementIterator_;
318  subEntity = -1;
319  }
320  entityImpl() = EntityImpl( grid(), subEntity );
321  }
322 
323  private:
324  HostElementIterator hostEnd_;
325  const HostIndexSet *hostIndexSet_;
326  std::vector< bool > visited_;
327  };
328 
329 
330 
331  // HierarchicIteratorTraits
332  // ------------------------
333 
334  template< class Grid >
336  : public EntityPointerTraits< 0, Grid >
337  {
338  typedef typename remove_const< Grid >::type::Traits Traits;
339 
340  typedef typename Traits::HostGrid::Traits::HierarchicIterator HostEntityIterator;
341  typedef typename Traits::HostGrid::Traits::HierarchicIterator HostElementIterator;
342  };
343 
344 
345 
346  // HierarchicIterator
347  // ------------------
348 
349  template< class Grid >
351  : public EntityPointer< HierarchicIteratorTraits< Grid > >
352  {
354 
356 
357  protected:
358  typedef typename Base::EntityImpl EntityImpl;
360 
361  using Base::hostEntityIterator_;
362  using Base::entityImpl;
363  using Base::grid;
364 
365  public:
366  HierarchicIterator ( const Grid &grid,
367  const HostEntityIterator &hostEntityIterator )
368  : Base( grid, hostEntityIterator )
369  {}
370 
371  void increment ()
372  {
373  ++hostEntityIterator_;
374  entityImpl() = EntityImpl( grid() );
375  }
376  };
377 
378  } // namespace GeoGrid
379 
380 } // namespace Dune
381 
382 #endif // #ifndef DUNE_GEOGRID_ITERATOR_HH