Dune Core Modules (2.3.1)

elementinfo.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#ifndef DUNE_ALBERTA_ELEMENTINFO_HH
4#define DUNE_ALBERTA_ELEMENTINFO_HH
5
11#include <cassert>
12#include <vector>
13
14#include <dune/grid/albertagrid/geometrycache.hh>
15#include <dune/grid/albertagrid/macroelement.hh>
16
17#if HAVE_ALBERTA
18
19namespace Dune
20{
21
22 namespace Alberta
23 {
24
25 // External Forward Declarations
26 // -----------------------------
27
28 template< int dim >
29 class MeshPointer;
30
31 struct BasicNodeProjection;
32
33
34
35 // ElementInfo
36 // -----------
37
38 template< int dim >
39 class ElementInfo
40 {
41 struct Instance;
42 class Stack;
43
44 template< int >
45 struct Library;
46
47 typedef Instance *InstancePtr;
48
49 public:
50 static const int dimension = dim;
51
52 static const int numVertices = NumSubEntities< dimension, dimension >::value;
53 static const int numFaces = NumSubEntities< dimension, 1 >::value;
54
55 typedef Alberta::MacroElement< dimension > MacroElement;
56 typedef Alberta::MeshPointer< dimension > MeshPointer;
57 typedef Alberta::FillFlags< dimension > FillFlags;
58
59 static const int maxNeighbors = N_NEIGH_MAX;
60
61 static const int maxLevelNeighbors = Library< dimWorld >::maxLevelNeighbors;
62
63#if !DUNE_ALBERTA_CACHE_COORDINATES
64 typedef GeometryCacheProxy< dim > GeometryCache;
65#endif
66
67 struct Seed;
68
69 private:
70 explicit ElementInfo ( const InstancePtr &instance );
71
72 public:
73 ElementInfo ();
74 ElementInfo ( const MeshPointer &mesh, const MacroElement &macroElement,
75 typename FillFlags::Flags fillFlags = FillFlags::standard );
76 ElementInfo ( const MeshPointer &mesh, const Seed &seed,
77 typename FillFlags::Flags fillFlags = FillFlags::standard );
78 ElementInfo ( const ElementInfo &other );
79
80 ~ElementInfo ();
81
82 ElementInfo &operator= ( const ElementInfo &other );
83
84 operator bool () const { return (instance_ != null()); }
85
86 bool operator== ( const ElementInfo &other ) const;
87 bool operator!= ( const ElementInfo &other ) const;
88
89 const MacroElement &macroElement () const;
90 ElementInfo father () const;
91 int indexInFather () const;
92 ElementInfo child ( int i ) const;
93 bool isLeaf () const;
94
95 Seed seed () const;
96
97 MeshPointer mesh () const;
98
99 bool mightVanish () const;
100
101 int level () const;
102 // see ALBERTA documentation for definition of element type
103 // values are 0, 1, 2
104 int type () const;
105
106 int getMark () const;
107 void setMark ( int refCount ) const;
108
109 bool hasLeafNeighbor ( const int face ) const;
110 ElementInfo leafNeighbor ( const int face ) const;
111
112 /* obtain all level neighbors of a face
113 *
114 * param[in] face face for which the neighbors are desired
115 * param[out] neighbor array storing the neighbors
116 * param[out] faceInNeighbor array storing the faces in neighbor
117 * (-1, if this neighbor does not exist)
118 *
119 * returns (potential) number of neighbors (i.e., the number of valid
120 * entries in the output arrays
121 */
122 int levelNeighbors ( const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ], int (&faceInNeighbor)[ maxLevelNeighbors ] ) const;
123
124 template< int codim >
125 int twist ( int subEntity ) const;
126 int twistInNeighbor ( int face ) const;
127 bool isBoundary ( int face ) const;
128 int boundaryId ( int face ) const;
129 AffineTransformation *transformation ( int face ) const;
130 BasicNodeProjection *boundaryProjection ( int face ) const;
131
132 bool hasCoordinates () const;
133 const GlobalVector &coordinate ( int vertex ) const;
134#if !DUNE_ALBERTA_CACHE_COORDINATES
135 GeometryCache geometryCache () const
136 {
137 return GeometryCache( instance_->geometryCache, instance_->elInfo );
138 }
139#endif
140
141 template< class Functor >
142 void hierarchicTraverse ( Functor &functor ) const;
143
144 template< class Functor >
145 void leafTraverse ( Functor &functor ) const;
146
147 const Element *element () const;
148 const Element *neighbor ( int face ) const;
149 Element *el () const;
150 ALBERTA EL_INFO &elInfo () const;
151
152 static ElementInfo
153 createFake ( const MeshPointer &mesh,
154 const Element *element, int level, int type = 0 );
155 static ElementInfo createFake ( const ALBERTA EL_INFO &elInfo );
156
157 private:
158 static bool isLeaf ( Element *element );
159 static bool mightVanish ( Element *element, int depth );
160
161 static void fill ( Mesh *mesh, const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo );
162 static void fill ( int ichild, const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo );
163
164 void addReference () const;
165 void removeReference () const;
166
167 static InstancePtr null ();
168 static Stack &stack ();
169
170 InstancePtr instance_;
171 };
172
173
174
175 // ElementInfo::Instance
176 // ---------------------
177
178 template< int dim >
179 struct ElementInfo< dim >::Instance
180 {
181 ALBERTA EL_INFO elInfo;
182 unsigned int refCount;
183
184 InstancePtr &parent ()
185 {
186 return parent_;
187 }
188
189 private:
190 InstancePtr parent_;
191
192#if !DUNE_ALBERTA_CACHE_COORDINATES
193 public:
194 Alberta::GeometryCache< dim > geometryCache;
195#endif
196 };
197
198
199
200 // ElementInfo::Stack
201 // ------------------
202
203 template< int dim >
204 class ElementInfo< dim >::Stack
205 {
206 InstancePtr top_;
207 Instance null_;
208
209 public:
210 Stack ();
211 ~Stack ();
212
213 InstancePtr allocate ();
214 void release ( InstancePtr &p );
215 InstancePtr null ();
216 };
217
218
219
220 // ElementInfo::Library
221 // --------------------
222
223 template< int dim >
224 template< int >
225 struct ElementInfo< dim >::Library
226 {
227 typedef Alberta::ElementInfo< dim > ElementInfo;
228
229 static const int maxLevelNeighbors = (1 << (dim-1));
230
231 static int
232 leafNeighbor ( const ElementInfo &element, const int face, ElementInfo &neighbor );
233
234 static int
235 levelNeighbors ( const ElementInfo &element, const int face,
236 ElementInfo (&neighbor)[ maxLevelNeighbors ], int (&faceInNeighbor)[ maxLevelNeighbors ] );
237
238 private:
239 static int
240 macroNeighbor ( const ElementInfo &element, const int face, ElementInfo &neighbor );
241 };
242
243
244
245 // ElementInfo::Seed
246 // -----------------
247
248 template< int dim >
249 struct ElementInfo< dim >::Seed
250 {
251 Seed ()
252 : macroIndex_( -1 ), level_( 0 ), path_( 0 )
253 {}
254
255 Seed ( const int macroIndex, const int level, const unsigned long path )
256 : macroIndex_( macroIndex ), level_( level ), path_( path )
257 {}
258
259 bool operator== ( const Seed &other ) const
260 {
261 return (macroIndex() == other.macroIndex()) && (level() == other.level()) && (path() == other.path());
262 }
263
264 bool operator< ( const Seed &other ) const
265 {
266 const bool ml = (macroIndex() < other.macroIndex());
267 const bool me = (macroIndex() == other.macroIndex());
268 const bool ll = (level() < other.level());
269 const bool le = (level() == other.level());
270 const bool pl = (path() < other.path());
271 return ml | (me & (ll | (le & pl)));
272 }
273
274 bool operator!= ( const Seed &other ) const { return !(*this == other); }
275 bool operator<= ( const Seed &other ) const { return !(other < *this); }
276 bool operator> ( const Seed &other ) const { return (other < *this); }
277 bool operator>= ( const Seed &other ) const { return !(*this < other); }
278
279 bool isValid ( ) const { return macroIndex_ != -1; }
280
281 int macroIndex () const { return macroIndex_; }
282 int level () const { return level_; }
283 unsigned long path () const { return path_; }
284
285 private:
286 int macroIndex_;
287 int level_;
288 unsigned long path_;
289 };
290
291
292
293 // Implementation of ElementInfo
294 // -----------------------------
295
296 template< int dim >
297 inline ElementInfo< dim >::ElementInfo ( const InstancePtr &instance )
298 : instance_( instance )
299 {
300 addReference();
301 }
302
303
304 template< int dim >
305 inline ElementInfo< dim >::ElementInfo ()
306 : instance_( null() )
307 {
308 addReference();
309 }
310
311
312 template< int dim >
313 inline ElementInfo< dim >
314 ::ElementInfo ( const MeshPointer &mesh, const MacroElement &macroElement,
315 typename FillFlags::Flags fillFlags )
316 {
317 instance_ = stack().allocate();
318 instance_->parent() = null();
319 ++(instance_->parent()->refCount);
320
321 addReference();
322
323 elInfo().fill_flag = fillFlags;
324
325 // Alberta fills opp_vertex only if there is a neighbor
326 for( int k = 0; k < maxNeighbors; ++k )
327 elInfo().opp_vertex[ k ] = -1;
328
329 fill( mesh, &macroElement, elInfo() );
330 }
331
332
333 template< int dim >
334 inline ElementInfo< dim >
335 ::ElementInfo ( const MeshPointer &mesh, const Seed &seed,
336 typename FillFlags::Flags fillFlags )
337 {
338 instance_ = stack().allocate();
339 instance_->parent() = null();
340 ++(instance_->parent()->refCount);
341
342 addReference();
343
344 // fill in macro element info
345 elInfo().fill_flag = fillFlags;
346
347 // Alberta fills opp_vertex only if there is a neighbor
348 for( int k = 0; k < maxNeighbors; ++k )
349 elInfo().opp_vertex[ k ] = -1;
350
351 fill( mesh, ((Mesh *)mesh)->macro_els + seed.macroIndex(), elInfo() );
352
353 // traverse the seed's path
354 unsigned long path = seed.path();
355 for( int i = 0; i < seed.level(); ++i )
356 {
357 InstancePtr child = stack().allocate();
358 child->parent() = instance_;
359
360 // Alberta fills opp_vertex only if there is a neighbor
361 for( int k = 0; k < maxNeighbors; ++k )
362 child->elInfo.opp_vertex[ k ] = -2;
363
364 fill( path & 1, elInfo(), child->elInfo );
365
366 instance_ = child;
367 addReference();
368
369 path = path >> 1;
370 }
371
372 assert( this->seed() == seed );
373 }
374
375
376 template< int dim >
377 inline ElementInfo< dim >::ElementInfo ( const ElementInfo &other )
378 : instance_( other.instance_ )
379 {
380 addReference();
381 }
382
383
384 template< int dim >
385 inline ElementInfo< dim >::~ElementInfo ()
386 {
387 removeReference();
388 }
389
390
391 template< int dim >
392 inline ElementInfo< dim > &
393 ElementInfo< dim >::operator= ( const ElementInfo< dim > &other )
394 {
395 other.addReference();
396 removeReference();
397 instance_ = other.instance_;
398 return *this;
399 }
400
401
402 template< int dim >
403 inline bool
404 ElementInfo< dim >::operator== ( const ElementInfo< dim > &other ) const
405 {
406 return (instance_->elInfo.el == other.instance_->elInfo.el);
407 }
408
409
410 template< int dim >
411 inline bool
412 ElementInfo< dim >::operator!= ( const ElementInfo< dim > &other ) const
413 {
414 return (instance_->elInfo.el != other.instance_->elInfo.el);
415 }
416
417
418 template< int dim >
419 inline const typename ElementInfo< dim >::MacroElement &
420 ElementInfo< dim >::macroElement () const
421 {
422 assert( !!(*this) );
423 assert( elInfo().macro_el != NULL );
424 return static_cast< const MacroElement & >( *(elInfo().macro_el) );
425 }
426
427
428 template< int dim >
429 inline ElementInfo< dim > ElementInfo< dim >::father () const
430 {
431 assert( !!(*this) );
432 return ElementInfo< dim >( instance_->parent() );
433 }
434
435
436 template< int dim >
437 inline int ElementInfo< dim >::indexInFather () const
438 {
439 const Element *element = elInfo().el;
440#if DUNE_ALBERTA_VERSION >= 0x300
441 const Element *father = elInfo().parent->el;
442#else
443 const Element *father = elInfo().parent;
444#endif
445 assert( father != NULL );
446
447 const int index = (father->child[ 0 ] == element ? 0 : 1);
448 assert( father->child[ index ] == element );
449 return index;
450 }
451
452
453 template< int dim >
454 inline ElementInfo< dim > ElementInfo< dim >::child ( int i ) const
455 {
456 assert( !isLeaf() );
457
458 InstancePtr child = stack().allocate();
459 child->parent() = instance_;
460 addReference();
461
462 // Alberta fills opp_vertex only if there is a neighbor
463 for( int k = 0; k < maxNeighbors; ++k )
464 child->elInfo.opp_vertex[ k ] = -2;
465
466 fill( i, elInfo(), child->elInfo );
467 return ElementInfo< dim >( child );
468 }
469
470
471 template< int dim >
472 inline bool ElementInfo< dim >::isLeaf () const
473 {
474 assert( !(*this) == false );
475 return isLeaf( el() );
476 }
477
478
479 template< int dim >
480 inline typename ElementInfo< dim >::Seed ElementInfo< dim >::seed () const
481 {
482 assert( !!(*this) );
483
484 int level = 0;
485 unsigned long path = 0;
486 for( InstancePtr p = instance_; p->parent() != null(); p = p->parent() )
487 {
488 const Element *element = p->elInfo.el;
489 const Element *father = p->parent()->elInfo.el;
490 const unsigned long child = static_cast< unsigned long >( father->child[ 1 ] == element );
491 path = (path << 1) | child;
492 ++level;
493 }
494
495 if( level != elInfo().level )
496 DUNE_THROW( NotImplemented, "Seed for fake elements not implemented." );
497
498 return Seed( macroElement().index, level, path );
499 }
500
501
502 template< int dim >
503 inline typename ElementInfo< dim >::MeshPointer ElementInfo< dim >::mesh () const
504 {
505 return MeshPointer( elInfo().mesh );
506 }
507
508
509 template< int dim >
510 inline bool ElementInfo< dim >::mightVanish () const
511 {
512 return mightVanish( el(), 0 );
513 }
514
515
516 template< int dim >
517 inline int ElementInfo< dim >::level () const
518 {
519 return elInfo().level;
520 }
521
522
523 template< int dim >
524 inline int ElementInfo< dim >::type () const
525 {
526 return 0;
527 }
528
529
530 template<>
531 inline int ElementInfo< 3 >::type () const
532 {
533 return instance_->elInfo.el_type;
534 }
535
536
537 template< int dim >
538 inline int ElementInfo< dim >::getMark () const
539 {
540 return el()->mark;
541 }
542
543
544 template< int dim >
545 inline void ElementInfo< dim >::setMark ( int refCount ) const
546 {
547 assert( isLeaf() );
548 assert( (refCount >= -128) && (refCount < 127) );
549 el()->mark = refCount;
550 }
551
552
553#if DUNE_ALBERTA_VERSION >= 0x300
554 template< int dim >
555 inline bool ElementInfo< dim >::hasLeafNeighbor ( const int face ) const
556 {
557 assert( !!(*this) );
558 assert( (face >= 0) && (face < maxNeighbors) );
559
560 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
561 const int macroFace = elInfo().macro_wall[ face ];
562 if( macroFace >= 0 )
563 return (macroElement().neighbor( macroFace ) != NULL);
564 else
565 return true;
566 }
567#endif // DUNE_ALBERTA_VERSION >= 0x300
568
569#if DUNE_ALBERTA_VERSION < 0x300
570 template< int dim >
571 inline bool ElementInfo< dim >::hasLeafNeighbor ( const int face ) const
572 {
573 return (neighbor( face ) != NULL);
574 }
575#endif // DUNE_ALBERTA_VERSION < 0x300
576
577
578 template< int dim >
579 inline ElementInfo< dim > ElementInfo< dim >::leafNeighbor ( const int face ) const
580 {
581 assert( (face >= 0) && (face < numFaces) );
582 ElementInfo neighbor;
583 Library< dimWorld >::leafNeighbor( *this, face, neighbor );
584 return neighbor;
585 }
586
587
588 template< int dim >
589 inline int ElementInfo< dim >
590 ::levelNeighbors ( const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ], int (&faceInNeighbor)[ maxLevelNeighbors ] ) const
591 {
592 assert( (face >= 0) && (face < numFaces) );
593 return Library< dimWorld >::levelNeighbors( *this, face, neighbor, faceInNeighbor );
594 }
595
596
597 template< int dim >
598 template< int codim >
599 inline int ElementInfo< dim >::twist ( int subEntity ) const
600 {
601 return Twist< dim, dim-codim >::twist( element(), subEntity );
602 }
603
604
605 template< int dim >
606 inline int ElementInfo< dim >::twistInNeighbor ( const int face ) const
607 {
608 assert( neighbor( face ) != NULL );
609 return Twist< dim, dim-1 >::twist( neighbor( face ), elInfo().opp_vertex[ face ] );
610 }
611
612
613#if DUNE_ALBERTA_VERSION >= 0x300
614 template< int dim >
615 inline bool ElementInfo< dim >::isBoundary ( int face ) const
616 {
617 assert( !!(*this) );
618 assert( (face >= 0) && (face < maxNeighbors) );
619
620 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
621 const int macroFace = elInfo().macro_wall[ face ];
622 if( macroFace >= 0 )
623 return macroElement().isBoundary( macroFace );
624 else
625 return false;
626 }
627#endif // DUNE_ALBERTA_VERSION >= 0x300
628
629#if DUNE_ALBERTA_VERSION <= 0x200
630 template< int dim >
631 inline bool ElementInfo< dim >::isBoundary ( int face ) const
632 {
633 assert( !!(*this) );
634 assert( (face >= 0) && (face < maxNeighbors) );
635 return (elInfo().neigh[ face ] == 0);
636 }
637#endif // DUNE_ALBERTA_VERSION <= 0x200
638
639
640#if DUNE_ALBERTA_VERSION >= 0x300
641 template< int dim >
642 inline int ElementInfo< dim >::boundaryId ( int face ) const
643 {
644 assert( !!(*this) );
645 assert( (face >= 0) && (face < N_WALLS_MAX) );
646
647 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
648 const int macroFace = elInfo().macro_wall[ face ];
649 const int id = macroElement().boundaryId( macroFace );
650 // this assertion is only allowed, if FILL_BOUND is set
651 // assert( id == elInfo().wall_bound[ face ] );
652 return id;
653 }
654#endif // #if DUNE_ALBERTA_VERSION >= 0x300
655
656
657#if DUNE_ALBERTA_VERSION == 0x200
658 template<>
659 inline int ElementInfo< 1 >::boundaryId ( int face ) const
660 {
661 assert( !!(*this) );
662 assert( (face >= 0) && (face < N_VERTICES_MAX) );
663 return elInfo().vertex_bound[ 1-face ];
664 }
665
666 template<>
667 inline int ElementInfo< 2 >::boundaryId ( int face ) const
668 {
669 assert( !!(*this) );
670 assert( (face >= 0) && (face < N_EDGES_MAX) );
671 return elInfo().edge_bound[ face ];
672 }
673
674 template<>
675 inline int ElementInfo< 3 >::boundaryId ( int face ) const
676 {
677 assert( !!(*this) );
678 assert( (face >= 0) && (face < N_FACES_MAX) );
679 return elInfo().face_bound[ face ];
680 }
681#endif // #if DUNE_ALBERTA_VERSION == 0x200
682
683
684#if DUNE_ALBERTA_VERSION >= 0x300
685 template< int dim >
686 inline AffineTransformation *
687 ElementInfo< dim >::transformation ( int face ) const
688 {
689 assert( !!(*this) );
690 assert( (face >= 0) && (face < N_WALLS_MAX) );
691
692 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
693 const int macroFace = elInfo().macro_wall[ face ];
694 return (macroFace < 0 ? NULL : macroElement().wall_trafo[ macroFace ]);
695 }
696#endif // #if DUNE_ALBERTA_VERSION >= 0x300
697
698#if DUNE_ALBERTA_VERSION <= 0x200
699 template< int dim >
700 inline AffineTransformation *
701 ElementInfo< dim >::transformation ( int face ) const
702 {
703 return NULL;
704 }
705#endif // #if DUNE_ALBERTA_VERSION <= 0x200
706
707
708#if DUNE_ALBERTA_VERSION >= 0x300
709 template< int dim >
710 inline BasicNodeProjection *
711 ElementInfo< dim >::boundaryProjection ( int face ) const
712 {
713 assert( !!(*this) );
714 assert( (face >= 0) && (face < N_WALLS_MAX) );
715
716 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
717 const int macroFace = elInfo().macro_wall[ face ];
718 if( macroFace >= 0 )
719 return static_cast< BasicNodeProjection * >( macroElement().projection[ macroFace+1 ] );
720 else
721 return 0;
722 }
723#endif // #if DUNE_ALBERTA_VERSION >= 0x300
724
725#if DUNE_ALBERTA_VERSION <= 0x200
726 template< int dim >
727 inline BasicNodeProjection *
728 ElementInfo< dim >::boundaryProjection ( int face ) const
729 {
730 assert( !!(*this) );
731 assert( (face >= 0) && (face < maxNeighbors) );
732 const int idx = (dim == 1 ? 2-face : 1+face);
733 return static_cast< BasicNodeProjection * >( elInfo().projections[ idx ] );
734 }
735#endif // #if DUNE_ALBERTA_VERSION <= 0x200
736
737
738 template< int dim >
739 inline bool ElementInfo< dim >::hasCoordinates () const
740 {
741 return ((elInfo().fill_flag & FillFlags::coords) != 0);
742 }
743
744 template< int dim >
745 inline const GlobalVector &ElementInfo< dim >::coordinate ( int vertex ) const
746 {
747 assert( hasCoordinates() );
748 assert( (vertex >= 0) && (vertex < numVertices) );
749 return elInfo().coord[ vertex ];
750 }
751
752
753 template< int dim >
754 template< class Functor >
755 inline void ElementInfo< dim >::hierarchicTraverse ( Functor &functor ) const
756 {
757 functor( *this );
758 if( !isLeaf() )
759 {
760 child( 0 ).hierarchicTraverse( functor );
761 child( 1 ).hierarchicTraverse( functor );
762 }
763 }
764
765
766 template< int dim >
767 template< class Functor >
768 inline void ElementInfo< dim >::leafTraverse ( Functor &functor ) const
769 {
770 if( !isLeaf() )
771 {
772 child( 0 ).leafTraverse( functor );
773 child( 1 ).leafTraverse( functor );
774 }
775 else
776 functor( *this );
777 }
778
779
780 template< int dim >
781 inline const Element *ElementInfo< dim >::element () const
782 {
783 return elInfo().el;
784 }
785
786
787 template< int dim >
788 inline const Element *ElementInfo< dim >::neighbor ( int face ) const
789 {
790 assert( (face >= 0) && (face < numFaces) );
791 assert( (elInfo().fill_flag & FillFlags::neighbor) != 0 );
792 return elInfo().neigh[ face ];
793 }
794
795
796 template< int dim >
797 inline Element *ElementInfo< dim >::el () const
798 {
799 return elInfo().el;
800 }
801
802
803 template< int dim >
804 inline ALBERTA EL_INFO &ElementInfo< dim >::elInfo () const
805 {
806 return (instance_->elInfo);
807 }
808
809
810 template< int dim >
811 inline ElementInfo< dim >
812 ElementInfo< dim >::createFake ( const MeshPointer &mesh,
813 const Element *element, int level, int type )
814 {
815 InstancePtr instance = stack().allocate();
816 instance->parent() = null();
817 ++(instance->parent()->refCount);
818
819 instance->elInfo.mesh = mesh;
820 instance->elInfo.macro_el = NULL;
821 instance->elInfo.el = const_cast< Element * >( element );
822 instance->elInfo.parent = NULL;
823 instance->elInfo.fill_flag = FillFlags::nothing;
824 instance->elInfo.level = level;
825 instance->elInfo.el_type = type;
826
827 return ElementInfo< dim >( instance );
828 }
829
830
831 template< int dim >
832 inline ElementInfo< dim >
833 ElementInfo< dim >::createFake ( const ALBERTA EL_INFO &elInfo )
834 {
835 InstancePtr instance = stack().allocate();
836 instance->parent() = null();
837 ++(instance->parent()->refCount);
838
839 instance->elInfo = elInfo;
840 return ElementInfo< dim >( instance );
841 }
842
843
844 template< int dim >
845 inline bool ElementInfo< dim >::isLeaf ( Element *element )
846 {
847 return IS_LEAF_EL( element );
848 }
849
850
851 template< int dim >
852 inline bool ElementInfo< dim >::mightVanish ( Alberta::Element *element, int depth )
853 {
854 if( isLeaf( element ) )
855 return (element->mark < depth);
856 else
857 return (mightVanish( element->child[ 0 ], depth-1 ) && mightVanish( element->child[ 1 ], depth-1 ));
858 }
859
860
861 template< int dim >
862 inline void ElementInfo< dim >
863 ::fill ( Mesh *mesh, const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo )
864 {
865 ALBERTA fill_macro_info( mesh, mel, &elInfo );
866
867#if DUNE_ALBERTA_VERSION < 0x300
868 // The 1d grid does not fill in projections, so we do it here
869 if( (dim == 1) && (elInfo.fill_flag & FILL_PROJECTION) )
870 {
871 for( int i = 0; i <= N_VERTICES_1D; ++i )
872 elInfo.projections[ i ] = mel->projection[ i ];
873 }
874#endif
875 }
876
877 template< int dim >
878 inline void ElementInfo< dim >
879 ::fill ( int ichild, const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo )
880 {
881#if DUNE_ALBERTA_VERSION >= 0x300
882 ALBERTA fill_elinfo( ichild, FILL_ANY, &parentInfo, &elInfo );
883#else
884 ALBERTA fill_elinfo( ichild, &parentInfo, &elInfo );
885
886 // The 1d grid does not fill in projections, so we do it here
887 if( (dim == 1) && (elInfo.fill_flag & FILL_PROJECTION) )
888 {
889 elInfo.projections[ 0 ] = parentInfo.projections[ 0 ];
890 if( ichild == 0 )
891 {
892 elInfo.projections[ 1 ] = parentInfo.projections[ 0 ];
893 elInfo.projections[ 2 ] = parentInfo.projections[ 2 ];
894 }
895 else
896 {
897 elInfo.projections[ 1 ] = parentInfo.projections[ 1 ];
898 elInfo.projections[ 2 ] = parentInfo.projections[ 0 ];
899 }
900 }
901#endif
902 }
903
904
905 template< int dim >
906 inline void ElementInfo< dim >::addReference () const
907 {
908 ++(instance_->refCount);
909 }
910
911
912 template< int dim >
913 inline void ElementInfo< dim >::removeReference () const
914 {
915 // this loop breaks when instance becomes null()
916 for( InstancePtr instance = instance_; --(instance->refCount) == 0; )
917 {
918 const InstancePtr parent = instance->parent();
919 stack().release( instance );
920 instance = parent;
921 }
922 }
923
924
925 template< int dim >
926 inline typename ElementInfo< dim >::InstancePtr
927 ElementInfo< dim >::null ()
928 {
929 return stack().null();
930 }
931
932
933 template< int dim >
934 inline typename ElementInfo< dim >::Stack &
935 ElementInfo< dim >::stack ()
936 {
937 static Stack s;
938 return s;
939 }
940
941
942
943 // Implementation of ElementInfo::Stack
944 // ------------------------------------
945
946 template< int dim >
947 inline ElementInfo< dim >::Stack::Stack ()
948 : top_( 0 )
949 {
950 null_.elInfo.el = NULL;
951 null_.refCount = 1;
952 null_.parent() = 0;
953 }
954
955
956 template< int dim >
957 inline ElementInfo< dim >::Stack::~Stack ()
958 {
959 while( top_ != 0 )
960 {
961 InstancePtr p = top_;
962 top_ = p->parent();
963 delete p;
964 }
965 }
966
967
968 template< int dim >
969 inline typename ElementInfo< dim >::InstancePtr
970 ElementInfo< dim >::Stack::allocate ()
971 {
972 InstancePtr p = top_;
973 if( p != 0 )
974 top_ = p->parent();
975 else
976 p = new Instance;
977 p->refCount = 0;
978 return p;
979 }
980
981
982 template< int dim >
983 inline void ElementInfo< dim >::Stack::release ( InstancePtr &p )
984 {
985 assert( (p != null()) && (p->refCount == 0) );
986 p->parent() = top_;
987 top_ = p;
988 }
989
990
991 template< int dim >
992 inline typename ElementInfo< dim >::InstancePtr
993 ElementInfo< dim >::Stack::null ()
994 {
995 return &null_;
996 }
997
998 } // namespace Alberta
999
1000} // namespace Dune
1001
1002#endif // #if HAVE_ALBERTA
1003
1004#endif // #ifndef DUNE_ALBERTA_ELEMENTINFO_HH
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
bool le(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first lesser or equal second
Definition: float_cmp.cc:153
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:231
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:253
Dune namespace.
Definition: alignment.hh:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)