diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 791db2758290e400d4ed9ffe5b8e0d4303057874..6eb277b303f440de5f92b31caecc432c54069149 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -37,9 +37,10 @@ SPH: # Parameters for the self-gravity scheme Gravity: eta: 0.025 # Constant dimensionless multiplier for time integration. - theta: 0.7 # Opening angle (Multipole acceptance criterion) + theta: 0.7 # Opening angle (Multipole acceptance criterion). comoving_softening: 0.0026994 # Comoving softening length (in internal units). max_physical_softening: 0.0007 # Physical softening length (in internal units). + rebuild_frequency: 0.01 # (Optional) Frequency of the gravity-tree rebuild in units of the number of g-particles (this is the default value). a_smooth: 1.25 # (Optional) Smoothing scale in top-level cell sizes to smooth the long-range forces over (this is the default value). r_cut_max: 4.5 # (Optional) Cut-off in number of top-level cells beyond which no FMM forces are computed (this is the default value). r_cut_min: 0.1 # (Optional) Cut-off in number of top-level cells below which no truncation of FMM forces are performed (this is the default value). diff --git a/src/engine.c b/src/engine.c index 9a7a7ede8b5c7d5633543f083d6bef451c0f0059..ac70ef439a918be08afb2452cbdef714ba8c3a31 100644 --- a/src/engine.c +++ b/src/engine.c @@ -3854,6 +3854,11 @@ void engine_rebuild(struct engine *e, int clean_smoothing_length_values) { /* Print the status of the system */ if (e->verbose) engine_print_task_counts(e); + /* Clear the counters of updates since the last rebuild */ + e->updates_since_rebuild = 0; + e->g_updates_since_rebuild = 0; + e->s_updates_since_rebuild = 0; + /* Flag that a rebuild has taken place */ e->step_props |= engine_step_prop_rebuild; @@ -4543,6 +4548,11 @@ void engine_step(struct engine *e) { fflush(e->file_timesteps); } + /* Update the counters */ + e->updates_since_rebuild += e->updates; + e->g_updates_since_rebuild += e->g_updates; + e->s_updates_since_rebuild += e->s_updates; + /* Move forward in time */ e->ti_old = e->ti_current; e->ti_current = e->ti_end_min; @@ -4623,9 +4633,10 @@ void engine_step(struct engine *e) { gravity_exact_force_check(e->s, e, 1e-1); #endif - /* Let's trigger a non-SPH rebuild every-so-often for good measure */ - if (!(e->policy & engine_policy_hydro) && // MATTHIEU improve this - (e->policy & engine_policy_self_gravity) && e->step % 20 == 0) + /* Trigger a tree-rebuild if we passed the frequency threshold */ + if ((e->policy & engine_policy_self_gravity) && + (e->g_updates_since_rebuild > + e->total_nr_gparts * e->gravity_properties->rebuild_frequency)) e->forcerebuild = 1; /* Collect the values of rebuild from all nodes and recover the (integer) diff --git a/src/engine.h b/src/engine.h index 72f440b2e3c0efe4b86c8adb3c06bbe20d1a635c..3181179561d6feb5d9a33616563d3ffcdabd3339 100644 --- a/src/engine.h +++ b/src/engine.h @@ -188,6 +188,11 @@ struct engine { /* Number of particles updated in the previous step */ size_t updates, g_updates, s_updates; + /* Number of updates since the last rebuild */ + size_t updates_since_rebuild; + size_t g_updates_since_rebuild; + size_t s_updates_since_rebuild; + /* Properties of the previous step */ int step_props; diff --git a/src/gravity_properties.c b/src/gravity_properties.c index 928765cc14f856929cb30e936c6044d87b70186a..afebc604351d3210dc6149742ad47dd1089f5743 100644 --- a/src/gravity_properties.c +++ b/src/gravity_properties.c @@ -35,11 +35,20 @@ #define gravity_props_default_a_smooth 1.25f #define gravity_props_default_r_cut_max 4.5f #define gravity_props_default_r_cut_min 0.1f +#define gravity_props_default_rebuild_frequency 0.01f void gravity_props_init(struct gravity_props *p, const struct swift_params *params, const struct cosmology *cosmo) { + /* Tree updates */ + p->rebuild_frequency = + parser_get_opt_param_float(params, "Gravity:rebuild_frequency", + gravity_props_default_rebuild_frequency); + + if (p->rebuild_frequency < 0.f || p->rebuild_frequency > 1.f) + error("Invalid tree rebuild frequency. Must be in [0., 1.]"); + /* Tree-PM parameters */ p->a_smooth = parser_get_opt_param_float(params, "Gravity:a_smooth", gravity_props_default_a_smooth); @@ -116,12 +125,16 @@ void gravity_props_print(const struct gravity_props *p) { message("Self-gravity tree cut-off: r_cut_max=%f", p->r_cut_max); message("Self-gravity truncation cut-off: r_cut_min=%f", p->r_cut_min); + + message("Self-gravity tree update frequency: f=%f", p->rebuild_frequency); } #if defined(HAVE_HDF5) void gravity_props_print_snapshot(hid_t h_grpgrav, const struct gravity_props *p) { + io_write_attribute_f(h_grpgrav, "Tree update frequency", + p->rebuild_frequency); io_write_attribute_f(h_grpgrav, "Time integration eta", p->eta); io_write_attribute_f( h_grpgrav, "Comoving softening length", diff --git a/src/gravity_properties.h b/src/gravity_properties.h index f36a39a6e187b8b397a5f597692f5a37c982aa7a..418e74e715f86bfe7fe333fdcedeb19415bfd394 100644 --- a/src/gravity_properties.h +++ b/src/gravity_properties.h @@ -36,6 +36,9 @@ */ struct gravity_props { + /*! Frequency of tree-rebuild in units of #gpart updates. */ + float rebuild_frequency; + /*! Mesh smoothing scale in units of top-level cell size */ float a_smooth;