Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
discharge.h
Go to the documentation of this file.
1/** @file discharge.h
2 */
3/**
4# Shallow-water flux computation at boundaries
5
6In order to impose a given flow rate \f$Q_b\f$ through a boundary \f$b\f$, when
7solving the [Saint-Venant equations](saint-venant.h), we need to
8compute the water level \f$\eta_b\f$ corresponding to this flow rate. The
9flow rate \f$Q\f$ is a complicated, non-linear function of the water
10level, the bathymetry \f$z_b\f$ and the velocity normal to the boundary
11\f$u_n\f$.
12
13We first define a function which, given \f$\eta_b\f$ and the current
14topography and velocity fields (defined by the [Saint-Venant
15solver](saint-venant.h)), returns the flow rate through boundary *b*.
16
17The extent of the boundary can also be limited to points for which
18`limit[] = value`. */
19
20struct Eta_b {
21 // compulsory arguments
22 double Q_b;
24 // optional arguments
26 double value;
27 double prec; // precision (default 0.1%)
28};
29
30static double bflux (struct Eta_b p, double eta_b)
31{
32 double Q = 0.;
33 scalar limit = p.limit;
34 for (int _b = 0; _b < 1; _b++) /* boundary p.b, reduction(+:Q */)
35 if (limit.i < 0 || limit[] == p.value) {
36 scalar u_n = ig ? u.x : u.y; // normal velocity component
37 double sign = - (ig + jg), ub = u_n[]*sign;
38 double hn = max (eta_b - zb[], 0.), hp = max(h[],0.);
39 if (hp > dry || hn > dry) {
40 double fh, fu, dtmax;
41 kurganov (hn, hp, ub, ub, 0., &fh, &fu, &dtmax);
42 Q += fh*Delta; // fixme: metric
43 }
44 }
45 return Q;
46}
47
48/**
49To find the water level \f$\eta_b\f$ corresponding to the flow rate \f$Q_b\f$
50we want to impose, we need to invert the function above i.e. find
51\f$\eta_b\f$ such that
52\f[
53Q[z_b,u_n](\eta_b) = Q_b
54\f]
55We do this using the [false position
56method](http://en.wikipedia.org/wiki/False_position_method). */
57
58static double falsepos (struct Eta_b p,
59 double binf, double qinf,
60 double bsup, double qsup)
61{
62 int n = 0;
63 double newb, newq;
64 qinf -= p.Q_b;
65 qsup -= p.Q_b;
66 do {
67 newb = (binf*qsup - bsup*qinf)/(qsup - qinf);
68 newq = bflux (p, newb) - p.Q_b;
69 if (newq > 0.)
70 bsup = newb, qsup = newq;
71 else
72 binf = newb, qinf = newq;
73 n++;
74 } while (fabs(newq/p.Q_b) > p.prec && n < 100);
75
76 if (n >= 100)
77 fprintf (stderr, "src/discharge.h:%d: warning: eta_b(): convergence not reached\n", LINENO);
78
79 return newb;
80}
81
82/**
83## User interface
84
85Given a target flux \f$Q_b\f$ and a boundary \f$b\f$ (optionally limited to
86points for which `limit[] = value`), this function returns the
87corresponding water level \f$\eta_b\f$. */
88
89double eta_b (double Q_b, bid b,
90 scalar limit = {-1}, double value = 0, double prec = 0.001)
91{
92 double zmin = HUGE, etas = 0., hs = 0.;
93 for (int _b = 0; _b < 1; _b++) /* boundary b, reduction(+:etas */ reduction(+:hs) reduction(min:zmin))
94 if (limit.i < 0 || limit[] == value) {
95 if (zb[] < zmin)
96 zmin = zb[];
97 etas += Delta*h[]*eta[];
98 hs += Delta*h[];
99 }
100
101 if (Q_b <= 0.)
102 return zmin - 1.;
103
104 /**
105 We try to find good bounds on the solution. */
106
107 double etasup = hs > 0. ? etas/hs : zmin;
108 struct Eta_b p = { Q_b, b, limit, value, prec };
109 double Qsup = bflux (p, etasup), etainf = zmin, Qinf = 0.;
110 double h0 = etasup - zmin;
111 if (h0 < dry)
112 h0 = 1.;
113 int n = 0;
114 while (Qsup < p.Q_b && n++ < 100) {
115 etainf = etasup, Qinf = Qsup;
116 etasup += h0;
117 Qsup = bflux (p, etasup);
118 }
119 if (n >= 100)
120 fprintf (stderr, "src/discharge.h:%d: warning: eta_b() not converged\n", LINENO);
121 return falsepos (p, etainf, Qinf, etasup, Qsup);
122}
#define u
Definition advection.h:30
double dtmax
The timestep is computed using the CFL condition on the face velocity field.
Definition all-mach.h:105
scalar zb[]
Definition atmosphere.h:6
scalar hn[]
Definition atmosphere.h:6
scalar h[]
Definition atmosphere.h:6
int min
Definition balance.h:192
int bid
int x
Definition common.h:76
#define HUGE
Definition common.h:6
static int sign(number x)
Definition common.h:13
#define p
Definition tree.h:320
#define LINENO
Definition config.h:105
else return n
Definition curvature.h:101
double eta_b(double Q_b, bid b, scalar limit={-1}, double value=0, double prec=0.001)
Definition discharge.h:89
static double bflux(struct Eta_b p, double eta_b)
Definition discharge.h:30
static double falsepos(struct Eta_b p, double binf, double qinf, double bsup, double qsup)
To find the water level corresponding to the flow rate we want to impose, we need to invert the fun...
Definition discharge.h:58
if(2.*fabs(alpha)< fabs(n.y))
We need to reconstruct the face fractions fs for the fine cells.
Definition embed-tree.h:102
scalar int i
Definition embed.h:74
double dry
Definition entrainment.h:30
double h0
Definition heights.h:329
scalar eta
Definition hydro.h:50
size_t max
Definition mtrace.h:8
size *double * b
void kurganov(double hm, double hp, double um, double up, double Delta, double *fh, double *fq, double *dtmax)
Definition riemann.h:42
bid b
Definition discharge.h:23
scalar limit
Definition discharge.h:25
double prec
Definition discharge.h:27
double Q_b
Definition discharge.h:22
double value
Definition discharge.h:26
int i
Definition common.h:44