5#ifndef DUNE_ALBERTA_ELEMENTINFO_HH
6#define DUNE_ALBERTA_ELEMENTINFO_HH
17#include <dune/grid/albertagrid/geometrycache.hh>
18#include <dune/grid/albertagrid/macroelement.hh>
34 struct BasicNodeProjection;
50 typedef Instance *InstancePtr;
53 static const int dimension = dim;
55 static const int numVertices = NumSubEntities< dimension, dimension >::value;
56 static const int numFaces = NumSubEntities< dimension, 1 >::value;
58 typedef Alberta::MacroElement< dimension > MacroElement;
59 typedef Alberta::MeshPointer< dimension > MeshPointer;
60 typedef Alberta::FillFlags< dimension > FillFlags;
62 static const int maxNeighbors = N_NEIGH_MAX;
64 static const int maxLevelNeighbors = Library< dimWorld >::maxLevelNeighbors;
66#if !DUNE_ALBERTA_CACHE_COORDINATES
67 typedef GeometryCacheProxy< dim > GeometryCache;
73 explicit ElementInfo (
const InstancePtr &instance );
77 ElementInfo (
const MeshPointer &mesh,
const MacroElement ¯oElement,
78 typename FillFlags::Flags fillFlags = FillFlags::standard );
79 ElementInfo (
const MeshPointer &mesh,
const Seed &seed,
80 typename FillFlags::Flags fillFlags = FillFlags::standard );
81 ElementInfo (
const ElementInfo &other );
82 ElementInfo ( ElementInfo&& other );
86 ElementInfo &operator= (
const ElementInfo &other );
87 ElementInfo &operator= ( ElementInfo &&other );
89 explicit operator bool ()
const {
return (instance_ != null()); }
91 bool operator== (
const ElementInfo &other )
const;
92 bool operator!= (
const ElementInfo &other )
const;
94 const MacroElement ¯oElement ()
const;
95 ElementInfo father ()
const;
96 int indexInFather ()
const;
97 ElementInfo
child (
int i )
const;
102 MeshPointer mesh ()
const;
104 bool mightVanish ()
const;
111 int getMark ()
const;
112 void setMark (
int refCount )
const;
114 bool hasLeafNeighbor (
const int face )
const;
115 ElementInfo leafNeighbor (
const int face )
const;
127 int levelNeighbors (
const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ],
int (&faceInNeighbor)[ maxLevelNeighbors ] )
const;
129 template<
int codim >
130 int twist (
int subEntity )
const;
131 int twistInNeighbor (
int face )
const;
132 bool isBoundary (
int face )
const;
133 int boundaryId (
int face )
const;
134 AffineTransformation *transformation (
int face )
const;
135 BasicNodeProjection *boundaryProjection (
int face )
const;
137 bool hasCoordinates ()
const;
138 const GlobalVector &coordinate (
int vertex )
const;
139#if !DUNE_ALBERTA_CACHE_COORDINATES
140 GeometryCache geometryCache ()
const
142 return GeometryCache( instance_->geometryCache, instance_->elInfo );
146 template<
class Functor >
147 void hierarchicTraverse ( Functor &functor )
const;
149 template<
class Functor >
150 void leafTraverse ( Functor &functor )
const;
152 const Element *element ()
const;
153 const Element *neighbor (
int face )
const;
154 Element *el ()
const;
155 ALBERTA EL_INFO &elInfo ()
const;
158 createFake (
const MeshPointer &mesh,
159 const Element *element,
int level,
int type = 0 );
160 static ElementInfo createFake (
const ALBERTA EL_INFO &elInfo );
163 static bool isLeaf ( Element *element );
164 static bool mightVanish ( Element *element,
int depth );
166 static void fill ( Mesh *mesh,
const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo );
167 static void fill (
int ichild,
const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo );
169 void addReference ()
const;
170 void removeReference ()
const;
172 static InstancePtr null ();
173 static Stack &stack ();
175 InstancePtr instance_;
184 struct ElementInfo< dim >::Instance
186 ALBERTA EL_INFO elInfo;
187 unsigned int refCount;
189 InstancePtr &parent ()
197#if !DUNE_ALBERTA_CACHE_COORDINATES
199 Alberta::GeometryCache< dim > geometryCache;
209 class ElementInfo< dim >::Stack
218 InstancePtr allocate ();
219 void release ( InstancePtr &p );
230 struct ElementInfo< dim >::Library
232 typedef Alberta::ElementInfo< dim > ElementInfo;
234 static const int maxLevelNeighbors = (1 << (dim-1));
237 leafNeighbor (
const ElementInfo &element,
const int face, ElementInfo &neighbor );
240 levelNeighbors (
const ElementInfo &element,
const int face,
241 ElementInfo (&neighbor)[ maxLevelNeighbors ],
int (&faceInNeighbor)[ maxLevelNeighbors ] );
245 macroNeighbor (
const ElementInfo &element,
const int face, ElementInfo &neighbor );
254 struct ElementInfo< dim >::Seed
257 : macroIndex_( -1 ), level_( 0 ), path_( 0 )
260 Seed (
const int macroIndex,
const int level,
const unsigned long path )
261 : macroIndex_( macroIndex ), level_( level ), path_( path )
266 return (macroIndex() == other.macroIndex()) && (level() == other.level()) && (path() == other.path());
269 bool operator< (
const Seed &other )
const
271 const bool ml = (macroIndex() < other.macroIndex());
272 const bool me = (macroIndex() == other.macroIndex());
273 const bool ll = (level() < other.level());
274 const bool le = (level() == other.level());
275 const bool pl = (path() < other.path());
276 return ml | (me & (ll | (
le & pl)));
279 bool operator!= (
const Seed &other )
const {
return !(*
this == other); }
280 bool operator<= (
const Seed &other )
const {
return !(other < *
this); }
281 bool operator> (
const Seed &other )
const {
return (other < *
this); }
282 bool operator>= (
const Seed &other )
const {
return !(*
this < other); }
284 bool isValid ( )
const {
return macroIndex_ != -1; }
286 int macroIndex ()
const {
return macroIndex_; }
287 int level ()
const {
return level_; }
288 unsigned long path ()
const {
return path_; }
302 inline ElementInfo< dim >::ElementInfo (
const InstancePtr &instance )
303 : instance_( instance )
310 inline ElementInfo< dim >::ElementInfo ()
311 : instance_( null() )
318 inline ElementInfo< dim >
319 ::ElementInfo (
const MeshPointer &mesh,
const MacroElement ¯oElement,
320 typename FillFlags::Flags fillFlags )
322 instance_ = stack().allocate();
323 instance_->parent() = null();
324 ++(instance_->parent()->refCount);
328 elInfo().fill_flag = fillFlags;
331 for(
int k = 0; k < maxNeighbors; ++k )
332 elInfo().opp_vertex[ k ] = -1;
334 fill( mesh, ¯oElement, elInfo() );
339 inline ElementInfo< dim >
340 ::ElementInfo (
const MeshPointer &mesh,
const Seed &seed,
341 typename FillFlags::Flags fillFlags )
343 instance_ = stack().allocate();
344 instance_->parent() = null();
345 ++(instance_->parent()->refCount);
350 elInfo().fill_flag = fillFlags;
353 for(
int k = 0; k < maxNeighbors; ++k )
354 elInfo().opp_vertex[ k ] = -1;
356 fill( mesh, ((Mesh *)mesh)->macro_els + seed.macroIndex(), elInfo() );
359 unsigned long path = seed.path();
360 for(
int i = 0; i < seed.level(); ++i )
362 InstancePtr
child = stack().allocate();
363 child->parent() = instance_;
366 for(
int k = 0; k < maxNeighbors; ++k )
367 child->elInfo.opp_vertex[ k ] = -2;
369 fill( path & 1, elInfo(),
child->elInfo );
377 assert( this->seed() == seed );
382 inline ElementInfo< dim >::ElementInfo (
const ElementInfo &other )
383 : instance_( other.instance_ )
389 inline ElementInfo< dim >::ElementInfo ( ElementInfo &&other )
393 swap( instance_, other.instance_ );
397 inline ElementInfo< dim >::~ElementInfo ()
404 inline ElementInfo< dim > &
405 ElementInfo< dim >::operator= (
const ElementInfo< dim > &other )
407 other.addReference();
409 instance_ = other.instance_;
414 inline ElementInfo< dim > &
415 ElementInfo< dim >::operator= ( ElementInfo< dim > &&other )
418 swap( instance_, other.instance_ );
426 return (instance_->elInfo.el == other.instance_->elInfo.el);
434 return (instance_->elInfo.el != other.instance_->elInfo.el);
439 inline const typename ElementInfo< dim >::MacroElement &
440 ElementInfo< dim >::macroElement ()
const
443 assert( elInfo().macro_el != NULL );
444 return static_cast< const MacroElement &
>( *(elInfo().macro_el) );
449 inline ElementInfo< dim > ElementInfo< dim >::father ()
const
452 return ElementInfo< dim >( instance_->parent() );
457 inline int ElementInfo< dim >::indexInFather ()
const
459 const Element *element = elInfo().el;
460 const Element *father = elInfo().parent->el;
461 assert( father != NULL );
463 const int index = (father->child[ 0 ] == element ? 0 : 1);
464 assert( father->child[ index ] == element );
474 InstancePtr
child = stack().allocate();
475 child->parent() = instance_;
479 for(
int k = 0; k < maxNeighbors; ++k )
480 child->elInfo.opp_vertex[ k ] = -2;
482 fill( i, elInfo(),
child->elInfo );
483 return ElementInfo< dim >(
child );
488 inline bool ElementInfo< dim >::isLeaf ()
const
490 assert( !(*
this) ==
false );
491 return isLeaf( el() );
496 inline typename ElementInfo< dim >::Seed ElementInfo< dim >::seed ()
const
501 unsigned long path = 0;
502 for( InstancePtr p = instance_; p->parent() != null(); p = p->parent() )
504 const Element *element = p->elInfo.el;
505 const Element *father = p->parent()->elInfo.el;
506 const unsigned long child =
static_cast< unsigned long >( father->child[ 1 ] == element );
507 path = (path << 1) |
child;
511 if( level != elInfo().level )
512 DUNE_THROW( NotImplemented,
"Seed for fake elements not implemented." );
514 return Seed( macroElement().index, level, path );
519 inline typename ElementInfo< dim >::MeshPointer ElementInfo< dim >::mesh ()
const
521 return MeshPointer( elInfo().mesh );
526 inline bool ElementInfo< dim >::mightVanish ()
const
528 return mightVanish( el(), 0 );
533 inline int ElementInfo< dim >::level ()
const
535 return elInfo().level;
540 inline int ElementInfo< dim >::type ()
const
547 inline int ElementInfo< 3 >::type ()
const
549 return instance_->elInfo.el_type;
554 inline int ElementInfo< dim >::getMark ()
const
561 inline void ElementInfo< dim >::setMark (
int refCount )
const
564 assert( (refCount >= -128) && (refCount < 127) );
565 el()->mark = refCount;
570 inline bool ElementInfo< dim >::hasLeafNeighbor (
const int face )
const
573 assert( (face >= 0) && (face < maxNeighbors) );
575 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
576 const int macroFace = elInfo().macro_wall[ face ];
578 return (macroElement().neighbor( macroFace ) != NULL);
585 inline ElementInfo< dim > ElementInfo< dim >::leafNeighbor (
const int face )
const
587 assert( (face >= 0) && (face < numFaces) );
588 ElementInfo neighbor;
589 Library< dimWorld >::leafNeighbor( *
this, face, neighbor );
595 inline int ElementInfo< dim >
596 ::levelNeighbors (
const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ],
int (&faceInNeighbor)[ maxLevelNeighbors ] )
const
598 assert( (face >= 0) && (face < numFaces) );
599 return Library< dimWorld >::levelNeighbors( *
this, face, neighbor, faceInNeighbor );
604 template<
int codim >
605 inline int ElementInfo< dim >::twist (
int subEntity )
const
607 return Twist< dim, dim-codim >::twist( element(), subEntity );
612 inline int ElementInfo< dim >::twistInNeighbor (
const int face )
const
614 assert( neighbor( face ) != NULL );
615 return Twist< dim, dim-1 >::twist( neighbor( face ), elInfo().opp_vertex[ face ] );
620 inline bool ElementInfo< dim >::isBoundary (
int face )
const
623 assert( (face >= 0) && (face < maxNeighbors) );
625 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
626 const int macroFace = elInfo().macro_wall[ face ];
628 return macroElement().isBoundary( macroFace );
635 inline int ElementInfo< dim >::boundaryId (
int face )
const
638 assert( (face >= 0) && (face < N_WALLS_MAX) );
640 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
641 const int macroFace = elInfo().macro_wall[ face ];
642 const int id = macroElement().boundaryId( macroFace );
650 inline AffineTransformation *
651 ElementInfo< dim >::transformation (
int face )
const
654 assert( (face >= 0) && (face < N_WALLS_MAX) );
656 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
657 const int macroFace = elInfo().macro_wall[ face ];
658 return (macroFace < 0 ? NULL : macroElement().wall_trafo[ macroFace ]);
663 inline BasicNodeProjection *
664 ElementInfo< dim >::boundaryProjection (
int face )
const
667 assert( (face >= 0) && (face < N_WALLS_MAX) );
669 assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
670 const int macroFace = elInfo().macro_wall[ face ];
672 return static_cast< BasicNodeProjection *
>( macroElement().projection[ macroFace+1 ] );
679 inline bool ElementInfo< dim >::hasCoordinates ()
const
681 return ((elInfo().fill_flag & FillFlags::coords) != 0);
685 inline const GlobalVector &ElementInfo< dim >::coordinate (
int vertex )
const
687 assert( hasCoordinates() );
689 return elInfo().coord[
vertex ];
694 template<
class Functor >
695 inline void ElementInfo< dim >::hierarchicTraverse ( Functor &functor )
const
700 child( 0 ).hierarchicTraverse( functor );
701 child( 1 ).hierarchicTraverse( functor );
707 template<
class Functor >
708 inline void ElementInfo< dim >::leafTraverse ( Functor &functor )
const
712 child( 0 ).leafTraverse( functor );
713 child( 1 ).leafTraverse( functor );
721 inline const Element *ElementInfo< dim >::element ()
const
728 inline const Element *ElementInfo< dim >::neighbor (
int face )
const
730 assert( (face >= 0) && (face < numFaces) );
731 assert( (elInfo().fill_flag & FillFlags::neighbor) != 0 );
732 return elInfo().neigh[ face ];
737 inline Element *ElementInfo< dim >::el ()
const
744 inline ALBERTA EL_INFO &ElementInfo< dim >::elInfo ()
const
746 return (instance_->elInfo);
751 inline ElementInfo< dim >
752 ElementInfo< dim >::createFake (
const MeshPointer &mesh,
753 const Element *element,
int level,
int type )
755 InstancePtr instance = stack().allocate();
756 instance->parent() = null();
757 ++(instance->parent()->refCount);
759 instance->elInfo.mesh = mesh;
760 instance->elInfo.macro_el = NULL;
761 instance->elInfo.el =
const_cast< Element *
>( element );
762 instance->elInfo.parent = NULL;
763 instance->elInfo.fill_flag = FillFlags::nothing;
764 instance->elInfo.level = level;
765 instance->elInfo.el_type = type;
767 return ElementInfo< dim >( instance );
772 inline ElementInfo< dim >
773 ElementInfo< dim >::createFake (
const ALBERTA EL_INFO &elInfo )
775 InstancePtr instance = stack().allocate();
776 instance->parent() = null();
777 ++(instance->parent()->refCount);
779 instance->elInfo = elInfo;
780 return ElementInfo< dim >( instance );
785 inline bool ElementInfo< dim >::isLeaf ( Element *element )
787 return IS_LEAF_EL( element );
792 inline bool ElementInfo< dim >::mightVanish ( Alberta::Element *element,
int depth )
794 if( isLeaf( element ) )
795 return (element->mark < depth);
797 return (mightVanish( element->child[ 0 ], depth-1 ) && mightVanish( element->child[ 1 ], depth-1 ));
802 inline void ElementInfo< dim >
803 ::fill ( Mesh *mesh,
const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo )
805 ALBERTA fill_macro_info( mesh, mel, &elInfo );
809 inline void ElementInfo< dim >
810 ::fill (
int ichild,
const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo )
812 ALBERTA fill_elinfo( ichild, FILL_ANY, &parentInfo, &elInfo );
817 inline void ElementInfo< dim >::addReference ()
const
819 ++(instance_->refCount);
824 inline void ElementInfo< dim >::removeReference ()
const
830 for( InstancePtr instance = instance_; --(instance->refCount) == 0; )
832 const InstancePtr parent = instance->parent();
833 stack().release( instance );
840 inline typename ElementInfo< dim >::InstancePtr
841 ElementInfo< dim >::null ()
843 return stack().null();
848 inline typename ElementInfo< dim >::Stack &
849 ElementInfo< dim >::stack ()
861 inline ElementInfo< dim >::Stack::Stack ()
864 null_.elInfo.el = NULL;
871 inline ElementInfo< dim >::Stack::~Stack ()
875 InstancePtr p = top_;
883 inline typename ElementInfo< dim >::InstancePtr
884 ElementInfo< dim >::Stack::allocate ()
886 InstancePtr p = top_;
897 inline void ElementInfo< dim >::Stack::release ( InstancePtr &p )
899 assert( (p != null()) && (p->refCount == 0) );
906 inline typename ElementInfo< dim >::InstancePtr
907 ElementInfo< dim >::Stack::null ()
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
bool le(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first lesser or equal second
Definition: float_cmp.cc:179
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:506
EnableIfInterOperable< T1, T2, bool >::type operator<(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:637
EnableIfInterOperable< T1, T2, bool >::type operator>(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:683
EnableIfInterOperable< T1, T2, bool >::type operator<=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:660
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:237
EnableIfInterOperable< T1, T2, bool >::type operator>=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:705
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:259
Dune namespace.
Definition: alignedallocator.hh:13