dune-grid  2.3.1
elementinfo.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ALBERTA_ELEMENTINFO_HH
4 #define DUNE_ALBERTA_ELEMENTINFO_HH
5 
11 #include <cassert>
12 #include <vector>
13 
16 
17 #if HAVE_ALBERTA
18 
19 namespace Dune
20 {
21 
22  namespace Alberta
23  {
24 
25  // External Forward Declarations
26  // -----------------------------
27 
28  template< int dim >
29  class MeshPointer;
30 
31  struct BasicNodeProjection;
32 
33 
34 
35  // ElementInfo
36  // -----------
37 
38  template< int dim >
40  {
41  struct Instance;
42  class Stack;
43 
44  template< int >
45  struct Library;
46 
47  typedef Instance *InstancePtr;
48 
49  public:
50  static const int dimension = dim;
51 
52  static const int numVertices = NumSubEntities< dimension, dimension >::value;
53  static const int numFaces = NumSubEntities< dimension, 1 >::value;
54 
58 
59  static const int maxNeighbors = N_NEIGH_MAX;
60 
61  static const int maxLevelNeighbors = Library< dimWorld >::maxLevelNeighbors;
62 
63 #if !DUNE_ALBERTA_CACHE_COORDINATES
65 #endif
66 
67  struct Seed;
68 
69  private:
70  explicit ElementInfo ( const InstancePtr &instance );
71 
72  public:
73  ElementInfo ();
75  typename FillFlags::Flags fillFlags = FillFlags::standard );
76  ElementInfo ( const MeshPointer &mesh, const Seed &seed,
77  typename FillFlags::Flags fillFlags = FillFlags::standard );
78  ElementInfo ( const ElementInfo &other );
79 
80  ~ElementInfo ();
81 
82  ElementInfo &operator= ( const ElementInfo &other );
83 
84  operator bool () const { return (instance_ != null()); }
85 
86  bool operator== ( const ElementInfo &other ) const;
87  bool operator!= ( const ElementInfo &other ) const;
88 
89  const MacroElement &macroElement () const;
90  ElementInfo father () const;
91  int indexInFather () const;
92  ElementInfo child ( int i ) const;
93  bool isLeaf () const;
94 
95  Seed seed () const;
96 
97  MeshPointer mesh () const;
98 
99  bool mightVanish () const;
100 
101  int level () const;
102  // see ALBERTA documentation for definition of element type
103  // values are 0, 1, 2
104  int type () const;
105 
106  int getMark () const;
107  void setMark ( int refCount ) const;
108 
109  bool hasLeafNeighbor ( const int face ) const;
110  ElementInfo leafNeighbor ( const int face ) const;
111 
112  /* obtain all level neighbors of a face
113  *
114  * param[in] face face for which the neighbors are desired
115  * param[out] neighbor array storing the neighbors
116  * param[out] faceInNeighbor array storing the faces in neighbor
117  * (-1, if this neighbor does not exist)
118  *
119  * returns (potential) number of neighbors (i.e., the number of valid
120  * entries in the output arrays
121  */
122  int levelNeighbors ( const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ], int (&faceInNeighbor)[ maxLevelNeighbors ] ) const;
123 
124  template< int codim >
125  int twist ( int subEntity ) const;
126  int twistInNeighbor ( int face ) const;
127  bool isBoundary ( int face ) const;
128  int boundaryId ( int face ) const;
129  AffineTransformation *transformation ( int face ) const;
130  BasicNodeProjection *boundaryProjection ( int face ) const;
131 
132  bool hasCoordinates () const;
133  const GlobalVector &coordinate ( int vertex ) const;
134 #if !DUNE_ALBERTA_CACHE_COORDINATES
136  {
137  return GeometryCache( instance_->geometryCache, instance_->elInfo );
138  }
139 #endif
140 
141  template< class Functor >
142  void hierarchicTraverse ( Functor &functor ) const;
143 
144  template< class Functor >
145  void leafTraverse ( Functor &functor ) const;
146 
147  const Element *element () const;
148  const Element *neighbor ( int face ) const;
149  Element *el () const;
150  ALBERTA EL_INFO &elInfo () const;
151 
152  static ElementInfo
153  createFake ( const MeshPointer &mesh,
154  const Element *element, int level, int type = 0 );
155  static ElementInfo createFake ( const ALBERTA EL_INFO &elInfo );
156 
157  private:
158  static bool isLeaf ( Element *element );
159  static bool mightVanish ( Element *element, int depth );
160 
161  static void fill ( Mesh *mesh, const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo );
162  static void fill ( int ichild, const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo );
163 
164  void addReference () const;
165  void removeReference () const;
166 
167  static InstancePtr null ();
168  static Stack &stack ();
169 
170  InstancePtr instance_;
171  };
172 
173 
174 
175  // ElementInfo::Instance
176  // ---------------------
177 
178  template< int dim >
179  struct ElementInfo< dim >::Instance
180  {
181  ALBERTA EL_INFO elInfo;
182  unsigned int refCount;
183 
184  InstancePtr &parent ()
185  {
186  return parent_;
187  }
188 
189  private:
190  InstancePtr parent_;
191 
192 #if !DUNE_ALBERTA_CACHE_COORDINATES
193  public:
195 #endif
196  };
197 
198 
199 
200  // ElementInfo::Stack
201  // ------------------
202 
203  template< int dim >
204  class ElementInfo< dim >::Stack
205  {
206  InstancePtr top_;
207  Instance null_;
208 
209  public:
210  Stack ();
211  ~Stack ();
212 
213  InstancePtr allocate ();
214  void release ( InstancePtr &p );
215  InstancePtr null ();
216  };
217 
218 
219 
220  // ElementInfo::Library
221  // --------------------
222 
223  template< int dim >
224  template< int >
225  struct ElementInfo< dim >::Library
226  {
228 
229  static const int maxLevelNeighbors = (1 << (dim-1));
230 
231  static int
232  leafNeighbor ( const ElementInfo &element, const int face, ElementInfo &neighbor );
233 
234  static int
235  levelNeighbors ( const ElementInfo &element, const int face,
236  ElementInfo (&neighbor)[ maxLevelNeighbors ], int (&faceInNeighbor)[ maxLevelNeighbors ] );
237 
238  private:
239  static int
240  macroNeighbor ( const ElementInfo &element, const int face, ElementInfo &neighbor );
241  };
242 
243 
244 
245  // ElementInfo::Seed
246  // -----------------
247 
248  template< int dim >
249  struct ElementInfo< dim >::Seed
250  {
251  Seed ()
252  : macroIndex_( -1 ), level_( 0 ), path_( 0 )
253  {}
254 
255  Seed ( const int macroIndex, const int level, const unsigned long path )
256  : macroIndex_( macroIndex ), level_( level ), path_( path )
257  {}
258 
259  bool operator== ( const Seed &other ) const
260  {
261  return (macroIndex() == other.macroIndex()) && (level() == other.level()) && (path() == other.path());
262  }
263 
264  bool operator< ( const Seed &other ) const
265  {
266  const bool ml = (macroIndex() < other.macroIndex());
267  const bool me = (macroIndex() == other.macroIndex());
268  const bool ll = (level() < other.level());
269  const bool le = (level() == other.level());
270  const bool pl = (path() < other.path());
271  return ml | (me & (ll | (le & pl)));
272  }
273 
274  bool operator!= ( const Seed &other ) const { return !(*this == other); }
275  bool operator<= ( const Seed &other ) const { return !(other < *this); }
276  bool operator> ( const Seed &other ) const { return (other < *this); }
277  bool operator>= ( const Seed &other ) const { return !(*this < other); }
278 
279  bool isValid ( ) const { return macroIndex_ != -1; }
280 
281  int macroIndex () const { return macroIndex_; }
282  int level () const { return level_; }
283  unsigned long path () const { return path_; }
284 
285  private:
286  int macroIndex_;
287  int level_;
288  unsigned long path_;
289  };
290 
291 
292 
293  // Implementation of ElementInfo
294  // -----------------------------
295 
296  template< int dim >
297  inline ElementInfo< dim >::ElementInfo ( const InstancePtr &instance )
298  : instance_( instance )
299  {
300  addReference();
301  }
302 
303 
304  template< int dim >
306  : instance_( null() )
307  {
308  addReference();
309  }
310 
311 
312  template< int dim >
313  inline ElementInfo< dim >
314  ::ElementInfo ( const MeshPointer &mesh, const MacroElement &macroElement,
315  typename FillFlags::Flags fillFlags )
316  {
317  instance_ = stack().allocate();
318  instance_->parent() = null();
319  ++(instance_->parent()->refCount);
320 
321  addReference();
322 
323  elInfo().fill_flag = fillFlags;
324 
325  // Alberta fills opp_vertex only if there is a neighbor
326  for( int k = 0; k < maxNeighbors; ++k )
327  elInfo().opp_vertex[ k ] = -1;
328 
329  fill( mesh, &macroElement, elInfo() );
330  }
331 
332 
333  template< int dim >
334  inline ElementInfo< dim >
335  ::ElementInfo ( const MeshPointer &mesh, const Seed &seed,
336  typename FillFlags::Flags fillFlags )
337  {
338  instance_ = stack().allocate();
339  instance_->parent() = null();
340  ++(instance_->parent()->refCount);
341 
342  addReference();
343 
344  // fill in macro element info
345  elInfo().fill_flag = fillFlags;
346 
347  // Alberta fills opp_vertex only if there is a neighbor
348  for( int k = 0; k < maxNeighbors; ++k )
349  elInfo().opp_vertex[ k ] = -1;
350 
351  fill( mesh, ((Mesh *)mesh)->macro_els + seed.macroIndex(), elInfo() );
352 
353  // traverse the seed's path
354  unsigned long path = seed.path();
355  for( int i = 0; i < seed.level(); ++i )
356  {
357  InstancePtr child = stack().allocate();
358  child->parent() = instance_;
359 
360  // Alberta fills opp_vertex only if there is a neighbor
361  for( int k = 0; k < maxNeighbors; ++k )
362  child->elInfo.opp_vertex[ k ] = -2;
363 
364  fill( path & 1, elInfo(), child->elInfo );
365 
366  instance_ = child;
367  addReference();
368 
369  path = path >> 1;
370  }
371 
372  assert( this->seed() == seed );
373  }
374 
375 
376  template< int dim >
378  : instance_( other.instance_ )
379  {
380  addReference();
381  }
382 
383 
384  template< int dim >
386  {
387  removeReference();
388  }
389 
390 
391  template< int dim >
392  inline ElementInfo< dim > &
394  {
395  other.addReference();
396  removeReference();
397  instance_ = other.instance_;
398  return *this;
399  }
400 
401 
402  template< int dim >
403  inline bool
405  {
406  return (instance_->elInfo.el == other.instance_->elInfo.el);
407  }
408 
409 
410  template< int dim >
411  inline bool
413  {
414  return (instance_->elInfo.el != other.instance_->elInfo.el);
415  }
416 
417 
418  template< int dim >
419  inline const typename ElementInfo< dim >::MacroElement &
421  {
422  assert( !!(*this) );
423  assert( elInfo().macro_el != NULL );
424  return static_cast< const MacroElement & >( *(elInfo().macro_el) );
425  }
426 
427 
428  template< int dim >
430  {
431  assert( !!(*this) );
432  return ElementInfo< dim >( instance_->parent() );
433  }
434 
435 
436  template< int dim >
438  {
439  const Element *element = elInfo().el;
440 #if DUNE_ALBERTA_VERSION >= 0x300
441  const Element *father = elInfo().parent->el;
442 #else
443  const Element *father = elInfo().parent;
444 #endif
445  assert( father != NULL );
446 
447  const int index = (father->child[ 0 ] == element ? 0 : 1);
448  assert( father->child[ index ] == element );
449  return index;
450  }
451 
452 
453  template< int dim >
455  {
456  assert( !isLeaf() );
457 
458  InstancePtr child = stack().allocate();
459  child->parent() = instance_;
460  addReference();
461 
462  // Alberta fills opp_vertex only if there is a neighbor
463  for( int k = 0; k < maxNeighbors; ++k )
464  child->elInfo.opp_vertex[ k ] = -2;
465 
466  fill( i, elInfo(), child->elInfo );
467  return ElementInfo< dim >( child );
468  }
469 
470 
471  template< int dim >
472  inline bool ElementInfo< dim >::isLeaf () const
473  {
474  assert( !(*this) == false );
475  return isLeaf( el() );
476  }
477 
478 
479  template< int dim >
481  {
482  assert( !!(*this) );
483 
484  int level = 0;
485  unsigned long path = 0;
486  for( InstancePtr p = instance_; p->parent() != null(); p = p->parent() )
487  {
488  const Element *element = p->elInfo.el;
489  const Element *father = p->parent()->elInfo.el;
490  const unsigned long child = static_cast< unsigned long >( father->child[ 1 ] == element );
491  path = (path << 1) | child;
492  ++level;
493  }
494 
495  if( level != elInfo().level )
496  DUNE_THROW( NotImplemented, "Seed for fake elements not implemented." );
497 
498  return Seed( macroElement().index, level, path );
499  }
500 
501 
502  template< int dim >
504  {
505  return MeshPointer( elInfo().mesh );
506  }
507 
508 
509  template< int dim >
510  inline bool ElementInfo< dim >::mightVanish () const
511  {
512  return mightVanish( el(), 0 );
513  }
514 
515 
516  template< int dim >
517  inline int ElementInfo< dim >::level () const
518  {
519  return elInfo().level;
520  }
521 
522 
523  template< int dim >
524  inline int ElementInfo< dim >::type () const
525  {
526  return 0;
527  }
528 
529 
530  template<>
531  inline int ElementInfo< 3 >::type () const
532  {
533  return instance_->elInfo.el_type;
534  }
535 
536 
537  template< int dim >
538  inline int ElementInfo< dim >::getMark () const
539  {
540  return el()->mark;
541  }
542 
543 
544  template< int dim >
545  inline void ElementInfo< dim >::setMark ( int refCount ) const
546  {
547  assert( isLeaf() );
548  assert( (refCount >= -128) && (refCount < 127) );
549  el()->mark = refCount;
550  }
551 
552 
553 #if DUNE_ALBERTA_VERSION >= 0x300
554  template< int dim >
555  inline bool ElementInfo< dim >::hasLeafNeighbor ( const int face ) const
556  {
557  assert( !!(*this) );
558  assert( (face >= 0) && (face < maxNeighbors) );
559 
560  assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
561  const int macroFace = elInfo().macro_wall[ face ];
562  if( macroFace >= 0 )
563  return (macroElement().neighbor( macroFace ) != NULL);
564  else
565  return true;
566  }
567 #endif // DUNE_ALBERTA_VERSION >= 0x300
568 
569 #if DUNE_ALBERTA_VERSION < 0x300
570  template< int dim >
571  inline bool ElementInfo< dim >::hasLeafNeighbor ( const int face ) const
572  {
573  return (neighbor( face ) != NULL);
574  }
575 #endif // DUNE_ALBERTA_VERSION < 0x300
576 
577 
578  template< int dim >
579  inline ElementInfo< dim > ElementInfo< dim >::leafNeighbor ( const int face ) const
580  {
581  assert( (face >= 0) && (face < numFaces) );
582  ElementInfo neighbor;
583  Library< dimWorld >::leafNeighbor( *this, face, neighbor );
584  return neighbor;
585  }
586 
587 
588  template< int dim >
589  inline int ElementInfo< dim >
590  ::levelNeighbors ( const int face, ElementInfo (&neighbor)[ maxLevelNeighbors ], int (&faceInNeighbor)[ maxLevelNeighbors ] ) const
591  {
592  assert( (face >= 0) && (face < numFaces) );
593  return Library< dimWorld >::levelNeighbors( *this, face, neighbor, faceInNeighbor );
594  }
595 
596 
597  template< int dim >
598  template< int codim >
599  inline int ElementInfo< dim >::twist ( int subEntity ) const
600  {
601  return Twist< dim, dim-codim >::twist( element(), subEntity );
602  }
603 
604 
605  template< int dim >
606  inline int ElementInfo< dim >::twistInNeighbor ( const int face ) const
607  {
608  assert( neighbor( face ) != NULL );
609  return Twist< dim, dim-1 >::twist( neighbor( face ), elInfo().opp_vertex[ face ] );
610  }
611 
612 
613 #if DUNE_ALBERTA_VERSION >= 0x300
614  template< int dim >
615  inline bool ElementInfo< dim >::isBoundary ( int face ) const
616  {
617  assert( !!(*this) );
618  assert( (face >= 0) && (face < maxNeighbors) );
619 
620  assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
621  const int macroFace = elInfo().macro_wall[ face ];
622  if( macroFace >= 0 )
623  return macroElement().isBoundary( macroFace );
624  else
625  return false;
626  }
627 #endif // DUNE_ALBERTA_VERSION >= 0x300
628 
629 #if DUNE_ALBERTA_VERSION <= 0x200
630  template< int dim >
631  inline bool ElementInfo< dim >::isBoundary ( int face ) const
632  {
633  assert( !!(*this) );
634  assert( (face >= 0) && (face < maxNeighbors) );
635  return (elInfo().neigh[ face ] == 0);
636  }
637 #endif // DUNE_ALBERTA_VERSION <= 0x200
638 
639 
640 #if DUNE_ALBERTA_VERSION >= 0x300
641  template< int dim >
642  inline int ElementInfo< dim >::boundaryId ( int face ) const
643  {
644  assert( !!(*this) );
645  assert( (face >= 0) && (face < N_WALLS_MAX) );
646 
647  assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
648  const int macroFace = elInfo().macro_wall[ face ];
649  const int id = macroElement().boundaryId( macroFace );
650  // this assertion is only allowed, if FILL_BOUND is set
651  // assert( id == elInfo().wall_bound[ face ] );
652  return id;
653  }
654 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
655 
656 
657 #if DUNE_ALBERTA_VERSION == 0x200
658  template<>
659  inline int ElementInfo< 1 >::boundaryId ( int face ) const
660  {
661  assert( !!(*this) );
662  assert( (face >= 0) && (face < N_VERTICES_MAX) );
663  return elInfo().vertex_bound[ 1-face ];
664  }
665 
666  template<>
667  inline int ElementInfo< 2 >::boundaryId ( int face ) const
668  {
669  assert( !!(*this) );
670  assert( (face >= 0) && (face < N_EDGES_MAX) );
671  return elInfo().edge_bound[ face ];
672  }
673 
674  template<>
675  inline int ElementInfo< 3 >::boundaryId ( int face ) const
676  {
677  assert( !!(*this) );
678  assert( (face >= 0) && (face < N_FACES_MAX) );
679  return elInfo().face_bound[ face ];
680  }
681 #endif // #if DUNE_ALBERTA_VERSION == 0x200
682 
683 
684 #if DUNE_ALBERTA_VERSION >= 0x300
685  template< int dim >
686  inline AffineTransformation *
687  ElementInfo< dim >::transformation ( int face ) const
688  {
689  assert( !!(*this) );
690  assert( (face >= 0) && (face < N_WALLS_MAX) );
691 
692  assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
693  const int macroFace = elInfo().macro_wall[ face ];
694  return (macroFace < 0 ? NULL : macroElement().wall_trafo[ macroFace ]);
695  }
696 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
697 
698 #if DUNE_ALBERTA_VERSION <= 0x200
699  template< int dim >
700  inline AffineTransformation *
702  {
703  return NULL;
704  }
705 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
706 
707 
708 #if DUNE_ALBERTA_VERSION >= 0x300
709  template< int dim >
710  inline BasicNodeProjection *
711  ElementInfo< dim >::boundaryProjection ( int face ) const
712  {
713  assert( !!(*this) );
714  assert( (face >= 0) && (face < N_WALLS_MAX) );
715 
716  assert( (elInfo().fill_flag & FillFlags::boundaryId) != 0 );
717  const int macroFace = elInfo().macro_wall[ face ];
718  if( macroFace >= 0 )
719  return static_cast< BasicNodeProjection * >( macroElement().projection[ macroFace+1 ] );
720  else
721  return 0;
722  }
723 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
724 
725 #if DUNE_ALBERTA_VERSION <= 0x200
726  template< int dim >
727  inline BasicNodeProjection *
729  {
730  assert( !!(*this) );
731  assert( (face >= 0) && (face < maxNeighbors) );
732  const int idx = (dim == 1 ? 2-face : 1+face);
733  return static_cast< BasicNodeProjection * >( elInfo().projections[ idx ] );
734  }
735 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
736 
737 
738  template< int dim >
740  {
741  return ((elInfo().fill_flag & FillFlags::coords) != 0);
742  }
743 
744  template< int dim >
746  {
747  assert( hasCoordinates() );
748  assert( (vertex >= 0) && (vertex < numVertices) );
749  return elInfo().coord[ vertex ];
750  }
751 
752 
753  template< int dim >
754  template< class Functor >
755  inline void ElementInfo< dim >::hierarchicTraverse ( Functor &functor ) const
756  {
757  functor( *this );
758  if( !isLeaf() )
759  {
760  child( 0 ).hierarchicTraverse( functor );
761  child( 1 ).hierarchicTraverse( functor );
762  }
763  }
764 
765 
766  template< int dim >
767  template< class Functor >
768  inline void ElementInfo< dim >::leafTraverse ( Functor &functor ) const
769  {
770  if( !isLeaf() )
771  {
772  child( 0 ).leafTraverse( functor );
773  child( 1 ).leafTraverse( functor );
774  }
775  else
776  functor( *this );
777  }
778 
779 
780  template< int dim >
781  inline const Element *ElementInfo< dim >::element () const
782  {
783  return elInfo().el;
784  }
785 
786 
787  template< int dim >
788  inline const Element *ElementInfo< dim >::neighbor ( int face ) const
789  {
790  assert( (face >= 0) && (face < numFaces) );
791  assert( (elInfo().fill_flag & FillFlags::neighbor) != 0 );
792  return elInfo().neigh[ face ];
793  }
794 
795 
796  template< int dim >
798  {
799  return elInfo().el;
800  }
801 
802 
803  template< int dim >
804  inline ALBERTA EL_INFO &ElementInfo< dim >::elInfo () const
805  {
806  return (instance_->elInfo);
807  }
808 
809 
810  template< int dim >
811  inline ElementInfo< dim >
813  const Element *element, int level, int type )
814  {
815  InstancePtr instance = stack().allocate();
816  instance->parent() = null();
817  ++(instance->parent()->refCount);
818 
819  instance->elInfo.mesh = mesh;
820  instance->elInfo.macro_el = NULL;
821  instance->elInfo.el = const_cast< Element * >( element );
822  instance->elInfo.parent = NULL;
823  instance->elInfo.fill_flag = FillFlags::nothing;
824  instance->elInfo.level = level;
825  instance->elInfo.el_type = type;
826 
827  return ElementInfo< dim >( instance );
828  }
829 
830 
831  template< int dim >
832  inline ElementInfo< dim >
833  ElementInfo< dim >::createFake ( const ALBERTA EL_INFO &elInfo )
834  {
835  InstancePtr instance = stack().allocate();
836  instance->parent() = null();
837  ++(instance->parent()->refCount);
838 
839  instance->elInfo = elInfo;
840  return ElementInfo< dim >( instance );
841  }
842 
843 
844  template< int dim >
845  inline bool ElementInfo< dim >::isLeaf ( Element *element )
846  {
847  return IS_LEAF_EL( element );
848  }
849 
850 
851  template< int dim >
852  inline bool ElementInfo< dim >::mightVanish ( Alberta::Element *element, int depth )
853  {
854  if( isLeaf( element ) )
855  return (element->mark < depth);
856  else
857  return (mightVanish( element->child[ 0 ], depth-1 ) && mightVanish( element->child[ 1 ], depth-1 ));
858  }
859 
860 
861  template< int dim >
862  inline void ElementInfo< dim >
863  ::fill ( Mesh *mesh, const ALBERTA MACRO_EL *mel, ALBERTA EL_INFO &elInfo )
864  {
865  ALBERTA fill_macro_info( mesh, mel, &elInfo );
866 
867 #if DUNE_ALBERTA_VERSION < 0x300
868  // The 1d grid does not fill in projections, so we do it here
869  if( (dim == 1) && (elInfo.fill_flag & FILL_PROJECTION) )
870  {
871  for( int i = 0; i <= N_VERTICES_1D; ++i )
872  elInfo.projections[ i ] = mel->projection[ i ];
873  }
874 #endif
875  }
876 
877  template< int dim >
878  inline void ElementInfo< dim >
879  ::fill ( int ichild, const ALBERTA EL_INFO &parentInfo, ALBERTA EL_INFO &elInfo )
880  {
881 #if DUNE_ALBERTA_VERSION >= 0x300
882  ALBERTA fill_elinfo( ichild, FILL_ANY, &parentInfo, &elInfo );
883 #else
884  ALBERTA fill_elinfo( ichild, &parentInfo, &elInfo );
885 
886  // The 1d grid does not fill in projections, so we do it here
887  if( (dim == 1) && (elInfo.fill_flag & FILL_PROJECTION) )
888  {
889  elInfo.projections[ 0 ] = parentInfo.projections[ 0 ];
890  if( ichild == 0 )
891  {
892  elInfo.projections[ 1 ] = parentInfo.projections[ 0 ];
893  elInfo.projections[ 2 ] = parentInfo.projections[ 2 ];
894  }
895  else
896  {
897  elInfo.projections[ 1 ] = parentInfo.projections[ 1 ];
898  elInfo.projections[ 2 ] = parentInfo.projections[ 0 ];
899  }
900  }
901 #endif
902  }
903 
904 
905  template< int dim >
906  inline void ElementInfo< dim >::addReference () const
907  {
908  ++(instance_->refCount);
909  }
910 
911 
912  template< int dim >
913  inline void ElementInfo< dim >::removeReference () const
914  {
915  // this loop breaks when instance becomes null()
916  for( InstancePtr instance = instance_; --(instance->refCount) == 0; )
917  {
918  const InstancePtr parent = instance->parent();
919  stack().release( instance );
920  instance = parent;
921  }
922  }
923 
924 
925  template< int dim >
926  inline typename ElementInfo< dim >::InstancePtr
927  ElementInfo< dim >::null ()
928  {
929  return stack().null();
930  }
931 
932 
933  template< int dim >
934  inline typename ElementInfo< dim >::Stack &
935  ElementInfo< dim >::stack ()
936  {
937  static Stack s;
938  return s;
939  }
940 
941 
942 
943  // Implementation of ElementInfo::Stack
944  // ------------------------------------
945 
946  template< int dim >
948  : top_( 0 )
949  {
950  null_.elInfo.el = NULL;
951  null_.refCount = 1;
952  null_.parent() = 0;
953  }
954 
955 
956  template< int dim >
958  {
959  while( top_ != 0 )
960  {
961  InstancePtr p = top_;
962  top_ = p->parent();
963  delete p;
964  }
965  }
966 
967 
968  template< int dim >
969  inline typename ElementInfo< dim >::InstancePtr
971  {
972  InstancePtr p = top_;
973  if( p != 0 )
974  top_ = p->parent();
975  else
976  p = new Instance;
977  p->refCount = 0;
978  return p;
979  }
980 
981 
982  template< int dim >
984  {
985  assert( (p != null()) && (p->refCount == 0) );
986  p->parent() = top_;
987  top_ = p;
988  }
989 
990 
991  template< int dim >
992  inline typename ElementInfo< dim >::InstancePtr
994  {
995  return &null_;
996  }
997 
998  } // namespace Alberta
999 
1000 } // namespace Dune
1001 
1002 #endif // #if HAVE_ALBERTA
1003 
1004 #endif // #ifndef DUNE_ALBERTA_ELEMENTINFO_HH