GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/freeflow/shallowwater/boundaryfluxes.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 39 57 68.4%
Functions: 3 4 75.0%
Branches: 10 24 41.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 * \file
9 * \ingroup ShallowWaterModels
10 * \brief Compute boundary conditions for the Riemann Solver
11 *
12 * The boundary conditions are given at the the outer face of the
13 * the boundary cells. In this form the boundary condition can't be
14 * processed by the riemann Solver, because it needs two cell states, one at
15 * each side of a face. Therefore the Riemann invariants are used to
16 * calculate a virtual outer state.
17 */
18 #ifndef DUMUX_SHALLOWWATER_BOUNDARYFLUXES_HH
19 #define DUMUX_SHALLOWWATER_BOUNDARYFLUXES_HH
20
21 #include <array>
22 #include <cmath>
23 #include <algorithm>
24
25 namespace Dumux::ShallowWater {
26
27 /*!
28 * \brief Compute the outer cell state for fixed water depth boundary.
29 *
30 * \param waterDepthBoundary Water depth at the boundary face [m^2/s]
31 * \param waterDepthInside Water depth in the inner cell [m]
32 * \param velocityXInside Velocity in x-direction in the inner cell [m/s]
33 * \param velocityYInside Velocity in y-direction in the inner cell [m/s]
34 * \param gravity Gravity constant [m/s^2]
35 * \param nxy Normal vector of the boundary face
36 *
37 * \return cellStateOutside The outer cell state
38 */
39 template<class Scalar, class GlobalPosition>
40 23418 std::array<Scalar, 3> fixedWaterDepthBoundary(const Scalar waterDepthBoundary,
41 const Scalar waterDepthInside,
42 const Scalar velocityXInside,
43 const Scalar velocityYInside,
44 const Scalar gravity,
45 const GlobalPosition& nxy)
46
47 {
48 std::array<Scalar, 3> cellStateOutside;
49 46836 cellStateOutside[0] = waterDepthBoundary;
50
51 using std::sqrt;
52 70254 const auto uboundIn = nxy[0] * velocityXInside + nxy[1] * velocityYInside;
53 46836 const auto uboundQut = uboundIn + 2.0 * sqrt(gravity * waterDepthInside) - 2.0 * sqrt(gravity * cellStateOutside[0]);
54
55 70254 cellStateOutside[1] = (nxy[0] * uboundQut); // we only use the normal part
56 70254 cellStateOutside[2] = (nxy[1] * uboundQut); // we only use the normal part
57
58 23418 return cellStateOutside;
59 }
60
61 /*!
62 * \brief Compute the outer cell state for a fixed discharge boundary.
63 *
64 * \param dischargeBoundary Discharge per meter at the boundary face [m^2/s]
65 * \param waterDepthInside Water depth in the inner cell [m]
66 * \param velocityXInside Velocity in x-direction in the inner cell [m/s]
67 * \param velocityYInside Velocity in y-direction in the inner cell [m/s]
68 * \param gravity Gravity constant [m/s^2]
69 * \param nxy Normal vector of the boundary face
70 *
71 * \return cellStateOutside The outer cell state
72 */
73 template<class Scalar, class GlobalPosition>
74 23143 std::array<Scalar, 3> fixedDischargeBoundary(const Scalar dischargeBoundary,
75 const Scalar waterDepthInside,
76 const Scalar velocityXInside,
77 const Scalar velocityYInside,
78 const Scalar gravity,
79 const GlobalPosition& nxy)
80 {
81 std::array<Scalar, 3> cellStateOutside;
82 using std::abs;
83 using std::sqrt;
84 using std::max;
85
86 // only impose if abs(q) > 0
87
2/4
✓ Branch 0 taken 23143 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23143 times.
✗ Branch 3 not taken.
46286 if (abs(dischargeBoundary) > 1.0e-9)
88 {
89 46286 const auto uboundIn = nxy[0]*velocityXInside + nxy[1]*velocityYInside;
90 23143 const auto alphal = uboundIn + 2.0*sqrt(gravity * waterDepthInside);
91
92 //initial guess for hstar solved with newton
93 23143 constexpr Scalar tol_hstar = 1.0E-12;
94 23143 constexpr Scalar ink_hstar = 1.0E-9;
95 23143 constexpr int maxstep_hstar = 30;
96
97 23143 Scalar hstar = 0.1;
98
1/2
✓ Branch 0 taken 228064 times.
✗ Branch 1 not taken.
228064 for (int i = 0; i < maxstep_hstar; ++i)
99 {
100 228064 Scalar f_hstar = alphal - dischargeBoundary/hstar - 2 * sqrt(gravity * hstar);
101 228064 Scalar df_hstar = (f_hstar -(alphal - dischargeBoundary/(hstar + ink_hstar) - 2 * sqrt(gravity * (hstar+ink_hstar))))/ink_hstar;
102 228064 Scalar dx_hstar = -f_hstar/df_hstar;
103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 228064 times.
228064 hstar = max(hstar - dx_hstar,0.001);
104
105
2/2
✓ Branch 0 taken 204921 times.
✓ Branch 1 taken 23143 times.
228064 if (dx_hstar*dx_hstar < tol_hstar)
106 break;
107 }
108
109 46286 const auto qinner = (nxy[0] * waterDepthInside * velocityYInside) - (nxy[1] * waterDepthInside * velocityXInside);
110 23143 cellStateOutside[0] = hstar;
111 69429 cellStateOutside[1] = (nxy[0] * dischargeBoundary - nxy[1] * qinner)/hstar;
112 92572 cellStateOutside[2] = (nxy[1] * dischargeBoundary + nxy[0] * qinner)/hstar;
113 }
114
115 23143 return cellStateOutside;
116 }
117
118 /*!
119 * \brief Compute the viscosity/diffusive flux at a rough wall boundary using no-slip formulation.
120 *
121 * \param alphaWall Roughness parameter: alphaWall=0.0 means full slip, alphaWall=1.0 means no slip, \f$0.0<\text{alphaWall}<1.0\f$ means partial slip [-]
122 * \param turbulentViscosity Turbulent viscosity [m^2/s]
123 * \param state Primary variables (water depth, velocities)
124 * \param cellCenterToBoundaryFaceCenter Cell-center to boundary distance
125 * \param unitNormal Normal vector of the boundary face
126 */
127 template<class PrimaryVariables, class Scalar, class GlobalPosition>
128 80173 std::array<Scalar, 3> noslipWallBoundary(const Scalar alphaWall,
129 const Scalar turbulentViscosity,
130 const PrimaryVariables& state,
131 const GlobalPosition& cellCenterToBoundaryFaceCenter,
132 const GlobalPosition& unitNormal)
133 {
134 // only impose if abs(alphaWall) > 0
135 using std::abs;
136
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 80173 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80173 times.
160346 if (abs(alphaWall) <= 1.0e-9)
137 return {};
138
139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80173 times.
80173 const auto waterDepth = state[0];
140 // regularization: Set gradients to zero for drying cell
141 // Use LET-limiter instead for differentiability?
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80173 times.
80173 if (waterDepth <= 0.001)
143 return {};
144
145 80173 const auto xVelocity = state[1];
146 80173 const auto yVelocity = state[2];
147 80173 const auto distance = cellCenterToBoundaryFaceCenter.two_norm();
148
149 // Compute the velocity gradients
150 // Outside - inside cell: therefore the minus-sign
151 // Only when cell contains sufficient water.
152 80173 const auto gradU = -alphaWall * xVelocity/distance;
153 80173 const auto gradV = -alphaWall * yVelocity/distance;
154
155 // Factor that takes the direction of the unit vector into account
156 80173 const auto direction = (unitNormal*cellCenterToBoundaryFaceCenter)/distance;
157
158 // Compute the viscosity/diffusive fluxes at the rough wall
159 return {
160 0.0,
161 80173 -turbulentViscosity*waterDepth*gradU*direction,
162 80173 -turbulentViscosity*waterDepth*gradV*direction
163 80173 };
164 }
165
166 /*!
167 * \brief Compute the viscosity/diffusive flux at a rough wall boundary using Nikuradse formulation.
168 *
169 * \param ksWall Nikuradse roughness height for the wall [m]
170 * \param state the primary variable state (water depth, velocities)
171 * \param cellCenterToBoundaryFaceCenter Cell-center to boundary distance
172 * \param unitNormal Normal vector of the boundary face
173 */
174 template<class PrimaryVariables, class Scalar, class GlobalPosition>
175 std::array<Scalar, 3> nikuradseWallBoundary(const Scalar ksWall,
176 const PrimaryVariables& state,
177 const GlobalPosition& cellCenterToBoundaryFaceCenter,
178 const GlobalPosition& unitNormal)
179 {
180 // only impose if abs(ksWall) > 0
181 using std::abs;
182 if (abs(ksWall) <= 1.0e-9)
183 return {};
184
185 using std::hypot;
186 const Scalar xVelocity = state[1];
187 const Scalar yVelocity = state[2];
188 const Scalar velocityMagnitude = hypot(xVelocity, yVelocity);
189 const Scalar distance = cellCenterToBoundaryFaceCenter.two_norm();
190 const Scalar y0w = ksWall/30.0;
191 constexpr Scalar kappa2 = 0.41*0.41;
192
193 // should distance/y0w be limited to not become too small?
194 using std::log; using std::max;
195 const auto logYPlus = log(distance/y0w+1.0);
196 const auto fac = kappa2*velocityMagnitude / max(1.0e-3,logYPlus*logYPlus);
197
198 // Factor that takes the direction of the unit vector into account
199 const auto direction = (unitNormal*cellCenterToBoundaryFaceCenter)/distance;
200
201 // wall shear stress vector
202 const auto tauWx = direction*fac*xVelocity;
203 const auto tauWy = direction*fac*yVelocity;
204
205 // Compute the viscosity/diffusive fluxes at the rough wall
206 const auto waterDepth = state[0];
207 return {0.0, waterDepth*tauWx, waterDepth*tauWy};
208 }
209
210 } // end namespace Dumux::ShallowWater
211
212 #endif
213