Commit 691d8a15 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Re-generated the code from timestep_limiter2. Code runs until the first rebuild.

parent b3421a96
......@@ -64,6 +64,7 @@
#include "task.h"
#include "timers.h"
#include "timestep.h"
#include "timestep_limiter.h"
#include "tracers.h"
#define TASK_LOOP_DENSITY 0
......@@ -94,6 +95,13 @@
#undef FUNCTION
#undef FUNCTION_TASK_LOOP
/* Import the limiter loop functions. */
#define FUNCTION limiter
#define FUNCTION_TASK_LOOP TASK_LOOP_LIMITER
#include "runner_doiact.h"
#undef FUNCTION
#undef FUNCTION_TASK_LOOP
/* Import the gravity loop functions. */
#include "runner_doiact_grav.h"
......@@ -1673,19 +1681,26 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) {
/* If particle needs to be kicked */
if (part_is_starting(p, e)) {
#ifdef SWIFT_DEBUG_CHECKS
if (p->wakeup == time_bin_awake)
error("Woken-up particle that has not been processed in kick1");
#endif
/* Skip particles that have been woken up and treated by the limiter. */
if (p->wakeup != time_bin_not_awake) continue;
const integertime_t ti_step = get_integer_timestep(p->time_bin);
const integertime_t ti_begin =
get_integer_time_begin(ti_current + 1, p->time_bin);
#ifdef SWIFT_DEBUG_CHECKS
const integertime_t ti_end =
get_integer_time_end(ti_current + 1, p->time_bin);
const integertime_t ti_end = ti_begin + ti_step;
if (ti_begin != ti_current)
error(
"Particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, "
"ti_step=%lld time_bin=%d ti_current=%lld",
ti_end, ti_begin, ti_step, p->time_bin, ti_current);
"ti_step=%lld time_bin=%d wakeup=%d ti_current=%lld",
ti_end, ti_begin, ti_step, p->time_bin, p->wakeup, ti_current);
#endif
/* Time interval for this half-kick */
......@@ -1847,39 +1862,60 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) {
/* If particle needs to be kicked */
if (part_is_active(p, e)) {
const integertime_t ti_step = get_integer_timestep(p->time_bin);
const integertime_t ti_begin =
get_integer_time_begin(ti_current, p->time_bin);
integertime_t ti_begin, ti_end, ti_step;
#ifdef SWIFT_DEBUG_CHECKS
if (p->wakeup == time_bin_awake)
error("Woken-up particle that has not been processed in kick1");
#endif
if (p->wakeup == time_bin_not_awake) {
/* Time-step from a regular kick */
ti_step = get_integer_timestep(p->time_bin);
ti_begin = get_integer_time_begin(ti_current, p->time_bin);
ti_end = ti_begin + ti_step;
} else {
/* Time-step that follows a wake-up call */
ti_begin = get_integer_time_begin(ti_current, p->wakeup);
ti_end = get_integer_time_end(ti_current, p->time_bin);
ti_step = ti_end - ti_begin;
/* Reset the flag. Everything is back to normal from now on. */
p->wakeup = time_bin_awake;
}
#ifdef SWIFT_DEBUG_CHECKS
if (ti_begin + ti_step != ti_current)
error(
"Particle in wrong time-bin, ti_begin=%lld, ti_step=%lld "
"time_bin=%d ti_current=%lld",
ti_begin, ti_step, p->time_bin, ti_current);
"time_bin=%d wakeup=%d ti_current=%lld",
ti_begin, ti_step, p->time_bin, p->wakeup, ti_current);
#endif
/* Time interval for this half-kick */
double dt_kick_grav, dt_kick_hydro, dt_kick_therm, dt_kick_corr;
if (with_cosmology) {
dt_kick_hydro = cosmology_get_hydro_kick_factor(
cosmo, ti_begin + ti_step / 2, ti_begin + ti_step);
cosmo, ti_begin + ti_step / 2, ti_end);
dt_kick_grav = cosmology_get_grav_kick_factor(
cosmo, ti_begin + ti_step / 2, ti_begin + ti_step);
cosmo, ti_begin + ti_step / 2, ti_end);
dt_kick_therm = cosmology_get_therm_kick_factor(
cosmo, ti_begin + ti_step / 2, ti_begin + ti_step);
cosmo, ti_begin + ti_step / 2, ti_end);
dt_kick_corr = cosmology_get_corr_kick_factor(
cosmo, ti_begin + ti_step / 2, ti_begin + ti_step);
cosmo, ti_begin + ti_step / 2, ti_end);
} else {
dt_kick_hydro = (ti_step / 2) * time_base;
dt_kick_grav = (ti_step / 2) * time_base;
dt_kick_therm = (ti_step / 2) * time_base;
dt_kick_corr = (ti_step / 2) * time_base;
dt_kick_hydro = (ti_end - (ti_begin + ti_step / 2)) * time_base;
dt_kick_grav = (ti_end - (ti_begin + ti_step / 2)) * time_base;
dt_kick_therm = (ti_end - (ti_begin + ti_step / 2)) * time_base;
dt_kick_corr = (ti_end - (ti_begin + ti_step / 2)) * time_base;
}
/* Finish the time-step with a second half-kick */
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm,
dt_kick_corr, cosmo, hydro_props, ti_begin + ti_step / 2,
ti_begin + ti_step);
ti_end);
#ifdef SWIFT_DEBUG_CHECKS
/* Check that kick and the drift are synchronized */
......@@ -2281,6 +2317,132 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) {
if (timer) TIMER_TOC(timer_timestep);
}
/**
* @brief Apply the time-step limiter to all awaken particles in a cell
* hierarchy.
*
* @param r The task #runner.
* @param c The #cell.
* @param force Limit the particles irrespective of the #cell flags.
* @param timer Are we timing this ?
*/
void runner_do_limiter(struct runner *r, struct cell *c, int force, int timer) {
const struct engine *e = r->e;
const integertime_t ti_current = e->ti_current;
const int count = c->hydro.count;
struct part *restrict parts = c->hydro.parts;
struct xpart *restrict xparts = c->hydro.xparts;
TIMER_TIC;
#ifdef SWIFT_DEBUG_CHECKS
/* Check that we only limit local cells. */
if (c->nodeID != engine_rank) error("Limiting dt of a foreign cell is nope.");
#endif
integertime_t ti_hydro_end_min = max_nr_timesteps, ti_hydro_end_max = 0,
ti_hydro_beg_max = 0;
integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0,
ti_gravity_beg_max = 0;
/* Limit irrespective of cell flags? */
force |= c->hydro.do_limiter;
/* Loop over the progeny ? */
if (c->split && (force || c->hydro.do_sub_limiter)) {
for (int k = 0; k < 8; k++) {
if (c->progeny[k] != NULL) {
struct cell *restrict cp = c->progeny[k];
/* Recurse */
runner_do_limiter(r, cp, force, 0);
/* And aggregate */
ti_hydro_end_min = min(cp->hydro.ti_end_min, ti_hydro_end_min);
ti_hydro_end_max = max(cp->hydro.ti_end_max, ti_hydro_end_max);
ti_hydro_beg_max = max(cp->hydro.ti_beg_max, ti_hydro_beg_max);
ti_gravity_end_min = min(cp->grav.ti_end_min, ti_gravity_end_min);
ti_gravity_end_max = max(cp->grav.ti_end_max, ti_gravity_end_max);
ti_gravity_beg_max = max(cp->grav.ti_beg_max, ti_gravity_beg_max);
}
}
/* Store the updated values */
c->hydro.ti_end_min = min(c->hydro.ti_end_min, ti_hydro_end_min);
c->hydro.ti_end_max = max(c->hydro.ti_end_max, ti_hydro_end_max);
c->hydro.ti_beg_max = max(c->hydro.ti_beg_max, ti_hydro_beg_max);
c->grav.ti_end_min = min(c->grav.ti_end_min, ti_gravity_end_min);
c->grav.ti_end_max = max(c->grav.ti_end_max, ti_gravity_end_max);
c->grav.ti_beg_max = max(c->grav.ti_beg_max, ti_gravity_beg_max);
} else if (!c->split && force) {
ti_hydro_end_min = c->hydro.ti_end_min;
ti_hydro_end_max = c->hydro.ti_end_max;
ti_hydro_beg_max = c->hydro.ti_beg_max;
ti_gravity_end_min = c->grav.ti_end_min;
ti_gravity_end_max = c->grav.ti_end_max;
ti_gravity_beg_max = c->grav.ti_beg_max;
/* Loop over the gas particles in this cell. */
for (int k = 0; k < count; k++) {
/* Get a handle on the part. */
struct part *restrict p = &parts[k];
struct xpart *restrict xp = &xparts[k];
/* If the particle will be active no need to wake it up */
if (part_is_active(p, e) && p->wakeup != time_bin_not_awake)
p->wakeup = time_bin_not_awake;
/* Bip, bip, bip... wake-up time */
if (p->wakeup == time_bin_awake) {
/* Apply the limiter and get the new time-step size */
const integertime_t ti_new_step = timestep_limit_part(p, xp, e);
/* What is the next sync-point ? */
ti_hydro_end_min = min(ti_current + ti_new_step, ti_hydro_end_min);
ti_hydro_end_max = max(ti_current + ti_new_step, ti_hydro_end_max);
/* What is the next starting point for this cell ? */
ti_hydro_beg_max = max(ti_current, ti_hydro_beg_max);
/* Also limit the gpart counter-part */
if (p->gpart != NULL) {
/* Register the time-bin */
p->gpart->time_bin = p->time_bin;
/* What is the next sync-point ? */
ti_gravity_end_min =
min(ti_current + ti_new_step, ti_gravity_end_min);
ti_gravity_end_max =
max(ti_current + ti_new_step, ti_gravity_end_max);
/* What is the next starting point for this cell ? */
ti_gravity_beg_max = max(ti_current, ti_gravity_beg_max);
}
}
}
/* Store the updated values */
c->hydro.ti_end_min = min(c->hydro.ti_end_min, ti_hydro_end_min);
c->hydro.ti_end_max = max(c->hydro.ti_end_max, ti_hydro_end_max);
c->hydro.ti_beg_max = max(c->hydro.ti_beg_max, ti_hydro_beg_max);
c->grav.ti_end_min = min(c->grav.ti_end_min, ti_gravity_end_min);
c->grav.ti_end_max = max(c->grav.ti_end_max, ti_gravity_end_max);
c->grav.ti_beg_max = max(c->grav.ti_beg_max, ti_gravity_beg_max);
}
/* Clear the limiter flags. */
c->hydro.do_limiter = 0;
c->hydro.do_sub_limiter = 0;
if (timer) TIMER_TOC(timer_do_limiter);
}
/**
* @brief End the force calculation of all active particles in a cell
* by multiplying the acccelerations by the relevant constants
......@@ -2733,6 +2895,8 @@ void *runner_main(void *data) {
#endif
else if (t->subtype == task_subtype_force)
runner_doself2_branch_force(r, ci);
else if (t->subtype == task_subtype_limiter)
runner_doself2_branch_limiter(r, ci);
else if (t->subtype == task_subtype_grav)
runner_doself_recursive_grav(r, ci, 1);
else if (t->subtype == task_subtype_external_grav)
......@@ -2754,6 +2918,8 @@ void *runner_main(void *data) {
#endif
else if (t->subtype == task_subtype_force)
runner_dopair2_branch_force(r, ci, cj);
else if (t->subtype == task_subtype_limiter)
runner_dopair2_branch_limiter(r, ci, cj);
else if (t->subtype == task_subtype_grav)
runner_dopair_recursive_grav(r, ci, cj, 1);
else if (t->subtype == task_subtype_stars_density)
......@@ -2773,6 +2939,8 @@ void *runner_main(void *data) {
#endif
else if (t->subtype == task_subtype_force)
runner_dosub_self2_force(r, ci, 1);
else if (t->subtype == task_subtype_limiter)
runner_dosub_self2_limiter(r, ci, 1);
else if (t->subtype == task_subtype_stars_density)
runner_dosub_self_stars_density(r, ci, 1);
else if (t->subtype == task_subtype_stars_feedback)
......@@ -2790,6 +2958,8 @@ void *runner_main(void *data) {
#endif
else if (t->subtype == task_subtype_force)
runner_dosub_pair2_force(r, ci, cj, t->flags, 1);
else if (t->subtype == task_subtype_limiter)
runner_dosub_pair2_limiter(r, ci, cj, t->flags, 1);
else if (t->subtype == task_subtype_stars_density)
runner_dosub_pair_stars_density(r, ci, cj, t->flags, 1);
else if (t->subtype == task_subtype_stars_feedback)
......@@ -2849,6 +3019,9 @@ void *runner_main(void *data) {
case task_type_timestep:
runner_do_timestep(r, ci, 1);
break;
case task_type_timestep_limiter:
runner_do_limiter(r, ci, 0, 1);
break;
#ifdef WITH_MPI
case task_type_send:
if (t->subtype == task_subtype_tend) {
......@@ -2865,6 +3038,8 @@ void *runner_main(void *data) {
runner_do_recv_part(r, ci, 0, 1);
} else if (t->subtype == task_subtype_gradient) {
runner_do_recv_part(r, ci, 0, 1);
} else if (t->subtype == task_subtype_limiter) {
runner_do_recv_part(r, ci, 0, 1);
} else if (t->subtype == task_subtype_gpart) {
runner_do_recv_gpart(r, ci, 1);
} else if (t->subtype == task_subtype_spart) {
......
......@@ -263,6 +263,7 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) {
int density_cluster[4] = {0};
int gradient_cluster[4] = {0};
int force_cluster[4] = {0};
int limiter_cluster[4] = {0};
int gravity_cluster[5] = {0};
int stars_density_cluster[4] = {0};
......@@ -283,6 +284,8 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) {
gradient_cluster[k] = 1;
if (type == task_type_self + k && subtype == task_subtype_force)
force_cluster[k] = 1;
if (type == task_type_self + k && subtype == task_subtype_limiter)
limiter_cluster[k] = 1;
if (type == task_type_self + k && subtype == task_subtype_grav)
gravity_cluster[k] = 1;
if (type == task_type_self + k &&
......@@ -323,8 +326,17 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) {
subtaskID_names[task_subtype_gradient]);
fprintf(f, "\t};\n");
/* Make a cluster for the limiter tasks */
fprintf(f, "\t subgraph cluster2{\n");
fprintf(f, "\t\t label=\"\";\n");
for (int k = 0; k < 4; ++k)
if (limiter_cluster[k])
fprintf(f, "\t\t \"%s %s\";\n", taskID_names[task_type_self + k],
subtaskID_names[task_subtype_limiter]);
fprintf(f, "\t};\n");
/* Make a cluster for the gravity tasks */
fprintf(f, "\t subgraph cluster3{\n");
fprintf(f, "\t subgraph cluster4{\n");
fprintf(f, "\t\t label=\"\";\n");
for (int k = 0; k < 2; ++k)
if (gravity_cluster[k])
......@@ -1948,6 +1960,9 @@ void scheduler_reweight(struct scheduler *s, int verbose) {
case task_type_timestep:
cost = wscale * count_i + wscale * gcount_i;
break;
case task_type_timestep_limiter:
cost = wscale * count_i;
break;
case task_type_send:
#if defined(WITH_MPI) && (defined(HAVE_PARMETIS) || defined(HAVE_METIS))
partcost = 0;
......@@ -2157,7 +2172,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
subtaskMPI_comms[t->subtype], &t->req);
} else if (t->subtype == task_subtype_xv ||
t->subtype == task_subtype_rho ||
t->subtype == task_subtype_gradient) {
t->subtype == task_subtype_gradient ||
t->subtype == task_subtype_limiter) {
err = MPI_Irecv(t->ci->hydro.parts, t->ci->hydro.count, part_mpi_type,
t->ci->nodeID, t->flags, subtaskMPI_comms[t->subtype],
&t->req);
......@@ -2208,7 +2224,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
subtaskMPI_comms[t->subtype], &t->req);
} else if (t->subtype == task_subtype_xv ||
t->subtype == task_subtype_rho ||
t->subtype == task_subtype_gradient) {
t->subtype == task_subtype_gradient ||
t->subtype == task_subtype_limiter) {
if ((t->ci->hydro.count * sizeof(struct part)) > s->mpi_message_limit)
err = MPI_Isend(t->ci->hydro.parts, t->ci->hydro.count,
part_mpi_type, t->cj->nodeID, t->flags,
......
......@@ -189,6 +189,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements,
c->hydro.density = NULL;
c->hydro.gradient = NULL;
c->hydro.force = NULL;
c->hydro.limiter = NULL;
c->grav.grav = NULL;
c->grav.mm = NULL;
c->hydro.dx_max_part = 0.0f;
......@@ -223,12 +224,12 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements,
c->kick1 = NULL;
c->kick2 = NULL;
c->timestep = NULL;
c->timestep_limiter = NULL;
c->end_force = NULL;
c->hydro.drift = NULL;
c->grav.drift = NULL;
c->grav.drift_out = NULL;
c->hydro.cooling = NULL;
c->sourceterms = NULL;
c->grav.long_range = NULL;
c->grav.down_in = NULL;
c->grav.down = NULL;
......@@ -272,12 +273,14 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements,
c->mpi.hydro.recv_gradient = NULL;
c->mpi.grav.recv = NULL;
c->mpi.recv_ti = NULL;
c->mpi.limiter.recv = NULL;
c->mpi.hydro.send_xv = NULL;
c->mpi.hydro.send_rho = NULL;
c->mpi.hydro.send_gradient = NULL;
c->mpi.grav.send = NULL;
c->mpi.send_ti = NULL;
c->mpi.limiter.send = NULL;
#endif
}
}
......@@ -4268,6 +4271,44 @@ void space_check_timesteps(struct space *s) {
#endif
}
/**
* @brief #threadpool mapper function for the limiter debugging check
*/
void space_check_limiter_mapper(void *map_data, int nr_parts,
void *extra_data) {
#ifdef SWIFT_DEBUG_CHECKS
/* Unpack the data */
struct part *restrict parts = (struct part *)map_data;
/* Verify that all limited particles have been treated */
for (int k = 0; k < nr_parts; k++) {
if (parts[k].wakeup == time_bin_awake) error("Particle still woken up!");
if (parts[k].gpart != NULL)
if (parts[k].time_bin != parts[k].gpart->time_bin)
error("Gpart not on the same time-bin as part");
}
#else
error("Calling debugging code without debugging flag activated.");
#endif
}
/**
* @brief Checks that all particles have their wakeup flag in a correct state.
*
* Should only be used for debugging purposes.
*
* @param s The #space to check.
*/
void space_check_limiter(struct space *s) {
#ifdef SWIFT_DEBUG_CHECKS
threadpool_map(&s->e->threadpool, space_check_limiter_mapper, s->parts,
s->nr_parts, sizeof(struct part), 1000, NULL);
#else
error("Calling debugging code without debugging flag activated.");
#endif
}
/**
* @brief Resets all the individual cell task counters to 0.
*
......
......@@ -317,6 +317,7 @@ void space_check_drift_point(struct space *s, integertime_t ti_drift,
void space_check_top_multipoles_drift_point(struct space *s,
integertime_t ti_drift);
void space_check_timesteps(struct space *s);
void space_check_limiter(struct space *s);
void space_replicate(struct space *s, int replicate, int verbose);
void space_generate_gas(struct space *s, const struct cosmology *cosmo,
int periodic, const double dim[3], int verbose);
......
......@@ -66,6 +66,7 @@ const char *taskID_names[task_type_count] = {"none",
"kick1",
"kick2",
"timestep",
"timestep_limiter",
"send",
"recv",
"grav_long_range",
......@@ -83,10 +84,10 @@ const char *taskID_names[task_type_count] = {"none",
/* Sub-task type names. */
const char *subtaskID_names[task_subtype_count] = {
"none", "density", "gradient", "force",
"grav", "external_grav", "tend", "xv",
"rho", "gpart", "multipole", "spart",
"stars_density", "stars_feedback"};
"none", "density", "gradient", "force",
"limiter", "grav", "external_grav", "tend",
"xv", "rho", "gpart", "multipole",
"spart", "stars_density", "stars_feedback"};
#ifdef WITH_MPI
/* MPI communicators for the subtypes. */
......@@ -140,6 +141,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
case task_type_sort:
case task_type_ghost:
case task_type_extra_ghost:
case task_type_timestep_limiter:
case task_type_cooling:
return task_action_part;
break;
......@@ -161,6 +163,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
case task_subtype_density:
case task_subtype_gradient:
case task_subtype_force:
case task_subtype_limiter:
return task_action_part;
break;
......@@ -337,6 +340,7 @@ void task_unlock(struct task *t) {
case task_type_drift_part:
case task_type_sort:
case task_type_timestep_limiter:
cell_unlocktree(ci);
break;
......@@ -462,6 +466,7 @@ int task_lock(struct task *t) {
case task_type_drift_part:
case task_type_sort:
case task_type_timestep_limiter:
if (ci->hydro.hold) return 0;
if (cell_locktree(ci) != 0) return 0;
break;
......
......@@ -58,6 +58,7 @@ enum task_types {
task_type_kick1,
task_type_kick2,
task_type_timestep,
task_type_timestep_limiter,
task_type_send,
task_type_recv,
task_type_grav_long_range,
......@@ -83,6 +84,7 @@ enum task_subtypes {
task_subtype_density,
task_subtype_gradient,
task_subtype_force,
task_subtype_limiter,
task_subtype_grav,
task_subtype_external_grav,
task_subtype_tend,
......
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#ifndef SWIFT_TIMESTEP_LIMITER_H
#define SWIFT_TIMESTEP_LIMITER_H
/* Config parameters. */
#include "../config.h"
/**
* @brief Wakes up a particle by rewinding it's kick1 back in time and applying
* a new one such that the particle becomes active again in the next time-step.
*
* @param p The #part to update.
* @param xp Its #xpart companion.
* @param e The #engine (to extract time-line information).
*/
__attribute__((always_inline)) INLINE static integertime_t timestep_limit_part(
struct part *restrict p, struct xpart *restrict xp,
const struct engine *e) {
const int with_cosmology = e->policy & engine_policy_cosmology;
const double time_base = e->time_base;
integertime_t old_ti_beg, old_ti_end;
timebin_t old_time_bin;
/* Let's see when this particle started and used to end */
if (p->wakeup == time_bin_awake) {
/* Normal case */
old_ti_beg = get_integer_time_begin(e->ti_current, p->time_bin);
old_ti_end = get_integer_time_end(e->ti_current, p->time_bin);
old_time_bin = p->time_bin;
} else {
/* Particle that was limited in the previous step already */
old_ti_beg = get_integer_time_begin(e->ti_current, -p->wakeup);
old_ti_end = get_integer_time_end(e->ti_current, p->time_bin);
old_time_bin = -p->wakeup;
}
const integertime_t old_dti = old_ti_end - old_ti_beg;
/* The new fake time-step the particle will be on */
const integertime_t new_fake_ti_step =
get_integer_timestep(e->min_active_bin);
/* The actual time-step size this particle will use */
const integertime_t new_ti_beg = old_ti_beg;
const integertime_t new_ti_end = e->ti_current + new_fake_ti_step;
const integertime_t new_dti = new_ti_end - new_ti_beg;
#ifdef SWIFT_DEBUG_CHECKS
/* Some basic safety checks */
if (old_ti_beg >= e->ti_current)
error(
"Incorrect value for old time-step beginning ti_current=%lld, "
"old_ti_beg=%lld",
e->ti_current, old_ti_beg);
if (old_ti_end <= e->ti_current)
error(
"Incorrect value for old time-step end ti_current=%lld, "
"old_ti_end=%lld",
e->ti_current, old_ti_end);