/** ## Declaration of the structures gathering all the properties linked to a droplet. * The property of the drop are indexed \alpha and just "a" in the code. */ typedef struct { /** physical properties */ double vol; // volume double S; // surface double p; // pressure double W2; // internal fluctuation coord Y; // position of the center of mass coord U; // averaged velocity coord Uc; // centered velocity coord Fh; // drag force coord D_nbr; // distance to the nearest neigboring particles coord Per; // Indicator to identify teh peeriodicity of a drop tens P; // moment of momentum tensor defined as $\int \bm{ru} dV$ tens G; // shape tensor defined as $\int \bm{rr} dV$ double Gnorm; // norm of the inertia tensor double Pnorm; // norm of the moment of momentum tensor tens WW; // tensor product of the inner fluctuation tensor around Uc /** * @brief Think about how to compute the first moments of the surface * forces body forces and hydrodynamic forces * You might add the int of the stress here * so that you can compute the sum of each moments. * What about the centered grad of velocity ? */ tens Mh; // First hydrodinamical moment. tens Sig; // Sigma stress tesnor tens Ms; // Moment of the surface tension double ed; // energy dissipation /** * bilan on NRJ * */ /** Other properties linked to the identification */ double ct; // contact time with the nearest neigbor int tagmin; // tag of the nearest droplet int tag; int tagmax; int realtag; int si; int adj[100]; // maximum index of scalar feilds } Drop; /** assign a value to detect if a drop cross a bounday*/ void isperio(scalar s, scalar tag ,int nb,int tagi, Drop n[] ){ coord per1[nb],per2[nb]; for (int i = 0; i < nb; i++) foreach_dimension() per1[i].x = 0,per2[i].x = 0; foreach(reduction(+:per1[:nb]) reduction(+:per2[:nb])) if (s[] != nodata && dv() > 0. && s[]>=EPS) { int i=tag[]-1; coord pos = POS; foreach_dimension(){ if(pos.x>(L0/2-0.2*D)) per1[i].x = 1; else if(pos.x<-(L0/2-0.2*D)) per2[i].x = 1; } } for (int i = 0; i < nb; i++) foreach_dimension() n[tagi+i].Per.x = (per1[i].x && per2[i].x); } /** compute the center of mass and average velocity of the drop */ void pos_vol_and_vel(scalar s, scalar tag ,int nb,int tagi,Drop n[]){ double volume[nb]; coord posG[nb],v[nb]; for (int i = 0; i < nb; i++){ volume[i]=0; posG[i]=v[i]=Coord_nul; } foreach(reduction(+:posG[:nb]) reduction(+:v[:nb]) reduction(+:volume[:nb])) if (s[] != nodata && dv() > 0. && s[]>=EPS){ int i=tag[]-1; volume[i] += dv()*s[]; coord pos = POS; pos = POS_perio(pos,n[tagi+i].Per); foreach_dimension(){ posG[i].x += dv()*s[]*pos.x; v[i].x += dv()*s[]*u.x[]; } } for(int i=0;i 0. && s[]>=EPS) { int i=tag[]-1; einstein_sum(i,j){ WW[i].i.j += (u.i[] - n[tagi+i].U.i)*(u.j[] - n[tagi+i].U.j)*dv()*s[]; W2[i] += (u.i[] - n[tagi+i].U.i)*(u.j[] - n[tagi+i].U.j)*dv()*s[]; } } for(int i=0;i 0. && s[]>=EPS) { int i=tag[]-1; coord Pos = POS; coord r = dist_perio_coord(Pos,n[tagi+i].Y); einstein_sum(i,j){ G[i].i.j += r.i * r.j * dv() * s[]; P[i].i.j += r.i * u.j[] * dv() * s[]; } } for(int i=0;i 0. && s[]>=EPS) { int i = tag[]-1; pressure[i] += p[]*s[]*dv(); tens gradU,S,rdivS,rdivp; coord gradp,LapU; coord Pos = POS; coord r = dist_perio_coord(Pos,n[tagi+i].Y); vec_grad(u,gradU); vec_lap(u,LapU); scalar_grad(p,gradp); // need to think about what tensor is needed einstein_sum(i,j){ S.i.j = (gradU.i.j+gradU.j.i)*mu1; rdivp.i.j = r.i * gradp.j; rdivS.i.j = r.i * LapU.j * mu1; Sig[i].i.j += S.i.j * s[] * dv(); Mh[i].i.j += (S.i.j - rdivp.i.j + rdivS.i.j)*s[]*dv(); ed[i] += S.i.j*gradU.i.j*s[]*dv(); } } for(int i=0; i 0. && s[] > EPS && s[] < 1. - EPS){ int i = tag[]-1; coord normal = mycs(point, s), p; double alpha = plane_alpha(s[], normal); double dS = pow(Delta, dimension - 1) * plane_area_center(normal, alpha, &p); S[i] += dS; } if(i < 0){ foreach_neighbor(1) i = max(i,tag[]-1); } if(i>=0){ coord Pos = POS; coord r = dist_perio_coord(Pos,n[tagi+i].Y); coord acc = {a.x[1], a.y[0,1], a.z[0,0,1]}; coord grad = {s[1] != s[-1], s[0,1] != s[0,-1], s[0,0,1] != s[0,0,-1]}; einstein_sum(i,j){ Ms[i].i.j += (grad.j && fm.j[] > 0) ? r.i * (acc.j+a.j[])/2. * (f[]*(rho1-rho2)+rho2) * dv() :0.; } } } for(int i=0; iL0/2.) n[tagi+i].Y.x -= L0; // set the pos inside the domain points_vel(s,tag,nb,tagi,n); /** second order term calculation appearing in the * moment of momentum equation */ compute_G_and_P(s,tag,nb,tagi,n); compute_WW_W2(s,tag,nb,tagi,n); compute_Mh(s,tag,nb,tagi,n); compute_S_and_Ms(s,tag,nb,tagi,n); } /** funciton that link every drops from one step to the next by the variable tag */ void assign_tags_from_last_step (Drop datat0[],Drop datat1[],int tagi){ int tags_avail[tagi]; for(int k = 0;k=tagi) datat1[k].tag=-1; } int new_tag=0; for (int k = 0; k < tagi; k++){ if(datat1[k].tag == -1 && new_tag<=ta){ if(tags_avail[new_tag] >= tagi) new_tag++; datat1[k].tag = tags_avail[new_tag]; new_tag++; } } } /** print the distance between each droplets and store the tag of the closest * dorplet of a given droplet. besides it store the contact time */ void print_pair_dist(Drop data0[],Drop data[],int tagi,int step, float t){ Drop data_orderred[tagi]; for (int j = 0; j < tagi; j++) { data[j].ct = 0; foreach_dimension() data[j].D_nbr.x = Ls*100; data_orderred[data[j].tag]=data[j]; } foreach_dimension(){ Dist_x = fopen(name_x,"a"); fprintf(Dist_x,"%d,%g",step,t); } for (int k = 0; k < tagi; k++) { coord npi = data_orderred[k].Y; for (int j = k+1; j= data0[0].tagmax) data[k].ct = dtprint; if(tag < data0[0].tagmax) data[k].ct = data_orderred0[tag].ct + dtprint; } } #endif } /** Function that print the property of the droplets in fDrop.csv and * print the pair dist in Dist_x.csv */ void print_Drop(Drop data0[],Drop data1[],int tagi,int step,double time){ fDrop = fopen("fDrop.csv","a"); for(int j=0;j 0. && s[]>=EPS) { int i=tag[]-1; taggg[i] = tag[]; foreach_neighbor() for(scalar c in interfaces) if(c.i != s.i && c[] > EPS) adj[i*c.i + c.i] = true; } for (int i = 0; i < nb; i++){ n[tagi+i].realtag = taggg[i]; for(scalar c in interfaces){ n[tagi+i].adj[c.i] = adj[i*c.i + c.i]; } } } /** coalescence function. * It is activated only if COAL = 1 */ void coalescence(Drop data[],int tagi){ Drop DAT[tagi]; for (int j = 0; j < tagi; j++) DAT[data[j].tag]=data[j]; scalar b[]; for(scalar c in interfaces){ foreach(){ b[] = c[]>EPS;} tag (b); int si[tagi],realtag[tagi]; for (int i = 0; i < tagi; i++) si[i]=realtag[i]=-1; for(int j = 0 ;j < tagi ; j++){ if(DAT[j].ct != 0.){ fprintf(stdout,"time %g the tag %d %d ct %g\n",t,j,DAT[j].tag,DAT[j].ct); Drop b1 = DAT[j]; Drop b2 = DAT[DAT[j].tagmin]; double d_eq = 2*sqrt(b2.vol/M_PI)*sqrt(b1.vol/M_PI) / (sqrt(b2.vol/M_PI) + sqrt(b1.vol/M_PI)); double V_0 = normL2_coord(diff_coord(b1.U,b2.U)); double td = rho_f*sq(d_eq)*V_0/(8*sig); double We = rho_f*d_eq*sq(V_0)/(2*sig); fprintf(stdout,"coalescence time td = %g We = %g deq %g vel %g\n",td,We,d_eq,V_0); if (DAT[j].ct > td && DAT[j].si != DAT[DAT[j].tagmin].si && c.i == DAT[j].si) { // for(int l = 0 ;l < tagi ; l++){ // int tm = DAT[j].tag; // if(DAT[l].tag != DAT[j].tag && DAT[l].tag != DAT[tm].tag){ // if(DAT[l].adj[DAT[j].si] == 1 && DAT[l].si == DAT[tm].si) // if(DAT[l].tagmin == DAT[j].tag){ // fprintf(stdout,"l too close too ["); // for(scalar s in interfaces) fprintf(stdout,"(%d,%d),",DAT[l].adj[s.i],s.i); // fprintf(stdout,"]\n"); // } // }else{ realtag[j] = DAT[j].realtag; si[j] = DAT[DAT[j].tagmin].si; DAT[j].si = DAT[DAT[j].tagmin].si; fprintf(stdout,"add to caaol realt %d si objc %d\n",si[j],realtag[j]); // } // } } } } #if _MPI MPI_Bcast(si,tagi,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(realtag,tagi,MPI_INT,0,MPI_COMM_WORLD); #endif for (int i = 0; i < tagi; i++) if(si[i] != -1) foreach() if(b[] == realtag[i]){ scalar t = {si[i]}; t[] = c[]; c[] = 0.; } scalar * list = list_copy ({c}); for (int i = 0; i < tagi; i++) if(si[i] != -1) list = list_add(list,(scalar){si[i]}); boundary (list); free (list); } } #endif