diff --git a/INSTALL.swift b/INSTALL.swift
index fd960200117972d72ec5144250c51fa5126f09f4..e1efc945c83742cbd2cc2e9fe7afeec5cc9d1145 100644
--- a/INSTALL.swift
+++ b/INSTALL.swift
@@ -34,13 +34,17 @@ directory. See README for run parameters.
 
 SWIFT has been successfully built and tested with the following compilers:
 
-  - GCC 4.8.x  
+  - GCC 4.8.x
   - Intel ICC 15.0.x
-  - clang 3.4.x 
+  - clang 3.4.x
 
 More recent versions and slightly older ones should also be able to
 build the software.
 
+It has also been built with Intel and GNU C++ compilers, but that currently
+requires the --disable-vec and, for Intel, --disable-compiler-warnings
+configure options.
+
 By default an attempt to choose suitable set of optimizing compiler flags
 will be made, targeted for the host machine of the build. If this doesn't
 work or the binaries will for another architecture then you can stop the
@@ -61,7 +65,7 @@ You could also add some additional flags:
 
     ./configure --enable-debug --disable-optimization CFLAGS="-O2"
 
-for instance. GCC address sanitizer flags can be included using the 
+for instance. GCC address sanitizer flags can be included using the
 
     ./configure --enable-sanitizer
 
@@ -113,7 +117,7 @@ before you can build it.
 	none-standard name.
 
 
- - libtool: The build system relies on libtool.
+ - libtool: The build system relies on libtool as well as the other autotools.
 
 
                            Optional Dependencies
diff --git a/configure.ac b/configure.ac
index 3256c0ff55e452fb689a4d3cae052623d01923b3..b027d5b2159ce9b63d01117f9a6f07efa39c6311 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,9 @@ AC_USE_SYSTEM_EXTENSIONS
 AX_COMPILER_VENDOR
 AX_COMPILER_VERSION
 
+#  Restrict support.
+AC_C_RESTRICT
+
 # Interprocedural optimization support. Needs special handling for linking and
 # archiving as well as compilation with Intels, needs to be done before
 # libtool is configured (to use correct LD).
@@ -454,6 +457,14 @@ AC_SUBST([METIS_LIBS])
 AC_SUBST([METIS_INCS])
 AM_CONDITIONAL([HAVEMETIS],[test -n "$METIS_LIBS"])
 
+# METIS fixed width integer printing can require this, so define. Only needed
+# for some non C99 compilers, i.e. C++ pre C++11.
+AH_VERBATIM([__STDC_FORMAT_MACROS],
+            [/* Needed to get PRIxxx macros from stdint.h when not using C99 */
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif])
+
 # Check for grackle. 
 have_grackle="no"
 AC_ARG_WITH([grackle],
diff --git a/examples/CoolingHalo/cooling_halo.yml b/examples/CoolingHalo/cooling_halo.yml
index b6f6822224bbf25c4289898656a5863028d0d119..e4e8750f46bf7f46c692c4ccd3afe8453e0f606a 100644
--- a/examples/CoolingHalo/cooling_halo.yml
+++ b/examples/CoolingHalo/cooling_halo.yml
@@ -1,6 +1,6 @@
 # Define the system of units to use internally. 
 InternalUnitSystem:
-  UnitMass_in_cgs:     1.9885e39     # 10^6 solar masses
+  UnitMass_in_cgs:     1.98848e39    # 10^6 solar masses
   UnitLength_in_cgs:   3.0856776e21  # Kiloparsecs
   UnitVelocity_in_cgs: 1e5           # Kilometres per second
   UnitCurrent_in_cgs:  1   # Amperes
diff --git a/examples/CoolingHaloWithSpin/cooling_halo.yml b/examples/CoolingHaloWithSpin/cooling_halo.yml
index 5d46f957434c823a97f7d07f73afd5c806358e6f..1d548b2fb7e531b712548eb5834b2c4de575f941 100644
--- a/examples/CoolingHaloWithSpin/cooling_halo.yml
+++ b/examples/CoolingHaloWithSpin/cooling_halo.yml
@@ -1,6 +1,6 @@
 # Define the system of units to use internally. 
 InternalUnitSystem:
-  UnitMass_in_cgs:     1.9885e39     # 10^6 solar masses
+  UnitMass_in_cgs:     1.98848e39    # 10^6 solar masses
   UnitLength_in_cgs:   3.0856776e21  # Kiloparsecs
   UnitVelocity_in_cgs: 1e5           # Kilometres per second
   UnitCurrent_in_cgs:  1   # Amperes
diff --git a/examples/EvrardCollapse_3D/evrard.yml b/examples/EvrardCollapse_3D/evrard.yml
new file mode 100644
index 0000000000000000000000000000000000000000..006a22e65d3f674f124ce6c4994e752ba39cd1e1
--- /dev/null
+++ b/examples/EvrardCollapse_3D/evrard.yml
@@ -0,0 +1,44 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.8   # The end time of the simulation (in internal units).
+  dt_min:     1e-7  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-3  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            evrard # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.1     # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters for the self-gravity scheme
+Gravity:
+  eta:                   0.025    # Constant dimensionless multiplier for time integration.
+  epsilon:               0.001      # Softening length (in internal units).
+  theta:                 0.9
+  a_smooth:              1.25     # (Optional) Smoothing scale in top-level cell sizes to smooth the long-range forces over (this is the default value).
+  r_cut:                 4.5      # (Optional) Cut-off in number of top-level cells beyond which no FMM forces are computed (this is the default value).
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./evrard.hdf5       # The file to read
+
+PhysicalConstants:
+  G: 1.
diff --git a/examples/EvrardCollapse_3D/getReference.sh b/examples/EvrardCollapse_3D/getReference.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f8de6015c89ea78169c078217f04cc539f28efa8
--- /dev/null
+++ b/examples/EvrardCollapse_3D/getReference.sh
@@ -0,0 +1,2 @@
+#! /bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ReferenceSolutions/evrardCollapse3D_exact.txt
diff --git a/examples/EvrardCollapse_3D/makeIC.py b/examples/EvrardCollapse_3D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..b68f0da0e1869ce54ae7ab2ad3b33b8c3deb8b51
--- /dev/null
+++ b/examples/EvrardCollapse_3D/makeIC.py
@@ -0,0 +1,95 @@
+################################################################################
+# 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/>.
+#
+################################################################################
+
+import h5py
+from numpy import *
+
+# Generates a swift IC file for the Evrard collapse
+
+# Parameters
+gamma = 5. / 3.      # Gas adiabatic index
+M = 1.  # total mass of the sphere
+R = 1.               # radius of the sphere
+u0 = 0.05 / M        # initial thermal energy
+fileName = "evrard.hdf5" 
+numPart = 100000
+
+r = R * sqrt(random.random(numPart))
+phi = 2. * pi * random.random(numPart)
+cos_theta = 2. * random.random(numPart) - 1.
+
+sin_theta = sqrt(1. - cos_theta**2)
+cos_phi = cos(phi)
+sin_phi = sin(phi)
+
+pos = zeros((numPart, 3))
+pos[:,0] = r * sin_theta * cos_phi
+pos[:,1] = r * sin_theta * sin_phi
+pos[:,2] = r * cos_theta
+
+# shift particles to put the sphere in the centre of the box
+pos += array([50. * R, 50. * R, 50. * R])
+
+h = ones(numPart) * 2. * R / numPart**(1. / 3.)
+
+# Generate extra arrays
+v = zeros((numPart, 3))
+ids = linspace(1, numPart, numPart)
+m = ones(numPart) * M / numPart
+u = ones(numPart) * u0
+
+#--------------------------------------------------
+
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [100. * R, 100. * R, 100. * R]
+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
+grp.attrs["Dimension"] = 3
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 0
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+file.close()
diff --git a/examples/EvrardCollapse_3D/plotSolution.py b/examples/EvrardCollapse_3D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..8422b9c45fd573f3d0ae36324d6e39ab23cceb25
--- /dev/null
+++ b/examples/EvrardCollapse_3D/plotSolution.py
@@ -0,0 +1,172 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               2018 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/>.
+# 
+################################################################################
+
+# Compares the swift result for the 2D spherical Sod shock with a high
+# resolution 2D reference result
+
+import matplotlib
+matplotlib.use("Agg")
+from pylab import *
+from scipy import stats
+import h5py
+
+# Parameters
+gas_gamma = 5./3.      # Polytropic index
+rho_L = 1.             # Density left state
+rho_R = 0.125          # Density right state
+v_L = 0.               # Velocity left state
+v_R = 0.               # Velocity right state
+P_L = 1.               # Pressure left state
+P_R = 0.1              # Pressure right state
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+rcParams.update(params)
+rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+snap = int(sys.argv[1])
+
+# Read the simulation data
+sim = h5py.File("evrard_%04d.hdf5"%snap, "r")
+boxSize = sim["/Header"].attrs["BoxSize"][0]
+time = sim["/Header"].attrs["Time"][0]
+scheme = sim["/HydroScheme"].attrs["Scheme"]
+kernel = sim["/HydroScheme"].attrs["Kernel function"]
+neighbours = sim["/HydroScheme"].attrs["Kernel target N_ngb"]
+eta = sim["/HydroScheme"].attrs["Kernel eta"]
+git = sim["Code"].attrs["Git Revision"]
+
+coords = sim["/PartType0/Coordinates"]
+x = sqrt((coords[:,0] - 0.5 * boxSize)**2 + (coords[:,1] - 0.5 * boxSize)**2 + \
+         (coords[:,2] - 0.5 * boxSize)**2)
+vels = sim["/PartType0/Velocities"]
+v = sqrt(vels[:,0]**2 + vels[:,1]**2 + vels[:,2]**2)
+u = sim["/PartType0/InternalEnergy"][:]
+S = sim["/PartType0/Entropy"][:]
+P = sim["/PartType0/Pressure"][:]
+rho = sim["/PartType0/Density"][:]
+
+# Bin the data
+x_bin_edge = logspace(-3., log10(2.), 100)
+x_bin = 0.5*(x_bin_edge[1:] + x_bin_edge[:-1])
+rho_bin,_,_ = stats.binned_statistic(x, rho, statistic='mean', bins=x_bin_edge)
+v_bin,_,_ = stats.binned_statistic(x, v, statistic='mean', bins=x_bin_edge)
+P_bin,_,_ = stats.binned_statistic(x, P, statistic='mean', bins=x_bin_edge)
+S_bin,_,_ = stats.binned_statistic(x, S, statistic='mean', bins=x_bin_edge)
+u_bin,_,_ = stats.binned_statistic(x, u, statistic='mean', bins=x_bin_edge)
+rho2_bin,_,_ = stats.binned_statistic(x, rho**2, statistic='mean', bins=x_bin_edge)
+v2_bin,_,_ = stats.binned_statistic(x, v**2, statistic='mean', bins=x_bin_edge)
+P2_bin,_,_ = stats.binned_statistic(x, P**2, statistic='mean', bins=x_bin_edge)
+S2_bin,_,_ = stats.binned_statistic(x, S**2, statistic='mean', bins=x_bin_edge)
+u2_bin,_,_ = stats.binned_statistic(x, u**2, statistic='mean', bins=x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+ref = loadtxt("evrardCollapse3D_exact.txt")
+
+# Plot the interesting quantities
+figure()
+
+# Velocity profile --------------------------------
+subplot(231)
+semilogx(x, -v, '.', color='r', ms=0.2)
+semilogx(ref[:,0], ref[:,2], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, -v_bin, yerr=v_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Velocity}}~v_r$", labelpad=0)
+xlim(1.e-3, 2.)
+ylim(-1.7, 0.1)
+
+# Density profile --------------------------------
+subplot(232)
+loglog(x, rho, '.', color='r', ms=0.2)
+loglog(ref[:,0], ref[:,1], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, rho_bin, yerr=rho_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Density}}~\\rho$", labelpad=0)
+xlim(1.e-3, 2.)
+ylim(1.e-2, 1.e4)
+
+# Pressure profile --------------------------------
+subplot(233)
+loglog(x, P, '.', color='r', ms=0.2)
+loglog(ref[:,0], ref[:,3], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, P_bin, yerr=P_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Pressure}}~P$", labelpad=0)
+xlim(1.e-3, 2.)
+ylim(1.e-4, 1.e3)
+
+# Internal energy profile -------------------------
+subplot(234)
+loglog(x, u, '.', color='r', ms=0.2)
+loglog(ref[:,0], ref[:,3] / ref[:,1] / (gas_gamma - 1.), "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, u_bin, yerr=u_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Internal~Energy}}~u$", labelpad=0)
+xlim(1.e-3, 2.)
+ylim(1.e-2, 2.)
+
+# Entropy profile ---------------------------------
+subplot(235)
+semilogx(x, S, '.', color='r', ms=0.2)
+semilogx(ref[:,0], ref[:,3] / ref[:,1]**gas_gamma, "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Entropy}}~S$", labelpad=0)
+xlim(1.e-3, 2.)
+ylim(0., 0.25)
+
+# Information -------------------------------------
+subplot(236, frameon=False)
+
+text(-0.49, 0.9, "Evrard collapse with $\\gamma=%.3f$ in 3D\nat $t=%.2f$"%(gas_gamma,time), fontsize=10)
+plot([-0.49, 0.1], [0.62, 0.62], 'k-', lw=1)
+text(-0.49, 0.5, "$\\textsc{Swift}$ %s"%git, fontsize=10)
+text(-0.49, 0.4, scheme, fontsize=10)
+text(-0.49, 0.3, kernel, fontsize=10)
+text(-0.49, 0.2, "$%.2f$ neighbours ($\\eta=%.3f$)"%(neighbours, eta), fontsize=10)
+xlim(-0.5, 0.5)
+ylim(0, 1)
+xticks([])
+yticks([])
+
+tight_layout()
+savefig("EvrardCollapse.png", dpi=200)
diff --git a/examples/EvrardCollapse_3D/run.sh b/examples/EvrardCollapse_3D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..abb7614f66fc877aa670db9b0e1335fbfe2e85d2
--- /dev/null
+++ b/examples/EvrardCollapse_3D/run.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e evrard.hdf5 ]
+then
+    echo "Generating initial conditions for the Evrard collapse example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -G -t 4 evrard.yml 2>&1 | tee output.log
+
+# Get the high resolution 1D reference result if not present.
+if [ ! -e evrardCollapse3D_exact.txt ]
+then
+    echo "Fetching the reference result for the Evrard collapse example..."
+    ./getReference.sh
+fi
+
+# Plot the solution
+python plotSolution.py 8
diff --git a/examples/ExternalPointMass/externalPointMass.yml b/examples/ExternalPointMass/externalPointMass.yml
index a5077ee4437c1905d104676ee201a3be7c5391e8..6e2315cc4dd5c2c354375d39e03f13a1553ed08b 100644
--- a/examples/ExternalPointMass/externalPointMass.yml
+++ b/examples/ExternalPointMass/externalPointMass.yml
@@ -1,8 +1,8 @@
 # Define the system of units to use internally. 
 InternalUnitSystem:
-  UnitMass_in_cgs:     1.9885e33     # Grams
-  UnitLength_in_cgs:   3.0856776e21  # Centimeters
-  UnitVelocity_in_cgs: 1e5           # Centimeters per second
+  UnitMass_in_cgs:     1.98848e33    # M_sun
+  UnitLength_in_cgs:   3.0856776e21  # kpc
+  UnitVelocity_in_cgs: 1e5           # km/s
   UnitCurrent_in_cgs:  1   # Amperes
   UnitTemp_in_cgs:     1   # Kelvin
 
diff --git a/examples/ExternalPointMass/makeIC.py b/examples/ExternalPointMass/makeIC.py
index ba415daf9e03058239599cc08039fc89e0929393..f8310e1c04265b80c6dbf6e2b003e78d95d75281 100644
--- a/examples/ExternalPointMass/makeIC.py
+++ b/examples/ExternalPointMass/makeIC.py
@@ -28,7 +28,7 @@ import random
 
 # physical constants in cgs
 NEWTON_GRAVITY_CGS  = 6.67408e-8
-SOLAR_MASS_IN_CGS   = 1.9885e33
+SOLAR_MASS_IN_CGS   = 1.98848e33
 PARSEC_IN_CGS       = 3.0856776e18
 
 # choice of units
@@ -86,7 +86,7 @@ grp.attrs["PeriodicBoundariesOn"] = periodic
 #Units
 grp = file.create_group("/Units")
 grp.attrs["Unit length in cgs (U_L)"] = 3.0856776e21
-grp.attrs["Unit mass in cgs (U_M)"] = 1.9885e33
+grp.attrs["Unit mass in cgs (U_M)"] = 1.98848e33
 grp.attrs["Unit time in cgs (U_t)"] = 3.0856776e16
 grp.attrs["Unit current in cgs (U_I)"] = 1.
 grp.attrs["Unit temperature in cgs (U_T)"] = 1.
diff --git a/examples/GreshoVortex_3D/getGlass.sh b/examples/GreshoVortex_3D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d5c5f590ac37c9c9431d626a2ea61b0c12c1513c
--- /dev/null
+++ b/examples/GreshoVortex_3D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_64.hdf5
diff --git a/examples/GreshoVortex_3D/gresho.yml b/examples/GreshoVortex_3D/gresho.yml
new file mode 100644
index 0000000000000000000000000000000000000000..df941450196a7de6cd1471e1d258756ca8c36fb1
--- /dev/null
+++ b/examples/GreshoVortex_3D/gresho.yml
@@ -0,0 +1,36 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # Centimeters per second
+  UnitCurrent_in_cgs:  1   # Amperes
+  UnitTemp_in_cgs:     1   # Kelvin
+
+Scheduler:
+  max_top_level_cells: 15
+
+# Parameters governing the time integration
+TimeIntegration:
+  time_begin: 0.    # The starting time of the simulation (in internal units).
+  time_end:   1.    # The end time of the simulation (in internal units).
+  dt_min:     1e-6  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            gresho # Common part of the name of output files
+  time_first:          0.     # Time of the first output (in internal units)
+  delta_time:          1e-1   # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+  
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./greshoVortex.hdf5     # The file to read
diff --git a/examples/GreshoVortex_3D/makeIC.py b/examples/GreshoVortex_3D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..cba2158016bc86f58b6e89f83cbfb473798e1cf7
--- /dev/null
+++ b/examples/GreshoVortex_3D/makeIC.py
@@ -0,0 +1,120 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               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/>.
+#
+################################################################################
+
+import h5py
+from numpy import *
+
+# Generates a swift IC file for the Gresho-Chan vortex in a periodic box
+
+# Parameters
+gamma = 5./3.     # Gas adiabatic index
+rho0 = 1           # Gas density
+P0 = 0.           # Constant additional pressure (should have no impact on the dynamics)
+fileOutputName = "greshoVortex.hdf5" 
+fileGlass = "glassCube_64.hdf5"
+#---------------------------------------------------
+
+# Get position and smoothing lengths from the glass
+fileInput = h5py.File(fileGlass, 'r')
+coords = fileInput["/PartType0/Coordinates"][:,:]
+h = fileInput["/PartType0/SmoothingLength"][:]
+ids = fileInput["/PartType0/ParticleIDs"][:]
+boxSize = fileInput["/Header"].attrs["BoxSize"][0]
+numPart = size(h)
+fileInput.close()
+
+# Now generate the rest
+m = ones(numPart) * rho0 * boxSize**3 / numPart
+u = zeros(numPart)
+v = zeros((numPart, 3))
+
+for i in range(numPart):
+    
+    x = coords[i,0]
+    y = coords[i,1]
+
+    r2 = (x - boxSize / 2)**2 + (y - boxSize / 2)**2
+    r = sqrt(r2)
+
+    v_phi = 0.
+    if r < 0.2:
+        v_phi = 5.*r
+    elif r < 0.4:
+        v_phi = 2. - 5.*r
+    else:
+        v_phi = 0.
+    v[i,0] = -v_phi * (y - boxSize / 2) / r
+    v[i,1] =  v_phi * (x - boxSize / 2) / r
+    v[i,2] = 0.
+
+    P = P0
+    if r < 0.2:
+        P = P + 5. + 12.5*r2
+    elif r < 0.4:
+        P = P + 9. + 12.5*r2 - 20.*r + 4.*log(r/0.2)
+    else:
+        P = P + 3. + 4.*log(2.)
+    u[i] = P / ((gamma - 1.)*rho0)
+    
+
+
+#File
+fileOutput = h5py.File(fileOutputName, 'w')
+
+# Header
+grp = fileOutput.create_group("/Header")
+grp.attrs["BoxSize"] = [boxSize, boxSize, boxSize]
+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["NumFileOutputsPerSnapshot"] = 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"] = 3
+
+#Runtime parameters
+grp = fileOutput.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = fileOutput.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = fileOutput.create_group("/PartType0")
+ds = grp.create_dataset('Coordinates', (numPart, 3), 'd')
+ds[()] = coords
+ds = grp.create_dataset('Velocities', (numPart, 3), 'f')
+ds[()] = v
+ds = grp.create_dataset('Masses', (numPart, 1), 'f')
+ds[()] = m.reshape((numPart,1))
+ds = grp.create_dataset('SmoothingLength', (numPart,1), 'f')
+ds[()] = h.reshape((numPart,1))
+ds = grp.create_dataset('InternalEnergy', (numPart,1), 'f')
+ds[()] = u.reshape((numPart,1))
+ds = grp.create_dataset('ParticleIDs', (numPart,1), 'L')
+ds[()] = ids.reshape((numPart,1))
+
+fileOutput.close()
diff --git a/examples/GreshoVortex_3D/plotSolution.py b/examples/GreshoVortex_3D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fddf148bd169310d5e69ffbfa4a6de099068c69
--- /dev/null
+++ b/examples/GreshoVortex_3D/plotSolution.py
@@ -0,0 +1,227 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               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/>.
+#
+################################################################################
+
+# Computes the analytical solution of the Gresho-Chan vortex and plots the SPH
+# answer
+
+# Parameters
+gas_gamma = 5./3. # Gas adiabatic index
+rho0 = 1          # Gas density
+P0 = 0.           # Constant additional pressure (should have no impact on the
+                  # dynamics)
+
+# ---------------------------------------------------------------
+# Don't touch anything after this.
+# ---------------------------------------------------------------
+
+import matplotlib
+matplotlib.use("Agg")
+from pylab import *
+from scipy import stats
+import h5py
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+rcParams.update(params)
+rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+
+snap = int(sys.argv[1])
+
+# Generate the analytic solution at this time
+N = 200
+R_max = 0.8
+solution_r = arange(0, R_max, R_max / N)
+solution_P = zeros(N)
+solution_v_phi = zeros(N)
+solution_v_r = zeros(N)
+
+for i in range(N):
+    if solution_r[i] < 0.2:
+        solution_P[i] = P0 + 5. + 12.5*solution_r[i]**2
+        solution_v_phi[i] = 5.*solution_r[i]
+    elif solution_r[i] < 0.4:
+        solution_P[i] = P0 + 9. + 12.5*solution_r[i]**2 - 20.*solution_r[i] + 4.*log(solution_r[i]/0.2)
+        solution_v_phi[i] = 2. -5.*solution_r[i]
+    else:
+        solution_P[i] = P0 + 3. + 4.*log(2.)
+        solution_v_phi[i] = 0.
+
+solution_rho = ones(N) * rho0
+solution_s = solution_P / solution_rho**gas_gamma
+solution_u = solution_P /((gas_gamma - 1.)*solution_rho)
+
+# Read the simulation data
+sim = h5py.File("gresho_%04d.hdf5"%snap, "r")
+boxSize = sim["/Header"].attrs["BoxSize"][0]
+time = sim["/Header"].attrs["Time"][0]
+scheme = sim["/HydroScheme"].attrs["Scheme"]
+kernel = sim["/HydroScheme"].attrs["Kernel function"]
+neighbours = sim["/HydroScheme"].attrs["Kernel target N_ngb"]
+eta = sim["/HydroScheme"].attrs["Kernel eta"]
+git = sim["Code"].attrs["Git Revision"]
+
+pos = sim["/PartType0/Coordinates"][:,:]
+x = pos[:,0] - boxSize / 2
+y = pos[:,1] - boxSize / 2
+vel = sim["/PartType0/Velocities"][:,:]
+r = sqrt(x**2 + y**2)
+v_r = (x * vel[:,0] + y * vel[:,1]) / r
+v_phi = (-y * vel[:,0] + x * vel[:,1]) / r
+v_norm = sqrt(vel[:,0]**2 + vel[:,1]**2)
+rho = sim["/PartType0/Density"][:]
+u = sim["/PartType0/InternalEnergy"][:]
+S = sim["/PartType0/Entropy"][:]
+P = sim["/PartType0/Pressure"][:]
+
+# Bin te data
+r_bin_edge = np.arange(0., 1., 0.02)
+r_bin = 0.5*(r_bin_edge[1:] + r_bin_edge[:-1])
+rho_bin,_,_ = stats.binned_statistic(r, rho, statistic='mean', bins=r_bin_edge)
+v_bin,_,_ = stats.binned_statistic(r, v_phi, statistic='mean', bins=r_bin_edge)
+P_bin,_,_ = stats.binned_statistic(r, P, statistic='mean', bins=r_bin_edge)
+S_bin,_,_ = stats.binned_statistic(r, S, statistic='mean', bins=r_bin_edge)
+u_bin,_,_ = stats.binned_statistic(r, u, statistic='mean', bins=r_bin_edge)
+rho2_bin,_,_ = stats.binned_statistic(r, rho**2, statistic='mean', bins=r_bin_edge)
+v2_bin,_,_ = stats.binned_statistic(r, v_phi**2, statistic='mean', bins=r_bin_edge)
+P2_bin,_,_ = stats.binned_statistic(r, P**2, statistic='mean', bins=r_bin_edge)
+S2_bin,_,_ = stats.binned_statistic(r, S**2, statistic='mean', bins=r_bin_edge)
+u2_bin,_,_ = stats.binned_statistic(r, u**2, statistic='mean', bins=r_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+
+# Plot the interesting quantities
+figure()
+
+
+# Azimuthal velocity profile -----------------------------
+subplot(231)
+
+plot(r, v_phi, '.', color='r', ms=0.5)
+plot(solution_r, solution_v_phi, '--', color='k', alpha=0.8, lw=1.2)
+errorbar(r_bin, v_bin, yerr=v_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Azimuthal~velocity}}~v_\\phi$", labelpad=0)
+xlim(0,R_max)
+ylim(-0.1, 1.2)
+
+# Radial density profile --------------------------------
+subplot(232)
+
+plot(r, rho, '.', color='r', ms=0.5)
+plot(solution_r, solution_rho, '--', color='k', alpha=0.8, lw=1.2)
+errorbar(r_bin, rho_bin, yerr=rho_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Density}}~\\rho$", labelpad=0)
+xlim(0,R_max)
+ylim(rho0-0.3, rho0 + 0.3)
+#yticks([-0.2, -0.1, 0., 0.1, 0.2])
+
+# Radial pressure profile --------------------------------
+subplot(233)
+
+plot(r, P, '.', color='r', ms=0.5)
+plot(solution_r, solution_P, '--', color='k', alpha=0.8, lw=1.2)
+errorbar(r_bin, P_bin, yerr=P_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Pressure}}~P$", labelpad=0)
+xlim(0, R_max)
+ylim(4.9 + P0, P0 + 6.1)
+
+# Internal energy profile --------------------------------
+subplot(234)
+
+plot(r, u, '.', color='r', ms=0.5)
+plot(solution_r, solution_u, '--', color='k', alpha=0.8, lw=1.2)
+errorbar(r_bin, u_bin, yerr=u_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Internal~Energy}}~u$", labelpad=0)
+xlim(0,R_max)
+ylim(7.3, 9.1)
+
+
+# Radial entropy profile --------------------------------
+subplot(235)
+
+plot(r, S, '.', color='r', ms=0.5)
+plot(solution_r, solution_s, '--', color='k', alpha=0.8, lw=1.2)
+errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Entropy}}~S$", labelpad=0)
+xlim(0, R_max)
+ylim(4.9 + P0, P0 + 6.1)
+
+# Image --------------------------------------------------
+#subplot(234)
+#scatter(pos[:,0], pos[:,1], c=v_norm, cmap="PuBu", edgecolors='face', s=4, vmin=0, vmax=1)
+#text(0.95, 0.95, "$|v|$", ha="right", va="top")
+#xlim(0,1)
+#ylim(0,1)
+#xlabel("$x$", labelpad=0)
+#ylabel("$y$", labelpad=0)
+
+# Information -------------------------------------
+subplot(236, frameon=False)
+
+text(-0.49, 0.9, "Gresho-Chan vortex with  $\\gamma=%.3f$ at $t=%.2f$"%(gas_gamma,time), fontsize=10)
+text(-0.49, 0.8, "Background $\\rho_0=%.3f$"%rho0, fontsize=10)
+text(-0.49, 0.7, "Background $P_0=%.3f$"%P0, fontsize=10)
+plot([-0.49, 0.1], [0.62, 0.62], 'k-', lw=1)
+text(-0.49, 0.5, "$\\textsc{Swift}$ %s"%git, fontsize=10)
+text(-0.49, 0.4, scheme, fontsize=10)
+text(-0.49, 0.3, kernel, fontsize=10)
+text(-0.49, 0.2, "$%.2f$ neighbours ($\\eta=%.3f$)"%(neighbours, eta), fontsize=10)
+xlim(-0.5, 0.5)
+ylim(0, 1)
+xticks([])
+yticks([])
+
+savefig("GreshoVortex.png", dpi=200)
diff --git a/examples/GreshoVortex_3D/run.sh b/examples/GreshoVortex_3D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..da7d6cee111aebcfd2fcb0f3508af80ef73cbeb0
--- /dev/null
+++ b/examples/GreshoVortex_3D/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+ # Generate the initial conditions if they are not present.
+if [ ! -e glassCube_64.hdf5 ]
+then
+    echo "Fetching initial glass file for the Gresho-Chan vortex example..."
+    ./getGlass.sh
+fi
+if [ ! -e greshoVortex.hdf5 ]
+then
+    echo "Generating initial conditions for the Gresho-Chan vortex example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 4 gresho.yml 2>&1 | tee output.log
+
+# Plot the solution
+python plotSolution.py 11
diff --git a/examples/HydrostaticHalo/hydrostatic.yml b/examples/HydrostaticHalo/hydrostatic.yml
index 64144c6d9fe6e6d4e0731b16e8b694d92d6a4a3c..38a5df2866d39523e6e4b9f6c1c97a7537bff5a4 100644
--- a/examples/HydrostaticHalo/hydrostatic.yml
+++ b/examples/HydrostaticHalo/hydrostatic.yml
@@ -1,6 +1,6 @@
 # Define the system of units to use internally. 
 InternalUnitSystem:
-  UnitMass_in_cgs:     1.9885e39     # 10^6 solar masses
+  UnitMass_in_cgs:     1.98848e39    # 10^6 solar masses
   UnitLength_in_cgs:   3.0856776e21  # Kiloparsecs
   UnitVelocity_in_cgs: 1e5           # Kilometres per second
   UnitCurrent_in_cgs:  1   # Amperes
diff --git a/examples/InteractingBlastWaves_1D/getReference.sh b/examples/InteractingBlastWaves_1D/getReference.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9b6e884850571f7dfbc3f2018235118447bc00be
--- /dev/null
+++ b/examples/InteractingBlastWaves_1D/getReference.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ReferenceSolutions/interactingBlastWaves1D_exact.txt
diff --git a/examples/InteractingBlastWaves_1D/plotSolution.py b/examples/InteractingBlastWaves_1D/plotSolution.py
index 342b67eae1061a9a94675a59f53ebf9e4ba7717f..1719162dec34626d6f4ecb8267c4d06f85b3db26 100644
--- a/examples/InteractingBlastWaves_1D/plotSolution.py
+++ b/examples/InteractingBlastWaves_1D/plotSolution.py
@@ -17,21 +17,116 @@
 #
 ##############################################################################
 
-import h5py
+import numpy as np
 import matplotlib
 matplotlib.use("Agg")
 import pylab as pl
+import h5py
 import sys
 
+# Parameters
+gamma = 1.4 # Polytropic index
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+pl.rcParams.update(params)
+pl.rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+# Read the snapshot index from the command line argument
 snap = int(sys.argv[1])
 
