sandbox/nlemoine/SWE/diffwave/fullsaintvenant.c
#include "terrain.h"
#include "saint-venant.h"
#include "utils.h"
#include "output.h"
#include "nlemoine/SWE/manning-tilt.h"
#define ETABF 10.6
#define n_ch 0.03
#define n_fp 0.06
#define sec_per_day 86400.
#define M_PI acos(-1.0)
#define ETAE 1e-2 // error on water depth (1 cm)
#define HE 1e-2 // error on water depth (1 cm)
#define UE 1e-2 // 0.01 m/s
#define LEVEL 7
#define MINLEVEL 5
double stage_hydrograph (double tt)
{
return( ETABF-2.0*cos(2.0*M_PI*tt/sec_per_day) );
}
double segment_Q (coord segment[2], scalar h, vector u) // vient de "layered/hydro.h"
{
= {segment[0].y - segment[1].y, segment[1].x - segment[0].x};
coord m (&m);
normalize double tot = 0.;
foreach_segment (segment, p) {
double dl = 0.;
foreach_dimension() {
double dp = (p[1].x - p[0].x)*Delta/Delta_x*(fm.y[] + fm.y[0,1])/2.;
+= sq(dp);
dl }
= sqrt (dl);
dl for (int i = 0; i < 2; i++) {
= p[i];
coord a += dl/2.*
tot interpolate_linear (point, (struct _interpolate)
{h, a.x, a.y, 0.})*
(m.x*interpolate_linear (point, (struct _interpolate)
{u.x, a.x, a.y, 0.}) +
.y*interpolate_linear (point, (struct _interpolate)
m{u.y, a.x, a.y, 0.}));
}
}
// reduction
#if _MPI
(MPI_IN_PLACE, &tot, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce #endif
return tot;
}
double segment_eta (coord segment[2], scalar h, scalar eta)
{
= {segment[0].y - segment[1].y, segment[1].x - segment[0].x};
coord m (&m);
normalize double tot = 0., wtot = 0.;
foreach_segment (segment, p) {
double dl = 0.;
foreach_dimension() {
double dp = (p[1].x - p[0].x)*Delta/Delta_x*(fm.y[] + fm.y[0,1])/2.;
+= sq(dp);
dl }
= sqrt (dl);
dl for (int i = 0; i < 2; i++) {
= p[i];
coord a += dl/2.*
tot interpolate_linear (point, (struct _interpolate)
{h, a.x, a.y, 0.})*
interpolate_linear (point, (struct _interpolate)
{eta, a.x, a.y, 0.}) ;
+= dl/2.* interpolate_linear (point, (struct _interpolate)
wtot {h, a.x, a.y, 0.});
}
}
// reduction
#if _MPI
(MPI_IN_PLACE, &tot, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce (MPI_IN_PLACE, &wtot, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce #endif
return (tot/wtot);
}
FILE * fpcontrol;
int main (int argc, char * argv[])
{
(2048.);
size (-424.,-2332.);
origin (1 << LEVEL);
init_grid
// Get .kdt file
system("wget https://dropsu.sorbonne-universite.fr/s/sT5GkqPqzsaMYab/download");
system("mv download garonne_local.kdt");
// Get .pts file
system("wget https://dropsu.sorbonne-universite.fr/s/5TWiFJaAXGKcb6L/download");
system("mv download garonne_local.pts");
// Get .sum file
system("wget https://dropsu.sorbonne-universite.fr/s/sz5qF6fc7MwkPzz/download");
system("mv download garonne_local.sum");
= 9.81;
G .x = 0.;
tilt.y = 1.103e-3;
tilt
run();
if(pid()==0.)
fclose(fpcontrol);
}
event initialize (i=0)
{
terrain(zb,"garonne_local", NULL);
scalar zmin = zb.dmin;
output_ppm (zb, min = 3, max = 20, file = "topo6.png",
= 512, linear = true);
n
foreach()
{
double etaini = stage_hydrograph(0.);
[] = zb[]>etaini ? zb[] : etaini;
eta[] = eta[] > zb[] ? eta[]-zb[] : 0.;
h[] = zb[] + h[];
eta.x[] = 0.;
u.y[] = 0.;
udouble zzmin = zmin[]<nodata ? zmin[] : zb[];
[] = zzmin<ETABF ? n_ch : n_fp ;
nmanning}
if(pid()==0)
= fopen("outlet_info.txt","w");
fpcontrol
}
event update_BC(i++)
{
// Conditions aux limites
.n[top] = neumann(0.);
u// u.t[top] = dirichlet(0.);
.t[top] = neumann(0.);
u[top] = neumann(0.);
h[top] = neumann(0.);
zb[top] = neumann(0.);
eta[top] = neumann(0.);
nmanning
.n[bottom] = neumann(0.);
u.t[bottom] = dirichlet(0.);
u[bottom] = neumann(0.);
zb[bottom] = neumann(0.);
nmanning
foreach_boundary(bottom)
{
[] = fmax(zb[],stage_hydrograph(t));
eta[] = eta[]-zb[];
h}
[bottom] = neumann(0.);
eta[bottom] = neumann(0.);
h
boundary(all);
}
scalar l[];
event snapshot (t+=300. ; t<=86400.)
{
scalar m[], etam[];
foreach() {
[] = eta[]*(h[] > dry) - zb[];
m[] = h[] < dry ? 0. : (zb[] > 0. ? eta[] - zb[] : eta[]);
etam}
output_ppm (h, mask = m, min = 0, max = 10,
= 2048, linear = true, file = "h.mp4");
n }
event info_conservation (t+=30. ; t<=86400.)
{
[2];
coord Section[0] = (coord) { X0 , Y0+L0-L0/N };
Section[1] = (coord) { X0+L0 , Y0+L0-L0/N };
Section
// "Measure" discharge at top (outlet) section
double Q = segment_Q (Section,h,u);
// "Measure" mean elevation at top (outlet) section
double etam = segment_eta (Section,h,eta);
// Total water volume in domain
double Vol = 0.;
foreach()
+= h[] * Delta * Delta ;
Vol
if(pid()==0){
fprintf(fpcontrol,"%g %g %g %g\n",t/3600.,Q,etam,Vol);
fflush(fpcontrol);
}
}
// Adaptivity
scalar absu[];
int adapt() {
#if TREE
scalar eta[];
foreach()
[] = h[] > dry ? h[] + zb[] : 0;
etaboundary ({eta});
foreach()
[]= h[] > dry ? sqrt(u.y[]*u.y[]+u.x[]*u.x[]) : 0.;
absu
astats s = adapt_wavelet ({h,eta,absu}, (double[]){HE,ETAE,UE},
, MINLEVEL);
LEVEL
scalar zmin = zb.dmin;
foreach(){
double zzmin = zmin[]<nodata ? zmin[] : zb[];
[] = zzmin<ETABF ? n_ch : n_fp;
nmanning[] = level;
l}
boundary(all);
// fprintf (ferr, "# refined %d cells, coarsened %d cells\n", s.nf, s.nc);
return s.nf;
#else // Cartesian
return 0;
#endif
}
event do_adapt (i++) adapt();
Results
Simulated water depth (flow direction is from bottom to top)