diff --git a/src/const.h b/src/const.h
index 6432ef6a9e8107d94c93a32967e291d7e1e4d24d..8390da08980a47f45823fe7bcf3b784415305dd8 100644
--- a/src/const.h
+++ b/src/const.h
@@ -40,6 +40,7 @@
 #define const_max_u_change 0.1f
 
 /* Gravity stuff. */
+#define multipole_order 1
 #define const_theta_max 0.57735f
 #define const_G 6.672e-8f     /* Gravitational constant. */
 #define const_epsilon 0.0014f /* Gravity blending distance. */
diff --git a/src/engine.c b/src/engine.c
index d5fe48bf1f75d3afe17efef60391d9a9f099af48..e7c7e8aa363ca15203cc9c2f945b64de5d32c893 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1947,7 +1947,7 @@ void engine_init_particles(struct engine *e) {
   /* Add the tasks corresponding to self-gravity to the masks */
   if (e->policy & engine_policy_self_gravity) {
 
-    /* Nothing here for now */
+    mask |= 1 << task_type_grav_up;
   }
 
   /* Add the tasks corresponding to external gravity to the masks */
@@ -2128,7 +2128,7 @@ void engine_step(struct engine *e) {
   /* Add the tasks corresponding to self-gravity to the masks */
   if (e->policy & engine_policy_self_gravity) {
 
-    /* Nothing here for now */
+    mask |= 1 << task_type_grav_up;
   }
 
   /* Add the tasks corresponding to external gravity to the masks */
diff --git a/src/multipole.c b/src/multipole.c
index fc4701fead68e64e8742730325931282f80e8934..23d845c323efeab9f8bbf7206e925c6aef0d8d29 100644
--- a/src/multipole.c
+++ b/src/multipole.c
@@ -1,6 +1,7 @@
 /*******************************************************************************
  * This file is part of SWIFT.
  * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
+ *               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
@@ -37,27 +38,28 @@
 #include "multipole.h"
 
 /**
- * @brief Merge two multipoles.
+ * @brief Add the second multipole to the first one.
  *
- * @param ma The #multipole which will contain the merged result.
- * @param mb The other #multipole.
+ * @param m_sum The #multipole which will contain the sum.
+ * @param m_other The #multipole to add.
  */
 
-void multipole_merge(struct multipole *ma, struct multipole *mb) {
+void multipole_add(struct multipole *m_sum, const struct multipole *m_other) {
 
-#if multipole_order == 1
+#if multipole_order != 1
+#error "Multipoles of order >1 not yet implemented."
+#endif
 
   /* Correct the position. */
-  float mma = ma->coeffs[0], mmb = mb->coeffs[0];
-  float w = 1.0f / (mma + mmb);
-  for (int k = 0; k < 3; k++) ma->x[k] = (ma->x[k] * mma + mb->x[k] * mmb) * w;
+  const float M_tot = m_sum->mass + m_other->mass;
+  const float M_tot_inv = 1.f / M_tot;
+  for (int k = 0; k < 3; k++)
+    m_sum->CoM[k] =
+        (m_sum->CoM[k] * m_sum->mass + m_other->CoM[k] * m_other->mass) *
+        M_tot_inv;
 
   /* Add the particle to the moments. */
-  ma->coeffs[0] = mma + mmb;
-
-#else
-#error( "Multipoles of order %i not yet implemented." , multipole_order )
-#endif
+  m_sum->mass = M_tot;
 }
 
 /**
@@ -69,19 +71,21 @@ void multipole_merge(struct multipole *ma, struct multipole *mb) {
 
 void multipole_addpart(struct multipole *m, struct gpart *p) {
 
-#if multipole_order == 1
+  /* #if multipole_order == 1 */
 
-  /* Correct the position. */
-  float mm = m->coeffs[0], mp = p->mass;
-  float w = 1.0f / (mm + mp);
-  for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + p->x[k] * mp) * w;
+  /*   /\* Correct the position. *\/ */
+  /*   float mm = m->coeffs[0], mp = p->mass; */
+  /*   float w = 1.0f / (mm + mp); */
+  /*   for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + p->x[k] * mp) * w;
+   */
 
-  /* Add the particle to the moments. */
-  m->coeffs[0] = mm + mp;
+  /*   /\* Add the particle to the moments. *\/ */
+  /*   m->coeffs[0] = mm + mp; */
 
-#else
-#error( "Multipoles of order %i not yet implemented." , multipole_order )
-#endif
+  /* #else */
+  /* #error( "Multipoles of order %i not yet implemented." , multipole_order )
+   */
+  /* #endif */
 }
 
 /**
@@ -94,76 +98,76 @@ void multipole_addpart(struct multipole *m, struct gpart *p) {
 
 void multipole_addparts(struct multipole *m, struct gpart *p, int N) {
 
-#if multipole_order == 1
-
-  /* Get the combined mass and positions. */
-  double xp[3] = {0.0, 0.0, 0.0};
-  float mp = 0.0f, w;
-  for (int k = 0; k < N; k++) {
-    w = p[k].mass;
-    mp += w;
-    xp[0] += p[k].x[0] * w;
-    xp[1] += p[k].x[1] * w;
-    xp[2] += p[k].x[2] * w;
-  }
-
-  /* Correct the position. */
-  float mm = m->coeffs[0];
-  w = 1.0f / (mm + mp);
-  for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + xp[k]) * w;
+  /* #if multipole_order == 1 */
+
+  /*   /\* Get the combined mass and positions. *\/ */
+  /*   double xp[3] = {0.0, 0.0, 0.0}; */
+  /*   float mp = 0.0f, w; */
+  /*   for (int k = 0; k < N; k++) { */
+  /*     w = p[k].mass; */
+  /*     mp += w; */
+  /*     xp[0] += p[k].x[0] * w; */
+  /*     xp[1] += p[k].x[1] * w; */
+  /*     xp[2] += p[k].x[2] * w; */
+  /*   } */
+
+  /*   /\* Correct the position. *\/ */
+  /*   float mm = m->coeffs[0]; */
+  /*   w = 1.0f / (mm + mp); */
+  /*   for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + xp[k]) * w; */
+
+  /*   /\* Add the particle to the moments. *\/ */
+  /*   m->coeffs[0] = mm + mp; */
+
+  /* #else */
+  /* #error( "Multipoles of order %i not yet implemented." , multipole_order )
+   */
+  /* #endif */
+}
 
