3#ifndef DUNE_ALBERTA_ELEMENTINFO_HH
4#define DUNE_ALBERTA_ELEMENTINFO_HH
14#include <dune/grid/albertagrid/geometrycache.hh>
15#include <dune/grid/albertagrid/macroelement.hh>
31 struct BasicNodeProjection;
47 typedef Instance *InstancePtr;
50 static const int dimension = dim;
52 static const int numVertices = NumSubEntities< dimension, dimension >::value;
53 static const int numFaces = NumSubEntities< dimension, 1 >::value;
55 typedef Alberta::MacroElement< dimension > MacroElement;
56 typedef Alberta::MeshPointer< dimension > MeshPointer;
57 typedef Alberta::FillFlags< dimension > FillFlags;
59 static const int maxNeighbors = N_NEIGH_MAX;
61 static const int maxLevelNeighbors = Library< dimWorld >::maxLevelNeighbors;
63#if !DUNE_ALBERTA_CACHE_COORDINATES
64 typedef GeometryCacheProxy< dim > GeometryCache;
70 explicit ElementInfo (
const InstancePtr &instance );
74 ElementInfo (
const MeshPointer &mesh,
const MacroElement ¯oElement,
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 );
82 ElementInfo &operator= (
const ElementInfo &other );
84 operator bool ()
const {
return (instance_ != null()); }
86 bool operator== (
const ElementInfo &other )
const;
87 bool operator!= (
const ElementInfo &other )
const;
89 const MacroElement ¯oElement ()
const;
90 ElementInfo father ()
const;
91 int indexInFather ()
const;
92 ElementInfo child (
int i )
const;
97 MeshPointer mesh ()
const;
99 bool mightVanish ()
const;
106 int getMark ()
const;
107 void setMark (
int refCount )
const;
109 bool hasLeafNeighbor (
const int face )
const;
110 ElementInfo leafNeighbor (
const int face )
const;
122 int levelNeighbors (
const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ],
int (&faceInNeighbor)[ maxLevelNeighbors ] )
const;
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;
132 bool hasCoordinates ()
const;
133 const GlobalVector &coordinate (
int vertex )
const;
134#if !DUNE_ALBERTA_CACHE_COORDINATES
135 GeometryCache geometryCache ()
const
137 return GeometryCache( instance_->geometryCache, instance_->elInfo );
141 template<
class Functor >
142 void hierarchicTraverse ( Functor &functor )
const;
144 template<
class Functor >
145 void leafTraverse ( Functor &functor )
const;
147 const Element *element ()
const;
148 const Element *neighbor (
int face )
const;
149 Element *el ()
const;
150 ALBERTA EL_INFO &elInfo ()
const;
153 createFake (
const MeshPointer &mesh,
154 const Element *element,
int level,
int type = 0 );
155 static ElementInfo createFake (
const ALBERTA EL_INFO &elInfo );
158 static bool isLeaf ( Element *element );
159 static bool mightVanish ( Element *element,
int depth );
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 );
164 void addReference ()
const;
165 void removeReference ()
const;
167 static InstancePtr null ();
168 static Stack &stack ();
170 InstancePtr instance_;
179 struct ElementInfo< dim >::Instance
181 ALBERTA EL_INFO elInfo;
182 unsigned int refCount;
184 InstancePtr &parent ()
192#if !DUNE_ALBERTA_CACHE_COORDINATES
194 Alberta::GeometryCache< dim > geometryCache;
204 class ElementInfo< dim >::Stack
213 InstancePtr allocate ();
214 void release ( InstancePtr &p );
225 struct ElementInfo< dim >::Library
227 typedef Alberta::ElementInfo< dim > ElementInfo;
229 static const int maxLevelNeighbors = (1 << (dim-1));
232 leafNeighbor (
const ElementInfo &element,
const int face, ElementInfo &neighbor );
235 levelNeighbors (
const ElementInfo &element,
const int face,
236 ElementInfo (&neighbor)[ maxLevelNeighbors ],
int (&faceInNeighbor)[ maxLevelNeighbors ] );
240 macroNeighbor (
const ElementInfo &element,
const int face, ElementInfo &neighbor );
249 struct ElementInfo< dim >::Seed
252 : macroIndex_( -1 ), level_( 0 ), path_( 0 )
255 Seed (
const int macroIndex,
const int level,
const unsigned long path )
256 : macroIndex_( macroIndex ), level_( level ), path_( path )
261 return (macroIndex() == other.macroIndex()) && (level() == other.level()) && (path() == other.path());
264 bool operator< (
const Seed &other )
const
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)));
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); }
279 bool isValid ( )
const {
return macroIndex_ != -1; }
281 int macroIndex ()
const {
return macroIndex_; }
282 int level ()
const {
return level_; }
283 unsigned long path ()
const {
return path_; }
297 inline ElementInfo< dim >::ElementInfo (
const InstancePtr &instance )
298 : instance_( instance )
305 inline ElementInfo< dim >::ElementInfo ()
306 : instance_( null() )
313 inline ElementInfo< dim >
314 ::ElementInfo (
const MeshPointer &mesh,
const MacroElement ¯oElement,
315 typename FillFlags::Flags fillFlags )
317 instance_ = stack().allocate();
318 instance_->parent() = null();
319 ++(instance_->parent()->refCount);
323 elInfo().fill_flag = fillFlags;
326 for(
int k = 0; k < maxNeighbors; ++k )
327 elInfo().opp_vertex[ k ] = -1;
329 fill( mesh, ¯oElement, elInfo() );
334 inline ElementInfo< dim >
335 ::ElementInfo (
const MeshPointer &mesh,
const Seed &seed,
336 typename FillFlags::Flags fillFlags )
338 instance_ = stack().allocate();
339 instance_->parent() = null();
340 ++(instance_->parent()->refCount);
345 elInfo().fill_flag = fillFlags;
348 for(
int k = 0; k < maxNeighbors; ++k )
349 elInfo().opp_vertex[ k ] = -1;
351 fill( mesh, ((Mesh *)mesh)->macro_els + seed.macroIndex(), elInfo() );
354 unsigned long path = seed.path();
355 for(
int i = 0; i < seed.level(); ++i )
357 InstancePtr child = stack().allocate();
358 child->parent() = instance_;
361 for(
int k = 0; k < maxNeighbors; ++k )
362 child->elInfo.opp_vertex[ k ] = -2;
364 fill( path & 1, elInfo(), child->elInfo );
372 assert( this->seed() == seed );
377 inline ElementInfo< dim >::ElementInfo (
const ElementInfo &other )
378 : instance_( other.instance_ )
385 inline ElementInfo< dim >::~ElementInfo ()
392 inline ElementInfo< dim > &
393 ElementInfo< dim >::operator= (
const ElementInfo< dim > &other )
395 other.addReference();
397 instance_ = other.instance_;
406 return (instance_->elInfo.el == other.instance_->elInfo.el);
414 return (instance_->elInfo.el != other.instance_->elInfo.el);
419 inline const typename ElementInfo< dim >::MacroElement &
420 ElementInfo< dim >::macroElement ()
const
423 assert( elInfo().macro_el != NULL );
424 return static_cast< const MacroElement &
>( *(elInfo().macro_el) );
429 inline ElementInfo< dim > ElementInfo< dim >::father ()
const
432 return ElementInfo< dim >( instance_->parent() );
437 inline int ElementInfo< dim >::indexInFather ()
const
439 const Element *element = elInfo().el;
440#if DUNE_ALBERTA_VERSION >= 0x300
441 const Element *father = elInfo().parent->el;
443 const Element *father = elInfo().parent;
445 assert( father != NULL );
447 const int index = (father->child[ 0 ] == element ? 0 : 1);
448 assert( father->child[ index ] == element );
454 inline ElementInfo< dim > ElementInfo< dim >::child (
int i )
const
458 InstancePtr child = stack().allocate();
459 child->parent() = instance_;
463 for(
int k = 0; k < maxNeighbors; ++k )
464 child->elInfo.opp_vertex[ k ] = -2;
466 fill( i, elInfo(), child->elInfo );
467 return ElementInfo< dim >( child );
472 inline bool ElementInfo< dim >::isLeaf ()
const
474 assert( !(*
this) ==
false );
475 return isLeaf( el() );
480 inline typename ElementInfo< dim >::Seed ElementInfo< dim >::seed ()
const
485 unsigned long path = 0;
486 for( InstancePtr p = instance_; p->parent() != null(); p = p->parent() )
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;
495 if( level != elInfo().level )
496 DUNE_THROW( NotImplemented,
"Seed for fake elements not implemented." );
498 return Seed( macroElement().index, level, path );
503 inline typename ElementInfo< dim >::MeshPointer ElementInfo< dim >::mesh ()
const
505 return MeshPointer( elInfo().mesh );
510 inline bool ElementInfo< dim >::mightVanish ()
const
512 return mightVanish( el(), 0 );
517 inline int ElementInfo< dim >::level ()
const
519 return elInfo().level;
524 inline int ElementInfo< dim >::type ()
const
531 inline int ElementInfo< 3 >::type ()
const
533 return instance_->elInfo.el_type;
538 inline int ElementInfo< dim >::getMark ()
const
545 inline void ElementInfo< dim >::setMark (
int refCount )
const
548 assert( (refCount >= -128) && (refCount < 127) );
549 el()->mark = refCount;
553#if DUNE_ALBERTA_VERSION >= 0x300
555 inline bool ElementInfo< dim >::hasLeafNeighbor (
const int face )
const
558 assert( (face >= 0) && (face < maxNeighbors) );
560 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
561 const int macroFace = elInfo().macro_wall[ face ];
563 return (macroElement().neighbor( macroFace ) != NULL);
569#if DUNE_ALBERTA_VERSION < 0x300
571 inline bool ElementInfo< dim >::hasLeafNeighbor (
const int face )
const
573 return (neighbor( face ) != NULL);
579 inline ElementInfo< dim > ElementInfo< dim >::leafNeighbor (
const int face )
const
581 assert( (face >= 0) && (face < numFaces) );
582 ElementInfo neighbor;
583 Library< dimWorld >::leafNeighbor( *
this, face, neighbor );
589 inline int ElementInfo< dim >
590 ::levelNeighbors (
const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ],
int (&faceInNeighbor)[ maxLevelNeighbors ] )
const
592 assert( (face >= 0) && (face < numFaces) );
593 return Library< dimWorld >::levelNeighbors( *
this, face, neighbor, faceInNeighbor );
598 template<
int codim >
599 inline int ElementInfo< dim >::twist (
int subEntity )
const
601 return Twist< dim, dim-codim >::twist( element(), subEntity );
606 inline int ElementInfo< dim >::twistInNeighbor (
const int face )
const
608 assert( neighbor( face ) != NULL );
609 return Twist< dim, dim-1 >::twist( neighbor( face ), elInfo().opp_vertex[ face ] );
613#if DUNE_ALBERTA_VERSION >= 0x300
615 inline bool ElementInfo< dim >::isBoundary (
int face )
const
618 assert( (face >= 0) && (face < maxNeighbors) );
620 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
621 const int macroFace = elInfo().macro_wall[ face ];
623 return macroElement().isBoundary( macroFace );
629#if DUNE_ALBERTA_VERSION <= 0x200
631 inline bool ElementInfo< dim >::isBoundary (
int face )
const
634 assert( (face >= 0) && (face < maxNeighbors) );
635 return (elInfo().neigh[ face ] == 0);
640#if DUNE_ALBERTA_VERSION >= 0x300
642 inline int ElementInfo< dim >::boundaryId (
int face )
const
645 assert( (face >= 0) && (face < N_WALLS_MAX) );
647 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
648 const int macroFace = elInfo().macro_wall[ face ];
649 const int id = macroElement().boundaryId( macroFace );
657#if DUNE_ALBERTA_VERSION == 0x200
659 inline int ElementInfo< 1 >::boundaryId (
int face )
const
662 assert( (face >= 0) && (face < N_VERTICES_MAX) );
663 return elInfo().vertex_bound[ 1-face ];
667 inline int ElementInfo< 2 >::boundaryId (
int face )
const
670 assert( (face >= 0) && (face < N_EDGES_MAX) );
671 return elInfo().edge_bound[ face ];
675 inline int ElementInfo< 3 >::boundaryId (
int face )
const
678 assert( (face >= 0) && (face < N_FACES_MAX) );
679 return elInfo().face_bound[ face ];
684#if DUNE_ALBERTA_VERSION >= 0x300
686 inline AffineTransformation *
687 ElementInfo< dim >::transformation (
int face )
const
690 assert( (face >= 0) && (face < N_WALLS_MAX) );
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 ]);
698#if DUNE_ALBERTA_VERSION <= 0x200
700 inline AffineTransformation *
701 ElementInfo< dim >::transformation (
int face )
const
708#if DUNE_ALBERTA_VERSION >= 0x300
710 inline BasicNodeProjection *
711 ElementInfo< dim >::boundaryProjection (
int face )
const
714 assert( (face >= 0) && (face < N_WALLS_MAX) );
716 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
717 const int macroFace = elInfo().macro_wall[ face ];
719 return static_cast< BasicNodeProjection *
>( macroElement().projection[ macroFace+1 ] );
725#if DUNE_ALBERTA_VERSION <= 0x200
727 inline BasicNodeProjection *
728 ElementInfo< dim >::boundaryProjection (
int face )
const
731 assert( (face >= 0) && (face < maxNeighbors) );
732 const int idx = (dim == 1 ? 2-face : 1+face);
733 return static_cast< BasicNodeProjection *
>( elInfo().projections[ idx ] );
739 inline bool ElementInfo< dim >::hasCoordinates ()
const
741 return ((elInfo().fill_flag & FillFlags::coords) != 0);
745 inline const GlobalVector &ElementInfo< dim >::coordinate (
int vertex )
const
747 assert( hasCoordinates() );
748 assert( (vertex >= 0) && (vertex < numVertices) );
749 return elInfo().coord[ vertex ];
754 template<
class Functor >
755 inline void ElementInfo< dim >::hierarchicTraverse ( Functor &functor )
const
760 child( 0 ).hierarchicTraverse( functor );
761 child( 1 ).hierarchicTraverse( functor );
767 template<
class Functor >
768 inline void ElementInfo< dim >::leafTraverse ( Functor &functor )
const
772 child( 0 ).leafTraverse( functor );
773 child( 1 ).leafTraverse( functor );
781 inline const Element *ElementInfo< dim >::element ()
const
788 inline const Element *ElementInfo< dim >::neighbor (
int face )
const
790 assert( (face >= 0) && (face < numFaces) );
791 assert( (elInfo().fill_flag & FillFlags::neighbor) != 0 );
792 return elInfo().neigh[ face ];
797 inline Element *ElementInfo< dim >::el ()
const
804 inline ALBERTA EL_INFO &ElementInfo< dim >::elInfo ()
const
806 return (instance_->elInfo);
811 inline ElementInfo< dim >
812 ElementInfo< dim >::createFake (
const MeshPointer &mesh,
813 const Element *element,
int level,
int type )
815 InstancePtr instance = stack().allocate();
816 instance->parent() = null();
817 ++(instance->parent()->refCount);
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;
827 return ElementInfo< dim >( instance );
832 inline ElementInfo< dim >
833 ElementInfo< dim >::createFake (
const ALBERTA EL_INFO &elInfo )
835 InstancePtr instance = stack().allocate();
836 instance->parent() = null();
837 ++(instance->parent()->refCount);
839 instance->elInfo = elInfo;
840 return ElementInfo< dim >( instance );
845 inline bool ElementInfo< dim >::isLeaf ( Element *element )
847 return IS_LEAF_EL( element );
852 inline bool ElementInfo< dim >::mightVanish ( Alberta::Element *element,
int depth )
854 if( isLeaf( element ) )
855 return (element->mark < depth);
857 return (mightVanish( element->child[ 0 ], depth-1 ) && mightVanish( element->child[ 1 ], depth-1 ));
862 inline void ElementInfo< dim >
863 ::fill ( Mesh *mesh,
const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo )
865 ALBERTA fill_macro_info( mesh, mel, &elInfo );
867#if DUNE_ALBERTA_VERSION < 0x300
869 if( (dim == 1) && (elInfo.fill_flag & FILL_PROJECTION) )
871 for(
int i = 0; i <= N_VERTICES_1D; ++i )
872 elInfo.projections[ i ] = mel->projection[ i ];
878 inline void ElementInfo< dim >
879 ::fill (
int ichild,
const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo )
881#if DUNE_ALBERTA_VERSION >= 0x300
882 ALBERTA fill_elinfo( ichild, FILL_ANY, &parentInfo, &elInfo );
884 ALBERTA fill_elinfo( ichild, &parentInfo, &elInfo );
887 if( (dim == 1) && (elInfo.fill_flag & FILL_PROJECTION) )
889 elInfo.projections[ 0 ] = parentInfo.projections[ 0 ];
892 elInfo.projections[ 1 ] = parentInfo.projections[ 0 ];
893 elInfo.projections[ 2 ] = parentInfo.projections[ 2 ];
897 elInfo.projections[ 1 ] = parentInfo.projections[ 1 ];
898 elInfo.projections[ 2 ] = parentInfo.projections[ 0 ];
906 inline void ElementInfo< dim >::addReference ()
const
908 ++(instance_->refCount);
913 inline void ElementInfo< dim >::removeReference ()
const
916 for( InstancePtr instance = instance_; --(instance->refCount) == 0; )
918 const InstancePtr parent = instance->parent();
919 stack().release( instance );
926 inline typename ElementInfo< dim >::InstancePtr
927 ElementInfo< dim >::null ()
929 return stack().null();
934 inline typename ElementInfo< dim >::Stack &
935 ElementInfo< dim >::stack ()
947 inline ElementInfo< dim >::Stack::Stack ()
950 null_.elInfo.el = NULL;
957 inline ElementInfo< dim >::Stack::~Stack ()
961 InstancePtr p = top_;
969 inline typename ElementInfo< dim >::InstancePtr
970 ElementInfo< dim >::Stack::allocate ()
972 InstancePtr p = top_;
983 inline void ElementInfo< dim >::Stack::release ( InstancePtr &p )
985 assert( (p != null()) && (p->refCount == 0) );
992 inline typename ElementInfo< dim >::InstancePtr
993 ElementInfo< dim >::Stack::null ()
#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