diff --git a/src/cell.c b/src/cell.c index a2e55e3c0194baf2ae6509317b243f5304bfdb70..44aec0b50a9158d9d5d0c29e48bfde4902e52e27 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1850,6 +1850,26 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj, } /* Otherwise, pair interation */ } +void cell_activate_grav_mm_task(struct cell *ci, struct cell *cj, + struct scheduler *s) { + /* Some constants */ + const struct engine *e = s->space->e; + + /* Anything to do here? */ + if (!cell_is_active_gravity(ci, e) && !cell_is_active_gravity(cj, e)) + error("Inactive MM task being activated"); + + /* Atomically drift the multipole in ci */ + lock_lock(&ci->mlock); + if (ci->ti_old_multipole < e->ti_current) cell_drift_multipole(ci, e); + if (lock_unlock(&ci->mlock) != 0) error("Impossible to unlock m-pole"); + + /* Atomically drift the multipole in cj */ + lock_lock(&cj->mlock); + if (cj->ti_old_multipole < e->ti_current) cell_drift_multipole(cj, e); + if (lock_unlock(&cj->mlock) != 0) error("Impossible to unlock m-pole"); +} + /** * @brief Traverse a sub-cell task and activate the gravity drift tasks that * are required by a self gravity task. @@ -1863,9 +1883,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj, /* Some constants */ const struct space *sp = s->space; const struct engine *e = sp->e; - const int periodic = sp->periodic; - const double dim[3] = {sp->dim[0], sp->dim[1], sp->dim[2]}; - const double theta_crit2 = e->gravity_properties->theta_crit2; /* Self interaction? */ if (cj == NULL) { @@ -1911,27 +1928,8 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj, if (cj->ti_old_multipole < e->ti_current) cell_drift_multipole(cj, e); if (lock_unlock(&cj->mlock) != 0) error("Impossible to unlock m-pole"); - /* Recover the multipole information */ - struct gravity_tensors *const multi_i = ci->multipole; - struct gravity_tensors *const multi_j = cj->multipole; - const double ri_max = multi_i->r_max; - const double rj_max = multi_j->r_max; - - /* Get the distance between the CoMs */ - double dx = multi_i->CoM[0] - multi_j->CoM[0]; - double dy = multi_i->CoM[1] - multi_j->CoM[1]; - double dz = multi_i->CoM[2] - multi_j->CoM[2]; - - /* Apply BC */ - if (periodic) { - dx = nearest(dx, dim[0]); - dy = nearest(dy, dim[1]); - dz = nearest(dz, dim[2]); - } - const double r2 = dx * dx + dy * dy + dz * dz; - /* Can we use multipoles ? */ - if (gravity_M2L_accept(multi_i->r_max, multi_j->r_max, theta_crit2, r2)) { + if (cell_can_use_pair_mm(ci, cj, e, sp)) { /* Ok, no need to drift anything */ return; @@ -1948,6 +1946,12 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj, /* Ok, we can still recurse */ else { + /* Recover the multipole information */ + struct gravity_tensors *const multi_i = ci->multipole; + struct gravity_tensors *const multi_j = cj->multipole; + const double ri_max = multi_i->r_max; + const double rj_max = multi_j->r_max; + if (ri_max > rj_max) { if (ci->split) { @@ -2216,22 +2220,27 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { struct task *t = l->t; struct cell *ci = t->ci; struct cell *cj = t->cj; + const int ci_nodeID = ci->nodeID; + const int cj_nodeID = (cj != NULL) ? cj->nodeID : -1; const int ci_active = cell_is_active_gravity(ci, e); const int cj_active = (cj != NULL) ? cell_is_active_gravity(cj, e) : 0; /* Only activate tasks that involve a local active cell. */ - if ((ci_active && ci->nodeID == nodeID) || - (cj_active && cj->nodeID == nodeID)) { + if ((ci_active && ci_nodeID == nodeID) || + (cj_active && cj_nodeID == nodeID)) { scheduler_activate(s, t); /* Set the drifting flags */ if (t->type == task_type_self && t->subtype == task_subtype_external_grav) { - cell_activate_subcell_external_grav_tasks(t->ci, s); + cell_activate_subcell_external_grav_tasks(ci, s); } else if (t->type == task_type_self && t->subtype == task_subtype_grav) { - cell_activate_subcell_grav_tasks(t->ci, NULL, s); + cell_activate_subcell_grav_tasks(ci, NULL, s); } else if (t->type == task_type_pair) { - cell_activate_subcell_grav_tasks(t->ci, t->cj, s); + cell_activate_subcell_grav_tasks(ci, cj, s); + } else if (t->type == task_type_grav_mm) { + cell_activate_grav_mm_task(ci, cj, s); + scheduler_activate(s, t); } } @@ -2239,7 +2248,7 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { #ifdef WITH_MPI /* Activate the send/recv tasks. */ - if (ci->nodeID != nodeID) { + if (ci_nodeID != nodeID) { /* If the local cell is active, receive data from the foreign cell. */ if (cj_active) { @@ -2252,7 +2261,7 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { /* Is the foreign cell active and will need stuff from us? */ if (ci_active) { - scheduler_activate_send(s, cj->send_grav, ci->nodeID); + scheduler_activate_send(s, cj->send_grav, ci_nodeID); /* Drift the cell which will be sent at the level at which it is sent, i.e. drift the cell specified in the send task (l->t) @@ -2261,9 +2270,9 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { } /* If the local cell is active, send its ti_end values. */ - if (cj_active) scheduler_activate_send(s, cj->send_ti, ci->nodeID); + if (cj_active) scheduler_activate_send(s, cj->send_ti, ci_nodeID); - } else if (cj->nodeID != nodeID) { + } else if (cj_nodeID != nodeID) { /* If the local cell is active, receive data from the foreign cell. */ if (ci_active) { @@ -2276,7 +2285,7 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { /* Is the foreign cell active and will need stuff from us? */ if (cj_active) { - scheduler_activate_send(s, ci->send_grav, cj->nodeID); + scheduler_activate_send(s, ci->send_grav, cj_nodeID); /* Drift the cell which will be sent at the level at which it is sent, i.e. drift the cell specified in the send task (l->t) @@ -2285,7 +2294,7 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { } /* If the local cell is active, send its ti_end values. */ - if (ci_active) scheduler_activate_send(s, ci->send_ti, cj->nodeID); + if (ci_active) scheduler_activate_send(s, ci->send_ti, cj_nodeID); } #endif }