version 3.11-dev
discretization/pq1bubble/geometryhelper.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_PQ1BUBBLE_GEOMETRY_HELPER_HH
14#define DUMUX_DISCRETIZATION_PQ1BUBBLE_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/referenceelements.hh>
22#include <dune/geometry/multilineargeometry.hh>
23#include <dune/common/reservedvector.hh>
24
25#include <dumux/common/math.hh>
29
30namespace Dumux {
31
33template <class ct>
34struct PQ1BubbleMLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct>
35{
36 // we use static vectors to store the corners as we know
37 // the maximum number of corners in advance (2^dim for box-type sub-cells,
38 // overlapping sub-cells never exceed this count)
39 template< int mydim, int cdim >
41 {
42 using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<mydim)>;
43 };
44};
45
46
48
49template<Dune::GeometryType::Id gt>
51
52template<>
54{
55 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
56 static constexpr std::array<std::array<Key, 2>, 1> keys = {{
57 { Key{0, 1}, Key{1, 1} }
58 }};
59};
60
61template<>
62struct OverlappingScvCorners<Dune::GeometryTypes::triangle>
63{
64 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
65 static constexpr std::array<std::array<Key, 3>, 1> keys = {{
66 { Key{0, 1}, Key{1, 1}, Key{2, 1} }
67 }};
68};
69
70template<>
71struct OverlappingScvCorners<Dune::GeometryTypes::quadrilateral>
72{
73 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
74 static constexpr std::array<std::array<Key, 4>, 1> keys = {{
75 { Key{2, 1}, Key{1, 1}, Key{0, 1}, Key{3, 1} }
76 }};
77};
78
79template<>
80struct OverlappingScvCorners<Dune::GeometryTypes::tetrahedron>
81{
82 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
83 static constexpr std::array<std::array<Key, 4>, 1> keys = {{
84 { Key{0, 1}, Key{1, 1}, Key{2, 1}, Key{3, 1} }
85 }};
86};
87
88template<>
89struct OverlappingScvCorners<Dune::GeometryTypes::hexahedron>
90{
91 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
92 static constexpr std::array<std::array<Key, 6>, 1> keys = {{
93 { Key{0, 1}, Key{2, 1}, Key{3, 1}, Key{1, 1}, Key{4, 1}, Key{5, 1} }
94 }};
95};
96
97
98template<Dune::GeometryType::Id gt>
100
101template<>
103{
104 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
105 static constexpr std::array<std::array<Key, 1>, 1> keys = {{
106 { Key{0, 0} }
107 }};
108};
109
110template<>
111struct OverlappingScvfCorners<Dune::GeometryTypes::triangle>
112{
113 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
114 static constexpr std::array<std::array<Key, 2>, 3> keys = {{
115 { Key{0, 1}, Key{1, 1} },
116 { Key{0, 1}, Key{2, 1} },
117 { Key{1, 1}, Key{2, 1} }
118 }};
119};
120
121template<>
122struct OverlappingScvfCorners<Dune::GeometryTypes::quadrilateral>
123{
124 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
125 static constexpr std::array<std::array<Key, 2>, 4> keys = {{
126 { Key{0, 1}, Key{2, 1} },
127 { Key{2, 1}, Key{1, 1} },
128 { Key{0, 1}, Key{3, 1} },
129 { Key{1, 1}, Key{3, 1} }
130 }};
131};
132
133template<>
134struct OverlappingScvfCorners<Dune::GeometryTypes::tetrahedron>
135{
136 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
137 static constexpr std::array<std::array<Key, 3>, 10> keys = {{
138 { Key{0, 1}, Key{1, 1}, Key{2, 1} },
139 { Key{0, 1}, Key{1, 1}, Key{3, 1} },
140 { Key{0, 1}, Key{2, 1}, Key{3, 1} },
141 { Key{1, 1}, Key{2, 1}, Key{3, 1} }
142 }};
143};
144
145template<>
146struct OverlappingScvfCorners<Dune::GeometryTypes::hexahedron>
147{
148 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
149 static constexpr std::array<std::array<Key, 3>, 8> keys = {{
150 { Key{4, 1}, Key{0, 1}, Key{2, 1} },
151 { Key{4, 1}, Key{2, 1}, Key{1, 1} },
152 { Key{4, 1}, Key{0, 1}, Key{3, 1} },
153 { Key{4, 1}, Key{1, 1}, Key{3, 1} },
154 { Key{5, 1}, Key{0, 1}, Key{2, 1} },
155 { Key{5, 1}, Key{2, 1}, Key{1, 1} },
156 { Key{5, 1}, Key{0, 1}, Key{3, 1} },
157 { Key{5, 1}, Key{1, 1}, Key{3, 1} }
158 }};
159};
160
161} // end namespace Detail::PQ1Bubble
162
167template <class GridView, class ScvType, class ScvfType>
169{
170 using Scalar = typename GridView::ctype;
171 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
172 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
173 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
174 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
175
176 using Element = typename GridView::template Codim<0>::Entity;
177 using Intersection = typename GridView::Intersection;
178
179 static constexpr auto dim = GridView::dimension;
180 static constexpr auto dimWorld = GridView::dimensionworld;
181
183public:
184
185 PQ1BubbleGeometryHelper(const typename Element::Geometry& geometry)
186 : geo_(geometry)
187 , boxHelper_(geometry)
188 {}
189
191 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
192 {
193 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
194 }
195
197 template<class Transformation>
198 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
199 {
200 // proceed according to number of corners of the element
201 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
202 const auto numBoxScv = ref.size(dim);
203 // reuse box geometry helper for the corner scvs
204 if (localScvIdx < numBoxScv)
205 return BoxHelper::getScvCorners(type, trans, localScvIdx);
206
207 const auto localOverlappingScvIdx = localScvIdx-numBoxScv;
208 if (type == Dune::GeometryTypes::triangle)
209 {
211 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
212 }
213 else if (type == Dune::GeometryTypes::quadrilateral)
214 {
216 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
217 }
218 else if (type == Dune::GeometryTypes::tetrahedron)
219 {
221 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
222 }
223 else if (type == Dune::GeometryTypes::hexahedron)
224 {
226 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
227 }
228 else
229 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv geometries for dim=" << dim
230 << " dimWorld=" << dimWorld
231 << " type=" << type);
232 }
233
234 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
235 {
236 // proceed according to number of corners of the element
237 const auto type = geo_.type();
238 const auto numBoxScv = boxHelper_.numScv();
239 if (localScvIdx < numBoxScv)
240 return Dune::GeometryTypes::cube(dim);
241 else if (type == Dune::GeometryTypes::simplex(dim))
242 return Dune::GeometryTypes::simplex(dim);
243 else if (type == Dune::GeometryTypes::quadrilateral)
244 return Dune::GeometryTypes::quadrilateral;
245 else if (type == Dune::GeometryTypes::hexahedron)
246 return Dune::GeometryTypes::none(dim); // octahedron
247 else
248 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv geometries for dim=" << dim
249 << " dimWorld=" << dimWorld
250 << " type=" << type);
251 }
252
254 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
255 {
256 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
257 }
258
260 template<class Transformation>
261 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
262 {
263 // proceed according to number of corners
264 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
265 const auto numBoxScvf = ref.size(dim-1);
266 // reuse box geometry helper for the corner scvs
267 if (localScvfIdx < numBoxScvf)
268 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
269
270 const auto localOverlappingScvfIdx = localScvfIdx-numBoxScvf;
271 if (type == Dune::GeometryTypes::triangle)
272 {
274 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
275 }
276 else if (type == Dune::GeometryTypes::quadrilateral)
277 {
279 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
280 }
281 else if (type == Dune::GeometryTypes::tetrahedron)
282 {
284 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
285 }
286 else if (type == Dune::GeometryTypes::hexahedron)
287 {
289 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
290 }
291 else
292 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scvf geometries for dim=" << dim
293 << " dimWorld=" << dimWorld
294 << " type=" << type);
295 }
296
297 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
298 {
299 const auto numBoxScvf = boxHelper_.numInteriorScvf();
300 if (localScvfIdx < numBoxScvf)
301 return Dune::GeometryTypes::cube(dim-1);
302 else
303 return Dune::GeometryTypes::simplex(dim-1);
304 }
305
307 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
308 unsigned int indexInFacet) const
309 {
310 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
311 }
312
313 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
314 {
315 return Dune::GeometryTypes::cube(dim-1);
316 }
317
318 template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0>
319 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
320 {
321 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
322 normal /= normal.two_norm();
323
324 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
325
326 const auto s = v*normal;
327 if (std::signbit(s))
328 normal *= -1;
329
330 return normal;
331 }
332
333 template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0>
334 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
335 {
337 const auto t = p[1] - p[0];
338 GlobalPosition normal({-t[1], t[0]});
339 normal /= normal.two_norm();
340
341 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
342
343 const auto s = v*normal;
344 if (std::signbit(s))
345 normal *= -1;
346
347 return normal;
348 }
349
351 const typename Element::Geometry& elementGeometry() const
352 { return geo_; }
353
355 static auto numInteriorScvf(Dune::GeometryType type)
356 {
357 return BoxHelper::numInteriorScvf(type) + Dune::referenceElement<Scalar, dim>(type).size(dim);
358 }
359
361 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
362 {
363 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
364 }
365
367 std::size_t numScv() const
368 {
369 return boxHelper_.numScv() + 1;
370 }
371
373 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
374 {
375 const auto scvType = getScvGeometryType(localScvIdx);
376 if constexpr (dim == 3)
377 if (scvType == Dune::GeometryTypes::none(dim))
378 return octahedronVolume_(p);
379
380 return Dumux::convexPolytopeVolume<dim>(
381 scvType,
382 [&](unsigned int i){ return p[i]; }
383 );
384 }
385
387 static std::size_t numElementDofs(Dune::GeometryType type)
388 {
389 return Dune::referenceElement<Scalar, dim>(type).size(dim) + 1;
390 }
391
393 static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
394 {
395 return 0;
396 }
397
399 static auto numLocalDofsIntersection(Dune::GeometryType type, unsigned int iIdx)
400 {
401 return Dune::referenceElement<Scalar, dim>(type).size(iIdx, 1, dim);
402 }
403
405 static auto localDofIndexIntersection(Dune::GeometryType type, unsigned int iIdx, unsigned int ilocalDofIdx)
406 {
407 return Dune::referenceElement<Scalar, dim>(type).subEntity(iIdx, 1, ilocalDofIdx, dim);
408 }
409
410 template<class DofMapper, class LocalKey>
411 static auto dofIndex(const DofMapper& dofMapper, const Element& element, const LocalKey& localKey)
412 {
413 return dofMapper.subIndex(element, localKey.subEntity(), localKey.codim()) + localKey.index();
414 }
415
416 GlobalPosition dofPosition(unsigned int localDofIdx) const
417 {
418 if (localDofIdx < numElementDofs(geo_.type())-1)
419 return geo_.corner(localDofIdx);
420 else
421 return geo_.center();
422 }
423
425 template<class LocalKey>
426 static Element::Geometry::LocalCoordinate localDofPosition(Dune::GeometryType type, const LocalKey& localKey)
427 {
428 return Dune::referenceElement<Scalar, dim>(type).position(localKey.subEntity(), localKey.codim());
429 }
430
431 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
432 {
433 const auto numEdges = referenceElement(geo_).size(dim-1);
434 if (localScvfIndex < numEdges)
435 return {
436 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
437 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
438 };
439 else
440 return {
441 static_cast<LocalIndexType>(numElementDofs(geo_.type())-1),
442 static_cast<LocalIndexType>(localScvfIndex-numEdges)
443 };
444 }
445
446 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
447 {
448 const LocalIndexType insideScvIdx
449 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
450 return { insideScvIdx, insideScvIdx };
451 }
452
453 bool isOverlappingScvf(unsigned int localScvfIndex) const
454 {
455 if (localScvfIndex < boxHelper_.numInteriorScvf())
456 return false;
457 else
458 return true;
459 }
460
461 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
462 {
463 return false;
464 }
465
466 bool isOverlappingScv(unsigned int localScvIndex) const
467 {
468 if (localScvIndex < boxHelper_.numScv())
469 return false;
470 else
471 return true;
472 }
473
475 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
476 {
477 return Dumux::center(getScvfCorners(type, [&](const auto& local){ return local; }, localScvfIdx));
478 }
479
481 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
482 {
483 return Dumux::center(BoxHelper::getBoundaryScvfCorners(type, [&](const auto& local){ return local; }, localFacetIndex, indexInFace));
484 }
485
486private:
487 Scalar octahedronVolume_(const ScvCornerStorage& p) const
488 {
489 using std::abs;
490 return 1.0/6.0 * (
491 abs(Dumux::tripleProduct(p[4]-p[0], p[1]-p[0], p[2]-p[0]))
492 + abs(Dumux::tripleProduct(p[5]-p[0], p[1]-p[0], p[2]-p[0]))
493 );
494 }
495
496 const typename Element::Geometry& geo_;
497 BoxHelper boxHelper_;
498};
499
500template <class GridView, class ScvType, class ScvfType, std::size_t numCubeBubbleDofs>
502{
503 using Scalar = typename GridView::ctype;
504 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
505 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
506 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
507 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
508
509 using Element = typename GridView::template Codim<0>::Entity;
510 using Intersection = typename GridView::Intersection;
511
512 static constexpr auto dim = GridView::dimension;
513 static constexpr auto dimWorld = GridView::dimensionworld;
514
516public:
517
518 HybridPQ1BubbleGeometryHelper(const typename Element::Geometry& geometry)
519 : geo_(geometry)
520 , boxHelper_(geometry)
521 {}
522
524 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
525 {
526 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
527 }
528
530 template<class Transformation>
531 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
532 {
533 // proceed according to number of corners of the element
534 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
535 const auto numBoxScv = ref.size(dim);
536 // reuse box geometry helper for the corner scvs
537 if (localScvIdx < numBoxScv)
538 return BoxHelper::getScvCorners(type, trans, localScvIdx);
539
540 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv corners call for hybrid dofs");
541 }
542
543 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
544 {
545 // proceed according to number of corners of the element
546 const auto numBoxScv = boxHelper_.numScv();
547
548 if (localScvIdx < numBoxScv)
549 return Dune::GeometryTypes::cube(dim);
550
551 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv geometry call for hybrid dofs");
552 }
553
555 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
556 {
557 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
558 }
559
561 template<class Transformation>
562 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
563 {
564 // proceed according to number of corners
565 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
566 const auto numBoxScvf = ref.size(dim-1);
567 // reuse box geometry helper for scvfs
568 if (localScvfIdx < numBoxScvf)
569 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
570
571 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scvf corners call for hybrid dofs");
572 }
573
574 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
575 {
576 const auto numBoxScvf = boxHelper_.numInteriorScvf();
577 if (localScvfIdx < numBoxScvf)
578 return Dune::GeometryTypes::cube(dim-1);
579
580 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble interior scvf geometry type call for hybrid dofs");
581 }
582
584 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
585 unsigned int indexInFacet) const
586 {
587 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
588 }
589
590 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
591 {
592 return Dune::GeometryTypes::cube(dim-1);
593 }
594
595 template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0>
596 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
597 {
598 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
599 normal /= normal.two_norm();
600
601 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
602
603 const auto s = v*normal;
604 if (std::signbit(s))
605 normal *= -1;
606
607 return normal;
608 }
609
610 template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0>
611 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
612 {
614 const auto t = p[1] - p[0];
615 GlobalPosition normal({-t[1], t[0]});
616 normal /= normal.two_norm();
617
618 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
619
620 const auto s = v*normal;
621 if (std::signbit(s))
622 normal *= -1;
623
624 return normal;
625 }
626
628 const typename Element::Geometry& elementGeometry() const
629 { return geo_; }
630
632 static auto numInteriorScvf(Dune::GeometryType type)
633 {
634 return BoxHelper::numInteriorScvf(type);
635 }
636
638 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
639 {
640 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
641 }
642
644 std::size_t numScv() const
645 {
646 return boxHelper_.numScv();
647 }
648
650 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
651 {
652 const auto scvType = getScvGeometryType(localScvIdx);
653
654 return Dumux::convexPolytopeVolume<dim>(
655 scvType,
656 [&](unsigned int i){ return p[i]; }
657 );
658 }
659
661 static std::size_t numElementDofs(Dune::GeometryType type)
662 {
663 const auto numVertexDofs = Dune::referenceElement<Scalar, dim>(type).size(dim);
664 return numVertexDofs + (type.isCube() ? numCubeBubbleDofs : 1);
665 }
666
668 static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
669 {
670 return type.isCube() ? numCubeBubbleDofs : 1;
671 }
672
674 static auto numLocalDofsIntersection(Dune::GeometryType type, unsigned int iIdx)
675 {
676 return Dune::referenceElement<Scalar, dim>(type).size(iIdx, 1, dim);
677 }
678
680 static auto localDofIndexIntersection(Dune::GeometryType type, unsigned int iIdx, unsigned int ilocalDofIdx)
681 {
682 return Dune::referenceElement<Scalar, dim>(type).subEntity(iIdx, 1, ilocalDofIdx, dim);
683 }
684
685 template<class DofMapper, class LocalKey>
686 static auto dofIndex(const DofMapper& dofMapper, const Element& element, const LocalKey& localKey)
687 {
688 // For cube elements we have to add the additional index for the bubble dof
689 return dofMapper.subIndex(element, localKey.subEntity(), localKey.codim()) + localKey.index();
690 }
691
692 GlobalPosition dofPosition(unsigned int localDofIdx) const
693 {
694 const auto numVertexDofs = Dune::referenceElement<Scalar, dim>(geo_.type()).size(dim);
695 if (localDofIdx < numVertexDofs)
696 return geo_.corner(localDofIdx);
697 else
698 return geo_.center();
699 }
700
702 template<class LocalKey>
703 static Element::Geometry::LocalCoordinate localDofPosition(Dune::GeometryType type, const LocalKey& localKey)
704 {
705 return Dune::referenceElement<Scalar, dim>(type).position(localKey.subEntity(), localKey.codim());
706 }
707
708 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
709 {
710 const auto numEdges = referenceElement(geo_).size(dim-1);
711 if (localScvfIndex < numEdges)
712 return {
713 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
714 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
715 };
716
717 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv pair call for hybrid dofs");
718 }
719
720 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
721 {
722 const LocalIndexType insideScvIdx
723 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
724 return { insideScvIdx, insideScvIdx };
725 }
726
727 bool isOverlappingScvf(unsigned int localScvfIndex) const
728 { return false; }
729
730 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
731 { return false; }
732
733 bool isOverlappingScv(unsigned int localScvIndex) const
734 { return false; }
735
737 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
738 {
739 return Dumux::center(getScvfCorners(type, [&](const auto& local){ return local; }, localScvfIdx));
740 }
741
743 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
744 {
745 return Dumux::center(BoxHelper::getBoundaryScvfCorners(type, [&](const auto& local){ return local; }, localFacetIndex, indexInFace));
746 }
747
748private:
749 const typename Element::Geometry& geo_;
751};
752
753} // end namespace Dumux
754
755#endif
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
Compute the center point of a convex polytope geometry or a random-access container of corner points.
Create sub control volumes and sub control volume face geometries.
Definition: boxgeometryhelper.hh:257
Definition: discretization/pq1bubble/geometryhelper.hh:502
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition: discretization/pq1bubble/geometryhelper.hh:596
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition: discretization/pq1bubble/geometryhelper.hh:632
static auto numLocalDofsIntersection(Dune::GeometryType type, unsigned int iIdx)
Number of local dofs related to an intersection with index iIdx.
Definition: discretization/pq1bubble/geometryhelper.hh:674
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:708
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition: discretization/pq1bubble/geometryhelper.hh:737
bool isOverlappingScv(unsigned int localScvIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:733
HybridPQ1BubbleGeometryHelper(const typename Element::Geometry &geometry)
Definition: discretization/pq1bubble/geometryhelper.hh:518
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition: discretization/pq1bubble/geometryhelper.hh:628
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
local boundary scvf center
Definition: discretization/pq1bubble/geometryhelper.hh:743
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the corners of sub control volume faces.
Definition: discretization/pq1bubble/geometryhelper.hh:562
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition: discretization/pq1bubble/geometryhelper.hh:584
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:543
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:574
static auto localDofIndexIntersection(Dune::GeometryType type, unsigned int iIdx, unsigned int ilocalDofIdx)
Local dof index related to a localDof, with index ilocalDofIdx, on an intersection with index iIdx.
Definition: discretization/pq1bubble/geometryhelper.hh:680
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition: discretization/pq1bubble/geometryhelper.hh:531
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:730
static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
number of hybrid dofs
Definition: discretization/pq1bubble/geometryhelper.hh:668
static Element::Geometry::LocalCoordinate localDofPosition(Dune::GeometryType type, const LocalKey &localKey)
local dof position
Definition: discretization/pq1bubble/geometryhelper.hh:703
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition: discretization/pq1bubble/geometryhelper.hh:638
static auto dofIndex(const DofMapper &dofMapper, const Element &element, const LocalKey &localKey)
Definition: discretization/pq1bubble/geometryhelper.hh:686
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition: discretization/pq1bubble/geometryhelper.hh:650
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:720
GlobalPosition dofPosition(unsigned int localDofIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:692
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:727
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition: discretization/pq1bubble/geometryhelper.hh:555
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition: discretization/pq1bubble/geometryhelper.hh:524
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition: discretization/pq1bubble/geometryhelper.hh:644
static std::size_t numElementDofs(Dune::GeometryType type)
number of element dofs
Definition: discretization/pq1bubble/geometryhelper.hh:661
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:590
A class to create sub control volume and sub control volume face geometries per element.
Definition: discretization/pq1bubble/geometryhelper.hh:169
PQ1BubbleGeometryHelper(const typename Element::Geometry &geometry)
Definition: discretization/pq1bubble/geometryhelper.hh:185
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition: discretization/pq1bubble/geometryhelper.hh:361
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:461
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:453
static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
number of hybrid dofs
Definition: discretization/pq1bubble/geometryhelper.hh:393
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition: discretization/pq1bubble/geometryhelper.hh:367
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition: discretization/pq1bubble/geometryhelper.hh:355
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the corners of sub control volume faces.
Definition: discretization/pq1bubble/geometryhelper.hh:261
static std::size_t numElementDofs(Dune::GeometryType type)
number of element dofs
Definition: discretization/pq1bubble/geometryhelper.hh:387
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition: discretization/pq1bubble/geometryhelper.hh:198
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:313
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
local boundary scvf center
Definition: discretization/pq1bubble/geometryhelper.hh:481
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition: discretization/pq1bubble/geometryhelper.hh:307
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:431
GlobalPosition dofPosition(unsigned int localDofIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:416
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:297
static auto localDofIndexIntersection(Dune::GeometryType type, unsigned int iIdx, unsigned int ilocalDofIdx)
Local dof index related to a localDof, with index ilocalDofIdx, on an intersection with index iIdx.
Definition: discretization/pq1bubble/geometryhelper.hh:405
bool isOverlappingScv(unsigned int localScvIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:466
static auto numLocalDofsIntersection(Dune::GeometryType type, unsigned int iIdx)
Number of local dofs related to an intersection with index iIdx.
Definition: discretization/pq1bubble/geometryhelper.hh:399
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition: discretization/pq1bubble/geometryhelper.hh:373
static auto dofIndex(const DofMapper &dofMapper, const Element &element, const LocalKey &localKey)
Definition: discretization/pq1bubble/geometryhelper.hh:411
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition: discretization/pq1bubble/geometryhelper.hh:351
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition: discretization/pq1bubble/geometryhelper.hh:254
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition: discretization/pq1bubble/geometryhelper.hh:446
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition: discretization/pq1bubble/geometryhelper.hh:475
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition: discretization/pq1bubble/geometryhelper.hh:319
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition: discretization/pq1bubble/geometryhelper.hh:191
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition: discretization/pq1bubble/geometryhelper.hh:234
static Element::Geometry::LocalCoordinate localDofPosition(Dune::GeometryType type, const LocalKey &localKey)
local dof position
Definition: discretization/pq1bubble/geometryhelper.hh:426
Dune::FieldVector< Scalar, 3 > crossProduct(const Dune::FieldVector< Scalar, 3 > &vec1, const Dune::FieldVector< Scalar, 3 > &vec2)
Cross product of two vectors in three-dimensional Euclidean space.
Definition: math.hh:671
Scalar tripleProduct(const Dune::FieldVector< Scalar, 3 > &vec1, const Dune::FieldVector< Scalar, 3 > &vec2, const Dune::FieldVector< Scalar, 3 > &vec3)
Triple product of three vectors in three-dimensional Euclidean space retuning scalar.
Definition: math.hh:700
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition: center.hh:24
Define some often used mathematical functions.
constexpr None none
Definition: method.hh:163
CVFE< CVFEMethods::PQ1Bubble > PQ1Bubble
Definition: method.hh:112
constexpr Line line
Definition: couplingmanager1d3d_line.hh:31
Definition: adapt.hh:17
Definition: common/pdesolver.hh:24
Definition: discretization/pq1bubble/geometryhelper.hh:90
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:91
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:55
Definition: discretization/pq1bubble/geometryhelper.hh:72
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:73
Definition: discretization/pq1bubble/geometryhelper.hh:81
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:82
Definition: discretization/pq1bubble/geometryhelper.hh:63
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:64
Definition: discretization/pq1bubble/geometryhelper.hh:50
Definition: discretization/pq1bubble/geometryhelper.hh:147
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:148
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:104
Definition: discretization/pq1bubble/geometryhelper.hh:123
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:124
Definition: discretization/pq1bubble/geometryhelper.hh:135
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:136
Definition: discretization/pq1bubble/geometryhelper.hh:112
std::pair< std::uint8_t, std::uint8_t > Key
Definition: discretization/pq1bubble/geometryhelper.hh:113
Definition: discretization/pq1bubble/geometryhelper.hh:99
Definition: discretization/pq1bubble/geometryhelper.hh:41
Dune::ReservedVector< Dune::FieldVector< ct, cdim >,(1<< mydim)> Type
Definition: discretization/pq1bubble/geometryhelper.hh:42
Traits for an efficient corner storage for the PQ1Bubble method.
Definition: discretization/pq1bubble/geometryhelper.hh:35
Compute the volume of several common geometry types.