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-FileCopyrightText: 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 | 13507169 | std::size_t maxNumBoundaryVolVars(const FVElementGeometry& fvGeometry) | |
39 | { | ||
40 | 13507169 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
41 | 13507169 | const auto& gridIvIndexSets = gridGeometry.gridInteractionVolumeIndexSets(); | |
42 | |||
43 | 13507169 | std::size_t numBoundaryVolVars = 0; | |
44 |
4/4✓ Branch 0 taken 100784224 times.
✓ Branch 1 taken 13492229 times.
✓ Branch 2 taken 340544 times.
✓ Branch 3 taken 44596 times.
|
114369721 | for (const auto& scvf : scvfs(fvGeometry)) |
45 | { | ||
46 |
2/2✓ Branch 0 taken 262216 times.
✓ Branch 1 taken 29656 times.
|
90929300 | if (!gridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) |
47 | 100832896 | numBoundaryVolVars += gridIvIndexSets.primaryIndexSet(scvf).nodalIndexSet().numBoundaryScvfs(); | |
48 | else | ||
49 | 29656 | numBoundaryVolVars += gridIvIndexSets.secondaryIndexSet(scvf).nodalIndexSet().numBoundaryScvfs(); | |
50 | } | ||
51 | |||
52 | 12009634 | 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 |
2/2✓ Branch 0 taken 5625560 times.
✓ Branch 1 taken 5009026 times.
|
11100282 | 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 5625560 times.
✓ Branch 1 taken 5009026 times.
|
11100282 | if (nodalIndexSet.numBoundaryScvfs() == 0) |
78 | return; | ||
79 | |||
80 | // index of the element the fvGeometry was bound to | ||
81 | 5851352 | 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 13637696 times.
✓ Branch 1 taken 14416476 times.
✓ Branch 2 taken 23215868 times.
✓ Branch 3 taken 4775632 times.
|
34559532 | for (auto scvfIdx : nodalIndexSet.gridScvfIndices()) |
85 | { | ||
86 |
3/3✓ Branch 1 taken 15266404 times.
✓ Branch 2 taken 2288520 times.
✓ Branch 0 taken 9649320 times.
|
28708180 | 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 11349176 times.
✓ Branch 1 taken 15855068 times.
✓ Branch 2 taken 4995820 times.
✓ Branch 3 taken 6353356 times.
|
28708180 | if (!ivScvf.boundary() || ivScvf.insideScvIdx() == boundElemIdx) |
90 | 22044360 | continue; | |
91 | |||
92 | 6663820 | const auto insideScvIdx = ivScvf.insideScvIdx(); | |
93 |
2/2✓ Branch 0 taken 389788 times.
✓ Branch 1 taken 1869056 times.
|
6663820 | const auto insideElement = fvGeometry.gridGeometry().element(insideScvIdx); |
94 |
4/4✓ Branch 0 taken 764204 times.
✓ Branch 1 taken 5589152 times.
✓ Branch 2 taken 12396 times.
✓ Branch 3 taken 33832 times.
|
6710048 | 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 |
2/2✓ Branch 0 taken 826582 times.
✓ Branch 1 taken 5526774 times.
|
6663820 | if (bcTypes.hasOnlyDirichlet()) |
99 | { | ||
100 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 552618 times.
✗ Branch 2 not taken.
|
827102 | VolumeVariables dirichletVolVars; |
101 |
1/2✓ Branch 1 taken 147026 times.
✗ Branch 2 not taken.
|
1212886 | dirichletVolVars.update(elementSolution<FVElemGeom>(problem.dirichlet(insideElement, ivScvf)), |
102 | problem, | ||
103 | insideElement, | ||
104 |
2/3✓ Branch 1 taken 501130 times.
✗ Branch 2 not taken.
✓ Branch 0 taken 26488 times.
|
827102 | fvGeometry.scv(insideScvIdx)); |
105 | |||
106 |
1/2✓ Branch 1 taken 527434 times.
✗ Branch 2 not taken.
|
827102 | volVars.emplace_back(std::move(dirichletVolVars)); |
107 |
1/2✓ Branch 1 taken 527434 times.
✗ Branch 2 not taken.
|
827102 | 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 |
2/2✓ Branch 0 taken 1150319 times.
✓ Branch 1 taken 333636 times.
|
1561571 | 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 |
2/2✓ Branch 0 taken 1150319 times.
✓ Branch 1 taken 333636 times.
|
1561571 | const auto& gridGeometry = fvGeometry.gridGeometry(); |
131 | |||
132 | // treat the BCs inside the element | ||
133 |
2/2✓ Branch 0 taken 1150319 times.
✓ Branch 1 taken 333636 times.
|
1561571 | if (fvGeometry.hasBoundaryScvf()) |
134 | { | ||
135 |
2/2✓ Branch 1 taken 103200 times.
✓ Branch 2 taken 35000 times.
|
1185599 | const auto boundElemIdx = gridGeometry.elementMapper().index(element); |
136 | 1185599 | const auto& scvI = fvGeometry.scv(boundElemIdx); | |
137 | |||
138 |
4/4✓ Branch 0 taken 6110154 times.
✓ Branch 1 taken 2497910 times.
✓ Branch 2 taken 8608064 times.
✓ Branch 3 taken 1150319 times.
|
10005343 | for (const auto& scvf : scvfs(fvGeometry)) |
139 | { | ||
140 |
2/2✓ Branch 0 taken 6110154 times.
✓ Branch 1 taken 2497910 times.
|
8819744 | if (!scvf.boundary()) |
141 | 6251274 | continue; | |
142 | |||
143 | // Only proceed on dirichlet boundaries. On Neumann | ||
144 | // boundaries the "outside" vol vars cannot be properly defined. | ||
145 |
4/4✓ Branch 0 taken 287918 times.
✓ Branch 1 taken 2008506 times.
✓ Branch 2 taken 207222 times.
✓ Branch 3 taken 12884 times.
|
2587090 | if (problem.boundaryTypes(element, scvf).hasOnlyDirichlet()) |
146 | { | ||
147 | 315980 | VolumeVariables dirichletVolVars; | |
148 |
5/6✓ Branch 0 taken 14058 times.
✓ Branch 1 taken 125242 times.
✓ Branch 3 taken 27972 times.
✓ Branch 4 taken 11872 times.
✓ Branch 2 taken 137968 times.
✗ Branch 5 not taken.
|
333118 | dirichletVolVars.update(elementSolution<FVElemGeom>(problem.dirichlet(element, scvf)), |
149 | problem, | ||
150 | element, | ||
151 | scvI); | ||
152 | |||
153 |
1/2✓ Branch 1 taken 277860 times.
✗ Branch 2 not taken.
|
315980 | volVars.emplace_back(std::move(dirichletVolVars)); |
154 |
1/2✓ Branch 1 taken 277860 times.
✗ Branch 2 not taken.
|
315980 | volVarIndices.push_back(scvf.outsideScvIdx()); |
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | // Update boundary volume variables in the neighbors | ||
160 | 1561571 | const auto& gridIvIndexSets = gridGeometry.gridInteractionVolumeIndexSets(); | |
161 |
4/4✓ Branch 0 taken 28136 times.
✓ Branch 1 taken 10606450 times.
✓ Branch 2 taken 1534523 times.
✓ Branch 3 taken 7224 times.
|
12661853 | for (const auto& scvf : scvfs(fvGeometry)) |
162 | { | ||
163 |
2/2✓ Branch 0 taken 28136 times.
✓ Branch 1 taken 29656 times.
|
11100282 | if (!gridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) |
164 | 11070626 | addBoundaryVolVarsAtNode( volVars, volVarIndices, problem, element, fvGeometry, | |
165 | 11070626 | gridIvIndexSets.primaryIndexSet(scvf).nodalIndexSet() ); | |
166 | else | ||
167 | 29656 | addBoundaryVolVarsAtNode( volVars, volVarIndices, problem, element, fvGeometry, | |
168 | 29656 | gridIvIndexSets.secondaryIndexSet(scvf).nodalIndexSet() ); | |
169 | } | ||
170 | 1561571 | } | |
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 |
5/10✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 21 taken 339 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 339 times.
✗ Branch 26 not taken.
✓ Branch 33 taken 158 times.
✗ Branch 34 not taken.
✓ Branch 39 taken 159 times.
✗ Branch 40 not taken.
|
580075 | 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 | 7514790 | CCMpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars) | |
200 |
6/11✓ Branch 1 taken 105 times.
✓ Branch 2 taken 1283454 times.
✓ Branch 4 taken 6215316 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1741 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13214 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 186 times.
✗ Branch 14 not taken.
✗ Branch 3 not taken.
|
7514790 | : gridVolVarsPtr_(&gridVolVars) |
201 |
6/11✓ Branch 1 taken 105 times.
✓ Branch 2 taken 1283454 times.
✓ Branch 4 taken 6215316 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1741 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13214 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 186 times.
✗ Branch 14 not taken.
✗ Branch 3 not taken.
|
7514790 | , 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 |
1/2✓ Branch 0 taken 816264172 times.
✗ Branch 1 not taken.
|
816264172 | const VolumeVariables& operator [](const SubControlVolume& scv) const |
207 | { | ||
208 |
1/2✓ Branch 0 taken 816264172 times.
✗ Branch 1 not taken.
|
816264172 | return scv.dofIndex() < numScv_ ? gridVolVars().volVars(scv.dofIndex()) |
209 | ✗ | : boundaryVolVars_[getLocalIdx_(scv.dofIndex())]; | |
210 | } | ||
211 | |||
212 | //! operator for the access with an index | ||
213 | 2587662748 | const VolumeVariables& operator [](const std::size_t scvIdx) const | |
214 | { | ||
215 |
2/2✓ Branch 0 taken 2582754856 times.
✓ Branch 1 taken 4907892 times.
|
2587662748 | return scvIdx < numScv_ ? gridVolVars().volVars(scvIdx) |
216 | 4907892 | : 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 | 343 | CCMpfaElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
226 | const FVElementGeometry& fvGeometry, | ||
227 | const SolutionVector& sol) && | ||
228 | { | ||
229 |
1/2✓ Branch 1 taken 343 times.
✗ Branch 2 not taken.
|
343 | this->bind_(element, fvGeometry, sol); |
230 | 343 | return std::move(*this); | |
231 | } | ||
232 | |||
233 | template<class FVElementGeometry, class SolutionVector> | ||
234 | 11996235 | 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 5 taken 4456913 times.
✗ Branch 6 not taken.
|
11996235 | { 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 | 17412 | void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
255 | const FVElementGeometry& fvGeometry, | ||
256 | const SolutionVector& sol) & | ||
257 | 17412 | { this->bindElement_(element, fvGeometry, sol); } | |
258 | |||
259 | //! Clear all local storage | ||
260 | 11996578 | void clear() | |
261 | { | ||
262 | 23993156 | boundaryVolVarIndices_.clear(); | |
263 |
2/2✓ Branch 0 taken 88472 times.
✓ Branch 1 taken 11908106 times.
|
11996578 | boundaryVolVars_.clear(); |
264 | } | ||
265 | |||
266 | //! The global volume variables object we are a restriction of | ||
267 | 3400322237 | const GridVolumeVariables& gridVolVars() const | |
268 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
3399019046 | { return *gridVolVarsPtr_; } |
269 | |||
270 | private: | ||
271 | //! map a global scv index to the local storage index | ||
272 | 4907892 | int getLocalIdx_(const int volVarIdx) const | |
273 | { | ||
274 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4907892 times.
|
4907892 | auto it = std::find(boundaryVolVarIndices_.begin(), boundaryVolVarIndices_.end(), volVarIdx); |
275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4907892 times.
|
4907892 | assert(it != boundaryVolVarIndices_.end() && "Could not find the current volume variables for volVarIdx!"); |
276 | 4907892 | 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 |
2/2✓ Branch 0 taken 88472 times.
✓ Branch 1 taken 11908106 times.
|
11996578 | void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, |
282 | const FVElementGeometry& fvGeometry, | ||
283 | const SolutionVector& sol) | ||
284 | { | ||
285 | 11996578 | clear(); | |
286 | |||
287 | // maybe prepare boundary volume variables | ||
288 | 11996578 | const auto maxNumBoundaryVolVars = CCMpfa::maxNumBoundaryVolVars(fvGeometry); | |
289 |
2/2✓ Branch 0 taken 1303191 times.
✓ Branch 1 taken 10693387 times.
|
11996578 | if (maxNumBoundaryVolVars > 0) |
290 | { | ||
291 | 1303191 | boundaryVolVars_.reserve(maxNumBoundaryVolVars); | |
292 | 1303191 | boundaryVolVarIndices_.reserve(maxNumBoundaryVolVars); | |
293 | 1303191 | CCMpfa::addBoundaryVolVars(boundaryVolVars_, boundaryVolVarIndices_, gridVolVars().problem(), element, fvGeometry); | |
294 | } | ||
295 | 11996578 | } | |
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 |
1/2✓ Branch 7 taken 585 times.
✗ Branch 8 not taken.
|
168907 | 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 | 1493564 | CCMpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars) | |
328 |
8/16✓ Branch 1 taken 122 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 223667 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 249888 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5786 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 50000 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 964000 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 100 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
|
1493564 | : 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 | 9514230 | const VolumeVariables& operator [](const SubControlVolume& scv) const | |
333 |
8/18✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 8 taken 9995484 times.
✗ Branch 9 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 37820 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 124088 times.
✓ Branch 14 taken 3231730 times.
✓ Branch 15 taken 264 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 24 taken 9212046 times.
✗ Branch 25 not taken.
✓ Branch 7 taken 792 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 2892000 times.
✗ Branch 6 not taken.
|
173424611 | { 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 | 1522745 | VolumeVariables& operator [](const SubControlVolume& scv) | |
338 |
2/4✓ Branch 3 taken 65376 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9984 times.
✗ Branch 6 not taken.
|
1522745 | { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; } |
339 | |||
340 | //! access operator with scv index | ||
341 | 252392487 | const VolumeVariables& operator [](std::size_t scvIdx) const | |
342 |
20/20✓ Branch 1 taken 1007968 times.
✓ Branch 2 taken 24030020 times.
✓ Branch 4 taken 6786030 times.
✓ Branch 5 taken 21970241 times.
✓ Branch 6 taken 5609565 times.
✓ Branch 7 taken 2589980 times.
✓ Branch 8 taken 2915758 times.
✓ Branch 9 taken 5077016 times.
✓ Branch 10 taken 17327964 times.
✓ Branch 11 taken 22226860 times.
✓ Branch 13 taken 5936912 times.
✓ Branch 14 taken 6104304 times.
✓ Branch 12 taken 20003712 times.
✓ Branch 16 taken 9999114 times.
✓ Branch 17 taken 10026978 times.
✓ Branch 19 taken 5958 times.
✓ Branch 20 taken 5536 times.
✓ Branch 3 taken 8060 times.
✓ Branch 18 taken 3504 times.
✓ Branch 15 taken 172806 times.
|
250495086 | { return volumeVariables_[getLocalIdx_(scvIdx)]; } |
343 | |||
344 | //! access operator with scv index | ||
345 | 122340 | VolumeVariables& operator [](std::size_t scvIdx) | |
346 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 122340 times.
|
122340 | { 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 | 54373 | CCMpfaElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
355 | const FVElementGeometry& fvGeometry, | ||
356 | const SolutionVector& sol) && | ||
357 | { | ||
358 |
3/6✓ Branch 1 taken 4273 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 50000 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 100 times.
✗ Branch 10 not taken.
|
54373 | this->bind_(element, fvGeometry, sol); |
359 | 54373 | return std::move(*this); | |
360 | } | ||
361 | |||
362 | template<class FVElementGeometry, class SolutionVector> | ||
363 | 1456218 | 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 9 taken 1928 times.
✗ Branch 10 not taken.
✓ Branch 8 taken 164 times.
✗ Branch 6 not taken.
|
1456218 | { 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 | 1476680 | 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 86056 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31192 times.
✗ Branch 5 not taken.
|
1476680 | { this->bindElement_(element, fvGeometry, sol); } |
387 | |||
388 | //! The global volume variables object we are a restriction of | ||
389 | 2987296 | const GridVolumeVariables& gridVolVars() const | |
390 |
3/6✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
2475796 | { return *gridVolVarsPtr_; } |
391 | |||
392 | //! Clear all local storage | ||
393 | 2987271 | void clear() | |
394 | { | ||
395 | 5974542 | volVarIndices_.clear(); | |
396 |
7/8✓ Branch 0 taken 82517 times.
✓ Branch 1 taken 408571 times.
✓ Branch 2 taken 49831 times.
✓ Branch 3 taken 1424240 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1014000 times.
✓ Branch 6 taken 1927 times.
✓ Branch 7 taken 6185 times.
|
2987271 | volumeVariables_.clear(); |
397 | } | ||
398 | |||
399 | private: | ||
400 | |||
401 | //! Prepares the volume variables within the element stencil | ||
402 | template<class FVElementGeometry, class SolutionVector> | ||
403 |
2/2✓ Branch 0 taken 17156 times.
✓ Branch 1 taken 1493435 times.
|
2532703 | void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, |
404 | const FVElementGeometry& fvGeometry, | ||
405 | const SolutionVector& sol) | ||
406 | { | ||
407 | 2532703 | clear(); | |
408 | |||
409 | 2532703 | const auto& problem = gridVolVars().problem(); | |
410 | 2532703 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
411 | |||
412 | // stencil information | ||
413 | 2532703 | const auto globalI = gridGeometry.elementMapper().index(element); | |
414 | 2532703 | const auto& assemblyMapI = gridGeometry.connectivityMap()[globalI]; | |
415 | 2532703 | const auto numVolVars = assemblyMapI.size() + 1; | |
416 | |||
417 | // resize local containers to the required size (for internal elements) | ||
418 | 2532703 | const auto maxNumBoundaryVolVars = CCMpfa::maxNumBoundaryVolVars(fvGeometry); | |
419 | 2532703 | volumeVariables_.reserve(numVolVars+maxNumBoundaryVolVars); | |
420 | 2532703 | volVarIndices_.reserve(numVolVars+maxNumBoundaryVolVars); | |
421 | |||
422 |
1/2✓ Branch 0 taken 1510591 times.
✗ Branch 1 not taken.
|
2532703 | VolumeVariables volVars; |
423 | 2532703 | const auto& scvI = fvGeometry.scv(globalI); | |
424 | 2532703 | volVars.update(elementSolution(element, sol, gridGeometry), | |
425 | problem, | ||
426 | element, | ||
427 | scvI); | ||
428 | |||
429 | 2532703 | volVarIndices_.push_back(scvI.dofIndex()); | |
430 | 2532703 | volumeVariables_.emplace_back(std::move(volVars)); | |
431 | |||
432 | // Update the volume variables of the neighboring elements | ||
433 |
2/2✓ Branch 0 taken 15710483 times.
✓ Branch 1 taken 1510591 times.
|
30512562 | for (auto&& dataJ : assemblyMapI) |
434 | { | ||
435 | 27979859 | const auto& elementJ = gridGeometry.element(dataJ.globalJ); | |
436 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 15710483 times.
✓ Branch 3 taken 14715033 times.
✗ Branch 4 not taken.
|
55959718 | const auto& scvJ = fvGeometry.scv(dataJ.globalJ); |
437 |
1/2✓ Branch 1 taken 14715033 times.
✗ Branch 2 not taken.
|
27979859 | VolumeVariables volVarsJ; |
438 |
1/2✓ Branch 1 taken 14715033 times.
✗ Branch 2 not taken.
|
27979859 | volVarsJ.update(elementSolution(elementJ, sol, gridGeometry), |
439 | problem, | ||
440 | elementJ, | ||
441 | scvJ); | ||
442 | |||
443 |
1/2✓ Branch 1 taken 14715033 times.
✗ Branch 2 not taken.
|
27979859 | volVarIndices_.push_back(scvJ.dofIndex()); |
444 |
1/2✓ Branch 1 taken 14715033 times.
✗ Branch 2 not taken.
|
27979859 | volumeVariables_.emplace_back(std::move(volVarsJ)); |
445 | } | ||
446 | |||
447 | // maybe prepare boundary volume variables | ||
448 |
2/2✓ Branch 0 taken 180764 times.
✓ Branch 1 taken 1329827 times.
|
2532703 | if (maxNumBoundaryVolVars > 0) |
449 | 258380 | 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 | 2532703 | } | |
474 | |||
475 | //! Prepares the volume variables of an element | ||
476 | template<class FVElementGeometry, class SolutionVector> | ||
477 |
2/2✓ Branch 0 taken 117119 times.
✓ Branch 1 taken 1359561 times.
|
2463816 | void bindElement_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element, |
478 | const FVElementGeometry& fvGeometry, | ||
479 | const SolutionVector& sol) | ||
480 | { | ||
481 | 2463816 | clear(); | |
482 | |||
483 | 2463816 | const auto& gridGeometry = fvGeometry.gridGeometry(); | |
484 | 2463816 | auto eIdx = gridGeometry.elementMapper().index(element); | |
485 | 2463816 | volumeVariables_.resize(1); | |
486 |
1/2✓ Branch 1 taken 1476680 times.
✗ Branch 2 not taken.
|
2463816 | volVarIndices_.resize(1); |
487 | |||
488 | // update the volume variables of the element | ||
489 | 2463816 | const auto& scv = fvGeometry.scv(eIdx); | |
490 | 2463816 | volumeVariables_[0].update(elementSolution(element, sol, gridGeometry), | |
491 | 2463816 | gridVolVars().problem(), | |
492 | element, | ||
493 | scv); | ||
494 | 2463816 | volVarIndices_[0] = scv.dofIndex(); | |
495 | 2463816 | } | |
496 | |||
497 | const GridVolumeVariables* gridVolVarsPtr_; | ||
498 | |||
499 | //! map a global scv index to the local storage index | ||
500 | 488910658 | int getLocalIdx_(const int volVarIdx) const | |
501 | { | ||
502 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 466754346 times.
|
488910658 | auto it = std::find(volVarIndices_.begin(), volVarIndices_.end(), volVarIdx); |
503 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 466754346 times.
|
488910658 | assert(it != volVarIndices_.end() && "Could not find the current volume variables for volVarIdx!"); |
504 | 488910658 | 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 |