-sim = h5py.File("interactingBlastWaves_%04d.hdf5" % snap, "r")
-coords = sim["/PartType0/Coordinates"]
-rho = sim["/PartType0/Density"]
+# Open the file and read the relevant data
+file = h5py.File("interactingBlastWaves_{0:04d}.hdf5".format(snap), "r")
+x = file["/PartType0/Coordinates"][:,0]
+rho = file["/PartType0/Density"]
+v = file["/PartType0/Velocities"][:,0]
+u = file["/PartType0/InternalEnergy"]
+S = file["/PartType0/Entropy"]
+P = file["/PartType0/Pressure"]
+time = file["/Header"].attrs["Time"][0]
+
+scheme = file["/HydroScheme"].attrs["Scheme"]
+kernel = file["/HydroScheme"].attrs["Kernel function"]
+neighbours = file["/HydroScheme"].attrs["Kernel target N_ngb"][0]
+eta = file["/HydroScheme"].attrs["Kernel eta"][0]
+git = file["Code"].attrs["Git Revision"]
+
+ref = np.loadtxt("interactingBlastWaves1D_exact.txt")
+
+# Plot the interesting quantities
+fig, ax = pl.subplots(2, 3)
+
+# Velocity profile
+ax[0][0].plot(x, v, "r.", markersize = 4.)
+ax[0][0].plot(ref[:,0], ref[:,2], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][0].set_ylabel("${\\rm{Velocity}}~v_x$", labelpad = 0)
+ax[0][0].set_xlim(0., 1.)
+ax[0][0].set_ylim(-1., 15.)
+
+# Density profile
+ax[0][1].plot(x, rho, "r.", markersize = 4.)
+ax[0][1].plot(ref[:,0], ref[:,1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][1].set_ylabel("${\\rm{Density}}~\\rho$", labelpad = 0)
+ax[0][1].set_xlim(0., 1.)
+
+# Pressure profile
+ax[0][2].plot(x, P, "r.", markersize = 4.)
+ax[0][2].plot(ref[:,0], ref[:,3], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][2].set_ylabel("${\\rm{Pressure}}~P$", labelpad = 0)
+ax[0][2].set_xlim(0., 1.)
+
+# Internal energy profile
+ax[1][0].plot(x, u, "r.", markersize = 4.)
+ax[1][0].plot(ref[:,0], ref[:,3] / ref[:,1] / (gamma - 1.), "k--", alpha = 0.8,
+              linewidth = 1.2)
+ax[1][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][0].set_ylabel("${\\rm{Internal~Energy}}~u$", labelpad = 0)
+ax[1][0].set_xlim(0., 1.)
+
+# Entropy profile
+ax[1][1].plot(x, S, "r.", markersize = 4.)
+ax[1][1].plot(ref[:,0], ref[:,3] / ref[:,1]**gamma, "k--", alpha = 0.8,
+              linewidth = 1.2)
+ax[1][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][1].set_ylabel("${\\rm{Entropy}}~S$", labelpad = 0)
+ax[1][1].set_xlim(0., 1.)
+
+# Run information
+ax[1][2].set_frame_on(False)
+ax[1][2].text(-0.49, 0.9,
+  "Interacting blast waves test\nwith $\\gamma={0:.3f}$ in 1D at $t = {1:.2f}$".format(
+    gamma, time), fontsize = 10)
+ax[1][2].plot([-0.49, 0.1], [0.62, 0.62], "k-", lw = 1)
+ax[1][2].text(-0.49, 0.5, "$\\textsc{{Swift}}$ {0}".format(git), fontsize = 10)
+ax[1][2].text(-0.49, 0.4, scheme, fontsize = 10)
+ax[1][2].text(-0.49, 0.3, kernel, fontsize = 10)
+ax[1][2].text(-0.49, 0.2,
+  "${0:.2f}$ neighbours ($\\eta={1:.3f}$)".format(neighbours, eta),
+  fontsize = 10)
+ax[1][2].set_xlim(-0.5, 0.5)
+ax[1][2].set_ylim(0., 1.)
+ax[1][2].set_xticks([])
+ax[1][2].set_yticks([])
 
-pl.xlabel("$x$")
-pl.ylabel("$\\rho{}$")
-pl.xlim(0.4, 1.)
-pl.ylim(0., 7.)
-pl.plot(coords[:,0], rho, "k.")
-pl.savefig("InteractingBlastWaves.png")
+pl.tight_layout()
+pl.savefig("InteractingBlastWaves.png", dpi = 200)
diff --git a/examples/InteractingBlastWaves_1D/run.sh b/examples/InteractingBlastWaves_1D/run.sh
index 65a1a109857da6e32663451430b3284aa7207d5a..31717bd806ddd6c98c24dfc1def6f79dddff42ff 100755
--- a/examples/InteractingBlastWaves_1D/run.sh
+++ b/examples/InteractingBlastWaves_1D/run.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
- # Generate the initial conditions if they are not present.
+# Generate the initial conditions if they are not present.
 if [ ! -e interactingBlastWaves.hdf5 ]
 then
     echo "Generating initial conditions for the Sedov blast example..."
@@ -10,5 +10,12 @@ fi
 # Run SWIFT
 ../swift -s -t 1 interactingBlastWaves.yml 2>&1 | tee output.log
 
+# Get the high resolution reference solution if not present.
+if [ ! -e interactingBlastWaves1D_exact.txt ]
+then
+    echo "Fetching reference solution for the interacting blast waves test..."
+    ./getReference.sh
+fi
+
 # Plot the solution
 python plotSolution.py 4
diff --git a/examples/IsothermalPotential/isothermal.yml b/examples/IsothermalPotential/isothermal.yml
index 8d9ec3875e405d95a89b3486bca5fd3465a3e20d..bd59ddc5117f71c478ce5eeda0a08817eefe8624 100644
--- a/examples/IsothermalPotential/isothermal.yml
+++ b/examples/IsothermalPotential/isothermal.yml
@@ -1,8 +1,8 @@
 # Define the system of units to use internally. 
 InternalUnitSystem:
-  UnitMass_in_cgs:     1.9885e33     # Grams
-  UnitLength_in_cgs:   3.0856776e21  # Centimeters
-  UnitVelocity_in_cgs: 1e5           # Centimeters per second
+  UnitMass_in_cgs:     1.98848e33    # M_sun
+  UnitLength_in_cgs:   3.0856776e21  # kpc
+  UnitVelocity_in_cgs: 1e5           # km/s
   UnitCurrent_in_cgs:  1   # Amperes
   UnitTemp_in_cgs:     1   # Kelvin
 
diff --git a/examples/IsothermalPotential/makeIC.py b/examples/IsothermalPotential/makeIC.py
index 27ddf15fe63d69d4172b927cfca8b8662d11ea4e..85437442c6271589e3105c9c99477377b75b8d4b 100644
--- a/examples/IsothermalPotential/makeIC.py
+++ b/examples/IsothermalPotential/makeIC.py
@@ -31,7 +31,7 @@ import random
 
 # physical constants in cgs
 NEWTON_GRAVITY_CGS  = 6.67408e-8
-SOLAR_MASS_IN_CGS   = 1.9885e33
+SOLAR_MASS_IN_CGS   = 1.98848e33
 PARSEC_IN_CGS       = 3.0856776e18
 PROTON_MASS_IN_CGS  = 1.672621898e24
 YEAR_IN_CGS         = 3.154e+7
diff --git a/examples/KelvinHelmholtzGrowthRate_2D/getGlass.sh b/examples/KelvinHelmholtzGrowthRate_2D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ae3c977064f5e7a408aa249c5fd9089b3c52ecb1
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_2D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassPlane_128.hdf5
diff --git a/examples/KelvinHelmholtzGrowthRate_2D/kelvinHelmholtzGrowthRate.yml b/examples/KelvinHelmholtzGrowthRate_2D/kelvinHelmholtzGrowthRate.yml
new file mode 100644
index 0000000000000000000000000000000000000000..380dc2ab3a530e89b952aa41f425e50709d73ee9
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_2D/kelvinHelmholtzGrowthRate.yml
@@ -0,0 +1,33 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   4.   # The end time of the simulation (in internal units).
+  dt_min:     1e-6  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            kelvinHelmholtzGrowthRate  # Common part of the name of output files
+  time_first:          0.               # Time of the first output (in internal units)
+  delta_time:          0.04      # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+  
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./kelvinHelmholtzGrowthRate.hdf5     # The file to read
diff --git a/examples/KelvinHelmholtzGrowthRate_2D/makeIC.py b/examples/KelvinHelmholtzGrowthRate_2D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..f21d0c0abf9b15f8253f627bcb1da43ae276fb35
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_2D/makeIC.py
@@ -0,0 +1,100 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               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/>.
+#
+################################################################################
+
+import h5py
+import numpy as np
+
+# Generates a swift IC file for the Kelvin-Helmholtz vortex in a periodic box
+
+# Parameters
+gamma = 5./3.     # Gas adiabatic index
+P0    = 2.5       # Pressure
+rho0  = 1.        # Density
+d     = 0.0317    # Thickness of the transition layer
+B     = 0.0005    # Amplitude of the seed velocity
+
+fileOutputName = "kelvinHelmholtzGrowthRate.hdf5"
+
+#---------------------------------------------------
+
+glass = h5py.File("glassPlane_128.hdf5", 'r')
+pos = glass["/PartType0/Coordinates"][:, :]
+h = glass["/PartType0/SmoothingLength"][:]
+
+N = len(h)
+vol = 1.
+
+# Generate extra arrays
+v = np.zeros((N, 3))
+ids = np.linspace(1, N, N)
+m = np.ones(N) * rho0 * vol / N
+u = np.ones(N) * P0 / (rho0 * (gamma - 1.))
+
+v[pos[:, 1] <= 0.25 - d, 0] = -0.5
+v[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 0] = \
+  -0.5 + \
+  0.5 * (pos[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 1] + d - 0.25) / d
+v[(pos[:, 1] <= 0.75 - d) & (pos[:, 1] >= 0.25 + d), 0] = 0.5
+v[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 0] = \
+  0.5 - \
+  0.5 * (pos[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 1] + d - 0.75) / d
+v[pos[:, 1] >= 0.75 + d, 0] = -0.5
+
+v[:, 1] = B * np.sin(4. * np.pi * pos[:, 0]) * \
+          (np.exp(-(pos[:, 1] - 0.25)**2 / 32. / d**2) + \
+           np.exp(-(pos[:, 1] - 0.75)**2 / 32. / d**2))
+            
+#File
+fileOutput = h5py.File(fileOutputName, 'w')
+
+# Header
+grp = fileOutput.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 1., 1.]
+grp.attrs["NumPart_Total"] =  [N, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_ThisFile"] = [N, 0, 0, 0, 0, 0]
+grp.attrs["Time"] = 0.0
+grp.attrs["NumFileOutputsPerSnapshot"] = 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"] = 2
+
+#Runtime parameters
+grp = fileOutput.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = fileOutput.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = fileOutput.create_group("/PartType0")
+grp.create_dataset("Coordinates", data = pos, dtype = 'd')
+grp.create_dataset("Velocities", data = v, dtype = 'f')
+grp.create_dataset("Masses", data = m, dtype = 'f')
+grp.create_dataset("SmoothingLength", data = h, dtype = 'f')
+grp.create_dataset("InternalEnergy", data = u, dtype = 'f')
+grp.create_dataset("ParticleIDs", data = ids, dtype = 'L')
+
+fileOutput.close()
diff --git a/examples/KelvinHelmholtzGrowthRate_2D/makeIC_regular.py b/examples/KelvinHelmholtzGrowthRate_2D/makeIC_regular.py
new file mode 100644
index 0000000000000000000000000000000000000000..5029165a6a328b6c706d37b632b14cbcd51501d0
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_2D/makeIC_regular.py
@@ -0,0 +1,106 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               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/>.
+#
+################################################################################
+
+import h5py
+import numpy as np
+
+# Generates a swift IC file for the Kelvin-Helmholtz vortex in a periodic box
+
+# Parameters
+gamma = 5./3.     # Gas adiabatic index
+P0    = 2.5       # Pressure
+rho0  = 1.        # Density
+d     = 0.0317    # Thickness of the transition layer
+B     = 0.0005    # Amplitude of the seed velocity
+N1D   = 128       # Number of particles in one dimension
+
+fileOutputName = "kelvinHelmholtzGrowthRate.hdf5"
+
+#---------------------------------------------------
+
+N = N1D ** 2
+x = np.linspace(0., 1., N1D + 1)
+x = 0.5 * (x[1:] + x[:-1])
+y = x
+xx, yy = np.meshgrid(x, y)
+pos = np.zeros((N, 3))
+pos[:, 0] = xx.reshape((N))
+pos[:, 1] = yy.reshape((N))
+h = np.ones(N) * 2. / N1D
+
+vol = 1.
+
+# Generate extra arrays
+v = np.zeros((N, 3))
+ids = np.linspace(1, N, N)
+m = np.ones(N) * rho0 * vol / N
+u = np.ones(N) * P0 / (rho0 * (gamma - 1.))
+
+v[pos[:, 1] <= 0.25 - d, 0] = -0.5
+v[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 0] = \
+  -0.5 + \
+  0.5 * (pos[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 1] + d - 0.25) / d
+v[(pos[:, 1] <= 0.75 - d) & (pos[:, 1] >= 0.25 + d), 0] = 0.5
+v[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 0] = \
+  0.5 - \
+  0.5 * (pos[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 1] + d - 0.75) / d
+v[pos[:, 1] >= 0.75 + d, 0] = -0.5
+
+v[:, 1] = B * np.sin(4. * np.pi * pos[:, 0]) * \
+          (np.exp(-(pos[:, 1] - 0.25)**2 / 32. / d**2) + \
+           np.exp(-(pos[:, 1] - 0.75)**2 / 32. / d**2))
+            
+#File
+fileOutput = h5py.File(fileOutputName, 'w')
+
+# Header
+grp = fileOutput.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 1., 1.]
+grp.attrs["NumPart_Total"] =  [N, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_ThisFile"] = [N, 0, 0, 0, 0, 0]
+grp.attrs["Time"] = 0.0
+grp.attrs["NumFileOutputsPerSnapshot"] = 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"] = 2
+
+#Runtime parameters
+grp = fileOutput.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = fileOutput.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = fileOutput.create_group("/PartType0")
+grp.create_dataset("Coordinates", data = pos, dtype = 'd')
+grp.create_dataset("Velocities", data = v, dtype = 'f')
+grp.create_dataset("Masses", data = m, dtype = 'f')
+grp.create_dataset("SmoothingLength", data = h, dtype = 'f')
+grp.create_dataset("InternalEnergy", data = u, dtype = 'f')
+grp.create_dataset("ParticleIDs", data = ids, dtype = 'L')
+
+fileOutput.close()
diff --git a/examples/KelvinHelmholtzGrowthRate_2D/plotSolution.py b/examples/KelvinHelmholtzGrowthRate_2D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..b2e3e1766a2b7d2618611aca9fb938ab87d78872
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_2D/plotSolution.py
@@ -0,0 +1,47 @@
+###############################################################################
+# 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/>.
+#
+################################################################################
+
+import numpy as np
+import h5py
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import sys
+
+if len(sys.argv) < 2:
+  print "No final snapshot number provided!"
+  exit()
+lastsnap = int(sys.argv[1])
+
+# Read the simulation data
+t = np.zeros(lastsnap + 1)
+ey = np.zeros(lastsnap + 1)
+for i in range(lastsnap + 1):
+  file = h5py.File("kelvinHelmholtzGrowthRate_{0:04d}.hdf5".format(i), 'r')
+  t_snap = float(file["/Header"].attrs["Time"])
+  vy = file["/PartType0/Velocities"][:,1]
+  m = file["/PartType0/Masses"][:]
+
+  ey_snap = 0.5 * m * vy**2
+
+  t[i] = t_snap
+  ey[i] = ey_snap.sum()
+
+pl.semilogy(t, ey, "k.")
+pl.savefig("kelvinHelmholtzGrowthRate.png")
diff --git a/examples/KelvinHelmholtzGrowthRate_2D/run.sh b/examples/KelvinHelmholtzGrowthRate_2D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3e6e026f66b14846a5c6e8e9daf99797dc3ff87a
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_2D/run.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+ # Generate the initial conditions if they are not present.
+if [ ! -e kelvinHelmholtzGrowthRate.hdf5 ]
+then
+    echo "Generating initial conditions for the Kelvin-Helmholtz growth rate " \
+         "example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 1 kelvinHelmholtzGrowthRate.yml 2>&1 | tee output.log
+
+# Plot the solution
+python plotSolution.py 100
diff --git a/examples/KelvinHelmholtzGrowthRate_3D/getGlass.sh b/examples/KelvinHelmholtzGrowthRate_3D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d5c5f590ac37c9c9431d626a2ea61b0c12c1513c
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_3D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_64.hdf5
diff --git a/examples/KelvinHelmholtzGrowthRate_3D/kelvinHelmholtzGrowthRate.yml b/examples/KelvinHelmholtzGrowthRate_3D/kelvinHelmholtzGrowthRate.yml
new file mode 100644
index 0000000000000000000000000000000000000000..380dc2ab3a530e89b952aa41f425e50709d73ee9
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_3D/kelvinHelmholtzGrowthRate.yml
@@ -0,0 +1,33 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   4.   # The end time of the simulation (in internal units).
+  dt_min:     1e-6  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            kelvinHelmholtzGrowthRate  # Common part of the name of output files
+  time_first:          0.               # Time of the first output (in internal units)
+  delta_time:          0.04      # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+  
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./kelvinHelmholtzGrowthRate.hdf5     # The file to read
diff --git a/examples/KelvinHelmholtzGrowthRate_3D/makeIC.py b/examples/KelvinHelmholtzGrowthRate_3D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9bc20559b9fbb5da400ba5de2563cd715f473d5
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_3D/makeIC.py
@@ -0,0 +1,100 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               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/>.
+#
+################################################################################
+
+import h5py
+import numpy as np
+
+# Generates a swift IC file for the Kelvin-Helmholtz vortex in a periodic box
+
+# Parameters
+gamma = 5./3.     # Gas adiabatic index
+P0    = 2.5       # Pressure
+rho0  = 1.        # Density
+d     = 0.0317    # Thickness of the transition layer
+B     = 0.0005    # Amplitude of the seed velocity
+
+fileOutputName = "kelvinHelmholtzGrowthRate.hdf5"
+
+#---------------------------------------------------
+
+glass = h5py.File("glassCube_64.hdf5", 'r')
+pos = glass["/PartType0/Coordinates"][:, :]
+h = glass["/PartType0/SmoothingLength"][:]
+
+N = len(h)
+vol = 1.
+
+# Generate extra arrays
+v = np.zeros((N, 3))
+ids = np.linspace(1, N, N)
+m = np.ones(N) * rho0 * vol / N
+u = np.ones(N) * P0 / (rho0 * (gamma - 1.))
+
+v[pos[:, 1] <= 0.25 - d, 0] = -0.5
+v[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 0] = \
+  -0.5 + \
+  0.5 * (pos[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 1] + d - 0.25) / d
+v[(pos[:, 1] <= 0.75 - d) & (pos[:, 1] >= 0.25 + d), 0] = 0.5
+v[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 0] = \
+  0.5 - \
+  0.5 * (pos[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 1] + d - 0.75) / d
+v[pos[:, 1] >= 0.75 + d, 0] = -0.5
+
+v[:, 1] = B * np.sin(4. * np.pi * pos[:, 0]) * \
+          (np.exp(-(pos[:, 1] - 0.25)**2 / 32. / d**2) + \
+           np.exp(-(pos[:, 1] - 0.75)**2 / 32. / d**2))
+            
+#File
+fileOutput = h5py.File(fileOutputName, 'w')
+
+# Header
+grp = fileOutput.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 1., 1.]
+grp.attrs["NumPart_Total"] =  [N, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_ThisFile"] = [N, 0, 0, 0, 0, 0]
+grp.attrs["Time"] = 0.0
+grp.attrs["NumFileOutputsPerSnapshot"] = 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"] = 3
+
+#Runtime parameters
+grp = fileOutput.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = fileOutput.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = fileOutput.create_group("/PartType0")
+grp.create_dataset("Coordinates", data = pos, dtype = 'd')
+grp.create_dataset("Velocities", data = v, dtype = 'f')
+grp.create_dataset("Masses", data = m, dtype = 'f')
+grp.create_dataset("SmoothingLength", data = h, dtype = 'f')
+grp.create_dataset("InternalEnergy", data = u, dtype = 'f')
+grp.create_dataset("ParticleIDs", data = ids, dtype = 'L')
+
+fileOutput.close()
diff --git a/examples/KelvinHelmholtzGrowthRate_3D/makeIC_regular.py b/examples/KelvinHelmholtzGrowthRate_3D/makeIC_regular.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa7dd8f214f8ece1c1d142bf02bd653cd35f9973
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_3D/makeIC_regular.py
@@ -0,0 +1,108 @@
+################################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               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/>.
+#
+################################################################################
+
+import h5py
+import numpy as np
+
+# Generates a swift IC file for the Kelvin-Helmholtz vortex in a periodic box
+
+# Parameters
+gamma = 5./3.     # Gas adiabatic index
+P0    = 2.5       # Pressure
+rho0  = 1.        # Density
+d     = 0.0317    # Thickness of the transition layer
+B     = 0.0005    # Amplitude of the seed velocity
+N1D   = 64        # Number of particles in one dimension
+
+fileOutputName = "kelvinHelmholtzGrowthRate.hdf5"
+
+#---------------------------------------------------
+
+N = N1D ** 3
+x = np.linspace(0., 1., N1D + 1)
+x = 0.5 * (x[1:] + x[:-1])
+y = x
+z = x
+xx, yy, zz = np.meshgrid(x, y, z)
+pos = np.zeros((N, 3))
+pos[:, 0] = xx.reshape((N))
+pos[:, 1] = yy.reshape((N))
+pos[:, 2] = zz.reshape((N))
+h = np.ones(N) * 2. / N1D
+
+vol = 1.
+
+# Generate extra arrays
+v = np.zeros((N, 3))
+ids = np.linspace(1, N, N)
+m = np.ones(N) * rho0 * vol / N
+u = np.ones(N) * P0 / (rho0 * (gamma - 1.))
+
+v[pos[:, 1] <= 0.25 - d, 0] = -0.5
+v[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 0] = \
+  -0.5 + \
+  0.5 * (pos[(pos[:, 1] < 0.25 + d) & (pos[:, 1] > 0.25 - d), 1] + d - 0.25) / d
+v[(pos[:, 1] <= 0.75 - d) & (pos[:, 1] >= 0.25 + d), 0] = 0.5
+v[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 0] = \
+  0.5 - \
+  0.5 * (pos[(pos[:, 1] < 0.75 + d) & (pos[:, 1] > 0.75 - d), 1] + d - 0.75) / d
+v[pos[:, 1] >= 0.75 + d, 0] = -0.5
+
+v[:, 1] = B * np.sin(4. * np.pi * pos[:, 0]) * \
+          (np.exp(-(pos[:, 1] - 0.25)**2 / 32. / d**2) + \
+           np.exp(-(pos[:, 1] - 0.75)**2 / 32. / d**2))
+            
+#File
+fileOutput = h5py.File(fileOutputName, 'w')
+
+# Header
+grp = fileOutput.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 1., 1.]
+grp.attrs["NumPart_Total"] =  [N, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_ThisFile"] = [N, 0, 0, 0, 0, 0]
+grp.attrs["Time"] = 0.0
+grp.attrs["NumFileOutputsPerSnapshot"] = 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"] = 3
+
+#Runtime parameters
+grp = fileOutput.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = fileOutput.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = fileOutput.create_group("/PartType0")
+grp.create_dataset("Coordinates", data = pos, dtype = 'd')
+grp.create_dataset("Velocities", data = v, dtype = 'f')
+grp.create_dataset("Masses", data = m, dtype = 'f')
+grp.create_dataset("SmoothingLength", data = h, dtype = 'f')
+grp.create_dataset("InternalEnergy", data = u, dtype = 'f')
+grp.create_dataset("ParticleIDs", data = ids, dtype = 'L')
+
+fileOutput.close()
diff --git a/examples/KelvinHelmholtzGrowthRate_3D/plotSolution.py b/examples/KelvinHelmholtzGrowthRate_3D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..b2e3e1766a2b7d2618611aca9fb938ab87d78872
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_3D/plotSolution.py
@@ -0,0 +1,47 @@
+###############################################################################
+# 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/>.
+#
+################################################################################
+
+import numpy as np
+import h5py
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import sys
+
+if len(sys.argv) < 2:
+  print "No final snapshot number provided!"
+  exit()
+lastsnap = int(sys.argv[1])
+
+# Read the simulation data
+t = np.zeros(lastsnap + 1)
+ey = np.zeros(lastsnap + 1)
+for i in range(lastsnap + 1):
+  file = h5py.File("kelvinHelmholtzGrowthRate_{0:04d}.hdf5".format(i), 'r')
+  t_snap = float(file["/Header"].attrs["Time"])
+  vy = file["/PartType0/Velocities"][:,1]
+  m = file["/PartType0/Masses"][:]
+
+  ey_snap = 0.5 * m * vy**2
+
+  t[i] = t_snap
+  ey[i] = ey_snap.sum()
+
+pl.semilogy(t, ey, "k.")
+pl.savefig("kelvinHelmholtzGrowthRate.png")
diff --git a/examples/KelvinHelmholtzGrowthRate_3D/run.sh b/examples/KelvinHelmholtzGrowthRate_3D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3e6e026f66b14846a5c6e8e9daf99797dc3ff87a
--- /dev/null
+++ b/examples/KelvinHelmholtzGrowthRate_3D/run.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+ # Generate the initial conditions if they are not present.
+if [ ! -e kelvinHelmholtzGrowthRate.hdf5 ]
+then
+    echo "Generating initial conditions for the Kelvin-Helmholtz growth rate " \
+         "example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 1 kelvinHelmholtzGrowthRate.yml 2>&1 | tee output.log
+
+# Plot the solution
+python plotSolution.py 100
diff --git a/examples/SmoothedMetallicity/getGlass.sh b/examples/SmoothedMetallicity/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ffd92e88deae6e91237059adac2a6c2067caee46
--- /dev/null
+++ b/examples/SmoothedMetallicity/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_32.hdf5
diff --git a/examples/SmoothedMetallicity/makeIC.py b/examples/SmoothedMetallicity/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..86679d5efe897b9dfae7db94b36d74bb047661e6
--- /dev/null
+++ b/examples/SmoothedMetallicity/makeIC.py
@@ -0,0 +1,110 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 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/>.
+# 
+##############################################################################
+
+import h5py
+import numpy as np
+
+# Generates a swift IC file for the Smoothed Metallicity test in a periodic cubic box
+
+# Parameters
+gamma = 5./3.      # Gas adiabatic index
+rho0 = 1.          # Background density
+P0 = 1.e-6         # Background pressure
+Nelem = 9          # Gear: 9, EAGLE: 9
+low_metal = -6     # Low iron fraction
+high_metal = -5    # high iron fraction
+sigma_metal = 0.1  # relative standard deviation for the metallicities
+fileName = "smoothed_metallicity.hdf5"
+
+# shift all metals in order to obtain nicer plots
+low_metal = [low_metal] * Nelem + np.linspace(0, 3, Nelem)
+high_metal = [high_metal] * Nelem + np.linspace(0, 3, Nelem)
+
+# ---------------------------------------------------
+glass = h5py.File("glassCube_32.hdf5", "r")
+
+# Read particle positions and h from the glass
+pos = glass["/PartType0/Coordinates"][:, :]
+h = glass["/PartType0/SmoothingLength"][:]
+
+numPart = np.size(h)
+vol = 1.
+
+# Generate extra arrays
+v = np.zeros((numPart, 3))
+ids = np.linspace(1, numPart, numPart)
+m = np.zeros(numPart)
+u = np.zeros(numPart)
+r = np.zeros(numPart)
+Z = np.zeros((numPart, Nelem))
+
+r = np.sqrt((pos[:, 0] - 0.5)**2 + (pos[:, 1] - 0.5)**2 + (pos[:, 2] - 0.5)**2)
+m[:] = rho0 * vol / numPart
+u[:] = P0 / (rho0 * (gamma - 1))
+
+# set metallicities
+select = pos[:, 0] < 0.5
+nber = sum(select)
+Z[select, :] = low_metal * (1 + np.random.normal(loc=0., scale=sigma_metal,
+                                                 size=(nber, Nelem)))
+nber = numPart - nber
+Z[np.logical_not(select), :] = high_metal * (1 + np.random.normal(
+    loc=0., scale=sigma_metal, size=(nber, Nelem)))
+
+# --------------------------------------------------
+
+# File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 3
+
+# Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+# Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+# Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+grp.create_dataset('ElementAbundance', data=Z, dtype='f')
+
+
+file.close()
diff --git a/examples/SmoothedMetallicity/plotSolution.py b/examples/SmoothedMetallicity/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..e5bca3dfb7fe1e43c836733894c9e297cdd468ca
--- /dev/null
+++ b/examples/SmoothedMetallicity/plotSolution.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2015 Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
+#                    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/>.
+# 
+##############################################################################
+
+# Computes the analytical solution of the 3D Smoothed Metallicity example.
+
+import h5py
+import sys
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+
+# Parameters
+low_metal = -6     # low metal abundance
+high_metal = -5    # High metal abundance
+sigma_metal = 0.1  # relative standard deviation for Z
+
+Nelem = 9
+# shift all metals in order to obtain nicer plots
+low_metal = [low_metal] * Nelem + np.linspace(0, 3, Nelem)
+high_metal = [high_metal] * Nelem + np.linspace(0, 3, Nelem)
+
+# ---------------------------------------------------------------
+# Don't touch anything after this.
+# ---------------------------------------------------------------
+
+# Plot parameters
+params = {
+    'axes.labelsize': 10,
+    'axes.titlesize': 10,
+    'font.size': 12,
+    'legend.fontsize': 12,
+    'xtick.labelsize': 10,
+    'ytick.labelsize': 10,
+    'text.usetex': True,
+    'figure.figsize': (9.90, 6.45),
+    'figure.subplot.left': 0.045,
+    'figure.subplot.right': 0.99,
+    'figure.subplot.bottom': 0.05,
+    'figure.subplot.top': 0.99,
+    'figure.subplot.wspace': 0.15,
+    'figure.subplot.hspace': 0.12,
+    'lines.markersize': 6,
+    'lines.linewidth': 3.,
+    'text.latex.unicode': True
+}
+
+plt.rcParams.update(params)
+plt.rc('font', **{'family': 'sans-serif', 'sans-serif': ['Times']})
+
+
+snap = int(sys.argv[1])
+
+
+# Read the simulation data
+sim = h5py.File("smoothed_metallicity_%04d.hdf5" % snap, "r")
+boxSize = sim["/Header"].attrs["BoxSize"][0]
+time = sim["/Header"].attrs["Time"][0]
+scheme = sim["/HydroScheme"].attrs["Scheme"]
+kernel = sim["/HydroScheme"].attrs["Kernel function"]
+neighbours = sim["/HydroScheme"].attrs["Kernel target N_ngb"]
+eta = sim["/HydroScheme"].attrs["Kernel eta"]
+chemistry = sim["/SubgridScheme"].attrs["Chemistry Model"]
+git = sim["Code"].attrs["Git Revision"]
+
+pos = sim["/PartType0/Coordinates"][:, :]
+d = pos[:, 0] - boxSize / 2
+smooth_metal = sim["/PartType0/SmoothedElementAbundance"][:, :]
+metal = sim["/PartType0/ElementAbundance"][:, :]
+h = sim["/PartType0/SmoothingLength"][:]
+h = np.mean(h)
+
+if (Nelem != metal.shape[1]):
+    print("Unexpected number of element, please check makeIC.py"
+          " and plotSolution.py")
+    exit(1)
+
+N = 1000
+d_a = np.linspace(-boxSize / 2., boxSize / 2., N)
+
+# Now, work our the solution....
+
+
+def calc_a(d, high_metal, low_metal, std_dev, h):
+    """
+    Compute analytical solution:
+                        ___ High Metallicity
+    Low Metallicity ___/
+
+    where the linear part length is given by the smoothing length.
+
+    Parameters
+    ----------
+
+    d: np.array
+        Position to compute
+    high_metal: float
+        Value on the high metallicity side
+
+    low_metal: float
+        Value on the low metallicity side
+
+    std_dev: float
+        Standard deviation of the noise added
+
+    h: float
+        Mean smoothing length
+    """
+
+    # solution
+    a = np.zeros([len(d), Nelem])
+    # function at +- 1 sigma
+    sigma = np.zeros([len(d), Nelem, 2])
+
+    for i in range(Nelem):
+        # compute low metallicity side
+        s = d < -h
+        a[s, i] = low_metal[i]
+        # compute high metallicity side
+        s = d > h
+        a[s, i] = high_metal[i]
+
+        # compute non constant parts
+        m = (high_metal[i] - low_metal[i]) / (2.0 * h)
+        c = (high_metal[i] + low_metal[i]) / 2.0
+        # compute left linear part
+        s = d < - boxSize / 2.0 + h
+        a[s, i] = - m * (d[s] + boxSize / 2.0) + c
+        # compute middle linear part
+        s = np.logical_and(d >= -h, d <= h)
+        a[s, i] = m * d[s] + c
+        # compute right linear part
+        s = d > boxSize / 2.0 - h
+        a[s, i] = - m * (d[s] - boxSize / 2.0) + c
+
+    sigma[:, :, 0] = a * (1 + std_dev)
+    sigma[:, :, 1] = a * (1 - std_dev)
+    return a, sigma
+
+
+# compute solution
+sol, sig = calc_a(d_a, high_metal, low_metal, sigma_metal, h)
+
+# Plot the interesting quantities
+plt.figure()
+
+# Metallicity --------------------------------
+plt.subplot(221)
+for e in range(Nelem):
+    plt.plot(metal[:, e], smooth_metal[:, e], '.', ms=0.5, alpha=0.2)
+
+xmin, xmax = metal.min(), metal.max()
+ymin, ymax = smooth_metal.min(), smooth_metal.max()
+x = max(xmin, ymin)
+y = min(xmax, ymax)
+plt.plot([x, y], [x, y], "--k", lw=1.0)
+plt.xlabel("${\\rm{Metallicity}}~Z_\\textrm{part}$", labelpad=0)
+plt.ylabel("${\\rm{Smoothed~Metallicity}}~Z_\\textrm{sm}$", labelpad=0)
+
+# Metallicity --------------------------------
+e = 0
+plt.subplot(223)
+plt.plot(d, smooth_metal[:, e], '.', color='r', ms=0.5, alpha=0.2)
+plt.plot(d_a, sol[:, e], '--', color='b', alpha=0.8, lw=1.2)
+plt.fill_between(d_a, sig[:, e, 0], sig[:, e, 1], facecolor="b",
+                 interpolate=True, alpha=0.5)
+plt.xlabel("${\\rm{Distance}}~r$", labelpad=0)
+plt.ylabel("${\\rm{Smoothed~Metallicity}}~Z_\\textrm{sm}$", labelpad=0)
+plt.xlim(-0.5, 0.5)
+plt.ylim(low_metal[e]-1, high_metal[e]+1)
+
+# Information -------------------------------------
+plt.subplot(222, frameon=False)
+
+plt.text(-0.49, 0.9, "Smoothed Metallicity in 3D at $t=%.2f$" % time,
+         fontsize=10)
+plt.plot([-0.49, 0.1], [0.82, 0.82], 'k-', lw=1)
+plt.text(-0.49, 0.7, "$\\textsc{Swift}$ %s" % git, fontsize=10)
+plt.text(-0.49, 0.6, scheme, fontsize=10)
+plt.text(-0.49, 0.5, kernel, fontsize=10)
+plt.text(-0.49, 0.4, chemistry + "'s Chemistry", fontsize=10)
+plt.text(-0.49, 0.3, "$%.2f$ neighbours ($\\eta=%.3f$)" % (neighbours, eta),
+         fontsize=10)
+plt.xlim(-0.5, 0.5)
+plt.ylim(0, 1)
+plt.xticks([])
+plt.yticks([])
+
+plt.tight_layout()
+plt.savefig("SmoothedMetallicity.png", dpi=200)
diff --git a/examples/SmoothedMetallicity/run.sh b/examples/SmoothedMetallicity/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..de8c55d678bcb611934af450940d8ed8e6c15d6b
--- /dev/null
+++ b/examples/SmoothedMetallicity/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+ # Generate the initial conditions if they are not present.
+if [ ! -e glassCube_32.hdf5 ]
+then
+    echo "Fetching initial glass file for the SmoothedMetallicity example..."
+    ./getGlass.sh
+fi
+if [ ! -e smoothed_metallicity.hdf5 ]
+then
+    echo "Generating initial conditions for the SmoothedMetallicity example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -n 1 -s -t 4 smoothed_metallicity.yml 2>&1 | tee output.log
+
+# Plot the solution
+python plotSolution.py 1
diff --git a/examples/SmoothedMetallicity/smoothed_metallicity.yml b/examples/SmoothedMetallicity/smoothed_metallicity.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2e37695392b12c545bbbdbe7fd94748d5b3b9ff8
--- /dev/null
+++ b/examples/SmoothedMetallicity/smoothed_metallicity.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   2e-4  # The end time of the simulation (in internal units).
+  dt_min:     1e-7  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-4  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            smoothed_metallicity # Common part of the name of output files
+  time_first:          0.    # Time of the first output (in internal units)
+  delta_time:          5e-5  # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-5 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./smoothed_metallicity.hdf5          # The file to read
+
diff --git a/examples/SodShockSpherical_2D/getGlass.sh b/examples/SodShockSpherical_2D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f4cb4ebcb4b452b2b123462bc97eed532f43ba25
--- /dev/null
+++ b/examples/SodShockSpherical_2D/getGlass.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassPlane_128.hdf5
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassPlane_48.hdf5
diff --git a/examples/SodShockSpherical_2D/getReference.sh b/examples/SodShockSpherical_2D/getReference.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8b152badc65ece3b519fa660001acc792ee3f3dc
--- /dev/null
+++ b/examples/SodShockSpherical_2D/getReference.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ReferenceSolutions/sodShockSpherical2D_exact.txt
diff --git a/examples/SodShockSpherical_2D/makeIC.py b/examples/SodShockSpherical_2D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..ac9f6e193769d7466f5b8e41a408da2350777be6
--- /dev/null
+++ b/examples/SodShockSpherical_2D/makeIC.py
@@ -0,0 +1,125 @@
+###############################################################################
+ # This file is part of SWIFT.
+ # Copyright (c) 2016 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/>.
+ # 
+ ##############################################################################
+
+import h5py
+from numpy import *
+
+# Generates a swift IC file for the 2D Sod Shock in a periodic box
+
+# Parameters
+gamma = 5./3.          # Gas adiabatic index
+x_min = -1.
+x_max = 1.
+rho_L = 1.             # Density left state
+rho_R = 0.140625       # Density right state
+v_L = 0.               # Velocity left state
+v_R = 0.               # Velocity right state
+P_L = 1.               # Pressure left state
+P_R = 0.1              # Pressure right state
+fileName = "sodShock.hdf5"
+
+
+#---------------------------------------------------
+boxSize = (x_max - x_min)
+
+glass_L = h5py.File("glassPlane_128.hdf5", "r")
+glass_R = h5py.File("glassPlane_48.hdf5", "r")
+
+pos_L = glass_L["/PartType0/Coordinates"][:,:]
+pos_R = glass_R["/PartType0/Coordinates"][:,:]
+h_L = glass_L["/PartType0/SmoothingLength"][:]
+h_R = glass_R["/PartType0/SmoothingLength"][:]
+
+radius_L = sqrt((pos_L[:,0] - 0.5)**2 + (pos_L[:,1] - 0.5)**2)
+index_L = radius_L < 0.25
+pos_LL = pos_L[index_L]
+h_LL = h_L[index_L]
+
+radius_R = sqrt((pos_R[:,0] - 0.5)**2 + (pos_R[:,1] - 0.5)**2)
+index_R = radius_R > 0.25
+pos_RR = pos_R[index_R]
+h_RR = h_R[index_R]
+
+# Merge things
+pos = append(pos_LL, pos_RR, axis=0)
+h = append(h_LL, h_RR)
+
+numPart_L = size(h_LL)
+numPart_R = size(h_RR)
+numPart = size(h)
+
+vol_L = pi * 0.25**2
+vol_R = 1. - pi * 0.25**2
+
+# Generate extra arrays
+v = zeros((numPart, 3))
+ids = linspace(1, numPart, numPart)
+m = zeros(numPart)
+u = zeros(numPart)
+
+for i in range(numPart):
+    x = sqrt((pos[i,0]-0.5)**2+(pos[i,1]-0.5)**2)
+
+    if x < 0.25: #left
+        u[i] = P_L / (rho_L * (gamma - 1.))
+        m[i] = rho_L * vol_L / numPart_L
+        v[i,0] = v_L
+    else:     #right
+        u[i] = P_R / (rho_R * (gamma - 1.))
+        m[i] = rho_R * vol_R / numPart_R
+        v[i,0] = v_R
+        
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 2
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+
+file.close()
diff --git a/examples/SodShockSpherical_2D/plotSolution.py b/examples/SodShockSpherical_2D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..57b7f7ddc64bc25df031eb0cba7547f40d46b31a
--- /dev/null
+++ b/examples/SodShockSpherical_2D/plotSolution.py
@@ -0,0 +1,163 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               2018 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/>.
+# 
+################################################################################
+
+# Compares the swift result for the 2D spherical Sod shock with a high
+# resolution 2D reference result
+
+import matplotlib
+matplotlib.use("Agg")
+from pylab import *
+from scipy import stats
+import h5py
+
+# Parameters
+gas_gamma = 5./3.      # Polytropic index
+rho_L = 1.             # Density left state
+rho_R = 0.140625       # Density right state
+v_L = 0.               # Velocity left state
+v_R = 0.               # Velocity right state
+P_L = 1.               # Pressure left state
+P_R = 0.1              # Pressure right state
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+rcParams.update(params)
+rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+snap = int(sys.argv[1])
+
+# Read the simulation data
+sim = h5py.File("sodShock_%04d.hdf5"%snap, "r")
+boxSize = sim["/Header"].attrs["BoxSize"][0]
+time = sim["/Header"].attrs["Time"][0]
+scheme = sim["/HydroScheme"].attrs["Scheme"]
+kernel = sim["/HydroScheme"].attrs["Kernel function"]
+neighbours = sim["/HydroScheme"].attrs["Kernel target N_ngb"]
+eta = sim["/HydroScheme"].attrs["Kernel eta"]
+git = sim["Code"].attrs["Git Revision"]
+
+coords = sim["/PartType0/Coordinates"]
+x = sqrt((coords[:,0] - 0.5)**2 + (coords[:,1] - 0.5)**2)
+vels = sim["/PartType0/Velocities"]
+v = sqrt(vels[:,0]**2 + vels[:,1]**2)
+u = sim["/PartType0/InternalEnergy"][:]
+S = sim["/PartType0/Entropy"][:]
+P = sim["/PartType0/Pressure"][:]
+rho = sim["/PartType0/Density"][:]
+
+# Bin the data
+rho_bin,x_bin_edge,_ = \
+  stats.binned_statistic(x, rho, statistic='mean', bins=100)
+x_bin = 0.5*(x_bin_edge[1:] + x_bin_edge[:-1])
+v_bin,_,_ = stats.binned_statistic(x, v, statistic='mean', bins=x_bin_edge)
+P_bin,_,_ = stats.binned_statistic(x, P, statistic='mean', bins=x_bin_edge)
+S_bin,_,_ = stats.binned_statistic(x, S, statistic='mean', bins=x_bin_edge)
+u_bin,_,_ = stats.binned_statistic(x, u, statistic='mean', bins=x_bin_edge)
+rho2_bin,_,_ = stats.binned_statistic(x, rho**2, statistic='mean', bins=x_bin_edge)
+v2_bin,_,_ = stats.binned_statistic(x, v**2, statistic='mean', bins=x_bin_edge)
+P2_bin,_,_ = stats.binned_statistic(x, P**2, statistic='mean', bins=x_bin_edge)
+S2_bin,_,_ = stats.binned_statistic(x, S**2, statistic='mean', bins=x_bin_edge)
+u2_bin,_,_ = stats.binned_statistic(x, u**2, statistic='mean', bins=x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+ref = loadtxt("sodShockSpherical2D_exact.txt")
+
+# Plot the interesting quantities
+figure()
+
+# Velocity profile --------------------------------
+subplot(231)
+plot(x, v, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,2], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, v_bin, yerr=v_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Velocity}}~v_r$", labelpad=0)
+
+# Density profile --------------------------------
+subplot(232)
+plot(x, rho, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,1], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, rho_bin, yerr=rho_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Density}}~\\rho$", labelpad=0)
+
+# Pressure profile --------------------------------
+subplot(233)
+plot(x, P, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,3], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, P_bin, yerr=P_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Pressure}}~P$", labelpad=0)
+
+# Internal energy profile -------------------------
+subplot(234)
+plot(x, u, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,3] / ref[:,1] / (gas_gamma - 1.), "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, u_bin, yerr=u_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Internal~Energy}}~u$", labelpad=0)
+
+# Entropy profile ---------------------------------
+subplot(235)
+plot(x, S, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,3] / ref[:,1]**gas_gamma, "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Entropy}}~S$", labelpad=0)
+
+# Information -------------------------------------
+subplot(236, frameon=False)
+
+text(-0.49, 0.9, "Sod shock with  $\\gamma=%.3f$ in 2D at $t=%.2f$"%(gas_gamma,time), fontsize=10)
+text(-0.49, 0.8, "Left:~~ $(P_L, \\rho_L, v_L) = (%.3f, %.3f, %.3f)$"%(P_L, rho_L, v_L), fontsize=10)
+text(-0.49, 0.7, "Right: $(P_R, \\rho_R, v_R) = (%.3f, %.3f, %.3f)$"%(P_R, rho_R, v_R), fontsize=10)
+plot([-0.49, 0.1], [0.62, 0.62], 'k-', lw=1)
+text(-0.49, 0.5, "$\\textsc{Swift}$ %s"%git, fontsize=10)
+text(-0.49, 0.4, scheme, fontsize=10)
+text(-0.49, 0.3, kernel, fontsize=10)
+text(-0.49, 0.2, "$%.2f$ neighbours ($\\eta=%.3f$)"%(neighbours, eta), fontsize=10)
+xlim(-0.5, 0.5)
+ylim(0, 1)
+xticks([])
+yticks([])
+
+
+savefig("SodShock.png", dpi=200)
diff --git a/examples/SodShockSpherical_2D/run.sh b/examples/SodShockSpherical_2D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d662d20f40ef9e221285d5820e867607804e9dbe
--- /dev/null
+++ b/examples/SodShockSpherical_2D/run.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassPlane_128.hdf5 ]
+then
+    echo "Fetching initial glass file for the Sod shock example..."
+    ./getGlass.sh
+fi
+if [ ! -e sodShock.hdf5 ]
+then
+    echo "Generating initial conditions for the Sod shock example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 1 sodShock.yml 2>&1 | tee output.log
+
+# Get the high resolution 1D reference solution if not present.
+if [ ! -e sodShockSpherical2D_exact.txt ]
+then
+    echo "Fetching reference solution for 2D spherical Sod shock example..."
+    ./getReference.sh
+fi
+python plotSolution.py 1
diff --git a/examples/SodShockSpherical_2D/sodShock.yml b/examples/SodShockSpherical_2D/sodShock.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a26ab95b21c782ce83310038432ac08df0e024c3
--- /dev/null
+++ b/examples/SodShockSpherical_2D/sodShock.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.1   # The end time of the simulation (in internal units).
+  dt_min:     1e-7  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            sodShock # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.1      # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./sodShock.hdf5       # The file to read
+
diff --git a/examples/SodShockSpherical_3D/getGlass.sh b/examples/SodShockSpherical_3D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f61b61d4e6c51b44576fd7cdd6242cb9f0133039
--- /dev/null
+++ b/examples/SodShockSpherical_3D/getGlass.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_64.hdf5
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_32.hdf5
diff --git a/examples/SodShockSpherical_3D/getReference.sh b/examples/SodShockSpherical_3D/getReference.sh
new file mode 100755
index 0000000000000000000000000000000000000000..133d2fb8da9cbbfdc796140afc84a0859b9ca61e
--- /dev/null
+++ b/examples/SodShockSpherical_3D/getReference.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ReferenceSolutions/sodShockSpherical3D_exact.txt
diff --git a/examples/SodShockSpherical_3D/makeIC.py b/examples/SodShockSpherical_3D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..be8f9b61a1beef00f49786860ce94287b30e2ab3
--- /dev/null
+++ b/examples/SodShockSpherical_3D/makeIC.py
@@ -0,0 +1,127 @@
+###############################################################################
+ # This file is part of SWIFT.
+ # Copyright (c) 2016 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/>.
+ # 
+ ##############################################################################
+
+import h5py
+from numpy import *
+
+# Generates a swift IC file for the 3D Sod Shock in a periodic box
+
+# Parameters
+gamma = 5./3.          # Gas adiabatic index
+x_min = -1.
+x_max = 1.
+rho_L = 1.             # Density left state
+rho_R = 0.125          # Density right state
+v_L = 0.               # Velocity left state
+v_R = 0.               # Velocity right state
+P_L = 1.               # Pressure left state
+P_R = 0.1              # Pressure right state
+fileName = "sodShock.hdf5" 
+
+
+#---------------------------------------------------
+boxSize = (x_max - x_min)
+
+glass_L = h5py.File("glassCube_64.hdf5", "r")
+glass_R = h5py.File("glassCube_32.hdf5", "r")
+
+pos_L = glass_L["/PartType0/Coordinates"][:,:]
+pos_R = glass_R["/PartType0/Coordinates"][:,:]
+h_L = glass_L["/PartType0/SmoothingLength"][:]
+h_R = glass_R["/PartType0/SmoothingLength"][:]
+
+radius_L = sqrt((pos_L[:,0] - 0.5)**2 + (pos_L[:,1] - 0.5)**2 + \
+                (pos_L[:,2] - 0.5)**2)
+index_L = radius_L < 0.25
+pos_LL = pos_L[index_L]
+h_LL = h_L[index_L]
+
+radius_R = sqrt((pos_R[:,0] - 0.5)**2 + (pos_R[:,1] - 0.5)**2 + \
+                (pos_R[:,2] - 0.5)**2)
+index_R = radius_R > 0.25
+pos_RR = pos_R[index_R]
+h_RR = h_R[index_R]
+
+# Merge things
+pos = append(pos_LL, pos_RR, axis=0)
+h = append(h_LL, h_RR)
+
+numPart_L = size(h_LL)
+numPart_R = size(h_RR)
+numPart = size(h)
+
+vol_L = 4. * pi / 3. * 0.25**3
+vol_R = 1. - 4. * pi / 3. * 0.25**3
+
+# Generate extra arrays
+v = zeros((numPart, 3))
+ids = linspace(1, numPart, numPart)
+m = zeros(numPart)
+u = zeros(numPart)
+
+for i in range(numPart):
+    x = sqrt((pos[i,0]-0.5)**2+(pos[i,1]-0.5)**2+(pos[i,2]-0.5)**2)
+
+    if x < 0.25: #left
+        u[i] = P_L / (rho_L * (gamma - 1.))
+        m[i] = rho_L * vol_L / numPart_L
+        v[i,0] = v_L
+    else:     #right
+        u[i] = P_R / (rho_R * (gamma - 1.))
+        m[i] = rho_R * vol_R / numPart_R
+        v[i,0] = v_R
+        
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 3
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+
+file.close()
diff --git a/examples/SodShockSpherical_3D/plotSolution.py b/examples/SodShockSpherical_3D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..539bfba799e3231bd26ae2eb39c271baa1fa6a4b
--- /dev/null
+++ b/examples/SodShockSpherical_3D/plotSolution.py
@@ -0,0 +1,164 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+#               2018 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/>.
+# 
+################################################################################
+
+# Compares the swift result for the 2D spherical Sod shock with a high
+# resolution 2D reference result
+
+import matplotlib
+matplotlib.use("Agg")
+from pylab import *
+from scipy import stats
+import h5py
+
+# Parameters
+gas_gamma = 5./3.      # Polytropic index
+rho_L = 1.             # Density left state
+rho_R = 0.125          # Density right state
+v_L = 0.               # Velocity left state
+v_R = 0.               # Velocity right state
+P_L = 1.               # Pressure left state
+P_R = 0.1              # Pressure right state
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+rcParams.update(params)
+rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+snap = int(sys.argv[1])
+
+# Read the simulation data
+sim = h5py.File("sodShock_%04d.hdf5"%snap, "r")
+boxSize = sim["/Header"].attrs["BoxSize"][0]
+time = sim["/Header"].attrs["Time"][0]
+scheme = sim["/HydroScheme"].attrs["Scheme"]
+kernel = sim["/HydroScheme"].attrs["Kernel function"]
+neighbours = sim["/HydroScheme"].attrs["Kernel target N_ngb"]
+eta = sim["/HydroScheme"].attrs["Kernel eta"]
+git = sim["Code"].attrs["Git Revision"]
+
+coords = sim["/PartType0/Coordinates"]
+x = sqrt((coords[:,0] - 0.5)**2 + (coords[:,1] - 0.5)**2 + \
+         (coords[:,2] - 0.5)**2)
+vels = sim["/PartType0/Velocities"]
+v = sqrt(vels[:,0]**2 + vels[:,1]**2 + vels[:,2]**2)
+u = sim["/PartType0/InternalEnergy"][:]
+S = sim["/PartType0/Entropy"][:]
+P = sim["/PartType0/Pressure"][:]
+rho = sim["/PartType0/Density"][:]
+
+# Bin the data
+rho_bin,x_bin_edge,_ = \
+  stats.binned_statistic(x, rho, statistic='mean', bins=100)
+x_bin = 0.5*(x_bin_edge[1:] + x_bin_edge[:-1])
+v_bin,_,_ = stats.binned_statistic(x, v, statistic='mean', bins=x_bin_edge)
+P_bin,_,_ = stats.binned_statistic(x, P, statistic='mean', bins=x_bin_edge)
+S_bin,_,_ = stats.binned_statistic(x, S, statistic='mean', bins=x_bin_edge)
+u_bin,_,_ = stats.binned_statistic(x, u, statistic='mean', bins=x_bin_edge)
+rho2_bin,_,_ = stats.binned_statistic(x, rho**2, statistic='mean', bins=x_bin_edge)
+v2_bin,_,_ = stats.binned_statistic(x, v**2, statistic='mean', bins=x_bin_edge)
+P2_bin,_,_ = stats.binned_statistic(x, P**2, statistic='mean', bins=x_bin_edge)
+S2_bin,_,_ = stats.binned_statistic(x, S**2, statistic='mean', bins=x_bin_edge)
+u2_bin,_,_ = stats.binned_statistic(x, u**2, statistic='mean', bins=x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+ref = loadtxt("sodShockSpherical3D_exact.txt")
+
+# Plot the interesting quantities
+figure()
+
+# Velocity profile --------------------------------
+subplot(231)
+plot(x, v, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,2], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, v_bin, yerr=v_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Velocity}}~v_r$", labelpad=0)
+
+# Density profile --------------------------------
+subplot(232)
+plot(x, rho, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,1], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, rho_bin, yerr=rho_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Density}}~\\rho$", labelpad=0)
+
+# Pressure profile --------------------------------
+subplot(233)
+plot(x, P, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,3], "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, P_bin, yerr=P_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Pressure}}~P$", labelpad=0)
+
+# Internal energy profile -------------------------
+subplot(234)
+plot(x, u, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,3] / ref[:,1] / (gas_gamma - 1.), "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, u_bin, yerr=u_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Internal~Energy}}~u$", labelpad=0)
+
+# Entropy profile ---------------------------------
+subplot(235)
+plot(x, S, '.', color='r', ms=0.2)
+plot(ref[:,0], ref[:,3] / ref[:,1]**gas_gamma, "k--", alpha=0.8, lw=1.2)
+errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2)
+xlabel("${\\rm{Radius}}~r$", labelpad=0)
+ylabel("${\\rm{Entropy}}~S$", labelpad=0)
+
+# Information -------------------------------------
+subplot(236, frameon=False)
+
+text(-0.49, 0.9, "Sod shock with  $\\gamma=%.3f$ in 3D at $t=%.2f$"%(gas_gamma,time), fontsize=10)
+text(-0.49, 0.8, "Left:~~ $(P_L, \\rho_L, v_L) = (%.3f, %.3f, %.3f)$"%(P_L, rho_L, v_L), fontsize=10)
+text(-0.49, 0.7, "Right: $(P_R, \\rho_R, v_R) = (%.3f, %.3f, %.3f)$"%(P_R, rho_R, v_R), fontsize=10)
+plot([-0.49, 0.1], [0.62, 0.62], 'k-', lw=1)
+text(-0.49, 0.5, "$\\textsc{Swift}$ %s"%git, fontsize=10)
+text(-0.49, 0.4, scheme, fontsize=10)
+text(-0.49, 0.3, kernel, fontsize=10)
+text(-0.49, 0.2, "$%.2f$ neighbours ($\\eta=%.3f$)"%(neighbours, eta), fontsize=10)
+xlim(-0.5, 0.5)
+ylim(0, 1)
+xticks([])
+yticks([])
+
+
+savefig("SodShock.png", dpi=200)
diff --git a/examples/SodShockSpherical_3D/run.sh b/examples/SodShockSpherical_3D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..faf979869e175172ce31db6ac5021daf1758f3b0
--- /dev/null
+++ b/examples/SodShockSpherical_3D/run.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassCube_64.hdf5 ]
+then
+    echo "Fetching initial glass file for the Sod shock example..."
+    ./getGlass.sh
+fi
+if [ ! -e sodShock.hdf5 ]
+then
+    echo "Generating initial conditions for the Sod shock example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 4 sodShock.yml 2>&1 | tee output.log
+
+# Get the high resolution 1D reference solution if not present.
+if [ ! -e sodShockSpherical3D_exact.txt ]
+then
+    echo "Fetching reference solution for 3D spherical Sod shock example..."
+    ./getReference.sh
+fi
+python plotSolution.py 1
diff --git a/examples/SodShockSpherical_3D/sodShock.yml b/examples/SodShockSpherical_3D/sodShock.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a26ab95b21c782ce83310038432ac08df0e024c3
--- /dev/null
+++ b/examples/SodShockSpherical_3D/sodShock.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.1   # The end time of the simulation (in internal units).
+  dt_min:     1e-7  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            sodShock # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.1      # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./sodShock.hdf5       # The file to read
+
diff --git a/examples/VacuumSpherical_2D/getGlass.sh b/examples/VacuumSpherical_2D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ae3c977064f5e7a408aa249c5fd9089b3c52ecb1
--- /dev/null
+++ b/examples/VacuumSpherical_2D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassPlane_128.hdf5
diff --git a/examples/VacuumSpherical_2D/getReference.sh b/examples/VacuumSpherical_2D/getReference.sh
new file mode 100755
index 0000000000000000000000000000000000000000..01080400dba430852f0245d42fb5e30f971721a8
--- /dev/null
+++ b/examples/VacuumSpherical_2D/getReference.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ReferenceSolutions/vacuumSpherical2D_exact.txt
diff --git a/examples/VacuumSpherical_2D/makeIC.py b/examples/VacuumSpherical_2D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..498f1b5bc5277188d8ff8d34a5ec24cd314332d4
--- /dev/null
+++ b/examples/VacuumSpherical_2D/makeIC.py
@@ -0,0 +1,101 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import h5py
+
+# Generates an overdensity within a vacuum to test the vacuum resolving
+# capabilities of the code
+
+# Parameters
+gamma = 5. / 3.    # Gas adiabatic index
+
+fileName = "vacuum.hdf5" 
+
+#---------------------------------------------------
+glass = h5py.File("glassPlane_128.hdf5", "r")
+
+# Read particle positions and h from the glass
+pos = glass["/PartType0/Coordinates"][:,:]
+h = glass["/PartType0/SmoothingLength"][:] * 0.3
+
+# Make 4 copies of the glass to have more particles
+pos *= 0.5
+h *= 0.5
+pos = np.append(pos, pos + np.array([0.5, 0., 0.]), axis = 0)
+h = np.append(h, h)
+pos = np.append(pos, pos + np.array([0., 0.5, 0.]), axis = 0)
+h = np.append(h, h)
+
+radius = np.sqrt((pos[:,0] - 0.5)**2 + (pos[:,1] - 0.5)**2)
+index = radius < 0.25
+pos = pos[index]
+h = h[index]
+
+numPart = len(h)
+vol = np.pi * 0.25**2
+
+# Generate extra arrays
+v = np.zeros((numPart, 3))
+ids = np.linspace(1, numPart, numPart)
+m = np.zeros(numPart)
+u = np.zeros(numPart)
+
+m[:] = 1. * vol / numPart
+u[:] = 1. / (1. * (gamma - 1.))
+
+#--------------------------------------------------
+
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 2
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+file.close()
diff --git a/examples/VacuumSpherical_2D/plotSolution.py b/examples/VacuumSpherical_2D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a65206ae20ccf79392054d047ba6be04f169f3e
--- /dev/null
+++ b/examples/VacuumSpherical_2D/plotSolution.py
@@ -0,0 +1,192 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import h5py
+import sys
+import scipy.stats as stats
+
+# Parameters
+gamma = 5. / 3. # Polytropic index
+rhoL = 1.       # Initial density in the non vacuum state
+vL = 0.         # Initial velocity in the non vacuum state
+PL = 1.         # Initial pressure in the non vacuum state
+rhoR = 0.       # Initial vacuum density
+vR = 0.         # Initial vacuum velocity
+PR = 0.         # Initial vacuum pressure
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+pl.rcParams.update(params)
+pl.rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+# Read the snapshot index from the command line argument
+snap = int(sys.argv[1])
+
+# Open the file and read the relevant data
+file = h5py.File("vacuum_{0:04d}.hdf5".format(snap), "r")
+coords = file["/PartType0/Coordinates"]
+x = np.sqrt((coords[:,0] - 0.5)**2 + (coords[:,1] - 0.5)**2)
+rho = file["/PartType0/Density"][:]
+vels = file["/PartType0/Velocities"]
+v = np.sqrt(vels[:,0]**2 + vels[:,1]**2)
+u = file["/PartType0/InternalEnergy"][:]
+S = file["/PartType0/Entropy"][:]
+P = file["/PartType0/Pressure"][:]
+time = file["/Header"].attrs["Time"][0]
+
+scheme = file["/HydroScheme"].attrs["Scheme"]
+kernel = file["/HydroScheme"].attrs["Kernel function"]
+neighbours = file["/HydroScheme"].attrs["Kernel target N_ngb"][0]
+eta = file["/HydroScheme"].attrs["Kernel eta"][0]
+git = file["Code"].attrs["Git Revision"]
+
+# Bin the data values
+# We let scipy choose the bins and then reuse them for all other quantities
+rho_bin, x_bin_edge, _ = \
+  stats.binned_statistic(x, rho, statistic = "mean", bins = 50)
+rho2_bin, _, _ = \
+  stats.binned_statistic(x, rho**2, statistic = "mean", bins = x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+
+v_bin, _, _ = \
+  stats.binned_statistic(x, v, statistic = "mean", bins = x_bin_edge)
+v2_bin, _, _ = \
+  stats.binned_statistic(x, v**2, statistic = "mean", bins = x_bin_edge)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+
+P_bin, _, _ = \
+  stats.binned_statistic(x, P, statistic = "mean", bins = x_bin_edge)
+P2_bin, _, _ = \
+  stats.binned_statistic(x, P**2, statistic = "mean", bins = x_bin_edge)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+
+u_bin, _, _ = \
+  stats.binned_statistic(x, u, statistic = "mean", bins = x_bin_edge)
+u2_bin, _, _ = \
+  stats.binned_statistic(x, u**2, statistic = "mean", bins = x_bin_edge)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+S_bin, _, _ = \
+  stats.binned_statistic(x, S, statistic = "mean", bins = x_bin_edge)
+S2_bin, _, _ = \
+  stats.binned_statistic(x, S**2, statistic = "mean", bins = x_bin_edge)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+
+x_bin = 0.5 * (x_bin_edge[1:] + x_bin_edge[:-1])
+
+ref = np.loadtxt("vacuumSpherical2D_exact.txt")
+
+# Plot the interesting quantities
+fig, ax = pl.subplots(2, 3)
+
+# Velocity profile
+ax[0][0].plot(x, v, "r.", markersize = 0.2)
+ax[0][0].plot(ref[:,0], ref[:,2], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].errorbar(x_bin, v_bin, yerr = v_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][0].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[0][0].set_ylabel("${\\rm{Velocity}}~v_r$", labelpad = 0)
+ax[0][0].set_xlim(0., 0.4)
+ax[0][0].set_ylim(-0.1, 3.2)
+
+# Density profile
+ax[0][1].plot(x, rho, "r.", markersize = 0.2)
+ax[0][1].plot(ref[:,0], ref[:,1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].errorbar(x_bin, rho_bin, yerr = rho_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][1].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[0][1].set_ylabel("${\\rm{Density}}~\\rho$", labelpad = 0)
+ax[0][1].set_xlim(0., 0.4)
+
+# Pressure profile
+ax[0][2].plot(x, P, "r.", markersize = 0.2)
+ax[0][2].plot(ref[:,0], ref[:,3], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].errorbar(x_bin, P_bin, yerr = P_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][2].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[0][2].set_ylabel("${\\rm{Pressure}}~P$", labelpad = 0)
+ax[0][2].set_xlim(0., 0.4)
+
+# Internal energy profile
+ax[1][0].plot(x, u, "r.", markersize = 0.2)
+ax[1][0].plot(ref[:,0], ref[:,3] / ref[:,1] / (gamma - 1.), "k--", alpha = 0.8,
+              linewidth = 1.2)
+ax[1][0].errorbar(x_bin, u_bin, yerr = u_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][0].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[1][0].set_ylabel("${\\rm{Internal~Energy}}~u$", labelpad = 0)
+ax[1][0].set_xlim(0., 0.4)
+
+# Entropy profile
+ax[1][1].plot(x, S, "r.", markersize = 0.2)
+ax[1][1].plot(ref[:,0], ref[:,3] / ref[:,1]**gamma, "k--", alpha = 0.8,
+              linewidth = 1.2)
+ax[1][1].errorbar(x_bin, S_bin, yerr = S_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][1].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[1][1].set_ylabel("${\\rm{Entropy}}~S$", labelpad = 0)
+ax[1][1].set_xlim(0., 0.4)
+ax[1][1].set_ylim(0., 4.)
+
+# Run information
+ax[1][2].set_frame_on(False)
+ax[1][2].text(-0.49, 0.9,
+  "Vacuum test with $\\gamma={0:.3f}$ in 1D at $t = {1:.2f}$".format(
+    gamma, time), fontsize = 10)
+ax[1][2].text(-0.49, 0.8,
+  "Left:~~ $(P_L, \\rho_L, v_L) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PL, rhoL, vL), fontsize = 10)
+ax[1][2].text(-0.49, 0.7,
+  "Right: $(P_R, \\rho_R, v_R) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PR, rhoR, vR), fontsize = 10)
+ax[1][2].plot([-0.49, 0.1], [0.62, 0.62], "k-", lw = 1)
+ax[1][2].text(-0.49, 0.5, "$\\textsc{{Swift}}$ {0}".format(git), fontsize = 10)
+ax[1][2].text(-0.49, 0.4, scheme, fontsize = 10)
+ax[1][2].text(-0.49, 0.3, kernel, fontsize = 10)
+ax[1][2].text(-0.49, 0.2,
+  "${0:.2f}$ neighbours ($\\eta={1:.3f}$)".format(neighbours, eta),
+  fontsize = 10)
+ax[1][2].set_xlim(-0.5, 0.5)
+ax[1][2].set_ylim(0., 1.)
+ax[1][2].set_xticks([])
+ax[1][2].set_yticks([])
+
+pl.tight_layout()
+pl.savefig("Vacuum.png", dpi = 200)
diff --git a/examples/VacuumSpherical_2D/run.sh b/examples/VacuumSpherical_2D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..51d32b4de679877741b7ecd74238fecb785579e7
--- /dev/null
+++ b/examples/VacuumSpherical_2D/run.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassPlane_128.hdf5 ]
+then
+    echo "Fetching initial glass file for the 2D vacuum expansion example..."
+    ./getGlass.sh
+fi
+if [ ! -e vacuum.hdf5 ]
+then
+    echo "Generating initial conditions for the 2D vacuum expansion example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 4 vacuum.yml 2>&1 | tee output.log
+
+# Get the 1D high resolution reference result if not present.
+if [ ! -e vacuumSpherical2D_exact.txt ]
+then
+    echo "Fetching reference solution for the 2D vacuum expansion test..."
+    ./getReference.sh
+fi
+
+# Plot the result
+python plotSolution.py 1
diff --git a/examples/VacuumSpherical_2D/vacuum.yml b/examples/VacuumSpherical_2D/vacuum.yml
new file mode 100644
index 0000000000000000000000000000000000000000..881b155b62c7f1f2af12a1d013ff5c05f1c16a88
--- /dev/null
+++ b/examples/VacuumSpherical_2D/vacuum.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.05   # The end time of the simulation (in internal units).
+  dt_min:     1e-10  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            vacuum # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.05     # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./vacuum.hdf5       # The file to read
+
diff --git a/examples/VacuumSpherical_3D/getGlass.sh b/examples/VacuumSpherical_3D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d5c5f590ac37c9c9431d626a2ea61b0c12c1513c
--- /dev/null
+++ b/examples/VacuumSpherical_3D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_64.hdf5
diff --git a/examples/VacuumSpherical_3D/getReference.sh b/examples/VacuumSpherical_3D/getReference.sh
new file mode 100755
index 0000000000000000000000000000000000000000..49784c313f0c8758d88970169c30d39c58745ec4
--- /dev/null
+++ b/examples/VacuumSpherical_3D/getReference.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ReferenceSolutions/vacuumSpherical3D_exact.txt
diff --git a/examples/VacuumSpherical_3D/makeIC.py b/examples/VacuumSpherical_3D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..d67a30707a904268a09641210a6a3bfcbf305dad
--- /dev/null
+++ b/examples/VacuumSpherical_3D/makeIC.py
@@ -0,0 +1,104 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import h5py
+
+# Generates an overdensity within a vacuum to test the vacuum resolving
+# capabilities of the code
+
+# Parameters
+gamma = 5. / 3.    # Gas adiabatic index
+
+fileName = "vacuum.hdf5" 
+
+#---------------------------------------------------
+glass = h5py.File("glassCube_64.hdf5", "r")
+
+# Read particle positions and h from the glass
+pos = glass["/PartType0/Coordinates"][:,:]
+h = glass["/PartType0/SmoothingLength"][:] * 0.3
+
+# Make 8 copies of the glass to get more particles
+pos *= 0.5
+h *= 0.5
+pos = np.append(pos, pos + np.array([0.5, 0., 0.]), axis = 0)
+pos = np.append(pos, pos + np.array([0., 0.5, 0.]), axis = 0)
+pos = np.append(pos, pos + np.array([0., 0., 0.5]), axis = 0)
+h = np.append(h, h)
+h = np.append(h, h)
+h = np.append(h, h)
+
+radius = np.sqrt((pos[:,0] - 0.5)**2 + (pos[:,1] - 0.5)**2 + \
+                 (pos[:,2] - 0.5)**2)
+index = radius < 0.25
+pos = pos[index]
+h = h[index]
+
+numPart = len(h)
+vol = 4. * np.pi / 3. * 0.25**3
+
+# Generate extra arrays
+v = np.zeros((numPart, 3))
+ids = np.linspace(1, numPart, numPart)
+m = np.zeros(numPart)
+u = np.zeros(numPart)
+
+m[:] = 1. * vol / numPart
+u[:] = 1. / (1. * (gamma - 1.))
+
+#--------------------------------------------------
+
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 3
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+file.close()
diff --git a/examples/VacuumSpherical_3D/plotSolution.py b/examples/VacuumSpherical_3D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..c73e48ee2d311692cdf4aa3b0e52f4766b339df8
--- /dev/null
+++ b/examples/VacuumSpherical_3D/plotSolution.py
@@ -0,0 +1,193 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import h5py
+import sys
+import scipy.stats as stats
+
+# Parameters
+gamma = 5. / 3. # Polytropic index
+rhoL = 1.       # Initial density in the non vacuum state
+vL = 0.         # Initial velocity in the non vacuum state
+PL = 1.         # Initial pressure in the non vacuum state
+rhoR = 0.       # Initial vacuum density
+vR = 0.         # Initial vacuum velocity
+PR = 0.         # Initial vacuum pressure
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+pl.rcParams.update(params)
+pl.rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+# Read the snapshot index from the command line argument
+snap = int(sys.argv[1])
+
+# Open the file and read the relevant data
+file = h5py.File("vacuum_{0:04d}.hdf5".format(snap), "r")
+coords = file["/PartType0/Coordinates"]
+x = np.sqrt((coords[:,0] - 0.5)**2 + (coords[:,1] - 0.5)**2 + \
+            (coords[:,2] - 0.5)**2)
+rho = file["/PartType0/Density"][:]
+vels = file["/PartType0/Velocities"]
+v = np.sqrt(vels[:,0]**2 + vels[:,1]**2 + vels[:,2]**2)
+u = file["/PartType0/InternalEnergy"][:]
+S = file["/PartType0/Entropy"][:]
+P = file["/PartType0/Pressure"][:]
+time = file["/Header"].attrs["Time"][0]
+
+scheme = file["/HydroScheme"].attrs["Scheme"]
+kernel = file["/HydroScheme"].attrs["Kernel function"]
+neighbours = file["/HydroScheme"].attrs["Kernel target N_ngb"][0]
+eta = file["/HydroScheme"].attrs["Kernel eta"][0]
+git = file["Code"].attrs["Git Revision"]
+
+# Bin the data values
+# We let scipy choose the bins and then reuse them for all other quantities
+rho_bin, x_bin_edge, _ = \
+  stats.binned_statistic(x, rho, statistic = "mean", bins = 50)
+rho2_bin, _, _ = \
+  stats.binned_statistic(x, rho**2, statistic = "mean", bins = x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+
+v_bin, _, _ = \
+  stats.binned_statistic(x, v, statistic = "mean", bins = x_bin_edge)
+v2_bin, _, _ = \
+  stats.binned_statistic(x, v**2, statistic = "mean", bins = x_bin_edge)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+
+P_bin, _, _ = \
+  stats.binned_statistic(x, P, statistic = "mean", bins = x_bin_edge)
+P2_bin, _, _ = \
+  stats.binned_statistic(x, P**2, statistic = "mean", bins = x_bin_edge)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+
+u_bin, _, _ = \
+  stats.binned_statistic(x, u, statistic = "mean", bins = x_bin_edge)
+u2_bin, _, _ = \
+  stats.binned_statistic(x, u**2, statistic = "mean", bins = x_bin_edge)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+S_bin, _, _ = \
+  stats.binned_statistic(x, S, statistic = "mean", bins = x_bin_edge)
+S2_bin, _, _ = \
+  stats.binned_statistic(x, S**2, statistic = "mean", bins = x_bin_edge)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+
+x_bin = 0.5 * (x_bin_edge[1:] + x_bin_edge[:-1])
+
+ref = np.loadtxt("vacuumSpherical3D_exact.txt")
+
+# Plot the interesting quantities
+fig, ax = pl.subplots(2, 3)
+
+# Velocity profile
+ax[0][0].plot(x, v, "r.", markersize = 0.2)
+ax[0][0].plot(ref[:,0], ref[:,2], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].errorbar(x_bin, v_bin, yerr = v_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][0].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[0][0].set_ylabel("${\\rm{Velocity}}~v_r$", labelpad = 0)
+ax[0][0].set_xlim(0., 0.4)
+ax[0][0].set_ylim(-0.1, 3.2)
+
+# Density profile
+ax[0][1].plot(x, rho, "r.", markersize = 0.2)
+ax[0][1].plot(ref[:,0], ref[:,1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].errorbar(x_bin, rho_bin, yerr = rho_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][1].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[0][1].set_ylabel("${\\rm{Density}}~\\rho$", labelpad = 0)
+ax[0][1].set_xlim(0., 0.4)
+
+# Pressure profile
+ax[0][2].plot(x, P, "r.", markersize = 0.2)
+ax[0][2].plot(ref[:,0], ref[:,3], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].errorbar(x_bin, P_bin, yerr = P_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][2].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[0][2].set_ylabel("${\\rm{Pressure}}~P$", labelpad = 0)
+ax[0][2].set_xlim(0., 0.4)
+
+# Internal energy profile
+ax[1][0].plot(x, u, "r.", markersize = 0.2)
+ax[1][0].plot(ref[:,0], ref[:,3] / ref[:,1] / (gamma - 1.), "k--", alpha = 0.8,
+              linewidth = 1.2)
+ax[1][0].errorbar(x_bin, u_bin, yerr = u_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][0].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[1][0].set_ylabel("${\\rm{Internal~Energy}}~u$", labelpad = 0)
+ax[1][0].set_xlim(0., 0.4)
+
+# Entropy profile
+ax[1][1].plot(x, S, "r.", markersize = 0.2)
+ax[1][1].plot(ref[:,0], ref[:,3] / ref[:,1]**gamma, "k--", alpha = 0.8,
+              linewidth = 1.2)
+ax[1][1].errorbar(x_bin, S_bin, yerr = S_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][1].set_xlabel("${\\rm{Radius}}~r$", labelpad = 0)
+ax[1][1].set_ylabel("${\\rm{Entropy}}~S$", labelpad = 0)
+ax[1][1].set_xlim(0., 0.4)
+ax[1][1].set_ylim(0., 4.)
+
+# Run information
+ax[1][2].set_frame_on(False)
+ax[1][2].text(-0.49, 0.9,
+  "Vacuum test with $\\gamma={0:.3f}$ in 1D at $t = {1:.2f}$".format(
+    gamma, time), fontsize = 10)
+ax[1][2].text(-0.49, 0.8,
+  "Left:~~ $(P_L, \\rho_L, v_L) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PL, rhoL, vL), fontsize = 10)
+ax[1][2].text(-0.49, 0.7,
+  "Right: $(P_R, \\rho_R, v_R) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PR, rhoR, vR), fontsize = 10)
+ax[1][2].plot([-0.49, 0.1], [0.62, 0.62], "k-", lw = 1)
+ax[1][2].text(-0.49, 0.5, "$\\textsc{{Swift}}$ {0}".format(git), fontsize = 10)
+ax[1][2].text(-0.49, 0.4, scheme, fontsize = 10)
+ax[1][2].text(-0.49, 0.3, kernel, fontsize = 10)
+ax[1][2].text(-0.49, 0.2,
+  "${0:.2f}$ neighbours ($\\eta={1:.3f}$)".format(neighbours, eta),
+  fontsize = 10)
+ax[1][2].set_xlim(-0.5, 0.5)
+ax[1][2].set_ylim(0., 1.)
+ax[1][2].set_xticks([])
+ax[1][2].set_yticks([])
+
+pl.tight_layout()
+pl.savefig("Vacuum.png", dpi = 200)
diff --git a/examples/VacuumSpherical_3D/run.sh b/examples/VacuumSpherical_3D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a136929678f745f6a3d0859ba146e1bc1c6c43d0
--- /dev/null
+++ b/examples/VacuumSpherical_3D/run.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassCube_64.hdf5 ]
+then
+    echo "Fetching initial glass file for the 3D vacuum expansion example..."
+    ./getGlass.sh
+fi
+if [ ! -e vacuum.hdf5 ]
+then
+    echo "Generating initial conditions for the 3D vacuum expansion example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 16 vacuum.yml 2>&1 | tee output.log
+
+# Get the reference solution if it is not present.
+if [ ! -e vacuumSpherical3D_exact.txt ]
+then
+    echo "Fetching reference solution for the 3D vacuum expansion test..."
+    ./getReference.sh
+fi
+
+# Plot the result
+python plotSolution.py 1
diff --git a/examples/VacuumSpherical_3D/vacuum.yml b/examples/VacuumSpherical_3D/vacuum.yml
new file mode 100644
index 0000000000000000000000000000000000000000..881b155b62c7f1f2af12a1d013ff5c05f1c16a88
--- /dev/null
+++ b/examples/VacuumSpherical_3D/vacuum.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.05   # The end time of the simulation (in internal units).
+  dt_min:     1e-10  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            vacuum # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.05     # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./vacuum.hdf5       # The file to read
+
diff --git a/examples/Vacuum_1D/makeIC.py b/examples/Vacuum_1D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..067304ec951182da862cf2812cdc68a51a56d23b
--- /dev/null
+++ b/examples/Vacuum_1D/makeIC.py
@@ -0,0 +1,88 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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/>.
+#
+##############################################################################
+
+# Generates an overdensity within a vacuum to test the vacuum handling
+# capabilities of the code
+
+import numpy as np
+import h5py
+
+fileName = "vacuum.hdf5"
+numPart = 100
+boxSize = 1.
+gamma = 5. / 3.
+
+coords = np.zeros((numPart, 3))
+v = np.zeros((numPart, 3))
+m = np.zeros(numPart)
+h = np.zeros(numPart)
+u = np.zeros(numPart)
+ids = np.arange(numPart, dtype = 'L')
+rho = np.zeros(numPart)
+
+# first set the positions, as we try to do a reasonable volume estimate to
+# set the masses
+for i in range(numPart):
+  # we only generate particles in the range [0.25, 0.75]
+  coords[i,0] = 0.25 + 0.5 * (i + 0.5) / numPart
+  rho[i] = 1.
+  P = 1.
+  u[i] = P / (gamma - 1.) / rho[i]
+  m[i] = rho[i] * 0.5 / numPart
+  # reasonable smoothing length estimate
+  h[i] = 1. / numPart
+
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = boxSize
+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
+grp.attrs["Dimension"] = 1
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=coords, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+grp.create_dataset('Density', data=rho, dtype='f')
+
+file.close()
diff --git a/examples/Vacuum_1D/plotSolution.py b/examples/Vacuum_1D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..fceac10c25fd58b5bbcb6e31884cd62b4cfd61f5
--- /dev/null
+++ b/examples/Vacuum_1D/plotSolution.py
@@ -0,0 +1,180 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import h5py
+import sys
+
+# Parameters
+gamma = 5. / 3. # Polytropic index
+rhoL = 1.       # Initial density in the non vacuum state
+vL = 0.         # Initial velocity in the non vacuum state
+PL = 1.         # Initial pressure in the non vacuum state
+rhoR = 0.       # Initial vacuum density
+vR = 0.         # Initial vacuum velocity
+PR = 0.         # Initial vacuum pressure
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+pl.rcParams.update(params)
+pl.rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+# Read the snapshot index from the command line argument
+snap = int(sys.argv[1])
+
+# Open the file and read the relevant data
+file = h5py.File("vacuum_{0:04d}.hdf5".format(snap), "r")
+x = file["/PartType0/Coordinates"][:,0]
+rho = file["/PartType0/Density"]
+v = file["/PartType0/Velocities"][:,0]
+u = file["/PartType0/InternalEnergy"]
+S = file["/PartType0/Entropy"]
+P = file["/PartType0/Pressure"]
+time = file["/Header"].attrs["Time"][0]
+
+scheme = file["/HydroScheme"].attrs["Scheme"]
+kernel = file["/HydroScheme"].attrs["Kernel function"]
+neighbours = file["/HydroScheme"].attrs["Kernel target N_ngb"][0]
+eta = file["/HydroScheme"].attrs["Kernel eta"][0]
+git = file["Code"].attrs["Git Revision"]
+
+# Get the analytic solution, which is just the solution of the corresponding
+# vacuum Riemann problem evaluated at the correct time
+
+# left state sound speed (and rarefaction wave speed)
+aL = np.sqrt(gamma * PL / rhoL)
+
+# vacuum front speed
+SL = vL + 2. / (gamma - 1.) * aL
+
+# we evaluate the solution centred on 0., and shift to the correct position
+# afterwards
+xa = np.arange(-0.25, 0.25, 0.001)
+rhoa = np.zeros(len(xa))
+va = np.zeros(len(xa))
+Pa = np.zeros(len(xa))
+
+for i in range(len(xa)):
+  dxdt = xa[i] / time
+  if dxdt > vL - aL:
+    if dxdt < SL:
+      # rarefaction regime
+      # factor that appears in both the density and pressure expression
+      fac = 2. / (gamma + 1.) + \
+            (gamma - 1.) / (gamma + 1.) * (vL - dxdt) / aL
+      rhoa[i] = rhoL * fac**(2. / (gamma - 1.))
+      va[i] = 2. / (gamma + 1.) * (aL + 0.5 * (gamma - 1.) * vL + dxdt)
+      Pa[i] = PL * fac**(2. * gamma / (gamma - 1.))
+    else:
+      # vacuum regime
+      rhoa[i] = 0.
+      va[i] = 0.
+      Pa[i] = 0.
+  else:
+    # left state regime
+    rhoa[i] = rhoL
+    va[i] = vL
+    Pa[i] = PL
+
+ua = Pa / (gamma - 1.) / rhoa
+Sa = Pa / rhoa**gamma
+
+# Plot the interesting quantities
+fig, ax = pl.subplots(2, 3)
+
+# Velocity profile
+ax[0][0].plot(x, v, "r.", markersize = 4.)
+ax[0][0].plot(xa + 0.75, va, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].plot(xa + 0.25, -va[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][0].set_ylabel("${\\rm{Velocity}}~v_x$", labelpad = 0)
+
+# Density profile
+ax[0][1].plot(x, rho, "r.", markersize = 4.)
+ax[0][1].plot(xa + 0.75, rhoa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].plot(xa + 0.25, rhoa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][1].set_ylabel("${\\rm{Density}}~\\rho$", labelpad = 0)
+
+# Pressure profile
+ax[0][2].plot(x, P, "r.", markersize = 4.)
+ax[0][2].plot(xa + 0.75, Pa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].plot(xa + 0.25, Pa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][2].set_ylabel("${\\rm{Pressure}}~P$", labelpad = 0)
+
+# Internal energy profile
+ax[1][0].plot(x, u, "r.", markersize = 4.)
+ax[1][0].plot(xa + 0.75, ua, "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][0].plot(xa + 0.25, ua[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][0].set_ylabel("${\\rm{Internal~Energy}}~u$", labelpad = 0)
+
+# Entropy profile
+ax[1][1].plot(x, S, "r.", markersize = 4.)
+ax[1][1].plot(xa + 0.75, Sa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][1].plot(xa + 0.25, Sa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][1].set_ylabel("${\\rm{Entropy}}~S$", labelpad = 0)
+
+# Run information
+ax[1][2].set_frame_on(False)
+ax[1][2].text(-0.49, 0.9,
+  "Vacuum test with $\\gamma={0:.3f}$ in 1D at $t = {1:.2f}$".format(
+    gamma, time), fontsize = 10)
+ax[1][2].text(-0.49, 0.8,
+  "Left:~~ $(P_L, \\rho_L, v_L) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PL, rhoL, vL), fontsize = 10)
+ax[1][2].text(-0.49, 0.7,
+  "Right: $(P_R, \\rho_R, v_R) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PR, rhoR, vR), fontsize = 10)
+ax[1][2].plot([-0.49, 0.1], [0.62, 0.62], "k-", lw = 1)
+ax[1][2].text(-0.49, 0.5, "$\\textsc{{Swift}}$ {0}".format(git), fontsize = 10)
+ax[1][2].text(-0.49, 0.4, scheme, fontsize = 10)
+ax[1][2].text(-0.49, 0.3, kernel, fontsize = 10)
+ax[1][2].text(-0.49, 0.2,
+  "${0:.2f}$ neighbours ($\\eta={1:.3f}$)".format(neighbours, eta),
+  fontsize = 10)
+ax[1][2].set_xlim(-0.5, 0.5)
+ax[1][2].set_ylim(0., 1.)
+ax[1][2].set_xticks([])
+ax[1][2].set_yticks([])
+
+pl.tight_layout()
+pl.savefig("Vacuum.png", dpi = 200)
diff --git a/examples/Vacuum_1D/run.sh b/examples/Vacuum_1D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b141f91f877c5b553281e53cdf02fbea948b0a97
--- /dev/null
+++ b/examples/Vacuum_1D/run.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e vacuum.hdf5 ]
+then
+    echo "Generating initial conditions for the 1D vacuum expansion example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 1 vacuum.yml 2>&1 | tee output.log
+
+# Plot the result
+python plotSolution.py 1
diff --git a/examples/Vacuum_1D/vacuum.yml b/examples/Vacuum_1D/vacuum.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5ef5ce3da68febb086a14ad1a2207711f680d9ff
--- /dev/null
+++ b/examples/Vacuum_1D/vacuum.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.1   # The end time of the simulation (in internal units).
+  dt_min:     1e-10  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            vacuum # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.1     # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./vacuum.hdf5       # The file to read
+
diff --git a/examples/Vacuum_2D/getGlass.sh b/examples/Vacuum_2D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ae3c977064f5e7a408aa249c5fd9089b3c52ecb1
--- /dev/null
+++ b/examples/Vacuum_2D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassPlane_128.hdf5
diff --git a/examples/Vacuum_2D/makeIC.py b/examples/Vacuum_2D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef267c092cafdb95457d5adad1e6858df0e14bd3
--- /dev/null
+++ b/examples/Vacuum_2D/makeIC.py
@@ -0,0 +1,95 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import h5py
+
+# Generates an overdensity within a vacuum to test the vacuum resolving
+# capabilities of the code
+
+# Parameters
+gamma = 5. / 3.    # Gas adiabatic index
+
+fileName = "vacuum.hdf5" 
+
+#---------------------------------------------------
+glass = h5py.File("glassPlane_128.hdf5", "r")
+
+# Read particle positions and h from the glass
+pos = glass["/PartType0/Coordinates"][:,:]
+h = glass["/PartType0/SmoothingLength"][:] * 0.3
+
+# Shrink the glass to half its size, move it to the centre of the box, and
+# clone it in the y direction
+pos = 0.5 * pos + np.array([0.25, 0., 0.])
+h *= 0.5
+pos = np.append(pos, pos + np.array([0., 0.5, 0.]), axis = 0)
+h = np.append(h, h)
+
+numPart = len(h)
+vol = 0.5
+
+# Generate extra arrays
+v = np.zeros((numPart, 3))
+ids = np.linspace(1, numPart, numPart)
+m = np.zeros(numPart)
+u = np.zeros(numPart)
+
+m[:] = 1. * vol / numPart
+u[:] = 1. / (1. * (gamma - 1.))
+
+#--------------------------------------------------
+
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 2
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+file.close()
diff --git a/examples/Vacuum_2D/plotSolution.py b/examples/Vacuum_2D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d197234237df10b8cdbf197048a65991da023cf
--- /dev/null
+++ b/examples/Vacuum_2D/plotSolution.py
@@ -0,0 +1,225 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import h5py
+import sys
+import scipy.stats as stats
+
+# Parameters
+gamma = 5. / 3. # Polytropic index
+rhoL = 1.       # Initial density in the non vacuum state
+vL = 0.         # Initial velocity in the non vacuum state
+PL = 1.         # Initial pressure in the non vacuum state
+rhoR = 0.       # Initial vacuum density
+vR = 0.         # Initial vacuum velocity
+PR = 0.         # Initial vacuum pressure
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+pl.rcParams.update(params)
+pl.rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+# Read the snapshot index from the command line argument
+snap = int(sys.argv[1])
+
+# Open the file and read the relevant data
+file = h5py.File("vacuum_{0:04d}.hdf5".format(snap), "r")
+x = file["/PartType0/Coordinates"][:,0]
+rho = file["/PartType0/Density"][:]
+v = file["/PartType0/Velocities"][:,0]
+u = file["/PartType0/InternalEnergy"][:]
+S = file["/PartType0/Entropy"][:]
+P = file["/PartType0/Pressure"][:]
+time = file["/Header"].attrs["Time"][0]
+
+scheme = file["/HydroScheme"].attrs["Scheme"]
+kernel = file["/HydroScheme"].attrs["Kernel function"]
+neighbours = file["/HydroScheme"].attrs["Kernel target N_ngb"][0]
+eta = file["/HydroScheme"].attrs["Kernel eta"][0]
+git = file["Code"].attrs["Git Revision"]
+
+# Get the analytic solution, which is just the solution of the corresponding
+# vacuum Riemann problem evaluated at the correct time
+
+# left state sound speed (and rarefaction wave speed)
+aL = np.sqrt(gamma * PL / rhoL)
+
+# vacuum front speed
+SL = vL + 2. / (gamma - 1.) * aL
+
+# we evaluate the solution centred on 0., and shift to the correct position
+# afterwards
+xa = np.arange(-0.25, 0.25, 0.001)
+rhoa = np.zeros(len(xa))
+va = np.zeros(len(xa))
+Pa = np.zeros(len(xa))
+
+for i in range(len(xa)):
+  dxdt = xa[i] / time
+  if dxdt > vL - aL:
+    if dxdt < SL:
+      # rarefaction regime
+      # factor that appears in both the density and pressure expression
+      fac = 2. / (gamma + 1.) + \
+            (gamma - 1.) / (gamma + 1.) * (vL - dxdt) / aL
+      rhoa[i] = rhoL * fac**(2. / (gamma - 1.))
+      va[i] = 2. / (gamma + 1.) * (aL + 0.5 * (gamma - 1.) * vL + dxdt)
+      Pa[i] = PL * fac**(2. * gamma / (gamma - 1.))
+    else:
+      # vacuum regime
+      rhoa[i] = 0.
+      va[i] = 0.
+      Pa[i] = 0.
+  else:
+    # left state regime
+    rhoa[i] = rhoL
+    va[i] = vL
+    Pa[i] = PL
+
+ua = Pa / (gamma - 1.) / rhoa
+Sa = Pa / rhoa**gamma
+
+# Bin the data values
+# We let scipy choose the bins and then reuse them for all other quantities
+rho_bin, x_bin_edge, _ = \
+  stats.binned_statistic(x, rho, statistic = "mean", bins = 50)
+rho2_bin, _, _ = \
+  stats.binned_statistic(x, rho**2, statistic = "mean", bins = x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+
+v_bin, _, _ = \
+  stats.binned_statistic(x, v, statistic = "mean", bins = x_bin_edge)
+v2_bin, _, _ = \
+  stats.binned_statistic(x, v**2, statistic = "mean", bins = x_bin_edge)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+
+P_bin, _, _ = \
+  stats.binned_statistic(x, P, statistic = "mean", bins = x_bin_edge)
+P2_bin, _, _ = \
+  stats.binned_statistic(x, P**2, statistic = "mean", bins = x_bin_edge)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+
+u_bin, _, _ = \
+  stats.binned_statistic(x, u, statistic = "mean", bins = x_bin_edge)
+u2_bin, _, _ = \
+  stats.binned_statistic(x, u**2, statistic = "mean", bins = x_bin_edge)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+S_bin, _, _ = \
+  stats.binned_statistic(x, S, statistic = "mean", bins = x_bin_edge)
+S2_bin, _, _ = \
+  stats.binned_statistic(x, S**2, statistic = "mean", bins = x_bin_edge)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+
+x_bin = 0.5 * (x_bin_edge[1:] + x_bin_edge[:-1])
+
+# Plot the interesting quantities
+fig, ax = pl.subplots(2, 3)
+
+# Velocity profile
+ax[0][0].plot(x, v, "r.", markersize = 0.2)
+ax[0][0].plot(xa + 0.75, va, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].plot(xa + 0.25, -va[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].errorbar(x_bin, v_bin, yerr = v_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][0].set_ylabel("${\\rm{Velocity}}~v_x$", labelpad = 0)
+
+# Density profile
+ax[0][1].plot(x, rho, "r.", markersize = 0.2)
+ax[0][1].plot(xa + 0.75, rhoa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].plot(xa + 0.25, rhoa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].errorbar(x_bin, rho_bin, yerr = rho_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][1].set_ylabel("${\\rm{Density}}~\\rho$", labelpad = 0)
+
+# Pressure profile
+ax[0][2].plot(x, P, "r.", markersize = 0.2)
+ax[0][2].plot(xa + 0.75, Pa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].plot(xa + 0.25, Pa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].errorbar(x_bin, P_bin, yerr = P_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][2].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][2].set_ylabel("${\\rm{Pressure}}~P$", labelpad = 0)
+
+# Internal energy profile
+ax[1][0].plot(x, u, "r.", markersize = 0.2)
+ax[1][0].plot(xa + 0.75, ua, "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][0].plot(xa + 0.25, ua[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][0].errorbar(x_bin, u_bin, yerr = u_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][0].set_ylabel("${\\rm{Internal~Energy}}~u$", labelpad = 0)
+
+# Entropy profile
+ax[1][1].plot(x, S, "r.", markersize = 0.2)
+ax[1][1].plot(xa + 0.75, Sa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][1].plot(xa + 0.25, Sa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][1].errorbar(x_bin, S_bin, yerr = S_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][1].set_ylabel("${\\rm{Entropy}}~S$", labelpad = 0)
+
+# Run information
+ax[1][2].set_frame_on(False)
+ax[1][2].text(-0.49, 0.9,
+  "Vacuum test with $\\gamma={0:.3f}$ in 1D at $t = {1:.2f}$".format(
+    gamma, time), fontsize = 10)
+ax[1][2].text(-0.49, 0.8,
+  "Left:~~ $(P_L, \\rho_L, v_L) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PL, rhoL, vL), fontsize = 10)
+ax[1][2].text(-0.49, 0.7,
+  "Right: $(P_R, \\rho_R, v_R) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PR, rhoR, vR), fontsize = 10)
+ax[1][2].plot([-0.49, 0.1], [0.62, 0.62], "k-", lw = 1)
+ax[1][2].text(-0.49, 0.5, "$\\textsc{{Swift}}$ {0}".format(git), fontsize = 10)
+ax[1][2].text(-0.49, 0.4, scheme, fontsize = 10)
+ax[1][2].text(-0.49, 0.3, kernel, fontsize = 10)
+ax[1][2].text(-0.49, 0.2,
+  "${0:.2f}$ neighbours ($\\eta={1:.3f}$)".format(neighbours, eta),
+  fontsize = 10)
+ax[1][2].set_xlim(-0.5, 0.5)
+ax[1][2].set_ylim(0., 1.)
+ax[1][2].set_xticks([])
+ax[1][2].set_yticks([])
+
+pl.tight_layout()
+pl.savefig("Vacuum.png", dpi = 200)
diff --git a/examples/Vacuum_2D/run.sh b/examples/Vacuum_2D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5c0b2ca5e19e33e813b7ff478ed4494752c0a2a5
--- /dev/null
+++ b/examples/Vacuum_2D/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassPlane_128.hdf5 ]
+then
+    echo "Fetching initial glass file for the 2D vacuum expansion example..."
+    ./getGlass.sh
+fi
+if [ ! -e vacuum.hdf5 ]
+then
+    echo "Generating initial conditions for the 2D vacuum expansion example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 4 vacuum.yml 2>&1 | tee output.log
+
+# Plot the result
+python plotSolution.py 1
diff --git a/examples/Vacuum_2D/vacuum.yml b/examples/Vacuum_2D/vacuum.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5ef5ce3da68febb086a14ad1a2207711f680d9ff
--- /dev/null
+++ b/examples/Vacuum_2D/vacuum.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.1   # The end time of the simulation (in internal units).
+  dt_min:     1e-10  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            vacuum # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.1     # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./vacuum.hdf5       # The file to read
+
diff --git a/examples/Vacuum_3D/getGlass.sh b/examples/Vacuum_3D/getGlass.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d5c5f590ac37c9c9431d626a2ea61b0c12c1513c
--- /dev/null
+++ b/examples/Vacuum_3D/getGlass.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_64.hdf5
diff --git a/examples/Vacuum_3D/makeIC.py b/examples/Vacuum_3D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..09c3cb4d6f5525d54fab59643ab4a7d0540a2a92
--- /dev/null
+++ b/examples/Vacuum_3D/makeIC.py
@@ -0,0 +1,97 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import h5py
+
+# Generates an overdensity within a vacuum to test the vacuum resolving
+# capabilities of the code
+
+# Parameters
+gamma = 5. / 3.    # Gas adiabatic index
+
+fileName = "vacuum.hdf5" 
+
+#---------------------------------------------------
+glass = h5py.File("glassCube_64.hdf5", "r")
+
+# Read particle positions and h from the glass
+pos = glass["/PartType0/Coordinates"][:,:]
+h = glass["/PartType0/SmoothingLength"][:] * 0.3
+
+# Shrink the glass to half its size, move it to the centre of the box, and
+# clone it in the y and z directions
+pos = 0.5 * pos + np.array([0.25, 0., 0.])
+h *= 0.5
+pos = np.append(pos, pos + np.array([0., 0.5, 0.]), axis = 0)
+pos = np.append(pos, pos + np.array([0., 0., 0.5]), axis = 0)
+h = np.append(h, h)
+h = np.append(h, h)
+
+numPart = len(h)
+vol = 0.5
+
+# Generate extra arrays
+v = np.zeros((numPart, 3))
+ids = np.linspace(1, numPart, numPart)
+m = np.zeros(numPart)
+u = np.zeros(numPart)
+
+m[:] = 1. * vol / numPart
+u[:] = 1. / (1. * (gamma - 1.))
+
+#--------------------------------------------------
+
+#File
+file = h5py.File(fileName, 'w')
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = [1., 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
+grp.attrs["Dimension"] = 3
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = 1
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = 1.
+grp.attrs["Unit mass in cgs (U_M)"] = 1.
+grp.attrs["Unit time in cgs (U_t)"] = 1.
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+#Particle group
+grp = file.create_group("/PartType0")
+grp.create_dataset('Coordinates', data=pos, dtype='d')
+grp.create_dataset('Velocities', data=v, dtype='f')
+grp.create_dataset('Masses', data=m, dtype='f')
+grp.create_dataset('SmoothingLength', data=h, dtype='f')
+grp.create_dataset('InternalEnergy', data=u, dtype='f')
+grp.create_dataset('ParticleIDs', data=ids, dtype='L')
+
+file.close()
diff --git a/examples/Vacuum_3D/plotSolution.py b/examples/Vacuum_3D/plotSolution.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d197234237df10b8cdbf197048a65991da023cf
--- /dev/null
+++ b/examples/Vacuum_3D/plotSolution.py
@@ -0,0 +1,225 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2018 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 numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import pylab as pl
+import h5py
+import sys
+import scipy.stats as stats
+
+# Parameters
+gamma = 5. / 3. # Polytropic index
+rhoL = 1.       # Initial density in the non vacuum state
+vL = 0.         # Initial velocity in the non vacuum state
+PL = 1.         # Initial pressure in the non vacuum state
+rhoR = 0.       # Initial vacuum density
+vR = 0.         # Initial vacuum velocity
+PR = 0.         # Initial vacuum pressure
+
+# Plot parameters
+params = {'axes.labelsize': 10,
+'axes.titlesize': 10,
+'font.size': 12,
+'legend.fontsize': 12,
+'xtick.labelsize': 10,
+'ytick.labelsize': 10,
+'text.usetex': True,
+ 'figure.figsize' : (9.90,6.45),
+'figure.subplot.left'    : 0.045,
+'figure.subplot.right'   : 0.99,
+'figure.subplot.bottom'  : 0.05,
+'figure.subplot.top'     : 0.99,
+'figure.subplot.wspace'  : 0.15,
+'figure.subplot.hspace'  : 0.12,
+'lines.markersize' : 6,
+'lines.linewidth' : 3.,
+'text.latex.unicode': True
+}
+pl.rcParams.update(params)
+pl.rc('font',**{'family':'sans-serif','sans-serif':['Times']})
+
+# Read the snapshot index from the command line argument
+snap = int(sys.argv[1])
+
+# Open the file and read the relevant data
+file = h5py.File("vacuum_{0:04d}.hdf5".format(snap), "r")
+x = file["/PartType0/Coordinates"][:,0]
+rho = file["/PartType0/Density"][:]
+v = file["/PartType0/Velocities"][:,0]
+u = file["/PartType0/InternalEnergy"][:]
+S = file["/PartType0/Entropy"][:]
+P = file["/PartType0/Pressure"][:]
+time = file["/Header"].attrs["Time"][0]
+
+scheme = file["/HydroScheme"].attrs["Scheme"]
+kernel = file["/HydroScheme"].attrs["Kernel function"]
+neighbours = file["/HydroScheme"].attrs["Kernel target N_ngb"][0]
+eta = file["/HydroScheme"].attrs["Kernel eta"][0]
+git = file["Code"].attrs["Git Revision"]
+
+# Get the analytic solution, which is just the solution of the corresponding
+# vacuum Riemann problem evaluated at the correct time
+
+# left state sound speed (and rarefaction wave speed)
+aL = np.sqrt(gamma * PL / rhoL)
+
+# vacuum front speed
+SL = vL + 2. / (gamma - 1.) * aL
+
+# we evaluate the solution centred on 0., and shift to the correct position
+# afterwards
+xa = np.arange(-0.25, 0.25, 0.001)
+rhoa = np.zeros(len(xa))
+va = np.zeros(len(xa))
+Pa = np.zeros(len(xa))
+
+for i in range(len(xa)):
+  dxdt = xa[i] / time
+  if dxdt > vL - aL:
+    if dxdt < SL:
+      # rarefaction regime
+      # factor that appears in both the density and pressure expression
+      fac = 2. / (gamma + 1.) + \
+            (gamma - 1.) / (gamma + 1.) * (vL - dxdt) / aL
+      rhoa[i] = rhoL * fac**(2. / (gamma - 1.))
+      va[i] = 2. / (gamma + 1.) * (aL + 0.5 * (gamma - 1.) * vL + dxdt)
+      Pa[i] = PL * fac**(2. * gamma / (gamma - 1.))
+    else:
+      # vacuum regime
+      rhoa[i] = 0.
+      va[i] = 0.
+      Pa[i] = 0.
+  else:
+    # left state regime
+    rhoa[i] = rhoL
+    va[i] = vL
+    Pa[i] = PL
+
+ua = Pa / (gamma - 1.) / rhoa
+Sa = Pa / rhoa**gamma
+
+# Bin the data values
+# We let scipy choose the bins and then reuse them for all other quantities
+rho_bin, x_bin_edge, _ = \
+  stats.binned_statistic(x, rho, statistic = "mean", bins = 50)
+rho2_bin, _, _ = \
+  stats.binned_statistic(x, rho**2, statistic = "mean", bins = x_bin_edge)
+rho_sigma_bin = np.sqrt(rho2_bin - rho_bin**2)
+
+v_bin, _, _ = \
+  stats.binned_statistic(x, v, statistic = "mean", bins = x_bin_edge)
+v2_bin, _, _ = \
+  stats.binned_statistic(x, v**2, statistic = "mean", bins = x_bin_edge)
+v_sigma_bin = np.sqrt(v2_bin - v_bin**2)
+
+P_bin, _, _ = \
+  stats.binned_statistic(x, P, statistic = "mean", bins = x_bin_edge)
+P2_bin, _, _ = \
+  stats.binned_statistic(x, P**2, statistic = "mean", bins = x_bin_edge)
+P_sigma_bin = np.sqrt(P2_bin - P_bin**2)
+
+u_bin, _, _ = \
+  stats.binned_statistic(x, u, statistic = "mean", bins = x_bin_edge)
+u2_bin, _, _ = \
+  stats.binned_statistic(x, u**2, statistic = "mean", bins = x_bin_edge)
+u_sigma_bin = np.sqrt(u2_bin - u_bin**2)
+
+S_bin, _, _ = \
+  stats.binned_statistic(x, S, statistic = "mean", bins = x_bin_edge)
+S2_bin, _, _ = \
+  stats.binned_statistic(x, S**2, statistic = "mean", bins = x_bin_edge)
+S_sigma_bin = np.sqrt(S2_bin - S_bin**2)
+
+x_bin = 0.5 * (x_bin_edge[1:] + x_bin_edge[:-1])
+
+# Plot the interesting quantities
+fig, ax = pl.subplots(2, 3)
+
+# Velocity profile
+ax[0][0].plot(x, v, "r.", markersize = 0.2)
+ax[0][0].plot(xa + 0.75, va, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].plot(xa + 0.25, -va[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][0].errorbar(x_bin, v_bin, yerr = v_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][0].set_ylabel("${\\rm{Velocity}}~v_x$", labelpad = 0)
+
+# Density profile
+ax[0][1].plot(x, rho, "r.", markersize = 0.2)
+ax[0][1].plot(xa + 0.75, rhoa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].plot(xa + 0.25, rhoa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][1].errorbar(x_bin, rho_bin, yerr = rho_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][1].set_ylabel("${\\rm{Density}}~\\rho$", labelpad = 0)
+
+# Pressure profile
+ax[0][2].plot(x, P, "r.", markersize = 0.2)
+ax[0][2].plot(xa + 0.75, Pa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].plot(xa + 0.25, Pa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[0][2].errorbar(x_bin, P_bin, yerr = P_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[0][2].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[0][2].set_ylabel("${\\rm{Pressure}}~P$", labelpad = 0)
+
+# Internal energy profile
+ax[1][0].plot(x, u, "r.", markersize = 0.2)
+ax[1][0].plot(xa + 0.75, ua, "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][0].plot(xa + 0.25, ua[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][0].errorbar(x_bin, u_bin, yerr = u_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][0].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][0].set_ylabel("${\\rm{Internal~Energy}}~u$", labelpad = 0)
+
+# Entropy profile
+ax[1][1].plot(x, S, "r.", markersize = 0.2)
+ax[1][1].plot(xa + 0.75, Sa, "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][1].plot(xa + 0.25, Sa[::-1], "k--", alpha = 0.8, linewidth = 1.2)
+ax[1][1].errorbar(x_bin, S_bin, yerr = S_sigma_bin, fmt = ".",
+  markersize = 8., color = "b", linewidth = 1.2)
+ax[1][1].set_xlabel("${\\rm{Position}}~x$", labelpad = 0)
+ax[1][1].set_ylabel("${\\rm{Entropy}}~S$", labelpad = 0)
+
+# Run information
+ax[1][2].set_frame_on(False)
+ax[1][2].text(-0.49, 0.9,
+  "Vacuum test with $\\gamma={0:.3f}$ in 1D at $t = {1:.2f}$".format(
+    gamma, time), fontsize = 10)
+ax[1][2].text(-0.49, 0.8,
+  "Left:~~ $(P_L, \\rho_L, v_L) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PL, rhoL, vL), fontsize = 10)
+ax[1][2].text(-0.49, 0.7,
+  "Right: $(P_R, \\rho_R, v_R) = ({0:.3f}, {1:.3f}, {2:.3f})$".format(
+    PR, rhoR, vR), fontsize = 10)
+ax[1][2].plot([-0.49, 0.1], [0.62, 0.62], "k-", lw = 1)
+ax[1][2].text(-0.49, 0.5, "$\\textsc{{Swift}}$ {0}".format(git), fontsize = 10)
+ax[1][2].text(-0.49, 0.4, scheme, fontsize = 10)
+ax[1][2].text(-0.49, 0.3, kernel, fontsize = 10)
+ax[1][2].text(-0.49, 0.2,
+  "${0:.2f}$ neighbours ($\\eta={1:.3f}$)".format(neighbours, eta),
+  fontsize = 10)
+ax[1][2].set_xlim(-0.5, 0.5)
+ax[1][2].set_ylim(0., 1.)
+ax[1][2].set_xticks([])
+ax[1][2].set_yticks([])
+
+pl.tight_layout()
+pl.savefig("Vacuum.png", dpi = 200)
diff --git a/examples/Vacuum_3D/run.sh b/examples/Vacuum_3D/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5029626f67659bba1f22600bb5bd38859dd805ce
--- /dev/null
+++ b/examples/Vacuum_3D/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e glassCube_64.hdf5 ]
+then
+    echo "Fetching initial glass file for the 3D vacuum expansion example..."
+    ./getGlass.sh
+fi
+if [ ! -e vacuum.hdf5 ]
+then
+    echo "Generating initial conditions for the 3D vacuum expansion example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../swift -s -t 16 vacuum.yml 2>&1 | tee output.log
+
+# Plot the result
+python plotSolution.py 1
diff --git a/examples/Vacuum_3D/vacuum.yml b/examples/Vacuum_3D/vacuum.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5ef5ce3da68febb086a14ad1a2207711f680d9ff
--- /dev/null
+++ b/examples/Vacuum_3D/vacuum.yml
@@ -0,0 +1,34 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1   # Grams
+  UnitLength_in_cgs:   1   # Centimeters
+  UnitVelocity_in_cgs: 1   # 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:   0.1   # The end time of the simulation (in internal units).
+  dt_min:     1e-10  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-2  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the snapshots
+Snapshots:
+  basename:            vacuum # Common part of the name of output files
+  time_first:          0.       # Time of the first output (in internal units)
+  delta_time:          0.1     # Time difference between consecutive outputs (in internal units)
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2348   # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  ./vacuum.hdf5       # The file to read
+
diff --git a/examples/main.c b/examples/main.c
index 4b4c36c68cd4420a0d831b9709eff4fd25256a70..6244a7bb615d2a29002625a4ca233aec7ab11eeb 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -432,7 +432,8 @@ int main(int argc, char *argv[]) {
   }
 
   /* Read the parameter file */
-  struct swift_params *params = malloc(sizeof(struct swift_params));
+  struct swift_params *params =
+      (struct swift_params *)malloc(sizeof(struct swift_params));
   if (params == NULL) error("Error allocating memory for the parameter file.");
   if (myrank == 0) {
     message("Reading runtime parameters from file '%s'", paramFileName);
@@ -589,7 +590,7 @@ int main(int argc, char *argv[]) {
     /* Not restarting so look for the ICs. */
     /* Initialize unit system and constants */
     units_init(&us, params, "InternalUnitSystem");
-    phys_const_init(&us, &prog_const);
+    phys_const_init(&us, params, &prog_const);
     if (myrank == 0 && verbose > 0) {
       message("Internal unit system: U_M = %e g.", us.UnitMass_in_cgs);
       message("Internal unit system: U_L = %e cm.", us.UnitLength_in_cgs);
diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml
index 046ad0da52e772d406220573d4b09213c31c0a52..e304639cb579e0bdec9926775c45fb445da18b80 100644
--- a/examples/parameter_example.yml
+++ b/examples/parameter_example.yml
@@ -6,6 +6,10 @@ InternalUnitSystem:
   UnitCurrent_in_cgs:  1   # Amperes
   UnitTemp_in_cgs:     1   # Kelvin
 
+# Values of some physical constants
+PhysicalConstants:
+  G:            6.67408e-8 # (Optional) Overwrite the value of Newton's constant used internally by the code.
+
 # Parameters for the task scheduling
 Scheduler:
   nr_queues:                 0         # (Optional) The number of task queues to use. Use 0  to let the system decide.
diff --git a/src/Makefile.am b/src/Makefile.am
index 82b7aa73e10c1fa0b369886c48322985aadbc618..7b216af3ad083379f182fb6e8d887b4767837bc5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -122,12 +122,15 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h
                  chemistry/none/chemistry.h \
 		 chemistry/none/chemistry_io.h \
 		 chemistry/none/chemistry_struct.h \
+		 chemistry/none/chemistry_iact.h \
                  chemistry/gear/chemistry.h \
 		 chemistry/gear/chemistry_io.h \
 		 chemistry/gear/chemistry_struct.h \
+		 chemistry/gear/chemistry_iact.h \
                  chemistry/EAGLE/chemistry.h \
 		 chemistry/EAGLE/chemistry_io.h \
-		 chemistry/EAGLE/chemistry_struct.h
+		 chemistry/EAGLE/chemistry_struct.h\
+		 chemistry/EAGLE/chemistry_iact.h
 
 
 # Sources and flags for regular library
diff --git a/src/align.h b/src/align.h
index 54435c4c9baa1ce9dc511e2903b7e2be2d6655de..243557ee0b4c6c0ae6d7ee75d92c50ec5e3b2f4a 100644
--- a/src/align.h
+++ b/src/align.h
@@ -49,11 +49,11 @@
  * @param alignment The alignment in bytes of the array.
  */
 #if defined(__ICC)
-#define swift_align_information(array, alignment) \
+#define swift_align_information(type, array, alignment) \
   __assume_aligned(array, alignment);
 #elif defined(__GNUC__)
-#define swift_align_information(array, alignment) \
-  array = __builtin_assume_aligned(array, alignment);
+#define swift_align_information(type, array, alignment) \
+  array = (type *)__builtin_assume_aligned(array, alignment);
 #else
 #define swift_align_information(array, alignment) ;
 #endif
@@ -72,7 +72,7 @@
  */
 #define swift_declare_aligned_ptr(type, array, ptr, alignment) \
   type *restrict array = ptr;                                  \
-  swift_align_information(array, alignment);
+  swift_align_information(type, array, alignment);
 
 /**
  * @brief Macro to tell the compiler that a given number is 0 modulo a given
diff --git a/src/atomic.h b/src/atomic.h
index 4f180c643a304a801a9d70940fd12f9f193941e1..b09ed3dd22001586cfde8545e636de67a819c003 100644
--- a/src/atomic.h
+++ b/src/atomic.h
@@ -26,9 +26,10 @@
 #include "inline.h"
 
 #define atomic_add(v, i) __sync_fetch_and_add(v, i)
+#define atomic_sub(v, i) __sync_fetch_and_sub(v, i)
 #define atomic_or(v, i) __sync_fetch_and_or(v, i)
 #define atomic_inc(v) atomic_add(v, 1)
-#define atomic_dec(v) atomic_add(v, -1)
+#define atomic_dec(v) atomic_sub(v, 1)
 #define atomic_cas(v, o, n) __sync_val_compare_and_swap(v, o, n)
 #define atomic_swap(v, n) __sync_lock_test_and_set(v, n)
 
diff --git a/src/cell.c b/src/cell.c
index a36b8fd2fd28157fd1b35df572c3c831f78d26a9..30c0fd6a548822cfbb206bb47b16fb6cad6c0e83 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -49,6 +49,7 @@
 /* Local headers. */
 #include "active.h"
 #include "atomic.h"
+#include "chemistry.h"
 #include "drift.h"
 #include "engine.h"
 #include "error.h"
@@ -2423,6 +2424,7 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
       /* Get ready for a density calculation */
       if (part_is_active(p, e)) {
         hydro_init_part(p, &e->s->hs);
+        chemistry_init_part(p, e->chemistry);
       }
     }
 
diff --git a/src/chemistry.h b/src/chemistry.h
index b7a17bdb313f3b5ddc2416cdc7a729e4f8916ffe..25de507d60d8aa4bbb9cc4f0f6499dc52aeb93d4 100644
--- a/src/chemistry.h
+++ b/src/chemistry.h
@@ -31,10 +31,13 @@
 /* Import the right chemistry definition */
 #if defined(CHEMISTRY_NONE)
 #include "./chemistry/none/chemistry.h"
+#include "./chemistry/none/chemistry_iact.h"
 #elif defined(CHEMISTRY_GEAR)
 #include "./chemistry/gear/chemistry.h"
+#include "./chemistry/gear/chemistry_iact.h"
 #elif defined(CHEMISTRY_EAGLE)
 #include "./chemistry/EAGLE/chemistry.h"
+#include "./chemistry/EAGLE/chemistry_iact.h"
 #else
 #error "Invalid choice of chemistry function."
 #endif
diff --git a/src/chemistry/EAGLE/chemistry.h b/src/chemistry/EAGLE/chemistry.h
index df0a4599a0f81eaf619b078b86c0ade4e1eba7b8..0ee4d2a2bfc54b1fe4b9b64f321cc23862841952 100644
--- a/src/chemistry/EAGLE/chemistry.h
+++ b/src/chemistry/EAGLE/chemistry.h
@@ -50,6 +50,32 @@ chemistry_get_element_name(enum chemistry_element elem) {
   return chemistry_element_names[elem];
 }
 
+/**
+ * @brief Prepares a particle for the smooth metal calculation.
+ *
+ * Zeroes all the relevant arrays in preparation for the sums taking place in
+ * the various smooth metallicity tasks
+ *
+ * @param p The particle to act upon
+ * @param cd #chemistry_data containing chemistry informations.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_init_part(
+    struct part* restrict p, const struct chemistry_data* cd) {}
+
+/**
+ * @brief Finishes the smooth metal calculation.
+ *
+ * Multiplies the smoothed metallicity and number of neighbours by the
+ * appropiate constants and add the self-contribution term.
+ *
+ * This function requires the #hydro_end_density to have been called.
+ *
+ * @param p The particle to act upon.
+ * @param cd #chemistry_data containing chemistry informations.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_end_density(
+    struct part* restrict p, const struct chemistry_data* cd) {}
+
 /**
  * @brief Sets the chemistry properties of the (x-)particles to a valid start
  * state.
diff --git a/src/chemistry/EAGLE/chemistry_iact.h b/src/chemistry/EAGLE/chemistry_iact.h
new file mode 100644
index 0000000000000000000000000000000000000000..a00938e3557e68b0007e1464be2f05baefaf554a
--- /dev/null
+++ b/src/chemistry/EAGLE/chemistry_iact.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2018 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/>.
+ *
+ ******************************************************************************/
+#ifndef SWIFT_EAGLE_CHEMISTRY_IACT_H
+#define SWIFT_EAGLE_CHEMISTRY_IACT_H
+
+/**
+ * @file EAGLE/chemistry_iact.h
+ * @brief Smooth metal interaction functions following the EAGLE model.
+ */
+
+#include "chemistry_struct.h"
+
+/**
+ * @brief Do chemistry computation after the runner_iact_density (symmetric
+ * version)
+ *
+ * @param r2 Distance squared between particles
+ * @param dx Distance between particles
+ * @param hi Smoothing length of i
+ * @param hj Smoothing length of j
+ * @param pi #part i
+ * @param pj #part j
+ */
+__attribute__((always_inline)) INLINE static void runner_iact_chemistry(
+    float r2, float *dx, float hi, float hj, struct part *pi, struct part *pj) {
+}
+
+/**
+ * @brief Do chemistry computation after the runner_iact_density (non-symmetric
+ * version)
+ *
+ * @param r2 Distance squared between particles
+ * @param dx Distance between particles
+ * @param hi Smoothing length of i
+ * @param hj Smoothing length of j
+ * @param pi #part i
+ * @param pj #part j
+ */
+__attribute__((always_inline)) INLINE static void runner_iact_nonsym_chemistry(
+    float r2, float *dx, float hi, float hj, struct part *pi,
+    const struct part *pj) {}
+
+#endif /* SWIFT_EAGLE_CHEMISTRY_IACT_H */
diff --git a/src/chemistry/gear/chemistry.h b/src/chemistry/gear/chemistry.h
index 0718cfd59fd2e86c4eb968241d5418dfd52045d9..5dc7a48939cdb298233abbe358473f59fc7e72f4 100644
--- a/src/chemistry/gear/chemistry.h
+++ b/src/chemistry/gear/chemistry.h
@@ -38,18 +38,17 @@
 #include "units.h"
 
 /**
- * @brief Sets the chemistry properties of the (x-)particles to a valid start
- * state.
- *
- * Nothing to do here.
- *
- * @param p Pointer to the particle data.
- * @param xp Pointer to the extended particle data.
- * @param data The global chemistry information.
+ * @brief Return a string containing the name of a given #chemistry_element.
  */
-__attribute__((always_inline)) INLINE static void chemistry_first_init_part(
-    const struct part* restrict p, struct xpart* restrict xp,
-    const struct chemistry_data* data) {}
+__attribute__((always_inline)) INLINE static const char*
+chemistry_get_element_name(enum chemistry_element elem) {
+
+  static const char* chemistry_element_names[chemistry_element_count] = {
+      "Oxygen",    "Magnesium", "Sulfur", "Iron",    "Zinc",
+      "Strontium", "Yttrium",   "Barium", "Europium"};
+
+  return chemistry_element_names[elem];
+}
 
 /**
  * @brief Initialises the chemistry properties.
@@ -72,7 +71,74 @@ static INLINE void chemistry_init_backend(
  */
 static INLINE void chemistry_print_backend(const struct chemistry_data* data) {
 
-  message("Chemistry function is 'gear'.");
+  message("Chemistry function is 'Gear'.");
+}
+
+/**
+ * @brief Prepares a particle for the smooth metal calculation.
+ *
+ * Zeroes all the relevant arrays in preparation for the sums taking place in
+ * the various smooth metallicity tasks
+ *
+ * @param p The particle to act upon
+ * @param cd #chemistry_data containing chemistry informations.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_init_part(
+    struct part* restrict p, const struct chemistry_data* cd) {
+
+  struct chemistry_part_data* cpd = &p->chemistry_data;
+
+  for (int i = 0; i < chemistry_element_count; i++) {
+    cpd->smoothed_metal_mass_fraction[i] = 0.f;
+  }
+}
+
+/**
+ * @brief Finishes the smooth metal calculation.
+ *
+ * Multiplies the smoothed metallicity and number of neighbours by the
+ * appropiate constants and add the self-contribution term.
+ *
+ * This function requires the #hydro_end_density to have been called.
+ *
+ * @param p The particle to act upon.
+ * @param cd #chemistry_data containing chemistry informations.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_end_density(
+    struct part* restrict p, const struct chemistry_data* cd) {
+
+  /* Some smoothing length multiples. */
+  const float h = p->h;
+  const float h_inv = 1.0f / h;                       /* 1/h */
+  const float factor = pow_dimension(h_inv) / p->rho; /* 1 / h^d * rho */
+  const float m = p->mass;
+
+  struct chemistry_part_data* cpd = &p->chemistry_data;
+
+  for (int i = 0; i < chemistry_element_count; i++) {
+    /* Final operation on the density (add self-contribution). */
+    cpd->smoothed_metal_mass_fraction[i] +=
+        m * cpd->metal_mass_fraction[i] * kernel_root;
+
+    /* Finish the calculation by inserting the missing h-factors */
+    cpd->smoothed_metal_mass_fraction[i] *= factor;
+  }
+}
+
+/**
+ * @brief Sets the chemistry properties of the (x-)particles to a valid start
+ * state.
+ *
+ * Nothing to do here.
+ *
+ * @param p Pointer to the particle data.
+ * @param xp Pointer to the extended particle data.
+ * @param data The global chemistry information.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_first_init_part(
+    struct part* restrict p, struct xpart* restrict xp,
+    const struct chemistry_data* data) {
+  chemistry_init_part(p, data);
 }
 
 #endif /* SWIFT_CHEMISTRY_GEAR_H */
diff --git a/src/chemistry/gear/chemistry_iact.h b/src/chemistry/gear/chemistry_iact.h
new file mode 100644
index 0000000000000000000000000000000000000000..269d33e35fc7a2ba4f93c018c0c942fe99fb944c
--- /dev/null
+++ b/src/chemistry/gear/chemistry_iact.h
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
+ *                    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/>.
+ *
+ ******************************************************************************/
+#ifndef SWIFT_GEAR_CHEMISTRY_IACT_H
+#define SWIFT_GEAR_CHEMISTRY_IACT_H
+
+/**
+ * @file GEAR/chemistry_iact.h
+ * @brief Smooth metal interaction functions following the GEAR version of
+ * smooth metalicity.
+ *
+ * The interactions computed here are the ones presented in Wiersma, Schaye et
+ * al. 2009
+ */
+
+#include "chemistry_struct.h"
+
+/**
+ * @brief do chemistry computation after the runner_iact_density (symmetric
+ * version)
+ *
+ * @param r2 Distance squared between particles
+ * @param dx Distance between particles
+ * @param hi Smoothing length of i
+ * @param hj Smoothing length of j
+ * @param pi #part i
+ * @param pj #part j
+ */
+__attribute__((always_inline)) INLINE static void runner_iact_chemistry(
+    float r2, float *dx, float hi, float hj, struct part *pi, struct part *pj) {
+
+  struct chemistry_part_data *chi = &pi->chemistry_data;
+  struct chemistry_part_data *chj = &pj->chemistry_data;
+
+  float wi, wi_dx;
+  float wj, wj_dx;
+
+  /* Get the masses. */
+  const float mi = pi->mass;
+  const float mj = pj->mass;
+
+  /* Get r */
+  const float r = sqrtf(r2);
+
+  /* Compute the kernel function for pi */
+  const float ui = r / hi;
+  kernel_deval(ui, &wi, &wi_dx);
+
+  /* Compute the kernel function for pj */
+  const float uj = r / hj;
+  kernel_deval(uj, &wj, &wj_dx);
+
+  /* Compute contribution to the smooth metallicity */
+  for (int i = 0; i < chemistry_element_count; i++) {
+    chi->smoothed_metal_mass_fraction[i] +=
+        mj * chj->metal_mass_fraction[i] * wi;
+    chj->smoothed_metal_mass_fraction[i] +=
+        mi * chi->metal_mass_fraction[i] * wj;
+  }
+}
+
+/**
+ * @brief do chemistry computation after the runner_iact_density (non symmetric
+ * version)
+ *
+ * @param r2 Distance squared between particles
+ * @param dx Distance between particles
+ * @param hi Smoothing length of i
+ * @param hj Smoothing length of j
+ * @param pi #part i
+ * @param pj #part j
+ */
+__attribute__((always_inline)) INLINE static void runner_iact_nonsym_chemistry(
+    float r2, float *dx, float hi, float hj, struct part *pi,
+    const struct part *pj) {
+
+  struct chemistry_part_data *chi = &pi->chemistry_data;
+  const struct chemistry_part_data *chj = &pj->chemistry_data;
+
+  float wi, wi_dx;
+
+  /* Get the masses. */
+  const float mj = pj->mass;
+
+  /* Get r */
+  const float r = sqrtf(r2);
+
+  /* Compute the kernel function for pi */
+  const float ui = r / hi;
+  kernel_deval(ui, &wi, &wi_dx);
+
+  /* Compute contribution to the smooth metallicity */
+  for (int i = 0; i < chemistry_element_count; i++) {
+    chi->smoothed_metal_mass_fraction[i] +=
+        mj * chj->metal_mass_fraction[i] * wi;
+  }
+}
+
+#endif /* SWIFT_GEAR_CHEMISTRY_IACT_H */
diff --git a/src/chemistry/gear/chemistry_io.h b/src/chemistry/gear/chemistry_io.h
index 8a6cb2279ce444d47bf732b8f89b5f161dbb6994..81ee8d59f58eef67097b38dec6ce04f7319b04d1 100644
--- a/src/chemistry/gear/chemistry_io.h
+++ b/src/chemistry/gear/chemistry_io.h
@@ -19,6 +19,8 @@
 #ifndef SWIFT_CHEMISTRY_IO_GEAR_H
 #define SWIFT_CHEMISTRY_IO_GEAR_H
 
+#include "chemistry.h"
+#include "chemistry_struct.h"
 #include "io_properties.h"
 
 /**
@@ -32,10 +34,9 @@
 int chemistry_read_particles(struct part* parts, struct io_props* list) {
 
   /* List what we want to read */
-  list[0] =
-      io_make_input_field("HeDensity", FLOAT, 1, COMPULSORY, UNIT_CONV_DENSITY,
-                          parts, chemistry_data.he_density);
-
+  list[0] = io_make_input_field(
+      "ElementAbundance", FLOAT, chemistry_element_count, OPTIONAL,
+      UNIT_CONV_NO_UNITS, parts, chemistry_data.metal_mass_fraction);
   return 1;
 }
 
@@ -50,19 +51,29 @@ int chemistry_read_particles(struct part* parts, struct io_props* list) {
 int chemistry_write_particles(const struct part* parts, struct io_props* list) {
 
   /* List what we want to write */
-  list[0] = io_make_output_field("HeDensity", FLOAT, 1, UNIT_CONV_DENSITY,
-                                 parts, chemistry_data.he_density);
+  list[0] = io_make_output_field(
+      "SmoothedElementAbundance", FLOAT, chemistry_element_count,
+      UNIT_CONV_NO_UNITS, parts, chemistry_data.smoothed_metal_mass_fraction);
 
-  return 1;
+  list[1] = io_make_output_field("ElementAbundance", FLOAT,
+                                 chemistry_element_count, UNIT_CONV_NO_UNITS,
+                                 parts, chemistry_data.metal_mass_fraction);
+
+  return 2;
 }
 
 /**
  * @brief Writes the current model of SPH to the file
- * @param h_grpsph The HDF5 group in which to write
+ * @param h_grp The HDF5 group in which to write
  */
-void chemistry_write_flavour(hid_t h_grpsph) {
+void chemistry_write_flavour(hid_t h_grp) {
 
-  io_write_attribute_s(h_grpsph, "Chemistry Model", "GEAR");
+  io_write_attribute_s(h_grp, "Chemistry Model", "GEAR");
+  for (size_t i = 0; i < chemistry_element_count; i++) {
+    char buffer[20];
+    sprintf(buffer, "Element %lu", i);
+    io_write_attribute_s(h_grp, buffer, chemistry_get_element_name(i));
+  }
 }
 
 #endif /* SWIFT_CHEMISTRY_IO_GEAR_H */
diff --git a/src/chemistry/gear/chemistry_struct.h b/src/chemistry/gear/chemistry_struct.h
index 401a68cdbf09cc59028c66d10833e19a95b5a297..b0ddee2b37c2d1126523ff7a4283f5c18ae3a7b4 100644
--- a/src/chemistry/gear/chemistry_struct.h
+++ b/src/chemistry/gear/chemistry_struct.h
@@ -22,7 +22,18 @@
 /**
  * @brief The individual elements traced in the model.
  */
-enum chemistry_element { chemistry_element_count = 0 };
+enum chemistry_element {
+  chemistry_element_O = 0,
+  chemistry_element_Mg,
+  chemistry_element_S,
+  chemistry_element_Fe,
+  chemistry_element_Zn,
+  chemistry_element_Sr,
+  chemistry_element_Y,
+  chemistry_element_Ba,
+  chemistry_element_Eu,
+  chemistry_element_count
+};
 
 /**
  * @brief Global chemical abundance information.
@@ -33,7 +44,12 @@ struct chemistry_data {};
  * @brief Properties of the chemistry function.
  */
 struct chemistry_part_data {
-  float he_density;
+
+  /*! Fraction of the particle mass in a given element */
+  float metal_mass_fraction[chemistry_element_count];
+
+  /*! Smoothed fraction of the particle mass in a given element */
+  float smoothed_metal_mass_fraction[chemistry_element_count];
 };
 
 #endif /* SWIFT_CHEMISTRY_STRUCT_GEAR_H */
diff --git a/src/chemistry/none/chemistry.h b/src/chemistry/none/chemistry.h
index ec183f7701dd6da0bcea12eff23cad2ee30ab97e..f6f826d580502f3c65bf56480ef0c04ddff1ee37 100644
--- a/src/chemistry/none/chemistry.h
+++ b/src/chemistry/none/chemistry.h
@@ -38,18 +38,15 @@
 #include "units.h"
 
 /**
- * @brief Sets the chemistry properties of the (x-)particles to a valid start
- * state.
- *
- * Nothing to do here.
- *
- * @param p Pointer to the particle data.
- * @param xp Pointer to the extended particle data.
- * @param data The global chemistry information used for this run.
+ * @brief Return a string containing the name of a given #chemistry_element.
  */
-__attribute__((always_inline)) INLINE static void chemistry_first_init_part(
-    const struct part* restrict p, struct xpart* restrict xp,
-    const struct chemistry_data* data) {}
+__attribute__((always_inline)) INLINE static const char*
+chemistry_get_element_name(enum chemistry_element elem) {
+
+  static const char* chemistry_element_names[chemistry_element_count] = {};
+
+  return chemistry_element_names[elem];
+}
 
 /**
  * @brief Initialises the chemistry properties.
@@ -75,4 +72,39 @@ static INLINE void chemistry_print_backend(const struct chemistry_data* data) {
   message("Chemistry function is 'No chemistry'.");
 }
 
+/**
+ * @brief Finishes the density calculation.
+ *
+ * @param p The particle to act upon
+ * @param cd The global chemistry information.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_end_density(
+    struct part* restrict p, const struct chemistry_data* cd) {}
+
+/**
+ * @brief Sets the chemistry properties of the (x-)particles to a valid start
+ * state.
+ *
+ * Nothing to do here.
+ *
+ * @param p Pointer to the particle data.
+ * @param xp Pointer to the extended particle data.
+ * @param data The global chemistry information used for this run.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_first_init_part(
+    const struct part* restrict p, struct xpart* restrict xp,
+    const struct chemistry_data* data) {}
+
+/**
+ * @brief Sets the chemistry properties of the (x-)particles to a valid start
+ * state.
+ *
+ * Nothing to do here.
+ *
+ * @param p Pointer to the particle data.
+ * @param data The global chemistry information.
+ */
+__attribute__((always_inline)) INLINE static void chemistry_init_part(
+    struct part* restrict p, const struct chemistry_data* data) {}
+
 #endif /* SWIFT_CHEMISTRY_NONE_H */
diff --git a/src/chemistry/none/chemistry_iact.h b/src/chemistry/none/chemistry_iact.h
new file mode 100644
index 0000000000000000000000000000000000000000..d963e4310e529f1a0f3202bc1f3ee68f605e811e
--- /dev/null
+++ b/src/chemistry/none/chemistry_iact.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
+ *                    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/>.
+ *
+ ******************************************************************************/
+#ifndef SWIFT_NONE_CHEMISTRY_IACT_H
+#define SWIFT_NONE_CHEMISTRY_IACT_H
+
+/**
+ * @file none/chemistry_iact.h
+ * @brief Density computation
+ */
+
+#include "cache.h"
+#include "chemistry_struct.h"
+#include "minmax.h"
+
+/**
+ * @brief do chemistry computation after the runner_iact_density (symmetric
+ * version)
+ *
+ * @param r2 Distance squared between particles
+ * @param dx Distance between particles
+ * @param hi Smoothing length of i
+ * @param hj Smoothing length of j
+ * @param pi #part i
+ * @param pj #part j
+ */
+__attribute__((always_inline)) INLINE static void runner_iact_chemistry(
+    float r2, float *dx, float hi, float hj, struct part *pi, struct part *pj) {
+}
+
+/**
+ * @brief do chemistry computation after the runner_iact_density (non symmetric
+ * version)
+ *
+ * @param r2 Distance squared between particles
+ * @param dx Distance between particles
+ * @param hi Smoothing length of i
+ * @param hj Smoothing length of j
+ * @param pi #part i
+ * @param pj #part j
+ */
+__attribute__((always_inline)) INLINE static void runner_iact_nonsym_chemistry(
+    float r2, float *dx, float hi, float hj, struct part *pi,
+    const struct part *pj) {}
+
+#endif /* SWIFT_NONE_CHEMISTRY_IACT_H */
diff --git a/src/clocks.c b/src/clocks.c
index 4b8b269143bb3dba606c77a00eaf12b3b614eb8f..fbaa83f15fafda23751d5d6c34d40750132287b5 100644
--- a/src/clocks.c
+++ b/src/clocks.c
@@ -45,7 +45,7 @@ static unsigned long long clocks_cpufreq = 0;
 static ticks clocks_start = 0;
 
 /* The units of any returned times. */
-static char *clocks_units[] = {"ms", "~ms"};
+static const char *clocks_units[] = {"ms", "~ms"};
 static int clocks_units_index = 0;
 static double clocks_units_scale = 1000.0;
 
diff --git a/src/common_io.c b/src/common_io.c
index 7d0b0cb3ef026eb7bbbe17b82fb072f83c395305..22e5fd9289cdca52435c001be7a26105b9e5ca80 100644
--- a/src/common_io.c
+++ b/src/common_io.c
@@ -142,7 +142,7 @@ int io_is_double_precision(enum IO_DATA_TYPE type) {
  *
  * Calls #error() if an error occurs.
  */
-void io_read_attribute(hid_t grp, char* name, enum IO_DATA_TYPE type,
+void io_read_attribute(hid_t grp, const char* name, enum IO_DATA_TYPE type,
                        void* data) {
   hid_t h_attr = 0, h_err = 0;
 
@@ -173,7 +173,7 @@ void io_read_attribute(hid_t grp, char* name, enum IO_DATA_TYPE type,
 void io_write_attribute(hid_t grp, const char* name, enum IO_DATA_TYPE type,
                         void* data, int num) {
   hid_t h_space = 0, h_attr = 0, h_err = 0;
-  hsize_t dim[1] = {num};
+  hsize_t dim[1] = {(hsize_t)num};
 
   h_space = H5Screate(H5S_SIMPLE);
   if (h_space < 0) {
@@ -418,7 +418,7 @@ void io_copy_mapper(void* restrict temp, int N, void* restrict extra_data) {
   const size_t copySize = typeSize * props.dimension;
 
   /* How far are we with this chunk? */
-  char* restrict temp_c = temp;
+  char* restrict temp_c = (char*)temp;
   const ptrdiff_t delta = (temp_c - props.start_temp_c) / copySize;
 
   for (int k = 0; k < N; k++) {
@@ -440,7 +440,7 @@ void io_convert_part_f_mapper(void* restrict temp, int N,
   const size_t dim = props.dimension;
 
   /* How far are we with this chunk? */
-  float* restrict temp_f = temp;
+  float* restrict temp_f = (float*)temp;
   const ptrdiff_t delta = (temp_f - props.start_temp_f) / dim;
 
   for (int i = 0; i < N; i++)
@@ -460,7 +460,7 @@ void io_convert_part_d_mapper(void* restrict temp, int N,
   const size_t dim = props.dimension;
 
   /* How far are we with this chunk? */
-  double* restrict temp_d = temp;
+  double* restrict temp_d = (double*)temp;
   const ptrdiff_t delta = (temp_d - props.start_temp_d) / dim;
 
   for (int i = 0; i < N; i++)
@@ -480,7 +480,7 @@ void io_convert_gpart_f_mapper(void* restrict temp, int N,
   const size_t dim = props.dimension;
 
   /* How far are we with this chunk? */
-  float* restrict temp_f = temp;
+  float* restrict temp_f = (float*)temp;
   const ptrdiff_t delta = (temp_f - props.start_temp_f) / dim;
 
   for (int i = 0; i < N; i++)
@@ -500,7 +500,7 @@ void io_convert_gpart_d_mapper(void* restrict temp, int N,
   const size_t dim = props.dimension;
 
   /* How far are we with this chunk? */
-  double* restrict temp_d = temp;
+  double* restrict temp_d = (double*)temp;
   const ptrdiff_t delta = (temp_d - props.start_temp_d) / dim;
 
   for (int i = 0; i < N; i++)
@@ -531,7 +531,7 @@ void io_copy_temp_buffer(void* temp, const struct engine* e,
   if (props.conversion == 0) { /* No conversion */
 
     /* Prepare some parameters */
-    char* temp_c = temp;
+    char* temp_c = (char*)temp;
     props.start_temp_c = temp_c;
 
     /* Copy the whole thing into a buffer */
@@ -543,8 +543,8 @@ void io_copy_temp_buffer(void* temp, const struct engine* e,
     if (props.convert_part_f != NULL) {
 
       /* Prepare some parameters */
-      float* temp_f = temp;
-      props.start_temp_f = temp;
+      float* temp_f = (float*)temp;
+      props.start_temp_f = (float*)temp;
       props.e = e;
 
       /* Copy the whole thing into a buffer */
@@ -555,8 +555,8 @@ void io_copy_temp_buffer(void* temp, const struct engine* e,
     } else if (props.convert_part_d != NULL) {
 
       /* Prepare some parameters */
-      double* temp_d = temp;
-      props.start_temp_d = temp;
+      double* temp_d = (double*)temp;
+      props.start_temp_d = (double*)temp;
       props.e = e;
 
       /* Copy the whole thing into a buffer */
@@ -567,8 +567,8 @@ void io_copy_temp_buffer(void* temp, const struct engine* e,
     } else if (props.convert_gpart_f != NULL) {
 
       /* Prepare some parameters */
-      float* temp_f = temp;
-      props.start_temp_f = temp;
+      float* temp_f = (float*)temp;
+      props.start_temp_f = (float*)temp;
       props.e = e;
 
       /* Copy the whole thing into a buffer */
@@ -579,8 +579,8 @@ void io_copy_temp_buffer(void* temp, const struct engine* e,
     } else if (props.convert_gpart_d != NULL) {
 
       /* Prepare some parameters */
-      double* temp_d = temp;
-      props.start_temp_d = temp;
+      double* temp_d = (double*)temp;
+      props.start_temp_d = (double*)temp;
       props.e = e;
 
       /* Copy the whole thing into a buffer */
@@ -601,10 +601,12 @@ void io_copy_temp_buffer(void* temp, const struct engine* e,
     /* message("Converting ! factor=%e", factor); */
 
     if (io_is_double_precision(props.type)) {
-      swift_declare_aligned_ptr(double, temp_d, temp, IO_BUFFER_ALIGNMENT);
+      swift_declare_aligned_ptr(double, temp_d, (double*)temp,
+                                IO_BUFFER_ALIGNMENT);
       for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
     } else {
-      swift_declare_aligned_ptr(float, temp_f, temp, IO_BUFFER_ALIGNMENT);
+      swift_declare_aligned_ptr(float, temp_f, (float*)temp,
+                                IO_BUFFER_ALIGNMENT);
       for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
     }
   }
diff --git a/src/common_io.h b/src/common_io.h
index d37b52a13a1420fb325b054de13a62bbc4ad17aa..c317238160e45a9d141619d313e47c715adf8537 100644
--- a/src/common_io.h
+++ b/src/common_io.h
@@ -60,7 +60,7 @@ hid_t io_hdf5_type(enum IO_DATA_TYPE type);
 size_t io_sizeof_type(enum IO_DATA_TYPE type);
 int io_is_double_precision(enum IO_DATA_TYPE type);
 
-void io_read_attribute(hid_t grp, char* name, enum IO_DATA_TYPE type,
+void io_read_attribute(hid_t grp, const char* name, enum IO_DATA_TYPE type,
                        void* data);
 
 void io_write_attribute(hid_t grp, const char* name, enum IO_DATA_TYPE type,
diff --git a/src/const.h b/src/const.h
index dd7e1e267246c0f73e760191a071c6e24b96cfe8..85d64f5f3bf97b3f6ca6df8f230e0e0990687d34 100644
--- a/src/const.h
+++ b/src/const.h
@@ -68,7 +68,7 @@
 #define GIZMO_UNPHYSICAL_RESCUE
 /* Show a warning message if an unphysical value was reset (only works if
    GIZMO_UNPHYSICAL_RESCUE is also selected). */
-//#define GIZMO_UNPHYSICAL_WARNING
+#define GIZMO_UNPHYSICAL_WARNING
 
 /* Parameters that control how GIZMO handles pathological particle
    configurations. */
diff --git a/src/cycle.h b/src/cycle.h
index 4925808f5a4c4ea7828bc1a6b7a9490d2d2ca255..f220ecd120b14db0a8cdaf5d1105be4bd0e70831 100644
--- a/src/cycle.h
+++ b/src/cycle.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2003, 2007-8 Matteo Frigo
- * Copyright (c) 2003, 2007-8 Massachusetts Institute of Technology
+ * Copyright (c) 2003, 2007-14 Matteo Frigo
+ * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -179,14 +179,7 @@ INLINE_ELAPSED(__inline__)
     !defined(HAVE_TICK_COUNTER)
 typedef unsigned long long ticks;
 
-#ifndef INLINE
-#if __GNUC__ && !__GNUC_STDC_INLINE__
-#define INLINE extern inline
-#else
-#define INLINE inline
-#endif
-#endif
-INLINE static ticks getticks(void) {
+static __inline__ ticks getticks(void) {
   ticks ret;
 
   __asm__ __volatile__("rdtsc" : "=A"(ret));
@@ -210,8 +203,9 @@ static __inline ticks getticks(void) {
   ticks retval;
 
   __asm {
-    RDTSC
-    mov retval.HighPart, edx mov retval.LowPart, eax
+	  RDTSC
+	  mov retval.HighPart, edx
+	  mov retval.LowPart, eax
   }
   return retval;
 }
@@ -232,22 +226,16 @@ static __inline double elapsed(ticks t1, ticks t0) {
     defined(__x86_64__) && !defined(HAVE_TICK_COUNTER)
 typedef unsigned long long ticks;
 
-#ifndef INLINE
-#if __GNUC__ && !__GNUC_STDC_INLINE__
-#define INLINE extern inline
-#else
-#define INLINE inline
-#endif
-#endif
-INLINE static ticks getticks(void) {
+static __inline__ ticks getticks(void) {
   unsigned a, d;
-  asm volatile("rdtsc" : "=a"(a), "=d"(d));
+  __asm__ __volatile__("rdtsc" : "=a"(a), "=d"(d));
   return ((ticks)a) | (((ticks)d) << 32);
 }
 
 INLINE_ELAPSED(__inline__)
 
 #define HAVE_TICK_COUNTER
+#define TIME_MIN 5000.0
 #endif
 
 /* PGI compiler, courtesy Cristiano Calonaci, Andrea Tarsi, & Roberto Gori.
@@ -260,6 +248,7 @@ static ticks getticks(void) {
 }
 INLINE_ELAPSED(__inline__)
 #define HAVE_TICK_COUNTER
+#define TIME_MIN 5000.0
 #endif
 
 /* Visual C++, courtesy of Dirk Michaelis */
@@ -273,6 +262,7 @@ typedef unsigned __int64 ticks;
 INLINE_ELAPSED(__inline)
 
 #define HAVE_TICK_COUNTER
+#define TIME_MIN 5000.0
 #endif
 
 /*----------------------------------------------------------------*/
@@ -352,7 +342,7 @@ INLINE_ELAPSED(inline)
 /*
  * PA-RISC cycle counter
  */
-#if defined(__hppa__) || defined(__hppa) && !defined(HAVE_TICK_COUNTER)
+#if (defined(__hppa__) || defined(__hppa)) && !defined(HAVE_TICK_COUNTER)
 typedef unsigned long ticks;
 
 #ifdef __GNUC__
@@ -445,7 +435,7 @@ INLINE_ELAPSED(__inline)
 /*----------------------------------------------------------------*/
 /* SGI/Irix */
 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE) && \
-    !defined(HAVE_TICK_COUNTER)
+    !defined(HAVE_TICK_COUNTER) && !defined(__ANDROID__)
 typedef struct timespec ticks;
 
 static inline ticks getticks(void) {
@@ -517,3 +507,37 @@ INLINE_ELAPSED(inline)
 #define HAVE_TICK_COUNTER
 #endif
 #endif /* HAVE_MIPS_ZBUS_TIMER */
+
+#if defined(HAVE_ARMV7A_CNTVCT)
+typedef uint64_t ticks;
+static inline ticks getticks(void) {
+  uint32_t Rt, Rt2 = 0;
+  asm volatile("mrrc p15, 1, %0, %1, c14" : "=r"(Rt), "=r"(Rt2));
+  return ((uint64_t)Rt) | (((uint64_t)Rt2) << 32);
+}
+INLINE_ELAPSED(inline)
+#define HAVE_TICK_COUNTER
+#endif
+
+#if defined(__aarch64__) && defined(HAVE_ARMV8_CNTVCT_EL0) && \
+    !defined(HAVE_ARMV8CC)
+typedef uint64_t ticks;
+static inline ticks getticks(void) {
+  uint64_t Rt;
+  asm volatile("mrs %0,  CNTVCT_EL0" : "=r"(Rt));
+  return Rt;
+}
+INLINE_ELAPSED(inline)
+#define HAVE_TICK_COUNTER
+#endif
+
+#if defined(__aarch64__) && defined(HAVE_ARMV8CC)
+typedef uint64_t ticks;
+static inline ticks getticks(void) {
+  uint64_t cc = 0;
+  asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(cc));
+  return cc;
+}
+INLINE_ELAPSED(inline)
+#define HAVE_TICK_COUNTER
+#endif
diff --git a/src/engine.c b/src/engine.c
index ffae3ef1de11f3714f8ab417b7cca6bb24e7a25e..f4a51ff70d8fe8332eae053dec7c25f02791ea2e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2070,7 +2070,8 @@ void engine_exchange_proxy_multipoles(struct engine *e) {
 
   /* Also allocate the MPI requests */
   const int count_requests = count_send_requests + count_recv_requests;
-  MPI_Request *requests = malloc(sizeof(MPI_Request) * count_requests);
+  MPI_Request *requests =
+      (MPI_Request *)malloc(sizeof(MPI_Request) * count_requests);
   if (requests == NULL) error("Unable to allocate memory for MPI requests");
 
   int this_request = 0;
@@ -2121,7 +2122,7 @@ void engine_exchange_proxy_multipoles(struct engine *e) {
   }
 
   /* Wait for all the requests to arrive home */
-  MPI_Status *stats = malloc(count_requests * sizeof(MPI_Status));
+  MPI_Status *stats = (MPI_Status *)malloc(count_requests * sizeof(MPI_Status));
   int res;
   if ((res = MPI_Waitall(count_requests, requests, stats)) != MPI_SUCCESS) {
     for (int k = 0; k < count_requests; ++k) {
@@ -2311,7 +2312,8 @@ void engine_make_self_gravity_tasks(struct engine *e) {
                                           task_subtype_none, 0, 0, NULL, NULL);
 
     /* Create a grid of ghosts to deal with the dependencies */
-    if ((ghosts = malloc(n_ghosts * sizeof(struct task *))) == 0)
+    if ((ghosts = (struct task **)malloc(n_ghosts * sizeof(struct task *))) ==
+        0)
       error("Error allocating memory for gravity fft ghosts");
 
     /* Make the ghosts implicit and add the dependencies */
@@ -3022,7 +3024,8 @@ void engine_maketasks(struct engine *e) {
     e->size_links += s->tot_cells * self_grav_tasks_per_cell;
 
   /* Allocate the new list */
-  if ((e->links = malloc(sizeof(struct link) * e->size_links)) == NULL)
+  if ((e->links = (struct link *)malloc(sizeof(struct link) * e->size_links)) ==
+      NULL)
     error("Failed to allocate cell-task links.");
   e->nr_links = 0;
 
@@ -3489,7 +3492,7 @@ int engine_marktasks(struct engine *e) {
   int rebuild_space = 0;
 
   /* Run through the tasks and mark as skip or not. */
-  size_t extra_data[3] = {(size_t)e, rebuild_space, (size_t)&e->sched};
+  size_t extra_data[3] = {(size_t)e, (size_t)rebuild_space, (size_t)&e->sched};
   threadpool_map(&e->threadpool, engine_marktasks_mapper, s->tasks, s->nr_tasks,
                  sizeof(struct task), 0, extra_data);
   rebuild_space = extra_data[1];
@@ -5211,7 +5214,7 @@ void engine_init(
   parser_get_param_string(params, "Snapshots:basename", e->snapshotBaseName);
   e->snapshotCompression =
       parser_get_opt_param_int(params, "Snapshots:compression", 0);
-  e->snapshotUnits = malloc(sizeof(struct unit_system));
+  e->snapshotUnits = (struct unit_system *)malloc(sizeof(struct unit_system));
   units_init_default(e->snapshotUnits, params, "Snapshots", internal_units);
   e->snapshotOutputCount = 0;
   e->dt_min = parser_get_param_double(params, "TimeIntegration:dt_min");
@@ -5312,7 +5315,7 @@ void engine_config(int restart, struct engine *e,
   if (nr_cores > CPU_SETSIZE) /* Unlikely, except on e.g. SGI UV. */
     error("must allocate dynamic cpu_set_t (too many cores per node)");
 
-  char *buf = malloc((nr_cores + 1) * sizeof(char));
+  char *buf = (char *)malloc((nr_cores + 1) * sizeof(char));
   buf[nr_cores] = '\0';
   for (int j = 0; j < nr_cores; ++j) {
     /* Reversed bit order from convention, but same as e.g. Intel MPI's
@@ -5327,7 +5330,7 @@ void engine_config(int restart, struct engine *e,
 
   if (with_aff) {
 
-    cpuid = malloc(nr_affinity_cores * sizeof(int));
+    cpuid = (int *)malloc(nr_affinity_cores * sizeof(int));
 
     int skip = 0;
     for (int k = 0; k < nr_affinity_cores; k++) {
@@ -5345,7 +5348,7 @@ void engine_config(int restart, struct engine *e,
         if (nodeID == 0) message("prefer NUMA-distant CPUs");
 
         /* Get list of numa nodes of all available cores. */
-        int *nodes = malloc(nr_affinity_cores * sizeof(int));
+        int *nodes = (int *)malloc(nr_affinity_cores * sizeof(int));
         int nnodes = 0;
         for (int i = 0; i < nr_affinity_cores; i++) {
           nodes[i] = numa_node_of_cpu(cpuid[i]);
@@ -5354,7 +5357,7 @@ void engine_config(int restart, struct engine *e,
         nnodes += 1;
 
         /* Count cores per node. */
-        int *core_counts = malloc(nnodes * sizeof(int));
+        int *core_counts = (int *)malloc(nnodes * sizeof(int));
         for (int i = 0; i < nr_affinity_cores; i++) {
           core_counts[nodes[i]] = 0;
         }
@@ -5363,7 +5366,7 @@ void engine_config(int restart, struct engine *e,
         }
 
         /* Index cores within each node. */
-        int *core_indices = malloc(nr_affinity_cores * sizeof(int));
+        int *core_indices = (int *)malloc(nr_affinity_cores * sizeof(int));
         for (int i = nr_affinity_cores - 1; i >= 0; i--) {
           core_indices[i] = core_counts[nodes[i]];
           core_counts[nodes[i]] -= 1;
@@ -5437,7 +5440,7 @@ void engine_config(int restart, struct engine *e,
   if (e->nodeID == 0) {
 
     /* When restarting append to these files. */
-    char *mode;
+    const char *mode;
     if (restart)
       mode = "a";
     else
@@ -5849,53 +5852,60 @@ void engine_struct_restore(struct engine *e, FILE *stream) {
 
   /* Now for the other pointers, these use their own restore functions. */
   /* Note all this memory leaks, but is used once. */
-  struct space *s = malloc(sizeof(struct space));
+  struct space *s = (struct space *)malloc(sizeof(struct space));
   space_struct_restore(s, stream);
   e->s = s;
   s->e = e;
 
-  struct unit_system *us = malloc(sizeof(struct unit_system));
+  struct unit_system *us =
+      (struct unit_system *)malloc(sizeof(struct unit_system));
   units_struct_restore(us, stream);
   e->internal_units = us;
 
-  us = malloc(sizeof(struct unit_system));
+  us = (struct unit_system *)malloc(sizeof(struct unit_system));
   units_struct_restore(us, stream);
   e->snapshotUnits = us;
 
 #ifdef WITH_MPI
-  struct repartition *reparttype = malloc(sizeof(struct repartition));
+  struct repartition *reparttype =
+      (struct repartition *)malloc(sizeof(struct repartition));
   partition_struct_restore(reparttype, stream);
   e->reparttype = reparttype;
 #endif
 
-  struct phys_const *physical_constants = malloc(sizeof(struct phys_const));
+  struct phys_const *physical_constants =
+      (struct phys_const *)malloc(sizeof(struct phys_const));
   phys_const_struct_restore(physical_constants, stream);
   e->physical_constants = physical_constants;
 
-  struct hydro_props *hydro_properties = malloc(sizeof(struct hydro_props));
+  struct hydro_props *hydro_properties =
+      (struct hydro_props *)malloc(sizeof(struct hydro_props));
   hydro_props_struct_restore(hydro_properties, stream);
   e->hydro_properties = hydro_properties;
 
   struct gravity_props *gravity_properties =
-      malloc(sizeof(struct gravity_props));
+      (struct gravity_props *)malloc(sizeof(struct gravity_props));
   gravity_props_struct_restore(gravity_properties, stream);
   e->gravity_properties = gravity_properties;
 
   struct external_potential *external_potential =
-      malloc(sizeof(struct external_potential));
+      (struct external_potential *)malloc(sizeof(struct external_potential));
   potential_struct_restore(external_potential, stream);
   e->external_potential = external_potential;
 
   struct cooling_function_data *cooling_func =
-      malloc(sizeof(struct cooling_function_data));
+      (struct cooling_function_data *)malloc(
+          sizeof(struct cooling_function_data));
   cooling_struct_restore(cooling_func, stream);
   e->cooling_func = cooling_func;
 
-  struct sourceterms *sourceterms = malloc(sizeof(struct sourceterms));
+  struct sourceterms *sourceterms =
+      (struct sourceterms *)malloc(sizeof(struct sourceterms));
   sourceterms_struct_restore(sourceterms, stream);
   e->sourceterms = sourceterms;
 
-  struct swift_params *parameter_file = malloc(sizeof(struct swift_params));
+  struct swift_params *parameter_file =
+      (struct swift_params *)malloc(sizeof(struct swift_params));
   parser_struct_restore(parameter_file, stream);
   e->parameter_file = parameter_file;
 
diff --git a/src/gravity_cache.h b/src/gravity_cache.h
index 097e4e1cb36e74ddb548fb3ab74196dd66512e6e..d46dc3cb1f307aee0b5c7352ea3c5b27b640cfdc 100644
--- a/src/gravity_cache.h
+++ b/src/gravity_cache.h
@@ -187,8 +187,9 @@ __attribute__((always_inline)) INLINE static void gravity_cache_populate(
 
   /* Particles used for padding should get impossible positions
    * that have a reasonable magnitude. We use the cell width for this */
-  const float pos_padded[3] = {-2. * cell->width[0], -2. * cell->width[1],
-                               -2. * cell->width[2]};
+  const float pos_padded[3] = {-2.f * (float)cell->width[0],
+                               -2.f * (float)cell->width[1],
+                               -2.f * (float)cell->width[2]};
   const float eps_padded = epsilon[0];
 
   /* Pad the caches */
@@ -247,8 +248,9 @@ gravity_cache_populate_no_mpole(timebin_t max_active_bin,
 
   /* Particles used for padding should get impossible positions
    * that have a reasonable magnitude. We use the cell width for this */
-  const float pos_padded[3] = {-2. * cell->width[0], -2. * cell->width[1],
-                               -2. * cell->width[2]};
+  const float pos_padded[3] = {-2.f * (float)cell->width[0],
+                               -2.f * (float)cell->width[1],
+                               -2.f * (float)cell->width[2]};
   const float eps_padded = epsilon[0];
 
   /* Pad the caches */
diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h
index a7ccde6a9bcd2ea87e16b89e07bcb4782e7044ad..b8c2c5e405e116acf5632b42b3b5fb60ae3e0d4e 100644
--- a/src/hydro/Gizmo/hydro.h
+++ b/src/hydro/Gizmo/hydro.h
@@ -645,18 +645,6 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra(
     /* Make sure the gpart knows the mass has changed. */
     p->gpart->mass = p->conserved.mass;
 
-#if !defined(EOS_ISOTHERMAL_GAS)
-    /* 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]);
-
-    p->conserved.energy += dt * (a_grav[0] * p->gravity.mflux[0] +
-                                 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. */
diff --git a/src/hydro_space.c b/src/hydro_space.c
index c4a6f9c1495a44050c5477ebfdf0bb76a64bfc51..442945caf83a692efadf7755ebf463ebde38e0a4 100644
--- a/src/hydro_space.c
+++ b/src/hydro_space.c
@@ -47,6 +47,5 @@ __attribute__((always_inline)) INLINE void hydro_space_init(
   }
 }
 #else
-__attribute__((always_inline)) INLINE void hydro_space_init(
-    struct hydro_space *hs, const struct space *s) {}
+void hydro_space_init(struct hydro_space *hs, const struct space *s) {}
 #endif
diff --git a/src/inline.h b/src/inline.h
index 538f6f520c9d6187dc02f1cbd5d59480aac7bdb2..7477153b5ba3b3a42a63982292909dd3f3a396d0 100644
--- a/src/inline.h
+++ b/src/inline.h
@@ -27,11 +27,15 @@
  * @brief Defines inline
  */
 #ifndef INLINE
+#ifdef __cplusplus
+#define INLINE inline
+#else
 #if __GNUC__ && !__GNUC_STDC_INLINE__
 #define INLINE extern inline
 #else
 #define INLINE inline
 #endif
 #endif
+#endif
 
 #endif /* SWIFT_INLINE_H */
diff --git a/src/io_properties.h b/src/io_properties.h
index 7afd22a7dc5cb81571e098e7d1b4a1b1efc30682..17db123ba8325ede0c7af4e4b005e359cace7a7f 100644
--- a/src/io_properties.h
+++ b/src/io_properties.h
@@ -113,7 +113,7 @@ struct io_props {
  * Do not call this function directly. Use the macro defined above.
  */
 INLINE static struct io_props io_make_input_field_(
-    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
+    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
     enum DATA_IMPORTANCE importance, enum unit_conversion_factor units,
     char* field, size_t partSize) {
   struct io_props r;
@@ -155,7 +155,7 @@ INLINE static struct io_props io_make_input_field_(
  * Do not call this function directly. Use the macro defined above.
  */
 INLINE static struct io_props io_make_output_field_(
-    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
+    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
     enum unit_conversion_factor units, char* field, size_t partSize) {
   struct io_props r;
   strcpy(r.name, name);
@@ -198,7 +198,7 @@ INLINE static struct io_props io_make_output_field_(
  * Do not call this function directly. Use the macro defined above.
  */
 INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
-    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
+    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
     enum unit_conversion_factor units, size_t partSize,
     const struct part* parts, conversion_func_part_float functionPtr) {
 
@@ -235,7 +235,7 @@ INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
  * Do not call this function directly. Use the macro defined above.
  */
 INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
-    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
+    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
     enum unit_conversion_factor units, size_t partSize,
     const struct part* parts, conversion_func_part_double functionPtr) {
 
@@ -280,7 +280,7 @@ INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
  * Do not call this function directly. Use the macro defined above.
  */
 INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
-    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
+    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
     enum unit_conversion_factor units, size_t gpartSize,
     const struct gpart* gparts, conversion_func_gpart_float functionPtr) {
 
@@ -317,7 +317,7 @@ INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
  * Do not call this function directly. Use the macro defined above.
  */
 INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE(
-    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
+    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
     enum unit_conversion_factor units, size_t gpartSize,
     const struct gpart* gparts, conversion_func_gpart_double functionPtr) {
 
diff --git a/src/logger.c b/src/logger.c
index 0e0bc930c0841f985da2c353357a69b69aba5d91..38cb220b94dd14680584e9edca75883e1df16907 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -108,7 +108,7 @@ void logger_log_part(struct part *p, unsigned int mask, size_t *offset,
 
   /* Allocate a chunk of memory in the dump of the right size. */
   size_t offset_new;
-  char *buff = dump_get(dump, size, &offset_new);
+  char *buff = (char *)dump_get(dump, size, &offset_new);
 
   /* Write the header. */
   uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffULL) |
@@ -192,7 +192,7 @@ void logger_log_gpart(struct gpart *p, unsigned int mask, size_t *offset,
 
   /* Allocate a chunk of memory in the dump of the right size. */
   size_t offset_new;
-  char *buff = dump_get(dump, size, &offset_new);
+  char *buff = (char *)dump_get(dump, size, &offset_new);
 
   /* Write the header. */
   uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffULL) |
@@ -244,7 +244,7 @@ void logger_log_timestamp(unsigned long long int timestamp, size_t *offset,
 
   /* Allocate a chunk of memory in the dump of the right size. */
   size_t offset_new;
-  char *buff = dump_get(dump, size, &offset_new);
+  char *buff = (char *)dump_get(dump, size, &offset_new);
 
   /* Write the header. */
   uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffULL) |
diff --git a/src/parallel_io.c b/src/parallel_io.c
index 11d6db69654efd01f60371390f3fefb6ee408715..315c187e65f1a30b0401cb9368944f8f9968223a 100644
--- a/src/parallel_io.c
+++ b/src/parallel_io.c
@@ -128,16 +128,16 @@ void readArray_chunk(hid_t h_data, hid_t h_plist_id,
     /* message("Converting ! factor=%e", factor); */
 
     if (io_is_double_precision(props.type)) {
-      double* temp_d = temp;
+      double* temp_d = (double*)temp;
       for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
     } else {
-      float* temp_f = temp;
+      float* temp_f = (float*)temp;
       for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
     }
   }
 
   /* Copy temporary buffer to particle data */
-  char* temp_c = temp;
+  char* temp_c = (char*)temp;
   for (size_t i = 0; i < N; ++i)
     memcpy(props.field + i * props.partSize, &temp_c[i * copySize], copySize);
 
@@ -279,7 +279,7 @@ void prepareArray(struct engine* e, hid_t grp, char* fileName, FILE* xmfFile,
   }
 
   /* Make sure the chunks are not larger than the dataset */
-  if ((long long) chunk_shape[0] > N_total) chunk_shape[0] = N_total;
+  if ((long long)chunk_shape[0] > N_total) chunk_shape[0] = N_total;
 
   /* Change shape of data space */
   hid_t h_err = H5Sset_extent_simple(h_space, rank, shape, NULL);
@@ -640,7 +640,8 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
   H5Gclose(h_grp);
 
   /* Read the unit system used in the ICs */
-  struct unit_system* ic_units = malloc(sizeof(struct unit_system));
+  struct unit_system* ic_units =
+      (struct unit_system*)malloc(sizeof(struct unit_system));
   if (ic_units == NULL) error("Unable to allocate memory for IC unit system");
   io_read_unit_system(h_file, ic_units, mpi_rank);
 
@@ -683,7 +684,7 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
   /* Allocate memory to store SPH particles */
   if (with_hydro) {
     *Ngas = N[0];
-    if (posix_memalign((void*)parts, part_align,
+    if (posix_memalign((void**)parts, part_align,
                        (*Ngas) * sizeof(struct part)) != 0)
       error("Error while allocating memory for particles");
     bzero(*parts, *Ngas * sizeof(struct part));
@@ -692,7 +693,7 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
   /* Allocate memory to store star particles */
   if (with_stars) {
     *Nstars = N[swift_type_star];
-    if (posix_memalign((void*)sparts, spart_align,
+    if (posix_memalign((void**)sparts, spart_align,
                        *Nstars * sizeof(struct spart)) != 0)
       error("Error while allocating memory for star particles");
     bzero(*sparts, *Nstars * sizeof(struct spart));
@@ -704,7 +705,7 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
     *Ngparts = (with_hydro ? N[swift_type_gas] : 0) +
                N[swift_type_dark_matter] +
                (with_stars ? N[swift_type_star] : 0);
-    if (posix_memalign((void*)gparts, gpart_align,
+    if (posix_memalign((void**)gparts, gpart_align,
                        *Ngparts * sizeof(struct gpart)) != 0)
       error("Error while allocating memory for gravity particles");
     bzero(*gparts, *Ngparts * sizeof(struct gpart));
@@ -1199,7 +1200,7 @@ void write_output_parallel(struct engine* e, const char* baseName,
 
       case swift_type_dark_matter:
         /* Allocate temporary array */
-        if (posix_memalign((void*)&dmparts, gpart_align,
+        if (posix_memalign((void**)&dmparts, gpart_align,
                            Ndm * sizeof(struct gpart)) != 0)
           error(
               "Error while allocating temporart memory for "
diff --git a/src/parser.c b/src/parser.c
index cbd63e913010066cbd39418b81609f4669404213..af9ef5fd6b7228dd4ad96640b59322175586862b 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -110,9 +110,9 @@ void parser_set_param(struct swift_params *params, const char *namevalue) {
   value[0] = '\0';
 
   /* Name is part until second colon. */
-  char *p1 = strchr(namevalue, ':');
+  const char *p1 = strchr(namevalue, ':');
   if (p1 != NULL) {
-    char *p2 = strchr(p1 + 1, ':');
+    const char *p2 = strchr(p1 + 1, ':');
     if (p2 != NULL) {
       memcpy(name, namevalue, p2 - namevalue);
       name[p2 - namevalue] = '\0';
diff --git a/src/partition.c b/src/partition.c
index b46172d859e1e19221ee86ecf2c28650715281ef..8203c255d484672254b249042db22f5952579b4e 100644
--- a/src/partition.c
+++ b/src/partition.c
@@ -442,7 +442,8 @@ static void pick_metis(struct space *s, int nregions, double *vertexw,
    * of old and new ranks. Each element of the array has a cell count and
    * an unique index so we can sort into decreasing counts. */
   int indmax = nregions * nregions;
-  struct indexval *ivs = malloc(sizeof(struct indexval) * indmax);
+  struct indexval *ivs =
+      (struct indexval *)malloc(sizeof(struct indexval) * indmax);
   bzero(ivs, sizeof(struct indexval) * indmax);
   for (int k = 0; k < ncells; k++) {
     int index = regionid[k] + nregions * s->cells_top[k].nodeID;
@@ -453,8 +454,8 @@ static void pick_metis(struct space *s, int nregions, double *vertexw,
 
   /* Go through the ivs using the largest counts first, these are the
    * regions with the most cells in common, old partition to new. */
-  int *oldmap = malloc(sizeof(int) * nregions);
-  int *newmap = malloc(sizeof(int) * nregions);
+  int *oldmap = (int *)malloc(sizeof(int) * nregions);
+  int *newmap = (int *)malloc(sizeof(int) * nregions);
   for (int k = 0; k < nregions; k++) {
     oldmap[k] = -1;
     newmap[k] = -1;
@@ -1267,7 +1268,7 @@ int partition_space_to_space(double *oldh, double *oldcdim, int *oldnodeIDs,
  */
 void partition_store_celllist(struct space *s, struct repartition *reparttype) {
   if (reparttype->celllist != NULL) free(reparttype->celllist);
-  reparttype->celllist = malloc(sizeof(int) * s->nr_cells);
+  reparttype->celllist = (int *)malloc(sizeof(int) * s->nr_cells);
   reparttype->ncelllist = s->nr_cells;
   if (reparttype->celllist == NULL) error("Failed to allocate celllist");
 
@@ -1333,7 +1334,7 @@ void partition_struct_restore(struct repartition *reparttype, FILE *stream) {
 
   /* Also restore the celllist, if we have one. */
   if (reparttype->ncelllist > 0) {
-    reparttype->celllist = malloc(sizeof(int) * reparttype->ncelllist);
+    reparttype->celllist = (int *)malloc(sizeof(int) * reparttype->ncelllist);
     if (reparttype->celllist == NULL) error("Failed to allocate celllist");
     restart_read_blocks(reparttype->celllist,
                         sizeof(int) * reparttype->ncelllist, 1, stream, NULL,
diff --git a/src/physical_constants.c b/src/physical_constants.c
index b70b80574e7f73fe3568e18f0809350548564c4b..b1dbeaeecfbf2e056a68b7866766bb07efb5efba 100644
--- a/src/physical_constants.c
+++ b/src/physical_constants.c
@@ -32,10 +32,14 @@
 /**
  * @brief Converts physical constants to the internal unit system
  *
+ * Some constants can be overwritten by the YAML file values.
+ *
  * @param us The current internal system of units.
+ * @param params The parsed parameter file.
  * @param internal_const The physical constants to initialize.
  */
-void phys_const_init(struct unit_system *us,
+void phys_const_init(const struct unit_system *us,
+                     const struct swift_params *params,
                      struct phys_const *internal_const) {
 
   /* Units are declared as {U_M, U_L, U_t, U_I, U_T} */
@@ -44,6 +48,10 @@ void phys_const_init(struct unit_system *us,
   internal_const->const_newton_G =
       const_newton_G_cgs / units_general_cgs_conversion_factor(us, dimension_G);
 
+  /* Overwrite G if present in the file */
+  internal_const->const_newton_G = parser_get_opt_param_double(
+      params, "PhysicalConstants:G", internal_const->const_newton_G);
+
   const float dimension_c[5] = {0, 1, -1, 0, 0};
   internal_const->const_speed_light_c =
       const_speed_light_c_cgs /
@@ -61,6 +69,11 @@ void phys_const_init(struct unit_system *us,
       const_boltzmann_k_cgs /
       units_general_cgs_conversion_factor(us, dimension_k);
 
+  const float dimension_Na[5] = {0, 0, 0, 0, 0};
+  internal_const->const_avogadro_number =
+      const_avogadro_number_cgs /
+      units_general_cgs_conversion_factor(us, dimension_Na);
+
   const float dimension_thomson[5] = {0, 2, 0, 0, 0};
   internal_const->const_thomson_cross_section =
       const_thomson_cross_section_cgs /
@@ -106,7 +119,12 @@ void phys_const_init(struct unit_system *us,
       units_general_cgs_conversion_factor(us, dimension_length);
 }
 
-void phys_const_print(struct phys_const *internal_const) {
+/**
+ * @brief Print the value of the physical constants to stdout.
+ *
+ * @param internal_const The constants in the internal unit system.
+ */
+void phys_const_print(const struct phys_const *internal_const) {
 
   message("%25s = %e", "Gravitational constant",
           internal_const->const_newton_G);
diff --git a/src/physical_constants.h b/src/physical_constants.h
index 39c6c52cba311228d6152fd59e8a6001d11a3ac1..b0f929632ba8a55a57376975597e444a8344e4fc 100644
--- a/src/physical_constants.h
+++ b/src/physical_constants.h
@@ -20,67 +20,80 @@
 #ifndef SWIFT_PHYSICAL_CONSTANTS_H
 #define SWIFT_PHYSICAL_CONSTANTS_H
 
+/**
+ * @file physical_constants.h
+ * @brief Physical constants in the internal unit system.
+ */
+
 /* Config parameters. */
 #include "../config.h"
 
 /* Local includes. */
+#include "parser.h"
 #include "units.h"
 
-/* physical constants in in defined programme units */
+/**
+ * @brief  physical constants in in defined programme units
+ */
 struct phys_const {
 
-  /* Newton's gravitationl constant */
+  /*! Newton's gravitationl constant */
   double const_newton_G;
 
-  /* Speed of light in vacuum */
+  /*! Speed of light in vacuum */
   double const_speed_light_c;
 
-  /* Planck's constant */
+  /*! Planck's constant */
   double const_planck_h;
 
-  /* Planck's reduced constant */
+  /*! Planck's reduced constant */
   double const_planck_hbar;
 
-  /* Boltzmann's constant */
+  /*! Boltzmann's constant */
   double const_boltzmann_k;
 
-  /* Thomson cross-section */
+  /*! Avogadro's number */
+  double const_avogadro_number;
+
+  /*! Thomson cross-section */
   double const_thomson_cross_section;
 
-  /* Charge of the electron  */
+  /*! Charge of the electron  */
   double const_electron_charge;
 
-  /* Electron-Volt */
+  /*! Electron-Volt */
   double const_electron_volt;
 
-  /* Mass of the electron */
+  /*! Mass of the electron */
   double const_electron_mass;
 
-  /* Mass of the proton */
+  /*! Mass of the proton */
   double const_proton_mass;
 
-  /* (Tropical) Year */
+  /*! (Tropical) Year */
   double const_year;
 
-  /* Astronomical unit */
+  /*! Astronomical unit */
   double const_astronomical_unit;
 
-  /* Parsec */
+  /*! Parsec */
   double const_parsec;
 
-  /* Light-year */
+  /*! Light-year */
   double const_light_year;
 
-  /* Mass of the Sun */
+  /*! Mass of the Sun */
   double const_solar_mass;
 
-  /* Mass of the Earth */
+  /*! Mass of the Earth */
   double const_earth_mass;
 };
 
-void phys_const_init(struct unit_system* us, struct phys_const* internal_const);
+void phys_const_init(const struct unit_system* us,
+                     const struct swift_params* params,
+                     struct phys_const* internal_const);
 
-void phys_const_print(struct phys_const* internal_const);
+void phys_const_print(const struct phys_const* internal_const);
 
 /* Dump/restore. */
 void phys_const_struct_dump(const struct phys_const* internal_const,
diff --git a/src/physical_constants_cgs.h b/src/physical_constants_cgs.h
index 9bd435bde9f0f80c06f0de5fee980f080c2f57d3..1d44dae491961b60a596ec85b5ca589411516079 100644
--- a/src/physical_constants_cgs.h
+++ b/src/physical_constants_cgs.h
@@ -20,62 +20,70 @@
 #ifndef SWIFT_PHYSICAL_CONSTANTS_CGS_H
 #define SWIFT_PHYSICAL_CONSTANTS_CGS_H
 
-/* The constants declared in this file should _NOT_ be used directly */
-/* Users should use the converted values in the phys_const structure */
-/* where all the constants are defined in the system of units specified */
-/* in the parameter file. */
+/**
+ * @file physical_constants_cgs.h
+ * @brief Physical constants in the CGS unit system.
+ *
+ * The constants declared in this file should _NOT_ be used directly
+ * Users should use the converted values in the phys_const structure
+ * where all the constants are defined in the system of units specified
+ * in the parameter file.
+ *
+ * All values are taken from C. Patrignani et al. (Particle Data Group), Chin.
+ * Phys. C, 40, 100001 (2016) and 2017 update.
+ * http://pdg.lbl.gov/2017/reviews/rpp2017-rev-phys-constants.pdf
+ * http://pdg.lbl.gov/2017/reviews/rpp2017-rev-astrophysical-constants.pdf
+ */
 
-/* All values are taken from K.A. Olive et al. (Particle Data Group), Chin. */
-/* Phys. C, 38, 090001 (2014) and 2015 update. */
-/* http://pdg.lbl.gov/2015/reviews/rpp2015-rev-phys-constants.pdf */
-/* http://pdg.lbl.gov/2015/reviews/rpp2015-rev-astrophysical-constants.pdf */
+/*! Newton's gravitation constant [g^-1 cm^3 s^-2] */
+const double const_newton_G_cgs = 6.67408e-8;
 
-/* Newton's gravitation constant */
-const double const_newton_G_cgs = 6.67408e-8; /* g^-1 cm^3 s^-2 */
+/*! Speed of light in vacuum [cm s^-1] */
+const double const_speed_light_c_cgs = 2.99792458e10;
 
-/* Speed of light in vacuum */
-const double const_speed_light_c_cgs = 2.99792458e10; /* cm s^-1 */
+/*! Planck's constant [g cm^-2 s^-1] */
+const double const_planck_h_cgs = 6.626070040e-27;
 
-/* Planck's constant */
-const double const_planck_h_cgs = 6.626070040e-27; /* g cm^-2 s^-1 */
+/*! Planck's reduced constant [g cm^-2 s^-1] */
+const double const_planck_hbar_cgs = 1.054571800e-27;
 
-/* Planck's reduced constant */
-const double const_planck_hbar_cgs = 1.054571800e-27; /* g cm^-2 s^-1 */
+/*! Boltzmann's constant [g cm^2 s^-2 K^-1] */
+const double const_boltzmann_k_cgs = 1.38064852e-16;
 
-/* Boltzmann's constant */
-const double const_boltzmann_k_cgs = 1.38064852e-16; /* g cm^2 s^-2 K^-1 */
+/*! Avogadro number [-] */
+const double const_avogadro_number_cgs = 6.022140857e23;
 
-/* Thomson cross-section */
-const double const_thomson_cross_section_cgs = 6.6524587158e-25; /* cm^2 */
+/*! Thomson cross-section [cm^2] */
+const double const_thomson_cross_section_cgs = 6.6524587158e-25;
 
-/* Elementary charge */
-const double const_electron_charge_cgs = 1.6021766208e-19; /* A s^-1 */
+/*! Elementary charge [A s^-1] */
+const double const_electron_charge_cgs = 1.6021766208e-19;
 
-/* Electron-Volt */
-const double const_electron_volt_cgs = 1.6021766208e-12; /* g cm^2 s^-2 */
+/*! Electron-Volt [g cm^2 s^-2] */
+const double const_electron_volt_cgs = 1.6021766208e-12;
 
-/* Mass of the electron */
-const double const_electron_mass_cgs = 9.10938356e-28; /* g */
+/*! Mass of the electron [g] */
+const double const_electron_mass_cgs = 9.10938356e-28;
 
-/* Mass of the proton */
-const double const_proton_mass_cgs = 1.672621898e-24; /* g */
+/*! Mass of the proton [g] */
+const double const_proton_mass_cgs = 1.672621898e-24;
 
-/* Tropical year */
-const double const_year_cgs = 3.15569252e7; /* s */
+/*! Tropical year [s] */
+const double const_year_cgs = 3.15569252e7;
 
-/* Astronomical unit */
-const double const_astronomical_unit_cgs = 1.49597870700e13; /* cm */
+/*! Astronomical unit [cm] */
+const double const_astronomical_unit_cgs = 1.49597870700e13;
 
-/* Parsec */
-const double const_parsec_cgs = 3.08567758149e18; /* cm */
+/*! Parsec [cm] */
+const double const_parsec_cgs = 3.08567758149e18;
 
-/* Light-year */
-const double const_light_year_cgs = 9.46053e17; /* cm */
+/*! Light-year [cm] */
+const double const_light_year_cgs = 9.46053e17;
 
-/* Mass of the Sun */
-const double const_solar_mass_cgs = 1.9885e33; /* g */
+/*! Mass of the Sun [g] */
+const double const_solar_mass_cgs = 1.98848e33;
 
-/* Mass of the Earth */
-const double const_earth_mass_cgs = 5.9726e27; /* g */
+/*! Mass of the Earth [g] */
+const double const_earth_mass_cgs = 5.9724e27;
 
 #endif /* SWIFT_PHYSICAL_CONSTANTS_CGS_H */
diff --git a/src/proxy.c b/src/proxy.c
index 4c110d1a23cbe337978147567b2e6ad8a6d6ba65..10df8d191db992bdd26b39cd18e950f41c4690b3 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -145,14 +145,15 @@ void proxy_addcell_in(struct proxy *p, struct cell *c, int type) {
     p->size_cells_in *= proxy_buffgrow;
 
     struct cell **temp_cell;
-    if ((temp_cell = malloc(sizeof(struct cell *) * p->size_cells_in)) == NULL)
+    if ((temp_cell = (struct cell **)malloc(sizeof(struct cell *) *
+                                            p->size_cells_in)) == NULL)
       error("Failed to allocate incoming cell list.");
     memcpy(temp_cell, p->cells_in, sizeof(struct cell *) * p->nr_cells_in);
     free(p->cells_in);
     p->cells_in = temp_cell;
 
     int *temp_type;
-    if ((temp_type = malloc(sizeof(int) * p->size_cells_in)) == NULL)
+    if ((temp_type = (int *)malloc(sizeof(int) * p->size_cells_in)) == NULL)
       error("Failed to allocate incoming cell type list.");
     memcpy(temp_type, p->cells_in_type, sizeof(int) * p->nr_cells_in);
     free(p->cells_in_type);
@@ -190,14 +191,15 @@ void proxy_addcell_out(struct proxy *p, struct cell *c, int type) {
     p->size_cells_out *= proxy_buffgrow;
 
     struct cell **temp_cell;
-    if ((temp_cell = malloc(sizeof(struct cell *) * p->size_cells_out)) == NULL)
+    if ((temp_cell = (struct cell **)malloc(sizeof(struct cell *) *
+                                            p->size_cells_out)) == NULL)
       error("Failed to allocate outgoing cell list.");
     memcpy(temp_cell, p->cells_out, sizeof(struct cell *) * p->nr_cells_out);
     free(p->cells_out);
     p->cells_out = temp_cell;
 
     int *temp_type;
-    if ((temp_type = malloc(sizeof(int) * p->size_cells_out)) == NULL)
+    if ((temp_type = (int *)malloc(sizeof(int) * p->size_cells_out)) == NULL)
       error("Failed to allocate outgoing cell type list.");
     memcpy(temp_type, p->cells_out_type, sizeof(int) * p->nr_cells_out);
     free(p->cells_out_type);
diff --git a/src/restart.c b/src/restart.c
index d3ec48724a0e97ea9bd40b243b17419387633559..6344e10e2480134959e18a76a2b6d2244531baec 100644
--- a/src/restart.c
+++ b/src/restart.c
@@ -93,7 +93,7 @@ char **restart_locate(const char *dir, const char *basename, int *nfiles) {
     char **files = NULL;
     if (glob(pattern, 0, NULL, &globbuf) == 0) {
       *nfiles = globbuf.gl_pathc;
-      files = malloc(sizeof(char *) * *nfiles);
+      files = (char **)malloc(sizeof(char *) * *nfiles);
       for (int i = 0; i < *nfiles; i++) {
         files[i] = strdup(globbuf.gl_pathv[i]);
       }
@@ -136,15 +136,16 @@ void restart_write(struct engine *e, const char *filename) {
     error("Failed to open restart file: %s (%s)", filename, strerror(errno));
 
   /* Dump our signature and version. */
-  restart_write_blocks(SWIFT_RESTART_SIGNATURE, strlen(SWIFT_RESTART_SIGNATURE),
-                       1, stream, "signature", "SWIFT signature");
+  restart_write_blocks((void *)SWIFT_RESTART_SIGNATURE,
+                       strlen(SWIFT_RESTART_SIGNATURE), 1, stream, "signature",
+                       "SWIFT signature");
   restart_write_blocks((void *)package_version(), strlen(package_version()), 1,
                        stream, "version", "SWIFT version");
 
   engine_struct_dump(e, stream);
 
   /* Just an END statement to spot truncated files. */
-  restart_write_blocks(SWIFT_RESTART_END_SIGNATURE,
+  restart_write_blocks((void *)SWIFT_RESTART_END_SIGNATURE,
                        strlen(SWIFT_RESTART_END_SIGNATURE), 1, stream,
                        "endsignature", "SWIFT end signature");
 
diff --git a/src/runner.c b/src/runner.c
index 592ccdb5b411dbfa0ea60dd3928a53a4a79c5cb5..0738267cf340da1039071f96f7e3d296c4169ef5 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -42,6 +42,7 @@
 #include "approx_math.h"
 #include "atomic.h"
 #include "cell.h"
+#include "chemistry.h"
 #include "const.h"
 #include "cooling.h"
 #include "debug.h"
@@ -64,21 +65,33 @@
 #include "timers.h"
 #include "timestep.h"
 
+#define TASK_LOOP_DENSITY 0
+#define TASK_LOOP_GRADIENT 1
+#define TASK_LOOP_FORCE 2
+#define TASK_LOOP_LIMITER 3
+
 /* Import the density loop functions. */
 #define FUNCTION density
+#define FUNCTION_TASK_LOOP TASK_LOOP_DENSITY
 #include "runner_doiact.h"
+#undef FUNCTION
+#undef FUNCTION_TASK_LOOP
 
 /* Import the gradient loop functions (if required). */
 #ifdef EXTRA_HYDRO_LOOP
-#undef FUNCTION
 #define FUNCTION gradient
+#define FUNCTION_TASK_LOOP TASK_LOOP_GRADIENT
 #include "runner_doiact.h"
+#undef FUNCTION
+#undef FUNCTION_TASK_LOOP
 #endif
 
 /* Import the force loop functions. */
-#undef FUNCTION
 #define FUNCTION force
+#define FUNCTION_TASK_LOOP TASK_LOOP_FORCE
 #include "runner_doiact.h"
+#undef FUNCTION
+#undef FUNCTION_TASK_LOOP
 
 /* Import the gravity loop functions. */
 #include "runner_doiact_fft.h"
@@ -648,7 +661,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
 
     /* Init the list of active particles that have to be updated. */
     int *pid = NULL;
-    if ((pid = malloc(sizeof(int) * c->count)) == NULL)
+    if ((pid = (int *)malloc(sizeof(int) * c->count)) == NULL)
       error("Can't allocate memory for pid.");
     for (int k = 0; k < c->count; k++)
       if (part_is_active(&parts[k], e)) {
@@ -689,6 +702,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
 
           /* Finish the density calculation */
           hydro_end_density(p);
+          chemistry_end_density(p, e->chemistry);
 
           /* Compute one step of the Newton-Raphson scheme */
           const float n_sum = p->density.wcount * h_old_dim;
@@ -726,6 +740,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
 
             /* Re-initialise everything */
             hydro_init_part(p, &s->hs);
+            chemistry_init_part(p, e->chemistry);
 
             /* Off we go ! */
             continue;
@@ -1990,7 +2005,7 @@ void *runner_main(void *data) {
           break;
         case task_type_recv:
           if (t->subtype == task_subtype_tend) {
-            cell_unpack_end_step(ci, t->buff);
+            cell_unpack_end_step(ci, (struct pcell_step *)t->buff);
             free(t->buff);
           } else if (t->subtype == task_subtype_xv) {
             runner_do_recv_part(r, ci, 1, 1);
@@ -2003,7 +2018,7 @@ void *runner_main(void *data) {
           } else if (t->subtype == task_subtype_spart) {
             runner_do_recv_spart(r, ci, 1);
           } else if (t->subtype == task_subtype_multipole) {
-            cell_unpack_multipoles(ci, t->buff);
+            cell_unpack_multipoles(ci, (struct gravity_tensors *)t->buff);
             free(t->buff);
           } else {
             error("Unknown/invalid task subtype (%d).", t->subtype);
diff --git a/src/runner_doiact.h b/src/runner_doiact.h
index dda34a6dc3eb7cb3ee77789cfb4a8cd51db37266..038c27a950d8748512b484d8941e2f029edaaab0 100644
--- a/src/runner_doiact.h
+++ b/src/runner_doiact.h
@@ -166,9 +166,9 @@ void DOPAIR1_NAIVE(struct runner *r, struct cell *restrict ci,
     const int pi_active = part_is_active(pi, e);
     const float hi = pi->h;
     const float hig2 = hi * hi * kernel_gamma2;
-    const float pix[3] = {pi->x[0] - (cj->loc[0] + shift[0]),
-                          pi->x[1] - (cj->loc[1] + shift[1]),
-                          pi->x[2] - (cj->loc[2] + shift[2])};
+    const float pix[3] = {(float)(pi->x[0] - (cj->loc[0] + shift[0])),
+                          (float)(pi->x[1] - (cj->loc[1] + shift[1])),
+                          (float)(pi->x[2] - (cj->loc[2] + shift[2]))};
 
     /* Loop over the parts in cj. */
     for (int pjd = 0; pjd < count_j; pjd++) {
@@ -180,8 +180,9 @@ void DOPAIR1_NAIVE(struct runner *r, struct cell *restrict ci,
       const int pj_active = part_is_active(pj, e);
 
       /* Compute the pairwise distance. */
-      const float pjx[3] = {pj->x[0] - cj->loc[0], pj->x[1] - cj->loc[1],
-                            pj->x[2] - cj->loc[2]};
+      const float pjx[3] = {(float)(pj->x[0] - cj->loc[0]),
+                            (float)(pj->x[1] - cj->loc[1]),
+                            (float)(pj->x[2] - cj->loc[2])};
       float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]};
       const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
@@ -197,6 +198,9 @@ void DOPAIR1_NAIVE(struct runner *r, struct cell *restrict ci,
       if (r2 < hig2 && pi_active) {
 
         IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
       }
       if (r2 < hjg2 && pj_active) {
 
@@ -205,6 +209,9 @@ void DOPAIR1_NAIVE(struct runner *r, struct cell *restrict ci,
         dx[2] = -dx[2];
 
         IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
       }
 
     } /* loop over the parts in cj. */
@@ -254,9 +261,9 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci,
     const int pi_active = part_is_active(pi, e);
     const float hi = pi->h;
     const float hig2 = hi * hi * kernel_gamma2;
-    const float pix[3] = {pi->x[0] - (cj->loc[0] + shift[0]),
-                          pi->x[1] - (cj->loc[1] + shift[1]),
-                          pi->x[2] - (cj->loc[2] + shift[2])};
+    const float pix[3] = {(float)(pi->x[0] - (cj->loc[0] + shift[0])),
+                          (float)(pi->x[1] - (cj->loc[1] + shift[1])),
+                          (float)(pi->x[2] - (cj->loc[2] + shift[2]))};
 
     /* Loop over the parts in cj. */
     for (int pjd = 0; pjd < count_j; pjd++) {
@@ -268,8 +275,9 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci,
       const float hjg2 = hj * hj * kernel_gamma2;
 
       /* Compute the pairwise distance. */
-      const float pjx[3] = {pj->x[0] - cj->loc[0], pj->x[1] - cj->loc[1],
-                            pj->x[2] - cj->loc[2]};
+      const float pjx[3] = {(float)(pj->x[0] - cj->loc[0]),
+                            (float)(pj->x[1] - cj->loc[1]),
+                            (float)(pj->x[2] - cj->loc[2])};
       float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]};
       const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
@@ -287,9 +295,15 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci,
         if (pi_active && pj_active) {
 
           IACT(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
         } else if (pi_active) {
 
           IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
         } else if (pj_active) {
 
           dx[0] = -dx[0];
@@ -297,6 +311,9 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci,
           dx[2] = -dx[2];
 
           IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
         }
       }
     } /* loop over the parts in cj. */
@@ -333,8 +350,9 @@ void DOSELF1_NAIVE(struct runner *r, struct cell *restrict c) {
     const int pi_active = part_is_active(pi, e);
     const float hi = pi->h;
     const float hig2 = hi * hi * kernel_gamma2;
-    const float pix[3] = {pi->x[0] - c->loc[0], pi->x[1] - c->loc[1],
-                          pi->x[2] - c->loc[2]};
+    const float pix[3] = {(float)(pi->x[0] - c->loc[0]),
+                          (float)(pi->x[1] - c->loc[1]),
+                          (float)(pi->x[2] - c->loc[2])};
 
     /* Loop over the parts in cj. */
     for (int pjd = pid + 1; pjd < count; pjd++) {
@@ -346,8 +364,9 @@ void DOSELF1_NAIVE(struct runner *r, struct cell *restrict c) {
       const int pj_active = part_is_active(pj, e);
 
       /* Compute the pairwise distance. */
-      const float pjx[3] = {pj->x[0] - c->loc[0], pj->x[1] - c->loc[1],
-                            pj->x[2] - c->loc[2]};
+      const float pjx[3] = {(float)(pj->x[0] - c->loc[0]),
+                            (float)(pj->x[1] - c->loc[1]),
+                            (float)(pj->x[2] - c->loc[2])};
       float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]};
       const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
@@ -366,9 +385,15 @@ void DOSELF1_NAIVE(struct runner *r, struct cell *restrict c) {
       if (doi && doj) {
 
         IACT(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
       } else if (doi) {
 
         IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
       } else if (doj) {
 
         dx[0] = -dx[0];
@@ -376,6 +401,9 @@ void DOSELF1_NAIVE(struct runner *r, struct cell *restrict c) {
         dx[2] = -dx[2];
 
         IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
       }
     } /* loop over the parts in cj. */
   }   /* loop over the parts in ci. */
@@ -411,8 +439,9 @@ void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) {
     const int pi_active = part_is_active(pi, e);
     const float hi = pi->h;
     const float hig2 = hi * hi * kernel_gamma2;
-    const float pix[3] = {pi->x[0] - c->loc[0], pi->x[1] - c->loc[1],
-                          pi->x[2] - c->loc[2]};
+    const float pix[3] = {(float)(pi->x[0] - c->loc[0]),
+                          (float)(pi->x[1] - c->loc[1]),
+                          (float)(pi->x[2] - c->loc[2])};
 
     /* Loop over the parts in cj. */
     for (int pjd = pid + 1; pjd < count; pjd++) {
@@ -424,8 +453,9 @@ void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) {
       const int pj_active = part_is_active(pj, e);
 
       /* Compute the pairwise distance. */
-      const float pjx[3] = {pj->x[0] - c->loc[0], pj->x[1] - c->loc[1],
-                            pj->x[2] - c->loc[2]};
+      const float pjx[3] = {(float)(pj->x[0] - c->loc[0]),
+                            (float)(pj->x[1] - c->loc[1]),
+                            (float)(pj->x[2] - c->loc[2])};
       float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]};
       const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
@@ -444,9 +474,15 @@ void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) {
       if (doi && doj) {
 
         IACT(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
       } else if (doi) {
 
         IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
       } else if (doj) {
 
         dx[0] = -dx[0];
@@ -454,6 +490,9 @@ void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) {
         dx[2] = -dx[2];
 
         IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
       }
     } /* loop over the parts in cj. */
   }   /* loop over the parts in ci. */
@@ -527,6 +566,9 @@ void DOPAIR_SUBSET_NAIVE(struct runner *r, struct cell *restrict ci,
       if (r2 < hig2) {
 
         IACT_NONSYM(r2, dx, hi, pj->h, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hi, pj->h, pi, pj);
+#endif
       }
     } /* loop over the parts in cj. */
   }   /* loop over the parts in ci. */
@@ -589,7 +631,8 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci,
         const double pjz = pj->x[2];
 
         /* Compute the pairwise distance. */
-        float dx[3] = {pix - pjx, piy - pjy, piz - pjz};
+        float dx[3] = {(float)(pix - pjx), (float)(piy - pjy),
+                       (float)(piz - pjz)};
         const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -605,6 +648,9 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci,
         if (r2 < hig2) {
 
           IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
         }
       } /* loop over the parts in cj. */
     }   /* loop over the parts in ci. */
@@ -637,7 +683,8 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci,
         const double pjz = pj->x[2];
 
         /* Compute the pairwise distance. */
-        float dx[3] = {pix - pjx, piy - pjy, piz - pjz};
+        float dx[3] = {(float)(pix - pjx), (float)(piy - pjy),
+                       (float)(piz - pjz)};
         const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -653,6 +700,9 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci,
         if (r2 < hig2) {
 
           IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
         }
       } /* loop over the parts in cj. */
     }   /* loop over the parts in ci. */
@@ -746,8 +796,9 @@ void DOSELF_SUBSET(struct runner *r, struct cell *restrict ci,
 
     /* Get a hold of the ith part in ci. */
     struct part *pi = &parts[ind[pid]];
-    const float pix[3] = {pi->x[0] - ci->loc[0], pi->x[1] - ci->loc[1],
-                          pi->x[2] - ci->loc[2]};
+    const float pix[3] = {(float)(pi->x[0] - ci->loc[0]),
+                          (float)(pi->x[1] - ci->loc[1]),
+                          (float)(pi->x[2] - ci->loc[2])};
     const float hi = pi->h;
     const float hig2 = hi * hi * kernel_gamma2;
 
@@ -762,8 +813,9 @@ void DOSELF_SUBSET(struct runner *r, struct cell *restrict ci,
       struct part *restrict pj = &parts_j[pjd];
 
       /* Compute the pairwise distance. */
-      const float pjx[3] = {pj->x[0] - ci->loc[0], pj->x[1] - ci->loc[1],
-                            pj->x[2] - ci->loc[2]};
+      const float pjx[3] = {(float)(pj->x[0] - ci->loc[0]),
+                            (float)(pj->x[1] - ci->loc[1]),
+                            (float)(pj->x[2] - ci->loc[2])};
       float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]};
       const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
 
@@ -779,6 +831,9 @@ void DOSELF_SUBSET(struct runner *r, struct cell *restrict ci,
       if (r2 > 0.f && r2 < hig2) {
 
         IACT_NONSYM(r2, dx, hi, pj->h, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+        runner_iact_nonsym_chemistry(r2, dx, hi, pj->h, pi, pj);
+#endif
       }
     } /* loop over the parts in cj. */
   }   /* loop over the parts in ci. */
@@ -927,6 +982,9 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
         if (r2 < hig2) {
 
           IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
         }
       } /* loop over the parts in cj. */
     }   /* loop over the parts in ci. */
@@ -1007,6 +1065,9 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
         if (r2 < hjg2) {
 
           IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
         }
       } /* loop over the parts in ci. */
     }   /* loop over the parts in cj. */
@@ -1086,7 +1147,8 @@ void DOPAIR1_BRANCH(struct runner *r, struct cell *ci, struct cell *cj) {
 
 #if defined(SWIFT_USE_NAIVE_INTERACTIONS)
   DOPAIR1_NAIVE(r, ci, cj);
-#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
+#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
+    (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
   if (!sort_is_corner(sid))
     runner_dopair1_density_vec(r, ci, cj, sid, shift);
   else
@@ -1158,7 +1220,7 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
     sort_active_i = sort_i;
     count_active_i = count_i;
   } else if (cell_is_active_hydro(ci, e)) {
-    if (posix_memalign((void *)&sort_active_i, SWIFT_CACHE_ALIGNMENT,
+    if (posix_memalign((void **)&sort_active_i, SWIFT_CACHE_ALIGNMENT,
                        sizeof(struct entry) * count_i) != 0)
       error("Failed to allocate active sortlists.");
 
@@ -1176,7 +1238,7 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
     sort_active_j = sort_j;
     count_active_j = count_j;
   } else if (cell_is_active_hydro(cj, e)) {
-    if (posix_memalign((void *)&sort_active_j, SWIFT_CACHE_ALIGNMENT,
+    if (posix_memalign((void **)&sort_active_j, SWIFT_CACHE_ALIGNMENT,
                        sizeof(struct entry) * count_j) != 0)
       error("Failed to allocate active sortlists.");
 
@@ -1269,6 +1331,9 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
            (note that we will do the other condition in the reverse loop) */
         if (r2 < hig2) {
           IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
         }
       } /* loop over the active parts in cj. */
     }
@@ -1329,10 +1394,17 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
         if (r2 < hig2) {
 
           /* Does pj need to be updated too? */
-          if (part_is_active(pj, e))
+          if (part_is_active(pj, e)) {
             IACT(r2, dx, hi, hj, pi, pj);
-          else
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
+          } else {
             IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
+          }
         }
       } /* loop over the parts in cj. */
     }   /* Is pi active? */
@@ -1419,6 +1491,9 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
            (note that we must avoid the r2 < hig2 cases we already processed) */
         if (r2 < hjg2 && r2 >= hig2) {
           IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
         }
       } /* loop over the active parts in ci. */
     }
@@ -1482,10 +1557,17 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
         if (r2 < hjg2 && r2 >= hig2) {
 
           /* Does pi need to be updated too? */
-          if (part_is_active(pi, e))
+          if (part_is_active(pi, e)) {
             IACT(r2, dx, hj, hi, pj, pi);
-          else
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
+          } else {
             IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
+          }
         }
       } /* loop over the parts in ci. */
     }   /* Is pj active? */
@@ -1571,7 +1653,8 @@ void DOPAIR2_BRANCH(struct runner *r, struct cell *ci, struct cell *cj) {
 
 #ifdef SWIFT_USE_NAIVE_INTERACTIONS
   DOPAIR2_NAIVE(r, ci, cj);
-#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
+#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
+    (FUNCTION_TASK_LOOP == TASK_LOOP_FORCE)
   if (!sort_is_corner(sid))
     runner_dopair2_force_vec(r, ci, cj, sid, shift);
   else
@@ -1599,7 +1682,7 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
   /* Set up indt. */
   int *indt = NULL;
   int countdt = 0, firstdt = 0;
-  if (posix_memalign((void *)&indt, VEC_SIZE * sizeof(int),
+  if (posix_memalign((void **)&indt, VEC_SIZE * sizeof(int),
                      count * sizeof(int)) != 0)
     error("Failed to allocate indt.");
   for (int k = 0; k < count; k++)
@@ -1650,6 +1733,9 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
         if (r2 < hj * hj * kernel_gamma2) {
 
           IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
         }
       } /* loop over all other particles. */
     }
@@ -1689,15 +1775,24 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
         if (r2 < hig2 || doj) {
 
           /* Which parts need to be updated? */
-          if (r2 < hig2 && doj)
+          if (r2 < hig2 && doj) {
             IACT(r2, dx, hi, hj, pi, pj);
-          else if (!doj)
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
+          } else if (!doj) {
             IACT_NONSYM(r2, dx, hi, hj, pi, pj);
-          else {
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
+          } else {
             dx[0] = -dx[0];
             dx[1] = -dx[1];
             dx[2] = -dx[2];
             IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
           }
         }
       } /* loop over all other particles. */
@@ -1733,7 +1828,8 @@ void DOSELF1_BRANCH(struct runner *r, struct cell *c) {
 
 #if defined(SWIFT_USE_NAIVE_INTERACTIONS)
   DOSELF1_NAIVE(r, c);
-#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
+#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
+    (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
   runner_doself1_density_vec(r, c);
 #else
   DOSELF1(r, c);
@@ -1758,7 +1854,7 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
   /* Set up indt. */
   int *indt = NULL;
   int countdt = 0, firstdt = 0;
-  if (posix_memalign((void *)&indt, VEC_SIZE * sizeof(int),
+  if (posix_memalign((void **)&indt, VEC_SIZE * sizeof(int),
                      count * sizeof(int)) != 0)
     error("Failed to allocate indt.");
   for (int k = 0; k < count; k++)
@@ -1809,6 +1905,9 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
         if (r2 < hig2 || r2 < hj * hj * kernel_gamma2) {
 
           IACT_NONSYM(r2, dx, hj, hi, pj, pi);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+          runner_iact_nonsym_chemistry(r2, dx, hj, hi, pj, pi);
+#endif
         }
       } /* loop over all other particles. */
     }
@@ -1846,10 +1945,17 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
         if (r2 < hig2 || r2 < hj * hj * kernel_gamma2) {
 
           /* Does pj need to be updated too? */
-          if (part_is_active(pj, e))
+          if (part_is_active(pj, e)) {
             IACT(r2, dx, hi, hj, pi, pj);
-          else
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
+          } else {
             IACT_NONSYM(r2, dx, hi, hj, pi, pj);
+#if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY)
+            runner_iact_nonsym_chemistry(r2, dx, hi, hj, pi, pj);
+#endif
+          }
         }
       } /* loop over all other particles. */
     }
@@ -1884,7 +1990,8 @@ void DOSELF2_BRANCH(struct runner *r, struct cell *c) {
 
 #if defined(SWIFT_USE_NAIVE_INTERACTIONS)
   DOSELF2_NAIVE(r, c);
-#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
+#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
+    (FUNCTION_TASK_LOOP == TASK_LOOP_FORCE)
   runner_doself2_force_vec(r, c);
 #else
   DOSELF2(r, c);
diff --git a/src/runner_doiact_fft.c b/src/runner_doiact_fft.c
index 9e9841496707cb0d0dc0b7b6f3d8d98399414d91..1bc3846531504087c1f696f8b3d8eeb6c88dfe71 100644
--- a/src/runner_doiact_fft.c
+++ b/src/runner_doiact_fft.c
@@ -194,12 +194,12 @@ void runner_do_grav_fft(struct runner* r, int timer) {
 #endif
 
   /* Allocates some memory for the density mesh */
-  double* restrict rho = fftw_malloc(sizeof(double) * N * N * N);
+  double* restrict rho = (double*)fftw_malloc(sizeof(double) * N * N * N);
   if (rho == NULL) error("Error allocating memory for density mesh");
 
   /* Allocates some memory for the mesh in Fourier space */
   fftw_complex* restrict frho =
-      fftw_malloc(sizeof(fftw_complex) * N * N * (N_half + 1));
+      (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N * N * (N_half + 1));
   if (frho == NULL)
     error("Error allocating memory for transform of density mesh");
 
diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h
index cee0737cbae7b7d1d67d74d829447a77ada66928..0bc7b851c05e94974ef6337ba3d8df5e5420c9a1 100644
--- a/src/runner_doiact_grav.h
+++ b/src/runner_doiact_grav.h
@@ -208,10 +208,10 @@ static INLINE void runner_dopair_grav_pp_full(const struct engine *e,
     float a_x = 0.f, a_y = 0.f, a_z = 0.f;
 
     /* Make the compiler understand we are in happy vectorization land */
-    swift_align_information(cj_cache->x, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(cj_cache->y, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(cj_cache->z, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(cj_cache->m, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->x, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->y, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->z, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->m, SWIFT_CACHE_ALIGNMENT);
     swift_assume_size(gcount_padded_j, VEC_SIZE);
 
     /* Loop over every particle in the other cell. */
@@ -299,10 +299,10 @@ static INLINE void runner_dopair_grav_pp_truncated(
     float a_x = 0.f, a_y = 0.f, a_z = 0.f;
 
     /* Make the compiler understand we are in happy vectorization land */
-    swift_align_information(cj_cache->x, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(cj_cache->y, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(cj_cache->z, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(cj_cache->m, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->x, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->y, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->z, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, cj_cache->m, SWIFT_CACHE_ALIGNMENT);
     swift_assume_size(gcount_padded_j, VEC_SIZE);
 
     /* Loop over every particle in the other cell. */
@@ -496,12 +496,12 @@ void runner_dopair_grav_pp(struct runner *r, struct cell *ci, struct cell *cj) {
   const float rmax2_j = rmax_j * rmax_j;
   const struct multipole *multi_i = &ci->multipole->m_pole;
   const struct multipole *multi_j = &cj->multipole->m_pole;
-  const float CoM_i[3] = {ci->multipole->CoM[0] - shift_i[0],
-                          ci->multipole->CoM[1] - shift_i[1],
-                          ci->multipole->CoM[2] - shift_i[2]};
-  const float CoM_j[3] = {cj->multipole->CoM[0] - shift_j[0],
-                          cj->multipole->CoM[1] - shift_j[1],
-                          cj->multipole->CoM[2] - shift_j[2]};
+  const float CoM_i[3] = {(float)(ci->multipole->CoM[0] - shift_i[0]),
+                          (float)(ci->multipole->CoM[1] - shift_i[1]),
+                          (float)(ci->multipole->CoM[2] - shift_i[2])};
+  const float CoM_j[3] = {(float)(cj->multipole->CoM[0] - shift_j[0]),
+                          (float)(cj->multipole->CoM[1] - shift_j[1]),
+                          (float)(cj->multipole->CoM[2] - shift_j[2])};
 
   /* Start by constructing particle caches */
 
@@ -686,10 +686,10 @@ void runner_doself_grav_pp_full(struct runner *r, struct cell *c) {
     float a_x = 0.f, a_y = 0.f, a_z = 0.f;
 
     /* Make the compiler understand we are in happy vectorization land */
-    swift_align_information(ci_cache->x, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(ci_cache->y, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(ci_cache->z, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(ci_cache->m, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->x, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->y, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->z, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->m, SWIFT_CACHE_ALIGNMENT);
     swift_assume_size(gcount_padded, VEC_SIZE);
 
     /* Loop over every other particle in the cell. */
@@ -812,10 +812,10 @@ void runner_doself_grav_pp_truncated(struct runner *r, struct cell *c) {
     float a_x = 0.f, a_y = 0.f, a_z = 0.f;
 
     /* Make the compiler understand we are in happy vectorization land */
-    swift_align_information(ci_cache->x, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(ci_cache->y, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(ci_cache->z, SWIFT_CACHE_ALIGNMENT);
-    swift_align_information(ci_cache->m, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->x, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->y, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->z, SWIFT_CACHE_ALIGNMENT);
+    swift_align_information(float, ci_cache->m, SWIFT_CACHE_ALIGNMENT);
     swift_assume_size(gcount_padded, VEC_SIZE);
 
     /* Loop over every other particle in the cell. */
diff --git a/src/scheduler.c b/src/scheduler.c
index 0d96368e5711935813322107df4286176210552a..f9cfff5645c571a6bae1d0dc111766e2b2be1120 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -136,7 +136,7 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) {
    * ind = (ta * task_subtype_count + sa) * max_nber_dep * 2
    * where ta is the value of task_type and sa is the value of
    * task_subtype  */
-  int *table = malloc(nber_relation * sizeof(int));
+  int *table = (int *)malloc(nber_relation * sizeof(int));
   if (table == NULL)
     error("Error allocating memory for task-dependency graph.");
 
@@ -996,9 +996,10 @@ void scheduler_set_unlocks(struct scheduler *s) {
 #ifdef SWIFT_DEBUG_CHECKS
     /* Check that we are not overflowing */
     if (counts[s->unlock_ind[k]] < 0)
-      error("Task unlocking more than %d other tasks!",
+      error("Task (type=%s/%s) unlocking more than %d other tasks!",
+            taskID_names[s->tasks[s->unlock_ind[k]].type],
+            subtaskID_names[s->tasks[s->unlock_ind[k]].subtype],
             (1 << (8 * sizeof(short int) - 1)) - 1);
-
 #endif
   }
 
@@ -1143,7 +1144,7 @@ void scheduler_reset(struct scheduler *s, int size) {
     scheduler_free_tasks(s);
 
     /* Allocate the new lists. */
-    if (posix_memalign((void *)&s->tasks, task_align,
+    if (posix_memalign((void **)&s->tasks, task_align,
                        size * sizeof(struct task)) != 0)
       error("Failed to allocate task array.");
 
@@ -1462,7 +1463,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
       case task_type_recv:
 #ifdef WITH_MPI
         if (t->subtype == task_subtype_tend) {
-          t->buff = malloc(sizeof(struct pcell_step) * t->ci->pcell_size);
+          t->buff = (struct pcell_step *)malloc(sizeof(struct pcell_step) *
+                                                t->ci->pcell_size);
           err = MPI_Irecv(
               t->buff, t->ci->pcell_size * sizeof(struct pcell_step), MPI_BYTE,
               t->ci->nodeID, t->flags, MPI_COMM_WORLD, &t->req);
@@ -1481,7 +1483,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
           err = MPI_Irecv(t->ci->sparts, t->ci->scount, spart_mpi_type,
                           t->ci->nodeID, t->flags, MPI_COMM_WORLD, &t->req);
         } else if (t->subtype == task_subtype_multipole) {
-          t->buff = malloc(sizeof(struct gravity_tensors) * t->ci->pcell_size);
+          t->buff = (struct gravity_tensors *)malloc(
+              sizeof(struct gravity_tensors) * t->ci->pcell_size);
           err = MPI_Irecv(
               t->buff, sizeof(struct gravity_tensors) * t->ci->pcell_size,
               MPI_BYTE, t->ci->nodeID, t->flags, MPI_COMM_WORLD, &t->req);
@@ -1499,8 +1502,9 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
       case task_type_send:
 #ifdef WITH_MPI
         if (t->subtype == task_subtype_tend) {
-          t->buff = malloc(sizeof(struct pcell_step) * t->ci->pcell_size);
-          cell_pack_end_step(t->ci, t->buff);
+          t->buff = (struct pcell_step *)malloc(sizeof(struct pcell_step) *
+                                                t->ci->pcell_size);
+          cell_pack_end_step(t->ci, (struct pcell_step *)t->buff);
           if ((t->ci->pcell_size * sizeof(struct pcell_step)) >
               s->mpi_message_limit)
             err = MPI_Isend(
@@ -1537,8 +1541,9 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
             err = MPI_Issend(t->ci->sparts, t->ci->scount, spart_mpi_type,
                              t->cj->nodeID, t->flags, MPI_COMM_WORLD, &t->req);
         } else if (t->subtype == task_subtype_multipole) {
-          t->buff = malloc(sizeof(struct gravity_tensors) * t->ci->pcell_size);
-          cell_pack_multipoles(t->ci, t->buff);
+          t->buff = (struct gravity_tensors *)malloc(
+              sizeof(struct gravity_tensors) * t->ci->pcell_size);
+          cell_pack_multipoles(t->ci, (struct gravity_tensors *)t->buff);
           err = MPI_Isend(
               t->buff, t->ci->pcell_size * sizeof(struct gravity_tensors),
               MPI_BYTE, t->cj->nodeID, t->flags, MPI_COMM_WORLD, &t->req);
diff --git a/src/single_io.c b/src/single_io.c
index 79dc6d43d645862edb3e0f8a9a6480f368265a50..4ba85c2b1b6970469b17ac2d475e297b848604c6 100644
--- a/src/single_io.c
+++ b/src/single_io.c
@@ -131,16 +131,16 @@ void readArray(hid_t h_grp, const struct io_props prop, size_t N,
     /* message("Converting ! factor=%e", factor); */
 
     if (io_is_double_precision(prop.type)) {
-      double* temp_d = temp;
+      double* temp_d = (double*)temp;
       for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
     } else {
-      float* temp_f = temp;
+      float* temp_f = (float*)temp;
       for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
     }
   }
 
   /* Copy temporary buffer to particle data */
-  char* temp_c = temp;
+  char* temp_c = (char*)temp;
   for (size_t i = 0; i < N; ++i)
     memcpy(prop.field + i * prop.partSize, &temp_c[i * copySize], copySize);
 
@@ -387,7 +387,8 @@ void read_ic_single(char* fileName, const struct unit_system* internal_units,
   H5Gclose(h_grp);
 
   /* Read the unit system used in the ICs */
-  struct unit_system* ic_units = malloc(sizeof(struct unit_system));
+  struct unit_system* ic_units =
+      (struct unit_system*)malloc(sizeof(struct unit_system));
   if (ic_units == NULL) error("Unable to allocate memory for IC unit system");
   io_read_unit_system(h_file, ic_units, 0);
 
@@ -428,8 +429,8 @@ void read_ic_single(char* fileName, const struct unit_system* internal_units,
   /* Allocate memory to store SPH particles */
   if (with_hydro) {
     *Ngas = N[swift_type_gas];
-    if (posix_memalign((void*)parts, part_align, *Ngas * sizeof(struct part)) !=
-        0)
+    if (posix_memalign((void**)parts, part_align,
+                       *Ngas * sizeof(struct part)) != 0)
       error("Error while allocating memory for SPH particles");
     bzero(*parts, *Ngas * sizeof(struct part));
   }
@@ -437,7 +438,7 @@ void read_ic_single(char* fileName, const struct unit_system* internal_units,
   /* Allocate memory to store star particles */
   if (with_stars) {
     *Nstars = N[swift_type_star];
-    if (posix_memalign((void*)sparts, spart_align,
+    if (posix_memalign((void**)sparts, spart_align,
                        *Nstars * sizeof(struct spart)) != 0)
       error("Error while allocating memory for star particles");
     bzero(*sparts, *Nstars * sizeof(struct spart));
@@ -449,7 +450,7 @@ void read_ic_single(char* fileName, const struct unit_system* internal_units,
     *Ngparts = (with_hydro ? N[swift_type_gas] : 0) +
                N[swift_type_dark_matter] +
                (with_stars ? N[swift_type_star] : 0);
-    if (posix_memalign((void*)gparts, gpart_align,
+    if (posix_memalign((void**)gparts, gpart_align,
                        *Ngparts * sizeof(struct gpart)) != 0)
       error("Error while allocating memory for gravity particles");
     bzero(*gparts, *Ngparts * sizeof(struct gpart));
@@ -581,7 +582,8 @@ void write_output_single(struct engine* e, const char* baseName,
   /* Number of unassociated gparts */
   const size_t Ndm = Ntot > 0 ? Ntot - (Ngas + Nstars) : 0;
 
-  long long N_total[swift_type_count] = {Ngas, Ndm, 0, 0, Nstars, 0};
+  long long N_total[swift_type_count] = {
+      (long long)Ngas, (long long)Ndm, 0, 0, (long long)Nstars, 0};
 
   /* File name */
   char fileName[FILENAME_BUFFER_SIZE];
@@ -765,7 +767,7 @@ void write_output_single(struct engine* e, const char* baseName,
 
       case swift_type_dark_matter:
         /* Allocate temporary array */
-        if (posix_memalign((void*)&dmparts, gpart_align,
+        if (posix_memalign((void**)&dmparts, gpart_align,
                            Ndm * sizeof(struct gpart)) != 0)
           error("Error while allocating temporart memory for DM particles");
         bzero(dmparts, Ndm * sizeof(struct gpart));
diff --git a/src/space.c b/src/space.c
index c0381b619f1aa8b1847fda84e3b15255cdfc9f85..329526fe14e38220750903058bc5201ef7486f63 100644
--- a/src/space.c
+++ b/src/space.c
@@ -319,12 +319,12 @@ void space_regrid(struct space *s, int verbose) {
 
   /* Get the new putative cell dimensions. */
   const int cdim[3] = {
-      floor(s->dim[0] /
-            fmax(h_max * kernel_gamma * space_stretch, s->cell_min)),
-      floor(s->dim[1] /
-            fmax(h_max * kernel_gamma * space_stretch, s->cell_min)),
-      floor(s->dim[2] /
-            fmax(h_max * kernel_gamma * space_stretch, s->cell_min))};
+      (int)floor(s->dim[0] /
+                 fmax(h_max * kernel_gamma * space_stretch, s->cell_min)),
+      (int)floor(s->dim[1] /
+                 fmax(h_max * kernel_gamma * space_stretch, s->cell_min)),
+      (int)floor(s->dim[2] /
+                 fmax(h_max * kernel_gamma * space_stretch, s->cell_min))};
 
   /* Check if we have enough cells for periodicity. */
   if (s->periodic && (cdim[0] < 3 || cdim[1] < 3 || cdim[2] < 3))
@@ -423,21 +423,21 @@ void space_regrid(struct space *s, int verbose) {
 
     /* Allocate the highest level of cells. */
     s->tot_cells = s->nr_cells = cdim[0] * cdim[1] * cdim[2];
-    if (posix_memalign((void *)&s->cells_top, cell_align,
+    if (posix_memalign((void **)&s->cells_top, cell_align,
                        s->nr_cells * sizeof(struct cell)) != 0)
       error("Failed to allocate top-level cells.");
     bzero(s->cells_top, s->nr_cells * sizeof(struct cell));
 
     /* Allocate the multipoles for the top-level cells. */
     if (s->gravity) {
-      if (posix_memalign((void *)&s->multipoles_top, multipole_align,
+      if (posix_memalign((void **)&s->multipoles_top, multipole_align,
                          s->nr_cells * sizeof(struct gravity_tensors)) != 0)
         error("Failed to allocate top-level multipoles.");
       bzero(s->multipoles_top, s->nr_cells * sizeof(struct gravity_tensors));
     }
 
     /* Allocate the indices of local cells */
-    if (posix_memalign((void *)&s->local_cells_top, SWIFT_STRUCT_ALIGNMENT,
+    if (posix_memalign((void **)&s->local_cells_top, SWIFT_STRUCT_ALIGNMENT,
                        s->nr_cells * sizeof(int)) != 0)
       error("Failed to allocate indices of local top-level cells.");
     bzero(s->local_cells_top, s->nr_cells * sizeof(int));
@@ -1346,8 +1346,8 @@ void space_parts_sort(struct space *s, int *ind, size_t N, int min, int max,
   sort_struct.xparts = s->xparts;
   sort_struct.ind = ind;
   sort_struct.stack_size = 2 * (max - min + 1) + 10 + s->e->nr_threads;
-  if ((sort_struct.stack =
-           malloc(sizeof(struct qstack) * sort_struct.stack_size)) == NULL)
+  if ((sort_struct.stack = (struct qstack *)malloc(
+           sizeof(struct qstack) * sort_struct.stack_size)) == NULL)
     error("Failed to allocate sorting stack.");
   for (unsigned int i = 0; i < sort_struct.stack_size; i++)
     sort_struct.stack[i].ready = 0;
@@ -1530,8 +1530,8 @@ void space_sparts_sort(struct space *s, int *ind, size_t N, int min, int max,
   sort_struct.sparts = s->sparts;
   sort_struct.ind = ind;
   sort_struct.stack_size = 2 * (max - min + 1) + 10 + s->e->nr_threads;
-  if ((sort_struct.stack =
-           malloc(sizeof(struct qstack) * sort_struct.stack_size)) == NULL)
+  if ((sort_struct.stack = (struct qstack *)malloc(
+           sizeof(struct qstack) * sort_struct.stack_size)) == NULL)
     error("Failed to allocate sorting stack.");
   for (unsigned int i = 0; i < sort_struct.stack_size; i++)
     sort_struct.stack[i].ready = 0;
@@ -1713,8 +1713,8 @@ void space_gparts_sort(struct space *s, int *ind, size_t N, int min, int max,
   sort_struct.gparts = s->gparts;
   sort_struct.ind = ind;
   sort_struct.stack_size = 2 * (max - min + 1) + 10 + s->e->nr_threads;
-  if ((sort_struct.stack =
-           malloc(sizeof(struct qstack) * sort_struct.stack_size)) == NULL)
+  if ((sort_struct.stack = (struct qstack *)malloc(
+           sizeof(struct qstack) * sort_struct.stack_size)) == NULL)
     error("Failed to allocate sorting stack.");
   for (unsigned int i = 0; i < sort_struct.stack_size; i++)
     sort_struct.stack[i].ready = 0;
@@ -2062,7 +2062,7 @@ void space_split_recursive(struct space *s, struct cell *c,
   const int allocate_buffer = (buff == NULL && gbuff == NULL && sbuff == NULL);
   if (allocate_buffer) {
     if (count > 0) {
-      if (posix_memalign((void *)&buff, SWIFT_STRUCT_ALIGNMENT,
+      if (posix_memalign((void **)&buff, SWIFT_STRUCT_ALIGNMENT,
                          sizeof(struct cell_buff) * count) != 0)
         error("Failed to allocate temporary indices.");
       for (int k = 0; k < count; k++) {
@@ -2072,7 +2072,7 @@ void space_split_recursive(struct space *s, struct cell *c,
       }
     }
     if (gcount > 0) {
-      if (posix_memalign((void *)&gbuff, SWIFT_STRUCT_ALIGNMENT,
+      if (posix_memalign((void **)&gbuff, SWIFT_STRUCT_ALIGNMENT,
                          sizeof(struct cell_buff) * gcount) != 0)
         error("Failed to allocate temporary indices.");
       for (int k = 0; k < gcount; k++) {
@@ -2082,7 +2082,7 @@ void space_split_recursive(struct space *s, struct cell *c,
       }
     }
     if (scount > 0) {
-      if (posix_memalign((void *)&sbuff, SWIFT_STRUCT_ALIGNMENT,
+      if (posix_memalign((void **)&sbuff, SWIFT_STRUCT_ALIGNMENT,
                          sizeof(struct cell_buff) * scount) != 0)
         error("Failed to allocate temporary indices.");
       for (int k = 0; k < scount; k++) {
@@ -2510,7 +2510,7 @@ void space_getcells(struct space *s, int nr_cells, struct cell **cells) {
 
     /* Is the cell buffer empty? */
     if (s->cells_sub == NULL) {
-      if (posix_memalign((void *)&s->cells_sub, cell_align,
+      if (posix_memalign((void **)&s->cells_sub, cell_align,
                          space_cellallocchunk * sizeof(struct cell)) != 0)
         error("Failed to allocate more cells.");
 
@@ -2523,7 +2523,7 @@ void space_getcells(struct space *s, int nr_cells, struct cell **cells) {
     /* Is the multipole buffer empty? */
     if (s->gravity && s->multipoles_sub == NULL) {
       if (posix_memalign(
-              (void *)&s->multipoles_sub, multipole_align,
+              (void **)&s->multipoles_sub, multipole_align,
               space_cellallocchunk * sizeof(struct gravity_tensors)) != 0)
         error("Failed to allocate more multipoles.");
 
@@ -2740,8 +2740,8 @@ void space_first_init_sparts(struct space *s) {
 void space_init_parts_mapper(void *restrict map_data, int count,
                              void *restrict extra_data) {
 
-  struct part *restrict parts = map_data;
-  const struct hydro_space *restrict hs = extra_data;
+  struct part *restrict parts = (struct part *)map_data;
+  const struct hydro_space *restrict hs = (struct hydro_space *)extra_data;
   for (int k = 0; k < count; k++) hydro_init_part(&parts[k], hs);
 }
 
@@ -2766,7 +2766,7 @@ void space_init_parts(struct space *s, int verbose) {
 void space_init_gparts_mapper(void *restrict map_data, int count,
                               void *restrict extra_data) {
 
-  struct gpart *gparts = map_data;
+  struct gpart *gparts = (struct gpart *)map_data;
   for (int k = 0; k < count; k++) gravity_init_gpart(&gparts[k]);
 }
 
@@ -2791,8 +2791,8 @@ void space_init_gparts(struct space *s, int verbose) {
 
 void space_convert_quantities_mapper(void *restrict map_data, int count,
                                      void *restrict extra_data) {
-  struct space *s = extra_data;
-  struct part *restrict parts = map_data;
+  struct space *s = (struct space *)extra_data;
+  struct part *restrict parts = (struct part *)map_data;
   const ptrdiff_t index = parts - s->parts;
   struct xpart *restrict xparts = s->xparts + index;
   for (int k = 0; k < count; k++)
@@ -3007,7 +3007,7 @@ void space_init(struct space *s, const struct swift_params *params,
 
   /* Allocate the extra parts array for the gas particles. */
   if (Npart > 0) {
-    if (posix_memalign((void *)&s->xparts, xpart_align,
+    if (posix_memalign((void **)&s->xparts, xpart_align,
                        Npart * sizeof(struct xpart)) != 0)
       error("Failed to allocate xparts.");
     bzero(s->xparts, Npart * sizeof(struct xpart));
@@ -3055,15 +3055,15 @@ void space_replicate(struct space *s, int replicate, int verbose) {
   struct gpart *gparts = NULL;
   struct spart *sparts = NULL;
 
-  if (posix_memalign((void *)&parts, part_align,
+  if (posix_memalign((void **)&parts, part_align,
                      s->nr_parts * sizeof(struct part)) != 0)
     error("Failed to allocate new part array.");
 
-  if (posix_memalign((void *)&gparts, gpart_align,
+  if (posix_memalign((void **)&gparts, gpart_align,
                      s->nr_gparts * sizeof(struct gpart)) != 0)
     error("Failed to allocate new gpart array.");
 
-  if (posix_memalign((void *)&sparts, spart_align,
+  if (posix_memalign((void **)&sparts, spart_align,
                      s->nr_sparts * sizeof(struct spart)) != 0)
     error("Failed to allocate new spart array.");
 
@@ -3300,10 +3300,10 @@ void space_struct_restore(struct space *s, FILE *stream) {
   if (s->nr_parts > 0) {
 
     /* Need the memory for these. */
-    if (posix_memalign((void *)&s->parts, part_align,
+    if (posix_memalign((void **)&s->parts, part_align,
                        s->size_parts * sizeof(struct part)) != 0)
       error("Failed to allocate restore part array.");
-    if (posix_memalign((void *)&s->xparts, xpart_align,
+    if (posix_memalign((void **)&s->xparts, xpart_align,
                        s->size_parts * sizeof(struct xpart)) != 0)
       error("Failed to allocate restore xpart array.");
 
@@ -3314,7 +3314,7 @@ void space_struct_restore(struct space *s, FILE *stream) {
   }
   s->gparts = NULL;
   if (s->nr_gparts > 0) {
-    if (posix_memalign((void *)&s->gparts, gpart_align,
+    if (posix_memalign((void **)&s->gparts, gpart_align,
                        s->size_gparts * sizeof(struct gpart)) != 0)
       error("Failed to allocate restore gpart array.");
 
@@ -3324,7 +3324,7 @@ void space_struct_restore(struct space *s, FILE *stream) {
 
   s->sparts = NULL;
   if (s->nr_sparts > 0) {
-    if (posix_memalign((void *)&s->sparts, spart_align,
+    if (posix_memalign((void **)&s->sparts, spart_align,
                        s->size_sparts * sizeof(struct spart)) != 0)
       error("Failed to allocate restore spart array.");
 
diff --git a/src/statistics.c b/src/statistics.c
index f3604a2417159abab59f84e66130449a9203e362..ed5e0f743411d501c11c7ada35d82d77c2398a3d 100644
--- a/src/statistics.c
+++ b/src/statistics.c
@@ -140,7 +140,7 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) {
     const double x[3] = {p->x[0], p->x[1], p->x[2]};
     const float m = hydro_get_mass(p);
     const float entropy = hydro_get_entropy(p);
-    const float u_int = hydro_get_internal_energy(p);
+    const float u_inter = hydro_get_internal_energy(p);
 
     /* Collect mass */
     stats.mass += m;
@@ -162,7 +162,7 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) {
 
     /* Collect energies. */
     stats.E_kin += 0.5f * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
-    stats.E_int += m * u_int;
+    stats.E_int += m * u_inter;
     stats.E_rad += cooling_get_radiated_energy(xp);
     if (gp != NULL) {
       stats.E_pot_self += m * gravity_get_potential(gp);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7e139754598bc3e52771b47c02c39429c9bd49c9..e830aad453653dd2ffa265627953af1c28d8cf59 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -62,7 +62,7 @@ test27cells_SOURCES = test27cells.c
 
 test27cells_subset_SOURCES = test27cells.c
 
-test27cells_subset_CFLAGS = $(AM_CFLAGS) -DDOSELF_SUBSET
+test27cells_subset_CFLAGS = $(AM_CFLAGS) -DTEST_DOSELF_SUBSET -DTEST_DOPAIR_SUBSET
 
 testPeriodicBC_SOURCES = testPeriodicBC.c
 
diff --git a/tests/test125cells.c b/tests/test125cells.c
index 6df500f05c254ed9b6686956dce1a07588318e35..7c6a161093c0cb823efb04f62e0ba570a5dd1651 100644
--- a/tests/test125cells.c
+++ b/tests/test125cells.c
@@ -48,7 +48,7 @@
 #define DOPAIR2_NAME "runner_dopair2_force"
 #endif
 
-#define NODE_ID 1
+#define NODE_ID 0
 
 enum velocity_field {
   velocity_zero,
@@ -464,7 +464,10 @@ void runner_doself2_force_vec(struct runner *r, struct cell *ci);
 /* And go... */
 int main(int argc, char *argv[]) {
 
+#ifdef HAVE_SETAFFINITY
   engine_pin();
+#endif
+
   size_t runs = 0, particles = 0;
   double h = 1.23485, size = 1., rho = 2.5;
   double perturbation = 0.;
diff --git a/tests/test27cells.c b/tests/test27cells.c
index 2d9cce7028026514e78da0ae09984ab39d7dce38..0b8d96a29649d2af14deaefd105901936d337842 100644
--- a/tests/test27cells.c
+++ b/tests/test27cells.c
@@ -31,29 +31,29 @@
 #include "swift.h"
 
 #if defined(WITH_VECTORIZATION)
-#define DOSELF1 runner_doself1_density_vec
-#define DOSELF1_SUBSET runner_doself_subset_density_vec
+#define DOSELF1 runner_doself1_branch_density
+#define DOSELF1_SUBSET runner_doself_subset_branch_density
 #define DOPAIR1_SUBSET runner_dopair_subset_branch_density
 #define DOPAIR1 runner_dopair1_branch_density
 #ifdef TEST_DOSELF_SUBSET
-#define DOSELF1_NAME "runner_doself_subset_density_vec"
+#define DOSELF1_NAME "runner_doself_subset_branch_density"
 #else
-#define DOSELF1_NAME "runner_doself_density_vec"
+#define DOSELF1_NAME "runner_doself1_branch_density"
 #endif
 #ifdef TEST_DOPAIR_SUBSET
 #define DOPAIR1_NAME "runner_dopair_subset_branch_density"
 #else
-#define DOPAIR1_NAME "runner_dopair_density_vec"
+#define DOPAIR1_NAME "runner_dopair1_branch_density"
 #endif
 #endif
 
 #ifndef DOSELF1
-#define DOSELF1 runner_doself1_density
-#define DOSELF1_SUBSET runner_doself_subset_density
+#define DOSELF1 runner_doself1_branch_density
+#define DOSELF1_SUBSET runner_doself_subset_branch_density
 #ifdef TEST_DOSELF_SUBSET
-#define DOSELF1_NAME "runner_doself1_subset_density"
+#define DOSELF1_NAME "runner_doself_subset_branch_density"
 #else
-#define DOSELF1_NAME "runner_doself1_density"
+#define DOSELF1_NAME "runner_doself1_branch_density"
 #endif
 #endif
 
@@ -63,11 +63,11 @@
 #ifdef TEST_DOPAIR_SUBSET
 #define DOPAIR1_NAME "runner_dopair1_subset_branch_density"
 #else
-#define DOPAIR1_NAME "runner_dopair1_density"
+#define DOPAIR1_NAME "runner_dopair1_branch_density"
 #endif
 #endif
 
-#define NODE_ID 1
+#define NODE_ID 0
 
 enum velocity_types {
   velocity_zero,
@@ -319,31 +319,26 @@ void dump_particle_fields(char *fileName, struct cell *main_cell,
 }
 
 /* Just a forward declaration... */
-void runner_doself1_density(struct runner *r, struct cell *ci);
-void runner_doself1_density_vec(struct runner *r, struct cell *ci);
 void runner_dopair1_branch_density(struct runner *r, struct cell *ci,
                                    struct cell *cj);
-void runner_doself_subset_density(struct runner *r, struct cell *restrict ci,
-                                  struct part *restrict parts,
-                                  int *restrict ind, int count);
-void runner_dopair_subset_density(struct runner *r, struct cell *restrict ci,
-                                  struct part *restrict parts_i,
-                                  int *restrict ind, int count,
-                                  struct cell *restrict cj);
-void runner_doself_subset_density_vec(struct runner *r,
-                                      struct cell *restrict ci,
-                                      struct part *restrict parts,
-                                      int *restrict ind, int count);
+void runner_doself1_branch_density(struct runner *r, struct cell *c);
 void runner_dopair_subset_branch_density(struct runner *r,
                                          struct cell *restrict ci,
                                          struct part *restrict parts_i,
                                          int *restrict ind, int count,
                                          struct cell *restrict cj);
+void runner_doself_subset_branch_density(struct runner *r,
+                                         struct cell *restrict ci,
+                                         struct part *restrict parts,
+                                         int *restrict ind, int count);
 
 /* And go... */
 int main(int argc, char *argv[]) {
 
+#ifdef HAVE_SETAFFINITY
   engine_pin();
+#endif
+
   size_t runs = 0, particles = 0;
   double h = 1.23485, size = 1., rho = 1.;
   double perturbation = 0., h_pert = 0.;
diff --git a/tests/testPeriodicBC.c b/tests/testPeriodicBC.c
index 53337e499673a7ac92c1e7ce3e0da189e9e76f06..f2929061a2449a76f5e5cee0412bd7c90865fbf8 100644
--- a/tests/testPeriodicBC.c
+++ b/tests/testPeriodicBC.c
@@ -49,7 +49,7 @@
 #define DOPAIR1_NAME "runner_dopair1_density"
 #endif
 
-#define NODE_ID 1
+#define NODE_ID 0
 
 enum velocity_types {
   velocity_zero,
@@ -380,7 +380,10 @@ void test_boundary_conditions(struct cell **cells, struct runner runner,
 /* And go... */
 int main(int argc, char *argv[]) {
 
+#ifdef HAVE_SETAFFINITY
   engine_pin();
+#endif
+
   size_t runs = 0, particles = 0;
   double h = 1.23485, size = 1., rho = 1.;
   double perturbation = 0.;
diff --git a/tests/testSymmetry.c b/tests/testSymmetry.c
index 68a878b05c3fc298ef7d0b159df9997d2ef1f82d..2e950c5c79f84d601b8d034927b174ac0454de68 100644
--- a/tests/testSymmetry.c
+++ b/tests/testSymmetry.c
@@ -26,12 +26,13 @@
 
 #include "swift.h"
 
-int main(int argc, char *argv[]) {
+void print_bytes(void *p, size_t len) {
+  printf("(");
+  for (size_t i = 0; i < len; ++i) printf("%02x", ((unsigned char *)p)[i]);
+  printf(")\n");
+}
 
-/* Choke on FPEs */
-#ifdef HAVE_FE_ENABLE_EXCEPT
-  feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
-#endif
+void test() {
 
 #if defined(SHADOWFAX_SPH)
   /* Initialize the Voronoi simulation box */
@@ -52,8 +53,8 @@ int main(int argc, char *argv[]) {
   for (size_t i = 0; i < 3; ++i) pj.x[0] = random_uniform(-1., 1.);
   pi.h = 2.f;
   pj.h = 2.f;
-  pi.id = 1;
-  pj.id = 2;
+  pi.id = 1ll;
+  pj.id = 2ll;
 
 #if defined(GIZMO_SPH) || defined(SHADOWFAX_SPH)
   /* Give the primitive variables sensible values, since the Riemann solver does
@@ -120,11 +121,11 @@ int main(int argc, char *argv[]) {
   memcpy(&pi2, &pi, sizeof(struct part));
   memcpy(&pj2, &pj, sizeof(struct part));
 
-  int i_ok = memcmp(&pi, &pi2, sizeof(struct part));
-  int j_ok = memcmp(&pj, &pj2, sizeof(struct part));
+  int i_not_ok = memcmp(&pi, &pi2, sizeof(struct part));
+  int j_not_ok = memcmp(&pj, &pj2, sizeof(struct part));
 
-  if (i_ok != 0) error("Particles 'pi' do not match after copy");
-  if (j_ok != 0) error("Particles 'pj' do not match after copy");
+  if (i_not_ok) error("Particles 'pi' do not match after copy");
+  if (j_not_ok) error("Particles 'pj' do not match after copy");
 
   /* Compute distance vector */
   float dx[3];
@@ -137,20 +138,26 @@ int main(int argc, char *argv[]) {
 
   /* Call the symmetric version */
   runner_iact_density(r2, dx, pi.h, pj.h, &pi, &pj);
+  /* Now the chemistry. WARNING chemistry is not initialized */
+  runner_iact_chemistry(r2, dx, pi.h, pj.h, &pi, &pj);
 
   /* Call the non-symmetric version */
   runner_iact_nonsym_density(r2, dx, pi2.h, pj2.h, &pi2, &pj2);
+  /* Now the chemistry. WARNING chemistry is not initialized */
+  runner_iact_nonsym_chemistry(r2, dx, pi2.h, pj2.h, &pi2, &pj2);
   dx[0] = -dx[0];
   dx[1] = -dx[1];
   dx[2] = -dx[2];
   runner_iact_nonsym_density(r2, dx, pj2.h, pi2.h, &pj2, &pi2);
+  /* Now the chemistry. WARNING chemistry is not initialized */
+  runner_iact_nonsym_chemistry(r2, dx, pj2.h, pi2.h, &pj2, &pi2);
 
   /* Check that the particles are the same */
-  i_ok = memcmp(&pi, &pi2, sizeof(struct part));
-  j_ok = memcmp(&pj, &pj2, sizeof(struct part));
+  i_not_ok = memcmp(&pi, &pi2, sizeof(struct part));
+  j_not_ok = memcmp(&pj, &pj2, sizeof(struct part));
 
-  if (i_ok) error("Particles 'pi' do not match after density");
-  if (j_ok) error("Particles 'pj' do not match after density");
+  if (i_not_ok) error("Particles 'pi' do not match after density");
+  if (j_not_ok) error("Particles 'pj' do not match after density");
 
   /* --- Test the force loop --- */
 
@@ -166,8 +173,8 @@ int main(int argc, char *argv[]) {
 
 /* Check that the particles are the same */
 #if defined(GIZMO_SPH)
-  i_ok = 0;
-  j_ok = 0;
+  i_not_ok = 0;
+  j_not_ok = 0;
   for (size_t i = 0; i < sizeof(struct part) / sizeof(float); ++i) {
     float a = *(((float *)&pi) + i);
     float b = *(((float *)&pi2) + i);
@@ -194,24 +201,53 @@ int main(int argc, char *argv[]) {
       message("%.8e, %.8e, %lu", c, d, i);
     }
 
-    i_ok |= a_is_b;
-    j_ok |= c_is_d;
+    i_not_ok |= a_is_b;
+    j_not_ok |= c_is_d;
   }
 #else
-  i_ok = memcmp(&pi, &pi2, sizeof(struct part));
-  j_ok = memcmp(&pj, &pj2, sizeof(struct part));
+  i_not_ok =
+      strncmp((const char *)&pi, (const char *)&pi2, sizeof(struct part));
+  j_not_ok =
+      strncmp((const char *)&pj, (const char *)&pj2, sizeof(struct part));
 #endif
 
-  if (i_ok) {
+  if (i_not_ok) {
     printParticle_single(&pi, &xpi);
     printParticle_single(&pi2, &xpi);
-    error("Particles 'pi' do not match after force");
+    print_bytes(&pj, sizeof(struct part));
+    print_bytes(&pj2, sizeof(struct part));
+    error("Particles 'pi' do not match after force (byte = %d)", i_not_ok);
   }
-  if (j_ok) {
+  if (j_not_ok) {
     printParticle_single(&pj, &xpj);
     printParticle_single(&pj2, &xpj);
-    error("Particles 'pj' do not match after force");
+    print_bytes(&pj, sizeof(struct part));
+    print_bytes(&pj2, sizeof(struct part));
+    error("Particles 'pj' do not match after force (byte = %d)", j_not_ok);
+  }
+}
+
+int main(int argc, char *argv[]) {
+
+  /* Initialize CPU frequency, this also starts time. */
+  unsigned long long cpufreq = 0;
+  clocks_set_cpufreq(cpufreq);
+
+/* Choke on FPEs */
+#ifdef HAVE_FE_ENABLE_EXCEPT
+  feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
+#endif
+
+  /* Get some randomness going */
+  const int seed = time(NULL);
+  message("Seed = %d", seed);
+  srand(seed);
+
+  for (int i = 0; i < 100; ++i) {
+    message("Random test %d/100", i);
+    test();
   }
+  message("All good");
 
   return 0;
 }