Dune Core Modules (2.6.0)

yaspgridintersection.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_YASPGRIDINTERSECTION_HH
4 #define DUNE_GRID_YASPGRIDINTERSECTION_HH
5 
13 namespace Dune {
14 
18  template<class GridImp>
20  {
21  enum { dim=GridImp::dimension };
22  enum { dimworld=GridImp::dimensionworld };
23  typedef typename GridImp::ctype ctype;
24 
25  typedef typename GridImp::Traits::template Codim< 1 >::GeometryImpl GeometryImpl;
26  typedef typename GridImp::Traits::template Codim< 1 >::LocalGeometryImpl LocalGeometryImpl;
27 
28  friend class YaspIntersectionIterator<GridImp>;
29 
30  public:
31  // types used from grids
32  typedef typename GridImp::YGridLevelIterator YGLI;
33  typedef typename GridImp::YGrid::Iterator I;
34  typedef typename GridImp::template Codim<0>::Entity Entity;
35  typedef typename GridImp::template Codim<1>::Geometry Geometry;
36  typedef typename GridImp::template Codim<1>::LocalGeometry LocalGeometry;
37 
38  void update() {
39 
40  // vector with per-direction movements
41  std::array<int,dim> dist{{0}};
42 
43  // first move: back to center
44  dist[_dir] = 1 - 2*_face;
45 
46  // update face info
47  _dir = _count / 2;
48  _face = _count % 2;
49 
50  // second move: to new neighbor
51  dist[_dir] += -1 + 2*_face;
52 
53  // move transforming iterator
54  _outside.transformingsubiterator().move(dist);
55  }
56 
60  bool boundary () const
61  {
62  // Coordinate of intersection in its direction
63  int coord = _inside.transformingsubiterator().coord(_dir) + _face;
64  if (_inside.gridlevel()->mg->isPeriodic(_dir))
65  return false;
66  else
67  return coord == 0
68  ||
69  coord == _inside.gridlevel()->mg->levelSize(_inside.gridlevel()->level(),_dir);
70  }
71 
73  bool neighbor () const
74  {
75  // Coordinate of intersection in its direction
76  int coord = _inside.transformingsubiterator().coord(_dir) + _face;
77  return coord > _inside.gridlevel()->overlap[0].dataBegin()->min(_dir)
78  &&
79  coord <= _inside.gridlevel()->overlap[0].dataBegin()->max(_dir);
80  }
81 
83  bool conforming () const
84  {
85  return true;
86  }
87 
90  Entity inside() const
91  {
92  return Entity(_inside);
93  }
94 
96  Entity outside() const
97  {
98  return Entity(_outside);
99  }
100 
104  {
105  if(! boundary())
106  DUNE_THROW(GridError, "called boundarySegmentIndex while boundary() == false");
107  // size of local macro grid
108  const std::array<int, dim> & size = _inside.gridlevel()->mg->begin()->overlap[0].dataBegin()->size();
109  const std::array<int, dim> & origin = _inside.gridlevel()->mg->begin()->overlap[0].dataBegin()->origin();
110  std::array<int, dim> sides;
111  {
112  for (int i=0; i<dim; i++)
113  {
114  sides[i] =
115  ((_inside.gridlevel()->mg->begin()->overlap[0].dataBegin()->origin(i)
116  == 0)+
117  (_inside.gridlevel()->mg->begin()->overlap[0].dataBegin()->origin(i) +
118  _inside.gridlevel()->mg->begin()->overlap[0].dataBegin()->size(i)
119  ==
120  _inside.gridlevel()->mg->levelSize(0,i)));
121 
122  }
123  }
124  // global position of the cell on macro grid
125  std::array<int, dim> pos = _inside.transformingsubiterator().coord();
126  for(int i=0; i<dim; i++)
127  {
128  pos[i] = pos[i] / (1<<_inside.level());
129  pos[i] = pos[i] - origin[i];
130  }
131  // compute unit-cube-face-sizes
132  std::array<int, dim> fsize;
133  {
134  int vol = 1;
135  for (int k=0; k<dim; k++)
136  vol *= size[k];
137  for (int k=0; k<dim; k++)
138  fsize[k] = vol/size[k];
139  }
140  // compute index in the unit-cube-face
141  int index = 0;
142  {
143  int localoffset = 1;
144  for (int k=dim-1; k>=0; k--)
145  {
146  if (k == _dir) continue;
147  index += (pos[k]) * localoffset;
148  localoffset *= size[k];
149  }
150  }
151  // add unit-cube-face-offsets
152  {
153  for (int k=0; k<_dir; k++)
154  index += sides[k] * fsize[k];
155  // add fsize if we are on the right face and there is a left-face-boundary on this processor
156  index += _face * (sides[_dir]>1) * fsize[_dir];
157  }
158 
159  return index;
160  }
161 
164  {
165  return _faceInfo[_count].normal;
166  }
167 
170  {
171  return _faceInfo[_count].normal;
172  }
173 
176  {
177  return _faceInfo[_count].normal;
178  }
179 
184  {
185  FieldVector<ctype, dimworld> n = _faceInfo[_count].normal;
186  n *= geometry().volume();
187  return n;
188  }
189 
193  LocalGeometry geometryInInside () const
194  {
195  return LocalGeometry( _faceInfo[_count].geom_inside );
196  }
197 
201  LocalGeometry geometryInOutside () const
202  {
203  return LocalGeometry( _faceInfo[_count].geom_outside );
204  }
205 
208  Geometry geometry () const
209  {
210 
211  std::bitset<dim> shift;
212  shift.set();
213  shift[_dir] = false;
214 
216  for (int i=0; i<dimworld; i++)
217  {
218  int coord = _inside.transformingsubiterator().coord(i);
219 
220  if ((i == _dir) and (_face))
221  coord++;
222 
223  ll[i] = _inside.transformingsubiterator().coordCont()->coordinate(i,coord);
224  if (i != _dir)
225  coord++;
226  ur[i] = _inside.transformingsubiterator().coordCont()->coordinate(i,coord);
227 
228  // If on periodic overlap, transform coordinates by domain size
229  if (_inside.gridlevel()->mg->isPeriodic(i)) {
230  int coordPeriodic = _inside.transformingsubiterator().coord(i);
231  if (coordPeriodic < 0) {
232  auto size = _inside.gridlevel()->mg->domainSize()[i];
233  ll[i] += size;
234  ur[i] += size;
235  } else if (coordPeriodic + 1 > _inside.gridlevel()->mg->levelSize(_inside.gridlevel()->level(),i)) {
236  auto size = _inside.gridlevel()->mg->domainSize()[i];
237  ll[i] -= size;
238  ur[i] -= size;
239  }
240  }
241  }
242 
243  GeometryImpl _is_global(ll,ur,shift);
244  return Geometry( _is_global );
245  }
246 
249  {
250  return GeometryTypes::cube(dim-1);
251  }
252 
254  int indexInInside () const
255  {
256  return _count;
257  }
258 
260  int indexInOutside () const
261  {
262  // flip the last bit
263  return _count^1;
264  }
265 
267  : _count(~uint8_t(0)) // Use as marker for invalid intersection
268  , _dir(0)
269  , _face(0)
270  {}
271 
273  YaspIntersection (const YaspEntity<0,dim,GridImp>& myself, bool toend) :
274  _inside(myself.gridlevel(),
275  myself.transformingsubiterator()),
276  _outside(myself.gridlevel(),
277  myself.transformingsubiterator()),
278  // initialize to first neighbor
279  _count(0),
280  _dir(0),
281  _face(0)
282  {
283  if (toend)
284  {
285  // initialize end iterator
286  _count = 2*dim;
287  return;
288  }
289  _count = 0;
290 
291  // move transforming iterator
292  _outside.transformingsubiterator().move(_dir,-1);
293  }
294 
296 
298  void assign (const YaspIntersection& it)
299  {
300  *this = it;
301  }
302 
303  bool equals(const YaspIntersection& other) const
304  {
305  // compare counts first -- that's cheaper if the test fails
306  return _count == other._count && _inside.equals(other._inside);
307  }
308 
309  private:
310  /* The two entities that make up the intersection */
311  YaspEntity<0,GridImp::dimension,GridImp> _inside;
312  YaspEntity<0,GridImp::dimension,GridImp> _outside;
313  /* current position */
314  uint8_t _count;
315  uint8_t _dir;
316  uint8_t _face;
317 
318  /* static data */
319  struct faceInfo
320  {
321  FieldVector<ctype, dimworld> normal;
322  LocalGeometryImpl geom_inside;
323  LocalGeometryImpl geom_outside;
324  };
325 
326  /* static face info */
327  static const std::array<faceInfo, 2*GridImp::dimension> _faceInfo;
328 
329  static std::array<faceInfo, 2*dim> initFaceInfo()
330  {
331  std::array<faceInfo, 2*dim> I;
332  for (uint8_t i=0; i<dim; i++)
333  {
334  // compute normals
335  I[2*i].normal = 0.0;
336  I[2*i+1].normal = 0.0;
337  I[2*i].normal[i] = -1.0;
338  I[2*i+1].normal[i] = +1.0;
339 
340  // determine the shift vector for these intersection
341  std::bitset<dim> s;
342  s.set();
343  s[i] = false;
344 
345  // store intersection geometries
348  ur[i] = 0.0;
349 
350  I[2*i].geom_inside = LocalGeometryImpl(ll,ur,s);
351  I[2*i+1].geom_outside = LocalGeometryImpl(ll,ur,s);
352 
353  ll[i] = 1.0;
354  ur[i] = 1.0;
355 
356  I[2*i].geom_outside = LocalGeometryImpl(ll,ur,s);
357  I[2*i+1].geom_inside = LocalGeometryImpl(ll,ur,s);
358  }
359 
360  return I;
361  }
362  };
363 
364  template<class GridImp>
365  const std::array<typename YaspIntersection<GridImp>::faceInfo, 2*GridImp::dimension>
366  YaspIntersection<GridImp>::_faceInfo =
367  YaspIntersection<GridImp>::initFaceInfo();
368 
369 } // namespace Dune
370 
371 #endif // DUNE_GRID_YASPGRIDINTERSECTION_HH
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:277
Base class for exceptions in Dune grid modules.
Definition: exceptions.hh:18
YaspIntersectionIterator enables iteration over intersections with neighboring codim 0 entities.
Definition: yaspgridintersectioniterator.hh:20
YaspIntersection provides data about intersection with neighboring codim 0 entities.
Definition: yaspgridintersection.hh:20
Entity inside() const
Definition: yaspgridintersection.hh:90
Geometry geometry() const
Definition: yaspgridintersection.hh:208
FieldVector< ctype, dimworld > unitOuterNormal(const FieldVector< ctype, dim-1 > &local) const
return unit outer normal, this should be dependent on local coordinates for higher order boundary
Definition: yaspgridintersection.hh:169
FieldVector< ctype, dimworld > outerNormal(const FieldVector< ctype, dim-1 > &local) const
return unit outer normal, this should be dependent on local coordinates for higher order boundary
Definition: yaspgridintersection.hh:163
int indexInOutside() const
local index of codim 1 entity in neighbor where intersection is contained in
Definition: yaspgridintersection.hh:260
LocalGeometry geometryInInside() const
Definition: yaspgridintersection.hh:193
int boundarySegmentIndex() const
Definition: yaspgridintersection.hh:103
bool conforming() const
Yasp is always conform.
Definition: yaspgridintersection.hh:83
bool neighbor() const
return true if neighbor across intersection exists in this processor
Definition: yaspgridintersection.hh:73
YaspIntersection(const YaspEntity< 0, dim, GridImp > &myself, bool toend)
make intersection iterator from entity, initialize to first neighbor
Definition: yaspgridintersection.hh:273
GeometryType type() const
obtain the type of reference element for this intersection
Definition: yaspgridintersection.hh:248
void assign(const YaspIntersection &it)
copy constructor – use default
Definition: yaspgridintersection.hh:298
int indexInInside() const
local index of codim 1 entity in self where intersection is contained in
Definition: yaspgridintersection.hh:254
FieldVector< ctype, dimworld > integrationOuterNormal(const FieldVector< ctype, dim-1 > &local) const
Definition: yaspgridintersection.hh:183
LocalGeometry geometryInOutside() const
Definition: yaspgridintersection.hh:201
Entity outside() const
return Entity on the outside of this intersection
Definition: yaspgridintersection.hh:96
bool boundary() const
Definition: yaspgridintersection.hh:60
FieldVector< ctype, dimworld > centerUnitOuterNormal() const
return unit outer normal at center of intersection geometry
Definition: yaspgridintersection.hh:175
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:705
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:435
Dune namespace.
Definition: alignedallocator.hh:10
Static tag representing a codimension.
Definition: dimension.hh:22
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 2, 22:35, 2024)