version 3.11-dev
Loading...
Searching...
No Matches
discretization/pq2/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_PQ2_GEOMETRY_HELPER_HH
14#define DUMUX_DISCRETIZATION_PQ2_GEOMETRY_HELPER_HH
15
16#include <array>
17#include <ranges>
18
19#include <dune/common/exceptions.hh>
20
21#include <dune/geometry/type.hh>
22#include <dune/geometry/referenceelements.hh>
23#include <dune/geometry/multilineargeometry.hh>
24#include <dune/common/reservedvector.hh>
25
26#include <dumux/common/math.hh>
32
33namespace Dumux {
34
36template <class ct>
37struct PQ2MLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct>
38{
39 // we use static vectors to store the corners as we know
40 // the maximum number of corners in advance (2^dim for box-type sub-cells)
41 template< int mydim, int cdim >
43 {
44 using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<mydim)>;
45 };
46};
47
48
53template <class GridView, class ScvType, class ScvfType>
55{
56 using Scalar = typename GridView::ctype;
57 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
58 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
59 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
60 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
61
62 using Element = typename GridView::template Codim<0>::Entity;
63 using Intersection = typename GridView::Intersection;
64
65 static constexpr auto dim = GridView::dimension;
66 static constexpr auto dimWorld = GridView::dimensionworld;
67
69public:
71
72 HybridPQ2GeometryHelper(const typename Element::Geometry& geometry)
73 : geo_(geometry)
74 , boxHelper_(geometry)
75 {}
76
78 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
79 {
80 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
81 }
82
84 template<class Transformation>
85 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
86 {
87 // proceed according to number of corners of the element
88 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
89 const auto numBoxScv = ref.size(dim);
90 // reuse box geometry helper for the corner scvs
91 if (localScvIdx < numBoxScv)
92 return BoxHelper::getScvCorners(type, trans, localScvIdx);
93
94 DUNE_THROW(Dune::NotImplemented, "PQ2 scv corners call for hybrid dofs");
95 }
96
97 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
98 {
99 // proceed according to number of corners of the element
100 const auto numBoxScv = boxHelper_.numScv();
101
102 if (localScvIdx < numBoxScv)
103 return Dune::GeometryTypes::cube(dim);
104
105 DUNE_THROW(Dune::NotImplemented, "PQ2 scv geometry call for hybrid dofs");
106 }
107
109 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
110 {
111 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
112 }
113
115 template<class Transformation>
116 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
117 {
118 // proceed according to number of corners
119 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
120 const auto numBoxScvf = ref.size(dim-1);
121 // reuse box geometry helper for scvfs
122 if (localScvfIdx < numBoxScvf)
123 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
124
125 DUNE_THROW(Dune::NotImplemented, "PQ2 scvf corners call for hybrid dofs");
126 }
127
128 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
129 {
130 const auto numBoxScvf = boxHelper_.numInteriorScvf();
131 if (localScvfIdx < numBoxScvf)
132 return Dune::GeometryTypes::cube(dim-1);
133
134 DUNE_THROW(Dune::NotImplemented, "PQ2 interior scvf geometry type call for hybrid dofs");
135 }
136
138 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
139 unsigned int indexInFacet) const
140 {
141 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
142 }
143
144 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
145 {
146 return Dune::GeometryTypes::cube(dim-1);
147 }
148
149 template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0>
150 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
151 {
152 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
153 normal /= normal.two_norm();
154
155 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
156
157 const auto s = v*normal;
158 if (std::signbit(s))
159 normal *= -1;
160
161 return normal;
162 }
163
164 template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0>
165 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
166 {
168 const auto t = p[1] - p[0];
169 GlobalPosition normal({-t[1], t[0]});
170 normal /= normal.two_norm();
171
172 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
173
174 const auto s = v*normal;
175 if (std::signbit(s))
176 normal *= -1;
177
178 return normal;
179 }
180
182 const typename Element::Geometry& elementGeometry() const
183 { return geo_; }
184
186 static auto numInteriorScvf(Dune::GeometryType type)
187 {
188 return BoxHelper::numInteriorScvf(type);
189 }
190
192 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
193 {
194 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
195 }
196
198 std::size_t numScv() const
199 {
200 return boxHelper_.numScv();
201 }
202
204 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
205 {
206 const auto scvType = getScvGeometryType(localScvIdx);
207
209 scvType,
210 [&](unsigned int i){ return p[i]; }
211 );
212 }
213
214 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
215 {
216 const auto numBoxFaces = boxHelper_.numInteriorScvf();
217 if (localScvfIndex < numBoxFaces)
218 {
219 return {
220 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
221 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
222 };
223 }
224
225 DUNE_THROW(Dune::NotImplemented, "PQ2 scv pair call for hybrid dofs");
226 }
227
228 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
229 {
230 const auto numBoxScvf = referenceElement(geo_).size(localFacetIndex, 1, dim);
231 if (localIsScvfIndex < numBoxScvf)
232 {
233 const LocalIndexType insideScvIdx
234 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
235 return { insideScvIdx, insideScvIdx };
236 }
237
238 DUNE_THROW(Dune::NotImplemented, "PQ2 scv boundary pair call for hybrid dofs");
239 }
240
241 // For hybrid dofs we don't construct scvfs
242 bool isOverlappingScvf(unsigned int localScvfIndex) const
243 { return false; }
244
245 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
246 { return false; }
247
248 // For hybrid dofs we don't construct scvs
249 bool isOverlappingScv(unsigned int localScvIndex) const
250 { return false; }
251
252private:
253 const typename Element::Geometry& geo_;
254 BoxHelper boxHelper_;
255};
256
257} // end namespace Dumux
258
259#endif
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
Create sub control volumes and sub control volume face geometries.
Definition boxgeometryhelper.hh:261
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq2/geometryhelper.hh:144
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition discretization/pq2/geometryhelper.hh:198
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition discretization/pq2/geometryhelper.hh:245
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition discretization/pq2/geometryhelper.hh:109
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition discretization/pq2/geometryhelper.hh:242
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition discretization/pq2/geometryhelper.hh:228
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition discretization/pq2/geometryhelper.hh:78
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition discretization/pq2/geometryhelper.hh:182
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition discretization/pq2/geometryhelper.hh:214
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition discretization/pq2/geometryhelper.hh:186
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition discretization/pq2/geometryhelper.hh:138
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition discretization/pq2/geometryhelper.hh:204
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition discretization/pq2/geometryhelper.hh:192
Dumux::PQ2LagrangeDofHelper< GridView > DofHelper
Definition discretization/pq2/geometryhelper.hh:70
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq2/geometryhelper.hh:128
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition discretization/pq2/geometryhelper.hh:97
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition discretization/pq2/geometryhelper.hh:150
bool isOverlappingScv(unsigned int localScvIndex) const
Definition discretization/pq2/geometryhelper.hh:249
HybridPQ2GeometryHelper(const typename Element::Geometry &geometry)
Definition discretization/pq2/geometryhelper.hh:72
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the corners of sub control volume faces.
Definition discretization/pq2/geometryhelper.hh:116
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition discretization/pq2/geometryhelper.hh:85
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
auto convexPolytopeVolume(Dune::GeometryType type, const CornerF &c)
Compute the volume of several common geometry types.
Definition volume.hh:41
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.
Definition adapt.hh:17
Lightweight DOF helper for order-2 Lagrange elements.
DOF index and position helper for order-2 Lagrange discretizations.
Definition pq2/dofhelper.hh:36
Definition discretization/pq2/geometryhelper.hh:43
Dune::ReservedVector< Dune::FieldVector< ct, cdim >,(1<< mydim)> Type
Definition discretization/pq2/geometryhelper.hh:44
Traits for an efficient corner storage for the PQ2 method.
Definition discretization/pq2/geometryhelper.hh:38
Compute the volume of several common geometry types.