#include "grid/octree.h" #include "navier-stokes/centered.h" #include "two-phase.h" #include "navier-stokes/conserving.h" #include "tension.h" #include "tag.h" #include "view.h" /** Include profiling information. */ #include "navier-stokes/perfs.h" #include "profiling.h" #include #include #include #include #include #include #define LEVEL 11 #define MINLEVEL 7 #define MAXTIME 0.03 //#define R0 0.05 // Initial bubble radius #define R0 0.05 #define WE 280. //Weber number //#define OH 0.14 //Ohnesorge number #define OH 0.01 // Try this #define OFFSET 0.95 #define ETA 0.06 #define RATIO 1./833. //#define MURATIO 17.4e-6/8.9e-4 //dynamic viscosity ratio, water to air #define MURATIO 1./55. //viscosity ratio water to air, not chosen according to Pierson but to previous bubble-in-turbulence studies; expect it will not have much effect, especially for values below 0.1 #define ADDNOISE 1 //boolean noise #define CONSTANT 0.01 // noise scaling double raw_series_l[4096]; double raw_series_r[4096]; double raw_series_l_old[4096]; double raw_series_r_old[4096]; int series_len; u.n[top] = neumann(0.); u.t[top] = neumann(0.); u.r[top] = neumann(0.); FILE * fk = NULL; FILE * fe = NULL; //----------------------MAIN-----------------------// //Begin main function int main() { L0 = 2.; periodic(front); origin (-L0/2., 0., 0.); rho1 = 1.0; rho2 = RATIO; /** For calculating viscosities, interpret Reynolds number as defined at depth of unity. */ f.sigma = 1.; //0.01 is very stable mu1 = OH*sqrt(rho1*f.sigma*2*R0); //double check this definition mu2 = mu1*MURATIO; /** Use depth length scale for Bond number as well. */ //TOLERANCE = HUGE; //NITERMIN = 20; mkdir("./interface", 0777); mkdir("./frag_stats", 0777); char name[80]; sprintf (name, "3Denergy-%d.dat", LEVEL); fe = fopen (name, "w"); sprintf (name, "3Dkinetics-%d.dat", LEVEL); fk = fopen (name, "w"); series_len = (1 << LEVEL); init_grid(1 << (MINLEVEL+1)); run(); fclose (fe); fclose (fk); } //---------------------INITIALIZATION------------------------// void set_noise_signal() { gsl_fft_real_wavetable * real; gsl_fft_halfcomplex_wavetable * hc; gsl_fft_real_workspace * work; if (pid() == 0) { srand(time(NULL)); for (int i=0; i series_len) index = series_len; if (x < 0.) return -sq(x + R0*OFFSET) - sq(y) + sq(R0 + amp*R0*raw_series_l[index]); else return -sq(x - R0*OFFSET) - sq(y) + sq(R0 + amp*R0*raw_series_r[index]); } // /*Write initialization event*/ event init (i = 0) { if (!restore("restart")){ set_noise_signal(); // int jdx = 0; double dropvel = sqrt(WE*f.sigma/(2.*R0)/rho1)/2.; // double femax = 2e-4; // double uemax = 2e-2; // do { // jdx += 1; // fprintf(ferr, "Initializing, %d\n", jdx ); //fraction (f, -sq(x - R0*OFFSET) - sq(y) + sq(R0)); refine (fabs(x) < 2.2*R0 && fabs(y) < 1.1*R0 && level < (LEVEL-1)); fraction (f, dropletValue(x, y, z, ETA)); boundary ((scalar *){f,u}); foreach() u.x[] = -f[]*dropvel*sign(x); // } // while (adapt_wavelet ({f,u}, (double[]){femax,uemax, uemax, uemax}, LEVEL, MINLEVEL).nf); } } //-------------------ADAPTIVITY---------------------// /*Adapt once on error in volume fraction, velocity field, and beach fraction*/ event adapt(i++) { double femax = 1e-2; double uemax = 5e-2; adapt_wavelet ({f,u.x,u.y,u.z}, (double[]){femax,uemax,uemax,uemax}, LEVEL, 5); } //------------------------IMAGING-------------------------- /* event intoutput(t += 0.0001) { char resultname[100]; char tmpname[100]; sprintf( tmpname, "interface/_res-%d.dat", pid() ); if (pid() == 0) sprintf (resultname, "interface/results%4.4f.dat", t ); FILE * fp = fopen(tmpname, "w"); scalar xpos[]; scalar ypos[]; scalar zpos[]; position (f, xpos, {1, 0, 0}); position (f, ypos, {0, 1, 0}); position (f, zpos, {0, 0, 1}); foreach() if (xpos[] != nodata) fprintf (fp, "%g %g %g\n", xpos[], ypos[], zpos[]); fclose (fp); char copycat[200]; if (pid() == 0){ sprintf (copycat, "cat interface/_res-*.dat > %s", resultname); system (copycat); system ("rm interface/_res-*.dat"); } } */ int dissipation_rate (vector u, double* rates) { double rateWater = 0.0; double rateAir = 0.0; foreach (reduction (+:rateWater) reduction (+:rateAir)) { double dudx = (u.x[1] - u.x[-1])/(2.0*Delta); double dudy = (u.x[0,1] - u.x[0,-1])/(2.*Delta); double dudz = (u.x[0,0,1] - u.x[0,0,-1])/(2.*Delta); double dvdx = (u.y[1] - u.y[-1] )/(2.*Delta); double dvdy = (u.y[0,1] - u.y[0,-1])/(2.0*Delta); double dvdz = (u.y[0,0,1] - u.y[0,0,-1])/(2.*Delta); double dwdx = (u.z[1] - u.z[-1] )/(2.*Delta); double dwdy = (u.z[0,1] - u.z[0,-1] )/(2.*Delta); double dwdz = (u.z[0,0,1] - u.z[0,0,-1])/(2.0*Delta); double SDeformxx = dudx; double SDeformxy = 0.5*(dudy + dvdx); double SDeformxz = 0.5*(dudz + dwdx); double SDeformyx = SDeformxy; double SDeformyy = dvdy; double SDeformyz = 0.5*(dvdz + dwdy); double SDeformzx = SDeformxz; double SDeformzy = SDeformyz; double SDeformzz = dwdz; double sqterm = 2.0*dv()*(sq(SDeformxx) + sq(SDeformxy) + sq(SDeformxz) + sq(SDeformyx) + sq(SDeformyy) + sq(SDeformyz) + sq(SDeformzx) + sq(SDeformzy) + sq(SDeformzz)); rateWater += mu1*f[]*sqterm; //water rateAir += mu2*(1. - f[])*sqterm; //air } rates[0] = rateWater; rates[1] = rateAir; return 0; } event logfile (t = 1e-6; t <= MAXTIME; t += 2e-5) { double ke_d = 0., ke_a = 0., area = 0.; foreach(reduction(+:ke_d) reduction(+:ke_a)) { // Kinetic energy of the droplet and ambient airflow ke_d += 0.5*dv()*(sq(u.x[]) + sq(u.y[]) + sq(u.z[])) * rho1*f[]; ke_a += 0.5*dv()*(sq(u.x[]) + sq(u.y[]) + sq(u.z[])) * rho2*(1-f[]); } // Droplet surface area area = interface_area(f); // Viscous dissipation rate double rates[2]; dissipation_rate(u, rates); double diss_w = rates[0], diss_a = rates[1]; double delta = L0 / (double)(1 << LEVEL); double h_contact_ave = 0.0; int n_contact = 0; double h_contact_max = 0.0; foreach(reduction(+:h_contact_ave) reduction(+:n_contact) reduction(max:h_contact_max)) if (f[] > 1e-6 && f[] < 1.-1e-6 && -0.5*delta <= x && x <= 0.5*delta) { h_contact_ave += y; h_contact_max = fmax(h_contact_max, y); n_contact++; } h_contact_ave /= n_contact; fprintf (fk, "%.8f %.8f %.8f %.8f\n", t, h_contact_ave, h_contact_max, area); fflush (fk); fprintf (fe, "%.8f %.8f %.8f %.8f %.8f\n", t, ke_d, ke_a, diss_w, diss_a); fflush (fe); } event count_droplets (t = 0; t <= MAXTIME; t += 2e-5) { scalar m_cd[]; foreach() m_cd[] = f[] > 0.5; int n = tag (m_cd); double v[n], ux_drop[n], uy_drop[n], uz_drop[n], area[n], ke[n]; coord b[n]; for (int j = 0; j < n; j++) v[j] = b[j].x = b[j].y = b[j].z = ux_drop[j] = uy_drop[j] = uz_drop[j] = area[j] = ke[j] = 0.; foreach_leaf() if (m_cd[] > 0) { int j = m_cd[] - 1; v[j] += dv()*f[]; coord p = {x,y,z}; foreach_dimension() b[j].x += dv()*f[]*p.x; ux_drop[j] += dv()*f[]*u.x[]; uy_drop[j] += dv()*f[]*u.y[]; uz_drop[j] += dv()*f[]*u.z[]; ke[j] += 0.5 * rho1*dv()*f[] * (sq(u.x[]) + sq(u.y[]) + sq(u.z[])); // interfacial area if (f[] > 1e-4 && f[] < 1. - 1e-4) { coord m = mycs (point, f); double alpha = plane_alpha (f[], m); coord p; area[j] += sq(Delta) * plane_area_center(m, alpha, &p); } } #if _MPI MPI_Allreduce (MPI_IN_PLACE, v, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce (MPI_IN_PLACE, area, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce (MPI_IN_PLACE, ke, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce (MPI_IN_PLACE, b, 3*n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce (MPI_IN_PLACE, ux_drop, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce (MPI_IN_PLACE, uy_drop, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce (MPI_IN_PLACE, uz_drop, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #endif if (n > 1 && pid() == 0) { char resultname[100]; sprintf(resultname, "./frag_stats/frag_stat_%4.4f.dat", t); FILE * fdrop = fopen(resultname, "w"); for (int j=0; j