void compute_volume_fractions(const Array3f& levelset, const Vec3f& ls_origin, float ls_dx, Array3f& volumes, const Vec3f& v_origin, float v_dx, int subdivisions) { float sub_dx = v_dx / (float)(subdivisions+1); for(int k = 0; k < volumes.nk; ++k) for(int j = 0; j < volumes.nj; ++j) for(int i = 0; i < volumes.ni; ++i) { //centre of the volume cells Vec3f bottom_left = v_origin + Vec3f((i-0.5f)*v_dx, (j-0.5f)*v_dx, (k-0.5f)*v_dx); int inside_samples = 0; //Speedup! Test the centre point, and if it's more than a grid cell away from the interface, we can assume //the cell is either totally full or totally empty float estimate = interpolate_phi(bottom_left + 0.5f*v_dx*Vec3f(1,1,1), levelset, ls_origin, ls_dx); if(estimate > v_dx) { volumes(i,j,k) = 0; continue; } else if(estimate < -v_dx) { volumes(i,j,k) = 1; continue; } for(int subk = 0; subk < subdivisions+1; ++subk) for(int subj = 0; subj < subdivisions+1; ++subj) for(int subi = 0; subi < subdivisions+1; ++subi) { Vec3f point = bottom_left + Vec3f( (subi+0.5f)*sub_dx, (subj+0.5f)*sub_dx, (subk+0.5f)*sub_dx); float data = interpolate_phi(point, levelset, ls_origin, ls_dx); inside_samples += (data < 0)?1:0; } volumes(i,j,k) = (float)inside_samples / (float)cube(subdivisions+1); } }
void compute_volume_fractions(const Array2f& levelset, const Vec2f& ls_origin, float ls_dx, Array2f& volumes, const Vec2f& v_origin, float v_dx, int subdivisions) { float sub_dx = v_dx / (float)(subdivisions+1); for(int j = 0; j < volumes.nj; ++j) for(int i = 0; i < volumes.ni; ++i) { //centre of the volume cells Vec2f bottom_left = v_origin + Vec2f(i*v_dx, j*v_dx); int inside_samples = 0; for(int subj = 0; subj < subdivisions+1; ++subj) for(int subi = 0; subi < subdivisions+1; ++subi) { Vec2f point = bottom_left + Vec2f( (subi+0.5f)*sub_dx, (subj+0.5f)*sub_dx); float data = interpolate_phi(point, levelset, ls_origin, ls_dx); inside_samples += (data < 0)?1:0; } volumes(i,j) = (float)inside_samples / (float)sqr(subdivisions+1); } }
void estimate_volume_fractions(Array3f& volumes, const Vec3f& start_centre, const float dx, const Array3f& phi, const Vec3f& phi_origin, const float phi_dx) { for(int k = 0; k < volumes.nk; ++k) for(int j = 0; j < volumes.nj; ++j) for(int i = 0; i < volumes.ni; ++i) { Vec3f centre = start_centre + Vec3f(i*dx, j*dx, k*dx); float offset = 0.5f*dx; float phi000 = interpolate_phi(centre + Vec3f(-offset,-offset,-offset), phi, phi_origin, phi_dx); float phi001 = interpolate_phi(centre + Vec3f(-offset,-offset,+offset), phi, phi_origin, phi_dx); float phi010 = interpolate_phi(centre + Vec3f(-offset,+offset,-offset), phi, phi_origin, phi_dx); float phi011 = interpolate_phi(centre + Vec3f(-offset,+offset,+offset), phi, phi_origin, phi_dx); float phi100 = interpolate_phi(centre + Vec3f(+offset,-offset,-offset), phi, phi_origin, phi_dx); float phi101 = interpolate_phi(centre + Vec3f(+offset,-offset,+offset), phi, phi_origin, phi_dx); float phi110 = interpolate_phi(centre + Vec3f(+offset,+offset,-offset), phi, phi_origin, phi_dx); float phi111 = interpolate_phi(centre + Vec3f(+offset,+offset,+offset), phi, phi_origin, phi_dx); volumes(i,j,k) = volume_fraction(phi000, phi100, phi010, phi110, phi001, phi101, phi011, phi111); } }