/** # écoulement de lave visqueuse le long d'un volcan On suppose de manière simplifiée et abusive que la lave est un fluide visqueux, on va donc mettre un frottement de type Poiseuille en terme de frottement, en effet */ #include "saint-venant.h" /** résout la partie non visqueuse. Auparavant quelques déclarations */ double tmax,Cf; #define MAXLEVEL 8 #define MINLEVEL 6 #define LEVEL 6 /** Conditions aux limites Neumann */ u.n[left] = neumann(0); u.n[right] = neumann(0); u.t[left] = neumann(0); u.t[right] = neumann(0); h[left] = neumann(0); u.n[top] = neumann(0); u.t[top] = neumann(0); h[top] = neumann(0); h[right] = neumann(0); /** Initialement un cône pour la topo zb et une hauteur de lave nulle */ event init (i = 0) { foreach(){ zb[] = fmax((1.-sqrt(x*x+y*y))+0*(x-2)/10,0); h[]= 0; } boundary (all); } /** à chaque pas de temps, on fait sortir de la lave */ event source (i++) { // source near the summit // source pendant un temps fini foreach(){ h[]= ((x-.3)*(x-.3)+y*y < (0.15)*(0.15) ? h[]+0.3*dt*(t<5): h[]);} } /** à chaque pas de temps, on met le frottement de Poiseuille $$ \frac{\partial u}{\partial t} = - 3 \nu \frac{u}{h^2} $$ */ event friction (i++) { // Poiseuille friction (implicit scheme) foreach() {double ff = h[] < dry ? HUGE : (1. + Cf*dt/h[]/h[]); foreach_dimension() u.x[] /= ff; } } /** à chaque pas de temps, on adapte le maillage */ event adapt (i++) { astats s = adapt_wavelet ({h}, (double[]){1e-3}, MAXLEVEL, MINLEVEL); fprintf (stderr, "# refined %d cells, coarsened %d cells\n", s.nf, s.nc); } /** Film */ event movies (t <= tmax;t+=.01) { static FILE * fp = popen ("ppm2mpeg > eta.mpg", "w"); scalar m[], etam[]; foreach() { etam[] = eta[]*(h[] > dry); m[] = etam[] - zb[]; } boundary ({m, etam}); output_ppm (etam, fp, mask = m, min = 0, max = 1.005, n = 512, linear = true);} /** et sortie directe gnuplot */ event splot(t <= tmax;t+=.125) { double dx=L0/pow(2.,LEVEL),dy=dx; fprintf (stderr,"--- %lf \n",t); printf("set hidden3d; unset border ; unset ytics ;unset xtics ; unset ztics;\n"); printf("set view 60,%lf \n",t/tmax*360); printf("sp[:][:][0:2] '-' u 1:2:($3+$4-.01) not w l linec 1,''u 1:2:4 not w l linec 2\n"); for(double x=X0; x v.out echo "set term gif animate; set output 'v.gif'" > dmp cat v.out >> dmp mv dmp v.out cat v.out | gnuplot gifsicle --colors 256 --optimize --delay 1 --loopcount=0 v.gif > volcan.gif rm v.out v.gif ~~~ ce qui produit: ![lave visqueuse sur un cône](/sandbox/M1EMN/Exemples/Img/volcan.gif) OK v2 */