dune-grid  2.6-git
treeiterator.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 
4 #ifndef DUNE_ALBERTA_TREEITERATOR_HH
5 #define DUNE_ALBERTA_TREEITERATOR_HH
6 
7 #include <dune/common/hybridutilities.hh>
8 #include <dune/common/std/utility.hh>
9 #include <dune/common/typetraits.hh>
10 
13 
14 #if HAVE_ALBERTA
15 
16 namespace Dune
17 {
18 
19  // AlbertaMarkerVector
20  // -------------------
21 
30  template< int dim, int dimworld >
32  {
34 
36 
37  //friend class AlbertaGrid< dim, dimworld >;
38 
39  static const int dimension = Grid::dimension;
40 
43 
44  template< bool >
45  struct NoMarkSubEntities;
46  template< bool >
47  struct MarkSubEntities;
48 
49  public:
51  explicit AlbertaMarkerVector ( const DofNumbering &dofNumbering )
52  : dofNumbering_( dofNumbering )
53  {
54  for( int codim = 0; codim <= dimension; ++codim )
55  marker_[ codim ] = 0;
56  }
57 
58  AlbertaMarkerVector ( const This &other )
59  : dofNumbering_( other.dofNumbering_ )
60  {
61  for( int codim = 0; codim <= dimension; ++codim )
62  marker_[ codim ] = 0;
63  }
64 
66  {
67  clear();
68  }
69 
70  private:
71  This &operator= ( const This & );
72 
73  public:
75  template< int codim >
76  bool subEntityOnElement ( const ElementInfo &elementInfo, int subEntity ) const;
77 
78  template< int firstCodim, class Iterator >
79  void markSubEntities ( const Iterator &begin, const Iterator &end );
80 
81  void clear ()
82  {
83  for( int codim = 0; codim <= dimension; ++codim )
84  {
85  if( marker_[ codim ] != 0 )
86  delete[] marker_[ codim ];
87  marker_[ codim ] = 0;
88  }
89  }
90 
92  bool up2Date () const
93  {
94  return (marker_[ dimension ] != 0);
95  }
96 
98  void print ( std::ostream &out = std::cout ) const;
99 
100  private:
101  const DofNumbering &dofNumbering_;
102  int *marker_[ dimension+1 ];
103  };
104 
105 
106 
107  // AlbertaMarkerVector::NoMarkSubEntities
108  // --------------------------------------
109 
110  template< int dim, int dimworld >
111  template< bool >
112  struct AlbertaMarkerVector< dim, dimworld >::NoMarkSubEntities
113  {
114  template< int firstCodim, class Iterator >
115  static void mark ( const DofNumbering &dofNumbering, int *(&marker)[ dimension + 1 ],
116  const Iterator &begin, const Iterator &end )
117  {}
118  };
119 
120 
121 
122  // AlbertaMarkerVector::MarkSubEntities
123  // ------------------------------------
124 
125  template< int dim, int dimworld >
126  template< bool >
127  struct AlbertaMarkerVector< dim, dimworld >::MarkSubEntities
128  {
129  template< int codim >
130  struct Codim
131  {
132  static const int numSubEntities = Alberta::NumSubEntities< dimension, codim >::value;
133 
135 
136  static void apply ( const DofNumbering &dofNumbering,
137  int *(&marker)[ dimension + 1 ],
138  const ElementInfo &elementInfo )
139  {
140  int *array = marker[ codim ];
141 
142  const int index = dofNumbering( elementInfo, 0, 0 );
143  for( int i = 0; i < numSubEntities; ++i )
144  {
145  int &mark = array[ dofNumbering( elementInfo, codim, i ) ];
146  mark = std::max( index, mark );
147  }
148  }
149  };
150 
151  template< int firstCodim, class Iterator >
152  static void mark ( const DofNumbering &dofNumbering, int *(&marker)[ dimension + 1 ],
153  const Iterator &begin, const Iterator &end )
154  {
155  for( int codim = firstCodim; codim <= dimension; ++codim )
156  {
157  const int size = dofNumbering.size( codim );
158  marker[ codim ] = new int[ size ];
159 
160  int *array = marker[ codim ];
161  for( int i = 0; i < size; ++i )
162  array[ i ] = -1;
163  }
164 
165  for( Iterator it = begin; it != end; ++it )
166  {
167  const ElementInfo &elementInfo = Grid::getRealImplementation( *it ).elementInfo();
168  Hybrid::forEach( Std::make_index_sequence< dimension+1-firstCodim >{},
169  [ & ]( auto i ){ Codim< i+firstCodim >::apply( dofNumbering, marker, elementInfo ); } );
170  }
171  }
172  };
173 
174 
175 
176  // AlbertaGridTreeIterator
177  // -----------------------
178 
182  template< int codim, class GridImp, bool leafIterator >
184  {
186 
187  public:
188  static const int dimension = GridImp::dimension;
189  static const int codimension = codim;
190  static const int dimensionworld = GridImp::dimensionworld;
191 
192  private:
193  friend class AlbertaGrid< dimension, dimensionworld >;
194 
195  static const int numSubEntities
197 
198  public:
200  typedef typename MeshPointer::MacroIterator MacroIterator;
201 
202  typedef typename GridImp::template Codim< codim >::Entity Entity;
205  typedef typename EntityImp::ElementInfo ElementInfo;
206 
208 
210 
212  AlbertaGridTreeIterator ( const This &other );
213 
215  This &operator= ( const This &other );
216 
218  AlbertaGridTreeIterator ( const GridImp &grid, int travLevel );
219 
221  AlbertaGridTreeIterator ( const GridImp &grid,
222  const MarkerVector *marker,
223  int travLevel );
224 
226  bool equals ( const This &other ) const
227  {
228  return entityImp().equals( other.entityImp() );
229  }
230 
232  Entity &dereference () const
233  {
234  return entity_;
235  }
236 
238  int level () const
239  {
240  return entityImp().level();
241  }
242 
244  void increment();
245 
246  protected:
248  EntityImp &entityImp ()
249  {
250  return GridImp::getRealImplementation( entity_ );
251  }
252 
254  const EntityImp &entityImp () const
255  {
256  return GridImp::getRealImplementation( entity_ );
257  }
258 
260  const GridImp &grid () const
261  {
262  return entityImp().grid();
263  }
264 
265  private:
266  void nextElement ( ElementInfo &elementInfo );
267  void nextElementStop (ElementInfo &elementInfo );
268  bool stopAtElement ( const ElementInfo &elementInfo ) const;
269 
270  void goNext ( ElementInfo &elementInfo );
271  void goNext ( const std::integral_constant< int, 0 > cdVariable,
272  ElementInfo &elementInfo );
273  void goNext ( const std::integral_constant< int, 1 > cdVariable,
274  ElementInfo &elementInfo );
275  template< int cd >
276  void goNext ( const std::integral_constant< int, cd > cdVariable,
277  ElementInfo &elementInfo );
278 
279  mutable Entity entity_;
280 
282  int level_;
283 
285  int subEntity_;
286 
287  MacroIterator macroIterator_;
288 
289  // knows on which element a point,edge,face is viewed
290  const MarkerVector *marker_;
291  };
292 
293 
294 
295  // Implementation of AlbertaMarkerVector
296  // -------------------------------------
297 
298  template< int dim, int dimworld >
299  template< int codim >
301  ::subEntityOnElement ( const ElementInfo &elementInfo, int subEntity ) const
302  {
303  assert( marker_[ codim ] != 0 );
304 
305  const int subIndex = dofNumbering_( elementInfo, codim, subEntity );
306  const int markIndex = marker_[ codim ][ subIndex ];
307  assert( (markIndex >= 0) );
308 
309  const int index = dofNumbering_( elementInfo, 0, 0 );
310  return (markIndex == index);
311  }
312 
313 
314  template< int dim, int dimworld >
315  template< int firstCodim, class Iterator >
317  ::markSubEntities ( const Iterator &begin, const Iterator &end )
318  {
319  clear();
320  std::conditional< (firstCodim <= dimension), MarkSubEntities<true>, NoMarkSubEntities<false> >::type
321  ::template mark< firstCodim, Iterator >( dofNumbering_, marker_, begin, end );
322  }
323 
324 
325  template< int dim, int dimworld >
326  inline void AlbertaMarkerVector< dim, dimworld >::print ( std::ostream &out ) const
327  {
328  for( int codim = 1; codim <= dimension; ++codim )
329  {
330  int *marker = marker_[ codim ];
331  if( marker != 0 )
332  {
333  const int size = dofNumbering_.size( codim );
334  out << std::endl;
335  out << "Codimension " << codim << " (" << size << " entries)" << std::endl;
336  for( int i = 0; i < size; ++i )
337  out << "subentity " << i << " visited on Element " << marker[ i ] << std::endl;
338  }
339  }
340  }
341 
342 
343 
344  // Implementation of AlbertaGridTreeIterator
345  // -----------------------------------------
346 
347  template< int codim, class GridImp, bool leafIterator >
350  : entity_(),
351  level_( -1 ),
352  subEntity_( -1 ),
353  macroIterator_(),
354  marker_( NULL )
355  {}
356 
357  template< int codim, class GridImp, bool leafIterator >
359  ::AlbertaGridTreeIterator ( const GridImp &grid,
360  const MarkerVector *marker,
361  int travLevel )
362  : entity_( EntityImp( grid ) ),
363  level_( travLevel ),
364  subEntity_( (codim == 0 ? 0 : -1) ),
365  macroIterator_( grid.meshPointer().begin() ),
366  marker_( marker )
367  {
368  ElementInfo elementInfo = *macroIterator_;
369  nextElementStop( elementInfo );
370  if( codim > 0 )
371  goNext( elementInfo );
372  // it is ok to set the invalid ElementInfo
373  entityImp().setElement( elementInfo, subEntity_ );
374  }
375 
376 
377  // Make LevelIterator with point to element from previous iterations
378  template< int codim, class GridImp, bool leafIterator >
380  ::AlbertaGridTreeIterator ( const GridImp &grid,
381  int travLevel )
382  : entity_( EntityImp( grid ) ),
383  level_( travLevel ),
384  subEntity_( -1 ),
385  macroIterator_( grid.meshPointer().end() ),
386  marker_( 0 )
387  {}
388 
389 
390  // Make LevelIterator with point to element from previous iterations
391  template< int codim, class GridImp, bool leafIterator >
394  : entity_( other.entity_ ),
395  level_( other.level_ ),
396  subEntity_( other.subEntity_ ),
397  macroIterator_( other.macroIterator_ ),
398  marker_( other.marker_ )
399  {}
400 
401 
402  // Make LevelIterator with point to element from previous iterations
403  template< int codim, class GridImp, bool leafIterator >
406  {
407  entity_ = other.entity_;
408  level_ = other.level_;
409  subEntity_ = other.subEntity_;
410  macroIterator_ = other.macroIterator_;
411  marker_ = other.marker_;
412 
413  return *this;
414  }
415 
416 
417  template< int codim, class GridImp, bool leafIterator >
419  {
420  ElementInfo elementInfo = entityImp().elementInfo_;
421  goNext ( elementInfo );
422  // it is ok to set the invalid ElementInfo
423  entityImp().setElement( elementInfo, subEntity_ );
424  }
425 
426 
427  template< int codim, class GridImp, bool leafIterator >
429  ::nextElement ( ElementInfo &elementInfo )
430  {
431  if( elementInfo.isLeaf() || (elementInfo.level() >= level_) )
432  {
433  while( (elementInfo.level() > 0) && (elementInfo.indexInFather() == 1) )
434  elementInfo = elementInfo.father();
435  if( elementInfo.level() == 0 )
436  {
437  ++macroIterator_;
438  elementInfo = *macroIterator_;
439  }
440  else
441  elementInfo = elementInfo.father().child( 1 );
442  }
443  else
444  elementInfo = elementInfo.child( 0 );
445  }
446 
447 
448  template< int codim, class GridImp, bool leafIterator >
450  ::nextElementStop ( ElementInfo &elementInfo )
451  {
452  while( !(!elementInfo || stopAtElement( elementInfo )) )
453  nextElement( elementInfo );
454  }
455 
456 
457  template< int codim, class GridImp, bool leafIterator >
459  ::stopAtElement ( const ElementInfo &elementInfo ) const
460  {
461  if( !elementInfo )
462  return true;
463  return (leafIterator ? elementInfo.isLeaf() : (level_ == elementInfo.level()));
464  }
465 
466 
467  template< int codim, class GridImp, bool leafIterator >
469  ::goNext ( ElementInfo &elementInfo )
470  {
471  std::integral_constant< int, codim > codimVariable;
472  goNext( codimVariable, elementInfo );
473  }
474 
475  template< int codim, class GridImp, bool leafIterator >
477  ::goNext ( const std::integral_constant< int, 0 > cdVariable,
478  ElementInfo &elementInfo )
479  {
480  assert( stopAtElement( elementInfo ) );
481 
482  nextElement( elementInfo );
483  nextElementStop( elementInfo );
484  }
485 
486  template< int codim, class GridImp, bool leafIterator >
488  ::goNext ( const std::integral_constant< int, 1 > cdVariable,
489  ElementInfo &elementInfo )
490  {
491  assert( stopAtElement( elementInfo ) );
492 
493  ++subEntity_;
494  if( subEntity_ >= numSubEntities )
495  {
496  subEntity_ = 0;
497  nextElement( elementInfo );
498  nextElementStop( elementInfo );
499  if( !elementInfo )
500  return;
501  }
502 
503  if( leafIterator )
504  {
505  const int face = (dimension == 1 ? (numSubEntities-1)-subEntity_ : subEntity_);
506 
507  const ALBERTA EL *neighbor = elementInfo.elInfo().neigh[ face ];
508  if( (neighbor != NULL) && !elementInfo.isBoundary( face ) )
509  {
510  // face is reached from element with largest number
511  const int elIndex = grid().dofNumbering() ( elementInfo, 0, 0 );
512  const int nbIndex = grid().dofNumbering() ( neighbor, 0, 0 );
513  if( elIndex < nbIndex )
514  goNext( cdVariable, elementInfo );
515  }
516  // uncomment this assertion only if codimension 1 entities are marked
517  // assert( marker_->template subEntityOnElement< 1 >( elementInfo, subEntity_ ) );
518  }
519  else
520  {
521  assert( marker_ != 0 );
522  if( !marker_->template subEntityOnElement< 1 >( elementInfo, subEntity_ ) )
523  goNext( cdVariable, elementInfo );
524  }
525  }
526 
527  template< int codim, class GridImp, bool leafIterator >
528  template< int cd >
530  ::goNext ( const std::integral_constant< int, cd > cdVariable,
531  ElementInfo &elementInfo )
532  {
533  assert( stopAtElement( elementInfo ) );
534 
535  ++subEntity_;
536  if( subEntity_ >= numSubEntities )
537  {
538  subEntity_ = 0;
539  nextElement( elementInfo );
540  nextElementStop( elementInfo );
541  if( !elementInfo )
542  return;
543  }
544 
545  assert( marker_ != 0 );
546  if( !marker_->template subEntityOnElement< cd >( elementInfo, subEntity_ ) )
547  goNext( cdVariable, elementInfo );
548  }
549 
550 }
551 
552 #endif // #if HAVE_ALBERTA
553 
554 #endif // #ifndef DUNE_ALBERTA_TREEITERATOR_HH
Include standard header files.
Definition: agrid.hh:58
const EntityImp & entityImp() const
obtain const reference to internal entity implementation
Definition: treeiterator.hh:254
Definition: albertagrid/entity.hh:21
Entity & dereference() const
dereferencing
Definition: treeiterator.hh:232
bool up2Date() const
return true if marking is up to date
Definition: treeiterator.hh:92
static std::conditional< std::is_reference< InterfaceType >::value, typename std::add_lvalue_reference< typename ReturnImplementationType< typename std::remove_reference< InterfaceType >::type >::ImplementationType >::type, typename std::remove_const< typename ReturnImplementationType< typename std::remove_reference< InterfaceType >::type >::ImplementationType >::type >::type getRealImplementation(InterfaceType &&i)
return real implementation of interface class
Definition: common/grid.hh:1026
Alberta::ElementInfo< dimension > ElementInfo
Definition: treeiterator.hh:134
static void apply(const DofNumbering &dofNumbering, int *(&marker)[dimension+1], const ElementInfo &elementInfo)
Definition: treeiterator.hh:136
EntityObject::ImplementationType EntityImp
Definition: treeiterator.hh:204
int level() const
ask for level of entities
Definition: treeiterator.hh:238
#define ALBERTA
Definition: albertaheader.hh:27
[ provides Dune::Grid ]
Definition: agrid.hh:136
Entity ::Implementation ImplementationType
Definition: common/grid.hh:1173
marker assigning subentities to one element containing them
Definition: treeiterator.hh:31
GridImp::template Codim< codim >::Entity Entity
Definition: treeiterator.hh:202
AlbertaMarkerVector(const DofNumbering &dofNumbering)
create AlbertaMarkerVector with empty vectors
Definition: treeiterator.hh:51
provides a wrapper for ALBERTA&#39;s el_info structure
AlbertaMarkerVector< dimension, dimensionworld > MarkerVector
Definition: treeiterator.hh:207
Alberta::MeshPointer< dimension > MeshPointer
Definition: treeiterator.hh:199
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition: treeiterator.hh:248
Definition: misc.hh:146
EntityImp::ElementInfo ElementInfo
Definition: treeiterator.hh:205
AlbertaGridTreeIterator()
Definition: treeiterator.hh:349
void clear()
Definition: treeiterator.hh:81
This & operator=(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:405
MeshPointer::MacroIterator MacroIterator
Definition: treeiterator.hh:200
int max(const DofVectorPointer< int > &dofVector)
Definition: dofvector.hh:335
void increment()
increment
Definition: treeiterator.hh:418
provides a wrapper for ALBERTA&#39;s mesh structure
~AlbertaMarkerVector()
Definition: treeiterator.hh:65
MakeableInterfaceObject< Entity > EntityObject
Definition: treeiterator.hh:203
bool subEntityOnElement(const ElementInfo &elementInfo, int subEntity) const
visit subentity on this element?
Definition: treeiterator.hh:301
bool equals(const This &other) const
equality
Definition: treeiterator.hh:226
int size(int codim) const
Definition: dofadmin.hh:160
static const int dimension
Definition: agrid.hh:175
AlbertaMarkerVector(const This &other)
Definition: treeiterator.hh:58
const GridImp & grid() const
obtain a reference to the grid
Definition: treeiterator.hh:260
void markSubEntities(const Iterator &begin, const Iterator &end)
Definition: treeiterator.hh:317
void print(std::ostream &out=std::cout) const
print for debugin&#39; only
Definition: treeiterator.hh:326