3#ifndef DUNE_GRID_YASPGRIDENTITY_HH
4#define DUNE_GRID_YASPGRIDENTITY_HH
36 static constexpr int evaluate(
int d,
int c)
38 return _values[_offsets[d] + c];
42 static constexpr int binomial(
int d,
int c)
45 for (
int i=d-c+1; i<=d; i++)
47 for (
long i=2; i<=c; i++)
54 BinomialTable() =
delete;
57 static constexpr int nextValue(
int& r,
int& c)
70 template<std::size_t... I>
71 static constexpr std::array<int,
sizeof...(I)> computeValues(std::index_sequence<I...>)
74 return {{ ((void)I, nextValue(r, c))... }};
77 template<std::size_t... I>
78 static constexpr std::array<int,
sizeof...(I)> computeOffsets(std::index_sequence<I...>)
79 {
return {{ (I*(I+1)/2)... }}; }
81 static constexpr std::array<int,(n+1)*(n+2)/2> _values = computeValues(std::make_index_sequence<(n+1)*(n+2)/2>{});
82 static constexpr std::array<int,n+1> _offsets = computeOffsets(std::make_index_sequence<n+1>{});
85#if __cplusplus < 201703L
87 constexpr std::array<int,(n+1)*(n+2)/2> BinomialTable<n>::_values;
89 constexpr std::array<int,n+1> BinomialTable<n>::_offsets;
98 template<
int dimworld>
99 constexpr int subEnt(
int d,
int c)
101 return (d < c ? 0 : BinomialTable<dimworld>::evaluate(d,c) << c);
106 template<
typename F,
int dim>
107 struct EntityShiftTable
109 typedef std::bitset<dim> value_type;
111 static value_type evaluate(
int i,
int codim)
113 return {_values[_offsets[codim] + i]};
119 EntityShiftTable() =
delete;
122 static constexpr int nextOffset(
int& offset,
int codim)
129 offset += subEnt<dim>(dim, codim-1);
133 template<std::size_t... I>
134 static constexpr std::array<int,
sizeof...(I)> computeOffsets(std::index_sequence<I...>)
137 return {{ (nextOffset(offset, I))... }};
141 static constexpr unsigned char nextValue(
int& codim,
int& i)
143 const auto result = F::evaluate(i, codim);
146 if (i >= subEnt<dim>(dim, codim)) {
154 template<std::size_t... I>
155 static constexpr std::array<
unsigned char,
sizeof...(I)> computeValues(std::index_sequence<I...>)
157 int codim = 0, i = 0;
158 return {{ ((void)I, nextValue(codim, i))... }};
161 static constexpr std::array<int,dim+1> _offsets = computeOffsets(std::make_index_sequence<dim+1>{});
166#if __cplusplus < 201703L
167 template<
typename F,
int dim>
168 constexpr std::array<int,dim+1> EntityShiftTable<F, dim>::_offsets;
169 template<
typename F,
int dim>
175 struct calculate_entity_shift
177 static constexpr unsigned long long evaluate(
int index,
int cc)
180 for (
int d = dim; d>0; d--)
184 if (index < subEnt<dim>(d-1,cc))
185 result |= 1ull << (d-1);
188 index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
205 std::bitset<dim> entityShift(
int index,
int cc)
207 return EntityShiftTable<calculate_entity_shift<dim>,dim>::evaluate(index,cc);
212 struct calculate_entity_move
214 static constexpr unsigned long long evaluate(
int index,
int cc)
217 for (
int d = dim; d>0; d--)
222 result &= ~(1ull << (d-1));
223 result |= index & (1ull << (d-1));
225 index &= ~(1<<(d-1));
227 if (index >= subEnt<dim>(d-1,cc))
229 if ((index - subEnt<dim>(d-1,cc)) / subEnt<dim>(d-1,cc-1) == 1)
231 result |= 1ull << (d-1);
233 index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
250 std::bitset<dim> entityMove(
int index,
int cc)
252 return EntityShiftTable<calculate_entity_move<dim>,dim>::evaluate(index,cc);
259 template<
int codim,
int dim,
class Gr
idImp>
261 :
public EntityDefaultImplementation <codim,dim,GridImp,YaspEntity>
264 template<
int, PartitionIteratorType,
typename>
265 friend class YaspLevelIterator;
268 typedef typename GridImp::ctype ctype;
270 typedef typename GridImp::template Codim<codim>::Geometry Geometry;
271 typedef typename GridImp::Traits::template Codim<codim>::GeometryImpl GeometryImpl;
273 typedef typename GridImp::template Codim<codim>::EntitySeed EntitySeed;
284 EntitySeed seed()
const
286 return EntitySeed(YaspEntitySeed<codim,GridImp>(_g->level(), _it.coord(), _it.which()));
290 Geometry geometry ()
const
292 GeometryImpl _geometry(_it.lowerleft(),_it.upperright(),_it.shift());
293 return Geometry(_geometry);
300 unsigned int subEntities (
unsigned int cc)
const
302 return Dune::Yasp::subEnt<dim>(dim-codim,cc-codim);
308 if (_g->interior[codim].inside(_it.coord(),_it.shift()))
310 if (_g->interiorborder[codim].inside(_it.coord(),_it.shift()))
312 if (_g->overlap[codim].inside(_it.coord(),_it.shift()))
314 if (_g->overlapfront[codim].inside(_it.coord(),_it.shift()))
319 typedef typename GridImp::YGridLevelIterator YGLI;
320 typedef typename GridImp::YGrid::Iterator I;
324 YaspEntity (
const YGLI& g,
const I& it)
328 YaspEntity (YGLI&& g,
const I&& it)
329 : _it(
std::move(it)), _g(
std::move(g))
333 bool equals (
const YaspEntity& e)
const
335 return _it == e._it && _g == e._g;
342 typedef typename GridImp::PersistentIndexType PersistentIndexType;
345 PersistentIndexType persistentIndex ()
const
348 std::array<int,dim> size;
350 for (
int i=0; i<dim; i++)
353 size[i] = _g->mg->levelSize(_g->level(), i);
359 PersistentIndexType
id(_it.shift().to_ulong());
362 id =
id << yaspgrid_level_bits;
363 id =
id+PersistentIndexType(_g->level());
366 for (
int i=dim-1; i>=0; i--)
368 id =
id << yaspgrid_dim_bits;
369 id =
id+PersistentIndexType(_it.coord(i));
376 int compressedIndex ()
const
378 return _it.superindex();
382 int subCompressedIndex (
int i,
unsigned int cc)
const
386 std::bitset<dim-codim> subent_shift = Dune::Yasp::entityShift<dim-codim>(i,cc-codim);
387 std::bitset<dim-codim> subent_move = Dune::Yasp::entityMove<dim-codim>(i,cc-codim);
389 std::bitset<dim> shift = _it.shift();
390 std::array<int, dim> coord = _it.coord();
391 for (
int j=0, k=0; j<dim; j++)
396 coord[j] += subent_move[k];
397 shift[j] = subent_shift[k];
401 int which = _g->overlapfront[cc].shiftmapping(shift);
402 return _g->overlapfront[cc].superindex(coord,which);
405 const I& transformingsubiterator()
const {
return _it; }
406 const YGLI& gridlevel()
const {
return _g; }
407 I& transformingsubiterator() {
return _it; }
408 YGLI& gridlevel() {
return _g; }
409 const GridImp * yaspgrid()
const {
return _g->mg; }
417 template<
int dim,
class Gr
idImp>
418 class YaspEntity<0,dim,GridImp>
419 :
public EntityDefaultImplementation <0,dim,GridImp,YaspEntity>
421 enum { dimworld = GridImp::dimensionworld };
423 typedef typename GridImp::Traits::template Codim< 0 >::GeometryImpl GeometryImpl;
425 template<
int, PartitionIteratorType,
typename>
426 friend class YaspLevelIterator;
429 friend class YaspHierarchicIterator;
432 typedef typename GridImp::ctype ctype;
434 typedef typename GridImp::YGridLevelIterator YGLI;
435 typedef typename GridImp::YGrid::Iterator I;
437 typedef typename GridImp::template Codim< 0 >::Geometry Geometry;
438 typedef typename GridImp::template Codim< 0 >::LocalGeometry LocalGeometry;
443 typedef typename GridImp::template Codim<cd>::Entity Entity;
446 typedef typename GridImp::template Codim<0>::Entity Entity;
447 typedef typename GridImp::template Codim<0>::EntitySeed EntitySeed;
448 typedef typename GridImp::LevelIntersectionIterator IntersectionIterator;
449 typedef typename GridImp::LevelIntersectionIterator LevelIntersectionIterator;
450 typedef typename GridImp::LeafIntersectionIterator LeafIntersectionIterator;
451 typedef typename GridImp::HierarchicIterator HierarchicIterator;
454 typedef typename GridImp::PersistentIndexType PersistentIndexType;
457 typedef typename GridImp::YGrid::iTupel iTupel;
463 YaspEntity (
const YGLI& g,
const I& it)
467 YaspEntity (
const YGLI& g, I&& it)
468 : _it(
std::move(it)), _g(g)
471 YaspEntity (YGLI&& g, I&& it)
472 : _it(
std::move(it)), _g(
std::move(g))
476 bool equals (
const YaspEntity& e)
const
478 return _it == e._it && _g == e._g;
482 int level ()
const {
return _g->level(); }
487 EntitySeed seed ()
const {
488 return EntitySeed(YaspEntitySeed<0,GridImp>(_g->level(), _it.coord()));
494 if (_g->interior[0].inside(_it.coord(),_it.shift()))
496 if (_g->overlap[0].inside(_it.coord(),_it.shift()))
498 DUNE_THROW(GridError,
"Impossible GhostEntity");
503 Geometry geometry ()
const {
505 auto ll = _it.lowerleft();
506 auto ur = _it.upperright();
509 for (
int i=0; i<dimworld; i++) {
510 if (gridlevel()->mg->isPeriodic(i)) {
511 int coord = transformingsubiterator().coord(i);
513 auto size = _g->mg->domainSize()[i];
516 }
else if (coord + 1 > gridlevel()->mg->levelSize(gridlevel()->level(),i)) {
517 auto size = _g->mg->domainSize()[i];
524 GeometryImpl _geometry(ll,ur);
525 return Geometry( _geometry );
532 template<
int cc>
int count ()
const
534 return Dune::Yasp::subEnt<dim>(dim,cc);
541 unsigned int subEntities (
unsigned int codim)
const
543 return Dune::Yasp::subEnt<dim>(dim,codim);
549 typename Codim<cc>::Entity subEntity (
int i)
const
552 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
555 iTupel coord = _it.coord();
556 for (
int j=0; j<dim; j++)
560 int which = _g->overlapfront[cc].shiftmapping(Dune::Yasp::entityShift<dim>(i,cc));
561 return typename Codim<cc>::Entity(YaspEntity<cc,GridImp::dimension,GridImp>(_g,_g->overlapfront[cc].begin(coord, which)));
565 Entity father ()
const
569 DUNE_THROW(GridError,
"tried to call father on level 0");
576 iTupel coord = _it.coord();
579 for (
int k=0; k<dim; k++) coord[k] = coord[k]/2;
581 return Entity(YaspEntity<0,GridImp::dimension,GridImp>(cg,cg->overlap[0].begin(coord)));
585 bool hasFather ()
const
587 return (_g->level()>0);
592 LocalGeometry geometryInFather ()
const
595 FieldVector<ctype,dim> ll(0.0),ur(0.5);
597 for (
int k=0; k<dim; k++)
606 return LocalGeometry( YaspGeometry<dim,dim,GridImp>(ll,ur) );
609 const I& transformingsubiterator ()
const {
return _it; }
610 const YGLI& gridlevel ()
const {
return _g; }
611 I& transformingsubiterator() {
return _it; }
612 YGLI& gridlevel() {
return _g; }
613 const GridImp* yaspgrid ()
const {
return _g->mg; }
617 return (_g->level() == yaspgrid()->maxLevel());
622 bool isNew ()
const {
return yaspgrid()->adaptRefCount > 0 && yaspgrid()->maxLevel() < _g->level() + yaspgrid()->adaptRefCount; }
626 bool mightVanish ()
const {
return false; }
629 IntersectionIterator ibegin ()
const
631 return YaspIntersectionIterator<GridImp>(*
this,
false);
635 LeafIntersectionIterator ileafbegin ()
const
638 return YaspIntersectionIterator<GridImp>(*
this, ! isLeaf() );
642 LevelIntersectionIterator ilevelbegin ()
const
648 IntersectionIterator iend ()
const
650 return YaspIntersectionIterator<GridImp>(*
this,
true);
654 LeafIntersectionIterator ileafend ()
const
660 LevelIntersectionIterator ilevelend ()
const
669 HierarchicIterator hbegin (
int maxlevel)
const
671 return YaspHierarchicIterator<GridImp>(_g,_it,maxlevel);
675 HierarchicIterator hend (
int )
const
677 return YaspHierarchicIterator<GridImp>(_g,_it,_g->level());
687 PersistentIndexType persistentIndex ()
const
690 PersistentIndexType
id(_it.shift().to_ulong());
693 id =
id << yaspgrid_level_bits;
694 id =
id+PersistentIndexType(_g->level());
698 for (
int i=dim-1; i>=0; i--)
700 id =
id << yaspgrid_dim_bits;
701 id =
id+PersistentIndexType(_it.coord(i));
708 int compressedIndex ()
const
710 return _it.superindex();
714 PersistentIndexType subPersistentIndex (
int i,
int cc)
const
717 std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
718 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
720 int trailing = (cc == dim) ? 1000 : 0;
722 std::array<int,dim> size = _g->mg->levelSize(_g->level());
723 std::array<int, dim> coord = _it.coord();
724 for (
int j=0; j<dim; j++)
735 for (
int j=0; j<dim; j++)
741 for (
int k=0; k<_g->level(); k++)
742 if (coord[j] & (1<<k))
746 trailing =
std::min(trailing,zeroes);
751 PersistentIndexType
id(shift.to_ulong());
754 id =
id << yaspgrid_level_bits;
755 id =
id+PersistentIndexType(_g->level()-trailing);
758 for (
int j=dim-1; j>=0; j--)
760 id =
id << yaspgrid_dim_bits;
761 id =
id+PersistentIndexType(coord[j]>>trailing);
768 int subCompressedIndex (
int i,
int cc)
const
771 std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
772 std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
774 std::array<int, dim> coord = _it.coord();
775 for (
int j=0; j<dim; j++)
778 int which = _g->overlapfront[cc].shiftmapping(shift);
779 return _g->overlapfront[cc].superindex(coord,which);
788 template<
int dim,
class Gr
idImp>
789 class YaspEntity<dim,dim,GridImp>
790 :
public EntityDefaultImplementation <dim,dim,GridImp,YaspEntity>
792 enum { dimworld = GridImp::dimensionworld };
794 template<
int, PartitionIteratorType,
typename>
795 friend class YaspLevelIterator;
797 typedef typename GridImp::Traits::template Codim<dim>::GeometryImpl GeometryImpl;
800 typedef typename GridImp::ctype ctype;
802 typedef typename GridImp::YGridLevelIterator YGLI;
803 typedef typename GridImp::YGrid::Iterator I;
805 typedef typename GridImp::template Codim<dim>::Geometry Geometry;
807 typedef typename GridImp::template Codim<dim>::EntitySeed EntitySeed;
810 typedef typename GridImp::PersistentIndexType PersistentIndexType;
813 typedef typename GridImp::YGrid::iTupel iTupel;
819 YaspEntity (
const YGLI& g,
const I& it)
823 YaspEntity (YGLI&& g, I&& it)
824 : _it(
std::move(it)), _g(
std::move(g))
828 bool equals (
const YaspEntity& e)
const
830 return _it == e._it && _g == e._g;
834 int level ()
const {
return _g->level();}
839 EntitySeed seed ()
const {
840 return EntitySeed(YaspEntitySeed<dim,GridImp>(_g->level(), _it.coord(), _it.which()));
847 unsigned int subEntities (
unsigned int cc)
const
849 return Dune::Yasp::subEnt<dim>(dim-dim,cc-dim);
853 Geometry geometry ()
const {
854 GeometryImpl _geometry((_it).lowerleft());
855 return Geometry( _geometry );
861 if (_g->interior[dim].inside(_it.coord(),_it.shift()))
863 if (_g->interiorborder[dim].inside(_it.coord(),_it.shift()))
865 if (_g->overlap[dim].inside(_it.coord(),_it.shift()))
867 if (_g->overlapfront[dim].inside(_it.coord(),_it.shift()))
873 int subCompressedIndex (
int,
unsigned int )
const
875 return compressedIndex();
885 PersistentIndexType persistentIndex ()
const
888 iTupel size = _g->mg->levelSize(_g->level());
890 for (
int i=0; i<dim; i++)
898 for (
int i=0; i<dim; i++)
902 for (
int j=0; j<_g->level(); j++)
903 if (_it.coord(i)&(1<<j))
907 trailing =
std::min(trailing,zeros);
911 int level = _g->level()-trailing;
914 PersistentIndexType
id(0);
917 id =
id << yaspgrid_level_bits;
918 id =
id+PersistentIndexType(level);
921 for (
int i=dim-1; i>=0; i--)
923 id =
id << yaspgrid_dim_bits;
924 id =
id+PersistentIndexType(_it.coord(i)>>trailing);
931 int compressedIndex ()
const {
return _it.superindex();}
934 const I& transformingsubiterator()
const {
return _it; }
935 const YGLI& gridlevel()
const {
return _g; }
936 I& transformingsubiterator() {
return _it; }
937 YGLI& gridlevel() {
return _g; }
939 const GridImp * yaspgrid()
const {
return _g->mg; }
persistent, globally unique Ids
Definition: yaspgrididset.hh:23
IdType id(const typename std::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
static constexpr int power
power stores m^p
Definition: power.hh:26
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:400
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:87
Dune namespace.
Definition: alignedallocator.hh:11
static constexpr T binomial(const T &n, const T &k) noexcept
calculate the binomial coefficient n over k as a constexpr
Definition: math.hh:128
constexpr Mantissa power(Mantissa m, Exponent p)
Power method for integer exponents.
Definition: math.hh:73