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.
|
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 | 14288 | bool update(SolutionVector& curSol, | |
77 | GridVariables& gridVariables, | ||
78 | const Problem& problem, | ||
79 | const typename GridVariables::GridGeometry& gridGeometry) | ||
80 | { | ||
81 | 14288 | bool switched = false; | |
82 | 28576 | visited_.assign(wasSwitched_.size(), false); | |
83 | 14288 | std::size_t countSwitched = 0; | |
84 | |||
85 |
1/4✓ Branch 1 taken 13333 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
16455 | auto fvGeometry = localView(gridGeometry); |
86 |
5/8✓ Branch 1 taken 13333 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13333 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 796 times.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
|
33099 | auto elemVolVars = localView(gridVariables.curGridVolVars()); |
87 | |||
88 |
15/19✓ Branch 1 taken 13333 times.
✓ Branch 2 taken 623445 times.
✓ Branch 3 taken 730 times.
✓ Branch 4 taken 16278 times.
✓ Branch 5 taken 730 times.
✓ Branch 6 taken 1694741 times.
✓ Branch 7 taken 5225 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1373298 times.
✓ Branch 10 taken 2280 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6092034 times.
✓ Branch 13 taken 2280 times.
✓ Branch 14 taken 6092034 times.
✓ Branch 15 taken 2280 times.
✓ Branch 17 taken 6092034 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 6092034 times.
✗ Branch 21 not taken.
|
10731504 | for (const auto& element : elements(gridGeometry.gridView())) |
89 | { | ||
90 | // make sure FVElementGeometry is bound to the element | ||
91 |
1/2✓ Branch 1 taken 7468277 times.
✗ Branch 2 not taken.
|
8398965 | fvGeometry.bindElement(element); |
92 |
2/2✓ Branch 1 taken 6864054 times.
✓ Branch 2 taken 23 times.
|
8398965 | elemVolVars.bindElement(element, fvGeometry, curSol); |
93 | |||
94 |
1/2✓ Branch 1 taken 7164405 times.
✗ Branch 2 not taken.
|
8398942 | const auto curElemSol = elementSolution(element, curSol, gridGeometry); |
95 |
5/6✓ Branch 0 taken 19394307 times.
✓ Branch 1 taken 8296212 times.
✓ Branch 2 taken 18032210 times.
✓ Branch 3 taken 6937047 times.
✓ Branch 4 taken 2674292 times.
✗ Branch 5 not taken.
|
36291989 | for (auto&& scv : scvs(fvGeometry)) |
96 | { | ||
97 |
3/3✓ Branch 0 taken 2629408 times.
✓ Branch 1 taken 9029902 times.
✓ Branch 2 taken 3601742 times.
|
23733022 | if (!asImp_().skipDof_(element, fvGeometry, scv, problem)) |
98 | { | ||
99 |
1/2✓ Branch 1 taken 2674292 times.
✗ Branch 2 not taken.
|
8643511 | 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 6461519 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6461519 times.
✗ Branch 5 not taken.
|
17287022 | 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 4542864 times.
✗ Branch 2 not taken.
|
10562166 | auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv); |
106 | 8643511 | volVars.update(curElemSol, problem, element, scv); | |
107 | |||
108 |
6/9✓ Branch 1 taken 8023212 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 146 times.
✓ Branch 4 taken 8643365 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8023212 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4389 times.
✓ Branch 10 taken 8018823 times.
|
25930533 | if (asImp_().update_(curSol[dofIdxGlobal], volVars, dofIdxGlobal, scv.dofPosition())) |
109 | { | ||
110 | 4535 | switched = true; | |
111 | 4535 | ++countSwitched; | |
112 | } | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 |
3/4✓ Branch 0 taken 14265 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1035 times.
✓ Branch 3 taken 13230 times.
|
14265 | if (verbosity_ > 0 && countSwitched > 0) |
118 |
1/2✓ Branch 2 taken 1006 times.
✗ Branch 3 not taken.
|
2070 | std::cout << "Switched primary variables at " << countSwitched << " dof locations on processor " |
119 |
8/14✗ Branch 0 not taken.
✓ Branch 1 taken 323 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1035 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 294 times.
✓ Branch 6 taken 712 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 170 times.
✓ Branch 9 taken 124 times.
✓ Branch 10 taken 712 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 170 times.
✗ Branch 13 not taken.
|
3105 | << 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 11985 times.
✓ Branch 2 taken 1308 times.
✓ Branch 3 taken 12957 times.
✓ Branch 4 taken 1308 times.
✓ Branch 5 taken 12227 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 11255 times.
|
28530 | if (gridGeometry.gridView().comm().size() > 1) |
124 |
3/6✓ Branch 1 taken 1308 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1308 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1308 times.
✗ Branch 8 not taken.
|
3924 | switched = gridGeometry.gridView().comm().max(switched); |
125 | |||
126 |
1/2✓ Branch 0 taken 4899 times.
✗ Branch 1 not taken.
|
22117 | 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 | 2582 | 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 2344 times.
✗ Branch 4 not taken.
|
7746 | std::vector<bool> stateChanged(sol.size(), false); |
204 | 2582 | std::size_t countChanged = 0; | |
205 | |||
206 |
15/19✓ Branch 1 taken 2344 times.
✓ Branch 2 taken 952 times.
✓ Branch 3 taken 238 times.
✓ Branch 4 taken 3296 times.
✓ Branch 5 taken 238 times.
✓ Branch 6 taken 361050 times.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 245402 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.
|
1145656 | for (const auto& element : elements(gridGeometry.gridView())) |
207 | { | ||
208 |
4/10✓ Branch 1 taken 668146 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 667194 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.
|
2261310 | 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 619068 times.
✓ Branch 1 taken 162550 times.
✓ Branch 2 taken 205324 times.
✓ Branch 3 taken 119044 times.
|
1105986 | if (!Problem::enableInternalDirichletConstraints() && !fvGeometry.hasBoundaryScvf()) |
212 |
1/2✓ Branch 0 taken 196896 times.
✗ Branch 1 not taken.
|
807536 | continue; |
213 | |||
214 |
4/11✓ Branch 1 taken 54626 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 54626 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 54626 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 40626 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
279054 | const auto elemVolVars = localView(gridVariables.curGridVolVars()).bindElement(element, fvGeometry, sol); |
215 | |||
216 |
4/4✓ Branch 0 taken 255732 times.
✓ Branch 1 taken 65934 times.
✓ Branch 2 taken 254780 times.
✓ Branch 3 taken 65458 times.
|
387600 | for (const auto& scv : scvs(fvGeometry)) |
217 | { | ||
218 | 255732 | const auto dofIdx = scv.dofIndex(); | |
219 | |||
220 |
6/6✓ Branch 0 taken 255715 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 255715 times.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 255715 times.
✓ Branch 5 taken 17 times.
|
767196 | if (stateChanged[dofIdx]) |
221 | continue; | ||
222 | |||
223 | if constexpr (GridVariables::GridGeometry::discMethod == DiscretizationMethods::box) | ||
224 | { | ||
225 |
4/4✓ Branch 0 taken 149077 times.
✓ Branch 1 taken 106638 times.
✓ Branch 2 taken 149077 times.
✓ Branch 3 taken 106638 times.
|
511430 | if (gridGeometry.dofOnBoundary(dofIdx)) |
226 | { | ||
227 |
3/4✓ Branch 1 taken 149077 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 149060 times.
|
149077 | 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 2582 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2581 times.
|
2582 | 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 | 2582 | } | |
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 | 15261052 | 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 4532366 times.
✓ Branch 1 taken 10728686 times.
✓ Branch 2 taken 4532366 times.
✓ Branch 3 taken 10728686 times.
✓ Branch 4 taken 4532366 times.
✓ Branch 5 taken 10728686 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4235985 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4235985 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4235985 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4235985 times.
✗ Branch 15 not taken.
|
62727096 | if (visited_[scv.dofIndex()]) |
304 | ✗ | return true; | |
305 | |||
306 |
3/3✓ Branch 0 taken 47888 times.
✓ Branch 1 taken 2706360 times.
✓ Branch 2 taken 1778118 times.
|
4532366 | if (isConstrainedDof_(element, fvGeometry, scv, problem)) |
307 | 124840 | return true; | |
308 | |||
309 | return false; | ||
310 | } | ||
311 | |||
312 | template<class Geometry, class Problem> | ||
313 | 4532366 | 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 616843 times.
✓ Branch 1 taken 3915523 times.
✓ Branch 2 taken 213649 times.
✓ Branch 3 taken 1730070 times.
|
6476085 | if (!fvGeometry.hasBoundaryScvf()) |
341 | 4187723 | return false; | |
342 | |||
343 | 616843 | const auto dofIdx = scv.dofIndex(); | |
344 |
6/6✓ Branch 0 taken 469483 times.
✓ Branch 1 taken 147360 times.
✓ Branch 2 taken 469483 times.
✓ Branch 3 taken 147360 times.
✓ Branch 4 taken 468015 times.
✓ Branch 5 taken 146622 times.
|
1848323 | if (!fvGeometry.gridGeometry().dofOnBoundary(dofIdx)) |
345 | return false; | ||
346 | |||
347 |
2/2✓ Branch 0 taken 135463 times.
✓ Branch 1 taken 47888 times.
|
469483 | const auto bcTypes = problem.boundaryTypes(element, scv); |
348 |
4/4✓ Branch 0 taken 344643 times.
✓ Branch 1 taken 124840 times.
✓ Branch 2 taken 344643 times.
✓ Branch 3 taken 124840 times.
|
938966 | if (bcTypes.hasDirichlet()) |
349 | return true; | ||
350 | } | ||
351 | |||
352 | 344643 | return false; | |
353 | } | ||
354 | |||
355 | template<class Problem, class Element, class SubControlVolume, class SolutionVector> | ||
356 | 149077 | bool handleDirichletBoundaryCondition_(const Problem& problem, | |
357 | const Element& element, | ||
358 | const SubControlVolume& scv, | ||
359 | SolutionVector& sol) | ||
360 | { | ||
361 | 149077 | bool changed = false; | |
362 |
2/2✓ Branch 0 taken 9072 times.
✓ Branch 1 taken 47152 times.
|
149077 | const auto bcTypes = problem.boundaryTypes(element, scv); |
363 |
4/4✓ Branch 0 taken 25036 times.
✓ Branch 1 taken 124041 times.
✓ Branch 2 taken 25036 times.
✓ Branch 3 taken 124041 times.
|
298154 | if (bcTypes.hasDirichlet()) |
364 | { | ||
365 | 25036 | const auto dirichletValues = problem.dirichlet(element, scv); | |
366 | 25036 | const auto dofIdx = scv.dofIndex(); | |
367 | |||
368 |
2/2✓ Branch 3 taken 17 times.
✓ Branch 4 taken 25019 times.
|
50072 | 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 | 149077 | 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 4542864 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 4542864 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.
|
10326394 | return gridVolVars.volVars(scv); |
443 | else | ||
444 |
3/5✓ Branch 1 taken 1918655 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1561693 times.
✓ Branch 4 taken 1918655 times.
✗ Branch 5 not taken.
|
5399003 | 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 |