Skip to content
Snippets Groups Projects
Commit b623db15 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Kick task now also updating the gparts (linked and stand-alone)

parent da47a754
No related branches found
No related tags found
1 merge request!135First implementation of gpart motion
...@@ -544,8 +544,8 @@ int main(int argc, char *argv[]) { ...@@ -544,8 +544,8 @@ int main(int argc, char *argv[]) {
/* Legend */ /* Legend */
if (myrank == 0) if (myrank == 0)
printf( printf(
"# Step Time time-step Number of updates CPU Wall-clock time " "# Step Time time-step Number of updates Number of updates "
"[%s]\n", "CPU Wall-clock time [%s]\n",
clocks_getunit()); clocks_getunit());
/* Let loose a runner on the space. */ /* Let loose a runner on the space. */
......
...@@ -141,7 +141,7 @@ struct cell { ...@@ -141,7 +141,7 @@ struct cell {
double mass, e_pot, e_int, e_kin; double mass, e_pot, e_int, e_kin;
/* Number of particles updated in this cell. */ /* Number of particles updated in this cell. */
int updated; int updated, g_updated;
/* Linking pointer for "memory management". */ /* Linking pointer for "memory management". */
struct cell *next; struct cell *next;
......
...@@ -1558,6 +1558,7 @@ int engine_marktasks(struct engine *e) { ...@@ -1558,6 +1558,7 @@ int engine_marktasks(struct engine *e) {
else if (t->type == task_type_kick) { else if (t->type == task_type_kick) {
t->skip = (t->ci->ti_end_min > ti_end); t->skip = (t->ci->ti_end_min > ti_end);
t->ci->updated = 0; t->ci->updated = 0;
t->ci->g_updated = 0;
} }
/* Drift? */ /* Drift? */
...@@ -1743,7 +1744,7 @@ void engine_collect_kick(struct cell *c) { ...@@ -1743,7 +1744,7 @@ void engine_collect_kick(struct cell *c) {
if (c->kick != NULL) return; if (c->kick != NULL) return;
/* Counters for the different quantities. */ /* Counters for the different quantities. */
int updated = 0; int updated = 0, g_updated = 0;
double e_kin = 0.0, e_int = 0.0, e_pot = 0.0; double e_kin = 0.0, e_int = 0.0, e_pot = 0.0;
float mom[3] = {0.0f, 0.0f, 0.0f}, ang[3] = {0.0f, 0.0f, 0.0f}; float mom[3] = {0.0f, 0.0f, 0.0f}, ang[3] = {0.0f, 0.0f, 0.0f};
int ti_end_min = max_nr_timesteps, ti_end_max = 0; int ti_end_min = max_nr_timesteps, ti_end_max = 0;
...@@ -1766,6 +1767,7 @@ void engine_collect_kick(struct cell *c) { ...@@ -1766,6 +1767,7 @@ void engine_collect_kick(struct cell *c) {
ti_end_min = min(ti_end_min, cp->ti_end_min); ti_end_min = min(ti_end_min, cp->ti_end_min);
ti_end_max = max(ti_end_max, cp->ti_end_max); ti_end_max = max(ti_end_max, cp->ti_end_max);
updated += cp->updated; updated += cp->updated;
g_updated += cp->g_updated;
e_kin += cp->e_kin; e_kin += cp->e_kin;
e_int += cp->e_int; e_int += cp->e_int;
e_pot += cp->e_pot; e_pot += cp->e_pot;
...@@ -1783,6 +1785,7 @@ void engine_collect_kick(struct cell *c) { ...@@ -1783,6 +1785,7 @@ void engine_collect_kick(struct cell *c) {
c->ti_end_min = ti_end_min; c->ti_end_min = ti_end_min;
c->ti_end_max = ti_end_max; c->ti_end_max = ti_end_max;
c->updated = updated; c->updated = updated;
c->g_updated = g_updated;
c->e_kin = e_kin; c->e_kin = e_kin;
c->e_int = e_int; c->e_int = e_int;
c->e_pot = e_pot; c->e_pot = e_pot;
...@@ -1928,7 +1931,7 @@ void engine_init_particles(struct engine *e) { ...@@ -1928,7 +1931,7 @@ void engine_init_particles(struct engine *e) {
*/ */
void engine_step(struct engine *e) { void engine_step(struct engine *e) {
int updates = 0; int updates = 0, g_updates = 0;
int ti_end_min = max_nr_timesteps, ti_end_max = 0; int ti_end_min = max_nr_timesteps, ti_end_max = 0;
double e_pot = 0.0, e_int = 0.0, e_kin = 0.0; double e_pot = 0.0, e_int = 0.0, e_kin = 0.0;
float mom[3] = {0.0, 0.0, 0.0}; float mom[3] = {0.0, 0.0, 0.0};
...@@ -1955,6 +1958,7 @@ void engine_step(struct engine *e) { ...@@ -1955,6 +1958,7 @@ void engine_step(struct engine *e) {
e_int += c->e_int; e_int += c->e_int;
e_pot += c->e_pot; e_pot += c->e_pot;
updates += c->updated; updates += c->updated;
g_updates += c->g_updated;
mom[0] += c->mom[0]; mom[0] += c->mom[0];
mom[1] += c->mom[1]; mom[1] += c->mom[1];
mom[2] += c->mom[2]; mom[2] += c->mom[2];
...@@ -1980,18 +1984,20 @@ void engine_step(struct engine *e) { ...@@ -1980,18 +1984,20 @@ void engine_step(struct engine *e) {
ti_end_max = in_i[0]; ti_end_max = in_i[0];
} }
{ {
double in_d[4], out_d[4]; double in_d[5], out_d[5];
out_d[0] = updates; out_d[0] = updates;
out_d[1] = e_kin; out_d[1] = g_updates;
out_d[2] = e_int; out_d[2] = e_kin;
out_d[3] = e_pot; out_d[3] = e_int;
if (MPI_Allreduce(out_d, in_d, 4, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) != out_d[4] = e_pot;
if (MPI_Allreduce(out_d, in_d, 5, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) !=
MPI_SUCCESS) MPI_SUCCESS)
error("Failed to aggregate energies."); error("Failed to aggregate energies.");
updates = in_d[0]; updates = in_d[0];
e_kin = in_d[1]; g_updates = in_d[1];
e_int = in_d[2]; e_kin = in_d[2];
e_pot = in_d[3]; e_int = in_d[3];
e_pot = in_d[4];
} }
#endif #endif
...@@ -2016,8 +2022,8 @@ void engine_step(struct engine *e) { ...@@ -2016,8 +2022,8 @@ void engine_step(struct engine *e) {
if (e->nodeID == 0) { if (e->nodeID == 0) {
/* Print some information to the screen */ /* Print some information to the screen */
printf("%d %e %e %d %.3f\n", e->step, e->time, e->timeStep, updates, printf("%d %e %e %d %d %.3f\n", e->step, e->time, e->timeStep, updates,
e->wallclock_time); g_updates, e->wallclock_time);
fflush(stdout); fflush(stdout);
/* Write some energy statistics */ /* Write some energy statistics */
......
...@@ -27,14 +27,13 @@ ...@@ -27,14 +27,13 @@
* *
*/ */
__attribute__((always_inline)) INLINE static float gravity_compute_timestep( __attribute__((always_inline))
struct part* p, struct xpart* xp) { INLINE static float gravity_compute_timestep(struct gpart* gp) {
/* Currently no limit is imposed */ /* Currently no limit is imposed */
return FLT_MAX; return FLT_MAX;
} }
/** /**
* @brief Initialises the g-particles for the first time * @brief Initialises the g-particles for the first time
* *
...@@ -44,8 +43,7 @@ __attribute__((always_inline)) INLINE static float gravity_compute_timestep( ...@@ -44,8 +43,7 @@ __attribute__((always_inline)) INLINE static float gravity_compute_timestep(
* @param gp The particle to act upon * @param gp The particle to act upon
*/ */
__attribute__((always_inline)) __attribute__((always_inline))
INLINE static void gravity_first_init_gpart(struct gpart* gp) { INLINE static void gravity_first_init_gpart(struct gpart* gp) {}
}
/** /**
* @brief Prepares a g-particle for the gravity calculation * @brief Prepares a g-particle for the gravity calculation
...@@ -63,3 +61,23 @@ __attribute__((always_inline)) ...@@ -63,3 +61,23 @@ __attribute__((always_inline))
gp->a_grav[1] = 0.f; gp->a_grav[1] = 0.f;
gp->a_grav[2] = 0.f; gp->a_grav[2] = 0.f;
} }
/**
* @brief Finishes the gravity calculation.
*
* Multiplies the forces and accelerations by the appropiate constants
*
* @param gp The particle to act upon
*/
__attribute__((always_inline))
INLINE static void gravity_end_force(struct gpart* gp) {}
/**
* @brief Kick the additional variables
*
* @param gp The particle to act upon
* @param dt The time-step for this kick
* @param half_dt The half time-step for this kick
*/
__attribute__((always_inline)) INLINE static void gravity_kick_extra(
struct gpart* gp, float dt, float half_dt) {}
...@@ -788,27 +788,91 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -788,27 +788,91 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
const double timeBase = r->e->timeBase; const double timeBase = r->e->timeBase;
const double timeBase_inv = 1.0 / r->e->timeBase; const double timeBase_inv = 1.0 / r->e->timeBase;
const int count = c->count; const int count = c->count;
// const int gcount = c->gcount; const int gcount = c->gcount;
struct part *const parts = c->parts;
struct xpart *const xparts = c->xparts;
struct gpart *const gparts = c->gparts;
const int is_fixdt = const int is_fixdt =
(r->e->policy & engine_policy_fixdt) == engine_policy_fixdt; (r->e->policy & engine_policy_fixdt) == engine_policy_fixdt;
int new_dti; int updated = 0, g_updated = 0;
int dti_timeline;
int updated = 0;
int ti_end_min = max_nr_timesteps, ti_end_max = 0; int ti_end_min = max_nr_timesteps, ti_end_max = 0;
double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0; double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0;
float mom[3] = {0.0f, 0.0f, 0.0f}; float mom[3] = {0.0f, 0.0f, 0.0f};
float ang[3] = {0.0f, 0.0f, 0.0f}; float ang[3] = {0.0f, 0.0f, 0.0f};
struct part *const parts = c->parts;
struct xpart *const xparts = c->xparts;
// struct gpart *const gparts = c->gparts;
TIMER_TIC TIMER_TIC
/* No children? */ /* No children? */
if (!c->split) { if (!c->split) {
/* Loop over the g-particles and kick the active ones. */
for (int k = 0; k < gcount; k++) {
/* Get a handle on the part. */
struct gpart *const gp = &gparts[k];
/* If the g-particle has no counterpart and needs to be kicked */
if (gp->id < 0 && (is_fixdt || gp->ti_end <= ti_current)) {
/* First, finish the force calculation */
gravity_end_force(gp);
/* Now we are ready to compute the next time-step size */
int new_dti;
if (is_fixdt) {
/* Now we have a time step, proceed with the kick */
new_dti = global_dt_max * timeBase_inv;
} else {
/* Compute the next timestep (gravity condition) */
float new_dt = gravity_compute_timestep(gp);
/* Limit timestep within the allowed range */
new_dt = fminf(new_dt, global_dt_max);
new_dt = fmaxf(new_dt, global_dt_min);
/* Convert to integer time */
new_dti = new_dt * timeBase_inv;
/* Recover the current timestep */
const int current_dti = gp->ti_end - gp->ti_begin;
/* Limit timestep increase */
if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti);
/* Put this timestep on the time line */
int dti_timeline = max_nr_timesteps;
while (new_dti < dti_timeline) dti_timeline /= 2;
/* Now we have a time step, proceed with the kick */
new_dti = dti_timeline;
}
/* Compute the time step for this kick */
const int ti_start = (gp->ti_begin + gp->ti_end) / 2;
const int ti_end = gp->ti_end + new_dti / 2;
const double dt = (ti_end - ti_start) * timeBase;
const double half_dt = (ti_end - gp->ti_end) * timeBase;
/* Kick particles in momentum space */
gp->v_full[0] += gp->a_grav[0] * dt;
gp->v_full[1] += gp->a_grav[1] * dt;
gp->v_full[2] += gp->a_grav[2] * dt;
/* Extra kick work */
gravity_kick_extra(gp, dt, half_dt);
/* Number of updated g-particles */
g_updated++;
}
}
/* Now do the hydro ones... */
/* Loop over the particles and kick the active ones. */ /* Loop over the particles and kick the active ones. */
for (int k = 0; k < count; k++) { for (int k = 0; k < count; k++) {
...@@ -824,8 +888,10 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -824,8 +888,10 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
/* And do the same of the extra variable */ /* And do the same of the extra variable */
hydro_end_force(p); hydro_end_force(p);
if (p->gpart != NULL) gravity_end_force(p->gpart);
/* Now we are ready to compute the next time-step size */ /* Now we are ready to compute the next time-step size */
int new_dti;
if (is_fixdt) { if (is_fixdt) {
...@@ -834,9 +900,13 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -834,9 +900,13 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
} else { } else {
/* Compute the next timestep */ /* Compute the next timestep (hydro condition) */
const float new_dt_hydro = hydro_compute_timestep(p, xp); const float new_dt_hydro = hydro_compute_timestep(p, xp);
const float new_dt_grav = gravity_compute_timestep(p, xp);
/* Compute the next timestep (gravity condition) */
float new_dt_grav = FLT_MAX;
if (p->gpart != NULL)
new_dt_grav = gravity_compute_timestep(p->gpart);
float new_dt = fminf(new_dt_hydro, new_dt_grav); float new_dt = fminf(new_dt_hydro, new_dt_grav);
...@@ -861,7 +931,7 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -861,7 +931,7 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti); if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti);
/* Put this timestep on the time line */ /* Put this timestep on the time line */
dti_timeline = max_nr_timesteps; int dti_timeline = max_nr_timesteps;
while (new_dti < dti_timeline) dti_timeline /= 2; while (new_dti < dti_timeline) dti_timeline /= 2;
/* Now we have a time step, proceed with the kick */ /* Now we have a time step, proceed with the kick */
...@@ -871,28 +941,38 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -871,28 +941,38 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
/* Compute the time step for this kick */ /* Compute the time step for this kick */
const int ti_start = (p->ti_begin + p->ti_end) / 2; const int ti_start = (p->ti_begin + p->ti_end) / 2;
const int ti_end = p->ti_end + new_dti / 2; const int ti_end = p->ti_end + new_dti / 2;
const float dt = (ti_end - ti_start) * timeBase; const double dt = (ti_end - ti_start) * timeBase;
const float half_dt = (ti_end - p->ti_end) * timeBase; const double half_dt = (ti_end - p->ti_end) * timeBase;
/* Move particle forward in time */ /* Move particle forward in time */
p->ti_begin = p->ti_end; p->ti_begin = p->ti_end;
p->ti_end = p->ti_begin + new_dti; p->ti_end = p->ti_begin + new_dti;
/* Get the acceleration */
float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]};
if (p->gpart != NULL) {
a_tot[0] += p->gpart->a_grav[0];
a_tot[1] += p->gpart->a_grav[1];
a_tot[1] += p->gpart->a_grav[2];
}
/* Kick particles in momentum space */ /* Kick particles in momentum space */
xp->v_full[0] += p->a_hydro[0] * dt; xp->v_full[0] += a_tot[0] * dt;
xp->v_full[1] += p->a_hydro[1] * dt; xp->v_full[1] += a_tot[1] * dt;
xp->v_full[2] += p->a_hydro[2] * dt; xp->v_full[2] += a_tot[2] * dt;
/* Go back by half-step for the hydro velocity */ /* Go back by half-step for the hydro velocity */
p->v[0] = xp->v_full[0] - half_dt * p->a_hydro[0]; p->v[0] = xp->v_full[0] - half_dt * a_tot[0];
p->v[1] = xp->v_full[1] - half_dt * p->a_hydro[1]; p->v[1] = xp->v_full[1] - half_dt * a_tot[1];
p->v[2] = xp->v_full[2] - half_dt * p->a_hydro[2]; p->v[2] = xp->v_full[2] - half_dt * a_tot[2];
/* Extra kick work */ /* Extra kick work */
hydro_kick_extra(p, xp, dt, half_dt); hydro_kick_extra(p, xp, dt, half_dt);
if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt, half_dt);
/* Number of updated particles */ /* Number of updated particles */
updated++; updated++;
if (p->gpart != NULL) g_updated++;
} }
/* Now collect quantities for statistics */ /* Now collect quantities for statistics */
...@@ -940,6 +1020,7 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -940,6 +1020,7 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
/* And aggregate */ /* And aggregate */
updated += cp->updated; updated += cp->updated;
g_updated += cp->g_updated;
e_kin += cp->e_kin; e_kin += cp->e_kin;
e_int += cp->e_int; e_int += cp->e_int;
e_pot += cp->e_pot; e_pot += cp->e_pot;
...@@ -957,6 +1038,7 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) { ...@@ -957,6 +1038,7 @@ void runner_dokick(struct runner *r, struct cell *c, int timer) {
/* Store the values. */ /* Store the values. */
c->updated = updated; c->updated = updated;
c->g_updated = g_updated;
c->e_kin = e_kin; c->e_kin = e_kin;
c->e_int = e_int; c->e_int = e_int;
c->e_pot = e_pot; c->e_pot = e_pot;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment