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 PorousmediumflowModels | ||
10 | * \brief The primary variable switch base class for compositional models. | ||
11 | */ | ||
12 | |||
13 | #ifndef DUMUX_PRIMARY_VARIABLE_SWITCH_HH | ||
14 | #define DUMUX_PRIMARY_VARIABLE_SWITCH_HH | ||
15 | |||
16 | #include <iostream> | ||
17 | |||
18 | #include <dune/common/exceptions.hh> | ||
19 | #include <dune/common/fvector.hh> | ||
20 | #include <dumux/discretization/method.hh> | ||
21 | #include <dumux/discretization/elementsolution.hh> | ||
22 | |||
23 | namespace Dumux { | ||
24 | |||
25 | /*! | ||
26 | * \ingroup PorousmediumflowModels | ||
27 | * \brief Empty class for models without pri var switch. | ||
28 | */ | ||
29 | class NoPrimaryVariableSwitch | ||
30 | { | ||
31 | public: | ||
32 | template<typename... Args> | ||
33 | NoPrimaryVariableSwitch(Args&&...) {} | ||
34 | |||
35 | template<typename... Args> void reset(Args&&...) {} | ||
36 | template<typename... Args> bool wasSwitched(Args&&...) const { return false; } | ||
37 | template<typename... Args> bool update(Args&&...) { return false; } | ||
38 | template<typename... Args> void updateSwitchedVolVars(Args&&...) {} | ||
39 | template<typename... Args> void updateSwitchedFluxVarsCache(Args&&...) {} | ||
40 | template<typename... Args> void updateDirichletConstraints(Args&&...) {} | ||
41 | }; | ||
42 | |||
43 | /*! | ||
44 | * \ingroup PorousmediumflowModels | ||
45 | * \brief The primary variable switch controlling the phase presence state variable. | ||
46 | */ | ||
47 | template<class Implementation> | ||
48 | 61 | class PrimaryVariableSwitch | |
49 | { | ||
50 | public: | ||
51 | 61 | PrimaryVariableSwitch(int verbosity = 1) | |
52 | 61 | : verbosity_(verbosity) | |
53 | {} | ||
54 | |||
55 | //! If the primary variables were recently switched | ||
56 | 3416051 | bool wasSwitched(std::size_t dofIdxGlobal) const | |
57 | { | ||
58 | 3416051 | return wasSwitched_[dofIdxGlobal]; | |
59 | } | ||
60 | |||
61 | //! Reset all flags | ||
62 | 3292 | void reset(const std::size_t numDofs) | |
63 | { | ||
64 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 631 times.
|
3292 | wasSwitched_.assign(numDofs, false); |
65 | } | ||
66 | |||
67 | /*! | ||
68 | * \brief Updates the variable switch / phase presence. | ||
69 | * | ||
70 | * \param curSol The current solution to be updated / modified | ||
71 | * \param gridVariables The secondary variables on the grid | ||
72 | * \param problem The problem | ||
73 | * \param gridGeometry The finite-volume grid geometry | ||
74 | */ | ||
75 | template<class SolutionVector, class GridVariables, class Problem> | ||
76 | 14274 | bool update(SolutionVector& curSol, | |
77 | GridVariables& gridVariables, | ||
78 | const Problem& problem, | ||
79 | const typename GridVariables::GridGeometry& gridGeometry) | ||
80 | { | ||
81 | 14274 | bool switched = false; | |
82 | 14274 | bool successfulUpdate = false; | |
83 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11999 times.
|
14274 | const auto& comm = gridGeometry.gridView().comm(); |
84 | |||
85 | try { | ||
86 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 14274 times.
✓ Branch 3 taken 14274 times.
✗ Branch 4 not taken.
|
14274 | visited_.assign(wasSwitched_.size(), false); |
87 |
1/2✓ Branch 1 taken 13531 times.
✗ Branch 2 not taken.
|
14274 | std::size_t countSwitched = 0; |
88 | |||
89 |
1/2✓ Branch 1 taken 13462 times.
✗ Branch 2 not taken.
|
14274 | auto fvGeometry = localView(gridGeometry); |
90 |
1/2✓ Branch 1 taken 13531 times.
✗ Branch 2 not taken.
|
14274 | auto elemVolVars = localView(gridVariables.curGridVolVars()); |
91 | |||
92 |
10/14✓ Branch 1 taken 13531 times.
✓ Branch 2 taken 2945 times.
✓ Branch 4 taken 2325633 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1375507 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6077168 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1255952 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1254177 times.
✓ Branch 16 taken 500 times.
✓ Branch 12 taken 4822991 times.
✓ Branch 3 taken 730 times.
|
20371792 | for (const auto& element : elements(gridGeometry.gridView())) |
93 | { | ||
94 | // make sure FVElementGeometry is bound to the element | ||
95 |
2/2✓ Branch 1 taken 7453340 times.
✓ Branch 2 taken 5 times.
|
8392225 | fvGeometry.bindElement(element); |
96 |
2/2✓ Branch 1 taken 7773173 times.
✓ Branch 2 taken 18 times.
|
8392220 | elemVolVars.bindElement(element, fvGeometry, curSol); |
97 | |||
98 | 8398066 | const auto curElemSol = elementSolution(element, curSol, gridGeometry); | |
99 |
3/3✓ Branch 0 taken 19364238 times.
✓ Branch 1 taken 8392202 times.
✓ Branch 2 taken 102500 times.
|
27858940 | for (auto&& scv : scvs(fvGeometry)) |
100 | { | ||
101 |
2/3✓ Branch 0 taken 10830698 times.
✓ Branch 1 taken 7077330 times.
✗ Branch 2 not taken.
|
23703836 | if (!asImp_().skipDof_(element, fvGeometry, scv, problem)) |
102 | { | ||
103 | 8633838 | const auto dofIdxGlobal = scv.dofIndex(); | |
104 | // Note this implies that volume variables don't differ | ||
105 | // in any sub control volume associated with the dof! | ||
106 |
1/2✓ Branch 1 taken 7077330 times.
✗ Branch 2 not taken.
|
8636040 | visited_[dofIdxGlobal] = true; |
107 | // Compute volVars on which grounds we decide | ||
108 | // if we need to switch the primary variables | ||
109 | 10187950 | auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv); | |
110 |
1/2✓ Branch 1 taken 2678388 times.
✗ Branch 2 not taken.
|
8636040 | volVars.update(curElemSol, problem, element, scv); |
111 | |||
112 |
3/4✓ Branch 1 taken 8636040 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8631494 times.
✓ Branch 4 taken 4546 times.
|
8636040 | if (asImp_().update_(curSol[dofIdxGlobal], volVars, dofIdxGlobal, scv.dofPosition())) |
113 | { | ||
114 | 4546 | switched = true; | |
115 | 4546 | ++countSwitched; | |
116 | } | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 |
3/4✓ Branch 0 taken 14251 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1037 times.
✓ Branch 3 taken 13214 times.
|
14251 | if (verbosity_ > 0 && countSwitched > 0) |
122 |
3/6✓ Branch 1 taken 1037 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1037 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 913 times.
✗ Branch 8 not taken.
|
1037 | std::cout << "Switched primary variables at " << countSwitched << " dof locations on processor " |
123 |
3/6✓ Branch 1 taken 1037 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1037 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1037 times.
✗ Branch 8 not taken.
|
1037 | << comm.rank() << "." << std::endl; |
124 | |||
125 |
1/2✓ Branch 0 taken 4890 times.
✗ Branch 1 not taken.
|
14251 | successfulUpdate = true; |
126 | 14862 | } | |
127 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
|
23 | catch (const Dumux::NumericalProblem& e) |
128 | { | ||
129 |
1/2✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
|
23 | if (verbosity_ > 0) |
130 |
2/4✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
|
23 | std::cout << "Primary variable switch caught: \"" << e.what() << "\"\n"; |
131 | |||
132 | 23 | successfulUpdate = false; | |
133 | } | ||
134 | |||
135 | // make sure all processes were successful | ||
136 |
2/2✓ Branch 0 taken 1306 times.
✓ Branch 1 taken 12225 times.
|
14274 | int successfulUpdateRemote = static_cast<int>(successfulUpdate); |
137 |
2/2✓ Branch 0 taken 1306 times.
✓ Branch 1 taken 12225 times.
|
13531 | if (comm.size() > 1) |
138 | 1306 | successfulUpdateRemote = comm.min(static_cast<int>(successfulUpdate)); | |
139 | |||
140 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 14251 times.
|
14274 | if (!successfulUpdate) |
141 |
12/24✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 23 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 23 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 23 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 23 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 23 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 23 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 23 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 23 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 23 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 23 times.
✗ Branch 36 not taken.
|
115 | DUNE_THROW(NumericalProblem, "Primary variable switch caught exception on process " << comm.rank()); |
142 | |||
143 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13521 times.
|
13521 | else if (!successfulUpdateRemote) |
144 |
2/24✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 35 taken 1306 times.
✓ Branch 36 taken 12215 times.
|
14251 | DUNE_THROW(NumericalProblem, "Primary variable switch caught exception on a remote process"); |
145 | |||
146 | // make sure that if there was a variable switch in an | ||
147 | // other partition we will also set the switch flag for our partition. | ||
148 |
2/2✓ Branch 0 taken 1306 times.
✓ Branch 1 taken 12215 times.
|
13521 | if (comm.size() > 1) |
149 | 1306 | switched = comm.max(switched); | |
150 | |||
151 | 14251 | return switched; | |
152 | } | ||
153 | |||
154 | /*! | ||
155 | * \brief Updates the volume variables whose primary variables were | ||
156 | * switched. | ||
157 | * | ||
158 | * Required when volume variables are cached globally. | ||
159 | */ | ||
160 | template<class Problem, class GridVariables, class SolutionVector> | ||
161 |
1/2✓ Branch 1 taken 1359142 times.
✗ Branch 2 not taken.
|
1505190 | void updateSwitchedVolVars(const Problem& problem, |
162 | const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
163 | const typename GridVariables::GridGeometry& gridGeometry, | ||
164 | GridVariables& gridVariables, | ||
165 | const SolutionVector& sol) | ||
166 | { | ||
167 | if constexpr (GridVariables::GridVolumeVariables::cachingEnabled) | ||
168 | { | ||
169 | // make sure FVElementGeometry is bound to the element | ||
170 |
2/4✓ Branch 1 taken 1359142 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1359142 times.
✗ Branch 4 not taken.
|
4261874 | const auto fvGeometry = localView(gridGeometry).bindElement(element); |
171 | |||
172 | // update the secondary variables if global caching is enabled | ||
173 |
4/4✓ Branch 0 taken 4807 times.
✓ Branch 1 taken 3156491 times.
✓ Branch 2 taken 3161298 times.
✓ Branch 3 taken 1505190 times.
|
4666488 | for (auto&& scv : scvs(fvGeometry)) |
174 | { | ||
175 | 3161298 | const auto dofIdxGlobal = scv.dofIndex(); | |
176 |
2/2✓ Branch 0 taken 4807 times.
✓ Branch 1 taken 3156491 times.
|
3161298 | if (asImp_().wasSwitched(dofIdxGlobal)) |
177 | { | ||
178 |
1/2✓ Branch 1 taken 3337 times.
✗ Branch 2 not taken.
|
4807 | const auto elemSol = elementSolution(element, sol, gridGeometry); |
179 |
1/2✓ Branch 1 taken 4729 times.
✗ Branch 2 not taken.
|
4807 | auto& volVars = gridVariables.curGridVolVars().volVars(scv); |
180 |
1/2✓ Branch 1 taken 4729 times.
✗ Branch 2 not taken.
|
4807 | volVars.update(elemSol, problem, element, scv); |
181 | } | ||
182 | } | ||
183 | 1359142 | } | |
184 | 1505190 | } | |
185 | |||
186 | /*! | ||
187 | * \brief Updates the fluxVars cache for dof whose primary variables were | ||
188 | * switched. | ||
189 | * | ||
190 | * Required when flux variables are cached globally (not for box method). | ||
191 | */ | ||
192 | template<class Problem, class GridVariables, class SolutionVector> | ||
193 | 254753 | void updateSwitchedFluxVarsCache(const Problem& problem, | |
194 | const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element, | ||
195 | const typename GridVariables::GridGeometry& gridGeometry, | ||
196 | GridVariables& gridVariables, | ||
197 | const SolutionVector& sol) | ||
198 | { | ||
199 | if constexpr (GridVariables::GridFluxVariablesCache::cachingEnabled | ||
200 | && GridVariables::GridGeometry::discMethod != DiscretizationMethods::box) | ||
201 | { | ||
202 | // update the flux variables if global caching is enabled | ||
203 | 254753 | const auto dofIdxGlobal = gridGeometry.dofMapper().index(element); | |
204 | |||
205 |
2/2✓ Branch 0 taken 417 times.
✓ Branch 1 taken 254336 times.
|
254753 | if (asImp_().wasSwitched(dofIdxGlobal)) |
206 | { | ||
207 | // make sure FVElementGeometry and the volume variables are bound | ||
208 |
4/6✓ Branch 1 taken 339 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 339 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 339 times.
✗ Branch 7 not taken.
|
1173 | const auto fvGeometry = localView(gridGeometry).bind(element); |
209 |
2/6✓ Branch 1 taken 417 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 417 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
756 | const auto curElemVolVars = localView(gridVariables.curGridVolVars()).bind(element, fvGeometry, sol); |
210 |
1/2✓ Branch 1 taken 417 times.
✗ Branch 2 not taken.
|
417 | gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars); |
211 | 756 | } | |
212 | } | ||
213 | 254753 | } | |
214 | |||
215 | /*! | ||
216 | * \brief Updates the the primary variables state at the boundary. | ||
217 | * | ||
218 | * Required when a Dirichlet constraint (at a boundary or internal) differs from the initial condition. | ||
219 | */ | ||
220 | template<class Problem, class GridVariables, class SolutionVector> | ||
221 | 2582 | void updateDirichletConstraints(const Problem& problem, | |
222 | const typename GridVariables::GridGeometry& gridGeometry, | ||
223 | GridVariables& gridVariables, | ||
224 | SolutionVector& sol) | ||
225 | { | ||
226 | if constexpr (GridVariables::GridGeometry::discMethod == DiscretizationMethods::box || Problem::enableInternalDirichletConstraints()) | ||
227 | { | ||
228 |
1/2✓ Branch 2 taken 2344 times.
✗ Branch 3 not taken.
|
2582 | std::vector<bool> stateChanged(sol.size(), false); |
229 | 2582 | std::size_t countChanged = 0; | |
230 | |||
231 |
13/16✓ Branch 1 taken 2344 times.
✓ Branch 2 taken 952 times.
✓ Branch 4 taken 113693 times.
✓ Branch 5 taken 247525 times.
✓ Branch 7 taken 168 times.
✓ Branch 8 taken 245402 times.
✓ Branch 10 taken 421792 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 210896 times.
✓ Branch 14 taken 210896 times.
✓ Branch 15 taken 210896 times.
✓ Branch 16 taken 210980 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 3 taken 238 times.
✓ Branch 17 taken 84 times.
|
2390018 | for (const auto& element : elements(gridGeometry.gridView())) |
232 | { | ||
233 |
6/6✓ Branch 1 taken 744160 times.
✓ Branch 2 taken 37458 times.
✓ Branch 3 taken 211372 times.
✓ Branch 4 taken 442774 times.
✓ Branch 5 taken 210896 times.
✓ Branch 6 taken 14000 times.
|
1659708 | const auto fvGeometry = localView(gridGeometry).bindElement(element); |
234 | |||
235 | // skip if the element is not at a boundary or if no internal Dirichlet constraints are set | ||
236 |
3/4✓ Branch 0 taken 715684 times.
✓ Branch 1 taken 65934 times.
✓ Branch 2 taken 196896 times.
✗ Branch 3 not taken.
|
781618 | if (!Problem::enableInternalDirichletConstraints() && !fvGeometry.hasBoundaryScvf()) |
237 | 476 | continue; | |
238 | |||
239 |
1/2✓ Branch 1 taken 54626 times.
✗ Branch 2 not taken.
|
65934 | const auto elemVolVars = localView(gridVariables.curGridVolVars()).bindElement(element, fvGeometry, sol); |
240 | |||
241 |
4/4✓ Branch 0 taken 17 times.
✓ Branch 1 taken 255715 times.
✓ Branch 2 taken 255732 times.
✓ Branch 3 taken 65934 times.
|
321666 | for (const auto& scv : scvs(fvGeometry)) |
242 | { | ||
243 | 255732 | const auto dofIdx = scv.dofIndex(); | |
244 | |||
245 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 255715 times.
|
255732 | if (stateChanged[dofIdx]) |
246 | 17 | continue; | |
247 | |||
248 | if constexpr (GridVariables::GridGeometry::discMethod == DiscretizationMethods::box) | ||
249 | { | ||
250 |
2/2✓ Branch 0 taken 106638 times.
✓ Branch 1 taken 149077 times.
|
255715 | if (gridGeometry.dofOnBoundary(dofIdx)) |
251 | { | ||
252 |
3/4✓ Branch 1 taken 149077 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 149060 times.
✓ Branch 4 taken 17 times.
|
149077 | if (handleDirichletBoundaryCondition_(problem, element, scv, sol)) |
253 | { | ||
254 | 17 | stateChanged[dofIdx] = true; | |
255 | 17 | ++countChanged; | |
256 | 17 | continue; | |
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | if constexpr (Problem::enableInternalDirichletConstraints()) | ||
262 | { | ||
263 | if (handleInternalDirichletConstraint_(problem, element, scv, sol)) | ||
264 | { | ||
265 | stateChanged[dofIdx] = true; | ||
266 | ++countChanged; | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | // update the volVars if caching is enabled | ||
272 | if constexpr (GridVariables::GridVolumeVariables::cachingEnabled) | ||
273 | { | ||
274 |
2/2✓ Branch 0 taken 229 times.
✓ Branch 1 taken 25079 times.
|
25308 | if (countChanged > 0) |
275 | { | ||
276 | 229 | const auto curElemSol = elementSolution(element, sol, gridGeometry); | |
277 |
4/4✓ Branch 0 taken 34 times.
✓ Branch 1 taken 882 times.
✓ Branch 2 taken 916 times.
✓ Branch 3 taken 229 times.
|
1145 | for (const auto& scv : scvs(fvGeometry)) |
278 | { | ||
279 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 882 times.
|
916 | if (stateChanged[scv.dofIndex()]) |
280 | { | ||
281 | 34 | auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv); | |
282 | 34 | volVars.update(curElemSol, problem, element, scv); | |
283 | } | ||
284 | } | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 |
3/4✓ Branch 0 taken 2582 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2581 times.
|
2582 | if (verbosity_ > 0 && countChanged > 0) |
290 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | std::cout << "Changed primary variable states and solution values to Dirichlet states and values at " << countChanged << " dof locations on processor " |
291 |
4/11✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
|
2582 | << gridGeometry.gridView().comm().rank() << "." << std::endl; |
292 | 2582 | } | |
293 | 2582 | } | |
294 | |||
295 | //! The verbosity level | ||
296 | 4563 | int verbosity() const | |
297 |
5/28✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3908 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 143 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 344 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 39 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
4546 | { return verbosity_; } |
298 | |||
299 | protected: | ||
300 | |||
301 | //! Return actual implementation (static polymorphism) | ||
302 | Implementation &asImp_() | ||
303 | { return *static_cast<Implementation*>(this); } | ||
304 | |||
305 | //! Return actual implementation (static polymorphism) | ||
306 | const Implementation &asImp_() const | ||
307 | { return *static_cast<const Implementation*>(this); } | ||
308 | |||
309 | // Perform variable switch at a degree of freedom location | ||
310 | template<class VolumeVariables, class GlobalPosition> | ||
311 | bool update_(typename VolumeVariables::PrimaryVariables& priVars, | ||
312 | const VolumeVariables& volVars, | ||
313 | std::size_t dofIdxGlobal, | ||
314 | const GlobalPosition& globalPos) | ||
315 | { | ||
316 | // evaluate if the primary variable switch would switch | ||
317 | // to be implemented by the deriving class | ||
318 | DUNE_THROW(Dune::NotImplemented, "This model seems to use a primary variable switch but none is implemented!"); | ||
319 | } | ||
320 | |||
321 | // Maybe skip the degree of freedom (do not switch variables at this dof) | ||
322 | template<class Geometry, class Problem> | ||
323 | 19466738 | bool skipDof_(const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
324 | const Geometry& fvGeometry, | ||
325 | const typename Geometry::SubControlVolume& scv, | ||
326 | const Problem& problem) | ||
327 | { | ||
328 |
2/2✓ Branch 0 taken 4523769 times.
✓ Branch 1 taken 14942969 times.
|
19466738 | if (visited_[scv.dofIndex()]) |
329 | return true; | ||
330 | |||
331 | 4523769 | if (isConstrainedDof_(element, fvGeometry, scv, problem)) | |
332 | return true; | ||
333 | |||
334 | return false; | ||
335 | } | ||
336 | |||
337 | template<class Geometry, class Problem> | ||
338 | 4523769 | bool isConstrainedDof_(const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element, | |
339 | const Geometry& fvGeometry, | ||
340 | const typename Geometry::SubControlVolume& scv, | ||
341 | const Problem& problem) | ||
342 | { | ||
343 | // Dofs can be only constrained when using the Box method or when imposing internal Dirichlet constraints | ||
344 | if constexpr (Geometry::GridGeometry::discMethod != DiscretizationMethods::box && !Problem::enableInternalDirichletConstraints()) | ||
345 | return false; | ||
346 | |||
347 | // check for internally constrained Dofs | ||
348 |
2/2✓ Branch 0 taken 615580 times.
✓ Branch 1 taken 3908189 times.
|
4523769 | const auto isInternallyConstrainedDof = [&]() |
349 | { | ||
350 | if constexpr (!Problem::enableInternalDirichletConstraints()) | ||
351 | return false; | ||
352 | else | ||
353 | { | ||
354 | const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv); | ||
355 | return internalDirichletConstraints.any(); | ||
356 | } | ||
357 | }; | ||
358 | |||
359 | if (isInternallyConstrainedDof()) | ||
360 | return true; | ||
361 | |||
362 | // check for a Dirichlet BC when using the Box method | ||
363 | if constexpr (Geometry::GridGeometry::discMethod == DiscretizationMethods::box) | ||
364 | { | ||
365 |
2/2✓ Branch 0 taken 615580 times.
✓ Branch 1 taken 3908189 times.
|
4523769 | if (!fvGeometry.hasBoundaryScvf()) |
366 | 4179939 | return false; | |
367 | |||
368 |
2/2✓ Branch 0 taken 468657 times.
✓ Branch 1 taken 146923 times.
|
615580 | const auto dofIdx = scv.dofIndex(); |
369 |
2/2✓ Branch 0 taken 468657 times.
✓ Branch 1 taken 146923 times.
|
615580 | if (!fvGeometry.gridGeometry().dofOnBoundary(dofIdx)) |
370 | return false; | ||
371 | |||
372 |
2/2✓ Branch 0 taken 343830 times.
✓ Branch 1 taken 124827 times.
|
468657 | const auto bcTypes = problem.boundaryTypes(element, scv); |
373 |
2/2✓ Branch 0 taken 343830 times.
✓ Branch 1 taken 124827 times.
|
468657 | if (bcTypes.hasDirichlet()) |
374 | return true; | ||
375 | } | ||
376 | |||
377 | 343830 | return false; | |
378 | } | ||
379 | |||
380 | template<class Problem, class Element, class SubControlVolume, class SolutionVector> | ||
381 | 149077 | bool handleDirichletBoundaryCondition_(const Problem& problem, | |
382 | const Element& element, | ||
383 | const SubControlVolume& scv, | ||
384 | SolutionVector& sol) | ||
385 | { | ||
386 |
2/2✓ Branch 0 taken 9072 times.
✓ Branch 1 taken 47152 times.
|
149077 | bool changed = false; |
387 |
2/2✓ Branch 0 taken 25036 times.
✓ Branch 1 taken 124041 times.
|
149077 | const auto bcTypes = problem.boundaryTypes(element, scv); |
388 |
2/2✓ Branch 0 taken 25036 times.
✓ Branch 1 taken 124041 times.
|
149077 | if (bcTypes.hasDirichlet()) |
389 | { | ||
390 |
3/5✓ Branch 1 taken 24480 times.
✓ Branch 2 taken 80 times.
✓ Branch 4 taken 9712 times.
✗ Branch 5 not taken.
✗ Branch 3 not taken.
|
39436 | const auto dirichletValues = problem.dirichlet(element, scv); |
391 | 25036 | const auto dofIdx = scv.dofIndex(); | |
392 | |||
393 |
4/6✓ Branch 1 taken 25036 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25036 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 25019 times.
|
25036 | if (sol[dofIdx].state() != dirichletValues.state()) |
394 | { | ||
395 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (verbosity() > 1) |
396 | ✗ | std::cout << "Changing primary variable state at boundary (" << sol[dofIdx].state() | |
397 | ✗ | << ") to the one given by the Dirichlet condition (" << dirichletValues.state() << ") at dof " << dofIdx | |
398 | ✗ | << ", coordinates: " << scv.dofPosition() | |
399 | 17 | << std::endl; | |
400 | |||
401 | // make sure the solution vector has the right state (given by the Dirichlet BC) | ||
402 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | sol[dofIdx].setState(dirichletValues.state()); |
403 | 17 | changed = true; | |
404 | |||
405 | // overwrite initial with Dirichlet values | ||
406 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 17 times.
|
68 | for (int eqIdx = 0; eqIdx < SolutionVector::block_type::dimension; ++eqIdx) |
407 | { | ||
408 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
51 | if (bcTypes.isDirichlet(eqIdx)) |
409 | { | ||
410 | 51 | const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx); | |
411 | 51 | sol[dofIdx][pvIdx] = dirichletValues[pvIdx]; | |
412 | } | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | |||
417 | 149077 | return changed; | |
418 | } | ||
419 | |||
420 | template<class Problem, class Element, class SubControlVolume, class SolutionVector> | ||
421 | bool handleInternalDirichletConstraint_(const Problem& problem, | ||
422 | const Element& element, | ||
423 | const SubControlVolume& scv, | ||
424 | SolutionVector& sol) | ||
425 | { | ||
426 | bool changed = false; | ||
427 | |||
428 | const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv); | ||
429 | if (internalDirichletConstraints.none()) | ||
430 | return changed; | ||
431 | |||
432 | const auto dirichletValues = problem.internalDirichlet(element, scv); | ||
433 | const auto dofIdx = scv.dofIndex(); | ||
434 | |||
435 | if (sol[dofIdx].state() != dirichletValues.state()) | ||
436 | { | ||
437 | if (verbosity() > 1) | ||
438 | std::cout << "Changing primary variable state at internal DOF (" << sol[dofIdx].state() | ||
439 | << ") to the one given by the internal Dirichlet constraint (" << dirichletValues.state() << ") at dof " << dofIdx | ||
440 | << ", coordinates: " << scv.dofPosition() | ||
441 | << std::endl; | ||
442 | |||
443 | // make sure the solution vector has the right state (given by the Dirichlet constraint) | ||
444 | sol[dofIdx].setState(dirichletValues.state()); | ||
445 | changed = true; | ||
446 | |||
447 | // overwrite initial with Dirichlet values | ||
448 | for (int pvIdx = 0; pvIdx < SolutionVector::block_type::dimension; ++pvIdx) | ||
449 | { | ||
450 | if (internalDirichletConstraints[pvIdx]) | ||
451 | sol[dofIdx][pvIdx] = dirichletValues[pvIdx]; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | return changed; | ||
456 | } | ||
457 | |||
458 | std::vector<bool> wasSwitched_; | ||
459 | std::vector<bool> visited_; | ||
460 | |||
461 | private: | ||
462 | template<class GridVolumeVariables, class ElementVolumeVariables, class SubControlVolume> | ||
463 | typename GridVolumeVariables::VolumeVariables& | ||
464 |
2/4✓ Branch 1 taken 4398942 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
|
8636074 | getVolVarAccess_(GridVolumeVariables& gridVolVars, ElementVolumeVariables& elemVolVars, const SubControlVolume& scv) const |
465 | { | ||
466 | if constexpr (GridVolumeVariables::cachingEnabled) | ||
467 |
2/4✓ Branch 1 taken 5171354 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
|
5171388 | return gridVolVars.volVars(scv); |
468 | else | ||
469 |
1/2✓ Branch 1 taken 3464686 times.
✗ Branch 2 not taken.
|
3464686 | return elemVolVars[scv]; |
470 | } | ||
471 | |||
472 | int verbosity_; //!< The verbosity level of the primary variable switch | ||
473 | }; | ||
474 | |||
475 | } // end namespace dumux | ||
476 | |||
477 | #endif | ||
478 |