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
00022
00023
00024 template< int dim >
00025 class MeshPointer;
00026
00027
00028
00029
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 ¯oElement,
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
00087
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
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
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
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 ¯oElement,
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
00208 for( int k = 0; k < maxNeighbors; ++k )
00209 elInfo().opp_vertex[ k ] = -1;
00210
00211 fill_macro_info( mesh, ¯oElement, &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
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
00437
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
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
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
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
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
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
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
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
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