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
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