diff --git a/configure.ac b/configure.ac
index 6f47f86d304bf666fc261bd6c941ec081cc17a6f..498820bfd17e9dca0e076c32e9520eb41c24ef85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -362,6 +362,21 @@ elif test "$no_gravity_below_id" != "no"; then
    AC_DEFINE_UNQUOTED([SWIFT_NO_GRAVITY_BELOW_ID], [$enableval] ,[Particles with smaller ID than this will have zero gravity forces])
 fi
 
+# Check if we want to use boundary particles.
+AC_ARG_ENABLE([boundary-particles],
+   [AS_HELP_STRING([--enable-boundary-particles],
+     [Set all particles with an ID smaller than @<:@N@:>@ as boundary particles (i.e. receive zero gravity + hydro forces).]
+   )],
+   [boundary_particles="$enableval"],
+   [boundary_particles="no"]
+)
+if test "$boundary_particles" == "yes"; then
+   AC_MSG_ERROR(Need to specify the ID below which particles get zero forces when using --enable-boundary-particles!)
+elif test "$boundary_particles" != "no"; then
+   AC_DEFINE_UNQUOTED([SWIFT_NO_GRAVITY_BELOW_ID], [$enableval] ,[Particles with smaller ID than this will have zero gravity forces])
+   AC_DEFINE_UNQUOTED([SWIFT_BOUNDARY_PARTICLES], [$enableval] ,[Particles with smaller ID than this will be considered as boundaries.])
+fi
+
 # Check whether we have any of the ARM v8.1 tick timers
 AX_ASM_ARM_PMCCNTR
 AX_ASM_ARM_CNTVCT
@@ -1832,7 +1847,7 @@ esac
 #  External potential
 AC_ARG_WITH([ext-potential],
    [AS_HELP_STRING([--with-ext-potential=<pot>],
-      [external potential @<:@none, point-mass, point-mass-ring, point-mass-softened, isothermal, nfw, hernquist, disc-patch, sine-wave, default: none@:>@]
+      [external potential @<:@none, point-mass, point-mass-ring, point-mass-softened, isothermal, nfw, hernquist, disc-patch, sine-wave, constant, default: none@:>@]
    )],
    [with_potential="$withval"],
    [with_potential="none"]
@@ -1865,6 +1880,9 @@ case "$with_potential" in
    point-mass-softened)
       AC_DEFINE([EXTERNAL_POTENTIAL_POINTMASS_SOFT], [1], [Softened point-mass potential with form 1/(r^2 + softening^2).])
    ;;
+   constant)
+      AC_DEFINE([EXTERNAL_POTENTIAL_CONSTANT], [1], [Constant gravitational acceleration.])
+   ;;
    *)
       AC_MSG_ERROR([Unknown external potential: $with_potential])
    ;;
