diff --git a/build/build_scripts/build_v4_local.sh b/build/build_scripts/build_v4_local.sh
index a3f990e6249a53118febf3233507cd82839f2c1b..8024e64ceacd90560134838302deb43b1198fa4d 100755
--- a/build/build_scripts/build_v4_local.sh
+++ b/build/build_scripts/build_v4_local.sh
@@ -11,5 +11,5 @@ export LIBRARY_LINKS='-llapack;-lgfortran;-lnetcdff;-lnetcdf' # list of library
 export SUNDIALS_PATH="/usr/local/sundials"
 export ACTOR_FRAMEWORK_PATH="/usr/local"
 
-cmake -B ./cmake_build -S ../summa/build/cmake/. -DCMAKE_BUILD_TYPE=Sundials_Actors
-cmake --build ./cmake_build --target all
+cmake -B ./cmake_build -S ../summa/build/cmake/. -DCMAKE_BUILD_TYPE=Sundials_Actors_Debug
+cmake --build ./cmake_build --target all -j
diff --git a/build/includes/global/gru_struc.hpp b/build/includes/global/gru_struc.hpp
deleted file mode 100644
index 2d8765ae79eff42956ef2114fd666eb17800f924..0000000000000000000000000000000000000000
--- a/build/includes/global/gru_struc.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <string>
-
-extern "C" {
-  void init_gru_struc(int* num_gru, int* file_hru, int* hru_ix);
-  void pop_gru_struc(int* iGRU, long int* gru_id, long int* hru_id, long int* hru2gru_id, 
-                     int* hru_ix, int* file_gru, int* file_hru, int* num_gru,
-                     int* start_gru);
-}
-
-class gruStruc {
-  
-  public:
-    gruStruc(const std::string &settingsPath, 
-    const std::string &attributeFile, int num_gru, int start_gru);
-    ~gruStruc() {};
-};
\ No newline at end of file
diff --git a/build/includes/global/message_atoms.hpp b/build/includes/global/message_atoms.hpp
index d66b742501998879121d8990efb4a49901e0cc7b..e440f7f790bfff1876de3f95fed8251f1d365e77 100644
--- a/build/includes/global/message_atoms.hpp
+++ b/build/includes/global/message_atoms.hpp
@@ -1,162 +1,21 @@
 #pragma once
+#include "caf/all.hpp"
 
 #include "batch.hpp"
 #include "batch_container.hpp"
+
 #include "client.hpp"
 #include "client_container.hpp"
-#include <vector>
+
+#include "hru_utils.hpp"
+#include "num_gru_info.hpp"
 #include "settings_functions.hpp"
 #include "global.hpp"
-#include "caf/all.hpp"
+
+#include <vector>
 #include <unordered_map>
 
 // HRU Data structure used for serialization
-struct hru {
-  int indx_hru;
-  int indx_gru;
-  int ref_gru;
-
-  // Misc Variables
-  int timestep;
-  int forcing_step;
-  int num_steps;
-  int iFile;
-  int dt_init_factor;
-  int output_structure_step_index;
-  double dt_init;
-  double upArea;
-
-  // Sundials variables
-  double rtol;
-  double atol;
-
-  // HRU data structures
-  // Statistic Structure
-  std::vector<std::vector<double>> forc_stat;
-  std::vector<std::vector<double>> prog_stat;
-  std::vector<std::vector<double>> diag_stat;
-  std::vector<std::vector<double>> flux_stat;
-  std::vector<std::vector<double>> indx_stat;
-  std::vector<std::vector<double>> bvar_stat;
-  // Primary Data Strutures (scalars)
-  std::vector<int> time_struct;
-  std::vector<double> forc_struct;
-  std::vector<double> attr_struct;
-  std::vector<int> type_struct;
-  std::vector<long int> id_struct;
-  // Primary Data Structures (arrays)
-  std::vector<std::vector<int>> indx_struct;
-  std::vector<std::vector<double>> mpar_struct;
-  std::vector<std::vector<double>> prog_struct;
-  std::vector<std::vector<double>> diag_struct;
-  std::vector<std::vector<double>> flux_struct;
-  // Basin-average structures
-  std::vector<double> bpar_struct;
-  std::vector<std::vector<double>> bvar_struct;
-  std::vector<double> dpar_struct;
-  // Local HRU data structures
-  std::vector<int> start_time;
-  std::vector<int> end_time;
-  std::vector<int> ref_time;
-  std::vector<int> old_time;
-  // statistic flags
-  std::vector<int> stat_counter;
-  std::vector<int> output_timestep;
-  std::vector<int> reset_stats;
-  std::vector<int> finalize_stats;
-
-  // scalar data
-  double frac_jul_day;
-  double tm_zone_offset_frac_day;
-  int year_length;
-  int compute_veg_flux;
-};
-
-template <class Inspector>
-bool inspect(Inspector& inspector, hru& hru_data) {
-  return inspector.object(hru_data).fields(
-      inspector.field("indx_hru", hru_data.indx_hru),
-      inspector.field("indx_gru", hru_data.indx_gru),
-      inspector.field("ref_gru", hru_data.ref_gru),
-      inspector.field("timestep", hru_data.timestep),
-      inspector.field("forcing_step", hru_data.forcing_step),
-      inspector.field("num_steps", hru_data.num_steps),
-      inspector.field("iFile", hru_data.iFile),
-      inspector.field("dt_init_factor", hru_data.dt_init_factor),
-      inspector.field("output_structure_step_index", 
-          hru_data.output_structure_step_index),
-      inspector.field("dt_init", hru_data.dt_init),
-      inspector.field("upArea", hru_data.upArea),
-      inspector.field("rtol", hru_data.rtol),
-      inspector.field("atol", hru_data.atol),
-      inspector.field("forc_stat", hru_data.forc_stat),
-      inspector.field("prog_stat", hru_data.prog_stat),
-      inspector.field("diag_stat", hru_data.diag_stat),
-      inspector.field("flux_stat", hru_data.flux_stat),
-      inspector.field("indx_stat", hru_data.indx_stat),
-      inspector.field("bvar_stat", hru_data.bvar_stat),
-      inspector.field("time_struct", hru_data.time_struct),
-      inspector.field("forc_struct", hru_data.forc_struct),
-      inspector.field("attr_struct", hru_data.attr_struct),
-      inspector.field("type_struct", hru_data.type_struct),
-      inspector.field("id_struct", hru_data.id_struct),
-      inspector.field("indx_struct", hru_data.indx_struct),
-      inspector.field("mpar_struct", hru_data.mpar_struct),
-      inspector.field("prog_struct", hru_data.prog_struct),
-      inspector.field("diag_struct", hru_data.diag_struct),
-      inspector.field("flux_struct", hru_data.flux_struct),
-      inspector.field("bpar_struct", hru_data.bpar_struct),
-      inspector.field("bvar_struct", hru_data.bvar_struct),
-      inspector.field("dpar_struct", hru_data.dpar_struct),
-      inspector.field("start_time", hru_data.start_time),
-      inspector.field("end_time", hru_data.end_time),
-      inspector.field("ref_time", hru_data.ref_time),
-      inspector.field("old_time", hru_data.old_time),
-      inspector.field("stat_counter", hru_data.stat_counter),
-      inspector.field("output_timestep", hru_data.output_timestep),
-      inspector.field("reset_stats", hru_data.reset_stats),
-      inspector.field("finalize_stats", hru_data.finalize_stats),
-      inspector.field("frac_jul_day", hru_data.frac_jul_day),
-      inspector.field("tm_zone_offset_frac_day", 
-          hru_data.tm_zone_offset_frac_day),
-      inspector.field("year_length", hru_data.year_length),
-      inspector.field("compute_veg_flux", hru_data.compute_veg_flux));
-}
-
-struct NumGRUInfo {
-  int start_gru_local;
-  int start_gru_global; 
-  int num_gru_local;
-  int num_gru_global;
-  int file_gru; 
-  bool use_global_for_data_structures;
-
-  // Constructor
-  NumGRUInfo(int start_gru_local = 0, int start_gru_global= 0, 
-      int num_gru_local = 0, int num_gru_global = 0, int file_gru = 0, 
-      bool use_global_for_data_structures = false) 
-    : start_gru_local(start_gru_local), start_gru_global(start_gru_global), 
-    num_gru_local(num_gru_local), num_gru_global(num_gru_global), 
-    file_gru(file_gru), 
-    use_global_for_data_structures(use_global_for_data_structures) {}
-};
-template <class Insepctor>
-bool inspect(Insepctor& inspector, NumGRUInfo& num_gru) {
-  return inspector.object(num_gru).fields(
-      inspector.field("start_gru_local", num_gru.start_gru_local),
-      inspector.field("start_gru_global", num_gru.start_gru_global),
-      inspector.field("num_gru_local", num_gru.num_gru_local),
-      inspector.field("num_gru_global", num_gru.num_gru_global),
-      inspector.field("file_gru", num_gru.file_gru),
-      inspector.field("use_global_for_data_structures", 
-          num_gru.use_global_for_data_structures));
-}
-
-
-enum class hru_error : uint8_t {
-    run_physics_unhandleable = 1,
-    run_physics_infeasible_state = 2,
-};
 
 enum class file_access_error : uint8_t {
     writing_error = 1,
@@ -164,15 +23,6 @@ enum class file_access_error : uint8_t {
     mDecisions_error = 100,
 };
 
-// HRU Errors
-std::string to_string(hru_error err);
-bool from_string(caf::string_view in, hru_error& out);
-bool from_integer(uint8_t in, hru_error& out);
-template<class Inspector>
-bool inspect(Inspector& f, hru_error& x) {
-    return caf::default_enum_inspect(f, x);
-}
-
 // File Access Actor
 std::string to_string(file_access_error err);
 bool from_string(caf::string_view in, file_access_error& out);
@@ -390,14 +240,12 @@ CAF_BEGIN_TYPE_ID_BLOCK(summa, first_custom_type_id)
 
     CAF_ADD_TYPE_ID(summa, (std::optional<caf::strong_actor_ptr>))
 
-    // error types
-    CAF_ADD_TYPE_ID(summa, (hru_error))
+
 
     CAF_ADD_TYPE_ID(summa, (file_access_error))
 
 
 CAF_END_TYPE_ID_BLOCK(summa)
 
-CAF_ERROR_CODE_ENUM(hru_error)
 CAF_ERROR_CODE_ENUM(file_access_error)
 
diff --git a/build/includes/global/num_gru_info.hpp b/build/includes/global/num_gru_info.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ae115673224e38fcb9bdc30dd152c05b4bb270b
--- /dev/null
+++ b/build/includes/global/num_gru_info.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+
+struct NumGRUInfo {
+  int start_gru_local;
+  int start_gru_global; 
+  int num_gru_local;
+  int num_gru_global;
+  int file_gru; 
+  bool use_global_for_data_structures;
+
+  // Constructor
+  NumGRUInfo(int start_gru_local = 0, int start_gru_global= 0, 
+             int num_gru_local = 0, int num_gru_global = 0, int file_gru = 0, 
+             bool use_global_for_data_structures = false) 
+      : start_gru_local(start_gru_local), start_gru_global(start_gru_global), 
+        num_gru_local(num_gru_local), num_gru_global(num_gru_global), 
+        file_gru(file_gru), 
+        use_global_for_data_structures(use_global_for_data_structures) {}
+};
+template <class Insepctor>
+bool inspect(Insepctor& inspector, NumGRUInfo& num_gru) {
+  return inspector.object(num_gru).fields(
+      inspector.field("start_gru_local", num_gru.start_gru_local),
+      inspector.field("start_gru_global", num_gru.start_gru_global),
+      inspector.field("num_gru_local", num_gru.num_gru_local),
+      inspector.field("num_gru_global", num_gru.num_gru_global),
+      inspector.field("file_gru", num_gru.file_gru),
+      inspector.field("use_global_for_data_structures", 
+          num_gru.use_global_for_data_structures));
+}
diff --git a/build/includes/hru_actor/hru_actor.hpp b/build/includes/hru_actor/hru_actor.hpp
index 4467993c76d83dca9ac3cac70ce35fb91089a0d9..95bd6713bd88b1949f79b32703f424f0fdabe054 100644
--- a/build/includes/hru_actor/hru_actor.hpp
+++ b/build/includes/hru_actor/hru_actor.hpp
@@ -42,27 +42,26 @@ extern "C" {
   void set_sundials_tolerances(void* hru_data, double* relTol, double* absTol);
 
   void setIDATolerances(void* hru_data, double* relTolTempCas, 
-      double* absTolTempCas, double* relTolTempVeg, double* absTolTempVeg, 
-      double* relTolWatVeg, double* absTolWatVeg, double* relTolTempSoilSnow,
-      double* absTolTempSoilSnow, double* relTolWatSnow, 
-      double* absTolWatSnow, double* relTolMatric,
-      double* absTolMatric, double* relTolAquifr, double* absTolAquifr);
+                        double* absTolTempCas, double* relTolTempVeg, 
+                        double* absTolTempVeg, double* relTolWatVeg, 
+                        double* absTolWatVeg, double* relTolTempSoilSnow,
+                        double* absTolTempSoilSnow, double* relTolWatSnow, 
+                        double* absTolWatSnow, double* relTolMatric,
+                        double* absTolMatric, double* relTolAquifr, 
+                        double* absTolAquifr);
 }
 
 /*********************************************
  * HRU Actor state variables
  *********************************************/
