DUNE-FEM (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
22namespace 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 RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:638
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:684
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:661
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:238
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:706
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:260
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)