/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2018 Matthieu Schaller (schaller@strw.leidenuniv.nl)
*
* 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 .
*
******************************************************************************/
#ifndef SWIFT_TIMESTEP_SYNC_H
#define SWIFT_TIMESTEP_SYNC_H
/* Config parameters. */
#include
/* Local includes */
#include "engine.h"
#include "kick.h"
/**
* @brief Processes a particle that has been flagged for synchronization on the
* time-line.
*
* We revert the particle's kick and apply a new one that ends at the current
* time. The particle is then ready to compute a new time-step and proceed with
* a regular kick1.
*
* @param p The #part.
* @param xp The #xpart.
* @param e The #engine.
* @param cosmo The cosmology model.
*/
INLINE static void timestep_process_sync_part(struct part *p, struct xpart *xp,
const struct engine *e,
const struct cosmology *cosmo) {
const int with_cosmology = (e->policy & engine_policy_cosmology);
const integertime_t ti_current = e->ti_current;
const timebin_t max_active_bin = e->max_active_bin;
const timebin_t min_active_bin = e->min_active_bin;
const double time_base = e->time_base;
p->limiter_data.to_be_synchronized = 0;
/* This particle is already active. Nothing to do here... */
if (p->time_bin <= max_active_bin) {
return;
}
/* We want to make the particle finish it's time-step now. */
/* Start by recovering the start and end point of the particle's time-step. */
const integertime_t old_ti_beg =
get_integer_time_begin(ti_current, p->time_bin);
const integertime_t old_ti_end =
get_integer_time_end(ti_current, p->time_bin);
/* Old time-step length on the time-line */
const integertime_t old_dti = old_ti_end - old_ti_beg;
const integertime_t ti_end_half_old = old_ti_beg + old_dti / 2;
/* The actual time-step size this particle will use */
const integertime_t new_ti_beg = old_ti_beg;
const integertime_t new_ti_end = ti_current;
#ifdef SWIFT_DEBUG_CHECKS
const integertime_t new_dti = new_ti_end - new_ti_beg;
/* Some basic safety checks */
if (old_ti_beg >= ti_current)
error(
"Incorrect value for old time-step beginning ti_current=%lld, "
"old_ti_beg=%lld",
ti_current, old_ti_beg);
if (old_ti_end <= ti_current)
error(
"Incorrect value for old time-step end ti_current=%lld, "
"old_ti_end=%lld",
ti_current, old_ti_end);
if (new_ti_end > old_ti_end) error("New end of time-step after the old one");
if (new_dti > old_dti) error("New time-step larger than old one");
#endif
double dt_kick_grav = 0., dt_kick_hydro = 0., dt_kick_therm = 0.,
dt_kick_corr = 0.;
/* Now we need to reverse the kick1...
* Note the minus sign! (the dt are negative here) */
dt_kick_hydro = -kick_get_hydro_kick_dt(old_ti_beg, ti_end_half_old,
time_base, with_cosmology, cosmo);
dt_kick_grav = -kick_get_grav_kick_dt(old_ti_beg, ti_end_half_old, time_base,
with_cosmology, cosmo);
dt_kick_therm = -kick_get_therm_kick_dt(old_ti_beg, ti_end_half_old,
time_base, with_cosmology, cosmo);
dt_kick_corr = -kick_get_corr_kick_dt(old_ti_beg, ti_end_half_old, time_base,
with_cosmology, cosmo);
/* Note that there is no need to change the mesh integration as we
* can't go back more than one global step */
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0.,
dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties,
e->entropy_floor, ti_end_half_old, old_ti_beg,
/*ti_start_mesh=*/-1, /*ti_end_mesh=*/-1);
/* We can now produce a kick to the current point */
dt_kick_hydro = kick_get_hydro_kick_dt(new_ti_beg, new_ti_end, time_base,
with_cosmology, cosmo);
dt_kick_grav = kick_get_grav_kick_dt(new_ti_beg, new_ti_end, time_base,
with_cosmology, cosmo);
dt_kick_therm = kick_get_therm_kick_dt(new_ti_beg, new_ti_end, time_base,
with_cosmology, cosmo);
dt_kick_corr = kick_get_corr_kick_dt(new_ti_beg, new_ti_end, time_base,
with_cosmology, cosmo);
/* Note that there is no need to change the mesh integration as we
* can't go back more than one global step */
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0.,
dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties,
e->entropy_floor, new_ti_beg, new_ti_end,
/*ti_start_mesh=*/-1, /*ti_end_mesh=*/-1);
/* The particle is now ready to compute its new time-step size and for the
* next kick */
p->time_bin = -min_active_bin;
/* do not touch the limiter flag, as we might still need to limit the time
step of this particle (if the new time step is still too large) */
}
#endif /* SWIFT_TIMESTEP_SYNC_H */