version 3.11-dev
Loading...
Searching...
No Matches
boundaryfluxes.hh
Go to the documentation of this file.
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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
18#ifndef DUMUX_SHALLOWWATER_BOUNDARYFLUXES_HH
19#define DUMUX_SHALLOWWATER_BOUNDARYFLUXES_HH
20
21#include <array>
22#include <cmath>
23#include <algorithm>
24
25namespace Dumux::ShallowWater {
26
40template<class Scalar, class GlobalPosition>
41std::array<Scalar, 3> wallBoundary(const Scalar waterDepthInside,
42 const Scalar velocityXInside,
43 const Scalar velocityYInside,
44 const GlobalPosition& nxy)
45{
46 const auto uNormalIn = nxy[0]*velocityXInside + nxy[1]*velocityYInside;
47 return {{waterDepthInside,
48 velocityXInside - 2.0*uNormalIn*nxy[0],
49 velocityYInside - 2.0*uNormalIn*nxy[1]}};
50}
51
65template<class Scalar, class GlobalPosition>
66std::array<Scalar, 3> inflowBoundary(const Scalar waterDepthBoundary,
67 const Scalar speedBoundary,
68 const GlobalPosition& nxy)
69{
70 return {{waterDepthBoundary, -speedBoundary*nxy[0], -speedBoundary*nxy[1]}};
71}
72
92template<class Scalar, class GlobalPosition>
93std::array<Scalar, 3> criticalDepthOutflowBoundary(const Scalar waterDepthInside,
94 const Scalar velocityXInside,
95 const Scalar velocityYInside,
96 const Scalar gravity,
97 const GlobalPosition& nxy)
98{
99 using std::sqrt; using std::cbrt; using std::max;
100
101 const auto uNormalIn = nxy[0]*velocityXInside + nxy[1]*velocityYInside;
102 if (uNormalIn <= 0.0)
103 return wallBoundary(waterDepthInside, velocityXInside, velocityYInside, nxy);
104
105 const auto froude = uNormalIn/sqrt(gravity*max(waterDepthInside, Scalar(1e-12)));
106 if (froude >= 1.0)
107 return {{waterDepthInside, velocityXInside, velocityYInside}};
108
109 const auto normalDischarge = waterDepthInside*uNormalIn;
110 const auto criticalDepth = cbrt(normalDischarge*normalDischarge/gravity);
111 const auto uNormalOut = sqrt(gravity*criticalDepth);
112 const auto uTangentialIn = -nxy[1]*velocityXInside + nxy[0]*velocityYInside;
113 return {{criticalDepth,
114 nxy[0]*uNormalOut - nxy[1]*uTangentialIn,
115 nxy[1]*uNormalOut + nxy[0]*uTangentialIn}};
116}
117
130template<class Scalar, class GlobalPosition>
131std::array<Scalar, 3> fixedWaterDepthBoundary(const Scalar waterDepthBoundary,
132 const Scalar waterDepthInside,
133 const Scalar velocityXInside,
134 const Scalar velocityYInside,
135 const Scalar gravity,
136 const GlobalPosition& nxy)
137{
138 std::array<Scalar, 3> cellStateOutside;
139 cellStateOutside[0] = waterDepthBoundary;
140 using std::sqrt;
141 const auto uNormalIn = nxy[0] * velocityXInside + nxy[1] * velocityYInside;
142 const auto uTangentialIn = -nxy[1] * velocityXInside + nxy[0] * velocityYInside;
143 const auto uNormalOut = uNormalIn + 2.0 * sqrt(gravity * waterDepthInside) - 2.0 * sqrt(gravity * cellStateOutside[0]);
144
145 cellStateOutside[1] = (nxy[0] * uNormalOut - nxy[1] * uTangentialIn);
146 cellStateOutside[2] = (nxy[1] * uNormalOut + nxy[0] * uTangentialIn);
147
148 return cellStateOutside;
149}
150
163template<class Scalar, class GlobalPosition>
164std::array<Scalar, 3> fixedDischargeBoundary(const Scalar dischargeBoundary,
165 const Scalar waterDepthInside,
166 const Scalar velocityXInside,
167 const Scalar velocityYInside,
168 const Scalar gravity,
169 const GlobalPosition& nxy)
170{
171 using std::abs;
172 using std::sqrt;
173 using std::max;
174
175 // a vanishing discharge is a wall
176 auto cellStateOutside = wallBoundary(waterDepthInside, velocityXInside, velocityYInside, nxy);
177
178 if (abs(dischargeBoundary) > 1.0e-9)
179 {
180 const auto uboundIn = nxy[0]*velocityXInside + nxy[1]*velocityYInside;
181 const auto alphal = uboundIn + 2.0*sqrt(gravity * waterDepthInside);
182
183 //initial guess for hstar solved with newton
184 constexpr Scalar tol_hstar = 1.0E-12;
185 constexpr Scalar ink_hstar = 1.0E-9;
186 constexpr int maxstep_hstar = 30;
187
188 Scalar hstar = 0.1;
189 for (int i = 0; i < maxstep_hstar; ++i)
190 {
191 Scalar f_hstar = alphal - dischargeBoundary/hstar - 2 * sqrt(gravity * hstar);
192 Scalar df_hstar = (f_hstar -(alphal - dischargeBoundary/(hstar + ink_hstar) - 2 * sqrt(gravity * (hstar+ink_hstar))))/ink_hstar;
193 Scalar dx_hstar = -f_hstar/df_hstar;
194 hstar = max(hstar - dx_hstar,0.001);
195
196 if (dx_hstar*dx_hstar < tol_hstar)
197 break;
198 }
199
200 const auto qinner = (nxy[0] * waterDepthInside * velocityYInside) - (nxy[1] * waterDepthInside * velocityXInside);
201 cellStateOutside[0] = hstar;
202 cellStateOutside[1] = (nxy[0] * dischargeBoundary - nxy[1] * qinner)/hstar;
203 cellStateOutside[2] = (nxy[1] * dischargeBoundary + nxy[0] * qinner)/hstar;
204 }
205
206 return cellStateOutside;
207}
208
218template<class PrimaryVariables, class Scalar, class GlobalPosition>
219std::array<Scalar, 3> noslipWallBoundary(const Scalar alphaWall,
220 const Scalar turbulentViscosity,
221 const PrimaryVariables& state,
222 const GlobalPosition& cellCenterToBoundaryFaceCenter,
223 const GlobalPosition& unitNormal)
224{
225 // only impose if abs(alphaWall) > 0
226 using std::abs;
227 if (abs(alphaWall) <= 1.0e-9)
228 return {};
229
230 const auto waterDepth = state[0];
231 // regularization: Set gradients to zero for drying cell
232 // Use LET-limiter instead for differentiability?
233 if (waterDepth <= 0.001)
234 return {};
235
236 const auto xVelocity = state[1];
237 const auto yVelocity = state[2];
238 const auto distance = cellCenterToBoundaryFaceCenter.two_norm();
239
240 // Compute the velocity gradients
241 // Outside - inside cell: therefore the minus-sign
242 // Only when cell contains sufficient water.
243 const auto gradU = -alphaWall * xVelocity/distance;
244 const auto gradV = -alphaWall * yVelocity/distance;
245
246 // Factor that takes the direction of the unit vector into account
247 const auto direction = (unitNormal*cellCenterToBoundaryFaceCenter)/distance;
248
249 // Compute the viscosity/diffusive fluxes at the rough wall
250 return {
251 0.0,
252 -turbulentViscosity*waterDepth*gradU*direction,
253 -turbulentViscosity*waterDepth*gradV*direction
254 };
255}
256
265template<class PrimaryVariables, class Scalar, class GlobalPosition>
266std::array<Scalar, 3> nikuradseWallBoundary(const Scalar ksWall,
267 const PrimaryVariables& state,
268 const GlobalPosition& cellCenterToBoundaryFaceCenter,
269 const GlobalPosition& unitNormal)
270{
271 // only impose if abs(ksWall) > 0
272 using std::abs;
273 if (abs(ksWall) <= 1.0e-9)
274 return {};
275
276 using std::hypot;
277 const Scalar xVelocity = state[1];
278 const Scalar yVelocity = state[2];
279 const Scalar velocityMagnitude = hypot(xVelocity, yVelocity);
280 const Scalar distance = cellCenterToBoundaryFaceCenter.two_norm();
281 const Scalar y0w = ksWall/30.0;
282 constexpr Scalar kappa2 = 0.41*0.41;
283
284 // should distance/y0w be limited to not become too small?
285 using std::log; using std::max;
286 const auto logYPlus = log(distance/y0w+1.0);
287 const auto fac = kappa2*velocityMagnitude / max(1.0e-3,logYPlus*logYPlus);
288
289 // Factor that takes the direction of the unit vector into account
290 const auto direction = (unitNormal*cellCenterToBoundaryFaceCenter)/distance;
291
292 // wall shear stress vector
293 const auto tauWx = direction*fac*xVelocity;
294 const auto tauWy = direction*fac*yVelocity;
295
296 // Compute the viscosity/diffusive fluxes at the rough wall
297 const auto waterDepth = state[0];
298 return {0.0, waterDepth*tauWx, waterDepth*tauWy};
299}
300
301} // end namespace Dumux::ShallowWater
302
303#endif
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition distance.hh:282
Vector unitNormal(const Vector &v)
Create a vector normal to the given one (v is expected to be non-zero).
Definition normal.hh:58
Definition exactriemann.hh:19
std::array< Scalar, 3 > criticalDepthOutflowBoundary(const Scalar waterDepthInside, const Scalar velocityXInside, const Scalar velocityYInside, const Scalar gravity, const GlobalPosition &nxy)
Compute the outer cell state for a free overfall (open outflow).
Definition boundaryfluxes.hh:93
std::array< Scalar, 3 > fixedDischargeBoundary(const Scalar dischargeBoundary, const Scalar waterDepthInside, const Scalar velocityXInside, const Scalar velocityYInside, const Scalar gravity, const GlobalPosition &nxy)
Compute the outer cell state for a fixed discharge boundary.
Definition boundaryfluxes.hh:164
std::array< Scalar, 3 > nikuradseWallBoundary(const Scalar ksWall, const PrimaryVariables &state, const GlobalPosition &cellCenterToBoundaryFaceCenter, const GlobalPosition &unitNormal)
Compute the viscosity/diffusive flux at a rough wall boundary using Nikuradse formulation.
Definition boundaryfluxes.hh:266
std::array< Scalar, 3 > inflowBoundary(const Scalar waterDepthBoundary, const Scalar speedBoundary, const GlobalPosition &nxy)
Compute the outer cell state for an inflow with prescribed depth and speed.
Definition boundaryfluxes.hh:66
std::array< Scalar, 3 > noslipWallBoundary(const Scalar alphaWall, const Scalar turbulentViscosity, const PrimaryVariables &state, const GlobalPosition &cellCenterToBoundaryFaceCenter, const GlobalPosition &unitNormal)
Compute the viscosity/diffusive flux at a rough wall boundary using no-slip formulation.
Definition boundaryfluxes.hh:219
std::array< Scalar, 3 > wallBoundary(const Scalar waterDepthInside, const Scalar velocityXInside, const Scalar velocityYInside, const GlobalPosition &nxy)
Compute the outer cell state for a slip wall.
Definition boundaryfluxes.hh:41
std::array< Scalar, 3 > fixedWaterDepthBoundary(const Scalar waterDepthBoundary, const Scalar waterDepthInside, const Scalar velocityXInside, const Scalar velocityYInside, const Scalar gravity, const GlobalPosition &nxy)
Compute the outer cell state for fixed water depth boundary.
Definition boundaryfluxes.hh:131