Dune Core Modules (unstable)

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