diff --git a/src/engine.c b/src/engine.c index 3a1c0bbe47779478ebc29dbcb400b9089d16936e..d1b1365323854f4d6e510472342edcb40db9c06b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -3401,62 +3401,145 @@ void engine_unskip(struct engine *e) { } /** - * @brief Mapper function to drift *all* particle types and multipoles forward - * in time. + * @brief Mapper function to drift *all* the #part to the current time. * * @param map_data An array of #cell%s. * @param num_elements Chunk size. * @param extra_data Pointer to an #engine. */ -void engine_do_drift_all_mapper(void *map_data, int num_elements, - void *extra_data) { +void engine_do_drift_all_part_mapper(void *map_data, int num_elements, + void *extra_data) { const struct engine *e = (const struct engine *)extra_data; const int restarting = e->restarting; struct space *s = e->s; struct cell *cells_top; - int *local_cells_with_tasks_top; + int *local_cells_top; if (restarting) { /* When restarting, we loop over all top-level cells */ cells_top = (struct cell *)map_data; - local_cells_with_tasks_top = NULL; + local_cells_top = NULL; } else { - /* In any other case, we use th list of local cells with tasks */ + /* In any other case, we use the list of local cells with tasks */ cells_top = s->cells_top; - local_cells_with_tasks_top = (int *)map_data; + local_cells_top = (int *)map_data; } for (int ind = 0; ind < num_elements; ind++) { struct cell *c; - /* When restarting, the list of local cells with tasks does not + /* When restarting, the list of local cells does not yet exist. We use the raw list of top-level cells instead */ if (restarting) c = &cells_top[ind]; else - c = &cells_top[local_cells_with_tasks_top[ind]]; + c = &cells_top[local_cells_top[ind]]; if (c->nodeID == e->nodeID) { /* Drift all the particles */ - cell_drift_part(c, e, 1); - - /* Drift all the g-particles */ - cell_drift_gpart(c, e, 1); + cell_drift_part(c, e, /* force the drift=*/1); } + } +} - /* Drift the multipoles */ - if (e->policy & engine_policy_self_gravity) { - cell_drift_all_multipoles(c, e); +/** + * @brief Mapper function to drift *all* the #gpart to the current time. + * + * @param map_data An array of #cell%s. + * @param num_elements Chunk size. + * @param extra_data Pointer to an #engine. + */ +void engine_do_drift_all_gpart_mapper(void *map_data, int num_elements, + void *extra_data) { + + const struct engine *e = (const struct engine *)extra_data; + const int restarting = e->restarting; + struct space *s = e->s; + struct cell *cells_top; + int *local_cells_top; + + if (restarting) { + + /* When restarting, we loop over all top-level cells */ + cells_top = (struct cell *)map_data; + local_cells_top = NULL; + + } else { + + /* In any other case, we use the list of local cells with tasks */ + cells_top = s->cells_top; + local_cells_top = (int *)map_data; + } + + for (int ind = 0; ind < num_elements; ind++) { + + struct cell *c; + + /* When restarting, the list of local cells does not + yet exist. We use the raw list of top-level cells instead */ + if (restarting) + c = &cells_top[ind]; + else + c = &cells_top[local_cells_top[ind]]; + + if (c->nodeID == e->nodeID) { + + /* Drift all the particles */ + cell_drift_gpart(c, e, /* force the drift=*/1); } } } +/** + * @brief Mapper function to drift *all* the multipoles to the current time. + * + * @param map_data An array of #cell%s. + * @param num_elements Chunk size. + * @param extra_data Pointer to an #engine. + */ +void engine_do_drift_all_multipole_mapper(void *map_data, int num_elements, + void *extra_data) { + + const struct engine *e = (const struct engine *)extra_data; + const int restarting = e->restarting; + struct space *s = e->s; + struct cell *cells_top; + int *local_cells_with_tasks_top; + + if (restarting) { + + /* When restarting, we loop over all top-level cells */ + cells_top = (struct cell *)map_data; + local_cells_with_tasks_top = NULL; + + } else { + + /* In any other case, we use the list of local cells with tasks */ + cells_top = s->cells_top; + local_cells_with_tasks_top = (int *)map_data; + } + + for (int ind = 0; ind < num_elements; ind++) { + + struct cell *c; + + /* When restarting, the list of local cells does not + yet exist. We use the raw list of top-level cells instead */ + if (restarting) + c = &cells_top[ind]; + else + c = &cells_top[local_cells_with_tasks_top[ind]]; + + cell_drift_all_multipoles(c, e); + } +} + /** * @brief Drift *all* particles and multipoles at all levels * forward to the current time. @@ -3481,15 +3564,44 @@ void engine_drift_all(struct engine *e) { if (!e->restarting) { /* Normal case: We have a list of local cells with tasks to play with */ - threadpool_map(&e->threadpool, engine_do_drift_all_mapper, - e->s->local_cells_with_tasks_top, - e->s->nr_local_cells_with_tasks, sizeof(int), 0, e); + + if (e->s->nr_parts > 0) { + threadpool_map(&e->threadpool, engine_do_drift_all_part_mapper, + e->s->local_cells_top, e->s->nr_local_cells, sizeof(int), + /* default chunk */ 0, e); + } + if (e->s->nr_gparts > 0) { + threadpool_map(&e->threadpool, engine_do_drift_all_gpart_mapper, + e->s->local_cells_top, e->s->nr_local_cells, sizeof(int), + /* default chunk */ 0, e); + } + if (e->policy & engine_policy_self_gravity) { + threadpool_map(&e->threadpool, engine_do_drift_all_multipole_mapper, + e->s->local_cells_with_tasks_top, + e->s->nr_local_cells_with_tasks, sizeof(int), + /* default chunk */ 0, e); + } + } else { /* When restarting, the list of local cells with tasks does not yet exist. We use the raw list of top-level cells instead */ - threadpool_map(&e->threadpool, engine_do_drift_all_mapper, e->s->cells_top, - e->s->nr_cells, sizeof(struct cell), 0, e); + + if (e->s->nr_parts > 0) { + threadpool_map(&e->threadpool, engine_do_drift_all_part_mapper, + e->s->cells_top, e->s->nr_cells, sizeof(struct cell), + /* default chunk */ 0, e); + } + if (e->s->nr_gparts > 0) { + threadpool_map(&e->threadpool, engine_do_drift_all_gpart_mapper, + e->s->cells_top, e->s->nr_cells, sizeof(struct cell), + /* default chunk */ 0, e); + } + if (e->policy & engine_policy_self_gravity) { + threadpool_map(&e->threadpool, engine_do_drift_all_multipole_mapper, + e->s->cells_top, e->s->nr_cells, sizeof(struct cell), + /* default chunk */ 0, e); + } } /* Synchronize particle positions */