version 3.11-dev
Loading...
Searching...
No Matches
pq3/fegriddiscretization.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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_DISCRETIZATION_PQ3_FE_GRID_DISCRETIZATION_HH
13#define DUMUX_DISCRETIZATION_PQ3_FE_GRID_DISCRETIZATION_HH
14
15#include <ranges>
16
17#include <dune/localfunctions/lagrange/lagrangelfecache.hh>
18
26
27#include "dofhelper.hh"
28
29namespace Dumux::Experimental {
30
35template<class GridView,
36 class ElementRule = Dumux::QuadratureRules::DuneQuadrature<6>,
37 class IntersectionRule = Dumux::QuadratureRules::DuneQuadrature<6>,
38 class BoundaryFaceRule = Dumux::QuadratureRules::DuneQuadrature<6>>
40{
41 using ElementQuadratureRule = ElementRule;
42 using IntersectionQuadratureRule = IntersectionRule;
43 using BoundaryFaceQuadratureRule = BoundaryFaceRule;
44};
45
52template<class GridView,
53 class Scalar,
54 class MapperTraits = Dumux::PQ3MapperTraits<GridView>,
55 class QuadratureTraits = PQ3FEQuadratureTraits<GridView>>
57: public MapperTraits, public QuadratureTraits
58{
59 using FeCache = Dune::LagrangeLocalFiniteElementCache<typename GridView::ctype, Scalar, GridView::dimension, 3>;
61
62 template<class GridDiscretization, bool enableCache>
64
65 // Maximum number of element-local DOFs (for cubes, order 3)
66 static constexpr std::size_t maxNumElementDofs = []()
67 {
68 if constexpr (GridView::dimension == 1)
69 return 4; // Q3 interval: 2 vertices + 2 edge interior
70 else if constexpr (GridView::dimension == 2)
71 return 16; // Q3 quad: 4 vertices + 8 edge + 4 interior
72 else if constexpr (GridView::dimension == 3)
73 return 64; // Q3 hex: 8 vertices + 24 edge + 24 face + 8 interior
74 }();
75};
76
81template<class Scalar,
82 class GV,
83 bool enableCaching = true,
84 class Traits = PQ3FEDefaultGridDiscretizationTraits<GV, Scalar>>
86: public BaseGridGeometry<GV, Traits>
87{
89 using ParentType = BaseGridGeometry<GV, Traits>;
90 using GridIndexType = typename IndexTraits<GV>::GridIndex;
91 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
92 static const int dim = GV::dimension;
93
94public:
97 static constexpr DiscretizationMethod discMethod{};
98
99 static constexpr std::size_t maxNumElementDofs = Traits::maxNumElementDofs;
100
103
107 using LocalView = typename Traits::template LocalView<ThisType, true>;
111 using DofMapper = typename Traits::DofMapper;
113 using FeCache = typename Traits::FeCache;
115 using GridView = GV;
119 using ElementQuadratureRule = typename Traits::ElementQuadratureRule;
121 using IntersectionQuadratureRule = typename Traits::IntersectionQuadratureRule;
123 using BoundaryFaceQuadratureRule = typename Traits::BoundaryFaceQuadratureRule;
124
126 PQ3FEGridDiscretization(std::shared_ptr<BasicGridGeometry> gd)
127 : ParentType(std::move(gd))
128 , dofMapper_(this->gridView(), Traits::layout())
129 , cache_(*this)
130 , periodicGridTraits_(this->gridView().grid())
131 {
132 update_();
133 }
134
139
141 const DofMapper& dofMapper() const
142 { return dofMapper_; }
143
145 std::size_t numDofs() const
146 { return this->dofMapper().size(); }
147
150 {
152 update_();
153 }
154
157 {
158 ParentType::update(std::move(gridView));
159 update_();
160 }
161
163 const FeCache& feCache() const
164 { return feCache_; }
165
172 template<class LocalKey>
173 auto dofIndex(const typename GV::template Codim<0>::Entity& element,
174 const LocalKey& localKey) const
175 { return Traits::DofHelper::dofIndex(dofMapper_, element, localKey, this->gridView().grid().globalIdSet()); }
176
178 bool dofOnBoundary(GridIndexType dofIdx) const
179 { return boundaryDofIndices_[dofIdx]; }
180
182 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
183 { return periodicDofMap_.count(dofIdx); }
184
186 [[deprecated("Will be removed after release 3.11. Use periodicallyMappedDofs, returning a range of dofs")]]
187 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
188 { return periodicDofMap_.at(dofIdx)[0]; }
189
191 const std::ranges::range auto periodicallyMappedDofs(GridIndexType dofIdx) const
192 { return std::views::all(periodicDofMap_.at(dofIdx)); }
193
195 const std::unordered_map<GridIndexType, std::vector<GridIndexType>>& periodicDofMap() const
196 { return periodicDofMap_; }
197
200 { return { gd.cache_ }; }
201
202private:
203 class PQ3FEGridDiscretizationCache
204 {
205 friend class PQ3FEGridDiscretization;
206 public:
208 using DofHelper = typename Traits::DofHelper;
209
210 explicit PQ3FEGridDiscretizationCache(const PQ3FEGridDiscretization& gd)
211 : gridDiscretization_(&gd)
212 {}
213
214 const PQ3FEGridDiscretization& gridDiscretization() const
215 { return *gridDiscretization_; }
216
218 auto boundaryFaces(GridIndexType eIdx) const -> std::span<const BoundaryFace>
219 {
220 if (auto it = boundaryFaces_.find(eIdx); it != boundaryFaces_.end())
221 return {it->second};
222 return {};
223 }
224
225 private:
226 void clear_()
227 { boundaryFaces_.clear(); }
228
229 std::unordered_map<GridIndexType, Dune::ReservedVector<BoundaryFace, 2*dim>> boundaryFaces_;
230
231 const PQ3FEGridDiscretization* gridDiscretization_;
232 };
233
234public:
237 using Cache = PQ3FEGridDiscretizationCache;
238
239private:
241 void update_()
242 {
243 using DofHelper = typename Cache::DofHelper;
244
245 dofMapper_.update(this->gridView());
246 cache_.clear_();
247 boundaryDofIndices_.assign(numDofs(), false);
248 periodicDofMap_.clear();
249 const auto& idSet = this->gridView().grid().globalIdSet();
250
251 for (const auto& element : elements(this->gridView()))
252 {
253 auto elementGeometry = element.geometry();
254 const auto& localCoefficients = this->feCache().get(element.type()).localCoefficients();
255 const auto eIdx = this->elementMapper().index(element);
256
257 LocalIndexType numBoundaryFaces = 0;
258 for (const auto& intersection : intersections(this->gridView(), element))
259 {
260 if (intersection.boundary() && !periodicGridTraits_.isPeriodic(intersection))
261 {
262 // add one boundary face per boundary intersection
263 const auto isGeometry = intersection.geometry();
264 cache_.boundaryFaces_[eIdx].push_back(BoundaryFace{
265 isGeometry.center(),
266 isGeometry.volume(),
267 intersection.centerUnitOuterNormal(),
268 numBoundaryFaces++,
269 static_cast<LocalIndexType>(intersection.indexInInside()),
270 typename BoundaryFace::Traits::BoundaryFlag{intersection}
271 });
272
273 // mark all dofs on this intersection as boundary dofs
274 for (LocalIndexType keyIdx = 0; keyIdx < localCoefficients.size(); ++keyIdx)
275 {
276 if (DofHelper::localDofOnIntersection(elementGeometry.type(),
277 intersection.indexInInside(),
278 localCoefficients.localKey(keyIdx)))
279 {
280 const auto dofIdxGlobal = DofHelper::dofIndex(
281 this->dofMapper(), element, localCoefficients.localKey(keyIdx), idSet);
282 boundaryDofIndices_[dofIdxGlobal] = true;
283 }
284 }
285 }
286
287 // inform the grid discretization if we have periodic boundaries
288 else if (periodicGridTraits_.isPeriodic(intersection))
289 {
290 this->setPeriodic();
291
292 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
293 for (int localDofIdx = 0; localDofIdx < localCoefficients.size(); ++localDofIdx)
294 {
295 if (!DofHelper::localDofOnIntersection(elementGeometry.type(),
296 intersection.indexInInside(),
297 localCoefficients.localKey(localDofIdx)))
298 continue;
299
300 const auto dofIdxGlobal = DofHelper::dofIndex(
301 this->dofMapper(), element, localCoefficients.localKey(localDofIdx), idSet);
302 const auto dofPos = DofHelper::dofPosition(elementGeometry, localCoefficients.localKey(localDofIdx));
303
304 const auto& outside = intersection.outside();
305 const auto outsideGeometry = outside.geometry();
306 const auto& localCoefficientsOut = this->feCache().get(outsideGeometry.type()).localCoefficients();
307 for (const auto& isOutside : intersections(this->gridView(), outside))
308 {
309 if (periodicGridTraits_.isPeriodic(isOutside))
310 {
311 for (int localDofIdxOut = 0; localDofIdxOut < localCoefficientsOut.size(); ++localDofIdxOut)
312 {
313 const auto& localKeyOut = localCoefficientsOut.localKey(localDofIdxOut);
314 if (!DofHelper::localDofOnIntersection(outsideGeometry.type(),
315 isOutside.indexInInside(),
316 localKeyOut))
317 continue;
318
319 const auto dofIdxGlobalOut = DofHelper::dofIndex(this->dofMapper(), outside, localKeyOut, idSet);
320 const auto dofPosOutside = DofHelper::dofPosition(outsideGeometry, localKeyOut);
321 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
322 if ((dofPosOutside - dofPos + shift*intersection.centerUnitOuterNormal()).two_norm() < eps)
323 Dumux::Detail::addPeriodicallyMappedDof(periodicDofMap_, dofIdxGlobal, dofIdxGlobalOut);
324 }
325 }
326 }
327 }
328 }
329 }
330 }
331
332 Dumux::Detail::closePeriodicDofMap(periodicDofMap_);
333
334 // error check: periodic boundaries currently don't work in parallel
335 if (this->isPeriodic() && this->gridView().comm().size() > 1)
336 DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for FE PQ3 method for parallel simulations!");
337 }
338
339 DofMapper dofMapper_;
340 const FeCache feCache_;
341 // dofs on the boundary
342 std::vector<bool> boundaryDofIndices_;
343 // a map for periodic boundary dofs
344 std::unordered_map<GridIndexType, std::vector<GridIndexType>> periodicDofMap_;
345 Cache cache_;
347};
348
349} // end namespace Dumux::Experimental
350
351#endif
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
Definition basegridgeometry.hh:142
const GridView & gridView() const
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
Class for a boundary face related to primary grid elements (dune intersections).
Definition boundaryface.hh:69
Default class for the local finite element discretization. All schemes share the same structure....
Definition feelementdiscretization.hh:41
Class for pq3 finite element grid discretizations.
Definition pq3/fegriddiscretization.hh:87
typename PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar >::template LocalView< ThisType, true > LocalView
Definition pq3/fegriddiscretization.hh:107
void update(GridView &&gridView)
update all geometries (call this after grid adaption)
Definition pq3/fegriddiscretization.hh:156
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the d.o.f. on the other side of the periodic boundary.
Definition pq3/fegriddiscretization.hh:187
typename PeriodicGridTraits< typename GridView::Grid >::SupportsPeriodicity SupportsPeriodicity
Definition pq3/fegriddiscretization.hh:117
void update(const GridView &gridView)
update all geometries (call this after grid adaption)
Definition pq3/fegriddiscretization.hh:149
static constexpr DiscretizationMethod discMethod
Definition pq3/fegriddiscretization.hh:97
Experimental::BoundaryFace< GridView > BoundaryFace
Definition pq3/fegriddiscretization.hh:102
PQ3FEGridDiscretization(const GridView &gridView)
Constructor.
Definition pq3/fegriddiscretization.hh:136
bool dofOnBoundary(GridIndexType dofIdx) const
If a d.o.f. is on the boundary.
Definition pq3/fegriddiscretization.hh:178
GridView GridView
Definition pq3/fegriddiscretization.hh:115
Extrusion_t< PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar > > Extrusion
Definition pq3/fegriddiscretization.hh:109
auto dofIndex(const typename GV::template Codim< 0 >::Entity &element, const LocalKey &localKey) const
The global dof index of a local key.
Definition pq3/fegriddiscretization.hh:173
typename PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar >::DofMapper DofMapper
Definition pq3/fegriddiscretization.hh:111
PQ3FEGridDiscretizationCache Cache
Definition pq3/fegriddiscretization.hh:237
typename PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar >::IntersectionQuadratureRule IntersectionQuadratureRule
Definition pq3/fegriddiscretization.hh:121
typename PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar >::FeCache FeCache
Definition pq3/fegriddiscretization.hh:113
std::size_t numDofs() const
The total number of degrees of freedom.
Definition pq3/fegriddiscretization.hh:145
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition pq3/fegriddiscretization.hh:163
friend LocalView localView(const PQ3FEGridDiscretization &gd)
local view of this object (constructed with the internal cache)
Definition pq3/fegriddiscretization.hh:199
const DofMapper & dofMapper() const
The dof mapper.
Definition pq3/fegriddiscretization.hh:141
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a d.o.f. is on a periodic boundary.
Definition pq3/fegriddiscretization.hh:182
const std::ranges::range auto periodicallyMappedDofs(GridIndexType dofIdx) const
The indices of the d.o.f.s on the other side of the periodic boundaries.
Definition pq3/fegriddiscretization.hh:191
typename PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar >::ElementQuadratureRule ElementQuadratureRule
Definition pq3/fegriddiscretization.hh:119
static constexpr std::size_t maxNumElementDofs
Definition pq3/fegriddiscretization.hh:99
BasicGridGeometry_t< GridView, PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar > > BasicGridGeometry
Definition pq3/fegriddiscretization.hh:105
typename DiscretizationMethods::PQ3 DiscretizationMethod
Definition pq3/fegriddiscretization.hh:96
const std::unordered_map< GridIndexType, std::vector< GridIndexType > > & periodicDofMap() const
Returns the map between dofs across periodic boundaries.
Definition pq3/fegriddiscretization.hh:195
PQ3FEGridDiscretization(std::shared_ptr< BasicGridGeometry > gd)
Constructor.
Definition pq3/fegriddiscretization.hh:126
typename PQ3FEDefaultGridDiscretizationTraits< GridView, Scalar >::BoundaryFaceQuadratureRule BoundaryFaceQuadratureRule
Definition pq3/fegriddiscretization.hh:123
DOF index and position helper for order-3 Lagrange discretizations.
Definition pq3/dofhelper.hh:51
Defines the default element and vertex mapper types.
Base class for the finite volume geometry vector for the pq3 method This builds up the sub control vo...
Default class for the local finite element discretization. All schemes share the same structure....
Default class for finite element grid discretizations.
void closePeriodicDofMap(std::unordered_map< Index, std::vector< Index > > &periodicDofMap)
Map every degree of freedom to all others it is identified with.
Definition periodicdofmap.hh:48
Dune::Std::detected_or_t< Dumux::BasicGridGeometry< GV, typename T::ElementMapper, typename T::VertexMapper >, Detail::SpecifiesBaseGridGeometry, T > BasicGridGeometry_t
Type of the basic grid geometry implementation used as backend.
Definition basegridgeometry.hh:38
void addPeriodicallyMappedDof(std::unordered_map< Index, std::vector< Index > > &periodicDofMap, std::type_identity_t< Index > dofIdx, std::type_identity_t< Index > periodicDofIdx)
Register a degree of freedom as periodically mapped to another one.
Definition periodicdofmap.hh:29
BaseGridGeometry(std::shared_ptr< BaseImplementation > impl)
Constructor from a BaseImplementation.
Definition basegridgeometry.hh:72
decltype(auto) gridDiscretization(const T &t, Args &&... args)
The grid discretization.
Definition griddiscretization.hh:65
The available discretization methods in Dumux.
CVFE< CVFEMethods::PQ3 > PQ3
Definition method.hh:138
Definition assembly/assembler.hh:46
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:257
Helpers for maps between degrees of freedom identified across periodic boundaries.
Lightweight DOF helper for order-3 Lagrange elements.
Quadrature rules over sub-control volumes and sub-control volume faces.
The default traits for the PQ3 finite element grid discretization.
Definition pq3/fegriddiscretization.hh:58
Dune::LagrangeLocalFiniteElementCache< typename GridView::ctype, Scalar, GridView::dimension, 3 > FeCache
Definition pq3/fegriddiscretization.hh:59
PQ3LagrangeDofHelper< GridView > DofHelper
Definition pq3/fegriddiscretization.hh:60
FEElementDiscretization< GridDiscretization, enableCache > LocalView
Definition pq3/fegriddiscretization.hh:63
static constexpr std::size_t maxNumElementDofs
Definition pq3/fegriddiscretization.hh:66
Quadrature rule traits for PQ3 FE discretization.
Definition pq3/fegriddiscretization.hh:40
ElementRule ElementQuadratureRule
Definition pq3/fegriddiscretization.hh:41
IntersectionRule IntersectionQuadratureRule
Definition pq3/fegriddiscretization.hh:42
BoundaryFaceRule BoundaryFaceQuadratureRule
Definition pq3/fegriddiscretization.hh:43
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:27
unsigned int LocalIndex
Definition indextraits.hh:28
Mapper traits for PQ3: vertices get 1 DOF, edges get 2 DOFs, quad faces/elements get 4 DOFs,...
Definition discretization/pq3/fvgridgeometry.hh:83
Definition periodicgridtraits.hh:24
Definition periodicgridtraits.hh:23