/** Numerical clone of Dossmann et al 2016 https://doi.org/10.1002/2016JC011990 Inspired from http://basilisk.fr/sandbox/popinet/movingcylinder.c Compile with CC99='mpicc -std=c99' qcc -D_MPI=1 -D_NETCDF=1 -grid=multigrid3D -lm -lpnetcdf -O3 movingtopo.c -o movingtopo.e mpirun -np 4 movingtopo.e HPC: qcc -D_MPI=1 -D_NETCDF=1 -grid=multigrid3D -source movingtopo.c */ //#include "grid/multigrid.h" //#include "grid/multigrid3D.h" #include "navier-stokes/centered.h" #include "../libs/boussinesq.h" #include "../libs/extra.h" #include "fractions.h" #if _NETCDF #include "../libs/pnetcdf_bas.h" #endif double mu0 = 0.; // double kappa0 = 0.; double h0 = 0.06; double lr = 0.05; double xm = 0.; double N2 = 1.; double Ut = 1.; double d_acc = 0.15; double d_plate = 0.4; double tau1; double tau2; int npy = 1; int npz = 1; int slip_bc = 1; // free slip by default double tend = 5.; double dtout = 0.1; scalar topo[]; #if dimension > 2 #define MOUNTAIN (h0*exp(-(sq((x - xm)/lr))) - z) #define STRATIFICATION ((z*N2)) #else #define MOUNTAIN (h0*exp(-(sq((x - xm)/lr))) - y) #define STRATIFICATION ((y*N2)) #endif int main() { // declare user parameters params = array_new(); add_param ("N", &N, "int"); add_param ("npy", &npy, "int"); add_param ("npz", &npz, "int"); add_param ("slip_bc", &slip_bc, "int"); add_param ("L0", &L0, "double"); add_param ("h0", &h0, "double"); add_param ("lr", &lr, "double"); add_param ("Ut", &Ut, "double"); add_param ("N2", &N2, "double"); add_param ("xm", &xm, "double"); add_param ("mu", &mu0, "double"); add_param ("tend", &tend, "double"); add_param ("dtout", &dtout, "double"); add_param ("kappa", &kappa0, "double"); // Read the configuration file params.in read_params("params.in"); create_outdir(); backup_config(); // Topo CFL //dtmax = L0/N/Ut; dimensions(ny=npy); #if dimension > 2 dimensions(ny=npy, nz=npz); #endif const face vector muc[] = {mu0, mu0, mu0}; const face vector kappac[] = {kappa0, kappa0, kappa0}; if (mu0 > 0) mu = muc; if (kappa0 > 0) kappa = kappac; tau1 = 2*d_acc/Ut; tau2 = (L0 - d_plate/2 - 2*d_acc)/Ut; // tend = tau2 + 2*tau1; run(); array_free (params); } event init (t = 0) { if (slip_bc == 0){ u.t[top] = dirichlet(0.); u.t[bottom] = dirichlet(0.); u.t[left] = dirichlet(0.); u.t[right] = dirichlet(0.); #if dimension > 2 u.t[front] = dirichlet(0.); u.t[back] = dirichlet(0.); u.r[top] = dirichlet(0.); u.r[bottom] = dirichlet(0.); u.r[left] = dirichlet(0.); u.r[right] = dirichlet(0.); u.r[front] = dirichlet(0.); u.r[back] = dirichlet(0.); #endif } coord vc = {Ut,0., 0.}; // the velocity of the topo xm = 0.; fraction (topo, MOUNTAIN); foreach() { b[] = STRATIFICATION; foreach_dimension() u.x[] = topo[]*vc.x + 0.05*Ut*noise(); } #if _NETCDF FILE * fp; if ((fp = fopen("restart.nc", "r"))) { read_nc({b,u}, "restart.nc"); fclose(fp); } #endif #if _NETCDF char file_nc[90]; sprintf (file_nc, "%svars.nc", dpath); create_nc({b,u}, file_nc); #endif } event moving_topo (i++) { double u_var; if (t=tau1) & (t=tau1 + tau2) & (t<2*tau1 + tau2)) { double tprime = t - tau1 - tau2; u_var = Ut*(1 - tprime/tau1); xm = d_acc + Ut*tau2 + Ut*tprime - Ut*tprime*tprime/(2*tau1); } else { u_var = 0; xm = L0 - d_plate/2; } coord vc = {u_var,0., 0.}; // the velocity of the topo fraction (topo, MOUNTAIN); foreach() foreach_dimension() u.x[] = topo[]*vc.x + (1. - topo[])*u.x[]; boundary ((scalar *){u}); } event output (t = 0; t <= tend+1e-10; t += dtout) { #if _NETCDF write_nc(); #endif } event logfile (i++) fprintf (stderr, "%d %g %d %d %d %d\n", i, t, mgp.i, mgp.nrelax, mgu.i, mgu.nrelax);