version 3.11-dev
Loading...
Searching...
No Matches
discretization/pq3/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//
7// This file includes code adapted from dune-functions.
8// These parts are clearly marked with inline comments and were originally
9// licensed under LGPL-3.0-or-later. They are adapted and relicensed here
10// under the terms of the GNU GPL-3.0-or-later as permitted by LGPLv3 Sec. 3.
11//
12// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
13//
20#ifndef DUMUX_DISCRETIZATION_PQ3_GEOMETRY_HELPER_HH
21#define DUMUX_DISCRETIZATION_PQ3_GEOMETRY_HELPER_HH
22
23#include <array>
24
25#include <dune/common/exceptions.hh>
26#include <dune/geometry/type.hh>
27#include <dune/geometry/referenceelements.hh>
28#include <dune/geometry/multilineargeometry.hh>
29#include <dune/common/reservedvector.hh>
30
31#include <dumux/common/math.hh>
34// Reuse PQ2 corner storage traits (same structure, different order)
37
38namespace Dumux {
39
51template <class GridView, class ScvType, class ScvfType>
53{
54 using Scalar = typename GridView::ctype;
55 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
56 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
57 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
58 using LocalIndexType = typename ScvType::Traits::LocalIndexType;
59
60 using Element = typename GridView::template Codim<0>::Entity;
61 using Intersection = typename GridView::Intersection;
62
63 static constexpr auto dim = GridView::dimension;
64 static constexpr auto dimWorld = GridView::dimensionworld;
65
67public:
69
70 HybridPQ3GeometryHelper(const typename Element::Geometry& geometry)
71 : geo_(geometry)
72 , boxHelper_(geometry)
73 {}
74
76 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
77 {
78 return getScvCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvIdx);
79 }
80
82 template<class Transformation>
83 static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvIdx)
84 {
85 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
86 const auto numBoxScv = ref.size(dim);
87 if (localScvIdx < numBoxScv)
88 return BoxHelper::getScvCorners(type, trans, localScvIdx);
89
90 DUNE_THROW(Dune::NotImplemented, "PQ3 scv corners call for hybrid dofs");
91 }
92
93 Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
94 {
95 const auto numBoxScv = boxHelper_.numScv();
96 if (localScvIdx < numBoxScv)
97 return Dune::GeometryTypes::cube(dim);
98
99 DUNE_THROW(Dune::NotImplemented, "PQ3 scv geometry call for hybrid dofs");
100 }
101
103 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
104 {
105 return getScvfCorners(geo_.type(), [&](const auto& local){ return geo_.global(local); }, localScvfIdx);
106 }
107
109 template<class Transformation>
110 static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation&& trans, unsigned int localScvfIdx)
111 {
112 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
113 const auto numBoxScvf = ref.size(dim-1);
114 if (localScvfIdx < numBoxScvf)
115 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
116
117 DUNE_THROW(Dune::NotImplemented, "PQ3 scvf corners call for hybrid dofs");
118 }
119
120 Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
121 {
122 const auto numBoxScvf = boxHelper_.numInteriorScvf();
123 if (localScvfIdx < numBoxScvf)
124 return Dune::GeometryTypes::cube(dim-1);
125
126 DUNE_THROW(Dune::NotImplemented, "PQ3 interior scvf geometry type call for hybrid dofs");
127 }
128
130 ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
131 {
132 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
133 }
134
135 Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
136 {
137 return Dune::GeometryTypes::cube(dim-1);
138 }
139
140 template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0>
141 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
142 {
143 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
144 normal /= normal.two_norm();
145
146 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
147
148 const auto s = v*normal;
149 if (std::signbit(s))
150 normal *= -1;
151
152 return normal;
153 }
154
155 template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0>
156 GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair)
157 {
158 const auto t = p[1] - p[0];
159 GlobalPosition normal({-t[1], t[0]});
160 normal /= normal.two_norm();
161
162 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
163
164 const auto s = v*normal;
165 if (std::signbit(s))
166 normal *= -1;
167
168 return normal;
169 }
170
172 const typename Element::Geometry& elementGeometry() const
173 { return geo_; }
174
176 static auto numInteriorScvf(Dune::GeometryType type)
177 {
178 return BoxHelper::numInteriorScvf(type);
179 }
180
182 static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
183 {
184 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
185 }
186
188 std::size_t numScv() const
189 {
190 return boxHelper_.numScv();
191 }
192
194 Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage& p) const
195 {
196 const auto scvType = getScvGeometryType(localScvIdx);
198 scvType,
199 [&](unsigned int i){ return p[i]; }
200 );
201 }
202
203 std::array<LocalIndexType, 2> getScvPairForScvf(unsigned int localScvfIndex) const
204 {
205 const auto numBoxFaces = boxHelper_.numInteriorScvf();
206 if (localScvfIndex < numBoxFaces)
207 {
208 return {
209 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
210 static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
211 };
212 }
213
214 DUNE_THROW(Dune::NotImplemented, "PQ3 scv pair call for hybrid dofs");
215 }
216
217 std::array<LocalIndexType, 2> getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
218 {
219 const auto numBoxScvf = referenceElement(geo_).size(localFacetIndex, 1, dim);
220 if (localIsScvfIndex < numBoxScvf)
221 {
222 const LocalIndexType insideScvIdx
223 = static_cast<LocalIndexType>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
224 return { insideScvIdx, insideScvIdx };
225 }
226
227 DUNE_THROW(Dune::NotImplemented, "PQ3 scv boundary pair call for hybrid dofs");
228 }
229
230 bool isOverlappingScvf(unsigned int localScvfIndex) const
231 { return false; }
232
233 bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
234 { return false; }
235
236 bool isOverlappingScv(unsigned int localScvIndex) const
237 { return false; }
238
239private:
240 const typename Element::Geometry& geo_;
241 BoxHelper boxHelper_;
242};
243
244} // end namespace Dumux
245
246#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/pq3/geometryhelper.hh:135
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition discretization/pq3/geometryhelper.hh:217
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition discretization/pq3/geometryhelper.hh:233
HybridPQ3GeometryHelper(const typename Element::Geometry &geometry)
Definition discretization/pq3/geometryhelper.hh:70
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition discretization/pq3/geometryhelper.hh:230
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition discretization/pq3/geometryhelper.hh:103
bool isOverlappingScv(unsigned int localScvIndex) const
Definition discretization/pq3/geometryhelper.hh:236
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition discretization/pq3/geometryhelper.hh:76
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition discretization/pq3/geometryhelper.hh:141
std::size_t numScv() const
number of sub control volumes (one per vertex)
Definition discretization/pq3/geometryhelper.hh:188
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq3/geometryhelper.hh:120
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition discretization/pq3/geometryhelper.hh:93
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition discretization/pq3/geometryhelper.hh:130
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition discretization/pq3/geometryhelper.hh:194
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition discretization/pq3/geometryhelper.hh:172
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition discretization/pq3/geometryhelper.hh:203
PQ3LagrangeDofHelper< GridView > DofHelper
Definition discretization/pq3/geometryhelper.hh:68
static ScvfCornerStorage getScvfCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvfIdx)
Create a vector with the corners of sub control volume faces.
Definition discretization/pq3/geometryhelper.hh:110
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition discretization/pq3/geometryhelper.hh:176
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition discretization/pq3/geometryhelper.hh:182
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition discretization/pq3/geometryhelper.hh:83
DOF index and position helper for order-3 Lagrange discretizations.
Definition pq3/dofhelper.hh:51
Helper class constructing the dual grid finite volume geometries for the cvfe discretizazion method.
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
Define some often used mathematical functions.
Definition adapt.hh:17
Lightweight DOF helper for order-3 Lagrange elements.
Compute the volume of several common geometry types.