version 3.11-dev
Loading...
Searching...
No Matches
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/common/reservedvector.hh>
27#include <dune/geometry/type.hh>
28#include <dune/localfunctions/lagrange/pqkfactory.hh>
29
35
37
38namespace Dumux {
39
48template<class GG, bool enableGridGeometryCache>
50
52template<class GG>
53class PQ2FVElementGeometry<GG, true>
54{
55 using GridView = typename GG::GridView;
56 static constexpr int dim = GridView::dimension;
57 static constexpr int dimWorld = GridView::dimensionworld;
58 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
59 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
60 using CoordScalar = typename GridView::ctype;
61 using FiniteElement = typename GG::FeCache::FiniteElementType;
62 using FeLocalBasis = typename FiniteElement::Traits::LocalBasisType;
63 using GGCache = typename GG::Cache;
64 using GeometryHelper = typename GGCache::GeometryHelper;
65 using DofHelper = typename GGCache::DofHelper;
66
67 using BaseIpData = CVFE::InterpolationPointData<
68 typename GridView::template Codim<0>::Entity::Geometry::LocalCoordinate,
69 typename GridView::template Codim<0>::Entity::Geometry::GlobalCoordinate
70 >;
71
72public:
74 using Element = typename GridView::template Codim<0>::Entity;
76 using SubControlVolume = typename GG::SubControlVolume;
78 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
80 using GridGeometry = GG;
82 using BoundaryFace = typename GG::BoundaryFace;
84 using ScvQuadratureRule = typename GG::ScvQuadratureRule;
86 using ScvfQuadratureRule = typename GG::ScvfQuadratureRule;
88 using ElementQuadratureRule = typename GG::ElementQuadratureRule;
90 using IntersectionQuadratureRule = typename GG::IntersectionQuadratureRule;
92 using BoundaryFaceQuadratureRule = typename GG::BoundaryFaceQuadratureRule;
94 static constexpr std::size_t maxNumElementDofs = GridGeometry::maxNumElementDofs;
95
97 PQ2FVElementGeometry(const GGCache& ggCache)
98 : ggCache_(&ggCache)
99 {}
100
102 const SubControlVolume& scv(LocalIndexType scvIdx) const
103 {
104 return ggCache_->scvs(eIdx_)[scvIdx];
105 }
106
108 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
109 {
110 return ggCache_->scvfs(eIdx_)[scvfIdx];
111 }
112
118 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
119 scvs(const PQ2FVElementGeometry& fvGeometry)
120 {
121 using Iter = typename std::vector<SubControlVolume>::const_iterator;
122 const auto& s = fvGeometry.ggCache_->scvs(fvGeometry.eIdx_);
123 return Dune::IteratorRange<Iter>(s.begin(), s.end());
124 }
125
126 friend inline auto cvLocalDofs(const PQ2FVElementGeometry& fvGeometry)
127 {
128 return std::views::iota(std::size_t(0), fvGeometry.numLocalDofs())
129 | std::views::filter([&](size_t i) { return fvGeometry.feLocalCoefficients().localKey(i).codim() == dim; })
130 | std::views::transform([&](size_t i) {
131 return CVFE::LocalDof{
132 static_cast<LocalIndexType>(i),
133 fvGeometry.dofIndices_[i],
134 static_cast<GridIndexType>(fvGeometry.elementIndex())
135 };
136 });
137 }
138
139 friend inline auto nonCVLocalDofs(const PQ2FVElementGeometry& fvGeometry)
140 {
141 return std::views::iota(std::size_t(0), fvGeometry.numLocalDofs())
142 | std::views::filter([&](size_t i) { return !(fvGeometry.feLocalCoefficients().localKey(i).codim() == dim); })
143 | std::views::transform([&](size_t i) {
144 return CVFE::LocalDof{
145 static_cast<LocalIndexType>(i),
146 fvGeometry.dofIndices_[i],
147 static_cast<GridIndexType>(fvGeometry.elementIndex())
148 };
149 });
150 }
151
152 friend inline auto localDofs(const PQ2FVElementGeometry& fvGeometry)
153 {
154 return Dune::transformedRangeView(
155 Dune::range(std::size_t(0), fvGeometry.numLocalDofs()), [&](const auto i) {
156 return CVFE::LocalDof{
157 static_cast<LocalIndexType>(i),
158 fvGeometry.dofIndices_[i],
159 static_cast<GridIndexType>(fvGeometry.elementIndex())
160 };
161 }
162 );
163 }
164
166 friend inline auto localDofs(const PQ2FVElementGeometry& fvGeometry, const BoundaryFace& boundaryFace)
167 { return DofHelper::localDofsOnBoundaryFace(fvGeometry, boundaryFace); }
168
174 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
175 scvfs(const PQ2FVElementGeometry& fvGeometry)
176 {
177 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
178 const auto& s = fvGeometry.ggCache_->scvfs(fvGeometry.eIdx_);
179 return Dune::IteratorRange<Iter>(s.begin(), s.end());
180 }
181
184 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
186 {
187 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
188 const auto& s = fvGeometry.ggCache_->scvfs(fvGeometry.eIdx_);
189 const auto& range = fvGeometry.ggCache_->boundaryFaceScvfRanges(fvGeometry.eIdx_)[boundaryFace.index()];
190 return Dune::IteratorRange<Iter>(s.begin() + range[0], s.begin() + range[0] + range[1]);
191 }
192
195 friend inline std::ranges::view auto
197 {
198 const auto& v = fvGeometry.ggCache_->boundaryFaces(fvGeometry.eIdx_);
199 return std::ranges::views::all(v);
200 }
201
203 const FeLocalBasis& feLocalBasis() const
204 {
205 return fe_->localBasis();
206 }
207
209 const auto& feLocalCoefficients() const
210 {
211 return fe_->localCoefficients();
212 }
213
215 std::size_t numLocalDofs() const
216 {
217 return dofIndices_.size();
218 }
219
221 std::size_t numScv() const
222 {
223 return ggCache_->scvs(eIdx_).size();
224 }
225
227 std::size_t numScvf() const
228 {
229 return ggCache_->scvfs(eIdx_).size();
230 }
231
238 {
239 this->bindElement(element);
240 return std::move(*this);
241 }
242
246 void bind(const Element& element) &
247 { this->bindElement(element); }
248
255 {
256 this->bindElement(element);
257 return std::move(*this);
258 }
259
264 {
265 element_ = element;
266 // cache element index
267 eIdx_ = gridDiscretization().elementMapper().index(element);
268 elementGeometry_.emplace(element.geometry());
269
270 // the local dofs are iterated many times per bind (every quadrature point of every face,
271 // every perturbation of a numerical derivative); look up the finite element and the dof
272 // indices once here instead of on every iteration
273 fe_ = &gridDiscretization().feCache().get(element.type());
274 const auto& localCoefficients = fe_->localCoefficients();
275 dofIndices_.clear();
276 for (std::size_t i = 0; i < localCoefficients.size(); ++i)
277 dofIndices_.push_back(dofIndex_(*this, localCoefficients.localKey(i)));
278 }
279
281 bool isBound() const
282 { return static_cast<bool>(element_); }
283
285 const Element& element() const
286 { return *element_; }
287
289 const typename Element::Geometry& elementGeometry() const
290 { return *elementGeometry_; }
291
294 { return ggCache_->gridGeometry(); }
295
297 bool hasBoundaryScvf() const
298 { return ggCache_->hasBoundaryScvf(eIdx_); }
299
301 bool hasBoundaryFaces() const
302 { return hasBoundaryScvf(); }
303
305 const BoundaryFace& boundaryFace(LocalIndexType bfIdx) const
306 { return ggCache_->boundaryFaces(eIdx_)[bfIdx]; }
307
309 std::size_t elementIndex() const
310 { return eIdx_; }
311
314 {
315 const auto localScvfIdx = scvf.index() - GeometryHelper::numInteriorScvf(element().type());
316 return ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx][0];
317 }
318
320 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
321 {
322 assert(isBound());
323 const auto& geo = elementGeometry();
324 const GeometryHelper helper(geo);
325 const auto scvIdx = this->feLocalCoefficients().localKey(scv.localDofIndex()).subEntity();
326 return {
327 helper.getScvGeometryType(scvIdx),
328 helper.getScvCorners(scvIdx)
329 };
330 }
331
333 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
334 {
335 assert(isBound());
336 if (scvf.boundary())
337 {
338 GeometryHelper helper(*elementGeometry_);
339 const auto localScvfIdx = scvf.index() - GeometryHelper::numInteriorScvf(element().type());
340 const auto [localFacetIndex, isScvfLocalIdx]
341 = ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx];
342 return {
343 helper.getBoundaryScvfGeometryType(isScvfLocalIdx),
344 helper.getBoundaryScvfCorners(localFacetIndex, isScvfLocalIdx)
345 };
346 }
347 else
348 {
349 GeometryHelper helper(*elementGeometry_);
350 return {
351 helper.getInteriorScvfGeometryType(scvf.index()),
352 helper.getScvfCorners(scvf.index())
353 };
354 }
355 }
356
358 typename BoundaryFace::Traits::Geometry geometry(const BoundaryFace& boundaryFace) const
359 {
360 assert(isBound());
361 const auto& elemGeo = elementGeometry();
362 const auto faceGeoInRef = referenceElement(elemGeo).template geometry<1>(boundaryFace.intersectionIndex());
363 typename BoundaryFace::Traits::CornerStorage corners;
364 for (int i = 0; i < faceGeoInRef.corners(); ++i)
365 corners.push_back(elemGeo.global(faceGeoInRef.corner(i)));
366 return { faceGeoInRef.type(), corners };
367 }
368
370 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const SubControlVolume& scv)
371 {
372 const auto type = fvGeometry.element().type();
373 const auto& localKey = fvGeometry.feLocalCoefficients().localKey(scv.localDofIndex());
374
375 return CVFE::LocalDofInterpolationPointData{ DofHelper::localDofPosition(type, localKey), scv.dofPosition(), scv.localDofIndex() };
376 }
377
379 template<class LocalDof>
380 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const LocalDof& localDof)
381 {
382 const auto type = fvGeometry.element().type();
383 const auto& localKey = fvGeometry.feLocalCoefficients().localKey(localDof.index());
384 const auto& localPos = DofHelper::localDofPosition(type, localKey);
385
386 return CVFE::LocalDofInterpolationPointData{ localPos, fvGeometry.elementGeometry().global(localPos), localDof.index() };
387 }
388
390 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const typename Element::Geometry::GlobalCoordinate& globalPos)
391 {
392 // Create ipData that does not automatically calculate the local position but only if it is called
394 [&] (const typename Element::Geometry::GlobalCoordinate& pos) { return fvGeometry.elementGeometry().local(pos); },
395 globalPos
396 };
397 }
398
400 friend inline auto ipData(const PQ2FVElementGeometry& fvGeometry, const SubControlVolumeFace& scvf)
401 {
403 { scvf.unitOuterNormal(), scvf.index(), fvGeometry.elementGeometry().local(scvf.ipGlobal()), scvf.ipGlobal() };
404 }
405
406private:
410 template<class LocalKey>
411 static GridIndexType dofIndex_(const PQ2FVElementGeometry& fvGeometry, const LocalKey& lk)
412 {
413 if constexpr (requires { fvGeometry.gridDiscretization().dofIndex(fvGeometry.element(), lk); })
414 return static_cast<GridIndexType>(fvGeometry.gridDiscretization().dofIndex(fvGeometry.element(), lk));
415 else
416 return static_cast<GridIndexType>(DofHelper::dofIndex(fvGeometry.gridDiscretization().dofMapper(), fvGeometry.element(), lk));
417 }
418
419 const GGCache* ggCache_;
420 GridIndexType eIdx_;
421
422 std::optional<Element> element_;
423 std::optional<typename Element::Geometry> elementGeometry_;
424 const FiniteElement* fe_ = nullptr;
425 Dune::ReservedVector<GridIndexType, maxNumElementDofs> dofIndices_;
426};
427
428} // end namespace Dumux
429
430#endif
An interpolation point related to a face of an element.
Definition cvfe/interpolationpointdata.hh:109
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
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition discretization/pq2/fvelementgeometry.hh:281
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const PQ2FVElementGeometry &fvGeometry, const BoundaryFace &boundaryFace)
Definition discretization/pq2/fvelementgeometry.hh:185
std::size_t intersectionIndex(const SubControlVolumeFace &scvf) const
The intersection index the scvf belongs to.
Definition discretization/pq2/fvelementgeometry.hh:313
const Element::Geometry & elementGeometry() const
The bound element geometry.
Definition discretization/pq2/fvelementgeometry.hh:289
typename GG::ScvfQuadratureRule ScvfQuadratureRule
the quadrature rule type for scvfs
Definition discretization/pq2/fvelementgeometry.hh:86
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const SubControlVolume &scv)
Interpolation point data for an scv.
Definition discretization/pq2/fvelementgeometry.hh:370
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const PQ2FVElementGeometry &fvGeometry)
Definition discretization/pq2/fvelementgeometry.hh:175
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const LocalDof &localDof)
Interpolation point data for a localDof.
Definition discretization/pq2/fvelementgeometry.hh:380
void bind(const Element &element) &
Definition discretization/pq2/fvelementgeometry.hh:246
BoundaryFace::Traits::Geometry geometry(const BoundaryFace &boundaryFace) const
Geometry of a boundary face.
Definition discretization/pq2/fvelementgeometry.hh:358
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Geometry of a sub control volume face.
Definition discretization/pq2/fvelementgeometry.hh:333
PQ2FVElementGeometry(const GGCache &ggCache)
Constructor.
Definition discretization/pq2/fvelementgeometry.hh:97
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const PQ2FVElementGeometry &fvGeometry)
Definition discretization/pq2/fvelementgeometry.hh:119
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf)
Interpolation point data for scvf.
Definition discretization/pq2/fvelementgeometry.hh:400
const auto & feLocalCoefficients() const
Get a local finite element basis.
Definition discretization/pq2/fvelementgeometry.hh:209
typename GG::SubControlVolumeFace SubControlVolumeFace
export type of subcontrol volume face
Definition discretization/pq2/fvelementgeometry.hh:78
friend auto nonCVLocalDofs(const PQ2FVElementGeometry &fvGeometry)
Definition discretization/pq2/fvelementgeometry.hh:139
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Geometry of a sub control volume.
Definition discretization/pq2/fvelementgeometry.hh:320
friend auto ipData(const PQ2FVElementGeometry &fvGeometry, const typename Element::Geometry::GlobalCoordinate &globalPos)
Interpolation point data for a global position.
Definition discretization/pq2/fvelementgeometry.hh:390
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:237
std::size_t numScv() const
The total number of sub control volumes.
Definition discretization/pq2/fvelementgeometry.hh:221
std::size_t numScvf() const
The total number of sub control volume faces.
Definition discretization/pq2/fvelementgeometry.hh:227
void bindElement(const Element &element) &
Definition discretization/pq2/fvelementgeometry.hh:263
static constexpr std::size_t maxNumElementDofs
the maximum number of scvs per element for hypercubes
Definition discretization/pq2/fvelementgeometry.hh:94
bool hasBoundaryScvf() const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition discretization/pq2/fvelementgeometry.hh:297
typename GG::ScvQuadratureRule ScvQuadratureRule
the quadrature rule type for scvs
Definition discretization/pq2/fvelementgeometry.hh:84
bool hasBoundaryFaces() const
Returns whether the element has boundary faces.
Definition discretization/pq2/fvelementgeometry.hh:301
std::size_t elementIndex() const
The bound element index.
Definition discretization/pq2/fvelementgeometry.hh:309
const SubControlVolumeFace & scvf(LocalIndexType scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition discretization/pq2/fvelementgeometry.hh:108
friend auto localDofs(const PQ2FVElementGeometry &fvGeometry)
Definition discretization/pq2/fvelementgeometry.hh:152
const BoundaryFace & boundaryFace(LocalIndexType bfIdx) const
Get a boundary face with a local boundary face index.
Definition discretization/pq2/fvelementgeometry.hh:305
friend auto cvLocalDofs(const PQ2FVElementGeometry &fvGeometry)
Definition discretization/pq2/fvelementgeometry.hh:126
typename GG::ElementQuadratureRule ElementQuadratureRule
the quadrature rule type for elements
Definition discretization/pq2/fvelementgeometry.hh:88
typename GG::IntersectionQuadratureRule IntersectionQuadratureRule
the quadrature rule type for intersections
Definition discretization/pq2/fvelementgeometry.hh:90
friend std::ranges::view auto boundaryFaces(const PQ2FVElementGeometry &fvGeometry)
Definition discretization/pq2/fvelementgeometry.hh:196
typename GG::BoundaryFace BoundaryFace
export the boundary face type
Definition discretization/pq2/fvelementgeometry.hh:82
const SubControlVolume & scv(LocalIndexType scvIdx) const
Get a sub control volume with a local scv index.
Definition discretization/pq2/fvelementgeometry.hh:102
std::size_t numLocalDofs() const
The total number of element-local dofs.
Definition discretization/pq2/fvelementgeometry.hh:215
typename GG::SubControlVolume SubControlVolume
export type of subcontrol volume
Definition discretization/pq2/fvelementgeometry.hh:76
typename GG::BoundaryFaceQuadratureRule BoundaryFaceQuadratureRule
the quadrature rule type for boundary faces
Definition discretization/pq2/fvelementgeometry.hh:92
GG GridGeometry
export type of finite volume grid geometry
Definition discretization/pq2/fvelementgeometry.hh:80
typename GridView::template Codim< 0 >::Entity Element
export the element type
Definition discretization/pq2/fvelementgeometry.hh:74
const GridGeometry & gridDiscretization() const
The grid discretization we are a restriction of.
Definition discretization/pq2/fvelementgeometry.hh:293
const Element & element() const
The bound element.
Definition discretization/pq2/fvelementgeometry.hh:285
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:254
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition discretization/pq2/fvelementgeometry.hh:203
Base class for the finite volume geometry vector for pq2 models This builds up the sub control volume...
Definition discretization/pq2/fvelementgeometry.hh:49
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.
decltype(auto) gridDiscretization(const T &t, Args &&... args)
The grid discretization.
Definition griddiscretization.hh:65
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