Dune Core Modules (2.3.1)

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
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
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
63 ~AlbertaMarkerVector ()
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
210
212 This &operator= ( const This &other );
213
215 AlbertaGridTreeIterator ( const GridImp &grid, int travLevel );
216
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
EntityPointer implementation for AlbertaGrid.
Definition: entitypointer.hh:29
const GridImp & grid() const
obtain a reference to the grid
Definition: entitypointer.hh:192
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition: entitypointer.hh:177
Definition: treeiterator.hh:182
AlbertaGridTreeIterator(const GridImp &grid, const MarkerVector *marker, int travLevel)
Constructor making begin iterator.
Definition: treeiterator.hh:311
AlbertaGridTreeIterator(const GridImp &grid, int travLevel)
Constructor making end iterator.
Definition: treeiterator.hh:332
This & operator=(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:357
const GridImp & grid() const
obtain a reference to the grid
Definition: entitypointer.hh:192
EntityImp & entityImp()
obtain reference to internal entity implementation
Definition: entitypointer.hh:177
void increment()
increment
Definition: treeiterator.hh:371
AlbertaGridTreeIterator(const This &other)
Constructor making end iterator.
Definition: treeiterator.hh:345
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:263
void print(std::ostream &out=std::cout) const
print for debugin' only
Definition: treeiterator.hh:288
static ReturnImplementationType< InterfaceType >::ImplementationType & getRealImplementation(InterfaceType &i)
return real implementation of interface class
Definition: grid.hh:1223
provides a wrapper for ALBERTA's mesh structure
Dune namespace.
Definition: alignment.hh:14
Select a type based on a condition.
Definition: typetraits.hh:419
Generate a type for a given integral constant.
Definition: typetraits.hh:457
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)