version 3.11-dev
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
39template<class Scalar, class GlobalPosition>
40std::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 std::array<Scalar, 3> cellStateOutside;
48 cellStateOutside[0] = waterDepthBoundary;
49 using std::sqrt;
50 const auto uNormalIn = nxy[0] * velocityXInside + nxy[1] * velocityYInside;
51 const auto uTangentialIn = -nxy[1] * velocityXInside + nxy[0] * velocityYInside;
52 const auto uNormalOut = uNormalIn + 2.0 * sqrt(gravity * waterDepthInside) - 2.0 * sqrt(gravity * cellStateOutside[0]);
53
54 cellStateOutside[1] = (nxy[0] * uNormalOut - nxy[1] * uTangentialIn);
55 cellStateOutside[2] = (nxy[1] * uNormalOut + nxy[0] * uTangentialIn);
56
57 return cellStateOutside;
58}
59
72template<class Scalar, class GlobalPosition>
73std::array<Scalar, 3> fixedDischargeBoundary(const Scalar dischargeBoundary,
74 const Scalar waterDepthInside,
75 const Scalar velocityXInside,
76 const Scalar velocityYInside,
77 const Scalar gravity,
78 const GlobalPosition& nxy)
79{
80 std::array<Scalar, 3> cellStateOutside;
81 using std::abs;
82 using std::sqrt;
83 using std::max;
84
85 // only impose if abs(q) > 0
86 if (abs(dischargeBoundary) > 1.0e-9)
87 {
88 const auto uboundIn = nxy[0]*velocityXInside + nxy[1]*velocityYInside;
89 const auto alphal = uboundIn + 2.0*sqrt(gravity * waterDepthInside);
90
91 //initial guess for hstar solved with newton
92 constexpr Scalar tol_hstar = 1.0E-12;
93 constexpr Scalar ink_hstar = 1.0E-9;
94 constexpr int maxstep_hstar = 30;
95
96 Scalar hstar = 0.1;
97 for (int i = 0; i < maxstep_hstar; ++i)
98 {
99 Scalar f_hstar = alphal - dischargeBoundary/hstar - 2 * sqrt(gravity * hstar);
100 Scalar df_hstar = (f_hstar -(alphal - dischargeBoundary/(hstar + ink_hstar) - 2 * sqrt(gravity * (hstar+ink_hstar))))/ink_hstar;
101 Scalar dx_hstar = -f_hstar/df_hstar;
102 hstar = max(hstar - dx_hstar,0.001);
103
104 if (dx_hstar*dx_hstar < tol_hstar)
105 break;
106 }
107
108 const auto qinner = (nxy[0] * waterDepthInside * velocityYInside) - (nxy[1] * waterDepthInside * velocityXInside);
109 cellStateOutside[0] = hstar;
110 cellStateOutside[1] = (nxy[0] * dischargeBoundary - nxy[1] * qinner)/hstar;
111 cellStateOutside[2] = (nxy[1] * dischargeBoundary + nxy[0] * qinner)/hstar;
112 }
113
114 return cellStateOutside;
115}
116
126template<class PrimaryVariables, class Scalar, class GlobalPosition>
127std::array<Scalar, 3> noslipWallBoundary(const Scalar alphaWall,
128 const Scalar turbulentViscosity,
129 const PrimaryVariables& state,
130 const GlobalPosition& cellCenterToBoundaryFaceCenter,
131 const GlobalPosition& unitNormal)
132{
133 // only impose if abs(alphaWall) > 0
134 using std::abs;
135 if (abs(alphaWall) <= 1.0e-9)
136 return {};
137
138 const auto waterDepth = state[0];
139 // regularization: Set gradients to zero for drying cell
140 // Use LET-limiter instead for differentiability?
141 if (waterDepth <= 0.001)
142 return {};
143
144 const auto xVelocity = state[1];
145 const auto yVelocity = state[2];
146 const auto distance = cellCenterToBoundaryFaceCenter.two_norm();
147
148 // Compute the velocity gradients
149 // Outside - inside cell: therefore the minus-sign
150 // Only when cell contains sufficient water.
151 const auto gradU = -alphaWall * xVelocity/distance;
152 const auto gradV = -alphaWall * yVelocity/distance;
153
154 // Factor that takes the direction of the unit vector into account
155 const auto direction = (unitNormal*cellCenterToBoundaryFaceCenter)/distance;
156
157 // Compute the viscosity/diffusive fluxes at the rough wall
158 return {
159 0.0,
160 -turbulentViscosity*waterDepth*gradU*direction,
161 -turbulentViscosity*waterDepth*gradV*direction
162 };
163}
164
173template<class PrimaryVariables, class Scalar, class GlobalPosition>
174std::array<Scalar, 3> nikuradseWallBoundary(const Scalar ksWall,
175 const PrimaryVariables& state,
176 const GlobalPosition& cellCenterToBoundaryFaceCenter,
177 const GlobalPosition& unitNormal)
178{
179 // only impose if abs(ksWall) > 0
180 using std::abs;
181 if (abs(ksWall) <= 1.0e-9)
182 return {};
183
184 using std::hypot;
185 const Scalar xVelocity = state[1];
186 const Scalar yVelocity = state[2];
187 const Scalar velocityMagnitude = hypot(xVelocity, yVelocity);
188 const Scalar distance = cellCenterToBoundaryFaceCenter.two_norm();
189 const Scalar y0w = ksWall/30.0;
190 constexpr Scalar kappa2 = 0.41*0.41;
191
192 // should distance/y0w be limited to not become too small?
193 using std::log; using std::max;
194 const auto logYPlus = log(distance/y0w+1.0);
195 const auto fac = kappa2*velocityMagnitude / max(1.0e-3,logYPlus*logYPlus);
196
197 // Factor that takes the direction of the unit vector into account
198 const auto direction = (unitNormal*cellCenterToBoundaryFaceCenter)/distance;
199
200 // wall shear stress vector
201 const auto tauWx = direction*fac*xVelocity;
202 const auto tauWy = direction*fac*yVelocity;
203
204 // Compute the viscosity/diffusive fluxes at the rough wall
205 const auto waterDepth = state[0];
206 return {0.0, waterDepth*tauWx, waterDepth*tauWy};
207}
208
209} // end namespace Dumux::ShallowWater
210
211#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 > 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:73
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:174
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:127
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:40