diff --git a/src/cell.c b/src/cell.c index 4502f5d265dc68540e16ed0e51e681cf5733f842..f85e4dbd2a71033b10852bc65a97b8eec6bf75f9 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1328,7 +1328,7 @@ void cell_clear_drift_flags(struct cell *c, void *data) { } /** - * @brief Activate the drifts on the given cell. + * @brief Activate the #part drifts on the given cell. */ void cell_activate_drift_part(struct cell *c, struct scheduler *s) { @@ -1354,6 +1354,14 @@ void cell_activate_drift_part(struct cell *c, struct scheduler *s) { } } +/** + * @brief Activate the #gpart drifts on the given cell. + */ +void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) { + + scheduler_activate(s, c->super->drift_gpart); +} + /** * @brief Activate the sorts up a cell hierarchy. */ @@ -1843,6 +1851,25 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { } } + /* Un-skip the gravity tasks involved with this cell. */ + for (struct link *l = c->grav; l != NULL; l = l->next) { + struct task *t = l->t; + struct cell *ci = t->ci; + struct cell *cj = t->cj; + + /* Only activate tasks that involve a local active cell. */ + if ((cell_is_active(ci, e) && ci->nodeID == engine_rank) || + (cj != NULL && cell_is_active(cj, e) && cj->nodeID == engine_rank)) { + scheduler_activate(s, t); + + /* Set the drifting flags */ + if (t->type == task_type_pair) { + cell_activate_drift_gpart(ci, s); + cell_activate_drift_gpart(cj, s); + } + } + } + /* Unskip all the other task types. */ if (c->nodeID == engine_rank && cell_is_active(c, e)) { @@ -1850,15 +1877,12 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { scheduler_activate(s, l->t); for (struct link *l = c->force; l != NULL; l = l->next) scheduler_activate(s, l->t); - for (struct link *l = c->grav; l != NULL; l = l->next) - scheduler_activate(s, l->t); if (c->extra_ghost != NULL) scheduler_activate(s, c->extra_ghost); if (c->ghost_in != NULL) scheduler_activate(s, c->ghost_in); if (c->ghost_out != NULL) scheduler_activate(s, c->ghost_out); if (c->ghost != NULL) scheduler_activate(s, c->ghost); if (c->init_grav != NULL) scheduler_activate(s, c->init_grav); - if (c->drift_gpart != NULL) scheduler_activate(s, c->drift_gpart); if (c->kick1 != NULL) scheduler_activate(s, c->kick1); if (c->kick2 != NULL) scheduler_activate(s, c->kick2); if (c->timestep != NULL) scheduler_activate(s, c->timestep); diff --git a/src/cell.h b/src/cell.h index e97400623dbb7a66aee981d21883fe4d8f73406a..82cda87444e60fde9eb4b9a6914c2ed1ba3a470d 100644 --- a/src/cell.h +++ b/src/cell.h @@ -402,6 +402,7 @@ void cell_store_pre_drift_values(struct cell *c); void cell_activate_subcell_tasks(struct cell *ci, struct cell *cj, struct scheduler *s); void cell_activate_drift_part(struct cell *c, struct scheduler *s); +void cell_activate_drift_gpart(struct cell *c, struct scheduler *s); void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s); void cell_clear_drift_flags(struct cell *c, void *data); void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data); diff --git a/src/engine.c b/src/engine.c index 5cade0e2b25c1354df5d61a5a3662054a4475f70..5ed61430c47cbdd2030fd0b53473aca519cebb3e 100644 --- a/src/engine.c +++ b/src/engine.c @@ -156,6 +156,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { const int periodic = e->s->periodic; const int is_with_hydro = (e->policy & engine_policy_hydro); const int is_self_gravity = (e->policy & engine_policy_self_gravity); + const int is_external_gravity = (e->policy & engine_policy_external_gravity); const int is_with_cooling = (e->policy & engine_policy_cooling); const int is_with_sourceterms = (e->policy & engine_policy_sourceterms); @@ -171,11 +172,15 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { /* Local tasks only... */ if (c->nodeID == e->nodeID) { - /* Add the drift task. */ + /* Add the drift tasks corresponding to the policy. */ if (is_with_hydro) { c->drift_part = scheduler_addtask(s, task_type_drift_part, task_subtype_none, 0, 0, c, NULL); } + if (is_self_gravity || is_external_gravity) { + c->drift_gpart = scheduler_addtask(s, task_type_drift_gpart, + task_subtype_none, 0, 0, c, NULL); + } /* Add the two half kicks */ c->kick1 = scheduler_addtask(s, task_type_kick1, task_subtype_none, 0, 0, @@ -191,6 +196,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { scheduler_addunlock(s, c->kick2, c->timestep); scheduler_addunlock(s, c->timestep, c->kick1); + /* Add the gravity tasks */ if (is_self_gravity) { /* Initialisation of the multipoles */ @@ -220,14 +226,13 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, /* implicit = */ 1, c, NULL); engine_add_ghosts(e, c, c->ghost_in, c->ghost_out); - } +/* Generate the extra ghost task. */ #ifdef EXTRA_HYDRO_LOOP - /* Generate the extra ghost task. */ - if (is_hydro) c->extra_ghost = scheduler_addtask(s, task_type_extra_ghost, task_subtype_none, 0, 0, c, NULL); #endif + } /* Cooling task */ if (is_with_cooling) { @@ -1840,11 +1845,9 @@ void engine_make_self_gravity_tasks(struct engine *e) { /* Make the ghosts implicit and add the dependencies */ for (int n = 0; n < n_ghosts / 2; ++n) { ghosts[2 * n + 0] = scheduler_addtask( - sched, task_type_grav_ghost, task_subtype_none, 0, 0, NULL, NULL); + sched, task_type_grav_ghost, task_subtype_none, 0, 1, NULL, NULL); ghosts[2 * n + 1] = scheduler_addtask( - sched, task_type_grav_ghost, task_subtype_none, 0, 0, NULL, NULL); - ghosts[2 * n + 0]->implicit = 1; - ghosts[2 * n + 1]->implicit = 1; + sched, task_type_grav_ghost, task_subtype_none, 0, 1, NULL, NULL); scheduler_addunlock(sched, ghosts[2 * n + 0], s->grav_top_level); scheduler_addunlock(sched, s->grav_top_level, ghosts[2 * n + 1]); } @@ -2064,6 +2067,7 @@ static inline void engine_make_self_gravity_dependencies( struct scheduler *sched, struct task *gravity, struct cell *c) { /* init --> gravity --> grav_down --> kick */ + scheduler_addunlock(sched, c->super->drift_gpart, gravity); scheduler_addunlock(sched, c->super->init_grav, gravity); scheduler_addunlock(sched, gravity, c->super->grav_down); } diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 01ea6a073211a08430e77721f4c2e60ef7adfd04..d018ec8839036eaba5e7b581e4a2b990186cb673 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -78,6 +78,8 @@ void runner_do_grav_down(struct runner *r, struct cell *c, int timer) { } else { /* Leaf case */ + if (!cell_are_gpart_drifted(c, e)) error("Un-drifted gparts"); + /* Apply accelerations to the particles */ for (int i = 0; i < gcount; ++i) { @@ -880,8 +882,8 @@ void runner_dopair_grav_pp(struct runner *r, struct cell *ci, struct cell *cj) { if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) return; /* Let's start by drifting things */ - if (!cell_are_gpart_drifted(ci, e)) cell_drift_gpart(ci, e); - if (!cell_are_gpart_drifted(cj, e)) cell_drift_gpart(cj, e); + if (!cell_are_gpart_drifted(ci, e)) error("Un-drifted gparts"); + if (!cell_are_gpart_drifted(cj, e)) error("Un-drifted gparts"); /* Can we use the Newtonian version or do we need the truncated one ? */ if (!periodic) { @@ -1365,7 +1367,7 @@ void runner_doself_grav_pp(struct runner *r, struct cell *c) { if (!cell_is_active(c, e)) return; /* Do we need to start by drifting things ? */ - if (!cell_are_gpart_drifted(c, e)) cell_drift_gpart(c, e); + if (!cell_are_gpart_drifted(c, e)) error("Un-drifted gparts"); /* Can we use the Newtonian version or do we need the truncated one ? */ if (!periodic) { diff --git a/src/scheduler.c b/src/scheduler.c index 4081cde0489b1b439ceb46fc9b4e191541f15bef..fccad7eb54890f4ec585ed98aa74d9508ff88d59 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -649,18 +649,8 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) { ci->progeny[k]), s); } - } - - /* Otherwise, make sure the self task has a drift task */ - else { - - lock_lock(&ci->lock); + } /* Cell is split */ - if (ci->drift_gpart == NULL) - ci->drift_gpart = scheduler_addtask( - s, task_type_drift_gpart, task_subtype_none, 0, 0, ci, NULL); - lock_unlock_blind(&ci->lock); - } } /* Self interaction */ /* Pair interaction? */ @@ -675,28 +665,6 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) { t->skip = 1; break; } - - /* Should this task be split-up? */ - if (0 && ci->split && cj->split) { - - // MATTHIEU: nothing here for now - - } else { - - /* Create the drift for ci. */ - lock_lock(&ci->lock); - if (ci->drift_gpart == NULL && ci->nodeID == engine_rank) - ci->drift_gpart = scheduler_addtask( - s, task_type_drift_gpart, task_subtype_none, 0, 0, ci, NULL); - lock_unlock_blind(&ci->lock); - - /* Create the drift for cj. */ - lock_lock(&cj->lock); - if (cj->drift_gpart == NULL && cj->nodeID == engine_rank) - cj->drift_gpart = scheduler_addtask( - s, task_type_drift_gpart, task_subtype_none, 0, 0, cj, NULL); - lock_unlock_blind(&cj->lock); - } } /* pair interaction? */ } /* iterate over the current task. */ }