sandbox/YiDai/BASI/invis_burgers_fv.c

    solving inviscid burgers equation using finite volume

    The equation \displaystyle \partial_t U + U \partial_x U = 0

    can be written in conservative form \displaystyle \partial_t U + \partial_x (\frac{1}{2}U^{2}) = 0

    Finite volume method describes the variable in integral form and approximates the first term using slab average and second term interface flux F(U) = \frac{1}{2}U^{2}. The approximation of the flux depends on moving direction of the shock wave if there is one in the case of burgers equation.

    \displaystyle \frac{d}{d t} \int_{x_{i-\frac{1}{2}}}^{x_{i+\frac{1}{2}}} U d x+\left.F(U)\right|_{x_{i+\frac{1}{2}}}-\left.F(U)\right|_{x_{i-\frac{1}{2}}}=0

    In the presence of shock wave, the flux is always taken as the upwind scheme.

    #include "grid/cartesian1D.h"
    #include "run.h"
    
    scalar u[], du[], flux[];
    double dt;
    double BT = 0.3;
    
    int main(){
        L0 = 1;
        X0 = 0.;
        N = 1 << 8;
        DT = L0/N;            // smaller than von neumann stability
        run();
    }
    
    u[left] = dirichlet(0.);
    u[right] = dirichlet(0.);
    
    event init(t = 0){
        foreach(){
            // u[] = cos(2 * pi * x);
            u[] = sin(2 * pi * x);
        }
        boundary ({u});
    }
    
    // do note that the printed data are vary with different DT in this case
    
    // event printdata (t = 0; t <= 1000 * DT; t += 100 * DT) {
    event printdata (t = 0) {
      static FILE * fp = fopen ("case1_FV_T0","w");
      foreach()
        fprintf (fp, "%g %g %g\n", x, u[], t);
      fprintf (fp, "\n\n");
      fflush (fp);
    }
    
    event printdata2 (t = BT) {
      static FILE * fp1 = fopen ("case1_FV_T1","w");
      foreach()
        fprintf (fp1, "%g %g %g\n", x, u[], t);
      fprintf (fp1, "\n\n");
      fflush (fp1);
    }
    
    event printdata3 (t = 0; t <= BT; t += 0.01) {
      static FILE * fp3 = fopen ("case1_FV_TS","w");
      foreach()
        fprintf (fp3, "%g %g %g\n", x, u[], t);
      fprintf (fp3, "\n\n");
      fflush (fp3);
    }
    
    event integration (i++) {
      // DT = sq(L0/(1 << grid->maxdepth))/3.;    // smaller time step when the tree grid is refined
      double dt = DT;
      dt = dtnext (dt);
      // #if upwind nonconservative
      foreach()
        flux[] = u[]<0? 0.5 * sq(u[1]): 0.5 * sq(u[]);
      boundary ({flux});
      foreach()
        du[] = (-flux[] + flux[-1])/Delta;
      foreach()
        u[] += dt*du[];
      boundary ({u});
    }
    data1 = "case_FV_T0"
    data2 = "case_FV_T1"
    set xlabel "x"
    set ylabel "u"
    p[][-1.1:1.1] data1 u ($1):($2) t "T0" w l,\
     data2 u ($1):($2) t "T1" w l
    (script)

    (script)

    with different initial condition
    data1 = "case1_FV_T0"
    data2 = "case1_FV_T1"
    set xlabel "x"
    set ylabel "u"
    p[][-1.1:1.1] data1 u ($1):($2) t "T0" w l,\
     data2 u ($1):($2) t "T1" w l
    (script)

    (script)