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

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].