GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/test/freeflow/shallowwater/poiseuilleflow/problem.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 88 94 93.6%
Functions: 6 7 85.7%
Branches: 145 208 69.7%

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 #ifndef DUMUX_POISEUILLE_FLOW_TEST_PROBLEM_HH
9 #define DUMUX_POISEUILLE_FLOW_TEST_PROBLEM_HH
10
11 #include <algorithm>
12 #include <cctype>
13
14 #include <dumux/common/properties.hh>
15 #include <dumux/common/parameters.hh>
16 #include <dumux/common/numeqvector.hh>
17
18 #include <dumux/freeflow/shallowwater/problem.hh>
19 #include <dumux/freeflow/shallowwater/boundaryfluxes.hh>
20
21 namespace Dumux {
22
23 /*!
24 * \ingroup ShallowWaterTests
25 * \brief A simple test for the 2D flow in a channel with rough side walls (Poiseuille flow).
26 *
27 * The initial water depth corresponds to the analytical solution:
28 * having a slope equal to \f$ ib = d \Theta / L \f$ , where \f$ d \Theta \f$ is the water level difference between upstream and downstream and \f$ L \f$ is the domain length.
29 * At the west/left (inflow) boundary a discharge is prescribed of \f$ Q_{in} \f$ or \f$ q_{in} \f$ per meter.
30 * At the east/right (outflow) boundary a fixed water level is prescribed of \f$ \Theta \f$.
31 * The south and north boundaries are set to roughwall type boundaries,
32 * with a coefficient alphaWall = 1.0, where:
33 * alphaWall = 0.0: full slip (smooth wall)
34 * 0.0 <alphaWall < 1.0: partial slip (partially-rough wall)
35 * alphaWall = 1.0: no slip (fully-rough wall)
36 * Additionally these (south and north) boundaries are (automatically) set to no-flow boundaries.
37
38 * The flow in the channel experiences two forces:
39 * 1) the pressure gradient, driving the flow downstream
40 * 2) the wall roughness,
41
42 * It can be verified that this force balance reduces the momentum equation in X-direction to:
43 *
44 \f[
45 \frac{\partial p}{\partial x} = \nu_T \frac{\partial^2 u}{\partial y^2}
46 \f]
47 * where \f$ \nu_T \f$ is the turbulent viscosity.
48 *
49 * This ordinary differential equation can be solved (applying the boundary conditions to obtain the integration constants),
50 * resulting in a parabolic velocity profile in lateral direction (over the width of the channel):
51 *
52 \f[
53 u(y) = \frac{g d \Theta}{8 \nu_T L} \left(4y^2 - W^2\right)
54 \f]
55 *
56 * where y the coordinate in lateral direction.
57 * The velocity has a maximum value at y = 0:
58 \f[
59 u_{max} = \frac{g d \Theta W^2}{8 \nu_T L}
60 \f]
61 *
62 The formula for \f$ u(y) \f$ is also used to calculate the analytic solution.
63 * It should be noted that u = f(x) and that v = 0 in the whole domain (in the final steady state).
64 * Therefore the momentum advection/convection terms should be zero for this test, as:
65 * \f$ u \partial u / \partial x = v \partial u / \partial y = u \partial v / \partial x = v \partial v / \partial y = 0 \f$
66 *
67 * This problem uses the \ref ShallowWaterModel
68 */
69 template<class TypeTag>
70 class PoiseuilleFlowProblem
71 : public ShallowWaterProblem<TypeTag>
72 {
73 using ParentType = ShallowWaterProblem<TypeTag>;
74 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
75 using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>;
76 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
77 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
78 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
79 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
80 using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
81 using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
82 using VolumeVariables = typename ElementVolumeVariables::VolumeVariables;
83 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
84 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
85 using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView;
86 using Element = typename GridView::template Codim<0>::Entity;
87 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
88 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
89 using NeumannFluxes = NumEqVector;
90 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
91
92 public:
93 6 PoiseuilleFlowProblem(std::shared_ptr<const GridGeometry> gridGeometry)
94
11/34
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✓ Branch 15 taken 6 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 6 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
18 : ParentType(gridGeometry)
95 {
96
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 name_ = getParam<std::string>("Problem.Name");
97
4/7
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
12 exactWaterDepth_.resize(gridGeometry->numDofs(), 0.0);
98
4/7
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
12 exactVelocityX_.resize(gridGeometry->numDofs(), 0.0);
99
4/10
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
12 exactVelocityY_.resize(gridGeometry->numDofs(), 0.0);
100
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 bedSlope_ = getParam<Scalar>("Problem.BedSlope");
101
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 discharge_ = getParam<Scalar>("Problem.Discharge");
102
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 hBoundary_ = getParam<Scalar>("Problem.HBoundary");
103
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 alphaWall_ = getParam<Scalar>("Problem.AlphaWall");
104
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 turbViscosity_ = getParam<Scalar>("ShallowWater.TurbulentViscosity");
105
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 ksWall_ = getParam<Scalar>("Problem.KsWall");
106
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 wallFrictionLawType_ = getParam<std::string>("Problem.WallFrictionLaw");
107 // Make the wallFrictionLawType_ lower case
108 60 std::transform(wallFrictionLawType_.begin(), wallFrictionLawType_.end(), wallFrictionLawType_.begin(), [](unsigned char c){ return std::tolower(c); });
109 6 }
110
111 //! Get the analytical water depth
112 const std::vector<Scalar>& getExactWaterDepth() const
113
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 { return exactWaterDepth_; }
114
115 //! Get the analytical U-velocity
116 const std::vector<Scalar>& getExactVelocityX() const
117
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 { return exactVelocityX_; }
118
119 //! Get the analytical V-velocity
120 const std::vector<Scalar>& getExactVelocityY() const
121
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 { return exactVelocityY_; }
122
123 //! Update the analytical solution
124 219 void updateAnalyticalSolution()
125 {
126
4/4
✓ Branch 3 taken 74674 times.
✓ Branch 4 taken 111 times.
✓ Branch 5 taken 44326 times.
✓ Branch 6 taken 111 times.
149789 for (const auto& element : elements(this->gridGeometry().gridView()))
127 {
128 223698 const auto eIdx = this->gridGeometry().elementMapper().index(element);
129 118892 const auto& globalPos = element.geometry().center();
130 104806 const auto gravity = this->spatialParams().gravity(globalPos);
131 104806 const Scalar y = globalPos[1];
132 477636 const Scalar width = this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1];
133 74566 const Scalar h = hBoundary_;
134 74566 const Scalar u = -(gravity*bedSlope_/(8.0*turbViscosity_)) * (4.0*y*y - width*width);
135 104806 exactWaterDepth_[eIdx] = h;
136 104806 exactVelocityX_[eIdx] = u;
137 149132 exactVelocityY_[eIdx] = 0.0;
138 }
139 219 }
140
141 const std::string& name() const
142
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 { return name_; }
143
144 /*!
145 * \name Boundary conditions
146 */
147 // \{
148
149 /*!
150 * \brief Specifies which kind of boundary condition should be
151 * used for which equation on a given boundary segment.
152 *
153 * \param globalPos The position for which the boundary type is set
154 */
155 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
156 {
157 148431 BoundaryTypes bcTypes;
158
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31760 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 116671 times.
148431 bcTypes.setAllNeumann();
159 return bcTypes;
160 }
161
162 /*!
163 * \brief Specifies the neumann boundary
164 *
165 * We need the Riemann invariants to compute the values depending of the boundary type.
166 * Since we use a weak imposition we do not have a dirichlet value. We impose fluxes
167 * based on q, h, etc. computed with the Riemann invariants
168 */
169 116671 NeumannFluxes neumann(const Element& element,
170 const FVElementGeometry& fvGeometry,
171 const ElementVolumeVariables& elemVolVars,
172 const ElementFluxVariablesCache& elemFluxVarsCache,
173 const SubControlVolumeFace& scvf) const
174 {
175 116671 NeumannFluxes values(0.0);
176
177 233342 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
178 116671 const auto& insideVolVars = elemVolVars[insideScv];
179
2/2
✓ Branch 0 taken 18192 times.
✓ Branch 1 taken 98479 times.
116671 const auto& unitNormal = scvf.unitOuterNormal();
180
4/4
✓ Branch 0 taken 18192 times.
✓ Branch 1 taken 98479 times.
✓ Branch 2 taken 18192 times.
✓ Branch 3 taken 98479 times.
233342 const auto gravity = this->spatialParams().gravity(scvf.center());
181 std::array<Scalar, 3> boundaryStateVariables;
182
183 // impose discharge at the left side
184
12/12
✓ Branch 0 taken 18192 times.
✓ Branch 1 taken 98479 times.
✓ Branch 2 taken 18192 times.
✓ Branch 3 taken 98479 times.
✓ Branch 4 taken 18192 times.
✓ Branch 5 taken 98479 times.
✓ Branch 6 taken 18192 times.
✓ Branch 7 taken 98479 times.
✓ Branch 8 taken 18192 times.
✓ Branch 9 taken 98479 times.
✓ Branch 10 taken 18192 times.
✓ Branch 11 taken 98479 times.
700026 if (scvf.center()[0] < this->gridGeometry().bBoxMin()[0] + eps_)
185 {
186 // Prescribe the exact q-distribution long the inflow boundaryStateVariables
187 // based on the parabolic u-profile:
188 // q(y) = (g*H*ib/(8*nu_T)) * (4*y^2^-W^2)
189 // Note the opposite sign to the velocity u, due to the fact that it is an inflow discharge
190 36384 const auto y = scvf.center()[1];
191 109152 const auto width = this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1];
192 18192 const auto h = hBoundary_;
193 // Now compute a weighted average between the constant q (from input) and the parabolic q from the analytical solution
194 // based on the prescribed alphaWall
195 18192 const auto q_in0 = (gravity*h*bedSlope_/(8.0*turbViscosity_)) * (4.0*y*y - width*width);
196 18192 const auto q_in1 = discharge_;
197 18192 const auto q_in = (1.0-alphaWall_)*q_in1 + alphaWall_*q_in0;
198 72768 boundaryStateVariables = ShallowWater::fixedDischargeBoundary(q_in,
199 insideVolVars.waterDepth(),
200 insideVolVars.velocity(0),
201 insideVolVars.velocity(1),
202 gravity,
203 unitNormal);
204 }
205 // impose water depth at the right side
206
12/12
✓ Branch 0 taken 18306 times.
✓ Branch 1 taken 80173 times.
✓ Branch 2 taken 18306 times.
✓ Branch 3 taken 80173 times.
✓ Branch 4 taken 18306 times.
✓ Branch 5 taken 80173 times.
✓ Branch 6 taken 18306 times.
✓ Branch 7 taken 80173 times.
✓ Branch 8 taken 18306 times.
✓ Branch 9 taken 80173 times.
✓ Branch 10 taken 18306 times.
✓ Branch 11 taken 80173 times.
590874 else if (scvf.center()[0] > this->gridGeometry().bBoxMax()[0] - eps_)
207 {
208 73224 boundaryStateVariables = ShallowWater::fixedWaterDepthBoundary(hBoundary_,
209 insideVolVars.waterDepth(),
210 insideVolVars.velocity(0),
211 insideVolVars.velocity(1),
212 gravity,
213 unitNormal);
214 }
215 // no flow boundary
216 else
217 {
218 // For the rough side walls of type no-slip we prescribe a slip condition based on alphaWall
219 // for smooth closed walls we prescribed a full-slip condition (zero-roughness)
220
221 // Get inside velocity components in cell face coordinates (t,n) using normal vector unitNormal
222 // Note that the first component is the normal component
223 // since we are rotating to the normal vector coordinate system
224
8/8
✓ Branch 0 taken 40109 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 40109 times.
✓ Branch 3 taken 40064 times.
✓ Branch 4 taken 40109 times.
✓ Branch 5 taken 40064 times.
✓ Branch 6 taken 40109 times.
✓ Branch 7 taken 40064 times.
320692 const Scalar insideVelocityNWall = insideVolVars.velocity(0)*unitNormal[0] + insideVolVars.velocity(1)*unitNormal[1];
225
8/8
✓ Branch 0 taken 40109 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 40109 times.
✓ Branch 3 taken 40064 times.
✓ Branch 4 taken 40109 times.
✓ Branch 5 taken 40064 times.
✓ Branch 6 taken 40109 times.
✓ Branch 7 taken 40064 times.
320692 const Scalar insideVelocityTWall = -insideVolVars.velocity(0)*unitNormal[1] + insideVolVars.velocity(1)*unitNormal[0];
226
227 // Initialisation of outside velocities
228 80173 auto outsideVelocityNWall = insideVelocityNWall;
229 80173 auto outsideVelocityTWall = insideVelocityTWall;
230
231 // Now set the outside (ghost cell) velocities based on the chosen slip condition
232
19/28
✓ Branch 0 taken 40109 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 40109 times.
✓ Branch 3 taken 40064 times.
✓ Branch 4 taken 40109 times.
✓ Branch 5 taken 40064 times.
✓ Branch 6 taken 40109 times.
✓ Branch 7 taken 40064 times.
✓ Branch 8 taken 40109 times.
✓ Branch 9 taken 40064 times.
✓ Branch 10 taken 40109 times.
✓ Branch 11 taken 40064 times.
✓ Branch 12 taken 40109 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40109 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40109 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 40109 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 40109 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 40109 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 80173 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
481038 if ((scvf.center()[1] < this->gridGeometry().bBoxMin()[1] + eps_ || scvf.center()[1] > this->gridGeometry().bBoxMax()[1] - eps_) && (wallFrictionLawType_ == "noslip" || wallFrictionLawType_ == "nikuradse"))
233 {
234 // Set the outside state using the no-slip wall roughness conditions based on alphaWall
235 // alphaWall = 0.0: full slip (wall tangential velocity equals inside tangential velocity)
236 // alphaWall = 1.0: no slip (wall tangential velocity=0.0: point mirroring of the velocity)
237 // 0.0 < alphaWall < 1.0: 'partial' slip.
238 // e.g. for alphaWall = 0.5 the wall tangential velocity is half the inside tangential velocity.
239 80173 outsideVelocityNWall = -insideVelocityNWall;
240 80173 outsideVelocityTWall = (1.0 - 2.0*alphaWall_)*insideVelocityTWall;
241 }
242 else
243 {
244 // Set the outside state using the full-slip wall roughness conditions (line mirroring in the boundary face)
245 // Only mirror the normal component
246 outsideVelocityNWall = -insideVelocityNWall;
247 outsideVelocityTWall = insideVelocityTWall;
248 }
249 // Rotate back to cartesian coordinate system
250 160346 const Scalar outsideVelocityXWall = outsideVelocityNWall*unitNormal[0] - outsideVelocityTWall*unitNormal[1];
251 160346 const Scalar outsideVelocityYWall = outsideVelocityNWall*unitNormal[1] + outsideVelocityTWall*unitNormal[0];
252
253 160346 boundaryStateVariables[0] = insideVolVars.waterDepth();
254 80173 boundaryStateVariables[1] = outsideVelocityXWall;
255 160346 boundaryStateVariables[2] = outsideVelocityYWall;
256
257 }
258
259 116671 auto riemannFlux = ShallowWater::riemannProblem(insideVolVars.waterDepth(),
260 233342 boundaryStateVariables[0],
261 insideVolVars.velocity(0),
262 233342 boundaryStateVariables[1],
263 insideVolVars.velocity(1),
264 233342 boundaryStateVariables[2],
265 insideVolVars.bedSurface(),
266 insideVolVars.bedSurface(),
267 gravity,
268 unitNormal);
269
270
4/4
✓ Branch 0 taken 76607 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 76607 times.
✓ Branch 3 taken 40064 times.
233342 values[Indices::massBalanceIdx] = riemannFlux[0];
271
4/4
✓ Branch 0 taken 76607 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 76607 times.
✓ Branch 3 taken 40064 times.
233342 values[Indices::velocityXIdx] = riemannFlux[1];
272
4/4
✓ Branch 0 taken 76607 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 76607 times.
✓ Branch 3 taken 40064 times.
233342 values[Indices::velocityYIdx] = riemannFlux[2];
273
274 // Addition of viscosity/diffusive flux rough wall boundaries
275 // No-slip wall (with coefficient alphaWall):
276 // Compute wall shear stress using turbulent viscosity and local velocity gradient
277 // Assume velocity gradient (in cell adjacent to wall) equal to alphaWall*(0 - u_c)
278 116671 std::array<Scalar, 3> roughWallFlux{};
279
24/24
✓ Branch 0 taken 76607 times.
✓ Branch 1 taken 40064 times.
✓ Branch 2 taken 76607 times.
✓ Branch 3 taken 40064 times.
✓ Branch 4 taken 76607 times.
✓ Branch 5 taken 40064 times.
✓ Branch 6 taken 76607 times.
✓ Branch 7 taken 40064 times.
✓ Branch 8 taken 76607 times.
✓ Branch 9 taken 40064 times.
✓ Branch 10 taken 76607 times.
✓ Branch 11 taken 40064 times.
✓ Branch 12 taken 40109 times.
✓ Branch 13 taken 36498 times.
✓ Branch 14 taken 40109 times.
✓ Branch 15 taken 36498 times.
✓ Branch 16 taken 40109 times.
✓ Branch 17 taken 36498 times.
✓ Branch 18 taken 40109 times.
✓ Branch 19 taken 36498 times.
✓ Branch 20 taken 40109 times.
✓ Branch 21 taken 36498 times.
✓ Branch 22 taken 40109 times.
✓ Branch 23 taken 36498 times.
700026 if (scvf.center()[1] < this->gridGeometry().bBoxMin()[1] + eps_ || scvf.center()[1] > this->gridGeometry().bBoxMax()[1] - eps_)
280 {
281 // Distance vector between the inside cell center and the boundary face center
282 240519 const auto& cellCenterToBoundaryFaceCenter = scvf.center() - insideScv.center();
283
284 // The left (inside) state vector
285 80173 const auto& leftState = insideVolVars.priVars();
286
287
1/2
✓ Branch 1 taken 80173 times.
✗ Branch 2 not taken.
80173 if (wallFrictionLawType_ == "noslip")
288 {
289 80173 roughWallFlux = ShallowWater::noslipWallBoundary(alphaWall_,
290 80173 turbViscosity_,
291 leftState,
292 cellCenterToBoundaryFaceCenter,
293 unitNormal);
294 }
295 else if (wallFrictionLawType_ == "nikuradse")
296 {
297 roughWallFlux = ShallowWater::nikuradseWallBoundary(ksWall_,
298 leftState,
299 cellCenterToBoundaryFaceCenter,
300 unitNormal);
301 }
302 }
303
304 350013 values[Indices::massBalanceIdx] += roughWallFlux[0];
305 350013 values[Indices::velocityXIdx] += roughWallFlux[1];
306 350013 values[Indices::velocityYIdx] += roughWallFlux[2];
307
308 116671 return values;
309 }
310
311 // \}
312
313 /*!
314 * \brief Evaluate the initial values for a control volume.
315 * \param globalPos The position for which the boundary type is set
316 */
317 2038 PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
318 {
319 2038 PrimaryVariables values(0.0);
320
321 // Set the initial values to the analytical solution
322 4076 const auto gravity = this->spatialParams().gravity(globalPos);
323 14266 const auto width = this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1];
324
325 4076 values[0] = hBoundary_;
326 8152 values[1] = -(gravity*bedSlope_/(8.0*turbViscosity_)) * (4.0*globalPos[1]*globalPos[1] - width*width);
327 4076 values[2] = 0.0;
328
329 2038 return values;
330 };
331
332 private:
333
334 std::vector<Scalar> exactWaterDepth_;
335 std::vector<Scalar> exactVelocityX_;
336 std::vector<Scalar> exactVelocityY_;
337
338 Scalar hBoundary_; // water level at the outflow boundary
339 Scalar bedSlope_; // bed slope (positive downwards)
340 Scalar discharge_; // discharge at the inflow boundary
341 Scalar alphaWall_; // wall roughness coefficient for no-slip type wall roughness
342 Scalar ksWall_; // Nikuradse wall roughness height for Nikuradse type wall roughness
343 Scalar turbViscosity_; // turbulent viscosity
344 std::string wallFrictionLawType_; // wall friction law type
345
346 static constexpr Scalar eps_ = 1.0e-6;
347 std::string name_;
348 };
349
350 } //end namespace Dumux
351
352 #endif
353