version 3.11-dev
discretization/pq2/fvelementgeometry.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//
14#ifndef DUMUX_DISCRETIZATION_PQ2_FV_ELEMENT_GEOMETRY_HH
15#define DUMUX_DISCRETIZATION_PQ2_FV_ELEMENT_GEOMETRY_HH
16
17#include <cstddef>
18#include <cassert>
19#include <optional>
20#include <ranges>
21#include <span>
22#include <utility>
23#include <vector>
24
25#include <dune/common/rangeutilities.hh>
26#include <dune/geometry/type.hh>
27#include <dune/localfunctions/lagrange/pqkfactory.hh>
28
34
36
37namespace Dumux {
38
47template<class GG, bool enableGridGeometryCache>
49
51template<class GG>
52class PQ2FVElementGeometry<GG, true>
53{
54 using GridView = typename GG::GridView;
55 static constexpr int dim = GridView::dimension;
56 static constexpr int dimWorld = GridView::dimensionworld;
57 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
58 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
59 using CoordScalar = typename GridView::ctype;
60 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
61 using GGCache = typename GG::Cache;
62 using GeometryHelper = typename GGCache::GeometryHelper;
63
65 typename GridView::template Codim<0>::Entity::Geometry::LocalCoordinate,
66 typename GridView::template Codim<0>::Entity::Geometry::GlobalCoordinate
67 >;
68
69public:
71 using Element = typename GridView::template Codim<0>::Entity;
73 using SubControlVolume = typename GG::SubControlVolume;
75 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
77 using GridGeometry = GG;
79 using BoundaryFace = typename GG::BoundaryFace;
81 using ScvQuadratureRule = typename GG::ScvQuadratureRule;
83 using ScvfQuadratureRule = typename GG::ScvfQuadratureRule;
85 using ElementQuadratureRule = typename GG::ElementQuadratureRule;
87 using IntersectionQuadratureRule = typename GG::IntersectionQuadratureRule;
89 using BoundaryFaceQuadratureRule = typename GG::BoundaryFaceQuadratureRule;
91 static constexpr std::size_t maxNumElementDofs = GridGeometry::maxNumElementDofs;
92
94 PQ2FVElementGeometry(const GGCache& ggCache)
95 : ggCache_(&ggCache)
96 {}
97
99 const SubControlVolume& scv(LocalIndexType scvIdx) const
100 {
101 return ggCache_->scvs(eIdx_)[scvIdx];
102 }
103
105 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
106 {
107 return ggCache_->scvfs(eIdx_)[scvfIdx];
108 }
109
115 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
116 scvs(const PQ2FVElementGeometry& fvGeometry)
117 {
118 using Iter = typename std::vector<SubControlVolume>::const_iterator;
119 const auto& s = fvGeometry.ggCache_->scvs(fvGeometry.eIdx_);
120 return Dune::IteratorRange<Iter>(s.begin(), s.end());
121 }
122
123 friend inline auto cvLocalDofs(const PQ2FVElementGeometry& fvGeometry)
124 {
125 return std::views::iota(std::size_t(0), fvGeometry.numLocalDofs())
126 | std::views::filter([&](size_t i) { return fvGeometry.feLocalCoefficients().localKey(i).codim() == dim; })
127 | std::views::transform([&](size_t i) {
128 return CVFE::LocalDof{
129 static_cast<LocalIndexType>(i),
130 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(),
131 fvGeometry.feLocalCoefficients().localKey(i))),
132 static_cast<GridIndexType>(fvGeometry.elementIndex())
133 };
134 });
135 }
136
137 friend inline auto nonCVLocalDofs(const PQ2FVElementGeometry& fvGeometry)
138 {
139 return std::views::iota(std::size_t(0), fvGeometry.numLocalDofs())
140 | std::views::filter([&](size_t i) { return !(fvGeometry.feLocalCoefficients().localKey(i).codim() == dim); })
141 | std::views::transform([&](size_t i) {
142 return CVFE::LocalDof{
143 static_cast<LocalIndexType>(i),
144 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(),
145 fvGeometry.feLocalCoefficients().localKey(i))),
146 static_cast<GridIndexType>(fvGeometry.elementIndex())
147 };
148 });
149 }
150
151 friend inline auto localDofs(const PQ2FVElementGeometry& fvGeometry)
152 {
153 return Dune::transformedRangeView(
154 Dune::range(std::size_t(0), fvGeometry.numLocalDofs()), [&](const auto i) {
155 return CVFE::LocalDof{
156 static_cast<LocalIndexType>(i),
157 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(),
158 fvGeometry.feLocalCoefficients().localKey(i))),
159 static_cast<GridIndexType>(fvGeometry.elementIndex())
160 };
161 }
162 );
163 }
164
166 friend inline auto localDofs(const PQ2FVElementGeometry& fvGeometry, const BoundaryFace& boundaryFace)
167 {
168 return std::views::iota(std::size_t(0), fvGeometry.numLocalDofs())
169 | std::views::filter([&](size_t i) {
170 return GeometryHelper::localDofOnIntersection(fvGeometry.element().type(),
171 boundaryFace.intersectionIndex(),
172 fvGeometry.feLocalCoefficients().localKey(i)); })
173 | std::views::transform([&](size_t i) {
174 return CVFE::LocalDof{
175 static_cast<LocalIndexType>(i),
176 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(),
177 fvGeometry.feLocalCoefficients().localKey(i))),
178 static_cast<GridIndexType>(fvGeometry.elementIndex())
179 };
180 });
181 }
182
188 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
189 scvfs(const PQ2FVElementGeometry& fvGeometry)
190 {
191 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
192 const auto& s = fvGeometry.ggCache_->scvfs(fvGeometry.eIdx_);
193 return Dune::IteratorRange<Iter>(s.begin(), s.end());
194 }
195
198 friend inline std::ranges::view auto
200 {
201 const auto& v = fvGeometry.ggCache_->boundaryFaces(fvGeometry.eIdx_);
202 return std::ranges::views::all(v);
203 }
204
206 const FeLocalBasis& feLocalBasis() const
207 {
208 return gridGeometry().feCache().get(element_->type()).localBasis();
209 }
210
212 const auto& feLocalCoefficients() const
213 {
214 return gridGeometry().feCache().get(element_->type()).localCoefficients();
215 }
216
218 std::size_t numLocalDofs() const
219 {
220 return feLocalCoefficients().size();
221 }
222
224 std::size_t numScv() const
225 {
226 return ggCache_->scvs(eIdx_).size();
227 }
228
230 std::size_t numScvf() const
231 {
232 return ggCache_->scvfs(eIdx_).size();
233 }
234
241 {
242 this->bindElement(element);
243 return std::move(*this);
244 }
245
249 void bind(const Element& element) &
250 { this->bindElement(element); }
251
258 {
259 this->bindElement(element);
260 return std::move(*this);
261 }
262
266 void bindElement(const Element& element) &
267 {
268 element_ = element;
269 // cache element index
270 eIdx_ = gridGeometry().elementMapper().index(element);
271 elementGeometry_.emplace(element.geometry());
272 }
273
275 bool isBound() const
276 { return static_cast<bool>(element_); }
277
279 const Element& element() const
280 { return *element_; }
281
283 const typename Element::Geometry& elementGeometry() const
284 { return *elementGeometry_; }
285
288 { return ggCache_->gridGeometry(); }
289
291 bool hasBoundaryScvf() const
292 { return ggCache_->hasBoundaryScvf(eIdx_); }
293
295 bool hasBoundaryFaces() const
296 { return hasBoundaryScvf(); }
297
299 const BoundaryFace& boundaryFace(LocalIndexType bfIdx) const
300 { return ggCache_->boundaryFaces(eIdx_)[bfIdx]; }
301
303 std::size_t elementIndex() const
304 { return eIdx_; }
305
307 std::size_t intersectionIndex(const SubControlVolumeFace& scvf) const
308 {
309 const auto localScvfIdx = scvf.index() - GeometryHelper::numInteriorScvf(element().type());
310 return ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx][0];
311 }
312
314 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
315 {
316 assert(isBound());
317 const auto& geo = elementGeometry();
318 const GeometryHelper helper(geo);
319 const auto scvIdx = this->feLocalCoefficients().localKey(scv.localDofIndex()).subEntity();
320 return {
321 helper.getScvGeometryType(scvIdx),
322 helper.getScvCorners(scvIdx)
323 };
324 }
325
327 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
328 {
329 assert(isBound());
330 if (scvf.boundary())
331 {
332 GeometryHelper helper(*elementGeometry_);
333 const auto localScvfIdx = scvf.index() - GeometryHelper::numInteriorScvf(element().type());
334 const auto [localFacetIndex, isScvfLocalIdx]
335 = ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx];
336 return {
337 helper.getBoundaryScvfGeometryType(isScvfLocalIdx),
338 helper.getBoundaryScvfCorners(localFacetIndex, isScvfLocalIdx)
339 };
340 }
341 else
342 {
343 GeometryHelper helper(*elementGeometry_);
344 return {
345 helper.getInteriorScvfGeometryType(scvf.index()),
346 helper.getScvfCorners(scvf.index())
347 };
348 }
349 }
350
352 typename BoundaryFace::Traits::Geometry geometry(const BoundaryFace& boundaryFace) const
353 {
354 assert(isBound());
355 const auto& elemGeo = elementGeometry();
356 const auto faceGeoInRef = referenceElement(elemGeo).template geometry<1>(boundaryFace.intersectionIndex());
357 typename BoundaryFace::Traits::CornerStorage corners;
358 for (int i = 0; i < faceGeoInRef.corners(); ++i)
359 corners.push_back(elemGeo.global(faceGeoInRef.corner(i)));
360 return { faceGeoInRef.type(), corners };
361 }
362
364 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const SubControlVolume& scv)
365 {
366 const auto type = fvGeometry.element().type();
367 const auto& localKey = fvGeometry.feLocalCoefficients().localKey(scv.localDofIndex());
368
369 return CVFE::LocalDofInterpolationPointData{ GeometryHelper::localDofPosition(type, localKey), scv.dofPosition(), scv.localDofIndex() };
370 }
371
373 template<class LocalDof>
374 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const LocalDof& localDof)
375 {
376 const auto type = fvGeometry.element().type();
377 const auto& localKey = fvGeometry.feLocalCoefficients().localKey(localDof.index());
378 const auto& localPos = GeometryHelper::localDofPosition(type, localKey);
379
380 return CVFE::LocalDofInterpolationPointData{ localPos, fvGeometry.elementGeometry().global(localPos), localDof.index() };
381 }
382
384 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const typename Element::Geometry::GlobalCoordinate& globalPos)
385 {
386 // Create ipData that does not automatically calculate the local position but only if it is called
388 [&] (const typename Element::Geometry::GlobalCoordinate& pos) { return fvGeometry.elementGeometry().local(pos); },
389 globalPos
390 };
391 }
392
394 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const SubControlVolumeFace& scvf)
395 {
397 { scvf.unitOuterNormal(), scvf.index(), fvGeometry.elementGeometry().local(scvf.ipGlobal()), scvf.ipGlobal() };
398 }
399
400private:
401 const GGCache* ggCache_;
402 GridIndexType eIdx_;
403
404 std::optional<Element> element_;
405 std::optional<typename Element::Geometry> elementGeometry_;
406};
407
408} // end namespace Dumux
409
410#endif
An interpolation point related to a face of an element.
Definition: cvfe/interpolationpointdata.hh:109
const GlobalPosition & unitOuterNormal() const
The unit outer normal vector at the quadrature point.
Definition: cvfe/interpolationpointdata.hh:123
An interpolation point related to an element that includes global and local positions.
Definition: cvfe/interpolationpointdata.hh:31
An interpolation point related to a global position of an element, giving its local positions by a ma...
Definition: cvfe/interpolationpointdata.hh:82
A local degree of freedom from an element perspective.
Definition: localdof.hh:27
An interpolation point related to a localDof of an element, giving its global and local positions.
Definition: cvfe/interpolationpointdata.hh:60
LocalIndex localDofIndex() const
The local index of the corresponding dof.
Definition: cvfe/interpolationpointdata.hh:69
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: discretization/pq2/fvelementgeometry.hh:275
std::size_t intersectionIndex(const SubControlVolumeFace &scvf) const
The intersection index the scvf belongs to.
Definition: discretization/pq2/fvelementgeometry.hh:307
const Element::Geometry & elementGeometry() const
The bound element geometry.
Definition: discretization/pq2/fvelementgeometry.hh:283
typename GG::ScvfQuadratureRule ScvfQuadratureRule
the quadrature rule type for scvfs
Definition: discretization/pq2/fvelementgeometry.hh:83
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const SubControlVolume &scv)
Interpolation point data for an scv.
Definition: discretization/pq2/fvelementgeometry.hh:364
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const PQ2FVElementGeometry &fvGeometry)
Definition: discretization/pq2/fvelementgeometry.hh:189
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const LocalDof &localDof)
Interpolation point data for a localDof.
Definition: discretization/pq2/fvelementgeometry.hh:374
void bind(const Element &element) &
Definition: discretization/pq2/fvelementgeometry.hh:249
BoundaryFace::Traits::Geometry geometry(const BoundaryFace &boundaryFace) const
Geometry of a boundary face.
Definition: discretization/pq2/fvelementgeometry.hh:352
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Geometry of a sub control volume face.
Definition: discretization/pq2/fvelementgeometry.hh:327
PQ2FVElementGeometry(const GGCache &ggCache)
Constructor.
Definition: discretization/pq2/fvelementgeometry.hh:94
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const PQ2FVElementGeometry &fvGeometry)
Definition: discretization/pq2/fvelementgeometry.hh:116
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf)
Interpolation point data for scvf.
Definition: discretization/pq2/fvelementgeometry.hh:394
const auto & feLocalCoefficients() const
Get a local finite element basis.
Definition: discretization/pq2/fvelementgeometry.hh:212
typename GG::SubControlVolumeFace SubControlVolumeFace
export type of subcontrol volume face
Definition: discretization/pq2/fvelementgeometry.hh:75
friend auto nonCVLocalDofs(const PQ2FVElementGeometry &fvGeometry)
Definition: discretization/pq2/fvelementgeometry.hh:137
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Geometry of a sub control volume.
Definition: discretization/pq2/fvelementgeometry.hh:314
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const typename Element::Geometry::GlobalCoordinate &globalPos)
Interpolation point data for a global position.
Definition: discretization/pq2/fvelementgeometry.hh:384
PQ2FVElementGeometry bind(const Element &element) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: discretization/pq2/fvelementgeometry.hh:240
std::size_t numScv() const
The total number of sub control volumes.
Definition: discretization/pq2/fvelementgeometry.hh:224
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: discretization/pq2/fvelementgeometry.hh:230
void bindElement(const Element &element) &
Definition: discretization/pq2/fvelementgeometry.hh:266
bool hasBoundaryScvf() const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition: discretization/pq2/fvelementgeometry.hh:291
typename GG::ScvQuadratureRule ScvQuadratureRule
the quadrature rule type for scvs
Definition: discretization/pq2/fvelementgeometry.hh:81
bool hasBoundaryFaces() const
Returns whether the element has boundary faces.
Definition: discretization/pq2/fvelementgeometry.hh:295
std::size_t elementIndex() const
The bound element index.
Definition: discretization/pq2/fvelementgeometry.hh:303
const SubControlVolumeFace & scvf(LocalIndexType scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: discretization/pq2/fvelementgeometry.hh:105
friend auto localDofs(const PQ2FVElementGeometry &fvGeometry)
Definition: discretization/pq2/fvelementgeometry.hh:151
const BoundaryFace & boundaryFace(LocalIndexType bfIdx) const
Get a boundary face with a local boundary face index.
Definition: discretization/pq2/fvelementgeometry.hh:299
friend auto cvLocalDofs(const PQ2FVElementGeometry &fvGeometry)
Definition: discretization/pq2/fvelementgeometry.hh:123
typename GG::ElementQuadratureRule ElementQuadratureRule
the quadrature rule type for elements
Definition: discretization/pq2/fvelementgeometry.hh:85
typename GG::IntersectionQuadratureRule IntersectionQuadratureRule
the quadrature rule type for intersections
Definition: discretization/pq2/fvelementgeometry.hh:87
friend std::ranges::view auto boundaryFaces(const PQ2FVElementGeometry &fvGeometry)
Definition: discretization/pq2/fvelementgeometry.hh:199
typename GG::BoundaryFace BoundaryFace
export the boundary face type
Definition: discretization/pq2/fvelementgeometry.hh:79
const SubControlVolume & scv(LocalIndexType scvIdx) const
Get a sub control volume with a local scv index.
Definition: discretization/pq2/fvelementgeometry.hh:99
std::size_t numLocalDofs() const
The total number of element-local dofs.
Definition: discretization/pq2/fvelementgeometry.hh:218
typename GG::SubControlVolume SubControlVolume
export type of subcontrol volume
Definition: discretization/pq2/fvelementgeometry.hh:73
typename GG::BoundaryFaceQuadratureRule BoundaryFaceQuadratureRule
the quadrature rule type for boundary faces
Definition: discretization/pq2/fvelementgeometry.hh:89
GG GridGeometry
export type of finite volume grid geometry
Definition: discretization/pq2/fvelementgeometry.hh:77
typename GridView::template Codim< 0 >::Entity Element
export the element type
Definition: discretization/pq2/fvelementgeometry.hh:71
const Element & element() const
The bound element.
Definition: discretization/pq2/fvelementgeometry.hh:279
const GridGeometry & gridGeometry() const
The grid geometry we are a restriction of.
Definition: discretization/pq2/fvelementgeometry.hh:287
friend auto localDofs(const PQ2FVElementGeometry &fvGeometry, const BoundaryFace &boundaryFace)
an iterator over all local dofs related to a boundary face
Definition: discretization/pq2/fvelementgeometry.hh:166
PQ2FVElementGeometry bindElement(const Element &element) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: discretization/pq2/fvelementgeometry.hh:257
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: discretization/pq2/fvelementgeometry.hh:206
Base class for the finite volume geometry vector for pq2 models This builds up the sub control volume...
Definition: discretization/pq2/fvelementgeometry.hh:48
Classes representing interpolation point data for control-volume finite element schemes.
Helper class constructing the dual grid finite volume geometries for the cvfe discretizazion method.
Defines the index types used for grid and local indices.
Class representing dofs on elements for control-volume finite element schemes.
Definition: adapt.hh:17
Quadrature rules over sub-control volumes and sub-control volume faces.
Class providing iterators over sub control volumes and sub control volume faces of an element.
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:27
unsigned int LocalIndex
Definition: indextraits.hh:28