From b7e42cf5aea6b70bbe7c9ca1990ca40a0cd38e13 Mon Sep 17 00:00:00 2001
From: Matthieu Schaller <schaller@strw.leidenuniv.nl>
Date: Wed, 1 May 2019 16:19:45 +0200
Subject: [PATCH] Added the self tasks for the black holes

---
 src/cell.c                      | 38 ++++++++++++++++++++++++
 src/cell.h                      |  1 +
 src/engine_maketasks.c          | 51 +++++++++++++++++++++++++++++++++
 src/engine_marktasks.c          | 32 +++++++++++++++++++++
 src/task.c                      | 10 +++++++
 src/task.h                      |  1 +
 tools/plot_task_dependencies.py |  2 +-
 7 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/src/cell.c b/src/cell.c
index 8740866efe..5501a259c9 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -2313,6 +2313,44 @@ void cell_activate_drift_spart(struct cell *c, struct scheduler *s) {
   }
 }
 
+/**
+ * @brief Activate the #bpart drifts on the given cell.
+ */
+void cell_activate_drift_bpart(struct cell *c, struct scheduler *s) {
+
+  /* If this cell is already marked for drift, quit early. */
+  if (cell_get_flag(c, cell_flag_do_bh_drift)) return;
+
+  /* Mark this cell for drifting. */
+  cell_set_flag(c, cell_flag_do_bh_drift);
+
+  /* Set the do_black_holes_sub_drifts all the way up and activate the super
+     drift if this has not yet been done. */
+  if (c == c->hydro.super) {
+#ifdef SWIFT_DEBUG_CHECKS
+    if (c->black_holes.drift == NULL)
+      error("Trying to activate un-existing c->black_holes.drift");
+#endif
+    scheduler_activate(s, c->black_holes.drift);
+  } else {
+    for (struct cell *parent = c->parent;
+         parent != NULL && !cell_get_flag(parent, cell_flag_do_bh_sub_drift);
+         parent = parent->parent) {
+      /* Mark this cell for drifting */
+      cell_set_flag(parent, cell_flag_do_bh_sub_drift);
+
+      if (parent == c->hydro.super) {
+#ifdef SWIFT_DEBUG_CHECKS
+        if (parent->black_holes.drift == NULL)
+          error("Trying to activate un-existing parent->black_holes.drift");
+#endif
+        scheduler_activate(s, parent->black_holes.drift);
+        break;
+      }
+    }
+  }
+}
+
 /**
  * @brief Activate the drifts on the given cell.
  */
diff --git a/src/cell.h b/src/cell.h
index 52853c3eae..18b4512cf1 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -824,6 +824,7 @@ void cell_activate_super_spart_drifts(struct cell *c, struct scheduler *s);
 void cell_activate_drift_part(struct cell *c, struct scheduler *s);
 void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
 void cell_activate_drift_spart(struct cell *c, struct scheduler *s);
+void cell_activate_drift_bpart(struct cell *c, struct scheduler *s);
 void cell_activate_hydro_sorts(struct cell *c, int sid, struct scheduler *s);
 void cell_activate_stars_sorts(struct cell *c, int sid, struct scheduler *s);
 void cell_activate_limiter(struct cell *c, struct scheduler *s);
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index 920b7f430d..ee5f7bfd4f 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -1112,6 +1112,10 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements,
         engine_addlink(e, &ci->stars.density, t);
       } else if (t->subtype == task_subtype_stars_feedback) {
         engine_addlink(e, &ci->stars.feedback, t);
+      } else if (t->subtype == task_subtype_bh_density) {
+        engine_addlink(e, &ci->black_holes.density, t);
+      } else if (t->subtype == task_subtype_bh_feedback) {
+        engine_addlink(e, &ci->black_holes.feedback, t);
       }
 
       /* Link pair tasks to cells. */
