From defbca15c0320bbb553fe547af367e32574b1ce3 Mon Sep 17 00:00:00 2001
From: Kyle Klenk <kyle.c.klenk@gmail.com>
Date: Mon, 6 May 2024 18:06:49 +0000
Subject: [PATCH] Tested basic cases to verify mutli-gru and now multi-hru
 cases work with the updates

---
 build/includes/job_actor/GRU.hpp       |  2 ++
 build/includes/job_actor/gru_struc.hpp |  6 ++++++
 build/source/job_actor/gru_struc.cpp   |  5 +++++
 build/source/job_actor/gru_struc.f90   | 17 +++++++++++++++++
 build/source/job_actor/job_actor.cpp   |  9 +++++----
 build/source/job_actor/job_utils.cpp   | 26 +++++++++++++-------------
 build/source/main.cpp                  |  2 ++
 7 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/build/includes/job_actor/GRU.hpp b/build/includes/job_actor/GRU.hpp
index 69dc872..6ada689 100644
--- a/build/includes/job_actor/GRU.hpp
+++ b/build/includes/job_actor/GRU.hpp
@@ -11,6 +11,8 @@ class GRU {
     int index_job_;          // The index of the GRU within this job
     caf::actor actor_ref_;   // The actor for the GRU
 
+    int num_hrus_;           // The number of HRUs in the GRU
+
     // Modifyable Parameters
     int dt_init_factor_;     // The initial dt for the GRU
     double rel_tol_;         // The relative tolerance for the GRU
diff --git a/build/includes/job_actor/gru_struc.hpp b/build/includes/job_actor/gru_struc.hpp
index 347050c..1966ec0 100644
--- a/build/includes/job_actor/gru_struc.hpp
+++ b/build/includes/job_actor/gru_struc.hpp
@@ -9,6 +9,8 @@ extern "C" {
 
   void read_icond_nlayers_fortran(int& num_gru, int& err, void* message);
 
+  void get_num_hru_per_gru_fortran(int& arr_size, int& num_hru_per_gru_array);
+
   void deallocate_gru_struc_fortran();
 }
 
@@ -50,6 +52,9 @@ class GruStruc {
       return -1;
     }
 
+    void getNumHrusPerGru();
+    inline int getNumHruPerGru(int index) { return num_hru_per_gru_[index]; }
+
   private:
     // Inital Information about the GRUs
     int start_gru_;
@@ -60,6 +65,7 @@ class GruStruc {
     
     // GRU specific Information
     std::vector<std::unique_ptr<GRU>> gru_info_;
+    std::vector<int> num_hru_per_gru_;
 
     // Runtime status of the GRUs
     int num_gru_done_ = 0;
diff --git a/build/source/job_actor/gru_struc.cpp b/build/source/job_actor/gru_struc.cpp
index 78ef42e..ec5a7a7 100644
--- a/build/source/job_actor/gru_struc.cpp
+++ b/build/source/job_actor/gru_struc.cpp
@@ -10,6 +10,7 @@ GruStruc::GruStruc(int start_gru, int num_gru, int num_retry_attempts) {
 }
 
 int GruStruc::ReadDimension() {
+  // gru_struc is set up in fortran here
   int err = 0; int num_hru, file_gru, file_hru;
   std::unique_ptr<char[]> err_msg(new char[256]);
   read_dimension_fortran(start_gru_, num_gru_, num_hru, file_gru, file_hru,
@@ -33,5 +34,9 @@ int GruStruc::ReadIcondNlayers() {
   return 0;
 }
 
+void GruStruc::getNumHrusPerGru() {
+  num_hru_per_gru_.resize(num_gru_, 0);
+  get_num_hru_per_gru_fortran(num_gru_, num_hru_per_gru_[0]);
+}
 
 
diff --git a/build/source/job_actor/gru_struc.f90 b/build/source/job_actor/gru_struc.f90
index 8843739..c7eb554 100644
--- a/build/source/job_actor/gru_struc.f90
+++ b/build/source/job_actor/gru_struc.f90
@@ -5,6 +5,7 @@ module gru_struc_module
 
   public::read_dimension_fortran
   public::read_icond_nlayers_fortran
+  public::get_num_hru_per_gru_fortran
   public::deallocate_gru_struc_fortran
   contains
 
@@ -87,6 +88,22 @@ subroutine read_icond_nlayers_fortran(num_gru, err, message_r)&
 
 end subroutine read_icond_nlayers_fortran
 
+subroutine get_num_hru_per_gru_fortran(num_gru, num_hru_per_gru_array) &
+    bind(C, name="get_num_hru_per_gru_fortran")
+  USE globalData,only:gru_struc           ! gru->hru mapping structure
+  implicit none
+  ! Dummy Variables
+  integer(c_int), intent(in)      :: num_gru
+  integer(c_int), intent(out)     :: num_hru_per_gru_array(num_gru)
+  ! Local Variables
+  integer                         :: iGRU
+
+  do iGRU = 1, num_gru
+    num_hru_per_gru_array(iGRU) = gru_struc(iGRU)%hruCount
+  end do
+  
+end subroutine 
+
 subroutine deallocate_gru_struc_fortran() bind(C, name="deallocate_gru_struc_fortran")
     USE globalData,only:gru_struc           ! gru->hru mapping structure
     USE globalData,only:index_map
diff --git a/build/source/job_actor/job_actor.cpp b/build/source/job_actor/job_actor.cpp
index 58a1433..cf9ab3d 100644
--- a/build/source/job_actor/job_actor.cpp
+++ b/build/source/job_actor/job_actor.cpp
@@ -55,6 +55,7 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
     aout(self) << "ERROR: Job_Actor - ReadIcondNlayers\n";
     return {};
   }
+  gru_struc->getNumHrusPerGru();
 
   self->state.summa_init_struc = std::make_unique<SummaInitStruc>();
   if (self->state.summa_init_struc->allocate(self->state.num_gru) != 0) {
@@ -78,9 +79,10 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
                                         gru_struc->get_file_gru(), 
                                         false);
 
-  self->state.file_access_actor = self->spawn(
-      file_access_actor, self->state.num_gru_info, 
-      self->state.file_access_actor_settings, self);
+  self->state.file_access_actor = self->spawn(file_access_actor, 
+                                              self->state.num_gru_info, 
+                                              self->state.file_access_actor_settings, 
+                                              self);
   self->request(self->state.file_access_actor, caf::infinite, 
                 init_file_access_actor_v, gru_struc->get_file_gru(),
                 gru_struc->getNumHrus())
@@ -93,7 +95,6 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
       return;
     }
 
-
     aout(self) << "Job_Actor: File Access Actor Ready\n";  
     self->state.job_timing.updateEndPoint("init_duration");
     aout(self) << "Job Actor Initialized \n";
diff --git a/build/source/job_actor/job_utils.cpp b/build/source/job_actor/job_utils.cpp
index 042c76e..24fe4af 100644
--- a/build/source/job_actor/job_utils.cpp
+++ b/build/source/job_actor/job_utils.cpp
@@ -7,20 +7,20 @@ void spawnHRUActors(stateful_actor<job_state>* self) {
   for (int i = 0; i < gru_struc->getNumGrus(); i++) {
     auto netcdf_index = gru_struc->getStartGru() + i;
     auto job_index = i + 1;
+    caf::actor gru;
+    if (gru_struc->getNumHruPerGru(i) > 1) {
+      gru = self->spawn(gru_actor, netcdf_index, job_index, 
+                        self->state.num_steps, 
+                        self->state.hru_actor_settings, 
+                        self->state.file_access_actor, self);
+    } else {
+      gru = self->spawn(hru_actor, netcdf_index, job_index, 
+                        self->state.hru_actor_settings, 
+                        self->state.file_access_actor, self);
+      self->send(gru, init_hru_v);
+      self->send(gru, update_hru_async_v);
+    }
     
-    auto gru = self->spawn(gru_actor, netcdf_index, job_index, 
-                           self->state.num_steps, 
-                           self->state.hru_actor_settings, 
-                           self->state.file_access_actor, self);
-    
-    // Start GRU
-    // auto gru = self->spawn(hru_actor, netcdf_index, job_index, 
-    //                        self->state.hru_actor_settings, 
-    //                        self->state.file_access_actor, self);
-    // self->send(gru, init_hru_v);
-    // self->send(gru, update_hru_async_v);
-
-
     // Save information about the GRU
     std::unique_ptr<GRU> gru_obj = std::make_unique<GRU>(
         netcdf_index, job_index, gru, self->state.dt_init_start_factor, 
diff --git a/build/source/main.cpp b/build/source/main.cpp
index d3a52e1..16a2092 100644
--- a/build/source/main.cpp
+++ b/build/source/main.cpp
@@ -114,6 +114,8 @@ void caf_main(actor_system& sys, const config& cfg) {
     if (!std::filesystem::exists((std::filesystem::path) cfg.config_file)) {
       aout(self) << "\n\n**** Config (-c) or Master File (-m) "
                  << "Does Not Exist or Not Specified!! ****\n\n" 
+                 << "Config File: " << cfg.config_file << "\n"
+                 << "Master File: " << cfg.master_file << "\n\n"
                  << command_line_help << std::endl;
       return;
     }
-- 
GitLab