version 3.9
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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
14#ifndef DUMUX_DISCRETIZATION_PQ1BUBBLE_GRID_GEOMETRY_HH
15#define DUMUX_DISCRETIZATION_PQ1BUBBLE_GRID_GEOMETRY_HH
16
17#include <utility>
18#include <unordered_map>
19
20#include <dune/grid/common/mcmgmapper.hh>
21
23
26
29
37
38namespace Dumux {
39
40namespace Detail {
41template<class GV, class T>
42using PQ1BubbleGeometryHelper_t = Dune::Std::detected_or_t<
45 T
46>;
47} // end namespace Detail
48
49template <class GridView>
51{
52 using DofMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
53
58 static Dune::MCMGLayout layout()
59 {
60 return [](Dune::GeometryType gt, int dimgrid) {
61 return (gt.dim() == dimgrid) || (gt.dim() == 0);
62 };
63 }
64};
65
72template<class GridView, class MapperTraits = PQ1BubbleMapperTraits<GridView>>
74: public MapperTraits
75{
78
79 template<class GridGeometry, bool enableCache>
81};
82
89template<class Scalar,
90 class GV,
91 bool enableCaching = true,
94: public BaseGridGeometry<GV, Traits>
95{
98 using GridIndexType = typename IndexTraits<GV>::GridIndex;
99 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
100
101 using Element = typename GV::template Codim<0>::Entity;
102 using CoordScalar = typename GV::ctype;
103 static const int dim = GV::dimension;
104 static const int dimWorld = GV::dimensionworld;
105
106 static_assert(dim > 1, "Only implemented for dim > 1");
107
108public:
112
114 using LocalView = typename Traits::template LocalView<ThisType, true>;
116 using SubControlVolume = typename Traits::SubControlVolume;
118 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
122 using DofMapper = typename Traits::DofMapper;
126 using GridView = GV;
127
131 , dofMapper_(gridView, Traits::layout())
132 , cache_(*this)
133 {
134 update_();
135 }
136
138 const DofMapper& dofMapper() const
139 { return dofMapper_; }
140
142 std::size_t numScv() const
143 { return numScv_; }
144
146 std::size_t numScvf() const
147 { return numScvf_; }
148
150 std::size_t numBoundaryScvf() const
151 { return numBoundaryScvf_; }
152
154 std::size_t numDofs() const
155 { return this->dofMapper().size(); }
156
159 {
161 update_();
162 }
163
166 {
167 ParentType::update(std::move(gridView));
168 update_();
169 }
170
172 const FeCache& feCache() const
173 { return feCache_; }
174
176 bool dofOnBoundary(GridIndexType dofIdx) const
177 { return boundaryDofIndices_[dofIdx]; }
178
180 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
181 { return periodicVertexMap_.count(dofIdx); }
182
184 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
185 { return periodicVertexMap_.at(dofIdx); }
186
188 const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap() const
189 { return periodicVertexMap_; }
190
192 [[deprecated("Will be removed after release 3.9. Use periodicDofMap() instead.")]]
193 const std::unordered_map<GridIndexType, GridIndexType>& periodicVertexMap() const
194 { return periodicDofMap(); }
195
198 { return { gg.cache_ }; }
199
200private:
201
202 class PQ1BubbleGridGeometryCache
203 {
204 friend class PQ1BubbleFVGridGeometry;
205 public:
208
209 explicit PQ1BubbleGridGeometryCache(const PQ1BubbleFVGridGeometry& gg)
210 : gridGeometry_(&gg)
211 {}
212
213 const PQ1BubbleFVGridGeometry& gridGeometry() const
214 { return *gridGeometry_; }
215
217 const std::vector<SubControlVolume>& scvs(GridIndexType eIdx) const
218 { return scvs_[eIdx]; }
219
221 const std::vector<SubControlVolumeFace>& scvfs(GridIndexType eIdx) const
222 { return scvfs_[eIdx]; }
223
225 bool hasBoundaryScvf(GridIndexType eIdx) const
226 { return hasBoundaryScvf_[eIdx]; }
227
229 const std::vector<std::array<LocalIndexType, 2>>& scvfBoundaryGeometryKeys(GridIndexType eIdx) const
230 { return scvfBoundaryGeometryKeys_.at(eIdx); }
231
232 private:
233 void clear_()
234 {
235 scvs_.clear();
236 scvfs_.clear();
237 hasBoundaryScvf_.clear();
238 scvfBoundaryGeometryKeys_.clear();
239 }
240
241 std::vector<std::vector<SubControlVolume>> scvs_;
242 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
243 std::vector<bool> hasBoundaryScvf_;
244 std::unordered_map<GridIndexType, std::vector<std::array<LocalIndexType, 2>>> scvfBoundaryGeometryKeys_;
245
246 const PQ1BubbleFVGridGeometry* gridGeometry_;
247 };
248
249public:
252 using Cache = PQ1BubbleGridGeometryCache;
253
254private:
255 using GeometryHelper = typename Cache::GeometryHelper;
256
257 void update_()
258 {
259 cache_.clear_();
260 dofMapper_.update(this->gridView());
261
262 auto numElements = this->gridView().size(0);
263 cache_.scvs_.resize(numElements);
264 cache_.scvfs_.resize(numElements);
265 cache_.hasBoundaryScvf_.resize(numElements, false);
266
267 boundaryDofIndices_.assign(numDofs(), false);
268
269 numScv_ = 0;
270 numScvf_ = 0;
271 numBoundaryScvf_ = 0;
272
273 // Build the scvs and scv faces
274 for (const auto& element : elements(this->gridView()))
275 {
276 auto eIdx = this->elementMapper().index(element);
277
278 // get the element geometry
279 auto elementGeometry = element.geometry();
280 const auto refElement = referenceElement(elementGeometry);
281
282 // instantiate the geometry helper
283 GeometryHelper geometryHelper(elementGeometry);
284
285 numScv_ += geometryHelper.numScv();
286 // construct the sub control volumes
287 cache_.scvs_[eIdx].resize(geometryHelper.numScv());
288 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < geometryHelper.numScv(); ++scvLocalIdx)
289 {
290 auto corners = geometryHelper.getScvCorners(scvLocalIdx);
291 cache_.scvs_[eIdx][scvLocalIdx] = SubControlVolume(
292 geometryHelper.scvVolume(scvLocalIdx, corners),
293 geometryHelper.dofPosition(scvLocalIdx),
294 Dumux::center(corners),
295 scvLocalIdx,
296 eIdx,
297 geometryHelper.dofIndex(this->dofMapper(), element, scvLocalIdx),
298 geometryHelper.isOverlappingScv(scvLocalIdx)
299 );
300 }
301
302 // construct the sub control volume faces
303 numScvf_ += geometryHelper.numInteriorScvf();
304 cache_.scvfs_[eIdx].resize(geometryHelper.numInteriorScvf());
305 LocalIndexType scvfLocalIdx = 0;
306 for (; scvfLocalIdx < geometryHelper.numInteriorScvf(); ++scvfLocalIdx)
307 {
308 const auto scvPair = geometryHelper.getScvPairForScvf(scvfLocalIdx);
309 const auto corners = geometryHelper.getScvfCorners(scvfLocalIdx);
310 const auto area = Dumux::convexPolytopeVolume<dim-1>(
311 geometryHelper.getInteriorScvfGeometryType(scvfLocalIdx),
312 [&](unsigned int i){ return corners[i]; }
313 );
314
315 cache_.scvfs_[eIdx][scvfLocalIdx] = SubControlVolumeFace(
316 Dumux::center(corners),
317 area,
318 geometryHelper.normal(corners, scvPair),
319 std::move(scvPair),
320 scvfLocalIdx,
321 geometryHelper.isOverlappingScvf(scvfLocalIdx)
322 );
323 }
324
325 // construct the sub control volume faces on the domain boundary
326 for (const auto& intersection : intersections(this->gridView(), element))
327 {
328 if (intersection.boundary() && !intersection.neighbor())
329 {
330 cache_.hasBoundaryScvf_[eIdx] = true;
331
332 const auto localFacetIndex = intersection.indexInInside();
333 const auto numBoundaryScvf = geometryHelper.numBoundaryScvf(localFacetIndex);
334 numScvf_ += numBoundaryScvf;
335 numBoundaryScvf_ += numBoundaryScvf;
336
337 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < numBoundaryScvf; ++isScvfLocalIdx)
338 {
339 // find the scvs this scvf is belonging to
340 const auto scvPair = geometryHelper.getScvPairForBoundaryScvf(localFacetIndex, isScvfLocalIdx);
341 const auto corners = geometryHelper.getBoundaryScvfCorners(localFacetIndex, isScvfLocalIdx);
342 const auto area = Dumux::convexPolytopeVolume<dim-1>(
343 Dune::GeometryTypes::cube(dim-1),
344 [&](unsigned int i){ return corners[i]; }
345 );
346 cache_.scvfs_[eIdx].emplace_back(
347 Dumux::center(corners),
348 area,
349 intersection.centerUnitOuterNormal(),
350 std::move(scvPair),
351 scvfLocalIdx,
352 typename SubControlVolumeFace::Traits::BoundaryFlag{ intersection }
353 );
354
355 // store look-up map to construct boundary scvf geometries
356 cache_.scvfBoundaryGeometryKeys_[eIdx].emplace_back(std::array<LocalIndexType, 2>{{
357 static_cast<LocalIndexType>(localFacetIndex),
358 static_cast<LocalIndexType>(isScvfLocalIdx)
359 }});
360
361 // increment local counter
362 scvfLocalIdx++;
363 }
364
365 // TODO also move this to helper class
366
367 // add all vertices on the intersection to the set of boundary vertices
368 for (int localVIdx = 0; localVIdx < numBoundaryScvf; ++localVIdx)
369 {
370 const auto vIdx = refElement.subEntity(localFacetIndex, 1, localVIdx, dim);
371 const auto vIdxGlobal = this->dofMapper().subIndex(element, vIdx, dim);
372 boundaryDofIndices_[vIdxGlobal] = true;
373 }
374 }
375
376 // inform the grid geometry if we have periodic boundaries
377 else if (intersection.boundary() && intersection.neighbor())
378 {
379 this->setPeriodic();
380
381 // find the mapped periodic vertex of all vertices on periodic boundaries
382 const auto fIdx = intersection.indexInInside();
383 const auto numFaceVerts = refElement.size(fIdx, 1, dim);
384 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
385 for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
386 {
387 const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
388 const auto vIdxGlobal = this->dofMapper().subIndex(element, vIdx, dim);
389 const auto vPos = elementGeometry.corner(vIdx);
390
391 const auto& outside = intersection.outside();
392 const auto outsideGeometry = outside.geometry();
393 for (const auto& isOutside : intersections(this->gridView(), outside))
394 {
395 // only check periodic vertices of the periodic neighbor
396 if (isOutside.boundary() && isOutside.neighbor())
397 {
398 const auto fIdxOutside = isOutside.indexInInside();
399 const auto numFaceVertsOutside = refElement.size(fIdxOutside, 1, dim);
400 for (int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
401 {
402 const auto vIdxOutside = refElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
403 const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
404 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
405 if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps)
406 periodicVertexMap_[vIdxGlobal] = this->dofMapper().subIndex(outside, vIdxOutside, dim);
407 }
408 }
409 }
410 }
411 }
412 }
413 }
414
415 // error check: periodic boundaries currently don't work for pq1bubble in parallel
416 if (this->isPeriodic() && this->gridView().comm().size() > 1)
417 DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for pq1bubble method for parallel simulations!");
418 }
419
420 DofMapper dofMapper_;
421
422 const FeCache feCache_;
423
424 std::size_t numScv_;
425 std::size_t numScvf_;
426 std::size_t numBoundaryScvf_;
427
428 // vertices on the boundary
429 std::vector<bool> boundaryDofIndices_;
430
431 // a map for periodic boundary vertices
432 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap_;
433
434 Cache cache_;
435};
436
437} // end namespace Dumux
438
439#endif
Base class for grid geometries.
Compute the center point of a convex polytope geometry or a random-access container of corner points.
Base class for all grid geometries.
Definition: basegridgeometry.hh:52
const ElementMapper & elementMapper() const
Returns the mapper for elements to indices for constant grids.
Definition: basegridgeometry.hh:112
void setPeriodic(bool value=true)
Set the periodicity of the grid geometry.
Definition: basegridgeometry.hh:169
const GlobalCoordinate & bBoxMax() const
The coordinate of the corner of the GridView's bounding box with the largest values.
Definition: basegridgeometry.hh:156
Element element(GridIndexType eIdx) const
Get an element from a global element index.
Definition: basegridgeometry.hh:142
const GridView & gridView() const
Return the gridView this grid geometry object lives on.
Definition: basegridgeometry.hh:100
void update(const GridView &gridView)
Update all fvElementGeometries (call this after grid adaption)
Definition: basegridgeometry.hh:88
const GlobalCoordinate & bBoxMin() const
The coordinate of the corner of the GridView's bounding box with the smallest values.
Definition: basegridgeometry.hh:149
bool isPeriodic() const
Returns if the grid geometry is periodic (at all)
Definition: basegridgeometry.hh:162
Definition: pq1bubblefecache.hh:29
Base class for the finite volume geometry vector for pq1bubble models This builds up the sub control ...
Definition: discretization/pq1bubble/fvelementgeometry.hh:40
Base class for the finite volume geometry vector for pq1bubble schemes This builds up the sub control...
Definition: discretization/pq1bubble/fvgridgeometry.hh:95
void update(const GridView &gridView)
update all geometries (call this after grid adaption)
Definition: discretization/pq1bubble/fvgridgeometry.hh:158
friend LocalView localView(const PQ1BubbleFVGridGeometry &gg)
local view of this object (constructed with the internal cache)
Definition: discretization/pq1bubble/fvgridgeometry.hh:197
PQ1BubbleGridGeometryCache Cache
Definition: discretization/pq1bubble/fvgridgeometry.hh:252
static constexpr DiscretizationMethod discMethod
Definition: discretization/pq1bubble/fvgridgeometry.hh:111
std::size_t numBoundaryScvf() const
The total number of boundary sub control volume faces.
Definition: discretization/pq1bubble/fvgridgeometry.hh:150
std::size_t numScv() const
The total number of sub control volumes.
Definition: discretization/pq1bubble/fvgridgeometry.hh:142
std::size_t numScvf() const
The total number of sub control volume faces.
Definition: discretization/pq1bubble/fvgridgeometry.hh:146
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: discretization/pq1bubble/fvgridgeometry.hh:172
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:184
Extrusion_t< Traits > Extrusion
export the type of extrusion
Definition: discretization/pq1bubble/fvgridgeometry.hh:120
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: discretization/pq1bubble/fvgridgeometry.hh:118
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: discretization/pq1bubble/fvgridgeometry.hh:154
const std::unordered_map< GridIndexType, GridIndexType > & periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: discretization/pq1bubble/fvgridgeometry.hh:193
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: discretization/pq1bubble/fvgridgeometry.hh:176
typename Traits::DofMapper DofMapper
export dof mapper type
Definition: discretization/pq1bubble/fvgridgeometry.hh:122
const DofMapper & dofMapper() const
The dofMapper.
Definition: discretization/pq1bubble/fvgridgeometry.hh:138
const std::unordered_map< GridIndexType, GridIndexType > & periodicDofMap() const
Returns the map between dofs across periodic boundaries.
Definition: discretization/pq1bubble/fvgridgeometry.hh:188
GV GridView
export the grid view type
Definition: discretization/pq1bubble/fvgridgeometry.hh:126
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary.
Definition: discretization/pq1bubble/fvgridgeometry.hh:180
typename Traits::template LocalView< ThisType, true > LocalView
export the type of the fv element geometry (the local view type)
Definition: discretization/pq1bubble/fvgridgeometry.hh:114
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: discretization/pq1bubble/fvgridgeometry.hh:116
PQ1BubbleFVGridGeometry(const GridView gridView)
Constructor.
Definition: discretization/pq1bubble/fvgridgeometry.hh:129
void update(GridView &&gridView)
update all geometries (call this after grid adaption)
Definition: discretization/pq1bubble/fvgridgeometry.hh:165
Dumux::PQ1BubbleFECache< CoordScalar, Scalar, dim > FeCache
export the finite element cache type
Definition: discretization/pq1bubble/fvgridgeometry.hh:124
A class to create sub control volume and sub control volume face geometries per element.
Definition: discretization/pq1bubble/geometryhelper.hh:166
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:60
the sub control volume for the pq1bubble scheme
Definition: discretization/pq1bubble/subcontrolvolume.hh:56
Defines the default element and vertex mapper types.
Base class for the local finite volume geometry for the pq1bubble method This builds up the sub contr...
Helper class constructing the dual grid finite volume geometries for the cvfe discretizazion method.
the sub control volume for the cvfe scheme
Base class for a sub control volume face.
Helper classes to compute the integration elements.
auto convexPolytopeVolume(Dune::GeometryType type, const CornerF &c)
Compute the volume of several common geometry types.
Definition: volume.hh:41
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition: center.hh:24
Defines the index types used for grid and local indices.
The available discretization methods in Dumux.
Dune::Std::detected_or_t< Dumux::PQ1BubbleGeometryHelper< GV, typename T::SubControlVolume, typename T::SubControlVolumeFace >, SpecifiesGeometryHelper, T > PQ1BubbleGeometryHelper_t
Definition: discretization/pq1bubble/fvgridgeometry.hh:46
typename T::GeometryHelper SpecifiesGeometryHelper
Definition: basegridgeometry.hh:30
CVFE< CVFEMethods::PQ1Bubble > PQ1Bubble
Definition: method.hh:108
Definition: adapt.hh:17
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:166
A finite element cache for P1/Q1 function with bubble.
Definition: defaultmappertraits.hh:23
Definition: method.hh:46
Structure to define the index types used for grid and local indices.
Definition: indextraits.hh:26
The default traits for the pq1bubble finite volume grid geometry Defines the scv and scvf types and t...
Definition: discretization/pq1bubble/fvgridgeometry.hh:75
Definition: discretization/pq1bubble/fvgridgeometry.hh:51
Dune::MultipleCodimMultipleGeomTypeMapper< GridView > DofMapper
Definition: discretization/pq1bubble/fvgridgeometry.hh:52
static Dune::MCMGLayout layout()
layout for elements and vertices
Definition: discretization/pq1bubble/fvgridgeometry.hh:58
Compute the volume of several common geometry types.