5#ifndef DUNE_GRID_YASPGRIDENTITY_HH
6#define DUNE_GRID_YASPGRIDENTITY_HH
41 static constexpr int evaluate(
int d,
int c)
43 return _values[_offsets[d] + c];
47 [[deprecated(
"Use binomial from dune-common's math.hh")]]
48 static constexpr int binomial(
int d,
int c)
51 for (
int i=d-c+1; i<=d; i++)
53 for (
long i=2; i<=c; i++)
60 BinomialTable() =
delete;
63 static constexpr int nextValue(
int& r,
int& c)
76 template<std::size_t... I>
77 static constexpr std::array<int,
sizeof...(I)> computeValues(std::index_sequence<I...>)
80 return {{ ((void)I, nextValue(r, c))... }};
83 template<std::size_t... I>
84 static constexpr std::array<int,
sizeof...(I)> computeOffsets(std::index_sequence<I...>)
85 {
return {{ (I*(I+1)/2)... }}; }
87 static constexpr std::array<int,(n+1)*(n+2)/2> _values = computeValues(std::make_index_sequence<(n+1)*(n+2)/2>{});
88 static constexpr std::array<int,n+1> _offsets = computeOffsets(std::make_index_sequence<n+1>{});
91#if __cplusplus < 201703L
93 constexpr std::array<int,(n+1)*(n+2)/2> BinomialTable<n>::_values;
95 constexpr std::array<int,n+1> BinomialTable<n>::_offsets;
104 template<
int dimworld>
105 constexpr int subEnt(
int d,
int c)
107 return (d < c ? 0 : BinomialTable<dimworld>::evaluate(d,c) << c);
112 template<
typename F,
int dim>
113 struct EntityShiftTable
115 typedef std::bitset<dim> value_type;
117 static value_type evaluate(
int i,
int codim)
119 return {_values[_offsets[codim] + i]};
125 EntityShiftTable() =
delete;
128 static constexpr int nextOffset(
int& offset,
int codim)
135 offset += subEnt<dim>(dim, codim-1);
139 template<std::size_t... I>
140 static constexpr std::array<int,
sizeof...(I)> computeOffsets(std::index_sequence<I...>)
143 return {{ (nextOffset(offset, I))... }};
147 static constexpr unsigned char nextValue(
int& codim,
int& i)
149 const auto result = F::evaluate(i, codim);
152 if (i >= subEnt<dim>(dim, codim)) {
160 template<std::size_t... I>
161 static constexpr std::array<
unsigned char,
sizeof...(I)> computeValues(std::index_sequence<I...>)
163 int codim = 0, i = 0;
164 return {{ ((void)I, nextValue(codim, i))... }};
167 static constexpr std::array<int,dim+1> _offsets = computeOffsets(std::make_index_sequence<dim+1>{});
168 static constexpr std::array<
unsigned char,
Dune::power(3,dim)> _values = computeValues(std::make_index_sequence<
Dune::power(3,dim)>{});
172#if __cplusplus < 201703L
173 template<
typename F,
int dim>
174 constexpr std::array<int,dim+1> EntityShiftTable<F, dim>::_offsets;
175 template<
typename F,
int dim>
176 constexpr std::array<
unsigned char,
Dune::power(3,dim)> EntityShiftTable<F, dim>::_values;
181 struct calculate_entity_shift
183 static constexpr unsigned long long evaluate(
int index,
int cc)
186 for (
int d = dim; d>0; d--)
190 if (index < subEnt<dim>(d-1,cc))
191 result |= 1ull << (d-1);
194 index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
211 std::bitset<dim> entityShift(
int index,
int cc)
213 return EntityShiftTable<calculate_entity_shift<dim>,dim>::evaluate(index,cc);
218 struct calculate_entity_move
220 static constexpr unsigned long long evaluate(
int index,
int cc)
223 for (
int d = dim; d>0; d--)
228 result &= ~(1ull << (d-1));
229 result |= index & (1ull << (d-1));
231 index &= ~(1<<(d-1));
233 if (index >= subEnt<dim>(d-1,cc))
235 if ((index - subEnt<dim>(d-1,cc)) / subEnt<dim>(d-1,cc-1) == 1)
237 result |= 1ull << (d-1);
239 index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
256 std::bitset<dim> entityMove(
int index,
int cc)
258 return EntityShiftTable<calculate_entity_move<dim>,dim>::evaluate(index,cc);
265 template<
int codim,
int dim,
class Gr
idImp>
267 :
public EntityDefaultImplementation <codim,dim,GridImp,YaspEntity>
270 template<
int, PartitionIteratorType,
typename>
271 friend class YaspLevelIterator;
274 typedef typename GridImp::ctype ctype;
276 typedef typename GridImp::template Codim<codim>::Geometry Geometry;
277 typedef typename GridImp::Traits::template Codim<codim>::GeometryImpl GeometryImpl;
279 typedef typename GridImp::template Codim<codim>::EntitySeed EntitySeed;
290 EntitySeed seed()
const
292 return EntitySeed(YaspEntitySeed<codim,GridImp>(_g->level(), _it.coord(), _it.which()));
296 Geometry geometry ()
const
298 GeometryImpl _geometry(_it.lowerleft(),_it.upperright(),_it.shift());
299 return Geometry(_geometry);
314 unsigned int subEntities (
unsigned int cc)
const
316 return Dune::Yasp::subEnt<dim>(dim-codim,cc-codim);
322 if (_g->interior[codim].inside(_it.coord(),_it.shift()))
324 if (_g->interiorborder[codim].inside(_it.coord(),_it.shift()))
326 if (_g->overlap[codim].inside(_it.coord(),_it.shift()))
328 if (_g->overlapfront[codim].inside(_it.coord(),_it.shift()))
333 typedef typename GridImp::YGridLevelIterator YGLI;
334 typedef typename GridImp::YGrid::Iterator I;
338 YaspEntity (
const YGLI& g,
const I& it)
342 YaspEntity (YGLI&& g,
const I&& it)
343 : _it(
std::move(it)), _g(
std::move(g))
347 bool equals (
const YaspEntity& e)
const
349 return _it == e._it && _g == e._g;
356 typedef typename GridImp::PersistentIndexType PersistentIndexType;
359 PersistentIndexType persistentIndex ()
const
362 std::array<int,dim> size;
364 for (
int i=0; i<dim; i++)
367 size[i] = _g->mg->levelSize(_g->level(), i);
373 PersistentIndexType
id(_it.shift().to_ulong());
376 id =
id << yaspgrid_level_bits;
377 id =
id+PersistentIndexType(_g->level());
380 for (
int i=dim-1; i>=0; i--)
382 id =
id << yaspgrid_dim_bits;
383 id =
id+PersistentIndexType(_it.coord(i));
390 int compressedIndex ()
const
392 return _it.superindex();
396 int subCompressedIndex (
int i,
unsigned int cc)
const
400 std::bitset<dim-codim> subent_shift = Dune::Yasp::entityShift<dim-codim>(i,cc-codim);
401 std::bitset<dim-codim> subent_move = Dune::Yasp::entityMove<dim-codim>(i,cc-codim);
403 std::bitset<dim> shift = _it.shift();
404 std::array<int, dim> coord = _it.coord();
405 for (
int j=0, k=0; j<dim; j++)
410 coord[j] += subent_move[k];
411 shift[j] = subent_shift[k];
415 int which = _g->overlapfront[cc].shiftmapping(shift);
416 return _g->overlapfront[cc].superindex(coord,which);
419 const I& transformingsubiterator()
const {
return _it; }
420 const YGLI& gridlevel()
const {
return _g; }
421 I& transformingsubiterator() {
return _it; }
422 YGLI& gridlevel() {
return _g; }
423 const GridImp * yaspgrid()
const {
return _g->mg; }
431 template<
int dim,
class Gr
idImp>
432 class YaspEntity<0,dim,GridImp>
433 :
public EntityDefaultImplementation <0,dim,GridImp,YaspEntity>
435 constexpr static int dimworld = GridImp::dimensionworld;
437 typedef typename GridImp::Traits::template Codim< 0 >::GeometryImpl GeometryImpl;
439 template<
int, PartitionIteratorType,
typename>
440 friend class YaspLevelIterator;
443 friend class YaspHierarchicIterator;
446 typedef typename GridImp::ctype ctype;
448 typedef typename GridImp::YGridLevelIterator YGLI;
449 typedef typename GridImp::YGrid::Iterator I;
451 typedef typename GridImp::template Codim< 0 >::Geometry Geometry;
452 typedef typename GridImp::template Codim< 0 >::LocalGeometry LocalGeometry;
457 typedef typename GridImp::template Codim<cd>::Entity Entity;
460 typedef typename GridImp::template Codim<0>::Entity Entity;
461 typedef typename GridImp::template Codim<0>::EntitySeed EntitySeed;
462 typedef typename GridImp::LevelIntersectionIterator IntersectionIterator;
463 typedef typename GridImp::LevelIntersectionIterator LevelIntersectionIterator;
464 typedef typename GridImp::LeafIntersectionIterator LeafIntersectionIterator;
465 typedef typename GridImp::HierarchicIterator HierarchicIterator;
468 typedef typename GridImp::PersistentIndexType PersistentIndexType;
471 typedef typename GridImp::YGrid::iTupel iTupel;
477 YaspEntity (
const YGLI& g,
const I& it)
481 YaspEntity (
const YGLI& g, I&& it)
482 : _it(
std::move(it)), _g(g)
485 YaspEntity (YGLI&& g, I&& it)
486 : _it(
std::move(it)), _g(
std::move(g))
490 bool equals (
const YaspEntity& e)
const
492 return _it == e._it && _g == e._g;
496 int level ()
const {
return _g->level(); }
501 EntitySeed seed ()
const {
502 return EntitySeed(YaspEntitySeed<0,GridImp>(_g->level(), _it.coord()));
508 if (_g->interior[0].inside(_it.coord(),_it.shift()))
510 if (_g->overlap[0].inside(_it.coord(),_it.shift()))
512 DUNE_THROW(GridError,
"Impossible GhostEntity");
517 Geometry geometry ()
const {
519 auto ll = _it.lowerleft();
520 auto ur = _it.upperright();
523 for (
int i=0; i<dimworld; i++) {
524 if (gridlevel()->mg->isPeriodic(i)) {
525 int coord = transformingsubiterator().coord(i);
527 auto size = _g->mg->domainSize()[i];
530 }
else if (coord + 1 > gridlevel()->mg->levelSize(gridlevel()->level(),i)) {
531 auto size = _g->mg->domainSize()[i];
538 GeometryImpl _geometry(ll,ur);
539 return Geometry( _geometry );
554 template<
int cc>
int count ()
const
556 return Dune::Yasp::subEnt<dim>(dim,cc);
563 unsigned int subEntities (
unsigned int codim)
const
565 return Dune::Yasp::subEnt<dim>(dim,codim);
571 typename Codim<cc>::Entity subEntity (
int i)
const
574 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
577 iTupel coord = _it.coord();
578 for (
int j=0; j<dim; j++)
582 int which = _g->overlapfront[cc].shiftmapping(Dune::Yasp::entityShift<dim>(i,cc));
583 return typename Codim<cc>::Entity(YaspEntity<cc,GridImp::dimension,GridImp>(_g,_g->overlapfront[cc].begin(coord, which)));
587 Entity father ()
const
591 DUNE_THROW(GridError,
"tried to call father on level 0");
598 iTupel coord = _it.coord();
601 for (
int k=0; k<dim; k++) coord[k] = coord[k]/2;
603 return Entity(YaspEntity<0,GridImp::dimension,GridImp>(cg,cg->overlap[0].begin(coord)));
607 bool hasFather ()
const
609 return (_g->level()>0);
614 LocalGeometry geometryInFather ()
const
617 FieldVector<ctype,dim> ll(0.0),ur(0.5);
619 for (
int k=0; k<dim; k++)
628 return LocalGeometry( YaspGeometry<dim,dim,GridImp>(ll,ur) );
631 const I& transformingsubiterator ()
const {
return _it; }
632 const YGLI& gridlevel ()
const {
return _g; }
633 I& transformingsubiterator() {
return _it; }
634 YGLI& gridlevel() {
return _g; }
635 const GridImp* yaspgrid ()
const {
return _g->mg; }
639 return (_g->level() == yaspgrid()->maxLevel());
644 bool isNew ()
const {
return yaspgrid()->adaptRefCount > 0 && yaspgrid()->maxLevel() < _g->level() + yaspgrid()->adaptRefCount; }
648 bool mightVanish ()
const {
return false; }
651 IntersectionIterator ibegin ()
const
653 return YaspIntersectionIterator<GridImp>(*
this,
false);
657 LeafIntersectionIterator ileafbegin ()
const
660 return YaspIntersectionIterator<GridImp>(*
this, ! isLeaf() );
664 LevelIntersectionIterator ilevelbegin ()
const
670 IntersectionIterator iend ()
const
672 return YaspIntersectionIterator<GridImp>(*
this,
true);
676 LeafIntersectionIterator ileafend ()
const
682 LevelIntersectionIterator ilevelend ()
const
691 HierarchicIterator hbegin (
int maxlevel)
const
693 return YaspHierarchicIterator<GridImp>(_g,_it,maxlevel);
697 HierarchicIterator hend (
int )
const
699 return YaspHierarchicIterator<GridImp>(_g,_it,_g->level());
709 PersistentIndexType persistentIndex ()
const
712 PersistentIndexType
id(_it.shift().to_ulong());
715 id =
id << yaspgrid_level_bits;
716 id =
id+PersistentIndexType(_g->level());
720 for (
int i=dim-1; i>=0; i--)
722 id =
id << yaspgrid_dim_bits;
723 id =
id+PersistentIndexType(_it.coord(i));
730 int compressedIndex ()
const
732 return _it.superindex();
736 PersistentIndexType subPersistentIndex (
int i,
int cc)
const
739 std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
740 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
742 int trailing = (cc == dim) ? 1000 : 0;
744 std::array<int,dim> size = _g->mg->levelSize(_g->level());
745 std::array<int, dim> coord = _it.coord();
746 for (
int j=0; j<dim; j++)
757 for (
int j=0; j<dim; j++)
763 for (
int k=0; k<_g->level(); k++)
764 if (coord[j] & (1<<k))
768 trailing = std::min(trailing,zeroes);
773 PersistentIndexType
id(shift.to_ulong());
776 id =
id << yaspgrid_level_bits;
777 id =
id+PersistentIndexType(_g->level()-trailing);
780 for (
int j=dim-1; j>=0; j--)
782 id =
id << yaspgrid_dim_bits;
783 id =
id+PersistentIndexType(coord[j]>>trailing);
790 int subCompressedIndex (
int i,
int cc)
const
793 std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
794 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
796 std::array<int, dim> coord = _it.coord();
797 for (
int j=0; j<dim; j++)
800 int which = _g->overlapfront[cc].shiftmapping(shift);
801 return _g->overlapfront[cc].superindex(coord,which);
810 template<
int dim,
class Gr
idImp>
811 class YaspEntity<dim,dim,GridImp>
812 :
public EntityDefaultImplementation <dim,dim,GridImp,YaspEntity>
814 constexpr static int dimworld = GridImp::dimensionworld;
816 template<
int, PartitionIteratorType,
typename>
817 friend class YaspLevelIterator;
819 typedef typename GridImp::Traits::template Codim<dim>::GeometryImpl GeometryImpl;
822 typedef typename GridImp::ctype ctype;
824 typedef typename GridImp::YGridLevelIterator YGLI;
825 typedef typename GridImp::YGrid::Iterator I;
827 typedef typename GridImp::template Codim<dim>::Geometry Geometry;
829 typedef typename GridImp::template Codim<dim>::EntitySeed EntitySeed;
832 typedef typename GridImp::PersistentIndexType PersistentIndexType;
835 typedef typename GridImp::YGrid::iTupel iTupel;
841 YaspEntity (
const YGLI& g,
const I& it)
845 YaspEntity (YGLI&& g, I&& it)
846 : _it(
std::move(it)), _g(
std::move(g))
850 bool equals (
const YaspEntity& e)
const
852 return _it == e._it && _g == e._g;
856 int level ()
const {
return _g->level();}
861 EntitySeed seed ()
const {
862 return EntitySeed(YaspEntitySeed<dim,GridImp>(_g->level(), _it.coord(), _it.which()));
869 unsigned int subEntities (
unsigned int cc)
const
871 return Dune::Yasp::subEnt<dim>(dim-dim,cc-dim);
875 Geometry geometry ()
const {
876 GeometryImpl _geometry((_it).lowerleft());
877 return Geometry( _geometry );
891 if (_g->interior[dim].inside(_it.coord(),_it.shift()))
893 if (_g->interiorborder[dim].inside(_it.coord(),_it.shift()))
895 if (_g->overlap[dim].inside(_it.coord(),_it.shift()))
897 if (_g->overlapfront[dim].inside(_it.coord(),_it.shift()))
903 int subCompressedIndex (
int,
unsigned int )
const
905 return compressedIndex();
915 PersistentIndexType persistentIndex ()
const
918 iTupel size = _g->mg->levelSize(_g->level());
920 for (
int i=0; i<dim; i++)
928 for (
int i=0; i<dim; i++)
932 for (
int j=0; j<_g->level(); j++)
933 if (_it.coord(i)&(1<<j))
937 trailing = std::min(trailing,zeros);
941 int level = _g->level()-trailing;
944 PersistentIndexType
id(0);
947 id =
id << yaspgrid_level_bits;
948 id =
id+PersistentIndexType(level);
951 for (
int i=dim-1; i>=0; i--)
953 id =
id << yaspgrid_dim_bits;
954 id =
id+PersistentIndexType(_it.coord(i)>>trailing);
961 int compressedIndex ()
const {
return _it.superindex();}
964 const I& transformingsubiterator()
const {
return _it; }
965 const YGLI& gridlevel()
const {
return _g; }
966 I& transformingsubiterator() {
return _it; }
967 YGLI& gridlevel() {
return _g; }
969 const GridImp * yaspgrid()
const {
return _g->mg; }
static constexpr int mydimension
geometry dimension
Definition: geometry.hh:94
persistent, globally unique Ids
Definition: yaspgrididset.hh:25
IdType id(const typename std::remove_const< GridImp >::type::Traits::template Codim< cd >::Entity &e) const
get id of an entity
Definition: yaspgrididset.hh:44
Implementation of Level- and LeafIndexSets for YaspGrid.
Definition: yaspgridindexsets.hh:25
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:472
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:402
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
static constexpr T binomial(const T &n, const T &k) noexcept
calculate the binomial coefficient n over k as a constexpr
Definition: math.hh:131
constexpr Base power(Base m, Exponent p)
Power method for integer exponents.
Definition: math.hh:75
A unique label for each type of element that can occur in a grid.