From f1c0d0e9bb9db83d2aa165e91b3d5e87b96ea38f Mon Sep 17 00:00:00 2001
From: Matthieu Schaller <matthieu.schaller@durham.ac.uk>
Date: Thu, 8 Jun 2017 17:08:59 +0100
Subject: [PATCH] Also create functions to decide when to rebuild and when to
 split a task. Update the rebuild and split condition to correctly use
 kernel_gamma.

---
 src/cell.c      | 38 ++++++++++++++++++++++++++++++++------
 src/cell.h      |  1 +
 src/engine.c    |  4 +---
 src/scheduler.c | 10 ++--------
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/src/cell.c b/src/cell.c
index c73eae8119..de34f37b5e 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -1317,16 +1317,44 @@ int cell_is_drift_needed(struct cell *c, const struct engine *e) {
 }
 
 /**
- * @brief Can a task recurse to a lower level based on the staus of the particles
+ * @brief Can a task recurse to a lower level based on the staus of the
+ * particles
  * in the cell.
  *
  * @param c The #cell.
  */
 int cell_can_recurse_in_pair_task(const struct cell *c) {
 
+  /* Is the cell split ? */
+  /* If so, is the cut-off radius plus the max distance the parts have moved */
+  /* smaller than the sub-cell sizes ? */
   return c->split &&
-         (2.f * kernel_gamma * space_stretch * (c->h_max_old + c->dx_max_old) <
-          c->dmin);
+         ((kernel_gamma * c->h_max_old + c->dx_max_old) < 0.5f * c->dmin);
+}
+
+/**
+ * @brief Can a task associated with a cell be split into smaller sub-tasks.
+ *
+ * @param c The #cell.
+ */
+int cell_can_split_task(const struct cell *c) {
+
+  /* Is the cell split ? */
+  /* If so, is the cut-off radius with some leeway smaller than */
+  /* the sub-cell sizes ? */
+  /* Note that since tasks are build after a rebuild no need to take */
+  /* into account any part motion (i.e. dx_max == 0 here) */
+  return c->split && (space_stretch * kernel_gamma * c->h_max < 0.5f * c->dmin);
+}
+
+int cell_need_rebuild_for_pair(const struct cell *ci, const struct cell *cj) {
+
+  /* Is the cut-off radius plus the max distance the parts in both cells have */
+  /* moved larger than the cell size ? */
+  /* Note ci->dmin == cj->dmin */
+  return (kernel_gamma * max(ci->h_max, cj->h_max) + ci->dx_max_part +
+              cj->dx_max_part >
+          cj->dmin);
 }
 
 /**
@@ -1690,9 +1718,7 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) {
 
       /* Check whether there was too much particle motion, i.e. the
          cell neighbour conditions were violated. */
-      if (max(ci->h_max, cj->h_max) + ci->dx_max_part + cj->dx_max_part >
-          cj->dmin)
-        rebuild = 1;
+      if (cell_need_rebuild_for_pair(ci, cj)) rebuild = 1;
 
 #ifdef WITH_MPI
       /* Activate the send/recv flags. */
diff --git a/src/cell.h b/src/cell.h
index 1f0482f0c6..021cdccf08 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -389,4 +389,5 @@ void cell_store_pre_drift_values(struct cell *c);
 void cell_activate_subcell_tasks(struct cell *ci, struct cell *cj,
                                  struct scheduler *s);
 int cell_can_recurse_in_pair_task(const struct cell *c);
+int cell_can_split_task(const struct cell *c);
 #endif /* SWIFT_CELL_H */
diff --git a/src/engine.c b/src/engine.c
index ffbc6558e0..3375b8fd0a 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2569,9 +2569,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
       if (t->subtype != task_subtype_density) continue;
 
       /* Too much particle movement? */
-      if (max(ci->h_max, cj->h_max) + ci->dx_max_part + cj->dx_max_part >
-          cj->dmin)
-        *rebuild_space = 1;
+      if (cell_need_rebuild_for_pair(ci, cj)) *rebuild_space = 1;
 
       /* Set the correct sorting flags */
       if (t->type == task_type_pair) {
diff --git a/src/scheduler.c b/src/scheduler.c
index c8acb0feaf..f669e62945 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -180,7 +180,6 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
 
       /* Get a handle on the cell involved. */
       struct cell *ci = t->ci;
-      const double width = ci->dmin;
 
       /* Foreign task? */
       if (ci->nodeID != s->nodeID) {
@@ -189,7 +188,7 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
       }
 
       /* Is this cell even split and the task does not violate h ? */
-      if (ci->split && 2.f * kernel_gamma * ci->h_max * space_stretch < width) {
+      if (cell_can_split_task(ci)) {
 
         /* Make a sub? */
         if (scheduler_dosub && /* Note division here to avoid overflow */
@@ -260,13 +259,8 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) {
       double shift[3];
       const int sid = space_getsid(s->space, &ci, &cj, shift);
 
-      const double width_i = ci->dmin;
-      const double width_j = cj->dmin;
-
       /* Should this task be split-up? */
-      if (ci->split && cj->split &&
-          2.f * kernel_gamma * space_stretch * ci->h_max < width_i &&
-          2.f * kernel_gamma * space_stretch * cj->h_max < width_j) {
+      if (cell_can_split_task(ci) && cell_can_split_task(cj)) {
 
         /* Replace by a single sub-task? */
         if (scheduler_dosub &&
-- 
GitLab