Dune Core Modules (2.4.2)

yaspgridentity.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_GRID_YASPGRIDENTITY_HH
4#define DUNE_GRID_YASPGRIDENTITY_HH
5
19//========================================================================
20
21
22
23
24namespace Dune {
25
26 namespace Yasp {
27
28#ifndef DOXYGEN
29
30 // table for quick evaluation of binomial coefficients
31 template<int n>
32 struct BinomialTable
33 {
34 static void init()
35 {
36 if (_initialized)
37 return;
38 int offset = 0;
39 for (int d = 0; d <= n; ++d)
40 {
41 _offsets[d] = offset;
42 for (int c = 0; c <= d; ++c, ++offset)
43 _values[offset] = binomial(d,c);
44 }
45 _initialized = true;
46 }
47
48 // evaluation - note that in general d!=n, n is only the
49 // maximum value of d (in our case dimworld)
50 static int evaluate(int d, int c)
51 {
52 return _values[_offsets[d] + c];
53 }
54
55 private:
56 // prevent construction
57 BinomialTable();
58
59 static bool _initialized;
60 static std::array<int,(n+1)*(n+2)/2> _values;
61 static std::array<int,n+1> _offsets;
62
63 public:
64
65 // the actual implementation
66 static int binomial(int d, int c)
67 {
68 long binomial=1;
69 for (int i=d-c+1; i<=d; i++)
70 binomial *= i;
71 for (long i=2; i<=c; i++)
72 binomial /= i;
73 return binomial;
74 }
75 };
76
77 template<int n>
78 bool BinomialTable<n>::_initialized = false;
79 template<int n>
80 std::array<int,(n+1)*(n+2)/2> BinomialTable<n>::_values;
81 template<int n>
82 std::array<int,n+1> BinomialTable<n>::_offsets;
83
90 template<int dimworld>
91 int subEnt(int d, int c)
92 {
93 return (d < c ? 0 : BinomialTable<dimworld>::evaluate(d,c) << c);
94 }
95
96 // Make a table mapping all subentities of a codim 0 entity to a value.
97 // F is the functor to be evaluated.
98 template<typename F, int dim>
99 struct EntityShiftTable
100 {
101
102 typedef std::bitset<dim> value_type;
103
104 static void init()
105 {
106 if (_initialized)
107 return;
108 F f;
109 int offset = 0;
110 for (int codim = 0; codim <= dim; ++codim)
111 {
112 _offsets[codim] = offset;
113 for (int i = 0; i < subEnt<dim>(dim,codim); ++i, ++offset)
114 _values[offset] = static_cast<unsigned char>(f(i,codim).to_ulong());
115 }
116 _initialized = true;
117 }
118
119 static value_type evaluate(int i, int codim)
120 {
121 return {_values[_offsets[codim] + i]};
122 }
123
124 private:
125
126 // prevent construction
127 EntityShiftTable();
128
129 static bool _initialized;
130 static std::array<int,dim+1> _offsets;
131 static std::array<unsigned char,StaticPower<3,dim>::power> _values;
132
133 };
134
135 template<typename F, int dim>
136 bool EntityShiftTable<F,dim>::_initialized = false;
137 template<typename F, int dim>
138 std::array<int,dim+1> EntityShiftTable<F,dim>::_offsets;
139 template<typename F, int dim>
140 std::array<unsigned char,StaticPower<3,dim>::power> EntityShiftTable<F,dim>::_values;
141
142 // functor for doing the actual entity shift calculation
143 template<int dim>
144 struct calculate_entity_shift
145 {
146 calculate_entity_shift()
147 {
148 BinomialTable<dim>::init();
149 }
150
151 std::bitset<dim> operator()(int index, int cc) const
152 {
153 std::bitset<dim> result(0ull);
154 for (int d = dim; d>0; d--)
155 {
156 if (cc == d)
157 return result;
158 if (index < subEnt<dim>(d-1,cc))
159 result[d-1]=true;
160 else
161 {
162 index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
163 cc--;
164 }
165 }
166 return result;
167 }
168 };
169
178 template<int dim>
179 std::bitset<dim> entityShift(int index, int cc)
180 {
181 return EntityShiftTable<calculate_entity_shift<dim>,dim>::evaluate(index,cc);
182 }
183
184 // functor for doing the actual entity move calculation
185 template<int dim>
186 struct calculate_entity_move
187 {
188
189 calculate_entity_move()
190 {
191 BinomialTable<dim>::init();
192 }
193
194 std::bitset<dim> operator()(int index, int cc) const
195 {
196 std::bitset<dim> result(0ull);
197 for (int d = dim; d>0; d--)
198 {
199 if (d == cc)
200 {
201 result[d-1] = index & (1<<(d-1));
202 index &= ~(1<<(d-1));
203 }
204 if (index >= subEnt<dim>(d-1,cc))
205 {
206 if ((index - subEnt<dim>(d-1,cc)) / subEnt<dim>(d-1,cc-1) == 1)
207 {
208 result[d-1] = true;
209 }
210 index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
211 cc--;
212 }
213 }
214 return result;
215 }
216
217 };
218
226 template<int dim>
227 std::bitset<dim> entityMove(int index, int cc)
228 {
229 return EntityShiftTable<calculate_entity_move<dim>,dim>::evaluate(index,cc);
230 }
231
232#endif //DOXYGEN
233
234 } // namespace Yasp.
235
236 template<int codim, int dim, class GridImp>
237 class YaspEntity
238 : public EntityDefaultImplementation <codim,dim,GridImp,YaspEntity>
239 {
240
241 template<int, PartitionIteratorType, typename>
242 friend class YaspLevelIterator;
243
244 public:
245 typedef typename GridImp::ctype ctype;
246
247 typedef typename GridImp::template Codim<codim>::Geometry Geometry;
248 typedef typename GridImp::Traits::template Codim<codim>::GeometryImpl GeometryImpl;
249
250 typedef typename GridImp::template Codim<codim>::EntityPointer EntityPointer;
251 typedef typename GridImp::template Codim<codim>::EntitySeed EntitySeed;
252
254 int level () const
255 {
256 return _g->level();
257 }
258
262 EntitySeed seed() const
263 {
264 return EntitySeed(YaspEntitySeed<codim,GridImp>(_g->level(), _it.coord(), _it.which()));
265 }
266
268 Geometry geometry () const
269 {
270 GeometryImpl _geometry(_it.lowerleft(),_it.upperright(),_it.shift());
271 return Geometry(_geometry);
272 }
273
275 PartitionType partitionType () const
276 {
277 if (_g->interior[codim].inside(_it.coord(),_it.shift()))
278 return InteriorEntity;
279 if (_g->interiorborder[codim].inside(_it.coord(),_it.shift()))
280 return BorderEntity;
281 if (_g->overlap[codim].inside(_it.coord(),_it.shift()))
282 return OverlapEntity;
283 if (_g->overlapfront[codim].inside(_it.coord(),_it.shift()))
284 return FrontEntity;
285 return GhostEntity;
286 }
287
288 typedef typename GridImp::YGridLevelIterator YGLI;
289 typedef typename GridImp::YGrid::Iterator I;
290 YaspEntity ()
291 {}
292
293 YaspEntity (const YGLI& g, const I& it)
294 : _it(it), _g(g)
295 {}
296
297// skip this constructor for GCC 4.4, which has a number of nasty bugs in its rvalue reference support
298// As this behavior is hard to trigger in small configuration tests and because we'll probably drop GCC 4.4
299// after the next release anyway, I hacked in this hardcoded check for the compiler version
300#if not (defined(__GNUC__) && (__GNUC__ < 5) && (__GNUC_MINOR__ < 5))
301
302 YaspEntity (YGLI&& g, const I&& it)
303 : _it(std::move(it)), _g(std::move(g))
304 {}
305
306#endif
307
309 bool equals (const YaspEntity& e) const
310 {
311 return _it == e._it && _g == e._g;
312 }
313
314 // IndexSets needs access to the private index methods
315 friend class Dune::YaspIndexSet<GridImp,true>;
316 friend class Dune::YaspIndexSet<GridImp,false>;
317 friend class Dune::YaspGlobalIdSet<GridImp>;
318 typedef typename GridImp::PersistentIndexType PersistentIndexType;
319
321 PersistentIndexType persistentIndex () const
322 {
323 // get size of global grid (in elements)
324 Dune::array<int,dim> size;
325
326 for (int i=0; i<dim; i++)
327 {
328 // correct size according to shift
329 size[i] = _g->mg->levelSize(_g->level(), i);
330 if (!_it.shift(i))
331 size[i]++;
332 }
333
334 // encode codim
335 PersistentIndexType id(_it.shift().to_ulong());
336
337 // encode level
338 id = id << yaspgrid_level_bits;
339 id = id+PersistentIndexType(_g->level());
340
341 // encode coordinates
342 for (int i=dim-1; i>=0; i--)
343 {
344 id = id << yaspgrid_dim_bits;
345 id = id+PersistentIndexType(_it.coord(i));
346 }
347
348 return id;
349 }
350
352 int compressedIndex () const
353 {
354 return _it.superindex();
355 }
356
358 int subCompressedIndex (int i, unsigned int cc) const
359 {
360 // get the shift of the entity and the subentity
361 // the subentity shift is only available in the space spanned by the entity
362 std::bitset<dim> ent_shift = _it.shift();
363 std::bitset<dim-codim> subent_shift = Dune::Yasp::entityShift<dim-codim>(i,cc);
364 std::bitset<dim-codim> subent_move = Dune::Yasp::entityMove<dim-codim>(i,cc);
365 // combine the shifts to get the global shift of the subentity
366 std::bitset<dim> shift,move;
367 for (int i=0,j=0; i<dim; i++)
368 if (ent_shift[i])
369 {
370 shift[i] = subent_shift[j];
371 move[i] = subent_move[j];
372 j++;
373 }
374
375 Dune::array<int, dim> size = _g->mg->levelSize(_g->level());
376 Dune::array<int, dim> coord = _it.coord();
377 for (int j=0; j<dim; j++)
378 {
379 if (!shift[j])
380 size[j]++;
381 if (move[j])
382 coord[j]++;
383 }
384
385 int which = _g->overlapfront[cc].shiftmapping(shift);
386 return _g->overlapfront[cc].superindex(coord,which);
387 }
388 public:
389 const I& transformingsubiterator() const { return _it; }
390 const YGLI& gridlevel() const { return _g; }
391 I& transformingsubiterator() { return _it; }
392 YGLI& gridlevel() { return _g; }
393 const GridImp * yaspgrid() const { return _g->mg; }
394 protected:
395 I _it; // position in the grid level
396 YGLI _g; // access to grid level
397 };
398
399
400 // specialization for codim=0
401 template<int dim, class GridImp>
402 class YaspEntity<0,dim,GridImp>
403 : public EntityDefaultImplementation <0,dim,GridImp,YaspEntity>
404 {
405 enum { dimworld = GridImp::dimensionworld };
406
407 typedef typename GridImp::Traits::template Codim< 0 >::GeometryImpl GeometryImpl;
408
409 template<int, PartitionIteratorType, typename>
410 friend class YaspLevelIterator;
411
412 template<typename>
413 friend class YaspHierarchicIterator;
414
415 public:
416 typedef typename GridImp::ctype ctype;
417
418 typedef typename GridImp::YGridLevelIterator YGLI;
419 typedef typename GridImp::YGrid::Iterator I;
420
421 typedef typename GridImp::template Codim< 0 >::Geometry Geometry;
422 typedef typename GridImp::template Codim< 0 >::LocalGeometry LocalGeometry;
423
424 template <int cd>
425 struct Codim
426 {
427 typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
428 typedef typename GridImp::template Codim<cd>::Entity Entity;
429 };
430
431 typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
432 typedef typename GridImp::template Codim<0>::Entity Entity;
433 typedef typename GridImp::template Codim<0>::EntitySeed EntitySeed;
434 typedef typename GridImp::LevelIntersectionIterator IntersectionIterator;
435 typedef typename GridImp::LevelIntersectionIterator LevelIntersectionIterator;
436 typedef typename GridImp::LeafIntersectionIterator LeafIntersectionIterator;
437 typedef typename GridImp::HierarchicIterator HierarchicIterator;
438
440 typedef typename GridImp::PersistentIndexType PersistentIndexType;
441
443 typedef typename GridImp::YGrid::iTupel iTupel;
444
445 // constructor
446 YaspEntity ()
447 {}
448
449 YaspEntity (const YGLI& g, const I& it)
450 : _it(it), _g(g)
451 {}
452
453 YaspEntity (const YGLI& g, I&& it)
454 : _it(std::move(it)), _g(g)
455 {}
456
457// skip this constructor for GCC 4.4, which has a number of nasty bugs in its rvalue reference support
458// As this behavior is hard to trigger in small configuration tests and because we'll probably drop GCC 4.4
459// after the next release anyway, I hacked in this hardcoded check for the compiler version
460#if not (defined(__GNUC__) && (__GNUC__ < 5) && (__GNUC_MINOR__ < 5))
461
462 YaspEntity (YGLI&& g, I&& it)
463 : _it(std::move(it)), _g(std::move(g))
464 {}
465
466#endif
467
469 bool equals (const YaspEntity& e) const
470 {
471 return _it == e._it && _g == e._g;
472 }
473
475 int level () const { return _g->level(); }
476
480 EntitySeed seed () const {
481 return EntitySeed(YaspEntitySeed<0,GridImp>(_g->level(), _it.coord()));
482 }
483
485 PartitionType partitionType () const
486 {
487 if (_g->interior[0].inside(_it.coord(),_it.shift()))
488 return InteriorEntity;
489 if (_g->overlap[0].inside(_it.coord(),_it.shift()))
490 return OverlapEntity;
491 DUNE_THROW(GridError, "Impossible GhostEntity");
492 return GhostEntity;
493 }
494
496 Geometry geometry () const {
497 // the element geometry
498 auto ll = _it.lowerleft();
499 auto ur = _it.upperright();
500
501 // If on periodic overlap, transform coordinates by domain size
502 for (int i=0; i<dimworld; i++) {
503 if (gridlevel()->mg->isPeriodic(i)) {
504 int coord = transformingsubiterator().coord(i);
505 if (coord < 0) {
506 auto size = _g->mg->domainSize()[i];
507 ll[i] += size;
508 ur[i] += size;
509 } else if (coord + 1 > gridlevel()->mg->levelSize(gridlevel()->level(),i)) {
510 auto size = _g->mg->domainSize()[i];
511 ll[i] -= size;
512 ur[i] -= size;
513 }
514 }
515 }
516
517 GeometryImpl _geometry(ll,ur);
518 return Geometry( _geometry );
519 }
520
525 template<int cc> int count () const
526 {
527 return Dune::Yasp::subEnt<dim>(dim,cc);
528 }
529
534 unsigned int subEntities (unsigned int codim) const
535 {
536 return Dune::Yasp::subEnt<dim>(dim,codim);
537 }
538
541 template<int cc>
542 typename Codim<cc>::Entity subEntity (int i) const
543 {
544 // calculate move bitset
545 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
546
547 // get the coordinate and modify it
548 iTupel coord = _it.coord();
549 for (int j=0; j<dim; j++)
550 if (move[j])
551 coord[j]++;
552
553 int which = _g->overlapfront[cc].shiftmapping(Dune::Yasp::entityShift<dim>(i,cc));
554 return typename Codim<cc>::Entity(YaspEntity<cc,GridImp::dimension,GridImp>(_g,_g->overlapfront[cc].begin(coord, which)));
555 }
556
558 Entity father () const
559 {
560 // check if coarse level exists
561 if (_g->level()<=0)
562 DUNE_THROW(GridError, "tried to call father on level 0");
563
564 // yes, get iterator to it
565 YGLI cg(_g);
566 --cg;
567
568 // coordinates of the cell
569 iTupel coord = _it.coord();
570
571 // get coordinates on next coarser level
572 for (int k=0; k<dim; k++) coord[k] = coord[k]/2;
573
574 return Entity(YaspEntity<0,GridImp::dimension,GridImp>(cg,cg->overlap[0].begin(coord)));
575 }
576
578 bool hasFather () const
579 {
580 return (_g->level()>0);
581 }
582
585 LocalGeometry geometryInFather () const
586 {
587 // configure one of the 2^dim transformations
588 FieldVector<ctype,dim> ll(0.0),ur(0.5);
589
590 for (int k=0; k<dim; k++)
591 {
592 if (_it.coord(k)%2)
593 {
594 ll[k] = 0.5;
595 ur[k] = 1.0;
596 }
597 }
598
599 return LocalGeometry( YaspGeometry<dim,dim,GridImp>(ll,ur) );
600 }
601
602 const I& transformingsubiterator () const { return _it; }
603 const YGLI& gridlevel () const { return _g; }
604 I& transformingsubiterator() { return _it; }
605 YGLI& gridlevel() { return _g; }
606 const GridImp* yaspgrid () const { return _g->mg; }
607
608 bool isLeaf() const
609 {
610 return (_g->level() == yaspgrid()->maxLevel());
611 }
612
615 bool isNew () const { return yaspgrid()->adaptRefCount > 0 && yaspgrid()->maxLevel() < _g->level() + yaspgrid()->adaptRefCount; }
616
619 bool mightVanish () const { return false; }
620
622 IntersectionIterator ibegin () const
623 {
624 return YaspIntersectionIterator<GridImp>(*this,false);
625 }
626
628 LeafIntersectionIterator ileafbegin () const
629 {
630 // only if entity is leaf this iterator delivers intersections
631 return YaspIntersectionIterator<GridImp>(*this, ! isLeaf() );
632 }
633
635 LevelIntersectionIterator ilevelbegin () const
636 {
637 return ibegin();
638 }
639
641 IntersectionIterator iend () const
642 {
643 return YaspIntersectionIterator<GridImp>(*this,true);
644 }
645
647 LeafIntersectionIterator ileafend () const
648 {
649 return iend();
650 }
651
653 LevelIntersectionIterator ilevelend () const
654 {
655 return iend();
656 }
657
662 HierarchicIterator hbegin (int maxlevel) const
663 {
664 return YaspHierarchicIterator<GridImp>(_g,_it,maxlevel);
665 }
666
668 HierarchicIterator hend (int maxlevel) const
669 {
670 return YaspHierarchicIterator<GridImp>(_g,_it,_g->level());
671 }
672
673 private:
674 // IndexSets needs access to the private index methods
675 friend class Dune::YaspIndexSet<GridImp,true>;
676 friend class Dune::YaspIndexSet<GridImp,false>;
677 friend class Dune::YaspGlobalIdSet<GridImp>;
678
680 PersistentIndexType persistentIndex () const
681 {
682 // encode codim
683 PersistentIndexType id(_it.shift().to_ulong());
684
685 // encode level
686 id = id << yaspgrid_level_bits;
687 id = id+PersistentIndexType(_g->level());
688
689
690 // encode coordinates
691 for (int i=dim-1; i>=0; i--)
692 {
693 id = id << yaspgrid_dim_bits;
694 id = id+PersistentIndexType(_it.coord(i));
695 }
696
697 return id;
698 }
699
701 int compressedIndex () const
702 {
703 return _it.superindex();
704 }
705
707 PersistentIndexType subPersistentIndex (int i, int cc) const
708 {
709 // calculate shift and move bitsets
710 std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
711 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
712
713 int trailing = (cc == dim) ? 1000 : 0;
714
715 Dune::array<int,dim> size = _g->mg->levelSize(_g->level());
716 Dune::array<int, dim> coord = _it.coord();
717 for (int j=0; j<dim; j++)
718 {
719 // correct size according to shift
720 if (!shift[j])
721 size[j]++;
722
723 // move the coordinates to the cell on which the entity lives
724 if (move[j])
725 coord[j]++;
726 }
727
728 for (int j=0; j<dim; j++)
729 {
730 // in the codim==dim case, count trailing zeroes.
731 if (cc == dim)
732 {
733 int zeroes = 0;
734 for (int k=0; k<_g->level(); k++)
735 if (coord[j] & (1<<k))
736 break;
737 else
738 zeroes++;
739 trailing = std::min(trailing,zeroes);
740 }
741 }
742
743 // encode codim
744 PersistentIndexType id(shift.to_ulong());
745
746 // encode level
747 id = id << yaspgrid_level_bits;
748 id = id+PersistentIndexType(_g->level()-trailing);
749
750 // encode coordinates
751 for (int j=dim-1; j>=0; j--)
752 {
753 id = id << yaspgrid_dim_bits;
754 id = id+PersistentIndexType(coord[j]>>trailing);
755 }
756
757 return id;
758 }
759
761 int subCompressedIndex (int i, int cc) const
762 {
763 // get shift and move of the subentity in question
764 std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
765 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
766
767 Dune::array<int,dim> size = _g->mg->levelSize(_g->level());
768 Dune::array<int, dim> coord = _it.coord();
769 for (int j=0; j<dim; j++)
770 {
771
772 size[j] += !shift[j];
773 coord[j] += move[j];
774 }
775
776 int which = _g->overlapfront[cc].shiftmapping(shift);
777 return _g->overlapfront[cc].superindex(coord,which);
778 }
779
780 I _it; // position in the grid level
781 YGLI _g; // access to grid level
782 };
783
784
785 // specialization for codim=dim (vertex)
786 template<int dim, class GridImp>
787 class YaspEntity<dim,dim,GridImp>
788 : public EntityDefaultImplementation <dim,dim,GridImp,YaspEntity>
789 {
790 enum { dimworld = GridImp::dimensionworld };
791
792 template<int, PartitionIteratorType, typename>
793 friend class YaspLevelIterator;
794
795 typedef typename GridImp::Traits::template Codim<dim>::GeometryImpl GeometryImpl;
796
797 public:
798 typedef typename GridImp::ctype ctype;
799
800 typedef typename GridImp::YGridLevelIterator YGLI;
801 typedef typename GridImp::YGrid::Iterator I;
802
803 typedef typename GridImp::template Codim<dim>::Geometry Geometry;
804
805 template <int cd>
806 struct Codim
807 {
808 typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
809 };
810
811 typedef typename GridImp::template Codim<dim>::EntityPointer EntityPointer;
812 typedef typename GridImp::template Codim<dim>::EntitySeed EntitySeed;
813
815 typedef typename GridImp::PersistentIndexType PersistentIndexType;
816
818 typedef typename GridImp::YGrid::iTupel iTupel;
819
820 // constructor
821 YaspEntity ()
822 {}
823
824 YaspEntity (const YGLI& g, const I& it)
825 : _it(it), _g(g)
826 {}
827
828// skip this constructor for GCC 4.4, which has a number of nasty bugs in its rvalue reference support
829// As this behavior is hard to trigger in small configuration tests and because we'll probably drop GCC 4.4
830// after the next release anyway, I hacked in this hardcoded check for the compiler version
831#if not (defined(__GNUC__) && (__GNUC__ < 5) && (__GNUC_MINOR__ < 5))
832
833 YaspEntity (YGLI&& g, I&& it)
834 : _it(std::move(it)), _g(std::move(g))
835 {}
836
837#endif
838
840 bool equals (const YaspEntity& e) const
841 {
842 return _it == e._it && _g == e._g;
843 }
844
846 int level () const {return _g->level();}
847
851 EntitySeed seed () const {
852 return EntitySeed(YaspEntitySeed<dim,GridImp>(_g->level(), _it.coord(), _it.which()));
853 }
854
856 Geometry geometry () const {
857 GeometryImpl _geometry((_it).lowerleft());
858 return Geometry( _geometry );
859 }
860
862 PartitionType partitionType () const
863 {
864 if (_g->interior[dim].inside(_it.coord(),_it.shift()))
865 return InteriorEntity;
866 if (_g->interiorborder[dim].inside(_it.coord(),_it.shift()))
867 return BorderEntity;
868 if (_g->overlap[dim].inside(_it.coord(),_it.shift()))
869 return OverlapEntity;
870 if (_g->overlapfront[dim].inside(_it.coord(),_it.shift()))
871 return FrontEntity;
872 return GhostEntity;
873 }
874
876 int subCompressedIndex (int, unsigned int ) const
877 {
878 return compressedIndex();
879 }
880
881 private:
882 // IndexSets needs access to the private index methods
883 friend class Dune::YaspIndexSet<GridImp,true>;
884 friend class Dune::YaspIndexSet<GridImp,false>;
885 friend class Dune::YaspGlobalIdSet<GridImp>;
886
888 PersistentIndexType persistentIndex () const
889 {
890 // get coordinate and size of global grid
891 iTupel size = _g->mg->levelSize(_g->level());
892
893 for (int i=0; i<dim; i++)
894 {
895 // we have vertices, add 1 size to all directions
896 size[i]++;
897 }
898
899 // determine min number of trailing zeroes
900 int trailing = 1000;
901 for (int i=0; i<dim; i++)
902 {
903 // count trailing zeros
904 int zeros = 0;
905 for (int j=0; j<_g->level(); j++)
906 if (_it.coord(i)&(1<<j))
907 break;
908 else
909 zeros++;
910 trailing = std::min(trailing,zeros);
911 }
912
913 // determine the level of this vertex
914 int level = _g->level()-trailing;
915
916 // encode codim: shift vector of vertices is 0.
917 PersistentIndexType id(0);
918
919 // encode level
920 id = id << yaspgrid_level_bits;
921 id = id+PersistentIndexType(level);
922
923 // encode coordinates
924 for (int i=dim-1; i>=0; i--)
925 {
926 id = id << yaspgrid_dim_bits;
927 id = id+PersistentIndexType(_it.coord(i)>>trailing);
928 }
929
930 return id;
931 }
932
934 int compressedIndex () const { return _it.superindex();}
935
936 public:
937 const I& transformingsubiterator() const { return _it; }
938 const YGLI& gridlevel() const { return _g; }
939 I& transformingsubiterator() { return _it; }
940 YGLI& gridlevel() { return _g; }
941
942 const GridImp * yaspgrid() const { return _g->mg; }
943 protected:
944 I _it; // position in the grid level
945 YGLI _g; // access to grid level
946 };
947
948} // namespace Dune
949
950#endif // DUNE_GRID_YASPGRIDENTITY_HH
persistent, globally unique Ids
Definition: yaspgrididset.hh:23
IdType id(const typename remove_const< GridImp >::type::Traits::template Codim< cd >::Entity &e) const
get id of an entity
Definition: yaspgrididset.hh:42
Implementation of Level- and LeafIndexSets for YaspGrid.
Definition: yaspgridindexsets.hh:23
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
PartitionType
Attributes used in the generic overlap model.
Definition: gridenums.hh:28
@ FrontEntity
on boundary between overlap and ghost
Definition: gridenums.hh:32
@ InteriorEntity
all interior entities
Definition: gridenums.hh:29
@ GhostEntity
ghost entities
Definition: gridenums.hh:33
@ BorderEntity
on boundary between interior and overlap
Definition: gridenums.hh:30
@ OverlapEntity
all entities lying in the overlap zone
Definition: gridenums.hh:31
int binomial(int upper, int lower)
calculate
Definition: simplex.cc:292
Dune namespace.
Definition: alignment.hh:10
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)