diff --git a/src/const.h b/src/const.h
index 87852ba5ead8bd8b626658537221d5a6ff6c3a4e..e6941f2cad4c62ed54f147628d47ccadab86050e 100644
--- a/src/const.h
+++ b/src/const.h
@@ -61,4 +61,6 @@
 /* Gravity properties */
 #define EXTERNAL_POTENTIAL_POINTMASS
 
+#define SANITY_CHECK
+
 #endif /* SWIFT_CONST_H */
diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h
index 396206eb719899ffb701db09d2eaab637e3da4bb..1007b09ed901095b7c2f96b9b41934e512de126d 100644
--- a/src/runner_doiact_grav.h
+++ b/src/runner_doiact_grav.h
@@ -62,7 +62,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) {
  * @param ci The #cell with particles to interct.
  * @param cj The #cell with the multipole.
  */
-void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) {
+__attribute__((always_inline)) INLINE static void runner_dograv_pair_pm(
+    struct runner *r, struct cell *ci, struct cell *cj) {
 
   const struct engine *e = r->e;
   const int gcount = ci->gcount;
@@ -72,14 +73,16 @@ void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) {
 
   TIMER_TIC;
 
+#ifdef SANITY_CHECK
+  if (gcount == 0) error("Empty cell!");  // MATTHIEU sanity check
+
+  if (multi.mass == 0.0)  // MATTHIEU sanity check
+    error("Multipole does not seem to have been set.");
+#endif
+
   /* Anything to do here? */
   if (ci->ti_end_min > ti_current) return;
 
-  if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check
-
-  if (multi.mass == 0.0) // MATTHIEU sanity check
-      error("Multipole does not seem to have been set.");
-  
   /* Loop over every particle in leaf. */
   for (int pid = 0; pid < gcount; pid++) {
 
@@ -87,7 +90,7 @@ void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) {
     struct gpart *restrict gp = &gparts[pid];
 
     if (gp->ti_end > ti_current) continue;
-    
+
     /* Compute the pairwise distance. */
     const float dx[3] = {multi.CoM[0] - gp->x[0],   // x
                          multi.CoM[1] - gp->x[1],   // y
@@ -146,8 +149,11 @@ void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) {
  * @param r The #runner.
  * @param ci The first #cell.
  * @param cj The other #cell.
+ *
+ * @todo Use a local cache for the particles.
  */
-void runner_dograv_pp(struct runner *r, struct cell *ci, struct cell *cj) {
+__attribute__((always_inline)) INLINE static void runner_dograv_pair_pp(
+    struct runner *r, struct cell *ci, struct cell *cj) {
 
   const struct engine *e = r->e;
   const int gcount_i = ci->gcount;
@@ -158,55 +164,120 @@ void runner_dograv_pp(struct runner *r, struct cell *ci, struct cell *cj) {
 
   TIMER_TIC;
 
+#ifdef SANITY_CHECK
+  if (ci->h[0] != cj->h[0])  // MATTHIEU sanity check
+    error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]);
+#endif
+
   /* Anything to do here? */
   if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return;
 
-  if(ci->h[0] != cj->h[0]) // MATTHIEU sanity check
-    error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]);
-  
   /* Loop over all particles in ci... */
   for (int pid = 0; pid < gcount_i; pid++) {
 
     /* Get a hold of the ith part in ci. */
     struct gpart *restrict gpi = &gparts_i[pid];
     const float mi = gpi->mass;
-    
+
     /* Loop over every particle in the other cell. */
     for (int pjd = 0; pjd < gcount_j; pjd++) {
 
-      /* Get a hold of the ith part in ci. */
+      /* Get a hold of the jth part in cj. */
       struct gpart *restrict gpj = &gparts_j[pjd];
       const float mj = gpj->mass;
-      
+
       /* Compute the pairwise distance. */
       const float dx[3] = {gpi->x[0] - gpj->x[0],   // x
-			   gpi->x[1] - gpj->x[1],   // y
-			   gpi->x[2] - gpj->x[2]};  // z
+                           gpi->x[1] - gpj->x[1],   // y
+                           gpi->x[2] - gpj->x[2]};  // z
       const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
-      
+
       /* Apply the gravitational acceleration. */
       const float ir = 1.0f / sqrtf(r2);
       const float w = ir * ir * ir;
-      const float wdx[3] = {w*dx[0], w*dx[1], w*dx[2]};
-      
-      if(gpi->ti_end <= ti_current) {
-	gpi->a_grav[0] -=  wdx[0] * mj;
-	gpi->a_grav[1] -=  wdx[1] * mj;
-	gpi->a_grav[2] -=  wdx[2] * mj;
+      const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]};
+
+      if (gpi->ti_end <= ti_current) {
+        gpi->a_grav[0] -= wdx[0] * mj;
+        gpi->a_grav[1] -= wdx[1] * mj;
+        gpi->a_grav[2] -= wdx[2] * mj;
       }
-      if(gpj->ti_end <= ti_current) {
-	gpj->a_grav[0] +=  wdx[0] * mi;
-	gpj->a_grav[1] +=  wdx[1] * mi;
-	gpj->a_grav[2] +=  wdx[2] * mi;	
+      if (gpj->ti_end <= ti_current) {
+        gpj->a_grav[0] += wdx[0] * mi;
+        gpj->a_grav[1] += wdx[1] * mi;
+        gpj->a_grav[2] += wdx[2] * mi;
       }
-      
     }
-
   }
-      
-  
 
   TIMER_TOC(TIMER_DOPAIR);  // MATTHIEU
 }
 
+/**
+ * @brief Computes the interaction of all the particles in a cell directly
+ *
+ * @param r The #runner.
+ * @param ci The first #cell.
+ *
+ * @todo Use a local cache for the particles.
+ */
+__attribute__((always_inline))
+    INLINE static void runner_dograv_self_pp(struct runner *r, struct cell *c) {
+
+  const struct engine *e = r->e;
+  const int gcount = c->gcount;
+  struct gpart *restrict gparts = c->gparts;
+  const int ti_current = e->ti_current;
+
+  TIMER_TIC;
+
+#ifdef SANITY_CHECK
+  if (c->gcount == 0)  // MATTHIEU sanity check
+    error("Empty cell !");
+#endif
+
+  /* Anything to do here? */
+  if (c->ti_end_min > ti_current) return;
+
+  /* Loop over all particles in ci... */
+  for (int pid = 0; pid < gcount; pid++) {
+
+    /* Get a hold of the ith part in ci. */
+    struct gpart *restrict gpi = &gparts[pid];
+    const float mi = gpi->mass;
+
+    /* Loop over every particle in the other cell. */
+    for (int pjd = pid + 1; pjd < gcount; pjd++) {
+
+      /* Get a hold of the jth part in ci. */
+      struct gpart *restrict gpj = &gparts[pjd];
+      const float mj = gpj->mass;
+
+      /* Compute the pairwise distance. */
+      const float dx[3] = {gpi->x[0] - gpj->x[0],   // x
+                           gpi->x[1] - gpj->x[1],   // y
+                           gpi->x[2] - gpj->x[2]};  // z
+      const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
+
+      /* Apply the gravitational acceleration. */
+      const float ir = 1.0f / sqrtf(r2);
+      const float w = ir * ir * ir;
+      const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]};
+
+      if (gpi->ti_end <= ti_current) {
+        gpi->a_grav[0] -= wdx[0] * mj;
+        gpi->a_grav[1] -= wdx[1] * mj;
+        gpi->a_grav[2] -= wdx[2] * mj;
+      }
+      if (gpj->ti_end <= ti_current) {
+        gpj->a_grav[0] += wdx[0] * mi;
+        gpj->a_grav[1] += wdx[1] * mi;
+        gpj->a_grav[2] += wdx[2] * mi;
+      }
+    }
+  }
+
+  TIMER_TOC(TIMER_DOSELF);  // MATTHIEU
+}
+
 #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */