Line | Branch | Exec | Source |
---|---|---|---|
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 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup CCMpfaDiscretization | ||
10 | * \brief The local (stencil) volume variables class for cell centered mpfa models | ||
11 | */ | ||
12 | #ifndef DUMUX_DISCRETIZATION_CCMPFA_ELEMENT_VOLUMEVARIABLES_HH | ||
13 | #define DUMUX_DISCRETIZATION_CCMPFA_ELEMENT_VOLUMEVARIABLES_HH | ||
14 | |||
15 | #include <algorithm> | ||
16 | #include <type_traits> | ||
17 | #include <utility> | ||
18 | #include <vector> | ||
19 | #include <utility> | ||
20 | |||
21 | #include <dumux/discretization/cellcentered/elementsolution.hh> | ||
22 | |||
23 | namespace Dumux { | ||
24 | namespace CCMpfa { | ||
25 | |||
26 | /*! | ||
27 | * \ingroup CCMpfaDiscretization | ||
28 | * \brief Computes how many boundary vol vars come into play for flux calculations | ||
29 | * on an element (for a given element finite volume geometry). This number here | ||
30 | * is probably always higher than the actually needed number of volume variables. | ||
31 | * However, we want to make sure it is high enough so that enough memory is reserved | ||
32 | * in the element volume variables below. | ||
33 | * \todo TODO What about non-symmetric schemes? Is there a better way for estimating this? | ||
34 | * | ||
35 | * \param fvGeometry the element finite volume geometry | ||
36 | */ | ||
37 | template<class FVElementGeometry> | ||
38 | 12004674 | std::size_t maxNumBoundaryVolVars(const FVElementGeometry& fvGeometry) | |
39 | { | ||
40 | 13458919 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
41 | 14913164 | const auto& gridIvIndexSets = gridGeometry.gridInteractionVolumeIndexSets(); | |
42 | |||
43 | 13458919 | std::size_t numBoundaryVolVars = 0; | |
44 |
8/8✓ Branch 0 taken 100427880 times.
✓ Branch 1 taken 13450807 times.
✓ Branch 2 taken 100427880 times.
✓ Branch 3 taken 13450807 times.
✓ Branch 4 taken 217048 times.
✓ Branch 5 taken 27160 times.
✓ Branch 6 taken 48672 times.
✓ Branch 7 taken 8112 times.
|
136981322 | for (const auto& scvf : scvfs(fvGeometry)) |
45 | { | ||
46 |
4/4✓ Branch 0 taken 262216 times.
✓ Branch 1 taken 29656 times.
✓ Branch 2 taken 262216 times.
✓ Branch 3 taken 29656 times.
|
100768424 | if (!gridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) |
47 | 200893792 | numBoundaryVolVars += gridIvIndexSets.primaryIndexSet(scvf).nodalIndexSet().numBoundaryScvfs(); | |
48 | else | ||
49 | 59312 | numBoundaryVolVars += gridIvIndexSets.secondaryIndexSet(scvf).nodalIndexSet().numBoundaryScvfs(); | |
50 | } | ||
51 | |||
52 | 12004674 | return numBoundaryVolVars; | |
53 | } | ||
54 | |||
55 | /*! | ||
56 | * \ingroup CCMpfaDiscretization | ||
57 | * \brief Adds the boundary volume variables found within a given nodal index set | ||
58 | * into the provided containers and stores the indices associated with them. | ||
59 | * \note It only adds those boundary vol vars that do not live on scvfs that are | ||
60 | * inside the bound element. These have to be added separately | ||
61 | * | ||
62 | * \param volVars The container where the volume variables are stored | ||
63 | * \param volVarIndices The container where the volume variable indices are stored | ||
64 | * \param problem The problem containing the Dirichlet boundary conditions | ||
65 | * \param element The element to which the finite volume geometry is bound | ||
66 | * \param fvGeometry The element finite volume geometry | ||
67 | * \param nodalIndexSet The dual grid index set around a node | ||
68 | */ | ||
69 | template<class VolumeVariables, class IndexType, class Problem, class FVElemGeom, class NodalIndexSet> | ||
70 | 10995002 | void addBoundaryVolVarsAtNode(std::vector<VolumeVariables>& volVars, | |
71 | std::vector<IndexType>& volVarIndices, | ||
72 | const Problem& problem, | ||
73 | const typename FVElemGeom::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
74 | const FVElemGeom& fvGeometry, | ||
75 | const NodalIndexSet& nodalIndexSet) | ||
76 | { | ||
77 |
2/2✓ Branch 0 taken 5542720 times.
✓ Branch 1 taken 4986586 times.
|
10995002 | if (nodalIndexSet.numBoundaryScvfs() == 0) |
78 | return; | ||
79 | |||
80 | // index of the element the fvGeometry was bound to | ||
81 | 11537024 | const auto boundElemIdx = fvGeometry.gridGeometry().elementMapper().index(element); | |
82 | |||
83 | // check each scvf in the index set for boundary presence | ||
84 |
4/4✓ Branch 0 taken 26875252 times.
✓ Branch 1 taken 5542720 times.
✓ Branch 2 taken 26875252 times.
✓ Branch 3 taken 5542720 times.
|
51453236 | for (auto scvfIdx : nodalIndexSet.gridScvfIndices()) |
85 | { | ||
86 |
2/2✓ Branch 0 taken 9569960 times.
✓ Branch 1 taken 13488180 times.
|
28379188 | const auto& ivScvf = fvGeometry.scvf(scvfIdx); |
87 | |||
88 | // only proceed for scvfs on the boundary and not in the bound element | ||
89 |
4/4✓ Branch 0 taken 11183496 times.
✓ Branch 1 taken 15691756 times.
✓ Branch 2 taken 4911796 times.
✓ Branch 3 taken 6271700 times.
|
28379188 | if (!ivScvf.boundary() || ivScvf.insideScvIdx() == boundElemIdx) |
90 | 21797024 | continue; | |
91 | |||
92 | 6582164 | const auto insideScvIdx = ivScvf.insideScvIdx(); | |
93 |
2/3✓ Branch 0 taken 17444 times.
✓ Branch 1 taken 4014088 times.
✗ Branch 2 not taken.
|
7835868 | const auto insideElement = fvGeometry.gridGeometry().element(insideScvIdx); |
94 |
2/3✓ Branch 0 taken 78936 times.
✓ Branch 1 taken 840764 times.
✗ Branch 2 not taken.
|
6582164 | const auto bcTypes = problem.boundaryTypes(insideElement, ivScvf); |
95 | |||
96 | // Only proceed on dirichlet boundaries. On Neumann | ||
97 | // boundaries the "outside" vol vars cannot be properly defined. | ||
98 |
4/4✓ Branch 0 taken 814702 times.
✓ Branch 1 taken 5456998 times.
✓ Branch 2 taken 814702 times.
✓ Branch 3 taken 5456998 times.
|
13164328 | if (bcTypes.hasOnlyDirichlet()) |
99 | { | ||
100 |
2/3✓ Branch 0 taken 246604 times.
✓ Branch 1 taken 538754 times.
✗ Branch 2 not taken.
|
815222 | VolumeVariables dirichletVolVars; |
101 |
11/12✓ Branch 0 taken 246604 times.
✓ Branch 1 taken 538754 times.
✓ Branch 2 taken 261508 times.
✓ Branch 3 taken 78504 times.
✓ Branch 4 taken 473634 times.
✓ Branch 5 taken 282056 times.
✓ Branch 6 taken 57956 times.
✓ Branch 7 taken 473634 times.
✓ Branch 8 taken 282056 times.
✓ Branch 9 taken 28612 times.
✓ Branch 10 taken 469194 times.
✗ Branch 11 not taken.
|
2925364 | dirichletVolVars.update(elementSolution<FVElemGeom>(problem.dirichlet(insideElement, ivScvf)), |
102 | problem, | ||
103 | insideElement, | ||
104 | fvGeometry.scv(insideScvIdx)); | ||
105 | |||
106 |
1/2✓ Branch 1 taken 814702 times.
✗ Branch 2 not taken.
|
815222 | volVars.emplace_back(std::move(dirichletVolVars)); |
107 |
2/4✓ Branch 1 taken 814702 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 814702 times.
✗ Branch 5 not taken.
|
1630444 | volVarIndices.push_back(ivScvf.outsideScvIdx()); |
108 | } | ||
109 | } | ||
110 | } | ||
111 | |||
112 | /*! | ||
113 | * \ingroup CCMpfaDiscretization | ||
114 | * \brief Adds the boundary volume variables found within the stencil to the | ||
115 | * provided containers and stores the indices associated with them. | ||
116 | * | ||
117 | * \param volVars The container where the volume variables are stored | ||
118 | * \param volVarIndices The container where the volume variable indices are stored | ||
119 | * \param problem The problem containing the Dirichlet boundary conditions | ||
120 | * \param element The element to which the finite volume geometry was bound | ||
121 | * \param fvGeometry The element finite volume geometry | ||
122 | */ | ||
123 | template<class VolumeVariables, class IndexType, class Problem, class FVElemGeom> | ||
124 | 1548411 | void addBoundaryVolVars(std::vector<VolumeVariables>& volVars, | |
125 | std::vector<IndexType>& volVarIndices, | ||
126 | const Problem& problem, | ||
127 | const typename FVElemGeom::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
128 | const FVElemGeom& fvGeometry) | ||
129 | { | ||
130 | 1548411 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
131 | |||
132 | // treat the BCs inside the element | ||
133 |
4/4✓ Branch 0 taken 1137159 times.
✓ Branch 1 taken 333636 times.
✓ Branch 2 taken 1007159 times.
✓ Branch 3 taken 291072 times.
|
2846642 | if (fvGeometry.hasBoundaryScvf()) |
134 | { | ||
135 | 2344878 | const auto boundElemIdx = gridGeometry.elementMapper().index(element); | |
136 |
2/2✓ Branch 0 taken 90220 times.
✓ Branch 1 taken 39780 times.
|
1172439 | const auto& scvI = fvGeometry.scv(boundElemIdx); |
137 | |||
138 |
6/6✓ Branch 0 taken 8502784 times.
✓ Branch 1 taken 1137159 times.
✓ Branch 2 taken 8502784 times.
✓ Branch 3 taken 1137159 times.
✓ Branch 4 taken 2091598 times.
✓ Branch 5 taken 5442718 times.
|
11059342 | for (const auto& scvf : scvfs(fvGeometry)) |
139 | { | ||
140 |
2/2✓ Branch 0 taken 2455898 times.
✓ Branch 1 taken 6046886 times.
|
8714464 | if (!scvf.boundary()) |
141 | continue; | ||
142 | |||
143 | // Only proceed on dirichlet boundaries. On Neumann | ||
144 | // boundaries the "outside" vol vars cannot be properly defined. | ||
145 |
6/6✓ Branch 0 taken 35798 times.
✓ Branch 1 taken 360114 times.
✓ Branch 2 taken 2083210 times.
✓ Branch 3 taken 372688 times.
✓ Branch 4 taken 2083210 times.
✓ Branch 5 taken 86584 times.
|
2878054 | if (problem.boundaryTypes(element, scvf).hasOnlyDirichlet()) |
146 | { | ||
147 |
2/2✓ Branch 0 taken 131322 times.
✓ Branch 1 taken 10698 times.
|
309448 | VolumeVariables dirichletVolVars; |
148 |
2/2✓ Branch 0 taken 131322 times.
✓ Branch 1 taken 10698 times.
|
768388 | dirichletVolVars.update(elementSolution<FVElemGeom>(problem.dirichlet(element, scvf)), |
149 | problem, | ||
150 | element, | ||
151 | scvI); | ||
152 | |||
153 | 309448 | volVars.emplace_back(std::move(dirichletVolVars)); | |
154 | 618896 | volVarIndices.push_back(scvf.outsideScvIdx()); | |
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | // Update boundary volume variables in the neighbors | ||
160 | 1548411 | const auto& gridIvIndexSets = gridGeometry.gridInteractionVolumeIndexSets(); | |
161 |
6/6✓ Branch 0 taken 10529306 times.
✓ Branch 1 taken 1470795 times.
✓ Branch 2 taken 10529306 times.
✓ Branch 3 taken 1470795 times.
✓ Branch 4 taken 18072 times.
✓ Branch 5 taken 19048 times.
|
14091824 | for (const auto& scvf : scvfs(fvGeometry)) |
162 | { | ||
163 |
4/4✓ Branch 0 taken 28136 times.
✓ Branch 1 taken 29656 times.
✓ Branch 2 taken 28136 times.
✓ Branch 3 taken 29656 times.
|
11052794 | if (!gridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) |
164 | 10965346 | addBoundaryVolVarsAtNode( volVars, volVarIndices, problem, element, fvGeometry, | |
165 | 21930692 | gridIvIndexSets.primaryIndexSet(scvf).nodalIndexSet() ); | |
166 | else | ||
167 | 29656 | addBoundaryVolVarsAtNode( volVars, volVarIndices, problem, element, fvGeometry, | |
168 | 59312 | gridIvIndexSets.secondaryIndexSet(scvf).nodalIndexSet() ); | |
169 | } | ||
170 | 1548411 | } | |
171 | } // end namespace CCMpfa | ||
172 | |||
173 | /*! | ||
174 | * \ingroup CCMpfaDiscretization | ||
175 | * \brief The local (stencil) volume variables class for cell centered mpfa models | ||
176 | * \note The class is specialized for versions with and without caching | ||
177 | * \tparam GVV the grid volume variables type | ||
178 | * \tparam cachingEnabled if the cache is enabled | ||
179 | */ | ||
180 | template<class GVV, bool cachingEnabled> | ||
181 | class CCMpfaElementVolumeVariables; | ||
182 | |||
183 | /*! | ||
184 | * \ingroup CCMpfaDiscretization | ||
185 | * \brief The local (stencil) volume variables class for cell centered mpfa models with caching | ||
186 | * \note the volume variables are stored for the whole grid view in the corresponding GridVolumeVariables class | ||
187 | */ | ||
188 | template<class GVV> | ||
189 | ✗ | class CCMpfaElementVolumeVariables<GVV, /*cachingEnabled*/true> | |
190 | { | ||
191 | public: | ||
192 | //! export type of the grid volume variables | ||
193 | using GridVolumeVariables = GVV; | ||
194 | |||
195 | //! export type of the volume variables | ||
196 | using VolumeVariables = typename GridVolumeVariables::VolumeVariables; | ||
197 | |||
198 | //! Constructor | ||
199 | CCMpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars) | ||
200 | : gridVolVarsPtr_(&gridVolVars) | ||
201 |
40/70✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 104 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1283454 times.
✓ Branch 7 taken 104 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1283454 times.
✓ Branch 10 taken 104 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1283454 times.
✓ Branch 13 taken 104 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1283454 times.
✓ Branch 16 taken 6212836 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1283454 times.
✓ Branch 19 taken 6212836 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1283454 times.
✓ Branch 22 taken 6212836 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1283454 times.
✓ Branch 25 taken 6212836 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1283454 times.
✓ Branch 28 taken 6212836 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1283454 times.
✓ Branch 31 taken 1213859 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1283454 times.
✓ Branch 34 taken 1213859 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1213859 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1213859 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1213859 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 13739 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 13739 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 13739 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 13739 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 13739 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 185 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 185 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 185 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 185 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 185 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 159 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 159 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 159 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 159 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 159 times.
✗ Branch 89 not taken.
|
50042820 | , numScv_(gridVolVars.problem().gridGeometry().numScv()) |
202 | {} | ||
203 | |||
204 | //! operator for the access with an scv | ||
205 | template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0> | ||
206 | 825675628 | const VolumeVariables& operator [](const SubControlVolume& scv) const | |
207 | { | ||
208 |
2/4✓ Branch 0 taken 825675628 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 825675628 times.
✗ Branch 3 not taken.
|
1651351256 | return scv.dofIndex() < numScv_ ? gridVolVars().volVars(scv.dofIndex()) |
209 | ✗ | : boundaryVolVars_[getLocalIdx_(scv.dofIndex())]; | |
210 | } | ||
211 | |||
212 | //! operator for the access with an index | ||
213 | 2586794252 | const VolumeVariables& operator [](const std::size_t scvIdx) const | |
214 | { | ||
215 |
2/2✓ Branch 0 taken 2581889832 times.
✓ Branch 1 taken 4904420 times.
|
2586794252 | return scvIdx < numScv_ ? gridVolVars().volVars(scvIdx) |
216 | 4904420 | : boundaryVolVars_[getLocalIdx_(scvIdx)]; | |
217 | } | ||
218 | |||
219 | /*! | ||
220 | * \brief bind the local view (r-value overload) | ||
221 | * This overload is called when an instance of this class is a temporary in the usage context | ||
222 | * This allows a usage like this: `const auto view = localView(...).bind(element);` | ||
223 | */ | ||
224 | template<class FVElementGeometry, class SolutionVector> | ||
225 | ✗ | CCMpfaElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
226 | const FVElementGeometry& fvGeometry, | ||
227 | const SolutionVector& sol) && | ||
228 | { | ||
229 | ✗ | this->bind_(element, fvGeometry, sol); | |
230 | ✗ | return std::move(*this); | |
231 | } | ||
232 | |||
233 | template<class FVElementGeometry, class SolutionVector> | ||
234 | ✗ | void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
235 | const FVElementGeometry& fvGeometry, | ||
236 | const SolutionVector& sol) & | ||
237 |
2/4✓ Branch 1 taken 27500 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 4454433 times.
✗ Branch 7 not taken.
|
11991275 | { this->bind_(element, fvGeometry, sol); } |
238 | |||
239 | /*! | ||
240 | * \brief bind the local view (r-value overload) | ||
241 | * This overload is called when an instance of this class is a temporary in the usage context | ||
242 | * This allows a usage like this: `const auto view = localView(...).bind(element);` | ||
243 | */ | ||
244 | template<class FVElementGeometry, class SolutionVector> | ||
245 | CCMpfaElementVolumeVariables bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
246 | const FVElementGeometry& fvGeometry, | ||
247 | const SolutionVector& sol) && | ||
248 | { | ||
249 | this->bindElement_(element, fvGeometry, sol); | ||
250 | return std::move(*this); | ||
251 | } | ||
252 | |||
253 | template<class FVElementGeometry, class SolutionVector> | ||
254 | ✗ | void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
255 | const FVElementGeometry& fvGeometry, | ||
256 | const SolutionVector& sol) & | ||
257 |
1/2✓ Branch 1 taken 1158772 times.
✗ Branch 2 not taken.
|
1168756 | { this->bindElement_(element, fvGeometry, sol); } |
258 | |||
259 | //! Clear all local storage | ||
260 | void clear() | ||
261 | { | ||
262 | ✗ | boundaryVolVarIndices_.clear(); | |
263 | ✗ | boundaryVolVars_.clear(); | |
264 | } | ||
265 | |||
266 | //! The global volume variables object we are a restriction of | ||
267 | ✗ | const GridVolumeVariables& gridVolVars() const | |
268 | ✗ | { return *gridVolVarsPtr_; } | |
269 | |||
270 | private: | ||
271 | //! map a global scv index to the local storage index | ||
272 | 4904420 | int getLocalIdx_(const int volVarIdx) const | |
273 | { | ||
274 | 14713260 | auto it = std::find(boundaryVolVarIndices_.begin(), boundaryVolVarIndices_.end(), volVarIdx); | |
275 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 4904420 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4904420 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4904420 times.
|
14713260 | assert(it != boundaryVolVarIndices_.end() && "Could not find the current volume variables for volVarIdx!"); |
276 | 14713260 | return std::distance(boundaryVolVarIndices_.begin(), it); | |
277 | } | ||
278 | |||
279 | //! precompute all volume variables in a stencil of an element - bind Dirichlet vol vars in the stencil | ||
280 | template<class FVElementGeometry, class SolutionVector> | ||
281 | ✗ | void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
282 | const FVElementGeometry& fvGeometry, | ||
283 | const SolutionVector& sol) | ||
284 | { | ||
285 | ✗ | clear(); | |
286 | |||
287 | // maybe prepare boundary volume variables | ||
288 | ✗ | const auto maxNumBoundaryVolVars = CCMpfa::maxNumBoundaryVolVars(fvGeometry); | |
289 | ✗ | if (maxNumBoundaryVolVars > 0) | |
290 | { | ||
291 | ✗ | boundaryVolVars_.reserve(maxNumBoundaryVolVars); | |
292 | ✗ | boundaryVolVarIndices_.reserve(maxNumBoundaryVolVars); | |
293 | ✗ | CCMpfa::addBoundaryVolVars(boundaryVolVars_, boundaryVolVarIndices_, gridVolVars().problem(), element, fvGeometry); | |
294 | } | ||
295 | ✗ | } | |
296 | |||
297 | //! precompute the volume variables of an element - do nothing: volVars are cached | ||
298 | template<class FVElementGeometry, class SolutionVector> | ||
299 | ✗ | void bindElement_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
300 | const FVElementGeometry& fvGeometry, | ||
301 | const SolutionVector& sol) | ||
302 | ✗ | {} | |
303 | |||
304 | const GridVolumeVariables* gridVolVarsPtr_; | ||
305 | |||
306 | std::size_t numScv_; | ||
307 | std::vector<std::size_t> boundaryVolVarIndices_; | ||
308 | std::vector<VolumeVariables> boundaryVolVars_; | ||
309 | }; | ||
310 | |||
311 | |||
312 | /*! | ||
313 | * \ingroup CCMpfaDiscretization | ||
314 | * \brief The local (stencil) volume variables class for cell centered tpfa models with caching | ||
315 | */ | ||
316 | template<class GVV> | ||
317 | 321618 | class CCMpfaElementVolumeVariables<GVV, /*cachingEnabled*/false> | |
318 | { | ||
319 | public: | ||
320 | //! export type of the grid volume variables | ||
321 | using GridVolumeVariables = GVV; | ||
322 | |||
323 | //! export type of the volume variables | ||
324 | using VolumeVariables = typename GridVolumeVariables::VolumeVariables; | ||
325 | |||
326 | //! Constructor | ||
327 | CCMpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars) | ||
328 |
30/60✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 121 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 121 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 220417 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 220417 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 220417 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 427022 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 427022 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 427022 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 202276 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 202276 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 202276 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 5786 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 5786 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 5786 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 50000 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 50000 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 50000 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 964000 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 964000 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 964000 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 964000 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 964000 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 964000 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 100 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 100 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 100 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 1 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 1 times.
✗ Branch 89 not taken.
|
8501169 | : gridVolVarsPtr_(&gridVolVars) {} |
329 | |||
330 | //! access operator with scv | ||
331 | template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0> | ||
332 | const VolumeVariables& operator [](const SubControlVolume& scv) const | ||
333 |
17/30✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 15 taken 5615706 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 792 times.
✓ Branch 18 taken 5615706 times.
✓ Branch 19 taken 792 times.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 11568 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 11568 times.
✓ Branch 27 taken 2267730 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 2267730 times.
✓ Branch 31 taken 1088088 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1088088 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 264 times.
✓ Branch 40 taken 2892000 times.
✓ Branch 41 taken 38084 times.
✓ Branch 42 taken 2892000 times.
✓ Branch 43 taken 37820 times.
✓ Branch 47 taken 4606476 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 4606476 times.
✗ Branch 51 not taken.
|
291093806 | { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; } |
334 | |||
335 | //! access operator with scv | ||
336 | template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0> | ||
337 | VolumeVariables& operator [](const SubControlVolume& scv) | ||
338 |
4/8✓ Branch 7 taken 65376 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 65376 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 9984 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 9984 times.
✗ Branch 17 not taken.
|
2960290 | { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; } |
339 | |||
340 | //! access operator with scv index | ||
341 | const VolumeVariables& operator [](std::size_t scvIdx) const | ||
342 |
36/36✓ Branch 1 taken 828448 times.
✓ Branch 2 taken 19153580 times.
✓ Branch 3 taken 828448 times.
✓ Branch 4 taken 19527260 times.
✓ Branch 5 taken 9965660 times.
✓ Branch 6 taken 6794310 times.
✓ Branch 7 taken 19533689 times.
✓ Branch 8 taken 9585551 times.
✓ Branch 9 taken 12115585 times.
✓ Branch 10 taken 5681749 times.
✓ Branch 11 taken 2598412 times.
✓ Branch 12 taken 5392442 times.
✓ Branch 13 taken 2499252 times.
✓ Branch 14 taken 3228126 times.
✓ Branch 15 taken 12386316 times.
✓ Branch 16 taken 10823794 times.
✓ Branch 17 taken 12713644 times.
✓ Branch 18 taken 24756840 times.
✓ Branch 19 taken 19280488 times.
✓ Branch 20 taken 19066006 times.
✓ Branch 21 taken 16505164 times.
✓ Branch 22 taken 4780448 times.
✓ Branch 23 taken 5119084 times.
✓ Branch 24 taken 5149108 times.
✓ Branch 25 taken 6218552 times.
✓ Branch 26 taken 6404618 times.
✓ Branch 27 taken 1262668 times.
✓ Branch 28 taken 1255910 times.
✓ Branch 29 taken 168726 times.
✓ Branch 30 taken 5536 times.
✓ Branch 31 taken 5526 times.
✓ Branch 32 taken 5536 times.
✓ Branch 33 taken 3504 times.
✓ Branch 34 taken 432 times.
✓ Branch 35 taken 3504 times.
✓ Branch 36 taken 432 times.
|
197742542 | { return volumeVariables_[getLocalIdx_(scvIdx)]; } |
343 | |||
344 | //! access operator with scv index | ||
345 | VolumeVariables& operator [](std::size_t scvIdx) | ||
346 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 94620 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 94620 times.
|
94620 | { return volumeVariables_[getLocalIdx_(scvIdx)]; } |
347 | |||
348 | /*! | ||
349 | * \brief bind the local view (r-value overload) | ||
350 | * This overload is called when an instance of this class is a temporary in the usage context | ||
351 | * This allows a usage like this: `const auto view = localView(...).bind(element);` | ||
352 | */ | ||
353 | template<class FVElementGeometry, class SolutionVector> | ||
354 | 104003 | CCMpfaElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
355 | const FVElementGeometry& fvGeometry, | ||
356 | const SolutionVector& sol) && | ||
357 | { | ||
358 | 104003 | this->bind_(element, fvGeometry, sol); | |
359 | 208006 | return std::move(*this); | |
360 | } | ||
361 | |||
362 | template<class FVElementGeometry, class SolutionVector> | ||
363 | void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
364 | const FVElementGeometry& fvGeometry, | ||
365 | const SolutionVector& sol) & | ||
366 |
5/8✓ Branch 1 taken 2728 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✓ Branch 5 taken 12272 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 164 times.
✓ Branch 9 taken 1928 times.
✗ Branch 10 not taken.
|
1413698 | { this->bind_(element, fvGeometry, sol); } |
367 | |||
368 | /*! | ||
369 | * \brief bind the local view (r-value overload) | ||
370 | * This overload is called when an instance of this class is a temporary in the usage context | ||
371 | * This allows a usage like this: `const auto view = localView(...).bind(element);` | ||
372 | */ | ||
373 | template<class FVElementGeometry, class SolutionVector> | ||
374 | CCMpfaElementVolumeVariables bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
375 | const FVElementGeometry& fvGeometry, | ||
376 | const SolutionVector& sol) && | ||
377 | { | ||
378 | this->bindElement_(element, fvGeometry, sol); | ||
379 | return std::move(*this); | ||
380 | } | ||
381 | |||
382 | template<class FVElementGeometry, class SolutionVector> | ||
383 | void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
384 | const FVElementGeometry& fvGeometry, | ||
385 | const SolutionVector& sol) & | ||
386 |
2/4✓ Branch 1 taken 85976 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31192 times.
✗ Branch 5 not taken.
|
1434080 | { this->bindElement_(element, fvGeometry, sol); } |
387 | |||
388 | //! The global volume variables object we are a restriction of | ||
389 | ✗ | const GridVolumeVariables& gridVolVars() const | |
390 | ✗ | { return *gridVolVarsPtr_; } | |
391 | |||
392 | //! Clear all local storage | ||
393 | void clear() | ||
394 | { | ||
395 | 5802762 | volVarIndices_.clear(); | |
396 |
7/8✓ Branch 0 taken 82438 times.
✓ Branch 1 taken 366050 times.
✓ Branch 2 taken 49831 times.
✓ Branch 3 taken 1380950 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1014000 times.
✓ Branch 6 taken 1927 times.
✓ Branch 7 taken 6185 times.
|
2901381 | volumeVariables_.clear(); |
397 | } | ||
398 | |||
399 | private: | ||
400 | |||
401 | //! Prepares the volume variables within the element stencil | ||
402 | template<class FVElementGeometry, class SolutionVector> | ||
403 | 2489413 | void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
404 | const FVElementGeometry& fvGeometry, | ||
405 | const SolutionVector& sol) | ||
406 | { | ||
407 |
2/2✓ Branch 0 taken 17156 times.
✓ Branch 1 taken 1450145 times.
|
2489413 | clear(); |
408 | |||
409 | 2489413 | const auto& problem = gridVolVars().problem(); | |
410 | 2489413 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
411 | |||
412 | // stencil information | ||
413 | 4978826 | const auto globalI = gridGeometry.elementMapper().index(element); | |
414 | 2489413 | const auto& assemblyMapI = gridGeometry.connectivityMap()[globalI]; | |
415 | 2489413 | const auto numVolVars = assemblyMapI.size() + 1; | |
416 | |||
417 | // resize local containers to the required size (for internal elements) | ||
418 | 2489413 | const auto maxNumBoundaryVolVars = CCMpfa::maxNumBoundaryVolVars(fvGeometry); | |
419 | 2489413 | volumeVariables_.reserve(numVolVars+maxNumBoundaryVolVars); | |
420 | 2489413 | volVarIndices_.reserve(numVolVars+maxNumBoundaryVolVars); | |
421 | |||
422 |
1/2✓ Branch 0 taken 1467301 times.
✗ Branch 1 not taken.
|
2489413 | VolumeVariables volVars; |
423 |
1/2✓ Branch 0 taken 1467301 times.
✗ Branch 1 not taken.
|
2489413 | const auto& scvI = fvGeometry.scv(globalI); |
424 | 2489413 | volVars.update(elementSolution(element, sol, gridGeometry), | |
425 | problem, | ||
426 | element, | ||
427 | scvI); | ||
428 | |||
429 | 4978826 | volVarIndices_.push_back(scvI.dofIndex()); | |
430 | 2489413 | volumeVariables_.emplace_back(std::move(volVars)); | |
431 | |||
432 | // Update the volume variables of the neighboring elements | ||
433 |
4/4✓ Branch 0 taken 15396705 times.
✓ Branch 1 taken 1467301 times.
✓ Branch 2 taken 15396705 times.
✓ Branch 3 taken 1467301 times.
|
61809849 | for (auto&& dataJ : assemblyMapI) |
434 | { | ||
435 |
1/2✓ Branch 1 taken 15396705 times.
✗ Branch 2 not taken.
|
54341610 | const auto& elementJ = gridGeometry.element(dataJ.globalJ); |
436 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15396705 times.
|
27666081 | const auto& scvJ = fvGeometry.scv(dataJ.globalJ); |
437 |
1/2✓ Branch 1 taken 14488745 times.
✗ Branch 2 not taken.
|
27666081 | VolumeVariables volVarsJ; |
438 |
3/5✓ Branch 1 taken 14488745 times.
✓ Branch 2 taken 901120 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14486225 times.
✗ Branch 5 not taken.
|
27666081 | volVarsJ.update(elementSolution(elementJ, sol, gridGeometry), |
439 | problem, | ||
440 | elementJ, | ||
441 | scvJ); | ||
442 | |||
443 |
2/4✓ Branch 1 taken 15396705 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15396705 times.
✗ Branch 5 not taken.
|
55332162 | volVarIndices_.push_back(scvJ.dofIndex()); |
444 |
1/2✓ Branch 1 taken 15396705 times.
✗ Branch 2 not taken.
|
27666081 | volumeVariables_.emplace_back(std::move(volVarsJ)); |
445 | } | ||
446 | |||
447 | // maybe prepare boundary volume variables | ||
448 |
2/2✓ Branch 0 taken 172564 times.
✓ Branch 1 taken 1294737 times.
|
2489413 | if (maxNumBoundaryVolVars > 0) |
449 | 250180 | CCMpfa::addBoundaryVolVars(volumeVariables_, volVarIndices_, problem, element, fvGeometry); | |
450 | |||
451 | // //! TODO Check if user added additional DOF dependencies, i.e. the residual of DOF globalI depends | ||
452 | // //! on additional DOFs not included in the discretization schemes' occupation pattern | ||
453 | // const auto& additionalDofDependencies = problem.getAdditionalDofDependencies(globalI); | ||
454 | // if (!additionalDofDependencies.empty()) | ||
455 | // { | ||
456 | // volumeVariables_.reserve(volumeVariables_.size() + additionalDofDependencies.size()); | ||
457 | // volVarIndices_.reserve(volVarIndices_.size() + additionalDofDependencies.size()); | ||
458 | // for (auto globalJ : additionalDofDependencies) | ||
459 | // { | ||
460 | // const auto& elementJ = gridGeometry.element(globalJ); | ||
461 | // const auto& scvJ = fvGeometry.scv(globalJ); | ||
462 | |||
463 | // VolumeVariables additionalVolVars; | ||
464 | // additionalVolVars.update(elementSolution(elementJ, sol, gridGeometry), | ||
465 | // problem, | ||
466 | // elementJ, | ||
467 | // scvJ); | ||
468 | |||
469 | // volumeVariables_.emplace_back(std::move(additionalVolVars)); | ||
470 | // volVarIndices_.push_back(globalJ); | ||
471 | // } | ||
472 | // } | ||
473 | 2489413 | } | |
474 | |||
475 | //! Prepares the volume variables of an element | ||
476 | template<class FVElementGeometry, class SolutionVector> | ||
477 | 2421216 | void bindElement_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
478 | const FVElementGeometry& fvGeometry, | ||
479 | const SolutionVector& sol) | ||
480 | { | ||
481 |
2/2✓ Branch 0 taken 117040 times.
✓ Branch 1 taken 1317040 times.
|
2421216 | clear(); |
482 | |||
483 | 2421216 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
484 | 4842432 | auto eIdx = gridGeometry.elementMapper().index(element); | |
485 | 2421216 | volumeVariables_.resize(1); | |
486 | 2421216 | volVarIndices_.resize(1); | |
487 | |||
488 | // update the volume variables of the element | ||
489 |
1/2✓ Branch 0 taken 1434080 times.
✗ Branch 1 not taken.
|
2421216 | const auto& scv = fvGeometry.scv(eIdx); |
490 | 2421216 | volumeVariables_[0].update(elementSolution(element, sol, gridGeometry), | |
491 | 2421216 | gridVolVars().problem(), | |
492 | element, | ||
493 | scv); | ||
494 | 4842432 | volVarIndices_[0] = scv.dofIndex(); | |
495 | 2421216 | } | |
496 | |||
497 | const GridVolumeVariables* gridVolVarsPtr_; | ||
498 | |||
499 | //! map a global scv index to the local storage index | ||
500 | 407838145 | int getLocalIdx_(const int volVarIdx) const | |
501 | { | ||
502 | 1223514435 | auto it = std::find(volVarIndices_.begin(), volVarIndices_.end(), volVarIdx); | |
503 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 385681833 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 385681833 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 385681833 times.
|
1223514435 | assert(it != volVarIndices_.end() && "Could not find the current volume variables for volVarIdx!"); |
504 | 1223514435 | return std::distance(volVarIndices_.begin(), it); | |
505 | } | ||
506 | |||
507 | std::vector<std::size_t> volVarIndices_; | ||
508 | std::vector<VolumeVariables> volumeVariables_; | ||
509 | }; | ||
510 | |||
511 | } // end namespace Dumux | ||
512 | |||
513 | #endif | ||
514 |