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 |