Commit 3eae86b1 authored by James Willis's avatar James Willis
Browse files

Merge branch 'master' into swift-velociraptor-C

Conflicts:
	src/engine.c
parents a8a7fcc3 5ceceb7f
......@@ -24,7 +24,6 @@ TimeIntegration:
Scheduler:
max_top_level_cells: 8
cell_split_size: 50
# Parameters governing the snapshots
Snapshots:
......
......@@ -34,7 +34,6 @@ TimeIntegration:
Scheduler:
max_top_level_cells: 16
cell_split_size: 50
# Parameters governing the snapshots
Snapshots:
......
......@@ -24,7 +24,6 @@ TimeIntegration:
Scheduler:
max_top_level_cells: 20
cell_split_size: 50
# Parameters governing the snapshots
Snapshots:
......
......@@ -27,7 +27,6 @@ Cosmology:
Scheduler:
max_top_level_cells: 8
cell_split_size: 50
# Parameters governing the time integration
TimeIntegration:
......
......@@ -24,7 +24,6 @@ TimeIntegration:
Scheduler:
max_top_level_cells: 8
cell_split_size: 50
# Parameters governing the snapshots
Snapshots:
......
......@@ -24,7 +24,6 @@ TimeIntegration:
Scheduler:
max_top_level_cells: 16
cell_split_size: 50
# Parameters governing the snapshots
Snapshots:
......
......@@ -24,7 +24,6 @@ TimeIntegration:
Scheduler:
max_top_level_cells: 20
cell_split_size: 50
# Parameters governing the snapshots
Snapshots:
......
......@@ -52,10 +52,10 @@ infile = args.input
# Tasks and subtypes. Indexed as in tasks.h.
TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair",
"init_grav", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart",
"end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_top_level",
"grav_long_range", "grav_ghost_in", "grav_ghost_out", "grav_mm", "grav_down", "cooling",
"sourceterms", "count"]
"init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart",
"end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in",
"grav_down", "grav_mesh", "cooling", "sourceterms", "count"]
SUBTYPES = ["none", "density", "gradient", "force", "grav", "external_grav",
"tend", "xv", "rho", "gpart", "multipole", "spart", "count"]
......
......@@ -936,11 +936,13 @@ int main(int argc, char *argv[]) {
}
/* Legend */
if (myrank == 0)
if (myrank == 0) {
printf("# %6s %14s %14s %10s %14s %9s %12s %12s %12s %16s [%s] %6s\n",
"Step", "Time", "Scale-factor", "Redshift", "Time-step", "Time-bins",
"Updates", "g-Updates", "s-Updates", "Wall-clock time",
clocks_getunit(), "Props");
fflush(stdout);
}
/* File for the timers */
if (with_verbose_timers) timers_open_file(myrank);
......
......@@ -55,6 +55,7 @@ Scheduler:
cell_sub_size_pair_grav: 256000000 # (Optional) Maximal number of interactions per sub-pair gravity task (this is the default value).
cell_sub_size_self_grav: 32000 # (Optional) Maximal number of interactions per sub-self gravity task (this is the default value).
cell_split_size: 400 # (Optional) Maximal number of particles per cell (this is the default value).
cell_subdepth_grav: 2 # (Optional) Maximal depth the gravity tasks can be pushed down (this is the default value).
max_top_level_cells: 12 # (Optional) Maximal number of top-level cells in any dimension. The number of top-level cells will be the cube of this (this is the default value).
tasks_per_cell: 0 # (Optional) The average number of tasks per cell. If not large enough the simulation will fail (means guess...).
mpi_message_limit: 4096 # (Optional) Maximum MPI task message size to send non-buffered, KB.
......
......@@ -110,10 +110,9 @@ pl.rcParams.update(PLOT_PARAMS)
# Tasks and subtypes. Indexed as in tasks.h.
TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair",
"init_grav", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart",
"end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_top_level",
"grav_long_range", "grav_ghost_in", "grav_ghost_out", "grav_mm", "grav_down", "cooling",
"sourceterms", "count"]
"init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart",
"end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in",
"grav_down", "grav_mesh", "cooling", "sourceterms", "count"]
SUBTYPES = ["none", "density", "gradient", "force", "grav", "external_grav",
"tend", "xv", "rho", "gpart", "multipole", "spart", "count"]
......
......@@ -1406,12 +1406,20 @@ void cell_activate_drift_part(struct cell *c, struct scheduler *s) {
/* Set the do_sub_drifts all the way up and activate the super drift
if this has not yet been done. */
if (c == c->super_hydro) {
#ifdef SWIFT_DEBUG_CHECKS
if (c->drift_part == NULL)
error("Trying to activate un-existing c->drift_part");
#endif
scheduler_activate(s, c->drift_part);
} else {
for (struct cell *parent = c->parent;
parent != NULL && !parent->do_sub_drift; parent = parent->parent) {
parent->do_sub_drift = 1;
if (parent == c->super_hydro) {
#ifdef SWIFT_DEBUG_CHECKS
if (parent->drift_part == NULL)
error("Trying to activate un-existing parent->drift_part");
#endif
scheduler_activate(s, parent->drift_part);
break;
}
......@@ -1433,6 +1441,10 @@ void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
/* Set the do_grav_sub_drifts all the way up and activate the super drift
if this has not yet been done. */
if (c == c->super_gravity) {
#ifdef SWIFT_DEBUG_CHECKS
if (c->drift_gpart == NULL)
error("Trying to activate un-existing c->drift_gpart");
#endif
scheduler_activate(s, c->drift_gpart);
} else {
for (struct cell *parent = c->parent;
......@@ -1440,7 +1452,11 @@ void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
parent = parent->parent) {
parent->do_grav_sub_drift = 1;
if (parent == c->super_gravity) {
scheduler_activate(s, parent->drift_gpart);
#ifdef SWIFT_DEBUG_CHECKS
if (parent->drift_gpart == NULL)
error("Trying to activate un-existing parent->drift_gpart");
#endif
scheduler_activate(s, parent->drift_gpart);
break;
}
}
......@@ -1453,6 +1469,9 @@ void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
void cell_activate_sorts_up(struct cell *c, struct scheduler *s) {
if (c == c->super_hydro) {
#ifdef SWIFT_DEBUG_CHECKS
if (c->sorts == NULL) error("Trying to activate un-existing c->sorts");
#endif
scheduler_activate(s, c->sorts);
if (c->nodeID == engine_rank) cell_activate_drift_part(c, s);
} else {
......@@ -1461,6 +1480,10 @@ void cell_activate_sorts_up(struct cell *c, struct scheduler *s) {
parent != NULL && !parent->do_sub_sort; parent = parent->parent) {
parent->do_sub_sort = 1;
if (parent == c->super_hydro) {
#ifdef SWIFT_DEBUG_CHECKS
if (parent->sorts == NULL)
error("Trying to activate un-existing parents->sorts");
#endif
scheduler_activate(s, parent->sorts);
if (parent->nodeID == engine_rank) cell_activate_drift_part(parent, s);
break;
......@@ -1522,7 +1545,7 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
if (ci->count == 0 || !cell_is_active_hydro(ci, e)) return;
/* Recurse? */
if (cell_can_recurse_in_self_task(ci)) {
if (cell_can_recurse_in_self_hydro_task(ci)) {
/* Loop over all progenies and pairs of progenies */
for (int j = 0; j < 8; j++) {
......@@ -1553,8 +1576,8 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
int sid = space_getsid(s->space, &ci, &cj, shift);
/* recurse? */
if (cell_can_recurse_in_pair_task(ci) &&
cell_can_recurse_in_pair_task(cj)) {
if (cell_can_recurse_in_pair_hydro_task(ci) &&
cell_can_recurse_in_pair_hydro_task(cj)) {
/* Different types of flags. */
switch (sid) {
......@@ -1850,6 +1873,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 +1906,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 +1951,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 +1969,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 +2243,26 @@ 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);
}
}
......@@ -2239,7 +2270,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 +2283,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 +2292,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 +2307,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 +2316,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
}
......@@ -2295,11 +2326,13 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
if (c->nodeID == nodeID && cell_is_active_gravity(c, e)) {
if (c->init_grav != NULL) scheduler_activate(s, c->init_grav);
if (c->init_grav_out != NULL) scheduler_activate(s, c->init_grav_out);
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);
if (c->end_force != NULL) scheduler_activate(s, c->end_force);
if (c->grav_down != NULL) scheduler_activate(s, c->grav_down);
if (c->grav_down_in != NULL) scheduler_activate(s, c->grav_down_in);
if (c->grav_mesh != NULL) scheduler_activate(s, c->grav_mesh);
if (c->grav_long_range != NULL) scheduler_activate(s, c->grav_long_range);
}
......@@ -2384,10 +2417,16 @@ void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data) {
for (int ind = 0; ind < num_elements; ind++) {
struct cell *c = &((struct cell *)map_data)[ind];
/* Super-pointer for hydro */
if (e->policy & engine_policy_hydro) cell_set_super_hydro(c, NULL);
if (e->policy &
(engine_policy_self_gravity | engine_policy_external_gravity))
/* Super-pointer for gravity */
if ((e->policy & engine_policy_self_gravity) ||
(e->policy & engine_policy_external_gravity))
cell_set_super_gravity(c, NULL);
/* Super-pointer for common operations */
cell_set_super(c, NULL);
}
}
......@@ -2762,3 +2801,38 @@ void cell_check_timesteps(struct cell *c) {
error("Calling debugging code without debugging flag activated.");
#endif
}
/**
* @brief Can we use the MM interactions fo a given pair of cells?
*
* @param ci The first #cell.
* @param cj The second #cell.
* @param e The #engine.
* @param s The #space.
*/
int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
const struct engine *e, const struct space *s) {
const double theta_crit2 = e->gravity_properties->theta_crit2;
const int periodic = s->periodic;
const double dim[3] = {s->dim[0], s->dim[1], s->dim[2]};
/* Recover the multipole information */
const struct gravity_tensors *const multi_i = ci->multipole;
const struct gravity_tensors *const multi_j = cj->multipole;
/* 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;
return gravity_M2L_accept(multi_i->r_max, multi_j->r_max, theta_crit2, r2);
}
......@@ -225,6 +225,9 @@ struct cell {
/*! The multipole initialistation task */
struct task *init_grav;
/*! Implicit task for the gravity initialisation */
struct task *init_grav_out;
/*! Dependency implicit task for the ghost (in->ghost->out)*/
struct task *ghost_in;
......@@ -258,6 +261,9 @@ struct cell {
/*! Task computing long range non-periodic gravity interactions */
struct task *grav_long_range;
/*! Implicit task for the down propagation */
struct task *grav_down_in;
/*! Task propagating the mesh forces to the particles */
struct task *grav_mesh;
......@@ -521,6 +527,8 @@ 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);
int cell_has_tasks(struct cell *c);
int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
const struct engine *e, const struct space *s);
/* Inlined functions (for speed). */
......@@ -530,8 +538,8 @@ int cell_has_tasks(struct cell *c);
*
* @param c The #cell.
*/
__attribute__((always_inline)) INLINE static int cell_can_recurse_in_pair_task(
const struct cell *c) {
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
/* Is the cell split ? */
/* If so, is the cut-off radius plus the max distance the parts have moved */
......@@ -547,20 +555,20 @@ __attribute__((always_inline)) INLINE static int cell_can_recurse_in_pair_task(
*
* @param c The #cell.
*/
__attribute__((always_inline)) INLINE static int cell_can_recurse_in_self_task(
const struct cell *c) {
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_self_hydro_task(const struct cell *c) {
/* Is the cell split and not smaller than the smoothing length? */
return c->split && (kernel_gamma * c->h_max_old < 0.5f * c->dmin);
}
/**
* @brief Can a pair task associated with a cell be split into smaller
* @brief Can a pair hydro task associated with a cell be split into smaller
* sub-tasks.
*
* @param c The #cell.
*/
__attribute__((always_inline)) INLINE static int cell_can_split_pair_task(
__attribute__((always_inline)) INLINE static int cell_can_split_pair_hydro_task(
const struct cell *c) {
/* Is the cell split ? */
......@@ -572,20 +580,48 @@ __attribute__((always_inline)) INLINE static int cell_can_split_pair_task(
}
/**
* @brief Can a self task associated with a cell be split into smaller
* @brief Can a self hydro task associated with a cell be split into smaller
* sub-tasks.
*
* @param c The #cell.
*/
__attribute__((always_inline)) INLINE static int cell_can_split_self_task(
__attribute__((always_inline)) INLINE static int cell_can_split_self_hydro_task(
const struct cell *c) {
/* Is the cell split ? */
/* If so, is the cut-off radius with some leeway smaller than */
/* the sub-cell sizes ? */
/* Note: No need for more checks here as all the sub-pairs and sub-self */
/* tasks will be created. So no need to check for h_max */
return c->split && (space_stretch * kernel_gamma * c->h_max < 0.5f * c->dmin);
}
/**
* @brief Can a pair gravity task associated with a cell be split into smaller
* sub-tasks.
*
* @param c The #cell.
*/
__attribute__((always_inline)) INLINE static int
cell_can_split_pair_gravity_task(const struct cell *c) {
/* Is the cell split ? */
return c->split && c->depth < space_subdepth_grav;
}
/**
* @brief Can a self gravity task associated with a cell be split into smaller
* sub-tasks.
*
* @param c The #cell.
*/
__attribute__((always_inline)) INLINE static int
cell_can_split_self_gravity_task(const struct cell *c) {
/* Is the cell split ? */
return c->split && c->depth < space_subdepth_grav;
}
/**
* @brief Have particles in a pair of cells moved too much and require a rebuild
* ?
......
......@@ -88,6 +88,7 @@ void collectgroup1_apply(struct collectgroup1 *grp1, struct engine *e) {
e->updates = grp1->updates;
e->g_updates = grp1->g_updates;
e->s_updates = grp1->s_updates;
e->forcerebuild = grp1->forcerebuild;
}
/**
......
This diff is collapsed.
......@@ -284,12 +284,6 @@ struct engine {
int forcerepart;
struct repartition *reparttype;
/* Need to dump some statistics ? */
int save_stats;
/* Need to dump a snapshot ? */
int dump_snapshot;
/* How many steps have we done with the same set of tasks? */
int tasks_age;
......@@ -361,6 +355,7 @@ struct engine {
};
/* Function prototypes. */
void engine_addlink(struct engine *e, struct link **l, struct task *t);
void engine_barrier(struct engine *e);
void engine_compute_next_snapshot_time(struct engine *e);
void engine_compute_next_stf_time(struct engine *e);
......
......@@ -968,7 +968,7 @@ static void runner_do_unskip_gravity(struct cell *c, struct engine *e) {
if (!cell_is_active_gravity(c, e)) return;
/* Recurse */
if (c->split) {
if (c->split && c->depth < space_subdepth_grav) {
for (int k = 0; k < 8; k++) {
if (c->progeny[k] != NULL) {
struct cell *cp = c->progeny[k];
......@@ -998,9 +998,13 @@ void runner_do_unskip_mapper(void *map_data, int num_elements,
for (int ind = 0; ind < num_elements; ind++) {
struct cell *c = &s->cells_top[local_cells[ind]];
if (c != NULL) {
/* Hydro tasks */
if (e->policy & engine_policy_hydro) runner_do_unskip_hydro(c, e);
if (e->policy &
(engine_policy_self_gravity | engine_policy_external_gravity))
/* All gravity tasks */
if ((e->policy & engine_policy_self_gravity) ||
(e->policy & engine_policy_external_gravity))
runner_do_unskip_gravity(c, e);
}
}
......@@ -2219,6 +2223,9 @@ void *runner_main(void *data) {
case task_type_grav_long_range:
runner_do_grav_long_range(r, t->ci, 1);
break;
case task_type_grav_mm:
runner_dopair_grav_mm_symmetric(r, t->ci, t->cj);
break;
case task_type_cooling:
runner_do_cooling(r, t->ci, 1);
break;
......
......@@ -2086,7 +2086,8 @@ void DOSUB_PAIR1(struct runner *r, struct cell *ci, struct cell *cj, int sid,
sid = space_getsid(s, &ci, &cj, shift);
/* Recurse? */
if (cell_can_recurse_in_pair_task(ci) && cell_can_recurse_in_pair_task(cj)) {
if (cell_can_recurse_in_pair_hydro_task(ci) &&
cell_can_recurse_in_pair_hydro_task(cj)) {