elementinfo.hh

Go to the documentation of this file.
00001 #ifndef DUNE_ALBERTA_ELEMENTINFO_HH
00002 #define DUNE_ALBERTA_ELEMENTINFO_HH
00003 
00009 #include <cassert>
00010 
00011 #include <dune/grid/albertagrid/misc.hh>
00012 
00013 #if HAVE_ALBERTA
00014 
00015 namespace Dune
00016 {
00017 
00018   namespace Alberta
00019   {
00020 
00021     // External Forward Declarations
00022     // -----------------------------
00023 
00024     template< int dim >
00025     class MeshPointer;
00026 
00027 
00028 
00029     // ElementInfo
00030     // -----------
00031 
00032     template< int dim >
00033     class ElementInfo
00034     {
00035       class Instance;
00036       class Stack;
00037 
00038       typedef Instance *InstancePtr;
00039 
00040     public:
00041       static const int dimension = dim;
00042 
00043       static const int numVertices = NumSubEntities< dimension, dimension >::value;
00044       static const int numFaces = NumSubEntities< dimension, 1 >::value;
00045 
00046       typedef Alberta::MeshPointer< dimension > MeshPointer;
00047       typedef Alberta::FillFlags< dimension > FillFlags;
00048 
00049 #if DUNE_ALBERTA_VERSION >= 0x200
00050       static const int maxNeighbors = N_NEIGH_MAX;
00051 #else
00052       static const int maxNeighbors = N_NEIGH;
00053 #endif
00054 
00055       typedef ElementInfo< dimension > LevelNeighborSet[ 1 << dimension ];
00056 
00057     private:
00058       InstancePtr instance_;
00059 
00060       explicit ElementInfo ( const InstancePtr &instance );
00061 
00062     public:
00063       ElementInfo ();
00064       ElementInfo ( const MeshPointer &mesh, const MacroElement &macroElement,
00065                     typename FillFlags::Flags fillFlags = FillFlags::standard );
00066       ElementInfo ( const ElementInfo &other );
00067 
00068       ~ElementInfo ();
00069 
00070       ElementInfo &operator= ( const ElementInfo &other );
00071 
00072       bool operator! () const;
00073       bool operator== ( const ElementInfo &other ) const;
00074       bool operator!= ( const ElementInfo &other ) const;
00075 
00076       ElementInfo father () const;
00077       int indexInFather () const;
00078       ElementInfo child ( int i ) const;
00079       bool isLeaf () const;
00080 
00081       MeshPointer mesh () const;
00082 
00083       bool mightVanish () const;
00084 
00085       int level () const;
00086       // see ALBERTA documentation for definition of element type
00087       // values are 0, 1, 2
00088       int type () const;
00089 
00090       int getMark () const;
00091       void setMark ( int refCount ) const;
00092 
00093       ElementInfo leafNeighbor ( int face ) const;
00094       int twistInSelf ( int face ) const;
00095       int twistInNeighbor ( int face ) const;
00096       bool isBoundary ( int face ) const;
00097       int boundaryId ( int face ) const;
00098       AffineTransformation *transformation ( int face ) const;
00099 
00100       bool hasCoordinates () const;
00101       const GlobalVector &coordinate ( int vertex ) const;
00102 
00103       template< class Functor >
00104       void hierarchicTraverse ( Functor &functor ) const;
00105 
00106       template< class Functor >
00107       void leafTraverse ( Functor &functor ) const;
00108 
00109       const Element *element () const;
00110       const Element *neighbor ( int face ) const;
00111       Element *el () const;
00112       ALBERTA EL_INFO &elInfo () const;
00113 
00114       static ElementInfo
00115       createFake ( const MeshPointer &mesh,
00116                    const Element *element, int level, int type = 0 );
00117       static ElementInfo createFake ( const ALBERTA EL_INFO &elInfo );
00118 
00119     private:
00120       static bool isLeaf ( Element *element );
00121       static bool mightVanish ( Element *element, int depth );
00122 
00123       int macroNeighbor ( int face, ElementInfo &neighbor ) const;
00124       int leafNeighbor ( const int face, ElementInfo &neighbor ) const;
00125 
00126       void addReference () const;
00127       void removeReference () const;
00128 
00129       static InstancePtr null ();
00130       static Stack &stack ();
00131     };
00132 
00133 
00134 
00135     // ElementInfo::Instance
00136     // ---------------------
00137 
00138     template< int dim >
00139     struct ElementInfo< dim >::Instance
00140     {
00141       ALBERTA EL_INFO elInfo;
00142       unsigned int refCount;
00143 
00144       InstancePtr &parent ()
00145       {
00146         return parent_;
00147       }
00148 
00149     private:
00150       InstancePtr parent_;
00151     };
00152 
00153 
00154 
00155     // ElementInfo::Stack
00156     // ------------------
00157 
00158     template< int dim >
00159     class ElementInfo< dim >::Stack
00160     {
00161       InstancePtr top_;
00162       Instance null_;
00163 
00164     public:
00165       Stack ();
00166       ~Stack ();
00167 
00168       InstancePtr allocate ();
00169       void release ( InstancePtr &p );
00170       InstancePtr null ();
00171     };
00172 
00173 
00174 
00175     // Implementation of ElementInfo
00176     // -----------------------------
00177 
00178     template< int dim >
00179     inline ElementInfo< dim >::ElementInfo ( const InstancePtr &instance )
00180     : instance_( instance )
00181     {
00182       addReference();
00183     }
00184 
00185 
00186     template< int dim >
00187     inline ElementInfo< dim >::ElementInfo ()
00188     : instance_( null() )
00189     {
00190       addReference();
00191     }
00192 
00193 
00194     template< int dim >
00195     inline ElementInfo< dim >
00196       ::ElementInfo ( const MeshPointer &mesh, const MacroElement &macroElement,
00197                       typename FillFlags::Flags fillFlags )
00198     {
00199       instance_ = stack().allocate();
00200       instance_->parent() = null();
00201       ++(instance_->parent()->refCount);
00202 
00203       addReference();
00204 
00205       elInfo().fill_flag = fillFlags;
00206 
00207       // Alberta fills opp_vertex only if there is a neighbor
00208       for( int k = 0; k < maxNeighbors; ++k )
00209         elInfo().opp_vertex[ k ] = -1;
00210 
00211       fill_macro_info( mesh, &macroElement, &elInfo() );
00212     }
00213 
00214 
00215     template< int dim >
00216     inline ElementInfo< dim >::ElementInfo ( const ElementInfo &other )
00217     : instance_( other.instance_ )
00218     {
00219       addReference();
00220     }
00221 
00222 
00223     template< int dim >
00224     inline ElementInfo< dim >::~ElementInfo ()
00225     {
00226       removeReference();
00227     }
00228 
00229 
00230     template< int dim >
00231     inline ElementInfo< dim > &
00232     ElementInfo< dim >::operator= ( const ElementInfo< dim > &other )
00233     {
00234       other.addReference();
00235       removeReference();
00236       instance_ = other.instance_;
00237       return *this;
00238     }
00239 
00240 
00241     template< int dim >
00242     inline bool ElementInfo< dim >::operator! () const
00243     {
00244       return (instance_ == null());
00245     }
00246 
00247 
00248     template< int dim >
00249     inline bool
00250     ElementInfo< dim >::operator== ( const ElementInfo< dim > &other ) const
00251     {
00252       return (instance_->elInfo.el == other.instance_->elInfo.el);
00253     }
00254 
00255 
00256     template< int dim >
00257     inline bool
00258     ElementInfo< dim >::operator!= ( const ElementInfo< dim > &other ) const
00259     {
00260       return (instance_->elInfo.el != other.instance_->elInfo.el);
00261     }
00262 
00263 
00264     template< int dim >
00265     inline ElementInfo< dim > ElementInfo< dim >::father () const
00266     {
00267       assert( !!(*this) );
00268       return ElementInfo< dim >( instance_->parent() );
00269     }
00270 
00271 
00272     template< int dim >
00273     inline int ElementInfo< dim >::indexInFather () const
00274     {
00275       const Element *element = elInfo().el;
00276 #if DUNE_ALBERTA_VERSION >= 0x201
00277       const Element *father = elInfo().parent->el;
00278 #else
00279       const Element *father = elInfo().parent;
00280 #endif
00281       assert( father != NULL );
00282 
00283       const int index = (father->child[ 0 ] == element ? 0 : 1);
00284       assert( father->child[ index ] == element );
00285       return index;
00286     }
00287 
00288 
00289     template< int dim >
00290     inline ElementInfo< dim > ElementInfo< dim >::child ( int i ) const
00291     {
00292       assert( !isLeaf() );
00293 
00294       InstancePtr child = stack().allocate();
00295       child->parent() = instance_;
00296       addReference();
00297 
00298       // Alberta fills opp_vertex only if there is a neighbor
00299       for( int k = 0; k < maxNeighbors; ++k )
00300         child->elInfo.opp_vertex[ k ] = -2;
00301 
00302 #if DUNE_ALBERTA_VERSION >= 0x201
00303       ALBERTA fill_elinfo( i, FILL_ANY, &elInfo(), &(child->elInfo) );
00304 #else
00305       ALBERTA fill_elinfo( i, &elInfo(), &(child->elInfo) );
00306 #endif
00307 
00308       return ElementInfo< dim >( child );
00309     }
00310 
00311 
00312     template< int dim >
00313     inline bool ElementInfo< dim >::isLeaf () const
00314     {
00315       assert( !(*this) == false );
00316       return isLeaf( el() );
00317     }
00318 
00319 
00320     template< int dim >
00321     inline typename ElementInfo< dim >::MeshPointer ElementInfo< dim >::mesh () const
00322     {
00323       return MeshPointer( elInfo().mesh );
00324     }
00325 
00326 
00327     template< int dim >
00328     inline bool ElementInfo< dim >::mightVanish () const
00329     {
00330       return mightVanish( el(), 0 );
00331     }
00332 
00333 
00334     template< int dim >
00335     inline int ElementInfo< dim >::level () const
00336     {
00337       return instance_->elInfo.level;
00338     }
00339 
00340 
00341     template< int dim >
00342     inline int ElementInfo< dim >::type () const
00343     {
00344       return 0;
00345     }
00346 
00347 
00348 #if (DUNE_ALBERTA_VERSION >= 0x200) || (DIM == 3)
00349     template<>
00350     inline int ElementInfo< 3 >::type () const
00351     {
00352       return instance_->elInfo.el_type;
00353     }
00354 #endif
00355 
00356 
00357     template< int dim >
00358     inline int ElementInfo< dim >::getMark () const
00359     {
00360       return el()->mark;
00361     }
00362 
00363 
00364     template< int dim >
00365     inline void ElementInfo< dim >::setMark ( int refCount ) const
00366     {
00367       assert( isLeaf() );
00368       assert( (refCount >= -128) && (refCount < 127) );
00369       el()->mark = refCount;
00370     }
00371 
00372     
00373     template< int dim >
00374     inline ElementInfo< dim > ElementInfo< dim >::leafNeighbor ( int face ) const
00375     {
00376       assert( (face >= 0) && (face < numFaces) );
00377       ElementInfo neighbor;
00378       leafNeighbor( face, neighbor );
00379       return neighbor;
00380     }
00381 
00382 
00383     template< int dim >
00384     inline int ElementInfo< dim >::twistInSelf ( int face ) const
00385     {
00386       return Twist< dim >::faceTwist( element(), face );
00387     }
00388 
00389 
00390     template< int dim >
00391     inline int ElementInfo< dim >::twistInNeighbor ( const int face ) const
00392     {
00393       assert( neighbor( face ) != NULL );
00394       return Twist< dim >::faceTwist( neighbor( face ), elInfo().opp_vertex[ face ] );
00395     }
00396 
00397 
00398 #if DUNE_ALBERTA_VERSION >= 0x201
00399     template< int dim >
00400     inline bool ElementInfo< dim >::isBoundary ( int face ) const
00401     {
00402       assert( !!(*this) );
00403       assert( (face >= 0) && (face < maxNeighbors) );
00404 
00405       const int macroFace = elInfo().macro_wall[ face ];
00406       if( macroFace >= 0 )
00407       {
00408         const int id = elInfo().macro_el->wall_bound[ macroFace ];
00409         return (id != 0);
00410       }
00411       else
00412         return false;
00413     }
00414 #endif // DUNE_ALBERTA_VERSION >= 0x201
00415 
00416 #if DUNE_ALBERTA_VERSION <= 0x200
00417     template< int dim >
00418     inline bool ElementInfo< dim >::isBoundary ( int face ) const
00419     {
00420       assert( !!(*this) );
00421       assert( (face >= 0) && (face < maxNeighbors) );
00422       return (elInfo().neigh[ face ] == 0);
00423     }
00424 #endif // DUNE_ALBERTA_VERSION <= 0x200
00425 
00426 
00427 #if DUNE_ALBERTA_VERSION >= 0x201
00428     template< int dim >
00429     inline int ElementInfo< dim >::boundaryId ( int face ) const
00430     {
00431       assert( !!(*this) );
00432       assert( (face >= 0) && (face < N_WALLS_MAX) );
00433       
00434       const int macroFace = elInfo().macro_wall[ face ];
00435       const int id = elInfo().macro_el->wall_bound[ macroFace ];
00436       // this assertion is only allowed, if FILL_BOUND is set
00437       // assert( id == elInfo().wall_bound[ face ] );
00438       return id;
00439     }
00440 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00441 
00442 
00443 #if DUNE_ALBERTA_VERSION == 0x200
00444     template<>
00445     inline int ElementInfo< 1 >::boundaryId ( int face ) const
00446     {
00447       assert( !!(*this) );
00448       assert( (face >= 0) && (face < N_VERTICES_MAX) );
00449       return elInfo().vertex_bound[ face ];
00450     }
00451 
00452     template<>
00453     inline int ElementInfo< 2 >::boundaryId ( int face ) const
00454     {
00455       assert( !!(*this) );
00456       assert( (face >= 0) && (face < N_EDGES_MAX) );
00457       return elInfo().edge_bound[ face ];
00458     }
00459 
00460     template<>
00461     inline int ElementInfo< 3 >::boundaryId ( int face ) const
00462     {
00463       assert( !!(*this) );
00464       assert( (face >= 0) && (face < N_FACES_MAX) );
00465       return elInfo().face_bound[ face ];
00466     }
00467 #endif // #if DUNE_ALBERTA_VERSION == 0x200
00468 
00469 
00470 #if DUNE_ALBERTA_VERSION < 0x200
00471 #if DIM == 1
00472     template<>
00473     inline int ElementInfo< 1 >::boundaryId ( int face ) const
00474     {
00475       assert( !!(*this) );
00476       assert( (face >= 0) && (face < N_VERTICES) );
00477       return elInfo().bound[ face ];
00478     }
00479 #endif // #if DIM == 1
00480 
00481 #if DIM == 2
00482     template<>
00483     inline int ElementInfo< 2 >::boundaryId ( int face ) const
00484     {
00485       assert( !!(*this) );
00486       assert( (face >= 0) && (face < N_EDGES) );
00487       return elInfo().boundary[ face ]->bound;
00488     }
00489 #endif // #if DIM == 2
00490 
00491 #if DIM == 3
00492     template<>
00493     inline int ElementInfo< 3 >::boundaryId ( int face ) const
00494     {
00495       assert( !!(*this) );
00496       assert( (face >= 0) && (face < N_FACES) );
00497       return elInfo().boundary[ face ]->bound;
00498     }
00499 #endif // #if DIM == 3
00500 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00501 
00502 
00503 #if DUNE_ALBERTA_VERSION >= 0x201
00504     template< int dim >
00505     inline AffineTransformation *
00506     ElementInfo< dim >::transformation ( int face ) const
00507     {
00508       assert( !!(*this) );
00509       assert( (face >= 0) && (face < N_WALLS_MAX) );
00510       
00511       const int macroFace = elInfo().macro_wall[ face ];
00512       return (macroFace < 0 ? NULL : elInfo().macro_el->wall_trafo[ face ]);
00513     }
00514 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00515 
00516 #if DUNE_ALBERTA_VERSION <= 0x200
00517     template< int dim >
00518     inline AffineTransformation *
00519     ElementInfo< dim >::transformation ( int face ) const
00520     {
00521       return NULL;
00522     }
00523 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
00524 
00525 
00526     template< int dim >
00527     inline bool ElementInfo< dim >::hasCoordinates () const
00528     {
00529       return ((elInfo().fill_flag & FillFlags::coords) != 0);
00530     }
00531 
00532     template< int dim >
00533     inline const GlobalVector &ElementInfo< dim >::coordinate ( int vertex ) const
00534     {
00535       assert( hasCoordinates() );
00536       assert( (vertex >= 0) && (vertex < numVertices) );
00537       return elInfo().coord[ vertex ];
00538     }
00539 
00540 
00541     template< int dim >
00542     template< class Functor >
00543     void ElementInfo< dim >::hierarchicTraverse ( Functor &functor ) const
00544     {
00545       functor( *this );
00546       if( !isLeaf() )
00547       {
00548         child( 0 ).hierarchicTraverse( functor );
00549         child( 1 ).hierarchicTraverse( functor );
00550       }
00551     }
00552 
00553 
00554     template< int dim >
00555     template< class Functor >
00556     void ElementInfo< dim >::leafTraverse ( Functor &functor ) const
00557     {
00558       if( !isLeaf() )
00559       {
00560         child( 0 ).leafTraverse( functor );
00561         child( 1 ).leafTraverse( functor );
00562       }
00563       else
00564         functor( *this );
00565     }
00566 
00567 
00568     template< int dim >
00569     inline const Element *ElementInfo< dim >::element () const
00570     {
00571       return elInfo().el;
00572     }
00573 
00574 
00575     template< int dim >
00576     inline const Element *ElementInfo< dim >::neighbor ( int face ) const
00577     {
00578       assert( (face >= 0) && (face < numFaces) );
00579       assert( (elInfo().fill_flag & FillFlags::neighbor) != 0 );
00580       return elInfo().neigh[ face ];
00581     }
00582 
00583 
00584     template< int dim >
00585     inline Element *ElementInfo< dim >::el () const
00586     {
00587       return elInfo().el;
00588     }
00589 
00590 
00591     template< int dim >
00592     inline ALBERTA EL_INFO &ElementInfo< dim >::elInfo () const
00593     {
00594       return (instance_->elInfo);
00595     }
00596 
00597 
00598     template< int dim >
00599     inline ElementInfo< dim >
00600     ElementInfo< dim >::createFake ( const MeshPointer &mesh,
00601                                      const Element *element, int level, int type )
00602     {
00603       InstancePtr instance = stack().allocate();
00604       instance->parent() = null();
00605       ++(instance->parent()->refCount);
00606 
00607       instance->elInfo.mesh = mesh;
00608       instance->elInfo.macro_el = NULL;
00609       instance->elInfo.el = const_cast< Element * >( element );
00610       instance->elInfo.parent = NULL;
00611       instance->elInfo.fill_flag = FillFlags::nothing;
00612       instance->elInfo.level = level;
00613 #if (DUNE_ALBERTA_VERSION >= 0x200) || (DIM == 3)
00614       instance->elInfo.el_type = type;
00615 #endif
00616 
00617       return ElementInfo< dim >( instance );
00618     }
00619 
00620 
00621     template< int dim >
00622     inline ElementInfo< dim >
00623     ElementInfo< dim >::createFake ( const ALBERTA EL_INFO &elInfo )
00624     {
00625       InstancePtr instance = stack().allocate();
00626       instance->parent() = null();
00627       ++(instance->parent()->refCount);
00628 
00629       instance->elInfo = elInfo;
00630       return ElementInfo< dim >( instance );
00631     }
00632 
00633 
00634     template< int dim >
00635     inline bool ElementInfo< dim >::isLeaf ( Element *element )
00636     {
00637       return IS_LEAF_EL( element );
00638     }
00639 
00640 
00641     template< int dim >
00642     inline bool ElementInfo< dim >::mightVanish ( Alberta::Element *element, int depth )
00643     {
00644       if( isLeaf( element ) )
00645         return (element->mark < depth);
00646       else
00647         return (mightVanish( element->child[ 0 ], depth-1 ) && mightVanish( element->child[ 1 ], depth-1 ));
00648     }
00649 
00650 
00651     template< int dim >
00652     inline int ElementInfo< dim >::macroNeighbor ( int face, ElementInfo &neighbor ) const
00653     {
00654       assert( (face >= 0) && (face < numFaces) );
00655       const MacroElement *const macroElement = elInfo().macro_el;
00656       const MacroElement *const macroNeighbor = macroElement->neigh[ face ];
00657       if( macroNeighbor != NULL )
00658       {
00659         neighbor = ElementInfo( mesh(), *macroNeighbor, elInfo().fill_flag );
00660         return macroElement->opp_vertex[ face ];
00661       }
00662       else
00663         return -1;
00664     }
00665 
00666 
00667     template<>
00668     inline int ElementInfo< 1 >::leafNeighbor ( const int face, ElementInfo &neighbor ) const
00669     {
00670       static const int neighborInFather[ 2 ][ numFaces ] = { {-1, 1}, {0, -1} };
00671 
00672       assert( !!(*this) );
00673 
00674       int faceInNeighbor;
00675       if( level() > 0 )
00676       {
00677         assert( (face >= 0) && (face < numFaces) );
00678 
00679         const int myIndex = indexInFather();
00680         const int nbInFather = neighborInFather[ myIndex ][ face ];
00681         if( nbInFather >= 0 )
00682           return father().leafNeighbor( nbInFather, neighbor );
00683         else
00684         {
00685           neighbor = father().child( 1-myIndex );
00686           faceInNeighbor = 1-myIndex;
00687         }
00688       }
00689       else
00690         faceInNeighbor = macroNeighbor( face, neighbor );
00691 
00692       if( faceInNeighbor >= 0 )
00693       {
00694         // refine until we are on the leaf level (faceInNeighbor < 2 is always true)
00695         while( !neighbor.isLeaf() )
00696           neighbor = neighbor.child( 1-faceInNeighbor );
00697         assert( neighbor.el() == elInfo().neigh[ face ] );
00698       }
00699       return faceInNeighbor;
00700     }
00701 
00702 
00703     template<>
00704     inline int ElementInfo< 2 >::leafNeighbor ( const int face, ElementInfo &neighbor ) const
00705     {
00706       static const int neighborInFather[ 2 ][ numFaces ] = { {2, -1, 1}, {-1, 2, 0} };
00707 
00708       assert( !!(*this) );
00709 
00710       int faceInNeighbor;
00711       if( level() > 0 )
00712       {
00713         assert( (face >= 0) && (face < numFaces) );
00714 
00715         const int myIndex = indexInFather();
00716         const int nbInFather = neighborInFather[ myIndex ][ face ];
00717         if( nbInFather >= 0 )
00718         {
00719           faceInNeighbor = father().leafNeighbor( nbInFather, neighbor );
00720 
00721           // handle a common face of in refinement patch
00722           if( (faceInNeighbor >= 0) && (nbInFather >= 2) )
00723           {
00724             assert( faceInNeighbor >= 2 );
00725 
00726             int childIndex = myIndex;
00727             if( father().el()->dof[ 0 ][ 0 ] != neighbor.el()->dof[ 0 ][ 0 ] )
00728             {
00729               assert( father().el()->dof[ 0 ][ 0 ] == neighbor.el()->dof[ 1 ][ 0 ] );
00730               childIndex = 1-myIndex;
00731             }
00732             neighbor = neighbor.child( childIndex );
00733             faceInNeighbor = childIndex;
00734           }
00735         }
00736         else
00737         {
00738           neighbor = father().child( 1-myIndex );
00739           faceInNeighbor = myIndex;
00740         }
00741       }
00742       else
00743         faceInNeighbor = macroNeighbor( face, neighbor );
00744 
00745       if( faceInNeighbor >= 0 )
00746       {
00747         // refine until we share a refinement face of the neighbor
00748         if( !neighbor.isLeaf() && (faceInNeighbor < 2) )
00749         {
00750           neighbor = neighbor.child( 1-faceInNeighbor );
00751           faceInNeighbor = dimension;
00752         }
00753         assert( neighbor.el() == elInfo().neigh[ face ] );
00754       }
00755       return faceInNeighbor;
00756     }
00757 
00758 
00759     template<>
00760     inline int ElementInfo< 3 >::leafNeighbor ( const int face, ElementInfo &neighbor ) const
00761     {
00762       // father.neigh[ neighborInFather[ child[ i ].el_type ][ i ][ j ] == child[ i ].neigh[ j ]
00763       static const int neighborInFather[ 3 ][ 2 ][ numFaces ]
00764         = { { {-1, 2, 3, 1}, {-1, 2, 3, 0} },
00765             { {-1, 2, 3, 1}, {-1, 3, 2, 0} },
00766             { {-1, 2, 3, 1}, {-1, 2, 3, 0} } };
00767 
00768       assert( !!(*this) );
00769 
00770       int faceInNeighbor;
00771       if( level() > 0 )
00772       {
00773         assert( (face >= 0) && (face < numFaces) );
00774 
00775         const int myIndex = indexInFather();
00776         const int nbInFather = neighborInFather[ type() ][ myIndex ][ face ];
00777         if( nbInFather >= 0 )
00778         {
00779           faceInNeighbor = father().leafNeighbor( nbInFather, neighbor );
00780 
00781           // handle a common face of in refinement patch
00782           if( (faceInNeighbor >= 0) && (nbInFather >= 2) )
00783           {
00784             assert( faceInNeighbor >= 2 );
00785 
00786             int childIndex = myIndex;
00787             if( father().el()->dof[ 0 ][ 0 ] != neighbor.el()->dof[ 0 ][ 0 ] )
00788             {
00789               assert( father().el()->dof[ 0 ][ 0 ] == neighbor.el()->dof[ 1 ][ 0 ] );
00790               childIndex = 1-myIndex;
00791             }
00792 
00793             const int oppDof = neighbor.el()->dof[ faceInNeighbor ][ 0 ];
00794             neighbor = neighbor.child( childIndex );
00795             faceInNeighbor = (oppDof == neighbor.el()->dof[ 1 ][ 0 ] ? 1 : 2);
00796             assert( oppDof == neighbor.el()->dof[ faceInNeighbor ][ 0 ] );
00797           }
00798         }
00799         else
00800         {
00801           neighbor = father().child( 1-myIndex );
00802           faceInNeighbor = 0;
00803         }
00804       }
00805       else
00806         faceInNeighbor = macroNeighbor( face, neighbor );
00807 
00808       if( faceInNeighbor >= 0 )
00809       {
00810         // refine until we share a refinement face of the neighbor
00811         if( !neighbor.isLeaf() && (faceInNeighbor < 2) )
00812         {
00813           neighbor = neighbor.child( 1-faceInNeighbor );
00814           faceInNeighbor = dimension;
00815         }
00816         assert( neighbor.el() == elInfo().neigh[ face ] );
00817       }
00818       return faceInNeighbor;
00819     }
00820 
00821 
00822     template< int dim >
00823     inline void ElementInfo< dim >::addReference () const
00824     {
00825       ++(instance_->refCount);
00826     }
00827 
00828 
00829     template< int dim >
00830     inline void ElementInfo< dim >::removeReference () const
00831     {
00832       // this loop breaks when instance becomes null()
00833       for( InstancePtr instance = instance_; --(instance->refCount) == 0; )
00834       {
00835         const InstancePtr parent = instance->parent();
00836         stack().release( instance );
00837         instance = parent;
00838       }
00839     }
00840 
00841 
00842     template< int dim >
00843     inline typename ElementInfo< dim >::InstancePtr
00844     ElementInfo< dim >::null ()
00845     {
00846       return stack().null();
00847     }
00848 
00849 
00850     template< int dim >
00851     inline typename ElementInfo< dim >::Stack &
00852     ElementInfo< dim >::stack ()
00853     {
00854       static Stack s;
00855       return s;
00856     }
00857 
00858 
00859 
00860     // Implementation of ElementInfo::Stack
00861     // ------------------------------------
00862 
00863     template< int dim >
00864     inline ElementInfo< dim >::Stack::Stack ()
00865     : top_( 0 )
00866     {
00867       null_.elInfo.el = NULL;
00868       null_.refCount = 1;
00869       null_.parent() = 0;
00870     }
00871 
00872 
00873     template< int dim >
00874     inline ElementInfo< dim >::Stack::~Stack ()
00875     {
00876       while( top_ != 0 )
00877       {
00878         InstancePtr p = top_;
00879         top_ = p->parent();
00880         delete p;
00881       }
00882     }
00883 
00884 
00885     template< int dim >
00886     inline typename ElementInfo< dim >::InstancePtr
00887     ElementInfo< dim >::Stack::allocate ()
00888     {
00889       InstancePtr p = top_;
00890       if( p != 0 )
00891         top_ = p->parent();
00892       else
00893         p = new Instance;
00894       p->refCount = 0;
00895       return p;
00896     }
00897 
00898 
00899     template< int dim >
00900     inline void ElementInfo< dim >::Stack::release ( InstancePtr &p )
00901     {
00902       assert( (p != null()) && (p->refCount == 0) );
00903       p->parent() = top_;
00904       top_ = p;
00905     }
00906 
00907 
00908     template< int dim >
00909     inline typename ElementInfo< dim >::InstancePtr
00910     ElementInfo< dim >::Stack::null ()
00911     {
00912       return &null_;
00913     }
00914 
00915   }
00916 
00917 }
00918 
00919 #endif // #if HAVE_ALBERTA
00920 
00921 #endif

Generated on Thu Apr 2 10:40:39 2009 for dune-grid by  doxygen 1.5.6