Dune Core Modules (2.6.0)

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