dune-grid  2.3.1-rc1
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/typetraits.hh>
8 
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 
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 
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 >
180  class AlbertaGridTreeIterator
181  : public AlbertaGridEntityPointer< codim, GridImp >
182  {
183  typedef AlbertaGridTreeIterator< codim, GridImp, leafIterator > This;
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:
193 
194  static const int numSubEntities
196 
197  public:
198  typedef typename Base::ElementInfo ElementInfo;
200  typedef typename MeshPointer::MacroIterator MacroIterator;
201 
202  typedef typename GridImp::template Codim< codim >::Entity Entity;
205 
207 
209  AlbertaGridTreeIterator ( const This &other );
210 
212  This &operator= ( const This &other );
213 
215  AlbertaGridTreeIterator ( const GridImp &grid, int travLevel );
216 
218  AlbertaGridTreeIterator ( const GridImp &grid,
219  const MarkerVector *marker,
220  int travLevel );
221 
223  void increment();
224 
225  protected:
226  using Base::entityImp;
227  using Base::grid;
228 
229  private:
230  void nextElement ( ElementInfo &elementInfo );
231  void nextElementStop (ElementInfo &elementInfo );
232  bool stopAtElement ( const ElementInfo &elementInfo ) const;
233 
234  void goNext ( ElementInfo &elementInfo );
235  void goNext ( const integral_constant< int, 0 > cdVariable,
236  ElementInfo &elementInfo );
237  void goNext ( const integral_constant< int, 1 > cdVariable,
238  ElementInfo &elementInfo );
239  template< int cd >
240  void goNext ( const integral_constant< int, cd > cdVariable,
241  ElementInfo &elementInfo );
242 
244  int level_;
245 
247  int subEntity_;
248 
249  MacroIterator macroIterator_;
250 
251  // knows on which element a point,edge,face is viewed
252  const MarkerVector *marker_;
253  };
254 
255 
256 
257  // Implementation of AlbertaMarkerVector
258  // -------------------------------------
259 
260  template< int dim, int dimworld >
261  template< int codim >
263  ::subEntityOnElement ( const ElementInfo &elementInfo, int subEntity ) const
264  {
265  assert( marker_[ codim ] != 0 );
266 
267  const int subIndex = dofNumbering_( elementInfo, codim, subEntity );
268  const int markIndex = marker_[ codim ][ subIndex ];
269  assert( (markIndex >= 0) );
270 
271  const int index = dofNumbering_( elementInfo, 0, 0 );
272  return (markIndex == index);
273  }
274 
275 
276  template< int dim, int dimworld >
277  template< int firstCodim, class Iterator >
279  ::markSubEntities ( const Iterator &begin, const Iterator &end )
280  {
281  clear();
282  conditional< (firstCodim <= dimension), MarkSubEntities<true>, NoMarkSubEntities<false> >::type
283  ::template mark< firstCodim, Iterator >( dofNumbering_, marker_, begin, end );
284  }
285 
286 
287  template< int dim, int dimworld >
288  inline void AlbertaMarkerVector< dim, dimworld >::print ( std::ostream &out ) const
289  {
290  for( int codim = 1; codim <= dimension; ++codim )
291  {
292  int *marker = marker_[ codim ];
293  if( marker != 0 )
294  {
295  const int size = dofNumbering_.size( codim );
296  out << std::endl;
297  out << "Codimension " << codim << " (" << size << " entries)" << std::endl;
298  for( int i = 0; i < size; ++i )
299  out << "subentity " << i << " visited on Element " << marker[ i ] << std::endl;
300  }
301  }
302  }
303 
304 
305 
306  // Implementation of AlbertaGridTreeIterator
307  // -----------------------------------------
308 
309  template< int codim, class GridImp, bool leafIterator >
311  ::AlbertaGridTreeIterator ( const GridImp &grid,
312  const MarkerVector *marker,
313  int travLevel )
314  : Base( grid ),
315  level_( travLevel ),
316  subEntity_( (codim == 0 ? 0 : -1) ),
317  macroIterator_( grid.meshPointer().begin() ),
318  marker_( marker )
319  {
320  ElementInfo elementInfo = *macroIterator_;
321  nextElementStop( elementInfo );
322  if( codim > 0 )
323  goNext( elementInfo );
324  // it is ok to set the invalid ElementInfo
325  entityImp().setElement( elementInfo, subEntity_ );
326  }
327 
328 
329  // Make LevelIterator with point to element from previous iterations
330  template< int codim, class GridImp, bool leafIterator >
332  ::AlbertaGridTreeIterator ( const GridImp &grid,
333  int travLevel )
334  : Base( grid ),
335  level_( travLevel ),
336  subEntity_( -1 ),
337  macroIterator_( grid.meshPointer().end() ),
338  marker_( 0 )
339  {}
340 
341 
342  // Make LevelIterator with point to element from previous iterations
343  template< int codim, class GridImp, bool leafIterator >
346  : Base( other ),
347  level_( other.level_ ),
348  subEntity_( other.subEntity_ ),
349  macroIterator_( other.macroIterator_ ),
350  marker_( other.marker_ )
351  {}
352 
353 
354  // Make LevelIterator with point to element from previous iterations
355  template< int codim, class GridImp, bool leafIterator >
358  {
359  Base::operator=( other );
360 
361  level_ = other.level_;
362  subEntity_ = other.subEntity_;
363  macroIterator_ = other.macroIterator_;
364  marker_ = other.marker_;
365 
366  return *this;
367  }
368 
369 
370  template< int codim, class GridImp, bool leafIterator >
372  {
373  ElementInfo elementInfo = entityImp().elementInfo_;
374  goNext ( elementInfo );
375  // it is ok to set the invalid ElementInfo
376  entityImp().setElement( elementInfo, subEntity_ );
377  }
378 
379 
380  template< int codim, class GridImp, bool leafIterator >
382  ::nextElement ( ElementInfo &elementInfo )
383  {
384  if( elementInfo.isLeaf() || (elementInfo.level() >= level_) )
385  {
386  while( (elementInfo.level() > 0) && (elementInfo.indexInFather() == 1) )
387  elementInfo = elementInfo.father();
388  if( elementInfo.level() == 0 )
389  {
390  ++macroIterator_;
391  elementInfo = *macroIterator_;
392  }
393  else
394  elementInfo = elementInfo.father().child( 1 );
395  }
396  else
397  elementInfo = elementInfo.child( 0 );
398  }
399 
400 
401  template< int codim, class GridImp, bool leafIterator >
402  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
403  ::nextElementStop ( ElementInfo &elementInfo )
404  {
405  while( !(!elementInfo || stopAtElement( elementInfo )) )
406  nextElement( elementInfo );
407  }
408 
409 
410  template< int codim, class GridImp, bool leafIterator >
411  inline bool AlbertaGridTreeIterator< codim, GridImp, leafIterator >
412  ::stopAtElement ( const ElementInfo &elementInfo ) const
413  {
414  if( !elementInfo )
415  return true;
416  return (leafIterator ? elementInfo.isLeaf() : (level_ == elementInfo.level()));
417  }
418 
419 
420  template< int codim, class GridImp, bool leafIterator >
421  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
422  ::goNext ( ElementInfo &elementInfo )
423  {
424  integral_constant< int, codim > codimVariable;
425  goNext( codimVariable, elementInfo );
426  }
427 
428  template< int codim, class GridImp, bool leafIterator >
429  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
430  ::goNext ( const integral_constant< int, 0 > cdVariable,
431  ElementInfo &elementInfo )
432  {
433  assert( stopAtElement( elementInfo ) );
434 
435  nextElement( elementInfo );
436  nextElementStop( elementInfo );
437  }
438 
439  template< int codim, class GridImp, bool leafIterator >
440  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
441  ::goNext ( const integral_constant< int, 1 > cdVariable,
442  ElementInfo &elementInfo )
443  {
444  assert( stopAtElement( elementInfo ) );
445 
446  ++subEntity_;
447  if( subEntity_ >= numSubEntities )
448  {
449  subEntity_ = 0;
450  nextElement( elementInfo );
451  nextElementStop( elementInfo );
452  if( !elementInfo )
453  return;
454  }
455 
456  if( leafIterator )
457  {
458  const int face = (dimension == 1 ? (numSubEntities-1)-subEntity_ : subEntity_);
459 
460  const ALBERTA EL *neighbor = elementInfo.elInfo().neigh[ face ];
461  if( (neighbor != NULL) && !elementInfo.isBoundary( face ) )
462  {
463  // face is reached from element with largest number
464  const int elIndex = grid().dofNumbering() ( elementInfo, 0, 0 );
465  const int nbIndex = grid().dofNumbering() ( neighbor, 0, 0 );
466  if( elIndex < nbIndex )
467  goNext( cdVariable, elementInfo );
468  }
469  // uncomment this assertion only if codimension 1 entities are marked
470  // assert( marker_->template subEntityOnElement< 1 >( elementInfo, subEntity_ ) );
471  }
472  else
473  {
474  assert( marker_ != 0 );
475  if( !marker_->template subEntityOnElement< 1 >( elementInfo, subEntity_ ) )
476  goNext( cdVariable, elementInfo );
477  }
478  }
479 
480  template< int codim, class GridImp, bool leafIterator >
481  template< int cd >
482  inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
483  ::goNext ( const integral_constant< int, cd > cdVariable,
484  ElementInfo &elementInfo )
485  {
486  assert( stopAtElement( elementInfo ) );
487 
488  ++subEntity_;
489  if( subEntity_ >= numSubEntities )
490  {
491  subEntity_ = 0;
492  nextElement( elementInfo );
493  nextElementStop( elementInfo );
494  if( !elementInfo )
495  return;
496  }
497 
498  assert( marker_ != 0 );
499  if( !marker_->template subEntityOnElement< cd >( elementInfo, subEntity_ ) )
500  goNext( cdVariable, elementInfo );
501  }
502 
503 }
504 
505 #endif // #if HAVE_ALBERTA
506 
507 #endif // #ifndef DUNE_ALBERTA_TREEITERATOR_HH
bool up2Date() const
return true if marking is up to date
Definition: treeiterator.hh:90
Definition: albertagrid/entity.hh:24
int size(int codim) const
Definition: dofadmin.hh:157
static ReturnImplementationType< InterfaceType >::ImplementationType & getRealImplementation(InterfaceType &i)
return real implementation of interface class
Definition: common/grid.hh:1223
int max(const DofVectorPointer< int > &dofVector)
Definition: dofvector.hh:341
provides a wrapper for ALBERTA's mesh structure
AlbertaMarkerVector(const This &other)
Definition: treeiterator.hh:56
MakeableInterfaceObject< Entity > EntityObject
Definition: treeiterator.hh:203
Alberta::MeshPointer< dimension > MeshPointer
Definition: treeiterator.hh:199
Base::ElementInfo ElementInfo
Definition: treeiterator.hh:198
static void apply(const DofNumbering &dofNumbering, int *(&marker)[dimension+1], const ElementInfo &elementInfo)
Definition: treeiterator.hh:134
Alberta::ElementInfo< dimension > ElementInfo
Definition: treeiterator.hh:132
bool subEntityOnElement(const ElementInfo &elementInfo, int subEntity) const
visit subentity on this element?
Definition: treeiterator.hh:263
MeshPointer::MacroIterator MacroIterator
Definition: treeiterator.hh:200
void markSubEntities(const Iterator &begin, const Iterator &end)
Definition: treeiterator.hh:279
[ provides Dune::Grid ]
Definition: agrid.hh:137
This & operator=(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:357
AlbertaMarkerVector(const DofNumbering &dofNumbering)
create AlbertaMarkerVector with empty vectors
Definition: treeiterator.hh:49
const GridImp & grid() const
obtain a reference to the grid
void increment()
increment
Definition: treeiterator.hh:371
void print(std::ostream &out=std::cout) const
print for debugin' only
Definition: treeiterator.hh:288
~AlbertaMarkerVector()
Definition: treeiterator.hh:63
static const int dimension
Definition: treeiterator.hh:187
AlbertaMarkerVector< dimension, dimensionworld > MarkerVector
Definition: treeiterator.hh:206
Definition: misc.hh:159
Entity::Implementation ImplementationType
Definition: common/grid.hh:1377
static const int codimension
Definition: treeiterator.hh:188
GridImp::template Codim< codim >::Entity Entity
Definition: treeiterator.hh:202
static const int dimension
Definition: agrid.hh:177
#define ALBERTA
Definition: albertaheader.hh:27
EntityImp::ElementInfo ElementInfo
Definition: albertagrid/entitypointer.hh:49
EntityObject::ImplementationType EntityImp
Definition: treeiterator.hh:204
marker assigning subentities to one element containing them
Definition: treeiterator.hh:29
void clear()
Definition: treeiterator.hh:79
EntityImp & entityImp()
obtain reference to internal entity implementation
AlbertaGridTreeIterator(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:345
static const int dimensionworld
Definition: treeiterator.hh:189