-  /* Add the particle to the moments. */
-  m->coeffs[0] = mm + mp;
+/**
+* @brief Reset the data of a #multipole.
+*
+* @param m The #multipole.
+*/
+void multipole_reset(struct multipole *m) {
 
-#else
-#error( "Multipoles of order %i not yet implemented." , multipole_order )
-#endif
+  /* Just bzero the struct. */
+  bzero(m, sizeof(struct multipole));
 }
 
 /**
- * @brief Init a multipole from a set of particles.
- *
- * @param m The #multipole.
- * @param parts The #gpart.
- * @param N The number of particles.
- */
-
-void multipole_init(struct multipole *m, struct gpart *parts, int N) {
+* @brief Init a multipole from a set of particles.
+*
+* @param m The #multipole.
+* @param parts The #gpart.
+* @param N The number of particles.
+*/
+void multipole_init(struct multipole *m, const struct gpart *gparts,
+                    int gcount) {
+
+#if multipole_order != 1
+#error "Multipoles of order >1 not yet implemented."
+#endif
 
-#if multipole_order == 1
+  /* Zero everything */
+  multipole_reset(m);
 
-  float mass = 0.0f, w;
+  float mass = 0.0f;
   double x[3] = {0.0, 0.0, 0.0};
-  int k;
 
   /* Collect the particle data. */
-  for (k = 0; k < N; k++) {
-    w = parts[k].mass;
+  for (int k = 0; k < gcount; k++) {
+    const float w = gparts[k].mass;
     mass += w;
-    x[0] += parts[k].x[0] * w;
-    x[1] += parts[k].x[1] * w;
-    x[2] += parts[k].x[2] * w;
+    x[0] += gparts[k].x[0] * w;
+    x[1] += gparts[k].x[1] * w;
+    x[2] += gparts[k].x[2] * w;
   }
 
   /* Store the data on the multipole. */
-  m->coeffs[0] = mass;
-  m->x[0] = x[0] / mass;
-  m->x[1] = x[1] / mass;
-  m->x[2] = x[2] / mass;
-
-#else
-#error( "Multipoles of order %i not yet implemented." , multipole_order )
-#endif
-}
-
-/**
- * @brief Reset the data of a #multipole.
- *
- * @param m The #multipole.
- */
-
-void multipole_reset(struct multipole *m) {
-
-  /* Just bzero the struct. */
-  bzero(m, sizeof(struct multipole));
+  m->mass = mass;
+  m->CoM[0] = x[0] / mass;
+  m->CoM[1] = x[1] / mass;
+  m->CoM[2] = x[2] / mass;
 }
diff --git a/src/multipole.h b/src/multipole.h
index 85ba44d3ce95d958b721d435ccd26b72e30a79c1..07e9ecbd48fec5844ef3df3555b48c5fa4b6c0e3 100644
--- a/src/multipole.h
+++ b/src/multipole.h
@@ -1,6 +1,7 @@
 /*******************************************************************************
  * This file is part of SWIFT.
  * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
+ *               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
@@ -28,31 +29,33 @@
 #include "kernel_gravity.h"
 #include "part.h"
 
-/* Some constants. */
-#define multipole_order 1
-
 /* Multipole struct. */
 struct multipole {
 
   /* Multipole location. */
-  double x[3];
+  double CoM[3];
+
+  /* Multipole mass */
+  float mass;
 
-  /* Acceleration on this multipole. */
-  float a[3];
+  /* /\* Acceleration on this multipole. *\/ */
+  /* float a[3]; */
 
-  /* Multipole coefficients. */
-  float coeffs[multipole_order * multipole_order];
+  /* /\* Multipole coefficients. *\/ */
+  /* float coeffs[multipole_order * multipole_order]; */
 };
 
 /* Multipole function prototypes. */
-static void multipole_iact_mm(struct multipole *ma, struct multipole *mb,
-                              double *shift);
-void multipole_merge(struct multipole *ma, struct multipole *mb);
-void multipole_addpart(struct multipole *m, struct gpart *p);
-void multipole_addparts(struct multipole *m, struct gpart *p, int N);
-void multipole_init(struct multipole *m, struct gpart *parts, int N);
+void multipole_add(struct multipole *m_sum, const struct multipole *m_term);
+void multipole_init(struct multipole *m, const struct gpart *gparts,
+                    int gcount);
 void multipole_reset(struct multipole *m);
 
+/* static void multipole_iact_mm(struct multipole *ma, struct multipole *mb, */
+/*                               double *shift); */
+/* void multipole_addpart(struct multipole *m, struct gpart *p); */
+/* void multipole_addparts(struct multipole *m, struct gpart *p, int N); */
+
 /**
  * @brief Compute the pairwise interaction between two multipoles.
  *
@@ -60,39 +63,38 @@ void multipole_reset(struct multipole *m);
  * @param mb The second #multipole.
  * @param shift The periodicity correction.
  */
-
 __attribute__((always_inline)) INLINE static void multipole_iact_mm(
     struct multipole *ma, struct multipole *mb, double *shift) {
-
-  float dx[3], ir, r, r2 = 0.0f, acc;
-  int k;
-
-  /* Compute the multipole distance. */
-  for (k = 0; k < 3; k++) {
-    dx[k] = ma->x[k] - mb->x[k] - shift[k];
-    r2 += dx[k] * dx[k];
-  }
-
-  /* Compute the normalized distance vector. */
-  ir = 1.0f / sqrtf(r2);
-  r = r2 * ir;
-
-  /* Evaluate the gravity kernel. */
-  kernel_grav_eval(r, &acc);
-
-  /* Scale the acceleration. */
-  acc *= const_G * ir * ir * ir;
-
-/* Compute the forces on both multipoles. */
-#if multipole_order == 1
-  float mma = ma->coeffs[0], mmb = mb->coeffs[0];
-  for (k = 0; k < 3; k++) {
-    ma->a[k] -= dx[k] * acc * mmb;
-    mb->a[k] += dx[k] * acc * mma;
-  }
-#else
-#error( "Multipoles of order %i not yet implemented." , multipole_order )
-#endif
+  /*   float dx[3], ir, r, r2 = 0.0f, acc; */
+  /*   int k; */
+
+  /*   /\* Compute the multipole distance. *\/ */
+  /*   for (k = 0; k < 3; k++) { */
+  /*     dx[k] = ma->x[k] - mb->x[k] - shift[k]; */
+  /*     r2 += dx[k] * dx[k]; */
+  /*   } */
+
+  /*   /\* Compute the normalized distance vector. *\/ */
+  /*   ir = 1.0f / sqrtf(r2); */
+  /*   r = r2 * ir; */
+
+  /*   /\* Evaluate the gravity kernel. *\/ */
+  /*   kernel_grav_eval(r, &acc); */
+
+  /*   /\* Scale the acceleration. *\/ */
+  /*   acc *= const_G * ir * ir * ir; */
+
+  /* /\* Compute the forces on both multipoles. *\/ */
+  /* #if multipole_order == 1 */
+  /*   float mma = ma->coeffs[0], mmb = mb->coeffs[0]; */
+  /*   for (k = 0; k < 3; k++) { */
+  /*     ma->a[k] -= dx[k] * acc * mmb; */
+  /*     mb->a[k] += dx[k] * acc * mma; */
+  /*   } */
+  /* #else */
+  /* #error( "Multipoles of order %i not yet implemented." , multipole_order )
+   */
+  /* #endif */
 }
 
 /**
@@ -102,35 +104,35 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mm(
  * @param p The #gpart.
  * @param shift The periodicity correction.
  */
-
 __attribute__((always_inline)) INLINE static void multipole_iact_mp(
     struct multipole *m, struct gpart *p, double *shift) {
 
-  float dx[3], ir, r, r2 = 0.0f, acc;
-  int k;
+  /*   float dx[3], ir, r, r2 = 0.0f, acc; */
+  /*   int k; */
 
-  /* Compute the multipole distance. */
-  for (k = 0; k < 3; k++) {
-    dx[k] = m->x[k] - p->x[k] - shift[k];
-    r2 += dx[k] * dx[k];
-  }
+  /*   /\* Compute the multipole distance. *\/ */
+  /*   for (k = 0; k < 3; k++) { */
+  /*     dx[k] = m->x[k] - p->x[k] - shift[k]; */
+  /*     r2 += dx[k] * dx[k]; */
+  /*   } */
 
-  /* Compute the normalized distance vector. */
-  ir = 1.0f / sqrtf(r2);
-  r = r2 * ir;
+  /*   /\* Compute the normalized distance vector. *\/ */
+  /*   ir = 1.0f / sqrtf(r2); */
+  /*   r = r2 * ir; */
 
-  /* Evaluate the gravity kernel. */
-  kernel_grav_eval(r, &acc);
+  /*   /\* Evaluate the gravity kernel. *\/ */
+  /*   kernel_grav_eval(r, &acc); */
 
-  /* Scale the acceleration. */
-  acc *= const_G * ir * ir * ir * m->coeffs[0];
+  /*   /\* Scale the acceleration. *\/ */
+  /*   acc *= const_G * ir * ir * ir * m->coeffs[0]; */
 
-/* Compute the forces on both multipoles. */
-#if multipole_order == 1
-  for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc;
-#else
-#error( "Multipoles of order %i not yet implemented." , multipole_order )
-#endif
+  /* /\* Compute the forces on both multipoles. *\/ */
+  /* #if multipole_order == 1 */
+  /*   for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; */
+  /* #else */
+  /* #error( "Multipoles of order %i not yet implemented." , multipole_order )
+   */
+  /* #endif */
 }
 
 #endif /* SWIFT_MULTIPOLE_H */
diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h
index 19e77879501c1e34a54e0d436e9a140a9b273d1a..31aac56827eb8f52af13a883ce8f5e002c6ded9e 100644
--- a/src/runner_doiact_grav.h
+++ b/src/runner_doiact_grav.h
@@ -1,6 +1,7 @@
 /*******************************************************************************
  * This file is part of SWIFT.
  * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
+ *               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
@@ -39,7 +40,8 @@
 /*   int pid, pjd, k, sid; */
 /*   double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; */
 /*   struct entry *restrict sort_i, *restrict sort_j; */
-/*   struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; */
+/*   struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict
+ * parts_j; */
 /*   double pix[3]; */
 /*   float dx[3], r2, h_max, di, dj; */
 /*   int count_i, count_j, cnj, cnj_new; */
@@ -77,7 +79,8 @@
 
 /*   /\* Get some other useful values. *\/ */
 /*   h_max = */
-/*       sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * */
+/*       sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])
+ * * */
 /*       const_theta_max; */
 /*   count_i = ci->gcount; */
 /*   count_j = cj->gcount; */
@@ -114,9 +117,12 @@
 
 /* #ifndef VECTORIZE */
 
-/*       // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */
-/*       //     message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */
-/*       // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */
+/*       // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525
+ * ) */
+/*       //     message( "interacting particles pi=%lli and pj=%lli with r=%.3e
+ * in */
+/*       // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long
+ */
 /*       // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */
 /*       // sizeof(struct cell) ); */
 
@@ -206,11 +212,7 @@
 
 void runner_dograv_up(struct runner *r, struct cell *c) {
 
-  /* Re-set this cell's multipole. */
-  multipole_reset(&c->multipole);
-
-  /* Split? */
-  if (c->split) {
+  if (c->split) {/* Regular node */
 
     /* Recurse. */
     for (int k = 0; k < 8; k++)
@@ -218,17 +220,16 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
 
     /* Collect the multipoles from the progeny. */
     multipole_reset(&c->multipole);
-    for (int k = 0; k < 8; k++)
+    for (int k = 0; k < 8; k++) {
       if (c->progeny[k] != NULL)
-        multipole_merge(&c->multipole, &c->progeny[k]->multipole);
+        multipole_add(&c->multipole, &c->progeny[k]->multipole);
+    }
 
-  }
+  } else {/* Leaf node. */
 
-  /* No, leaf node. */
-  else
-
-    /* Just collect the multipole. */
+    /* Just construct the multipole from the gparts. */
     multipole_init(&c->multipole, c->gparts, c->gcount);
+  }
 }
 
 /* /\** */
@@ -303,7 +304,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
 /*   } */
 /*   theta = */
 /*       sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */
-/*            (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); */
+/*            (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] *
+ * ci->h[2])); */
 
 /*   /\* Do an MM or an MP/PM? *\/ */
 /*   if (theta > const_theta_max * 4) { */
@@ -335,7 +337,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
 /*   struct engine *e = r->e; */
 /*   int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; */
 /*   double shift[3] = {0.0, 0.0, 0.0}; */
-/*   struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; */
+/*   struct gpart *restrict parts_i = ci->gparts, *restrict parts_j =
+ * cj->gparts; */
 /*   struct gpart *restrict pi, *restrict pj; */
 /*   double pix[3]; */
 /*   float dx[3], r2; */
@@ -383,9 +386,12 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
 /* /\* Compute the interaction. *\/ */
 /* #ifndef VECTORIZE */
 
-/*       // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */
-/*       //     message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */
-/*       // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */
+/*       // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525
+ * ) */
+/*       //     message( "interacting particles pi=%lli and pj=%lli with r=%.3e
+ * in */
+/*       // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long
+ */
 /*       // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */
 /*       // sizeof(struct cell) ); */
 
@@ -473,8 +479,10 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
 /* /\* Compute the interaction. *\/ */
 /* #ifndef VECTORIZE */
 
-/*       // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */
-/*       //     message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , */
+/*       // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525
+ * ) */
+/*       //     message( "interacting particles pi=%lli and pj=%lli with
+ * r=%.3e." , */
 /*       // pi->part->id , pj->part->id , sqrtf(r2) ); */
 
 /*       runner_iact_grav(r2, dx, pi, pj); */
@@ -563,7 +571,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
 /*       if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */
 /*     } */
 /*     theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */
-/*             (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); */
+/*             (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] *
+ * ci->h[2]); */
 
 /*     /\* Split the interaction? *\/ */
 /*     if (theta < const_theta_max * const_theta_max) { */