From 6010f1daa32f124a02c2d32632c92ec724b7ae8e Mon Sep 17 00:00:00 2001
From: Matthieu Schaller <matthieu.schaller@durham.ac.uk>
Date: Mon, 14 Nov 2016 14:52:12 -0700
Subject: [PATCH] Added an (expensive) debugging check to verify that all cells
 have been drifted to the current point in time before a rebuild or a
 repartition.

---
 examples/main.c |  5 +++++
 src/cell.c      | 17 +++++++++++++++++
 src/cell.h      |  1 +
 src/engine.c    | 10 ++++++++++
 src/space.c     | 18 ++++++++++++++++++
 src/space.h     |  1 +
 6 files changed, 52 insertions(+)

diff --git a/examples/main.c b/examples/main.c
index f9745b4d04..dcc113ab6a 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -285,6 +285,11 @@ int main(int argc, char *argv[]) {
   message("Running on: %s", hostname());
 #endif
 
+/* Do we have debugging checks ? */
+#ifdef SWIFT_DEBUG_CHECKS
+  message("WARNING: Debugging checks activated. Code will be slower !");
+#endif
+
   /* Do we choke on FP-exceptions ? */
   if (with_fp_exceptions) {
     feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
diff --git a/src/cell.c b/src/cell.c
index 18c2279b76..878401d770 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -763,6 +763,23 @@ void cell_clean_links(struct cell *c, void *data) {
   c->grav = NULL;
 }
 
+/**
+ * @brief Checks that a cell is at the current point in time
+ *
+ * Calls error() if the cell is not at the current time.
+ *
+ * @param c Cell to act upon
+ * @param data The current time on the integer time-line
+ */
+void cell_check_drift_point(struct cell *c, void *data) {
+
+  const int ti_current = *(int *)data;
+
+  if (c->ti_old != ti_current)
+    error("Cell in an incorrect time-zone! c->ti_old=%d ti_current=%d",
+          c->ti_old, ti_current);
+}
+
 /**
  * @brief Checks whether the cells are direct neighbours ot not. Both cells have
  * to be of the same size
diff --git a/src/cell.h b/src/cell.h
index 10c67be768..eefb2114cd 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -291,6 +291,7 @@ int cell_are_neighbours(const struct cell *restrict ci,
                         const struct cell *restrict cj);
 void cell_check_multipole(struct cell *c, void *data);
 void cell_clean(struct cell *c);
+void cell_check_drift_point(struct cell *c, void *data);
 int cell_is_drift_needed(struct cell *c, const struct engine *e);
 int cell_unskip_tasks(struct cell *c, struct scheduler *s);
 void cell_set_super(struct cell *c, struct cell *super);
diff --git a/src/engine.c b/src/engine.c
index 6727dce6c3..e989aefd53 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -557,6 +557,11 @@ void engine_repartition(struct engine *e) {
 
   ticks tic = getticks();
 
+#ifdef SWIFT_DEBUG_CHECKS
+  /* Check that all cells have been drifted to the current time */
+  space_check_drift_point(e->s, e->ti_current);
+#endif
+
   /* Clear the repartition flag. */
   enum repartition_type reparttype = e->forcerepart;
   e->forcerepart = REPART_NONE;
@@ -2234,6 +2239,11 @@ void engine_prepare(struct engine *e, int nodrift) {
       e->drift_all = (e->policy & engine_policy_drift_all);
     }
 
+#ifdef SWIFT_DEBUG_CHECKS
+    /* Check that all cells have been drifted to the current time */
+    space_check_drift_point(e->s, e->ti_current);
+#endif
+
     engine_rebuild(e);
   }
 
diff --git a/src/space.c b/src/space.c
index 5f7e3522ee..e04aad2207 100644
--- a/src/space.c
+++ b/src/space.c
@@ -318,6 +318,8 @@ void space_regrid(struct space *s, int verbose) {
                        s->nr_cells * sizeof(struct cell)) != 0)
       error("Failed to allocate cells.");
     bzero(s->cells_top, s->nr_cells * sizeof(struct cell));
+
+    /* Set the cells' locks */
     for (int k = 0; k < s->nr_cells; k++)
       if (lock_init(&s->cells_top[k].lock) != 0)
         error("Failed to init spinlock.");
@@ -1874,6 +1876,8 @@ void space_init(struct space *s, const struct swift_params *params,
  * @brief Cleans-up all the cell links in the space
  *
  * Expensive funtion. Should only be used for debugging purposes.
+ *
+ * @param s The #space to clean.
  */
 void space_link_cleanup(struct space *s) {
 
@@ -1881,6 +1885,20 @@ void space_link_cleanup(struct space *s) {
   space_map_cells_pre(s, 1, cell_clean_links, NULL);
 }
 
+/**
+ * @brief Checks that all cells have been drifted to the current point in time
+ *
+ * Expensive function. Should only be used for debugging purposes.
+ *
+ * @param s The #space to check.
+ * @param ti_current The (integer) time.
+ */
+void space_check_drift_point(struct space *s, int ti_current) {
+
+  /* Recursively check all cells */
+  space_map_cells_pre(s, 1, cell_check_drift_point, &ti_current);
+}
+
 /**
  * @brief Frees up the memory allocated for this #space
  */
diff --git a/src/space.h b/src/space.h
index 975786c098..53cf2d0c8f 100644
--- a/src/space.h
+++ b/src/space.h
@@ -183,6 +183,7 @@ void space_do_gparts_sort();
 void space_init_parts(struct space *s);
 void space_init_gparts(struct space *s);
 void space_link_cleanup(struct space *s);
+void space_check_drift_point(struct space *s, int ti_current);
 void space_clean(struct space *s);
 
 #endif /* SWIFT_SPACE_H */
-- 
GitLab