-namespace caf {
 struct hru_state {
-	// Actor References
+  // Actor References
 	caf::actor file_access_actor;
 	caf::actor parent;
 
-  // Info about which HRU we are and our indexes
-  // into global structures in Fortran
+  int ref_gru;			  // gru_index from attributes/forcing files
+  int indxGRU; 		  // index for gru part of derived types in FORTRAN
   int indxHRU; 	    // index for hru part of derived types in FORTRAN
-  int indxGRU; 		// index for gru part of derived types in FORTRAN
-  int refGRU;			// The actual ID of the GRU we are
 
     // Variables for forcing structures
 	int stepsInCurrentFFile;        // number of time steps in current forcing file
@@ -83,7 +82,6 @@ struct hru_state {
   int     output_structure_step_index = 1; // index of current time step in output structure
   double  dt_init;            // used to initialize the length of the sub-step for each HRU
   double	upArea;             // area upslope of each HRU
-  int     err = 0;	
 
   // Sundials variables
   double rtol = -9999; // -9999 uses default
@@ -99,19 +97,19 @@ struct hru_state {
   }
 };
 
-behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
-    HRU_Actor_Settings hru_actor_settings, caf::actor file_access_actor, 
-    caf::actor parent);
+caf::behavior hru_actor(caf::stateful_actor<hru_state>* self, int ref_gru, 
+                        int indx_gru, HRU_Actor_Settings hru_actor_settings, 
+                        caf::actor file_access_actor, caf::actor parent);
 
 /*********************************************
  * Functions for the HRU Actor
  *********************************************/
 
 /** Function to initalize the HRU for running */
-void Initialize_HRU(stateful_actor<hru_state>* self);
+void Initialize_HRU(caf::stateful_actor<hru_state>* self);
 
 /** Function runs all of the hru time_steps */
-int Run_HRU(stateful_actor<hru_state>* self);
+int Run_HRU(caf::stateful_actor<hru_state>* self);
 
-
-}
\ No newline at end of file
+void serializeHru(caf::stateful_actor<hru_state>* self, hru& serialized_state);
+void deserializeHru(caf::stateful_actor<hru_state>* self, hru& new_state);
diff --git a/build/includes/hru_actor/hru_utils.hpp b/build/includes/hru_actor/hru_utils.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0275d60d5e9d405fdbe55eac2325588468896c5f
--- /dev/null
+++ b/build/includes/hru_actor/hru_utils.hpp
@@ -0,0 +1,115 @@
+#pragma once
+#include <vector>
+
+// Serialization HRU Stucture
+struct hru {
+  int indx_hru;
+  int indx_gru;
+  int ref_gru;
+
+  // Misc Variables
+  int timestep;
+  int forcing_step;
+  int num_steps;
+  int iFile;
+  int dt_init_factor;
+  int output_structure_step_index;
+  double dt_init;
+  double upArea;
+
+  // Sundials variables
+  double rtol;
+  double atol;
+
+  // HRU data structures
+  // Statistic Structure
+  std::vector<std::vector<double>> forc_stat;
+  std::vector<std::vector<double>> prog_stat;
+  std::vector<std::vector<double>> diag_stat;
+  std::vector<std::vector<double>> flux_stat;
+  std::vector<std::vector<double>> indx_stat;
+  std::vector<std::vector<double>> bvar_stat;
+  // Primary Data Strutures (scalars)
+  std::vector<int> time_struct;
+  std::vector<double> forc_struct;
+  std::vector<double> attr_struct;
+  std::vector<int> type_struct;
+  std::vector<long int> id_struct;
+  // Primary Data Structures (arrays)
+  std::vector<std::vector<int>> indx_struct;
+  std::vector<std::vector<double>> mpar_struct;
+  std::vector<std::vector<double>> prog_struct;
+  std::vector<std::vector<double>> diag_struct;
+  std::vector<std::vector<double>> flux_struct;
+  // Basin-average structures
+  std::vector<double> bpar_struct;
+  std::vector<std::vector<double>> bvar_struct;
+  std::vector<double> dpar_struct;
+  // Local HRU data structures
+  std::vector<int> start_time;
+  std::vector<int> end_time;
+  std::vector<int> ref_time;
+  std::vector<int> old_time;
+  // statistic flags
+  std::vector<int> stat_counter;
+  std::vector<int> output_timestep;
+  std::vector<int> reset_stats;
+  std::vector<int> finalize_stats;
+
+  // scalar data
+  double frac_jul_day;
+  double tm_zone_offset_frac_day;
+  int year_length;
+  int compute_veg_flux;
+};
+
+template <class Inspector>
+bool inspect(Inspector& inspector, hru& hru_data) {
+  return inspector.object(hru_data).fields(
+         inspector.field("indx_hru", hru_data.indx_hru),
+         inspector.field("indx_gru", hru_data.indx_gru),
+         inspector.field("ref_gru", hru_data.ref_gru),
+         inspector.field("timestep", hru_data.timestep),
+         inspector.field("forcing_step", hru_data.forcing_step),
+         inspector.field("num_steps", hru_data.num_steps),
+         inspector.field("iFile", hru_data.iFile),
+         inspector.field("dt_init_factor", hru_data.dt_init_factor),
+         inspector.field("output_structure_step_index", 
+                         hru_data.output_structure_step_index),
+         inspector.field("dt_init", hru_data.dt_init),
+         inspector.field("upArea", hru_data.upArea),
+         inspector.field("rtol", hru_data.rtol),
+         inspector.field("atol", hru_data.atol),
+         inspector.field("forc_stat", hru_data.forc_stat),
+         inspector.field("prog_stat", hru_data.prog_stat),
+         inspector.field("diag_stat", hru_data.diag_stat),
+         inspector.field("flux_stat", hru_data.flux_stat),
+         inspector.field("indx_stat", hru_data.indx_stat),
+         inspector.field("bvar_stat", hru_data.bvar_stat),
+         inspector.field("time_struct", hru_data.time_struct),
+         inspector.field("forc_struct", hru_data.forc_struct),
+         inspector.field("attr_struct", hru_data.attr_struct),
+         inspector.field("type_struct", hru_data.type_struct),
+         inspector.field("id_struct", hru_data.id_struct),
+         inspector.field("indx_struct", hru_data.indx_struct),
+         inspector.field("mpar_struct", hru_data.mpar_struct),
+         inspector.field("prog_struct", hru_data.prog_struct),
+         inspector.field("diag_struct", hru_data.diag_struct),
+         inspector.field("flux_struct", hru_data.flux_struct),
+         inspector.field("bpar_struct", hru_data.bpar_struct),
+         inspector.field("bvar_struct", hru_data.bvar_struct),
+         inspector.field("dpar_struct", hru_data.dpar_struct),
+         inspector.field("start_time", hru_data.start_time),
+         inspector.field("end_time", hru_data.end_time),
+         inspector.field("ref_time", hru_data.ref_time),
+         inspector.field("old_time", hru_data.old_time),
+         inspector.field("stat_counter", hru_data.stat_counter),
+         inspector.field("output_timestep", hru_data.output_timestep),
+         inspector.field("reset_stats", hru_data.reset_stats),
+         inspector.field("finalize_stats", hru_data.finalize_stats),
+         inspector.field("frac_jul_day", hru_data.frac_jul_day),
+         inspector.field("tm_zone_offset_frac_day", 
+                         hru_data.tm_zone_offset_frac_day),
+         inspector.field("year_length", hru_data.year_length),
+         inspector.field("compute_veg_flux", hru_data.compute_veg_flux));
+}
\ No newline at end of file
diff --git a/build/includes/job_actor/GRU.hpp b/build/includes/job_actor/GRU.hpp
index 3c33f51d0afd520b43a230c2fd370f3f7a846959..69dc87275da50f368443772996922c4d086c8485 100644
--- a/build/includes/job_actor/GRU.hpp
+++ b/build/includes/job_actor/GRU.hpp
@@ -1,92 +1,57 @@
 #pragma once
-
 #include "caf/all.hpp"
-#include <iostream>
-#include <fstream>
-
-/*
- * Determine the state of the GRU
-*/
-enum class gru_state {
-    running,
-    failed,
-    succeeded
-};
 
-int is_success(const gru_state& state);
+/** Determine the state of the GRU */
+enum class gru_state { running, failed, succeeded };
 
-/**
- * Class that holds information about the running GRUs. This class is held by the job actor
- * The GRU/HRU actors that carry out the simulation are held by the GRU class 
-*/
+/** Gru Information (meant to mimic gru_struc)*/
 class GRU {
   private:
-    int global_gru_index; // The index of the GRU in the netcdf file
-    int local_gru_index; // The index of the GRU within this job
-    caf::actor gru_actor; // The actor for the GRU
+    int index_netcdf_;       // The index of the GRU in the netcdf file
+    int index_job_;          // The index of the GRU within this job
+    caf::actor actor_ref_;   // The actor for the GRU
 
     // Modifyable Parameters
-    int dt_init_factor; // The initial dt for the GRU
-    double rel_tol; // The relative tolerance for the GRU
-    double abs_tol; // The absolute tolerance for the GRU
+    int dt_init_factor_;     // The initial dt for the GRU
+    double rel_tol_;         // The relative tolerance for the GRU
+    double abs_tol_;         // The absolute tolerance for the GRU
 
     // Status Information
-    int attempts_left; // The number of attempts left for the GRU to succeed
-    gru_state state; // The state of the GRU
+    int attempts_left_;      // The number of attempts left for the GRU to succeed
+    gru_state state_;        // The state of the GRU
 
     // Timing Information
-    double run_time = 0.0; // The total time to run the GRU
-    double init_duration = 0.0; // The time to initialize the GRU
-    double forcing_duration = 0.0; // The time to read the forcing data
-    double run_physics_duration = 0.0; // The time to run the physics
-    double write_output_duration = 0.0; // The time to write the output
+    double run_time_ = 0.0;  // The total time to run the GRU
 
     
   public:
     // Constructor
-    GRU(int global_gru_index, int local_gru_index, caf::actor gru_actor, int dt_init_factor, 
-        double rel_tol, double abs_tol, int max_attempts);
+    GRU(int index_netcdf, int index_job, caf::actor actor_ref, 
+        int dt_init_factor, double rel_tol, double abs_tol, int max_attempts);
 
     // Deconstructor
     ~GRU();
 
     // Getters
-    int getGlobalGRUIndex();
-    int getLocalGRUIndex();
-    caf::actor getGRUActor();
-
-    double getRunTime();
-    double getInitDuration();
-    double getForcingDuration();
-    double getRunPhysicsDuration();
-    double getWriteOutputDuration();
-
-    double getRelTol();
-    double getAbsTol();
-
-    double getAttemptsLeft();
-    gru_state getStatus();
-
-    bool isFailed();
-
-
+    inline int getIndexNetcdf() const { return index_netcdf_; }
+    inline int getIndexJob() const { return index_job_; }
+    inline caf::actor getActorRef() const { return actor_ref_; }
+    inline double getRunTime() const { return run_time_; }
+    inline double getRelTol() const { return rel_tol_; }
+    inline double getAbsTol() const { return abs_tol_; }
+    inline int getAttemptsLeft() const { return attempts_left_; }
+    inline gru_state getStatus() const { return state_; }
 
     // Setters
-    void setRunTime(double run_time);
-    void setInitDuration(double init_duration);
-    void setForcingDuration(double forcing_duration);
-    void setRunPhysicsDuration(double run_physics_duration);
-    void setWriteOutputDuration(double write_output_duration);
-
-    void setRelTol(double rel_tol);
-    void setAbsTol(double abs_tol);
-
-    void setSuccess();
-    void setFailed();
-    void setRunning();
-
-    void decrementAttemptsLeft();
-
-    void setGRUActor(caf::actor gru_actor);
-
+    inline void setRunTime(double run_time) { run_time_ = run_time; }
+    inline void setRelTol(double rel_tol) { rel_tol_ = rel_tol; }
+    inline void setAbsTol(double abs_tol) { abs_tol_ = abs_tol; }
+    inline void setSuccess() { state_ = gru_state::succeeded; }
+    inline void setFailed() { state_ = gru_state::failed; }
+    inline void setRunning() { state_ = gru_state::running; }
+
+    // Methods
+    inline bool isFailed() const { return state_ == gru_state::failed; }
+    inline void decrementAttemptsLeft() { attempts_left_--; }
+    inline void setActorRef(caf::actor gru_actor) { actor_ref_ = gru_actor; }
 };
diff --git a/build/includes/job_actor/gru_struc.hpp b/build/includes/job_actor/gru_struc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..47b4ebc6e7259ac6ef44cd557387987ec7e3d46f
--- /dev/null
+++ b/build/includes/job_actor/gru_struc.hpp
@@ -0,0 +1,57 @@
+#pragma once
+#include <string>
+#include "GRU.hpp"
+
+extern "C" {
+  void read_dimension_fortran(int& start_gru, int& num_gru, int& num_hru, 
+                              int& file_gru, int& file_hru, int& err, 
+                              void* message);
+
+  void read_icond_nlayers_fortran(int& num_gru, int& err, void* message);
+
+  void deallocate_gru_struc_fortran();
+}
+
+class GruStruc {
+  
+  public:
+    GruStruc(int start_gru, int num_gru, int num_retry_attempts);
+    ~GruStruc(){deallocate_gru_struc_fortran();};
+    int ReadDimension();
+    int ReadIcondNlayers();
+    inline int getStartGru() const { return start_gru_; }
+    inline int getNumGrus() const { return num_gru_; }
+    inline int get_file_gru() const { return file_gru_; }
+    inline int get_gru_info_size() const { return gru_info_.size(); }
+    inline int getNumGrusDone() const { return num_gru_done_; }
+
+    inline void addGRU(std::unique_ptr<GRU> gru) {
+      gru_info_[gru->getIndexJob() - 1] = std::move(gru);
+    }
+
+    inline void incrementNumGRUDone() { num_gru_done_++; }
+
+    inline GRU* getGRU(int index) { return gru_info_[index-1].get(); }
+
+    inline bool isDone() { return num_gru_done_ >= num_gru_; }
+    inline bool hasFailures() { return num_gru_failed_ > 0; }
+    inline bool shouldRetry() { return num_retry_attempts_left_ > 0; }
+
+
+  private:
+    // Inital Information about the GRUs
+    int start_gru_;
+    int num_gru_;
+    int num_hru_;
+    int file_gru_;
+    int file_hru_;
+    
+    // GRU specific Information
+    std::vector<std::unique_ptr<GRU>> gru_info_;
+
+    // Runtime status of the GRUs
+    int num_gru_done_ = 0;
+    int num_gru_failed_ = 0;
+    int num_retry_attempts_left_ = 0;
+
+};
\ No newline at end of file
diff --git a/build/includes/job_actor/job_actor.hpp b/build/includes/job_actor/job_actor.hpp
index 6c42a0007d91709be06f79371feca7459f43c45b..1601413459c11c92aff8d340a2dd8ef8b57e6078 100644
--- a/build/includes/job_actor/job_actor.hpp
+++ b/build/includes/job_actor/job_actor.hpp
@@ -1,7 +1,9 @@
 #pragma once
 #include "caf/all.hpp"
 #include "caf/io/all.hpp"
