sandbox/hugoj/test_windinput/linear_wave_wind_input.c

    Wave growth: from linear to breaking

    Analytical solution

    A linear surface gravity wave will decay in a viscous fluid. The rate of this decay is E(t)=E_0 e^{-4\nu k^2 t} (Lamb 1932)

    References

    Horace Lamb, Hydrodynamics (6th ed., 1932), Chapter XI, Article 348, “Effect of Viscosity on Water-Waves,” pp. 623–625

    et Article 349 pour une dérivation plus sérieuse

    #include "grid/multigrid1D.h"
    #include "layered/hydro.h"
    #include "layered/nh.h"
    #include "layered/remap.h"
    #include "layered/perfs.h"
    #include "bderembl/libs/netcdf_bas.h"
    
    double k_ = 2.*pi, h_ = 5., g_ = 9.81, ak = 0.01; 
    double RE = 400.;
    
    #define T0  (2.*pi/sqrt(g_*k_))
    double lam, p0;
    double base_gpe=0.;
    double NT0 = 100.;
    scalar ps[], Fp[]; 
    
    
    
    int main()
    {
      L0=1.;
      origin (-L0/2.);
      periodic (right);
      N = 1024;
      nl = 60; // 60
      G = g_;
      lam = 2*pi/k_*L0;
      //nu = sqrt(g_*lam*lam*lam)/RE; // sqrt(g_*lam*lam*lam)
      nu = 1./RE;
      CFL_H = 1.; 
      max_slope = 1.; // a bit less dissipative
      //theta_H = 0.5; // >0.5 or else energy increases even without forcing ? 0.51
      //CFL=0.5;
      //DT = 0.05;
      p0=1.; 
      base_gpe=0.5*g_*h_*h_;
      run();
    }
    
    
    
    event init (i = 0)
    {
      foreach() {
        zb[] = -h_; //-h_*lam;
        double H =  ak/k_*cos(k_*x) - zb[];
        double z = zb[];
        foreach_layer() {
          h[] = H/nl;
          z += h[]/2.;
          u.x[] = ak/k_*sqrt(g_*k_)*exp(k_*z)*cos(k_*x); // 
          w[] = ak/k_*sqrt(g_*k_)*exp(k_*z)*sin(k_*x);  // 
          z += h[]/2.;
        }
      }
      create_nc({zb, eta, h, u.x, w, Fp}, "out.nc");
    }
    
    
    event viscous_term (i++) {
      // vertical diffusion is done in diffusion.h (u.x) and nh.h (w)
      //implicit_horizontal_diffusion ({u.x, w}, nu, dt);
      horizontal_diffusion ({u.x, w}, nu, dt);
    }
    
    
    #if FORCING
    #warning "FORCING accel branch active"
    event acceleration(i++, last){
      foreach_face(x) {
        double detadx = 0.;
        detadx = (eta[] - eta[-1])/Delta;
        ha.x[0,0,nl-1] += hf.x[]*(p0 * detadx * sin(atan(detadx))); //   
      }
    }
    #endif
    
    event logfile (i++; t <= NT0*T0) // target: at least 300*T0
    {
      double ke = 0., gpe = 0.;
      foreach (reduction(+:ke) reduction(+:gpe)) {
        foreach_layer() {
          double norm2 = sq(w[]);
          foreach_dimension()
    	norm2 += sq(u.x[]);
          ke += norm2*h[]*dv();
        }
        gpe += sq(eta[])*dv();
      }
      printf ("%g %g %g\n", t/T0, ke/2., g_*gpe/2.);
    }
    
    
    event movie (i+=3)
    {
      static FILE * fp = popen ("gnuplot", "w");
      if (i == 0)
        fprintf (fp, "set term pngcairo font ',9' size 800,250;"
          "set size ratio -1\n");  
      fprintf (fp,
        "set output 'plot%04d.png'\n"
        "set title 't = %.2f'\n"
        "p [%g:%g][-0.1:0.15]'-' u 1:(-1):2 w filledcu lc 3 t ''",
        i/3, t/(k_/sqrt(g_*k_)), X0, X0 + L0);
      fprintf (fp, "\n");
      foreach (serial) {
        double H = 0.;
        foreach_layer()
          H += h[];
        fprintf (fp, "%g %g %g", x, zb[] + H, zb[]);
        fprintf (fp, "\n");
      }
      fprintf (fp, "e\n\n");
      fflush (fp);
      write_nc();
    }
    
    event moviemaker (t = end)
    {
      system ("rm -f movie.mp4 && "
    	  "ffmpeg -r 25 -f image2 -i plot%04d.png "
    	  "-vcodec libx264 -vf format=yuv420p -movflags +faststart "
    	  "movie.mp4 2> /dev/null && "
    	  "rm -f plot*.png");
    }
    import numpy as np
    import matplotlib.pyplot as plt
    
    g = 9.81
    L0 = 100
    ak = 0.01
    k = 2*np.pi/10
    lam = 2*np.pi/k*L0
    Re = 400
    
    nu = np.sqrt(g*lam**3)/Re
    nu = 1/Re
    T0 = (2*np.pi/np.sqrt(g*k))
    
    def E_linwave(E0,nu,ak,k,t):
      print('\nWave decay for linear wave (theory)')
      print(f'nu={nu},ak={ak},k={k/np.pi}pi\n')
      return E0*np.exp(-4*nu*k**2*t)
    
    data = np.loadtxt("out",skiprows=1)
    data_ref = np.loadtxt('../no_forcing/out',skiprows=1)
    time = data[:,0]
    ke  = data[:,1]
    gpe = data[:,2]
    E = ke + gpe
    timeref = data_ref[:,0]
    Eref = data_ref[:,1]+data_ref[:,2]
    E0 = E[0]
    Eth = E_linwave(E0,nu,ak,k,time*T0)
    #E0 = 1 
    fig, ax = plt.subplots(figsize=(5, 5))
    ax.plot(timeref,Eref/E0,c='k',ls='--',label='no forcing')
    ax.plot(time,2*ke/E0,color='b', label='2*ke')
    ax.plot(time,2*gpe/E0,color='g', label='2*gpe')
    ax.plot(time,E/E0, color='k', label='E')
    ax.plot(time, Eth/E0, color='r', label=r'$E(t)=E_0 e^{-4 \nu k^2 t}$')
    ax.set_xlabel("t/T0")
    ax.set_ylabel("E/E0")
    ax.legend(loc="lower left")
    plt.tight_layout()
    plt.savefig("energy.png", dpi=150)
    plt.show()
    Wave energy (script)