13#ifndef DUMUX_DISCRETIZATION_PQ2_GEOMETRY_HELPER_HH
14#define DUMUX_DISCRETIZATION_PQ2_GEOMETRY_HELPER_HH
18#include <dune/common/exceptions.hh>
20#include <dune/geometry/type.hh>
21#include <dune/geometry/referenceelements.hh>
22#include <dune/geometry/multilineargeometry.hh>
23#include <dune/common/reservedvector.hh>
37 template<
int mydim,
int cdim >
40 using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<mydim)+ mydim*(1<<(mydim-1))>;
48template <
class Gr
idView,
class ScvType,
class ScvfType>
51 using Scalar =
typename GridView::ctype;
52 using GlobalPosition =
typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
53 using ScvCornerStorage =
typename ScvType::Traits::CornerStorage;
54 using ScvfCornerStorage =
typename ScvfType::Traits::CornerStorage;
55 using LocalIndexType =
typename ScvType::Traits::LocalIndexType;
57 using Element =
typename GridView::template Codim<0>::Entity;
58 using Intersection =
typename GridView::Intersection;
60 static constexpr auto dim = GridView::dimension;
61 static constexpr auto dimWorld = GridView::dimensionworld;
68 , boxHelper_(geometry)
74 return getScvCorners(geo_.type(), [&](
const auto& local){ return geo_.global(local); }, localScvIdx);
78 template<
class Transformation>
79 static ScvCornerStorage
getScvCorners(Dune::GeometryType type, Transformation&& trans,
unsigned int localScvIdx)
82 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
83 const auto numBoxScv = ref.size(dim);
85 if (localScvIdx < numBoxScv)
86 return BoxHelper::getScvCorners(type, trans, localScvIdx);
88 DUNE_THROW(Dune::NotImplemented,
"PQ2 scv corners call for hybrid dofs");
94 const auto numBoxScv = boxHelper_.numScv();
96 if (localScvIdx < numBoxScv)
97 return Dune::GeometryTypes::cube(dim);
99 DUNE_THROW(Dune::NotImplemented,
"PQ2 scv geometry call for hybrid dofs");
105 return getScvfCorners(geo_.type(), [&](
const auto& local){ return geo_.global(local); }, localScvfIdx);
109 template<
class Transformation>
110 static ScvfCornerStorage
getScvfCorners(Dune::GeometryType type, Transformation&& trans,
unsigned int localScvfIdx)
113 const auto& ref = Dune::referenceElement<Scalar, dim>(type);
114 const auto numBoxScvf = ref.size(dim-1);
116 if (localScvfIdx < numBoxScvf)
117 return BoxHelper::getScvfCorners(type, trans, localScvfIdx);
119 DUNE_THROW(Dune::NotImplemented,
"PQ2 scvf corners call for hybrid dofs");
124 const auto numBoxScvf = boxHelper_.numInteriorScvf();
125 if (localScvfIdx < numBoxScvf)
126 return Dune::GeometryTypes::cube(dim-1);
128 DUNE_THROW(Dune::NotImplemented,
"PQ2 interior scvf geometry type call for hybrid dofs");
133 unsigned int indexInFacet)
const
135 return boxHelper_.getBoundaryScvfCorners(localFacetIndex, indexInFacet);
140 return Dune::GeometryTypes::cube(dim-1);
143 template<
int d = dimWorld, std::enable_if_t<(d==3),
int> = 0>
144 GlobalPosition
normal(
const ScvfCornerStorage& p,
const std::array<LocalIndexType, 2>& scvPair)
149 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
158 template<
int d = dimWorld, std::enable_if_t<(d==2),
int> = 0>
159 GlobalPosition
normal(
const ScvfCornerStorage& p,
const std::array<LocalIndexType, 2>& scvPair)
162 const auto t = p[1] - p[0];
163 GlobalPosition
normal({-t[1], t[0]});
166 GlobalPosition v = geo_.corner(scvPair[1]) - geo_.corner(scvPair[0]);
182 return BoxHelper::numInteriorScvf(type);
188 return Dune::referenceElement<Scalar, dim>(type).size(localFacetIndex, 1, dim);
194 return boxHelper_.numScv();
198 Scalar
scvVolume(
unsigned int localScvIdx,
const ScvCornerStorage& p)
const
202 return Dumux::convexPolytopeVolume<dim>(
204 [&](
unsigned int i){
return p[i]; }
209 template<
class LocalKey>
212 const auto& refElement = Dune::referenceElement<Scalar, dim>(type);
214 const auto numEntitiesIntersection = refElement.size(iIdx, 1, localKey.codim());
215 for(std::size_t idx=0; idx < numEntitiesIntersection; idx++)
216 if(localKey.subEntity() == refElement.subEntity(iIdx, 1, idx, localKey.codim()))
222 template<
class DofMapper,
class LocalKey>
223 static auto dofIndex(
const DofMapper& dofMapper,
const Element& element,
const LocalKey& localKey)
226 return dofMapper.subIndex(element, localKey.subEntity(), localKey.codim());
229 template<
class Geometry,
class LocalKey>
230 static GlobalPosition
dofPosition(
const Geometry& geo,
const LocalKey& localKey)
232 if(localKey.codim() == dim)
233 return geo.corner(localKey.subEntity());
234 else if(localKey.codim() == 0)
240 template<
class LocalKey>
247 template<
class LocalKey>
248 static Element::Geometry::LocalCoordinate
localDofPosition(Dune::GeometryType type,
const LocalKey& localKey)
250 return Dune::referenceElement<Scalar, dim>(type).position(localKey.subEntity(), localKey.codim());
255 const auto numBoxFaces = boxHelper_.numInteriorScvf();
256 if (localScvfIndex < numBoxFaces)
259 static_cast<LocalIndexType
>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 0, dim)),
260 static_cast<LocalIndexType
>(referenceElement(geo_).subEntity(localScvfIndex, dim-1, 1, dim))
264 DUNE_THROW(Dune::NotImplemented,
"PQ2 scv pair call for hybrid dofs");
269 const auto numBoxScvf = referenceElement(geo_).size(localFacetIndex, 1, dim);
270 if (localIsScvfIndex < numBoxScvf)
272 const LocalIndexType insideScvIdx
273 =
static_cast<LocalIndexType
>(referenceElement(geo_).subEntity(localFacetIndex, 1, localIsScvfIndex, dim));
274 return { insideScvIdx, insideScvIdx };
277 DUNE_THROW(Dune::NotImplemented,
"PQ2 scv boundary pair call for hybrid dofs");
292 const typename Element::Geometry& geo_;
293 BoxHelper boxHelper_;
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:257
A class to create sub control volume and sub control volume face geometries per element.
Definition: discretization/pq2/geometryhelper.hh:50
Dune::GeometryType getBoundaryScvfGeometryType(unsigned int localScvfIdx) const
Definition: discretization/pq2/geometryhelper.hh:138
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition: discretization/pq2/geometryhelper.hh:192
bool isOverlappingBoundaryScvf(unsigned int localFacetIndex) const
Definition: discretization/pq2/geometryhelper.hh:284
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition: discretization/pq2/geometryhelper.hh:103
GlobalPosition dofPosition(const LocalKey &localKey) const
Definition: discretization/pq2/geometryhelper.hh:241
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition: discretization/pq2/geometryhelper.hh:281
static auto dofIndex(const DofMapper &dofMapper, const Element &element, const LocalKey &localKey)
Definition: discretization/pq2/geometryhelper.hh:223
static auto localDofOnIntersection(Dune::GeometryType type, unsigned int iIdx, const LocalKey &localKey)
Local dof index related to a localDof, with index ilocalDofIdx, on an intersection with index iIdx.
Definition: discretization/pq2/geometryhelper.hh:210
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition: discretization/pq2/geometryhelper.hh:267
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition: discretization/pq2/geometryhelper.hh:72
const Element::Geometry & elementGeometry() const
the wrapped element geometry
Definition: discretization/pq2/geometryhelper.hh:176
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition: discretization/pq2/geometryhelper.hh:253
static auto numInteriorScvf(Dune::GeometryType type)
number of interior sub control volume faces
Definition: discretization/pq2/geometryhelper.hh:180
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition: discretization/pq2/geometryhelper.hh:132
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition: discretization/pq2/geometryhelper.hh:198
static auto numBoundaryScvf(Dune::GeometryType type, unsigned int localFacetIndex)
number of boundary sub control volume faces for face localFacetIndex
Definition: discretization/pq2/geometryhelper.hh:186
static Element::Geometry::LocalCoordinate localDofPosition(Dune::GeometryType type, const LocalKey &localKey)
local dof position
Definition: discretization/pq2/geometryhelper.hh:248
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition: discretization/pq2/geometryhelper.hh:122
Dune::GeometryType getScvGeometryType(unsigned int localScvIdx) const
Definition: discretization/pq2/geometryhelper.hh:91
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition: discretization/pq2/geometryhelper.hh:144
bool isOverlappingScv(unsigned int localScvIndex) const
Definition: discretization/pq2/geometryhelper.hh:288
HybridPQ2GeometryHelper(const typename Element::Geometry &geometry)
Definition: discretization/pq2/geometryhelper.hh:66
static GlobalPosition dofPosition(const Geometry &geo, const LocalKey &localKey)
Definition: discretization/pq2/geometryhelper.hh:230
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:110
static ScvCornerStorage getScvCorners(Dune::GeometryType type, Transformation &&trans, unsigned int localScvIdx)
Create a vector with the scv corners.
Definition: discretization/pq2/geometryhelper.hh:79
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
Define some often used mathematical functions.
Definition: discretization/pq2/geometryhelper.hh:39
Dune::ReservedVector< Dune::FieldVector< ct, cdim >,(1<< mydim)+mydim *(1<<(mydim-1))> Type
Definition: discretization/pq2/geometryhelper.hh:40
Traits for an efficient corner storage for the PQ2 method.
Definition: discretization/pq2/geometryhelper.hh:34
Compute the volume of several common geometry types.