+#include "num_gru_info.hpp"
 #include "GRU.hpp"
+#include "gru_struc.hpp"
 #include "timing_info.hpp"
 #include "settings_functions.hpp"
 #include "global.hpp"
@@ -16,34 +18,27 @@
 #include <vector>
 #include <tuple>
 
-/*********************************************
- * Job Actor Fortran Functions
- *********************************************/
-extern "C" {
-  void job_init_fortran(char const* file_manager, int* start_gru_index, 
-      int* num_gru, int* num_hru, int* file_gru, int* err);
-
-  void deallocateJobActor(int* err);
-}
 
 
 /*********************************************
- * Job Actor state variables
+ * Job Actor Data Structures
  *********************************************/
-namespace caf {
-using chrono_time = std::chrono::time_point<std::chrono::system_clock>;
-
 // Holds information about the GRUs
 struct GRU_Container {
   std::vector<GRU*> gru_list;
-  chrono_time gru_start_time; // Vector of start times for each GRU
+  std::chrono::time_point<std::chrono::system_clock> gru_start_time; // Vector of start times for each GRU
   int num_gru_done = 0; 
   int num_gru_failed = 0; // number of grus that are waiting to be restarted
   int num_gru_in_run_domain = 0; // number of grus we are currently solving for
   int run_attempts_left = 1; // current run attempt for all grus
 };
 
+
+/*********************************************
+ * Job Actor state variables
+ *********************************************/
 struct job_state {
+  TimingInfo job_timing;
   // Actor References
   caf::actor file_access_actor; // actor reference for the file_access_actor
   caf::actor parent;            // actor reference to the top-level SummaActor
@@ -53,10 +48,10 @@ struct job_state {
   int num_gru;                  // Number of GRUs for this job
   int num_hru;
   int max_run_attempts = 1;     // Max number of attempts to solve a GRU
-
+  
+  // TODO: gru_struc can contain the num_gru_info and be the gru_container
+  std::unique_ptr<GruStruc> gru_struc; 
   NumGRUInfo num_gru_info;
-
-
   GRU_Container gru_container;
   
   // Variables for GRU monitoring
@@ -65,7 +60,6 @@ struct job_state {
   int num_gru_failed = 0;       // Number of GRUs that have failed
 
   // Timing Variables
-  TimingInfo job_timing;
   
   std::string hostname;
 
@@ -105,8 +99,8 @@ struct distributed_job_state {
   std::vector<std::vector<double>> gru_times_per_node;
   std::vector<double> node_walltimes;
 
-  chrono_time load_balance_start_time;
-  chrono_time load_balance_end_time;
+  std::chrono::time_point<std::chrono::system_clock> load_balance_start_time;
+  std::chrono::time_point<std::chrono::system_clock> load_balance_end_time;
   double load_balance_time = 0.0;
 
   
@@ -145,19 +139,20 @@ struct distributed_job_state {
 };
 
 /** The Job Actor Behaviors */
-behavior job_actor(stateful_actor<job_state>* self, 
-    int start_gru, int num_gru, 
-    File_Access_Actor_Settings file_access_actor_settings, 
-    Job_Actor_Settings job_actor_settings, 
-    HRU_Actor_Settings hru_actor_settings, actor parent);
+caf::behavior job_actor(caf::stateful_actor<job_state>* self, int start_gru, 
+                        int num_gru, 
+                        File_Access_Actor_Settings file_access_actor_settings, 
+                        Job_Actor_Settings job_actor_settings, 
+                        HRU_Actor_Settings hru_actor_settings, 
+                        caf::actor parent);
 
-behavior data_assimilation_mode(stateful_actor<job_state>* self);
-behavior async_mode(stateful_actor<job_state>* self); 
+caf::behavior data_assimilation_mode(caf::stateful_actor<job_state>* self);
+caf::behavior async_mode(caf::stateful_actor<job_state>* self); 
 
 /** The Job Actor For Internode Communication */
-behavior distributed_job_actor(stateful_actor<distributed_job_state>* self,
-    int start_gru, int num_gru,
-    Distributed_Settings distributed_settings,
+caf::behavior distributed_job_actor(
+    caf::stateful_actor<distributed_job_state>* self, int start_gru, 
+    int num_gru, Distributed_Settings distributed_settings,
     File_Access_Actor_Settings file_access_actor_settings,
     Job_Actor_Settings job_actor_settings, 
     HRU_Actor_Settings hru_actor_settings);
@@ -167,17 +162,17 @@ behavior distributed_job_actor(stateful_actor<distributed_job_state>* self,
  * Functions for the Job Actor (job_utils.cpp)
  *********************************************/
 // Spawn HRU Actors Individually
-void spawnHRUActors(stateful_actor<job_state>* self);
+void spawnHRUActors(caf::stateful_actor<job_state>* self);
 // Spawn HRU Batch Actors
-void spawnHRUBatches(stateful_actor<job_state>* self);
+void spawnHRUBatches(caf::stateful_actor<job_state>* self);
 
-void handleFinishedGRU(stateful_actor<job_state>* self, int local_gru_index);
+void handleFinishedGRU(caf::stateful_actor<job_state>* self,
+                       int local_gru_index);
 
-void finalizeJob(stateful_actor<job_state>* self);
+void finalizeJob(caf::stateful_actor<job_state>* self);
 
 /** Get the information for the GRUs that will be written to the netcdf file */
 std::vector<serializable_netcdf_gru_actor_info> getGruNetcdfInfo(
     int max_run_attempts, std::vector<GRU*> &gru_list);
 
-void handleGRUError(stateful_actor<job_state>* self, caf::actor src);
-} // end namespace
\ No newline at end of file
+void handleGRUError(caf::stateful_actor<job_state>* self, caf::actor src);
\ No newline at end of file
diff --git a/build/includes/job_actor/node_actor.hpp b/build/includes/job_actor/node_actor.hpp
index 7e5b27947db73bc78035e63c2cb5dadc91b7ee08..7b6a4b175eb16e699c45cf182583afd64f235a7e 100644
--- a/build/includes/job_actor/node_actor.hpp
+++ b/build/includes/job_actor/node_actor.hpp
@@ -33,6 +33,8 @@ struct node_state {
   caf::actor file_access_actor; // actor reference for the file_access_actor
   GRU_Container gru_container;
 
+  std::unique_ptr<GruStruc> gru_struc;
+
   Distributed_Settings distributed_settings;
   File_Access_Actor_Settings file_access_actor_settings;
   Job_Actor_Settings job_actor_settings;
diff --git a/build/source/file_access_actor/summa_init_struc.f90 b/build/source/file_access_actor/summa_init_struc.f90
index 8291ccb425f1edc85616de1b1850b2bfd774fa77..4788ce83cd66feb86cbc992fec2707a2f327e39f 100644
--- a/build/source/file_access_actor/summa_init_struc.f90
+++ b/build/source/file_access_actor/summa_init_struc.f90
@@ -36,6 +36,8 @@ subroutine initialize_init_struc(num_gru, err, message_r) bind(C, name="initiali
                       statIndx_meta, &        ! child metadata for stats
                       statBvar_meta           ! child metadata for stats
   USE allocspace_module,only:allocGlobal      ! module to allocate space for global data structures
+  USE allocspace_module,only:allocLocal
+  USE globalData,only:startTime,finshTime,refTime,oldTime
   USE C_interface_module,only:f_c_string_ptr  ! convert fortran string to c string
   implicit none
   ! dummy variables
@@ -156,9 +158,16 @@ subroutine initialize_init_struc(num_gru, err, message_r) bind(C, name="initiali
 
   nGRU = num_gru
   nHRU = sum(gru_struc%hruCount)
+  
+  end associate summaVars
 
+  ! Allocate the time structures
+  call allocLocal(time_meta, startTime, err=err, message=message)
+  call allocLocal(time_meta, finshTime, err=err, message=message)
+  call allocLocal(time_meta, refTime,   err=err, message=message)
+  call allocLocal(time_meta, oldTime,   err=err, message=message)
+  if(err/=0)then; call f_c_string_ptr(trim(message), message_r); return; endif
 
-  end associate summaVars
 end subroutine initialize_init_struc
 
 subroutine paramSetup_fortran(err, message_r) bind(C, name="paramSetup_fortran")
@@ -197,8 +206,14 @@ subroutine readRestart_fortran(err, message_r) bind(C, name="readRestart_fortran
 end subroutine readRestart_fortran
 
 subroutine deallocate_init_struc() bind(C, name="deallocate_init_struc")
+  USE globalData,only:startTime,finshTime,refTime,oldTime
   implicit none
   deallocate(init_struc)
+  deallocate(startTime%var);
+  deallocate(finshTime%var);
+  deallocate(refTime%var);
+  deallocate(oldTime%var);
+  
 end subroutine deallocate_init_struc
 
 end module summa_init_struc
\ No newline at end of file
diff --git a/build/source/global/gru_struc.cpp b/build/source/global/gru_struc.cpp
deleted file mode 100644
index ecbe633a846816c001e4968017610efd652a0451..0000000000000000000000000000000000000000
--- a/build/source/global/gru_struc.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "gru_struc.hpp"
-#include <iostream>
-#include <netcdf.h>
-#include <vector>
-#include <future>
-
-gruStruc::gruStruc(const std::string &settingsPath, 
-    const std::string &attributeFile, int num_gru, int start_gru) {
-  std::cout << "Creating GRU Structure\n";
-  
-  size_t fileGRU, fileHRU;
-  int ncid, gru_dim_id, hru_dim_id, var_id;
-
-
-  std::string attributes_path = settingsPath + attributeFile;
-  // Read and set dimensions of whole file
-  nc_open(attributes_path.c_str(), NC_NOWRITE, &ncid);
-  nc_inq_dimid(ncid, "gru", &gru_dim_id);
-  nc_inq_dimid(ncid, "hru", &hru_dim_id);
-  nc_inq_dimlen(ncid, gru_dim_id, &fileGRU);
-  nc_inq_dimlen(ncid, hru_dim_id, &fileHRU);
-
-  std::vector<long int> gru_id(fileGRU);
-  std::vector<int> hru_ix(fileHRU);
-  std::vector<long int> hru_id(fileHRU);
-  std::vector<long int> hru2gru_id(fileHRU);
-
-  size_t start[1] = {0};
-  size_t count[1] = {fileGRU};
-  nc_inq_varid(ncid, "gruId", &var_id);
-  nc_get_vara_long(ncid, var_id, start, count, gru_id.data());
-
-  count[0] = fileHRU;
-  nc_inq_varid(ncid, "hruId", &var_id);
-  nc_get_vara_long(ncid, var_id, start, count, hru_id.data());
-
-  nc_inq_varid(ncid, "hru2gruId", &var_id);
-  nc_get_vara_long(ncid, var_id, start, count, hru2gru_id.data());
-
-  std::cout << "DONE READING\n";
-  nc_close(ncid);
-  
-  int file_hru = fileHRU;
-  int file_gru = fileGRU;
-  init_gru_struc(&num_gru, &file_hru, hru_ix.data());
-
-  std::vector<std::future<void>> futures;
-  
-  for (int i = 1; i < num_gru; i++) {
-    futures.push_back(std::async(std::launch::async, pop_gru_struc, &i, 
-        gru_id.data(), hru_id.data(), hru2gru_id.data(), hru_ix.data(), 
-        &file_gru, &file_hru, &num_gru, &start_gru));
-    // pop_gru_struc(&i, gru_id.data(), hru_id.data(), hru2gru_id.data(), 
-    //     hru_ix.data(), &file_gru, &file_hru, &num_gru, &start_gru);
-  }
-
-}
\ No newline at end of file
diff --git a/build/source/global/gru_struc.f90 b/build/source/global/gru_struc.f90
deleted file mode 100644
index 37c0aa6599331bf2004bc33e6cba0cd92b828635..0000000000000000000000000000000000000000
--- a/build/source/global/gru_struc.f90
+++ /dev/null
@@ -1,55 +0,0 @@
-module gru_struc_module
-  USE, intrinsic :: iso_c_binding
-  implicit none
-
-  public::init_gru_struc
-  public::pop_gru_struc
-  contains
-subroutine init_gru_struc(num_gru, file_hru, hru_ix) bind(C, name="init_gru_struc")
-  USE globalData,only:gru_struc                   ! gru->hru mapping structure
-  USE globalData,only:index_map                   ! hru->gru mapping structure
-  USE nr_utility_module,only:arth
-  implicit none
-  integer(c_int), intent(in) :: num_gru
-  integer(c_int), intent(in) :: file_hru
-  integer(c_int), intent(out) :: hru_ix(file_hru)
-
-  if (allocated(gru_struc)) deallocate(gru_struc)
-  allocate(gru_struc(num_gru))
-
-  hru_ix = arth(1,1,file_hru)
-
-end subroutine init_gru_struc
-
-subroutine pop_gru_struc(iGRU, gru_id, hru_id, hru2gru_id, hru_ix, file_gru, &
-    file_hru, num_gru, start_gru) bind(C, name="pop_gru_struc")
-  USE globalData,only:gru_struc                   ! gru->hru mapping structure
-  USE globalData,only:index_map                   ! hru->gru mapping structure
-  USE nr_utility_module,only:arth
-  implicit none
-  integer(c_int), intent(in)  :: iGRU
-  integer(c_int), intent(in)  :: file_gru
-  integer(c_int), intent(in)  :: file_hru
-  integer(c_int), intent(in)  :: num_gru
-  integer(c_int), intent(in)  :: start_gru
-  integer(c_long), intent(in) :: gru_id(file_gru)
-  integer(c_long), intent(in) :: hru_id(file_hru)
-  integer(c_long), intent(in) :: hru2gru_id(file_hru)
-  integer(c_int), intent(in)  :: hru_ix(file_hru)
-  integer ::  iHRU
-
-  iHRU = 1
-  gru_struc(iGRU)%hruCount          = count(hru2gru_Id == gru_id(iGRU+start_gru-1))                 ! number of HRUs in each GRU
-  gru_struc(iGRU)%gru_id            = gru_id(iGRU+start_gru-1)                                      ! set gru id
-  gru_struc(iGRU)%gru_nc            = iGRU+start_gru-1                                              ! set gru index in the netcdf file
-
-  allocate(gru_struc(iGRU)%hruInfo(gru_struc(iGRU)%hruCount))                                  ! allocate second level of gru to hru map
-  gru_struc(iGRU)%hruInfo(:)%hru_nc = pack(hru_ix,hru2gru_id == gru_struc(iGRU)%gru_id)        ! set hru id in attributes netcdf file
-  gru_struc(iGRU)%hruInfo(:)%hru_ix = arth(iHRU,1,gru_struc(iGRU)%hruCount)                    ! set index of hru in run domain
-  gru_struc(iGRU)%hruInfo(:)%hru_id = hru_id(gru_struc(iGRU)%hruInfo(:)%hru_nc)                ! set id of hru
-  iHRU = iHRU + gru_struc(iGRU)%hruCount
-
-
-end subroutine pop_gru_struc
-
-end module gru_struc_module
\ No newline at end of file
diff --git a/build/source/global/message_atoms.cpp b/build/source/global/message_atoms.cpp
index 25037a479af6b2b24744eac87975ba03d25c5a02..dd86857c1b31d3d2d2ff587b2549256760472a6c 100644
--- a/build/source/global/message_atoms.cpp
+++ b/build/source/global/message_atoms.cpp
@@ -1,42 +1,6 @@
 #include "caf/all.hpp"
 #include "message_atoms.hpp"
 
-// HRU Errors
-std::string to_string(hru_error err) {
-    switch(err) {
-        case hru_error::run_physics_unhandleable:
-            return "run_physics_unhandleable";
-        case hru_error::run_physics_infeasible_state:
-            return "run_physics_infeasible_state";
-        default:
-            return "unknown";
-    }
-}
-
-bool from_string(caf::string_view in, hru_error& out) {
-    if (in == "run_physics_unhandleable") {
-        out = hru_error::run_physics_unhandleable;
-        return true;
-    }
-    if (in == "run_physics_infeasible_state") {
-        out = hru_error::run_physics_infeasible_state;
-        return true;
-    }
-    return false;
-}
-
-bool from_integer(uint8_t in, hru_error& out) {
-    switch(in) {
-        case 1:
-            out = hru_error::run_physics_unhandleable;
-            return true;
-        case 2:
-            out = hru_error::run_physics_infeasible_state;
-            return true;
-        default:
-            return false;
-    }
-}
 
 // File Access Error
 std::string to_string(file_access_error err) {
diff --git a/build/source/hru_actor/hru_actor.cpp b/build/source/hru_actor/hru_actor.cpp
index dc754f017c2f63b0a54875e1cbb0577e77751842..616ce29fa46678a48042b8a170627f50ca693e2e 100644
--- a/build/source/hru_actor/hru_actor.cpp
+++ b/build/source/hru_actor/hru_actor.cpp
@@ -1,14 +1,13 @@
 #include "hru_actor.hpp"
 
-bool hru_extra_logging = true;
-
-namespace caf {
-
-behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
-    HRU_Actor_Settings hru_actor_settings, caf::actor file_access_actor, 
-    caf::actor parent) {
-
-  self->set_exit_handler([=](const exit_msg& msg) {
+bool hru_extra_logging = false;
+
+using namespace caf;
+behavior hru_actor(stateful_actor<hru_state>* self, int ref_gru, int indx_gru,
+                   HRU_Actor_Settings hru_actor_settings, 
+                   actor file_access_actor, actor parent) {
+            
+  self->set_exit_handler([=](const caf::exit_msg& msg) {
     aout(self) << "HRU Actor: Received Exit Message\n";
   });
   
@@ -16,13 +15,13 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
   self->state.file_access_actor = file_access_actor;
   self->state.parent            = parent;
   // Indexes into global structures
+  self->state.ref_gru           = ref_gru;
+  self->state.indxGRU           = indx_gru;
   self->state.indxHRU           = 1;
-  self->state.indxGRU           = indxGRU;
-  self->state.refGRU            = refGRU;
   if (hru_extra_logging) {
     aout(self) << "HRU Actor: indxHRU = " << self->state.indxHRU 
                << " indxGRU = " << self->state.indxGRU 
-               << " refGRU = " << self->state.refGRU << "\n";
+               << " ref_gru = " << self->state.ref_gru << "\n";
   }
   // Get the settings for the HRU
   self->state.hru_actor_settings = hru_actor_settings;
@@ -61,15 +60,7 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
         self->state.num_steps_until_write--;
         err = Run_HRU(self); // Simulate a Timestep
         if (err != 0) {
-          #ifdef SUNDIALS_ACTIVE                        
-            get_sundials_tolerances(self->state.hru_data, &self->state.rtol, 
-                                    &self->state.atol);
-            self->send(self->state.parent, err_atom_v, self, self->state.rtol,
-                self->state.atol);
-          #else                        
-            self->send(self->state.parent, hru_error::run_physics_unhandleable, 
-                       self);
-          #endif
+            self->send(self->state.parent, err_atom_v, err);
           self->quit();
           return;
         }
@@ -96,7 +87,7 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
       if (hru_extra_logging) {
         aout(self) << "Recieved New iFile-" << iFile 
                    << " with " << num_forcing_steps_in_iFile 
-                  << " forcing steps\n";
+                   << " forcing steps\n";
       }
       int err;
       self->state.iFile = iFile;
@@ -106,7 +97,7 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
         aout(self) << "Error: HRU_Actor - setTimeZoneOffset - HRU = " 
                    << self->state.indxHRU << " - indxGRU = " 
                    << self->state.indxGRU << " - refGRU = " 
-                   << self->state.refGRU << "\n";
+                   << self->state.ref_gru << "\n";
         self->quit();
         return;
       }
@@ -147,8 +138,7 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
 
       int err = Run_HRU(self);
       if (err != 0) {
-        self->send(self->state.parent, hru_error::run_physics_unhandleable,
-            self);
+        self->send(self->state.parent, err_atom_v, err);
         self->quit();
         return;
       }
@@ -159,208 +149,51 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
 
     // Get Fortran Data into C++
     [=](serialize_hru) {
-
-      // std::vector<std::vector<std::vector<double>>> lookup_struct = 
-          // get_lookup_struct(self->state.hru_data);
-
-      self->state.hru_data_serialized.indx_hru = self->state.indxHRU;
-      self->state.hru_data_serialized.indx_gru = self->state.indxGRU;
-      self->state.hru_data_serialized.ref_gru = self->state.refGRU;
-      self->state.hru_data_serialized.timestep = self->state.timestep;
-      self->state.hru_data_serialized.forcing_step = self->state.forcingStep;
-      self->state.hru_data_serialized.num_steps = self->state.num_steps;
-      self->state.hru_data_serialized.iFile = self->state.iFile;
-      self->state.hru_data_serialized.dt_init_factor = 
-          self->state.dt_init_factor;
-      self->state.hru_data_serialized.output_structure_step_index = 
-          self->state.output_structure_step_index; 
-      self->state.hru_data_serialized.dt_init = self->state.dt_init;
-      self->state.hru_data_serialized.upArea = self->state.upArea;
-      self->state.hru_data_serialized.rtol = self->state.rtol;
-      self->state.hru_data_serialized.atol = self->state.atol;
-
-      // Statistic Structures
-      self->state.hru_data_serialized.forc_stat = 
-          get_var_dlength_by_indx(self->state.hru_data, 1); 
-      self->state.hru_data_serialized.prog_stat = 
-          get_var_dlength_by_indx(self->state.hru_data, 2); 
-      self->state.hru_data_serialized.diag_stat = 
-          get_var_dlength_by_indx(self->state.hru_data, 3); 
-      self->state.hru_data_serialized.flux_stat = 
-          get_var_dlength_by_indx(self->state.hru_data, 4); 
-      self->state.hru_data_serialized.indx_stat = 
-          get_var_dlength_by_indx(self->state.hru_data, 5); 
-      self->state.hru_data_serialized.bvar_stat = 
-          get_var_dlength_by_indx(self->state.hru_data, 6);
-      
-      // Primary Data Structures (scalars)
-      self->state.hru_data_serialized.time_struct = 
-          get_var_i_by_indx(self->state.hru_data, 1);
-      self->state.hru_data_serialized.forc_struct = 
-          get_var_d_by_indx(self->state.hru_data, 1);
-      self->state.hru_data_serialized.attr_struct = 
-          get_var_d_by_indx(self->state.hru_data, 2);
-      self->state.hru_data_serialized.type_struct = 
-          get_var_i_by_indx(self->state.hru_data, 2);
-      self->state.hru_data_serialized.id_struct = 
-          get_var_i8_by_indx(self->state.hru_data, 1);
-      
-      // Primary Data Structures (variable length vectors)
-      self->state.hru_data_serialized.indx_struct = 
-          get_var_ilength_by_indx(self->state.hru_data, 1);
-      self->state.hru_data_serialized.mpar_struct = 
-          get_var_dlength_by_indx(self->state.hru_data, 7);      
-      self->state.hru_data_serialized.prog_struct = 
-          get_var_dlength_by_indx(self->state.hru_data, 8);
-      self->state.hru_data_serialized.diag_struct = 
-          get_var_dlength_by_indx(self->state.hru_data, 9);
-      self->state.hru_data_serialized.flux_struct = 
-          get_var_dlength_by_indx(self->state.hru_data, 10);
-
-      // Basin-average structures
-      self->state.hru_data_serialized.bpar_struct = 
-          get_var_d_by_indx(self->state.hru_data, 3);
-      self->state.hru_data_serialized.bvar_struct = 
-          get_var_dlength_by_indx(self->state.hru_data, 11);
-      self->state.hru_data_serialized.dpar_struct = 
-          get_var_d_by_indx(self->state.hru_data, 4);
-
-      // Local HRU data structures
-      self->state.hru_data_serialized.start_time = 
-          get_var_i_by_indx(self->state.hru_data, 3);
-      self->state.hru_data_serialized.end_time = 
-          get_var_i_by_indx(self->state.hru_data, 4);
-      self->state.hru_data_serialized.ref_time = 
-          get_var_i_by_indx(self->state.hru_data, 5);
-      self->state.hru_data_serialized.old_time = 
-          get_var_i_by_indx(self->state.hru_data, 6);
-
-      // Statistic flags
-      self->state.hru_data_serialized.stat_counter = 
-          get_var_i_by_indx(self->state.hru_data, 7);
-      self->state.hru_data_serialized.output_timestep = 
-          get_var_i_by_indx(self->state.hru_data, 8);
-      self->state.hru_data_serialized.reset_stats = 
-          get_flagVec_by_indx(self->state.hru_data, 1);
-      self->state.hru_data_serialized.finalize_stats = 
-          get_flagVec_by_indx(self->state.hru_data, 2);
-
-      get_scalar_data(self->state.hru_data,
-          self->state.hru_data_serialized.frac_jul_day,
-          self->state.hru_data_serialized.tm_zone_offset_frac_day,
-          self->state.hru_data_serialized.year_length,
-          self->state.hru_data_serialized.compute_veg_flux);
-       
-      self->send(self->state.parent, self->state.hru_data_serialized);
+      hru serialized_state;
+      serializeHru(self, serialized_state);
+      self->send(self->state.parent, serialized_state);
     },
 
     [=](reinit_hru, hru hru_data) {
-
-      // Set output structure finalize stats to false for all timesteps of 
-      // the old GRU index
-      setFinalizeStatsFalse(&self->state.indxGRU);
-      // deallocate the old hru_data
-      delete_handle_hru_type(self->state.hru_data);
-      self->state.hru_data = new_handle_hru_type();
-
-
-      self->state.indxHRU = hru_data.indx_hru;
-      self->state.indxGRU = hru_data.indx_gru;
-      self->state.refGRU = hru_data.ref_gru;
-      self->state.timestep = hru_data.timestep;
-      self->state.forcingStep = hru_data.forcing_step;
-      self->state.num_steps = hru_data.num_steps;
-      self->state.iFile = hru_data.iFile;
-      self->state.dt_init_factor = hru_data.dt_init_factor;
-      self->state.output_structure_step_index = 
-          hru_data.output_structure_step_index;
-      self->state.dt_init = hru_data.dt_init;
-      self->state.upArea = hru_data.upArea;
-      self->state.rtol = hru_data.rtol;
-      self->state.atol = hru_data.atol;
-
-      // Statistic Structures
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.forc_stat, 1);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.prog_stat, 2);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.diag_stat, 3);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.flux_stat, 4);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.indx_stat, 5);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.bvar_stat, 6);
-
-      // Primary Data Structures (scalars)
-      set_var_i_by_indx(self->state.hru_data, hru_data.time_struct, 1);
-      set_var_d_by_indx(self->state.hru_data, hru_data.forc_struct, 1);
-      set_var_d_by_indx(self->state.hru_data, hru_data.attr_struct, 2);
-      set_var_i_by_indx(self->state.hru_data, hru_data.type_struct, 2);
-      set_var_i8_by_indx(self->state.hru_data, hru_data.id_struct, 1);
-
-      // Primary Data Structures (variable length vectors)
-      set_var_ilength_by_indx(self->state.hru_data, hru_data.indx_struct, 1);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.mpar_struct, 7);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.prog_struct, 8);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.diag_struct, 9);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.flux_struct, 10);
-
-      // Basin-average structures
-      set_var_d_by_indx(self->state.hru_data, hru_data.bpar_struct, 3);
-      set_var_dlength_by_indx(self->state.hru_data, hru_data.bvar_struct, 11);
-      set_var_d_by_indx(self->state.hru_data, hru_data.dpar_struct, 4);
-
-      // Local HRU data structures
-      set_var_i_by_indx(self->state.hru_data, hru_data.start_time, 3);
-      set_var_i_by_indx(self->state.hru_data, hru_data.end_time, 4);
-      set_var_i_by_indx(self->state.hru_data, hru_data.ref_time, 5);
-      set_var_i_by_indx(self->state.hru_data, hru_data.old_time, 6);
-
-      // statistic flags
-      set_var_i_by_indx(self->state.hru_data, hru_data.stat_counter, 7);
-      set_var_i_by_indx(self->state.hru_data, hru_data.output_timestep, 8);
-      set_flagVec_by_indx(self->state.hru_data, hru_data.reset_stats, 1);
-      set_flagVec_by_indx(self->state.hru_data, hru_data.finalize_stats, 2);
-
-      // scalar data
-      set_scalar_data(self->state.hru_data, hru_data.frac_jul_day,
-          hru_data.tm_zone_offset_frac_day, hru_data.year_length,
-          hru_data.compute_veg_flux);
-
+      deserializeHru(self, hru_data);
       self->send(self->state.parent, reinit_hru_v);
     },
-
   };
 }
 
 
 
 void Initialize_HRU(stateful_actor<hru_state>* self) {
+  int err = 0;
   initHRU(&self->state.indxGRU, &self->state.num_steps, self->state.hru_data, 
-      &self->state.err);
-  if (self->state.err != 0) {
+          &err);
+  if (err != 0) {
     aout(self) << "Error: HRU_Actor - Initialize - HRU = " 
                << self->state.indxHRU  
                << " - indxGRU = " << self->state.indxGRU 
-               << " - refGRU = "<< self->state.refGRU
-               << "\nError Code = " << self->state.err << "\n";
+               << " - refGRU = "<< self->state.ref_gru
+               << "\nError Code = " << err << "\n";
     self->quit();
   }
 
   setupHRUParam(&self->state.indxGRU, &self->state.indxHRU, 
-      self->state.hru_data, &self->state.upArea, &self->state.err);
-  if (self->state.err != 0) {
+                self->state.hru_data, &self->state.upArea, &err);
+  if (err != 0) {
     aout(self) << "Error: HRU_Actor - SetupHRUParam - HRU = " 
                 << self->state.indxHRU
                 << " - indxGRU = " << self->state.indxGRU 
-                << " - refGRU = " << self->state.refGRU << "\n";
+                << " - refGRU = " << self->state.ref_gru << "\n";
     self->quit();
     return;
   }
           
   summa_readRestart(&self->state.indxGRU, &self->state.indxHRU,
-      self->state.hru_data, &self->state.dt_init, &self->state.err);
-  if (self->state.err != 0) {
+                    self->state.hru_data, &self->state.dt_init, &err);
+  if (err != 0) {
     aout(self) << "Error: HRU_Actor - summa_readRestart - HRU = " 
                << self->state.indxHRU
                << " - indxGRU = " << self->state.indxGRU 
-               << " - refGRU = " << self->state.refGRU << "\n";
+               << " - refGRU = " << self->state.ref_gru << "\n";
     self->quit();
     return;
   }
@@ -374,57 +207,54 @@ void Initialize_HRU(stateful_actor<hru_state>* self) {
 }
 
 int Run_HRU(stateful_actor<hru_state>* self) {
+  int err = 0;
   HRU_readForcing(&self->state.indxGRU, &self->state.timestep, 
                   &self->state.forcingStep, &self->state.iFile, 
-                  self->state.hru_data, &self->state.err);
-  if (self->state.err != 0) {
+                  self->state.hru_data, &err);
+  if (err != 0) {
     aout(self) << "Error---HRU_Actor: ReadForcingHRU\n" 
                << "\tIndxGRU = " << self->state.indxGRU << "\n"
-               << "\tRefGRU = " << self->state.refGRU << "\n"
+               << "\tRefGRU = " << self->state.ref_gru << "\n"
                << "\tForcing Step = " << self->state.forcingStep << "\n"
                << "\tTimestep = " << self->state.timestep << "\n"
                << "\tiFile = " << self->state.iFile << "\n"
                << "\tSteps in Forcing File = " 
                << self->state.stepsInCurrentFFile << "\n";
     self->quit();
-    return -1;
+    return err;
   }
 
-  if (self->state.hru_actor_settings.print_output && self->state.timestep % 
-      self->state.hru_actor_settings.output_frequency == 0) {
-    aout(self) << self->state.refGRU << " - Timestep = " 
+  auto& settings = self->state.hru_actor_settings;
+  if (settings.print_output && self->state.timestep % 
+      settings.output_frequency == 0) {
+    aout(self) << self->state.ref_gru << " - Timestep = " 
                << self->state.timestep << "\n";
   }
     
-
-  self->state.err = 0;
   RunPhysics(&self->state.indxHRU, &self->state.timestep, self->state.hru_data, 
              &self->state.dt_init,  &self->state.dt_init_factor, 
-             &self->state.walltime_timestep, &self->state.err);
-  if (self->state.err != 0) {
+             &self->state.walltime_timestep, &err);
+  if (err != 0) {
     aout(self) << "Error---RunPhysics:\n"
                << "\tIndxGRU = "  << self->state.indxGRU 
-               << "\tRefGRU = "   << self->state.refGRU 
+               << "\tRefGRU = "   << self->state.ref_gru 
                << "\tTimestep = " << self->state.timestep <<  "\n";
     self->quit();
-    return 20;
+    return err;
   }
 
   hru_writeOutput(&self->state.indxHRU, &self->state.indxGRU,
                   &self->state.timestep, 
                   &self->state.output_structure_step_index, 
-                  self->state.hru_data, &self->state.err);
-  if (self->state.err != 0) {
+                  self->state.hru_data, &err);
+  if (err != 0) {
     aout(self) << "Error: HRU_Actor - writeHRUToOutputStructure - HRU = " 
                 << self->state.indxHRU << " - indxGRU = " 
-                << self->state.indxGRU << " - refGRU = " << self->state.refGRU
-                << "\nError = " << self->state.err  << "\n";
+                << self->state.indxGRU << " - refGRU = " << self->state.ref_gru
+                << "\nError = " << err  << "\n";
     self->quit();
-    return 21;
+    return err;
   }
 
   return 0;      
-}
-
-
 }
\ No newline at end of file
diff --git a/build/source/hru_actor/hru_utils.cpp b/build/source/hru_actor/hru_utils.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..87535b73fe70e60e1674ee748fac1c2a3eafea91 100644
--- a/build/source/hru_actor/hru_utils.cpp
+++ b/build/source/hru_actor/hru_utils.cpp
@@ -0,0 +1,133 @@
+#include "hru_actor.hpp"
+
+using namespace caf;
+
+
+/*********************************************
+ * HRU Actor Serialization Functions
+ *********************************************/
+void serializeHru(stateful_actor<hru_state>* self, hru& serialized_state) {
+  // std::vector<std::vector<std::vector<double>>> lookup_struct = 
+      // get_lookup_struct(self->state.hru_data);
+  serialized_state.indx_hru = self->state.indxHRU;
+  serialized_state.indx_gru = self->state.indxGRU;
+  serialized_state.ref_gru = self->state.ref_gru;
+  serialized_state.timestep = self->state.timestep;
+  serialized_state.forcing_step = self->state.forcingStep;
+  serialized_state.num_steps = self->state.num_steps;
+  serialized_state.iFile = self->state.iFile;
+  serialized_state.dt_init_factor = self->state.dt_init_factor;
+  serialized_state.output_structure_step_index = 
+      self->state.output_structure_step_index; 
+  serialized_state.dt_init = self->state.dt_init;
+  serialized_state.upArea = self->state.upArea;
+  serialized_state.rtol = self->state.rtol;
+  serialized_state.atol = self->state.atol;
+
+  // Statistic Structures
+  serialized_state.forc_stat = get_var_dlength_by_indx(self->state.hru_data, 1); 
+  serialized_state.prog_stat = get_var_dlength_by_indx(self->state.hru_data, 2); 
+  serialized_state.diag_stat = get_var_dlength_by_indx(self->state.hru_data, 3); 
+  serialized_state.flux_stat = get_var_dlength_by_indx(self->state.hru_data, 4); 
+  serialized_state.indx_stat = get_var_dlength_by_indx(self->state.hru_data, 5); 
+  serialized_state.bvar_stat = get_var_dlength_by_indx(self->state.hru_data, 6);
+  // Primary Data Structures (scalars)
+  serialized_state.time_struct = get_var_i_by_indx(self->state.hru_data, 1);
+  serialized_state.forc_struct = get_var_d_by_indx(self->state.hru_data, 1);
+  serialized_state.attr_struct = get_var_d_by_indx(self->state.hru_data, 2);
+  serialized_state.type_struct = get_var_i_by_indx(self->state.hru_data, 2);
+  serialized_state.id_struct = get_var_i8_by_indx(self->state.hru_data, 1);
+  // Primary Data Structures (variable length vectors)
+  serialized_state.indx_struct = 
+      get_var_ilength_by_indx(self->state.hru_data, 1);
+  serialized_state.mpar_struct = 
+      get_var_dlength_by_indx(self->state.hru_data, 7);      
+  serialized_state.prog_struct = 
+      get_var_dlength_by_indx(self->state.hru_data, 8);
+  serialized_state.diag_struct = 
+      get_var_dlength_by_indx(self->state.hru_data, 9);
+  serialized_state.flux_struct = 
+      get_var_dlength_by_indx(self->state.hru_data, 10);
+  // Basin-average structures
+  serialized_state.bpar_struct = get_var_d_by_indx(self->state.hru_data, 3);
+  serialized_state.bvar_struct = 
+      get_var_dlength_by_indx(self->state.hru_data, 11);
+  serialized_state.dpar_struct = get_var_d_by_indx(self->state.hru_data, 4);
+
+  // Local HRU data structures
+  serialized_state.start_time = get_var_i_by_indx(self->state.hru_data, 3);
+  serialized_state.end_time = get_var_i_by_indx(self->state.hru_data, 4);
+  serialized_state.ref_time = get_var_i_by_indx(self->state.hru_data, 5);
+  serialized_state.old_time = get_var_i_by_indx(self->state.hru_data, 6);
+
+  // Statistic flags
+  serialized_state.stat_counter = get_var_i_by_indx(self->state.hru_data, 7);
+  serialized_state.output_timestep = get_var_i_by_indx(self->state.hru_data, 8);
+  serialized_state.reset_stats = get_flagVec_by_indx(self->state.hru_data, 1);
+  serialized_state.finalize_stats = get_flagVec_by_indx(self->state.hru_data, 2);
+
+  get_scalar_data(self->state.hru_data, serialized_state.frac_jul_day,
+                  serialized_state.tm_zone_offset_frac_day,
+                  serialized_state.year_length,
+                  serialized_state.compute_veg_flux);
+}
+
+void deserializeHru(stateful_actor<hru_state>* self, hru& new_state) {
+  setFinalizeStatsFalse(&self->state.indxGRU);
+
+  // Delete the old hru_data in Fortran
+  delete_handle_hru_type(self->state.hru_data);
+  self->state.hru_data = new_handle_hru_type();
+
+  self->state.indxHRU = new_state.indx_hru;
+  self->state.indxGRU = new_state.indx_gru;
+  self->state.ref_gru = new_state.ref_gru;
+  self->state.timestep = new_state.timestep;
+  self->state.forcingStep = new_state.forcing_step;
+  self->state.num_steps = new_state.num_steps;
+  self->state.iFile = new_state.iFile;
+  self->state.dt_init_factor = new_state.dt_init_factor;
+  self->state.output_structure_step_index = 
+      new_state.output_structure_step_index;
+  self->state.dt_init = new_state.dt_init;
+  self->state.upArea = new_state.upArea;
+  self->state.rtol = new_state.rtol;
+  self->state.atol = new_state.atol;
+  // Statistic Structures
+  set_var_dlength_by_indx(self->state.hru_data, new_state.forc_stat, 1);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.prog_stat, 2);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.diag_stat, 3);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.flux_stat, 4);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.indx_stat, 5);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.bvar_stat, 6);
+ // Primary Data Structures (scalars)
+  set_var_i_by_indx(self->state.hru_data, new_state.time_struct, 1);
+  set_var_d_by_indx(self->state.hru_data, new_state.forc_struct, 1);
+  set_var_d_by_indx(self->state.hru_data, new_state.attr_struct, 2);
+  set_var_i_by_indx(self->state.hru_data, new_state.type_struct, 2);
+  set_var_i8_by_indx(self->state.hru_data, new_state.id_struct, 1);
+  // Primary Data Structures (variable length vectors)
+  set_var_ilength_by_indx(self->state.hru_data, new_state.indx_struct, 1);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.mpar_struct, 7);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.prog_struct, 8);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.diag_struct, 9);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.flux_struct, 10);
+  // Basin-average structures
+  set_var_d_by_indx(self->state.hru_data, new_state.bpar_struct, 3);
+  set_var_dlength_by_indx(self->state.hru_data, new_state.bvar_struct, 11);
+  set_var_d_by_indx(self->state.hru_data, new_state.dpar_struct, 4);
+  // Local HRU data structures
+  set_var_i_by_indx(self->state.hru_data, new_state.start_time, 3);
+  set_var_i_by_indx(self->state.hru_data, new_state.end_time, 4);
+  set_var_i_by_indx(self->state.hru_data, new_state.ref_time, 5);
+  set_var_i_by_indx(self->state.hru_data, new_state.old_time, 6);
+    // statistic flags
+  set_var_i_by_indx(self->state.hru_data, new_state.stat_counter, 7);
+  set_var_i_by_indx(self->state.hru_data, new_state.output_timestep, 8);
+  set_flagVec_by_indx(self->state.hru_data, new_state.reset_stats, 1);
+  set_flagVec_by_indx(self->state.hru_data, new_state.finalize_stats, 2);
+  // scalar data
+  set_scalar_data(self->state.hru_data, new_state.frac_jul_day,
+                  new_state.tm_zone_offset_frac_day, new_state.year_length,
+                  new_state.compute_veg_flux);
+}
\ No newline at end of file
diff --git a/build/source/job_actor/GRU.cpp b/build/source/job_actor/GRU.cpp
index 3f81ab2d39ca9e0d1b8f3711fd1c4aef7485b82e..ecef34302240f17a0110f33f2ecf59a1d6c36986 100644
--- a/build/source/job_actor/GRU.cpp
+++ b/build/source/job_actor/GRU.cpp
@@ -1,119 +1,15 @@
-#include "caf/all.hpp"
 #include "GRU.hpp"
