17#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH
18#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH
23#include <dune/geometry/type.hh>
24#include <dune/localfunctions/lagrange/pqkfactory.hh>
40template<
class GG,
bool enableGr
idGeometryCache>
47 using GridView =
typename GG::GridView;
48 static constexpr int dim = GridView::dimension;
49 static constexpr int dimWorld = GridView::dimensionworld;
50 using GridIndexType =
typename GridView::IndexSet::IndexType;
51 using CoordScalar =
typename GridView::ctype;
52 using FeLocalBasis =
typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
55 using Element =
typename GridView::template Codim<0>::Entity;
65 static constexpr std::size_t maxNumElementScvs = (1<<dim)*3;
69 : gridGeometryPtr_(&gridGeometry) {}
73 {
return gridGeometry().scvs(eIdx_)[scvIdx]; }
77 {
return gridGeometry().scvfs(eIdx_)[scvfIdx]; }
87 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
90 const auto& g = fvGeometry.gridGeometry();
91 using Iter =
typename std::vector<SubControlVolume>::const_iterator;
92 return Dune::IteratorRange<Iter>(g.scvs(fvGeometry.eIdx_).begin(), g.scvs(fvGeometry.eIdx_).end());
103 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
106 const auto& g = fvGeometry.gridGeometry();
107 using Iter =
typename std::vector<SubControlVolumeFace>::const_iterator;
108 return Dune::IteratorRange<Iter>(g.scvfs(fvGeometry.eIdx_).begin(), g.scvfs(fvGeometry.eIdx_).end());
113 {
return gridGeometry().feCache().get(element_->type()).localBasis(); }
117 {
return gridGeometry().scvs(eIdx_).size(); }
121 {
return gridGeometry().scvfs(eIdx_).size(); }
130 this->bindElement(element);
131 return std::move(*
this);
137 { this->bindElement(element); }
146 this->bindElement(element);
147 return std::move(*
this);
159 eIdx_ = gridGeometry().elementMapper().index(element);
164 {
return *gridGeometryPtr_; }
168 {
return static_cast<bool>(element_); }
172 {
return *element_; }
177 if (scv.isOnFracture())
178 DUNE_THROW(Dune::InvalidStateException,
"The geometry object cannot be defined for fracture scvs "
179 "because the number of known corners is insufficient. "
180 "You can do this manually by extracting the corners from this scv "
181 "and extruding them by the corresponding aperture. ");
183 const typename GG::GeometryHelper geometryHelper(element().geometry());
184 const auto corners = geometryHelper.getScvCorners(scv.index());
185 using ScvGeometry =
typename SubControlVolume::Traits::Geometry;
186 return { Dune::GeometryTypes::cube(ScvGeometry::mydimension), corners };
192 if (scvf.isOnFracture())
193 DUNE_THROW(Dune::InvalidStateException,
"The geometry object cannot be defined for fracture scvs "
194 "because the number of known corners is insufficient. "
195 "You can do this manually by extracting the corners from this scv "
196 "and extruding them by the corresponding aperture. ");
197 const typename GG::GeometryHelper geometryHelper(element().geometry());
198 const auto corners = geometryHelper.getScvfCorners(scvf.indexInElement());
199 using ScvfGeometry =
typename SubControlVolumeFace::Traits::Geometry;
200 return { Dune::GeometryTypes::cube(ScvfGeometry::mydimension), corners };
204 const GridGeometry* gridGeometryPtr_;
206 std::optional<Element> element_;
214 using GridView =
typename GG::GridView;
215 static constexpr int dim = GridView::dimension;
216 static constexpr int dimWorld = GridView::dimensionworld;
218 using GridIndexType =
typename GridView::IndexSet::IndexType;
220 using CoordScalar =
typename GridView::ctype;
221 using FeLocalBasis =
typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
222 using GeometryHelper =
typename GG::GeometryHelper;
225 using Element =
typename GridView::template Codim<0>::Entity;
234 static constexpr std::size_t maxNumElementScvs = (1<<dim)*3;
238 : gridGeometryPtr_(&gridGeometry) {}
242 {
return scvs_[scvIdx]; }
246 {
return scvfs_[scvfIdx]; }
256 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
259 using Iter =
typename std::vector<SubControlVolume>::const_iterator;
260 return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
271 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
274 using Iter =
typename std::vector<SubControlVolumeFace>::const_iterator;
275 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
280 {
return gridGeometry().feCache().get(element_->type()).localBasis(); }
284 {
return scvs_.size(); }
288 {
return scvfs_.size(); }
297 this->bindElement(element);
298 return std::move(*
this);
308 { this->bindElement(element); }
317 this->bindElement(element);
318 return std::move(*
this);
328 eIdx_ = gridGeometry().elementMapper().index(element);
329 makeElementGeometries_();
334 {
return *gridGeometryPtr_; }
338 {
return static_cast<bool>(element_); }
342 {
return *element_; }
347 if (scv.isOnFracture())
348 DUNE_THROW(Dune::InvalidStateException,
"The geometry object cannot be defined for fracture scvs "
349 "because the number of known corners is insufficient. "
350 "You can do this manually by extracting the corners from this scv "
351 "and extruding them by the corresponding aperture. ");
353 const GeometryHelper geometryHelper(element().geometry());
354 const auto corners = geometryHelper.getScvCorners(scv.index());
355 using ScvGeometry =
typename SubControlVolume::Traits::Geometry;
356 return { Dune::GeometryTypes::cube(ScvGeometry::mydimension), corners };
362 if (scvf.isOnFracture())
363 DUNE_THROW(Dune::InvalidStateException,
"The geometry object cannot be defined for fracture scvs "
364 "because the number of known corners is insufficient. "
365 "You can do this manually by extracting the corners from this scv "
366 "and extruding them by the corresponding aperture. ");
367 const GeometryHelper geometryHelper(element().geometry());
368 const auto corners = geometryHelper.getScvfCorners(scvf.indexInElement());
369 using ScvfGeometry =
typename SubControlVolumeFace::Traits::Geometry;
370 return { Dune::GeometryTypes::cube(ScvfGeometry::mydimension), corners };
375 void makeElementGeometries_()
378 const auto& element = *element_;
379 const auto elementGeometry = element.geometry();
380 const auto refElement = referenceElement(element);
383 GeometryHelper geometryHelper(elementGeometry);
386 scvs_.resize(elementGeometry.corners());
387 using LocalIndexType =
typename SubControlVolumeFace::Traits::LocalIndexType;
388 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
391 const auto dofIdxGlobal = gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim);
394 scvs_[scvLocalIdx] = SubControlVolume(geometryHelper,
401 const auto numInnerScvf = (dim==1) ? 1 : element.subEntities(dim-1);
402 scvfs_.resize(numInnerScvf);
404 unsigned int scvfLocalIdx = 0;
405 for (; scvfLocalIdx < numInnerScvf; ++scvfLocalIdx)
408 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
409 static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
411 scvfs_[scvfLocalIdx] = SubControlVolumeFace(geometryHelper,
415 std::move(localScvIndices));
429 LocalIndexType scvLocalIdx =
element.subEntities(dim);
430 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
433 const auto& isGeometry = intersection.geometry();
435 const auto idxInInside = intersection.indexInInside();
437 std::vector<GridIndexType> isVertexIndices(
numCorners);
438 for (
unsigned int vIdxLocal = 0; vIdxLocal <
numCorners; ++vIdxLocal)
439 isVertexIndices[vIdxLocal] = gridGeometry().vertexMapper().subIndex(element,
440 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
443 if (intersection.boundary())
445 for (
unsigned int isScvfLocalIdx = 0; isScvfLocalIdx <
numCorners; ++isScvfLocalIdx)
448 const LocalIndexType insideScvIdx =
static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, isScvfLocalIdx, dim));
449 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
451 scvfs_.emplace_back(geometryHelper,
456 std::move(localScvIndices));
464 if (this->gridGeometry().isOnFracture(element, intersection))
467 const auto curNumScvs = scvs_.size();
469 for (
unsigned int vIdxLocal = 0; vIdxLocal <
numCorners; ++vIdxLocal)
470 scvs_.emplace_back(geometryHelper,
474 static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, vIdxLocal, dim)),
478 isVertexIndices[vIdxLocal]);
483 const auto& faceRefElement = referenceElement(isGeometry);
484 for (
unsigned int edgeIdx = 0; edgeIdx < faceRefElement.size(1); ++edgeIdx)
487 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 0, dim-1)),
488 static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 1, dim-1))});
491 std::for_each( localScvIndices.begin(),
492 localScvIndices.end(),
493 [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
496 scvfs_.emplace_back(geometryHelper,
501 std::move(localScvIndices),
502 intersection.boundary());
510 std::vector<LocalIndexType> localScvIndices({0, 1});
513 std::for_each( localScvIndices.begin(),
514 localScvIndices.end(),
515 [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
518 scvfs_.emplace_back(geometryHelper,
523 std::move(localScvIndices),
524 intersection.boundary());
531 std::optional<Element> element_;
535 const GridGeometry* gridGeometryPtr_;
538 std::vector<SubControlVolume> scvs_;
539 std::vector<SubControlVolumeFace> scvfs_;
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:345
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:279
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:245
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:333
BoxDfmFVElementGeometry 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: porousmediumflow/boxdfm/fvelementgeometry.hh:315
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:225
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:287
void bind(const Element &element) &
Binding of an element, has to be called before using the fvgeometries Prepares all the volume variabl...
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:307
BoxDfmFVElementGeometry 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: porousmediumflow/boxdfm/fvelementgeometry.hh:295
const Element & element() const
The bound element.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:341
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:360
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:237
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:283
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:337
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:241
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:257
GG GridGeometry
Export type of finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:231
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:229
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:272
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:227
void bindElement(const Element &element) &
Binding of an element, has to be called before using the fvgeometries Prepares all the volume variabl...
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:325
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:59
void bindElement(const Element &element) &
Binding of an element, has to be called before using the fvgeometries.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:156
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:116
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:76
GG GridGeometry
Export type of finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:61
const Element & element() const
The bound element.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:171
void bind(const Element &element) &
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:136
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:68
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:120
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:112
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:55
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:57
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:190
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:72
BoxDfmFVElementGeometry 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: porousmediumflow/boxdfm/fvelementgeometry.hh:128
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:88
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:163
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:167
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:175
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:104
BoxDfmFVElementGeometry 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: porousmediumflow/boxdfm/fvelementgeometry.hh:144
Base class for the finite volume geometry vector for box discrete fracture model.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:41
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:220
Helper class constructing the dual grid finite volume geometries for the box discrete fracture model.
Class providing iterators over sub control volumes and sub control volume faces of an element.