dune-grid
2.1.1
|
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 ¯oElement, 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 ¯oElement () 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 ¯oElement, 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, ¯oElement, 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