17#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_GRID_FVGEOMETRY_HH
18#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_GRID_FVGEOMETRY_HH
21#include <unordered_map>
23#include <dune/localfunctions/lagrange/lagrangelfecache.hh>
24#include <dune/geometry/multilineargeometry.hh>
25#include <dune/grid/common/mcmgmapper.hh>
41template<
class GV,
class T>
57template<
class Gr
idView,
class MapperTraits = DefaultMapperTraits<Gr
idView>>
64 template<
class Gr
idGeometry,
bool enableCache>
68 using FacetMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
81 bool enableGridGeometryCache =
false,
95template<
class Scalar,
class GV,
class Traits>
101 using GridIndexType =
typename GV::IndexSet::IndexType;
103 using Element =
typename GV::template Codim<0>::Entity;
104 using CoordScalar =
typename GV::ctype;
105 static const int dim = GV::dimension;
106 static const int dimWorld = GV::dimensionworld;
107 static_assert(dim == 2 || dim == 3,
"The box-dfm GridGeometry is only implemented in 2 or 3 dimensions.");
125 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
132 template<
class FractureGr
idAdapter >
136 update_(fractureGridAdapter);
142 {
return this->vertexMapper(); }
155 {
return numBoundaryScvf_; }
159 {
return this->gridView().size(dim); }
162 template<
class FractureGr
idAdapter >
163 void update(
const GridView& gridView,
const FractureGridAdapter& fractureGridAdapter)
165 ParentType::update(gridView);
166 update_(fractureGridAdapter);
170 template<
class FractureGr
idAdapter >
173 ParentType::update(std::move(gridView));
174 update_(fractureGridAdapter);
180 const std::vector<SubControlVolume>&
scvs(GridIndexType eIdx)
const {
return scvs_[eIdx]; }
182 const std::vector<SubControlVolumeFace>&
scvfs(GridIndexType eIdx)
const {
return scvfs_[eIdx]; }
184 bool dofOnBoundary(
unsigned int dofIdx)
const {
return boundaryDofIndices_[dofIdx]; }
186 bool dofOnFracture(
unsigned int dofIdx)
const {
return fractureDofIndices_[dofIdx]; }
192 { DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme"); }
196 {
return std::unordered_map<std::size_t, std::size_t>(); }
200 template<
class FractureGr
idAdapter >
201 void update_(
const FractureGridAdapter& fractureGridAdapter)
206 auto numElements = this->gridView().size(0);
207 scvs_.resize(numElements);
208 scvfs_.resize(numElements);
210 boundaryDofIndices_.assign(numDofs(),
false);
211 fractureDofIndices_.assign(this->gridView.size(dim),
false);
215 numBoundaryScvf_ = 0;
217 for (
const auto& element : elements(this->gridView()))
220 auto eIdx = this->elementMapper().index(element);
223 numScv_ += element.subEntities(dim);
224 numScvf_ += element.subEntities(dim-1);
227 auto elementGeometry = element.geometry();
228 const auto refElement = referenceElement(elementGeometry);
231 GeometryHelper geometryHelper(elementGeometry);
234 scvs_[eIdx].resize(elementGeometry.corners());
235 using LocalIndexType =
typename SubControlVolumeFace::Traits::LocalIndexType;
236 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
238 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
240 scvs_[eIdx][scvLocalIdx] = SubControlVolume(geometryHelper,
247 LocalIndexType scvfLocalIdx = 0;
248 scvfs_[eIdx].resize(element.subEntities(dim-1));
249 for (; scvfLocalIdx < element.subEntities(dim-1); ++scvfLocalIdx)
252 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
253 static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
255 scvfs_[eIdx][scvfLocalIdx] = SubControlVolumeFace(geometryHelper,
259 std::move(localScvIndices));
273 LocalIndexType scvLocalIdx =
element.subEntities(dim);
274 for (
const auto& intersection : intersections(this->gridView(), element))
277 const auto& isGeometry = intersection.geometry();
279 const auto idxInInside = intersection.indexInInside();
281 std::vector<GridIndexType> isVertexIndices(
numCorners);
282 for (
unsigned int vIdxLocal = 0; vIdxLocal <
numCorners; ++vIdxLocal)
283 isVertexIndices[vIdxLocal] = this->vertexMapper().subIndex(element,
284 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
287 if (intersection.boundary() && !intersection.neighbor())
289 numScvf_ += isGeometry.corners();
290 numBoundaryScvf_ += isGeometry.corners();
292 for (
unsigned int isScvfLocalIdx = 0; isScvfLocalIdx <
numCorners; ++isScvfLocalIdx)
295 const LocalIndexType insideScvIdx =
static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, isScvfLocalIdx, dim));
296 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
297 scvfs_[eIdx].emplace_back(geometryHelper,
302 std::move(localScvIndices));
307 const auto numFaceVerts = refElement.size(idxInInside, 1, dim);
308 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
310 const auto vIdx = refElement.subEntity(idxInInside, 1, localVIdx, dim);
311 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
312 boundaryDofIndices_[vIdxGlobal] =
true;
316 else if (intersection.boundary() && intersection.neighbor())
317 DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme");
320 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
322 for (
auto vIdx : isVertexIndices)
323 fractureDofIndices_[vIdx] =
true;
327 const auto curNumScvs = scvs_[eIdx].size();
329 for (
unsigned int vIdxLocal = 0; vIdxLocal <
numCorners; ++vIdxLocal)
330 scvs_[eIdx].emplace_back(geometryHelper,
334 static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, vIdxLocal, dim)),
338 isVertexIndices[vIdxLocal]);
343 const auto& faceRefElement = referenceElement(isGeometry);
344 for (
unsigned int edgeIdx = 0; edgeIdx < faceRefElement.size(1); ++edgeIdx)
347 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 0, dim-1)),
348 static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 1, dim-1))});
351 std::for_each( localScvIndices.begin(),
352 localScvIndices.end(),
353 [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
357 scvfs_[eIdx].emplace_back(geometryHelper,
362 std::move(localScvIndices),
363 intersection.boundary());
371 std::vector<LocalIndexType> localScvIndices({0, 1});
374 std::for_each( localScvIndices.begin(),
375 localScvIndices.end(),
376 [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
380 scvfs_[eIdx].emplace_back(geometryHelper,
385 std::move(localScvIndices),
386 intersection.boundary());
393 const FeCache feCache_;
395 std::vector<std::vector<SubControlVolume>> scvs_;
396 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
400 std::size_t numScvf_;
401 std::size_t numBoundaryScvf_;
404 std::vector<bool> boundaryDofIndices_;
405 std::vector<bool> fractureDofIndices_;
415template<
class Scalar,
class GV,
class Traits>
421 using GridIndexType =
typename GV::IndexSet::IndexType;
423 static const int dim = GV::dimension;
424 static const int dimWorld = GV::dimensionworld;
426 using Element =
typename GV::template Codim<0>::Entity;
427 using Intersection =
typename GV::Intersection;
428 using CoordScalar =
typename GV::ctype;
446 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
453 template<
class FractureGr
idAdapter >
456 , facetMapper_(gridView,
Dune::mcmgLayout(
Dune::template Codim<1>()))
458 update_(fractureGridAdapter);
464 {
return this->vertexMapper(); }
477 {
return numBoundaryScvf_; }
481 {
return this->gridView().size(dim); }
484 template<
class FractureGr
idAdapter >
485 void update(
const GridView& gridView,
const FractureGridAdapter& fractureGridAdapter)
487 ParentType::update(gridView);
488 updateFacetMapper_();
489 update_(fractureGridAdapter);
493 template<
class FractureGr
idAdapter >
496 ParentType::update(std::move(gridView));
497 updateFacetMapper_();
498 update_(fractureGridAdapter);
504 bool dofOnBoundary(
unsigned int dofIdx)
const {
return boundaryDofIndices_[dofIdx]; }
506 bool dofOnFracture(
unsigned int dofIdx)
const {
return fractureDofIndices_[dofIdx]; }
511 bool isOnFracture(
const Element& element,
const Intersection& intersection)
const
512 {
return facetOnFracture_[facetMapper_.subIndex(element, intersection.indexInInside(), 1)]; }
516 { DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme"); }
520 {
return std::unordered_map<std::size_t, std::size_t>(); }
524 void updateFacetMapper_()
526 facetMapper_.update(this->gridView());
529 template<
class FractureGr
idAdapter >
530 void update_(
const FractureGridAdapter& fractureGridAdapter)
532 boundaryDofIndices_.assign(numDofs(),
false);
533 fractureDofIndices_.assign(numDofs(),
false);
534 facetOnFracture_.assign(this->gridView().size(1),
false);
540 numBoundaryScvf_ = 0;
541 for (
const auto& element : elements(this->gridView()))
543 numScv_ += element.subEntities(dim);
544 numScvf_ += element.subEntities(dim-1);
546 const auto elementGeometry = element.geometry();
547 const auto refElement = referenceElement(elementGeometry);
550 for (
const auto& intersection : intersections(this->gridView(), element))
553 const auto& isGeometry = intersection.geometry();
555 const auto idxInInside = intersection.indexInInside();
557 std::vector<GridIndexType> isVertexIndices(
numCorners);
558 for (
unsigned int vIdxLocal = 0; vIdxLocal <
numCorners; ++vIdxLocal)
559 isVertexIndices[vIdxLocal] = this->vertexMapper().subIndex(element,
560 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
563 if (intersection.boundary() && !intersection.neighbor())
570 const auto fIdx = intersection.indexInInside();
571 const auto numFaceVerts = refElement.size(fIdx, 1, dim);
572 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
574 const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
575 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
576 boundaryDofIndices_[vIdxGlobal] =
true;
581 else if (intersection.boundary() && intersection.neighbor())
582 DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme");
585 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
587 facetOnFracture_[facetMapper_.subIndex(element, idxInInside, 1)] =
true;
588 for (
auto vIdx : isVertexIndices)
589 fractureDofIndices_[vIdx] =
true;
591 const auto isGeometry = intersection.geometry();
592 numScv_ += isGeometry.corners();
593 numScvf_ += dim == 3 ? referenceElement(isGeometry).size(1) : 1;
599 const FeCache feCache_;
604 std::size_t numScvf_;
605 std::size_t numBoundaryScvf_;
608 std::vector<bool> boundaryDofIndices_;
609 std::vector<bool> fractureDofIndices_;
612 typename Traits::FacetMapper facetMapper_;
613 std::vector<bool> facetOnFracture_;
Base class for grid geometries.
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
Base class for all grid geometries.
Definition: basegridgeometry.hh:52
typename BaseImplementation::GridView GridView
export the grid view type
Definition: basegridgeometry.hh:60
Base class for the finite volume geometry vector for box discrete fracture model.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:41
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:418
Extrusion_t< Traits > Extrusion
Export the extrusion type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:442
bool dofOnBoundary(unsigned int dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:504
bool dofOnPeriodicBoundary(std::size_t dofIdx) const
Periodic boundaries are not supported for the box-dfm scheme.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:508
BoxDfmFVGridGeometry(const GridView gridView, const FractureGridAdapter &fractureGridAdapter)
Constructor.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:454
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:467
bool isOnFracture(const Element &element, const Intersection &intersection) const
Returns true if an intersection coincides with a fracture element.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:511
std::unordered_map< std::size_t, std::size_t > periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:519
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:480
std::size_t numBoundaryScvf() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:476
void update(const GridView &gridView, const FractureGridAdapter &fractureGridAdapter)
update all fvElementGeometries (call this after grid adaption)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:485
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:444
typename Traits::template LocalView< ThisType, false > LocalView
export the type of the fv element geometry (the local view type)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:436
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:471
Dune::LagrangeLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:446
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:502
const DofMapper & dofMapper() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:463
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:440
Detail::BoxDfmGeometryHelper_t< GV, Traits > GeometryHelper
export the geometry helper type
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:450
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:438
bool dofOnFracture(unsigned int dofIdx) const
If a vertex / d.o.f. is on a fracture.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:506
void update(GridView &&gridView, const FractureGridAdapter &fractureGridAdapter)
update all fvElementGeometries (call this after grid adaption)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:494
std::size_t periodicallyMappedDof(std::size_t dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:515
Base class for the finite volume geometry vector for box schemes that consider extra connectivity bet...
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:98
typename Traits::SubControlVolume SubControlVolume
Export the type of sub control volume.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:117
Dune::LagrangeLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
Export the finite element cache type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:125
std::unordered_map< std::size_t, std::size_t > periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:195
Detail::BoxDfmGeometryHelper_t< GV, Traits > GeometryHelper
export the geometry helper type
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:129
const std::vector< SubControlVolumeFace > & scvfs(GridIndexType eIdx) const
Get the local scvfs for an element.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:182
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:158
typename Traits::VertexMapper DofMapper
Export dof mapper type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:123
BoxDfmFVGridGeometry(const GridView gridView, const FractureGridAdapter &fractureGridAdapter)
Constructor.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:133
void update(GridView &&gridView, const FractureGridAdapter &fractureGridAdapter)
update all fvElementGeometries (call this after grid adaption)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:171
const std::vector< SubControlVolume > & scvs(GridIndexType eIdx) const
Get the local scvs for an element.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:180
Extrusion_t< Traits > Extrusion
Export the extrusion type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:121
typename Traits::template LocalView< ThisType, true > LocalView
Export the type of the fv element geometry (the local view type)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:115
const DofMapper & dofMapper() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:141
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:149
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:145
std::size_t periodicallyMappedDof(std::size_t dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:191
std::size_t numBoundaryScvf() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:154
bool dofOnBoundary(unsigned int dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:184
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:178
void update(const GridView &gridView, const FractureGridAdapter &fractureGridAdapter)
update all fvElementGeometries (call this after grid adaption)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:163
typename Traits::SubControlVolumeFace SubControlVolumeFace
Export the type of sub control volume.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:119
bool dofOnPeriodicBoundary(std::size_t dofIdx) const
Periodic boundaries are not supported for the box-dfm scheme.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:188
bool dofOnFracture(unsigned int dofIdx) const
If a vertex / d.o.f. is on a fracture.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:186
Base class for the finite volume geometry vector for box schemes.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:83
Create sub control volumes and sub control volume face geometries.
Definition: porousmediumflow/boxdfm/geometryhelper.hh:47
Class for a sub control volume face in the box discrete fracture method, i.e a part of the boundary o...
Definition: porousmediumflow/boxdfm/subcontrolvolumeface.hh:65
the sub control volume for the box discrete fracture scheme
Definition: porousmediumflow/boxdfm/subcontrolvolume.hh:64
Defines the default element and vertex mapper types.
Helper classes to compute the integration elements.
The available discretization methods in Dumux.
Dune::Std::detected_or_t< Dumux::BoxDfmGeometryHelper< GV, GV::dimension, typename T::SubControlVolume, typename T::SubControlVolumeFace >, SpecifiesGeometryHelper, T > BoxDfmGeometryHelper_t
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:46
typename T::GeometryHelper SpecifiesGeometryHelper
Definition: basegridgeometry.hh:30
CVFE< CVFEMethods::PQ1 > Box
Definition: method.hh:94
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:220
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:166
Definition: common/pdesolver.hh:24
Base class for the local finite volume geometry for the box discrete fracture model.
Helper class constructing the dual grid finite volume geometries for the box discrete fracture model.
the sub control volume for the box discrete fracture scheme
The sub control volume face class for the box discrete fracture model.
The default traits for the box finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:60
Dune::MultipleCodimMultipleGeomTypeMapper< GridView > FacetMapper
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:68