3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
Loading...
Searching...
No Matches
discretization/pq1bubble/fvgridgeometry.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 *****************************************************************************/
26#ifndef DUMUX_DISCRETIZATION_PQ1BUBBLE_GRID_GEOMETRY_HH
27#define DUMUX_DISCRETIZATION_PQ1BUBBLE_GRID_GEOMETRY_HH
28
29#include <utility>
30#include <unordered_map>
31
32#include <dune/grid/common/mcmgmapper.hh>
33
35
38
41
49
50namespace Dumux {
51
52template <class GridView>
54{
55 using DofMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
56
61 static Dune::MCMGLayout layout()
62 {
63 return [](Dune::GeometryType gt, int dimgrid) {
64 return (gt.dim() == dimgrid) || (gt.dim() == 0);
65 };
66 }
67};
68
75template<class GridView, class MapperTraits = PQ1BubbleMapperTraits<GridView>>
85
92template<class Scalar,
93 class GV,
94 bool enableCaching = true,
97: public BaseGridGeometry<GV, Traits>
98{
100 using ParentType = BaseGridGeometry<GV, Traits>;
101 using GridIndexType = typename IndexTraits<GV>::GridIndex;
102 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
103
104 using Element = typename GV::template Codim<0>::Entity;
105 using CoordScalar = typename GV::ctype;
106 static const int dim = GV::dimension;
107 static const int dimWorld = GV::dimensionworld;
108
109 using GeometryHelper = PQ1BubbleGeometryHelper<
110 GV, typename Traits::SubControlVolume, typename Traits::SubControlVolumeFace
111 >;
112
113 static_assert(dim > 1, "Only implemented for dim > 1");
114
115public:
119
121 using LocalView = typename Traits::template LocalView<ThisType, true>;
123 using SubControlVolume = typename Traits::SubControlVolume;
125 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
129 using DofMapper = typename Traits::DofMapper;
133 using GridView = GV;
134
137 : ParentType(gridView)
138 , dofMapper_(gridView, Traits::layout())
139 , cache_(*this)
140 {
141 update_();
142 }
143
145 const DofMapper& dofMapper() const
146 { return dofMapper_; }
147
149 std::size_t numScv() const
150 { return numScv_; }
151
153 std::size_t numScvf() const
154 { return numScvf_; }
155
157 std::size_t numBoundaryScvf() const
158 { return numBoundaryScvf_; }
159
161 std::size_t numDofs() const
162 { return this->dofMapper().size(); }
163
166 {
168 update_();
169 }
170
173 {
174 ParentType::update(std::move(gridView));
175 update_();
176 }
177
179 const FeCache& feCache() const
180 { return feCache_; }
181
183 bool dofOnBoundary(GridIndexType dofIdx) const
184 { return boundaryDofIndices_[dofIdx]; }
185
187 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
188 { return periodicVertexMap_.count(dofIdx); }
189
191 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
192 { return periodicVertexMap_.at(dofIdx); }
193
195 const std::unordered_map<GridIndexType, GridIndexType>& periodicVertexMap() const
196 { return periodicVertexMap_; }
197
200 { return { gg.cache_ }; }
201
202private:
203
204 class PQ1BubbleGridGeometryCache
205 {
206 friend class PQ1BubbleFVGridGeometry;
207 public:
208 explicit PQ1BubbleGridGeometryCache(const PQ1BubbleFVGridGeometry& gg)
209 : gridGeometry_(&gg)
210 {}
211
212 const PQ1BubbleFVGridGeometry& gridGeometry() const
213 { return *gridGeometry_; }
214
216 const std::vector<SubControlVolume>& scvs(GridIndexType eIdx) const
217 { return scvs_[eIdx]; }
218
220 const std::vector<SubControlVolumeFace>& scvfs(GridIndexType eIdx) const
221 { return scvfs_[eIdx]; }
222
224 bool hasBoundaryScvf(GridIndexType eIdx) const
225 { return hasBoundaryScvf_[eIdx]; }
226
228 const std::vector<std::array<LocalIndexType, 2>>& scvfBoundaryGeometryKeys(GridIndexType eIdx) const
229 { return scvfBoundaryGeometryKeys_.at(eIdx); }
230
231 private:
232 void clear_()
233 {
234 scvs_.clear();
235 scvfs_.clear();
236 hasBoundaryScvf_.clear();
237 scvfBoundaryGeometryKeys_.clear();
238 }
239
240 std::vector<std::vector<SubControlVolume>> scvs_;
241 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
242 std::vector<bool> hasBoundaryScvf_;
243 std::unordered_map<GridIndexType, std::vector<std::array<LocalIndexType, 2>>> scvfBoundaryGeometryKeys_;
244
245 const PQ1BubbleFVGridGeometry* gridGeometry_;
246 };
247
248public:
251 using Cache = PQ1BubbleGridGeometryCache;
252
253private:
254 void update_()
255 {
256 cache_.clear_();
257 dofMapper_.update(this->gridView());
258
259 auto numElements = this->gridView().size(0);
260 cache_.scvs_.resize(numElements);
261 cache_.scvfs_.resize(numElements);
262 cache_.hasBoundaryScvf_.resize(numElements, false);
263
264 boundaryDofIndices_.assign(numDofs(), false);
265
266 numScv_ = 0;
267 numScvf_ = 0;
268 numBoundaryScvf_ = 0;
269
270 // Build the scvs and scv faces
271 for (const auto& element : elements(this->gridView()))
272 {
273 auto eIdx = this->elementMapper().index(element);
274
275 // get the element geometry
276 auto elementGeometry = element.geometry();
277 const auto refElement = referenceElement(elementGeometry);
278
279 // instantiate the geometry helper
280 GeometryHelper geometryHelper(elementGeometry);
281
282 numScv_ += geometryHelper.numScv();
283 // construct the sub control volumes
284 cache_.scvs_[eIdx].resize(geometryHelper.numScv());
285 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < geometryHelper.numScv(); ++scvLocalIdx)
286 {
287 auto corners = geometryHelper.getScvCorners(scvLocalIdx);
288 cache_.scvs_[eIdx][scvLocalIdx] = SubControlVolume(
289 geometryHelper.scvVolume(scvLocalIdx, corners),
290 geometryHelper.dofPosition(scvLocalIdx),
291 Dumux::center(corners),
292 scvLocalIdx,
293 eIdx,
294 geometryHelper.dofIndex(this->dofMapper(), element, scvLocalIdx),
295 geometryHelper.isOverlappingScv(scvLocalIdx)
296 );
297 }
298
299 // construct the sub control volume faces
300 numScvf_ += geometryHelper.numInteriorScvf();
301 cache_.scvfs_[eIdx].resize(geometryHelper.numInteriorScvf());
302 LocalIndexType scvfLocalIdx = 0;
303 for (; scvfLocalIdx < geometryHelper.numInteriorScvf(); ++scvfLocalIdx)
304 {
305 const auto scvPair = geometryHelper.getScvPairForScvf(scvfLocalIdx);
306 const auto corners = geometryHelper.getScvfCorners(scvfLocalIdx);
307 const auto area = Dumux::convexPolytopeVolume<dim-1>(
308 geometryHelper.getInteriorScvfGeometryType(scvfLocalIdx),
309 [&](unsigned int i){ return corners[i]; }
310 );
311
312 cache_.scvfs_[eIdx][scvfLocalIdx] = SubControlVolumeFace(
313 Dumux::center(corners),
314 area,
315 geometryHelper.normal(corners, scvPair),
316 std::move(scvPair),
317 scvfLocalIdx,
318 geometryHelper.isOverlappingScvf(scvfLocalIdx)
319 );
320 }
321
322 // construct the sub control volume faces on the domain boundary
323 for (const auto& intersection : intersections(this->gridView(), element))
324 {
325 if (intersection.boundary() && !intersection.neighbor())
326 {
327 cache_.hasBoundaryScvf_[eIdx] = true;
328
329 const auto localFacetIndex = intersection.indexInInside();
330 const auto numBoundaryScvf = geometryHelper.numBoundaryScvf(localFacetIndex);
331 numScvf_ += numBoundaryScvf;
332 numBoundaryScvf_ += numBoundaryScvf;
333
334 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < numBoundaryScvf; ++isScvfLocalIdx)
335 {
336 // find the scvs this scvf is belonging to
337 const auto scvPair = geometryHelper.getScvPairForBoundaryScvf(localFacetIndex, isScvfLocalIdx);
338 const auto corners = geometryHelper.getBoundaryScvfCorners(localFacetIndex, isScvfLocalIdx);
339 const auto area = Dumux::convexPolytopeVolume<dim-1>(
340 Dune::GeometryTypes::cube(dim-1),
341 [&](unsigned int i){ return corners[i]; }
342 );
343 cache_.scvfs_[eIdx].emplace_back(
344 Dumux::center(corners),
345 area,
346 intersection.centerUnitOuterNormal(),
347 std::move(scvPair),
348 scvfLocalIdx,
349 typename SubControlVolumeFace::Traits::BoundaryFlag{ intersection }
350 );
351
352 // store look-up map to construct boundary scvf geometries
353 cache_.scvfBoundaryGeometryKeys_[eIdx].emplace_back(std::array<LocalIndexType, 2>{{
354 static_cast<LocalIndexType>(localFacetIndex),
355 static_cast<LocalIndexType>(isScvfLocalIdx)
356 }});
357
358 // increment local counter
359 scvfLocalIdx++;
360 }
361
362 // TODO also move this to helper class
363
364 // add all vertices on the intersection to the set of boundary vertices
365 for (int localVIdx = 0; localVIdx < numBoundaryScvf; ++localVIdx)
366 {
367 const auto vIdx = refElement.subEntity(localFacetIndex, 1, localVIdx, dim);
368 const auto vIdxGlobal = this->dofMapper().subIndex(element, vIdx, dim);
369 boundaryDofIndices_[vIdxGlobal] = true;
370 }
371 }
372
373 // inform the grid geometry if we have periodic boundaries
374 else if (intersection.boundary() && intersection.neighbor())
375 {
376 this->setPeriodic();
377
378 // find the mapped periodic vertex of all vertices on periodic boundaries
379 const auto fIdx = intersection.indexInInside();
380 const auto numFaceVerts = refElement.size(fIdx, 1, dim);
381 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
382 for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
383 {
384 const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
385 const auto vIdxGlobal = this->dofMapper().subIndex(element, vIdx, dim);
386 const auto vPos = elementGeometry.corner(vIdx);
387
388 const auto& outside = intersection.outside();
389 const auto outsideGeometry = outside.geometry();
390 for (const auto& isOutside : intersections(this->gridView(), outside))
391 {
392 // only check periodic vertices of the periodic neighbor
393 if (isOutside.boundary() && isOutside.neighbor())
394 {
395 const auto fIdxOutside = isOutside.indexInInside();
396 const auto numFaceVertsOutside = refElement.size(fIdxOutside, 1, dim);
397 for (int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
398 {
399 const auto vIdxOutside = refElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
400 const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
401 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
402 if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps)
403 periodicVertexMap_[vIdxGlobal] = this->dofMapper().subIndex(outside, vIdxOutside, dim);
404 }
405 }
406 }
407 }
408 }
409 }
410 }
411
412 // error check: periodic boundaries currently don't work for pq1bubble in parallel
413 if (this->isPeriodic() && this->gridView().comm().size() > 1)
414 DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for pq1bubble method for parallel simulations!");
415 }
416
417 DofMapper dofMapper_;
418
419 const FeCache feCache_;
420
421 std::size_t numScv_;
422 std::size_t numScvf_;
423 std::size_t numBoundaryScvf_;
424
425 // vertices on the boundary
426 std::vector<bool> boundaryDofIndices_;
427
428 // a map for periodic boundary vertices
429 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap_;
430
431 Cache cache_;
432};
433
434} // end namespace Dumux
435
436#endif
Defines the default element and vertex mapper types.
Defines the index types used for grid and local indices.
Base class for grid geometries.
Helper classes to compute the integration elements.
The available discretization methods in Dumux.
A finite element cache for P1/Q1 function with bubble.
Compute the center point of a convex polytope geometry or a random-access container of corner points.
Compute the volume of several common geometry types.
auto convexPolytopeVolume(Dune::GeometryType type, const CornerF &c)
Compute the volume of several common geometry types.
Definition volume.hh:53
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition center.hh:36
BaseGridGeometry(std::shared_ptr< BaseImplementation > impl)
Constructor from a BaseImplementation.
Definition basegridgeometry.hh:81
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition adapt.hh:29
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:251
CVFE< CVFEMethods::PQ1Bubble > PQ1Bubble
Definition method.hh:97
Definition defaultmappertraits.hh:35
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:39
unsigned int LocalIndex
Definition indextraits.hh:40
const ElementMapper & elementMapper() const
Returns the mapper for elements to indices for constant grids.
Definition basegridgeometry.hh:121
void setPeriodic(bool value=true)
Set the periodicity of the grid geometry.
Definition basegridgeometry.hh:178
const GlobalCoordinate & bBoxMax() const
The coordinate of the corner of the GridView's bounding box with the largest values.
Definition basegridgeometry.hh:165
Element element(GridIndexType eIdx) const
Definition basegridgeometry.hh:151
const GridView & gridView() const
Definition basegridgeometry.hh:109
void update(const GridView &gridView)
Update all fvElementGeometries (call this after grid adaption).
Definition basegridgeometry.hh:97
const GlobalCoordinate & bBoxMin() const
The coordinate of the corner of the GridView's bounding box with the smallest values.
Definition basegridgeometry.hh:158
bool isPeriodic() const
Returns if the grid geometry is periodic (at all).
Definition basegridgeometry.hh:171
Base class for the finite volume geometry vector for pq1bubble models This builds up the sub control ...
Definition discretization/pq1bubble/fvelementgeometry.hh:52
Definition discretization/pq1bubble/fvgridgeometry.hh:54
Dune::MultipleCodimMultipleGeomTypeMapper< GridView > DofMapper
Definition discretization/pq1bubble/fvgridgeometry.hh:55
static Dune::MCMGLayout layout()
layout for elements and vertices
Definition discretization/pq1bubble/fvgridgeometry.hh:61
The default traits for the pq1bubble finite volume grid geometry Defines the scv and scvf types and t...
Definition discretization/pq1bubble/fvgridgeometry.hh:78
PQ1BubbleSubControlVolume< GridView > SubControlVolume
Definition discretization/pq1bubble/fvgridgeometry.hh:79
PQ1BubbleSubControlVolumeFace< GridView > SubControlVolumeFace
Definition discretization/pq1bubble/fvgridgeometry.hh:80
PQ1BubbleFVElementGeometry< GridGeometry, enableCache > LocalView
Definition discretization/pq1bubble/fvgridgeometry.hh:83
Base class for the finite volume geometry vector for pq1bubble schemes This builds up the sub control...
Definition discretization/pq1bubble/fvgridgeometry.hh:98
void update(const GridView &gridView)
update all geometries (call this after grid adaption)
Definition discretization/pq1bubble/fvgridgeometry.hh:165
friend LocalView localView(const PQ1BubbleFVGridGeometry &gg)
local view of this object (constructed with the internal cache)
Definition discretization/pq1bubble/fvgridgeometry.hh:199
PQ1BubbleGridGeometryCache Cache
Definition discretization/pq1bubble/fvgridgeometry.hh:251
static constexpr DiscretizationMethod discMethod
Definition discretization/pq1bubble/fvgridgeometry.hh:118
std::size_t numBoundaryScvf() const
The total number of boundary sub control volume faces.
Definition discretization/pq1bubble/fvgridgeometry.hh:157
std::size_t numScv() const
The total number of sub control volumes.
Definition discretization/pq1bubble/fvgridgeometry.hh:149
std::size_t numScvf() const
The total number of sub control volume faces.
Definition discretization/pq1bubble/fvgridgeometry.hh:153
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition discretization/pq1bubble/fvgridgeometry.hh:179
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition discretization/pq1bubble/fvgridgeometry.hh:191
DiscretizationMethods::PQ1Bubble DiscretizationMethod
Definition discretization/pq1bubble/fvgridgeometry.hh:117
Extrusion_t< PQ1BubbleDefaultGridGeometryTraits< GridView > > Extrusion
Definition discretization/pq1bubble/fvgridgeometry.hh:127
typename PQ1BubbleDefaultGridGeometryTraits< GridView >::SubControlVolumeFace SubControlVolumeFace
Definition discretization/pq1bubble/fvgridgeometry.hh:125
std::size_t numDofs() const
The total number of degrees of freedom.
Definition discretization/pq1bubble/fvgridgeometry.hh:161
const std::unordered_map< GridIndexType, GridIndexType > & periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition discretization/pq1bubble/fvgridgeometry.hh:195
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition discretization/pq1bubble/fvgridgeometry.hh:183
typename PQ1BubbleDefaultGridGeometryTraits< GridView >::DofMapper DofMapper
Definition discretization/pq1bubble/fvgridgeometry.hh:129
const DofMapper & dofMapper() const
The dofMapper.
Definition discretization/pq1bubble/fvgridgeometry.hh:145
GridView GridView
Definition discretization/pq1bubble/fvgridgeometry.hh:133
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary.
Definition discretization/pq1bubble/fvgridgeometry.hh:187
typename PQ1BubbleDefaultGridGeometryTraits< GridView >::template LocalView< ThisType, true > LocalView
Definition discretization/pq1bubble/fvgridgeometry.hh:121
typename PQ1BubbleDefaultGridGeometryTraits< GridView >::SubControlVolume SubControlVolume
Definition discretization/pq1bubble/fvgridgeometry.hh:123
PQ1BubbleFVGridGeometry(const GridView gridView)
Constructor.
Definition discretization/pq1bubble/fvgridgeometry.hh:136
void update(GridView &&gridView)
update all geometries (call this after grid adaption)
Definition discretization/pq1bubble/fvgridgeometry.hh:172
Dumux::PQ1BubbleFECache< CoordScalar, Scalar, dim > FeCache
Definition discretization/pq1bubble/fvgridgeometry.hh:131
A class to create sub control volume and sub control volume face geometries per element.
Definition discretization/pq1bubble/geometryhelper.hh:178
bool isOverlappingScvf(unsigned int localScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:413
auto dofIndex(const DofMapper &dofMapper, const Element &element, unsigned int localScvIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:375
std::size_t numScv() const
number of sub control volumes (number of codim-1 entities)
Definition discretization/pq1bubble/geometryhelper.hh:355
std::size_t numBoundaryScvf(unsigned int localFacetIndex) const
number of boundary sub control volume faces for face localFacetIndex
Definition discretization/pq1bubble/geometryhelper.hh:349
std::size_t numInteriorScvf() const
number of interior sub control volume faces
Definition discretization/pq1bubble/geometryhelper.hh:343
ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on the boundary.
Definition discretization/pq1bubble/geometryhelper.hh:300
GlobalPosition dofPosition(unsigned int localScvIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:383
std::array< LocalIndexType, 2 > getScvPairForScvf(unsigned int localScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:391
Dune::GeometryType getInteriorScvfGeometryType(unsigned int localScvfIdx) const
Definition discretization/pq1bubble/geometryhelper.hh:290
bool isOverlappingScv(unsigned int localScvIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:421
Scalar scvVolume(unsigned int localScvIdx, const ScvCornerStorage &p) const
get scv volume
Definition discretization/pq1bubble/geometryhelper.hh:361
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition discretization/pq1bubble/geometryhelper.hh:254
std::array< LocalIndexType, 2 > getScvPairForBoundaryScvf(unsigned int localFacetIndex, unsigned int localIsScvfIndex) const
Definition discretization/pq1bubble/geometryhelper.hh:406
GlobalPosition normal(const ScvfCornerStorage &p, const std::array< LocalIndexType, 2 > &scvPair)
Definition discretization/pq1bubble/geometryhelper.hh:307
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition discretization/pq1bubble/geometryhelper.hh:198
Definition pq1bubblefecache.hh:41
the sub control volume for the pq1bubble scheme
Definition discretization/pq1bubble/subcontrolvolume.hh:68
Class for a sub control volume face in the cvfe method, i.e a part of the boundary of a sub control v...
Definition discretization/pq1bubble/subcontrolvolumeface.hh:72
Base class for the local finite volume geometry for the pq1bubble method This builds up the sub contr...
the sub control volume for the cvfe scheme
Base class for a sub control volume face.
Helper class constructing the dual grid finite volume geometries for the cvfe discretizazion method.