diff --git a/examples/main.c b/examples/main.c index 690cbba113e0f90037b57d80bc4f3245559efa03..37d9ff3346d94f8a2588f5bdfabf7406be557d26 100644 --- a/examples/main.c +++ b/examples/main.c @@ -798,8 +798,8 @@ int main(int argc, char *argv[]) { /* Initialize the engine with the space and policies. */ if (myrank == 0) clocks_gettime(&tic); - engine_init(&e, &s, params, N_total[0], N_total[1], engine_policies, - talking, &reparttype, &us, &prog_const, &cosmo, + engine_init(&e, &s, params, N_total[0], N_total[1], N_total[2], + engine_policies, talking, &reparttype, &us, &prog_const, &cosmo, &hydro_properties, &gravity_properties, &potential, &cooling_func, &chemistry, &sourceterms); engine_config(0, &e, params, nr_nodes, myrank, nr_threads, with_aff, diff --git a/src/engine.c b/src/engine.c index bb9a478b4933106c3753a31388bdf78117366147..a3e643fea695ccc33c6b44159569a9995e4fd5ef 100644 --- a/src/engine.c +++ b/src/engine.c @@ -5361,7 +5361,8 @@ void engine_unpin() { * @param s The #space in which this #runner will run. * @param params The parsed parameter file. * @param Ngas total number of gas particles in the simulation. - * @param Ndm total number of gravity particles in the simulation. + * @param Ngparts total number of gravity particles in the simulation. + * @param Nstars total number of star particles in the simulation. * @param policy The queuing policy to use. * @param verbose Is this #engine talkative ? * @param reparttype What type of repartition algorithm are we using ? @@ -5377,7 +5378,7 @@ void engine_unpin() { */ void engine_init(struct engine *e, struct space *s, const struct swift_params *params, long long Ngas, - long long Ndm, int policy, int verbose, + long long Ngparts, long long Nstars, int policy, int verbose, struct repartition *reparttype, const struct unit_system *internal_units, const struct phys_const *physical_constants, @@ -5396,7 +5397,8 @@ void engine_init(struct engine *e, struct space *s, e->policy = policy; e->step = 0; e->total_nr_parts = Ngas; - e->total_nr_gparts = Ndm; + e->total_nr_gparts = Ngparts; + e->total_nr_sparts = Nstars; e->proxy_ind = NULL; e->nr_proxies = 0; e->reparttype = reparttype; @@ -6136,7 +6138,74 @@ void engine_compute_next_statistics_time(struct engine *e) { */ void engine_recompute_displacement_constraint(struct engine *e) { - message("max_dt_RMS_displacement = %e", e->dt_max_RMS_displacement); + const struct cosmology *cosmo = e->cosmology; + const float Om = cosmo->Omega_m; + const float Ob = cosmo->Omega_b; + const float rho_crit = cosmo->critical_density; + const float a = cosmo->a; + + /* Start by reducing the minimal mass of each particle type */ + float min_mass[swift_type_count] = {e->s->min_part_mass, + e->s->min_gpart_mass, + FLT_MAX, + FLT_MAX, + e->s->min_spart_mass, + FLT_MAX}; +#ifdef WITH_MPI + MPI_Allreduce(MPI_IN_PLACE, min_mass, swift_type_count, MPI_FLOAT, MPI_MIN, + MPI_COMM_WORLD); +#endif + + /* Do the same for the velocity norm sum */ + float vel_norm[swift_type_count] = {e->s->sum_part_vel_norm, + e->s->sum_gpart_vel_norm, + 0.f, + 0.f, + e->s->sum_spart_vel_norm, + 0.f}; +#ifdef WITH_MPI + MPI_Allreduce(MPI_IN_PLACE, vel_norm, swift_type_count, MPI_FLOAT, MPI_SUM, + MPI_COMM_WORLD); +#endif + + /* Get the counts of each particle types */ + const long long total_nr_dm_gparts = + e->total_nr_gparts - e->total_nr_parts - e->total_nr_sparts; + float count_parts[swift_type_count] = { + e->total_nr_parts, total_nr_dm_gparts, 0.f, 0.f, e->total_nr_sparts, 0.f}; + + /* Minimal mass for the two species */ + const float min_mass_dm = min_mass[1]; + const float min_mass_b = min(min_mass[0], min_mass[4]); + + /* Inter-particle sepration for the two species */ + const float d_dm = cbrtf(min_mass_dm / ((Om - Ob) * rho_crit)); + const float d_b = cbrtf(min_mass_b / (Ob * rho_crit)); + + /* Count of particles for the two species */ + const float N_dm = count_parts[1]; + const float N_b = count_parts[0] + count_parts[4]; + + /* Peculiar motion norm for the two species */ + const float vel_norm_dm = vel_norm[1]; + const float vel_norm_b = vel_norm[0] + vel_norm[4]; + + /* RMS peculiar motion for the two species */ + const float rms_vel_dm = (N_dm > 0.f) ? (vel_norm_dm / N_dm) : 0.f; + const float rms_vel_b = (N_b > 0.f) ? (vel_norm_b / N_b) : 0.f; + + /* Time-step based on maximum displacement */ + const float dt_dm = a * a * d_dm / (sqrtf(rms_vel_dm) + FLT_MIN); + const float dt_b = a * a * d_b / (sqrtf(rms_vel_b) + FLT_MIN); + + /* Use the minimum */ + const float dt = min(dt_dm, dt_b); + + /* Apply the dimensionless factor */ + e->dt_max_RMS_displacement = dt * e->max_RMS_displacement_factor; + + if (e->verbose) + message("max_dt_RMS_displacement = %e", e->dt_max_RMS_displacement); } /** diff --git a/src/engine.h b/src/engine.h index a6707e0426d485a61464c440915c94d6e74a580b..db3db3158748414fb9b048feabcc2695ae0873a5 100644 --- a/src/engine.h +++ b/src/engine.h @@ -192,7 +192,7 @@ struct engine { int step_props; /* Total numbers of particles in the system. */ - long long total_nr_parts, total_nr_gparts; + long long total_nr_parts, total_nr_gparts, total_nr_sparts; /* The internal system of units */ const struct unit_system *internal_units; @@ -350,7 +350,7 @@ void engine_print_stats(struct engine *e); void engine_dump_snapshot(struct engine *e); void engine_init(struct engine *e, struct space *s, const struct swift_params *params, long long Ngas, - long long Ndm, int policy, int verbose, + long long Ngparts, long long Nstars, int policy, int verbose, struct repartition *reparttype, const struct unit_system *internal_units, const struct phys_const *physical_constants,