Commit 8f6ecbe0 authored by Loic Hausammann's avatar Loic Hausammann
Browse files

Implement stars sort

parent 10d0e160
...@@ -7,5 +7,5 @@ then ...@@ -7,5 +7,5 @@ then
./getIC.sh ./getIC.sh
fi fi
../swift -b -G -s -S -t 8 dwarf_galaxy.yml 2>&1 | tee output.log ../swift -b -G -s -S -t 8 $@ dwarf_galaxy.yml 2>&1 | tee output.log
...@@ -74,6 +74,20 @@ __attribute__((always_inline)) INLINE static int cell_are_gpart_drifted( ...@@ -74,6 +74,20 @@ __attribute__((always_inline)) INLINE static int cell_are_gpart_drifted(
return (c->grav.ti_old_part == e->ti_current); return (c->grav.ti_old_part == e->ti_current);
} }
/**
* @brief Check that the #spart in a #cell have been drifted to the current
* time.
*
* @param c The #cell.
* @param e The #engine containing information about the current time.
* @return 1 if the #cell has been drifted to the current time, 0 otherwise.
*/
__attribute__((always_inline)) INLINE static int cell_are_spart_drifted(
const struct cell *c, const struct engine *e) {
return cell_are_gpart_drifted(c, e);
}
/* Are cells / particles active for regular tasks ? */ /* Are cells / particles active for regular tasks ? */
/** /**
...@@ -185,9 +199,16 @@ __attribute__((always_inline)) INLINE static int cell_is_all_active_gravity( ...@@ -185,9 +199,16 @@ __attribute__((always_inline)) INLINE static int cell_is_all_active_gravity(
__attribute__((always_inline)) INLINE static int cell_is_active_stars( __attribute__((always_inline)) INLINE static int cell_is_active_stars(
const struct cell *c, const struct engine *e) { const struct cell *c, const struct engine *e) {
// LOIC: Need star-specific implementation #ifdef SWIFT_DEBUG_CHECKS
if (c->stars.ti_end_min < e->ti_current)
error(
"cell in an impossible time-zone! c->ti_end_min=%lld (t=%e) and "
"e->ti_current=%lld (t=%e, a=%e)",
c->stars.ti_end_min, c->stars.ti_end_min * e->time_base, e->ti_current,
e->ti_current * e->time_base, e->cosmology->a);
#endif
return cell_is_active_gravity(c, e); return (c->stars.ti_end_min == e->ti_current);
} }
/** /**
......
...@@ -342,6 +342,7 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c, ...@@ -342,6 +342,7 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c,
temp->hydro.dx_max_part = 0.f; temp->hydro.dx_max_part = 0.f;
temp->hydro.dx_max_sort = 0.f; temp->hydro.dx_max_sort = 0.f;
temp->stars.dx_max_part = 0.f; temp->stars.dx_max_part = 0.f;
temp->stars.dx_max_sort = 0.f;
temp->nodeID = c->nodeID; temp->nodeID = c->nodeID;
temp->parent = c; temp->parent = c;
c->progeny[k] = temp; c->progeny[k] = temp;
...@@ -1561,12 +1562,20 @@ void cell_check_multipole(struct cell *c) { ...@@ -1561,12 +1562,20 @@ void cell_check_multipole(struct cell *c) {
*/ */
void cell_clean(struct cell *c) { void cell_clean(struct cell *c) {
/* Hydro */
for (int i = 0; i < 13; i++) for (int i = 0; i < 13; i++)
if (c->hydro.sort[i] != NULL) { if (c->hydro.sort[i] != NULL) {
free(c->hydro.sort[i]); free(c->hydro.sort[i]);
c->hydro.sort[i] = NULL; c->hydro.sort[i] = NULL;
} }
/* Stars */
for (int i = 0; i < 13; i++)
if (c->stars.sort[i] != NULL) {
free(c->stars.sort[i]);
c->stars.sort[i] = NULL;
}
/* Recurse */ /* Recurse */
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k]) cell_clean(c->progeny[k]); if (c->progeny[k]) cell_clean(c->progeny[k]);
...@@ -1724,6 +1733,68 @@ void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s) { ...@@ -1724,6 +1733,68 @@ void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s) {
} }
} }
/**
* @brief Activate the sorts up a cell hierarchy.
*/
void cell_activate_stars_sorts_up(struct cell *c, struct scheduler *s) {
if (c == c->super) {
#ifdef SWIFT_DEBUG_CHECKS
if (c->stars.sorts == NULL)
error("Trying to activate un-existing c->stars.sorts");
#endif
scheduler_activate(s, c->stars.sorts);
if (c->nodeID == engine_rank) {
cell_activate_drift_part(c, s);
cell_activate_drift_spart(c, s);
}
} else {
for (struct cell *parent = c->parent;
parent != NULL && !parent->stars.do_sub_sort;
parent = parent->parent) {
parent->stars.do_sub_sort = 1;
if (parent == c->super) {
#ifdef SWIFT_DEBUG_CHECKS
if (parent->stars.sorts == NULL)
error("Trying to activate un-existing parents->hydro.sorts");
#endif
scheduler_activate(s, parent->stars.sorts);
if (parent->nodeID == engine_rank) {
cell_activate_drift_part(parent, s);
cell_activate_drift_spart(parent, s);
}
break;
}
}
}
}
/**
* @brief Activate the sorts on a given cell, if needed.
*/
void cell_activate_stars_sorts(struct cell *c, int sid, struct scheduler *s) {
/* Do we need to re-sort? */
if (c->stars.dx_max_sort > space_maxreldx * c->dmin) {
/* Climb up the tree to active the sorts in that direction */
for (struct cell *finger = c; finger != NULL; finger = finger->parent) {
if (finger->stars.requires_sorts) {
atomic_or(&finger->stars.do_sort, finger->stars.requires_sorts);
cell_activate_stars_sorts_up(finger, s);
}
finger->stars.sorted = 0;
}
}
/* Has this cell been sorted at all for the given sid? */
if (!(c->stars.sorted & (1 << sid)) || c->nodeID != engine_rank) {
atomic_or(&c->stars.do_sort, (1 << sid));
cell_activate_stars_sorts_up(c, s);
}
}
/** /**
* @brief Traverse a sub-cell task and activate the hydro drift tasks that are * @brief Traverse a sub-cell task and activate the hydro drift tasks that are
* required by a hydro task * required by a hydro task
...@@ -2105,7 +2176,9 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj, ...@@ -2105,7 +2176,9 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
if (cj == NULL) { if (cj == NULL) {
/* Do anything? */ /* Do anything? */
if (ci->stars.count == 0 || !cell_is_active_stars(ci, e)) return; if (!cell_is_active_stars(ci, e) || ci->hydro.count == 0 ||
ci->stars.count == 0)
return;
/* Recurse? */ /* Recurse? */
if (cell_can_recurse_in_self_stars_task(ci)) { if (cell_can_recurse_in_self_stars_task(ci)) {
...@@ -2133,7 +2206,10 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj, ...@@ -2133,7 +2206,10 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
/* Should we even bother? */ /* Should we even bother? */
if (!cell_is_active_stars(ci, e) && !cell_is_active_stars(cj, e)) return; if (!cell_is_active_stars(ci, e) && !cell_is_active_stars(cj, e)) return;
if (ci->stars.count == 0 || cj->stars.count == 0) return;
int should_do = ci->stars.count != 0 && cj->hydro.count != 0;
should_do |= cj->stars.count != 0 && ci->hydro.count != 0;
if (!should_do) return;
/* Get the orientation of the pair. */ /* Get the orientation of the pair. */
double shift[3]; double shift[3];
...@@ -2418,23 +2494,43 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj, ...@@ -2418,23 +2494,43 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
} }
/* Otherwise, activate the sorts and drifts. */ /* Otherwise, activate the sorts and drifts. */
else if (cell_is_active_stars(ci, e) || cell_is_active_stars(cj, e)) { else {
/* We are going to interact this pair, so store some values. */ if (cell_is_active_stars(ci, e) && cj->hydro.count != 0 &&
atomic_or(&ci->hydro.requires_sorts, 1 << sid); ci->stars.count != 0) {
atomic_or(&cj->hydro.requires_sorts, 1 << sid); /* We are going to interact this pair, so store some values. */
ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort; atomic_or(&cj->hydro.requires_sorts, 1 << sid);
cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort; atomic_or(&ci->stars.requires_sorts, 1 << sid);
/* Activate the drifts if the cells are local. */ cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort;
if (ci->nodeID == engine_rank) cell_activate_drift_part(ci, s); ci->stars.dx_max_sort_old = ci->stars.dx_max_sort;
if (ci->nodeID == engine_rank) cell_activate_drift_spart(ci, s);
if (cj->nodeID == engine_rank) cell_activate_drift_part(cj, s);
if (cj->nodeID == engine_rank) cell_activate_drift_spart(cj, s);
/* Do we need to sort the cells? */ /* Activate the drifts if the cells are local. */
cell_activate_sorts(ci, sid, s); if (ci->nodeID == engine_rank) cell_activate_drift_spart(ci, s);
cell_activate_sorts(cj, sid, s); if (cj->nodeID == engine_rank) cell_activate_drift_part(cj, s);
/* Do we need to sort the cells? */
cell_activate_sorts(cj, sid, s);
cell_activate_stars_sorts(ci, sid, s);
}
if (cell_is_active_stars(cj, e) && ci->hydro.count != 0 &&
cj->stars.count != 0) {
/* We are going to interact this pair, so store some values. */
atomic_or(&cj->stars.requires_sorts, 1 << sid);
atomic_or(&ci->hydro.requires_sorts, 1 << sid);
ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
cj->stars.dx_max_sort_old = cj->stars.dx_max_sort;
/* Activate the drifts if the cells are local. */
if (ci->nodeID == engine_rank) cell_activate_drift_part(ci, s);
if (cj->nodeID == engine_rank) cell_activate_drift_spart(cj, s);
/* Do we need to sort the cells? */
cell_activate_sorts(ci, sid, s);
cell_activate_stars_sorts(cj, sid, s);
}
} }
} /* Otherwise, pair interation */ } /* Otherwise, pair interation */
} }
...@@ -2965,25 +3061,48 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) { ...@@ -2965,25 +3061,48 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
/* Activate drifts */ /* Activate drifts */
if (t->type == task_type_self) { if (t->type == task_type_self) {
if (ci->nodeID == nodeID) cell_activate_drift_part(ci, s); if (ci->nodeID == nodeID) {
if (ci->nodeID == nodeID) cell_activate_drift_gpart(ci, s); cell_activate_drift_part(ci, s);
cell_activate_drift_spart(ci, s);
}
} }
/* Set the correct sorting flags and activate hydro drifts */ /* Set the correct sorting flags and activate hydro drifts */
else if (t->type == task_type_pair) { else if (t->type == task_type_pair) {
/* Store some values. */ /* Do ci */
atomic_or(&ci->hydro.requires_sorts, 1 << t->flags); /* stars for ci */
atomic_or(&ci->stars.requires_sorts, 1 << t->flags);
ci->stars.dx_max_sort_old = ci->stars.dx_max_sort;
/* hydro for cj */
atomic_or(&cj->hydro.requires_sorts, 1 << t->flags); atomic_or(&cj->hydro.requires_sorts, 1 << t->flags);
ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort; cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort;
/* Activate the drift tasks. */ /* Activate the drift tasks. */
if (ci->nodeID == nodeID) cell_activate_drift_part(ci, s); if (ci->nodeID == nodeID) cell_activate_drift_spart(ci, s);
if (cj->nodeID == nodeID) cell_activate_drift_part(cj, s); if (cj->nodeID == nodeID) cell_activate_drift_part(cj, s);
/* Check the sorts and activate them if needed. */ /* Check the sorts and activate them if needed. */
cell_activate_sorts(ci, t->flags, s); cell_activate_stars_sorts(ci, t->flags, s);
cell_activate_sorts(cj, t->flags, s); cell_activate_sorts(cj, t->flags, s);
/* Do cj */
/* hydro for ci */
atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
/* stars for cj */
atomic_or(&cj->stars.requires_sorts, 1 << t->flags);
cj->stars.dx_max_sort_old = cj->stars.dx_max_sort;
/* Activate the drift tasks. */
if (cj->nodeID == nodeID) cell_activate_drift_spart(cj, s);
if (ci->nodeID == nodeID) cell_activate_drift_part(ci, s);
/* Check the sorts and activate them if needed. */
cell_activate_sorts(ci, t->flags, s);
cell_activate_stars_sorts(cj, t->flags, s);
} }
/* Store current values of dx_max and h_max. */ /* Store current values of dx_max and h_max. */
else if (t->type == task_type_sub_pair || t->type == task_type_sub_self) { else if (t->type == task_type_sub_pair || t->type == task_type_sub_self) {
...@@ -3402,6 +3521,7 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) { ...@@ -3402,6 +3521,7 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
struct spart *const sparts = c->stars.parts; struct spart *const sparts = c->stars.parts;
float dx_max = 0.f, dx2_max = 0.f; float dx_max = 0.f, dx2_max = 0.f;
float dx_max_sort = 0.0f, dx2_max_sort = 0.f;
float cell_h_max = 0.f; float cell_h_max = 0.f;
/* Drift irrespective of cell flags? */ /* Drift irrespective of cell flags? */
...@@ -3428,6 +3548,7 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) { ...@@ -3428,6 +3548,7 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
/* Update */ /* Update */
dx_max = max(dx_max, cp->stars.dx_max_part); dx_max = max(dx_max, cp->stars.dx_max_part);
dx_max_sort = max(dx_max_sort, cp->stars.dx_max_sort);
cell_h_max = max(cell_h_max, cp->stars.h_max); cell_h_max = max(cell_h_max, cp->stars.h_max);
} }
} }
...@@ -3435,6 +3556,7 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) { ...@@ -3435,6 +3556,7 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
/* Store the values */ /* Store the values */
c->stars.h_max = cell_h_max; c->stars.h_max = cell_h_max;
c->stars.dx_max_part = dx_max; c->stars.dx_max_part = dx_max;
c->stars.dx_max_sort = dx_max_sort;
/* Update the time of the last drift */ /* Update the time of the last drift */
c->grav.ti_old_part = ti_current; c->grav.ti_old_part = ti_current;
...@@ -3528,6 +3650,12 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) { ...@@ -3528,6 +3650,12 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
sp->x_diff[2] * sp->x_diff[2]; sp->x_diff[2] * sp->x_diff[2];
dx2_max = max(dx2_max, dx2); dx2_max = max(dx2_max, dx2);
const float dx2_sort = sp->x_diff_sort[0] * sp->x_diff_sort[0] +
sp->x_diff_sort[1] * sp->x_diff_sort[1] +
sp->x_diff_sort[2] * sp->x_diff_sort[2];
dx2_max_sort = max(dx2_max_sort, dx2_sort);
/* Maximal smoothing length */ /* Maximal smoothing length */
cell_h_max = max(cell_h_max, sp->h); cell_h_max = max(cell_h_max, sp->h);
...@@ -3535,10 +3663,12 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) { ...@@ -3535,10 +3663,12 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
/* Now, get the maximal particle motion from its square */ /* Now, get the maximal particle motion from its square */
dx_max = sqrtf(dx2_max); dx_max = sqrtf(dx2_max);
dx_max_sort = sqrtf(dx2_max_sort);
/* Store the values */ /* Store the values */
c->stars.h_max = cell_h_max; c->stars.h_max = cell_h_max;
c->stars.dx_max_part = dx_max; c->stars.dx_max_part = dx_max;
c->stars.dx_max_sort = dx_max_sort;
/* Update the time of the last drift */ /* Update the time of the last drift */
c->grav.ti_old_part = ti_current; c->grav.ti_old_part = ti_current;
...@@ -3627,7 +3757,8 @@ void cell_drift_multipole(struct cell *c, const struct engine *e) { ...@@ -3627,7 +3757,8 @@ void cell_drift_multipole(struct cell *c, const struct engine *e) {
void cell_check_timesteps(struct cell *c) { void cell_check_timesteps(struct cell *c) {
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
if (c->hydro.ti_end_min == 0 && c->grav.ti_end_min == 0 && c->nr_tasks > 0) if (c->hydro.ti_end_min == 0 && c->grav.ti_end_min == 0 &&
c->stars.ti_end_min == 0 && c->nr_tasks > 0)
error("Cell without assigned time-step"); error("Cell without assigned time-step");
if (c->split) { if (c->split) {
......
...@@ -460,6 +460,30 @@ struct cell { ...@@ -460,6 +460,30 @@ struct cell {
/*! Values of dx_max before the drifts, used for sub-cell tasks. */ /*! Values of dx_max before the drifts, used for sub-cell tasks. */
float dx_max_part_old; float dx_max_part_old;
/*! Maximum particle movement in this cell since the last sort. */
float dx_max_sort;
/*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
float dx_max_sort_old;
/*! Bit mask of sort directions that will be needed in the next timestep. */
unsigned int requires_sorts;
/*! Pointer for the sorted indices. */
struct entry *sort[13];
/*! Bit-mask indicating the sorted directions */
unsigned int sorted;
/*! Bit mask of sorts that need to be computed for this cell. */
unsigned int do_sort;
/*! Do any of this cell's sub-cells need to be sorted? */
char do_sub_sort;
/*! Maximum end of (integer) time step in this cell for gravity tasks. */
integertime_t ti_end_min;
/*! Dependency implicit task for the star ghost (in->ghost->out)*/ /*! Dependency implicit task for the star ghost (in->ghost->out)*/
struct task *ghost_in; struct task *ghost_in;
...@@ -469,6 +493,9 @@ struct cell { ...@@ -469,6 +493,9 @@ struct cell {
/*! The star ghost task itself */ /*! The star ghost task itself */
struct task *ghost; struct task *ghost;
/*! The task computing this cell's sorts. */
struct task *sorts;
/*! Linked list of the tasks computing this cell's star density. */ /*! Linked list of the tasks computing this cell's star density. */
struct link *density; struct link *density;
...@@ -484,6 +511,11 @@ struct cell { ...@@ -484,6 +511,11 @@ struct cell {
/*! Spin lock for various uses (#spart case). */ /*! Spin lock for various uses (#spart case). */
swift_lock_type lock; swift_lock_type lock;
#ifdef SWIFT_DEBUG_CHECKS
/*! Last (integer) time the cell's sort arrays were updated. */
integertime_t ti_sort;
#endif
} stars; } stars;
#ifdef WITH_MPI #ifdef WITH_MPI
...@@ -652,7 +684,9 @@ void cell_activate_subcell_external_grav_tasks(struct cell *ci, ...@@ -652,7 +684,9 @@ void cell_activate_subcell_external_grav_tasks(struct cell *ci,
struct scheduler *s); struct scheduler *s);
void cell_activate_drift_part(struct cell *c, struct scheduler *s); void cell_activate_drift_part(struct cell *c, struct scheduler *s);
void cell_activate_drift_gpart(struct cell *c, struct scheduler *s); void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
void cell_activate_drift_spart(struct cell *c, struct scheduler *s);
void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s); void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s);
void cell_activate_stars_sorts(struct cell *c, int sid, struct scheduler *s);
void cell_clear_drift_flags(struct cell *c, void *data); void cell_clear_drift_flags(struct cell *c, void *data);
void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data); void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data);
int cell_has_tasks(struct cell *c); int cell_has_tasks(struct cell *c);
......
...@@ -142,6 +142,7 @@ __attribute__((always_inline)) INLINE static void drift_spart( ...@@ -142,6 +142,7 @@ __attribute__((always_inline)) INLINE static void drift_spart(
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
const float dx = sp->v[k] * dt_drift; const float dx = sp->v[k] * dt_drift;
sp->x_diff[k] -= dx; sp->x_diff[k] -= dx;
sp->x_diff_sort[k] -= dx;
} }
} }
......
...@@ -128,6 +128,7 @@ struct end_of_step_data { ...@@ -128,6 +128,7 @@ struct end_of_step_data {
size_t inhibited, g_inhibited, s_inhibited; size_t inhibited, g_inhibited, s_inhibited;
integertime_t ti_hydro_end_min, ti_hydro_end_max, ti_hydro_beg_max; integertime_t ti_hydro_end_min, ti_hydro_end_max, ti_hydro_beg_max;
integertime_t ti_gravity_end_min, ti_gravity_end_max, ti_gravity_beg_max; integertime_t ti_gravity_end_min, ti_gravity_end_max, ti_gravity_beg_max;
integertime_t ti_stars_end_min;
struct engine *e; struct engine *e;
}; };
...@@ -1924,7 +1925,8 @@ int engine_estimate_nr_tasks(struct engine *e) { ...@@ -1924,7 +1925,8 @@ int engine_estimate_nr_tasks(struct engine *e) {
n1 += 2; n1 += 2;
} }
if (e->policy & engine_policy_stars) { if (e->policy & engine_policy_stars) {
n1 += 2; /* 1 self, 1 sort, 26/2 pairs */
n1 += 15;
} }
#if defined(WITH_LOGGER) #if defined(WITH_LOGGER)
n1 += 1; n1 += 1;
...@@ -2214,6 +2216,7 @@ void engine_collect_end_of_step_recurse(struct cell *c, ...@@ -2214,6 +2216,7 @@ void engine_collect_end_of_step_recurse(struct cell *c,
ti_hydro_beg_max = 0; ti_hydro_beg_max = 0;
integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0, integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0,
ti_gravity_beg_max = 0; ti_gravity_beg_max = 0;
integertime_t ti_stars_end_min = max_nr_timesteps;
/* Collect the values from the progeny. */ /* Collect the values from the progeny. */
for (int k = 0; k < 8; k++) { for (int k = 0; k < 8; k++) {
...@@ -2233,6 +2236,8 @@ void engine_collect_end_of_step_recurse(struct cell *c, ...@@ -2233,6 +2236,8 @@ void engine_collect_end_of_step_recurse(struct cell *c,
ti_gravity_end_max = max(ti_gravity_end_max, cp->grav.ti_end_max); ti_gravity_end_max = max(ti_gravity_end_max, cp->grav.ti_end_max);
ti_gravity_beg_max = max(ti_gravity_beg_max, cp->grav.ti_beg_max); ti_gravity_beg_max = max(ti_gravity_beg_max, cp->grav.ti_beg_max);
ti_stars_end_min = min(ti_stars_end_min, cp->stars.ti_end_min);
updated += cp->hydro.updated; updated += cp->hydro.updated;
g_updated += cp->grav.updated; g_updated += cp->grav.updated;
s_updated += cp->stars.updated; s_updated += cp->stars.updated;
...@@ -2255,6 +2260,7 @@ void engine_collect_end_of_step_recurse(struct cell *c, ...@@ -2255,6 +2260,7 @@ void engine_collect_end_of_step_recurse(struct cell *c,
c->grav.ti_end_min = ti_gravity_end_min; c->grav.ti_end_min = ti_gravity_end_min;
c->grav.ti_end_max = ti_gravity_end_max; c->grav.ti_end_max = ti_gravity_end_max;
c->grav.ti_beg_max = ti_gravity_beg_max; c->grav.ti_beg_max = ti_gravity_beg_max;
c->stars.ti_end_min = ti_stars_end_min;
c->hydro.updated = updated; c->hydro.updated = updated;
c->grav.updated = g_updated; c->grav.updated = g_updated;
c->stars.updated = s_updated; c->stars.updated = s_updated;
...@@ -2289,6 +2295,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, ...@@ -2289,6 +2295,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements,
ti_hydro_beg_max = 0; ti_hydro_beg_max = 0;
integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0, integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0,
ti_gravity_beg_max = 0; ti_gravity_beg_max = 0;
integertime_t ti_stars_end_min = max_nr_timesteps;
for (int ind = 0; ind < num_elements; ind++) { for (int ind = 0; ind < num_elements; ind++) {
struct cell *c = &s->cells_top[local_cells[ind]]; struct cell *c = &s->cells_top[local_cells[ind]];
...@@ -2309,6 +2316,9 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, ...@@ -2309,6 +2316,9 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements,
ti_gravity_end_max = max(ti_gravity_end_max, c->grav.ti_end_max); ti_gravity_end_max = max(ti_gravity_end_max, c->grav.ti_end_max);
ti_gravity_beg_max = max(ti_gravity_beg_max, c->grav.ti_beg_max); ti_gravity_beg_max = max(ti_gravity_beg_max, c->grav.ti_beg_max);
if (c->stars.ti_end_min > e->ti_current)
ti_stars_end_min = min(ti_stars_end_min, c->stars.ti_end_min);