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>
33
34namespace Dumux {
35
37template <class ct>
38struct PQ2MLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct>
39{
40 // we use static vectors to store the corners as we know
41 // the maximum number of corners in advance (2^dim for box-type sub-cells)
42 template< int mydim, int cdim >
44 {
45 using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<mydim)>;
46 };
47};
48
49
54template <class GridView, class ScvType, class ScvfType>
56{
57 using Scalar = typename GridView::ctype;
58 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
59 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
60 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
61 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
62
63 using Element = typename GridView::template Codim<0>::Entity;
64 using Intersection = typename GridView::Intersection;
65
66 static constexpr auto dim = GridView::dimension;
67 static constexpr auto dimWorld = GridView::dimensionworld;
68
70public:
72
73 HybridPQ2GeometryHelper(const typename Element::Geometry& geometry)
74 : geo_(geometry)
75 , boxHelper_(geometry)
76 {}
77
79 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
80 {
81 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
82 }
83
85 template<class Transformation>
86 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
87 {
88 // proceed according to number of corners of the element
89 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
90 const auto numBoxScv = ref.size(dim);
91 // reuse box geometry helper for the corner scvs
92 if (localScvIdx < numBoxScv)
93 return BoxHelper::getScvCorners(type, trans, localScvIdx);
94
95 DUNE_THROW(Dune::NotImplemented, "PQ2 scv corners call for hybrid dofs");
96 }
97
98 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
99 {
100 // proceed according to number of corners of the element
101 const auto numBoxScv = boxHelper_.numScv();
102
103 if (localScvIdx < numBoxScv)
104 return Dune::GeometryTypes::cube(dim);
105
106 DUNE_THROW(Dune::NotImplemented, "PQ2 scv geometry call for hybrid dofs");
107 }
108
110 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
111 {
112 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
113 }
114
116 template<class Transformation>
117 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
118 {
119 // proceed according to number of corners
120 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
121 const auto numBoxScvf = ref.size(dim-1);
122 // reuse box geometry helper for scvfs
123 if (localScvfIdx < numBoxScvf)
124 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
125
126 DUNE_THROW(Dune::NotImplemented, "PQ2 scvf corners call for hybrid dofs");
127 }
128
129 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
130 {
131 const auto numBoxScvf = boxHelper_.numInteriorScvf();
132 if (localScvfIdx < numBoxScvf)
133 return Dune::GeometryTypes::cube(dim-1);
134
135 DUNE_THROW(Dune::NotImplemented, "PQ2 interior scvf geometry type call for hybrid dofs");
136 }
137
139 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex,
140 unsigned int indexInFacet) const
141 {
142 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
143 }
144
145 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
146 {
147 return Dune::GeometryTypes::cube(dim-1);
148 }
149
150 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
151 {
152 auto normal = Detail::scvfUnitNormal(geo_, p);
153
154 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
155
156 const auto s = v*normal;
157 if (std::signbit(s))
158 normal *= -1;
159
160 return normal;
161 }
162
164 const typename Element::Geometry& elementGeometry() const
165 { return geo_; }
166
168 static auto numInteriorScvf(Dune::GeometryType type)
169 {
170 return BoxHelper::numInteriorScvf(type);
171 }
172
174 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
175 {
176 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
177 }
178
180 std::size_t numScv() const
181 {
182 return boxHelper_.numScv();
183 }
184
186 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
187 {
188 const auto scvType = getScvGeometryType(localScvIdx);
189
191 scvType,
192 [&](unsigned int i){ return p[i]; }
193 );
194 }
195
196 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
197 {
198 const auto numBoxFaces = boxHelper_.numInteriorScvf();
199 if (localScvfIndex < numBoxFaces)
200 {
201 return {
202 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
203 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
204 };
205 }
206
207 DUNE_THROW(Dune::NotImplemented, "PQ2 scv pair call for hybrid dofs");
208 }
209
210 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
211 {
212 const auto numBoxScvf = referenceElement(geo_).size(localFacetIndex, 1, dim);
213 if (localIsScvfIndex < numBoxScvf)
214 {
215 const LocalIndexType insideScvIdx
216 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
217 return { insideScvIdx, insideScvIdx };
218 }
219
220 DUNE_THROW(Dune::NotImplemented, "PQ2 scv boundary pair call for hybrid dofs");
221 }
222
223 // For hybrid dofs we don't construct scvfs
224 bool isOverlappingScvf(unsigned int localScvfIndex) const
225 { return false; }
226
227 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
228 { return false; }
229
230 // For hybrid dofs we don't construct scvs
231 bool isOverlappingScv(unsigned int localScvIndex) const
232 { return false; }
233
234private:
235 const typename Element::Geometry& geo_;
236 BoxHelper boxHelper_;
237};
238
239} // end namespace Dumux
240
241#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:262
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq2/geometryhelper.hh:145
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition discretization/pq2/geometryhelper.hh:180
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition discretization/pq2/geometryhelper.hh:227
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition discretization/pq2/geometryhelper.hh:110
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition discretization/pq2/geometryhelper.hh:224
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition discretization/pq2/geometryhelper.hh:210
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition discretization/pq2/geometryhelper.hh:79
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition discretization/pq2/geometryhelper.hh:164
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition discretization/pq2/geometryhelper.hh:196
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition discretization/pq2/geometryhelper.hh:168
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition discretization/pq2/geometryhelper.hh:139
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition discretization/pq2/geometryhelper.hh:186
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition discretization/pq2/geometryhelper.hh:174
Dumux::PQ2LagrangeDofHelper< GridView > DofHelper
Definition discretization/pq2/geometryhelper.hh:71
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition discretization/pq2/geometryhelper.hh:150
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq2/geometryhelper.hh:129
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition discretization/pq2/geometryhelper.hh:98
bool isOverlappingScv(unsigned int localScvIndex) const
Definition discretization/pq2/geometryhelper.hh:231
HybridPQ2GeometryHelper(const typename Element::Geometry &geometry)
Definition discretization/pq2/geometryhelper.hh:73
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:117
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition discretization/pq2/geometryhelper.hh:86
auto scvfUnitNormal(const ElementGeometry &geo, const CornerStorage &corners)
Unit normal of an interior sub-control volume face, up to sign.
Definition scvfnormal.hh:33
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.
Normal vector of a sub-control volume face of an element-local dual grid.
DOF index and position helper for order-2 Lagrange discretizations.
Definition pq2/dofhelper.hh:36
Definition discretization/pq2/geometryhelper.hh:44
Dune::ReservedVector< Dune::FieldVector< ct, cdim >,(1<< mydim)> Type
Definition discretization/pq2/geometryhelper.hh:45
Traits for an efficient corner storage for the PQ2 method.
Definition discretization/pq2/geometryhelper.hh:39
Compute the volume of several common geometry types.