Dune Core Modules (2.6.0)

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
7#include <dune/common/hybridutilities.hh>
8#include <dune/common/std/utility.hh>
10
13
14#if HAVE_ALBERTA
15
16namespace 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
41 typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering;
42 typedef Alberta::ElementInfo< dimension > ElementInfo;
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
65 ~AlbertaMarkerVector ()
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
134 typedef Alberta::ElementInfo< dimension > ElementInfo;
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
196 = Alberta::NumSubEntities< dimension, codimension >::value;
197
198 public:
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 typedef typename EntityImp::ElementInfo ElementInfo;
206
208
210
213
215 This &operator= ( const This &other );
216
218 AlbertaGridTreeIterator ( const GridImp &grid, int travLevel );
219
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 >
358 inline AlbertaGridTreeIterator< codim, GridImp, 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 >
449 inline void AlbertaGridTreeIterator< codim, GridImp, 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 >
458 inline bool AlbertaGridTreeIterator< codim, GridImp, 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 >
468 inline void AlbertaGridTreeIterator< codim, GridImp, 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 >
476 inline void AlbertaGridTreeIterator< codim, GridImp, 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 >
487 inline void AlbertaGridTreeIterator< codim, GridImp, 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 >
529 inline void AlbertaGridTreeIterator< codim, GridImp, leafIterator >
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
Definition: treeiterator.hh:184
bool equals(const This &other) const
equality
Definition: treeiterator.hh:226
const EntityImp & entityImp() const
obtain const reference to internal entity implementation
Definition: treeiterator.hh:254
AlbertaGridTreeIterator(const GridImp &grid, const MarkerVector *marker, int travLevel)
Constructor making begin iterator.
Definition: treeiterator.hh:359
AlbertaGridTreeIterator(const GridImp &grid, int travLevel)
Constructor making end iterator.
Definition: treeiterator.hh:380
This & operator=(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:405
Entity & dereference() const
dereferencing
Definition: treeiterator.hh:232
int level() const
ask for level of entities
Definition: treeiterator.hh:238
void increment()
increment
Definition: treeiterator.hh:418
const GridImp & grid() const
obtain a reference to the grid
Definition: treeiterator.hh:260
AlbertaGridTreeIterator(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:393
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition: treeiterator.hh:248
marker assigning subentities to one element containing them
Definition: treeiterator.hh:32
AlbertaMarkerVector(const DofNumbering &dofNumbering)
create AlbertaMarkerVector with empty vectors
Definition: treeiterator.hh:51
bool up2Date() const
return true if marking is up to date
Definition: treeiterator.hh:92
bool subEntityOnElement(const ElementInfo &elementInfo, int subEntity) const
visit subentity on this element?
Definition: treeiterator.hh:301
void print(std::ostream &out=std::cout) const
print for debugin' only
Definition: treeiterator.hh:326
Wrapper class for entities.
Definition: entity.hh:64
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: grid.hh:1026
provides a wrapper for ALBERTA's el_info structure
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:58
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:308
provides a wrapper for ALBERTA's mesh structure
Dune namespace.
Definition: alignedallocator.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.111.3 (Nov 24, 23:30, 2024)