@@ -1131,6 +1135,12 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements,
       } else if (t->subtype == task_subtype_stars_feedback) {
         engine_addlink(e, &ci->stars.feedback, t);
         engine_addlink(e, &cj->stars.feedback, t);
+      } else if (t->subtype == task_subtype_bh_density) {
+        engine_addlink(e, &ci->black_holes.density, t);
+        engine_addlink(e, &cj->black_holes.density, t);
+      } else if (t->subtype == task_subtype_bh_feedback) {
+        engine_addlink(e, &ci->black_holes.feedback, t);
+        engine_addlink(e, &cj->black_holes.feedback, t);
       }
 #ifdef SWIFT_DEBUG_CHECKS
       else if (t_subtype == task_subtype_external_grav) {
@@ -1152,6 +1162,10 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements,
         engine_addlink(e, &ci->stars.density, t);
       } else if (t->subtype == task_subtype_stars_feedback) {
         engine_addlink(e, &ci->stars.feedback, t);
+      } else if (t->subtype == task_subtype_bh_density) {
+        engine_addlink(e, &ci->black_holes.density, t);
+      } else if (t->subtype == task_subtype_bh_feedback) {
+        engine_addlink(e, &ci->black_holes.feedback, t);
       }
 
       /* Link sub-pair tasks to cells. */
@@ -1171,6 +1185,12 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements,
       } else if (t->subtype == task_subtype_stars_feedback) {
         engine_addlink(e, &ci->stars.feedback, t);
         engine_addlink(e, &cj->stars.feedback, t);
+      } else if (t->subtype == task_subtype_bh_density) {
+        engine_addlink(e, &ci->black_holes.density, t);
+        engine_addlink(e, &cj->black_holes.density, t);
+      } else if (t->subtype == task_subtype_bh_feedback) {
+        engine_addlink(e, &ci->black_holes.feedback, t);
+        engine_addlink(e, &cj->black_holes.feedback, t);
       }
 #ifdef SWIFT_DEBUG_CHECKS
       else if (t_subtype == task_subtype_external_grav) {
@@ -1425,6 +1445,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
   const int with_cooling = (e->policy & engine_policy_cooling);
   const int with_limiter = (e->policy & engine_policy_limiter);
   const int with_feedback = (e->policy & engine_policy_feedback);
+  const int with_black_holes = (e->policy & engine_policy_black_holes);
 #ifdef EXTRA_HYDRO_LOOP
   struct task *t_gradient = NULL;
 #endif
@@ -1432,6 +1453,8 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
   struct task *t_limiter = NULL;
   struct task *t_star_density = NULL;
   struct task *t_star_feedback = NULL;
+  struct task *t_bh_density = NULL;
+  struct task *t_bh_feedback = NULL;
 
   for (int ind = 0; ind < num_elements; ind++) {
 
@@ -1478,6 +1501,15 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
                               task_subtype_stars_feedback, flags, 0, ci, NULL);
       }
 
+      /* The black hole feedback tasks */
+      if (with_feedback) {
+        t_bh_density = scheduler_addtask(
+            sched, task_type_self, task_subtype_bh_density, flags, 0, ci, NULL);
+        t_bh_feedback =
+            scheduler_addtask(sched, task_type_self, task_subtype_bh_feedback,
+                              flags, 0, ci, NULL);
+      }
+
       /* Link the tasks to the cells */
       engine_addlink(e, &ci->hydro.force, t_force);
       if (with_limiter) {
@@ -1487,6 +1519,10 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
         engine_addlink(e, &ci->stars.density, t_star_density);
         engine_addlink(e, &ci->stars.feedback, t_star_feedback);
       }
+      if (with_black_holes) {
+        engine_addlink(e, &ci->black_holes.density, t_bh_density);
+        engine_addlink(e, &ci->black_holes.feedback, t_bh_feedback);
+      }
 
 #ifdef EXTRA_HYDRO_LOOP
 
@@ -1527,6 +1563,21 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
                             ci->hydro.super->stars.stars_out);
       }
 
