version 3.11-dev
hybrid/gridvariablescache.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_HYBRID_CVFE_GRID_VARIABLES_CACHE_HH
13#define DUMUX_DISCRETIZATION_HYBRID_CVFE_GRID_VARIABLES_CACHE_HH
14
15#include <unordered_map>
16#include <utility>
17#include <vector>
18#include <ranges>
19#include <memory>
20
22
23#include <dumux/common/concepts/localdofs_.hh>
24
25// make the local view function available whenever we use this class
29#include "elementvariables.hh"
30
32
33template<class P, class V, class IPD>
35{
36 using Problem = P;
37 using Variables = V;
39
40 template<class GridVariablesCache, bool cachingEnabled>
42};
43
48template<class Traits, bool enableCaching>
50
51// specialization in case of storing the local variables
52template<class Traits>
53class HybridCVFEGridVariablesCache<Traits, /*cachingEnabled*/true>
54{
56public:
58 using Problem = typename Traits::Problem;
59
61 using Variables = typename Traits::Variables;
62
64 using InterpolationPointData = typename Traits::InterpolationPointData;
65
67 static constexpr bool cachingEnabled = true;
68
70 using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
71
73 using MutableLocalView = typename LocalView::MutableView;
74
75 HybridCVFEGridVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
76
77 template<class GridGeometry, class SolutionVector>
78 void init(const GridGeometry& gridGeometry, const SolutionVector& sol)
79 {
80 variables_.resize(gridGeometry.gridView().size(0));
81 ipDataCache_ = std::make_shared<InterpolationPointDataCache>();
82 ipDataCache_->resize(gridGeometry.gridView().size(0));
83
84 Dumux::parallelFor(gridGeometry.gridView().size(0), [&, &problem = problem()](const std::size_t eIdx)
85 {
86 const auto element = gridGeometry.element(eIdx);
87 const auto fvGeometry = localView(gridGeometry).bindElement(element);
88
89 // get the element solution
90 auto elemSol = elementSolution(element, sol, gridGeometry);
91
92 variables_[eIdx].resize(Dumux::Detail::LocalDofs::numLocalDofs(fvGeometry));
93 for (const auto& localDof : localDofs(fvGeometry))
94 variables_[eIdx][localDof.index()].update(elemSol, problem, fvGeometry, ipData(fvGeometry, localDof));
95
96 ipDataCache_->update(problem, element, fvGeometry, variables_[eIdx]);
97 });
98 }
99
100 template<class GridGeometry, class SolutionVector>
101 void update(const GridGeometry& gridGeometry, const SolutionVector& sol)
102 {
103 if constexpr (InterpolationPointData::isSolDependent)
104 {
105 auto newIpDataCache = std::make_shared<InterpolationPointDataCache>();
106 newIpDataCache->resize(gridGeometry.gridView().size(0));
107
108 Dumux::parallelFor(gridGeometry.gridView().size(0), [&, &problem = problem(), newIpDataCache](const std::size_t eIdx)
109 {
110 const auto element = gridGeometry.element(eIdx);
111 const auto fvGeometry = localView(gridGeometry).bindElement(element);
112
113 // get the element solution
114 auto elemSol = elementSolution(element, sol, gridGeometry);
115
116 for (const auto& localDof : localDofs(fvGeometry))
117 variables_[eIdx][localDof.index()].update(elemSol, problem, fvGeometry, ipData(fvGeometry, localDof));
118
119 newIpDataCache->update(problem, element, fvGeometry, variables_[eIdx]);
120 });
121
122 ipDataCache_ = std::move(newIpDataCache);
123 }
124 else
125 {
126 Dumux::parallelFor(gridGeometry.gridView().size(0), [&, &problem = problem()](const std::size_t eIdx)
127 {
128 const auto element = gridGeometry.element(eIdx);
129 const auto fvGeometry = localView(gridGeometry).bindElement(element);
130
131 // get the element solution
132 auto elemSol = elementSolution(element, sol, gridGeometry);
133
134 for (const auto& localDof : localDofs(fvGeometry))
135 variables_[eIdx][localDof.index()].update(elemSol, problem, fvGeometry, ipData(fvGeometry, localDof));
136 });
137 }
138 }
139
140 template<class ScvOrLocalDof>
141 const Variables& variables(const ScvOrLocalDof& scvOrLocalDof) const
142 {
143 if constexpr (Concept::LocalDof<ScvOrLocalDof>)
144 return variables_[scvOrLocalDof.elementIndex()][scvOrLocalDof.index()];
145 else
146 return variables_[scvOrLocalDof.elementIndex()][scvOrLocalDof.localDofIndex()];
147 }
148
149 template<class ScvOrLocalDof>
150 Variables& variables(const ScvOrLocalDof& scvOrLocalDof)
151 {
152 if constexpr (Concept::LocalDof<ScvOrLocalDof>)
153 return variables_[scvOrLocalDof.elementIndex()][scvOrLocalDof.index()];
154 else
155 return variables_[scvOrLocalDof.elementIndex()][scvOrLocalDof.localDofIndex()];
156 }
157
158 const Variables& variables(const std::size_t eIdx, const std::size_t localIdx) const
159 { return variables_[eIdx][localIdx]; }
160
161 Variables& variables(const std::size_t eIdx, const std::size_t localIdx)
162 { return variables_[eIdx][localIdx]; }
163
164 const InterpolationPointData& scvfCache(std::size_t eIdx, std::size_t scvfIdx, std::size_t qpIdx) const
165 { return ipDataCache_->scvfCache(eIdx, scvfIdx, qpIdx); }
166
167 InterpolationPointData& scvfCache(std::size_t eIdx, std::size_t scvfIdx, std::size_t qpIdx)
168 { return ipDataCache_->scvfCache(eIdx, scvfIdx, qpIdx); }
169
170 const InterpolationPointData& elementCache(std::size_t eIdx, std::size_t qpIdx) const
171 { return ipDataCache_->elementCache(eIdx, qpIdx); }
172
173 InterpolationPointData& elementCache(std::size_t eIdx, std::size_t qpIdx)
174 { return ipDataCache_->elementCache(eIdx, qpIdx); }
175
176 const InterpolationPointData& boundaryIntersectionCache(std::size_t eIdx, int intersectionIdx, std::size_t qpIdx) const
177 { return ipDataCache_->boundaryIntersectionCache(eIdx, intersectionIdx, qpIdx); }
178
179 InterpolationPointData& boundaryIntersectionCache(std::size_t eIdx, int intersectionIdx, std::size_t qpIdx)
180 { return ipDataCache_->boundaryIntersectionCache(eIdx, intersectionIdx, qpIdx); }
181
182 const Problem& problem() const
183 { return *problemPtr_; }
184
185private:
186 class InterpolationPointDataCache
187 {
188 struct ElementCache
189 {
190 std::vector<InterpolationPointData> scvfCache;
191 std::vector<std::size_t> qpsOffset;
192 std::vector<InterpolationPointData> elementCache;
193 std::unordered_map<int, std::vector<InterpolationPointData>> boundaryIntersectionCache;
194
195 template<class Problem, class FVElementGeometry, class ElementVariables>
196 void update(const Problem& problem,
197 const typename FVElementGeometry::Element& element,
198 const FVElementGeometry& fvGeometry,
199 const ElementVariables& elemVars)
200 {
201 qpsOffset.resize(fvGeometry.numScvf() + 1, 0);
202 for (const auto& scvf : scvfs(fvGeometry))
203 {
204 const auto numQps = std::ranges::size(Dumux::CVFE::quadratureRule(fvGeometry, scvf));
205 qpsOffset[scvf.index() + 1] = numQps;
206 }
207 for (std::size_t i = 2; i < qpsOffset.size(); ++i)
208 qpsOffset[i] += qpsOffset[i-1];
209
210 scvfCache.resize(qpsOffset.back());
211 for (const auto& scvf : scvfs(fvGeometry))
212 {
213 for (const auto& qpData : Dumux::CVFE::quadratureRule(fvGeometry, scvf))
214 {
215 const auto scvfIdx = qpData.ipData().scvfIndex();
216 const auto qpIdx = qpData.ipData().qpIndex();
217 scvfCache[qpsOffset[scvfIdx] + qpIdx].update(problem,
218 element,
219 fvGeometry,
220 elemVars,
221 qpData.ipData());
222 }
223 }
224
225 const auto elemQuadRule = Dumux::CVFE::quadratureRule(fvGeometry, element);
226 elementCache.resize(std::ranges::size(elemQuadRule));
227 for (const auto& qpData : elemQuadRule)
228 elementCache[qpData.ipData().qpIndex()].update(problem, element, fvGeometry, elemVars, qpData.ipData());
229
230 boundaryIntersectionCache.clear();
231 for (const auto& intersection : intersections(fvGeometry.gridGeometry().gridView(), element))
232 {
233 if (intersection.boundary())
234 {
235 const auto intersectionIndex = intersection.indexInInside();
236 auto& boundaryCache = boundaryIntersectionCache[intersectionIndex];
237 const auto quadRule = Dumux::CVFE::quadratureRule(fvGeometry, intersection);
238 boundaryCache.resize(std::ranges::size(quadRule));
239 for (const auto& qpData : quadRule)
240 boundaryCache[qpData.ipData().qpIndex()].update(problem,
241 element,
242 fvGeometry,
243 elemVars,
244 qpData.ipData());
245 }
246 }
247 }
248 };
249
250 public:
251
252 InterpolationPointDataCache()
253 {}
254
255 void resize(const std::size_t numElements)
256 {
257 elementCaches_.resize(numElements);
258 }
259
260 template<class Problem, class FVElementGeometry, class ElementVariables>
261 void update(const Problem& problem,
262 const typename FVElementGeometry::Element& element,
263 const FVElementGeometry& fvGeometry,
264 const ElementVariables& elemVars)
265 {
266 const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(element);
267 elementCaches_[eIdx].update(problem, element, fvGeometry, elemVars);
268 }
269
270 // access operator
271 const InterpolationPointData& scvfCache(std::size_t eIdx, std::size_t scvfIdx, std::size_t qpIdx) const
272 {
273 const auto& elementCache = elementCaches_[eIdx];
274 return elementCache.scvfCache[elementCache.qpsOffset[scvfIdx] + qpIdx];
275 }
276
277 // access operator
278 InterpolationPointData& scvfCache(std::size_t eIdx, std::size_t scvfIdx, std::size_t qpIdx)
279 {
280 auto& elementCache = elementCaches_[eIdx];
281 return elementCache.scvfCache[elementCache.qpsOffset[scvfIdx] + qpIdx];
282 }
283
284 // access operator
285 const InterpolationPointData& elementCache(std::size_t eIdx, std::size_t qpIdx) const
286 { return elementCaches_[eIdx].elementCache[qpIdx]; }
287
288 // access operator
289 InterpolationPointData& elementCache(std::size_t eIdx, std::size_t qpIdx)
290 { return elementCaches_[eIdx].elementCache[qpIdx]; }
291
292 // access operator
293 const InterpolationPointData& boundaryIntersectionCache(std::size_t eIdx, int intersectionIdx, std::size_t qpIdx) const
294 { return elementCaches_[eIdx].boundaryIntersectionCache.at(intersectionIdx)[qpIdx]; }
295
296 // access operator
297 InterpolationPointData& boundaryIntersectionCache(std::size_t eIdx, int intersectionIdx, std::size_t qpIdx)
298 { return elementCaches_[eIdx].boundaryIntersectionCache[intersectionIdx][qpIdx]; }
299
300 const ElementCache& cache(std::size_t eIdx) const
301 { return elementCaches_[eIdx]; }
302
303 ElementCache& cache(std::size_t eIdx)
304 { return elementCaches_[eIdx]; }
305
306 private:
307 std::vector<ElementCache> elementCaches_;
308 };
309
310public:
311 const auto& cache(std::size_t eIdx) const
312 { return ipDataCache_->cache(eIdx); }
313
314 auto& cache(std::size_t eIdx)
315 { return ipDataCache_->cache(eIdx); }
316
317private:
318 const Problem* problemPtr_;
319 std::vector<std::vector<Variables>> variables_;
320 std::shared_ptr<InterpolationPointDataCache> ipDataCache_;
321};
322
323// Specialization when the current local variables are not stored
324template<class Traits>
325class HybridCVFEGridVariablesCache<Traits, /*cachingEnabled*/false>
326{
328
329public:
331 using Problem = typename Traits::Problem;
332
334 using Variables = typename Traits::Variables;
335
337 static constexpr bool cachingEnabled = false;
338
340 using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
341
343 using MutableLocalView = typename LocalView::MutableView;
344
346 using InterpolationPointData = typename Traits::InterpolationPointData;
347
348 HybridCVFEGridVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
349
350 template<class GridGeometry, class SolutionVector>
351 void update(const GridGeometry& gridGeometry, const SolutionVector& sol) {}
352
353 const Problem& problem() const
354 { return *problemPtr_;}
355
356private:
357 const Problem* problemPtr_;
358};
359
360} // end namespace Dumux::Experimental::CVFE
361
362#endif
The (stencil) element variables class for hybrid control-volume finite element.
Definition: hybrid/elementvariables.hh:40
typename Traits::InterpolationPointData InterpolationPointData
export interpolation point data type
Definition: hybrid/gridvariablescache.hh:346
HybridCVFEGridVariablesCache(const Problem &problem)
Definition: hybrid/gridvariablescache.hh:348
typename Traits::template LocalView< ThisType, cachingEnabled > LocalView
export the type of the local view
Definition: hybrid/gridvariablescache.hh:340
const Problem & problem() const
Definition: hybrid/gridvariablescache.hh:353
typename Traits::Problem Problem
export the problem type
Definition: hybrid/gridvariablescache.hh:331
typename Traits::Variables Variables
export the variables type
Definition: hybrid/gridvariablescache.hh:334
typename LocalView::MutableView MutableLocalView
export the type of the mutable local view
Definition: hybrid/gridvariablescache.hh:343
void update(const GridGeometry &gridGeometry, const SolutionVector &sol)
Definition: hybrid/gridvariablescache.hh:351
void update(const GridGeometry &gridGeometry, const SolutionVector &sol)
Definition: hybrid/gridvariablescache.hh:101
Variables & variables(const std::size_t eIdx, const std::size_t localIdx)
Definition: hybrid/gridvariablescache.hh:161
void init(const GridGeometry &gridGeometry, const SolutionVector &sol)
Definition: hybrid/gridvariablescache.hh:78
InterpolationPointData & boundaryIntersectionCache(std::size_t eIdx, int intersectionIdx, std::size_t qpIdx)
Definition: hybrid/gridvariablescache.hh:179
Variables & variables(const ScvOrLocalDof &scvOrLocalDof)
Definition: hybrid/gridvariablescache.hh:150
auto & cache(std::size_t eIdx)
Definition: hybrid/gridvariablescache.hh:314
typename Traits::Variables Variables
export the variables type
Definition: hybrid/gridvariablescache.hh:61
InterpolationPointData & scvfCache(std::size_t eIdx, std::size_t scvfIdx, std::size_t qpIdx)
Definition: hybrid/gridvariablescache.hh:167
const InterpolationPointData & boundaryIntersectionCache(std::size_t eIdx, int intersectionIdx, std::size_t qpIdx) const
Definition: hybrid/gridvariablescache.hh:176
typename LocalView::MutableView MutableLocalView
export the type of the mutable local view
Definition: hybrid/gridvariablescache.hh:73
const InterpolationPointData & scvfCache(std::size_t eIdx, std::size_t scvfIdx, std::size_t qpIdx) const
Definition: hybrid/gridvariablescache.hh:164
HybridCVFEGridVariablesCache(const Problem &problem)
Definition: hybrid/gridvariablescache.hh:75
const auto & cache(std::size_t eIdx) const
Definition: hybrid/gridvariablescache.hh:311
typename Traits::InterpolationPointData InterpolationPointData
export interpolation point data type
Definition: hybrid/gridvariablescache.hh:64
typename Traits::template LocalView< ThisType, cachingEnabled > LocalView
export the type of the local view
Definition: hybrid/gridvariablescache.hh:70
const Problem & problem() const
Definition: hybrid/gridvariablescache.hh:182
typename Traits::Problem Problem
export the problem type
Definition: hybrid/gridvariablescache.hh:58
const Variables & variables(const ScvOrLocalDof &scvOrLocalDof) const
Definition: hybrid/gridvariablescache.hh:141
InterpolationPointData & elementCache(std::size_t eIdx, std::size_t qpIdx)
Definition: hybrid/gridvariablescache.hh:173
const Variables & variables(const std::size_t eIdx, const std::size_t localIdx) const
Definition: hybrid/gridvariablescache.hh:158
const InterpolationPointData & elementCache(std::size_t eIdx, std::size_t qpIdx) const
Definition: hybrid/gridvariablescache.hh:170
The grid variables cache class for hybrid control-volume finite element methods.
Definition: hybrid/gridvariablescache.hh:49
The local element solution class for control-volume finite element methods.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:26
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::cctpfa||GridGeometry::discMethod==DiscretizationMethods::ccmpfa, CCElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for cell-centered schemes.
Definition: cellcentered/elementsolution.hh:101
void parallelFor(const std::size_t count, const FunctorType &functor)
A parallel for loop (multithreading)
Definition: parallel_for.hh:160
The element variables class for hybrid control-volume finite element methods.
Free function to get the local view of a grid cache object.
auto quadratureRule(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolume &scv, QuadratureRules::MidpointQuadrature)
Midpoint quadrature for scv.
Definition: quadraturerules.hh:148
Definition: hybrid/elementvariables.hh:30
auto localDofs(const FVElementGeometry &fvGeometry)
range over local dofs
Definition: localdof.hh:50
Parallel for loop (multithreading)
Quadrature rules over sub-control volumes and sub-control volume faces.
IPD InterpolationPointData
Definition: hybrid/gridvariablescache.hh:38
P Problem
Definition: hybrid/gridvariablescache.hh:36
V Variables
Definition: hybrid/gridvariablescache.hh:37