sandbox/piersonj/taylor_culick.c
Taylor-Culick retraction of a liquid drop
This file is largely inspired by the work of Alexis Berny. Thanks to him !
#include "axi.h"
#include "navier-stokes/centered.h"
#include "two-phase.h"
#include "tension.h"
#define LEVEL 9
#define INLEVEL 5
#define MINLEVEL 5
We are simulating only one half of the liquid drop
#define L0 5.
#define L 2.
Parameters
#define R 0.5
//Ohnesorge number
#define Oh 1.
#define muRatio 1000.
#define rhoRatio 100.
double tC = R*R*Oh;
double tEnd = 30*R*R*Oh;
//Taylor-Culick velocity (viscosity / density inside the drop = 1)
double utc = 1./(1.*R*Oh);
The boundary conditions are slip walls
int main() {
The domain
size (L0);
init_grid (1 << INLEVEL);
//mass conservation tolerance
TOLERANCE = 1e-5;
NITERMAX = 200;
We define the parameters of the fluids. The internal fluid (the liquid) is the fluid 1. The external fluid is the fluid 2.
double rhoInt = 1;
double muInt = 1.;
rho1 = rhoInt, mu1 = muInt;
rho2 = rhoInt/rhoRatio, mu2 = muInt/muRatio;
f.sigma = (mu1 /Oh)*(mu1 /Oh)*1./rho1/R;
run();
}
We define the geometry with boolean operations. We define a rectangular area (the intersection of Line and Line_vert). We also define a half circle. Then, our geometry will be the union of the rectangle with the half circle.
double geometry (double x, double y) {
double Line = y-R;
double Line_vert = x-L;
double Circle = sq(x-L)+sq(y)-sq(R);
double right_part = max(-Circle,-Line_vert);
return min(-Line, right_part);
}
We do not use AMR, because previous tests have shown that it can generate spurious oscillations of the tip velocity.
We initialise the geometry of the interface.
fraction(f, geometry(x,y));
//Width of the region with maximal refinement
double Wm=3*R;
//Width between two adjacent layers
double Wa=0.5*R;
//Main region
refine (x < (L + Wm - R ) && y < (Wm) && level < LEVEL);
for(int k=0; k < (LEVEL-MINLEVEL); k +=1){
//East region
refine (x > (L + Wm - R + k*Wa) && x < (L + Wm - R + (k+1)*Wa) && y > 0. && y < (Wm) && level < LEVEL-k-1);
//Top region
refine (x < (L + Wm - R + (k+1)*Wa) && y > (Wm) && y < (Wm+(k+1)*Wa) && level < LEVEL-k-1);
}
}
scalar le[];
foreach(){
le[] = level;
}
char name_grid[100];
sprintf (name_grid, "grid.png");
FILE* fgrid = fopen (name_grid, "w");
output_ppm (le, file = name_grid,min=MINLEVEL,max=LEVEL,n = 1000,box = {{0.,0.},{L0,L0}});
fclose (fgrid);
}
We output : the interface position and scalar / vector fields .
We only output the interface in this function.
char name[80];
sprintf (name, "interface-%f.txt", t);
FILE* fp = fopen (name, "w");
output_facets (f, fp);
fclose (fp);
scalar vort[];
vorticity (u, vort);
char namev[80];
sprintf (namev, "vort-%f.txt", t);
FILE * fpv = fopen (namev, "w");
Txt format.
output_field ({vort}, fpv, n=1000);
fclose (fpv);
char named[80];
sprintf (named, "dump-%d", i);
dump (file = named);
}
We output the maximum x position of the liquid finger. Indeed this position should linearly evolve in time, with a few variations coming from the capillary wave.
double xPrev = -1, tPrev = -1;
event extractPosition (i ++) {
We define a new vector field, h.
vector h[];
We reconstruct the height function field and take the corresponding maximum along the x axis.
heights (f, h);
double xMax = -HUGE;;
foreach()
if (h.x[] != nodata) {
double xi = x + height(h.x[])*Delta;
if (xi > xMax)
xMax = xi;
}
We also output the velocity of the end of the bulge.
double veloTip = tPrev >= 0 ? (xMax - xPrev)/(t - tPrev) : 0.;
char name[80];
sprintf (name, "velocity_pos.dat");
static FILE * fp = fopen (name, "w");
fprintf (fp," %g %g %g\n", t, xMax, veloTip);
fflush (fp);
tPrev = t, xPrev = xMax;
}
We output, in the standard output file, the step with the corresponding time.
event logfile(i++) {
printf ("i = %d t = %g\n", i,t);
fflush(stdout);
}
/* Images for post processing */
event movies (t += tC*1e-1; t <= tEnd){
scalar vort[];
vorticity (u, vort);
scalar m[];
foreach() {
if (f[]<0.95 && f[] >0.05)
m[] = -10;
else
m[] = 0.;
}
//we output both the interface and the normalized vorticity.
char name_vort[100];
sprintf (name_vort, "vort-%g.png", t);
FILE* fvort = fopen (name_vort, "w");
double om = (mu1 /Oh)*1./rho1/R/R;
output_ppm (vort, fvort, mask =m,min=-om,max=om, map=cool_warm, n = 1000,box = {{0.,0.},{L0,3*R}});
fclose (fvort);
}
event end (t = tEnd) {}
![Tip velocity as function of time](data/velocity_oh1.png)