version 3.8
porousmediumflow/boxdfm/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//
17#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH
18#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH
19
20#include <optional>
21#include <utility>
22
23#include <dune/geometry/type.hh>
24#include <dune/localfunctions/lagrange/pqkfactory.hh>
25
27#include "geometryhelper.hh"
28
29namespace Dumux {
30
40template<class GG, bool enableGridGeometryCache>
42
44template<class GG>
46{
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;
53public:
55 using Element = typename GridView::template Codim<0>::Entity;
57 using SubControlVolume = typename GG::SubControlVolume;
59 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
61 using GridGeometry = GG;
62
65 static constexpr std::size_t maxNumElementScvs = (1<<dim)*3;
66
69 : gridGeometryPtr_(&gridGeometry) {}
70
72 const SubControlVolume& scv(std::size_t scvIdx) const
73 { return gridGeometry().scvs(eIdx_)[scvIdx]; }
74
76 const SubControlVolumeFace& scvf(std::size_t scvfIdx) const
77 { return gridGeometry().scvfs(eIdx_)[scvfIdx]; }
78
87 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
88 scvs(const BoxDfmFVElementGeometry& fvGeometry)
89 {
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());
93 }
94
103 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
105 {
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());
109 }
110
112 const FeLocalBasis& feLocalBasis() const
113 { return gridGeometry().feCache().get(element_->type()).localBasis(); }
114
116 std::size_t numScv() const
117 { return gridGeometry().scvs(eIdx_).size(); }
118
120 std::size_t numScvf() const
121 { return gridGeometry().scvfs(eIdx_).size(); }
122
129 {
130 this->bindElement(element);
131 return std::move(*this);
132 }
133
136 void bind(const Element& element) &
137 { this->bindElement(element); }
138
145 {
146 this->bindElement(element);
147 return std::move(*this);
148 }
149
156 void bindElement(const Element& element) &
157 {
158 element_ = element;
159 eIdx_ = gridGeometry().elementMapper().index(element);
160 }
161
164 { return *gridGeometryPtr_; }
165
167 bool isBound() const
168 { return static_cast<bool>(element_); }
169
171 const Element& element() const
172 { return *element_; }
173
174 // suppress warnings due to current implementation
175 // these interfaces should be used!
176 #pragma GCC diagnostic push
177 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
178
180 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
181 { return scv.geometry(); }
182
184 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
185 { return scvf.geometry(); }
186
187 #pragma GCC diagnostic pop
188
189private:
190 const GridGeometry* gridGeometryPtr_;
191
192 std::optional<Element> element_;
193 GridIndexType eIdx_;
194};
195
197template<class GG>
199{
200 using GridView = typename GG::GridView;
201 static constexpr int dim = GridView::dimension;
202 static constexpr int dimWorld = GridView::dimensionworld;
203
204 using GridIndexType = typename GridView::IndexSet::IndexType;
205
206 using CoordScalar = typename GridView::ctype;
207 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
208 using GeometryHelper = typename GG::GeometryHelper;
209public:
211 using Element = typename GridView::template Codim<0>::Entity;
213 using SubControlVolume = typename GG::SubControlVolume;
215 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
217 using GridGeometry = GG;
220 static constexpr std::size_t maxNumElementScvs = (1<<dim)*3;
221
224 : gridGeometryPtr_(&gridGeometry) {}
225
227 const SubControlVolume& scv(std::size_t scvIdx) const
228 { return scvs_[scvIdx]; }
229
231 const SubControlVolumeFace& scvf(std::size_t scvfIdx) const
232 { return scvfs_[scvfIdx]; }
233
242 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
243 scvs(const BoxDfmFVElementGeometry& fvGeometry)
244 {
245 using Iter = typename std::vector<SubControlVolume>::const_iterator;
246 return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
247 }
248
257 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
259 {
260 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
261 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
262 }
263
265 const FeLocalBasis& feLocalBasis() const
266 { return gridGeometry().feCache().get(element_->type()).localBasis(); }
267
269 std::size_t numScv() const
270 { return scvs_.size(); }
271
273 std::size_t numScvf() const
274 { return scvfs_.size(); }
275
282 {
283 this->bindElement(element);
284 return std::move(*this);
285 }
286
293 void bind(const Element& element) &
294 { this->bindElement(element); }
295
302 {
303 this->bindElement(element);
304 return std::move(*this);
305 }
306
311 void bindElement(const Element& element) &
312 {
313 element_ = element;
314 eIdx_ = gridGeometry().elementMapper().index(element);
315 makeElementGeometries_();
316 }
317
320 { return *gridGeometryPtr_; }
321
323 bool isBound() const
324 { return static_cast<bool>(element_); }
325
327 const Element& element() const
328 { return *element_; }
329
330 // suppress warnings due to current implementation
331 // these interfaces should be used!
332 #pragma GCC diagnostic push
333 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
334
336 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
337 { return scv.geometry(); }
338
340 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
341 { return scvf.geometry(); }
342
343 #pragma GCC diagnostic pop
344
345private:
346
347 void makeElementGeometries_()
348 {
349 // get the element geometry
350 const auto& element = *element_;
351 const auto elementGeometry = element.geometry();
352 const auto refElement = referenceElement(element);
353
354 // get the sub control volume geometries of this element
355 GeometryHelper geometryHelper(elementGeometry);
356
357 // construct the sub control volumes
358 scvs_.resize(elementGeometry.corners());
359 using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
360 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
361 {
362 // get associated dof index
363 const auto dofIdxGlobal = gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim);
364
365 // add scv to the local container
366 scvs_[scvLocalIdx] = SubControlVolume(geometryHelper,
367 scvLocalIdx,
368 eIdx_,
369 dofIdxGlobal);
370 }
371
372 // construct the sub control volume faces
373 const auto numInnerScvf = (dim==1) ? 1 : element.subEntities(dim-1);
374 scvfs_.resize(numInnerScvf);
375
376 unsigned int scvfLocalIdx = 0;
377 for (; scvfLocalIdx < numInnerScvf; ++scvfLocalIdx)
378 {
379 // find the local scv indices this scvf is connected to
380 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
381 static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
382
383 scvfs_[scvfLocalIdx] = SubControlVolumeFace(geometryHelper,
384 element,
385 elementGeometry,
386 scvfLocalIdx,
387 std::move(localScvIndices));
388 }
389
390 // construct the ...
391 // ... sub-control volume faces on the domain boundary
392 // ... sub-control volumes on fracture facets
393 // ... sub-control volume faces on fracture facets
394 // NOTE We do not construct fracture scvfs on boundaries here!
395 // That means specifying Neumann fluxes on only the fractures is not possible
396 // However, it is difficult to interpret this here as a fracture ending on the boundary
397 // could also be connected to a facet which is both boundary and fracture at the same time!
398 // In that case, the fracture boundary scvf wouldn't make sense. In order to do it properly
399 // we would have to find only those fractures that are at the boundary and aren't connected
400 // to a fracture which is a boundary.
401 LocalIndexType scvLocalIdx = element.subEntities(dim);
402 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
403 {
404 // first, obtain all vertex indices on this intersection
405 const auto& isGeometry = intersection.geometry();
406 const auto numCorners = isGeometry.corners();
407 const auto idxInInside = intersection.indexInInside();
408
409 std::vector<GridIndexType> isVertexIndices(numCorners);
410 for (unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
411 isVertexIndices[vIdxLocal] = gridGeometry().vertexMapper().subIndex(element,
412 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
413 dim);
414
415 if (intersection.boundary())
416 {
417 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < numCorners; ++isScvfLocalIdx)
418 {
419 // find the scv this scvf is connected to
420 const LocalIndexType insideScvIdx = static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, isScvfLocalIdx, dim));
421 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
422
423 scvfs_.emplace_back(geometryHelper,
424 intersection,
425 isGeometry,
426 isScvfLocalIdx,
427 scvfLocalIdx,
428 std::move(localScvIndices));
429
430 // increment local counter
431 scvfLocalIdx++;
432 }
433 }
434
435 // maybe add fracture scvs & scvfs
436 if (this->gridGeometry().isOnFracture(element, intersection))
437 {
438 // add fracture scv for each vertex of intersection
439 const auto curNumScvs = scvs_.size();
440 scvs_.reserve(curNumScvs+numCorners);
441 for (unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
442 scvs_.emplace_back(geometryHelper,
443 intersection,
444 isGeometry,
445 vIdxLocal,
446 static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, vIdxLocal, dim)),
447 scvLocalIdx++,
448 idxInInside,
449 eIdx_,
450 isVertexIndices[vIdxLocal]);
451
452 // add fracture scvf for each edge of the intersection in 3d
453 if (dim == 3)
454 {
455 const auto& faceRefElement = referenceElement(isGeometry);
456 for (unsigned int edgeIdx = 0; edgeIdx < faceRefElement.size(1); ++edgeIdx)
457 {
458 // inside/outside scv indices in face local node numbering
459 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(faceRefElement.subEntity(edgeIdx, 1, 0, dim-1)),
460 static_cast<LocalIndexType>(faceRefElement.subEntity(edgeIdx, 1, 1, dim-1))});
461
462 // add offset to get the right scv indices
463 std::for_each( localScvIndices.begin(),
464 localScvIndices.end(),
465 [curNumScvs] (auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
466
467 // add scvf
468 scvfs_.emplace_back(geometryHelper,
469 intersection,
470 isGeometry,
471 edgeIdx,
472 scvfLocalIdx++,
473 std::move(localScvIndices),
474 intersection.boundary());
475 }
476 }
477
478 // dim == 2, intersection is an edge, make 1 scvf
479 else
480 {
481 // inside/outside scv indices in face local node numbering
482 std::vector<LocalIndexType> localScvIndices({0, 1});
483
484 // add offset such that the fracture scvs above are addressed
485 std::for_each( localScvIndices.begin(),
486 localScvIndices.end(),
487 [curNumScvs] (auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
488
489 // add scvf
490 scvfs_.emplace_back(geometryHelper,
491 intersection,
492 isGeometry,
493 /*idxOnIntersection*/0,
494 scvfLocalIdx++,
495 std::move(localScvIndices),
496 intersection.boundary());
497 }
498 }
499 }
500 }
501
503 std::optional<Element> element_;
504 GridIndexType eIdx_;
505
507 const GridGeometry* gridGeometryPtr_;
508
510 std::vector<SubControlVolume> scvs_;
511 std::vector<SubControlVolumeFace> scvfs_;
512};
513
514} // end namespace Dumux
515
516#endif
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:336
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:265
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:231
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:319
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:301
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:211
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:273
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:293
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:281
const Element & element() const
The bound element.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:327
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:340
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:223
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:269
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:323
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:227
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:243
GG GridGeometry
Export type of finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:217
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:215
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:258
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:213
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:311
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:184
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:180
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
Definition: adapt.hh:17
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.