@@ -2043,5 +2061,6 @@ AC_MSG_RESULT([
    Naive stars interactions    : $enable_naive_interactions_stars
    Gravity checks              : $gravity_force_checks
    Custom icbrtf               : $enable_custom_icbrtf
+   Boundary particles          : $boundary_particles
 
  ------------------------])
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/README b/examples/HydroTests/Rayleigh-Taylor_2D/README
new file mode 100644
index 0000000000000000000000000000000000000000..b1ac67c0c24d98d6b3e03cec70697114bb2fb434
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/README
@@ -0,0 +1,17 @@
+Rayleigh Taylor
+---------------
+
+This is a common test for hydrodynamics (see Abel 2011, Saitoh and Makino 2013, Hopkins 2013).
+It consists in a low density layer of fluid at the bottom and a high density layer at the top.
+Due to a constant vertical gravitational acceleration, the two fluids mix togerther through the
+Rayleigh Taylor instability (e.g. nuclear mushroom cloud).
+
+In this example, we follow the implementation of Saitoh and Makino 2013, but with a longer box in order
+to avoid an interaction with the wall (see last image in Figure 10).
+
+The code needs to be compiled with the following options: `--with-hydro-dimension=2`,
+`--with-ext-potential=constant`, `--enable-boundary-particles` and `--with-adiabatic-index=7/5`.
+I also recommend to use `--with-kernel=wendland-C2`.
+
+The option `--enable-boundary-particles` requires the ID of the last boundary particle.
+This value is provided by the script makeIC.py and depends on the resolution.
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/generate_movie_from_png.sh b/examples/HydroTests/Rayleigh-Taylor_2D/generate_movie_from_png.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f97e447dc21abeabac6fe98eb23e17efd9051cf4
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/generate_movie_from_png.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+d1=gizmo/png
+d2=anarchy/png
+d3=pu/png
+
+for i in {0..1040}
+do
+    echo $i
+    tmp=`printf "%04i" $i`
+    convert $d1/rayleigh_taylor_$tmp.png $d2/rayleigh_taylor_$tmp.png $d3/rayleigh_taylor_$tmp.png +append movie/rayleigh_taylor_$tmp.png
+done
+
+ffmpeg -framerate 10 -i movie/rayleigh_taylor_%04d.png -c:v libx264 -r 30 -pix_fmt yuv420p rayleigh_taylor.mp4
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/makeIC.py b/examples/HydroTests/Rayleigh-Taylor_2D/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..d75d5f215f8b71d859693b842a1e637b52095f45
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/makeIC.py
@@ -0,0 +1,250 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
+#
+# 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
+from scipy.optimize import bisect
+
+# Generates a swift IC file for the Rayleigh-Taylor instability in a periodic
+# box following the conditions given in Saitoh and Makino 2013: 1202.4277v3
+
+# Parameters
+N = [128, 192]  # Particles along one edge
+gamma = 7./5.  # Gas adiabatic index
+dv = 0.025    # velocity perturbation
+rho_h = 2    # high density region
+rho_l = 1    # Low density region
+g = -0.5    # gravitational acceleration
+box_size = [1., 1.5]  # size of the box
+
+fixed = [0.1, 1.4]  # y-range of non fixed particles
+perturbation_box = [0.3, 1.2]  # y-range for the velocity perturbation
+fileOutputName = "rayleigh_taylor.hdf5"
+
+
+# ---------------------------------------------------
+
+if (N[0] / box_size[0] != N[1] / box_size[1]):
+    raise Exception("Suppose the same ratio for each directions")
+
+
+def density(y):
+    """
+    Mass density as function of the position y.
+    """
+    if isinstance(y, float) or isinstance(y, int):
+        y = np.array(y)
+
+    ind = y < 0.5 * box_size[1]
+    rho = np.zeros(y.shape)
+    tmp = (gamma - 1.) * g / (gamma * P0)
+    alpha = 1. / (gamma - 1.)
+
+    rho[ind] = rho_l * (1 + rho_l * tmp * (y[ind] - 0.5 * box_size[1]))**alpha
+    rho[~ind] = rho_h * (1 + rho_h * tmp * (y[~ind] - 0.5 * box_size[1]))**alpha
+
+    return rho
+
+
+def mass(y):
+    """
+    Integral of the density
+    """
+    if isinstance(y, float) or isinstance(y, int):
+        y = np.array(y)
+
+    ind = y < 0.5 * box_size[1]
+    m = np.zeros(y.shape)
+
+    B = (gamma - 1.) * g / (gamma * P0)
+    alpha = 1. / (gamma - 1.)
+
+    m[ind] = (1 + B * rho_l * (y[ind] - 0.5 * box_size[1]))**(alpha + 1)
+
+    m[~ind] = (1 + B * rho_h * (y[~ind] - 0.5 * box_size[1]))**(alpha + 1)
+
+    m -= (1 - 0.5 * B * box_size[1] * rho_l)**(alpha + 1)
+
+    return box_size[0] * m / (B * (alpha + 1))
+
+
+P0 = rho_h / gamma  # integration constant of the hydrostatic equation
+numPart = N[0] * N[1]
+
+m_tot = mass(box_size[1])
+m_part = m_tot / numPart
+
+
+def inv_mass(m):
+    """
+    Inverse of the function `mass`.
+    """
+    left = 0
+    right = box_size[1]
+
+    def f(y, x):
+        return x - mass(y)
+
+    return bisect(f, left, right, args=(m))
+
+
+def entropy(y):
+    """
+    Entropy as function of the position y.
+    Here we assume isoentropic medium.
+    """
+    if isinstance(y, float) or isinstance(y, int):
+        y = np.array(y)
+
+    ind = y < 0.5 * box_size[1]
+
+    a = np.zeros(y.shape)
+    a[ind] = P0 * rho_l**(-gamma)
+    a[~ind] = P0 * rho_h**(-gamma)
+    return a
+
+
+def smoothing_length(rho, m):
+    """
+    Compute the smoothing length
+    """
+    return 1.23 * np.sqrt(m / rho)
+
+
+def growth_rate():
+    """
+    Compute the growth rate of the instability.
+    Assumes a wavelength equal to the boxsize.
+    """
+    ymin = 0.
+    ymax = box_size[1]
+    A = density(ymax) - density(ymin)
+    A /= density(ymax) + density(ymin)
+    return np.sqrt(A * np.abs(g) * ymax / (2. * np.pi))
+
+
+def vy(x, y):
+    """
+    Velocity along the direction y
+    """
+    ind = y > perturbation_box[0]
+    ind = np.logical_and(ind, y < perturbation_box[1])
+
+    v = np.zeros(len(x))
+
+    v[ind] = 1 + np.cos(4 * np.pi * x[ind])
+    v[ind] *= 1 + np.cos(5 * np.pi * (y[ind] - 0.5 * box_size[1]))
+    v[ind] *= dv
+    return v
+
+
+if __name__ == "__main__":
+    # Start by generating grids of particles
+
+    coords = np.zeros((numPart, 3))
+    m = np.ones(numPart) * m_part
+    u = np.zeros(numPart)
+    vel = np.zeros((numPart, 3))
+    ids = np.zeros(numPart)
+
+    # generate grid of particles
+    y_prev = 0
+    uni_id = 1
+
+    # loop over y
+    eps = 1e-3 * box_size[1] / N[1]
+    for j in range(N[1]):
+        m_y = m_part * N[0] + mass(y_prev)
+        if m_y > m_tot:
+            y_j = box_size[1] - eps * (box_size[1] - y_prev)
+        else:
+            y_j = inv_mass(m_y)
+        y_prev = y_j
+
+        # loop over x
+        for i in range(N[0]):
+
+            index = j * N[0] + i
+
+            x = i * box_size[0] / float(N[0])
+
+            coords[index, 0] = x
+            coords[index, 1] = y_j
+            if (y_j < fixed[0] or y_j > fixed[1]):
+                ids[index] = uni_id
+                uni_id += 1
+
+    print("You need to compile the code with "
+          "--enable-boundary-particles=%i" % uni_id)
+    ids[ids == 0] = np.linspace(uni_id, numPart, numPart-uni_id+1)
+
+    # density
+    rho = density(coords[:, 1])
+
+    # internal energy
+    a = entropy(coords[:, 1])
+    u = a * rho**(gamma-1) / (gamma - 1.)
+
+    # smoothing length
+    h = smoothing_length(rho, m)
+
+    # Velocity perturbation
+    vel[:, 1] = vy(coords[:, 0], coords[:, 1])
+
+    # File
+    fileOutput = h5py.File(fileOutputName, 'w')
+
+    # Header
+    grp = fileOutput.create_group("/Header")
+    grp.attrs["BoxSize"] = box_size
+    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
+    grp.attrs["Dimension"] = 2
+
+    # 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[()] = vel
+    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))
+    ds = grp.create_dataset('Density', (numPart, 1), 'f')
+    ds[()] = rho.reshape((numPart, 1))
+
+    fileOutput.close()
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/makeMovie.py b/examples/HydroTests/Rayleigh-Taylor_2D/makeMovie.py
new file mode 100644
index 0000000000000000000000000000000000000000..b00c2946994e0e3d8e93b0824a4bc44b9079967e
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/makeMovie.py
@@ -0,0 +1,280 @@
+###############################################################################
+# This file is part of SWIFT.
+# Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
+#                    Josh Borrow (joshua.borrow@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/>.
+#
+##############################################################################
+
+from swiftsimio import load
+from swiftsimio.visualisation import scatter
+from matplotlib.animation import FuncAnimation
+from matplotlib.colors import LogNorm
+import matplotlib.pyplot as plt
+
+from numpy import max, min
+import numpy as np
+
+try:
+    # Try and load this, otherwise we're stuck with serial
+    from p_tqdm import p_map
+except:
+    print("Try installing the p_tqdm package to make movie frames in parallel")
+    p_map = map
+    pass
+
+
+info_frames = 40
+generate_png = False
+text_args = dict(color="black")
+
+
+class Metadata(object):
+    """
+    Copy the useful data in order to decrease the memory usage
+    """
+    def __init__(self, data):
+        metadata = data.metadata
+        self.t = metadata.t
+        try:
+            self.viscosity_info = metadata.viscosity_info
+        except:
+            self.viscosity_info = "No info"
+        try:
+            self.diffusion_info = metadata.diffusion_info
+        except:
+            self.diffusion_info = "No info"
+
+        self.code_info = metadata.code_info
+        self.compiler_info = metadata.compiler_info
+        self.hydro_info = metadata.hydro_info
+
+
+def project(data, m_res, property, ylim):
+    x, y, _ = data.gas.coordinates.value.T
+
+    mask = np.logical_and(y >= ylim[0], y <= ylim[1])
+
+    x = x[mask]
+    y = y[mask] - np.float64(ylim[0])
+
+    h = data.gas.smoothing_length[mask]
+
+    if property == "density":
+        property = "masses"
+
+    if property is not None:
+        quant = getattr(data.gas, property).value[mask]
+    else:
+        quant = np.ones_like(x)
+
+    image = scatter(x=x, y=y, m=quant, h=h, res=m_res)
+
+    return image.T
+
+
+def load_and_make_image(filename, res, property):
+    image = np.zeros(res, dtype=np.float32)
+    m_res = min(res)
+    border = int(0.2 * m_res)
+
+    # first part of the image
+    ylim = np.array([0., 1.])
+
+    data = load(filename)
+    image[:m_res, :m_res] = project(data, m_res, property, ylim)
+    if property != "density":
+        image[:m_res, :m_res] /= project(data, m_res, None, ylim)
+
+    # second part of the image
+    ylim = np.array([0.5, 1.5])
+
+    left = -m_res + border
+    image[left:, :] = project(data, m_res, property, ylim)[left:, :]
+    if property != "density":
+        image[left:, :] /= project(data, m_res, None, ylim)[left:, :]
+
+    metadata = Metadata(data)
+    return image, metadata
+
+
+def time_formatter(metadata):
+    return f"$t = {metadata.t:2.2f}$"
+
+
+def create_movie(filename, start, stop, resolution, property, output_filename):
+    """
+    Creates the movie with:
+
+    snapshots named {filename}_{start}.hdf5 to {filename}_{stop}.hdf5
+    at {resolution} x {resolution} pixel size and smoothing the given
+    {property} and outputting to {output_filename}.
+    """
+
+    if property != "density":
+        name = property
+    else:
+        name = "Fluid Density $\\rho$"
+
+    def baked_in_load(n):
+        f = filename + "_{:04d}.hdf5".format(n)
+        return load_and_make_image(f, resolution, property)
+
+    # Make frames in parallel (reading also parallel!)
+    frames, metadata = zip(*p_map(baked_in_load, list(range(start, stop))))
+
+    vmax = max(list(p_map(max, frames)))
+    vmin = min(list(p_map(min, frames)))
+
+    fig, ax = plt.subplots(figsize=(8, 1.5 * 8), dpi=resolution[0] // 8)
+    ax.axis("off")
+    fig.subplots_adjust(0, 0, 1, 1)
+
+    norm = LogNorm(vmin=vmin, vmax=vmax, clip="black")
+
+    image = ax.imshow(np.zeros_like(frames[0]), origin="lower",
+                      norm=norm)
+
+    description_text = ax.text(
+        0.5, 0.5,
+        get_simulation_information(metadata[0]),
+        va="center", ha="center",
+        **text_args, transform=ax.transAxes,
+    )
+
+    time_text = ax.text(
+        (1 - 0.025 * 0.25), 0.975,
+        time_formatter(metadata[0]),
+        **text_args,
+        va="top", ha="right",
+        transform=ax.transAxes,
+    )
+
+    ax.text(
+        0.025 * 0.25, 0.975, name, **text_args, va="top", ha="left",
+        transform=ax.transAxes
+    )
+
+    def frame(n):
+        if n >= 0:
+            image.set_array(frames[n])
+            description_text.set_text("")
+            time_text.set_text(time_formatter(metadata[n]))
+
+        if generate_png:
+            name = filename + "_{:04d}".format(n+info_frames)
+            fig.savefig(name + ".png")
+
+        else:
+            return (image,)
+
+    if generate_png:
+        for i in range(-info_frames, stop-start):
+            frame(i)
+    else:
+        animation = FuncAnimation(fig, frame,
+                                  range(-info_frames, stop-start),
+                                  interval=40)
+        animation.save(output_filename)
+
+
+def get_simulation_information(metadata):
+    """
+    Generates a string from the SWIFT metadata
+    """
+    viscosity = metadata.viscosity_info
+    diffusion = metadata.diffusion_info
+
+    output = (
+        "$\\bf{Rayleigh-Taylor}$ $\\bf{Instability}$\n\n"
+        "$\\bf{SWIFT}$\n"
+        + metadata.code_info
+        + "\n\n"
+        + "$\\bf{Compiler}$\n"
+        + metadata.compiler_info
+        + "\n\n"
+        + "$\\bf{Hydrodynamics}$\n"
+        + metadata.hydro_info
+        + "\n\n"
+        + "$\\bf{Viscosity}$\n"
+        + viscosity
+        + "\n\n"
+        + "$\\bf{Diffusion}$\n"
+        + diffusion
+    )
+
+    return output
+
+
+if __name__ == "__main__":
+    from argparse import ArgumentParser
+
+    parser = ArgumentParser(description="Creates a movie of the whole box.")
+
+    parser.add_argument(
+        "-s",
+        "--snapshot",
+        help="Snapshot name. Default: rayleigh_taylor",
+        type=str,
+        default="rayleigh_taylor",
+    )
+
+    parser.add_argument(
+        "-i", "--initial", help="Initial snapshot. Default: 0",
+        type=int, default=0
+    )
+
+    parser.add_argument(
+        "-f", "--final", help="Final snapshot. Default: 40",
+        type=int, default=40
+    )
+
+    parser.add_argument(
+        "-o",
+        "--output",
+        help="Output filename. Default: rayleigh_taylor.mp4",
+        type=str,
+        default="rayleigh_taylor.mp4",
+    )
+
+    parser.add_argument(
+        "-p",
+        "--property",
+        help="(swiftsimio) Property to plot. Default: density",
+        type=str,
+        default="density",
+    )
+
+    parser.add_argument(
+        "-r",
+        "--resolution",
+        help="Resolution to make the movie at. Default: 512",
+        type=int,
+        default=512,
+    )
+
+    vars = parser.parse_args()
+
+    yres = int(1.5 * vars.resolution)
+    vars.resolution = [yres, vars.resolution]
+
+    create_movie(
+        filename=vars.snapshot,
+        start=vars.initial,
+        stop=vars.final,
+        resolution=vars.resolution,
+        property=vars.property,
+        output_filename=vars.output,
+    )
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/plotInitialProfile.py b/examples/HydroTests/Rayleigh-Taylor_2D/plotInitialProfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..e89c4e8525fe4c88e517acbd453b0941f8f573c8
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/plotInitialProfile.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+import makeIC
+import matplotlib.pyplot as plt
+from swiftsimio import load
+import numpy as np
+
+
+N = 1000
+filename = "rayleigh_taylor_0000.hdf5"
+
+f = load(filename)
+
+# Get data from snapshot
+x, y, _ = f.gas.coordinates.value.T
+rho = f.gas.density.value
+a = f.gas.entropy.value
+
+# Get analytical solution
+y_an = np.linspace(0, makeIC.box_size[1], N)
+rho_an = makeIC.density(y_an)
+a_an = makeIC.entropy(y_an)
+
+plt.figure()
+plt.plot(a, y, ".r", label="Entropy")
+plt.plot(a_an, y_an, "--r")
+
+plt.plot(rho, y, ".k", label="Density")
+plt.plot(rho_an, y_an, "--k")
+
+plt.ylabel("Position")
+plt.xlabel("Density / Entropy")
+
+plt.xlim(0, 2.5)
+plt.ylim(0, makeIC.box_size[1])
+plt.legend()
+
+plt.show()
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/rayleigh_taylor.yml b/examples/HydroTests/Rayleigh-Taylor_2D/rayleigh_taylor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9e843c49448c27ff8c1452f7e28adbc6fe9a9cd6
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/rayleigh_taylor.yml
@@ -0,0 +1,37 @@
+# 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:   10.   # The end time of the simulation (in internal units).
+  dt_min:     1e-8  # 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:            rayleigh_taylor  # Common part of the name of output files
+  time_first:          0.               # Time of the first output (in internal units)
+  delta_time:          0.01      # 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:  ./rayleigh_taylor.hdf5     # The file to read
+  periodic:   1
+
+ConstantPotential:
+  g_cgs: [0, -0.5, 0]
\ No newline at end of file
diff --git a/examples/HydroTests/Rayleigh-Taylor_2D/run.sh b/examples/HydroTests/Rayleigh-Taylor_2D/run.sh
new file mode 100644
index 0000000000000000000000000000000000000000..0c8d3eaab9a401c4be3a586e3b7b8900406bbdbb
--- /dev/null
+++ b/examples/HydroTests/Rayleigh-Taylor_2D/run.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+# Generate the initial conditions if they are not present.
+if [ ! -e rayleigh_taylor.hdf5 ]
+then
+    echo "Generating initial conditions for the Rayleigh Taylor example..."
+    python makeIC.py
+fi
+
+# Run SWIFT
+../../swift --hydro --external-gravity  --threads=8 rayleigh_taylor.yml 2>&1 | tee output.log
+
+python makeMovie.py -i 0 -f 1001
diff --git a/src/potential.h b/src/potential.h
index 59567fe92296068f838c39a3eb5ff55c14005d48..9d1418cadafcabe1d66658c43f2c1ef15778fc2b 100644
--- a/src/potential.h
+++ b/src/potential.h
@@ -46,6 +46,8 @@
 #include "./potential/point_mass_ring/potential.h"
 #elif defined(EXTERNAL_POTENTIAL_POINTMASS_SOFT)
 #include "./potential/point_mass_softened/potential.h"
+#elif defined(EXTERNAL_POTENTIAL_CONSTANT)
+#include "./potential/constant/potential.h"
 #else
 #error "Invalid choice of external potential"
 #endif
diff --git a/src/potential/constant/potential.h b/src/potential/constant/potential.h
new file mode 100644
index 0000000000000000000000000000000000000000..f91d2b3fc8a13792901fee680678c9b93af20cbf
--- /dev/null
+++ b/src/potential/constant/potential.h
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2019  Loic Hausammann (loic.hausammann@epfl.ch)
+ *
+ * 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_POTENTIAL_CONSTANT_H
+#define SWIFT_POTENTIAL_CONSTANT_H
+
+/* Config parameters. */
+#include "../config.h"
+
+/* Some standard headers. */
+#include <float.h>
+#include <math.h>
+
+/* Local includes. */
+#include "error.h"
+#include "parser.h"
+#include "part.h"
+#include "physical_constants.h"
+#include "space.h"
+#include "units.h"
+
+/**
+ * @brief External Potential Properties - Constant acceleration.
+ */
+struct external_potential {
+
+  /*! Value of the acceleration */
+  double g[3];
+};
+
+/**
+ * @brief Computes the time-step due to the acceleration from an constant
+ * acceleration.
+ *
+ * @param time The current time.
+ * @param potential The #external_potential used in the run.
+ * @param phys_const The physical constants in internal units.
+ * @param g Pointer to the g-particle data.
+ */
+__attribute__((always_inline)) INLINE static float external_gravity_timestep(
+    double time, const struct external_potential* restrict potential,
+    const struct phys_const* restrict phys_const,
+    const struct gpart* restrict g) {
+
+  return FLT_MAX;
+}
+
+/**
+ * @brief Computes the gravitational acceleration from an constant acceleration.
+ *
+ * @param time The current time.
+ * @param potential The #external_potential used in the run.
+ * @param phys_const The physical constants in internal units.
+ * @param g Pointer to the g-particle data.
+ */
+__attribute__((always_inline)) INLINE static void external_gravity_acceleration(
+    double time, const struct external_potential* potential,
+    const struct phys_const* const phys_const, struct gpart* g) {
+
+  g->a_grav[0] += potential->g[0];
+  g->a_grav[1] += potential->g[1];
+  g->a_grav[2] += potential->g[2];
+}
+
+/**
+ * @brief Computes the gravitational potential energy of a particle in an
+ * constant acceleration.
+ *
+ * @param time The current time (unused here).
+ * @param potential The #external_potential used in the run.
+ * @param phys_const Physical constants in internal units.
+ * @param g Pointer to the particle data.
+ */
+__attribute__((always_inline)) INLINE static float
+external_gravity_get_potential_energy(
+    double time, const struct external_potential* potential,
+    const struct phys_const* const phys_const, const struct gpart* g) {
+
+  const float gh = g->x[0] * potential->g[0] + g->x[1] * potential->g[1] +
+                   g->x[2] * potential->g[2];
+
+  return g->mass * gh;
+}
+
+/**
+ * @brief Initialises the external potential properties in the internal system
+ * of units.
+ *
+ * @param parameter_file The parsed parameter file
+ * @param phys_const Physical constants in internal units
+ * @param us The current internal system of units
+ * @param potential The external potential properties to initialize
+ */
+static INLINE void potential_init_backend(
+    struct swift_params* parameter_file, const struct phys_const* phys_const,
+    const struct unit_system* us, const struct space* s,
+    struct external_potential* potential) {
+
+  /* Read in the acceleration */
+  parser_get_param_double_array(parameter_file, "ConstantPotential:g_cgs", 3,
+                                potential->g);
+
+  /* Change the unit system */
+  const double unit_length = units_cgs_conversion_factor(us, UNIT_CONV_LENGTH);
+  const double unit_time = units_cgs_conversion_factor(us, UNIT_CONV_TIME);
+  const double unit_g = unit_length / (unit_time * unit_time);
+
+  for (int i = 0; i < 3; i++) {
+    // Need to divide by G due to gravity_end_force
+    potential->g[i] /= unit_g * phys_const->const_newton_G;
+  }
+}
+
+/**
+ * @brief Prints the properties of the external potential to stdout.
+ *
+ * @param  potential The external potential properties.
+ */
+static INLINE void potential_print_backend(
+    const struct external_potential* potential) {
+
+  message(
+      "External potential is 'Constant' with properties are g = (%e, "
+      "%e, %e)",
+      potential->g[0], potential->g[1], potential->g[2]);
+}
+
+#endif /* SWIFT_CONSTANT_H */
diff --git a/src/runner.c b/src/runner.c
index 7f645665eb786ab578fd8e0cfccaa72420c08b1b..fdf371db2fb5b8a9ace982d4c35f7e37c4d2e3a1 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -3614,6 +3614,26 @@ void runner_do_end_hydro_force(struct runner *r, struct cell *c, int timer) {
 
         /* Finish the force loop */
         hydro_end_force(p, cosmo);
+
+#ifdef SWIFT_BOUNDARY_PARTICLES
+
+        /* Get the ID of the part */
+        const long long id = p->id;
+
+        /* Cancel hdyro forces of these particles */
+        if (id < SWIFT_BOUNDARY_PARTICLES) {
+
+          /* Don't move ! */
+          hydro_reset_acceleration(p);
+
+#if defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH)
+
+          /* Some values need to be reset in the Gizmo case. */
+          hydro_prepare_force(p, &c->hydro.xparts[k], cosmo,
+                              e->hydro_properties, 0);
+#endif
+        }
+#endif
       }
     }
   }