Dune Core Modules (2.9.0)

yaspgridentity.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 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_GRID_YASPGRIDENTITY_HH
6 #define DUNE_GRID_YASPGRIDENTITY_HH
7 
8 #include <dune/common/math.hh>
9 #include <dune/geometry/type.hh>
10 
24 //========================================================================
25 
26 
27 
28 
29 namespace Dune {
30 
31  namespace Yasp {
32 
33 #ifndef DOXYGEN
34 
35  // table for quick evaluation of binomial coefficients
36  template<int n>
37  struct BinomialTable
38  {
39  // evaluation - note that in general d!=n, n is only the
40  // maximum value of d (in our case dimworld)
41  static constexpr int evaluate(int d, int c)
42  {
43  return _values[_offsets[d] + c];
44  }
45 
46  // the actual implementation
47  [[deprecated("Use binomial from dune-common's math.hh")]]
48  static constexpr int binomial(int d, int c)
49  {
50  long binomial=1;
51  for (int i=d-c+1; i<=d; i++)
52  binomial *= i;
53  for (long i=2; i<=c; i++)
54  binomial /= i;
55  return binomial;
56  }
57 
58  private:
59  // prevent construction
60  BinomialTable() = delete;
61 
62  // compute binomial(r, c) and advance row `r` and column `c`
63  static constexpr int nextValue(int& r, int& c)
64  {
65  const auto result = Dune::binomial(r, c);
66 
67  c += 1;
68  if (c > r) {
69  r += 1;
70  c = 0;
71  }
72 
73  return result;
74  }
75 
76  template<std::size_t... I>
77  static constexpr std::array<int, sizeof...(I)> computeValues(std::index_sequence<I...>)
78  {
79  int r = 0, c = 0;
80  return {{ ((void)I, nextValue(r, c))... }};
81  }
82 
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)... }}; }
86 
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>{});
89  };
90 
91 #if __cplusplus < 201703L
92  template<int n>
93  constexpr std::array<int,(n+1)*(n+2)/2> BinomialTable<n>::_values;
94  template<int n>
95  constexpr std::array<int,n+1> BinomialTable<n>::_offsets;
96 #endif
97 
104  template<int dimworld>
105  constexpr int subEnt(int d, int c)
106  {
107  return (d < c ? 0 : BinomialTable<dimworld>::evaluate(d,c) << c);
108  }
109 
110  // Make a table mapping all subentities of a codim 0 entity to a value.
111  // F is the functor to be evaluated.
112  template<typename F, int dim>
113  struct EntityShiftTable
114  {
115  typedef std::bitset<dim> value_type;
116 
117  static value_type evaluate(int i, int codim)
118  {
119  return {_values[_offsets[codim] + i]};
120  }
121 
122  private:
123 
124  // prevent construction
125  EntityShiftTable() = delete;
126 
127  // compute offset of codimension `codim` entities and advance `offset`
128  static constexpr int nextOffset(int& offset, int codim)
129  {
130  if (codim == 0) {
131  offset = 0;
132  return 0;
133  }
134 
135  offset += subEnt<dim>(dim, codim-1);
136  return offset;
137  }
138 
139  template<std::size_t... I>
140  static constexpr std::array<int, sizeof...(I)> computeOffsets(std::index_sequence<I...>)
141  {
142  int offset = 0;
143  return {{ (nextOffset(offset, I))... }};
144  }
145 
146  // compute shift table entry for (`codim`, `i`) and advance `codim`, `i`
147  static constexpr unsigned char nextValue(int& codim, int& i)
148  {
149  const auto result = F::evaluate(i, codim);
150 
151  i += 1;
152  if (i >= subEnt<dim>(dim, codim)) {
153  codim += 1;
154  i = 0;
155  }
156 
157  return result;
158  }
159 
160  template<std::size_t... I>
161  static constexpr std::array<unsigned char, sizeof...(I)> computeValues(std::index_sequence<I...>)
162  {
163  int codim = 0, i = 0;
164  return {{ ((void)I, nextValue(codim, i))... }};
165  }
166 
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)>{});
169 
170  };
171 
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;
177 #endif
178 
179  // functor for doing the actual entity shift calculation
180  template<int dim>
181  struct calculate_entity_shift
182  {
183  static constexpr unsigned long long evaluate(int index, int cc)
184  {
185  auto result = 0ull;
186  for (int d = dim; d>0; d--)
187  {
188  if (cc == d)
189  return result;
190  if (index < subEnt<dim>(d-1,cc))
191  result |= 1ull << (d-1);
192  else
193  {
194  index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
195  cc--;
196  }
197  }
198  return result;
199  }
200  };
201 
210  template<int dim>
211  std::bitset<dim> entityShift(int index, int cc)
212  {
213  return EntityShiftTable<calculate_entity_shift<dim>,dim>::evaluate(index,cc);
214  }
215 
216  // functor for doing the actual entity move calculation
217  template<int dim>
218  struct calculate_entity_move
219  {
220  static constexpr unsigned long long evaluate(int index, int cc)
221  {
222  auto result = 0ull;
223  for (int d = dim; d>0; d--)
224  {
225  if (d == cc)
226  {
227  // result[d-1] = index & (1<<(d-1));
228  result &= ~(1ull << (d-1));
229  result |= index & (1ull << (d-1));
230 
231  index &= ~(1<<(d-1));
232  }
233  if (index >= subEnt<dim>(d-1,cc))
234  {
235  if ((index - subEnt<dim>(d-1,cc)) / subEnt<dim>(d-1,cc-1) == 1)
236  {
237  result |= 1ull << (d-1);
238  }
239  index = (index - subEnt<dim>(d-1, cc)) % subEnt<dim>(d-1,cc-1);
240  cc--;
241  }
242  }
243  return result;
244  }
245 
246  };
247 
255  template<int dim>
256  std::bitset<dim> entityMove(int index, int cc)
257  {
258  return EntityShiftTable<calculate_entity_move<dim>,dim>::evaluate(index,cc);
259  }
260 
261 #endif //DOXYGEN
262 
263  } // namespace Yasp.
264 
265  template<int codim, int dim, class GridImp>
266  class YaspEntity
267  : public EntityDefaultImplementation <codim,dim,GridImp,YaspEntity>
268  {
269 
270  template<int, PartitionIteratorType, typename>
271  friend class YaspLevelIterator;
272 
273  public:
274  typedef typename GridImp::ctype ctype;
275 
276  typedef typename GridImp::template Codim<codim>::Geometry Geometry;
277  typedef typename GridImp::Traits::template Codim<codim>::GeometryImpl GeometryImpl;
278 
279  typedef typename GridImp::template Codim<codim>::EntitySeed EntitySeed;
280 
282  int level () const
283  {
284  return _g->level();
285  }
286 
290  EntitySeed seed() const
291  {
292  return EntitySeed(YaspEntitySeed<codim,GridImp>(_g->level(), _it.coord(), _it.which()));
293  }
294 
296  Geometry geometry () const
297  {
298  GeometryImpl _geometry(_it.lowerleft(),_it.upperright(),_it.shift());
299  return Geometry(_geometry);
300  }
301 
305  constexpr GeometryType type () const
306  {
308  }
309 
314  unsigned int subEntities (unsigned int cc) const
315  {
316  return Dune::Yasp::subEnt<dim>(dim-codim,cc-codim);
317  }
318 
320  PartitionType partitionType () const
321  {
322  if (_g->interior[codim].inside(_it.coord(),_it.shift()))
323  return InteriorEntity;
324  if (_g->interiorborder[codim].inside(_it.coord(),_it.shift()))
325  return BorderEntity;
326  if (_g->overlap[codim].inside(_it.coord(),_it.shift()))
327  return OverlapEntity;
328  if (_g->overlapfront[codim].inside(_it.coord(),_it.shift()))
329  return FrontEntity;
330  return GhostEntity;
331  }
332 
333  typedef typename GridImp::YGridLevelIterator YGLI;
334  typedef typename GridImp::YGrid::Iterator I;
335  YaspEntity ()
336  {}
337 
338  YaspEntity (const YGLI& g, const I& it)
339  : _it(it), _g(g)
340  {}
341 
342  YaspEntity (YGLI&& g, const I&& it)
343  : _it(std::move(it)), _g(std::move(g))
344  {}
345 
347  bool equals (const YaspEntity& e) const
348  {
349  return _it == e._it && _g == e._g;
350  }
351 
352  // IndexSets needs access to the private index methods
353  friend class Dune::YaspIndexSet<GridImp,true>;
354  friend class Dune::YaspIndexSet<GridImp,false>;
355  friend class Dune::YaspGlobalIdSet<GridImp>;
356  typedef typename GridImp::PersistentIndexType PersistentIndexType;
357 
359  PersistentIndexType persistentIndex () const
360  {
361  // get size of global grid (in elements)
362  std::array<int,dim> size;
363 
364  for (int i=0; i<dim; i++)
365  {
366  // correct size according to shift
367  size[i] = _g->mg->levelSize(_g->level(), i);
368  if (!_it.shift(i))
369  size[i]++;
370  }
371 
372  // encode codim
373  PersistentIndexType id(_it.shift().to_ulong());
374 
375  // encode level
376  id = id << yaspgrid_level_bits;
377  id = id+PersistentIndexType(_g->level());
378 
379  // encode coordinates
380  for (int i=dim-1; i>=0; i--)
381  {
382  id = id << yaspgrid_dim_bits;
383  id = id+PersistentIndexType(_it.coord(i));
384  }
385 
386  return id;
387  }
388 
390  int compressedIndex () const
391  {
392  return _it.superindex();
393  }
394 
396  int subCompressedIndex (int i, unsigned int cc) const
397  {
398  // get the shift of the entity and the subentity
399  // the subentity shift is only available in the space spanned by the entity
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);
402 
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++)
406  {
407  if (!shift[j])
408  continue;
409 
410  coord[j] += subent_move[k];
411  shift[j] = subent_shift[k];
412  k++;
413  }
414 
415  int which = _g->overlapfront[cc].shiftmapping(shift);
416  return _g->overlapfront[cc].superindex(coord,which);
417  }
418  public:
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; }
424  protected:
425  I _it = {}; // position in the grid level
426  YGLI _g = {}; // access to grid level
427  };
428 
429 
430  // specialization for codim=0
431  template<int dim, class GridImp>
432  class YaspEntity<0,dim,GridImp>
433  : public EntityDefaultImplementation <0,dim,GridImp,YaspEntity>
434  {
435  constexpr static int dimworld = GridImp::dimensionworld;
436 
437  typedef typename GridImp::Traits::template Codim< 0 >::GeometryImpl GeometryImpl;
438 
439  template<int, PartitionIteratorType, typename>
440  friend class YaspLevelIterator;
441 
442  template<typename>
443  friend class YaspHierarchicIterator;
444 
445  public:
446  typedef typename GridImp::ctype ctype;
447 
448  typedef typename GridImp::YGridLevelIterator YGLI;
449  typedef typename GridImp::YGrid::Iterator I;
450 
451  typedef typename GridImp::template Codim< 0 >::Geometry Geometry;
452  typedef typename GridImp::template Codim< 0 >::LocalGeometry LocalGeometry;
453 
454  template <int cd>
455  struct Codim
456  {
457  typedef typename GridImp::template Codim<cd>::Entity Entity;
458  };
459 
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;
466 
468  typedef typename GridImp::PersistentIndexType PersistentIndexType;
469 
471  typedef typename GridImp::YGrid::iTupel iTupel;
472 
473  // constructor
474  YaspEntity ()
475  {}
476 
477  YaspEntity (const YGLI& g, const I& it)
478  : _it(it), _g(g)
479  {}
480 
481  YaspEntity (const YGLI& g, I&& it)
482  : _it(std::move(it)), _g(g)
483  {}
484 
485  YaspEntity (YGLI&& g, I&& it)
486  : _it(std::move(it)), _g(std::move(g))
487  {}
488 
490  bool equals (const YaspEntity& e) const
491  {
492  return _it == e._it && _g == e._g;
493  }
494 
496  int level () const { return _g->level(); }
497 
501  EntitySeed seed () const {
502  return EntitySeed(YaspEntitySeed<0,GridImp>(_g->level(), _it.coord()));
503  }
504 
506  PartitionType partitionType () const
507  {
508  if (_g->interior[0].inside(_it.coord(),_it.shift()))
509  return InteriorEntity;
510  if (_g->overlap[0].inside(_it.coord(),_it.shift()))
511  return OverlapEntity;
512  DUNE_THROW(GridError, "Impossible GhostEntity");
513  return GhostEntity;
514  }
515 
517  Geometry geometry () const {
518  // the element geometry
519  auto ll = _it.lowerleft();
520  auto ur = _it.upperright();
521 
522  // If on periodic overlap, transform coordinates by domain size
523  for (int i=0; i<dimworld; i++) {
524  if (gridlevel()->mg->isPeriodic(i)) {
525  int coord = transformingsubiterator().coord(i);
526  if (coord < 0) {
527  auto size = _g->mg->domainSize()[i];
528  ll[i] += size;
529  ur[i] += size;
530  } else if (coord + 1 > gridlevel()->mg->levelSize(gridlevel()->level(),i)) {
531  auto size = _g->mg->domainSize()[i];
532  ll[i] -= size;
533  ur[i] -= size;
534  }
535  }
536  }
537 
538  GeometryImpl _geometry(ll,ur);
539  return Geometry( _geometry );
540  }
541 
545  constexpr GeometryType type () const
546  {
548  }
549 
554  template<int cc> int count () const
555  {
556  return Dune::Yasp::subEnt<dim>(dim,cc);
557  }
558 
563  unsigned int subEntities (unsigned int codim) const
564  {
565  return Dune::Yasp::subEnt<dim>(dim,codim);
566  }
567 
570  template<int cc>
571  typename Codim<cc>::Entity subEntity (int i) const
572  {
573  // calculate move bitset
574  std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
575 
576  // get the coordinate and modify it
577  iTupel coord = _it.coord();
578  for (int j=0; j<dim; j++)
579  if (move[j])
580  coord[j]++;
581 
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)));
584  }
585 
587  Entity father () const
588  {
589  // check if coarse level exists
590  if (_g->level()<=0)
591  DUNE_THROW(GridError, "tried to call father on level 0");
592 
593  // yes, get iterator to it
594  YGLI cg(_g);
595  --cg;
596 
597  // coordinates of the cell
598  iTupel coord = _it.coord();
599 
600  // get coordinates on next coarser level
601  for (int k=0; k<dim; k++) coord[k] = coord[k]/2;
602 
603  return Entity(YaspEntity<0,GridImp::dimension,GridImp>(cg,cg->overlap[0].begin(coord)));
604  }
605 
607  bool hasFather () const
608  {
609  return (_g->level()>0);
610  }
611 
614  LocalGeometry geometryInFather () const
615  {
616  // configure one of the 2^dim transformations
617  FieldVector<ctype,dim> ll(0.0),ur(0.5);
618 
619  for (int k=0; k<dim; k++)
620  {
621  if (_it.coord(k)%2)
622  {
623  ll[k] = 0.5;
624  ur[k] = 1.0;
625  }
626  }
627 
628  return LocalGeometry( YaspGeometry<dim,dim,GridImp>(ll,ur) );
629  }
630 
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; }
636 
637  bool isLeaf() const
638  {
639  return (_g->level() == yaspgrid()->maxLevel());
640  }
641 
644  bool isNew () const { return yaspgrid()->adaptRefCount > 0 && yaspgrid()->maxLevel() < _g->level() + yaspgrid()->adaptRefCount; }
645 
648  bool mightVanish () const { return false; }
649 
651  IntersectionIterator ibegin () const
652  {
653  return YaspIntersectionIterator<GridImp>(*this,false);
654  }
655 
657  LeafIntersectionIterator ileafbegin () const
658  {
659  // only if entity is leaf this iterator delivers intersections
660  return YaspIntersectionIterator<GridImp>(*this, ! isLeaf() );
661  }
662 
664  LevelIntersectionIterator ilevelbegin () const
665  {
666  return ibegin();
667  }
668 
670  IntersectionIterator iend () const
671  {
672  return YaspIntersectionIterator<GridImp>(*this,true);
673  }
674 
676  LeafIntersectionIterator ileafend () const
677  {
678  return iend();
679  }
680 
682  LevelIntersectionIterator ilevelend () const
683  {
684  return iend();
685  }
686 
691  HierarchicIterator hbegin (int maxlevel) const
692  {
693  return YaspHierarchicIterator<GridImp>(_g,_it,maxlevel);
694  }
695 
697  HierarchicIterator hend (int /* maxlevel */) const
698  {
699  return YaspHierarchicIterator<GridImp>(_g,_it,_g->level());
700  }
701 
702  private:
703  // IndexSets needs access to the private index methods
704  friend class Dune::YaspIndexSet<GridImp,true>;
705  friend class Dune::YaspIndexSet<GridImp,false>;
706  friend class Dune::YaspGlobalIdSet<GridImp>;
707 
709  PersistentIndexType persistentIndex () const
710  {
711  // encode codim
712  PersistentIndexType id(_it.shift().to_ulong());
713 
714  // encode level
715  id = id << yaspgrid_level_bits;
716  id = id+PersistentIndexType(_g->level());
717 
718 
719  // encode coordinates
720  for (int i=dim-1; i>=0; i--)
721  {
722  id = id << yaspgrid_dim_bits;
723  id = id+PersistentIndexType(_it.coord(i));
724  }
725 
726  return id;
727  }
728 
730  int compressedIndex () const
731  {
732  return _it.superindex();
733  }
734 
736  PersistentIndexType subPersistentIndex (int i, int cc) const
737  {
738  // calculate shift and move bitsets
739  std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
740  std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
741 
742  int trailing = (cc == dim) ? 1000 : 0;
743 
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++)
747  {
748  // correct size according to shift
749  if (!shift[j])
750  size[j]++;
751 
752  // move the coordinates to the cell on which the entity lives
753  if (move[j])
754  coord[j]++;
755  }
756 
757  for (int j=0; j<dim; j++)
758  {
759  // in the codim==dim case, count trailing zeroes.
760  if (cc == dim)
761  {
762  int zeroes = 0;
763  for (int k=0; k<_g->level(); k++)
764  if (coord[j] & (1<<k))
765  break;
766  else
767  zeroes++;
768  trailing = std::min(trailing,zeroes);
769  }
770  }
771 
772  // encode codim
773  PersistentIndexType id(shift.to_ulong());
774 
775  // encode level
776  id = id << yaspgrid_level_bits;
777  id = id+PersistentIndexType(_g->level()-trailing);
778 
779  // encode coordinates
780  for (int j=dim-1; j>=0; j--)
781  {
782  id = id << yaspgrid_dim_bits;
783  id = id+PersistentIndexType(coord[j]>>trailing);
784  }
785 
786  return id;
787  }
788 
790  int subCompressedIndex (int i, int cc) const
791  {
792  // get shift and move of the subentity in question
793  std::bitset<dim> shift = Dune::Yasp::entityShift<dim>(i,cc);
794  std::bitset<dim> move = Dune::Yasp::entityMove<dim>(i,cc);
795 
796  std::array<int, dim> coord = _it.coord();
797  for (int j=0; j<dim; j++)
798  coord[j] += move[j];
799 
800  int which = _g->overlapfront[cc].shiftmapping(shift);
801  return _g->overlapfront[cc].superindex(coord,which);
802  }
803 
804  I _it = {}; // position in the grid level
805  YGLI _g = {}; // access to grid level
806  };
807 
808 
809  // specialization for codim=dim (vertex)
810  template<int dim, class GridImp>
811  class YaspEntity<dim,dim,GridImp>
812  : public EntityDefaultImplementation <dim,dim,GridImp,YaspEntity>
813  {
814  constexpr static int dimworld = GridImp::dimensionworld;
815 
816  template<int, PartitionIteratorType, typename>
817  friend class YaspLevelIterator;
818 
819  typedef typename GridImp::Traits::template Codim<dim>::GeometryImpl GeometryImpl;
820 
821  public:
822  typedef typename GridImp::ctype ctype;
823 
824  typedef typename GridImp::YGridLevelIterator YGLI;
825  typedef typename GridImp::YGrid::Iterator I;
826 
827  typedef typename GridImp::template Codim<dim>::Geometry Geometry;
828 
829  typedef typename GridImp::template Codim<dim>::EntitySeed EntitySeed;
830 
832  typedef typename GridImp::PersistentIndexType PersistentIndexType;
833 
835  typedef typename GridImp::YGrid::iTupel iTupel;
836 
837  // constructor
838  YaspEntity ()
839  {}
840 
841  YaspEntity (const YGLI& g, const I& it)
842  : _it(it), _g(g)
843  {}
844 
845  YaspEntity (YGLI&& g, I&& it)
846  : _it(std::move(it)), _g(std::move(g))
847  {}
848 
850  bool equals (const YaspEntity& e) const
851  {
852  return _it == e._it && _g == e._g;
853  }
854 
856  int level () const {return _g->level();}
857 
861  EntitySeed seed () const {
862  return EntitySeed(YaspEntitySeed<dim,GridImp>(_g->level(), _it.coord(), _it.which()));
863  }
864 
869  unsigned int subEntities (unsigned int cc) const
870  {
871  return Dune::Yasp::subEnt<dim>(dim-dim,cc-dim);
872  }
873 
875  Geometry geometry () const {
876  GeometryImpl _geometry((_it).lowerleft());
877  return Geometry( _geometry );
878  }
879 
883  constexpr GeometryType type () const
884  {
886  }
887 
889  PartitionType partitionType () const
890  {
891  if (_g->interior[dim].inside(_it.coord(),_it.shift()))
892  return InteriorEntity;
893  if (_g->interiorborder[dim].inside(_it.coord(),_it.shift()))
894  return BorderEntity;
895  if (_g->overlap[dim].inside(_it.coord(),_it.shift()))
896  return OverlapEntity;
897  if (_g->overlapfront[dim].inside(_it.coord(),_it.shift()))
898  return FrontEntity;
899  return GhostEntity;
900  }
901 
903  int subCompressedIndex (int, unsigned int ) const
904  {
905  return compressedIndex();
906  }
907 
908  private:
909  // IndexSets needs access to the private index methods
910  friend class Dune::YaspIndexSet<GridImp,true>;
911  friend class Dune::YaspIndexSet<GridImp,false>;
912  friend class Dune::YaspGlobalIdSet<GridImp>;
913 
915  PersistentIndexType persistentIndex () const
916  {
917  // get coordinate and size of global grid
918  iTupel size = _g->mg->levelSize(_g->level());
919 
920  for (int i=0; i<dim; i++)
921  {
922  // we have vertices, add 1 size to all directions
923  size[i]++;
924  }
925 
926  // determine min number of trailing zeroes
927  int trailing = 1000;
928  for (int i=0; i<dim; i++)
929  {
930  // count trailing zeros
931  int zeros = 0;
932  for (int j=0; j<_g->level(); j++)
933  if (_it.coord(i)&(1<<j))
934  break;
935  else
936  zeros++;
937  trailing = std::min(trailing,zeros);
938  }
939 
940  // determine the level of this vertex
941  int level = _g->level()-trailing;
942 
943  // encode codim: shift vector of vertices is 0.
944  PersistentIndexType id(0);
945 
946  // encode level
947  id = id << yaspgrid_level_bits;
948  id = id+PersistentIndexType(level);
949 
950  // encode coordinates
951  for (int i=dim-1; i>=0; i--)
952  {
953  id = id << yaspgrid_dim_bits;
954  id = id+PersistentIndexType(_it.coord(i)>>trailing);
955  }
956 
957  return id;
958  }
959 
961  int compressedIndex () const { return _it.superindex();}
962 
963  public:
964  const I& transformingsubiterator() const { return _it; }
965  const YGLI& gridlevel() const { return _g; }
966  I& transformingsubiterator() { return _it; }
967  YGLI& gridlevel() { return _g; }
968 
969  const GridImp * yaspgrid() const { return _g->mg; }
970  protected:
971  I _it = {}; // position in the grid level
972  YGLI _g = {}; // access to grid level
973  };
974 
975 } // namespace Dune
976 
977 #endif // DUNE_GRID_YASPGRIDENTITY_HH
constexpr static 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
PartitionType
Attributes used in the generic overlap model.
Definition: gridenums.hh:30
@ FrontEntity
on boundary between overlap and ghost
Definition: gridenums.hh:34
@ InteriorEntity
all interior entities
Definition: gridenums.hh:31
@ GhostEntity
ghost entities
Definition: gridenums.hh:35
@ BorderEntity
on boundary between interior and overlap
Definition: gridenums.hh:32
@ OverlapEntity
all entities lying in the overlap zone
Definition: gridenums.hh:33
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
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:89
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr Base power(Base m, Exponent p)
Power method for integer exponents.
Definition: math.hh:75
constexpr static T binomial(const T &n, const T &k) noexcept
calculate the binomial coefficient n over k as a constexpr
Definition: math.hh:131
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 12, 22:29, 2024)