GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/porousmediumflow/compositional/primaryvariableswitch.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 98 109 89.9%
Functions: 147 344 42.7%
Branches: 216 326 66.3%

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 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 class PrimaryVariableSwitch
49 {
50 public:
51 PrimaryVariableSwitch(int verbosity = 1)
52 : verbosity_(verbosity)
53 {}
54
55 //! If the primary variables were recently switched
56 bool wasSwitched(std::size_t dofIdxGlobal) const
57 {
58 6832102 return wasSwitched_[dofIdxGlobal];
59 }
60
61 //! Reset all flags
62 void reset(const std::size_t numDofs)
63 {
64
1/7
✗ Branch 2 not taken.
✓ Branch 3 taken 631 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
3283 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 14228 bool update(SolutionVector& curSol,
77 GridVariables& gridVariables,
78 const Problem& problem,
79 const typename GridVariables::GridGeometry& gridGeometry)
80 {
81 14228 bool switched = false;
82 28456 visited_.assign(wasSwitched_.size(), false);
83 14228 std::size_t countSwitched = 0;
84
85
1/4
✓ Branch 1 taken 13272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16390 auto fvGeometry = localView(gridGeometry);
86
5/8
✓ Branch 1 taken 13272 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13272 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 796 times.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
32922 auto elemVolVars = localView(gridVariables.curGridVolVars());
87
88
15/19
✓ Branch 1 taken 13272 times.
✓ Branch 2 taken 627542 times.
✓ Branch 3 taken 730 times.
✓ Branch 4 taken 16217 times.
✓ Branch 5 taken 730 times.
✓ Branch 6 taken 1686505 times.
✓ Branch 7 taken 5220 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1361022 times.
✓ Branch 10 taken 2275 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6077168 times.
✓ Branch 13 taken 2275 times.
✓ Branch 14 taken 6077168 times.
✓ Branch 15 taken 2275 times.
✓ Branch 17 taken 6077168 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 6077168 times.
✗ Branch 21 not taken.
10708350 for (const auto& element : elements(gridGeometry.gridView()))
89 {
90 // make sure FVElementGeometry is bound to the element
91
1/2
✓ Branch 1 taken 7441135 times.
✗ Branch 2 not taken.
8380015 fvGeometry.bindElement(element);
92
2/2
✓ Branch 1 taken 6836912 times.
✓ Branch 2 taken 23 times.
8380015 elemVolVars.bindElement(element, fvGeometry, curSol);
93
94
1/2
✓ Branch 1 taken 7136613 times.
✗ Branch 2 not taken.
8379992 const auto curElemSol = elementSolution(element, curSol, gridGeometry);
95
5/6
✓ Branch 0 taken 19315470 times.
✓ Branch 1 taken 8277462 times.
✓ Branch 2 taken 17955990 times.
✓ Branch 3 taken 6920914 times.
✓ Branch 4 taken 2678388 times.
✗ Branch 5 not taken.
36175052 for (auto&& scv : scvs(fvGeometry))
96 {
97
3/3
✓ Branch 0 taken 2617629 times.
✓ Branch 1 taken 8987262 times.
✓ Branch 2 taken 3576045 times.
23655064 if (!asImp_().skipDof_(element, fvGeometry, scv, problem))
98 {
99
1/2
✓ Branch 1 taken 2678388 times.
✗ Branch 2 not taken.
8623188 const auto dofIdxGlobal = scv.dofIndex();
100 // Note this implies that volume variables don't differ
101 // in any sub control volume associated with the dof!
102
2/4
✓ Branch 1 taken 6440118 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6440118 times.
✗ Branch 5 not taken.
17246376 visited_[dofIdxGlobal] = true;
103 // Compute volVars on which grounds we decide
104 // if we need to switch the primary variables
105
1/2
✓ Branch 1 taken 4546960 times.
✗ Branch 2 not taken.
10516346 auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv);
106 8623188 volVars.update(curElemSol, problem, element, scv);
107
108
6/9
✓ Branch 1 taken 7998794 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 146 times.
✓ Branch 4 taken 8623042 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7998794 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4374 times.
✓ Branch 10 taken 7994420 times.
25869564 if (asImp_().update_(curSol[dofIdxGlobal], volVars, dofIdxGlobal, scv.dofPosition()))
109 {
110 4520 switched = true;
111 4520 ++countSwitched;
112 }
113 }
114 }
115 }
116
117
3/4
✓ Branch 0 taken 14205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1031 times.
✓ Branch 3 taken 13174 times.
14205 if (verbosity_ > 0 && countSwitched > 0)
118
1/2
✓ Branch 2 taken 1002 times.
✗ Branch 3 not taken.
2062 std::cout << "Switched primary variables at " << countSwitched << " dof locations on processor "
119
8/14
✗ Branch 0 not taken.
✓ Branch 1 taken 319 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1031 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 290 times.
✓ Branch 6 taken 712 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 166 times.
✓ Branch 9 taken 124 times.
✓ Branch 10 taken 712 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 166 times.
✗ Branch 13 not taken.
3093 << gridGeometry.gridView().comm().rank() << "." << std::endl;
120
121 // make sure that if there was a variable switch in an
122 // other partition we will also set the switch flag for our partition.
123
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 11930 times.
✓ Branch 2 taken 1306 times.
✓ Branch 3 taken 12899 times.
✓ Branch 4 taken 1306 times.
✓ Branch 5 taken 12169 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 11200 times.
28410 if (gridGeometry.gridView().comm().size() > 1)
124
3/6
✓ Branch 1 taken 1306 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1306 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1306 times.
✗ Branch 8 not taken.
3918 switched = gridGeometry.gridView().comm().max(switched);
125
126
1/2
✓ Branch 0 taken 4842 times.
✗ Branch 1 not taken.
21995 return switched;
127 }
128
129 /*!
130 * \brief Updates the volume variables whose primary variables were
131 * switched.
132 *
133 * Required when volume variables are cached globally.
134 */
135 template<class Problem, class GridVariables, class SolutionVector>
136 1505190 void updateSwitchedVolVars(const Problem& problem,
137 const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
138 const typename GridVariables::GridGeometry& gridGeometry,
139 GridVariables& gridVariables,
140 const SolutionVector& sol)
141 {
142 if constexpr (GridVariables::GridVolumeVariables::cachingEnabled)
143 {
144 // make sure FVElementGeometry is bound to the element
145
4/10
✓ Branch 1 taken 1359142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1359142 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1359142 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1359142 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
5728664 const auto fvGeometry = localView(gridGeometry).bindElement(element);
146
147 // update the secondary variables if global caching is enabled
148
6/6
✓ Branch 0 taken 3161298 times.
✓ Branch 1 taken 1505190 times.
✓ Branch 2 taken 3161298 times.
✓ Branch 3 taken 1505190 times.
✓ Branch 4 taken 1470 times.
✓ Branch 5 taken 951684 times.
6171678 for (auto&& scv : scvs(fvGeometry))
149 {
150
2/2
✓ Branch 0 taken 1470 times.
✓ Branch 1 taken 951684 times.
3161298 const auto dofIdxGlobal = scv.dofIndex();
151
4/4
✓ Branch 0 taken 4807 times.
✓ Branch 1 taken 3156491 times.
✓ Branch 2 taken 4807 times.
✓ Branch 3 taken 3156491 times.
6322596 if (asImp_().wasSwitched(dofIdxGlobal))
152 {
153
1/2
✓ Branch 1 taken 4197 times.
✗ Branch 2 not taken.
4807 const auto elemSol = elementSolution(element, sol, gridGeometry);
154
2/4
✓ Branch 1 taken 4197 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2805 times.
✗ Branch 5 not taken.
8144 auto& volVars = gridVariables.curGridVolVars().volVars(scv);
155
1/2
✓ Branch 1 taken 4197 times.
✗ Branch 2 not taken.
4807 volVars.update(elemSol, problem, element, scv);
156 }
157 }
158 }
159 1505190 }
160
161 /*!
162 * \brief Updates the fluxVars cache for dof whose primary variables were
163 * switched.
164 *
165 * Required when flux variables are cached globally (not for box method).
166 */
167 template<class Problem, class GridVariables, class SolutionVector>
168 254753 void updateSwitchedFluxVarsCache(const Problem& problem,
169 const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
170 const typename GridVariables::GridGeometry& gridGeometry,
171 GridVariables& gridVariables,
172 const SolutionVector& sol)
173 {
174 if constexpr (GridVariables::GridFluxVariablesCache::cachingEnabled
175 && GridVariables::GridGeometry::discMethod != DiscretizationMethods::box)
176 {
177 // update the flux variables if global caching is enabled
178 509506 const auto dofIdxGlobal = gridGeometry.dofMapper().index(element);
179
180
4/4
✓ Branch 0 taken 417 times.
✓ Branch 1 taken 254336 times.
✓ Branch 2 taken 417 times.
✓ Branch 3 taken 254336 times.
509506 if (asImp_().wasSwitched(dofIdxGlobal))
181 {
182 // make sure FVElementGeometry and the volume variables are bound
183
3/6
✓ Branch 1 taken 339 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 339 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 339 times.
✗ Branch 7 not taken.
1512 const auto fvGeometry = localView(gridGeometry).bind(element);
184
4/10
✓ Branch 1 taken 417 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 417 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 417 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 339 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
1668 const auto curElemVolVars = localView(gridVariables.curGridVolVars()).bind(element, fvGeometry, sol);
185
2/4
✓ Branch 1 taken 417 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 417 times.
✗ Branch 5 not taken.
834 gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
186 }
187 }
188 254753 }
189
190 /*!
191 * \brief Updates the the primary variables state at the boundary.
192 *
193 * Required when a Dirichlet constraint (at a boundary or internal) differs from the initial condition.
194 */
195 template<class Problem, class GridVariables, class SolutionVector>
196 2573 void updateDirichletConstraints(const Problem& problem,
197 const typename GridVariables::GridGeometry& gridGeometry,
198 GridVariables& gridVariables,
199 SolutionVector& sol)
200 {
201 if constexpr (GridVariables::GridGeometry::discMethod == DiscretizationMethods::box || Problem::enableInternalDirichletConstraints())
202 {
203
1/2
✓ Branch 3 taken 2335 times.
✗ Branch 4 not taken.
7719 std::vector<bool> stateChanged(sol.size(), false);
204 2573 std::size_t countChanged = 0;
205
206
15/19
✓ Branch 1 taken 2335 times.
✓ Branch 2 taken 952 times.
✓ Branch 3 taken 238 times.
✓ Branch 4 taken 3287 times.
✓ Branch 5 taken 238 times.
✓ Branch 6 taken 358505 times.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 242866 times.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 421792 times.
✓ Branch 13 taken 168 times.
✓ Branch 14 taken 421792 times.
✓ Branch 15 taken 168 times.
✓ Branch 17 taken 421792 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 421792 times.
✗ Branch 21 not taken.
1140566 for (const auto& element : elements(gridGeometry.gridView()))
207 {
208
4/10
✓ Branch 1 taken 665610 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 664658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 210896 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14000 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2253702 const auto fvGeometry = localView(gridGeometry).bindElement(element);
209
210 // skip if the element is not at a boundary or if no internal Dirichlet constraints are set
211
4/4
✓ Branch 0 taken 617116 times.
✓ Branch 1 taken 161966 times.
✓ Branch 2 taken 205324 times.
✓ Branch 3 taken 119044 times.
1103450 if (!Problem::enableInternalDirichletConstraints() && !fvGeometry.hasBoundaryScvf())
212
1/2
✓ Branch 0 taken 196896 times.
✗ Branch 1 not taken.
805584 continue;
213
214
4/11
✓ Branch 1 taken 54042 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 54042 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 54042 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 40042 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
276134 const auto elemVolVars = localView(gridVariables.curGridVolVars()).bindElement(element, fvGeometry, sol);
215
216
4/4
✓ Branch 0 taken 253396 times.
✓ Branch 1 taken 65350 times.
✓ Branch 2 taken 252444 times.
✓ Branch 3 taken 64874 times.
384096 for (const auto& scv : scvs(fvGeometry))
217 {
218 253396 const auto dofIdx = scv.dofIndex();
219
220
6/6
✓ Branch 0 taken 253379 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 253379 times.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 253379 times.
✓ Branch 5 taken 17 times.
760188 if (stateChanged[dofIdx])
221 continue;
222
223 if constexpr (GridVariables::GridGeometry::discMethod == DiscretizationMethods::box)
224 {
225
4/4
✓ Branch 0 taken 147873 times.
✓ Branch 1 taken 105506 times.
✓ Branch 2 taken 147873 times.
✓ Branch 3 taken 105506 times.
506758 if (gridGeometry.dofOnBoundary(dofIdx))
226 {
227
3/4
✓ Branch 1 taken 147873 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 147856 times.
147873 if (handleDirichletBoundaryCondition_(problem, element, scv, sol))
228 {
229 34 stateChanged[dofIdx] = true;
230 17 ++countChanged;
231 17 continue;
232 }
233 }
234 }
235
236 if constexpr (Problem::enableInternalDirichletConstraints())
237 {
238 if (handleInternalDirichletConstraint_(problem, element, scv, sol))
239 {
240 stateChanged[dofIdx] = true;
241 ++countChanged;
242 }
243 }
244 }
245
246 // update the volVars if caching is enabled
247 if constexpr (GridVariables::GridVolumeVariables::cachingEnabled)
248 {
249
2/2
✓ Branch 0 taken 229 times.
✓ Branch 1 taken 25079 times.
25308 if (countChanged > 0)
250 {
251
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
229 const auto curElemSol = elementSolution(element, sol, gridGeometry);
252
4/4
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 229 times.
✓ Branch 2 taken 916 times.
✓ Branch 3 taken 229 times.
1374 for (const auto& scv : scvs(fvGeometry))
253 {
254
6/6
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 882 times.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 882 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 882 times.
2748 if (stateChanged[scv.dofIndex()])
255 {
256
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv);
257 34 volVars.update(curElemSol, problem, element, scv);
258 }
259 }
260 }
261 }
262 }
263
264
3/4
✓ Branch 0 taken 2573 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2572 times.
2573 if (verbosity_ > 0 && countChanged > 0)
265
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 std::cout << "Changed primary variable states and solution values to Dirichlet states and values at " << countChanged << " dof locations on processor "
266
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
3 << gridGeometry.gridView().comm().rank() << "." << std::endl;
267 }
268 2573 }
269
270 //! The verbosity level
271 int verbosity() const
272 { return verbosity_; }
273
274 protected:
275
276 //! Return actual implementation (static polymorphism)
277 Implementation &asImp_()
278 { return *static_cast<Implementation*>(this); }
279
280 //! Return actual implementation (static polymorphism)
281 const Implementation &asImp_() const
282 { return *static_cast<const Implementation*>(this); }
283
284 // Perform variable switch at a degree of freedom location
285 template<class VolumeVariables, class GlobalPosition>
286 bool update_(typename VolumeVariables::PrimaryVariables& priVars,
287 const VolumeVariables& volVars,
288 std::size_t dofIdxGlobal,
289 const GlobalPosition& globalPos)
290 {
291 // evaluate if the primary variable switch would switch
292 // to be implemented by the deriving class
293 DUNE_THROW(Dune::NotImplemented, "This model seems to use a primary variable switch but none is implemented!");
294 }
295
296 // Maybe skip the degree of freedom (do not switch variables at this dof)
297 template<class Geometry, class Problem>
298 15180936 bool skipDof_(const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element,
299 const Geometry& fvGeometry,
300 const typename Geometry::SubControlVolume& scv,
301 const Problem& problem)
302 {
303
10/16
✓ Branch 0 taken 4509143 times.
✓ Branch 1 taken 10671793 times.
✓ Branch 2 taken 4509143 times.
✓ Branch 3 taken 10671793 times.
✓ Branch 4 taken 4509143 times.
✓ Branch 5 taken 10671793 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4237064 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4237064 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4237064 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4237064 times.
✗ Branch 15 not taken.
62491064 if (visited_[scv.dofIndex()])
304 return true;
305
306
3/3
✓ Branch 0 taken 47669 times.
✓ Branch 1 taken 2692979 times.
✓ Branch 2 taken 1768495 times.
4509143 if (isConstrainedDof_(element, fvGeometry, scv, problem))
307 123019 return true;
308
309 return false;
310 }
311
312 template<class Geometry, class Problem>
313 4509143 bool isConstrainedDof_(const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element,
314 const Geometry& fvGeometry,
315 const typename Geometry::SubControlVolume& scv,
316 const Problem& problem)
317 {
318 // Dofs can be only constrained when using the Box method or when imposing internal Dirichlet constraints
319 if constexpr (Geometry::GridGeometry::discMethod != DiscretizationMethods::box && !Problem::enableInternalDirichletConstraints())
320 return false;
321
322 // check for internally constrained Dofs
323 const auto isInternallyConstrainedDof = [&]()
324 {
325 if constexpr (!Problem::enableInternalDirichletConstraints())
326 return false;
327 else
328 {
329 const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv);
330 return internalDirichletConstraints.any();
331 }
332 };
333
334 if (isInternallyConstrainedDof())
335 return true;
336
337 // check for a Dirichlet BC when using the Box method
338 if constexpr (Geometry::GridGeometry::discMethod == DiscretizationMethods::box)
339 {
340
4/4
✓ Branch 0 taken 610162 times.
✓ Branch 1 taken 3898981 times.
✓ Branch 2 taken 214156 times.
✓ Branch 3 taken 1733914 times.
6457213 if (!fvGeometry.hasBoundaryScvf())
341 4167487 return false;
342
343 610162 const auto dofIdx = scv.dofIndex();
344
6/6
✓ Branch 0 taken 464675 times.
✓ Branch 1 taken 145487 times.
✓ Branch 2 taken 464675 times.
✓ Branch 3 taken 145487 times.
✓ Branch 4 taken 463207 times.
✓ Branch 5 taken 144749 times.
1828280 if (!fvGeometry.gridGeometry().dofOnBoundary(dofIdx))
345 return false;
346
347
2/2
✓ Branch 0 taken 134844 times.
✓ Branch 1 taken 47669 times.
464675 const auto bcTypes = problem.boundaryTypes(element, scv);
348
4/4
✓ Branch 0 taken 341656 times.
✓ Branch 1 taken 123019 times.
✓ Branch 2 taken 341656 times.
✓ Branch 3 taken 123019 times.
929350 if (bcTypes.hasDirichlet())
349 return true;
350 }
351
352 341656 return false;
353 }
354
355 template<class Problem, class Element, class SubControlVolume, class SolutionVector>
356 147873 bool handleDirichletBoundaryCondition_(const Problem& problem,
357 const Element& element,
358 const SubControlVolume& scv,
359 SolutionVector& sol)
360 {
361 147873 bool changed = false;
362
2/2
✓ Branch 0 taken 9072 times.
✓ Branch 1 taken 47152 times.
147873 const auto bcTypes = problem.boundaryTypes(element, scv);
363
4/4
✓ Branch 0 taken 24708 times.
✓ Branch 1 taken 123165 times.
✓ Branch 2 taken 24708 times.
✓ Branch 3 taken 123165 times.
295746 if (bcTypes.hasDirichlet())
364 {
365 24708 const auto dirichletValues = problem.dirichlet(element, scv);
366 24708 const auto dofIdx = scv.dofIndex();
367
368
2/2
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 24691 times.
49416 if (sol[dofIdx].state() != dirichletValues.state())
369 {
370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (verbosity() > 1)
371 std::cout << "Changing primary variable state at boundary (" << sol[dofIdx].state()
372 << ") to the one given by the Dirichlet condition (" << dirichletValues.state() << ") at dof " << dofIdx
373 << ", coordinates: " << scv.dofPosition()
374 << std::endl;
375
376 // make sure the solution vector has the right state (given by the Dirichlet BC)
377 34 sol[dofIdx].setState(dirichletValues.state());
378 17 changed = true;
379
380 // overwrite initial with Dirichlet values
381
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 17 times.
68 for (int eqIdx = 0; eqIdx < SolutionVector::block_type::dimension; ++eqIdx)
382 {
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (bcTypes.isDirichlet(eqIdx))
384 {
385 51 const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
386 204 sol[dofIdx][pvIdx] = dirichletValues[pvIdx];
387 }
388 }
389 }
390 }
391
392 147873 return changed;
393 }
394
395 template<class Problem, class Element, class SubControlVolume, class SolutionVector>
396 bool handleInternalDirichletConstraint_(const Problem& problem,
397 const Element& element,
398 const SubControlVolume& scv,
399 SolutionVector& sol)
400 {
401 bool changed = false;
402
403 const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv);
404 if (internalDirichletConstraints.none())
405 return changed;
406
407 const auto dirichletValues = problem.internalDirichlet(element, scv);
408 const auto dofIdx = scv.dofIndex();
409
410 if (sol[dofIdx].state() != dirichletValues.state())
411 {
412 if (verbosity() > 1)
413 std::cout << "Changing primary variable state at internal DOF (" << sol[dofIdx].state()
414 << ") to the one given by the internal Dirichlet constraint (" << dirichletValues.state() << ") at dof " << dofIdx
415 << ", coordinates: " << scv.dofPosition()
416 << std::endl;
417
418 // make sure the solution vector has the right state (given by the Dirichlet constraint)
419 sol[dofIdx].setState(dirichletValues.state());
420 changed = true;
421
422 // overwrite initial with Dirichlet values
423 for (int pvIdx = 0; pvIdx < SolutionVector::block_type::dimension; ++pvIdx)
424 {
425 if (internalDirichletConstraints[pvIdx])
426 sol[dofIdx][pvIdx] = dirichletValues[pvIdx];
427 }
428 }
429
430 return changed;
431 }
432
433 std::vector<bool> wasSwitched_;
434 std::vector<bool> visited_;
435
436 private:
437 template<class GridVolumeVariables, class ElementVolumeVariables, class SubControlVolume>
438 typename GridVolumeVariables::VolumeVariables&
439 getVolVarAccess_(GridVolumeVariables& gridVolVars, ElementVolumeVariables& elemVolVars, const SubControlVolume& scv) const
440 {
441 if constexpr (GridVolumeVariables::cachingEnabled)
442
4/10
✓ Branch 1 taken 4546960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 4546960 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 34 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
10342776 return gridVolVars.volVars(scv);
443 else
444
3/5
✓ Branch 1 taken 1893158 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1558676 times.
✓ Branch 4 taken 1893158 times.
✗ Branch 5 not taken.
5344992 return elemVolVars[scv];
445 }
446
447 int verbosity_; //!< The verbosity level of the primary variable switch
448 };
449
450 } // end namespace dumux
451
452 #endif
453