version 3.11-dev
Loading...
Searching...
No Matches
boxgeometryhelper.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_DISCRETIZATION_BOX_GEOMETRY_HELPER_HH
14#define DUMUX_DISCRETIZATION_BOX_GEOMETRY_HELPER_HH
15
16#include <array>
17
18#include <dune/common/exceptions.hh>
19
20#include <dune/geometry/type.hh>
21#include <dune/geometry/typeindex.hh>
22#include <dune/geometry/referenceelements.hh>
23#include <dune/geometry/multilineargeometry.hh>
24
25#include <dune/common/rangeutilities.hh>
26
28#include <dumux/common/math.hh>
32
33namespace Dumux {
34
36template <class ct>
37struct BoxMLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct>
38{
39 // we use static vectors to store the corners as we know
40 // the number of corners in advance (2^(mydim) corners (1<<(mydim))
41 template< int mydim, int cdim >
43 {
44 using Type = std::array< Dune::FieldVector< ct, cdim >, (1<<(mydim)) >;
45 };
46
47 // we know all scvfs will have the same geometry type
48 template< int mydim >
50 {
51 static const bool v = true;
52 static const unsigned int topologyId = Dune::GeometryTypes::cube(mydim).id();
53 };
54};
55
56namespace Detail::Box {
57
58template<Dune::GeometryType::Id gt>
60
61template<>
62struct ScvCorners<Dune::GeometryTypes::line>
63{
64 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
65 static constexpr std::array<std::array<Key, 2>, 2> keys = {{
66 { Key{0, 1}, Key{0, 0} },
67 { Key{1, 1}, Key{0, 0} }
68 }};
69};
70
71template<>
72struct ScvCorners<Dune::GeometryTypes::triangle>
73{
74 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
75 static constexpr std::array<std::array<Key, 4>, 3> keys = {{
76 { Key{0, 2}, Key{0, 1}, Key{1, 1}, Key{0, 0} },
77 { Key{1, 2}, Key{2, 1}, Key{0, 1}, Key{0, 0} },
78 { Key{2, 2}, Key{1, 1}, Key{2, 1}, Key{0, 0} }
79 }};
80};
81
82template<>
83struct ScvCorners<Dune::GeometryTypes::quadrilateral>
84{
85 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
86 static constexpr std::array<std::array<Key, 4>, 4> keys = {{
87 { Key{0, 2}, Key{2, 1}, Key{0, 1}, Key{0, 0} },
88 { Key{1, 2}, Key{1, 1}, Key{2, 1}, Key{0, 0} },
89 { Key{2, 2}, Key{0, 1}, Key{3, 1}, Key{0, 0} },
90 { Key{3, 2}, Key{3, 1}, Key{1, 1}, Key{0, 0} }
91 }};
92};
93
94template<>
95struct ScvCorners<Dune::GeometryTypes::tetrahedron>
96{
97 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
98 static constexpr std::array<std::array<Key, 8>, 4> keys = {{
99 { Key{0, 3}, Key{0, 2}, Key{1, 2}, Key{0, 1}, Key{3, 2}, Key{1, 1}, Key{2, 1}, Key{0, 0} },
100 { Key{1, 3}, Key{2, 2}, Key{0, 2}, Key{0, 1}, Key{4, 2}, Key{3, 1}, Key{1, 1}, Key{0, 0} },
101 { Key{2, 3}, Key{1, 2}, Key{2, 2}, Key{0, 1}, Key{5, 2}, Key{2, 1}, Key{3, 1}, Key{0, 0} },
102 { Key{3, 3}, Key{3, 2}, Key{5, 2}, Key{2, 1}, Key{4, 2}, Key{1, 1}, Key{3, 1}, Key{0, 0} }
103 }};
104};
105
106template<>
107struct ScvCorners<Dune::GeometryTypes::prism>
108{
109 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
110 static constexpr std::array<std::array<Key, 8>, 6> keys = {{
111 { Key{0, 3}, Key{3, 2}, Key{4, 2}, Key{3, 1}, Key{0, 2}, Key{0, 1}, Key{1, 1}, Key{0, 0} },
112 { Key{1, 3}, Key{5, 2}, Key{3, 2}, Key{3, 1}, Key{1, 2}, Key{2, 1}, Key{0, 1}, Key{0, 0} },
113 { Key{2, 3}, Key{4, 2}, Key{5, 2}, Key{3, 1}, Key{2, 2}, Key{1, 1}, Key{2, 1}, Key{0, 0} },
114 { Key{3, 3}, Key{7, 2}, Key{6, 2}, Key{4, 1}, Key{0, 2}, Key{1, 1}, Key{0, 1}, Key{0, 0} },
115 { Key{4, 3}, Key{6, 2}, Key{8, 2}, Key{4, 1}, Key{1, 2}, Key{0, 1}, Key{2, 1}, Key{0, 0} },
116 { Key{5, 3}, Key{8, 2}, Key{7, 2}, Key{4, 1}, Key{2, 2}, Key{2, 1}, Key{1, 1}, Key{0, 0} }
117 }};
118};
119
120template<>
121struct ScvCorners<Dune::GeometryTypes::hexahedron>
122{
123 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
124 static constexpr std::array<std::array<Key, 8>, 8> keys = {{
125 { Key{0, 3}, Key{6, 2}, Key{4, 2}, Key{4, 1}, Key{0, 2}, Key{2, 1}, Key{0, 1}, Key{0, 0} },
126 { Key{1, 3}, Key{5, 2}, Key{6, 2}, Key{4, 1}, Key{1, 2}, Key{1, 1}, Key{2, 1}, Key{0, 0} },
127 { Key{2, 3}, Key{4, 2}, Key{7, 2}, Key{4, 1}, Key{2, 2}, Key{0, 1}, Key{3, 1}, Key{0, 0} },
128 { Key{3, 3}, Key{7, 2}, Key{5, 2}, Key{4, 1}, Key{3, 2}, Key{3, 1}, Key{1, 1}, Key{0, 0} },
129 { Key{4, 3}, Key{8, 2}, Key{10, 2}, Key{5, 1}, Key{0, 2}, Key{0, 1}, Key{2, 1}, Key{0, 0} },
130 { Key{5, 3}, Key{10, 2}, Key{9, 2}, Key{5, 1}, Key{1, 2}, Key{2, 1}, Key{1, 1}, Key{0, 0} },
131 { Key{6, 3}, Key{11, 2}, Key{8, 2}, Key{5, 1}, Key{2, 2}, Key{3, 1}, Key{0, 1}, Key{0, 0} },
132 { Key{7, 3}, Key{9, 2}, Key{11, 2}, Key{5, 1}, Key{3, 2}, Key{1, 1}, Key{3, 1}, Key{0, 0} }
133 }};
134};
135
136template<Dune::GeometryType::Id gt>
138
139template<>
140struct ScvfCorners<Dune::GeometryTypes::line>
141{
142 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
143 static constexpr std::array<std::array<Key, 1>, 1> keys = {{
144 { Key{0, 0} }
145 }};
146};
147
148template<>
149struct ScvfCorners<Dune::GeometryTypes::triangle>
150{
151 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
152 static constexpr std::array<std::array<Key, 2>, 3> keys = {{
153 { Key{0, 0}, Key{0, 1} },
154 { Key{1, 1}, Key{0, 0} },
155 { Key{0, 0}, Key{2, 1} }
156 }};
157};
158
159template<>
160struct ScvfCorners<Dune::GeometryTypes::quadrilateral>
161{
162 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
163 static constexpr std::array<std::array<Key, 2>, 4> keys = {{
164 { Key{0, 1}, Key{0, 0} },
165 { Key{0, 0}, Key{1, 1} },
166 { Key{0, 0}, Key{2, 1} },
167 { Key{3, 1}, Key{0, 0} }
168 }};
169};
170
171template<>
172struct ScvfCorners<Dune::GeometryTypes::tetrahedron>
173{
174 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
175 static constexpr std::array<std::array<Key, 4>, 6> keys = {{
176 { Key{0, 2}, Key{0, 1}, Key{1, 1}, Key{0, 0} },
177 { Key{0, 1}, Key{1, 2}, Key{0, 0}, Key{2, 1} },
178 { Key{2, 2}, Key{0, 1}, Key{3, 1}, Key{0, 0} },
179 { Key{2, 1}, Key{3, 2}, Key{0, 0}, Key{1, 1} },
180 { Key{3, 1}, Key{0, 0}, Key{4, 2}, Key{1, 1} },
181 { Key{5, 2}, Key{2, 1}, Key{3, 1}, Key{0, 0} }
182 }};
183};
184
185template<>
186struct ScvfCorners<Dune::GeometryTypes::prism>
187{
188 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
189 static constexpr std::array<std::array<Key, 4>, 9> keys = {{
190 { Key{0, 2}, Key{0, 1}, Key{1, 1}, Key{0, 0} },
191 { Key{1, 2}, Key{2, 1}, Key{0, 1}, Key{0, 0} },
192 { Key{2, 2}, Key{1, 1}, Key{2, 1}, Key{0, 0} },
193 { Key{3, 2}, Key{0, 1}, Key{3, 1}, Key{0, 0} },
194 { Key{4, 2}, Key{3, 1}, Key{1, 1}, Key{0, 0} },
195 { Key{5, 2}, Key{2, 1}, Key{3, 1}, Key{0, 0} },
196 { Key{6, 2}, Key{4, 1}, Key{0, 1}, Key{0, 0} },
197 { Key{7, 2}, Key{1, 1}, Key{4, 1}, Key{0, 0} },
198 { Key{8, 2}, Key{4, 1}, Key{2, 1}, Key{0, 0} }
199 }};
200};
201
202template<>
203struct ScvfCorners<Dune::GeometryTypes::hexahedron>
204{
205 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
206 static constexpr std::array<std::array<Key, 4>, 12> keys = {{
207 { Key{0, 1}, Key{0, 2}, Key{0, 0}, Key{2, 1} },
208 { Key{1, 1}, Key{0, 0}, Key{1, 2}, Key{2, 1} },
209 { Key{3, 1}, Key{2, 2}, Key{0, 0}, Key{0, 1} },
210 { Key{3, 2}, Key{3, 1}, Key{1, 1}, Key{0, 0} },
211 { Key{4, 1}, Key{4, 2}, Key{0, 0}, Key{0, 1} },
212 { Key{5, 2}, Key{4, 1}, Key{1, 1}, Key{0, 0} },
213 { Key{6, 2}, Key{4, 1}, Key{2, 1}, Key{0, 0} },
214 { Key{4, 1}, Key{7, 2}, Key{0, 0}, Key{3, 1} },
215 { Key{0, 0}, Key{0, 1}, Key{5, 1}, Key{8, 2} },
216 { Key{9, 2}, Key{1, 1}, Key{5, 1}, Key{0, 0} },
217 { Key{10, 2}, Key{2, 1}, Key{5, 1}, Key{0, 0} },
218 { Key{11, 2}, Key{5, 1}, Key{3, 1}, Key{0, 0} }
219 }};
220};
221
222
223// convert key array to corner storage
224template<class S, class ReferenceElement, class Transformation, class KeyArray, std::size_t... I>
225S keyToCornerStorageImpl(const ReferenceElement& ref, Transformation&& trans, const KeyArray& key, std::index_sequence<I...>)
226{
227 // key is a pair of a local sub-entity index (first) and the sub-entity's codim (second)
228 return { trans(ref.position(key[I].first, key[I].second))... };
229}
230
231// convert key array to corner storage
232template<class S, class ReferenceElement, class Transformation, class T, std::size_t N, class Indices = std::make_index_sequence<N>>
233S keyToCornerStorage(const ReferenceElement& ref, Transformation&& trans, const std::array<T, N>& key)
234{
235 return keyToCornerStorageImpl<S>(ref, trans, key, Indices{});
236}
237
238// convert key array to corner storage
239// for the i-th sub-entity of codim c (e.g. the i-th facet/codim-1-entity for boundaries)
240template<class S, class ReferenceElement, class Transformation, class KeyArray, std::size_t... I>
241S subEntityKeyToCornerStorageImpl(const ReferenceElement& ref, Transformation&& trans,
242 unsigned int i, unsigned int c, const KeyArray& key, std::index_sequence<I...>)
243{
244 // subEntity gives the subEntity number with respect to the codim-0 reference element
245 // key is a pair of a local sub-entity index (first) and the sub-entity's codim (second) but here w.r.t. the sub-entity i/c
246 return { trans(ref.position(ref.subEntity(i, c, key[I].first, c+key[I].second), c+key[I].second))... };
247}
248
249// convert key array to corner storage
250// for the i-th sub-entity of codim c (e.g. the i-th facet/codim-1-entity for boundaries)
251template<class S, class ReferenceElement, class Transformation, class T, std::size_t N, class Indices = std::make_index_sequence<N>>
252S subEntityKeyToCornerStorage(const ReferenceElement& ref, Transformation&& trans,
253 unsigned int i, unsigned int c, const std::array<T, N>& key)
254{
255 return subEntityKeyToCornerStorageImpl<S>(ref, trans, i, c, key, Indices{});
256}
257
258} // end namespace Detail::Box
259
261template<class GridView, int dim, class ScvType, class ScvfType>
263
265template <class GridView, class ScvType, class ScvfType>
266class BoxGeometryHelper<GridView, 1, ScvType, ScvfType>
267{
268private:
269 using Scalar = typename GridView::ctype;
270 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
271 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
272 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
273 using ScvGeometry = typename ScvType::Traits::Geometry;
274 using ScvfGeometry = typename ScvfType::Traits::Geometry;
275 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
276
277 using Element = typename GridView::template Codim<0>::Entity;
278 using Intersection = typename GridView::Intersection;
279
280 static constexpr int dim = 1;
281public:
283
284 explicit BoxGeometryHelper(const typename Element::Geometry& geometry)
285 : geo_(geometry)
286 {}
287
289 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
290 {
291 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
292 }
293
295 template<class Transformation>
296 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
297 {
298 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
300 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localScvIdx]);
301 }
302
303 ScvGeometry scvGeometry(unsigned int localScvIdx) const
304 {
305 return { Dune::GeometryTypes::line, getScvCorners(localScvIdx) };
306 }
307
309 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
310 {
311 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
312 }
313
315 template<class Transformation>
316 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
317 {
318 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
320 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localScvfIdx]);
321 }
322
324 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
325 unsigned int) const
326 {
327 return ScvfCornerStorage{{ geo_.corner(localFacetIndex) }};
328 }
329
331 template<class Transformation>
332 static ScvfCornerStorage getBoundaryScvfCorners(Dune::GeometryType type,
333 Transformation&& trans,
334 unsigned int localFacetIndex,
335 unsigned int indexInFacet)
336 {
337 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
338 return trans(ref.position(localFacetIndex, dim));
339 }
340
342 GlobalPosition normal(const ScvfCornerStorage& scvfCorners,
343 const std::array<LocalIndexType, 2>&) const
344 {
345 auto normal = geo_.corner(1) - geo_.corner(0);
346 normal /= normal.two_norm();
347 return normal;
348 }
349
351 std::size_t numInteriorScvf() const
352 {
353 return referenceElement(geo_).size(dim-1);
354 }
355
357 static auto numInteriorScvf(Dune::GeometryType type)
358 {
359 return Dune::referenceElement<Scalar, dim>(type).size(dim-1);
360 }
361
363 std::size_t numScv() const
364 {
365 return referenceElement(geo_).size(dim);
366 }
367
369 const typename Element::Geometry& elementGeometry() const
370 { return geo_; }
371
373 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
374 {
375 return Dumux::center(getScvfCorners_(type, [&](const auto& local){ return local; }, localScvfIdx));
376 }
377
379 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int)
380 {
381 return Dune::referenceElement<Scalar, dim>(type).position(localFacetIndex, dim);
382 }
383
384private:
385 const typename Element::Geometry& geo_;
386};
387
389template <class GridView, class ScvType, class ScvfType>
390class BoxGeometryHelper<GridView, 2, ScvType, ScvfType>
391{
392 using Scalar = typename GridView::ctype;
393 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
394 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
395 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
396 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
397
398 using Element = typename GridView::template Codim<0>::Entity;
399 using Intersection = typename GridView::Intersection;
400
401 static constexpr auto dim = GridView::dimension;
402 static constexpr auto dimWorld = GridView::dimensionworld;
403public:
405
406 explicit BoxGeometryHelper(const typename Element::Geometry& geometry)
407 : geo_(geometry)
408 {}
409
411 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
412 {
413 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
414 }
415
417 template<class Transformation>
418 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
419 {
420 // proceed according to number of corners of the element
421 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
422 if (type == Dune::GeometryTypes::triangle)
423 {
425 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localScvIdx]);
426 }
427 else if (type == Dune::GeometryTypes::quadrilateral)
428 {
430 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localScvIdx]);
431 }
432 else
433 DUNE_THROW(Dune::NotImplemented, "Box scv geometries for dim=" << dim
434 << " dimWorld=" << dimWorld
435 << " type=" << type);
436 }
437
439 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
440 {
441 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
442 }
443
445 template<class Transformation>
446 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
447 {
448 // proceed according to number of corners
449 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
450 if (type == Dune::GeometryTypes::triangle)
451 {
453 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localScvfIdx]);
454 }
455 else if (type == Dune::GeometryTypes::quadrilateral)
456 {
458 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localScvfIdx]);
459 }
460 else
461 DUNE_THROW(Dune::NotImplemented, "Box scvf geometries for dim=" << dim
462 << " dimWorld=" << dimWorld
463 << " type=" << type);
464 }
465
467 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
468 unsigned int indexInFacet) const
469 {
470 return getBoundaryScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localFacetIndex, indexInFacet);
471 }
472
474 template<class Transformation>
475 static ScvfCornerStorage getBoundaryScvfCorners(Dune::GeometryType type,
476 Transformation&& trans,
477 unsigned int localFacetIndex,
478 unsigned int indexInFacet)
479 {
480 // we have to use the corresponding facet geometry as the intersection geometry
481 // might be rotated or flipped. This makes sure that the corners (dof location)
482 // and corresponding scvfs are sorted in the same way
483 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
485 constexpr int facetCodim = 1;
486 return Detail::Box::subEntityKeyToCornerStorage<ScvfCornerStorage>(ref, trans, localFacetIndex, facetCodim, Corners::keys[indexInFacet]);
487 }
488
490 GlobalPosition normal(const ScvfCornerStorage& scvfCorners,
491 const std::array<LocalIndexType, 2>& scvIndices) const
492 {
493 auto normal = Detail::scvfUnitNormal(geo_, scvfCorners);
494
496 const auto v = geo_.corner(scvIndices[1]) - geo_.corner(scvIndices[0]);
497 const auto s = v*normal;
498 if (std::signbit(s))
499 normal *= -1;
500
501 return normal;
502 }
503
505 std::size_t numInteriorScvf() const
506 {
507 return referenceElement(geo_).size(dim-1);
508 }
509
511 static auto numInteriorScvf(Dune::GeometryType type)
512 {
513 return Dune::referenceElement<Scalar, dim>(type).size(dim-1);
514 }
515
517 std::size_t numScv() const
518 {
519 return referenceElement(geo_).size(dim);
520 }
521
523 const typename Element::Geometry& elementGeometry() const
524 { return geo_; }
525
527 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
528 {
529 return Dumux::center(getScvfCorners(type, [&](const auto& local){ return local; }, localScvfIdx));
530 }
531
533 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
534 {
535 return Dumux::center(getBoundaryScvfCorners(type, [&](const auto& local){ return local; }, localFacetIndex, indexInFace));
536 }
537
538private:
539 const typename Element::Geometry& geo_;
540};
541
543template <class GridView, class ScvType, class ScvfType>
544class BoxGeometryHelper<GridView, 3, ScvType, ScvfType>
545{
546 using Scalar = typename GridView::ctype;
547 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
548 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
549 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
550 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
551
552 using Element = typename GridView::template Codim<0>::Entity;
553 using Intersection = typename GridView::Intersection;
554
555 static constexpr auto dim = GridView::dimension;
556 static constexpr auto dimWorld = GridView::dimensionworld;
557
558public:
560
561 explicit BoxGeometryHelper(const typename Element::Geometry& geometry)
562 : geo_(geometry)
563 {}
564
566 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
567 {
568 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
569 }
570
572 template<class Transformation>
573 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
574 {
575 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
576 if (type == Dune::GeometryTypes::tetrahedron)
577 {
579 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localScvIdx]);
580 }
581 else if (type == Dune::GeometryTypes::prism)
582 {
584 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localScvIdx]);
585 }
586 else if (type == Dune::GeometryTypes::hexahedron)
587 {
589 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localScvIdx]);
590 }
591 else
592 DUNE_THROW(Dune::NotImplemented, "Box scv geometries for dim=" << dim
593 << " dimWorld=" << dimWorld
594 << " type=" << type);
595 }
596
598 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
599 {
600 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
601 }
602
604 template<class Transformation>
605 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
606 {
607 // proceed according to number of corners
608 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
609 if (type == Dune::GeometryTypes::tetrahedron)
610 {
612 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localScvfIdx]);
613 }
614 else if (type == Dune::GeometryTypes::prism)
615 {
617 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localScvfIdx]);
618 }
619 else if (type == Dune::GeometryTypes::hexahedron)
620 {
622 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localScvfIdx]);
623 }
624 else
625 DUNE_THROW(Dune::NotImplemented, "Box scvf geometries for dim=" << dim
626 << " dimWorld=" << dimWorld
627 << " type=" << type);
628 }
629
631 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
632 unsigned int indexInFacet) const
633 {
634 return getBoundaryScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localFacetIndex, indexInFacet);
635 }
636
638 template<class Transformation>
639 static ScvfCornerStorage getBoundaryScvfCorners(Dune::GeometryType type,
640 Transformation&& trans,
641 unsigned localFacetIndex,
642 unsigned int indexInFacet)
643 {
644 constexpr int facetCodim = 1;
645
646 // we have to use the corresponding facet geometry as the intersection geometry
647 // might be rotated or flipped. This makes sure that the corners (dof location)
648 // and corresponding scvfs are sorted in the same way
649 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
650 const auto facetType = ref.type(localFacetIndex, facetCodim);
651 if (facetType == Dune::GeometryTypes::triangle)
652 {
654 return Detail::Box::subEntityKeyToCornerStorage<ScvfCornerStorage>(ref, trans, localFacetIndex, facetCodim, Corners::keys[indexInFacet]);
655 }
656 else if (facetType == Dune::GeometryTypes::quadrilateral)
657 {
659 return Detail::Box::subEntityKeyToCornerStorage<ScvfCornerStorage>(ref, trans, localFacetIndex, facetCodim, Corners::keys[indexInFacet]);
660 }
661 else
662 DUNE_THROW(Dune::NotImplemented, "Box boundary scvf geometries for dim=" << dim
663 << " dimWorld=" << dimWorld
664 << " type=" << facetType);
665 }
666
668 GlobalPosition normal(const ScvfCornerStorage& p,
669 const std::array<LocalIndexType, 2>& scvIndices) const
670 {
671 auto normal = Detail::scvfUnitNormal(geo_, p);
672
673 const auto v = geo_.corner(scvIndices[1]) - geo_.corner(scvIndices[0]);
674 const auto s = v*normal;
675 if (std::signbit(s))
676 normal *= -1;
677
678 return normal;
679 }
680
682 std::size_t numInteriorScvf() const
683 {
684 return referenceElement(geo_).size(dim-1);
685 }
686
688 static auto numInteriorScvf(Dune::GeometryType type)
689 {
690 return Dune::referenceElement<Scalar, dim>(type).size(dim-1);
691 }
692
694 std::size_t numScv() const
695 {
696 return referenceElement(geo_).size(dim);
697 }
698
700 const typename Element::Geometry& elementGeometry() const
701 { return geo_; }
702
704 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
705 {
706 return Dumux::center(getScvfCorners(type, [&](const auto& local){ return local; }, localScvfIdx));
707 }
708
710 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
711 {
712 return Dumux::center(getBoundaryScvfCorners(type, [&](const auto& local){ return local; }, localFacetIndex, indexInFace));
713 }
714
715private:
716 const typename Element::Geometry& geo_;
717};
718
719} // end namespace Dumux
720
721#endif
Compute the center point of a convex polytope geometry or a random-access container of corner points.
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition boxgeometryhelper.hh:369
std::size_t numInteriorScvf() const
number of sub control volume faces (number of edges)
Definition boxgeometryhelper.hh:351
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition boxgeometryhelper.hh:373
BoxGeometryHelper(const typename Element::Geometry &geometry)
Definition boxgeometryhelper.hh:284
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition boxgeometryhelper.hh:289
PQ1LagrangeDofHelper< GridView > DofHelper
Definition boxgeometryhelper.hh:282
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int) const
Create the sub control volume face geometries on the boundary.
Definition boxgeometryhelper.hh:324
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition boxgeometryhelper.hh:296
GlobalPosition normal(const ScvfCornerStorage &scvfCorners, const std::array< LocalIndexType, 2 > &) const
get scvf normal vector
Definition boxgeometryhelper.hh:342
std::size_t numScv() const
number of sub control volumes (number of vertices)
Definition boxgeometryhelper.hh:363
ScvGeometry scvGeometry(unsigned int localScvIdx) const
Definition boxgeometryhelper.hh:303
static ScvfCornerStorage getBoundaryScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localFacetIndex, unsigned int indexInFacet)
Create the sub control volume face geometries on the boundary.
Definition boxgeometryhelper.hh:332
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition boxgeometryhelper.hh:309
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces (number of edges)
Definition boxgeometryhelper.hh:357
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int)
local boundary scvf center
Definition boxgeometryhelper.hh:379
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the corners of sub control volume faces.
Definition boxgeometryhelper.hh:316
std::size_t numScv() const
number of sub control volumes (number of vertices)
Definition boxgeometryhelper.hh:517
std::size_t numInteriorScvf() const
number of sub control volume faces (number of edges)
Definition boxgeometryhelper.hh:505
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition boxgeometryhelper.hh:527
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the corners of sub control volume faces.
Definition boxgeometryhelper.hh:446
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition boxgeometryhelper.hh:418
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition boxgeometryhelper.hh:439
PQ1LagrangeDofHelper< GridView > DofHelper
Definition boxgeometryhelper.hh:404
BoxGeometryHelper(const typename Element::Geometry &geometry)
Definition boxgeometryhelper.hh:406
static ScvfCornerStorage getBoundaryScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localFacetIndex, unsigned int indexInFacet)
Create the sub control volume face geometries on the boundary.
Definition boxgeometryhelper.hh:475
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition boxgeometryhelper.hh:467
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition boxgeometryhelper.hh:523
GlobalPosition normal(const ScvfCornerStorage &scvfCorners, const std::array< LocalIndexType, 2 > &scvIndices) const
get scvf normal vector
Definition boxgeometryhelper.hh:490
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
local boundary scvf center
Definition boxgeometryhelper.hh:533
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces (number of edges)
Definition boxgeometryhelper.hh:511
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition boxgeometryhelper.hh:411
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces (number of edges)
Definition boxgeometryhelper.hh:688
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvIndices) const
get scvf normal vector
Definition boxgeometryhelper.hh:668
BoxGeometryHelper(const typename Element::Geometry &geometry)
Definition boxgeometryhelper.hh:561
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition boxgeometryhelper.hh:700
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the scvf corners.
Definition boxgeometryhelper.hh:605
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition boxgeometryhelper.hh:631
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition boxgeometryhelper.hh:566
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
local boundary scvf center
Definition boxgeometryhelper.hh:710
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition boxgeometryhelper.hh:704
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the scvf corners.
Definition boxgeometryhelper.hh:598
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition boxgeometryhelper.hh:573
std::size_t numScv() const
number of sub control volumes (number of vertices)
Definition boxgeometryhelper.hh:694
std::size_t numInteriorScvf() const
number of sub control volume faces (number of edges)
Definition boxgeometryhelper.hh:682
static ScvfCornerStorage getBoundaryScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned localFacetIndex, unsigned int indexInFacet)
Create the sub control volume face geometries on the boundary.
Definition boxgeometryhelper.hh:639
PQ1LagrangeDofHelper< GridView > DofHelper
Definition boxgeometryhelper.hh:559
Create sub control volumes and sub control volume face geometries.
Definition boxgeometryhelper.hh:262
Helper class providing degree of freedom information for the PQ1 Lagrange basis. The pq1 basis uses v...
Definition pq1/dofhelper.hh:32
auto scvfUnitNormal(const ElementGeometry &geo, const CornerStorage &corners)
Unit normal of an interior sub-control volume face, up to sign.
Definition scvfnormal.hh:33
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition center.hh:24
Defines the index types used for grid and local indices.
Define some often used mathematical functions.
Definition boxgeometryhelper.hh:56
S subEntityKeyToCornerStorage(const ReferenceElement &ref, Transformation &&trans, unsigned int i, unsigned int c, const std::array< T, N > &key)
Definition boxgeometryhelper.hh:252
S keyToCornerStorageImpl(const ReferenceElement &ref, Transformation &&trans, const KeyArray &key, std::index_sequence< I... >)
Definition boxgeometryhelper.hh:225
S keyToCornerStorage(const ReferenceElement &ref, Transformation &&trans, const std::array< T, N > &key)
Definition boxgeometryhelper.hh:233
S subEntityKeyToCornerStorageImpl(const ReferenceElement &ref, Transformation &&trans, unsigned int i, unsigned int c, const KeyArray &key, std::index_sequence< I... >)
Definition boxgeometryhelper.hh:241
Definition adapt.hh:17
Definition common/pdesolver.hh:24
Helper class providing degree of freedom information for the PQ1 Lagrange basis.
Normal vector of a sub-control volume face of an element-local dual grid.
Definition boxgeometryhelper.hh:43
std::array< Dune::FieldVector< ct, cdim >,(1<<(mydim)) > Type
Definition boxgeometryhelper.hh:44
Definition boxgeometryhelper.hh:50
static const bool v
Definition boxgeometryhelper.hh:51
static const unsigned int topologyId
Definition boxgeometryhelper.hh:52
Traits for an efficient corner storage for box method sub control volumes.
Definition boxgeometryhelper.hh:38
static constexpr std::array< std::array< Key, 8 >, 8 > keys
Definition boxgeometryhelper.hh:124
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:123
static constexpr std::array< std::array< Key, 2 >, 2 > keys
Definition boxgeometryhelper.hh:65
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:64
static constexpr std::array< std::array< Key, 8 >, 6 > keys
Definition boxgeometryhelper.hh:110
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:109
static constexpr std::array< std::array< Key, 4 >, 4 > keys
Definition boxgeometryhelper.hh:86
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:85
static constexpr std::array< std::array< Key, 8 >, 4 > keys
Definition boxgeometryhelper.hh:98
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:97
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:74
static constexpr std::array< std::array< Key, 4 >, 3 > keys
Definition boxgeometryhelper.hh:75
Definition boxgeometryhelper.hh:59
static constexpr std::array< std::array< Key, 4 >, 12 > keys
Definition boxgeometryhelper.hh:206
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:205
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:142
static constexpr std::array< std::array< Key, 1 >, 1 > keys
Definition boxgeometryhelper.hh:143
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:188
static constexpr std::array< std::array< Key, 4 >, 9 > keys
Definition boxgeometryhelper.hh:189
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:162
static constexpr std::array< std::array< Key, 2 >, 4 > keys
Definition boxgeometryhelper.hh:163
static constexpr std::array< std::array< Key, 4 >, 6 > keys
Definition boxgeometryhelper.hh:175
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:174
static constexpr std::array< std::array< Key, 2 >, 3 > keys
Definition boxgeometryhelper.hh:152
std::pair< std::uint8_t, std::uint8_t > Key
Definition boxgeometryhelper.hh:151
Definition boxgeometryhelper.hh:137