dune-grid 3.0-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/typetraits.hh>
8
11
12#if HAVE_ALBERTA
13
14namespace 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 >
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
196
197 public:
200 typedef typename MeshPointer::MacroIterator MacroIterator;
201
202 typedef typename GridImp::template Codim< codim >::Entity Entity;
205
207
209
212
214 This &operator= ( const This &other );
215
217 AlbertaGridTreeIterator ( const GridImp &grid, int travLevel );
218
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 std::integral_constant< int, 0 > cdVariable,
238 ElementInfo &elementInfo );
239 void goNext ( const std::integral_constant< int, 1 > cdVariable,
240 ElementInfo &elementInfo );
241 template< int cd >
242 void goNext ( const std::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 std::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 >
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 std::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 std::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 std::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 std::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
#define ALBERTA
Definition albertaheader.hh:27
provides a wrapper for ALBERTA's mesh structure
Include standard header files.
Definition agrid.hh:60
static const int dimension
Definition agrid.hh:177
int size(int codim) const
Definition dofadmin.hh:157
EntityPointer implementation for AlbertaGrid.
Definition albertagrid/entitypointer.hh:29
EntityImp::ElementInfo ElementInfo
Definition albertagrid/entitypointer.hh:49
const GridImp & grid() const
obtain a reference to the grid
Definition albertagrid/entitypointer.hh:170
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition albertagrid/entitypointer.hh:155
Definition treeiterator.hh:182
MakeableInterfaceObject< Entity > EntityObject
Definition treeiterator.hh:203
Alberta::MeshPointer< dimension > MeshPointer
Definition treeiterator.hh:199
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
EntityObject::ImplementationType EntityImp
Definition treeiterator.hh:204
static const int codimension
Definition treeiterator.hh:188
MeshPointer::MacroIterator MacroIterator
Definition treeiterator.hh:200
This & operator=(const This &other)
Constructor making end iterator.
Definition treeiterator.hh:369
AlbertaMarkerVector< dimension, dimensionworld > MarkerVector
Definition treeiterator.hh:206
const GridImp & grid() const
obtain a reference to the grid
Definition albertagrid/entitypointer.hh:170
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition albertagrid/entitypointer.hh:155
GridImp::template Codim< codim >::Entity Entity
Definition treeiterator.hh:202
static const int dimensionworld
Definition treeiterator.hh:189
AlbertaGridTreeIterator()
Definition treeiterator.hh:313
void increment()
increment
Definition treeiterator.hh:383
static const int dimension
Definition treeiterator.hh:187
AlbertaGridTreeIterator(const This &other)
Constructor making end iterator.
Definition treeiterator.hh:357
Base::ElementInfo ElementInfo
Definition treeiterator.hh:198
Definition misc.hh:145
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 markSubEntities(const Iterator &begin, const Iterator &end)
Definition treeiterator.hh:281
~AlbertaMarkerVector()
Definition treeiterator.hh:63
void clear()
Definition treeiterator.hh:79
AlbertaMarkerVector(const This &other)
Definition treeiterator.hh:56
void print(std::ostream &out=std::cout) const
print for debugin' only
Definition treeiterator.hh:290
Alberta::ElementInfo< dimension > ElementInfo
Definition treeiterator.hh:132
static void apply(const DofNumbering &dofNumbering, int *(&marker)[dimension+1], const ElementInfo &elementInfo)
Definition treeiterator.hh:134
static std::conditional< std::is_reference< InterfaceType >::value, typenamestd::add_lvalue_reference< typenameReturnImplementationType< typenamestd::remove_reference< InterfaceType >::type >::ImplementationType >::type, typenamestd::remove_const< typenameReturnImplementationType< typenamestd::remove_reference< InterfaceType >::type >::ImplementationType >::type >::type getRealImplementation(InterfaceType &&i)
return real implementation of interface class
Definition common/grid.hh:1119
InterfaceType::Implementation ImplementationType
Definition common/grid.hh:1266