Dune Core Modules (2.4.2)

treeiterator.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_ALBERTA_TREEITERATOR_HH
5 #define DUNE_ALBERTA_TREEITERATOR_HH
6 
8 
10 #include <dune/grid/albertagrid/entitypointer.hh>
11 
12 #if HAVE_ALBERTA
13 
14 namespace Dune
15 {
16 
17  // AlbertaMarkerVector
18  // -------------------
19 
28  template< int dim, int dimworld >
30  {
32 
34 
35  //friend class AlbertaGrid< dim, dimworld >;
36 
37  static const int dimension = Grid::dimension;
38 
39  typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering;
40  typedef Alberta::ElementInfo< dimension > ElementInfo;
41 
42  template< bool >
43  struct NoMarkSubEntities;
44  template< bool >
45  struct MarkSubEntities;
46 
47  public:
49  explicit AlbertaMarkerVector ( const DofNumbering &dofNumbering )
50  : dofNumbering_( dofNumbering )
51  {
52  for( int codim = 0; codim <= dimension; ++codim )
53  marker_[ codim ] = 0;
54  }
55 
56  AlbertaMarkerVector ( const This &other )
57  : dofNumbering_( other.dofNumbering_ )
58  {
59  for( int codim = 0; codim <= dimension; ++codim )
60  marker_[ codim ] = 0;
61  }
62 
64  {
65  clear();
66  }
67 
68  private:
69  This &operator= ( const This & );
70 
71  public:
73  template< int codim >
74  bool subEntityOnElement ( const ElementInfo &elementInfo, int subEntity ) const;
75 
76  template< int firstCodim, class Iterator >
77  void markSubEntities ( const Iterator &begin, const Iterator &end );
78 
79  void clear ()
80  {
81  for( int codim = 0; codim <= dimension; ++codim )
82  {
83  if( marker_[ codim ] != 0 )
84  delete[] marker_[ codim ];
85  marker_[ codim ] = 0;
86  }
87  }
88 
90  bool up2Date () const
91  {
92  return (marker_[ dimension ] != 0);
93  }
94 
96  void print ( std::ostream &out = std::cout ) const;
97 
98  private:
99  const DofNumbering &dofNumbering_;
100  int *marker_[ dimension+1 ];
101  };
102 
103 
104 
105  // AlbertaMarkerVector::NoMarkSubEntities
106  // --------------------------------------
107 
108  template< int dim, int dimworld >
109  template< bool >
110  struct AlbertaMarkerVector< dim, dimworld >::NoMarkSubEntities
111  {
112  template< int firstCodim, class Iterator >
113  static void mark ( const DofNumbering &dofNumbering, int *(&marker)[ dimension + 1 ],
114  const Iterator &begin, const Iterator &end )
115  {}
116  };
117 
118 
119 
120  // AlbertaMarkerVector::MarkSubEntities
121  // ------------------------------------
122 
123  template< int dim, int dimworld >
124  template< bool >
125  struct AlbertaMarkerVector< dim, dimworld >::MarkSubEntities
126  {
127  template< int codim >
128  struct Codim
129  {
130  static const int numSubEntities = Alberta::NumSubEntities< dimension, codim >::value;
131 
132  typedef Alberta::ElementInfo< dimension > ElementInfo;
133 
134  static void apply ( const DofNumbering &dofNumbering,
135  int *(&marker)[ dimension + 1 ],
136  const ElementInfo &elementInfo )
137  {
138  int *array = marker[ codim ];
139 
140  const int index = dofNumbering( elementInfo, 0, 0 );
141  for( int i = 0; i < numSubEntities; ++i )
142  {
143  int &mark = array[ dofNumbering( elementInfo, codim, i ) ];
144  mark = std::max( index, mark );
145  }
146  }
147  };
148 
149  template< int firstCodim, class Iterator >
150  static void mark ( const DofNumbering &dofNumbering, int *(&marker)[ dimension + 1 ],
151  const Iterator &begin, const Iterator &end )
152  {
153  for( int codim = firstCodim; codim <= dimension; ++codim )
154  {
155  const int size = dofNumbering.size( codim );
156  marker[ codim ] = new int[ size ];
157 
158  int *array = marker[ codim ];
159  for( int i = 0; i < size; ++i )
160  array[ i ] = -1;
161  }
162 
163  for( Iterator it = begin; it != end; ++it )
164  {
165  const ElementInfo &elementInfo = Grid::getRealImplementation( *it ).elementInfo();
166  ForLoop< Codim, firstCodim, dimension >::apply( dofNumbering, marker, elementInfo );
167  }
168  }
169  };
170 
171 
172 
173  // AlbertaGridTreeIterator
174  // -----------------------
175 
179  template< int codim, class GridImp, bool leafIterator >
181  : public AlbertaGridEntityPointer< codim, GridImp >
182  {
185 
186  public:
187  static const int dimension = GridImp::dimension;
188  static const int codimension = codim;
189  static const int dimensionworld = GridImp::dimensionworld;
190 
191  private:
192  friend class AlbertaGrid< dimension, dimensionworld >;
193 
194  static const int numSubEntities
195  = Alberta::NumSubEntities< dimension, codimension >::value;
196 
197  public:
198  typedef typename Base::ElementInfo ElementInfo;
199  typedef Alberta::MeshPointer< dimension > MeshPointer;
200  typedef typename MeshPointer::MacroIterator MacroIterator;
201 
202  typedef typename GridImp::template Codim< codim >::Entity Entity;
204  typedef typename EntityObject::ImplementationType EntityImp;
205 
207 
209 
211  AlbertaGridTreeIterator ( const This &other );
212 
214  This &operator= ( const This &other );
215 
217  AlbertaGridTreeIterator ( const GridImp &grid, int travLevel );
218 
220  AlbertaGridTreeIterator ( const GridImp &grid,
221  const MarkerVector *marker,
222  int travLevel );
223 
225  void increment();
226 
227  protected:
228  using Base::entityImp;
229  using Base::grid;
230 
231  private:
232  void nextElement ( ElementInfo &elementInfo );
233  void nextElementStop (ElementInfo &elementInfo );
234  bool stopAtElement ( const ElementInfo &elementInfo ) const;
235 
236  void goNext ( ElementInfo &elementInfo );
237  void goNext ( const integral_constant< int, 0 > cdVariable,
238  ElementInfo &elementInfo );
239  void goNext ( const integral_constant< int, 1 > cdVariable,
240  ElementInfo &elementInfo );
241  template< int cd >
242  void goNext ( const integral_constant< int, cd > cdVariable,
243  ElementInfo &elementInfo );
244 
246  int level_;
247 
249  int subEntity_;
250 
251  MacroIterator macroIterator_;
252 
253  // knows on which element a point,edge,face is viewed
254  const MarkerVector *marker_;
255  };
256 
257 
258 
259  // Implementation of AlbertaMarkerVector
260  // -------------------------------------
261 
262  template< int dim, int dimworld >
263  template< int codim >
265  ::subEntityOnElement ( const ElementInfo &elementInfo, int subEntity ) const
266  {
267  assert( marker_[ codim ] != 0 );
268 
269  const int subIndex = dofNumbering_( elementInfo, codim, subEntity );
270  const int markIndex = marker_[ codim ][ subIndex ];
271  assert( (markIndex >= 0) );
272 
273  const int index = dofNumbering_( elementInfo, 0, 0 );
274  return (markIndex == index);
275  }
276 
277 
278  template< int dim, int dimworld >
279  template< int firstCodim, class Iterator >
281  ::markSubEntities ( const Iterator &begin, const Iterator &end )
282  {
283  clear();
284  conditional< (firstCodim <= dimension), MarkSubEntities<true>, NoMarkSubEntities<false> >::type
285  ::template mark< firstCodim, Iterator >( dofNumbering_, marker_, begin, end );
286  }
287 
288 
289  template< int dim, int dimworld >
290  inline void AlbertaMarkerVector< dim, dimworld >::print ( std::ostream &out ) const
291  {
292  for( int codim = 1; codim <= dimension; ++codim )
293  {
294  int *marker = marker_[ codim ];
295  if( marker != 0 )
296  {
297  const int size = dofNumbering_.size( codim );
298  out << std::endl;
299  out << "Codimension " << codim << " (" << size << " entries)" << std::endl;
300  for( int i = 0; i < size; ++i )
301  out << "subentity " << i << " visited on Element " << marker[ i ] << std::endl;
302  }
303  }
304  }
305 
306 
307 
308  // Implementation of AlbertaGridTreeIterator
309  // -----------------------------------------
310 
311  template< int codim, class GridImp, bool leafIterator >
314  : Base(),
315  level_( -1 ),
316  subEntity_( -1 ),
317  macroIterator_(),
318  marker_( NULL )
319  {}
320 
321  template< int codim, class GridImp, bool leafIterator >
322  inline AlbertaGridTreeIterator< codim, GridImp, leafIterator >
323  ::AlbertaGridTreeIterator ( const GridImp &grid,
324  const MarkerVector *marker,
325  int travLevel )
326  : Base( grid ),
327  level_( travLevel ),
328  subEntity_( (codim == 0 ? 0 : -1) ),
329  macroIterator_( grid.meshPointer().begin() ),
330  marker_( marker )
331  {
332  ElementInfo elementInfo = *macroIterator_;
333  nextElementStop( elementInfo );
334  if( codim > 0 )
335  goNext( elementInfo );
336  // it is ok to set the invalid ElementInfo
337  entityImp().setElement( elementInfo, subEntity_ );
338  }
339 
340 
341  // Make LevelIterator with point to element from previous iterations
342  template< int codim, class GridImp, bool leafIterator >
344  ::AlbertaGridTreeIterator ( const GridImp &grid,
345  int travLevel )
346  : Base( grid ),
347  level_( travLevel ),
348  subEntity_( -1 ),
349  macroIterator_( grid.meshPointer().end() ),
350  marker_( 0 )
351  {}
352 
353 
354  // Make LevelIterator with point to element from previous iterations
355  template< int codim, class GridImp, bool leafIterator >
358  : Base( other ),
359  level_( other.level_ ),
360  subEntity_( other.subEntity_ ),
361  macroIterator_( other.macroIterator_ ),
362  marker_( other.marker_ )
363  {}
364 
365 
366  // Make LevelIterator with point to element from previous iterations
367  template< int codim, class GridImp, bool leafIterator >
370  {
371  Base::operator=( other );
372 
373  level_ = other.level_;
374  subEntity_ = other.subEntity_;
375  macroIterator_ = other.macroIterator_;
376  marker_ = other.marker_;
377 
378  return *this;
379  }
380 
381 
382  template< int codim, class GridImp, bool leafIterator >
384  {
385  ElementInfo elementInfo = entityImp().elementInfo_;
386  goNext ( elementInfo );
387  // it is ok to set the invalid ElementInfo
388  entityImp().setElement( elementInfo, subEntity_ );
389  }
390 
391 
392  template< int codim, class GridImp, bool leafIterator >
394  ::nextElement ( ElementInfo &elementInfo )
395  {
396  if( elementInfo.isLeaf() || (elementInfo.level() >= level_) )
397  {
398  while( (elementInfo.level() > 0) && (elementInfo.indexInFather() == 1) )
399  elementInfo = elementInfo.father();
400  if( elementInfo.level() == 0 )
401  {
402  ++macroIterator_;
403  elementInfo = *macroIterator_;
404  }
405  else
406  elementInfo = elementInfo.father().child( 1 );
407  }
408  else
409  elementInfo = elementInfo.child( 0 );
410  }
411 
412 
413  template< int codim, class GridImp, bool leafIterator >
414  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
415  ::nextElementStop ( ElementInfo &elementInfo )
416  {
417  while( !(!elementInfo || stopAtElement( elementInfo )) )
418  nextElement( elementInfo );
419  }
420 
421 
422  template< int codim, class GridImp, bool leafIterator >
423  inline bool AlbertaGridTreeIterator< codim, GridImp, leafIterator >
424  ::stopAtElement ( const ElementInfo &elementInfo ) const
425  {
426  if( !elementInfo )
427  return true;
428  return (leafIterator ? elementInfo.isLeaf() : (level_ == elementInfo.level()));
429  }
430 
431 
432  template< int codim, class GridImp, bool leafIterator >
433  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
434  ::goNext ( ElementInfo &elementInfo )
435  {
436  integral_constant< int, codim > codimVariable;
437  goNext( codimVariable, elementInfo );
438  }
439 
440  template< int codim, class GridImp, bool leafIterator >
441  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
442  ::goNext ( const integral_constant< int, 0 > cdVariable,
443  ElementInfo &elementInfo )
444  {
445  assert( stopAtElement( elementInfo ) );
446 
447  nextElement( elementInfo );
448  nextElementStop( elementInfo );
449  }
450 
451  template< int codim, class GridImp, bool leafIterator >
452  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
453  ::goNext ( const integral_constant< int, 1 > cdVariable,
454  ElementInfo &elementInfo )
455  {
456  assert( stopAtElement( elementInfo ) );
457 
458  ++subEntity_;
459  if( subEntity_ >= numSubEntities )
460  {
461  subEntity_ = 0;
462  nextElement( elementInfo );
463  nextElementStop( elementInfo );
464  if( !elementInfo )
465  return;
466  }
467 
468  if( leafIterator )
469  {
470  const int face = (dimension == 1 ? (numSubEntities-1)-subEntity_ : subEntity_);
471 
472  const ALBERTA EL *neighbor = elementInfo.elInfo().neigh[ face ];
473  if( (neighbor != NULL) && !elementInfo.isBoundary( face ) )
474  {
475  // face is reached from element with largest number
476  const int elIndex = grid().dofNumbering() ( elementInfo, 0, 0 );
477  const int nbIndex = grid().dofNumbering() ( neighbor, 0, 0 );
478  if( elIndex < nbIndex )
479  goNext( cdVariable, elementInfo );
480  }
481  // uncomment this assertion only if codimension 1 entities are marked
482  // assert( marker_->template subEntityOnElement< 1 >( elementInfo, subEntity_ ) );
483  }
484  else
485  {
486  assert( marker_ != 0 );
487  if( !marker_->template subEntityOnElement< 1 >( elementInfo, subEntity_ ) )
488  goNext( cdVariable, elementInfo );
489  }
490  }
491 
492  template< int codim, class GridImp, bool leafIterator >
493  template< int cd >
494  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
495  ::goNext ( const integral_constant< int, cd > cdVariable,
496  ElementInfo &elementInfo )
497  {
498  assert( stopAtElement( elementInfo ) );
499 
500  ++subEntity_;
501  if( subEntity_ >= numSubEntities )
502  {
503  subEntity_ = 0;
504  nextElement( elementInfo );
505  nextElementStop( elementInfo );
506  if( !elementInfo )
507  return;
508  }
509 
510  assert( marker_ != 0 );
511  if( !marker_->template subEntityOnElement< cd >( elementInfo, subEntity_ ) )
512  goNext( cdVariable, elementInfo );
513  }
514 
515 }
516 
517 #endif // #if HAVE_ALBERTA
518 
519 #endif // #ifndef DUNE_ALBERTA_TREEITERATOR_HH
EntityPointer implementation for AlbertaGrid.
Definition: entitypointer.hh:19
const GridImp & grid() const
obtain a reference to the grid
Definition: entitypointer.hh:170
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition: entitypointer.hh:155
Definition: treeiterator.hh:182
AlbertaGridTreeIterator(const GridImp &grid, const MarkerVector *marker, int travLevel)
Constructor making begin iterator.
Definition: treeiterator.hh:323
AlbertaGridTreeIterator(const GridImp &grid, int travLevel)
Constructor making end iterator.
Definition: treeiterator.hh:344
This & operator=(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:369
const GridImp & grid() const
obtain a reference to the grid
Definition: entitypointer.hh:170
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition: entitypointer.hh:155
void increment()
increment
Definition: treeiterator.hh:383
AlbertaGridTreeIterator(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:357
[ provides Dune::Grid ]
Definition: agrid.hh:140
marker assigning subentities to one element containing them
Definition: treeiterator.hh:30
AlbertaMarkerVector(const DofNumbering &dofNumbering)
create AlbertaMarkerVector with empty vectors
Definition: treeiterator.hh:49
bool up2Date() const
return true if marking is up to date
Definition: treeiterator.hh:90
bool subEntityOnElement(const ElementInfo &elementInfo, int subEntity) const
visit subentity on this element?
Definition: treeiterator.hh:265
void print(std::ostream &out=std::cout) const
print for debugin' only
Definition: treeiterator.hh:290
provides a wrapper for ALBERTA's mesh structure
Dune namespace.
Definition: alignment.hh:10
Static tag representing a codimension.
Definition: dimension.hh:22
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 9, 22:29, 2024)