+      if (with_feedback) {
+
+        scheduler_addunlock(sched, ci->hydro.super->black_holes.drift,
+                            t_bh_density);
+        scheduler_addunlock(sched, ci->hydro.super->hydro.drift, t_bh_density);
+        scheduler_addunlock(sched, ci->hydro.super->black_holes.black_holes_in,
+                            t_bh_density);
+        scheduler_addunlock(sched, t_bh_density,
+                            ci->hydro.super->black_holes.ghost);
+        scheduler_addunlock(sched, ci->hydro.super->black_holes.ghost,
+                            t_bh_feedback);
+        scheduler_addunlock(sched, t_bh_feedback,
+                            ci->hydro.super->black_holes.black_holes_out);
+      }
+
       if (with_limiter) {
         scheduler_addunlock(sched, ci->super->kick2, t_limiter);
         scheduler_addunlock(sched, t_limiter, ci->super->timestep);
diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c
index fd0d99432e..ba69ab029c 100644
--- a/src/engine_marktasks.c
+++ b/src/engine_marktasks.c
@@ -164,6 +164,38 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
         if (cell_is_active_stars(ci, e)) scheduler_activate(s, t);
       }
 
+      /* Activate the black hole density */
+      else if (t_type == task_type_self &&
+               t_subtype == task_subtype_bh_density) {
+        if (cell_is_active_black_holes(ci, e)) {
+          scheduler_activate(s, t);
+          cell_activate_drift_part(ci, s);
+          cell_activate_drift_bpart(ci, s);
+        }
+      }
+
+      /* Store current values of dx_max and h_max. */
+      else if (t_type == task_type_sub_self &&
+               t_subtype == task_subtype_bh_density) {
+        if (cell_is_active_black_holes(ci, e)) {
+          scheduler_activate(s, t);
+          error("TODO!");
+          // cell_activate_subcell_bh_tasks(ci, NULL, s);
+        }
+      }
+
+      else if (t_type == task_type_self &&
+               t_subtype == task_subtype_bh_feedback) {
+        if (cell_is_active_black_holes(ci, e)) {
+          scheduler_activate(s, t);
+        }
+      }
+
+      else if (t_type == task_type_sub_self &&
+               t_subtype == task_subtype_bh_feedback) {
+        if (cell_is_active_black_holes(ci, e)) scheduler_activate(s, t);
+      }
+
       /* Activate the gravity drift */
       else if (t_type == task_type_self && t_subtype == task_subtype_grav) {
         if (cell_is_active_gravity(ci, e)) {
diff --git a/src/task.c b/src/task.c
index 7d79fb68a4..b9fd22a823 100644
--- a/src/task.c
+++ b/src/task.c
@@ -168,6 +168,11 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
       return task_action_spart;
       break;
 
+    case task_type_drift_bpart:
+    case task_type_bh_ghost:
+      return task_action_bpart;
+      break;
+
     case task_type_self:
     case task_type_pair:
     case task_type_sub_self:
@@ -186,6 +191,11 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
           return task_action_all;
           break;
 
+        case task_subtype_bh_density:
+        case task_subtype_bh_feedback:
+          return task_action_all;
+          break;
+
         case task_subtype_grav:
         case task_subtype_external_grav:
           return task_action_gpart;
diff --git a/src/task.h b/src/task.h
index b78e64ee43..0d8925173e 100644
--- a/src/task.h
+++ b/src/task.h
@@ -125,6 +125,7 @@ enum task_actions {
   task_action_part,
   task_action_gpart,
   task_action_spart,
+  task_action_bpart,
   task_action_all,
   task_action_multipole,
   task_action_count
diff --git a/tools/plot_task_dependencies.py b/tools/plot_task_dependencies.py
index bb4c2780f8..9a8b63ab31 100644
--- a/tools/plot_task_dependencies.py
+++ b/tools/plot_task_dependencies.py
@@ -176,7 +176,7 @@ def taskIsHydro(name):
     """
     if "_part" in name:
         return True
-    if "density" in name and "stars" not in name:
+    if "density" in name and "stars" not in name and "bh" not in name:
         return True
     if "rho" in name:
         return True
-- 
GitLab