GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/porousmediumflow/compositional/primaryvariableswitch.hh
Date: 2025-04-19 19:19:10
Exec Total Coverage
Lines: 126 129 97.7%
Functions: 147 154 95.5%
Branches: 183 334 54.8%

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