diff --git a/src/engine.c b/src/engine.c index 7a397e1a00b331946602b73dae9c5a11351b429b..7de758c86e0818035b30a00b75963ccbe6074c2a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -126,13 +126,21 @@ void engine_addlink(struct engine *e, struct link **l, struct task *t) { */ void engine_add_ghosts(struct engine *e, struct cell *c, struct task *ghost_in, struct task *ghost_out) { + + /* Break the recursion if we have no part to play with */ + if (c->count == 0) return; + + /* If we have reached the leaf OR have to few particles to play with*/ if (!c->split || c->count < engine_max_parts_per_ghost) { + + /* Add the ghost task and its dependencies */ struct scheduler *s = &e->sched; c->ghost = scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, 0, c, NULL); scheduler_addunlock(s, ghost_in, c->ghost); scheduler_addunlock(s, c->ghost, ghost_out); } else { + /* Keep recursing */ for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) engine_add_ghosts(e, c->progeny[k], ghost_in, ghost_out); @@ -145,7 +153,8 @@ void engine_add_ghosts(struct engine *e, struct cell *c, struct task *ghost_in, * * Tasks are only created here. The dependencies will be added later on. * - * Note that there is no need to recurse below the super-cell. + * Note that there is no need to recurse below the super-cell. Note also + * that we only add tasks if the relevant particles are present in the cell. * * @param e The #engine. * @param c The #cell. @@ -159,12 +168,14 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { 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); + const int has_part = (c->count > 0); + const int has_gpart = (c->gcount > 0); /* Are we in a super-cell ? */ if (c->super == c) { /* Add the sort task. */ - if (is_with_hydro) { + if (is_with_hydro && has_part) { c->sorts = scheduler_addtask(s, task_type_sort, task_subtype_none, 0, 0, c, NULL); } @@ -173,11 +184,11 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { if (c->nodeID == e->nodeID) { /* Add the drift tasks corresponding to the policy. */ - if (is_with_hydro) { + if (is_with_hydro && has_part) { c->drift_part = scheduler_addtask(s, task_type_drift_part, task_subtype_none, 0, 0, c, NULL); } - if (is_self_gravity || is_external_gravity) { + if ((is_self_gravity || is_external_gravity) && has_gpart) { c->drift_gpart = scheduler_addtask(s, task_type_drift_gpart, task_subtype_none, 0, 0, c, NULL); } @@ -197,7 +208,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { scheduler_addunlock(s, c->timestep, c->kick1); /* Add the self-gravity tasks */ - if (is_self_gravity) { + if (is_self_gravity && has_gpart) { /* Initialisation of the multipoles */ c->init_grav = scheduler_addtask(s, task_type_init_grav, @@ -218,7 +229,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { } /* Add the hydrodynamics tasks */ - if (is_with_hydro) { + if (is_with_hydro && has_part) { /* Generate the ghost tasks. */ c->ghost_in = @@ -237,7 +248,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { } /* Cooling task */ - if (is_with_cooling) { + if (is_with_cooling && has_part) { c->cooling = scheduler_addtask(s, task_type_cooling, task_subtype_none, 0, 0, c, NULL); @@ -245,7 +256,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { } /* add source terms */ - if (is_with_sourceterms) { + if (is_with_sourceterms && has_part) { c->sourceterms = scheduler_addtask(s, task_type_sourceterms, task_subtype_none, 0, 0, c, NULL); }