From 17157f90083538ef71d1ac34723f64d983db37a5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller <matthieu.schaller@durham.ac.uk> Date: Sat, 25 Feb 2017 14:08:02 +0000 Subject: [PATCH] Drift multipoles independently of the g-particles. --- src/cell.c | 37 ++++++++++++++++++++++++++++++++++++- src/cell.h | 6 +++++- src/engine.c | 2 +- src/multipole.h | 14 ++++++++++++++ src/runner.c | 12 +++++++++--- src/runner.h | 3 ++- src/space.c | 3 +++ 7 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/cell.c b/src/cell.c index c5f414817e..734b855851 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1326,7 +1326,7 @@ void cell_set_super(struct cell *c, struct cell *super) { } /** - * @brief Recursively drifts all particles and g-particles in a cell hierarchy. + * @brief Recursively drifts particles of all kinds in a cell hierarchy. * * @param c The #cell. * @param e The #engine (to get ti_current). @@ -1430,6 +1430,41 @@ void cell_drift_particles(struct cell *c, const struct engine *e) { c->ti_old = ti_current; } +/** + * @brief Recursively drifts all multipoles in a cell hierarchy. + * + * @param c The #cell. + * @param e The #engine (to get ti_current). + */ +void cell_drift_multipole(struct cell *c, const struct engine *e) { + + const double timeBase = e->timeBase; + const integertime_t ti_old_multipole = c->ti_old_multipole; + const integertime_t ti_current = e->ti_current; + + /* Drift from the last time the cell was drifted to the current time */ + const double dt = (ti_current - ti_old_multipole) * timeBase; + + /* Check that we are actually going to move forward. */ + if (ti_current < ti_old_multipole) error("Attempt to drift to the past"); + + /* Are we not in a leaf ? */ + if (c->split) { + + /* Loop over the progeny and drift the multipoles. */ + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) cell_drift_particles(c->progeny[k], e); + + } else if (ti_current > ti_old_multipole) { + + /* Drift the multipole */ + multipole_drift(c->multipole, dt); + } + + /* Update the time of the last drift */ + c->ti_old_multipole = ti_current; +} + /** * @brief Recursively checks that all particles in a cell have a time-step */ diff --git a/src/cell.h b/src/cell.h index 6c90f38c51..dc0e8886e0 100644 --- a/src/cell.h +++ b/src/cell.h @@ -230,9 +230,12 @@ struct cell { /*! Maximum beginning of (integer) time step in this cell. */ integertime_t ti_beg_max; - /*! Last (integer) time the cell's content was drifted forward in time. */ + /*! Last (integer) time the cell's particle was drifted forward in time. */ integertime_t ti_old; + /*! Last (integer) time the cell's multipole was drifted forward in time. */ + integertime_t ti_old_multipole; + /*! Minimum dimension, i.e. smallest edge of this cell (min(width)). */ float dmin; @@ -343,6 +346,7 @@ int cell_is_drift_needed(struct cell *c, const struct engine *e); int cell_unskip_tasks(struct cell *c, struct scheduler *s); void cell_set_super(struct cell *c, struct cell *super); void cell_drift_particles(struct cell *c, const struct engine *e); +void cell_drift_multipole(struct cell *c, const struct engine *e); void cell_check_timesteps(struct cell *c); #endif /* SWIFT_CELL_H */ diff --git a/src/engine.c b/src/engine.c index e46d0598f8..deae35f865 100644 --- a/src/engine.c +++ b/src/engine.c @@ -3144,7 +3144,7 @@ void engine_unskip(struct engine *e) { void engine_drift_all(struct engine *e) { const ticks tic = getticks(); - threadpool_map(&e->threadpool, runner_do_drift_mapper, e->s->cells_top, + threadpool_map(&e->threadpool, runner_do_drift_all_mapper, e->s->cells_top, e->s->nr_cells, sizeof(struct cell), 1, e); #ifdef SWIFT_DEBUG_CHECKS diff --git a/src/multipole.h b/src/multipole.h index 69195f8ec7..9521bd51db 100644 --- a/src/multipole.h +++ b/src/multipole.h @@ -185,6 +185,20 @@ INLINE static int multipole_equal(const struct multipole *ma, return 1; } +/** + * @brief Drifts a #multipole forward in time. + * + * @param m The #multipole. + * @param dt The drift time-step. + */ +INLINE static void multipole_drift(struct multipole *m, double dt) { + + /* Move the whole thing according to bulk motion */ + m->CoM[0] += m->vel[0]; + m->CoM[1] += m->vel[1]; + m->CoM[2] += m->vel[2]; +} + /** * @brief Applies the forces due to particles j onto particles i directly. * diff --git a/src/runner.c b/src/runner.c index 6f2f32c1f5..ff78e5d679 100644 --- a/src/runner.c +++ b/src/runner.c @@ -826,15 +826,21 @@ void runner_do_drift_particles(struct runner *r, struct cell *c, int timer) { * @param num_elements Chunk size. * @param extra_data Pointer to an #engine. */ -void runner_do_drift_mapper(void *map_data, int num_elements, - void *extra_data) { +void runner_do_drift_all_mapper(void *map_data, int num_elements, + void *extra_data) { struct engine *e = (struct engine *)extra_data; struct cell *cells = (struct cell *)map_data; for (int ind = 0; ind < num_elements; ind++) { struct cell *c = &cells[ind]; - if (c != NULL && c->nodeID == e->nodeID) cell_drift_particles(c, e); + if (c != NULL && c->nodeID == e->nodeID) { + /* Drift all the particles */ + cell_drift_particles(c, e); + + /* Drift the multipole */ + if (e->policy & engine_policy_self_gravity) cell_drift_multipole(c, e); + } } } diff --git a/src/runner.h b/src/runner.h index 49ad5c9835..ec63eb3ec9 100644 --- a/src/runner.h +++ b/src/runner.h @@ -66,6 +66,7 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer); void *runner_main(void *data); void runner_do_unskip_mapper(void *map_data, int num_elements, void *extra_data); -void runner_do_drift_mapper(void *map_data, int num_elements, void *extra_data); +void runner_do_drift_all_mapper(void *map_data, int num_elements, + void *extra_data); #endif /* SWIFT_RUNNER_H */ diff --git a/src/space.c b/src/space.c index 180b08c8f3..39a2ddbcd6 100644 --- a/src/space.c +++ b/src/space.c @@ -441,6 +441,7 @@ void space_regrid(struct space *s, int verbose) { c->scount = 0; c->super = c; c->ti_old = ti_old; + c->ti_old_multipole = ti_old; if (s->gravity) c->multipole = &s->multipoles_top[cid]; } @@ -922,6 +923,7 @@ void space_rebuild(struct space *s, int verbose) { for (int k = 0; k < s->nr_cells; k++) { struct cell *restrict c = &cells_top[k]; c->ti_old = ti_old; + c->ti_old_multipole = ti_old; c->parts = finger; c->xparts = xfinger; c->gparts = gfinger; @@ -2030,6 +2032,7 @@ void space_split_recursive(struct space *s, struct cell *c, cp->gcount = 0; cp->scount = 0; cp->ti_old = c->ti_old; + cp->ti_old_multipole = c->ti_old_multipole; cp->loc[0] = c->loc[0]; cp->loc[1] = c->loc[1]; cp->loc[2] = c->loc[2]; -- GitLab