29#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_GRID_FVGEOMETRY_HH
30#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_GRID_FVGEOMETRY_HH
32#include <unordered_map>
34#include <dune/localfunctions/lagrange/pqkfactory.hh>
35#include <dune/geometry/multilineargeometry.hh>
36#include <dune/grid/common/mcmgmapper.hh>
59template<
class Gr
idView,
class MapperTraits = DefaultMapperTraits<Gr
idView>>
66 template<
class Gr
idGeometry,
bool enableCache>
70 using FacetMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
83 bool enableGridGeometryCache =
false,
97template<
class Scalar,
class GV,
class Traits>
103 using GridIndexType =
typename GV::IndexSet::IndexType;
105 using Element =
typename GV::template Codim<0>::Entity;
106 using CoordScalar =
typename GV::ctype;
107 static const int dim = GV::dimension;
108 static const int dimWorld = GV::dimensionworld;
109 static_assert(dim == 2 || dim == 3,
"The box-dfm GridGeometry is only implemented in 2 or 3 dimensions.");
112 typename Traits::SubControlVolume,
113 typename Traits::SubControlVolumeFace>;
130 using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
141 {
return this->vertexMapper(); }
154 {
return numBoundaryScvf_; }
158 {
return this->gridView().size(dim); }
161 template<
class FractureGr
idAdapter >
162 void update(
const FractureGridAdapter& fractureGridAdapter)
164 ParentType::update();
169 auto numElements = this->gridView().size(0);
170 scvs_.resize(numElements);
171 scvfs_.resize(numElements);
173 boundaryDofIndices_.assign(numDofs(),
false);
174 fractureDofIndices_.assign(this->gridView.size(dim),
false);
178 numBoundaryScvf_ = 0;
180 for (
const auto& element : elements(this->gridView()))
183 auto eIdx = this->elementMapper().index(element);
186 numScv_ += element.subEntities(dim);
187 numScvf_ += element.subEntities(dim-1);
190 auto elementGeometry = element.geometry();
191 const auto refElement = referenceElement(elementGeometry);
197 scvs_[eIdx].resize(elementGeometry.corners());
198 using LocalIndexType =
typename SubControlVolumeFace::Traits::LocalIndexType;
199 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
201 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
210 LocalIndexType scvfLocalIdx = 0;
211 scvfs_[eIdx].resize(element.subEntities(dim-1));
212 for (; scvfLocalIdx < element.subEntities(dim-1); ++scvfLocalIdx)
215 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
216 static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
222 std::move(localScvIndices));
236 LocalIndexType scvLocalIdx = element.subEntities(dim);
237 for (
const auto& intersection : intersections(this->gridView(), element))
240 const auto& isGeometry = intersection.geometry();
241 const auto numCorners = isGeometry.corners();
242 const auto idxInInside = intersection.indexInInside();
244 std::vector<GridIndexType> isVertexIndices(numCorners);
245 for (
unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
246 isVertexIndices[vIdxLocal] = this->vertexMapper().subIndex(element,
247 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
250 if (intersection.boundary() && !intersection.neighbor())
252 numScvf_ += isGeometry.corners();
253 numBoundaryScvf_ += isGeometry.corners();
255 for (
unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < numCorners; ++isScvfLocalIdx)
258 const LocalIndexType insideScvIdx =
static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, isScvfLocalIdx, dim));
259 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
260 scvfs_[eIdx].emplace_back(geometryHelper,
265 std::move(localScvIndices));
270 const auto numFaceVerts = refElement.size(idxInInside, 1, dim);
271 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
273 const auto vIdx = refElement.subEntity(idxInInside, 1, localVIdx, dim);
274 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
275 boundaryDofIndices_[vIdxGlobal] =
true;
279 else if (intersection.boundary() && intersection.neighbor())
280 DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme");
283 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
285 for (
auto vIdx : isVertexIndices)
286 fractureDofIndices_[vIdx] =
true;
289 numScv_ += numCorners;
290 const auto curNumScvs = scvs_[eIdx].size();
291 scvs_[eIdx].reserve(curNumScvs+numCorners);
292 for (
unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
293 scvs_[eIdx].emplace_back(geometryHelper,
297 static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, vIdxLocal, dim)),
301 isVertexIndices[vIdxLocal]);
306 const auto& faceRefElement = referenceElement(isGeometry);
307 for (
unsigned int edgeIdx = 0; edgeIdx < faceRefElement.size(1); ++edgeIdx)
310 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 0, dim-1)),
311 static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 1, dim-1))});
314 std::for_each( localScvIndices.begin(),
315 localScvIndices.end(),
316 [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
320 scvfs_[eIdx].emplace_back(geometryHelper,
325 std::move(localScvIndices),
326 intersection.boundary());
334 std::vector<LocalIndexType> localScvIndices({0, 1});
337 std::for_each( localScvIndices.begin(),
338 localScvIndices.end(),
339 [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
343 scvfs_[eIdx].emplace_back(geometryHelper,
348 std::move(localScvIndices),
349 intersection.boundary());
359 const std::vector<SubControlVolume>&
scvs(GridIndexType eIdx)
const {
return scvs_[eIdx]; }
361 const std::vector<SubControlVolumeFace>&
scvfs(GridIndexType eIdx)
const {
return scvfs_[eIdx]; }
363 bool dofOnBoundary(
unsigned int dofIdx)
const {
return boundaryDofIndices_[dofIdx]; }
365 bool dofOnFracture(
unsigned int dofIdx)
const {
return fractureDofIndices_[dofIdx]; }
371 { DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme"); }
375 {
return std::unordered_map<std::size_t, std::size_t>(); }
378 const FeCache feCache_;
380 std::vector<std::vector<SubControlVolume>> scvs_;
381 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
385 std::size_t numScvf_;
386 std::size_t numBoundaryScvf_;
389 std::vector<bool> boundaryDofIndices_;
390 std::vector<bool> fractureDofIndices_;
400template<
class Scalar,
class GV,
class Traits>
406 using GridIndexType =
typename GV::IndexSet::IndexType;
408 static const int dim = GV::dimension;
409 static const int dimWorld = GV::dimensionworld;
411 using Element =
typename GV::template Codim<0>::Entity;
412 using Intersection =
typename GV::Intersection;
413 using CoordScalar =
typename GV::ctype;
430 using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
437 , facetMapper_(gridView,
Dune::mcmgLayout(
Dune::template Codim<1>()))
443 {
return this->vertexMapper(); }
456 {
return numBoundaryScvf_; }
460 {
return this->gridView().size(dim); }
463 template<
class FractureGr
idAdapter >
464 void update(
const FractureGridAdapter& fractureGridAdapter)
466 ParentType::update();
468 boundaryDofIndices_.assign(numDofs(),
false);
469 fractureDofIndices_.assign(numDofs(),
false);
470 facetOnFracture_.assign(this->gridView().size(1),
false);
476 numBoundaryScvf_ = 0;
477 for (
const auto& element : elements(this->gridView()))
479 numScv_ += element.subEntities(dim);
480 numScvf_ += element.subEntities(dim-1);
482 const auto elementGeometry = element.geometry();
483 const auto refElement = referenceElement(elementGeometry);
486 for (
const auto& intersection : intersections(this->gridView(), element))
489 const auto& isGeometry = intersection.geometry();
490 const auto numCorners = isGeometry.corners();
491 const auto idxInInside = intersection.indexInInside();
493 std::vector<GridIndexType> isVertexIndices(numCorners);
494 for (
unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
495 isVertexIndices[vIdxLocal] = this->vertexMapper().subIndex(element,
496 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
499 if (intersection.boundary() && !intersection.neighbor())
501 numScvf_ += numCorners;
502 numBoundaryScvf_ += numCorners;
506 const auto fIdx = intersection.indexInInside();
507 const auto numFaceVerts = refElement.size(fIdx, 1, dim);
508 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
510 const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
511 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
512 boundaryDofIndices_[vIdxGlobal] =
true;
517 else if (intersection.boundary() && intersection.neighbor())
518 DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme");
521 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
523 facetOnFracture_[facetMapper_.subIndex(element, idxInInside, 1)] =
true;
524 for (
auto vIdx : isVertexIndices)
525 fractureDofIndices_[vIdx] =
true;
527 const auto isGeometry = intersection.geometry();
528 numScv_ += isGeometry.corners();
529 numScvf_ += dim == 3 ? referenceElement(isGeometry).size(1) : 1;
538 bool dofOnBoundary(
unsigned int dofIdx)
const {
return boundaryDofIndices_[dofIdx]; }
540 bool dofOnFracture(
unsigned int dofIdx)
const {
return fractureDofIndices_[dofIdx]; }
545 bool isOnFracture(
const Element& element,
const Intersection& intersection)
const
546 {
return facetOnFracture_[facetMapper_.subIndex(element, intersection.indexInInside(), 1)]; }
550 { DUNE_THROW(Dune::InvalidStateException,
"Periodic boundaries are not supported by the box-dfm scheme"); }
554 {
return std::unordered_map<std::size_t, std::size_t>(); }
558 const FeCache feCache_;
563 std::size_t numScvf_;
564 std::size_t numBoundaryScvf_;
567 std::vector<bool> boundaryDofIndices_;
568 std::vector<bool> fractureDofIndices_;
571 typename Traits::FacetMapper facetMapper_;
572 std::vector<bool> facetOnFracture_;
Defines the default element and vertex mapper types.
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
The available discretization methods in Dumux.
Base class for grid geometries.
Helper classes to compute the integration elements.
Helper class constructing the dual grid finite volume geometries for the box discrete fracture model.
DiscretizationMethod
The available discretization methods in Dumux.
Definition: method.hh:37
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:177
Definition: common/pdesolver.hh:35
Base class for all finite volume grid geometries.
Definition: basegridgeometry.hh:49
GV GridView
export the grid view type
Definition: basegridgeometry.hh:64
Base class for the finite volume geometry vector for box discrete fracture model.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:51
The default traits for the box finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:62
Dune::MultipleCodimMultipleGeomTypeMapper< GridView > FacetMapper
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:70
Base class for the finite volume geometry vector for box schemes.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:85
Base class for the finite volume geometry vector for box schemes that consider extra connectivity bet...
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:100
typename Traits::SubControlVolume SubControlVolume
Export the type of sub control volume.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:122
std::unordered_map< std::size_t, std::size_t > periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:374
const std::vector< SubControlVolumeFace > & scvfs(GridIndexType eIdx) const
Get the local scvfs for an element.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:361
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:157
typename Traits::VertexMapper DofMapper
Export dof mapper type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:128
BoxDfmFVGridGeometry(const GridView gridView)
Constructor.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:135
Dune::PQkLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
Export the finite element cache type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:130
const std::vector< SubControlVolume > & scvs(GridIndexType eIdx) const
Get the local scvs for an element.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:359
Extrusion_t< Traits > Extrusion
Export the extrusion type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:126
typename Traits::template LocalView< ThisType, true > LocalView
Export the type of the fv element geometry (the local view type)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:120
const DofMapper & dofMapper() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:140
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:148
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:144
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:370
std::size_t numBoundaryScvf() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:153
bool dofOnBoundary(unsigned int dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:363
void update(const FractureGridAdapter &fractureGridAdapter)
Update all fvElementGeometries (do this again after grid adaption)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:162
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:357
typename Traits::SubControlVolumeFace SubControlVolumeFace
Export the type of sub control volume.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:124
bool dofOnPeriodicBoundary(std::size_t dofIdx) const
Periodic boundaries are not supported for the box-dfm scheme.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:367
bool dofOnFracture(unsigned int dofIdx) const
If a vertex / d.o.f. is on a fracture.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:365
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:403
Extrusion_t< Traits > Extrusion
Export the extrusion type.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:426
bool dofOnBoundary(unsigned int dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:538
bool dofOnPeriodicBoundary(std::size_t dofIdx) const
Periodic boundaries are not supported for the box-dfm scheme.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:542
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:446
bool isOnFracture(const Element &element, const Intersection &intersection) const
Returns true if an intersection coincides with a fracture element.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:545
std::unordered_map< std::size_t, std::size_t > periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:553
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:459
BoxDfmFVGridGeometry(const GridView gridView)
Constructor.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:435
std::size_t numBoundaryScvf() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:455
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:428
typename Traits::template LocalView< ThisType, false > LocalView
export the type of the fv element geometry (the local view type)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:420
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:450
Dune::PQkLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:430
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:536
const DofMapper & dofMapper() const
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:442
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:424
void update(const FractureGridAdapter &fractureGridAdapter)
update all fvElementGeometries (do this again after grid adaption)
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:464
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:422
bool dofOnFracture(unsigned int dofIdx) const
If a vertex / d.o.f. is on a fracture.
Definition: porousmediumflow/boxdfm/fvgridgeometry.hh:540
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:549
Create sub control volumes and sub control volume face geometries.
Definition: geometryhelper.hh:35
the sub control volume for the box discrete fracture scheme
Definition: porousmediumflow/boxdfm/subcontrolvolume.hh:95
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:99
Base class for the local finite volume geometry 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.