version 3.11-dev
Loading...
Searching...
No Matches
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#include <ranges>
18
19#include <dune/common/exceptions.hh>
20#include <dune/common/rangeutilities.hh>
21#include <dune/common/reservedvector.hh>
22
23#include <dune/geometry/type.hh>
24#include <dune/geometry/referenceelements.hh>
25#include <dune/geometry/multilineargeometry.hh>
26
28#include <dumux/common/math.hh>
33
34#include "dofhelper.hh"
35
36namespace Dumux {
37
39template <class ct>
40struct PQ1BubbleMLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct>
41{
42 // we use static vectors to store the corners as we know
43 // the maximum number of corners in advance (2^dim for box-type sub-cells,
44 // overlapping sub-cells never exceed this count)
45 template< int mydim, int cdim >
47 {
48 using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<mydim)>;
49 };
50};
51
52
54
55template<Dune::GeometryType::Id gt>
57
58template<>
59struct OverlappingScvCorners<Dune::GeometryTypes::line>
60{
61 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
62 static constexpr std::array<std::array<Key, 2>, 1> keys = {{
63 { Key{0, 1}, Key{1, 1} }
64 }};
65};
66
67template<>
68struct OverlappingScvCorners<Dune::GeometryTypes::triangle>
69{
70 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
71 static constexpr std::array<std::array<Key, 3>, 1> keys = {{
72 { Key{0, 1}, Key{1, 1}, Key{2, 1} }
73 }};
74};
75
76template<>
77struct OverlappingScvCorners<Dune::GeometryTypes::quadrilateral>
78{
79 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
80 static constexpr std::array<std::array<Key, 4>, 1> keys = {{
81 { Key{2, 1}, Key{1, 1}, Key{0, 1}, Key{3, 1} }
82 }};
83};
84
85template<>
86struct OverlappingScvCorners<Dune::GeometryTypes::tetrahedron>
87{
88 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
89 static constexpr std::array<std::array<Key, 4>, 1> keys = {{
90 { Key{0, 1}, Key{1, 1}, Key{2, 1}, Key{3, 1} }
91 }};
92};
93
94template<>
95struct OverlappingScvCorners<Dune::GeometryTypes::hexahedron>
96{
97 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
98 static constexpr std::array<std::array<Key, 6>, 1> keys = {{
99 { Key{0, 1}, Key{2, 1}, Key{3, 1}, Key{1, 1}, Key{4, 1}, Key{5, 1} }
100 }};
101};
102
103
104template<Dune::GeometryType::Id gt>
106
107template<>
108struct OverlappingScvfCorners<Dune::GeometryTypes::line>
109{
110 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
111 static constexpr std::array<std::array<Key, 1>, 1> keys = {{
112 { Key{0, 0} }
113 }};
114};
115
116template<>
117struct OverlappingScvfCorners<Dune::GeometryTypes::triangle>
118{
119 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
120 static constexpr std::array<std::array<Key, 2>, 3> keys = {{
121 { Key{0, 1}, Key{1, 1} },
122 { Key{0, 1}, Key{2, 1} },
123 { Key{1, 1}, Key{2, 1} }
124 }};
125};
126
127template<>
128struct OverlappingScvfCorners<Dune::GeometryTypes::quadrilateral>
129{
130 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
131 static constexpr std::array<std::array<Key, 2>, 4> keys = {{
132 { Key{0, 1}, Key{2, 1} },
133 { Key{2, 1}, Key{1, 1} },
134 { Key{0, 1}, Key{3, 1} },
135 { Key{1, 1}, Key{3, 1} }
136 }};
137};
138
139template<>
140struct OverlappingScvfCorners<Dune::GeometryTypes::tetrahedron>
141{
142 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
143 static constexpr std::array<std::array<Key, 3>, 4> keys = {{
144 { Key{0, 1}, Key{1, 1}, Key{2, 1} },
145 { Key{0, 1}, Key{1, 1}, Key{3, 1} },
146 { Key{0, 1}, Key{2, 1}, Key{3, 1} },
147 { Key{1, 1}, Key{2, 1}, Key{3, 1} }
148 }};
149};
150
151template<>
152struct OverlappingScvfCorners<Dune::GeometryTypes::hexahedron>
153{
154 using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim)
155 static constexpr std::array<std::array<Key, 3>, 8> keys = {{
156 { Key{4, 1}, Key{0, 1}, Key{2, 1} },
157 { Key{4, 1}, Key{2, 1}, Key{1, 1} },
158 { Key{4, 1}, Key{0, 1}, Key{3, 1} },
159 { Key{4, 1}, Key{1, 1}, Key{3, 1} },
160 { Key{5, 1}, Key{0, 1}, Key{2, 1} },
161 { Key{5, 1}, Key{2, 1}, Key{1, 1} },
162 { Key{5, 1}, Key{0, 1}, Key{3, 1} },
163 { Key{5, 1}, Key{1, 1}, Key{3, 1} }
164 }};
165};
166
167} // end namespace Detail::PQ1Bubble
168
173template <class GridView, class ScvType, class ScvfType>
175{
176 using Scalar = typename GridView::ctype;
177 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
178 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
179 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
180 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
181
182 using Element = typename GridView::template Codim<0>::Entity;
183 using Intersection = typename GridView::Intersection;
184
185 static constexpr auto dim = GridView::dimension;
186 static constexpr auto dimWorld = GridView::dimensionworld;
187
189public:
191
192 PQ1BubbleGeometryHelper(const typename Element::Geometry& geometry)
193 : geo_(geometry)
194 , boxHelper_(geometry)
195 {}
196
198 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
199 {
200 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
201 }
202
204 template<class Transformation>
205 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
206 {
207 // proceed according to number of corners of the element
208 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
209 const auto numBoxScv = ref.size(dim);
210 // reuse box geometry helper for the corner scvs
211 if (localScvIdx < numBoxScv)
212 return BoxHelper::getScvCorners(type, trans, localScvIdx);
213
214 const auto localOverlappingScvIdx = localScvIdx-numBoxScv;
215 if (type == Dune::GeometryTypes::triangle)
216 {
218 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
219 }
220 else if (type == Dune::GeometryTypes::quadrilateral)
221 {
223 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
224 }
225 else if (type == Dune::GeometryTypes::tetrahedron)
226 {
228 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
229 }
230 else if (type == Dune::GeometryTypes::hexahedron)
231 {
233 return Detail::Box::keyToCornerStorage<ScvCornerStorage>(ref, trans, Corners::keys[localOverlappingScvIdx]);
234 }
235 else
236 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv geometries for dim=" << dim
237 << " dimWorld=" << dimWorld
238 << " type=" << type);
239 }
240
241 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
242 {
243 // proceed according to number of corners of the element
244 const auto type = geo_.type();
245 const auto numBoxScv = boxHelper_.numScv();
246 if (localScvIdx < numBoxScv)
247 return Dune::GeometryTypes::cube(dim);
248 else if (type == Dune::GeometryTypes::simplex(dim))
249 return Dune::GeometryTypes::simplex(dim);
250 else if (type == Dune::GeometryTypes::quadrilateral)
251 return Dune::GeometryTypes::quadrilateral;
252 else if (type == Dune::GeometryTypes::hexahedron)
253 return Dune::GeometryTypes::none(dim); // octahedron
254 else
255 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv geometries for dim=" << dim
256 << " dimWorld=" << dimWorld
257 << " type=" << type);
258 }
259
261 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
262 {
263 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
264 }
265
267 template<class Transformation>
268 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
269 {
270 // proceed according to number of corners
271 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
272 const auto numBoxScvf = ref.size(dim-1);
273 // reuse box geometry helper for the corner scvs
274 if (localScvfIdx < numBoxScvf)
275 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
276
277 const auto localOverlappingScvfIdx = localScvfIdx-numBoxScvf;
278 if (type == Dune::GeometryTypes::triangle)
279 {
281 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
282 }
283 else if (type == Dune::GeometryTypes::quadrilateral)
284 {
286 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
287 }
288 else if (type == Dune::GeometryTypes::tetrahedron)
289 {
291 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
292 }
293 else if (type == Dune::GeometryTypes::hexahedron)
294 {
296 return Detail::Box::keyToCornerStorage<ScvfCornerStorage>(ref, trans, Corners::keys[localOverlappingScvfIdx]);
297 }
298 else
299 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scvf geometries for dim=" << dim
300 << " dimWorld=" << dimWorld
301 << " type=" << type);
302 }
303
304 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
305 {
306 const auto numBoxScvf = boxHelper_.numInteriorScvf();
307 if (localScvfIdx < numBoxScvf)
308 return Dune::GeometryTypes::cube(dim-1);
309 else
310 return Dune::GeometryTypes::simplex(dim-1);
311 }
312
314 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
315 unsigned int indexInFacet) const
316 {
317 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
318 }
319
320 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
321 {
322 return Dune::GeometryTypes::cube(dim-1);
323 }
324
325 template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0>
326 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
327 {
328 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
329 normal /= normal.two_norm();
330
331 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
332
333 const auto s = v*normal;
334 if (std::signbit(s))
335 normal *= -1;
336
337 return normal;
338 }
339
340 template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0>
341 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
342 {
344 const auto t = p[1] - p[0];
345 GlobalPosition normal({-t[1], t[0]});
346 normal /= normal.two_norm();
347
348 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
349
350 const auto s = v*normal;
351 if (std::signbit(s))
352 normal *= -1;
353
354 return normal;
355 }
356
358 const typename Element::Geometry& elementGeometry() const
359 { return geo_; }
360
362 static auto numInteriorScvf(Dune::GeometryType type)
363 {
364 return BoxHelper::numInteriorScvf(type) + Dune::referenceElement<Scalar, dim>(type).size(dim);
365 }
366
368 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
369 {
370 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
371 }
372
374 std::size_t numScv() const
375 {
376 return boxHelper_.numScv() + 1;
377 }
378
380 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
381 {
382 const auto scvType = getScvGeometryType(localScvIdx);
383 if constexpr (dim == 3)
384 if (scvType == Dune::GeometryTypes::none(dim))
385 return octahedronVolume_(p);
386
388 scvType,
389 [&](unsigned int i){ return p[i]; }
390 );
391 }
392
394 static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
395 {
396 return 0;
397 }
398
399 GlobalPosition dofPosition(unsigned int localDofIdx) const
400 {
401 const auto numVertexDofs = Dune::referenceElement<Scalar, dim>(geo_.type()).size(dim);
402 if (localDofIdx < numVertexDofs)
403 return geo_.corner(localDofIdx);
404 else
405 return geo_.center();
406 }
407
408 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
409 {
410 const auto numEdges = referenceElement(geo_).size(dim-1);
411 if (localScvfIndex < numEdges)
412 return {
413 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
414 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
415 };
416 else
417 return {
418 static_cast<LocalIndexType>(DofHelper::numElementDofs(geo_.type())-1),
419 static_cast<LocalIndexType>(localScvfIndex-numEdges)
420 };
421 }
422
423 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
424 {
425 const LocalIndexType insideScvIdx
426 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
427 return { insideScvIdx, insideScvIdx };
428 }
429
430 bool isOverlappingScvf(unsigned int localScvfIndex) const
431 {
432 if (localScvfIndex < boxHelper_.numInteriorScvf())
433 return false;
434 else
435 return true;
436 }
437
438 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
439 {
440 return false;
441 }
442
443 bool isOverlappingScv(unsigned int localScvIndex) const
444 {
445 if (localScvIndex < boxHelper_.numScv())
446 return false;
447 else
448 return true;
449 }
450
452 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
453 {
454 return Dumux::center(getScvfCorners(type, [&](const auto& local){ return local; }, localScvfIdx));
455 }
456
458 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
459 {
460 return Dumux::center(BoxHelper::getBoundaryScvfCorners(type, [&](const auto& local){ return local; }, localFacetIndex, indexInFace));
461 }
462
463private:
464 Scalar octahedronVolume_(const ScvCornerStorage& p) const
465 {
466 using std::abs;
467 return 1.0/6.0 * (
468 abs(Dumux::tripleProduct(p[4]-p[0], p[1]-p[0], p[2]-p[0]))
469 + abs(Dumux::tripleProduct(p[5]-p[0], p[1]-p[0], p[2]-p[0]))
470 );
471 }
472
473 typename Element::Geometry geo_;
474 BoxHelper boxHelper_;
475};
476
477template <class GridView, class ScvType, class ScvfType, std::size_t numCubeBubbleDofs>
479{
480 using Scalar = typename GridView::ctype;
481 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
482 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
483 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
484 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
485
486 using Element = typename GridView::template Codim<0>::Entity;
487 using Intersection = typename GridView::Intersection;
488
489 static constexpr auto dim = GridView::dimension;
490 static constexpr auto dimWorld = GridView::dimensionworld;
491
493public:
495
496 HybridPQ1BubbleGeometryHelper(const typename Element::Geometry& geometry)
497 : geo_(geometry)
498 , boxHelper_(geometry)
499 {}
500
502 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
503 {
504 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
505 }
506
508 template<class Transformation>
509 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
510 {
511 // proceed according to number of corners of the element
512 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
513 const auto numBoxScv = ref.size(dim);
514 // reuse box geometry helper for the corner scvs
515 if (localScvIdx < numBoxScv)
516 return BoxHelper::getScvCorners(type, trans, localScvIdx);
517
518 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv corners call for hybrid dofs");
519 }
520
521 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
522 {
523 // proceed according to number of corners of the element
524 const auto numBoxScv = boxHelper_.numScv();
525
526 if (localScvIdx < numBoxScv)
527 return Dune::GeometryTypes::cube(dim);
528
529 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv geometry call for hybrid dofs");
530 }
531
533 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
534 {
535 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
536 }
537
539 template<class Transformation>
540 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
541 {
542 // proceed according to number of corners
543 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
544 const auto numBoxScvf = ref.size(dim-1);
545 // reuse box geometry helper for scvfs
546 if (localScvfIdx < numBoxScvf)
547 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
548
549 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scvf corners call for hybrid dofs");
550 }
551
552 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
553 {
554 const auto numBoxScvf = boxHelper_.numInteriorScvf();
555 if (localScvfIdx < numBoxScvf)
556 return Dune::GeometryTypes::cube(dim-1);
557
558 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble interior scvf geometry type call for hybrid dofs");
559 }
560
562 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
563 unsigned int indexInFacet) const
564 {
565 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
566 }
567
568 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
569 {
570 return Dune::GeometryTypes::cube(dim-1);
571 }
572
573 template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0>
574 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
575 {
576 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
577 normal /= normal.two_norm();
578
579 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
580
581 const auto s = v*normal;
582 if (std::signbit(s))
583 normal *= -1;
584
585 return normal;
586 }
587
588 template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0>
589 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
590 {
592 const auto t = p[1] - p[0];
593 GlobalPosition normal({-t[1], t[0]});
594 normal /= normal.two_norm();
595
596 GlobalPosition v = dofPosition(scvPair[1]) - dofPosition(scvPair[0]);
597
598 const auto s = v*normal;
599 if (std::signbit(s))
600 normal *= -1;
601
602 return normal;
603 }
604
606 const typename Element::Geometry& elementGeometry() const
607 { return geo_; }
608
610 static auto numInteriorScvf(Dune::GeometryType type)
611 {
612 return BoxHelper::numInteriorScvf(type);
613 }
614
616 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
617 {
618 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
619 }
620
622 std::size_t numScv() const
623 {
624 return boxHelper_.numScv();
625 }
626
628 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
629 {
630 const auto scvType = getScvGeometryType(localScvIdx);
631
633 scvType,
634 [&](unsigned int i){ return p[i]; }
635 );
636 }
637
639 static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
640 {
641 return type.isCube() ? numCubeBubbleDofs : 1;
642 }
643
644 GlobalPosition dofPosition(unsigned int localDofIdx) const
645 {
646 const auto numVertexDofs = Dune::referenceElement<Scalar, dim>(geo_.type()).size(dim);
647 if (localDofIdx < numVertexDofs)
648 return geo_.corner(localDofIdx);
649 else
650 return geo_.center();
651 }
652
653 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
654 {
655 const auto numEdges = referenceElement(geo_).size(dim-1);
656 if (localScvfIndex < numEdges)
657 return {
658 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
659 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
660 };
661
662 DUNE_THROW(Dune::NotImplemented, "PQ1Bubble scv pair call for hybrid dofs");
663 }
664
665 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
666 {
667 const LocalIndexType insideScvIdx
668 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
669 return { insideScvIdx, insideScvIdx };
670 }
671
672 bool isOverlappingScvf(unsigned int localScvfIndex) const
673 { return false; }
674
675 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
676 { return false; }
677
678 bool isOverlappingScv(unsigned int localScvIndex) const
679 { return false; }
680
682 static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
683 {
684 return Dumux::center(getScvfCorners(type, [&](const auto& local){ return local; }, localScvfIdx));
685 }
686
688 static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
689 {
690 return Dumux::center(BoxHelper::getBoundaryScvfCorners(type, [&](const auto& local){ return local; }, localFacetIndex, indexInFace));
691 }
692
693private:
694 typename Element::Geometry geo_;
695
697};
698
699} // end namespace Dumux
700
701#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:261
PQ1BubbleDofHelper< GridView, numCubeBubbleDofs > DofHelper
Definition discretization/pq1bubble/geometryhelper.hh:494
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition discretization/pq1bubble/geometryhelper.hh:574
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition discretization/pq1bubble/geometryhelper.hh:610
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:653
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition discretization/pq1bubble/geometryhelper.hh:682
bool isOverlappingScv(unsigned int localScvIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:678
HybridPQ1BubbleGeometryHelper(const typename Element::Geometry &geometry)
Definition discretization/pq1bubble/geometryhelper.hh:496
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition discretization/pq1bubble/geometryhelper.hh:606
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
local boundary scvf center
Definition discretization/pq1bubble/geometryhelper.hh:688
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:540
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition discretization/pq1bubble/geometryhelper.hh:562
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:521
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:552
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition discretization/pq1bubble/geometryhelper.hh:509
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:675
static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
number of hybrid dofs (overrides base: for cube elements there are numCubeBubbleDofs extra dofs)
Definition discretization/pq1bubble/geometryhelper.hh:639
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition discretization/pq1bubble/geometryhelper.hh:616
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition discretization/pq1bubble/geometryhelper.hh:628
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:665
GlobalPosition dofPosition(unsigned int localDofIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:644
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:672
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition discretization/pq1bubble/geometryhelper.hh:533
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition discretization/pq1bubble/geometryhelper.hh:502
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition discretization/pq1bubble/geometryhelper.hh:622
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:568
Dof helper for the PQ1Bubble method, providing the number of dofs and their positions.
Definition pq1bubble/dofhelper.hh:36
static std::size_t numElementDofs(Dune::GeometryType type)
Definition pq1bubble/dofhelper.hh:48
PQ1BubbleGeometryHelper(const typename Element::Geometry &geometry)
Definition discretization/pq1bubble/geometryhelper.hh:192
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition discretization/pq1bubble/geometryhelper.hh:368
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:438
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:430
static std::size_t numNonCVLocalDofs(Dune::GeometryType type)
number of hybrid dofs (overrides base: PQ1Bubble uses no non-CV dofs in the FV context)
Definition discretization/pq1bubble/geometryhelper.hh:394
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition discretization/pq1bubble/geometryhelper.hh:374
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition discretization/pq1bubble/geometryhelper.hh:362
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:268
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition discretization/pq1bubble/geometryhelper.hh:205
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:320
static Element::Geometry::LocalCoordinate localBoundaryScvfCenter(Dune::GeometryType type, unsigned int localFacetIndex, unsigned int indexInFace)
local boundary scvf center
Definition discretization/pq1bubble/geometryhelper.hh:458
PQ1BubbleDofHelper< GridView, 1 > DofHelper
Definition discretization/pq1bubble/geometryhelper.hh:190
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition discretization/pq1bubble/geometryhelper.hh:314
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:408
GlobalPosition dofPosition(unsigned int localDofIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:399
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:304
bool isOverlappingScv(unsigned int localScvIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:443
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition discretization/pq1bubble/geometryhelper.hh:380
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition discretization/pq1bubble/geometryhelper.hh:358
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition discretization/pq1bubble/geometryhelper.hh:261
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:423
static Element::Geometry::LocalCoordinate localScvfCenter(Dune::GeometryType type, unsigned int localScvfIdx)
local scvf center
Definition discretization/pq1bubble/geometryhelper.hh:452
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition discretization/pq1bubble/geometryhelper.hh:326
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition discretization/pq1bubble/geometryhelper.hh:198
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:241
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
auto convexPolytopeVolume(Dune::GeometryType type, const CornerF &c)
Compute the volume of several common geometry types.
Definition volume.hh:41
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.
Class representing dofs on elements for control-volume finite element schemes.
Define some often used mathematical functions.
S keyToCornerStorage(const ReferenceElement &ref, Transformation &&trans, const std::array< T, N > &key)
Definition boxgeometryhelper.hh:232
Definition discretization/pq1bubble/geometryhelper.hh:53
Definition adapt.hh:17
Definition common/pdesolver.hh:24
Dof helper for the PQ1Bubble method, providing the number of dofs and their positions.
static constexpr std::array< std::array< Key, 6 >, 1 > keys
Definition discretization/pq1bubble/geometryhelper.hh:98
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:97
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:61
static constexpr std::array< std::array< Key, 2 >, 1 > keys
Definition discretization/pq1bubble/geometryhelper.hh:62
static constexpr std::array< std::array< Key, 4 >, 1 > keys
Definition discretization/pq1bubble/geometryhelper.hh:80
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:79
static constexpr std::array< std::array< Key, 4 >, 1 > keys
Definition discretization/pq1bubble/geometryhelper.hh:89
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:88
static constexpr std::array< std::array< Key, 3 >, 1 > keys
Definition discretization/pq1bubble/geometryhelper.hh:71
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:70
Definition discretization/pq1bubble/geometryhelper.hh:56
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:154
static constexpr std::array< std::array< Key, 3 >, 8 > keys
Definition discretization/pq1bubble/geometryhelper.hh:155
static constexpr std::array< std::array< Key, 1 >, 1 > keys
Definition discretization/pq1bubble/geometryhelper.hh:111
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:110
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:130
static constexpr std::array< std::array< Key, 2 >, 4 > keys
Definition discretization/pq1bubble/geometryhelper.hh:131
static constexpr std::array< std::array< Key, 3 >, 4 > keys
Definition discretization/pq1bubble/geometryhelper.hh:143
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:142
static constexpr std::array< std::array< Key, 2 >, 3 > keys
Definition discretization/pq1bubble/geometryhelper.hh:120
std::pair< std::uint8_t, std::uint8_t > Key
Definition discretization/pq1bubble/geometryhelper.hh:119
Definition discretization/pq1bubble/geometryhelper.hh:105
Definition discretization/pq1bubble/geometryhelper.hh:47
Dune::ReservedVector< Dune::FieldVector< ct, cdim >,(1<< mydim)> Type
Definition discretization/pq1bubble/geometryhelper.hh:48
Traits for an efficient corner storage for the PQ1Bubble method.
Definition discretization/pq1bubble/geometryhelper.hh:41
Compute the volume of several common geometry types.