26#ifndef DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH
27#define DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH
29#include <unordered_map>
31#include <dune/geometry/referenceelements.hh>
32#include <dune/localfunctions/lagrange/pqkfactory.hh>
52template<
class Gr
idView,
class MapperTraits = DefaultMapperTraits<Gr
idView>>
59 template<
class Gr
idGeometry,
bool enableCache>
71 bool enableGridGeometryCache =
false,
81template<
class Scalar,
class GV,
class Traits>
90 using Element =
typename GV::template Codim<0>::Entity;
91 using CoordScalar =
typename GV::ctype;
92 static const int dim = GV::dimension;
93 static const int dimWorld = GV::dimensionworld;
95 using ReferenceElements =
typename Dune::ReferenceElements<CoordScalar, dim>;
98 typename Traits::SubControlVolume,
99 typename Traits::SubControlVolumeFace>;
114 using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
124 DUNE_THROW(Dune::InvalidStateException,
"The box discretization method only works with zero overlap for parallel computations. "
125 <<
" Set the parameter \"Grid.Overlap\" in the input file.");
131 {
return this->vertexMapper(); }
144 {
return numBoundaryScvf_; }
148 {
return this->vertexMapper().size(); }
153 ParentType::update();
158 auto numElements = this->gridView().size(0);
159 scvs_.resize(numElements);
160 scvfs_.resize(numElements);
161 hasBoundaryScvf_.resize(numElements,
false);
163 boundaryDofIndices_.assign(numDofs(),
false);
167 numBoundaryScvf_ = 0;
169 for (
const auto& element : elements(this->gridView()))
172 auto eIdx = this->elementMapper().index(element);
175 numScv_ += element.subEntities(dim);
176 numScvf_ += element.subEntities(dim-1);
179 auto elementGeometry = element.geometry();
180 const auto referenceElement = ReferenceElements::general(elementGeometry.type());
186 scvs_[eIdx].resize(elementGeometry.corners());
187 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
189 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
198 LocalIndexType scvfLocalIdx = 0;
199 scvfs_[eIdx].resize(element.subEntities(dim-1));
200 for (; scvfLocalIdx < element.subEntities(dim-1); ++scvfLocalIdx)
203 std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(referenceElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
204 static_cast<LocalIndexType
>(referenceElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
210 std::move(localScvIndices),
215 for (
const auto& intersection :
intersections(this->gridView(), element))
217 if (intersection.boundary() && !intersection.neighbor())
219 const auto isGeometry = intersection.geometry();
220 hasBoundaryScvf_[eIdx] =
true;
223 numScvf_ += isGeometry.corners();
224 numBoundaryScvf_ += isGeometry.corners();
226 for (
unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < isGeometry.corners(); ++isScvfLocalIdx)
229 const LocalIndexType insideScvIdx =
static_cast<LocalIndexType
>(referenceElement.subEntity(intersection.indexInInside(), 1, isScvfLocalIdx, dim));
230 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
232 scvfs_[eIdx].emplace_back(geometryHelper,
237 std::move(localScvIndices),
246 const auto fIdx = intersection.indexInInside();
247 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
248 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
250 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
251 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
252 boundaryDofIndices_[vIdxGlobal] =
true;
257 else if (intersection.boundary() && intersection.neighbor())
262 const auto fIdx = intersection.indexInInside();
263 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
264 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
265 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
267 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
268 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
269 const auto vPos = elementGeometry.corner(vIdx);
271 const auto& outside = intersection.outside();
272 const auto outsideGeometry = outside.geometry();
273 for (
const auto& isOutside :
intersections(this->gridView(), outside))
276 if (isOutside.boundary() && isOutside.neighbor())
278 const auto fIdxOutside = isOutside.indexInInside();
279 const auto numFaceVertsOutside = referenceElement.size(fIdxOutside, 1, dim);
280 for (
int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
282 const auto vIdxOutside = referenceElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
283 const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
284 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
285 if (std::abs((vPosOutside-vPos).two_norm() - shift) <
eps)
286 periodicVertexMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim);
296 if (this->isPeriodic() && this->gridView().comm().size() > 1)
297 DUNE_THROW(Dune::NotImplemented,
"Periodic boundaries for box method for parallel simulations!");
305 const std::vector<SubControlVolume>&
scvs(GridIndexType eIdx)
const
306 {
return scvs_[eIdx]; }
309 const std::vector<SubControlVolumeFace>&
scvfs(GridIndexType eIdx)
const
310 {
return scvfs_[eIdx]; }
314 {
return boundaryDofIndices_[dofIdx]; }
318 {
return periodicVertexMap_.count(dofIdx); }
322 {
return periodicVertexMap_.at(dofIdx); }
326 {
return periodicVertexMap_; }
330 {
return hasBoundaryScvf_[eIdx]; }
334 const FeCache feCache_;
336 std::vector<std::vector<SubControlVolume>> scvs_;
337 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
340 std::size_t numScvf_;
341 std::size_t numBoundaryScvf_;
344 std::vector<bool> boundaryDofIndices_;
345 std::vector<bool> hasBoundaryScvf_;
348 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap_;
358template<
class Scalar,
class GV,
class Traits>
366 static const int dim = GV::dimension;
367 static const int dimWorld = GV::dimensionworld;
369 using Element =
typename GV::template Codim<0>::Entity;
370 using CoordScalar =
typename GV::ctype;
372 using ReferenceElements =
typename Dune::ReferenceElements<CoordScalar, dim>;
387 using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
397 DUNE_THROW(Dune::InvalidStateException,
"The box discretization method only works with zero overlap for parallel computations. "
398 <<
" Set the parameter \"Grid.Overlap\" in the input file.");
404 {
return this->vertexMapper(); }
417 {
return numBoundaryScvf_; }
421 {
return this->vertexMapper().size(); }
426 ParentType::update();
428 boundaryDofIndices_.assign(numDofs(),
false);
434 numBoundaryScvf_ = 0;
435 for (
const auto& element : elements(this->gridView()))
437 numScv_ += element.subEntities(dim);
438 numScvf_ += element.subEntities(dim-1);
440 const auto elementGeometry = element.geometry();
441 const auto referenceElement = ReferenceElements::general(elementGeometry.type());
444 for (
const auto& intersection :
intersections(this->gridView(), element))
446 if (intersection.boundary() && !intersection.neighbor())
448 const auto isGeometry = intersection.geometry();
449 numScvf_ += isGeometry.corners();
450 numBoundaryScvf_ += isGeometry.corners();
454 const auto fIdx = intersection.indexInInside();
455 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
456 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
458 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
459 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
460 boundaryDofIndices_[vIdxGlobal] =
true;
465 else if (intersection.boundary() && intersection.neighbor())
470 const auto fIdx = intersection.indexInInside();
471 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
472 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
473 for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
475 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
476 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
477 const auto vPos = elementGeometry.corner(vIdx);
479 const auto& outside = intersection.outside();
480 const auto outsideGeometry = outside.geometry();
481 for (
const auto& isOutside :
intersections(this->gridView(), outside))
484 if (isOutside.boundary() && isOutside.neighbor())
486 const auto fIdxOutside = isOutside.indexInInside();
487 const auto numFaceVertsOutside = referenceElement.size(fIdxOutside, 1, dim);
488 for (
int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
490 const auto vIdxOutside = referenceElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
491 const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
492 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
493 if (std::abs((vPosOutside-vPos).two_norm() - shift) <
eps)
494 periodicVertexMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim);
504 if (this->isPeriodic() && this->gridView().comm().size() > 1)
505 DUNE_THROW(Dune::NotImplemented,
"Periodic boundaries for box method for parallel simulations!");
514 {
return boundaryDofIndices_[dofIdx]; }
518 {
return periodicVertexMap_.count(dofIdx); }
522 {
return periodicVertexMap_.at(dofIdx); }
526 {
return periodicVertexMap_; }
530 const FeCache feCache_;
535 std::size_t numScvf_;
536 std::size_t numBoundaryScvf_;
539 std::vector<bool> boundaryDofIndices_;
542 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap_;
Defines the default element and vertex mapper types.
Defines the index types used for grid and local indices.
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
Base class for grid geometries.
Check the overlap size for different discretization methods.
The available discretization methods in Dumux.
DiscretizationMethod
The available discretization methods in Dumux.
Definition: method.hh:37
Dune::IteratorRange< typename MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper >::Intersections::const_iterator > intersections(const MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper > &glue)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: glue.hh:62
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
constexpr double eps
epsilon for checking direction of scvf normals
Definition: test_tpfafvgeometry_nonconforming.cc:44
Struture to define the index types used for grid and local indices.
Definition: indextraits.hh:38
Base class for all finite volume grid geometries.
Definition: basegridgeometry.hh:49
GV GridView
export the grid view type
Definition: basegridgeometry.hh:64
Create sub control volumes and sub control volume face geometries.
Definition: boxgeometryhelper.hh:37
Base class for the finite volume geometry vector for box models This builds up the sub control volume...
Definition: discretization/box/fvelementgeometry.hh:48
The default traits for the box finite volume grid geometry Defines the scv and scvf types and the map...
Definition: discretization/box/fvgridgeometry.hh:55
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: discretization/box/fvgridgeometry.hh:73
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: discretization/box/fvgridgeometry.hh:84
const std::vector< SubControlVolume > & scvs(GridIndexType eIdx) const
Get the local scvs for an element.
Definition: discretization/box/fvgridgeometry.hh:305
Dune::PQkLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition: discretization/box/fvgridgeometry.hh:114
const std::vector< SubControlVolumeFace > & scvfs(GridIndexType eIdx) const
Get the local scvfs for an element.
Definition: discretization/box/fvgridgeometry.hh:309
const std::unordered_map< GridIndexType, GridIndexType > & periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: discretization/box/fvgridgeometry.hh:325
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:321
bool hasBoundaryScvf(GridIndexType eIdx) const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition: discretization/box/fvgridgeometry.hh:329
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: discretization/box/fvgridgeometry.hh:147
std::size_t numScv() const
The total number of sub control volumes.
Definition: discretization/box/fvgridgeometry.hh:134
void update()
update all fvElementGeometries (do this again after grid adaption)
Definition: discretization/box/fvgridgeometry.hh:151
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: discretization/box/fvgridgeometry.hh:301
std::size_t numBoundaryScvf() const
Definition: discretization/box/fvgridgeometry.hh:143
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:110
const DofMapper & dofMapper() const
Definition: discretization/box/fvgridgeometry.hh:130
typename Traits::template LocalView< ThisType, true > LocalView
export the type of the fv element geometry (the local view type)
Definition: discretization/box/fvgridgeometry.hh:106
BoxFVGridGeometry(const GridView gridView)
Constructor.
Definition: discretization/box/fvgridgeometry.hh:119
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: discretization/box/fvgridgeometry.hh:313
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: discretization/box/fvgridgeometry.hh:138
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:317
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:108
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition: discretization/box/fvgridgeometry.hh:112
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: discretization/box/fvgridgeometry.hh:361
std::size_t numBoundaryScvf() const
Definition: discretization/box/fvgridgeometry.hh:416
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:517
typename Traits::template LocalView< ThisType, false > LocalView
export the type of the fv element geometry (the local view type)
Definition: discretization/box/fvgridgeometry.hh:379
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:383
void update()
update all fvElementGeometries (do this again after grid adaption)
Definition: discretization/box/fvgridgeometry.hh:424
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:381
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:521
Dune::PQkLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition: discretization/box/fvgridgeometry.hh:387
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: discretization/box/fvgridgeometry.hh:509
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: discretization/box/fvgridgeometry.hh:411
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition: discretization/box/fvgridgeometry.hh:385
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: discretization/box/fvgridgeometry.hh:513
BoxFVGridGeometry(const GridView gridView)
Constructor.
Definition: discretization/box/fvgridgeometry.hh:392
const DofMapper & dofMapper() const
Definition: discretization/box/fvgridgeometry.hh:403
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: discretization/box/fvgridgeometry.hh:420
const std::unordered_map< GridIndexType, GridIndexType > & periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: discretization/box/fvgridgeometry.hh:525
std::size_t numScv() const
The total number of sub control volumes.
Definition: discretization/box/fvgridgeometry.hh:407
the sub control volume for the box scheme
Definition: discretization/box/subcontrolvolume.hh:88
Class for a sub control volume face in the box method, i.e a part of the boundary of a sub control vo...
Definition: discretization/box/subcontrolvolumeface.hh:93
Check if the overlap size is valid for a given discretization method.
Definition: checkoverlapsize.hh:40
Base class for the local finite volume geometry for box models This builds up the sub control volumes...
the sub control volume for the box scheme
Base class for a sub control volume face.