diff --git a/doc/RTD/source/ParameterFiles/parameter_description.rst b/doc/RTD/source/ParameterFiles/parameter_description.rst
index a4159377631fb45cc8d8f91d58d06f720a5cb785..0055ed22c28c88bffc7d8f22df2f884e26d62104 100644
--- a/doc/RTD/source/ParameterFiles/parameter_description.rst
+++ b/doc/RTD/source/ParameterFiles/parameter_description.rst
@@ -656,6 +656,17 @@ which stops these from being done at the scale of the leaf cells, of which
 there can be a large number. In this case cells with gravity tasks must be at
 least 4 levels above the leaf cells (when possible).
 
+To control the depth at which the ghost tasks are placed, there are
+two parameters (one for the gas, one for the stars). These specify the
+maximum number of particles allowed in such a task before splitting
+into finer ones. These parameters are:
+
+.. code:: YAML
+
+  engine_max_parts_per_ghost:   1000
+  engine_max_sparts_per_ghost:  1000
+
+
 Extra space is required when particles are created in the system (to the time
 of the next rebuild). These are controlled by:
 
diff --git a/doc/RTD/source/Task/index.rst b/doc/RTD/source/Task/index.rst
index 549a89c834570c45e7b4233f3c412fe8afba226d..41fa06b04c2febaf9f3602bbaaea12eba7863b3c 100644
--- a/doc/RTD/source/Task/index.rst
+++ b/doc/RTD/source/Task/index.rst
@@ -10,7 +10,7 @@ This section of the documentation includes information on the task system
 available in SWIFT, as well as how to implement your own task.
 
 SWIFT can produce a graph containing all the dependencies.
-Everything is described in :ref:`_analysistools`.
+Everything is described in :ref:`_Analysis_Tools`.
 
 
 .. toctree::
diff --git a/examples/HydroTests/SodShock_3D/sodShock.yml b/examples/HydroTests/SodShock_3D/sodShock.yml
index b2d783cd74d66a8eaa3cbbf4b08fc686b0298244..816af9c9ad620ce8617340d749b8ab3e61e53ec6 100644
--- a/examples/HydroTests/SodShock_3D/sodShock.yml
+++ b/examples/HydroTests/SodShock_3D/sodShock.yml
@@ -34,3 +34,49 @@ InitialConditions:
   file_name:  ./sodShock.hdf5       # The file to read
   periodic:   1
 
+EAGLEChemistry:              # Solar abundances
+  init_abundance_metal:      0.014
+  init_abundance_Hydrogen:   0.70649785
+  init_abundance_Helium:     0.28055534
+  init_abundance_Carbon:     2.0665436e-3
+  init_abundance_Nitrogen:   8.3562563e-4
+  init_abundance_Oxygen:     5.4926244e-3
+  init_abundance_Neon:       1.4144605e-3
+  init_abundance_Magnesium:  5.907064e-4
+  init_abundance_Silicon:    6.825874e-4
+  init_abundance_Iron:       1.1032152e-3
+  
+EAGLECooling:
+  dir_name:                ./coolingtables/
+  H_reion_z:               11.5 
+  H_reion_eV_p_H:          2.0
+  He_reion_z_centre:       3.5
+  He_reion_z_sigma:        0.5
+  He_reion_eV_p_H:         2.0
+
+# EAGLE star formation parameters
+EAGLEStarFormation:
+  EOS_density_norm_H_p_cm3:          0.1       # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3.
+  EOS_temperature_norm_K:            8000      # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin.
+  EOS_gamma_effective:               1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas.
+  KS_normalisation:                  1.515e-4  # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr.
+  KS_exponent:                       1.4       # The exponent of the Kennicutt-Schmidt law.
+  KS_min_over_density:               57.7      # The over-density above which star-formation is allowed.
+  KS_high_density_threshold_H_p_cm3: 1e3       # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3.
+  KS_high_density_exponent:          2.0       # Slope of the Kennicut-Schmidt law above the high-density threshold.
+  KS_temperature_margin_dex:         0.5       # Logarithm base 10 of the maximal temperature difference above the EOS allowed to form stars.
+  threshold_norm_H_p_cm3:            0.1       # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3.
+  threshold_Z0:                      0.002     # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation.
+  threshold_slope:                   -0.64     # Slope of the metal-dependant star formation threshold
+  threshold_max_density_H_p_cm3:     10.0      # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3.
+  
+# Parameters for the EAGLE "equation of state"
+EAGLEEntropyFloor:
+  Jeans_density_threshold_H_p_cm3: 0.1       # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3.
+  Jeans_over_density_threshold:    10.       # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in.
+  Jeans_temperature_norm_K:        8000      # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin.
+  Jeans_gamma_effective:           1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor
+  Cool_density_threshold_H_p_cm3: 1e-5       # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3.
+  Cool_over_density_threshold:    10.        # Overdensity above which the EAGLE Cool limiter entropy floor can kick in.
+  Cool_temperature_norm_K:        8000       # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin.
+  Cool_gamma_effective:           1.         # Slope the of the EAGLE Cool limiter entropy floor
diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/plotSolution.py b/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/plotSolution.py
index 89a87923148cb6872ab17b6d7229aef597ef3287..f83607e03a162df5ecf83b675b2e0586bb71268a 100644
--- a/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/plotSolution.py
+++ b/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/plotSolution.py
@@ -1,3 +1,23 @@
+#!/usr/bin/env python3
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2019 Folkert Nobels    (nobels@strw.leidenuniv.nl)
+#                    Matthieu Schaller (schaller@strw.leidenuniv.nl)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+################################################################################
 import matplotlib
 
 matplotlib.use("Agg")
@@ -116,6 +136,9 @@ stars_pos[:,2] -= centre[2]
 # Turn the mass into better units
 gas_mass *= unit_mass_in_cgs / Msun_in_cgs
 
+# Calculate the median gas mass
+median_gas_mass = np.median(gas_mass)
+
 # Turn the SFR into better units
 gas_SFR = np.maximum(gas_SFR, np.zeros(np.size(gas_SFR)))
 gas_SFR /= unit_time_in_cgs / year_in_cgs
@@ -166,19 +189,6 @@ savefig("rhoT_SF.png", dpi=200)
 
 ########################################################################3
 
