// adjust fluid to terrain, compute sph parameters void adjust_fluid(fluid* f, lp_grid lpg, aabb faabb, aabb taabb) { float height = faabb.max.getY() - taabb.min.getY(); float v_max = sqrt(2 * G * height); float cs = v_max / sqrt(MAX_DENSITY_FLUCTUATION); f->ideal_k = WATER_IDEAL_K; f->tait_b = WATER_TAIT_B; // dt to match MAX_DENSITY_FLUCTUATION between ticks f->dt = COURANT * f->particle_radius / v_max; // measure and store max density and samples in the initial fluid // configuration in order to adjust later sph computations clear_particle_data(lpg); std::vector<interaction> interactions = collect_interactions(lpg); compute_densities(interactions, lpg.step); int max_samples = 0; float max_density = 0; for(particle* pp=f->particles; pp<f->particles + f->particle_count; pp++) { if (pp->samples > max_samples) { max_samples = pp->samples; max_density = pp->density; } } f->max_samples = (float) max_samples; f->density_factor = f->density / (max_density * f->particle_mass); printf("FLUID ADJUSTMENT INFO:\n"); printf("dt = %f\n", f->dt); printf("max_density = %f\n", max_density); printf("max_samples = %d\n", max_samples); printf("density_factor = %f\n\n", f->density_factor); }
void apply_sph(fluid_sim* fsimp) { clear_particle_data(fsimp->lpg); std::vector<interaction> interactions = collect_interactions(fsimp->lpg); compute_densities(interactions, fsimp->lpg.step); compute_pressures(fsimp->f); apply_forces(interactions, fsimp->f); }
static void rescale_layout_polarFocus(v_data * graph, int n, double *x_coords, double *y_coords, double x_focus, double y_focus, int interval, double distortion) { // Polar distortion - auxiliary function int i; double *densities = NULL, *smoothed_densities = NULL; double *distances = N_NEW(n, double); double *orig_distances = N_NEW(n, double); int *ordering; double ratio; for (i = 0; i < n; i++) { distances[i] = DIST(x_coords[i], y_coords[i], x_focus, y_focus); } cpvec(orig_distances, 0, n - 1, distances); ordering = N_NEW(n, int); for (i = 0; i < n; i++) { ordering[i] = i; } quicksort_place(distances, ordering, 0, n - 1); densities = compute_densities(graph, n, x_coords, y_coords); smoothed_densities = smooth_vec(densities, ordering, n, interval, smoothed_densities); // rescale distances if (distortion < 1.01 && distortion > 0.99) { for (i = 1; i < n; i++) { distances[ordering[i]] = distances[ordering[i - 1]] + (orig_distances[ordering[i]] - orig_distances[ordering [i - 1]]) / smoothed_densities[ordering[i]]; } } else { double factor; // just to make milder behavior: if (distortion >= 0) { factor = sqrt(distortion); } else { factor = -sqrt(-distortion); } for (i = 1; i < n; i++) { distances[ordering[i]] = distances[ordering[i - 1]] + (orig_distances[ordering[i]] - orig_distances[ordering [i - 1]]) / pow(smoothed_densities[ordering[i]], factor); } } // compute new coordinate: for (i = 0; i < n; i++) { if (orig_distances[i] == 0) { ratio = 0; } else { ratio = distances[i] / orig_distances[i]; } x_coords[i] = x_focus + (x_coords[i] - x_focus) * ratio; y_coords[i] = y_focus + (y_coords[i] - y_focus) * ratio; } free(densities); free(smoothed_densities); free(distances); free(orig_distances); free(ordering); }