-#include <iostream>
-#include <fstream>
 
-
-int is_success(const gru_state& state) {
-
-  return(state == gru_state::succeeded) ? 1 : 0;
-}
-
-
-GRU::GRU(int global_gru_index, int local_gru_index, caf::actor gru_actor, 
+GRU::GRU(int index_netcdf, int index_job, caf::actor actor_ref, 
          int dt_init_factor, double rel_tol, double abs_tol, int max_attempt) {
-  this->global_gru_index = global_gru_index;
-  this->local_gru_index = local_gru_index;
-  this->gru_actor = gru_actor;
-  this->dt_init_factor = dt_init_factor;
-  this->rel_tol = rel_tol;
-  this->abs_tol = abs_tol;
-  this->attempts_left = max_attempt;
-  this->state = gru_state::running;
-}
-GRU::~GRU() {};
-
-// Getters
-int GRU::getGlobalGRUIndex() {
-  return this->global_gru_index;
-}
-
-int GRU::getLocalGRUIndex() {
-  return this->local_gru_index;
-}
-
-caf::actor GRU::getGRUActor() {
-  return this->gru_actor;
-}
-
-double GRU::getRunTime() {
-  return this->run_time;
-}
-
-double GRU::getInitDuration() {
-  return this->init_duration;
-}
-
-double GRU::getForcingDuration() {
-  return this->forcing_duration;
-}
-
-double GRU::getRunPhysicsDuration() {
-  return this->run_physics_duration;
-}
-
-double GRU::getWriteOutputDuration() {
-  return this->write_output_duration;
-}
-
-double GRU::getRelTol() {
-  return this->rel_tol;
+  index_netcdf_ = index_netcdf;
+  index_job_ = index_job;
+  actor_ref_ = actor_ref;
+  dt_init_factor_ = dt_init_factor;
+  rel_tol_ = rel_tol;
+  abs_tol_ = abs_tol;
+  attempts_left_ = max_attempt;
+  state_ = gru_state::running;
 }
 
-double GRU::getAbsTol() {
-  return this->abs_tol;
-}
-
-double GRU::getAttemptsLeft() {
-  return this->attempts_left;
-}
-
-gru_state GRU::getStatus() {
-  return this->state;
-}
-
-bool GRU::isFailed() {
-  return this->state == gru_state::failed;
-}
-
-// Setters
-void GRU::setRunTime(double run_time) {
-  this->run_time = run_time;
-}
-void GRU::setInitDuration(double init_duration) {
-  this->init_duration = init_duration;
-}
-void GRU::setForcingDuration(double forcing_duration) {
-  this->forcing_duration = forcing_duration;
-}
-void GRU::setRunPhysicsDuration(double run_physics_duration) {
-  this->run_physics_duration = run_physics_duration;
-}
-void GRU::setWriteOutputDuration(double write_output_duration) {
-  this->write_output_duration = write_output_duration;
-}
-
-void GRU::setRelTol(double rel_tol) {
-  this->rel_tol = rel_tol;
-}
-void GRU::setAbsTol(double abs_tol) {
-  this->abs_tol = abs_tol;
-}
-
-void GRU::setSuccess() {
-  this->state = gru_state::succeeded;
-}
-void GRU::setFailed() {
-  this->state = gru_state::failed;
-}
-void GRU::setRunning() {
-  this->state = gru_state::running;
-}
-
-void GRU::decrementAttemptsLeft() {
-  this->attempts_left--;
-}
-
-void GRU::setGRUActor(caf::actor gru_actor) {
-  this->gru_actor = gru_actor;
-}
\ No newline at end of file
+GRU::~GRU() {};
diff --git a/build/source/job_actor/async_mode.cpp b/build/source/job_actor/async_mode.cpp
index 18c39f1e96f45c23b576caebc1b8d560a86ae9c5..3e115774fa2f78c911dedae80801751d7210c4a9 100644
--- a/build/source/job_actor/async_mode.cpp
+++ b/build/source/job_actor/async_mode.cpp
@@ -1,5 +1,6 @@
 #include "job_actor.hpp"
-namespace caf {
+
+using namespace caf;
 
 behavior async_mode(stateful_actor<job_state>* self) {
   aout(self) << "Async Mode Started\n";
@@ -10,20 +11,18 @@ behavior async_mode(stateful_actor<job_state>* self) {
       aout(self) << "Async Mode: init_file_access_actor\n";
       self->state.num_steps = num_timesteps;
       spawnHRUActors(self);
-      for(auto& gru : self->state.gru_container.gru_list) {
-        self->send(gru->getGRUActor(), init_hru_v);
-        self->send(gru->getGRUActor(), update_hru_async_v);
-      }
     },
 
-    [=](done_hru, int local_gru_index) {
-      aout(self) << "HRU Done: " << local_gru_index << "\n";
-      handleFinishedGRU(self, local_gru_index);
+    [=](done_hru, int gru_job_index) {
+      handleFinishedGRU(self, gru_job_index);
     },
 
     [=](finalize) { finalizeJob(self); },
+
+    /**Error Handling Functions*/
+    [=](err_atom, int err_code) {
+      aout(self) << "Async Mode: Error: " << err_code << "\n";
+    }
     
   };
 }
-
-} // End of Namespace
\ No newline at end of file
diff --git a/build/source/job_actor/data_assimilation_mode.cpp b/build/source/job_actor/data_assimilation_mode.cpp
index f36af0d23c894d11f9fc982740a2b87fb61bfafe..39419031dee69e066d0536f16780853af576d9e3 100644
--- a/build/source/job_actor/data_assimilation_mode.cpp
+++ b/build/source/job_actor/data_assimilation_mode.cpp
@@ -1,6 +1,7 @@
 #include "job_actor.hpp"
 
-namespace caf {
+using namespace caf;
+
 behavior data_assimilation_mode(stateful_actor<job_state>* self) {
   aout(self) << "Data Assimilation Mode: Started\n";
 
@@ -21,7 +22,7 @@ behavior data_assimilation_mode(stateful_actor<job_state>* self) {
       self->state.stepsInCurrentFFile = num_steps_in_iFile;
       self->state.forcingStep = 1;
       for(auto gru : self->state.gru_container.gru_list) {
-        self->send(gru->getGRUActor(), update_timeZoneOffset_v, 
+        self->send(gru->getActorRef(), update_timeZoneOffset_v, 
             self->state.iFile);
       }
 
@@ -30,7 +31,7 @@ behavior data_assimilation_mode(stateful_actor<job_state>* self) {
 
     [=](update_hru){
       for(auto gru : self->state.gru_container.gru_list) {
-        self->send(gru->getGRUActor(), update_hru_v, self->state.timestep, 
+        self->send(gru->getActorRef(), update_hru_v, self->state.timestep, 
             self->state.forcingStep);
       }      
     },
@@ -52,7 +53,7 @@ behavior data_assimilation_mode(stateful_actor<job_state>* self) {
             if (err != 0) {
               aout(self) << "Job_Actor: Error Writing Output\n";
               for (auto GRU : self->state.gru_container.gru_list)
-                self->send(GRU->getGRUActor(), exit_msg_v);
+                self->send(GRU->getActorRef(), exit_msg_v);
               
               self->send_exit(self->state.file_access_actor, 
                               exit_reason::user_shutdown);
@@ -67,7 +68,7 @@ behavior data_assimilation_mode(stateful_actor<job_state>* self) {
         if (self->state.timestep > self->state.num_steps) {
           aout(self) << "Job_Actor: Done Job\n";
           for (auto GRU : self->state.gru_container.gru_list) {
-            self->send_exit(GRU->getGRUActor(), exit_reason::user_shutdown);
+            self->send_exit(GRU->getActorRef(), exit_reason::user_shutdown);
             GRU->setSuccess();
           }
           self->send(self, finalize_v);
@@ -98,5 +99,4 @@ behavior data_assimilation_mode(stateful_actor<job_state>* self) {
   
 
   };
-}
-} // End of Namespace caf
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/build/source/job_actor/distributed_job_actor.cpp b/build/source/job_actor/distributed_job_actor.cpp
index fe760a4361503c0f4c55709a00c656903205f513..8309eb66dfca02c280f34c7e00e766a76d34932e 100644
--- a/build/source/job_actor/distributed_job_actor.cpp
+++ b/build/source/job_actor/distributed_job_actor.cpp
@@ -3,7 +3,9 @@
 #include "node_actor.hpp"
 #include <fstream>
 #include <iostream>
-namespace caf {
+
+
+using namespace caf;
 
 behavior distributed_job_actor(stateful_actor<distributed_job_state>* self,
     int start_gru_global, int num_gru_global, 
@@ -413,5 +415,3 @@ behavior distributed_job_actor(stateful_actor<distributed_job_state>* self,
 }
 
 
-
-} // namespace caf
\ No newline at end of file
diff --git a/build/source/job_actor/gru_struc.cpp b/build/source/job_actor/gru_struc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78ef42eddf4e2a1ccf52627db6b7f55ffc15e335
--- /dev/null
+++ b/build/source/job_actor/gru_struc.cpp
@@ -0,0 +1,37 @@
+#include "gru_struc.hpp"
+#include <iostream>
+#include <memory>
+
+GruStruc::GruStruc(int start_gru, int num_gru, int num_retry_attempts) {
+  start_gru_ = start_gru;
+  num_gru_ = num_gru;
+  num_retry_attempts_left_ = num_retry_attempts;
+  gru_info_.resize(num_gru);
+}
+
+int GruStruc::ReadDimension() {
+  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,
+                         err, &err_msg);
+  if (err != 0) { 
+    std::cout << "ERROR: GruStruc - ReadDimension\n";
+  }
+  num_hru_ = num_hru;
+  file_gru_ = file_gru;
+  file_hru_ = file_hru;
+  return err;
+}
+
+int GruStruc::ReadIcondNlayers() {
+  int err = 0;
+  std::unique_ptr<char[]> err_msg(new char[256]);
+  read_icond_nlayers_fortran(num_gru_, err, &err_msg);
+  if (err != 0) { 
+    std::cout << "ERROR: GruStruc - ReadIcondNlayers\n";
+  }
+  return 0;
+}
+
+
+
diff --git a/build/source/job_actor/gru_struc.f90 b/build/source/job_actor/gru_struc.f90
new file mode 100644
index 0000000000000000000000000000000000000000..884373935390b2af3c0106f0b20e06c32779c139
--- /dev/null
+++ b/build/source/job_actor/gru_struc.f90
@@ -0,0 +1,101 @@
+module gru_struc_module
+  USE, intrinsic :: iso_c_binding
+  USE globalData,only:integerMissing
+  implicit none
+
+  public::read_dimension_fortran
+  public::read_icond_nlayers_fortran
+  public::deallocate_gru_struc_fortran
+  contains
+
+subroutine read_dimension_fortran(start_gru, num_gru, num_hru, file_gru, &
+                                  file_hru, err, message_r) &
+    bind(C, name="read_dimension_fortran")
+  USE globalData,only:startGRU                               ! index of the GRU for a single GRU run
+  USE globalData,only:checkHRU                               ! index of the HRU for a single HRU run
+  USE globalData,only:iRunMode                               ! define the current running mode    
+  USE globalData,only:iRunModeFull, iRunModeGRU, iRunModeHRU ! define the running modes
+  
+  USE summaFileManager,only:SETTINGS_PATH, LOCAL_ATTRIBUTES
+  USE read_attrb_module,only:read_dimension
+  
+  USE C_interface_module,only:f_c_string_ptr
+  implicit none
+  ! Dummy Variables
+  integer(c_int), intent(in)      :: start_gru
+  integer(c_int), intent(inout)   :: num_gru
+  integer(c_int), intent(inout)   :: num_hru
+  integer(c_int), intent(out)     :: file_gru
+  integer(c_int), intent(out)     :: file_hru
+  integer(c_int), intent(out)     :: err
+  type(c_ptr),    intent(out)     :: message_r
+  ! Local Variables
+  character(len=256)              :: attrFile           ! attributes file name
+  character(len=256)              :: message
+  
+  err = 0
+  message = ""
+  call f_c_string_ptr(trim(message), message_r)
+
+  ! Set variables that were previosuly set by getCommandArguments()
+  startGRU=start_gru
+  iRunMode=iRunModeGRU
+  checkHRU=integerMissing
+
+  attrFile = trim(SETTINGS_PATH)//trim(LOCAL_ATTRIBUTES)
+  if (iRunMode == iRunModeGRU) then
+    call read_dimension(trim(attrFile),file_gru,file_hru,num_gru,num_hru,err,&
+                        message,startGRU=start_gru)
+  else
+    err = 20
+    message = "Error: iRunMode is not set to iRunModeGRU - other modes not supported yet."
+  end if
+  if (err /= 0) then; call f_c_string_ptr(trim(message), message_r); end if
+end subroutine read_dimension_fortran
+
+subroutine read_icond_nlayers_fortran(num_gru, err, message_r)& 
+    bind(C, name="read_icond_nlayers_fortran")
+  USE globalData,only:indx_meta                     ! metadata structures
+  
+  USE summaFileManager,only:SETTINGS_PATH,STATE_PATH,MODEL_INITCOND                    
+  USE read_icond_module,only:read_icond_nlayers               ! module to read initial condition dimensions
+  USE C_interface_module,only:f_c_string_ptr
+  implicit none
+  ! Dummy Variables
+  integer(c_int), intent(in)      :: num_gru
+  integer(c_int), intent(out)     :: err
+  type(c_ptr),    intent(out)     :: message_r
+  ! Local Variables
+  character(len=256)              :: restartFile        ! restart file name
+  character(len=256)              :: message
+
+  err = 0
+  message = ""
+  call f_c_string_ptr(trim(message), message_r)
+
+  ! *****************************************************************************
+  ! *** read the number of snow and soil layers
+  ! *****************************************************************************
+  ! set restart filename and read the number of snow and soil layers from the initial conditions (restart) file
+  if(STATE_PATH == '') then
+    restartFile = trim(SETTINGS_PATH)//trim(MODEL_INITCOND)
+  else
+    restartFile = trim(STATE_PATH)//trim(MODEL_INITCOND)
+  endif
+  call read_icond_nlayers(trim(restartFile),num_gru,indx_meta,err,message)
+  if(err/=0)then; call f_c_string_ptr(trim(message), message_r); endif
+
+end subroutine read_icond_nlayers_fortran
+
+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
+    implicit none
+    if(allocated(gru_struc))then; deallocate(gru_struc);endif
+    if(allocated(index_map))then; deallocate(index_map);endif
+end subroutine
+
+
+
+
+end module gru_struc_module
\ No newline at end of file
diff --git a/build/source/job_actor/job_actor.cpp b/build/source/job_actor/job_actor.cpp
index eedd1b1c944ef8d0fe3547f507c1f4610a3d272f..41fabc6eb5fd98ddcbe7bd62944aa3c80fdb9938 100644
--- a/build/source/job_actor/job_actor.cpp
+++ b/build/source/job_actor/job_actor.cpp
@@ -2,15 +2,13 @@
 
 using json = nlohmann::json;
 using chrono_time = std::chrono::time_point<std::chrono::system_clock>;
-
-namespace caf {
+using namespace caf;
 
 // First Actor that is spawned that is not the Coordinator Actor.
-behavior job_actor(stateful_actor<job_state>* self, 
-    int start_gru, int num_gru, 
-    File_Access_Actor_Settings file_access_actor_settings, 
-    Job_Actor_Settings job_actor_settings, 
-    HRU_Actor_Settings hru_actor_settings, caf::actor parent) {
+behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru, 
+                   File_Access_Actor_Settings file_access_actor_settings, 
+                   Job_Actor_Settings job_actor_settings, 
+                   HRU_Actor_Settings hru_actor_settings, caf::actor parent) {
     
   self->set_down_handler([=](const down_msg& dm) {
       aout(self) << "\n\n ********** DOWN HANDLER ********** \n"
@@ -18,7 +16,7 @@ behavior job_actor(stateful_actor<job_state>* self,
                  << "Reason: " << to_string(dm.reason) << "\n";
   });
 
-  self->set_exit_handler([=](const exit_msg& em) {
+  self->set_exit_handler([=](const caf::exit_msg& em) {
       aout(self) << "\n\n ********** EXIT HANDLER ********** \n"
                  << "Exit Reason: " << to_string(em.reason) << "\n";
   });
@@ -27,6 +25,8 @@ behavior job_actor(stateful_actor<job_state>* self,
   self->state.job_timing = TimingInfo(); 
   self->state.job_timing.addTimePoint("total_duration");
   self->state.job_timing.updateStartPoint("total_duration");
+  self->state.job_timing.addTimePoint("init_duration");
+  self->state.job_timing.updateStartPoint("init_duration");
   // Set Job Variables
   self->state.start_gru = start_gru;
   self->state.num_gru = num_gru;
@@ -42,31 +42,33 @@ behavior job_actor(stateful_actor<job_state>* self,
   char host[HOST_NAME_MAX];
   gethostname(host, HOST_NAME_MAX);
   self->state.hostname = host;
-  
-  /* Calls: summa_SetTimesDirsAndFiles(), summa_defineGlobalData(),
-         read_icond_nlayers(), Allocates time structures */
-  self->state.job_timing.addTimePoint("init_duration");
-  int file_gru = 0;
-  int err = 0;
-  job_init_fortran(self->state.job_actor_settings.file_manager_path.c_str(),
-      &self->state.start_gru, &self->state.num_gru, &self->state.num_hru, 
-      &file_gru, &err);
-  if (err != 0) { 
-    aout(self) << "\nERROR: Job_Actor - job_init_fortran\n"; 
+
+  auto& gru_struc = self->state.gru_struc;
+  gru_struc = std::make_unique<GruStruc>(self->state.start_gru, 
+                                         self->state.num_gru,
+                                         job_actor_settings.max_run_attempts);
+  if (gru_struc->ReadDimension()) {
+    aout(self) << "ERROR: Job_Actor - ReadDimension\n";
+    return {};
+  }
+  if (gru_struc->ReadIcondNlayers()) {
+    aout(self) << "ERROR: Job_Actor - ReadIcondNlayers\n";
     return {};
   }
 
   self->state.num_gru_info = NumGRUInfo(self->state.start_gru, 
-      self->state.start_gru, self->state.num_gru, self->state.num_gru, 
-      file_gru, false);
-
-  // Spawn File Access Actor and await confirmation it is ready
-  self->state.file_access_actor = self->spawn(file_access_actor, 
-      self->state.num_gru_info, self->state.file_access_actor_settings, self);
-  // self->send(self->state.file_access_actor, def_output_v, file_gru);
+                                        self->state.start_gru, 
+                                        self->state.num_gru, 
+                                        self->state.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->request(self->state.file_access_actor, caf::infinite, 
-      init_file_access_actor_v, file_gru).await(
-        [=](int num_timesteps){
+                init_file_access_actor_v, gru_struc->get_file_gru())
+      .await([=](int num_timesteps){
     
     if (num_timesteps < 0) {
       aout(self) << "ERROR: Job_Actor: File Access Actor Not Ready\n"
@@ -132,16 +134,12 @@ behavior job_actor(stateful_actor<job_state>* self,
         if(GRU->isFailed()) {
           GRU->setRunning();
           GRU->decrementAttemptsLeft();
-          auto global_gru_index = GRU->getGlobalGRUIndex();
-          auto local_gru_index = GRU->getLocalGRUIndex();
-          auto gru_actor = self->spawn(hru_actor, 
-                                        global_gru_index, 
-                                        local_gru_index, 
-                                        self->state.hru_actor_settings,
-                                        self->state.file_access_actor, 
-                                        self);
-          self->state.gru_container.gru_list[local_gru_index-1]->
-              setGRUActor(gru_actor);
+          auto gru_actor = self->spawn(hru_actor, GRU->getIndexNetcdf(), 
+                                       GRU->getIndexJob(),
+                                       self->state.hru_actor_settings,
+                                       self->state.file_access_actor, self);
+          self->state.gru_container.gru_list[GRU->getIndexJob()-1]->
+              setActorRef(gru_actor);
         }
       }
     },
@@ -153,33 +151,33 @@ behavior job_actor(stateful_actor<job_state>* self,
       handleGRUError(self, src);
     },
 
-    [=](const error& err, caf::actor src) {
+    // [=](const error& err, caf::actor src) {
       
-      aout(self) << "\n\n ********** ERROR HANDLER \n";
+    //   aout(self) << "\n\n ********** ERROR HANDLER \n";
       
-      switch(err.category()) {
+    //   switch(err.category()) {
         
-        case type_id_v<hru_error>:
-          aout(self) << "HRU Error: " << to_string(err) << "\n";
-          handleGRUError(self, src);
-
-          break;
-        case type_id_v<file_access_error>:
-          if (err == file_access_error::mDecisions_error) {
-            aout(self) << "Check mDecisions File For Correctness";
-          } else {
-            aout(self) << "File Access Error: " << to_string(err) << "No Handling Implemented\n";
-          }
-          for (auto GRU : self->state.gru_container.gru_list) {
-            self->send_exit(GRU->getGRUActor(), exit_reason::user_shutdown);
-          }
-          self->quit();
-          break;
-        default:
-          aout(self) << "Unknown Error: " << to_string(err) << "\n";
-          break;
-      }
-    },
+    //     case type_id_v<hru_error>:
+    //       aout(self) << "HRU Error: " << to_string(err) << "\n";
+    //       handleGRUError(self, src);
+
+    //       break;
+    //     case type_id_v<file_access_error>:
+    //       if (err == file_access_error::mDecisions_error) {
+    //         aout(self) << "Check mDecisions File For Correctness";
+    //       } else {
+    //         aout(self) << "File Access Error: " << to_string(err) << "No Handling Implemented\n";
+    //       }
+    //       for (auto GRU : self->state.gru_container.gru_list) {
+    //         self->send_exit(GRU->getGRUActor(), exit_reason::user_shutdown);
+    //       }
+    //       self->quit();
+    //       break;
+    //     default:
+    //       aout(self) << "Unknown Error: " << to_string(err) << "\n";
+    //       break;
+    //   }
+    // },
   };
 }
 
@@ -188,38 +186,11 @@ behavior job_actor(stateful_actor<job_state>* self,
 
 
 
-
-std::vector<serializable_netcdf_gru_actor_info> getGruNetcdfInfo(
-    int max_run_attempts, std::vector<GRU*> &gru_list) {
-  std::vector<serializable_netcdf_gru_actor_info> gru_netcdf_info;
-  
-  for(auto gru : gru_list) {
-    serializable_netcdf_gru_actor_info gru_info;
-    gru_info.run_time = gru->getRunTime();
-    gru_info.init_duration = gru->getInitDuration();
-    gru_info.forcing_duration = gru->getForcingDuration();
-    gru_info.run_physics_duration = gru->getRunPhysicsDuration();
-    gru_info.write_output_duration = gru->getWriteOutputDuration();
-    
-    gru_info.num_attempts = max_run_attempts - gru->getAttemptsLeft() + 1;
-    gru_info.successful = is_success(gru->getStatus());
-    gru_info.rel_tol = gru->getRelTol();
-    gru_info.abs_tol = gru->getAbsTol();
-
-    gru_netcdf_info.push_back(gru_info);
-  }
-  
-  return gru_netcdf_info;
-}
-
-
-
-
 void handleGRUError(stateful_actor<job_state>* self, caf::actor src) {
   auto it = std::find_if(self->state.gru_container.gru_list.begin(), 
                           self->state.gru_container.gru_list.end(),
                           [src](auto& gru) {
-                          return gru->getGRUActor() == src;
+                          return gru->getActorRef() == src;
                         });
 
   if (it != self->state.gru_container.gru_list.end()) {
@@ -228,7 +199,7 @@ void handleGRUError(stateful_actor<job_state>* self, caf::actor src) {
 
     self->state.gru_container.num_gru_done++;
     self->state.gru_container.num_gru_failed++;
-    self->send(self->state.file_access_actor, run_failure_v, (*it)->getLocalGRUIndex());
+    self->send(self->state.file_access_actor, run_failure_v, (*it)->getIndexJob());
   } else {
     aout(self) << "ERROR: Job_Actor: Could not find GRU in GRU_Container\n";
   }
@@ -245,6 +216,5 @@ void handleGRUError(stateful_actor<job_state>* self, caf::actor src) {
 
 }
 
-} // End Namespace caf
 
 
diff --git a/build/source/job_actor/job_actor.f90 b/build/source/job_actor/job_actor.f90
deleted file mode 100644
index 321971c312c83b9748235b885eff598dd609e0e5..0000000000000000000000000000000000000000
--- a/build/source/job_actor/job_actor.f90
+++ /dev/null
@@ -1,132 +0,0 @@
-module job_actor
-  USE, intrinsic :: iso_c_binding
-  
-  ! global data
-  USE globalData,only:integerMissing      ! missing integer value
-  USE globalData,only:realMissing         ! missing double precision value
-    
-    
-  implicit none
-  public::job_init_fortran
-  public::deallocateJobActor
-
-    contains
-
-subroutine job_init_fortran(file_manager, start_gru, num_gru,&
-                            num_hru, file_gru, err) bind(C, name="job_init_fortran")
-  USE nrtype  ! variable types, etc.
-  
-  USE summaFileManager,only:summa_SetTimesDirsAndFiles       ! sets directories and filenames
-  USE summa_globalData,only:summa_defineGlobalData           ! used to define global summa data structures
-  
-  USE cppwrap_auxiliary,only:c_f_string           ! Convert C String to Fortran String
-  
-  ! provide access to file paths
-  USE summaFileManager,only:SETTINGS_PATH                     ! define path to settings files (e.g., parameters, soil and veg. tables)
-  USE summaFileManager,only:STATE_PATH                        ! optional path to state/init. condition files (defaults to SETTINGS_PATH)
-  USE summaFileManager,only:MODEL_INITCOND                    ! name of model initial conditions file
-  USE summaFileManager,only:LOCAL_ATTRIBUTES                  ! name of model initial attributes file
-  
-  ! subroutines and functions: read dimensions (NOTE: NetCDF)
-  USE read_attrb_module,only:read_dimension              ! module to read dimensions of GRU and HRU
-  USE read_icond_module,only:read_icond_nlayers               ! module to read initial condition dimensions
-
-  USE globalData,only:indx_meta                     ! metadata structures
-  USE globalData,only:startTime,finshTime,refTime,oldTime
-  USE allocspace_module,only:allocLocal
-  USE globalData,only:time_meta
-
-  ! Variables that were set by getCommandArguments()
-  USE globalData,only: startGRU          ! index of the starting GRU for parallelization run
-  USE globalData,only: checkHRU          ! index of the HRU for a single HRU run
-  USE globalData,only: iRunMode          ! define the current running mode    
-  USE globalData,only:iRunModeFull, iRunModeGRU, iRunModeHRU  ! define the running modes
-  USE globalData,only:output_fileSuffix                       ! suffix for the output file
-  
-  implicit none
-
-  ! dummy variables
-  character(kind=c_char,len=1),intent(in)   :: file_manager
-  integer(c_int),intent(inout)              :: start_gru
-  integer(c_int),intent(inout)              :: num_gru
-  integer(c_int),intent(inout)              :: num_hru
-  integer(c_int),intent(out)                :: file_gru
-  integer(c_int),intent(out)                :: err
-
-  ! local variables
-  character(len=256)                        :: summaFileManagerIn
-  character(len=256)                        :: restartFile        ! restart file name
-  character(len=256)                        :: attrFile           ! attributes file name
-  integer(i4b)                              :: fileHRU            ! [used for filenames] number of HRUs in the input file
-  character(len=128)                        :: fmtGruOutput       ! a format string used to write start and end GRU in output file names
-
-  
-  character(len=256)                        :: message
-
-  ! Convert C Variables to Fortran Variables
-  call c_f_string(file_manager, summaFileManagerIn, 256)
-  summaFileManagerIn = trim(summaFileManagerIn)
-
-
-  ! Set variables that were previosuly set by getCommandArguments()
-  startGRU=start_gru
-  iRunMode=iRunModeGRU
-  checkHRU=integerMissing
-  
-  ! *****************************************************************************
-  ! *** read the number of GRUs and HRUs
-  ! *****************************************************************************
-  ! obtain the HRU and GRU dimensions in the LocalAttribute file
-  attrFile = trim(SETTINGS_PATH)//trim(LOCAL_ATTRIBUTES)
-  select case (iRunMode)
-    case(iRunModeFull); err=20; message='iRunModeFull not implemented for Actors Code'
-    case(iRunModeGRU ); call read_dimension(trim(attrFile),file_gru,fileHRU,num_gru,num_hru,err,message,startGRU=start_gru)
-    case(iRunModeHRU ); err=20; message='iRunModeHRU not implemented for Actors Code'
-  end select
-  if(err/=0)then; print*, trim(message); return; endif
-
-  ! *****************************************************************************
-  ! *** read the number of snow and soil layers
-  ! *****************************************************************************
-  ! set restart filename and read the number of snow and soil layers from the initial conditions (restart) file
-  if(STATE_PATH == '') then
-    restartFile = trim(SETTINGS_PATH)//trim(MODEL_INITCOND)
-  else
-    restartFile = trim(STATE_PATH)//trim(MODEL_INITCOND)
-  endif
-  call read_icond_nlayers(trim(restartFile),num_gru,indx_meta,err,message)
-  if(err/=0)then; print*, trim(message); return; endif
-
-
-  ! Allocate the time structures
-  call allocLocal(time_meta, startTime, err=err, message=message)
-  call allocLocal(time_meta, finshTime, err=err, message=message)
-  call allocLocal(time_meta, refTime,   err=err, message=message)
-  call allocLocal(time_meta, oldTime,   err=err, message=message)
-  if(err/=0)then; print*, trim(message); return; endif
-
-end subroutine job_init_fortran
-
-
-subroutine deallocateJobActor(err) bind(C, name="deallocateJobActor")
-    USE globalData,only:gru_struc                               ! gru->hru mapping structure
-    USE globalData,only:index_map
-    USE globalData,only:startTime,finshTime,refTime,oldTime
-  
-    implicit none
-    integer(c_int), intent(out)     :: err
-    err=0
-  
-    ! Deallocate Time Varaibles
-    deallocate(startTime%var);
-    deallocate(finshTime%var);
-    deallocate(refTime%var);
-    deallocate(oldTime%var);
-  
-    if(allocated(gru_struc))then; deallocate(gru_struc);endif
-    if(allocated(index_map))then; deallocate(index_map);endif
-end subroutine
-
-
-
-end module
\ No newline at end of file
diff --git a/build/source/job_actor/job_utils.cpp b/build/source/job_actor/job_utils.cpp
index ada32377151afdc4d7afc78a496b87da33eef558..2d81798fa9d25d67d4efb10e719f40b23e1a7f97 100644
--- a/build/source/job_actor/job_utils.cpp
+++ b/build/source/job_actor/job_utils.cpp
@@ -1,30 +1,25 @@
 #include "job_actor.hpp"
 
-namespace caf {
+using namespace caf;
 
 void spawnHRUActors(stateful_actor<job_state>* self) {
-  auto& gru_container = self->state.gru_container;
-  gru_container.gru_start_time = std::chrono::high_resolution_clock::now();
-  gru_container.run_attempts_left = self->state.max_run_attempts;
-  gru_container.run_attempts_left--;
-
-  for (int i = 0; i < gru_container.num_gru_in_run_domain; i++) {
-    auto global_gru_index = gru_container.gru_list.size() + 
-        self->state.start_gru;
-    auto local_gru_index = gru_container.gru_list.size() + 1;                                
-
-    auto gru = self->spawn(hru_actor, global_gru_index, local_gru_index,               
-        self->state.hru_actor_settings, self->state.file_access_actor, self);
-
-    // Create the GRU object (Job uses this to keep track of GRU status)
-    gru_container.gru_list.push_back(new GRU(global_gru_index, 
-        local_gru_index, gru, self->state.dt_init_start_factor, 
-        self->state.hru_actor_settings.rel_tol,
-        self->state.hru_actor_settings.abs_tol, self->state.max_run_attempts));  
-    
-    // if (normal_mode) self->send(gru, update_hru_async_v);
-  }                        
-          
+  auto& gru_struc = self->state.gru_struc;
+  for (int i = 0; i < gru_struc->getNumGrus(); i++) {
+    auto netcdf_index = gru_struc->getStartGru() + i;
+    auto job_index = i + 1;
+    // 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, 
+        self->state.hru_actor_settings.rel_tol, 
+        self->state.hru_actor_settings.abs_tol, self->state.max_run_attempts);
+    gru_struc->addGRU(std::move(gru_obj));
+  }    
 }
 
 void spawnHRUBatches(stateful_actor<job_state>* self) {
@@ -76,21 +71,9 @@ void spawnHRUBatches(stateful_actor<job_state>* self) {
 
 
 void finalizeJob(stateful_actor<job_state>* self) {
-  std::vector<serializable_netcdf_gru_actor_info> netcdf_gru_info = 
-      getGruNetcdfInfo(
-          self->state.max_run_attempts,self->state.gru_container.gru_list);
-  
-  self->state.num_gru_failed = std::count_if(netcdf_gru_info.begin(), 
-      netcdf_gru_info.end(), [](auto& gru_info) {
-    return !gru_info.successful;
-  });
-
   self->request(self->state.file_access_actor, infinite, finalize_v).await(
     [=](std::tuple<double, double> read_write_duration) {
       int err = 0;
-      for (auto GRU : self->state.gru_container.gru_list) 
-        delete GRU;
-      self->state.gru_container.gru_list.clear();
       self->state.job_timing.updateEndPoint("total_duration");
       aout(self) << "\n________________" 
                   << "PRINTING JOB_ACTOR TIMING INFO RESULTS"
@@ -109,45 +92,29 @@ void finalizeJob(stateful_actor<job_state>* self) {
                       .value_or(-1.0) << " Seconds\n"
                   << "_________________________________" 
                   << "_______________________________________\n\n";
-      
-      deallocateJobActor(&err);
-      
+            
       // Tell Parent we are done
+      auto total_duration = self->state.job_timing.getDuration("total_duration")
+          .value_or(-1.0);
       self->send(self->state.parent, done_job_v, self->state.num_gru_failed, 
-          self->state.job_timing.getDuration("total_duration").value_or(-1.0),
-          std::get<0>(read_write_duration), 
-          std::get<1>(read_write_duration));
+                 total_duration, std::get<0>(read_write_duration), 
+                 std::get<1>(read_write_duration));
       self->quit();
     });
 }
 
-void handleFinishedGRU(stateful_actor<job_state>* self, int local_gru_index) {
-  using namespace std::chrono;
-  auto& gru_container = self->state.gru_container;
-  chrono_time end_point = high_resolution_clock::now();
-  double total_duration = duration_cast<seconds>(end_point - 
-      gru_container.gru_start_time).count();
-  gru_container.num_gru_done++;
-
-  aout(self) << "GRU Finished: " << gru_container.num_gru_done << "/" 
-             << gru_container.num_gru_in_run_domain << " -- GlobalGRU=" 
-             << gru_container.gru_list[local_gru_index-1]->getGlobalGRUIndex()
-             << " -- LocalGRU=" << local_gru_index << "\n";
-
-  gru_container.gru_list[local_gru_index-1]->setRunTime(total_duration);
-  gru_container.gru_list[local_gru_index-1]->setInitDuration(-1);
-  gru_container.gru_list[local_gru_index-1]->setForcingDuration(-1);
-  gru_container.gru_list[local_gru_index-1]->setRunPhysicsDuration(-1);
-  gru_container.gru_list[local_gru_index-1]->setWriteOutputDuration(-1);
-  gru_container.gru_list[local_gru_index-1]->setSuccess();
-
-
-  // Check if all GRUs are done
-  if (gru_container.num_gru_done >= gru_container.num_gru_in_run_domain) {
-    if(gru_container.num_gru_failed == 0 || self->state.max_run_attempts == 1)
-      self->send(self, finalize_v);
-    else
-      self->send(self, restart_failures_v);
+void handleFinishedGRU(stateful_actor<job_state>* self, int gru_job_index) {
+  auto& gru_struc = self->state.gru_struc;
+  gru_struc->incrementNumGRUDone();
+  gru_struc->getGRU(gru_job_index)->setSuccess();
+  aout(self) << "GRU Finished: " << gru_struc->getNumGrusDone() << "/" 
+             << gru_struc->getNumGrus() << " -- GlobalGRU=" 
+             << gru_struc->getGRU(gru_job_index)->getIndexNetcdf()
+             << " -- LocalGRU=" 
+             << gru_struc->getGRU(gru_job_index)->getIndexJob() << "\n";
+
+  if (gru_struc->isDone()) {
+    gru_struc->hasFailures() && gru_struc->shouldRetry() ? 
+        self->send(self, restart_failures_v) : self->send(self, finalize_v);
   }
-}
-} // End of Namespace caf
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/build/source/job_actor/node_actor.cpp b/build/source/job_actor/node_actor.cpp
index 76d4bca67ca3a4a81cfa404be64ba1f95497585b..b06806c496a7329bb8d595c060ab43a5f5926d85 100644
--- a/build/source/job_actor/node_actor.cpp
+++ b/build/source/job_actor/node_actor.cpp
@@ -75,14 +75,29 @@ behavior node_actor(stateful_actor<node_state>* self, std::string host,
       
       self->state.node_timing.addTimePoint("node_init");
       self->state.node_timing.updateStartPoint("node_init");
-      int err, file_gru_to_remove;
-      job_init_fortran(self->state.job_actor_settings.file_manager_path.c_str(),
-          &start_gru, &num_gru, &num_hru, &file_gru_to_remove, &err);
-      if (err != 0) { 
-        aout(self) << "\nERROR: Job_Actor - job_init_fortran\n"; 
-        self->quit();
+
+
+
+      auto& gru_struc = self->state.gru_struc;
+      gru_struc = std::make_unique<GruStruc>(start_gru, num_gru, 
+                                             job_actor_settings.max_run_attempts);
+      if (gru_struc->ReadDimension()) {
+        aout(self) << "ERROR: Job_Actor - ReadDimension\n";
+        // TODO: Needs to return an error
+        return;
+      }
+      if (gru_struc->ReadIcondNlayers()) {
+        aout(self) << "ERROR: Job_Actor - ReadIcondNlayers\n";
+        // TODO: Needs to return an error
         return;
       }
+      // job_init_fortran(self->state.job_actor_settings.file_manager_path.c_str(),
+      //     &start_gru, &num_gru, &num_hru, &file_gru_to_remove, &err);
+      // if (err != 0) { 
+      //   aout(self) << "\nERROR: Job_Actor - job_init_fortran\n"; 
+      //   self->quit();
+      //   return;
+      // }
       // Spawn the file_access_actor.
       self->state.file_access_actor = self->spawn(file_access_actor, 
           self->state.num_gru_info, self->state.file_access_actor_settings, 
@@ -121,7 +136,7 @@ behavior node_actor(stateful_actor<node_state>* self, std::string host,
       self->state.stepsInCurrentFFile = num_steps_in_iFile;
       self->state.forcingStep = 1;
       for(auto gru : self->state.gru_container.gru_list) {
-        self->send(gru->getGRUActor(), update_timeZoneOffset_v, 
+        self->send(gru->getActorRef(), update_timeZoneOffset_v, 
             self->state.iFile);
       }
       self->send(self->state.current_server, new_forcing_file_v, 
@@ -133,7 +148,7 @@ behavior node_actor(stateful_actor<node_state>* self, std::string host,
       self->state.timestep_start_time 
         = std::chrono::high_resolution_clock::now();
       for (auto gru : self->state.gru_container.gru_list) {
-        self->send(gru->getGRUActor(), update_hru_v, self->state.timestep, 
+        self->send(gru->getActorRef(), update_hru_v, self->state.timestep, 
             self->state.forcingStep);
       }
     },
diff --git a/build/source/system_initialization/batch_distributer_actor.f90 b/build/source/system_initialization/batch_distributer_actor.f90
index cb62ad4d807457a8f4be2f162cef8a3950b92cc5..0572972218d76bbbe0da0cd55be0f13c1248668c 100644
--- a/build/source/system_initialization/batch_distributer_actor.f90
+++ b/build/source/system_initialization/batch_distributer_actor.f90
@@ -24,7 +24,8 @@ subroutine setTimesDirsAndFiles_fortran(summaFileManagerIn_C,err,message_r) &
   ! local variables
   character(len=256)                        :: summaFileManagerIn    
   character(len=256)                        :: message = ""
-  
+
+
   ! Convert strings 
   call f_c_string_ptr(trim(message), message_r);
   call c_f_string_chars(summaFileManagerIn_C, summaFileManagerIn)
diff --git a/build/summa_v3 b/build/summa_v3
new file mode 160000
index 0000000000000000000000000000000000000000..ded4be3e103134ece0ddef3f5be8e3aae2332b5f
--- /dev/null
+++ b/build/summa_v3
@@ -0,0 +1 @@
+Subproject commit ded4be3e103134ece0ddef3f5be8e3aae2332b5f