diff --git a/examples/DiscPatch/HydroStatic/disc-patch-icc.yml b/examples/DiscPatch/HydroStatic/disc-patch-icc.yml
index 9d1fe1b0948594f79c401e50308166313aa39924..6f17cfbb1e0125faf8e47fe4e9e55bfdf4df7b71 100644
--- a/examples/DiscPatch/HydroStatic/disc-patch-icc.yml
+++ b/examples/DiscPatch/HydroStatic/disc-patch-icc.yml
@@ -39,8 +39,8 @@ InitialConditions:
 DiscPatchPotential:
   surface_density: 10.
   scale_height:    100.
-  z_disc:          400.
-  z_trunc:         300.
-  z_max:           350.
+  x_disc:          400.
+  x_trunc:         300.
+  x_max:           350.
   timestep_mult:   0.03
   growth_time:     5.
diff --git a/examples/DiscPatch/HydroStatic/disc-patch.yml b/examples/DiscPatch/HydroStatic/disc-patch.yml
index 8ed78eaf8fffbb731cab4f583c3b3e8acee2b7be..8816bc17ca526d01b7abcf55bb43287bbb36224a 100644
--- a/examples/DiscPatch/HydroStatic/disc-patch.yml
+++ b/examples/DiscPatch/HydroStatic/disc-patch.yml
@@ -39,7 +39,7 @@ InitialConditions:
 DiscPatchPotential:
   surface_density: 10.
   scale_height:    100.
-  z_disc:          400.
-  z_trunc:         300.
-  z_max:           380.
+  x_disc:          400.
+  x_trunc:         300.
+  x_max:           380.
   timestep_mult:   0.03
diff --git a/examples/DiscPatch/HydroStatic/makeIC.py b/examples/DiscPatch/HydroStatic/makeIC.py
index 423dc8a44714a6e710b0c037f8a33d2120fbdcc8..11b482059b494fc9a6b9447fdfe2e7ec543d52ff 100644
--- a/examples/DiscPatch/HydroStatic/makeIC.py
+++ b/examples/DiscPatch/HydroStatic/makeIC.py
@@ -1,22 +1,24 @@
 ###############################################################################
- # This file is part of SWIFT.
- # Copyright (c) 2016 John A. Regan (john.a.regan@durham.ac.uk)
- #                    Tom Theuns (tom.theuns@durham.ac.uk)
- # 
- # 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/>.
- # 
- ##############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 John A. Regan (john.a.regan@durham.ac.uk)
+#                    Tom Theuns (tom.theuns@durham.ac.uk)
+#               2017 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#                    Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
+#
+# 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 h5py
 import sys
@@ -37,16 +39,16 @@ import random
 #                         Size of the patch -- side_length
 
 # Parameters of the gas disc
-surface_density = 10. 
+surface_density = 10.
 scale_height    = 100.
 gas_gamma       = 5./3.
 
 # Parameters of the problem
-z_factor        = 2
+x_factor        = 2
 side_length     = 400.
 
 # File
-fileName = "Disc-Patch.hdf5" 
+fileName = "Disc-Patch.hdf5"
 
 ####################################################################
 
@@ -64,30 +66,33 @@ unit_mass_in_cgs     =   (SOLAR_MASS_IN_CGS)
 unit_velocity_in_cgs =   (1e5)
 unit_time_in_cgs     =   unit_length_in_cgs / unit_velocity_in_cgs
 
-print "UnitMass_in_cgs:     %.5e"%unit_mass_in_cgs 
+print "UnitMass_in_cgs:     %.5e"%unit_mass_in_cgs
 print "UnitLength_in_cgs:   %.5e"%unit_length_in_cgs
 print "UnitVelocity_in_cgs: %.5e"%unit_velocity_in_cgs
 print "UnitTime_in_cgs:     %.5e"%unit_time_in_cgs
 print ""
 
 # Derived units
-const_G  = NEWTON_GRAVITY_CGS * unit_mass_in_cgs * unit_time_in_cgs**2 * unit_length_in_cgs**-3
+const_G  = NEWTON_GRAVITY_CGS * unit_mass_in_cgs * unit_time_in_cgs**2 * \
+           unit_length_in_cgs**-3
 const_mp = PROTON_MASS_IN_CGS * unit_mass_in_cgs**-1
-const_kb = BOLTZMANN_IN_CGS * unit_mass_in_cgs**-1 * unit_length_in_cgs**-2 * unit_time_in_cgs**2 
+const_kb = BOLTZMANN_IN_CGS * unit_mass_in_cgs**-1 * unit_length_in_cgs**-2 * \
+           unit_time_in_cgs**2
 
 print "--- Some constants [internal units] ---"
-print "G_Newton:            %.5e"%const_G
-print "m_proton:            %.5e"%const_mp
-print "k_boltzmann:         %.5e"%const_kb
+print "G_Newton:    %.5e"%const_G
+print "m_proton:    %.5e"%const_mp
+print "k_boltzmann: %.5e"%const_kb
 print ""
 
 # derived quantities
-temp                   = math.pi * const_G * surface_density * scale_height * const_mp / const_kb
-u_therm                = const_kb * temp / ((gas_gamma-1) * const_mp)
-v_disp                 = math.sqrt(2 * u_therm)
-soundspeed             = math.sqrt(u_therm / (gas_gamma * (gas_gamma-1.)))
-t_dyn                  = math.sqrt(scale_height / (const_G * surface_density))
-t_cross                = scale_height / soundspeed
+temp       = math.pi * const_G * surface_density * scale_height * const_mp / \
+             const_kb
+u_therm    = const_kb * temp / ((gas_gamma-1) * const_mp)
+v_disp     = math.sqrt(2 * u_therm)
+soundspeed = math.sqrt(u_therm / (gas_gamma * (gas_gamma-1.)))
+t_dyn      = math.sqrt(scale_height / (const_G * surface_density))
+t_cross    = scale_height / soundspeed
 
 print "--- Properties of the gas [internal units] ---"
 print "Gas temperature:     %.5e"%temp
@@ -101,18 +106,20 @@ print ""
 # Problem properties
 boxSize_x = side_length
 boxSize_y = boxSize_x
-boxSize_z = boxSize_x * z_factor
+boxSize_z = boxSize_x
+boxSize_x *= x_factor
 volume = boxSize_x * boxSize_y * boxSize_z
-M_tot = boxSize_x * boxSize_y * surface_density * math.tanh(boxSize_z / (2. * scale_height))
+M_tot = boxSize_y * boxSize_z * surface_density * \
+        math.tanh(boxSize_x / (2. * scale_height))
 density = M_tot / volume
 entropy = (gas_gamma - 1.) * u_therm / density**(gas_gamma - 1.)
 
 print "--- Problem properties [internal units] ---"
-print "Box:           [%.1f, %.1f, %.1f]"%(boxSize_x, boxSize_y, boxSize_z)
-print "Volume:        %.5e"%volume
-print "Total mass:    %.5e"%M_tot
-print "Density:       %.5e"%density
-print "Entropy:       %.5e"%entropy
+print "Box:        [%.1f, %.1f, %.1f]"%(boxSize_x, boxSize_y, boxSize_z)
+print "Volume:     %.5e"%volume
+print "Total mass: %.5e"%M_tot
+print "Density:    %.5e"%density
+print "Entropy:    %.5e"%entropy
 print ""
 
 ####################################################################
@@ -123,34 +130,24 @@ one_glass_pos = infile["/PartType0/Coordinates"][:,:]
 one_glass_h   = infile["/PartType0/SmoothingLength"][:]
 
 # Rescale to the problem size
-one_glass_pos    *= boxSize_x
-one_glass_h      *= boxSize_x
-
-#print min(one_glass_p[:,0]), max(one_glass_p[:,0])
-#print min(one_glass_p[:,1]), max(one_glass_p[:,1])
-#print min(one_glass_p[:,2]), max(one_glass_p[:,2])
+one_glass_pos *= side_length
+one_glass_h   *= side_length
 
-# Now create enough copies to fill the volume in z
+# Now create enough copies to fill the volume in x
 pos = np.copy(one_glass_pos)
 h = np.copy(one_glass_h)
-for i in range(1, z_factor):
-
-    one_glass_pos[:,2] += boxSize_x
-    
+for i in range(1, x_factor):
+    one_glass_pos[:,0] += side_length
     pos = np.append(pos, one_glass_pos, axis=0)
     h   = np.append(h, one_glass_h, axis=0)
 
-#print min(pos[:,0]), max(pos[:,0])
-#print min(pos[:,1]), max(pos[:,1])
-#print min(pos[:,2]), max(pos[:,2])
-
 # Compute further properties of ICs
 numPart = np.size(h)
 mass = M_tot / numPart
 
 print "--- Particle properties [internal units] ---"
 print "Number part.: ", numPart
-print "Part. mass:    %.5e"%mass
+print "Part. mass:   %.5e"%mass
 print ""
 
 # Create additional arrays
@@ -159,7 +156,6 @@ mass = np.ones(numPart) * mass
 vel  = np.zeros((numPart, 3))
 ids  = 1 + np.linspace(0, numPart, numPart, endpoint=False)
 
-
 ####################################################################
 # Create and write output file
 
@@ -169,7 +165,7 @@ file = h5py.File(fileName, 'w')
 #Units
 grp = file.create_group("/Units")
 grp.attrs["Unit length in cgs (U_L)"] = unit_length_in_cgs
-grp.attrs["Unit mass in cgs (U_M)"] = unit_mass_in_cgs 
+grp.attrs["Unit mass in cgs (U_M)"] = unit_mass_in_cgs
 grp.attrs["Unit time in cgs (U_t)"] = unit_time_in_cgs
 grp.attrs["Unit current in cgs (U_I)"] = 1.
 grp.attrs["Unit temperature in cgs (U_T)"] = 1.
@@ -200,13 +196,12 @@ ds = grp0.create_dataset('SmoothingLength', (numPart,), 'f', data=h)
 ds = grp0.create_dataset('InternalEnergy', (numPart,), 'f', data=u)
 ds = grp0.create_dataset('ParticleIDs', (numPart, ), 'L', data=ids)
 
-
 ####################################################################
 
 print "--- Runtime parameters (YAML file): ---"
 print "DiscPatchPotential:surface_density:    ", surface_density
 print "DiscPatchPotential:scale_height:       ", scale_height
-print "DiscPatchPotential:z_disc:             ", boxSize_z / 2.
+print "DiscPatchPotential:x_disc:             ", 0.5 * boxSize_x
 print ""
 
 print "--- Constant parameters: ---"
diff --git a/examples/DiscPatch/HydroStatic/plotSolution.py b/examples/DiscPatch/HydroStatic/plotSolution.py
index e70f595c645eaadc282e511bbc0d2c510025cc87..681f7d8ab3f2320b5de75e688edcb92efef9d883 100644
--- a/examples/DiscPatch/HydroStatic/plotSolution.py
+++ b/examples/DiscPatch/HydroStatic/plotSolution.py
@@ -1,6 +1,7 @@
 ################################################################################
 # This file is part of SWIFT.
 # Copyright (c) 2017 Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
+#                    Matthieu Schaller (matthieu.schaller@durham.ac.uk)
 #
 # 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
@@ -34,9 +35,9 @@ import sys
 # Parameters
 surface_density = 10.
 scale_height = 100.
-z_disc = 400.
-z_trunc = 300.
-z_max = 350.
+x_disc = 400.
+x_trunc = 300.
+x_max = 350.
 utherm = 20.2678457288
 gamma = 5. / 3.
 
@@ -50,14 +51,14 @@ if len(sys.argv) > 2:
 # Get the analytic solution for the density
 def get_analytic_density(x):
   return 0.5 * surface_density / scale_height / \
-           np.cosh( (x - z_disc) / scale_height )**2
+           np.cosh( (x - x_disc) / scale_height )**2
 
 # Get the analytic solution for the (isothermal) pressure
 def get_analytic_pressure(x):
   return (gamma - 1.) * utherm * get_analytic_density(x)
 
 # Get the data fields to plot from the snapshot file with the given name:
-#  snapshot time, z-coord, density, pressure, velocity norm
+#  snapshot time, x-coord, density, pressure, velocity norm
 def get_data(name):
   file = h5py.File(name, "r")
   coords = np.array(file["/PartType0/Coordinates"])
@@ -69,7 +70,7 @@ def get_data(name):
 
   vtot = np.sqrt( v[:,0]**2 + v[:,1]**2 + v[:,2]**2 )
 
-  return float(file["/Header"].attrs["Time"]), coords[:,2], rho, P, vtot
+  return float(file["/Header"].attrs["Time"]), coords[:,0], rho, P, vtot
 
 # scan the folder for snapshot files and plot all of them (within the requested
 # range)
@@ -80,38 +81,38 @@ for f in sorted(glob.glob("Disc-Patch_*.hdf5")):
 
   print "processing", f, "..."
 
-  zrange = np.linspace(0., 2. * z_disc, 1000)
-  time, z, rho, P, v = get_data(f)
+  xrange = np.linspace(0., 2. * x_disc, 1000)
+  time, x, rho, P, v = get_data(f)
 
   fig, ax = pl.subplots(3, 1, sharex = True)
 
