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