-# 3D Density vs SFR
-figure()
-subplot(111, xscale="log", yscale="log")
-scatter(gas_nH, gas_SFR, s=0.2)
-plot([1, 100], 2e-5 * np.array([1, 100]) ** 0.266667, "k--", lw=1)
-xlabel("${\\rm Density}~n_{\\rm H}~[{\\rm cm^{-3}}]$", labelpad=0)
-ylabel("${\\rm SFR}~[{\\rm M_\\odot~\\cdot~yr^{-1}}]$", labelpad=-7)
-xlim(1e-4, 3e3)
-ylim(8e-6, 2.5e-4)
-savefig("rho_SFR.png", dpi=200)
-
-########################################################################3
-
 star_mask = (
     (stars_pos[:, 0] > -15)
     & (stars_pos[:, 0] < 15)
@@ -224,6 +234,24 @@ xlim(-1.4, 4.9)
 ylim(-0.5, 2.2)
 savefig("density-sSFR.png", dpi=200)
 
+SFR_low = 10**(np.log10(sSFR)+np.log10(year_in_cgs)+np.log10(median_gas_mass))
+SFR_high = 10**(np.log10(sSFR_high_den)+np.log10(year_in_cgs)+np.log10(median_gas_mass))
+SFR_low_min = np.floor(np.log10(.75*np.min(SFR_low)))
+SFR_high_max = np.ceil(np.log10(1.25*np.max(SFR_high)))
+
+# 3D Density vs SFR
+rcParams.update({"figure.subplot.left": 0.18})
+figure()
+subplot(111, xscale="log", yscale="log")
+scatter(gas_nH, gas_SFR, s=0.2)
+plot(rhos,SFR_low,'k--',lw=1,label='SFR low density EAGLE')
+plot(rhoshigh,SFR_high,'k--',lw=1,label='SFR high density EAGLE')
+xlabel("${\\rm Density}~n_{\\rm H}~[{\\rm cm^{-3}}]$", labelpad=0)
+ylabel("${\\rm SFR}~[{\\rm M_\\odot~\\cdot~yr^{-1}}]$", labelpad=2)
+xlim(1e-2, 1e5)
+ylim(10**SFR_low_min, 10**(SFR_high_max+0.1))
+savefig("rho_SFR.png", dpi=200)
+rcParams.update({"figure.subplot.left": 0.15})
 ########################################################################3
 
 # Select gas in a pillow box around the galaxy
diff --git a/examples/SubgridTests/StellarEvolution/makeIC.py b/examples/SubgridTests/StellarEvolution/makeIC.py
index 0ad23b4a9c6d2d730e7b8ce8cd37a2362337e2b9..abc2d8126ae8ac1173f8918ffc818f9cb6bcb4fe 100644
--- a/examples/SubgridTests/StellarEvolution/makeIC.py
+++ b/examples/SubgridTests/StellarEvolution/makeIC.py
@@ -102,8 +102,10 @@ file = h5py.File(fileName, 'w')
 grp = file.create_group("/Header")
 grp.attrs["BoxSize"] = [boxsize]*3
 grp.attrs["NumPart_Total"] =  [numPart, 0, 0, 0, 1, 0]
+#grp.attrs["NumPart_Total"] =  [numPart, 0, 0, 0, 0, 0]
 grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
 grp.attrs["NumPart_ThisFile"] = [numPart, 0, 0, 0, 1, 0]
+#grp.attrs["NumPart_ThisFile"] = [numPart, 0, 0, 0, 0, 0]
 grp.attrs["Time"] = 0.0
 grp.attrs["NumFilesPerSnapshot"] = 1
 grp.attrs["MassTable"] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
diff --git a/examples/main.c b/examples/main.c
index 13d101549c2a68c52a1e616931a67a348177ce77..08e8eacf5510bf7af77175d9a74460651f656800 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -242,12 +242,12 @@ int main(int argc, char *argv[]) {
                  handle_cmdparam, (intptr_t)&cmdps, 0),
       OPT_BOOLEAN('r', "restart", &restart, "Continue using restart files.",
                   NULL, 0, 0),
+      OPT_BOOLEAN('T', "timers", &with_verbose_timers,
+                  "Print timers every time-step.", NULL, 0, 0),
       OPT_INTEGER('t', "threads", &nr_threads,
                   "The number of threads to use on each MPI rank. Defaults to "
                   "1 if not specified.",
                   NULL, 0, 0),
-      OPT_INTEGER('T', "timers", &with_verbose_timers,
-                  "Print timers every time-step.", NULL, 0, 0),
       OPT_INTEGER('v', "verbose", &verbose,
                   "Run in verbose mode, in MPI mode 2 outputs from all ranks.",
                   NULL, 0, 0),
diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml
index 2d9bd1ded443575c97a9d36f39af8880910a3e31..e904a0dd4499da96495be76dfded2989d46ac18c 100644
--- a/examples/parameter_example.yml
+++ b/examples/parameter_example.yml
@@ -74,6 +74,8 @@ Scheduler:
   tasks_per_cell:            0.0       # (Optional) The average number of tasks per cell. If not large enough the simulation will fail (means guess...).
   links_per_tasks:           10        # (Optional) The average number of links per tasks (before adding the communication tasks). If not large enough the simulation will fail (means guess...). Defaults to 10.
   mpi_message_limit:         4096      # (Optional) Maximum MPI task message size to send non-buffered, KB.
+  engine_max_parts_per_ghost:   1000   # (Optional) Maximum number of parts per ghost.
+  engine_max_sparts_per_ghost:  1000   # (Optional) Maximum number of sparts per ghost.
 
 # Parameters governing the time integration (Set dt_min and dt_max to the same value for a fixed time-step run.)
 TimeIntegration:
diff --git a/src/cell.c b/src/cell.c
index f14fcb711f1fd6f181785656b654ad91b0a28fb0..b4d2c9f62b74270024f25256e23ea76ee2aac949 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -71,13 +71,100 @@
 /* Global variables. */
 int cell_next_tag = 0;
 
+/** List of cell pairs for sub-cell recursion. For any sid, the entries in
+ * this array contain the number of sub-cell pairs and the indices and sid
+ * of the sub-cell pairs themselves. */
+struct cell_split_pair cell_split_pairs[13] = {
+    {1, /* (  1 ,  1 ,  1 ) */
+     {{7, 0, 0}}},
+
+    {4, /* (  1 ,  1 ,  0 ) */
+     {{6, 0, 1}, {7, 1, 1}, {6, 1, 0}, {7, 0, 2}}},
+
+    {1, /* (  1 ,  1 , -1 ) */
+     {{6, 1, 2}}},
+
+    {4, /* (  1 ,  0 ,  1 ) */
+     {{5, 0, 3}, {7, 2, 3}, {5, 2, 0}, {7, 0, 6}}},
+
+    {16, /* (  1 ,  0 ,  0 ) */
+     {{4, 0, 4},
+      {5, 0, 5},
+      {6, 0, 7},
+      {7, 0, 8},
+      {4, 1, 3},
+      {5, 1, 4},
+      {6, 1, 6},
+      {7, 1, 7},
+      {4, 2, 1},
+      {5, 2, 2},
+      {6, 2, 4},
+      {7, 2, 5},
+      {4, 3, 0},
+      {5, 3, 1},
+      {6, 3, 3},
+      {7, 3, 4}}},
+
+    {4, /* (  1 ,  0 , -1 ) */
+     {{4, 1, 5}, {6, 3, 5}, {4, 3, 2}, {6, 1, 8}}},
+
+    {1, /* (  1 , -1 ,  1 ) */
+     {{5, 2, 6}}},
+
+    {4, /* (  1 , -1 ,  0 ) */
+     {{4, 3, 6}, {5, 2, 8}, {4, 2, 7}, {5, 3, 7}}},
+
+    {1, /* (  1 , -1 , -1 ) */
+     {{4, 3, 8}}},
+
+    {4, /* (  0 ,  1 ,  1 ) */
+     {{3, 0, 9}, {7, 4, 9}, {3, 4, 0}, {7, 0, 8}}},
+
+    {16, /* (  0 ,  1 ,  0 ) */
+     {{2, 0, 10},
+      {3, 0, 11},
+      {6, 0, 7},
+      {7, 0, 6},
+      {2, 1, 9},
+      {3, 1, 10},
+      {6, 1, 8},
+      {7, 1, 7},
+      {2, 4, 1},
+      {3, 4, 2},
+      {6, 4, 10},
+      {7, 4, 11},
+      {2, 5, 0},
+      {3, 5, 1},
+      {6, 5, 9},
+      {7, 5, 10}}},
+
+    {4, /* (  0 ,  1 , -1 ) */
+     {{2, 1, 11}, {6, 5, 11}, {2, 5, 2}, {6, 1, 6}}},
+
+    {16, /* (  0 ,  0 ,  1 ) */
+     {{1, 0, 12},
+      {3, 0, 11},
+      {5, 0, 5},
+      {7, 0, 2},
+      {1, 2, 9},
+      {3, 2, 12},
+      {5, 2, 8},
+      {7, 2, 5},
+      {1, 4, 3},
+      {3, 4, 6},
+      {5, 4, 12},
+      {7, 4, 11},
+      {1, 6, 0},
+      {3, 6, 3},
+      {5, 6, 9},
+      {7, 6, 12}}}};
+
 /**
  * @brief Get the size of the cell subtree.
  *
  * @param c The #cell.
  */
 int cell_getsize(struct cell *c) {
-
   /* Number of cells in this subtree. */
   int count = 1;
 
@@ -99,7 +186,6 @@ int cell_getsize(struct cell *c) {
  * @return The number of particles linked.
  */
 int cell_link_parts(struct cell *c, struct part *parts) {
-
 #ifdef SWIFT_DEBUG_CHECKS
   if (c->nodeID == engine_rank)
     error("Linking foreign particles in a local cell!");
@@ -132,7 +218,6 @@ int cell_link_parts(struct cell *c, struct part *parts) {
  * @return The number of particles linked.
  */
 int cell_link_gparts(struct cell *c, struct gpart *gparts) {
-
 #ifdef SWIFT_DEBUG_CHECKS
   if (c->nodeID == engine_rank)
     error("Linking foreign particles in a local cell!");
@@ -165,7 +250,6 @@ int cell_link_gparts(struct cell *c, struct gpart *gparts) {
  * @return The number of particles linked.
  */
 int cell_link_sparts(struct cell *c, struct spart *sparts) {
-
 #ifdef SWIFT_DEBUG_CHECKS
   if (c->nodeID == engine_rank)
     error("Linking foreign particles in a local cell!");
@@ -233,7 +317,6 @@ int cell_link_bparts(struct cell *c, struct bpart *bparts) {
  * @return The number of particles linked.
  */
 int cell_link_foreign_parts(struct cell *c, struct part *parts) {
-
 #ifdef WITH_MPI
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -243,7 +326,6 @@ int cell_link_foreign_parts(struct cell *c, struct part *parts) {
 
   /* Do we have a hydro task at this level? */
   if (c->mpi.hydro.recv_xv != NULL) {
-
     /* Recursively attach the parts */
     const int counts = cell_link_parts(c, parts);
 #ifdef SWIFT_DEBUG_CHECKS
@@ -282,7 +364,6 @@ int cell_link_foreign_parts(struct cell *c, struct part *parts) {
  * @return The number of particles linked.
  */
 int cell_link_foreign_gparts(struct cell *c, struct gpart *gparts) {
-
 #ifdef WITH_MPI
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -292,7 +373,6 @@ int cell_link_foreign_gparts(struct cell *c, struct gpart *gparts) {
 
   /* Do we have a hydro task at this level? */
   if (c->mpi.grav.recv != NULL) {
-
     /* Recursively attach the gparts */
     const int counts = cell_link_gparts(c, gparts);
 #ifdef SWIFT_DEBUG_CHECKS
@@ -329,7 +409,6 @@ int cell_link_foreign_gparts(struct cell *c, struct gpart *gparts) {
  * @return The number of particles linked.
  */
 int cell_count_parts_for_tasks(const struct cell *c) {
-
 #ifdef WITH_MPI
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -368,7 +447,6 @@ int cell_count_parts_for_tasks(const struct cell *c) {
  * @return The number of particles linked.
  */
 int cell_count_gparts_for_tasks(const struct cell *c) {
-
 #ifdef WITH_MPI
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -411,7 +489,6 @@ int cell_count_gparts_for_tasks(const struct cell *c) {
  */
 int cell_pack(struct cell *restrict c, struct pcell *restrict pc,
               const int with_gravity) {
-
 #ifdef WITH_MPI
 
   /* Start by packing the data of the current cell. */
@@ -480,7 +557,6 @@ int cell_pack(struct cell *restrict c, struct pcell *restrict pc,
  * @return The number of packed tags.
  */
 int cell_pack_tags(const struct cell *c, int *tags) {
-
 #ifdef WITH_MPI
 
   /* Start by packing the data of the current cell. */
@@ -518,7 +594,6 @@ int cell_pack_tags(const struct cell *c, int *tags) {
  */
 int cell_unpack(struct pcell *restrict pc, struct cell *restrict c,
                 struct space *restrict s, const int with_gravity) {
-
 #ifdef WITH_MPI
 
   /* Unpack the current pcell. */
@@ -545,7 +620,6 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c,
 
   /* Copy the Multipole related information */
   if (with_gravity) {
-
     struct gravity_tensors *mp = c->grav.multipole;
 
     mp->m_pole = pc->grav.m_pole;
@@ -613,7 +687,6 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c,
  * @return The number of tags created.
  */
 int cell_unpack_tags(const int *tags, struct cell *restrict c) {
-
 #ifdef WITH_MPI
 
   /* Unpack the current pcell. */
@@ -651,7 +724,6 @@ int cell_unpack_tags(const int *tags, struct cell *restrict c) {
  */
 int cell_pack_end_step_hydro(struct cell *restrict c,
                              struct pcell_step_hydro *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Pack this cell's data. */
@@ -685,7 +757,6 @@ int cell_pack_end_step_hydro(struct cell *restrict c,
  */
 int cell_unpack_end_step_hydro(struct cell *restrict c,
                                struct pcell_step_hydro *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Unpack this cell's data. */
@@ -719,7 +790,6 @@ int cell_unpack_end_step_hydro(struct cell *restrict c,
  */
 int cell_pack_end_step_grav(struct cell *restrict c,
                             struct pcell_step_grav *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Pack this cell's data. */
@@ -752,7 +822,6 @@ int cell_pack_end_step_grav(struct cell *restrict c,
  */
 int cell_unpack_end_step_grav(struct cell *restrict c,
                               struct pcell_step_grav *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Unpack this cell's data. */
@@ -785,7 +854,6 @@ int cell_unpack_end_step_grav(struct cell *restrict c,
  */
 int cell_pack_end_step_stars(struct cell *restrict c,
                              struct pcell_step_stars *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Pack this cell's data. */
@@ -819,7 +887,6 @@ int cell_pack_end_step_stars(struct cell *restrict c,
  */
 int cell_unpack_end_step_stars(struct cell *restrict c,
                                struct pcell_step_stars *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Unpack this cell's data. */
@@ -922,7 +989,6 @@ int cell_unpack_end_step_black_holes(
  */
 int cell_pack_multipoles(struct cell *restrict c,
                          struct gravity_tensors *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Pack this cell's data. */
@@ -954,7 +1020,6 @@ int cell_pack_multipoles(struct cell *restrict c,
  */
 int cell_unpack_multipoles(struct cell *restrict c,
                            struct gravity_tensors *restrict pcells) {
-
 #ifdef WITH_MPI
 
   /* Unpack this cell's data. */
@@ -983,7 +1048,6 @@ int cell_unpack_multipoles(struct cell *restrict c,
  * @return 0 on success, 1 on failure
  */
 int cell_locktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to lock this cell. */
@@ -994,7 +1058,6 @@ int cell_locktree(struct cell *c) {
 
   /* Did somebody hold this cell in the meantime? */
   if (c->hydro.hold) {
-
     /* Unlock this cell. */
     if (lock_unlock(&c->hydro.lock) != 0) error("Failed to unlock cell.");
 
@@ -1006,7 +1069,6 @@ int cell_locktree(struct cell *c) {
   /* Climb up the tree and lock/hold/unlock. */
   struct cell *finger;
   for (finger = c->parent; finger != NULL; finger = finger->parent) {
-
     /* Lock this cell. */
     if (lock_trylock(&finger->hydro.lock) != 0) break;
 
@@ -1025,7 +1087,6 @@ int cell_locktree(struct cell *c) {
 
   /* Otherwise, we hit a snag. */
   else {
-
     /* Undo the holds up to finger. */
     for (struct cell *finger2 = c->parent; finger2 != finger;
          finger2 = finger2->parent)
@@ -1047,7 +1108,6 @@ int cell_locktree(struct cell *c) {
  * @return 0 on success, 1 on failure
  */
 int cell_glocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to lock this cell. */
@@ -1058,7 +1118,6 @@ int cell_glocktree(struct cell *c) {
 
   /* Did somebody hold this cell in the meantime? */
   if (c->grav.phold) {
-
     /* Unlock this cell. */
     if (lock_unlock(&c->grav.plock) != 0) error("Failed to unlock cell.");
 
@@ -1070,7 +1129,6 @@ int cell_glocktree(struct cell *c) {
   /* Climb up the tree and lock/hold/unlock. */
   struct cell *finger;
   for (finger = c->parent; finger != NULL; finger = finger->parent) {
-
     /* Lock this cell. */
     if (lock_trylock(&finger->grav.plock) != 0) break;
 
@@ -1089,7 +1147,6 @@ int cell_glocktree(struct cell *c) {
 
   /* Otherwise, we hit a snag. */
   else {
-
     /* Undo the holds up to finger. */
     for (struct cell *finger2 = c->parent; finger2 != finger;
          finger2 = finger2->parent)
@@ -1111,7 +1168,6 @@ int cell_glocktree(struct cell *c) {
  * @return 0 on success, 1 on failure
  */
 int cell_mlocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to lock this cell. */
@@ -1122,7 +1178,6 @@ int cell_mlocktree(struct cell *c) {
 
   /* Did somebody hold this cell in the meantime? */
   if (c->grav.mhold) {
-
     /* Unlock this cell. */
     if (lock_unlock(&c->grav.mlock) != 0) error("Failed to unlock cell.");
 
@@ -1134,7 +1189,6 @@ int cell_mlocktree(struct cell *c) {
   /* Climb up the tree and lock/hold/unlock. */
   struct cell *finger;
   for (finger = c->parent; finger != NULL; finger = finger->parent) {
-
     /* Lock this cell. */
     if (lock_trylock(&finger->grav.mlock) != 0) break;
 
@@ -1153,7 +1207,6 @@ int cell_mlocktree(struct cell *c) {
 
   /* Otherwise, we hit a snag. */
   else {
-
     /* Undo the holds up to finger. */
     for (struct cell *finger2 = c->parent; finger2 != finger;
          finger2 = finger2->parent)
@@ -1175,7 +1228,6 @@ int cell_mlocktree(struct cell *c) {
  * @return 0 on success, 1 on failure
  */
 int cell_slocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to lock this cell. */
@@ -1186,7 +1238,6 @@ int cell_slocktree(struct cell *c) {
 
   /* Did somebody hold this cell in the meantime? */
   if (c->stars.hold) {
-
     /* Unlock this cell. */
     if (lock_unlock(&c->stars.lock) != 0) error("Failed to unlock cell.");
 
@@ -1198,7 +1249,6 @@ int cell_slocktree(struct cell *c) {
   /* Climb up the tree and lock/hold/unlock. */
   struct cell *finger;
   for (finger = c->parent; finger != NULL; finger = finger->parent) {
-
     /* Lock this cell. */
     if (lock_trylock(&finger->stars.lock) != 0) break;
 
@@ -1217,7 +1267,6 @@ int cell_slocktree(struct cell *c) {
 
   /* Otherwise, we hit a snag. */
   else {
-
     /* Undo the holds up to finger. */
     for (struct cell *finger2 = c->parent; finger2 != finger;
          finger2 = finger2->parent)
@@ -1238,7 +1287,6 @@ int cell_slocktree(struct cell *c) {
  * @param c The #cell.
  */
 void cell_unlocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to unlock this cell. */
@@ -1257,7 +1305,6 @@ void cell_unlocktree(struct cell *c) {
  * @param c The #cell.
  */
 void cell_gunlocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to unlock this cell. */
@@ -1276,7 +1323,6 @@ void cell_gunlocktree(struct cell *c) {
  * @param c The #cell.
  */
 void cell_munlocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to unlock this cell. */
@@ -1295,7 +1341,6 @@ void cell_munlocktree(struct cell *c) {
  * @param c The #cell.
  */
 void cell_sunlocktree(struct cell *c) {
-
   TIMER_TIC
 
   /* First of all, try to unlock this cell. */
@@ -1332,7 +1377,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
                 ptrdiff_t bparts_offset, struct cell_buff *buff,
                 struct cell_buff *sbuff, struct cell_buff *bbuff,
                 struct cell_buff *gbuff) {
-
   const int count = c->hydro.count, gcount = c->grav.count,
             scount = c->stars.count, bcount = c->black_holes.count;
   struct part *parts = c->hydro.parts;
@@ -1677,7 +1721,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
  * @param treated Has the cell already been sanitized at this level ?
  */
 void cell_sanitize(struct cell *c, int treated) {
-
   const int count = c->hydro.count;
   const int scount = c->stars.count;
   struct part *parts = c->hydro.parts;
@@ -1687,7 +1730,6 @@ void cell_sanitize(struct cell *c, int treated) {
 
   /* Treat cells will <1000 particles */
   if (count < 1000 && !treated) {
-
     /* Get an upper bound on h */
     const float upper_h_max = c->dmin / (1.2f * kernel_gamma);
 
@@ -1704,10 +1746,8 @@ void cell_sanitize(struct cell *c, int treated) {
 
   /* Recurse and gather the new h_max values */
   if (c->split) {
-
     for (int k = 0; k < 8; ++k) {
       if (c->progeny[k] != NULL) {
-
         /* Recurse */
         cell_sanitize(c->progeny[k], (count < 1000));
 
@@ -1717,7 +1757,6 @@ void cell_sanitize(struct cell *c, int treated) {
       }
     }
   } else {
-
     /* Get the new value of h_max */
     for (int i = 0; i < count; ++i) h_max = max(h_max, parts[i].h);
     for (int i = 0; i < scount; ++i)
@@ -1756,7 +1795,6 @@ void cell_clean_links(struct cell *c, void *data) {
  * @param data The current time on the integer time-line
  */
 void cell_check_part_drift_point(struct cell *c, void *data) {
-
 #ifdef SWIFT_DEBUG_CHECKS
 
   const integertime_t ti_drift = *(integertime_t *)data;
@@ -1791,7 +1829,6 @@ void cell_check_part_drift_point(struct cell *c, void *data) {
  * @param data The current time on the integer time-line
  */
 void cell_check_gpart_drift_point(struct cell *c, void *data) {
-
 #ifdef SWIFT_DEBUG_CHECKS
 
   const integertime_t ti_drift = *(integertime_t *)data;
@@ -1828,7 +1865,6 @@ void cell_check_gpart_drift_point(struct cell *c, void *data) {
  * @param data The current time on the integer time-line
  */
 void cell_check_spart_drift_point(struct cell *c, void *data) {
-
 #ifdef SWIFT_DEBUG_CHECKS
 
   const integertime_t ti_drift = *(integertime_t *)data;
@@ -1864,7 +1900,6 @@ void cell_check_spart_drift_point(struct cell *c, void *data) {
  * @param data The current time on the integer time-line
  */
 void cell_check_multipole_drift_point(struct cell *c, void *data) {
-
 #ifdef SWIFT_DEBUG_CHECKS
 
   const integertime_t ti_drift = *(integertime_t *)data;
@@ -1895,7 +1930,6 @@ void cell_check_multipole_drift_point(struct cell *c, void *data) {
  * @param c The #cell to reset.
  */
 void cell_reset_task_counters(struct cell *c) {
-
 #ifdef SWIFT_DEBUG_CHECKS
   for (int t = 0; t < task_type_count; ++t) c->tasks_executed[t] = 0;
   for (int t = 0; t < task_subtype_count; ++t) c->subtasks_executed[t] = 0;
@@ -1913,12 +1947,10 @@ void cell_reset_task_counters(struct cell *c) {
  * @param ti_current The current integer time.
  */
 void cell_make_multipoles(struct cell *c, integertime_t ti_current) {
-
   /* Reset everything */
   gravity_reset(c->grav.multipole);
 
   if (c->split) {
-
     /* Start by recursing */
     for (int k = 0; k < 8; ++k) {
       if (c->progeny[k] != NULL)
@@ -1982,7 +2014,6 @@ void cell_make_multipoles(struct cell *c, integertime_t ti_current) {
     c->grav.multipole->r_max = min(r_max, sqrt(dx * dx + dy * dy + dz * dz));
 
   } else {
-
     if (c->grav.count > 0) {
       gravity_P2M(c->grav.multipole, c->grav.parts, c->grav.count);
       const double dx =
@@ -2025,11 +2056,9 @@ void cell_make_multipoles(struct cell *c, integertime_t ti_current) {
  * @param c The #cell to recursively search and verify.
  */
 void cell_check_foreign_multipole(const struct cell *c) {
-
 #ifdef SWIFT_DEBUG_CHECKS
 
   if (c->split) {
-
     double M_000 = 0.;
     long long num_gpart = 0;
 
@@ -2037,7 +2066,6 @@ void cell_check_foreign_multipole(const struct cell *c) {
       const struct cell *cp = c->progeny[k];
 
       if (cp != NULL) {
-
         /* Check the mass */
         M_000 += cp->grav.multipole->m_pole.M_000;
 
@@ -2065,7 +2093,6 @@ void cell_check_foreign_multipole(const struct cell *c) {
  * @param c Cell to act upon
  */
 void cell_check_multipole(struct cell *c) {
-
 #ifdef SWIFT_DEBUG_CHECKS
   struct gravity_tensors ma;
   const double tolerance = 1e-3; /* Relative */
@@ -2076,7 +2103,6 @@ void cell_check_multipole(struct cell *c) {
       if (c->progeny[k] != NULL) cell_check_multipole(c->progeny[k]);
 
   if (c->grav.count > 0) {
-
     /* Brute-force calculation */
     gravity_P2M(&ma, c->grav.parts, c->grav.count);
 
@@ -2112,7 +2138,6 @@ void cell_check_multipole(struct cell *c) {
  * @param c The #cell.
  */
 void cell_clean(struct cell *c) {
-
   /* Hydro */
   cell_free_hydro_sorts(c);
 
@@ -2150,7 +2175,6 @@ void cell_clear_limiter_flags(struct cell *c, void *data) {
  * @param s The #scheduler.
  */
 void cell_activate_super_spart_drifts(struct cell *c, struct scheduler *s) {
-
   if (c == c->hydro.super) {
     cell_activate_drift_spart(c, s);
   } else {
@@ -2172,7 +2196,6 @@ void cell_activate_super_spart_drifts(struct cell *c, struct scheduler *s) {
  * @brief Activate the #part drifts on the given cell.
  */
 void cell_activate_drift_part(struct cell *c, struct scheduler *s) {
-
   /* If this cell is already marked for drift, quit early. */
   if (cell_get_flag(c, cell_flag_do_hydro_drift)) return;
 
@@ -2191,7 +2214,6 @@ void cell_activate_drift_part(struct cell *c, struct scheduler *s) {
     for (struct cell *parent = c->parent;
          parent != NULL && !cell_get_flag(parent, cell_flag_do_hydro_sub_drift);
          parent = parent->parent) {
-
       /* Mark this cell for drifting */
       cell_set_flag(parent, cell_flag_do_hydro_sub_drift);
 
@@ -2211,7 +2233,6 @@ 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) {
-
   /* If this cell is already marked for drift, quit early. */
   if (cell_get_flag(c, cell_flag_do_grav_drift)) return;
 
@@ -2254,7 +2275,6 @@ void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
  * @brief Activate the #spart drifts on the given cell.
  */
 void cell_activate_drift_spart(struct cell *c, struct scheduler *s) {
-
   /* If this cell is already marked for drift, quit early. */
   if (cell_get_flag(c, cell_flag_do_stars_drift)) return;
 
@@ -2273,7 +2293,6 @@ void cell_activate_drift_spart(struct cell *c, struct scheduler *s) {
     for (struct cell *parent = c->parent;
          parent != NULL && !cell_get_flag(parent, cell_flag_do_stars_sub_drift);
          parent = parent->parent) {
-
       /* Mark this cell for drifting */
       cell_set_flag(parent, cell_flag_do_stars_sub_drift);
 
@@ -2293,7 +2312,6 @@ void cell_activate_drift_spart(struct cell *c, struct scheduler *s) {
  * @brief Activate the drifts on the given cell.
  */
 void cell_activate_limiter(struct cell *c, struct scheduler *s) {
-
   /* If this cell is already marked for limiting, quit early. */
   if (cell_get_flag(c, cell_flag_do_hydro_limiter)) return;
 
@@ -2313,7 +2331,6 @@ void cell_activate_limiter(struct cell *c, struct scheduler *s) {
          parent != NULL &&
          !cell_get_flag(parent, cell_flag_do_hydro_sub_limiter);
          parent = parent->parent) {
-
       /* Mark this cell for limiting */
       cell_set_flag(parent, cell_flag_do_hydro_sub_limiter);
 
@@ -2333,7 +2350,6 @@ void cell_activate_limiter(struct cell *c, struct scheduler *s) {
  * @brief Activate the sorts up a cell hierarchy.
  */
 void cell_activate_hydro_sorts_up(struct cell *c, struct scheduler *s) {
-
   if (c == c->hydro.super) {
 #ifdef SWIFT_DEBUG_CHECKS
     if (c->hydro.sorts == NULL)
@@ -2342,7 +2358,6 @@ void cell_activate_hydro_sorts_up(struct cell *c, struct scheduler *s) {
     scheduler_activate(s, c->hydro.sorts);
     if (c->nodeID == engine_rank) cell_activate_drift_part(c, s);
   } else {
-
     for (struct cell *parent = c->parent;
          parent != NULL && !cell_get_flag(parent, cell_flag_do_hydro_sub_sort);
          parent = parent->parent) {
@@ -2364,10 +2379,8 @@ void cell_activate_hydro_sorts_up(struct cell *c, struct scheduler *s) {
  * @brief Activate the sorts on a given cell, if needed.
  */
 void cell_activate_hydro_sorts(struct cell *c, int sid, struct scheduler *s) {
-
   /* Do we need to re-sort? */
   if (c->hydro.dx_max_sort > space_maxreldx * c->dmin) {
-
     /* Climb up the tree to active the sorts in that direction */
     for (struct cell *finger = c; finger != NULL; finger = finger->parent) {
       if (finger->hydro.requires_sorts) {
@@ -2380,7 +2393,6 @@ void cell_activate_hydro_sorts(struct cell *c, int sid, struct scheduler *s) {
 
   /* Has this cell been sorted at all for the given sid? */
   if (!(c->hydro.sorted & (1 << sid)) || c->nodeID != engine_rank) {
-
     atomic_or(&c->hydro.do_sort, (1 << sid));
     cell_activate_hydro_sorts_up(c, s);
   }
@@ -2390,7 +2402,6 @@ void cell_activate_hydro_sorts(struct cell *c, int sid, struct scheduler *s) {
  * @brief Activate the sorts up a cell hierarchy.
  */
 void cell_activate_stars_sorts_up(struct cell *c, struct scheduler *s) {
-
   if (c == c->hydro.super) {
 #ifdef SWIFT_DEBUG_CHECKS
     if (c->stars.sorts == NULL)
@@ -2402,7 +2413,6 @@ void cell_activate_stars_sorts_up(struct cell *c, struct scheduler *s) {
       cell_activate_drift_spart(c, s);
     }
   } else {
-
     for (struct cell *parent = c->parent;
          parent != NULL && !cell_get_flag(parent, cell_flag_do_stars_sub_sort);
          parent = parent->parent) {
@@ -2424,10 +2434,8 @@ void cell_activate_stars_sorts_up(struct cell *c, struct scheduler *s) {
  * @brief Activate the sorts on a given cell, if needed.
  */
 void cell_activate_stars_sorts(struct cell *c, int sid, struct scheduler *s) {
-
   /* Do we need to re-sort? */
   if (c->stars.dx_max_sort > space_maxreldx * c->dmin) {
-
     /* Climb up the tree to active the sorts in that direction */
     for (struct cell *finger = c; finger != NULL; finger = finger->parent) {
       if (finger->stars.requires_sorts) {
@@ -2440,7 +2448,6 @@ void cell_activate_stars_sorts(struct cell *c, int sid, struct scheduler *s) {
 
   /* Has this cell been sorted at all for the given sid? */
   if (!(c->stars.sorted & (1 << sid)) || c->nodeID != engine_rank) {
-
     atomic_or(&c->stars.do_sort, (1 << sid));
     cell_activate_stars_sorts_up(c, s);
   }
@@ -2470,13 +2477,11 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
 
   /* Self interaction? */
   if (cj == NULL) {
-
     /* Do anything? */
     if (ci->hydro.count == 0 || !cell_is_active_hydro(ci, e)) return;
 
     /* Recurse? */
     if (cell_can_recurse_in_self_hydro_task(ci)) {
-
       /* Loop over all progenies and pairs of progenies */
       for (int j = 0; j < 8; j++) {
         if (ci->progeny[j] != NULL) {
@@ -2488,7 +2493,6 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
         }
       }
     } else {
-
       /* We have reached the bottom of the tree: activate drift */
       cell_activate_drift_part(ci, s);
       if (with_limiter) cell_activate_limiter(ci, s);
@@ -2497,7 +2501,6 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
 
   /* Otherwise, pair interation */
   else {
-
     /* Should we even bother? */
     if (!cell_is_active_hydro(ci, e) && !cell_is_active_hydro(cj, e)) return;
     if (ci->hydro.count == 0 || cj->hydro.count == 0) return;
@@ -2509,284 +2512,18 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
     /* recurse? */
     if (cell_can_recurse_in_pair_hydro_task(ci) &&
         cell_can_recurse_in_pair_hydro_task(cj)) {
-
-      /* Different types of flags. */
-      switch (sid) {
-
-        /* Regular sub-cell interactions of a single cell. */
-        case 0: /* (  1 ,  1 ,  1 ) */
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          break;
-
-        case 1: /* (  1 ,  1 ,  0 ) */
-          if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[0],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[1],
-                                              s);
-          break;
-
-        case 2: /* (  1 ,  1 , -1 ) */
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          break;
-
-        case 3: /* (  1 ,  0 ,  1 ) */
-          if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[0],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[2],
-                                              s);
-          break;
-
-        case 4: /* (  1 ,  0 ,  0 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[0],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[1],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[2],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[0],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[1],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[3],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[0],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[2],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[3],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[1],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[2],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[3],
-                                              s);
-          break;
-
-        case 5: /* (  1 ,  0 , -1 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[1],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[3],
-                                              s);
-          break;
-
-        case 6: /* (  1 , -1 ,  1 ) */
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          break;
-
-        case 7: /* (  1 , -1 ,  0 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[2],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[3],
-                                              s);
-          break;
-
-        case 8: /* (  1 , -1 , -1 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          break;
-
-        case 9: /* (  0 ,  1 ,  1 ) */
-          if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[0],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[4],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[4],
-                                              s);
-          break;
-
-        case 10: /* (  0 ,  1 ,  0 ) */
-          if (ci->progeny[2] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[2], cj->progeny[0],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[2], cj->progeny[1],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[2], cj->progeny[4],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[2], cj->progeny[5],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[0],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[1],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[4],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[5],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[0],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[4],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[5],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[1],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[4],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[5],
-                                              s);
-          break;
-
-        case 11: /* (  0 ,  1 , -1 ) */
-          if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[2], cj->progeny[1],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[2], cj->progeny[5],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[6], cj->progeny[5],
-                                              s);
-          break;
-
-        case 12: /* (  0 ,  0 ,  1 ) */
-          if (ci->progeny[1] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[1], cj->progeny[0],
-                                              s);
-          if (ci->progeny[1] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[1], cj->progeny[2],
-                                              s);
-          if (ci->progeny[1] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[1], cj->progeny[4],
-                                              s);
-          if (ci->progeny[1] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[1], cj->progeny[6],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[0],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[2],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[4],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[3], cj->progeny[6],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[0],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[4],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[5], cj->progeny[6],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[2],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[4],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_hydro_tasks(ci->progeny[7], cj->progeny[6],
-                                              s);
-          break;
+      struct cell_split_pair *csp = &cell_split_pairs[sid];
+      for (int k = 0; k < csp->count; k++) {
+        const int pid = csp->pairs[k].pid;
+        const int pjd = csp->pairs[k].pjd;
+        if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL)
+          cell_activate_subcell_hydro_tasks(ci->progeny[pid], cj->progeny[pjd],
+                                            s);
       }
-
     }
 
     /* Otherwise, activate the sorts and drifts. */
     else if (cell_is_active_hydro(ci, e) || cell_is_active_hydro(cj, e)) {
-
       /* We are going to interact this pair, so store some values. */
       atomic_or(&ci->hydro.requires_sorts, 1 << sid);
       atomic_or(&cj->hydro.requires_sorts, 1 << sid);
@@ -2837,7 +2574,6 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
 
   /* Self interaction? */
   if (cj == NULL) {
-
     /* Do anything? */
     if (!cell_is_active_stars(ci, e) || ci->hydro.count == 0 ||
         ci->stars.count == 0)
@@ -2845,7 +2581,6 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
 
     /* Recurse? */
     if (cell_can_recurse_in_self_stars_task(ci)) {
-
       /* Loop over all progenies and pairs of progenies */
       for (int j = 0; j < 8; j++) {
         if (ci->progeny[j] != NULL) {
@@ -2857,7 +2592,6 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
         }
       }
     } else {
-
       /* We have reached the bottom of the tree: activate drift */
       cell_activate_drift_spart(ci, s);
       cell_activate_drift_part(ci, s);
@@ -2866,7 +2600,6 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
 
   /* Otherwise, pair interation */
   else {
-
     /* Should we even bother? */
     if (!cell_is_active_stars(ci, e) && !cell_is_active_stars(cj, e)) return;
 
@@ -2877,284 +2610,18 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
     /* recurse? */
     if (cell_can_recurse_in_pair_stars_task(ci, cj) &&
         cell_can_recurse_in_pair_stars_task(cj, ci)) {
-
-      /* Different types of flags. */
-      switch (sid) {
-
-        /* Regular sub-cell interactions of a single cell. */
-        case 0: /* (  1 ,  1 ,  1 ) */
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          break;
-
-        case 1: /* (  1 ,  1 ,  0 ) */
-          if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[0],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[1],
-                                              s);
-          break;
-
-        case 2: /* (  1 ,  1 , -1 ) */
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          break;
-
-        case 3: /* (  1 ,  0 ,  1 ) */
-          if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[0],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[2],
-                                              s);
-          break;
-
-        case 4: /* (  1 ,  0 ,  0 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[0],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[1],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[2],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[0],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[1],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[3],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[0],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[2],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[3],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[1],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[2],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[3],
-                                              s);
-          break;
-
-        case 5: /* (  1 ,  0 , -1 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[1],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[3],
-                                              s);
-          break;
-
-        case 6: /* (  1 , -1 ,  1 ) */
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          break;
-
-        case 7: /* (  1 , -1 ,  0 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[2],
-                                              s);
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[3],
-                                              s);
-          break;
-
-        case 8: /* (  1 , -1 , -1 ) */
-          if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[4], cj->progeny[3],
-                                              s);
-          break;
-
-        case 9: /* (  0 ,  1 ,  1 ) */
-          if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[0],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[4],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[4],
-                                              s);
-          break;
-
-        case 10: /* (  0 ,  1 ,  0 ) */
-          if (ci->progeny[2] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[2], cj->progeny[0],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[2], cj->progeny[1],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[2], cj->progeny[4],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[2], cj->progeny[5],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[0],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[1],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[4],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[5],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[0],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[4],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[5],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[1],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[4],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[5],
-                                              s);
-          break;
-
-        case 11: /* (  0 ,  1 , -1 ) */
-          if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[2], cj->progeny[1],
-                                              s);
-          if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[2], cj->progeny[5],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[1],
-                                              s);
-          if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[6], cj->progeny[5],
-                                              s);
-          break;
-
-        case 12: /* (  0 ,  0 ,  1 ) */
-          if (ci->progeny[1] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[1], cj->progeny[0],
-                                              s);
-          if (ci->progeny[1] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[1], cj->progeny[2],
-                                              s);
-          if (ci->progeny[1] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[1], cj->progeny[4],
-                                              s);
-          if (ci->progeny[1] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[1], cj->progeny[6],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[0],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[2],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[4],
-                                              s);
-          if (ci->progeny[3] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[3], cj->progeny[6],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[0],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[2],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[4],
-                                              s);
-          if (ci->progeny[5] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[5], cj->progeny[6],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[0],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[2],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[4],
-                                              s);
-          if (ci->progeny[7] != NULL && cj->progeny[6] != NULL)
-            cell_activate_subcell_stars_tasks(ci->progeny[7], cj->progeny[6],
-                                              s);
-          break;
+      struct cell_split_pair *csp = &cell_split_pairs[sid];
+      for (int k = 0; k < csp->count; k++) {
+        const int pid = csp->pairs[k].pid;
+        const int pjd = csp->pairs[k].pjd;
+        if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL)
+          cell_activate_subcell_stars_tasks(ci->progeny[pid], cj->progeny[pjd],
+                                            s);
       }
-
     }
 
     /* Otherwise, activate the sorts and drifts. */
     else {
-
       if (cell_is_active_stars(ci, e)) {
         /* We are going to interact this pair, so store some values. */
         atomic_or(&cj->hydro.requires_sorts, 1 << sid);
@@ -3208,13 +2675,11 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
 
   /* Self interaction? */
   if (cj == NULL) {
-
     /* Do anything? */
     if (ci->grav.count == 0 || !cell_is_active_gravity(ci, e)) return;
 
     /* Recurse? */
     if (ci->split) {
-
       /* Loop over all progenies and pairs of progenies */
       for (int j = 0; j < 8; j++) {
         if (ci->progeny[j] != NULL) {
@@ -3226,7 +2691,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
         }
       }
     } else {
-
       /* We have reached the bottom of the tree: activate gpart drift */
       cell_activate_drift_gpart(ci, s);
     }
@@ -3234,7 +2698,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
 
   /* Pair interaction */
   else {
-
     /* Anything to do here? */
     if (!cell_is_active_gravity(ci, e) && !cell_is_active_gravity(cj, e))
       return;
@@ -3252,13 +2715,11 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
 
     /* Can we use multipoles ? */
     if (cell_can_use_pair_mm(ci, cj, e, sp)) {
-
       /* Ok, no need to drift anything */
       return;
     }
     /* Otherwise, activate the gpart drifts if we are at the bottom. */
     else if (!ci->split && !cj->split) {
-
       /* Activate the drifts if the cells are local. */
       if (cell_is_active_gravity(ci, e) || cell_is_active_gravity(cj, e)) {
         if (ci->nodeID == engine_rank) cell_activate_drift_gpart(ci, s);
@@ -3267,7 +2728,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
     }
     /* Ok, we can still recurse */
     else {
-
       /* Recover the multipole information */
       const struct gravity_tensors *const multi_i = ci->grav.multipole;
       const struct gravity_tensors *const multi_j = cj->grav.multipole;
@@ -3276,7 +2736,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
 
       if (ri_max > rj_max) {
         if (ci->split) {
-
           /* Loop over ci's children */
           for (int k = 0; k < 8; k++) {
             if (ci->progeny[k] != NULL)
@@ -3284,7 +2743,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
           }
 
         } else if (cj->split) {
-
           /* Loop over cj's children */
           for (int k = 0; k < 8; k++) {
             if (cj->progeny[k] != NULL)
@@ -3296,7 +2754,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
         }
       } else if (rj_max >= ri_max) {
         if (cj->split) {
-
           /* Loop over cj's children */
           for (int k = 0; k < 8; k++) {
             if (cj->progeny[k] != NULL)
@@ -3304,7 +2761,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
           }
 
         } else if (ci->split) {
-
           /* Loop over ci's children */
           for (int k = 0; k < 8; k++) {
             if (ci->progeny[k] != NULL)
@@ -3328,7 +2784,6 @@ void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
  */
 void cell_activate_subcell_external_grav_tasks(struct cell *ci,
                                                struct scheduler *s) {
-
   /* Some constants */
   const struct space *sp = s->space;
   const struct engine *e = sp->e;
@@ -3338,7 +2793,6 @@ void cell_activate_subcell_external_grav_tasks(struct cell *ci,
 
   /* Recurse? */
   if (ci->split) {
-
     /* Loop over all progenies (no need for pairs for self-gravity) */
     for (int j = 0; j < 8; j++) {
       if (ci->progeny[j] != NULL) {
@@ -3346,7 +2800,6 @@ void cell_activate_subcell_external_grav_tasks(struct cell *ci,
       }
     }
   } else {
-
     /* We have reached the bottom of the tree: activate gpart drift */
     cell_activate_drift_gpart(ci, s);
   }
@@ -3362,7 +2815,6 @@ void cell_activate_subcell_external_grav_tasks(struct cell *ci,
  * @return 1 If the space needs rebuilding. 0 otherwise.
  */
 int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
-
   struct engine *e = s->space->e;
   const int nodeID = e->nodeID;
   const int with_limiter = (e->policy & engine_policy_limiter);
@@ -3422,7 +2874,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
     /* Only interested in pair interactions as of here. */
     if (t->type == task_type_pair || t->type == task_type_sub_pair) {
-
       /* Check whether there was too much particle motion, i.e. the
          cell neighbour conditions were violated. */
       if (cell_need_rebuild_for_hydro_pair(ci, cj)) rebuild = 1;
@@ -3430,7 +2881,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 #ifdef WITH_MPI
       /* Activate the send/recv tasks. */
       if (ci_nodeID != nodeID) {
-
         /* If the local cell is active, receive data from the foreign cell. */
         if (cj_active) {
           scheduler_activate(s, ci->mpi.hydro.recv_xv);
@@ -3453,7 +2903,6 @@ int cell_unskip_hydro_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->mpi.hydro.send_xv, ci_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
@@ -3476,7 +2925,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
           scheduler_activate_send(s, cj->mpi.hydro.send_ti, ci_nodeID);
 
       } else if (cj_nodeID != nodeID) {
-
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
           scheduler_activate(s, cj->mpi.hydro.recv_xv);
@@ -3499,7 +2947,6 @@ int cell_unskip_hydro_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->mpi.hydro.send_xv, cj_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
@@ -3509,7 +2956,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
           /* If the local cell is also active, more stuff will be needed. */
           if (ci_active) {
-
             scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
 
 #ifdef EXTRA_HYDRO_LOOP
@@ -3528,7 +2974,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
   /* Unskip all the other task types. */
   if (c->nodeID == nodeID && cell_is_active_hydro(c, e)) {
-
     for (struct link *l = c->hydro.gradient; l != NULL; l = l->next)
       scheduler_activate(s, l->t);
     for (struct link *l = c->hydro.force; l != NULL; l = l->next)
@@ -3567,7 +3012,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
  * @return 1 If the space needs rebuilding. 0 otherwise.
  */
 int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
-
   struct engine *e = s->space->e;
   const int nodeID = e->nodeID;
   int rebuild = 0;
@@ -3590,7 +3034,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
     /* Only activate tasks that involve a local active cell. */
     if ((ci_active && ci_nodeID == nodeID) ||
         (cj_active && cj_nodeID == nodeID)) {
-
       scheduler_activate(s, t);
 
       /* Set the drifting flags */
@@ -3609,11 +3052,9 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
     }
 
     if (t->type == task_type_pair) {
-
 #ifdef WITH_MPI
       /* Activate the send/recv tasks. */
       if (ci_nodeID != nodeID) {
-
         /* If the local cell is active, receive data from the foreign cell. */
         if (cj_active) scheduler_activate(s, ci->mpi.grav.recv);
 
@@ -3622,7 +3063,6 @@ 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->mpi.grav.send, ci_nodeID);
 
           /* Drift the cell which will be sent at the level at which it is
@@ -3636,7 +3076,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
           scheduler_activate_send(s, cj->mpi.grav.send_ti, ci_nodeID);
 
       } else if (cj_nodeID != nodeID) {
-
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) scheduler_activate(s, cj->mpi.grav.recv);
 
@@ -3645,7 +3084,6 @@ 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->mpi.grav.send, cj_nodeID);
 
           /* Drift the cell which will be sent at the level at which it is
@@ -3663,7 +3101,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
   }
 
   for (struct link *l = c->grav.mm; l != NULL; l = l->next) {
-
     struct task *t = l->t;
     struct cell *ci = t->ci;
     struct cell *cj = t->cj;
@@ -3684,14 +3121,12 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
     /* Only activate tasks that involve a local active cell. */
     if ((ci_active && ci_nodeID == nodeID) ||
         (cj_active && cj_nodeID == nodeID)) {
-
       scheduler_activate(s, t);
     }
   }
 
   /* Unskip all the other task types. */
   if (c->nodeID == nodeID && cell_is_active_gravity(c, e)) {
-
     if (c->grav.init != NULL) scheduler_activate(s, c->grav.init);
     if (c->grav.init_out != NULL) scheduler_activate(s, c->grav.init_out);
     if (c->kick1 != NULL) scheduler_activate(s, c->kick1);
@@ -3725,7 +3160,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
  * @return 1 If the space needs rebuilding. 0 otherwise.
  */
 int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
-
   struct engine *e = s->space->e;
   const int nodeID = e->nodeID;
   int rebuild = 0;
@@ -3758,11 +3192,9 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
     /* Only activate tasks that involve a local active cell. */
     if ((ci_active || cj_active) &&
         (ci_nodeID == nodeID || cj_nodeID == nodeID)) {
-
       scheduler_activate(s, t);
 
       if (t->type == task_type_pair) {
-
         /* Do ci */
         if (ci_active) {
           /* stars for ci */
@@ -3809,7 +3241,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
 
     /* Only interested in pair interactions as of here. */
     if (t->type == task_type_pair || t->type == task_type_sub_pair) {
-
       /* Check whether there was too much particle motion, i.e. the
          cell neighbour conditions were violated. */
       if (cell_need_rebuild_for_stars_pair(ci, cj)) rebuild = 1;
@@ -3818,7 +3249,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
 #ifdef WITH_MPI
       /* Activate the send/recv tasks. */
       if (ci_nodeID != nodeID) {
-
         if (cj_active) {
           scheduler_activate(s, ci->mpi.hydro.recv_xv);
           scheduler_activate(s, ci->mpi.hydro.recv_rho);
@@ -3847,7 +3277,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
         }
 
       } else if (cj_nodeID != nodeID) {
-
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
           scheduler_activate(s, cj->mpi.hydro.recv_xv);
@@ -3904,20 +3333,16 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
     }
 
     else if (t->type == task_type_pair || t->type == task_type_sub_pair) {
-
       /* We only want to activate the task if the cell is active and is
          going to update some gas on the *local* node */
       if ((ci_nodeID == nodeID && cj_nodeID == nodeID) &&
           (ci_active || cj_active)) {
-
         scheduler_activate(s, t);
 
       } else if ((ci_nodeID == nodeID && cj_nodeID != nodeID) && (cj_active)) {
-
         scheduler_activate(s, t);
 
       } else if ((ci_nodeID != nodeID && cj_nodeID == nodeID) && (ci_active)) {
-
         scheduler_activate(s, t);
       }
     }
@@ -3927,7 +3352,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
 
   /* Unskip all the other task types. */
   if (c->nodeID == nodeID && cell_is_active_stars(c, e)) {
-
     if (c->stars.ghost != NULL) scheduler_activate(s, c->stars.ghost);
     if (c->stars.stars_in != NULL) scheduler_activate(s, c->stars.stars_in);
     if (c->stars.stars_out != NULL) scheduler_activate(s, c->stars.stars_out);
@@ -3950,7 +3374,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
  */
 void cell_set_super(struct cell *c, struct cell *super, const int with_hydro,
                     const int with_grav) {
-
   /* Are we in a cell which is either the hydro or gravity super? */
   if (super == NULL && ((with_hydro && c->hydro.super != NULL) ||
                         (with_grav && c->grav.super != NULL)))
@@ -3974,7 +3397,6 @@ void cell_set_super(struct cell *c, struct cell *super, const int with_hydro,
  * tree.
  */
 void cell_set_super_hydro(struct cell *c, struct cell *super_hydro) {
-
   /* Are we in a cell with some kind of self/pair task ? */
   if (super_hydro == NULL && c->hydro.density != NULL) super_hydro = c;
 
@@ -3996,7 +3418,6 @@ void cell_set_super_hydro(struct cell *c, struct cell *super_hydro) {
  * the tree.
  */
 void cell_set_super_gravity(struct cell *c, struct cell *super_gravity) {
-
   /* Are we in a cell with some kind of self/pair task ? */
   if (super_gravity == NULL && (c->grav.grav != NULL || c->grav.mm != NULL))
     super_gravity = c;
@@ -4019,7 +3440,6 @@ void cell_set_super_gravity(struct cell *c, struct cell *super_gravity) {
  * @param extra_data Unused parameter.
  */
 void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data) {
-
   const struct engine *e = (const struct engine *)extra_data;
 
   const int with_hydro = (e->policy & engine_policy_hydro);
@@ -4054,7 +3474,6 @@ void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data) {
  * @param c The #cell to probe.
  */
 int cell_has_tasks(struct cell *c) {
-
 #ifdef WITH_MPI
   if (c->timestep != NULL || c->mpi.hydro.recv_ti != NULL ||
       c->mpi.grav.recv_ti != NULL || c->mpi.stars.recv_ti != NULL)
@@ -4081,7 +3500,6 @@ int cell_has_tasks(struct cell *c) {
  * @param force Drift the particles irrespective of the #cell flags.
  */
 void cell_drift_part(struct cell *c, const struct engine *e, int force) {
-
   const int periodic = e->s->periodic;
   const double dim[3] = {e->s->dim[0], e->s->dim[1], e->s->dim[2]};
   const int with_cosmology = (e->policy & engine_policy_cosmology);
@@ -4109,7 +3527,6 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
 
   /* Early abort? */
   if (c->hydro.count == 0) {
-
     /* Clear the drift flags. */
     cell_clear_flag(c, cell_flag_do_hydro_drift | cell_flag_do_hydro_sub_drift);
 
@@ -4148,7 +3565,6 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
     c->hydro.ti_old_part = ti_current;
 
   } else if (!c->split && force && ti_current > ti_old_part) {
-
     /* Drift from the last time the cell was drifted to the current time */
     double dt_drift, dt_kick_grav, dt_kick_hydro, dt_therm;
     if (with_cosmology) {
@@ -4170,7 +3586,6 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
     /* Loop over all the gas particles in the cell */
     const size_t nr_parts = c->hydro.count;
     for (size_t k = 0; k < nr_parts; k++) {
-
       /* Get a handle on the part. */
       struct part *const p = &parts[k];
       struct xpart *const xp = &xparts[k];
@@ -4202,7 +3617,6 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
 
       /* In non-periodic BC runs, remove particles that crossed the border */
       if (!periodic) {
-
         /* Did the particle leave the box?  */
         if ((p->x[0] > dim[0]) || (p->x[0] < 0.) ||  // x
             (p->x[1] > dim[1]) || (p->x[1] < 0.) ||  // y
@@ -4270,7 +3684,6 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
  * @param force Drift the particles irrespective of the #cell flags.
  */
 void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
-
   const int periodic = e->s->periodic;
   const double dim[3] = {e->s->dim[0], e->s->dim[1], e->s->dim[2]};
   const int with_cosmology = (e->policy & engine_policy_cosmology);
@@ -4291,7 +3704,6 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
 
   /* Early abort? */
   if (c->grav.count == 0) {
-
     /* Clear the drift flags. */
     cell_clear_flag(c, cell_flag_do_grav_drift | cell_flag_do_grav_sub_drift);
 
@@ -4320,7 +3732,6 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
     c->grav.ti_old_part = ti_current;
 
   } else if (!c->split && force && ti_current > ti_old_gpart) {
-
     /* Drift from the last time the cell was drifted to the current time */
     double dt_drift;
     if (with_cosmology) {
@@ -4333,7 +3744,6 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
     /* Loop over all the g-particles in the cell */
     const size_t nr_gparts = c->grav.count;
     for (size_t k = 0; k < nr_gparts; k++) {
-
       /* Get a handle on the gpart. */
       struct gpart *const gp = &gparts[k];
 
@@ -4357,7 +3767,6 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
 
       /* In non-periodic BC runs, remove particles that crossed the border */
       if (!periodic) {
-
         /* Did the particle leave the box?  */
         if ((gp->x[0] > dim[0]) || (gp->x[0] < 0.) ||  // x
             (gp->x[1] > dim[1]) || (gp->x[1] < 0.) ||  // y
@@ -4392,7 +3801,6 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
  * @param force Drift the particles irrespective of the #cell flags.
  */
 void cell_drift_spart(struct cell *c, const struct engine *e, int force) {
-
   const int periodic = e->s->periodic;
   const double dim[3] = {e->s->dim[0], e->s->dim[1], e->s->dim[2]};
   const int with_cosmology = (e->policy & engine_policy_cosmology);
@@ -4419,7 +3827,6 @@ void cell_drift_spart(struct cell *c, const struct engine *e, int force) {
 
   /* Early abort? */
   if (c->stars.count == 0) {
-
     /* Clear the drift flags. */
     cell_clear_flag(c, cell_flag_do_stars_drift | cell_flag_do_stars_sub_drift);
 
@@ -4458,7 +3865,6 @@ void cell_drift_spart(struct cell *c, const struct engine *e, int force) {
     c->stars.ti_old_part = ti_current;
 
   } else if (!c->split && force && ti_current > ti_old_spart) {
-
     /* Drift from the last time the cell was drifted to the current time */
     double dt_drift;
     if (with_cosmology) {
@@ -4471,7 +3877,6 @@ void cell_drift_spart(struct cell *c, const struct engine *e, int force) {
     /* Loop over all the star particles in the cell */
     const size_t nr_sparts = c->stars.count;
     for (size_t k = 0; k < nr_sparts; k++) {
-
       /* Get a handle on the spart. */
       struct spart *const sp = &sparts[k];
 
@@ -4492,7 +3897,6 @@ void cell_drift_spart(struct cell *c, const struct engine *e, int force) {
 
       /* In non-periodic BC runs, remove particles that crossed the border */
       if (!periodic) {
-
         /* Did the particle leave the box?  */
         if ((sp->x[0] > dim[0]) || (sp->x[0] < 0.) ||  // x
             (sp->x[1] > dim[1]) || (sp->x[1] < 0.) ||  // y
@@ -4715,7 +4119,6 @@ void cell_drift_bpart(struct cell *c, const struct engine *e, int force) {
  * @param e The #engine (to get ti_current).
  */
 void cell_drift_all_multipoles(struct cell *c, const struct engine *e) {
-
   const integertime_t ti_old_multipole = c->grav.ti_old_multipole;
   const integertime_t ti_current = e->ti_current;
 
@@ -4737,7 +4140,6 @@ void cell_drift_all_multipoles(struct cell *c, const struct engine *e) {
 
   /* Are we not in a leaf ? */
   if (c->split) {
-
     /* Loop over the progeny and recurse. */
     for (int k = 0; k < 8; k++)
       if (c->progeny[k] != NULL) cell_drift_all_multipoles(c->progeny[k], e);
@@ -4757,7 +4159,6 @@ void cell_drift_all_multipoles(struct cell *c, const struct engine *e) {
  * @param e The #engine (to get ti_current).
  */
 void cell_drift_multipole(struct cell *c, const struct engine *e) {
-
   const integertime_t ti_old_multipole = c->grav.ti_old_multipole;
   const integertime_t ti_current = e->ti_current;
 
@@ -4787,7 +4188,6 @@ void cell_drift_multipole(struct cell *c, const struct engine *e) {
  * @param c The #cell to clean.
  */
 void cell_clear_stars_sort_flags(struct cell *c) {
-
   /* Recurse if possible */
   if (c->split) {
     for (int k = 0; k < 8; k++)
@@ -4814,7 +4214,6 @@ void cell_check_timesteps(struct cell *c) {
     for (int k = 0; k < 8; ++k)
       if (c->progeny[k] != NULL) cell_check_timesteps(c->progeny[k]);
   } else {
-
     if (c->nodeID == engine_rank)
       for (int i = 0; i < c->hydro.count; ++i)
         if (c->hydro.parts[i].time_bin == 0)
@@ -4827,7 +4226,6 @@ void cell_check_timesteps(struct cell *c) {
 
 void cell_check_spart_pos(const struct cell *c,
                           const struct spart *global_sparts) {
-
 #ifdef SWIFT_DEBUG_CHECKS
 
   /* Recurse */
@@ -4840,7 +4238,6 @@ void cell_check_spart_pos(const struct cell *c,
   struct spart *sparts = c->stars.parts;
   const int count = c->stars.count;
   for (int i = 0; i < count; ++i) {
-
     const struct spart *sp = &sparts[i];
     if ((sp->x[0] < c->loc[0] / space_stretch) ||
         (sp->x[1] < c->loc[1] / space_stretch) ||
@@ -4852,7 +4249,6 @@ void cell_check_spart_pos(const struct cell *c,
 
     if (sp->time_bin != time_bin_not_created &&
         sp->time_bin != time_bin_inhibited) {
-
       const struct gpart *gp = sp->gpart;
       if (gp == NULL && sp->time_bin != time_bin_not_created)
         error("Unlinked spart!");
@@ -4881,12 +4277,10 @@ void cell_recursively_shift_sparts(struct cell *c,
                                    const int progeny_list[space_cell_maxdepth],
                                    const int main_branch) {
   if (c->split) {
-
     /* No need to recurse in progenies located before the insestion point */
     const int first_progeny = main_branch ? progeny_list[(int)c->depth] : 0;
 
     for (int k = first_progeny; k < 8; ++k) {
-
       if (c->progeny[k] != NULL)
         cell_recursively_shift_sparts(c->progeny[k], progeny_list,
                                       main_branch && (k == first_progeny));
@@ -4917,7 +4311,6 @@ void cell_recursively_shift_sparts(struct cell *c,
  * bin.
  */
 struct spart *cell_add_spart(struct engine *e, struct cell *const c) {
-
   /* Perform some basic consitency checks */
   if (c->nodeID != engine_rank) error("Adding spart on a foreign node");
   if (c->grav.ti_old_part != e->ti_current) error("Undrifted cell!");
@@ -4933,7 +4326,6 @@ struct spart *cell_add_spart(struct engine *e, struct cell *const c) {
      each level */
   struct cell *top = c;
   while (top->parent != NULL) {
-
     /* What is the progeny index of the cell? */
     for (int k = 0; k < 8; ++k) {
       if (top->parent->progeny[k] == top) {
@@ -4959,7 +4351,6 @@ struct spart *cell_add_spart(struct engine *e, struct cell *const c) {
 
   /* Are there any extra particles left? */
   if (top->stars.count == top->stars.count_total - 1) {
-
     /* Release the local lock before exiting. */
     if (lock_unlock(&top->stars.star_formation_lock) != 0)
       error("Failed to unlock the top-level cell.");
@@ -4977,7 +4368,6 @@ struct spart *cell_add_spart(struct engine *e, struct cell *const c) {
 #endif
 
   if (n_copy > 0) {
-
     // MATTHIEU: This can be improved. We don't need to copy everything, just
     // need to swap a few particles.
     memmove(&c->stars.parts[1], &c->stars.parts[0],
@@ -5047,7 +4437,6 @@ struct spart *cell_add_spart(struct engine *e, struct cell *const c) {
  */
 void cell_remove_part(const struct engine *e, struct cell *c, struct part *p,
                       struct xpart *xp) {
-
   /* Quick cross-check */
   if (c->nodeID != e->nodeID)
     error("Can't remove a particle in a foreign cell.");
@@ -5077,7 +4466,6 @@ void cell_remove_part(const struct engine *e, struct cell *c, struct part *p,
  */
 void cell_remove_gpart(const struct engine *e, struct cell *c,
                        struct gpart *gp) {
-
   /* Quick cross-check */
   if (c->nodeID != e->nodeID)
     error("Can't remove a particle in a foreign cell.");
@@ -5097,7 +4485,6 @@ void cell_remove_gpart(const struct engine *e, struct cell *c,
  */
 void cell_remove_spart(const struct engine *e, struct cell *c,
                        struct spart *sp) {
-
   /* Quick cross-check */
   if (c->nodeID != e->nodeID)
     error("Can't remove a particle in a foreign cell.");
@@ -5161,7 +4548,6 @@ void cell_remove_bpart(const struct engine *e, struct cell *c,
  */
 struct gpart *cell_convert_part_to_gpart(const struct engine *e, struct cell *c,
                                          struct part *p, struct xpart *xp) {
-
   /* Quick cross-checks */
   if (c->nodeID != e->nodeID)
     error("Can't remove a particle in a foreign cell.");
@@ -5207,7 +4593,6 @@ struct gpart *cell_convert_part_to_gpart(const struct engine *e, struct cell *c,
  */
 struct gpart *cell_convert_spart_to_gpart(const struct engine *e,
                                           struct cell *c, struct spart *sp) {
-
   /* Quick cross-check */
   if (c->nodeID != e->nodeID)
     error("Can't remove a particle in a foreign cell.");
@@ -5254,7 +4639,6 @@ struct gpart *cell_convert_spart_to_gpart(const struct engine *e,
  */
 struct spart *cell_convert_part_to_spart(struct engine *e, struct cell *c,
                                          struct part *p, struct xpart *xp) {
-
   /* Quick cross-check */
   if (c->nodeID != e->nodeID)
     error("Can't remove a particle in a foreign cell.");
@@ -5312,7 +4696,6 @@ struct spart *cell_convert_part_to_spart(struct engine *e, struct cell *c,
  * first #part in the global array in the space structure (for re-linking).
  */
 void cell_reorder_extra_parts(struct cell *c, const ptrdiff_t parts_offset) {
-
   struct part *parts = c->hydro.parts;
   struct xpart *xparts = c->hydro.xparts;
   const int count_real = c->hydro.count;
@@ -5325,7 +4708,6 @@ void cell_reorder_extra_parts(struct cell *c, const ptrdiff_t parts_offset) {
   /* Find extra particles */
   for (int i = 0; i < count_real; ++i) {
     if (parts[i].time_bin == time_bin_not_created) {
-
       /* Find the first non-extra particle after the end of the
          real particles */
       while (parts[first_not_extra].time_bin == time_bin_not_created) {
@@ -5366,7 +4748,6 @@ void cell_reorder_extra_parts(struct cell *c, const ptrdiff_t parts_offset) {
  * first #spart in the global array in the space structure (for re-linking).
  */
 void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset) {
-
   struct spart *sparts = c->stars.parts;
   const int count_real = c->stars.count;
 
@@ -5378,7 +4759,6 @@ void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset) {
   /* Find extra particles */
   for (int i = 0; i < count_real; ++i) {
     if (sparts[i].time_bin == time_bin_not_created) {
-
       /* Find the first non-extra particle after the end of the
          real particles */
       while (sparts[first_not_extra].time_bin == time_bin_not_created) {
@@ -5424,7 +4804,6 @@ void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset) {
  */
 void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
                                struct spart *sparts) {
-
   struct gpart *gparts = c->grav.parts;
   const int count_real = c->grav.count;
 
@@ -5436,7 +4815,6 @@ void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
   /* Find extra particles */
   for (int i = 0; i < count_real; ++i) {
     if (gparts[i].time_bin == time_bin_not_created) {
-
       /* Find the first non-extra particle after the end of the
          real particles */
       while (gparts[first_not_extra].time_bin == time_bin_not_created) {
@@ -5480,7 +4858,6 @@ void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
  */
 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]};
@@ -5519,7 +4896,6 @@ int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
 int cell_can_use_pair_mm_rebuild(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]};
diff --git a/src/cell.h b/src/cell.h
index 0824f71d020e9063be86421febf1e9923ae44aff..e9f58eb7991656ee501d018983757e2aa7211e6d 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -73,6 +73,17 @@ struct link {
   struct link *next;
 };
 
+/* Holds the pairs of progeny for each sid. */
+struct cell_split_pair {
+  int count;
+  struct {
+    int pid;
+    int pjd;
+    int sid;
+  } pairs[16];
+};
+extern struct cell_split_pair cell_split_pairs[13];
+
 /**
  * @brief Packed cell for information correct at rebuild time.
  *
@@ -1158,6 +1169,8 @@ __attribute__((always_inline)) INLINE static void cell_malloc_hydro_sorts(
 
   const int count = c->hydro.count;
 
+  /* Note that sorts can be used by different tasks at the same time (but not
+   * on the same dimensions), so we need separate allocations per dimension. */
   for (int j = 0; j < 13; j++) {
     if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) {
       if ((c->hydro.sort[j] = (struct entry *)swift_malloc(
@@ -1165,35 +1178,6 @@ __attribute__((always_inline)) INLINE static void cell_malloc_hydro_sorts(
         error("Failed to allocate sort memory.");
     }
   }
-
-  /* /\* Count the memory needed for all active dimensions. *\/ */
-  /* int count = 0; */
-  /* for (int j = 0; j < 13; j++) { */
-  /*   if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) */
-  /*     count += (c->hydro.count + 1); */
-  /* } */
-
-  /* if(c->hydro.sortptr != NULL) */
-  /*   error("Reallocating hydro sorts!"); */
-
-  /* /\* Allocate as a single chunk. *\/ */
-  /* struct entry *memptr = NULL; */
-  /* /\* if ((memptr = (struct entry *)swift_malloc( *\/ */
-  /* /\*          "hydro.sort", sizeof(struct entry) * count)) == NULL) *\/ */
-  /* if ((memptr = (struct entry *)malloc( */
-  /* 				       sizeof(struct entry) * count)) == NULL)
-   */
-  /*   error("Failed to allocate sort memory."); */
-
-  /* c->hydro.sortptr = memptr; */
-
-  /* /\* And attach spans as needed. *\/ */
-  /* for (int j = 0; j < 13; j++) { */
-  /*   if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) { */
-  /*     c->hydro.sort[j] = memptr; */
-  /*     memptr += (c->hydro.count + 1); */
-  /*   } */
-  /* } */
 }
 
 /**
@@ -1210,14 +1194,6 @@ __attribute__((always_inline)) INLINE static void cell_free_hydro_sorts(
       c->hydro.sort[i] = NULL;
     }
   }
-
-  /* /\* Note only one allocation for the dimensions. *\/ */
-  /* if (c->hydro.sortptr != NULL) { */
-  /*   //swift_free("hydro.sort", c->hydro.sortptr); */
-  /*   free(c->hydro.sortptr); */
-  /*   c->hydro.sortptr = NULL; */
-  /*   for (int i = 0; i < 13; i++) c->hydro.sort[i] = NULL; */
-  /* } */
 }
 
 /**
@@ -1231,6 +1207,8 @@ __attribute__((always_inline)) INLINE static void cell_malloc_stars_sorts(
 
   const int count = c->stars.count;
 
+  /* Note that sorts can be used by different tasks at the same time (but not
+   * on the same dimensions), so we need separate allocations per dimension. */
   for (int j = 0; j < 13; j++) {
     if ((flags & (1 << j)) && c->stars.sort[j] == NULL) {
       if ((c->stars.sort[j] = (struct entry *)swift_malloc(
@@ -1238,32 +1216,6 @@ __attribute__((always_inline)) INLINE static void cell_malloc_stars_sorts(
         error("Failed to allocate sort memory.");
     }
   }
-
-  /* /\* Count the memory needed for all active dimensions. *\/ */
-  /* int count = 0; */
-  /* for (int j = 0; j < 13; j++) { */
-  /*   if ((flags & (1 << j)) && c->stars.sort[j] == NULL) */
-  /*     count += (c->stars.count + 1); */
-  /* } */
-
-  /* /\* Allocate as a single chunk. *\/ */
-  /* struct entry *memptr = NULL; */
-  /* /\* if ((memptr = (struct entry *)swift_malloc( *\/ */
-  /* /\*          "stars.sort", sizeof(struct entry) * count)) == NULL) *\/ */
-  /* if ((memptr = (struct entry *)malloc( */
-  /* 				       sizeof(struct entry) * count)) == NULL)
-   */
-  /*   error("Failed to allocate sort memory."); */
-
-  /* c->stars.sortptr = memptr; */
-
-  /* /\* And attach spans as needed. *\/ */
-  /* for (int j = 0; j < 13; j++) { */
-  /*   if ((flags & (1 << j)) && c->stars.sort[j] == NULL) { */
-  /*     c->stars.sort[j] = memptr; */
-  /*     memptr += (c->stars.count + 1); */
-  /*   } */
-  /* } */
 }
 
 /**
@@ -1280,14 +1232,6 @@ __attribute__((always_inline)) INLINE static void cell_free_stars_sorts(
       c->stars.sort[i] = NULL;
     }
   }
-
-  /* /\* Note only one allocation for the dimensions. *\/ */
-  /* if (c->stars.sortptr != NULL) { */
-  /*   //swift_free("stars.sort", c->stars.sortptr); */
-  /*   free(c->stars.sortptr); */
-  /*   c->stars.sortptr = NULL; */
-  /*   for (int i = 0; i < 13; i++) c->stars.sort[i] = NULL; */
-  /* } */
 }
 
 /** Set the given flag for the given cell. */
diff --git a/src/debug.c b/src/debug.c
index 6257f7cf4e62c3db9027c820bb658eb678c0ecf1..e885df0e98634dd32f3cc3df9f979cdfd19775e3 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -311,7 +311,7 @@ int checkCellhdxmax(const struct cell *c, int *depth) {
         sp->x[2] < loc_min[2] || sp->x[2] >= loc_max[2]) {
 
       message(
-          "Inconsistent part position p->x=[%e %e %e], c->loc=[%e %e %e] "
+          "Inconsistent spart position p->x=[%e %e %e], c->loc=[%e %e %e] "
           "c->width=[%e %e %e]",
           sp->x[0], sp->x[1], sp->x[2], c->loc[0], c->loc[1], c->loc[2],
           c->width[0], c->width[1], c->width[2]);
diff --git a/src/engine.c b/src/engine.c
index 5c41c9ad7343e6cd4b68183506eaa5bbb2e953ae..d418515db4ccca8a72820c5fbb9dacc7bc0803f2 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -65,6 +65,7 @@
 #include "entropy_floor.h"
 #include "equation_of_state.h"
 #include "error.h"
+#include "feedback.h"
 #include "gravity.h"
 #include "gravity_cache.h"
 #include "hydro.h"
@@ -6078,6 +6079,7 @@ void engine_struct_dump(struct engine *e, FILE *stream) {
   potential_struct_dump(e->external_potential, stream);
   cooling_struct_dump(e->cooling_func, stream);
   starformation_struct_dump(e->star_formation, stream);
+  feedback_struct_dump(e->feedback_props, stream);
   chemistry_struct_dump(e->chemistry, stream);
   parser_struct_dump(e->parameter_file, stream);
   if (e->output_list_snapshots)
@@ -6180,6 +6182,11 @@ void engine_struct_restore(struct engine *e, FILE *stream) {
   starformation_struct_restore(star_formation, stream);
   e->star_formation = star_formation;
 
+  struct feedback_props *feedback_properties =
+      (struct feedback_props *)malloc(sizeof(struct feedback_props));
+  feedback_struct_restore(feedback_properties, stream);
+  e->feedback_props = feedback_properties;
+
   struct chemistry_global_data *chemistry =
       (struct chemistry_global_data *)malloc(
           sizeof(struct chemistry_global_data));
diff --git a/src/engine.h b/src/engine.h
index fe40a4212c5e6b48844d18a6a1d54c25fc73602e..3afa8c221d2d1690dec45d2017a18fc0d3aee8ca 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -107,8 +107,8 @@ enum engine_step_properties {
 #define engine_foreign_alloc_margin 1.05
 #define engine_default_energy_file_name "energy"
 #define engine_default_timesteps_file_name "timesteps"
-#define engine_max_parts_per_ghost 1000
-#define engine_max_sparts_per_ghost 1000
+#define engine_max_parts_per_ghost_default 1000
+#define engine_max_sparts_per_ghost_default 1000
 #define engine_tasks_per_cell_margin 1.2
 
 /**
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index 85a9e07ef06c80490d420f4b8ccbe0cd28261554..94792933ed4f75f310c8fb74d7d7b60d02b7f55c 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -52,6 +52,9 @@
 #include "proxy.h"
 #include "timers.h"
 
+extern int engine_max_parts_per_ghost;
+extern int engine_max_sparts_per_ghost;
+
 /**
  * @brief Add send tasks for the gravity pairs to a hierarchy of cells.
  *
diff --git a/src/equation_of_state/planetary/tillotson.h b/src/equation_of_state/planetary/tillotson.h
index 609cc8dcb33e6533f68e13430f6654832af4d0a5..7522ba7b17e0e1bf734b853a89aada0375072ddc 100644
--- a/src/equation_of_state/planetary/tillotson.h
+++ b/src/equation_of_state/planetary/tillotson.h
@@ -41,7 +41,8 @@
 
 // Tillotson parameters
 struct Til_params {
-  float rho_0, a, b, A, B, u_0, u_iv, u_cv, alpha, beta, eta_min, P_min;
+  float rho_0, a, b, A, B, u_0, u_iv, u_cv, alpha, beta, eta_min, eta_zero,
+      P_min;
   enum eos_planetary_material_id mat_id;
 };
 
@@ -60,6 +61,7 @@ INLINE static void set_Til_iron(struct Til_params *mat,
   mat->alpha = 5.0f;
   mat->beta = 5.0f;
   mat->eta_min = 0.0f;
+  mat->eta_zero = 0.0f;
   mat->P_min = 0.0f;
 }
 INLINE static void set_Til_granite(struct Til_params *mat,
@@ -76,6 +78,7 @@ INLINE static void set_Til_granite(struct Til_params *mat,
   mat->alpha = 5.0f;
   mat->beta = 5.0f;
   mat->eta_min = 0.0f;
+  mat->eta_zero = 0.0f;
   mat->P_min = 0.0f;
 }
 INLINE static void set_Til_water(struct Til_params *mat,
@@ -91,7 +94,8 @@ INLINE static void set_Til_water(struct Til_params *mat,
   mat->u_cv = 2.69e9f;
   mat->alpha = 10.0f;
   mat->beta = 5.0f;
-  mat->eta_min = 0.9f;
+  mat->eta_min = 0.925f;
+  mat->eta_zero = 0.875f;
   mat->P_min = 0.0f;
 }
 
@@ -177,11 +181,12 @@ INLINE static float Til_pressure_from_internal_energy(
   float P_c, P_e, P;
 
   // Condensed or cold
-  if (eta < mat->eta_min) {
+  P_c =
+      (mat->a + mat->b * w_inv) * density * u + mat->A * mu + mat->B * mu * mu;
+  if (eta < mat->eta_zero) {
     P_c = 0.f;
-  } else {
-    P_c = (mat->a + mat->b * w_inv) * density * u + mat->A * mu +
-          mat->B * mu * mu;
+  } else if (eta < mat->eta_min) {
+    P_c *= (eta - mat->eta_zero) / (mat->eta_min - mat->eta_zero);
   }
   // Expanded and hot
   P_e = mat->a * density * u +
@@ -237,11 +242,12 @@ INLINE static float Til_soundspeed_from_internal_energy(
   float P_c, P_e, c_sq_c, c_sq_e, c_sq;
 
   // Condensed or cold
-  if (eta < mat->eta_min) {
+  P_c =
+      (mat->a + mat->b * w_inv) * density * u + mat->A * mu + mat->B * mu * mu;
+  if (eta < mat->eta_zero) {
     P_c = 0.f;
-  } else {
-    P_c = (mat->a + mat->b * w_inv) * density * u + mat->A * mu +
-          mat->B * mu * mu;
+  } else if (eta < mat->eta_min) {
+    P_c *= (eta - mat->eta_zero) / (mat->eta_min - mat->eta_zero);
   }
   c_sq_c = P_c * rho_inv * (1.f + mat->a + mat->b * w_inv) +
            mat->b * (w - 1.f) * w_inv_sq * (2.f * u - P_c * rho_inv) +
diff --git a/src/feedback/EAGLE/feedback.c b/src/feedback/EAGLE/feedback.c
index 8d81eae0ac8932fcae39c8456710992048f73a80..37d028b64f944cd59cd931cb013b04bcde81c88d 100644
--- a/src/feedback/EAGLE/feedback.c
+++ b/src/feedback/EAGLE/feedback.c
@@ -690,6 +690,10 @@ void compute_stellar_evolution(const struct feedback_props* feedback_props,
 
   TIMER_TIC;
 
+#ifdef SWIFT_DEBUG_CHECKS
+  if (age < 0.f) error("Negative age for a star.");
+#endif
+
   /* Allocate temporary array for calculating imf weights */
   float stellar_yields[eagle_feedback_N_imf_bins];
 
@@ -991,3 +995,115 @@ void feedback_props_init(struct feedback_props* fp,
 
   message("initialized stellar feedback");
 }
+
+/**
+ * @brief Zero pointers in yield_table structs
+ *
+ * @param table yield_table struct in which pointers to tables
+ * set to NULL
+ */
+void zero_yield_table_pointers(struct yield_table* table) {
+
+  table->mass = NULL;
+  table->metallicity = NULL;
+  table->yield_IMF_resampled = NULL;
+  table->yield = NULL;
+  table->ejecta_IMF_resampled = NULL;
+  table->ejecta = NULL;
+  table->total_metals_IMF_resampled = NULL;
+  table->total_metals = NULL;
+}
+
+/**
+ * @brief Restore feedback tables (if applicable) after
+ * restart
+ *
+ * @param fp the #feedback_props structure
+ */
+void feedback_restore_tables(struct feedback_props* fp) {
+
+  init_imf(fp);
+
+  /* Allocate yield tables  */
+  allocate_yield_tables(fp);
+
+  /* Read the tables  */
+  read_yield_tables(fp);
+
+  /* Set yield_mass_bins array */
+  const float imf_log10_mass_bin_size =
+      (fp->log10_imf_max_mass_msun - fp->log10_imf_min_mass_msun) /
+      (eagle_feedback_N_imf_bins - 1);
+
+  for (int i = 0; i < eagle_feedback_N_imf_bins; i++)
+    fp->yield_mass_bins[i] =
+        imf_log10_mass_bin_size * i + fp->log10_imf_min_mass_msun;
+
+  /* Resample yields from mass bins used in tables to mass bins used in IMF  */
+  compute_yields(fp);
+
+  /* Resample ejecta contribution to enrichment from mass bins used in tables to
+   * mass bins used in IMF  */
+  compute_ejecta(fp);
+}
+
+/**
+ * @brief Write a feedback struct to the given FILE as a stream of bytes.
+ *
+ * @param feedback the struct
+ * @param stream the file stream
+ */
+void feedback_struct_dump(const struct feedback_props* feedback, FILE* stream) {
+
+  /* To make sure everything is restored correctly, we zero all the pointers to
+     tables. If they are not restored correctly, we would crash after restart on
+     the first call to the feedback routines. Helps debugging. */
+  struct feedback_props feedback_copy = *feedback;
+
+  /* zero AGB and SNII table pointers */
+  zero_yield_table_pointers(&feedback_copy.yield_AGB);
+  zero_yield_table_pointers(&feedback_copy.yield_SNII);
+
+  /* zero SNIa table pointers */
+  feedback_copy.yield_SNIa_IMF_resampled = NULL;
+  feedback_copy.yields_SNIa = NULL;
+  feedback_copy.yield_SNIa_total_metals_IMF_resampled = 0;
+
+  /* zero element name tables */
+  feedback_copy.SNIa_element_names = NULL;
+  feedback_copy.SNII_element_names = NULL;
+  feedback_copy.AGB_element_names = NULL;
+
+  /* zero mass bins table */
+  feedback_copy.yield_mass_bins = NULL;
+
+  /* zero lifetime tracks */
+  feedback_copy.lifetimes.mass = NULL;
+  feedback_copy.lifetimes.metallicity = NULL;
+  feedback_copy.lifetimes.dyingtime = NULL;
+
+  /* zero IMF tables */
+  feedback_copy.imf = NULL;
+  feedback_copy.imf_mass_bin = NULL;
+  feedback_copy.imf_mass_bin_log10 = NULL;
+
+  restart_write_blocks((void*)&feedback_copy, sizeof(struct feedback_props), 1,
+                       stream, "feedback", "feedback function");
+}
+
+/**
+ * @brief Restore a hydro_props struct from the given FILE as a stream of
+ * bytes.
+ *
+ * Read the structure from the stream and restore the feedback tables by
+ * re-reading them.
+ *
+ * @param feedback the struct
+ * @param stream the file stream
+ */
+void feedback_struct_restore(struct feedback_props* feedback, FILE* stream) {
+  restart_read_blocks((void*)feedback, sizeof(struct feedback_props), 1, stream,
+                      NULL, "feedback function");
+
+  feedback_restore_tables(feedback);
+}
diff --git a/src/feedback/EAGLE/feedback.h b/src/feedback/EAGLE/feedback.h
index 5fa32fc2fa8053dbeaa1c1f96b5abb8526942b68..4f341a00fcc333190210ab446c738090647855ed 100644
--- a/src/feedback/EAGLE/feedback.h
+++ b/src/feedback/EAGLE/feedback.h
@@ -44,6 +44,27 @@ __attribute__((always_inline)) INLINE static int feedback_do_feedback(
   return (sp->birth_time != -1.);
 }
 
+/**
+ * @brief Should this particle be doing any feedback-related operation?
+ *
+ * @param sp The #spart.
+ * @param time The current simulation time (Non-cosmological runs).
+ * @param cosmo The cosmological model (cosmological runs).
+ * @param with_cosmology Are we doing a cosmological run?
+ */
+__attribute__((always_inline)) INLINE static int feedback_is_active(
+    const struct spart* sp, const float time, const struct cosmology* cosmo,
+    const int with_cosmology) {
+
+  if (sp->birth_time == -1.) return 0;
+
+  if (with_cosmology) {
+    return ((float)cosmo->a) > sp->birth_scale_factor;
+  } else {
+    return time > sp->birth_time;
+  }
+}
+
 /**
  * @brief Prepares a s-particle for its feedback interactions
  *
@@ -139,7 +160,7 @@ __attribute__((always_inline)) INLINE static void feedback_evolve_spart(
     const double star_age_beg_step, const double dt) {
 
 #ifdef SWIFT_DEBUG_CHECKS
-  if (sp->birth_time == -1.) error("Evolving a star particle that shoul not!");
+  if (sp->birth_time == -1.) error("Evolving a star particle that should not!");
 #endif
 
   /* Compute amount of enrichment and feedback that needs to be done in this
@@ -151,4 +172,8 @@ __attribute__((always_inline)) INLINE static void feedback_evolve_spart(
   sp->mass -= sp->feedback_data.to_distribute.mass;
 }
 
+void feedback_struct_dump(const struct feedback_props* feedback, FILE* stream);
+
+void feedback_struct_restore(struct feedback_props* feedback, FILE* stream);
+
 #endif /* SWIFT_FEEDBACK_EAGLE_H */
diff --git a/src/feedback/EAGLE/feedback_iact.h b/src/feedback/EAGLE/feedback_iact.h
index 06fbd98a3cf5768a670506d689afffe9d95390a2..63d5332f4d7eed815d7e32119d3ce6db67eb3af6 100644
--- a/src/feedback/EAGLE/feedback_iact.h
+++ b/src/feedback/EAGLE/feedback_iact.h
@@ -114,6 +114,11 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx,
     Omega_frac = 0.f;
   }
 
+#ifdef SWIFT_DEBUG_CHECKS
+  if (Omega_frac < 0. || Omega_frac > 1.)
+    error("Invalid fraction of material to dsitribute.");
+#endif
+
   /* Update particle mass */
   const double current_mass = hydro_get_mass(pj);
   const double delta_mass = si->feedback_data.to_distribute.mass * Omega_frac;
@@ -227,10 +232,21 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx,
   const double current_kinetic_energy_gas =
       0.5 * cosmo->a2_inv * current_mass * current_v2;
 
-  /* Update velocity following injection of momentum */
-  xpj->v_full[0] += delta_mass * si->v[0] * new_mass_inv;
-  xpj->v_full[1] += delta_mass * si->v[1] * new_mass_inv;
-  xpj->v_full[2] += delta_mass * si->v[2] * new_mass_inv;
+  /* Compute the current thermal energy */
+  const double current_thermal_energy =
+      current_mass * hydro_get_physical_internal_energy(pj, xpj, cosmo);
+
+  /* Apply conservation of momentum */
+
+  /* Update velocity following change in gas mass */
+  xpj->v_full[0] *= current_mass * new_mass_inv;
+  xpj->v_full[1] *= current_mass * new_mass_inv;
+  xpj->v_full[2] *= current_mass * new_mass_inv;
+
+  /* Update velocity following addition of mass with different momentum */
+  xpj->v_full[0] += delta_mass * new_mass_inv * si->v[0];
+  xpj->v_full[1] += delta_mass * new_mass_inv * si->v[1];
+  xpj->v_full[2] += delta_mass * new_mass_inv * si->v[2];
 
   /* Compute the new kinetic energy */
   const double new_v2 = xpj->v_full[0] * xpj->v_full[0] +
@@ -238,32 +254,30 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx,
                         xpj->v_full[2] * xpj->v_full[2];
   const double new_kinetic_energy_gas = 0.5 * cosmo->a2_inv * new_mass * new_v2;
 
-  /* Injection energy */
+  /* Energy injected
+   * (thermal SNIa + kinetic energy of ejecta + kinetic energy of star) */
   const double injected_energy =
       si->feedback_data.to_distribute.energy * Omega_frac;
 
-  /* Total energy of that particle */
-  const double new_total_energy = current_kinetic_energy_gas + injected_energy;
+  /* Apply energy conservation to recover the new thermal energy of the gas */
+  const double new_thermal_energy = current_kinetic_energy_gas +
+                                    current_thermal_energy + injected_energy -
+                                    new_kinetic_energy_gas;
 
-  /* Thermal energy of the particle */
-  const double thermal_energy = new_total_energy - new_kinetic_energy_gas;
-  const double delta_u_enrich = thermal_energy / new_mass;
-
-  /* Energy feedback (ejecta energy + SNIa)*/
-  const double u_init_enrich =
-      hydro_get_physical_internal_energy(pj, xpj, cosmo);
+  /* Convert this to a specific thermal energy */
+  const double u_new_enrich = new_thermal_energy * new_mass_inv;
 
 #ifdef SWIFT_DEBUG_CHECKS
-  if (delta_u_enrich < -1e-3 * u_init_enrich)
-    error("Removing energy from the system.");
+  if (new_thermal_energy < 0.99 * current_thermal_energy)
+    error("Enrichment is cooling the gas");
 #endif
 
-  /* Do the energy injection.
-   * Note: We take a max() here just to be safe of rounding errors. */
-  const double u_new_enrich = u_init_enrich + max(delta_u_enrich, 0.);
+  /* Do the energy injection. */
   hydro_set_physical_internal_energy(pj, xpj, cosmo, u_new_enrich);
   hydro_set_drifted_physical_internal_energy(pj, cosmo, u_new_enrich);
 
+  /* Finally, SNII stochastic feedback */
+
   /* Get the SNII feedback properties */
   const float prob = si->feedback_data.to_distribute.SNII_heating_probability;
 
diff --git a/src/feedback/EAGLE/imf.h b/src/feedback/EAGLE/imf.h
index 5510c95ca197170c01b24fbe10539d1c7010541f..767b2c312bfc0a5041da0c6be1db9e356bc829ad 100644
--- a/src/feedback/EAGLE/imf.h
+++ b/src/feedback/EAGLE/imf.h
@@ -23,6 +23,7 @@
 #include <string.h>
 
 /* Local includes. */
+#include "exp10.h"
 #include "inline.h"
 #include "interpolate.h"
 #include "minmax.h"
diff --git a/src/feedback/none/feedback.h b/src/feedback/none/feedback.h
index de37015a9974df93d7dee81f7e386213f83b59bb..dd2ffd3d89cecffd024a7987d73e9d178165d7c1 100644
--- a/src/feedback/none/feedback.h
+++ b/src/feedback/none/feedback.h
@@ -45,6 +45,25 @@ __attribute__((always_inline)) INLINE static int feedback_do_feedback(
   return 0;
 }
 
+/**
+ * @brief Should this particle be doing any feedback-related operation?
+ *
+ * Note: Since this 'none' feedback mode is used for testing the neighbour
+ * loops only, we want to always do feedback irrespective of the particle
+ * or of the system's state.
+ *
+ * @param sp The #spart.
+ * @param time The current simulation time (Non-cosmological runs).
+ * @param cosmo The cosmological model (cosmological runs).
+ * @param with_cosmology Are we doing a cosmological run?
+ */
+__attribute__((always_inline)) INLINE static int feedback_is_active(
+    const struct spart* sp, const float time, const struct cosmology* cosmo,
+    const int with_cosmology) {
+
+  return 1;
+}
+
 /**
  * @brief Prepares a star's feedback field before computing what
  * needs to be distributed.
@@ -95,4 +114,24 @@ __attribute__((always_inline)) INLINE static void feedback_evolve_spart(
     const struct cosmology* cosmo, const struct unit_system* us,
     const double star_age_beg_step, const double dt) {}
 
+/**
+ * @brief Write a feedback struct to the given FILE as a stream of bytes.
+ *
+ * @param feedback the struct
+ * @param stream the file stream
+ */
+static INLINE void feedback_struct_dump(const struct feedback_props* feedback,
+                                        FILE* stream) {}
+
+/**
+ * @brief Restore a hydro_props struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param feedback the struct
+ * @param stream the file stream
+ * @param cosmo #cosmology structure
+ */
+static INLINE void feedback_struct_restore(struct feedback_props* feedback,
+                                           FILE* stream) {}
+
 #endif /* SWIFT_FEEDBACK_NONE_H */
diff --git a/src/memuse.h b/src/memuse.h
index 751b7195aa8ad705d03b2490876993331e495c15..dce03e949d8991ece16f1e31a14dd20ca89f26bc 100644
--- a/src/memuse.h
+++ b/src/memuse.h
@@ -120,6 +120,44 @@ __attribute__((always_inline)) inline void *swift_calloc(const char *label,
   return memptr;
 }
 
+/**
+ * @brief reallocate memory. The use and results are the same as the
+ *        realloc function. This function should be used for any
+ *        _significant_ allocations and consistently labelled.
+ *        Do not use this function for small or high frequency
+ *        allocations in production code.
+ *
+ * @param label a symbolic label for the memory, i.e. "parts".
+ * @param ptr pointer to memory that may need reallocating or allocating.
+ * @param size the quantity of bytes that should be available.
+ * @result pointer to the allocated memory or NULL on failure.
+ */
+__attribute__((always_inline)) inline void *swift_realloc(const char *label,
+                                                          void *ptr,
+                                                          size_t size) {
+  void *memptr = realloc(ptr, size);
+#ifdef SWIFT_MEMUSE_REPORTS
+  if (memptr != NULL) {
+
+    /* On reallocation we free the previous memory. */
+    if (ptr != NULL && ptr != memptr) memuse_log_allocation(label, ptr, 0, 0);
+    memuse_log_allocation(label, memptr, 1, size);
+
+  } else {
+
+    /* Can be NULL if size is zero, we have just freed the memory. */
+    if (size == 0) {
+      memuse_log_allocation(label, ptr, 0, 0);
+    } else {
+
+      /* Failed allocations are interesting as well. */
+      memuse_log_allocation(label, NULL, -1, size);
+    }
+  }
+#endif
+  return memptr;
+}
+
 /**
  * @brief free aligned memory. The use and results are the same as the
  *        free function. The label should match a prior call to swift_memalign
diff --git a/src/partition.c b/src/partition.c
index e4cfd9dd142739d9508af133617439db7ab6eef9..2ee321c872e6c34ff4ea82a9369c4637d56bb1d9 100644
--- a/src/partition.c
+++ b/src/partition.c
@@ -184,68 +184,142 @@ static void split_vector(struct space *s, int nregions, int *samplecells) {
  *
  * See the ParMETIS and METIS manuals if you want to understand this
  * format. The cell graph consists of all nodes as vertices with edges as the
- * connections to all neighbours, so we have 26 per vertex. Note you will
+ * connections to all neighbours, so we have 26 per vertex for periodic
+ * boundary, fewer than 26 on the space edges when non-periodic. Note you will
  * also need an xadj array, for METIS that would be:
  *
  *   xadj[0] = 0;
  *   for (int k = 0; k < s->nr_cells; k++) xadj[k + 1] = xadj[k] + 26;
  *
- * but each rank needs a different xadj when using ParMETIS.
+ * but each rank needs a different xadj when using ParMETIS (each segment
+ * should be rezeroed).
  *
  * @param s the space of cells.
+ * @param periodic whether to assume a periodic space (fixed 26 edges).
+ * @param weights_e the edge weights for the cells, if used. On input
+ *                  assumed to be ordered with a fixed 26 edges per cell, so
+ *                  will need reordering for non-periodic spaces.
  * @param adjncy the adjncy array to fill, must be of size 26 * the number of
  *               cells in the space.
+ * @param nadjcny number of adjncy elements used, can be less if not periodic.
  * @param xadj the METIS xadj array to fill, must be of size
  *             number of cells in space + 1. NULL for not used.
+ * @param nxadj the number of xadj element used.
  */
-static void graph_init(struct space *s, idx_t *adjncy, idx_t *xadj) {
+static void graph_init(struct space *s, int periodic, idx_t *weights_e,
+                       idx_t *adjncy, int *nadjcny, idx_t *xadj, int *nxadj) {
 
   /* Loop over all cells in the space. */
-  int cid = 0;
-  for (int l = 0; l < s->cdim[0]; l++) {
-    for (int m = 0; m < s->cdim[1]; m++) {
-      for (int n = 0; n < s->cdim[2]; n++) {
-
-        /* Visit all neighbours of this cell, wrapping space at edges. */
-        int p = 0;
-        for (int i = -1; i <= 1; i++) {
-          int ii = l + i;
-          if (ii < 0)
-            ii += s->cdim[0];
-          else if (ii >= s->cdim[0])
-            ii -= s->cdim[0];
-          for (int j = -1; j <= 1; j++) {
-            int jj = m + j;
-            if (jj < 0)
-              jj += s->cdim[1];
-            else if (jj >= s->cdim[1])
-              jj -= s->cdim[1];
-            for (int k = -1; k <= 1; k++) {
-              int kk = n + k;
-              if (kk < 0)
-                kk += s->cdim[2];
-              else if (kk >= s->cdim[2])
-                kk -= s->cdim[2];
-
-              /* If not self, record id of neighbour. */
-              if (i || j || k) {
-                adjncy[cid * 26 + p] = cell_getid(s->cdim, ii, jj, kk);
-                p++;
+  *nadjcny = 0;
+  if (periodic) {
+    int cid = 0;
+    for (int l = 0; l < s->cdim[0]; l++) {
+      for (int m = 0; m < s->cdim[1]; m++) {
+        for (int n = 0; n < s->cdim[2]; n++) {
+
+          /* Visit all neighbours of this cell, wrapping space at edges. */
+          int p = 0;
+          for (int i = -1; i <= 1; i++) {
+            int ii = l + i;
+            if (ii < 0)
+              ii += s->cdim[0];
+            else if (ii >= s->cdim[0])
+              ii -= s->cdim[0];
+            for (int j = -1; j <= 1; j++) {
+              int jj = m + j;
+              if (jj < 0)
+                jj += s->cdim[1];
+              else if (jj >= s->cdim[1])
+                jj -= s->cdim[1];
+              for (int k = -1; k <= 1; k++) {
+                int kk = n + k;
+                if (kk < 0)
+                  kk += s->cdim[2];
+                else if (kk >= s->cdim[2])
+                  kk -= s->cdim[2];
+
+                /* If not self, record id of neighbour. */
+                if (i || j || k) {
+                  adjncy[cid * 26 + p] = cell_getid(s->cdim, ii, jj, kk);
+                  p++;
+                }
               }
             }
           }
-        }
 
-        /* Next cell. */
-        cid++;
+          /* Next cell. */
+          cid++;
+        }
       }
     }
-  }
+    *nadjcny = cid * 26;
+
+    /* If given set METIS xadj. */
+    if (xadj != NULL) {
+      xadj[0] = 0;
+      for (int k = 0; k < s->nr_cells; k++) xadj[k + 1] = xadj[k] + 26;
+      *nxadj = s->nr_cells;
+    }
+
+  } else {
+
+    /* Non periodic. */
+    int ind = 0;
+    int cid = 0;
+    if (xadj != NULL) xadj[0] = 0;
+
+    /* May need to reorder weights, shuffle in place as moving to left. */
+    int shuffle = 0;
+    if (weights_e != NULL) shuffle = 1;
+
+    for (int l = 0; l < s->cdim[0]; l++) {
+      for (int m = 0; m < s->cdim[1]; m++) {
+        for (int n = 0; n < s->cdim[2]; n++) {
+
+          /* Visit all neighbours of this cell. */
+          int p = 0;
+          for (int i = -1; i <= 1; i++) {
+            int ii = l + i;
+            if (ii >= 0 && ii < s->cdim[0]) {
+              for (int j = -1; j <= 1; j++) {
+                int jj = m + j;
+                if (jj >= 0 && jj < s->cdim[1]) {
+                  for (int k = -1; k <= 1; k++) {
+                    int kk = n + k;
+                    if (kk >= 0 && kk < s->cdim[2]) {
+
+                      /* If not self, record id of neighbour. */
+                      if (i || j || k) {
+                        adjncy[ind] = cell_getid(s->cdim, ii, jj, kk);
+
+                        if (shuffle) {
+                          /* Keep this weight, need index for periodic
+                           * version for input weights... */
+                          int oldp = ((i + 1) * 9 + (j + 1) * 3 + (k + 1));
+                          oldp = oldp - (oldp / 14);
+                          weights_e[ind] = weights_e[cid * 26 + oldp];
+                        }
+
+                        ind++;
+                        p++;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
 
-  /* If given set METIS xadj. */
-  if (xadj != NULL) {
-    xadj[0] = 0;
-    for (int k = 0; k < s->nr_cells; k++) xadj[k + 1] = xadj[k] + 26;
+          /* Keep xadj in sync. */
+          if (xadj != NULL) {
+            xadj[cid + 1] = xadj[cid] + p;
+          }
+          cid++;
+        }
+      }
+    }
+    *nadjcny = ind;
+    *nxadj = cid;
   }
 }
 #endif
@@ -619,42 +693,27 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
     idx_t *full_xadj = NULL;
     if ((full_xadj =
              (idx_t *)malloc(sizeof(idx_t) * (ncells + nregions + 1))) == NULL)
-      error("Failed to allocate xadj buffer.");
+      error("Failed to allocate full xadj buffer.");
+    idx_t *std_xadj = NULL;
+    if ((std_xadj = (idx_t *)malloc(sizeof(idx_t) * (ncells + 1))) == NULL)
+      error("Failed to allocate std xadj buffer.");
     idx_t *full_adjncy = NULL;
     if ((full_adjncy = (idx_t *)malloc(sizeof(idx_t) * 26 * ncells)) == NULL)
-      error("Failed to allocate adjncy array.");
+      error("Failed to allocate full adjncy array.");
     idx_t *full_weights_v = NULL;
     if (weights_v != NULL)
       if ((full_weights_v = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL)
-        error("Failed to allocate vertex weights array");
+        error("Failed to allocate full vertex weights array");
     idx_t *full_weights_e = NULL;
     if (weights_e != NULL)
       if ((full_weights_e = (idx_t *)malloc(26 * sizeof(idx_t) * ncells)) ==
           NULL)
-        error("Failed to allocate edge weights array");
+        error("Failed to allocate full edge weights array");
 
     idx_t *full_regionid = NULL;
     if (refine) {
       if ((full_regionid = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL)
-        error("Failed to allocate regionid array");
-    }
-
-    /* Define the cell graph. */
-    graph_init(s, full_adjncy, NULL);
-
-    /* xadj is set for each rank, different to serial version in that each
-     * rank starts with 0 */
-    for (int rank = 0, j = 0; rank < nregions; rank++) {
-
-      /* Number of vertices for this rank. */
-      int nvt = vtxdist[rank + 1] - vtxdist[rank];
-
-      /* Start from 0, and step forward 26 edges each value. */
-      full_xadj[j] = 0;
-      for (int k = 0; k <= nvt; k++) {
-        full_xadj[j + 1] = full_xadj[j] + 26;
-        j++;
-      }
+        error("Failed to allocate full regionid array");
     }
 
     /* Init the vertex weights array. */
@@ -663,7 +722,7 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
         if (vertexw[k] > 1) {
           full_weights_v[k] = vertexw[k];
         } else {
-          full_weights_v[k] = 1;
+          full_weights_v[k] = 0;
         }
       }
 
@@ -675,7 +734,7 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
           message("Input vertex weight out of range: %ld", (long)vertexw[k]);
           failed++;
         }
-        if (full_weights_v[k] < 1) {
+        if (full_weights_v[k] < 0) {
           message("Used vertex weight  out of range: %" PRIDX,
                   full_weights_v[k]);
           failed++;
@@ -687,7 +746,7 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
 
     /* Init the edges weights array. */
     if (edgew != NULL) {
-      for (int k = 0; k < 26 * ncells; k++) {
+      for (int k = 0; k < ncells * 26; k++) {
         if (edgew[k] > 1) {
           full_weights_e[k] = edgew[k];
         } else {
@@ -698,7 +757,7 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
 #ifdef SWIFT_DEBUG_CHECKS
       /* Check weights are all in range. */
       int failed = 0;
-      for (int k = 0; k < 26 * ncells; k++) {
+      for (int k = 0; k < ncells * 26; k++) {
 
         if ((idx_t)edgew[k] < 0) {
           message("Input edge weight out of range: %ld", (long)edgew[k]);
@@ -713,30 +772,47 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
 #endif
     }
 
-    /* Dump graphs to disk files for testing. ParMETIS xadj isn't right for
-     * a dump, so make a serial-like version. */
-    /*{
-      idx_t *tmp_xadj =
-          (idx_t *)malloc(sizeof(idx_t) * (ncells + nregions + 1));
-      tmp_xadj[0] = 0;
-      for (int k = 0; k < ncells; k++) tmp_xadj[k + 1] = tmp_xadj[k] + 26;
-      dumpMETISGraph("parmetis_graph", ncells, 1, tmp_xadj, full_adjncy,
-                     full_weights_v, NULL, full_weights_e);
-      free(tmp_xadj);
-      }*/
+    /* Define the cell graph. Keeping the edge weights association. */
+    int nadjcny = 0;
+    int nxadj = 0;
+    graph_init(s, s->periodic, full_weights_e, full_adjncy, &nadjcny, std_xadj,
+               &nxadj);
+
+    /* Dump graphs to disk files for testing. */
+    /*dumpMETISGraph("parmetis_graph", ncells, 1, std_xadj, full_adjncy,
+      full_weights_v, NULL, full_weights_e);*/
+
+    /* xadj is set for each rank, different to serial version in that each
+     * rank starts with 0, so we need to re-offset. */
+    for (int rank = 0, i = 0, j = 0; rank < nregions; rank++) {
+
+      /* Number of vertices for this rank. */
+      int nvt = vtxdist[rank + 1] - vtxdist[rank];
+
+      /* Each xadj section starts at 0 and terminates like a complete one. */
+      int offset = std_xadj[j];
+      for (int k = 0; k < nvt; k++) {
+        full_xadj[i] = std_xadj[j] - offset;
+        j++;
+        i++;
+      }
+      full_xadj[i] = std_xadj[j] - offset;
+      i++;
+    }
 
     /* Send ranges to the other ranks and keep our own. */
     for (int rank = 0, j1 = 0, j2 = 0, j3 = 0; rank < nregions; rank++) {
       int nvt = vtxdist[rank + 1] - vtxdist[rank];
+      int nedge = std_xadj[vtxdist[rank + 1]] - std_xadj[vtxdist[rank]];
 
       if (refine)
         for (int i = 0; i < nvt; i++) full_regionid[j3 + i] = celllist[j3 + i];
 
       if (rank == 0) {
         memcpy(xadj, &full_xadj[j1], sizeof(idx_t) * (nvt + 1));
-        memcpy(adjncy, &full_adjncy[j2], sizeof(idx_t) * nvt * 26);
+        memcpy(adjncy, &full_adjncy[j2], sizeof(idx_t) * nedge);
         if (weights_e != NULL)
-          memcpy(weights_e, &full_weights_e[j2], sizeof(idx_t) * nvt * 26);
+          memcpy(weights_e, &full_weights_e[j2], sizeof(idx_t) * nedge);
         if (weights_v != NULL)
           memcpy(weights_v, &full_weights_v[j3], sizeof(idx_t) * nvt);
         if (refine) memcpy(regionid, full_regionid, sizeof(idx_t) * nvt);
@@ -759,7 +835,9 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
         if (res != MPI_SUCCESS) mpi_error(res, "Failed to send graph data");
       }
       j1 += nvt + 1;
-      j2 += nvt * 26;
+
+      /* Note we send 26 edges, but only increment by the correct number. */
+      j2 += nedge;
       j3 += nvt;
     }
 
@@ -779,6 +857,7 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
     if (weights_v != NULL) free(full_weights_v);
     if (weights_e != NULL) free(full_weights_e);
     free(full_xadj);
+    free(std_xadj);
     free(full_adjncy);
     if (refine) free(full_regionid);
 
@@ -944,7 +1023,7 @@ static void pick_parmetis(int nodeID, struct space *s, int nregions,
     int bad = 0;
     for (int k = 0; k < ncells; k++) {
       if (newcelllist[k] < 0 || newcelllist[k] >= nregions) {
-        message("Got bad nodeID %" PRIDX " for cell %i.", newcelllist[k], k);
+        message("Got bad nodeID %d for cell %i.", newcelllist[k], k);
         bad++;
       }
     }
@@ -1037,7 +1116,7 @@ static void pick_metis(int nodeID, struct space *s, int nregions,
   /* Only one node needs to calculate this. */
   if (nodeID == 0) {
 
-    /* Allocate weights and adjacency arrays . */
+    /* Allocate adjacency and weights arrays . */
     idx_t *xadj;
     if ((xadj = (idx_t *)malloc(sizeof(idx_t) * (ncells + 1))) == NULL)
       error("Failed to allocate xadj buffer.");
@@ -1056,16 +1135,13 @@ static void pick_metis(int nodeID, struct space *s, int nregions,
     if ((regionid = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL)
       error("Failed to allocate regionid array");
 
-    /* Define the cell graph. */
-    graph_init(s, adjncy, xadj);
-
     /* Init the vertex weights array. */
     if (vertexw != NULL) {
       for (int k = 0; k < ncells; k++) {
         if (vertexw[k] > 1) {
           weights_v[k] = vertexw[k];
         } else {
-          weights_v[k] = 1;
+          weights_v[k] = 0;
         }
       }
 
@@ -1077,7 +1153,7 @@ static void pick_metis(int nodeID, struct space *s, int nregions,
           message("Input vertex weight out of range: %ld", (long)vertexw[k]);
           failed++;
         }
-        if (weights_v[k] < 1) {
+        if (weights_v[k] < 0) {
           message("Used vertex weight  out of range: %" PRIDX, weights_v[k]);
           failed++;
         }
@@ -1115,6 +1191,11 @@ static void pick_metis(int nodeID, struct space *s, int nregions,
 #endif
     }
 
+    /* Define the cell graph. Keeping the edge weights association. */
+    int nadjcny = 0;
+    int nxadj = 0;
+    graph_init(s, s->periodic, weights_e, adjncy, &nadjcny, xadj, &nxadj);
+
     /* Set the METIS options. */
     idx_t options[METIS_NOPTIONS];
     METIS_SetDefaultOptions(options);
@@ -1266,6 +1347,7 @@ static void partition_gather_weights(void *map_data, int num_elements,
 
     /* Pair? */
     else if (t->type == task_type_pair || (t->type == task_type_sub_pair)) {
+
       /* In-cell pair? */
       if (ci == cj) {
         /* Add weight to vertex for ci. */
@@ -1275,6 +1357,7 @@ static void partition_gather_weights(void *map_data, int num_elements,
 
       /* Distinct cells. */
       else {
+
         /* Index of the jth cell. */
         int cjd = cj - cells;
 
@@ -1305,6 +1388,7 @@ static void partition_gather_weights(void *map_data, int num_elements,
               break;
             }
           }
+
           if (ik != -1 && jk != -1) {
 
             if (timebins) {
@@ -1362,7 +1446,10 @@ static void repart_edge_metis(int vweights, int eweights, int timebins,
   idx_t *inds;
   if ((inds = (idx_t *)malloc(sizeof(idx_t) * 26 * nr_cells)) == NULL)
     error("Failed to allocate the inds array");
-  graph_init(s, inds, NULL);
+  int nadjcny = 0;
+  int nxadj = 0;
+  graph_init(s, 1 /* periodic */, NULL /* no edge weights */, inds, &nadjcny,
+             NULL /* no xadj needed */, &nxadj);
 
   /* Allocate and init weights. */
   double *weights_v = NULL;
@@ -1734,15 +1821,12 @@ void partition_initial_partition(struct partition *initial_partition,
       error("Grid size does not match number of nodes.");
 
     /* Run through the cells and set their nodeID. */
-    // message("s->dim = [%e,%e,%e]", s->dim[0], s->dim[1], s->dim[2]);
     for (k = 0; k < s->nr_cells; k++) {
       c = &s->cells_top[k];
       for (j = 0; j < 3; j++)
         ind[j] = c->loc[j] / s->dim[j] * initial_partition->grid[j];
       c->nodeID = ind[0] + initial_partition->grid[0] *
                                (ind[1] + initial_partition->grid[1] * ind[2]);
-      // message("cell at [%e,%e,%e]: ind = [%i,%i,%i], nodeID = %i", c->loc[0],
-      // c->loc[1], c->loc[2], ind[0], ind[1], ind[2], c->nodeID);
     }
 
     /* The grid technique can fail, so check for this before proceeding. */
diff --git a/src/runner.c b/src/runner.c
index 1a15ce53711bc342eb5cfe11fd5abb5393133c22..ff2564d8b4b2fb4d6699b295c805cbfd2e6cbd41 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -185,7 +185,8 @@ void runner_do_stars_ghost(struct runner *r, struct cell *c, int timer) {
     if ((right = (float *)malloc(sizeof(float) * c->stars.count)) == NULL)
       error("Can't allocate memory for right.");
     for (int k = 0; k < c->stars.count; k++)
-      if (spart_is_active(&sparts[k], e)) {
+      if (spart_is_active(&sparts[k], e) &&
+          feedback_is_active(&sparts[k], e->time, cosmo, with_cosmology)) {
         sid[scount] = k;
         h_0[scount] = sparts[k].h;
         left[scount] = 0.f;
@@ -378,7 +379,7 @@ void runner_do_stars_ghost(struct runner *r, struct cell *c, int timer) {
             star_age_end_of_step = cosmology_get_delta_time_from_scale_factors(
                 cosmo, sp->birth_scale_factor, (float)cosmo->a);
           } else {
-            star_age_end_of_step = e->time - sp->birth_time;
+            star_age_end_of_step = (float)e->time - sp->birth_time;
           }
 
           /* Has this star been around for a while ? */
@@ -441,7 +442,7 @@ void runner_do_stars_ghost(struct runner *r, struct cell *c, int timer) {
             /* Otherwise, sub-self interaction? */
             else if (l->t->type == task_type_sub_self)
               runner_dosub_subset_stars_density(r, finger, sparts, sid, scount,
-                                                NULL, -1, 1);
+                                                NULL, 1);
 
             /* Otherwise, sub-pair interaction? */
             else if (l->t->type == task_type_sub_pair) {
@@ -449,10 +450,10 @@ void runner_do_stars_ghost(struct runner *r, struct cell *c, int timer) {
               /* Left or right? */
               if (l->t->ci == finger)
                 runner_dosub_subset_stars_density(r, finger, sparts, sid,
-                                                  scount, l->t->cj, -1, 1);
+                                                  scount, l->t->cj, 1);
               else
                 runner_dosub_subset_stars_density(r, finger, sparts, sid,
-                                                  scount, l->t->ci, -1, 1);
+                                                  scount, l->t->ci, 1);
             }
           }
         }
@@ -1608,14 +1609,12 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
         const float h_init = h_0[i];
         const float h_old = p->h;
         const float h_old_dim = pow_dimension(h_old);
-        // const float h_old_inv_dim = pow_dimension(1.f / h_old);
         const float h_old_dim_minus_one = pow_dimension_minus_one(h_old);
 
         float h_new;
         int has_no_neighbours = 0;
 
-        if (p->density.wcount == 0.f) {
-          // 1e-5 * kernel_root * h_old_inv_dim) { /* No neighbours case */
+        if (p->density.wcount == 0.f) { /* No neighbours case */
 
           /* Flag that there were no neighbours */
           has_no_neighbours = 1;
@@ -1898,7 +1897,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
             /* Otherwise, sub-self interaction? */
             else if (l->t->type == task_type_sub_self)
               runner_dosub_subset_density(r, finger, parts, pid, count, NULL,
-                                          -1, 1);
+                                          1);
 
             /* Otherwise, sub-pair interaction? */
             else if (l->t->type == task_type_sub_pair) {
@@ -1906,10 +1905,10 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
               /* Left or right? */
               if (l->t->ci == finger)
                 runner_dosub_subset_density(r, finger, parts, pid, count,
-                                            l->t->cj, -1, 1);
+                                            l->t->cj, 1);
               else
                 runner_dosub_subset_density(r, finger, parts, pid, count,
-                                            l->t->ci, -1, 1);
+                                            l->t->ci, 1);
             }
           }
         }
@@ -3578,19 +3577,19 @@ void *runner_main(void *data) {
 
         case task_type_sub_pair:
           if (t->subtype == task_subtype_density)
-            runner_dosub_pair1_density(r, ci, cj, t->flags, 1);
+            runner_dosub_pair1_density(r, ci, cj, 1);
 #ifdef EXTRA_HYDRO_LOOP
           else if (t->subtype == task_subtype_gradient)
-            runner_dosub_pair1_gradient(r, ci, cj, t->flags, 1);
+            runner_dosub_pair1_gradient(r, ci, cj, 1);
 #endif
           else if (t->subtype == task_subtype_force)
-            runner_dosub_pair2_force(r, ci, cj, t->flags, 1);
+            runner_dosub_pair2_force(r, ci, cj, 1);
           else if (t->subtype == task_subtype_limiter)
-            runner_dosub_pair2_limiter(r, ci, cj, t->flags, 1);
+            runner_dosub_pair2_limiter(r, ci, cj, 1);
           else if (t->subtype == task_subtype_stars_density)
-            runner_dosub_pair_stars_density(r, ci, cj, t->flags, 1);
+            runner_dosub_pair_stars_density(r, ci, cj, 1);
           else if (t->subtype == task_subtype_stars_feedback)
-            runner_dosub_pair_stars_feedback(r, ci, cj, t->flags, 1);
+            runner_dosub_pair_stars_feedback(r, ci, cj, 1);
           else
             error("Unknown/invalid task subtype (%d).", t->subtype);
           break;
diff --git a/src/runner_doiact.h b/src/runner_doiact.h
index 854f8b898df93be93bb020a46606a415170fe980..635d41a95d320dd99eb806c9aec61127e8c7e42d 100644
--- a/src/runner_doiact.h
+++ b/src/runner_doiact.h
@@ -2216,13 +2216,12 @@ void DOSELF2_BRANCH(struct runner *r, struct cell *c) {
  * @param r The #runner.
  * @param ci The first #cell.
  * @param cj The second #cell.
- * @param sid The direction linking the cells
  * @param gettimer Do we have a timer ?
  *
  * @todo Hard-code the sid on the recursive calls to avoid the
  * redundant computations to find the sid on-the-fly.
  */
-void DOSUB_PAIR1(struct runner *r, struct cell *ci, struct cell *cj, int sid,
+void DOSUB_PAIR1(struct runner *r, struct cell *ci, struct cell *cj,
                  int gettimer) {
 
   struct space *s = r->e->s;
@@ -2234,210 +2233,20 @@ void DOSUB_PAIR1(struct runner *r, struct cell *ci, struct cell *cj, int sid,
   if (!cell_is_active_hydro(ci, e) && !cell_is_active_hydro(cj, e)) return;
   if (ci->hydro.count == 0 || cj->hydro.count == 0) return;
 
-  /* Get the type of pair if not specified explicitly. */
+  /* Get the type of pair and flip ci/cj if needed. */
   double shift[3];
-  sid = space_getsid(s, &ci, &cj, shift);
+  const int sid = space_getsid(s, &ci, &cj, shift);
 
   /* Recurse? */
   if (cell_can_recurse_in_pair_hydro_task(ci) &&
       cell_can_recurse_in_pair_hydro_task(cj)) {
-
-    /* Different types of flags. */
-    switch (sid) {
-
-      /* Regular sub-cell interactions of a single cell. */
-      case 0: /* (  1 ,  1 ,  1 ) */
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        break;
-
-      case 1: /* (  1 ,  1 ,  0 ) */
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        break;
-
-      case 2: /* (  1 ,  1 , -1 ) */
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        break;
-
-      case 3: /* (  1 ,  0 ,  1 ) */
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        break;
-
-      case 4: /* (  1 ,  0 ,  0 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[0], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[1], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[2], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[1], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[3], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[2], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[3], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[3], -1, 0);
-        break;
-
-      case 5: /* (  1 ,  0 , -1 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[1], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[3], -1, 0);
-        break;
-
-      case 6: /* (  1 , -1 ,  1 ) */
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        break;
-
-      case 7: /* (  1 , -1 ,  0 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[2], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[3], -1, 0);
-        break;
-
-      case 8: /* (  1 , -1 , -1 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        break;
-
-      case 9: /* (  0 ,  1 ,  1 ) */
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        break;
-
-      case 10: /* (  0 ,  1 ,  0 ) */
-        if (ci->progeny[2] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[2], cj->progeny[0], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[2], cj->progeny[1], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[2], cj->progeny[4], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[2], cj->progeny[5], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[1], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[5], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[4], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[5], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[5], -1, 0);
-        break;
-
-      case 11: /* (  0 ,  1 , -1 ) */
-        if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[2], cj->progeny[1], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[2], cj->progeny[5], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[6], cj->progeny[5], -1, 0);
-        break;
-
-      case 12: /* (  0 ,  0 ,  1 ) */
-        if (ci->progeny[1] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[1], cj->progeny[0], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[1], cj->progeny[2], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[1], cj->progeny[4], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[1], cj->progeny[6], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[2], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[3], cj->progeny[6], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[4], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[5], cj->progeny[6], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1(r, ci->progeny[7], cj->progeny[6], -1, 0);
-        break;
+    struct cell_split_pair *csp = &cell_split_pairs[sid];
+    for (int k = 0; k < csp->count; k++) {
+      const int pid = csp->pairs[k].pid;
+      const int pjd = csp->pairs[k].pjd;
+      if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL)
+        DOSUB_PAIR1(r, ci->progeny[pid], cj->progeny[pjd], 0);
     }
-
   }
 
   /* Otherwise, compute the pair directly. */
@@ -2491,7 +2300,7 @@ void DOSUB_SELF1(struct runner *r, struct cell *ci, int gettimer) {
         DOSUB_SELF1(r, ci->progeny[k], 0);
         for (int j = k + 1; j < 8; j++)
           if (ci->progeny[j] != NULL)
-            DOSUB_PAIR1(r, ci->progeny[k], ci->progeny[j], -1, 0);
+            DOSUB_PAIR1(r, ci->progeny[k], ci->progeny[j], 0);
       }
   }
 
@@ -2513,13 +2322,12 @@ void DOSUB_SELF1(struct runner *r, struct cell *ci, int gettimer) {
  * @param r The #runner.
  * @param ci The first #cell.
  * @param cj The second #cell.
- * @param sid The direction linking the cells
  * @param gettimer Do we have a timer ?
  *
  * @todo Hard-code the sid on the recursive calls to avoid the
  * redundant computations to find the sid on-the-fly.
  */
-void DOSUB_PAIR2(struct runner *r, struct cell *ci, struct cell *cj, int sid,
+void DOSUB_PAIR2(struct runner *r, struct cell *ci, struct cell *cj,
                  int gettimer) {
 
   const struct engine *e = r->e;
@@ -2531,210 +2339,20 @@ void DOSUB_PAIR2(struct runner *r, struct cell *ci, struct cell *cj, int sid,
   if (!cell_is_active_hydro(ci, e) && !cell_is_active_hydro(cj, e)) return;
   if (ci->hydro.count == 0 || cj->hydro.count == 0) return;
 
-  /* Get the type of pair if not specified explicitly. */
+  /* Get the type of pair and flip ci/cj if needed. */
   double shift[3];
-  sid = space_getsid(s, &ci, &cj, shift);
+  const int sid = space_getsid(s, &ci, &cj, shift);
 
   /* Recurse? */
   if (cell_can_recurse_in_pair_hydro_task(ci) &&
       cell_can_recurse_in_pair_hydro_task(cj)) {
-
-    /* Different types of flags. */
-    switch (sid) {
-
-      /* Regular sub-cell interactions of a single cell. */
-      case 0: /* (  1 ,  1 ,  1 ) */
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        break;
-
-      case 1: /* (  1 ,  1 ,  0 ) */
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        break;
-
-      case 2: /* (  1 ,  1 , -1 ) */
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        break;
-
-      case 3: /* (  1 ,  0 ,  1 ) */
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        break;
-
-      case 4: /* (  1 ,  0 ,  0 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[0], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[1], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[2], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[1], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[3], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[2], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[3], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[3], -1, 0);
-        break;
-
-      case 5: /* (  1 ,  0 , -1 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[1], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[3], -1, 0);
-        break;
-
-      case 6: /* (  1 , -1 ,  1 ) */
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        break;
-
-      case 7: /* (  1 , -1 ,  0 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[2], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[3], -1, 0);
-        break;
-
-      case 8: /* (  1 , -1 , -1 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        break;
-
-      case 9: /* (  0 ,  1 ,  1 ) */
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        break;
-
-      case 10: /* (  0 ,  1 ,  0 ) */
-        if (ci->progeny[2] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[2], cj->progeny[0], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[2], cj->progeny[1], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[2], cj->progeny[4], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[2], cj->progeny[5], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[1], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[5], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[4], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[5], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[5], -1, 0);
-        break;
-
-      case 11: /* (  0 ,  1 , -1 ) */
-        if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[2], cj->progeny[1], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[2], cj->progeny[5], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[6], cj->progeny[5], -1, 0);
-        break;
-
-      case 12: /* (  0 ,  0 ,  1 ) */
-        if (ci->progeny[1] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[1], cj->progeny[0], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[1], cj->progeny[2], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[1], cj->progeny[4], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[1], cj->progeny[6], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[2], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[3], cj->progeny[6], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[4], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[5], cj->progeny[6], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR2(r, ci->progeny[7], cj->progeny[6], -1, 0);
-        break;
+    struct cell_split_pair *csp = &cell_split_pairs[sid];
+    for (int k = 0; k < csp->count; k++) {
+      const int pid = csp->pairs[k].pid;
+      const int pjd = csp->pairs[k].pjd;
+      if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL)
+        DOSUB_PAIR2(r, ci->progeny[pid], cj->progeny[pjd], 0);
     }
-
   }
 
   /* Otherwise, compute the pair directly. */
@@ -2788,7 +2406,7 @@ void DOSUB_SELF2(struct runner *r, struct cell *ci, int gettimer) {
         DOSUB_SELF2(r, ci->progeny[k], 0);
         for (int j = k + 1; j < 8; j++)
           if (ci->progeny[j] != NULL)
-            DOSUB_PAIR2(r, ci->progeny[k], ci->progeny[j], -1, 0);
+            DOSUB_PAIR2(r, ci->progeny[k], ci->progeny[j], 0);
       }
 
   }
@@ -2801,7 +2419,7 @@ void DOSUB_SELF2(struct runner *r, struct cell *ci, int gettimer) {
 }
 
 void DOSUB_SUBSET(struct runner *r, struct cell *ci, struct part *parts,
-                  int *ind, int count, struct cell *cj, int sid, int gettimer) {
+                  int *ind, int count, struct cell *cj, int gettimer) {
 
   const struct engine *e = r->e;
   struct space *s = e->s;
@@ -2836,10 +2454,10 @@ void DOSUB_SUBSET(struct runner *r, struct cell *ci, struct part *parts,
     if (cell_can_recurse_in_self_hydro_task(ci)) {
 
       /* Loop over all progeny. */
-      DOSUB_SUBSET(r, sub, parts, ind, count, NULL, -1, 0);
+      DOSUB_SUBSET(r, sub, parts, ind, count, NULL, 0);
       for (int j = 0; j < 8; j++)
         if (ci->progeny[j] != sub && ci->progeny[j] != NULL)
-          DOSUB_SUBSET(r, sub, parts, ind, count, ci->progeny[j], -1, 0);
+          DOSUB_SUBSET(r, sub, parts, ind, count, ci->progeny[j], 0);
 
     }
 
@@ -2855,510 +2473,21 @@ void DOSUB_SUBSET(struct runner *r, struct cell *ci, struct part *parts,
     if (cell_can_recurse_in_pair_hydro_task(ci) &&
         cell_can_recurse_in_pair_hydro_task(cj)) {
 
-      /* Get the type of pair if not specified explicitly. */
+      /* Get the type of pair and flip ci/cj if needed. */
       double shift[3] = {0.0, 0.0, 0.0};
-      sid = space_getsid(s, &ci, &cj, shift);
-
-      /* Different types of flags. */
-      switch (sid) {
-
-        /* Regular sub-cell interactions of a single cell. */
-        case 0: /* (  1 ,  1 ,  1 ) */
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
-
-        case 1: /* (  1 ,  1 ,  0 ) */
-          if (ci->progeny[6] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
-
-        case 2: /* (  1 ,  1 , -1 ) */
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          break;
-
-        case 3: /* (  1 ,  0 ,  1 ) */
-          if (ci->progeny[5] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
-
-        case 4: /* (  1 ,  0 ,  0 ) */
-          if (ci->progeny[4] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
-
-        case 5: /* (  1 ,  0 , -1 ) */
-          if (ci->progeny[4] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          break;
-
-        case 6: /* (  1 , -1 ,  1 ) */
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          break;
-
-        case 7: /* (  1 , -1 ,  0 ) */
-          if (ci->progeny[4] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          break;
-
-        case 8: /* (  1 , -1 , -1 ) */
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[4], parts, ind, count, cj->progeny[3],
-                         -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET(r, cj->progeny[3], parts, ind, count, ci->progeny[4],
-                         -1, 0);
-          break;
-
-        case 9: /* (  0 ,  1 ,  1 ) */
-          if (ci->progeny[3] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
-
-        case 10: /* (  0 ,  1 ,  0 ) */
-          if (ci->progeny[2] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[2], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[2],
-                         -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[2], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[2],
-                         -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[2], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[2],
-                         -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[2], parts, ind, count, cj->progeny[5],
-                         -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET(r, cj->progeny[5], parts, ind, count, ci->progeny[2],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[5],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET(r, cj->progeny[5], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[5],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET(r, cj->progeny[5], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[5],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET(r, cj->progeny[5], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
-
-        case 11: /* (  0 ,  1 , -1 ) */
-          if (ci->progeny[2] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[2], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[2],
-                         -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[2], parts, ind, count, cj->progeny[5],
-                         -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET(r, cj->progeny[5], parts, ind, count, ci->progeny[2],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[1],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET(r, cj->progeny[1], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[6], parts, ind, count, cj->progeny[5],
-                         -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET(r, cj->progeny[5], parts, ind, count, ci->progeny[6],
-                         -1, 0);
-          break;
-
-        case 12: /* (  0 ,  0 ,  1 ) */
-          if (ci->progeny[1] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[1], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[1],
-                         -1, 0);
-          if (ci->progeny[1] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[1], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[1],
-                         -1, 0);
-          if (ci->progeny[1] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[1], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[1],
-                         -1, 0);
-          if (ci->progeny[1] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[1], parts, ind, count, cj->progeny[6],
-                         -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET(r, cj->progeny[6], parts, ind, count, ci->progeny[1],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[3], parts, ind, count, cj->progeny[6],
-                         -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET(r, cj->progeny[6], parts, ind, count, ci->progeny[3],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[5], parts, ind, count, cj->progeny[6],
-                         -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET(r, cj->progeny[6], parts, ind, count, ci->progeny[5],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[0],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET(r, cj->progeny[0], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[2],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET(r, cj->progeny[2], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[4],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET(r, cj->progeny[4], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET(r, ci->progeny[7], parts, ind, count, cj->progeny[6],
-                         -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET(r, cj->progeny[6], parts, ind, count, ci->progeny[7],
-                         -1, 0);
-          break;
+      const int sid = space_getsid(s, &ci, &cj, shift);
+
+      struct cell_split_pair *csp = &cell_split_pairs[sid];
+      for (int k = 0; k < csp->count; k++) {
+        const int pid = csp->pairs[k].pid;
+        const int pjd = csp->pairs[k].pjd;
+        if (ci->progeny[pid] == sub && cj->progeny[pjd] != NULL)
+          DOSUB_SUBSET(r, ci->progeny[pid], parts, ind, count, cj->progeny[pjd],
+                       0);
+        if (ci->progeny[pid] != NULL && cj->progeny[pjd] == sub)
+          DOSUB_SUBSET(r, cj->progeny[pjd], parts, ind, count, ci->progeny[pid],
+                       0);
       }
-
     }
 
     /* Otherwise, compute the pair directly. */
diff --git a/src/runner_doiact_stars.h b/src/runner_doiact_stars.h
index 50cdad07a5b25ab124c1b7cbfca83a81aed85efd..be4f83f8137a1908f0d3dc7f321b2d11ea28bd3d 100644
--- a/src/runner_doiact_stars.h
+++ b/src/runner_doiact_stars.h
@@ -102,6 +102,7 @@ void DOSELF1_STARS(struct runner *r, struct cell *c, int timer) {
   TIMER_TIC;
 
   const struct engine *e = r->e;
+  const int with_cosmology = e->policy & engine_policy_cosmology;
   const integertime_t ti_current = e->ti_current;
   const struct cosmology *cosmo = e->cosmology;
 
@@ -124,8 +125,13 @@ void DOSELF1_STARS(struct runner *r, struct cell *c, int timer) {
 
     /* Get a hold of the ith spart in ci. */
     struct spart *restrict si = &sparts[sid];
+
+    /* Skip inactive particles */
     if (!spart_is_active(si, e)) continue;
 
+    /* Skip inactive particles */
+    if (!feedback_is_active(si, e->time, cosmo, with_cosmology)) continue;
+
     const float hi = si->h;
     const float hig2 = hi * hi * kernel_gamma2;
     const float six[3] = {(float)(si->x[0] - c->loc[0]),
@@ -191,6 +197,7 @@ void DO_NONSYM_PAIR1_STARS_NAIVE(struct runner *r, struct cell *restrict ci,
 #endif
 
   const struct engine *e = r->e;
+  const int with_cosmology = e->policy & engine_policy_cosmology;
   const integertime_t ti_current = e->ti_current;
   const struct cosmology *cosmo = e->cosmology;
 
@@ -222,8 +229,13 @@ void DO_NONSYM_PAIR1_STARS_NAIVE(struct runner *r, struct cell *restrict ci,
 
     /* Get a hold of the ith spart in ci. */
     struct spart *restrict si = &sparts_i[sid];
+
+    /* Skip inactive particles */
     if (!spart_is_active(si, e)) continue;
 
+    /* Skip inactive particles */
+    if (!feedback_is_active(si, e->time, cosmo, with_cosmology)) continue;
+
     const float hi = si->h;
     const float hig2 = hi * hi * kernel_gamma2;
     const float six[3] = {(float)(si->x[0] - (cj->loc[0] + shift[0])),
@@ -284,6 +296,7 @@ void DO_SYM_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj,
   TIMER_TIC;
 
   const struct engine *e = r->e;
+  const int with_cosmology = e->policy & engine_policy_cosmology;
   const integertime_t ti_current = e->ti_current;
   const struct cosmology *cosmo = e->cosmology;
 
@@ -350,6 +363,9 @@ void DO_SYM_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj,
       /* Skip inactive particles */
       if (!spart_is_active(spi, e)) continue;
 
+      /* Skip inactive particles */
+      if (!feedback_is_active(spi, e->time, cosmo, with_cosmology)) continue;
+
       /* Compute distance from the other cell. */
       const double px[3] = {spi->x[0], spi->x[1], spi->x[2]};
       float dist = px[0] * runner_shift[sid][0] + px[1] * runner_shift[sid][1] +
@@ -475,6 +491,9 @@ void DO_SYM_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj,
       /* Skip inactive particles */
       if (!spart_is_active(spj, e)) continue;
 
+      /* Skip inactive particles */
+      if (!feedback_is_active(spj, e->time, cosmo, with_cosmology)) continue;
+
       /* Compute distance from the other cell. */
       const double px[3] = {spj->x[0], spj->x[1], spj->x[2]};
       float dist = px[0] * runner_shift[sid][0] + px[1] * runner_shift[sid][1] +
@@ -1000,8 +1019,7 @@ void DOPAIR1_SUBSET_BRANCH_STARS(struct runner *r, struct cell *restrict ci,
 }
 
 void DOSUB_SUBSET_STARS(struct runner *r, struct cell *ci, struct spart *sparts,
-                        int *ind, int scount, struct cell *cj, int sid,
-                        int gettimer) {
+                        int *ind, int scount, struct cell *cj, int gettimer) {
 
   const struct engine *e = r->e;
   struct space *s = e->s;
@@ -1033,11 +1051,10 @@ void DOSUB_SUBSET_STARS(struct runner *r, struct cell *ci, struct spart *sparts,
     if (cell_can_recurse_in_self_stars_task(ci)) {
 
       /* Loop over all progeny. */
-      DOSUB_SUBSET_STARS(r, sub, sparts, ind, scount, NULL, -1, 0);
+      DOSUB_SUBSET_STARS(r, sub, sparts, ind, scount, NULL, 0);
       for (int j = 0; j < 8; j++)
         if (ci->progeny[j] != sub && ci->progeny[j] != NULL)
-          DOSUB_SUBSET_STARS(r, sub, sparts, ind, scount, ci->progeny[j], -1,
-                             0);
+          DOSUB_SUBSET_STARS(r, sub, sparts, ind, scount, ci->progeny[j], 0);
 
     }
 
@@ -1053,510 +1070,21 @@ void DOSUB_SUBSET_STARS(struct runner *r, struct cell *ci, struct spart *sparts,
     if (cell_can_recurse_in_pair_stars_task(ci, cj) &&
         cell_can_recurse_in_pair_stars_task(cj, ci)) {
 
-      /* Get the type of pair if not specified explicitly. */
+      /* Get the type of pair and flip ci/cj if needed. */
       double shift[3] = {0.0, 0.0, 0.0};
-      sid = space_getsid(s, &ci, &cj, shift);
-
-      /* Different types of flags. */
-      switch (sid) {
-
-        /* Regular sub-cell interactions of a single cell. */
-        case 0: /* (  1 ,  1 ,  1 ) */
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
-
-        case 1: /* (  1 ,  1 ,  0 ) */
-          if (ci->progeny[6] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
-
-        case 2: /* (  1 ,  1 , -1 ) */
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          break;
-
-        case 3: /* (  1 ,  0 ,  1 ) */
-          if (ci->progeny[5] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
-
-        case 4: /* (  1 ,  0 ,  0 ) */
-          if (ci->progeny[4] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
-
-        case 5: /* (  1 ,  0 , -1 ) */
-          if (ci->progeny[4] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          break;
-
-        case 6: /* (  1 , -1 ,  1 ) */
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          break;
-
-        case 7: /* (  1 , -1 ,  0 ) */
-          if (ci->progeny[4] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          break;
-
-        case 8: /* (  1 , -1 , -1 ) */
-          if (ci->progeny[4] == sub && cj->progeny[3] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[4], sparts, ind, scount,
-                               cj->progeny[3], -1, 0);
-          if (ci->progeny[4] != NULL && cj->progeny[3] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[3], sparts, ind, scount,
-                               ci->progeny[4], -1, 0);
-          break;
-
-        case 9: /* (  0 ,  1 ,  1 ) */
-          if (ci->progeny[3] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
-
-        case 10: /* (  0 ,  1 ,  0 ) */
-          if (ci->progeny[2] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[2], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[2], -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[2], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[2], -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[2], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[2], -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[2], sparts, ind, scount,
-                               cj->progeny[5], -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[5], sparts, ind, scount,
-                               ci->progeny[2], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[5], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[5], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[5], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[5], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[5], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[5], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
-
-        case 11: /* (  0 ,  1 , -1 ) */
-          if (ci->progeny[2] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[2], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[2], -1, 0);
-          if (ci->progeny[2] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[2], sparts, ind, scount,
-                               cj->progeny[5], -1, 0);
-          if (ci->progeny[2] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[5], sparts, ind, scount,
-                               ci->progeny[2], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[1] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[1], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[1] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[1], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          if (ci->progeny[6] == sub && cj->progeny[5] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[6], sparts, ind, scount,
-                               cj->progeny[5], -1, 0);
-          if (ci->progeny[6] != NULL && cj->progeny[5] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[5], sparts, ind, scount,
-                               ci->progeny[6], -1, 0);
-          break;
-
-        case 12: /* (  0 ,  0 ,  1 ) */
-          if (ci->progeny[1] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[1], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[1], -1, 0);
-          if (ci->progeny[1] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[1], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[1], -1, 0);
-          if (ci->progeny[1] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[1], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[1], -1, 0);
-          if (ci->progeny[1] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[1], sparts, ind, scount,
-                               cj->progeny[6], -1, 0);
-          if (ci->progeny[1] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[6], sparts, ind, scount,
-                               ci->progeny[1], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[3] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[3], sparts, ind, scount,
-                               cj->progeny[6], -1, 0);
-          if (ci->progeny[3] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[6], sparts, ind, scount,
-                               ci->progeny[3], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[5] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[5], sparts, ind, scount,
-                               cj->progeny[6], -1, 0);
-          if (ci->progeny[5] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[6], sparts, ind, scount,
-                               ci->progeny[5], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[0] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[0], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[0] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[0], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[2] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[2], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[2] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[2], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[4] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[4], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[4] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[4], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          if (ci->progeny[7] == sub && cj->progeny[6] != NULL)
-            DOSUB_SUBSET_STARS(r, ci->progeny[7], sparts, ind, scount,
-                               cj->progeny[6], -1, 0);
-          if (ci->progeny[7] != NULL && cj->progeny[6] == sub)
-            DOSUB_SUBSET_STARS(r, cj->progeny[6], sparts, ind, scount,
-                               ci->progeny[7], -1, 0);
-          break;
+      const int sid = space_getsid(s, &ci, &cj, shift);
+
+      struct cell_split_pair *csp = &cell_split_pairs[sid];
+      for (int k = 0; k < csp->count; k++) {
+        const int pid = csp->pairs[k].pid;
+        const int pjd = csp->pairs[k].pjd;
+        if (ci->progeny[pid] == sub && cj->progeny[pjd] != NULL)
+          DOSUB_SUBSET_STARS(r, ci->progeny[pid], sparts, ind, scount,
+                             cj->progeny[pjd], 0);
+        if (ci->progeny[pid] != NULL && cj->progeny[pjd] == sub)
+          DOSUB_SUBSET_STARS(r, cj->progeny[pjd], sparts, ind, scount,
+                             ci->progeny[pid], 0);
       }
-
     }
 
     /* Otherwise, compute the pair directly. */
@@ -1716,14 +1244,13 @@ void DOPAIR1_BRANCH_STARS(struct runner *r, struct cell *ci, struct cell *cj) {
  * @param r The #runner.
  * @param ci The first #cell.
  * @param cj The second #cell.
- * @param sid The direction linking the cells
  * @param gettimer Do we have a timer ?
  *
  * @todo Hard-code the sid on the recursive calls to avoid the
  * redundant computations to find the sid on-the-fly.
  */
 void DOSUB_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj,
-                       int sid, int gettimer) {
+                       int gettimer) {
 
   TIMER_TIC;
 
@@ -1737,210 +1264,20 @@ void DOSUB_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj,
                            cell_is_active_stars(cj, e);
   if (!should_do_ci && !should_do_cj) return;
 
-  /* Get the type of pair if not specified explicitly. */
+  /* Get the type of pair and flip ci/cj if needed. */
   double shift[3];
-  sid = space_getsid(s, &ci, &cj, shift);
+  const int sid = space_getsid(s, &ci, &cj, shift);
 
   /* Recurse? */
   if (cell_can_recurse_in_pair_stars_task(ci, cj) &&
       cell_can_recurse_in_pair_stars_task(cj, ci)) {
-
-    /* Different types of flags. */
-    switch (sid) {
-
-      /* Regular sub-cell interactions of a single cell. */
-      case 0: /* (  1 ,  1 ,  1 ) */
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        break;
-
-      case 1: /* (  1 ,  1 ,  0 ) */
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        break;
-
-      case 2: /* (  1 ,  1 , -1 ) */
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        break;
-
-      case 3: /* (  1 ,  0 ,  1 ) */
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        break;
-
-      case 4: /* (  1 ,  0 ,  0 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[0], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[1], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[2], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[1], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[3], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[2], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[3], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[3], -1, 0);
-        break;
-
-      case 5: /* (  1 ,  0 , -1 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[1], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[3], -1, 0);
-        break;
-
-      case 6: /* (  1 , -1 ,  1 ) */
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        break;
-
-      case 7: /* (  1 , -1 ,  0 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[2], -1, 0);
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[3], -1, 0);
-        break;
-
-      case 8: /* (  1 , -1 , -1 ) */
-        if (ci->progeny[4] != NULL && cj->progeny[3] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[4], cj->progeny[3], -1, 0);
-        break;
-
-      case 9: /* (  0 ,  1 ,  1 ) */
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        break;
-
-      case 10: /* (  0 ,  1 ,  0 ) */
-        if (ci->progeny[2] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[2], cj->progeny[0], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[2], cj->progeny[1], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[2], cj->progeny[4], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[2], cj->progeny[5], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[1], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[5], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[0], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[4], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[5], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[1], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[5], -1, 0);
-        break;
-
-      case 11: /* (  0 ,  1 , -1 ) */
-        if (ci->progeny[2] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[2], cj->progeny[1], -1, 0);
-        if (ci->progeny[2] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[2], cj->progeny[5], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[1] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[1], -1, 0);
-        if (ci->progeny[6] != NULL && cj->progeny[5] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[6], cj->progeny[5], -1, 0);
-        break;
-
-      case 12: /* (  0 ,  0 ,  1 ) */
-        if (ci->progeny[1] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[1], cj->progeny[0], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[1], cj->progeny[2], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[1], cj->progeny[4], -1, 0);
-        if (ci->progeny[1] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[1], cj->progeny[6], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[0], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[2], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[4], -1, 0);
-        if (ci->progeny[3] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[3], cj->progeny[6], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[0], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[2], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[4], -1, 0);
-        if (ci->progeny[5] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[5], cj->progeny[6], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[0] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[0], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[2] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[2], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[4] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[4], -1, 0);
-        if (ci->progeny[7] != NULL && cj->progeny[6] != NULL)
-          DOSUB_PAIR1_STARS(r, ci->progeny[7], cj->progeny[6], -1, 0);
-        break;
+    struct cell_split_pair *csp = &cell_split_pairs[sid];
+    for (int k = 0; k < csp->count; k++) {
+      const int pid = csp->pairs[k].pid;
+      const int pjd = csp->pairs[k].pjd;
+      if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL)
+        DOSUB_PAIR1_STARS(r, ci->progeny[pid], cj->progeny[pjd], 0);
     }
-
   }
 
   /* Otherwise, compute the pair directly. */
@@ -2036,7 +1373,7 @@ void DOSUB_SELF1_STARS(struct runner *r, struct cell *ci, int gettimer) {
         DOSUB_SELF1_STARS(r, ci->progeny[k], 0);
         for (int j = k + 1; j < 8; j++)
           if (ci->progeny[j] != NULL)
-            DOSUB_PAIR1_STARS(r, ci->progeny[k], ci->progeny[j], -1, 0);
+            DOSUB_PAIR1_STARS(r, ci->progeny[k], ci->progeny[j], 0);
       }
   }
 
diff --git a/src/scheduler.c b/src/scheduler.c
index 6b50738d4055909174359480324c0fc995c8cffd..6dba5f1593c8bf050a260ded5061ebc54fc63310 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -65,7 +65,6 @@ void scheduler_clear_active(struct scheduler *s) { s->active_count = 0; }
  *        current index == s->size_unlock;
  */
 static void scheduler_extend_unlocks(struct scheduler *s) {
-
   /* Allocate the new buffer. */
   const int size_unlocks_new = s->size_unlocks * 2;
   struct task **unlocks_new = (struct task **)swift_malloc(
@@ -143,7 +142,6 @@ void scheduler_addunlock(struct scheduler *s, struct task *ta,
 int scheduler_get_number_relation(const struct scheduler *s,
                                   const struct task *ta,
                                   const struct task *tb) {
-
   int count = 0;
 
   /* loop over all tasks */
@@ -207,7 +205,6 @@ struct task_dependency {
  * @param tstype The MPI_Datatype to initialize
  */
 void task_dependency_define(MPI_Datatype *tstype) {
-
   /* Define the variables */
   const int count = 8;
   int blocklens[count];
@@ -256,17 +253,14 @@ void task_dependency_define(MPI_Datatype *tstype) {
  */
 void task_dependency_sum(void *in_p, void *out_p, int *len,
                          MPI_Datatype *type) {
-
   /* change pointer type */
   struct task_dependency *in = (struct task_dependency *)in_p;
   struct task_dependency *out = (struct task_dependency *)out_p;
 
   /* Loop over all the current objects */
   for (int i = 0; i < *len; i++) {
-
     /* loop over all the object set in invals */
     for (int j = 0; j < MAX_NUMBER_DEP; j++) {
-
       /* Have we reached the end of the links? */
       if (in[i].number_link[j] == -1) {
         break;
@@ -354,7 +348,6 @@ void task_dependency_sum(void *in_p, void *out_p, int *len,
  * @param verbose Are we verbose about this?
  */
 void scheduler_write_dependencies(struct scheduler *s, int verbose) {
-
   const ticks tic = getticks();
 
   /* Number of possible relations between tasks */
@@ -398,7 +391,6 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) {
 
       int k = 0;
       while (k < MAX_NUMBER_DEP) {
-
         /* not written yet */
         if (cur->number_link[k] == -1) {
           /* set tb */
@@ -542,7 +534,6 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) {
  * @param s The #scheduler we are working in.
  */
 static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
-
   /* Are we considering both stars and hydro when splitting? */
   /* Note this is not very clean as the scheduler should not really
      access the engine... */
@@ -552,7 +543,6 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
   /* Iterate on this task until we're done with it. */
   int redo = 1;
   while (redo) {
-
     /* Reset the redo flag. */
     redo = 0;
 
@@ -579,7 +569,6 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
 
     /* Self-interaction? */
     if (t->type == task_type_self) {
-
       /* Get a handle on the cell involved. */
       struct cell *ci = t->ci;
 
@@ -591,16 +580,13 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
 
       /* Is this cell even split and the task does not violate h ? */
       if (cell_can_split_self_hydro_task(ci)) {
-
         /* Make a sub? */
         if (scheduler_dosub && ci->hydro.count < space_subsize_self_hydro) {
-
           /* convert to a self-subtask. */
           t->type = task_type_sub_self;
 
           /* Otherwise, make tasks explicitly. */
         } else {
-
           /* Take a step back (we're going to recycle the current task)... */
           redo = 1;
 
@@ -609,12 +595,10 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
           while (ci->progeny[first_child] == NULL) first_child++;
           t->ci = ci->progeny[first_child];
           for (int k = first_child + 1; k < 8; k++) {
-
             /* Do we have a non-empty progenitor? */
             if (ci->progeny[k] != NULL &&
                 (ci->progeny[k]->hydro.count ||
                  (with_feedback && ci->progeny[k]->stars.count))) {
-
               scheduler_splittask_hydro(
                   scheduler_addtask(s, task_type_self, t->subtype, 0, 0,
                                     ci->progeny[k], NULL),
@@ -624,19 +608,15 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
 
           /* Make a task for each pair of progeny */
           for (int j = 0; j < 8; j++) {
-
             /* Do we have a non-empty progenitor? */
             if (ci->progeny[j] != NULL &&
                 (ci->progeny[j]->hydro.count ||
                  (with_feedback && ci->progeny[j]->stars.count))) {
-
               for (int k = j + 1; k < 8; k++) {
-
                 /* Do we have a second non-empty progenitor? */
                 if (ci->progeny[k] != NULL &&
                     (ci->progeny[k]->hydro.count ||
                      (with_feedback && ci->progeny[k]->stars.count))) {
-
                   scheduler_splittask_hydro(
                       scheduler_addtask(s, task_type_pair, t->subtype,
                                         sub_sid_flag[j][k], 0, ci->progeny[j],
@@ -654,7 +634,6 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
 
     /* Pair interaction? */
     else if (t->type == task_type_pair) {
-
       /* Get a handle on the cells involved. */
       struct cell *ci = t->ci;
       struct cell *cj = t->cj;
@@ -679,361 +658,38 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
       /* Should this task be split-up? */
       if (cell_can_split_pair_hydro_task(ci) &&
           cell_can_split_pair_hydro_task(cj)) {
-
         /* Replace by a single sub-task? */
         if (scheduler_dosub && /* Use division to avoid integer overflow. */
             ci->hydro.count * sid_scale[sid] <
                 space_subsize_pair_hydro / cj->hydro.count &&
             !sort_is_corner(sid)) {
-
           /* Make this task a sub task. */
           t->type = task_type_sub_pair;
 
           /* Otherwise, split it. */
         } else {
-
           /* Take a step back (we're going to recycle the current task)... */
           redo = 1;
 
-          /* For each different sorting type... */
-          switch (sid) {
-
-            case 0: /* (  1 ,  1 ,  1 ) */
-              t->ci = ci->progeny[7];
-              t->cj = cj->progeny[0];
-              t->flags = 0;
-              break;
-
-            case 1: /* (  1 ,  1 ,  0 ) */
-              t->ci = ci->progeny[6];
-              t->cj = cj->progeny[0];
-              t->flags = 1;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 1, 0,
-                                    ci->progeny[7], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 0, 0,
-                                    ci->progeny[6], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 2, 0,
-                                    ci->progeny[7], cj->progeny[0]),
-                  s);
-              break;
-
-            case 2: /* (  1 ,  1 , -1 ) */
-              t->ci = ci->progeny[6];
-              t->cj = cj->progeny[1];
-              t->flags = 2;
-              break;
-
-            case 3: /* (  1 ,  0 ,  1 ) */
-              t->ci = ci->progeny[5];
-              t->cj = cj->progeny[0];
-              t->flags = 3;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 3, 0,
-                                    ci->progeny[7], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 0, 0,
-                                    ci->progeny[5], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 6, 0,
-                                    ci->progeny[7], cj->progeny[0]),
-                  s);
-              break;
-
-            case 4: /* (  1 ,  0 ,  0 ) */
-              t->ci = ci->progeny[4];
-              t->cj = cj->progeny[0];
-              t->flags = 4;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 5, 0,
-                                    ci->progeny[5], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 7, 0,
-                                    ci->progeny[6], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 8, 0,
-                                    ci->progeny[7], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 3, 0,
-                                    ci->progeny[4], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 4, 0,
-                                    ci->progeny[5], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 6, 0,
-                                    ci->progeny[6], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 7, 0,
-                                    ci->progeny[7], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 1, 0,
-                                    ci->progeny[4], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 2, 0,
-                                    ci->progeny[5], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 4, 0,
-                                    ci->progeny[6], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 5, 0,
-                                    ci->progeny[7], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 0, 0,
-                                    ci->progeny[4], cj->progeny[3]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 1, 0,
-                                    ci->progeny[5], cj->progeny[3]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 3, 0,
-                                    ci->progeny[6], cj->progeny[3]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 4, 0,
-                                    ci->progeny[7], cj->progeny[3]),
-                  s);
-              break;
-
-            case 5: /* (  1 ,  0 , -1 ) */
-              t->ci = ci->progeny[4];
-              t->cj = cj->progeny[1];
-              t->flags = 5;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 5, 0,
-                                    ci->progeny[6], cj->progeny[3]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 2, 0,
-                                    ci->progeny[4], cj->progeny[3]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 8, 0,
-                                    ci->progeny[6], cj->progeny[1]),
-                  s);
-              break;
-
-            case 6: /* (  1 , -1 ,  1 ) */
-              t->ci = ci->progeny[5];
-              t->cj = cj->progeny[2];
-              t->flags = 6;
-              break;
-
-            case 7: /* (  1 , -1 ,  0 ) */
-              t->ci = ci->progeny[4];
-              t->cj = cj->progeny[3];
-              t->flags = 6;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 8, 0,
-                                    ci->progeny[5], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 7, 0,
-                                    ci->progeny[4], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 7, 0,
-                                    ci->progeny[5], cj->progeny[3]),
-                  s);
-              break;
-
-            case 8: /* (  1 , -1 , -1 ) */
-              t->ci = ci->progeny[4];
-              t->cj = cj->progeny[3];
-              t->flags = 8;
-              break;
-
-            case 9: /* (  0 ,  1 ,  1 ) */
-              t->ci = ci->progeny[3];
-              t->cj = cj->progeny[0];
-              t->flags = 9;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 9, 0,
-                                    ci->progeny[7], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 0, 0,
-                                    ci->progeny[3], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 8, 0,
-                                    ci->progeny[7], cj->progeny[0]),
-                  s);
-              break;
-
-            case 10: /* (  0 ,  1 ,  0 ) */
-              t->ci = ci->progeny[2];
-              t->cj = cj->progeny[0];
-              t->flags = 10;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 11, 0,
-                                    ci->progeny[3], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 7, 0,
-                                    ci->progeny[6], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 6, 0,
-                                    ci->progeny[7], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 9, 0,
-                                    ci->progeny[2], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 10, 0,
-                                    ci->progeny[3], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 8, 0,
-                                    ci->progeny[6], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 7, 0,
-                                    ci->progeny[7], cj->progeny[1]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 1, 0,
-                                    ci->progeny[2], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 2, 0,
-                                    ci->progeny[3], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 10, 0,
-                                    ci->progeny[6], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 11, 0,
-                                    ci->progeny[7], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 0, 0,
-                                    ci->progeny[2], cj->progeny[5]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 1, 0,
-                                    ci->progeny[3], cj->progeny[5]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 9, 0,
-                                    ci->progeny[6], cj->progeny[5]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 10, 0,
-                                    ci->progeny[7], cj->progeny[5]),
-                  s);
-              break;
-
-            case 11: /* (  0 ,  1 , -1 ) */
-              t->ci = ci->progeny[2];
-              t->cj = cj->progeny[1];
-              t->flags = 11;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 11, 0,
-                                    ci->progeny[6], cj->progeny[5]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 2, 0,
-                                    ci->progeny[2], cj->progeny[5]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 6, 0,
-                                    ci->progeny[6], cj->progeny[1]),
-                  s);
-              break;
-
-            case 12: /* (  0 ,  0 ,  1 ) */
-              t->ci = ci->progeny[1];
-              t->cj = cj->progeny[0];
-              t->flags = 12;
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 11, 0,
-                                    ci->progeny[3], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 5, 0,
-                                    ci->progeny[5], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 2, 0,
-                                    ci->progeny[7], cj->progeny[0]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 9, 0,
-                                    ci->progeny[1], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 12, 0,
-                                    ci->progeny[3], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 8, 0,
-                                    ci->progeny[5], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 5, 0,
-                                    ci->progeny[7], cj->progeny[2]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 3, 0,
-                                    ci->progeny[1], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 6, 0,
-                                    ci->progeny[3], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 12, 0,
-                                    ci->progeny[5], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 11, 0,
-                                    ci->progeny[7], cj->progeny[4]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 0, 0,
-                                    ci->progeny[1], cj->progeny[6]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 3, 0,
-                                    ci->progeny[3], cj->progeny[6]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 9, 0,
-                                    ci->progeny[5], cj->progeny[6]),
-                  s);
-              scheduler_splittask_hydro(
-                  scheduler_addtask(s, task_type_pair, t->subtype, 12, 0,
-                                    ci->progeny[7], cj->progeny[6]),
-                  s);
-              break;
-          } /* switch(sid) */
+          /* Loop over the sub-cell pairs for the current sid and add new tasks
+           * for them. */
+          struct cell_split_pair *csp = &cell_split_pairs[sid];
+          t->ci = ci->progeny[csp->pairs[0].pid];
+          t->cj = cj->progeny[csp->pairs[0].pjd];
+          t->flags = csp->pairs[0].sid;
+          for (int k = 1; k < csp->count; k++) {
+            scheduler_splittask_hydro(
+                scheduler_addtask(s, task_type_pair, t->subtype,
+                                  csp->pairs[k].sid, 0,
+                                  ci->progeny[csp->pairs[k].pid],
+                                  cj->progeny[csp->pairs[k].pjd]),
+                s);
+          }
         }
 
         /* Otherwise, break it up if it is too large? */
       } else if (scheduler_doforcesplit && ci->split && cj->split &&
                  (ci->hydro.count > space_maxsize / cj->hydro.count)) {
-
         // message( "force splitting pair with %i and %i parts." ,
         // ci->hydro.count , cj->hydro.count );
 
@@ -1062,14 +718,12 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
  * @param s The #scheduler we are working in.
  */
 static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
-
   const struct space *sp = s->space;
   struct engine *e = sp->e;
 
   /* Iterate on this task until we're done with it. */
   int redo = 1;
   while (redo) {
-
     /* Reset the redo flag. */
     redo = 0;
 
@@ -1084,7 +738,6 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
 
     /* Self-interaction? */
     if (t->type == task_type_self) {
-
       /* Get a handle on the cell involved. */
       const struct cell *ci = t->ci;
 
@@ -1096,12 +749,9 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
 
       /* Should we split this task? */
       if (cell_can_split_self_gravity_task(ci)) {
-
         if (scheduler_dosub && ci->grav.count < space_subsize_self_grav) {
-
           /* Otherwise, split it. */
         } else {
-
           /* Take a step back (we're going to recycle the current task)... */
           redo = 1;
 
@@ -1136,7 +786,6 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
 
     /* Pair interaction? */
     else if (t->type == task_type_pair) {
-
       /* Get a handle on the cells involved. */
       struct cell *ci = t->ci;
       struct cell *cj = t->cj;
@@ -1150,17 +799,14 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
       /* Should this task be split-up? */
       if (cell_can_split_pair_gravity_task(ci) &&
           cell_can_split_pair_gravity_task(cj)) {
-
         const long long gcount_i = ci->grav.count;
         const long long gcount_j = cj->grav.count;
 
         /* Replace by a single sub-task? */
         if (scheduler_dosub &&
             gcount_i * gcount_j < ((long long)space_subsize_pair_grav)) {
-
           /* Otherwise, split it. */
         } else {
-
           /* Turn the task into a M-M task that will take care of all the
            * progeny pairs */
           t->type = task_type_grav_mm;
@@ -1172,11 +818,9 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
             if (ci->progeny[i] != NULL) {
               for (int j = 0; j < 8; j++) {
                 if (cj->progeny[j] != NULL) {
-
                   /* Can we use a M-M interaction here? */
                   if (cell_can_use_pair_mm_rebuild(ci->progeny[i],
                                                    cj->progeny[j], e, sp)) {
-
                     /* Flag this pair as being treated by the M-M task.
                      * We use the 64 bits in the task->flags field to store
                      * this information. The corresponding taks will unpack
@@ -1186,7 +830,6 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
                     t->flags |= (1ULL << flag);
 
                   } else {
-
                     /* Ok, we actually have to create a task */
                     scheduler_splittask_gravity(
                         scheduler_addtask(s, task_type_pair, task_subtype_grav,
@@ -1222,7 +865,6 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
  */
 void scheduler_splittasks_mapper(void *map_data, int num_elements,
                                  void *extra_data) {
-
   /* Extract the parameters. */
   struct scheduler *s = (struct scheduler *)extra_data;
   struct task *tasks = (struct task *)map_data;
@@ -1253,7 +895,6 @@ void scheduler_splittasks_mapper(void *map_data, int num_elements,
  * @param s The #scheduler.
  */
 void scheduler_splittasks(struct scheduler *s) {
-
   /* Call the mapper on each current task. */
   threadpool_map(s->threadpool, scheduler_splittasks_mapper, s->tasks,
                  s->nr_tasks, sizeof(struct task), 0, s);
@@ -1274,7 +915,6 @@ void scheduler_splittasks(struct scheduler *s) {
 struct task *scheduler_addtask(struct scheduler *s, enum task_types type,
                                enum task_subtypes subtype, int flags,
                                int implicit, struct cell *ci, struct cell *cj) {
-
   /* Get the next free task. */
   const int ind = atomic_inc(&s->tasks_next);
 
@@ -1321,7 +961,6 @@ struct task *scheduler_addtask(struct scheduler *s, enum task_types type,
  * @param s The #scheduler.
  */
 void scheduler_set_unlocks(struct scheduler *s) {
-
   /* Store the counts for each task. */
   short int *counts;
   if ((counts = (short int *)swift_malloc(
@@ -1410,7 +1049,6 @@ void scheduler_set_unlocks(struct scheduler *s) {
  * @param s The #scheduler.
  */
 void scheduler_ranktasks(struct scheduler *s) {
-
   struct task *tasks = s->tasks;
   int *tid = s->tasks_ind;
   const int nr_tasks = s->nr_tasks;
@@ -1435,7 +1073,6 @@ void scheduler_ranktasks(struct scheduler *s) {
 
   /* Main loop. */
   for (int j = 0, rank = 0; j < nr_tasks; rank++) {
-
     /* Did we get anything? */
     if (j == left) error("Unsatisfiable task dependencies detected.");
 
@@ -1475,10 +1112,8 @@ void scheduler_ranktasks(struct scheduler *s) {
  * @param size The maximum number of tasks in the #scheduler.
  */
 void scheduler_reset(struct scheduler *s, int size) {
-
   /* Do we need to re-allocate? */
   if (size > s->size) {
-
     /* Free existing task lists if necessary. */
     scheduler_free_tasks(s);
 
@@ -1516,7 +1151,6 @@ void scheduler_reset(struct scheduler *s, int size) {
  * @param verbose Are we talkative?
  */
 void scheduler_reweight(struct scheduler *s, int verbose) {
-
   const int nr_tasks = s->nr_tasks;
   int *tid = s->tasks_ind;
   struct task *tasks = s->tasks;
@@ -1709,7 +1343,6 @@ void scheduler_reweight(struct scheduler *s, int verbose) {
  */
 void scheduler_rewait_mapper(void *map_data, int num_elements,
                              void *extra_data) {
-
   struct scheduler *s = (struct scheduler *)extra_data;
   const int *tid = (int *)map_data;
 
@@ -1758,7 +1391,6 @@ void scheduler_enqueue_mapper(void *map_data, int num_elements,
  * @param s The #scheduler.
  */
 void scheduler_start(struct scheduler *s) {
-
   /* Reset all task timers. */
   for (int i = 0; i < s->nr_tasks; ++i) {
     s->tasks[i].tic = 0;
@@ -1800,7 +1432,6 @@ void scheduler_start(struct scheduler *s) {
  * @param t The #task.
  */
 void scheduler_enqueue(struct scheduler *s, struct task *t) {
-
   /* The target queue for this task. */
   int qid = -1;
 
@@ -2074,7 +1705,6 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
  *         been identified.
  */
 struct task *scheduler_done(struct scheduler *s, struct task *t) {
-
   /* Release whatever locks this task held. */
   if (!t->implicit) task_unlock(t);
 
@@ -2120,7 +1750,6 @@ struct task *scheduler_done(struct scheduler *s, struct task *t) {
  *         been identified.
  */
 struct task *scheduler_unlock(struct scheduler *s, struct task *t) {
-
   /* Loop through the dependencies and add them to a queue if
      they are ready. */
   for (int k = 0; k < t->nr_unlock_tasks; k++) {
@@ -2159,7 +1788,6 @@ struct task *scheduler_unlock(struct scheduler *s, struct task *t) {
  */
 struct task *scheduler_gettask(struct scheduler *s, int qid,
                                const struct task *prev) {
-
   struct task *res = NULL;
   const int nr_queues = s->nr_queues;
   unsigned int seed = qid;
@@ -2169,11 +1797,9 @@ struct task *scheduler_gettask(struct scheduler *s, int qid,
 
   /* Loop as long as there are tasks... */
   while (s->waiting > 0 && res == NULL) {
-
     /* Try more than once before sleeping. */
     for (int tries = 0; res == NULL && s->waiting && tries < scheduler_maxtries;
          tries++) {
-
       /* Try to get a task from the suggested queue. */
       if (s->queues[qid].count > 0 || s->queues[qid].count_incoming > 0) {
         TIMER_TIC
@@ -2245,7 +1871,6 @@ struct task *scheduler_gettask(struct scheduler *s, int qid,
 void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
                     int nr_queues, unsigned int flags, int nodeID,
                     struct threadpool *tp) {
-
   /* Init the lock. */
   lock_init(&s->lock);
 
@@ -2294,7 +1919,6 @@ void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
  * @param fileName Name of the file to write to
  */
 void scheduler_print_tasks(const struct scheduler *s, const char *fileName) {
-
   const int nr_tasks = s->nr_tasks, *tid = s->tasks_ind;
   struct task *t, *tasks = s->tasks;
 
@@ -2316,7 +1940,6 @@ void scheduler_print_tasks(const struct scheduler *s, const char *fileName) {
  * @brief Frees up the memory allocated for this #scheduler
  */
 void scheduler_clean(struct scheduler *s) {
-
   scheduler_free_tasks(s);
   swift_free("unlocks", s->unlocks);
   swift_free("unlock_ind", s->unlock_ind);
@@ -2328,7 +1951,6 @@ void scheduler_clean(struct scheduler *s) {
  * @brief Free the task arrays allocated by this #scheduler.
  */
 void scheduler_free_tasks(struct scheduler *s) {
-
   if (s->tasks != NULL) {
     swift_free("tasks", s->tasks);
     s->tasks = NULL;
@@ -2364,7 +1986,6 @@ void scheduler_write_task_level(const struct scheduler *s) {
   for (int i = 0; i < nr_tasks; i++) {
     const struct task *t = &tasks[i];
     if (t->ci) {
-
       if ((int)t->ci->depth >= max_depth)
         error("Cell is too deep, you need to increase max_depth");
 
diff --git a/src/space.c b/src/space.c
index 569bfa7eb46993def7cff2107868fb7afbae2d7e..4351c934d1bd7c69e646dc4810a04ad27617b61e 100644
--- a/src/space.c
+++ b/src/space.c
@@ -86,6 +86,10 @@ int space_extra_bparts = space_extra_bparts_default;
 /*! Number of extra #gpart we allocate memory for per top-level cell */
 int space_extra_gparts = space_extra_gparts_default;
 
+/*! Maximum number of particles per ghost */
+int engine_max_parts_per_ghost = engine_max_parts_per_ghost_default;
+int engine_max_sparts_per_ghost = engine_max_sparts_per_ghost_default;
+
 /*! Expected maximal number of strays received at a rebuild */
 int space_expected_max_nr_strays = space_expected_max_nr_strays_default;
 #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH)
@@ -1878,7 +1882,8 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) {
 
     const int is_local = (c->nodeID == engine_rank);
     const int has_particles = (c->hydro.count > 0) || (c->grav.count > 0) ||
-                              (c->stars.count > 0) | (c->black_holes.count > 0);
+                              (c->stars.count > 0) ||
+                              (c->black_holes.count > 0);
 
     if (is_local) {
       c->hydro.parts = finger;
@@ -3327,7 +3332,7 @@ void space_split_recursive(struct space *s, struct cell *c,
 #endif
     }
 
-    /* Split the cell's partcle data. */
+    /* Split the cell's particle data. */
     cell_split(c, c->hydro.parts - s->parts, c->stars.parts - s->sparts,
                c->black_holes.parts - s->bparts, buff, sbuff, bbuff, gbuff);
 
@@ -4621,6 +4626,13 @@ void space_init(struct space *s, struct swift_params *params,
   space_extra_bparts = parser_get_opt_param_int(
       params, "Scheduler:cell_extra_bparts", space_extra_bparts_default);
 
+  engine_max_parts_per_ghost =
+      parser_get_opt_param_int(params, "Scheduler:engine_max_parts_per_ghost",
+                               engine_max_parts_per_ghost_default);
+  engine_max_sparts_per_ghost =
+      parser_get_opt_param_int(params, "Scheduler:engine_max_sparts_per_ghost",
+                               engine_max_sparts_per_ghost_default);
+
   if (verbose) {
     message("max_size set to %d split_size set to %d", space_maxsize,
             space_splitsize);
@@ -4756,7 +4768,7 @@ void space_init(struct space *s, struct swift_params *params,
   last_cell_id = 1;
 #endif
 
-  /* Do we want any spare particles for on the fly cration? */
+  /* Do we want any spare particles for on the fly creation? */
   if (!star_formation) space_extra_sparts = 0;
 
   /* Build the cells recursively. */
@@ -5227,6 +5239,30 @@ void space_struct_dump(struct space *s, FILE *stream) {
   restart_write_blocks(s, sizeof(struct space), 1, stream, "space",
                        "space struct");
 
+  /* Now all our globals. */
+  restart_write_blocks(&space_splitsize, sizeof(int), 1, stream,
+                       "space_splitsize", "space_splitsize");
+  restart_write_blocks(&space_maxsize, sizeof(int), 1, stream, "space_maxsize",
+                       "space_maxsize");
+  restart_write_blocks(&space_subsize_pair_hydro, sizeof(int), 1, stream,
+                       "space_subsize_pair_hydro", "space_subsize_pair_hydro");
+  restart_write_blocks(&space_subsize_self_hydro, sizeof(int), 1, stream,
+                       "space_subsize_self_hydro", "space_subsize_self_hydro");
+  restart_write_blocks(&space_subsize_pair_grav, sizeof(int), 1, stream,
+                       "space_subsize_pair_grav", "space_subsize_pair_grav");
+  restart_write_blocks(&space_subsize_self_grav, sizeof(int), 1, stream,
+                       "space_subsize_self_grav", "space_subsize_self_grav");
+  restart_write_blocks(&space_subdepth_diff_grav, sizeof(int), 1, stream,
+                       "space_subdepth_diff_grav", "space_subdepth_diff_grav");
+  restart_write_blocks(&space_extra_parts, sizeof(int), 1, stream,
+                       "space_extra_parts", "space_extra_parts");
+  restart_write_blocks(&space_extra_gparts, sizeof(int), 1, stream,
+                       "space_extra_gparts", "space_extra_gparts");
+  restart_write_blocks(&space_extra_sparts, sizeof(int), 1, stream,
+                       "space_extra_sparts", "space_extra_sparts");
+  restart_write_blocks(&space_extra_bparts, sizeof(int), 1, stream,
+                       "space_extra_bparts", "space_extra_bparts");
+
   /* More things to write. */
   if (s->nr_parts > 0) {
     restart_write_blocks(s->parts, s->nr_parts, sizeof(struct part), stream,
@@ -5257,6 +5293,30 @@ void space_struct_restore(struct space *s, FILE *stream) {
 
   restart_read_blocks(s, sizeof(struct space), 1, stream, NULL, "space struct");
 
+  /* Now all our globals. */
+  restart_read_blocks(&space_splitsize, sizeof(int), 1, stream, NULL,
+                      "space_splitsize");
+  restart_read_blocks(&space_maxsize, sizeof(int), 1, stream, NULL,
+                      "space_maxsize");
+  restart_read_blocks(&space_subsize_pair_hydro, sizeof(int), 1, stream, NULL,
+                      "space_subsize_pair_hydro");
+  restart_read_blocks(&space_subsize_self_hydro, sizeof(int), 1, stream, NULL,
+                      "space_subsize_self_hydro");
+  restart_read_blocks(&space_subsize_pair_grav, sizeof(int), 1, stream, NULL,
+                      "space_subsize_pair_grav");
+  restart_read_blocks(&space_subsize_self_grav, sizeof(int), 1, stream, NULL,
+                      "space_subsize_self_grav");
+  restart_read_blocks(&space_subdepth_diff_grav, sizeof(int), 1, stream, NULL,
+                      "space_subdepth_diff_grav");
+  restart_read_blocks(&space_extra_parts, sizeof(int), 1, stream, NULL,
+                      "space_extra_parts");
+  restart_read_blocks(&space_extra_gparts, sizeof(int), 1, stream, NULL,
+                      "space_extra_gparts");
+  restart_read_blocks(&space_extra_sparts, sizeof(int), 1, stream, NULL,
+                      "space_extra_sparts");
+  restart_read_blocks(&space_extra_bparts, sizeof(int), 1, stream, NULL,
+                      "space_extra_bparts");
+
   /* Things that should be reconstructed in a rebuild. */
   s->cells_top = NULL;
   s->cells_sub = NULL;
diff --git a/src/space.h b/src/space.h
index 90ad0cfc8ce1173a3c75b36f560d12ef807ef8a0..4a2d5d8ce92d49ef129fc32c9332bc811e67f795 100644
--- a/src/space.h
+++ b/src/space.h
@@ -62,15 +62,14 @@ struct cosmology;
 /* Maximum allowed depth of cell splits. */
 #define space_cell_maxdepth 52
 
-/* Split size. */
+/* Globals needed in contexts without a space struct. Remember to dump and
+ * restore these. */
 extern int space_splitsize;
 extern int space_maxsize;
 extern int space_subsize_pair_hydro;
 extern int space_subsize_self_hydro;
 extern int space_subsize_pair_grav;
 extern int space_subsize_self_grav;
-extern int space_subsize_pair_stars;
-extern int space_subsize_self_stars;
 extern int space_subdepth_diff_grav;
 extern int space_extra_parts;
 extern int space_extra_gparts;
diff --git a/src/stars/Default/stars_iact.h b/src/stars/Default/stars_iact.h
index 1b68e83d7237f3bd042e520d2514df3506f93f1d..e48f37d7011f08a5396e164f05953dd8ad0c236e 100644
--- a/src/stars/Default/stars_iact.h
+++ b/src/stars/Default/stars_iact.h
@@ -79,7 +79,7 @@ runner_iact_nonsym_stars_density(const float r2, const float *dx,
 __attribute__((always_inline)) INLINE static void
 runner_iact_nonsym_stars_feedback(const float r2, const float *dx,
                                   const float hi, const float hj,
-                                  const struct spart *restrict si,
+                                  struct spart *restrict si,
                                   struct part *restrict pj, const float a,
                                   const float H) {
 #ifdef DEBUG_INTERACTIONS_STARS
diff --git a/src/tools.c b/src/tools.c
index 7290abc063c58a8b2d85b1137d23d3f647dbf456..bd467e1841b78d45a74b037c63e8ed58dd92183f 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -40,6 +40,7 @@
 #include "chemistry.h"
 #include "cosmology.h"
 #include "error.h"
+#include "feedback.h"
 #include "gravity.h"
 #include "hydro.h"
 #include "part.h"
@@ -424,6 +425,7 @@ void pairs_all_stars_density(struct runner *r, struct cell *ci,
   float r2, dx[3];
   const double dim[3] = {r->e->s->dim[0], r->e->s->dim[1], r->e->s->dim[2]};
   const struct engine *e = r->e;
+  const int with_cosmology = e->policy & engine_policy_cosmology;
   const struct cosmology *cosmo = e->cosmology;
   const float a = cosmo->a;
   const float H = cosmo->H;
@@ -437,6 +439,7 @@ void pairs_all_stars_density(struct runner *r, struct cell *ci,
 
     /* Skip inactive particles. */
     if (!spart_is_active(spi, e)) continue;
+    if (!feedback_is_active(spi, e->time, cosmo, with_cosmology)) continue;
 
     for (int j = 0; j < cj->hydro.count; ++j) {
 
@@ -470,6 +473,7 @@ void pairs_all_stars_density(struct runner *r, struct cell *ci,
 
     /* Skip inactive particles. */
     if (!spart_is_active(spj, e)) continue;
+    if (!feedback_is_active(spj, e->time, cosmo, with_cosmology)) continue;
 
     for (int i = 0; i < ci->hydro.count; ++i) {
 
@@ -649,6 +653,7 @@ void self_all_stars_density(struct runner *r, struct cell *ci) {
   struct spart *spi;
   struct part *pj;
   const struct engine *e = r->e;
+  const int with_cosmology = e->policy & engine_policy_cosmology;
   const struct cosmology *cosmo = e->cosmology;
   const float a = cosmo->a;
   const float H = cosmo->H;
@@ -661,6 +666,7 @@ void self_all_stars_density(struct runner *r, struct cell *ci) {
     hig2 = hi * hi * kernel_gamma2;
 
     if (!spart_is_active(spi, e)) continue;
+    if (!feedback_is_active(spi, e->time, cosmo, with_cosmology)) continue;
 
     for (int j = 0; j < ci->hydro.count; ++j) {
 
diff --git a/theory/SPH/Flavours/anarchy.tex b/theory/SPH/Flavours/anarchy.tex
index 5924f9438f9b553298b0d45a8e4d7ddae9167270..3a257bf7d95346733c58d9d2fae18df6acd47f49 100644
--- a/theory/SPH/Flavours/anarchy.tex
+++ b/theory/SPH/Flavours/anarchy.tex
@@ -108,7 +108,7 @@ their time-integration. The following quantities are calculated:
 	       \mu_{ij} (b_i + b_j) (\nabla_i W_i + \nabla_j W_j)/ (\rho_i + \rho_j)$
 	\item $\dot{u}_{ij, {\rm hydro}} = \sum_j m_j u_i u_j (\gamma - 1)^2
 	       \frac{f_{ij}}{\bar{P}_i} \nabla_i W_i$
-	\item $\dot{u}_{ij, {\rm visc}} = \frac{1}{2} \a_{\rm visc} (\mathbf{v}_{ij} \cdot \tilde{\mathbf{x}}_{ij} + r^2a^2 H)$
+	\item $\dot{u}_{ij, {\rm visc}} = \frac{1}{2} a_{\rm visc} (\mathbf{v}_{ij} \cdot \tilde{\mathbf{x}}_{ij} + r^2a^2 H)$
 	\item $v_{{\rm diff}, i} = {\rm max}(0, c_i + c_j + \mathbf{v}_{ij} \cdot \tilde{\mathbf{x}}_{ij} + r^2a^2 H)$
 	\item $\dot{u}_{ij, {\rm diff}} = \frac{1}{2}(\tilde{\alpha}_i + \tilde{\alpha}_j) a^{(3\gamma - 5)/2)}
 	       v_{{\rm diff}, i} (u_i - u_j) (\nabla_i W_i + \nabla_j W_j)/ (\rho_i + \rho_j) $
@@ -118,6 +118,6 @@ where:
 \begin{itemize}
 	\item $f_{ij}$ are the variable smoothing length correction factors
 	\item $b_i$ is the Balsara switch for particle $i$
-	\item $\mu_{ij} = a^{(3\gamma - 5)/2) {\rm min}(\mathbf{v}_{ij} \cdot \tilde{\mathbf{x}}_{ij} + r^2a^2 H, 0)$
+	\item $\mu_{ij} = a^{(3\gamma - 5)/2} {\rm min}(\mathbf{v}_{ij} \cdot \tilde{\mathbf{x}}_{ij} + r^2a^2 H, 0)$
 \end{itemize}