version 3.9
multidomain/facet/box/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-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_FACETCOUPLING_BOX_FV_ELEMENT_GEOMETRY_HH
13#define DUMUX_FACETCOUPLING_BOX_FV_ELEMENT_GEOMETRY_HH
14
15#include <algorithm>
16#include <optional>
17
18#include <dune/geometry/type.hh>
19
23
24namespace Dumux {
25
35template<class GG, bool enableGridGeometryCache>
37
39template<class GG>
41{
42 using GridView = typename GG::GridView;
43 static constexpr int dim = GridView::dimension;
44 static constexpr int dimWorld = GridView::dimensionworld;
45 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
46 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
47 using CoordScalar = typename GridView::ctype;
48 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
49
50 using GeometryHelper = typename GG::GeometryHelper;
51public:
53 using Element = typename GridView::template Codim<0>::Entity;
55 using SubControlVolume = typename GG::SubControlVolume;
57 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
59 using GridGeometry = GG;
61 static constexpr std::size_t maxNumElementScvs = (1<<dim);
62
65 : gridGeometryPtr_(&gridGeometry)
66 {}
67
69 const SubControlVolume& scv(LocalIndexType scvIdx) const
70 { return gridGeometry().scvs(eIdx_)[scvIdx]; }
71
73 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
74 { return gridGeometry().scvfs(eIdx_)[scvfIdx]; }
75
81 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
83 {
84 const auto& g = fvGeometry.gridGeometry();
85 using Iter = typename std::vector<SubControlVolume>::const_iterator;
86 return Dune::IteratorRange<Iter>(g.scvs(fvGeometry.eIdx_).begin(), g.scvs(fvGeometry.eIdx_).end());
87 }
88
94 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
96 {
97 const auto& g = fvGeometry.gridGeometry();
98 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
99 return Dune::IteratorRange<Iter>(g.scvfs(fvGeometry.eIdx_).begin(), g.scvfs(fvGeometry.eIdx_).end());
100 }
101
103 const FeLocalBasis& feLocalBasis() const
104 { return gridGeometry().feCache().get(element_->type()).localBasis(); }
105
107 std::size_t numScv() const
108 { return gridGeometry().scvs(eIdx_).size(); }
109
111 std::size_t numScvf() const
112 { return gridGeometry().scvfs(eIdx_).size(); }
113
120 {
121 this->bindElement(element);
122 return std::move(*this);
123 }
124
128 void bind(const Element& element) &
129 { this->bindElement(element); }
130
137 {
138 this->bindElement(element);
139 return std::move(*this);
140 }
141
145 void bindElement(const Element& element) &
146 {
147 element_ = element;
148 eIdx_ = gridGeometry().elementMapper().index(element);
149 }
150
153 { return *gridGeometryPtr_; }
154
156 bool isBound() const
157 { return static_cast<bool>(element_); }
158
160 const Element& element() const
161 { return *element_; }
162
164 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
165 {
166 assert(isBound());
167 const auto geo = element().geometry();
168 return { Dune::GeometryTypes::cube(dim), GeometryHelper(geo).getScvCorners(scv.indexInElement()) };
169 }
170
172 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
173 {
174 assert(isBound());
175 using ScvfGeometry = typename SubControlVolumeFace::Traits::Geometry;
176 const GeometryHelper geometryHelper(element().geometry());
177 if (scvf.boundary() || scvf.interiorBoundary())
178 return {
179 Dune::GeometryTypes::cube(ScvfGeometry::mydimension),
180 geometryHelper.getBoundaryScvfCorners(
181 scvf.facetIndexInElement(),
182 scvf.indexInElementFacet()
183 )
184 };
185
186 return {
187 Dune::GeometryTypes::cube(ScvfGeometry::mydimension),
188 geometryHelper.getScvfCorners(scvf.index())
189 };
190 }
191
192private:
193 const GridGeometry* gridGeometryPtr_;
194
195 GridIndexType eIdx_;
196 std::optional<Element> element_;
197};
198
200template<class GG>
202{
203 using GridView = typename GG::GridView;
204 static constexpr int dim = GridView::dimension;
205 static constexpr int dimWorld = GridView::dimensionworld;
206
207 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
208 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
209
210 using CoordScalar = typename GridView::ctype;
211 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
212
213 using GeometryHelper = typename GG::GeometryHelper;
214public:
216 using Element = typename GridView::template Codim<0>::Entity;
218 using SubControlVolume = typename GG::SubControlVolume;
220 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
222 using GridGeometry = GG;
224 static constexpr std::size_t maxNumElementScvs = (1<<dim);
225
228 : gridGeometryPtr_(&gridGeometry)
229 {}
230
232 const SubControlVolume& scv(LocalIndexType scvIdx) const
233 { return scvs_[scvIdx]; }
234
236 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
237 { return scvfs_[scvfIdx]; }
238
244 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
246 {
247 using Iter = typename std::vector<SubControlVolume>::const_iterator;
248 return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
249 }
250
256 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
258 {
259 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
260 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
261 }
262
264 const FeLocalBasis& feLocalBasis() const
265 { return gridGeometry().feCache().get(element_->type()).localBasis(); }
266
268 std::size_t numScv() const
269 { return scvs_.size(); }
270
272 std::size_t numScvf() const
273 { return scvfs_.size(); }
274
281 {
282 this->bindElement(element);
283 return std::move(*this);
284 }
285
289 void bind(const Element& element) &
290 { this->bindElement(element); }
291
298 {
299 this->bindElement(element);
300 return std::move(*this);
301 }
302
306 void bindElement(const Element& element) &
307 {
308 element_ = element;
309 eIdx_ = gridGeometry().elementMapper().index(element);
310 makeElementGeometries_();
311 }
312
315 { return *gridGeometryPtr_; }
316
318 bool isBound() const
319 { return static_cast<bool>(element_); }
320
322 const Element& element() const
323 { return *element_; }
324
326 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
327 {
328 assert(isBound());
329 const auto geo = element().geometry();
330 return { Dune::GeometryTypes::cube(dim), GeometryHelper(geo).getScvCorners(scv.indexInElement()) };
331 }
332
334 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
335 {
336 assert(isBound());
337 using ScvfGeometry = typename SubControlVolumeFace::Traits::Geometry;
338 GeometryHelper geometryHelper(element().geometry());
339
340 if (scvf.boundary() || scvf.interiorBoundary())
341 return {
342 Dune::GeometryTypes::cube(ScvfGeometry::mydimension),
343 geometryHelper.getBoundaryScvfCorners(
344 scvf.facetIndexInElement(),
345 scvf.indexInElementFacet()
346 )
347 };
348
349 return {
350 Dune::GeometryTypes::cube(ScvfGeometry::mydimension),
351 geometryHelper.getScvfCorners(scvf.index())
352 };
353 }
354
355private:
356
357 void makeElementGeometries_()
358 {
359 // get the element geometry
360 const auto& element = *element_;
361 const auto elementGeometry = element.geometry();
362 const auto refElement = referenceElement(elementGeometry);
363
364 // get the sub control volume geometries of this element
365 GeometryHelper geometryHelper(elementGeometry);
366
367 // construct the sub control volumes
368 scvs_.clear();
369 scvs_.reserve(elementGeometry.corners());
370 using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
371 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
372 scvs_.emplace_back(geometryHelper.getScvCorners(scvLocalIdx),
373 scvLocalIdx,
374 eIdx_,
375 gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim));
376
377 // construct the sub control volume faces
378 const auto numInnerScvf = (dim==1) ? 1 : element.subEntities(dim-1);
379 scvfs_.clear();
380 scvfs_.reserve(numInnerScvf);
381
382 unsigned int scvfLocalIdx = 0;
383 for (; scvfLocalIdx < numInnerScvf; ++scvfLocalIdx)
384 {
385 // find the local scv indices this scvf is connected to
386 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
387 static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
388
389 // create the sub-control volume face
390 scvfs_.emplace_back(geometryHelper,
391 element,
392 elementGeometry,
393 scvfLocalIdx,
394 std::move(localScvIndices));
395 }
396
397 // construct the sub control volume faces on the domain/interior boundaries
398 // skip handled facets (necessary for e.g. Dune::FoamGrid)
399 std::vector<unsigned int> handledFacets;
400 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
401 {
402 if (std::count(handledFacets.begin(), handledFacets.end(), intersection.indexInInside()))
403 continue;
404
405 handledFacets.push_back(intersection.indexInInside());
406
407 // determine if all corners live on the facet grid
408 const auto isGeometry = intersection.geometry();
409 const auto numFaceCorners = isGeometry.corners();
410 const auto idxInInside = intersection.indexInInside();
411 const auto boundary = intersection.boundary();
412
413 std::vector<LocalIndexType> vIndicesLocal(numFaceCorners);
414 for (int i = 0; i < numFaceCorners; ++i)
415 vIndicesLocal[i] = static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, i, dim));
416
417 // if all vertices are living on the facet grid, this is an interiour boundary
418 const bool isOnFacet = gridGeometry().isOnInteriorBoundary(element, intersection);
419
420 if (isOnFacet || boundary)
421 {
422 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < isGeometry.corners(); ++isScvfLocalIdx)
423 {
424 // find the inside scv this scvf is belonging to (localIdx = element local vertex index)
425 std::vector<LocalIndexType> localScvIndices = {vIndicesLocal[isScvfLocalIdx], vIndicesLocal[isScvfLocalIdx]};
426
427 // create the sub-control volume face
428 scvfs_.emplace_back(geometryHelper,
429 intersection,
430 isGeometry,
431 isScvfLocalIdx,
432 scvfLocalIdx,
433 std::move(localScvIndices),
434 boundary,
435 isOnFacet);
436
437 // increment local counter
438 scvfLocalIdx++;
439 }
440 }
441 }
442 }
443
445 const GridGeometry* gridGeometryPtr_;
446
448 GridIndexType eIdx_;
449 std::optional<Element> element_;
450
452 std::vector<SubControlVolume> scvs_;
453 std::vector<SubControlVolumeFace> scvfs_;
454};
455
456} // end namespace Dumux
457
458#endif
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
void bindElement(const Element &element) &
Definition: multidomain/facet/box/fvelementgeometry.hh:306
BoxFacetCouplingFVElementGeometry 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: multidomain/facet/box/fvelementgeometry.hh:297
BoxFacetCouplingFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: multidomain/facet/box/fvelementgeometry.hh:227
const SubControlVolume & scv(LocalIndexType scvIdx) const
Get a sub control volume with a local scv index.
Definition: multidomain/facet/box/fvelementgeometry.hh:232
typename GG::SubControlVolumeFace SubControlVolumeFace
export type of subcontrol volume face
Definition: multidomain/facet/box/fvelementgeometry.hh:220
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: multidomain/facet/box/fvelementgeometry.hh:264
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: multidomain/facet/box/fvelementgeometry.hh:334
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const BoxFacetCouplingFVElementGeometry &fvGeometry)
Definition: multidomain/facet/box/fvelementgeometry.hh:257
void bind(const Element &element) &
Definition: multidomain/facet/box/fvelementgeometry.hh:289
std::size_t numScv() const
The total number of sub control volumes.
Definition: multidomain/facet/box/fvelementgeometry.hh:268
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: multidomain/facet/box/fvelementgeometry.hh:318
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: multidomain/facet/box/fvelementgeometry.hh:272
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxFacetCouplingFVElementGeometry &fvGeometry)
Definition: multidomain/facet/box/fvelementgeometry.hh:245
typename GG::SubControlVolume SubControlVolume
export type of subcontrol volume
Definition: multidomain/facet/box/fvelementgeometry.hh:218
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: multidomain/facet/box/fvelementgeometry.hh:216
GG GridGeometry
export type of finite volume grid geometry
Definition: multidomain/facet/box/fvelementgeometry.hh:222
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: multidomain/facet/box/fvelementgeometry.hh:314
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: multidomain/facet/box/fvelementgeometry.hh:326
const Element & element() const
The bound element.
Definition: multidomain/facet/box/fvelementgeometry.hh:322
BoxFacetCouplingFVElementGeometry 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: multidomain/facet/box/fvelementgeometry.hh:280
const SubControlVolumeFace & scvf(LocalIndexType scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: multidomain/facet/box/fvelementgeometry.hh:236
void bindElement(const Element &element) &
Definition: multidomain/facet/box/fvelementgeometry.hh:145
GG GridGeometry
export type of finite volume grid geometry
Definition: multidomain/facet/box/fvelementgeometry.hh:59
BoxFacetCouplingFVElementGeometry 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: multidomain/facet/box/fvelementgeometry.hh:119
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: multidomain/facet/box/fvelementgeometry.hh:172
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: multidomain/facet/box/fvelementgeometry.hh:156
void bind(const Element &element) &
Definition: multidomain/facet/box/fvelementgeometry.hh:128
std::size_t numScv() const
The total number of sub control volumes.
Definition: multidomain/facet/box/fvelementgeometry.hh:107
const SubControlVolume & scv(LocalIndexType scvIdx) const
Get a sub control volume with a local scv index.
Definition: multidomain/facet/box/fvelementgeometry.hh:69
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const BoxFacetCouplingFVElementGeometry &fvGeometry)
Definition: multidomain/facet/box/fvelementgeometry.hh:95
const SubControlVolumeFace & scvf(LocalIndexType scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: multidomain/facet/box/fvelementgeometry.hh:73
typename GG::SubControlVolume SubControlVolume
export type of subcontrol volume
Definition: multidomain/facet/box/fvelementgeometry.hh:55
BoxFacetCouplingFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: multidomain/facet/box/fvelementgeometry.hh:64
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: multidomain/facet/box/fvelementgeometry.hh:152
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxFacetCouplingFVElementGeometry &fvGeometry)
Definition: multidomain/facet/box/fvelementgeometry.hh:82
typename GG::SubControlVolumeFace SubControlVolumeFace
export type of subcontrol volume face
Definition: multidomain/facet/box/fvelementgeometry.hh:57
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: multidomain/facet/box/fvelementgeometry.hh:164
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: multidomain/facet/box/fvelementgeometry.hh:111
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: multidomain/facet/box/fvelementgeometry.hh:103
const Element & element() const
The bound element.
Definition: multidomain/facet/box/fvelementgeometry.hh:160
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: multidomain/facet/box/fvelementgeometry.hh:53
BoxFacetCouplingFVElementGeometry 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: multidomain/facet/box/fvelementgeometry.hh:136
Base class for the element-local finite volume geometry for box models in the context of models consi...
Definition: multidomain/facet/box/fvelementgeometry.hh:36
Defines the index types used for grid and local indices.
Definition: adapt.hh:17
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