sandbox/ghigo/artery1D/steady-state.c

    Inviscid steady state

    We solve the inviscid steady state of the 1D blood flow equations in an artery with variable properties. A steady state verifies the following system of equations:

    \displaystyle \left\{ \begin{aligned} & Q = cst \\ & \frac{1}{2}\rho U^2 + p = cst\\ \end{aligned} \right.

    From a numerical standpoint, these steady states are not easily obtained in an artery with variable properties. Indeed, a numerical error between the treatment of the flux and the topography source term can lead to the apparition of spurious velocities. This test case is therefore designed to test the ability of different well-balanced schemes to capture inviscid steady states.

    Code

    #include "grid/cartesian1D.h"
    #include "bloodflow.h"
    
    double R0 = 1.;
    double K0 = 1.e4;
    double L = 10.;
    
    double DR = -1.e-1;
    double XS = 3./10.*10.;
    double XE = 7./10.*10.;
    
    double DK = 1.e-1;
    double XSS = 3./10.*10.;
    double XEE = 7./10.*10.;
    
    double SH = 1.e-1;
    double AIN = 0., QIN = 0.;
    
    scalar eq[];
    double eq1, eq2, eqmax;
    
    scalar am1[], qm1[];
    scalar ecva[], ecvq[];
    
    int ihr = 0;
    
    double celerity (double a, double k) {
    
      return sqrt(0.5*k*sqrt(a));
    }
    
    int main() {
    
      origin (0., 0.);
      L0 = L;
    
      AIN = pi*pow(R0*(1 + SH), 2.);
      QIN = SH*AIN*celerity(AIN, K0);
    
      ihr = 0;
      for (ihr = 0; ihr <= 2; ihr ++) {
        for (N = 32; N <= 256; N *= 2) {
    
          eq1 = eq2 = eqmax = 0.;
        
          run();
    
          printf ("eq%d, %d, %g, %g, %g\n", ihr, N, eq1/QIN,
    	      sqrt(eq2)/QIN, eqmax/QIN);
        }
      }
      
      return 0; 
    }
    
    q[left] = dirichlet(QIN);
    
    event defaults (i=0) {
    
      gradient = order1;
      if (ihr == 0) riemann = hll_hr;
      else if (ihr == 1) riemann = hll_hrls;
      else if (ihr == 2) riemann = hll_glu;
    }
    
    event init (i=0) {
      
      foreach() {
        k[] = K0*(XSS <= x && x<=XEE ?
    	      1. + DK/2.*(1 + cos(pi + 2.*pi*
    				  (x - XSS)/(XEE - XSS))) :
    	      1.);
        a0[] = pi*pow(R0, 2.)*pow(XS <= x && x <= XE ?
    			      1. + DR/2.*(1 + cos(pi + 2.*pi*
    						  (x - XS)/(XE - XS))) :
    			      1., 2.);
        a[] = a0[];
        q[] = QIN;
    
        am1[] = a[];
        qm1[] = q[];
      }
    }
    
    event convergence (i++) {
    
      if (N == 128) {
        foreach() {
          ecva[] = (a[] - am1[])/a[];
          ecvq[] = (q[] - qm1[])/q[];
        }
      
        norm ncva = normf (ecva);
        norm ncvq = normf (ecvq);
        fprintf (stderr, "cv%d, %g, %.14f, %.14f\n", ihr, t, ncva.rms, ncvq.rms);
    
        foreach() { 
          am1[] = a[];
          qm1[] = q[];
        } 
      }
    }
      
    event field (t = end) {
    
      if (N == 128) {
        foreach() {
          fprintf (stderr, "%d, %g, %.6f, %.6f, %.6f, %.6f\n", ihr, x,
    	       a0[]/(pi*R0*R0), k[]/K0, a[] - a0[], q[]) ;
        }
        fprintf (stderr, "\n\n") ;
      }
    }
    
    event error (t = end) {
    
      foreach() {
        eq[] = q[] - QIN;
      }
        
      norm nq = normf (eq);
      eq1 += nq.avg;
      eq2 += nq.rms*nq.rms;
      if (nq.max > eqmax)
        eqmax = nq.max;
    }
    
    event end (t = 1.5) {
      printf ("#Steady state test case completed\n") ;
    }

    Plots

    
    reset
    
    mycolors = "dark-blue red sea-green dark-violet orange brown4"
    mypoints = '1 2 3 4 6 5'
    
    set datafile separator ','
    set style line 1 lt -1 lw 2 lc 'black'
    
    set output 'A0K.png'
    set xlabel 'x [cm]'
    set ylabel 'Dimensionless arterial properties'
    set key top right
    
    plot '< grep ^0 log' u 2:3 w l ls 1 lc rgb word(mycolors, 1) t 'A_0/A_0(0)', \
         '< grep ^0 log' u 2:4 w l ls 1 lc rgb word(mycolors, 2) t 'K/K(0)'
    Spatial evolution of the cross-sectional area at rest A_0 and arterial wall rigidity K (script)

    Spatial evolution of the cross-sectional area at rest A_0 and arterial wall rigidity K (script)

    
    set output 'AmA0.png'
    set xlabel 'x [cm]'
    set ylabel 'A-A_0 [cm^2]'
    set key center right
    
    plot '< grep ^0 log' u 2:5 every 2 w p lt word(mypoints, 1) lc rgb word(mycolors, 1) ps 2 lw 1 t 'HR', \
         '< grep ^1 log' u 2:5 every 2 w p lt word(mypoints, 4) lc rgb word(mycolors, 2) ps 2 lw 1 t 'HR LS', \
         '< grep ^2 log' u 2:5 every 2 w p lt word(mypoints, 2) lc rgb word(mycolors, 3) ps 2 lw 1 t 'GLU'
    Spatial evolution of the cross-sectional area A-A_0 computed using the HR, HL-LS and GLU well-balanced schemes for N=128 (script)

    Spatial evolution of the cross-sectional area A-A_0 computed using the HR, HL-LS and GLU well-balanced schemes for N=128 (script)

    
    a0 = pi
    k0 = 1.e4
    sh = 1.e-1
    ain = a0*(1 + sh)**2.
    qin = sh*ain*sqrt(0.5*k0*sqrt(ain))
    
    set output 'Q.png'
    set xlabel 'x [cm]'
    set ylabel 'Q [cm^3/s]'
    set key top right
    
    plot qin w l ls 1 t 'Analytic', \
         '< grep ^0 log' u 2:6 every 2 w p lt word(mypoints, 1) lc rgb word(mycolors, 1) ps 2 lw 1 t 'HR', \
         '< grep ^1 log' u 2:6 every 2 w p lt word(mypoints, 4) lc rgb word(mycolors, 2) ps 2 lw 1 t 'HR LS', \
         '< grep ^2 log' u 2:6 every 2 w p lt word(mypoints, 2) lc rgb word(mycolors, 3) ps 2 lw 1 t 'GLU'
    Spatial evolution of the flow rate Q computed using the HR, HL-LS and GLU well-balanced schemes for N=128 (script)

    Spatial evolution of the flow rate Q computed using the HR, HL-LS and GLU well-balanced schemes for N=128 (script)

     
    set output 'errCV.png'
    set xlabel 't [s]'
    set ylabel 'L_2 relative error norm'
    set key top right
    set logscale y
    
    plot '< grep ^cv0 log' u 2:3 every ::1 w l ls 1 lc rgb word(mycolors, 1) t 'A', \
         '< grep ^cv0 log' u 2:4 every ::1 w l ls 1 lc rgb word(mycolors, 2) t 'Q'   
    Time evolution of the relative L_2 error between two consecutive time steps for the cross-sectional area A and the flow rate Q computed using the HR well-balanced scheme (script)

    Time evolution of the relative L_2 error between two consecutive time steps for the cross-sectional area A and the flow rate Q computed using the HR well-balanced scheme (script)

    
    set xtics 32,2,256
    set logscale
    
    ftitle(a,b) = sprintf('Order %4.2f', -b)
    f1(x) = a1 + b1*x
    f2(x) = a2 + b2*x
    f3(x) = a3 + b3*x
    
    fit f1(x) '< grep ^eq0 out' u (log($2)):(log($4)) via a1, b1
    fit f2(x) '< grep ^eq1 out' u (log($2)):(log($4)) via a2, b2
    fit f3(x) '< grep ^eq2 out' u (log($2)):(log($4)) via a3, b3
    
    set output 'errQL2.png'
    set xlabel 'N'
    set ylabel '|Q|_2'
    set key center right
    
    set cbrange[1e-10:1e10]
    
    plot '< grep ^eq0 out' u 2:4 w p lt word(mypoints, 1) lc rgb word(mycolors, 1) ps 3 lw 2 t 'HR, '.ftitle(a1, b1), \
         exp (f1(log(x))) ls 1 notitle, \
         '< grep ^eq1 out' u 2:4 w p lt word(mypoints, 2) lc rgb word(mycolors, 2) ps 3 lw 2 t 'HR LS, '.ftitle(a2, b2), \
         exp (f2(log(x))) ls 1 notitle, \
         '< grep ^eq2 out' u 2:4 w p lt word(mypoints, 3) lc rgb word(mycolors, 3) ps 3 lw 2 t 'GLU, '.ftitle(a3, b3), \
         exp (f3(log(x))) ls 1 notitle
    Comparison of the evolution of the L_2 relative error for the flow rate |Q|_2 with the number of cells N computed using the HR, HR-LS and GLU well-balanced schemes. (script)

    Comparison of the evolution of the L_2 relative error for the flow rate |Q|_2 with the number of cells N computed using the HR, HR-LS and GLU well-balanced schemes. (script)

    
    fit f1(x) '< grep ^eq0 out' u (log($2)):(log($3)) via a1, b1
    fit f2(x) '< grep ^eq0 out' u (log($2)):(log($4)) via a2, b2
    fit f3(x) '< grep ^eq0 out' u (log($2)):(log($5)) via a3, b3
    
    set output 'errQHR.png'
    set xlabel 'N'
    set ylabel 'Relative error norms'
    set key top right
    
    plot '< grep ^eq0 out' u 2:3 w p lt word(mypoints, 1) lc rgb word(mycolors, 1) ps 3 lw 2 t '|Q|_1, '.ftitle(a1, b1), \
         exp (f1(log(x))) ls 1 notitle, \
         '< grep ^eq0 out' u 2:4 w p lt word(mypoints, 2) lc rgb word(mycolors, 2) ps 3 lw 2 t '|Q|_2, '.ftitle(a2, b2), \
         exp (f2(log(x))) ls 1 notitle, \
         '< grep ^eq0 out' u 2:5 w p lt word(mypoints, 3) lc rgb word(mycolors, 3) ps 3 lw 2 t '|Q|_{max}, '.ftitle(a3, b3), \
         exp (f3(log(x))) ls 1 notitle
    Evolution of the relative error norms for the flow rate with the number of cells N computed using the HR well-balanced scheme (script)

    Evolution of the relative error norms for the flow rate with the number of cells N computed using the HR well-balanced scheme (script)