Commit ccf5f553 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Compute the minimal of all species when rebuilding.

parent 71b27da6
......@@ -24,7 +24,8 @@ TimeIntegration:
time_end: 1e-2 # The end time of the simulation (in internal units).
dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units).
dt_max: 1e-4 # The maximal time-step size of the simulation (in internal units).
max_dt_RMS_factor: 0.25
# Parameters governing the snapshots
Snapshots:
basename: eagle # Common part of the name of output files
......
......@@ -24,6 +24,7 @@
/* Includes. */
#include "inline.h"
#include "minmax.h"
#define atomic_add(v, i) __sync_fetch_and_add(v, i)
#define atomic_sub(v, i) __sync_fetch_and_sub(v, i)
......@@ -33,4 +34,40 @@
#define atomic_cas(v, o, n) __sync_val_compare_and_swap(v, o, n)
#define atomic_swap(v, n) __sync_lock_test_and_set(v, n)
/**
* @param Atomic min operation on floats.
*/
__attribute__((always_inline)) INLINE void atomic_min_f(float const* x,
float y) {
int done = 0;
while (!done) {
const float val = *x;
done = __sync_bool_compare_and_swap((int*)x, val, min(val, y));
}
}
/**
* @param Atomic max operation on floats.
*/
__attribute__((always_inline)) INLINE void atomic_max_f(float const* x,
float y) {
int done = 0;
while (!done) {
const float val = *x;
done = __sync_bool_compare_and_swap((int*)x, val, max(val, y));
}
}
/**
* @param Atomic add operation on floats.
*/
__attribute__((always_inline)) INLINE void atomic_add_f(float const* x,
float y) {
int done = 0;
while (!done) {
const float val = *x;
done = __sync_bool_compare_and_swap((int*)x, val, val + y);
}
}
#endif /* SWIFT_ATOMIC_H */
......@@ -3804,6 +3804,10 @@ void engine_rebuild(struct engine *e, int clean_smoothing_length_values) {
/* Re-build the space. */
space_rebuild(e->s, e->verbose);
/* Re-compute the maximal RMS displacement constraint */
if (e->policy & engine_policy_cosmology)
engine_recompute_displacement_constraint(e);
#ifdef SWIFT_DEBUG_CHECKS
part_verify_links(e->s->parts, e->s->gparts, e->s->sparts, e->s->nr_parts,
e->s->nr_gparts, e->s->nr_sparts, e->verbose);
......@@ -5422,8 +5426,8 @@ void engine_init(struct engine *e, struct space *s,
e->dt_min = parser_get_param_double(params, "TimeIntegration:dt_min");
e->dt_max = parser_get_param_double(params, "TimeIntegration:dt_max");
e->dt_max_RMS_displacement = FLT_MAX;
e->max_RMS_displacement_factor =
parser_get_param_double(params, "TimeIntegration:max_RMS_factor");
e->max_RMS_displacement_factor = parser_get_opt_param_double(
params, "TimeIntegration:max_dt_RMS_factor", 1.);
e->a_first_statistics =
parser_get_opt_param_double(params, "Statistics:scale_factor_first", 0.1);
e->time_first_statistics =
......@@ -6124,6 +6128,17 @@ void engine_compute_next_statistics_time(struct engine *e) {
}
}
/**
* @brief Computes the maximal time-step allowed by the max RMS displacement
* condition.
*
* @param e The #engine.
*/
void engine_recompute_displacement_constraint(struct engine *e) {
message("max_dt_RMS_displacement = %e", e->dt_max_RMS_displacement);
}
/**
* @brief Frees up the memory allocated for this #engine
*/
......
......@@ -341,6 +341,7 @@ struct engine {
void engine_barrier(struct engine *e);
void engine_compute_next_snapshot_time(struct engine *e);
void engine_compute_next_statistics_time(struct engine *e);
void engine_recompute_displacement_constraint(struct engine *e);
void engine_unskip(struct engine *e);
void engine_drift_all(struct engine *e);
void engine_drift_top_multipoles(struct engine *e);
......
......@@ -1087,6 +1087,9 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts,
if (cell_counts == NULL)
error("Failed to allocate temporary cell count buffer.");
/* Init the local minimal part mass */
float min_mass = FLT_MAX;
/* Loop over the parts. */
for (int k = 0; k < nr_parts; k++) {
......@@ -1119,6 +1122,9 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts,
pos_z);
#endif
/* Compute minimal mass */
min_mass = min(min_mass, hydro_get_mass(p));
/* Update the position */
p->x[0] = pos_x;
p->x[1] = pos_y;
......@@ -1129,6 +1135,9 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts,
for (int k = 0; k < s->nr_cells; k++)
if (cell_counts[k]) atomic_add(&data->cell_counts[k], cell_counts[k]);
free(cell_counts);
/* Write back thee minimal part mass */
atomic_min_f(&s->min_part_mass, min_mass);
}
/**
......@@ -1161,6 +1170,9 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts,
if (cell_counts == NULL)
error("Failed to allocate temporary cell count buffer.");
/* Init the local minimal part mass */
float min_mass = FLT_MAX;
for (int k = 0; k < nr_gparts; k++) {
/* Get the particle */
......@@ -1192,6 +1204,9 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts,
pos_z);
#endif
/* Compute minimal mass */
if (gp->type == swift_type_dark_matter) min_mass = min(min_mass, gp->mass);
/* Update the position */
gp->x[0] = pos_x;
gp->x[1] = pos_y;
......@@ -1202,6 +1217,9 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts,
for (int k = 0; k < s->nr_cells; k++)
if (cell_counts[k]) atomic_add(&data->cell_counts[k], cell_counts[k]);
free(cell_counts);
/* Write back thee minimal part mass */
atomic_min_f(&s->min_gpart_mass, min_mass);
}
/**
......@@ -1234,6 +1252,9 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts,
if (cell_counts == NULL)
error("Failed to allocate temporary cell count buffer.");
/* Init the local minimal part mass */
float min_mass = FLT_MAX;
for (int k = 0; k < nr_sparts; k++) {
/* Get the particle */
......@@ -1265,6 +1286,9 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts,
pos_z);
#endif
/* Compute minimal mass */
min_mass = min(min_mass, sp->mass);
/* Update the position */
sp->x[0] = pos_x;
sp->x[1] = pos_y;
......@@ -1275,11 +1299,16 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts,
for (int k = 0; k < s->nr_cells; k++)
if (cell_counts[k]) atomic_add(&data->cell_counts[k], cell_counts[k]);
free(cell_counts);
/* Write back thee minimal part mass */
atomic_min_f(&s->min_spart_mass, min_mass);
}
/**
* @brief Computes the cell index of all the particles.
*
* Also computes the minimal mass of all #part.
*
* @param s The #space.
* @param ind The array of indices to fill.
* @param cell_counts The cell counters to update.
......@@ -1291,6 +1320,9 @@ void space_parts_get_cell_index(struct space *s, int *ind, int *cell_counts,
const ticks tic = getticks();
/* Re-set the minimal mass */
s->min_part_mass = FLT_MAX;
/* Pack the extra information */
struct index_data data;
data.s = s;
......@@ -1309,6 +1341,8 @@ void space_parts_get_cell_index(struct space *s, int *ind, int *cell_counts,
/**
* @brief Computes the cell index of all the g-particles.
*
* Also computes the minimal mass of all dark-matter #gpart.
*
* @param s The #space.
* @param gind The array of indices to fill.
* @param cell_counts The cell counters to update.
......@@ -1320,6 +1354,9 @@ void space_gparts_get_cell_index(struct space *s, int *gind, int *cell_counts,
const ticks tic = getticks();
/* Re-set the minimal mass */
s->min_gpart_mass = FLT_MAX;
/* Pack the extra information */
struct index_data data;
data.s = s;
......@@ -1338,6 +1375,8 @@ void space_gparts_get_cell_index(struct space *s, int *gind, int *cell_counts,
/**
* @brief Computes the cell index of all the s-particles.
*
* Also computes the minimal mass of all #spart.
*
* @param s The #space.
* @param sind The array of indices to fill.
* @param cell_counts The cell counters to update.
......@@ -1349,6 +1388,9 @@ void space_sparts_get_cell_index(struct space *s, int *sind, int *cell_counts,
const ticks tic = getticks();
/* Re-set the minimal mass */
s->min_spart_mass = FLT_MAX;
/* Pack the extra information */
struct index_data data;
data.s = s;
......
......@@ -146,6 +146,15 @@ struct space {
/*! The top-level FFT task */
struct task *grav_top_level;
/*! Minimal mass of all the #part */
float min_part_mass;
/*! Minimal mass of all the dark-matter #gpart */
float min_gpart_mass;
/*! Minimal mass of all the #spart */
float min_spart_mass;
/*! General-purpose lock for this space. */
swift_lock_type lock;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment