3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
29#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH
30#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH
31
32#include <optional>
33
34#include <dune/common/version.hh>
35#include <dune/geometry/type.hh>
36#include <dune/localfunctions/lagrange/pqkfactory.hh>
37
39#include "geometryhelper.hh"
40
41namespace Dumux {
42
52template<class GG, bool enableGridGeometryCache>
54
56template<class GG>
58{
59 using GridView = typename GG::GridView;
60 static constexpr int dim = GridView::dimension;
61 static constexpr int dimWorld = GridView::dimensionworld;
62 using GridIndexType = typename GridView::IndexSet::IndexType;
63 using Element = typename GridView::template Codim<0>::Entity;
64 using CoordScalar = typename GridView::ctype;
65 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
66public:
68 using SubControlVolume = typename GG::SubControlVolume;
70 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
72 using GridGeometry = GG;
73
76 static constexpr std::size_t maxNumElementScvs = (1<<dim)*3;
77
80 : gridGeometryPtr_(&gridGeometry) {}
81
83 const SubControlVolume& scv(std::size_t scvIdx) const
84 { return gridGeometry().scvs(eIdx_)[scvIdx]; }
85
87 const SubControlVolumeFace& scvf(std::size_t scvfIdx) const
88 { return gridGeometry().scvfs(eIdx_)[scvfIdx]; }
89
98 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
99 scvs(const BoxDfmFVElementGeometry& fvGeometry)
100 {
101 const auto& g = fvGeometry.gridGeometry();
102 using Iter = typename std::vector<SubControlVolume>::const_iterator;
103 return Dune::IteratorRange<Iter>(g.scvs(fvGeometry.eIdx_).begin(), g.scvs(fvGeometry.eIdx_).end());
104 }
105
114 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
116 {
117 const auto& g = fvGeometry.gridGeometry();
118 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
119 return Dune::IteratorRange<Iter>(g.scvfs(fvGeometry.eIdx_).begin(), g.scvfs(fvGeometry.eIdx_).end());
120 }
121
123 const FeLocalBasis& feLocalBasis() const
124 { return gridGeometry().feCache().get(element_->type()).localBasis(); }
125
127 std::size_t numScv() const
128 { return gridGeometry().scvs(eIdx_).size(); }
129
131 std::size_t numScvf() const
132 { return gridGeometry().scvfs(eIdx_).size(); }
133
136 void bind(const Element& element)
137 {
138 this->bindElement(element);
139 }
140
147 void bindElement(const Element& element)
148 {
149 element_ = element;
150 eIdx_ = gridGeometry().elementMapper().index(element);
151 }
152
155 { return *gridGeometryPtr_; }
156
158 bool isBound() const
159 { return static_cast<bool>(element_); }
160
162 const Element& element() const
163 { return *element_; }
164
165private:
166 const GridGeometry* gridGeometryPtr_;
167
168 std::optional<Element> element_;
169 GridIndexType eIdx_;
170};
171
173template<class GG>
175{
176 using GridView = typename GG::GridView;
177 static constexpr int dim = GridView::dimension;
178 static constexpr int dimWorld = GridView::dimensionworld;
179
180 using GridIndexType = typename GridView::IndexSet::IndexType;
181 using Element = typename GridView::template Codim<0>::Entity;
182
183 using CoordScalar = typename GridView::ctype;
184 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
185 using GeometryHelper = BoxDfmGeometryHelper<GridView, dim,
186 typename GG::SubControlVolume,
187 typename GG::SubControlVolumeFace>;
188public:
190 using SubControlVolume = typename GG::SubControlVolume;
192 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
194 using GridGeometry = GG;
197 static constexpr std::size_t maxNumElementScvs = (1<<dim)*3;
198
201 : gridGeometryPtr_(&gridGeometry) {}
202
204 const SubControlVolume& scv(std::size_t scvIdx) const
205 { return scvs_[scvIdx]; }
206
208 const SubControlVolumeFace& scvf(std::size_t scvfIdx) const
209 { return scvfs_[scvfIdx]; }
210
219 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
220 scvs(const BoxDfmFVElementGeometry& fvGeometry)
221 {
222 using Iter = typename std::vector<SubControlVolume>::const_iterator;
223 return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
224 }
225
234 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
236 {
237 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
238 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
239 }
240
242 const FeLocalBasis& feLocalBasis() const
243 { return gridGeometry().feCache().get(element_->type()).localBasis(); }
244
246 std::size_t numScv() const
247 { return scvs_.size(); }
248
250 std::size_t numScvf() const
251 { return scvfs_.size(); }
252
259 void bind(const Element& element)
260 {
261 this->bindElement(element);
262 }
263
268 void bindElement(const Element& element)
269 {
270 element_ = element;
271 eIdx_ = gridGeometry().elementMapper().index(element);
272 makeElementGeometries_();
273 }
274
277 { return *gridGeometryPtr_; }
278
280 bool isBound() const
281 { return static_cast<bool>(element_); }
282
284 const Element& element() const
285 { return *element_; }
286
287private:
288
289 void makeElementGeometries_()
290 {
291 // get the element geometry
292 const auto& element = *element_;
293 const auto elementGeometry = element.geometry();
294 const auto refElement = referenceElement(element);
295
296 // get the sub control volume geometries of this element
297 GeometryHelper geometryHelper(elementGeometry);
298
299 // construct the sub control volumes
300 scvs_.resize(elementGeometry.corners());
301 using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
302 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
303 {
304 // get asssociated dof index
305 const auto dofIdxGlobal = gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim);
306
307 // add scv to the local container
308 scvs_[scvLocalIdx] = SubControlVolume(geometryHelper,
309 scvLocalIdx,
310 eIdx_,
311 dofIdxGlobal);
312 }
313
314 // construct the sub control volume faces
315 const auto numInnerScvf = (dim==1) ? 1 : element.subEntities(dim-1);
316 scvfs_.resize(numInnerScvf);
317
318 unsigned int scvfLocalIdx = 0;
319 for (; scvfLocalIdx < numInnerScvf; ++scvfLocalIdx)
320 {
321 // find the local scv indices this scvf is connected to
322 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
323 static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
324
325 scvfs_[scvfLocalIdx] = SubControlVolumeFace(geometryHelper,
326 element,
327 elementGeometry,
328 scvfLocalIdx,
329 std::move(localScvIndices));
330 }
331
332 // construct the ...
333 // ... sub-control volume faces on the domain boundary
334 // ... sub-control volumes on fracture facets
335 // ... sub-control volume faces on fracture facets
336 // NOTE We do not construct fracture scvfs on boundaries here!
337 // That means specifying Neumann fluxes on only the fractures is not possible
338 // However, it is difficult to interpret this here as a fracture ending on the boundary
339 // could also be connected to a facet which is both boundary and fracture at the same time!
340 // In that case, the fracture boundary scvf wouldn't make sense. In order to do it properly
341 // we would have to find only those fractures that are at the boundary and aren't connected
342 // to a fracture which is a boundary.
343 LocalIndexType scvLocalIdx = element.subEntities(dim);
344 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
345 {
346 // first, obtain all vertex indices on this intersection
347 const auto& isGeometry = intersection.geometry();
348 const auto numCorners = isGeometry.corners();
349 const auto idxInInside = intersection.indexInInside();
350
351 std::vector<GridIndexType> isVertexIndices(numCorners);
352 for (unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
353 isVertexIndices[vIdxLocal] = gridGeometry().vertexMapper().subIndex(element,
354 refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
355 dim);
356
357 if (intersection.boundary())
358 {
359 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < numCorners; ++isScvfLocalIdx)
360 {
361 // find the scv this scvf is connected to
362 const LocalIndexType insideScvIdx = static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, isScvfLocalIdx, dim));
363 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
364
365 scvfs_.emplace_back(geometryHelper,
366 intersection,
367 isGeometry,
368 isScvfLocalIdx,
369 scvfLocalIdx,
370 std::move(localScvIndices));
371
372 // increment local counter
373 scvfLocalIdx++;
374 }
375 }
376
377 // maybe add fracture scvs & scvfs
378 if (this->gridGeometry().isOnFracture(element, intersection))
379 {
380 // add fracture scv for each vertex of intersection
381 const auto curNumScvs = scvs_.size();
382 scvs_.reserve(curNumScvs+numCorners);
383 for (unsigned int vIdxLocal = 0; vIdxLocal < numCorners; ++vIdxLocal)
384 scvs_.emplace_back(geometryHelper,
385 intersection,
386 isGeometry,
387 vIdxLocal,
388 static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, vIdxLocal, dim)),
389 scvLocalIdx++,
390 idxInInside,
391 eIdx_,
392 isVertexIndices[vIdxLocal]);
393
394 // add fracture scvf for each edge of the intersection in 3d
395 if (dim == 3)
396 {
397 const auto& faceRefElement = referenceElement(isGeometry);
398 for (unsigned int edgeIdx = 0; edgeIdx < faceRefElement.size(1); ++edgeIdx)
399 {
400 // inside/outside scv indices in face local node numbering
401 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(faceRefElement.subEntity(edgeIdx, 1, 0, dim-1)),
402 static_cast<LocalIndexType>(faceRefElement.subEntity(edgeIdx, 1, 1, dim-1))});
403
404 // add offset to get the right scv indices
405 std::for_each( localScvIndices.begin(),
406 localScvIndices.end(),
407 [curNumScvs] (auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
408
409 // add scvf
410 scvfs_.emplace_back(geometryHelper,
411 intersection,
412 isGeometry,
413 edgeIdx,
414 scvfLocalIdx++,
415 std::move(localScvIndices),
416 intersection.boundary());
417 }
418 }
419
420 // dim == 2, intersection is an edge, make 1 scvf
421 else
422 {
423 // inside/outside scv indices in face local node numbering
424 std::vector<LocalIndexType> localScvIndices({0, 1});
425
426 // add offset such that the fracture scvs above are addressed
427 std::for_each( localScvIndices.begin(),
428 localScvIndices.end(),
429 [curNumScvs] (auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
430
431 // add scvf
432 scvfs_.emplace_back(geometryHelper,
433 intersection,
434 isGeometry,
435 /*idxOnIntersection*/0,
436 scvfLocalIdx++,
437 std::move(localScvIndices),
438 intersection.boundary());
439 }
440 }
441 }
442 }
443
445 std::optional<Element> element_;
446 GridIndexType eIdx_;
447
449 const GridGeometry* gridGeometryPtr_;
450
452 std::vector<SubControlVolume> scvs_;
453 std::vector<SubControlVolumeFace> scvfs_;
454};
455
456} // end namespace Dumux
457
458#endif
Class providing iterators over sub control volumes and sub control volume faces of an element.
Helper class constructing the dual grid finite volume geometries for the box discrete fracture model.
Definition: adapt.hh:29
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:215
Base class for the finite volume geometry vector for box discrete fracture model.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:53
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:70
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:127
void bind(const Element &element)
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:136
void bindElement(const Element &element)
Binding of an element, has to be called before using the fvgeometries.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:147
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:87
GG GridGeometry
Export type of finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:72
const Element & element() const
The bound element.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:162
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:79
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:131
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:123
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:68
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:83
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:99
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:154
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:158
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:115
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:268
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:242
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:208
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:276
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:259
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:250
const Element & element() const
The bound element.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:284
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:200
std::size_t numScv() const
The total number of sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:246
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:280
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:204
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:220
GG GridGeometry
Export type of finite volume grid geometry.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:194
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:192
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:235
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition: porousmediumflow/boxdfm/fvelementgeometry.hh:190
Create sub control volumes and sub control volume face geometries.
Definition: geometryhelper.hh:35