-  ax[0].plot(z, rho, "r.")
-  ax[0].plot(zrange, get_analytic_density(zrange), "k-")
-  ax[0].plot([z_disc - z_max, z_disc - z_max], [0, 10], "k--", alpha=0.5)
-  ax[0].plot([z_disc + z_max, z_disc + z_max], [0, 10], "k--", alpha=0.5)
-  ax[0].plot([z_disc - z_trunc, z_disc - z_trunc], [0, 10], "k--", alpha=0.5)
-  ax[0].plot([z_disc + z_trunc, z_disc + z_trunc], [0, 10], "k--", alpha=0.5)
-  ax[0].set_ylim(0., 1.2 * get_analytic_density(z_disc))
+  ax[0].plot(x, rho, "r.")
+  ax[0].plot(xrange, get_analytic_density(xrange), "k-")
+  ax[0].plot([x_disc - x_max, x_disc - x_max], [0, 10], "k--", alpha=0.5)
+  ax[0].plot([x_disc + x_max, x_disc + x_max], [0, 10], "k--", alpha=0.5)
+  ax[0].plot([x_disc - x_trunc, x_disc - x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[0].plot([x_disc + x_trunc, x_disc + x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[0].set_ylim(0., 1.2 * get_analytic_density(x_disc))
   ax[0].set_ylabel("density")
 
-  ax[1].plot(z, v, "r.")
-  ax[1].plot(zrange, np.zeros(len(zrange)), "k-")
-  ax[1].plot([z_disc - z_max, z_disc - z_max], [0, 10], "k--", alpha=0.5)
-  ax[1].plot([z_disc + z_max, z_disc + z_max], [0, 10], "k--", alpha=0.5)
-  ax[1].plot([z_disc - z_trunc, z_disc - z_trunc], [0, 10], "k--", alpha=0.5)
-  ax[1].plot([z_disc + z_trunc, z_disc + z_trunc], [0, 10], "k--", alpha=0.5)
+  ax[1].plot(x, v, "r.")
+  ax[1].plot(xrange, np.zeros(len(xrange)), "k-")
+  ax[1].plot([x_disc - x_max, x_disc - x_max], [0, 10], "k--", alpha=0.5)
+  ax[1].plot([x_disc + x_max, x_disc + x_max], [0, 10], "k--", alpha=0.5)
+  ax[1].plot([x_disc - x_trunc, x_disc - x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[1].plot([x_disc + x_trunc, x_disc + x_trunc], [0, 10], "k--", alpha=0.5)
   ax[1].set_ylim(-0.5, 10.)
   ax[1].set_ylabel("velocity norm")
 
-  ax[2].plot(z, P, "r.")
-  ax[2].plot(zrange, get_analytic_pressure(zrange), "k-")
-  ax[2].plot([z_disc - z_max, z_disc - z_max], [0, 10], "k--", alpha=0.5)
-  ax[2].plot([z_disc + z_max, z_disc + z_max], [0, 10], "k--", alpha=0.5)
-  ax[2].plot([z_disc - z_trunc, z_disc - z_trunc], [0, 10], "k--", alpha=0.5)
-  ax[2].plot([z_disc + z_trunc, z_disc + z_trunc], [0, 10], "k--", alpha=0.5)
-  ax[2].set_xlim(0., 2. * z_disc)
-  ax[2].set_ylim(0., 1.2 * get_analytic_pressure(z_disc))
-  ax[2].set_xlabel("z")
+  ax[2].plot(x, P, "r.")
+  ax[2].plot(xrange, get_analytic_pressure(xrange), "k-")
+  ax[2].plot([x_disc - x_max, x_disc - x_max], [0, 10], "k--", alpha=0.5)
+  ax[2].plot([x_disc + x_max, x_disc + x_max], [0, 10], "k--", alpha=0.5)
+  ax[2].plot([x_disc - x_trunc, x_disc - x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[2].plot([x_disc + x_trunc, x_disc + x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[2].set_xlim(0., 2. * x_disc)
+  ax[2].set_ylim(0., 1.2 * get_analytic_pressure(x_disc))
+  ax[2].set_xlabel("x")
   ax[2].set_ylabel("pressure")
 
   pl.suptitle("t = {0:.2f}".format(time))
diff --git a/examples/DiscPatch/HydroStatic/run.sh b/examples/DiscPatch/HydroStatic/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e1f47ecad54e7e171d78b7da080d56579e985d1e
--- /dev/null
+++ b/examples/DiscPatch/HydroStatic/run.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassCube_32.hdf5 ]
+then
+    echo "Fetching initial glass file for the disc patch example..."
+    ./getGlass.sh
+fi
+if [ ! -e Disc-Patch.hdf5 ]
+then
+    echo "Generating initial conditions for the disc patch example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../../swift -g -s -t 4 disc-patch-icc.yml 2>&1 | tee output.log
+
+python plotSolution.py
diff --git a/examples/DiscPatch/HydroStatic_1D/disc-patch-icc.yml b/examples/DiscPatch/HydroStatic_1D/disc-patch-icc.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6f17cfbb1e0125faf8e47fe4e9e55bfdf4df7b71
--- /dev/null
+++ b/examples/DiscPatch/HydroStatic_1D/disc-patch-icc.yml
@@ -0,0 +1,46 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1.9885e33         # Grams
+  UnitLength_in_cgs:   3.08567758149e18  # Centimeters
+  UnitVelocity_in_cgs: 1e5               # Centimeters per second
+  UnitCurrent_in_cgs:  1   # Amperes
+  UnitTemp_in_cgs:     1   # Kelvin
+
+# Parameters governing the time integration
+TimeIntegration:
+  time_begin: 0     # The starting time of the simulation (in internal units).
+  time_end:   968.  # The end time of the simulation (in internal units).
+  dt_min:     1e-4  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     10.   # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          12. # Time between statistics output
+  
+# Parameters governing the snapshots
+Snapshots:
+  basename:    Disc-Patch   # Common part of the name of output files
+  time_first:  0.           # Time of the first output (in internal units)
+  delta_time:  48.          # Time difference between outputs (in internal units)
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2349   # Target smoothing length in units of the mean inter-particle separation (1.2349 == 48Ngbs with the cubic spline kernel).
+  delta_neighbours:      0.1      # The tolerance for the targetted number of neighbours.
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+  max_ghost_iterations:  30       # Maximal number of iterations allowed to converge towards the smoothing length.
+  h_max:                 60.      # Maximal smoothing length allowed (in internal units).
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  Disc-Patch.hdf5       # The file to read
+
+# External potential parameters
+DiscPatchPotential:
+  surface_density: 10.
+  scale_height:    100.
+  x_disc:          400.
+  x_trunc:         300.
+  x_max:           350.
+  timestep_mult:   0.03
+  growth_time:     5.
diff --git a/examples/DiscPatch/HydroStatic_1D/makeIC.py b/examples/DiscPatch/HydroStatic_1D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..1589dfc8c73e5b9bf3c2cad4bcf3029654d9e67e
--- /dev/null
+++ b/examples/DiscPatch/HydroStatic_1D/makeIC.py
@@ -0,0 +1,194 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 John A. Regan (john.a.regan@durham.ac.uk)
+#                    Tom Theuns (tom.theuns@durham.ac.uk)
+#               2017 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#                    Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
+#
+# 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 h5py
+import sys
+import numpy as np
+import math
+import random
+
+# Generates a disc-patch in hydrostatic equilibrium
+#
+# See Creasey, Theuns & Bower, 2013, MNRAS, Volume 429, Issue 3, p.1922-1948
+#
+#
+# Disc parameters are: surface density  -- sigma
+#                      scale height -- b
+#                      gas adiabatic index -- gamma
+#
+# Problem parameters are: Ratio height/width of the box -- z_factor
+#                         Size of the patch -- side_length
+
+# Parameters of the gas disc
+surface_density = 10.
+scale_height    = 100.
+gas_gamma       = 5./3.
+
+# Parameters of the problem
+x_factor        = 2
+side_length     = 400.
+numPart         = 1000
+
+# File
+fileName = "Disc-Patch.hdf5"
+
+####################################################################
+
+# physical constants in cgs
+NEWTON_GRAVITY_CGS  = 6.67408e-8
+SOLAR_MASS_IN_CGS   = 1.9885e33
+PARSEC_IN_CGS       = 3.08567758149e18
+PROTON_MASS_IN_CGS  = 1.672621898e-24
+BOLTZMANN_IN_CGS    = 1.38064852e-16
+YEAR_IN_CGS         = 3.15569252e7
+
+# choice of units
+unit_length_in_cgs   =   (PARSEC_IN_CGS)
+unit_mass_in_cgs     =   (SOLAR_MASS_IN_CGS)
+unit_velocity_in_cgs =   (1e5)
+unit_time_in_cgs     =   unit_length_in_cgs / unit_velocity_in_cgs
+
+print "UnitMass_in_cgs:     %.5e"%unit_mass_in_cgs
+print "UnitLength_in_cgs:   %.5e"%unit_length_in_cgs
+print "UnitVelocity_in_cgs: %.5e"%unit_velocity_in_cgs
+print "UnitTime_in_cgs:     %.5e"%unit_time_in_cgs
+print ""
+
+# Derived units
+const_G  = NEWTON_GRAVITY_CGS * unit_mass_in_cgs * unit_time_in_cgs**2 * \
+           unit_length_in_cgs**-3
+const_mp = PROTON_MASS_IN_CGS * unit_mass_in_cgs**-1
+const_kb = BOLTZMANN_IN_CGS * unit_mass_in_cgs**-1 * unit_length_in_cgs**-2 * \
+           unit_time_in_cgs**2
+
+print "--- Some constants [internal units] ---"
+print "G_Newton:    %.5e"%const_G
+print "m_proton:    %.5e"%const_mp
+print "k_boltzmann: %.5e"%const_kb
+print ""
+
+# derived quantities
+temp       = math.pi * const_G * surface_density * scale_height * const_mp / \
+             const_kb
+u_therm    = const_kb * temp / ((gas_gamma-1) * const_mp)
+v_disp     = math.sqrt(2 * u_therm)
+soundspeed = math.sqrt(u_therm / (gas_gamma * (gas_gamma-1.)))
+t_dyn      = math.sqrt(scale_height / (const_G * surface_density))
+t_cross    = scale_height / soundspeed
+
+print "--- Properties of the gas [internal units] ---"
+print "Gas temperature:     %.5e"%temp
+print "Gas thermal_energy:  %.5e"%u_therm
+print "Dynamical time:      %.5e"%t_dyn
+print "Sound crossing time: %.5e"%t_cross
+print "Gas sound speed:     %.5e"%soundspeed
+print "Gas 3D vel_disp:     %.5e"%v_disp
+print ""
+
+# Problem properties
+boxSize_x = side_length
+boxSize_x *= x_factor
+volume = boxSize_x
+M_tot = surface_density * math.tanh(boxSize_x / (2. * scale_height))
+density = M_tot / volume
+entropy = (gas_gamma - 1.) * u_therm / density**(gas_gamma - 1.)
+
+print "--- Problem properties [internal units] ---"
+print "Box:        %.1f"%boxSize_x
+print "Volume:     %.5e"%volume
+print "Total mass: %.5e"%M_tot
+print "Density:    %.5e"%density
+print "Entropy:    %.5e"%entropy
+print ""
+
+####################################################################
+
+# Now create enough copies to fill the volume in x
+pos = np.zeros((numPart, 3))
+h = np.zeros(numPart) + 2. * boxSize_x / numPart
+for i in range(numPart):
+    pos[i, 0] = (i + 0.5) * boxSize_x / numPart
+
+# Compute further properties of ICs
+mass = M_tot / numPart
+
+print "--- Particle properties [internal units] ---"
+print "Number part.: ", numPart
+print "Part. mass:   %.5e"%mass
+print ""
+
+# Create additional arrays
+u    = np.ones(numPart) * u_therm
+mass = np.ones(numPart) * mass
+vel  = np.zeros((numPart, 3))
+ids  = 1 + np.linspace(0, numPart, numPart, endpoint=False)
+
+####################################################################
+# Create and write output file
+
+#File
+file = h5py.File(fileName, 'w')
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = unit_length_in_cgs
+grp.attrs["Unit mass in cgs (U_M)"] = unit_mass_in_cgs
+grp.attrs["Unit time in cgs (U_t)"] = unit_time_in_cgs
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [boxSize_x, 1., 1.]
+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, 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]
+grp.attrs["Flag_Entropy_ICs"] = [0, 0, 0, 0, 0, 0]
+grp.attrs["Dimension"] = 1
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+# write gas particles
+grp0   = file.create_group("/PartType0")
+
+ds = grp0.create_dataset('Coordinates', (numPart, 3), 'f', data=pos)
+ds = grp0.create_dataset('Velocities', (numPart, 3), 'f')
+ds = grp0.create_dataset('Masses', (numPart,), 'f', data=mass)
+ds = grp0.create_dataset('SmoothingLength', (numPart,), 'f', data=h)
+ds = grp0.create_dataset('InternalEnergy', (numPart,), 'f', data=u)
+ds = grp0.create_dataset('ParticleIDs', (numPart, ), 'L', data=ids)
+
+####################################################################
+
+print "--- Runtime parameters (YAML file): ---"
+print "DiscPatchPotential:surface_density:    ", surface_density
+print "DiscPatchPotential:scale_height:       ", scale_height
+print "DiscPatchPotential:x_disc:             ", 0.5 * boxSize_x
+print ""
+
+print "--- Constant parameters: ---"
+print "const_isothermal_internal_energy: %ef"%u_therm
diff --git a/examples/DiscPatch/HydroStatic_1D/plotSolution.py b/examples/DiscPatch/HydroStatic_1D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..681f7d8ab3f2320b5de75e688edcb92efef9d883
--- /dev/null
+++ b/examples/DiscPatch/HydroStatic_1D/plotSolution.py
@@ -0,0 +1,121 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2017 Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
+#                    Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#
+# 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/>.
+#
+################################################################################
+
+##
+# This script plots the Disc-Patch_*.hdf5 snapshots.
+# It takes two (optional) parameters: the counter value of the first and last
+# snapshot to plot (default: 0 21).
+##
+
+import numpy as np
+import h5py
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import glob
+import sys
+
+# Parameters
+surface_density = 10.
+scale_height = 100.
+x_disc = 400.
+x_trunc = 300.
+x_max = 350.
+utherm = 20.2678457288
+gamma = 5. / 3.
+
+start = 0
+stop = 21
+if len(sys.argv) > 1:
+  start = int(sys.argv[1])
+if len(sys.argv) > 2:
+  stop = int(sys.argv[2])
+
+# Get the analytic solution for the density
+def get_analytic_density(x):
+  return 0.5 * surface_density / scale_height / \
+           np.cosh( (x - x_disc) / scale_height )**2
+
+# Get the analytic solution for the (isothermal) pressure
+def get_analytic_pressure(x):
+  return (gamma - 1.) * utherm * get_analytic_density(x)
+
+# Get the data fields to plot from the snapshot file with the given name:
+#  snapshot time, x-coord, density, pressure, velocity norm
+def get_data(name):
+  file = h5py.File(name, "r")
+  coords = np.array(file["/PartType0/Coordinates"])
+  rho = np.array(file["/PartType0/Density"])
+  u = np.array(file["/PartType0/InternalEnergy"])
+  v = np.array(file["/PartType0/Velocities"])
+
+  P = (gamma - 1.) * rho * u
+
+  vtot = np.sqrt( v[:,0]**2 + v[:,1]**2 + v[:,2]**2 )
+
+  return float(file["/Header"].attrs["Time"]), coords[:,0], rho, P, vtot
+
+# scan the folder for snapshot files and plot all of them (within the requested
+# range)
+for f in sorted(glob.glob("Disc-Patch_*.hdf5")):
+  num = int(f[-8:-5])
+  if num < start or num > stop:
+    continue
+
+  print "processing", f, "..."
+
+  xrange = np.linspace(0., 2. * x_disc, 1000)
+  time, x, rho, P, v = get_data(f)
+
+  fig, ax = pl.subplots(3, 1, sharex = True)
+
+  ax[0].plot(x, rho, "r.")
+  ax[0].plot(xrange, get_analytic_density(xrange), "k-")
+  ax[0].plot([x_disc - x_max, x_disc - x_max], [0, 10], "k--", alpha=0.5)
+  ax[0].plot([x_disc + x_max, x_disc + x_max], [0, 10], "k--", alpha=0.5)
+  ax[0].plot([x_disc - x_trunc, x_disc - x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[0].plot([x_disc + x_trunc, x_disc + x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[0].set_ylim(0., 1.2 * get_analytic_density(x_disc))
+  ax[0].set_ylabel("density")
+
+  ax[1].plot(x, v, "r.")
+  ax[1].plot(xrange, np.zeros(len(xrange)), "k-")
+  ax[1].plot([x_disc - x_max, x_disc - x_max], [0, 10], "k--", alpha=0.5)
+  ax[1].plot([x_disc + x_max, x_disc + x_max], [0, 10], "k--", alpha=0.5)
+  ax[1].plot([x_disc - x_trunc, x_disc - x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[1].plot([x_disc + x_trunc, x_disc + x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[1].set_ylim(-0.5, 10.)
+  ax[1].set_ylabel("velocity norm")
+
+  ax[2].plot(x, P, "r.")
+  ax[2].plot(xrange, get_analytic_pressure(xrange), "k-")
+  ax[2].plot([x_disc - x_max, x_disc - x_max], [0, 10], "k--", alpha=0.5)
+  ax[2].plot([x_disc + x_max, x_disc + x_max], [0, 10], "k--", alpha=0.5)
+  ax[2].plot([x_disc - x_trunc, x_disc - x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[2].plot([x_disc + x_trunc, x_disc + x_trunc], [0, 10], "k--", alpha=0.5)
+  ax[2].set_xlim(0., 2. * x_disc)
+  ax[2].set_ylim(0., 1.2 * get_analytic_pressure(x_disc))
+  ax[2].set_xlabel("x")
+  ax[2].set_ylabel("pressure")
+
+  pl.suptitle("t = {0:.2f}".format(time))
+
+  pl.savefig("{name}.png".format(name = f[:-5]))
+  pl.close()
diff --git a/examples/DiscPatch/HydroStatic_1D/run.sh b/examples/DiscPatch/HydroStatic_1D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e9d073a6cc7a06ec9ebd9fdb556c44778d32c7f4
--- /dev/null
+++ b/examples/DiscPatch/HydroStatic_1D/run.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e Disc-Patch.hdf5 ]
+then
+    echo "Generating initial conditions for the disc patch example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../../swift -g -s -t 4 disc-patch-icc.yml 2>&1 | tee output.log
+
+python plotSolution.py
diff --git a/examples/plot_threadpool.py b/examples/plot_threadpool.py
deleted file mode 100755
index 68b038ed406fdac8c4fee3e250fbb397bb51ae21..0000000000000000000000000000000000000000
--- a/examples/plot_threadpool.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/usr/bin/env python
-"""
-Usage:
-    plot_threadpool.py [options] input.dat output.png
-
-where input.dat is a threadpool info file for a step.  Use the '-Y interval'
-flag of the swift command to create these. The output plot will be called
-'output.png'. The --limit option can be used to produce plots with the same
-time span and the --expand option to expand each thread line into '*expand'
-lines, so that adjacent tasks of the same type can be distinguished. Other
-options can be seen using the --help flag.
-
-This file is part of SWIFT.
-Copyright (c) 2015 Pedro Gonnet (pedro.gonnet@durham.ac.uk),
-                   Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
-                   Matthieu Schaller (matthieu.schaller@durham.ac.uk)
-          (c) 2017 Peter W. Draper (p.w.draper@durham.ac.uk)
-
-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")
-import matplotlib.collections as collections
-import matplotlib.ticker as plticker
-import pylab as pl
-import sys
-import argparse
-
-#  Handle the command line.
-parser = argparse.ArgumentParser(description="Plot threadpool function graphs")
-
-parser.add_argument("input", help="Threadpool data file (-Y output)")
-parser.add_argument("outpng", help="Name for output graphic file (PNG)")
-parser.add_argument("-l", "--limit", dest="limit",
-                    help="Upper time limit in millisecs (def: depends on data)",
-                    default=0, type=int)
-parser.add_argument("-e", "--expand", dest="expand",
-                    help="Thread expansion factor (def: 1)",
-                    default=1, type=int)
-parser.add_argument("--height", dest="height",
-                    help="Height of plot in inches (def: 4)",
-                    default=4., type=float)
-parser.add_argument("--width", dest="width",
-                    help="Width of plot in inches (def: 16)",
-                    default=16., type=float)
-parser.add_argument("--nolegend", dest="nolegend",
-                    help="Whether to show the legend (def: False)",
-                    default=False, action="store_true")
-parser.add_argument("-v", "--verbose", dest="verbose",
-                    help="Show colour assignments and other details (def: False)",
-                    default=False, action="store_true")
-
-args = parser.parse_args()
-infile = args.input
-outpng = args.outpng
-delta_t = args.limit
-expand = args.expand
-
-#  Basic plot configuration.
-PLOT_PARAMS = {"axes.labelsize": 10,
-               "axes.titlesize": 10,
-               "font.size": 12,
-               "legend.fontsize": 12,
-               "xtick.labelsize": 10,
-               "ytick.labelsize": 10,
-               "figure.figsize" : (args.width, args.height),
-               "figure.subplot.left" : 0.03,
-               "figure.subplot.right" : 0.995,
-               "figure.subplot.bottom" : 0.09,
-               "figure.subplot.top" : 0.99,
-               "figure.subplot.wspace" : 0.,
-               "figure.subplot.hspace" : 0.,
-               "lines.markersize" : 6,
-               "lines.linewidth" : 3.
-               }
-pl.rcParams.update(PLOT_PARAMS)
-
-#  A number of colours for the various types. Recycled when there are
-#  more task types than colours...
-colours = ["cyan", "lightgray", "darkblue", "yellow", "tan", "dodgerblue",
-           "sienna", "aquamarine", "bisque", "blue", "green", "lightgreen",
-           "brown", "purple", "moccasin", "olivedrab", "chartreuse",
-           "darksage", "darkgreen", "green", "mediumseagreen",
-           "mediumaquamarine", "darkslategrey", "mediumturquoise",
-           "black", "cadetblue", "skyblue", "red", "slategray", "gold",
-           "slateblue", "blueviolet", "mediumorchid", "firebrick",
-           "magenta", "hotpink", "pink", "orange", "lightgreen"]
-maxcolours = len(colours)
-
-#  Read header. First two lines.
-with open(infile) as infid:
-    head = [next(infid) for x in xrange(2)]
-header = head[1][2:].strip()
-header = eval(header)
-nthread = int(header['num_threads']) + 1
-CPU_CLOCK = float(header['cpufreq']) / 1000.0
-print "Number of threads: ", nthread
-if args.verbose:
-    print "CPU frequency:", CPU_CLOCK * 1000.0
-
-#  Read input.
-data = pl.genfromtxt(infile, dtype=None, delimiter=" ")
-
-#  Mixed types, so need to separate.
-tics = []
-tocs = []
-funcs = []
-threads = []
-chunks = []
-for i in data:
-    if i[0] != "#":
-        funcs.append(i[0])
-        if i[1] < 0:
-            threads.append(nthread-1)
-        else:
-            threads.append(i[1])
-        chunks.append(i[2])
-        tics.append(i[3])
-        tocs.append(i[4])
-tics = pl.array(tics)
-tocs = pl.array(tocs)
-funcs = pl.array(funcs)
-threads = pl.array(threads)
-chunks = pl.array(chunks)
-
-
-#  Recover the start and end time
-tic_step = min(tics)
-toc_step = max(tocs)
-
-#   Not known.
-
-#  Calculate the time range, if not given.
-delta_t = delta_t * CPU_CLOCK
-if delta_t == 0:
-    dt = toc_step - tic_step
-    if dt > delta_t:
-        delta_t = dt
-    print "Data range: ", delta_t / CPU_CLOCK, "ms"
-
-#  Once more doing the real gather and plots this time.
-start_t = float(tic_step)
-tics -= tic_step
-tocs -= tic_step
-end_t = (toc_step - start_t) / CPU_CLOCK
-
-#  Get all "task" names and assign colours.
-TASKTYPES = pl.unique(funcs)
-print TASKTYPES
-
-#  Set colours of task/subtype.
-TASKCOLOURS = {}
-ncolours = 0
-for task in TASKTYPES:
-    TASKCOLOURS[task] = colours[ncolours]
-    ncolours = (ncolours + 1) % maxcolours
-
-#  For fiddling with colours...
-if args.verbose:
-    print "#Selected colours:"
-    for task in sorted(TASKCOLOURS.keys()):
-        print "# " + task + ": " + TASKCOLOURS[task]
-    for task in sorted(SUBCOLOURS.keys()):
-        print "# " + task + ": " + SUBCOLOURS[task]
-
-tasks = {}
-tasks[-1] = []
-for i in range(nthread*expand):
-    tasks[i] = []
-
-#  Counters for each thread when expanding.
-ecounter = []
-for i in range(nthread):
-    ecounter.append(0)
-
-for i in range(len(threads)):
-    thread = threads[i]
-
-    # Expand to cover extra lines if expanding.
-    ethread = thread * expand + (ecounter[thread] % expand)
-    ecounter[thread] = ecounter[thread] + 1
-    thread = ethread
-
-    tasks[thread].append({})
-    tasks[thread][-1]["type"] = funcs[i]
-    tic = tics[i] / CPU_CLOCK
-    toc = tocs[i] / CPU_CLOCK
-    tasks[thread][-1]["tic"] = tic
-    tasks[thread][-1]["toc"] = toc
-    tasks[thread][-1]["colour"] = TASKCOLOURS[funcs[i]]
-
-# Use expanded threads from now on.
-nthread = nthread * expand
-
-typesseen = []
-fig = pl.figure()
-ax = fig.add_subplot(1,1,1)
-ax.set_xlim(-delta_t * 0.01 / CPU_CLOCK, delta_t * 1.01 / CPU_CLOCK)
-ax.set_ylim(0, nthread)
-
-# Fake thread is used to colour the whole range, do that first.
-tictocs = []
-colours = []
-j = 0
-for task in tasks[nthread - expand]:
-    tictocs.append((task["tic"], task["toc"] - task["tic"]))
-    colours.append(task["colour"])
-ax.broken_barh(tictocs, [0,(nthread-1)], facecolors = colours, linewidth=0, alpha=0.15)
-
-# And we don't plot the fake thread.
-nthread = nthread - expand
-for i in range(nthread):
-
-    #  Collect ranges and colours into arrays.
-    tictocs = []
-    colours = []
-    j = 0
-    for task in tasks[i]:
-        tictocs.append((task["tic"], task["toc"] - task["tic"]))
-        colours.append(task["colour"])
-
-        #  Legend support, collections don't add to this.
-        qtask = task["type"]
-        if qtask not in typesseen:
-            pl.plot([], [], color=task["colour"], label=qtask)
-            typesseen.append(qtask)
-
-    #  Now plot.
-    ax.broken_barh(tictocs, [i+0.05,0.90], facecolors = colours, linewidth=0)
-
-#  Legend and room for it.
-nrow = len(typesseen) / 5
-if not args.nolegend:
-    ax.fill_between([0, 0], nthread+0.5, nthread + nrow + 0.5, facecolor="white")
-    ax.set_ylim(0, nthread + 0.5)
-    ax.legend(loc=1, shadow=True, bbox_to_anchor=(0., 1.05 ,1., 0.2), mode="expand", ncol=5)
-    box = ax.get_position()
-    ax.set_position([box.x0, box.y0, box.width, box.height*0.8])
-    
-# Start and end of time-step
-ax.plot([0, 0], [0, nthread + nrow + 1], 'k--', linewidth=1)
-ax.plot([end_t, end_t], [0, nthread + nrow + 1], 'k--', linewidth=1)
-
-ax.set_xlabel("Wall clock time [ms]", labelpad=0.)
-if expand == 1:
-    ax.set_ylabel("Thread ID", labelpad=0 )
-else:
-    ax.set_ylabel("Thread ID * " + str(expand), labelpad=0 )
-ax.set_yticks(pl.array(range(nthread)), True)
-
-loc = plticker.MultipleLocator(base=expand)
-ax.yaxis.set_major_locator(loc)
-ax.grid(True, which='major', axis="y", linestyle="-")
-
-pl.show()
-pl.savefig(outpng)
-print "Graphics done, output written to", outpng
-
-sys.exit(0)
diff --git a/examples/process_plot_threadpool b/examples/process_plot_threadpool
deleted file mode 100755
index d7bef48d313d50a2627de69263202fa4782efa74..0000000000000000000000000000000000000000
--- a/examples/process_plot_threadpool
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/bash
-#
-# Usage:
-#  process_plot_threadpool nprocess time-range-ms
-#
-# Description:
-#  Process all the threadpool info files in the current directory
-#  creating function graphs for steps and threads.
-#
-#  The input files are created by a run using the "-Y interval" flag and
-#  should be named "threadpool_info-step<n>.dat" in the current directory.
-#  All located files will be processed using "nprocess" concurrent
-#  processes and all plots will have the given time range. An output
-#  HTML file "index.html" will be created to view all the plots.
-#
-#
-# This file is part of SWIFT:
-#
-#  Copyright (C) 2017 Peter W. Draper (p.w.draper@durham.ac.uk)
-#  All Rights Reserved.
-#
-#  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/>.
-
-#  Handle command-line
-if test "$2" == ""; then
-    echo "Usage: $0 nprocess time-range-ms"
-    exit 1
-fi
-NPROCS=$1
-TIMERANGE=$2
-
-#  Find all thread info files. Use version sort to get into correct order.
-files=$(ls -v threadpool_info-step*.dat)
-if test $? != 0; then
-    echo "Failed to find any threadpool info files"
-    exit 1
-fi
-
-#  Construct list of names, the step no and names for the graphics.
-list=""
-for f in $files; do
-    s=$(echo $f| sed 's,threadpool_info-step\(.*\).dat,\1,')
-    list="$list $f $s poolstep${s}r"
-done
-
-#  And process them,
-echo "Processing threadpool info files..."
-echo $list | xargs -P $NPROCS -n 3 /bin/bash -c "./plot_threadpool.py --expand 3 --limit $TIMERANGE --width 16 --height 4 \$0 \$2 "
-
-echo "Writing output index.html file"
-#  Construct document - serial.
-cat <<EOF > index.html
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-  <head>
-    <title>SWIFT task graphs</title>
-  </head>
-  <body>
-  <h1>SWIFT task graphs</h1>
-EOF
-
-echo $list | xargs -n 3 | while read f s g; do
-    cat <<EOF >> index.html
-<h2>Step $s</h2>
-EOF
-    cat <<EOF >> index.html
-<a href="poolstep${s}r${i}.html"><img src="poolstep${s}r${i}.png" width=400px/></a>
-EOF
-    cat <<EOF > poolstep${s}r${i}.html
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<body>
-<img src="poolstep${s}r${i}.png">
-<pre>
-EOF
-done
-
-cat <<EOF >> index.html
-  </body>
-</html>
-EOF
-
-echo "Finished"
-
-exit
diff --git a/src/Makefile.am b/src/Makefile.am
index 2ddcdb0908201c65053d7cc5380a4217277b5c13..3784886278544a1c6b606689bfbae0d6fa52cf19 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,6 +86,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h cycle.h error.h inline.h
                  hydro/Gizmo/hydro_slope_limiters_cell.h \
                  hydro/Gizmo/hydro_slope_limiters_face.h \
                  hydro/Gizmo/hydro_slope_limiters.h \
+                 hydro/Gizmo/hydro_flux_limiters.h \
                  hydro/Gizmo/hydro_unphysical.h \
                  hydro/Gizmo/hydro_velocities.h \
                  hydro/Shadowswift/hydro_debug.h \
diff --git a/src/cell.c b/src/cell.c
index 7edee4d9ae1c02311af295bb6eba5c846a94259c..8386161a15cc110b9abc92e3539776cba0c918ec 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -1745,9 +1745,9 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) {
           if (l == NULL) error("Missing link to send_xv task.");
           scheduler_activate(s, l->t);
 
-          /* Drift the cell which will be sent at the level at which it is sent,
-             i.e. drift the cell specified in the send task (l->t) itself. */
-          cell_activate_drift_part(l->t->ci, s);
+          /* Drift the cell which will be sent; note that not all sent
+             particles will be drifted, only those that are needed. */
+          cell_activate_drift_part(cj, s);
 
           if (cell_is_active(cj, e)) {
             struct link *l = NULL;
@@ -1802,9 +1802,9 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) {
           if (l == NULL) error("Missing link to send_xv task.");
           scheduler_activate(s, l->t);
 
-          /* Drift the cell which will be sent at the level at which it is sent,
-             i.e. drift the cell specified in the send task (l->t) itself. */
-          cell_activate_drift_part(l->t->ci, s);
+          /* Drift the cell which will be sent; note that not all sent
+             particles will be drifted, only those that are needed. */
+          cell_activate_drift_part(ci, s);
 
           if (cell_is_active(ci, e)) {
 
diff --git a/src/const.h b/src/const.h
index f5232de0b2b4aba6701c07f1e5f91d5be3d5b6cc..c8060a2be51468a791e192a65a74f1a4d9bc8e30 100644
--- a/src/const.h
+++ b/src/const.h
@@ -49,6 +49,9 @@
 #define SLOPE_LIMITER_PER_FACE
 #define SLOPE_LIMITER_CELL_WIDE
 
+/* Types of flux limiter to use (GIZMO_SPH only) */
+#define GIZMO_FLUX_LIMITER
+
 /* Options to control the movement of particles for GIZMO_SPH. */
 /* This option disables particle movement */
 //#define GIZMO_FIX_PARTICLES
diff --git a/src/engine.c b/src/engine.c
index 6bd2fb5ade526e4ff7fd363fa655fd096afcd827..ee48d6565dc62f725b0159dc44e8d9d92d7a4adf 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2402,6 +2402,21 @@ void engine_make_gravityrecursive_tasks(struct engine *e) {
   /* } */
 }
 
+void engine_check_sort_tasks(struct engine *e, struct cell *c) {
+
+  /* Find the parent sort task, if any, and copy its flags. */
+  if (c->sorts != NULL) {
+    struct cell *parent = c->parent;
+    while (parent != NULL && parent->sorts == NULL) parent = parent->parent;
+    if (parent != NULL) c->sorts->flags |= parent->sorts->flags;
+  }
+
+  /* Recurse? */
+  if (c->split)
+    for (int k = 0; k < 8; k++)
+      if (c->progeny[k] != NULL) engine_check_sort_tasks(e, c->progeny[k]);
+}
+
 /**
  * @brief Fill the #space's task list.
  *
@@ -2480,6 +2495,9 @@ void engine_maketasks(struct engine *e) {
   for (int k = 0; k < nr_cells; k++)
     engine_make_hierarchical_tasks(e, &cells[k]);
 
+  /* Append hierarchical tasks to each cell. */
+  for (int k = 0; k < nr_cells; k++) engine_check_sort_tasks(e, &cells[k]);
+
   /* Run through the tasks and make force tasks for each density task.
      Each force task depends on the cell ghosts and unlocks the kick task
      of its super-cell. */
@@ -2774,7 +2792,7 @@ int engine_marktasks(struct engine *e) {
   /* Run through the tasks and mark as skip or not. */
   size_t extra_data[3] = {(size_t)e, rebuild_space, (size_t)&e->sched};
   threadpool_map(&e->threadpool, engine_marktasks_mapper, s->tasks, s->nr_tasks,
-                 sizeof(struct task), 0, extra_data);
+                 sizeof(struct task), 10000, extra_data);
   rebuild_space = extra_data[1];
 
   if (e->verbose)
@@ -3678,7 +3696,7 @@ void engine_drift_all(struct engine *e) {
 #endif
 
   threadpool_map(&e->threadpool, engine_do_drift_all_mapper, e->s->cells_top,
-                 e->s->nr_cells, sizeof(struct cell), 0, e);
+                 e->s->nr_cells, sizeof(struct cell), 1, e);
 
   /* Synchronize particle positions */
   space_synchronize_particle_positions(e->s);
@@ -3730,7 +3748,7 @@ void engine_drift_top_multipoles(struct engine *e) {
   const ticks tic = getticks();
 
   threadpool_map(&e->threadpool, engine_do_drift_top_multipoles_mapper,
-                 e->s->cells_top, e->s->nr_cells, sizeof(struct cell), 0, e);
+                 e->s->cells_top, e->s->nr_cells, sizeof(struct cell), 10, e);
 
 #ifdef SWIFT_DEBUG_CHECKS
   /* Check that all cells have been drifted to the current time. */
@@ -3768,7 +3786,7 @@ void engine_reconstruct_multipoles(struct engine *e) {
   const ticks tic = getticks();
 
   threadpool_map(&e->threadpool, engine_do_reconstruct_multipoles_mapper,
-                 e->s->cells_top, e->s->nr_cells, sizeof(struct cell), 0, e);
+                 e->s->cells_top, e->s->nr_cells, sizeof(struct cell), 10, e);
 
   if (e->verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
diff --git a/src/engine.h b/src/engine.h
index 79ff45a69a39ee7d4d45589df51ce2d53f810fda..c7aaa08b57eb2e61b311deae7a7ccb102f7e3cf8 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -77,7 +77,7 @@ extern const char *engine_policy_names[];
 #define engine_queue_scale 1.2
 #define engine_maxtaskspercell 96
 #define engine_maxproxies 64
-#define engine_tasksreweight 1
+#define engine_tasksreweight 10
 #define engine_parts_size_grow 1.05
 #define engine_redistribute_alloc_margin 1.2
 #define engine_default_energy_file_name "energy"
diff --git a/src/gravity.c b/src/gravity.c
index 49bbaca39b5278009543204a0d9f5e72d69806c4..97b2955b32e1513c3d86d1d1f4da2169130feb77 100644
--- a/src/gravity.c
+++ b/src/gravity.c
@@ -207,7 +207,7 @@ void gravity_exact_force_compute(struct space *s, const struct engine *e) {
   data.const_G = e->physical_constants->const_newton_G;
 
   threadpool_map(&s->e->threadpool, gravity_exact_force_compute_mapper,
-                 s->gparts, s->nr_gparts, sizeof(struct gpart), 0, &data);
+                 s->gparts, s->nr_gparts, sizeof(struct gpart), 1000, &data);
 
   message("Computed exact gravity for %d gparts (took %.3f %s). ",
           data.counter_global, clocks_from_ticks(getticks() - tic),
diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h
index 49e748c71b4544ff6148e6910f66381294608e8f..2c2f54699bb380a491edf61a83ad8a031572c86c 100644
--- a/src/hydro/Gizmo/hydro.h
+++ b/src/hydro/Gizmo/hydro.h
@@ -49,17 +49,21 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep(
   return CFL_condition;
 #endif
 
-  if (p->timestepvars.vmax == 0.) {
-    /* vmax can be zero in vacuum cells that only have vacuum neighbours */
-    /* in this case, the time step should be limited by the maximally
-       allowed time step. Since we do not know what that value is here, we set
-       the time step to a very large value */
-    return FLT_MAX;
-  } else {
-    const float psize = powf(p->geometry.volume / hydro_dimension_unit_sphere,
-                             hydro_dimension_inv);
-    return 2. * CFL_condition * psize / fabsf(p->timestepvars.vmax);
+  float vrel[3];
+  vrel[0] = p->primitives.v[0] - xp->v_full[0];
+  vrel[1] = p->primitives.v[1] - xp->v_full[1];
+  vrel[2] = p->primitives.v[2] - xp->v_full[2];
+  float vmax =
+      sqrtf(vrel[0] * vrel[0] + vrel[1] * vrel[1] + vrel[2] * vrel[2]) +
+      sqrtf(hydro_gamma * p->primitives.P / p->primitives.rho);
+  vmax = max(vmax, p->timestepvars.vmax);
+  const float psize = powf(p->geometry.volume / hydro_dimension_unit_sphere,
+                           hydro_dimension_inv);
+  float dt = FLT_MAX;
+  if (vmax > 0.) {
+    dt = psize / vmax;
   }
+  return CFL_condition * dt;
 }
 
 /**
@@ -421,7 +425,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force(
     struct part* restrict p, struct xpart* restrict xp) {
 
   /* Initialize time step criterion variables */
-  p->timestepvars.vmax = 0.0f;
+  p->timestepvars.vmax = 0.;
 
   /* Set the actual velocity of the particle */
   hydro_velocities_prepare_force(p, xp);
@@ -638,24 +642,12 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra(
     a_grav[1] = p->gpart->a_grav[1];
     a_grav[2] = p->gpart->a_grav[2];
 
-    /* Store the gravitational acceleration for later use. */
-    /* This is used for the prediction step. */
-    p->gravity.old_a[0] = a_grav[0];
-    p->gravity.old_a[1] = a_grav[1];
-    p->gravity.old_a[2] = a_grav[2];
-
     /* Make sure the gpart knows the mass has changed. */
     p->gpart->mass = p->conserved.mass;
 
-    /* Kick the momentum for half a time step */
-    /* Note that this also affects the particle movement, as the velocity for
-       the particles is set after this. */
-    p->conserved.momentum[0] += dt * p->conserved.mass * a_grav[0];
-    p->conserved.momentum[1] += dt * p->conserved.mass * a_grav[1];
-    p->conserved.momentum[2] += dt * p->conserved.mass * a_grav[2];
-
 #if !defined(EOS_ISOTHERMAL_GAS)
-    /* This part still needs to be tested! */
+    /* If the energy needs to be updated, we need to do it before the momentum
+       is updated, as the old value of the momentum enters the equations. */
     p->conserved.energy += dt * (p->conserved.momentum[0] * a_grav[0] +
                                  p->conserved.momentum[1] * a_grav[1] +
                                  p->conserved.momentum[2] * a_grav[2]);
@@ -664,6 +656,13 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra(
                                  a_grav[1] * p->gravity.mflux[1] +
                                  a_grav[2] * p->gravity.mflux[2]);
 #endif
+
+    /* Kick the momentum for half a time step */
+    /* Note that this also affects the particle movement, as the velocity for
+       the particles is set after this. */
+    p->conserved.momentum[0] += dt * p->conserved.mass * a_grav[0];
+    p->conserved.momentum[1] += dt * p->conserved.mass * a_grav[1];
+    p->conserved.momentum[2] += dt * p->conserved.mass * a_grav[2];
   }
 
   /* reset fluxes */
diff --git a/src/hydro/Gizmo/hydro_debug.h b/src/hydro/Gizmo/hydro_debug.h
index a05ff9a7d96f04ca3354235540adc31386a2d2e3..17e7f8a08570e355a701f8e165ee8af745fa34ab 100644
--- a/src/hydro/Gizmo/hydro_debug.h
+++ b/src/hydro/Gizmo/hydro_debug.h
@@ -46,7 +46,7 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle(
       "volume=%.3e, "
       "matrix_E=[[%.3e,%.3e,%.3e],[%.3e,%.3e,%.3e],[%.3e,%.3e,%.3e]]}, "
       "timestepvars={"
-      "vmax=%.3e}, "
+      "vmax=%.3e},"
       "density={"
       "div_v=%.3e, "
       "wcount_dh=%.3e, "
diff --git a/src/hydro/Gizmo/hydro_flux_limiters.h b/src/hydro/Gizmo/hydro_flux_limiters.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc91cf2808e02d903ff97efddc20c164db9c954e
--- /dev/null
+++ b/src/hydro/Gizmo/hydro_flux_limiters.h
@@ -0,0 +1,81 @@
+
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2017 Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
+ *
+ * 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/>.
+ *
+ ******************************************************************************/
+
+#ifndef SWIFT_HYDRO_FLUX_LIMITERS_H
+#define SWIFT_HYDRO_FLUX_LIMITERS_H
+
+#ifdef GIZMO_FLUX_LIMITER
+
+#define HYDRO_FLUX_LIMITER_IMPLEMENTATION "GIZMO flux limiter"
+
+/**
+ * @brief Limit the flux between two particles.
+ *
+ * @param flux Unlimited flux between the particles.
+ * @param pi Particle i.
+ * @param pj Particle j.
+ */
+__attribute__((always_inline)) INLINE static void hydro_flux_limiters_apply(
+    float* flux, struct part* pi, struct part* pj) {
+
+  float flux_limit_factor = 1.;
+  const float timefac = max(pi->force.dt, pj->force.dt);
+  const float areafac = max(pi->geometry.Atot, pj->geometry.Atot);
+  const float totfac = timefac * areafac;
+  if (flux[0] * totfac > pi->conserved.mass) {
+    flux_limit_factor = pi->conserved.mass / (flux[0] * totfac);
+  }
+  if (flux[0] * totfac > pj->conserved.mass) {
+    flux_limit_factor =
+        min(pj->conserved.mass / (flux[0] * totfac), flux_limit_factor);
+  }
+  if (flux[4] * totfac > pi->conserved.energy) {
+    flux_limit_factor =
+        min(pi->conserved.energy / (flux[4] * totfac), flux_limit_factor);
+  }
+  if (flux[4] * totfac > pj->conserved.energy) {
+    flux_limit_factor =
+        min(pj->conserved.energy / (flux[4] * totfac), flux_limit_factor);
+  }
+
+  flux[0] *= flux_limit_factor;
+  flux[1] *= flux_limit_factor;
+  flux[2] *= flux_limit_factor;
+  flux[3] *= flux_limit_factor;
+  flux[4] *= flux_limit_factor;
+}
+
+#else
+
+#define HYDRO_FLUX_LIMITER_IMPLEMENTATION "No flux limiter"
+
+/**
+ * @brief Limit the flux between two particles.
+ *
+ * @param flux Unlimited flux between the particles.
+ * @param pi Particle i.
+ * @param pj Particle j.
+ */
+__attribute__((always_inline)) INLINE static void hydro_flux_limiters_apply(
+    float* flux, struct part* pi, struct part* pj) {}
+
+#endif
+
+#endif  // SWIFT_HYDRO_FLUX_LIMITERS_H
diff --git a/src/hydro/Gizmo/hydro_gradients.h b/src/hydro/Gizmo/hydro_gradients.h
index 5ad6d87619a7629a703a8b9c03d089e69ffbdf7d..896128bd45d7964c1f4c8d63564f6fced38db770 100644
--- a/src/hydro/Gizmo/hydro_gradients.h
+++ b/src/hydro/Gizmo/hydro_gradients.h
@@ -99,7 +99,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_predict(
   float xij_j[3];
   int k;
   float xfac;
-  float a_grav_i[3], a_grav_j[3];
 
   /* perform gradient reconstruction in space and time */
   /* space */
@@ -141,34 +140,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_predict(
            pj->primitives.gradients.P[1] * xij_j[1] +
            pj->primitives.gradients.P[2] * xij_j[2];
 
-  a_grav_i[0] = pi->gravity.old_a[0];
-  a_grav_i[1] = pi->gravity.old_a[1];
-  a_grav_i[2] = pi->gravity.old_a[2];
-
-  a_grav_i[0] += pi->gravity.grad_a[0][0] * xij_i[0] +
-                 pi->gravity.grad_a[0][1] * xij_i[1] +
-                 pi->gravity.grad_a[0][2] * xij_i[2];
-  a_grav_i[1] += pi->gravity.grad_a[1][0] * xij_i[0] +
-                 pi->gravity.grad_a[1][1] * xij_i[1] +
-                 pi->gravity.grad_a[1][2] * xij_i[2];
-  a_grav_i[2] += pi->gravity.grad_a[2][0] * xij_i[0] +
-                 pi->gravity.grad_a[2][1] * xij_i[1] +
-                 pi->gravity.grad_a[2][2] * xij_i[2];
-
-  a_grav_j[0] = pj->gravity.old_a[0];
-  a_grav_j[1] = pj->gravity.old_a[1];
-  a_grav_j[2] = pj->gravity.old_a[2];
-
-  a_grav_j[0] += pj->gravity.grad_a[0][0] * xij_j[0] +
-                 pj->gravity.grad_a[0][1] * xij_j[1] +
-                 pj->gravity.grad_a[0][2] * xij_j[2];
-  a_grav_j[1] += pj->gravity.grad_a[1][0] * xij_j[0] +
-                 pj->gravity.grad_a[1][1] * xij_j[1] +
-                 pj->gravity.grad_a[1][2] * xij_j[2];
-  a_grav_j[2] += pj->gravity.grad_a[2][0] * xij_j[0] +
-                 pj->gravity.grad_a[2][1] * xij_j[1] +
-                 pj->gravity.grad_a[2][2] * xij_j[2];
-
   hydro_slope_limit_face(Wi, Wj, dWi, dWj, xij_i, xij_j, r);
 
   /* time */
@@ -198,10 +169,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_predict(
                hydro_gamma * Wi[4] * (pi->primitives.gradients.v[0][0] +
                                       pi->primitives.gradients.v[1][1] +
                                       pi->primitives.gradients.v[2][2]));
-
-    dWi[1] += 0.5 * mindt * a_grav_i[0];
-    dWi[2] += 0.5 * mindt * a_grav_i[1];
-    dWi[3] += 0.5 * mindt * a_grav_i[2];
   }
 
   if (Wj[0] > 0.0f) {
@@ -230,10 +197,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_predict(
                hydro_gamma * Wj[4] * (pj->primitives.gradients.v[0][0] +
                                       pj->primitives.gradients.v[1][1] +
                                       pj->primitives.gradients.v[2][2]));
-
-    dWj[1] += 0.5 * mindt * a_grav_j[0];
-    dWj[2] += 0.5 * mindt * a_grav_j[1];
-    dWj[3] += 0.5 * mindt * a_grav_j[2];
   }
 
   Wi[0] += dWi[0];
diff --git a/src/hydro/Gizmo/hydro_gradients_gizmo.h b/src/hydro/Gizmo/hydro_gradients_gizmo.h
index ee3ad6919f81f042ceacc5db8b4e818d63c90266..bc50c10d84cdd6b444887a8bb5fdf7b49a004eb8 100644
--- a/src/hydro/Gizmo/hydro_gradients_gizmo.h
+++ b/src/hydro/Gizmo/hydro_gradients_gizmo.h
@@ -45,18 +45,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_init(
   p->primitives.gradients.P[1] = 0.0f;
   p->primitives.gradients.P[2] = 0.0f;
 
-  p->gravity.grad_a[0][0] = 0.0f;
-  p->gravity.grad_a[0][1] = 0.0f;
-  p->gravity.grad_a[0][2] = 0.0f;
-
-  p->gravity.grad_a[1][0] = 0.0f;
-  p->gravity.grad_a[1][1] = 0.0f;
-  p->gravity.grad_a[1][2] = 0.0f;
-
-  p->gravity.grad_a[2][0] = 0.0f;
-  p->gravity.grad_a[2][1] = 0.0f;
-  p->gravity.grad_a[2][2] = 0.0f;
-
   hydro_slope_limit_cell_init(p);
 }
 
@@ -157,35 +145,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_collect(
         (Wi[4] - Wj[4]) * wi *
         (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
 
-    pi->gravity.grad_a[0][0] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wi *
-        (Bi[0][0] * dx[0] + Bi[0][1] * dx[1] + Bi[0][2] * dx[2]);
-    pi->gravity.grad_a[0][1] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wi *
-        (Bi[1][0] * dx[0] + Bi[1][1] * dx[1] + Bi[1][2] * dx[2]);
-    pi->gravity.grad_a[0][2] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wi *
-        (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
-
-    pi->gravity.grad_a[1][0] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wi *
-        (Bi[0][0] * dx[0] + Bi[0][1] * dx[1] + Bi[0][2] * dx[2]);
-    pi->gravity.grad_a[1][1] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wi *
-        (Bi[1][0] * dx[0] + Bi[1][1] * dx[1] + Bi[1][2] * dx[2]);
-    pi->gravity.grad_a[1][2] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wi *
-        (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
-
-    pi->gravity.grad_a[2][0] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wi *
-        (Bi[0][0] * dx[0] + Bi[0][1] * dx[1] + Bi[0][2] * dx[2]);
-    pi->gravity.grad_a[2][1] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wi *
-        (Bi[1][0] * dx[0] + Bi[1][1] * dx[1] + Bi[1][2] * dx[2]);
-    pi->gravity.grad_a[2][2] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wi *
-        (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
   } else {
     /* The gradient matrix was not well-behaved, switch to SPH gradients */
 
@@ -223,27 +182,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_collect(
         wi_dx * dx[1] * (pi->primitives.P - pj->primitives.P) / r;
     pi->primitives.gradients.P[2] -=
         wi_dx * dx[2] * (pi->primitives.P - pj->primitives.P) / r;
-
-    pi->gravity.grad_a[0][0] -=
-        wi_dx * dx[0] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-    pi->gravity.grad_a[0][1] -=
-        wi_dx * dx[1] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-    pi->gravity.grad_a[0][2] -=
-        wi_dx * dx[2] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-
-    pi->gravity.grad_a[1][0] -=
-        wi_dx * dx[0] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-    pi->gravity.grad_a[1][1] -=
-        wi_dx * dx[1] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-    pi->gravity.grad_a[1][2] -=
-        wi_dx * dx[2] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-
-    pi->gravity.grad_a[2][0] -=
-        wi_dx * dx[0] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
-    pi->gravity.grad_a[2][1] -=
-        wi_dx * dx[1] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
-    pi->gravity.grad_a[2][2] -=
-        wi_dx * dx[2] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
   }
 
   hydro_slope_limit_cell_collect(pi, pj, r);
@@ -306,35 +244,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_collect(
         (Wi[4] - Wj[4]) * wj *
         (Bj[2][0] * dx[0] + Bj[2][1] * dx[1] + Bj[2][2] * dx[2]);
 
-    pj->gravity.grad_a[0][0] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wj *
-        (Bj[0][0] * dx[0] + Bj[0][1] * dx[1] + Bj[0][2] * dx[2]);
-    pj->gravity.grad_a[0][1] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wj *
-        (Bj[1][0] * dx[0] + Bj[1][1] * dx[1] + Bj[1][2] * dx[2]);
-    pj->gravity.grad_a[0][2] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wj *
-        (Bj[2][0] * dx[0] + Bj[2][1] * dx[1] + Bj[2][2] * dx[2]);
-
-    pj->gravity.grad_a[1][0] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wj *
-        (Bj[0][0] * dx[0] + Bj[0][1] * dx[1] + Bj[0][2] * dx[2]);
-    pj->gravity.grad_a[1][1] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wj *
-        (Bj[1][0] * dx[0] + Bj[1][1] * dx[1] + Bj[1][2] * dx[2]);
-    pj->gravity.grad_a[1][2] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wj *
-        (Bj[2][0] * dx[0] + Bj[2][1] * dx[1] + Bj[2][2] * dx[2]);
-
-    pj->gravity.grad_a[2][0] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wj *
-        (Bj[0][0] * dx[0] + Bj[0][1] * dx[1] + Bj[0][2] * dx[2]);
-    pj->gravity.grad_a[2][1] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wj *
-        (Bj[1][0] * dx[0] + Bj[1][1] * dx[1] + Bj[1][2] * dx[2]);
-    pj->gravity.grad_a[2][2] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wj *
-        (Bj[2][0] * dx[0] + Bj[2][1] * dx[1] + Bj[2][2] * dx[2]);
   } else {
     /* SPH gradients */
 
@@ -371,27 +280,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_collect(
         wj_dx * dx[1] * (pi->primitives.P - pj->primitives.P) / r;
     pj->primitives.gradients.P[2] -=
         wj_dx * dx[2] * (pi->primitives.P - pj->primitives.P) / r;
-
-    pj->gravity.grad_a[0][0] -=
-        wj_dx * dx[0] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-    pj->gravity.grad_a[0][1] -=
-        wj_dx * dx[1] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-    pj->gravity.grad_a[0][2] -=
-        wj_dx * dx[2] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-
-    pj->gravity.grad_a[1][0] -=
-        wj_dx * dx[0] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-    pj->gravity.grad_a[1][1] -=
-        wj_dx * dx[1] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-    pj->gravity.grad_a[1][2] -=
-        wj_dx * dx[2] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-
-    pj->gravity.grad_a[2][0] -=
-        wj_dx * dx[0] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
-    pj->gravity.grad_a[2][1] -=
-        wj_dx * dx[1] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
-    pj->gravity.grad_a[2][2] -=
-        wj_dx * dx[2] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
   }
 
   hydro_slope_limit_cell_collect(pj, pi, r);
@@ -493,35 +381,6 @@ hydro_gradients_nonsym_collect(float r2, float *dx, float hi, float hj,
         (Wi[4] - Wj[4]) * wi *
         (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
 
-    pi->gravity.grad_a[0][0] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wi *
-        (Bi[0][0] * dx[0] + Bi[0][1] * dx[1] + Bi[0][2] * dx[2]);
-    pi->gravity.grad_a[0][1] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wi *
-        (Bi[1][0] * dx[0] + Bi[1][1] * dx[1] + Bi[1][2] * dx[2]);
-    pi->gravity.grad_a[0][2] +=
-        (pi->gravity.old_a[0] - pj->gravity.old_a[0]) * wi *
-        (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
-
-    pi->gravity.grad_a[1][0] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wi *
-        (Bi[0][0] * dx[0] + Bi[0][1] * dx[1] + Bi[0][2] * dx[2]);
-    pi->gravity.grad_a[1][1] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wi *
-        (Bi[1][0] * dx[0] + Bi[1][1] * dx[1] + Bi[1][2] * dx[2]);
-    pi->gravity.grad_a[1][2] +=
-        (pi->gravity.old_a[1] - pj->gravity.old_a[1]) * wi *
-        (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
-
-    pi->gravity.grad_a[2][0] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wi *
-        (Bi[0][0] * dx[0] + Bi[0][1] * dx[1] + Bi[0][2] * dx[2]);
-    pi->gravity.grad_a[2][1] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wi *
-        (Bi[1][0] * dx[0] + Bi[1][1] * dx[1] + Bi[1][2] * dx[2]);
-    pi->gravity.grad_a[2][2] +=
-        (pi->gravity.old_a[2] - pj->gravity.old_a[2]) * wi *
-        (Bi[2][0] * dx[0] + Bi[2][1] * dx[1] + Bi[2][2] * dx[2]);
   } else {
     /* Gradient matrix is not well-behaved, switch to SPH gradients */
 
@@ -558,27 +417,6 @@ hydro_gradients_nonsym_collect(float r2, float *dx, float hi, float hj,
         wi_dx * dx[1] * (pi->primitives.P - pj->primitives.P) / r;
     pi->primitives.gradients.P[2] -=
         wi_dx * dx[2] * (pi->primitives.P - pj->primitives.P) / r;
-
-    pi->gravity.grad_a[0][0] -=
-        wi_dx * dx[0] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-    pi->gravity.grad_a[0][1] -=
-        wi_dx * dx[1] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-    pi->gravity.grad_a[0][2] -=
-        wi_dx * dx[2] * (pi->gravity.old_a[0] - pj->gravity.old_a[0]) / r;
-
-    pi->gravity.grad_a[1][0] -=
-        wi_dx * dx[0] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-    pi->gravity.grad_a[1][1] -=
-        wi_dx * dx[1] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-    pi->gravity.grad_a[1][2] -=
-        wi_dx * dx[2] * (pi->gravity.old_a[1] - pj->gravity.old_a[1]) / r;
-
-    pi->gravity.grad_a[2][0] -=
-        wi_dx * dx[0] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
-    pi->gravity.grad_a[2][1] -=
-        wi_dx * dx[1] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
-    pi->gravity.grad_a[2][2] -=
-        wi_dx * dx[2] * (pi->gravity.old_a[2] - pj->gravity.old_a[2]) / r;
   }
 
   hydro_slope_limit_cell_collect(pi, pj, r);
@@ -618,17 +456,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_finalize(
     p->primitives.gradients.P[1] *= ihdim;
     p->primitives.gradients.P[2] *= ihdim;
 
-    p->gravity.grad_a[0][0] *= ihdim;
-    p->gravity.grad_a[0][1] *= ihdim;
-    p->gravity.grad_a[0][2] *= ihdim;
-
-    p->gravity.grad_a[1][0] *= ihdim;
-    p->gravity.grad_a[1][1] *= ihdim;
-    p->gravity.grad_a[1][2] *= ihdim;
-
-    p->gravity.grad_a[2][0] *= ihdim;
-    p->gravity.grad_a[2][1] *= ihdim;
-    p->gravity.grad_a[2][2] *= ihdim;
   } else {
     const float ihdimp1 = pow_dimension_plus_one(ih);
 
@@ -653,18 +480,6 @@ __attribute__((always_inline)) INLINE static void hydro_gradients_finalize(
     p->primitives.gradients.P[0] *= ihdimp1 * volume;
     p->primitives.gradients.P[1] *= ihdimp1 * volume;
     p->primitives.gradients.P[2] *= ihdimp1 * volume;
-
-    p->gravity.grad_a[0][0] *= ihdimp1 * volume;
-    p->gravity.grad_a[0][1] *= ihdimp1 * volume;
-    p->gravity.grad_a[0][2] *= ihdimp1 * volume;
-
-    p->gravity.grad_a[1][0] *= ihdimp1 * volume;
-    p->gravity.grad_a[1][1] *= ihdimp1 * volume;
-    p->gravity.grad_a[1][2] *= ihdimp1 * volume;
-
-    p->gravity.grad_a[2][0] *= ihdimp1 * volume;
-    p->gravity.grad_a[2][1] *= ihdimp1 * volume;
-    p->gravity.grad_a[2][2] *= ihdimp1 * volume;
   }
 
   hydro_slope_limit_cell(p);
diff --git a/src/hydro/Gizmo/hydro_iact.h b/src/hydro/Gizmo/hydro_iact.h
index c7e86c22da5a8beeece0d7a1fcc9cff560105e6e..0c7c8251b7d1c105dfc0c4b1637724accadaa4ae 100644
--- a/src/hydro/Gizmo/hydro_iact.h
+++ b/src/hydro/Gizmo/hydro_iact.h
@@ -20,6 +20,7 @@
  ******************************************************************************/
 
 #include "adiabatic_index.h"
+#include "hydro_flux_limiters.h"
 #include "hydro_gradients.h"
 #include "riemann.h"
 
@@ -346,8 +347,11 @@ __attribute__((always_inline)) INLINE static void runner_iact_fluxes_common(
   }
   dvdotdx = (Wi[1] - Wj[1]) * dx[0] + (Wi[2] - Wj[2]) * dx[1] +
             (Wi[3] - Wj[3]) * dx[2];
-  if (dvdotdx > 0.) {
-    vmax -= dvdotdx / r;
+  dvdotdx = min(dvdotdx, (vi[0] - vj[0]) * dx[0] + (vi[1] - vj[1]) * dx[1] +
+                             (vi[2] - vj[2]) * dx[2]);
+  if (dvdotdx < 0.) {
+    /* the magical factor 3 also appears in Gadget2 */
+    vmax -= 3. * dvdotdx / r;
   }
   pi->timestepvars.vmax = max(pi->timestepvars.vmax, vmax);
   if (mode == 1) {
@@ -487,36 +491,10 @@ __attribute__((always_inline)) INLINE static void runner_iact_fluxes_common(
   float totflux[5];
   riemann_solve_for_flux(Wi, Wj, n_unit, vij, totflux);
 
-  /* Flux limiter */
-  float flux_limit_factor = 1.;
-  float timefac = max(dti, dtj);
-  float areafac = max(pi->geometry.Atot, pj->geometry.Atot);
-  if (totflux[0] * areafac * timefac > pi->conserved.mass) {
-    flux_limit_factor = pi->conserved.mass / (totflux[0] * areafac * timefac);
-  }
-  if (totflux[0] * areafac * timefac > pj->conserved.mass) {
-    flux_limit_factor =
-        min(pj->conserved.mass / (totflux[0] * areafac * timefac),
-            flux_limit_factor);
-  }
-  if (totflux[4] * areafac * timefac > pi->conserved.energy) {
-    flux_limit_factor =
-        min(pi->conserved.energy / (totflux[4] * areafac * timefac),
-            flux_limit_factor);
-  }
-  if (totflux[4] * areafac * timefac > pj->conserved.energy) {
-    flux_limit_factor =
-        min(pj->conserved.energy / (totflux[4] * areafac * timefac),
-            flux_limit_factor);
-  }
-  totflux[0] *= flux_limit_factor;
-  totflux[1] *= flux_limit_factor;
-  totflux[2] *= flux_limit_factor;
-  totflux[3] *= flux_limit_factor;
-  totflux[4] *= flux_limit_factor;
+  hydro_flux_limiters_apply(totflux, pi, pj);
 
   /* Store mass flux */
-  float mflux = mindt * Anorm * totflux[0];
+  float mflux = Anorm * totflux[0];
   pi->gravity.mflux[0] += mflux * dx[0];
   pi->gravity.mflux[1] += mflux * dx[1];
   pi->gravity.mflux[2] += mflux * dx[2];
@@ -554,7 +532,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_fluxes_common(
 
   if (mode == 1 || pj->force.active == 0) {
     /* Store mass flux */
-    mflux = mindt * Anorm * totflux[0];
+    mflux = Anorm * totflux[0];
     pj->gravity.mflux[0] -= mflux * dx[0];
     pj->gravity.mflux[1] -= mflux * dx[1];
     pj->gravity.mflux[2] -= mflux * dx[2];
diff --git a/src/hydro/Gizmo/hydro_io.h b/src/hydro/Gizmo/hydro_io.h
index 3d58be2f47c4e1904aaac5f69d1862f1d453e488..d20f7e2eb1cf50be7690e15a9569d8e9c4605af5 100644
--- a/src/hydro/Gizmo/hydro_io.h
+++ b/src/hydro/Gizmo/hydro_io.h
@@ -18,6 +18,7 @@
  ******************************************************************************/
 
 #include "adiabatic_index.h"
+#include "hydro_flux_limiters.h"
 #include "hydro_gradients.h"
 #include "hydro_slope_limiters.h"
 #include "io_properties.h"
@@ -127,7 +128,7 @@ float convert_Etot(struct engine* e, struct part* p) {
 void hydro_write_particles(struct part* parts, struct io_props* list,
                            int* num_fields) {
 
-  *num_fields = 11;
+  *num_fields = 10;
 
   /* List what we want to write */
   list[0] = io_make_output_field("Coordinates", DOUBLE, 3, UNIT_CONV_LENGTH,
@@ -152,8 +153,6 @@ void hydro_write_particles(struct part* parts, struct io_props* list,
   list[9] =
       io_make_output_field_convert_part("TotEnergy", FLOAT, 1, UNIT_CONV_ENERGY,
                                         parts, conserved.energy, convert_Etot);
-  list[10] = io_make_output_field("GravAcceleration", FLOAT, 3,
-                                  UNIT_CONV_ACCELERATION, parts, gravity.old_a);
 }
 
 /**
@@ -171,6 +170,10 @@ void writeSPHflavour(hid_t h_grpsph) {
   io_write_attribute_s(h_grpsph, "Piecewise slope limiter model",
                        HYDRO_SLOPE_LIMITER_FACE_IMPLEMENTATION);
 
+  /* Flux limiter information */
+  io_write_attribute_s(h_grpsph, "Flux limiter model",
+                       HYDRO_FLUX_LIMITER_IMPLEMENTATION);
+
   /* Riemann solver information */
   io_write_attribute_s(h_grpsph, "Riemann solver type",
                        RIEMANN_SOLVER_IMPLEMENTATION);
diff --git a/src/hydro/Gizmo/hydro_part.h b/src/hydro/Gizmo/hydro_part.h
index 6c96004847ae23b46ec3f5182f742e0e84f1118d..47f722c5a2dcce2f3ce603ade3029821d6686067 100644
--- a/src/hydro/Gizmo/hydro_part.h
+++ b/src/hydro/Gizmo/hydro_part.h
@@ -153,10 +153,13 @@ struct part {
 
   } geometry;
 
-  /* Variables used for timestep calculation (currently not used). */
+  /* Variables used for timestep calculation. */
   struct {
 
-    /* Maximum fluid velocity among all neighbours. */
+    /* Maximum signal velocity among all the neighbours of the particle. The
+     * signal velocity encodes information about the relative fluid velocities
+     * AND particle velocities of the neighbour and this particle, as well as
+     * the sound speed of both particles. */
     float vmax;
 
   } timestepvars;
@@ -201,14 +204,6 @@ struct part {
   /* Specific stuff for the gravity-hydro coupling. */
   struct {
 
-    /* Previous value of the gravitational acceleration. */
-    float old_a[3];
-
-    float grad_a[3][3];
-
-    /* Previous value of the mass flux vector. */
-    float old_mflux[3];
-
     /* Current value of the mass flux vector. */
     float mflux[3];
 
diff --git a/src/potential/disc_patch/potential.h b/src/potential/disc_patch/potential.h
index 07f3d7457e7e53debbdda09686ed1166966c1913..ab229d009c692db727e8f2341c3c49813f74f2b8 100644
--- a/src/potential/disc_patch/potential.h
+++ b/src/potential/disc_patch/potential.h
@@ -56,20 +56,20 @@ struct external_potential {
   /*! Inverse of disc scale-height (1/b) */
   float scale_height_inv;
 
-  /*! Position of the disc along the z-axis */
-  float z_disc;
+  /*! Position of the disc along the x-axis */
+  float x_disc;
 
   /*! Position above which the accelerations get truncated */
-  float z_trunc;
+  float x_trunc;
 
   /*! Position above which the accelerations are zero */
-  float z_max;
+  float x_max;
 
   /*! The truncated transition regime */
-  float z_trans;
+  float x_trans;
 
   /*! Inverse of the truncated transition regime */
-  float z_trans_inv;
+  float x_trans_inv;
 
   /*! Dynamical time of the system */
   float dynamical_time;
@@ -115,36 +115,36 @@ __attribute__((always_inline)) INLINE static float external_gravity_timestep(
   const float norm = potential->norm;
 
   /* absolute value of height above disc */
-  const float dz = fabsf(g->x[2] - potential->z_disc);
+  const float dx = fabsf(g->x[0] - potential->x_disc);
 
   /* vertical acceleration */
-  const float z_accel = norm * tanhf(dz * b_inv);
+  const float x_accel = norm * tanhf(dx * b_inv);
 
   float dt = dt_dyn;
 
   /* demand that dt * velocity <  fraction of scale height of disc */
-  if (g->v_full[2] != 0.f) {
+  if (g->v_full[0] != 0.f) {
 
-    const float dt1 = b / fabsf(g->v_full[2]);
+    const float dt1 = b / fabsf(g->v_full[0]);
     dt = min(dt1, dt);
   }
 
   /* demand that dt^2 * acceleration < fraction of scale height of disc */
-  if (z_accel != 0.f) {
+  if (x_accel != 0.f) {
 
-    const float dt2 = b / fabsf(z_accel);
+    const float dt2 = b / fabsf(x_accel);
     if (dt2 < dt * dt) dt = sqrtf(dt2);
   }
 
   /* demand that dt^3 * jerk < fraction of scale height of disc */
-  if (g->v_full[2] != 0.f) {
+  if (g->v_full[0] != 0.f) {
 
-    const float cosh_dz_inv = 1.f / coshf(dz * b_inv);
-    const float cosh_dz_inv2 = cosh_dz_inv * cosh_dz_inv;
-    const float dz_accel_over_dt =
-        norm * cosh_dz_inv2 * b_inv * fabsf(g->v_full[2]);
+    const float cosh_dx_inv = 1.f / coshf(dx * b_inv);
+    const float cosh_dx_inv2 = cosh_dx_inv * cosh_dx_inv;
+    const float dx_accel_over_dt =
+        norm * cosh_dx_inv2 * b_inv * fabsf(g->v_full[0]);
 
-    const float dt3 = b / fabsf(dz_accel_over_dt);
+    const float dt3 = b / fabsf(dx_accel_over_dt);
     if (dt3 < dt * dt * dt) dt = cbrtf(dt3);
   }
 
@@ -152,13 +152,13 @@ __attribute__((always_inline)) INLINE static float external_gravity_timestep(
 }
 
 /**
- * @brief Computes the gravitational acceleration along z due to a hydrostatic
+ * @brief Computes the gravitational acceleration along x due to a hydrostatic
  * disc
  *
  * See Creasey, Theuns & Bower, 2013, MNRAS, Volume 429, Issue 3, p.1922-1948,
  * equation 17.
- * We truncate the accelerations beyond z_trunc using a 1-cos(z) function
- * that smoothly brings the accelerations to 0 at z_max.
+ * We truncate the accelerations beyond x_trunc using a 1-cos(x) function
+ * that smoothly brings the accelerations to 0 at x_max.
  *
  * @param time The current time in internal units.
  * @param potential The properties of the potential.
@@ -169,40 +169,40 @@ __attribute__((always_inline)) INLINE static void external_gravity_acceleration(
     double time, const struct external_potential* restrict potential,
     const struct phys_const* restrict phys_const, struct gpart* restrict g) {
 
-  const float dz = g->x[2] - potential->z_disc;
-  const float abs_dz = fabsf(dz);
+  const float dx = g->x[0] - potential->x_disc;
+  const float abs_dx = fabsf(dx);
   const float t_growth = potential->growth_time;
   const float t_growth_inv = potential->growth_time_inv;
   const float b_inv = potential->scale_height_inv;
-  const float z_trunc = potential->z_trunc;
-  const float z_max = potential->z_max;
-  const float z_trans_inv = potential->z_trans_inv;
+  const float x_trunc = potential->x_trunc;
+  const float x_max = potential->x_max;
+  const float x_trans_inv = potential->x_trans_inv;
   const float norm_over_G = potential->norm_over_G;
 
   /* Are we still growing the disc ? */
   const float reduction_factor = time < t_growth ? time * t_growth_inv : 1.f;
 
   /* Truncated or not ? */
-  float a_z;
-  if (abs_dz < z_trunc) {
+  float a_x;
+  if (abs_dx < x_trunc) {
 
-    /* Acc. 2 pi sigma tanh(z/b) */
-    a_z = reduction_factor * norm_over_G * tanhf(abs_dz * b_inv);
-  } else if (abs_dz < z_max) {
+    /* Acc. 2 pi sigma tanh(x/b) */
+    a_x = reduction_factor * norm_over_G * tanhf(abs_dx * b_inv);
+  } else if (abs_dx < x_max) {
 
-    /* Acc. 2 pi sigma tanh(z/b) [1/2 + 1/2cos((z-zmax)/(pi z_trans))] */
-    a_z =
-        reduction_factor * norm_over_G * tanhf(abs_dz * b_inv) *
-        (0.5f + 0.5f * cosf((float)(M_PI) * (abs_dz - z_trunc) * z_trans_inv));
+    /* Acc. 2 pi sigma tanh(x/b) [1/2 + 1/2cos((x-xmax)/(pi x_trans))] */
+    a_x =
+        reduction_factor * norm_over_G * tanhf(abs_dx * b_inv) *
+        (0.5f + 0.5f * cosf((float)(M_PI) * (abs_dx - x_trunc) * x_trans_inv));
   } else {
 
     /* Acc. 0 */
-    a_z = 0.f;
+    a_x = 0.f;
   }
 
   /* Get the correct sign. Recall G is multipiled in later on */
-  if (dz > 0) g->a_grav[2] -= a_z;
-  if (dz < 0) g->a_grav[2] += a_z;
+  if (dx > 0) g->a_grav[0] -= a_x;
+  if (dx < 0) g->a_grav[0] += a_x;
 }
 
 /**
@@ -211,8 +211,8 @@ __attribute__((always_inline)) INLINE static void external_gravity_acceleration(
  *
  * See Creasey, Theuns & Bower, 2013, MNRAS, Volume 429, Issue 3, p.1922-1948,
  * equation 22.
- * We truncate the accelerations beyond z_trunc using a 1-cos(z) function
- * that smoothly brings the accelerations to 0 at z_max.
+ * We truncate the accelerations beyond x_trunc using a 1-cos(x) function
+ * that smoothly brings the accelerations to 0 at x_max.
  *
  * @param time The current time.
  * @param potential The #external_potential used in the run.
@@ -224,28 +224,28 @@ external_gravity_get_potential_energy(
     double time, const struct external_potential* potential,
     const struct phys_const* const phys_const, const struct gpart* gp) {
 
-  const float dz = gp->x[2] - potential->z_disc;
-  const float abs_dz = fabsf(dz);
+  const float dx = gp->x[0] - potential->x_disc;
+  const float abs_dx = fabsf(dx);
   const float t_growth = potential->growth_time;
   const float t_growth_inv = potential->growth_time_inv;
   const float b = potential->scale_height;
   const float b_inv = potential->scale_height_inv;
   const float norm = potential->norm;
-  const float z_trunc = potential->z_trunc;
-  const float z_max = potential->z_max;
+  const float x_trunc = potential->x_trunc;
+  const float x_max = potential->x_max;
 
   /* Are we still growing the disc ? */
   const float reduction_factor = time < t_growth ? time * t_growth_inv : 1.f;
 
   /* Truncated or not ? */
   float pot;
-  if (abs_dz < z_trunc) {
+  if (abs_dx < x_trunc) {
 
-    /* Potential (2 pi G sigma b ln(cosh(z/b)) */
-    pot = b * logf(coshf(dz * b_inv));
-  } else if (abs_dz < z_max) {
+    /* Potential (2 pi G sigma b ln(cosh(x/b)) */
+    pot = b * logf(coshf(dx * b_inv));
+  } else if (abs_dx < x_max) {
 
-    /* Potential. At z>>b, phi(z) = norm * z / b */
+    /* Potential. At x>>b, phi(x) = norm * x / b */
     pot = 0.f;
 
   } else {
@@ -277,14 +277,14 @@ static INLINE void potential_init_backend(
       parameter_file, "DiscPatchPotential:surface_density");
   potential->scale_height = parser_get_param_double(
       parameter_file, "DiscPatchPotential:scale_height");
-  potential->z_disc =
-      parser_get_param_double(parameter_file, "DiscPatchPotential:z_disc");
-  potential->z_trunc = parser_get_opt_param_double(
-      parameter_file, "DiscPatchPotential:z_trunc", FLT_MAX);
-  potential->z_max = parser_get_opt_param_double(
-      parameter_file, "DiscPatchPotential:z_max", FLT_MAX);
-  potential->z_disc =
-      parser_get_param_double(parameter_file, "DiscPatchPotential:z_disc");
+  potential->x_disc =
+      parser_get_param_double(parameter_file, "DiscPatchPotential:x_disc");
+  potential->x_trunc = parser_get_opt_param_double(
+      parameter_file, "DiscPatchPotential:x_trunc", FLT_MAX);
+  potential->x_max = parser_get_opt_param_double(
+      parameter_file, "DiscPatchPotential:x_max", FLT_MAX);
+  potential->x_disc =
+      parser_get_param_double(parameter_file, "DiscPatchPotential:x_disc");
   potential->timestep_mult = parser_get_param_double(
       parameter_file, "DiscPatchPotential:timestep_mult");
   potential->growth_time = parser_get_opt_param_double(
@@ -299,22 +299,22 @@ static INLINE void potential_init_backend(
   potential->growth_time *= potential->dynamical_time;
 
   /* Some cross-checks */
-  if (potential->z_trunc > potential->z_max)
-    error("Potential truncation z larger than maximal z");
-  if (potential->z_trunc < potential->scale_height)
-    error("Potential truncation z smaller than scale height");
+  if (potential->x_trunc > potential->x_max)
+    error("Potential truncation x larger than maximal z");
+  if (potential->x_trunc < potential->scale_height)
+    error("Potential truncation x smaller than scale height");
 
   /* Compute derived quantities */
   potential->scale_height_inv = 1. / potential->scale_height;
   potential->norm =
       2. * M_PI * phys_const->const_newton_G * potential->surface_density;
   potential->norm_over_G = 2 * M_PI * potential->surface_density;
-  potential->z_trans = potential->z_max - potential->z_trunc;
+  potential->x_trans = potential->x_max - potential->x_trunc;
 
-  if (potential->z_trans != 0.f)
-    potential->z_trans_inv = 1. / potential->z_trans;
+  if (potential->x_trans != 0.f)
+    potential->x_trans_inv = 1. / potential->x_trans;
   else
-    potential->z_trans_inv = FLT_MAX;
+    potential->x_trans_inv = FLT_MAX;
 
   if (potential->growth_time != 0.)
     potential->growth_time_inv = 1. / potential->growth_time;
@@ -331,14 +331,14 @@ static INLINE void potential_print_backend(
     const struct external_potential* potential) {
 
   message(
-      "External potential is 'Disk-patch' with Sigma=%f, z_disc=%f, b=%f and "
+      "External potential is 'Disk-patch' with Sigma=%f, x_disc=%f, b=%f and "
       "dt_mult=%f.",
-      potential->surface_density, potential->z_disc, potential->scale_height,
+      potential->surface_density, potential->x_disc, potential->scale_height,
       potential->timestep_mult);
 
-  if (potential->z_max < FLT_MAX)
-    message("Potential will be truncated at z_trunc=%f and zeroed at z_max=%f",
-            potential->z_trunc, potential->z_max);
+  if (potential->x_max < FLT_MAX)
+    message("Potential will be truncated at x_trunc=%f and zeroed at x_max=%f",
+            potential->x_trunc, potential->x_max);
 
   if (potential->growth_time > 0.)
     message("Disc will grow for %f [time_units]. (%f dynamical time)",
diff --git a/src/queue.h b/src/queue.h
index c85cf0cabe30a03d163e2564fdc216c19495761a..951a3e5a056d7ad0c3935f98341a0d93c805e3ad 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -29,7 +29,7 @@
 #define queue_sizeinit 100
 #define queue_sizegrow 2
 #define queue_search_window 8
-#define queue_incoming_size 10240
+#define queue_incoming_size 1024
 #define queue_struct_align 64
 
 /* Counters. */
diff --git a/src/runner.c b/src/runner.c
index 04d230209a27d9c16d5ffbc0fffc9d5519e025d4..c32ba4bf76ae2cd06c28ed1d41b4ebf16abe0885 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -1544,11 +1544,6 @@ void runner_do_recv_part(struct runner *r, struct cell *c, int clear_sorts,
       time_bin_min = min(time_bin_min, parts[k].time_bin);
       time_bin_max = max(time_bin_max, parts[k].time_bin);
       h_max = max(h_max, parts[k].h);
-
-#ifdef SWIFT_DEBUG_CHECKS
-      if (parts[k].ti_drift != ti_current)
-        error("Received un-drifted particle !");
-#endif
     }
 
     /* Convert into a time */
diff --git a/src/scheduler.c b/src/scheduler.c
index 2e645951256d415b072cc964003d4042a842923d..161be418046636c473362f061d4afa1c64ace04a 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -759,7 +759,7 @@ 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);
+                 s->nr_tasks, sizeof(struct task), 1000, s);
 }
 
 /**
@@ -1174,7 +1174,7 @@ void scheduler_start(struct scheduler *s) {
   /* Re-wait the tasks. */
   if (s->active_count > 1000) {
     threadpool_map(s->threadpool, scheduler_rewait_mapper, s->tid_active,
-                   s->active_count, sizeof(int), 0, s);
+                   s->active_count, sizeof(int), 1000, s);
   } else {
     scheduler_rewait_mapper(s->tid_active, s->active_count, s);
   }
@@ -1250,7 +1250,7 @@ void scheduler_start(struct scheduler *s) {
   /* Loop over the tasks and enqueue whoever is ready. */
   if (s->active_count > 1000) {
     threadpool_map(s->threadpool, scheduler_enqueue_mapper, s->tid_active,
-                   s->active_count, sizeof(int), 0, s);
+                   s->active_count, sizeof(int), 1000, s);
   } else {
     scheduler_enqueue_mapper(s->tid_active, s->active_count, s);
   }
@@ -1363,11 +1363,6 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
         } else if (t->subtype == task_subtype_xv ||
                    t->subtype == task_subtype_rho ||
                    t->subtype == task_subtype_gradient) {
-#ifdef SWIFT_DEBUG_CHECKS
-          for (int k = 0; k < t->ci->count; k++)
-            if (t->ci->parts[k].ti_drift != s->space->e->ti_current)
-              error("Sending un-drifted particle !");
-#endif
           err = MPI_Isend(t->ci->parts, t->ci->count, part_mpi_type,
                           t->cj->nodeID, t->flags, MPI_COMM_WORLD, &t->req);
           // message( "sending %i parts with tag=%i from %i to %i." ,
diff --git a/src/space.c b/src/space.c
index 8ad571be3800fbeebd280dfd09b9ee29158bfdf8..23902a37501c7b13992f5423a3f002d526ba2c27 100644
--- a/src/space.c
+++ b/src/space.c
@@ -378,7 +378,7 @@ void space_regrid(struct space *s, int verbose) {
     /* Free the old cells, if they were allocated. */
     if (s->cells_top != NULL) {
       threadpool_map(&s->e->threadpool, space_rebuild_recycle_mapper,
-                     s->cells_top, s->nr_cells, sizeof(struct cell), 0, s);
+                     s->cells_top, s->nr_cells, sizeof(struct cell), 100, s);
       free(s->cells_top);
       free(s->multipoles_top);
       s->maxdepth = 0;
@@ -491,7 +491,7 @@ void space_regrid(struct space *s, int verbose) {
 
     /* Free the old cells, if they were allocated. */
     threadpool_map(&s->e->threadpool, space_rebuild_recycle_mapper,
-                   s->cells_top, s->nr_cells, sizeof(struct cell), 0, s);
+                   s->cells_top, s->nr_cells, sizeof(struct cell), 100, s);
     s->maxdepth = 0;
   }
 
@@ -970,7 +970,7 @@ void space_split(struct space *s, struct cell *cells, int nr_cells,
   const ticks tic = getticks();
 
   threadpool_map(&s->e->threadpool, space_split_mapper, cells, nr_cells,
-                 sizeof(struct cell), 0, s);
+                 sizeof(struct cell), 1, s);
 
   if (verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
@@ -1004,7 +1004,7 @@ void space_sanitize(struct space *s) {
   if (s->e->nodeID == 0) message("Cleaning up unreasonable values of h");
 
   threadpool_map(&s->e->threadpool, space_sanitize_mapper, s->cells_top,
-                 s->nr_cells, sizeof(struct cell), 0, NULL);
+                 s->nr_cells, sizeof(struct cell), 1, NULL);
 }
 
 /**
@@ -1187,7 +1187,7 @@ void space_parts_get_cell_index(struct space *s, int *ind, struct cell *cells,
   data.ind = ind;
 
   threadpool_map(&s->e->threadpool, space_parts_get_cell_index_mapper, s->parts,
-                 s->nr_parts, sizeof(struct part), 0, &data);
+                 s->nr_parts, sizeof(struct part), 1000, &data);
 
   if (verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
@@ -1214,7 +1214,7 @@ void space_gparts_get_cell_index(struct space *s, int *gind, struct cell *cells,
   data.ind = gind;
 
   threadpool_map(&s->e->threadpool, space_gparts_get_cell_index_mapper,
-                 s->gparts, s->nr_gparts, sizeof(struct gpart), 0, &data);
+                 s->gparts, s->nr_gparts, sizeof(struct gpart), 1000, &data);
 
   if (verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
@@ -1241,7 +1241,7 @@ void space_sparts_get_cell_index(struct space *s, int *sind, struct cell *cells,
   data.ind = sind;
 
   threadpool_map(&s->e->threadpool, space_sparts_get_cell_index_mapper,
-                 s->sparts, s->nr_sparts, sizeof(struct spart), 0, &data);
+                 s->sparts, s->nr_sparts, sizeof(struct spart), 1000, &data);
 
   if (verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
@@ -2501,7 +2501,7 @@ void space_synchronize_particle_positions(struct space *s) {
       (s->nr_gparts > 0 && s->nr_sparts > 0))
     threadpool_map(&s->e->threadpool,
                    space_synchronize_particle_positions_mapper, s->gparts,
-                   s->nr_gparts, sizeof(struct gpart), 0, (void *)s);
+                   s->nr_gparts, sizeof(struct gpart), 1000, (void *)s);
 }
 
 /**
diff --git a/src/statistics.c b/src/statistics.c
index 5a3f1ff4f9a2232a14817e7e55fd2cff5bdcd80e..57d60bcb1b247c9616c859b7ac8a475acdcd878f 100644
--- a/src/statistics.c
+++ b/src/statistics.c
@@ -271,12 +271,12 @@ void stats_collect(const struct space *s, struct statistics *stats) {
   /* Run parallel collection of statistics for parts */
   if (s->nr_parts > 0)
     threadpool_map(&s->e->threadpool, stats_collect_part_mapper, s->parts,
-                   s->nr_parts, sizeof(struct part), 0, &extra_data);
+                   s->nr_parts, sizeof(struct part), 10000, &extra_data);
 
   /* Run parallel collection of statistics for gparts */
   if (s->nr_gparts > 0)
     threadpool_map(&s->e->threadpool, stats_collect_gpart_mapper, s->gparts,
-                   s->nr_gparts, sizeof(struct gpart), 0, &extra_data);
+                   s->nr_gparts, sizeof(struct gpart), 10000, &extra_data);
 }
 
 /**
diff --git a/src/swift.h b/src/swift.h
index 1d1a7c7d04b3662c524504c292aa7d9eee2c3d09..20397eb24df478cba65a0e35d686b402f1d8ee70 100644
--- a/src/swift.h
+++ b/src/swift.h
@@ -57,7 +57,6 @@
 #include "sourceterms.h"
 #include "space.h"
 #include "task.h"
-#include "threadpool.h"
 #include "timeline.h"
 #include "timers.h"
 #include "tools.h"
diff --git a/src/threadpool.c b/src/threadpool.c
index d1b3d0c4269a17022e30c5f5f8da5c8654b79034..3ad02cb369bfcec22689a5aacf97816213eb49f0 100644
--- a/src/threadpool.c
+++ b/src/threadpool.c
@@ -41,7 +41,7 @@
 
 #ifdef SWIFT_DEBUG_THREADPOOL
 /**
- * @breif Store a log entry of the given chunk.
+ * @brief Store a log entry of the given chunk.
  */
 void threadpool_log(struct threadpool *tp, int tid, size_t chunk_size,
                     ticks tic, ticks toc) {
diff --git a/tests/test27cells.c b/tests/test27cells.c
index f34d82c587a5a4abb91670b03f02393fa48e57ca..458129edd3b92d78a45102c118fb3e6f44ff604d 100644
--- a/tests/test27cells.c
+++ b/tests/test27cells.c
@@ -204,6 +204,10 @@ void zero_particle_fields(struct cell *c) {
 void end_calculation(struct cell *c) {
   for (int pid = 0; pid < c->count; pid++) {
     hydro_end_density(&c->parts[pid]);
+
+    /* Recover the common "Neighbour number" definition */
+    c->parts[pid].density.wcount *= pow_dimension(c->parts[pid].h);
+    c->parts[pid].density.wcount *= kernel_norm;
   }
 }
 
diff --git a/tests/testThreadpool.c b/tests/testThreadpool.c
index 2a9e98c5ca71ba62c5f6a266f4a36f658f61b063..aa65d533a29afbe4e7e8384fb887281822a31e58 100644
--- a/tests/testThreadpool.c
+++ b/tests/testThreadpool.c
@@ -23,7 +23,6 @@
 #include <unistd.h>
 
 // Local includes.
-#include "../config.h"
 #include "../src/atomic.h"
 #include "../src/threadpool.h"
 
@@ -79,11 +78,6 @@ int main(int argc, char *argv[]) {
     threadpool_map(&tp, map_function_first, data, N, sizeof(int), 2, NULL);
   }
 
-/* If logging was enabled, dump the log. */
-#ifdef SWIFT_DEBUG_THREADPOOL
-  threadpool_dump_log(&tp, "threadpool_log.txt", 1);
-#endif
-
   /* Be clean */
   threadpool_clean(&tp);