diff --git a/.gitignore b/.gitignore
index eb0a0acbf1c813b9301e8470090ae970e5ece707..c2dafa7571f4e6f20cd145068d57c9d12d36a500 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ bin/data_kinsol_state_vec.csv
 bin/plot_resuduial.py
 bin/state.png
 bin/submission_script_array.sh
+build/source/testing/containers/output_container/out.txt
diff --git a/bin/caf-application.conf b/bin/caf-application.conf
index 3e1e4479dbe11afb9ba9bf8bd0e7d564b6010a35..6e8ec76d083fee0f72df96fb597ca278de63334e 100644
--- a/bin/caf-application.conf
+++ b/bin/caf-application.conf
@@ -1,3 +1,3 @@
 caf {
-    max-threads = 1
+    # max-threads = 12
 }
\ No newline at end of file
diff --git a/build/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt
index dee87a506c5cd7577de4cede8a2e1442ed83a11a..44f345b142da8c422195d1664c85a450bb5eaac0 100644
--- a/build/cmake/CMakeLists.txt
+++ b/build/cmake/CMakeLists.txt
@@ -52,10 +52,10 @@ message("\nSelected Bulid Type: ${CMAKE_BUILD_TYPE}\n")
 if(CMAKE_BUILD_TYPE MATCHES Debug)
     message("\nSetting Debug Options\n")
     add_definitions(-DDEBUG)
-    set(SUMMA_NOAHMP_OPTIONS -pg -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors)
-    set(SUMMA_ALL_OPTIONS -pg -g -O0 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors)
-    set(CMAKE_CXX_FLAGS "-pg -g -O0 -Wfatal-errors -std=c++17")
-    set(CMAKE_CXX_LINK_FLAGS "-pg -g -O0 -Wfatal-errors -std=c++17")
+    set(SUMMA_NOAHMP_OPTIONS -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors)
+    set(SUMMA_ALL_OPTIONS -g -O0 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors)
+    set(CMAKE_CXX_FLAGS "-g -O0 -Wfatal-errors -std=c++17")
+    set(CMAKE_CXX_LINK_FLAGS "-g -O0 -Wfatal-errors -std=c++17")
 else()
     message("\nSetting Release Options\n")
     set(SUMMA_NOAHMP_OPTIONS -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors)
diff --git a/build/includes/file_access_actor/file_access_actor.hpp b/build/includes/file_access_actor/file_access_actor.hpp
index 7ddd19f8aa096e1a9a3e0aa072a6938537ef73ce..7bffc19830faec90e1566500b9928ade4ac3f969 100644
--- a/build/includes/file_access_actor/file_access_actor.hpp
+++ b/build/includes/file_access_actor/file_access_actor.hpp
@@ -47,9 +47,13 @@ struct file_access_state {
     int err;
     int num_output_steps;
 
+    Output_Container* output_container;
+    // std::vector<int> failed_gru_index_list;
+    
+
     // Output_Container *output_container;
     std::vector<std::shared_ptr<output_partition>> output_partitions;
-
+    std::vector<std::shared_ptr<output_partition>> output_partitions_for_reruns;
 
 
     File_Access_Actor_Settings file_access_actor_settings;
diff --git a/build/includes/file_access_actor/output_container.hpp b/build/includes/file_access_actor/output_container.hpp
index 468eedb22f36ee3dce4bc83a4dd0204d8297e3bf..4f0873ead19c132249758f74f87cecb768673939 100644
--- a/build/includes/file_access_actor/output_container.hpp
+++ b/build/includes/file_access_actor/output_container.hpp
@@ -9,6 +9,102 @@
 
 
 
+
+/*
+ * This class manages a portion of the HRUs in the model.
+ * All HRUs are grouped into partitions/objects of this class.
+ */
+class Output_Partition {
+  private:
+    int start_local_gru_index; // The index of the first GRU in the partition
+    int num_local_grus; // The number of GRUs in the partition
+    int num_timesteps_simulation; // The number of timesteps in the simulation
+    int num_stored_timesteps; // The number of timesteps held within the partition
+
+    std::vector<caf::actor> ready_to_write_list;
+    std::vector<int> failed_gru_index_list; // The list of GRUs that have failed
+  public:
+    Output_Partition(int start_local_gru_index, int num_local_grus, int num_timesteps_simulation, int num_timesteps_buffer);
+    ~Output_Partition();
+
+    // Set the GRU to ready to write
+    void setGRUReadyToWrite(caf::actor gru_actor);
+
+    // Check if all GRUs are ready to write
+    bool isReadyToWrite();
+
+    // Get the max index of the GRUs in the partition
+    int getMaxGRUIndex();
+
+    // Get the number of timesteps stored in the partition
+    int getNumStoredTimesteps();
+
+    // Get the start gru index
+    int getStartGRUIndex();
+
+    // Update the number of timesteps remaining in the simulation
+    void updateTimeSteps();
+
+    // Get the list of GRUs that have written so we can send them the next set of timesteps
+    std::vector<caf::actor> getReadyToWriteList();
+
+    // Reset the list of GRUs that are ready to write
+    void resetReadyToWriteList();
+
+    // Add a GRU index to the list of failed GRUs
+    void addFailedGRUIndex(int local_gru_index);
+
+    std::vector<int> getFailedGRUIndexList();
+
+
+    int getNumActiveGRUs();
+
+    int getNumLocalGRUs();
+
+    int getRemainingTimesteps();
+
+};
+
+
+/*
+ * This class is used to store informaiton about when 
+ * HRUs are ready to write. This class does not store
+ * the data of the HRUs only the information about if 
+ * HRUs are ready to write and which HRUs should be 
+ * written to the output file.
+*/
+class Output_Container {
+  private:
+    int num_partitions; // The number of partitions in the model
+    int num_grus_per_partition; // The average number of GRUs per partition
+    int num_grus; // The number of GRUs in the model
+    int num_timesteps_simulation; // The number of timesteps in the simulation
+    int num_stored_timesteps; // The number of timesteps a partion can hold before needing to write
+
+    bool rerunning_failed_hrus = false;
+    std::vector<Output_Partition*> output_partitions; // This is the main output partition
+    std::vector<int> failed_gru_index_list; // The list of GRUs that have failed
+    // Private Method
+
+
+  public:
+    Output_Container(int num_partitions, int num_grus, int num_timesteps_simulation, int num_timesteps_buffer);
+    ~Output_Container();
+
+    int findPartition(int local_gru_index);
+
+    int getNumPartitions();
+
+    // The output container needs to be restructured when rerunning the failed GRUs.
+    void reconstruct();
+
+    Output_Partition* getOutputPartition(int local_gru_index);
+
+    std::vector<int> getFailedGRUIndexList();
+
+};
+
+
 struct hru_output_handles {
     // Statistic Structures
     void* handle_forc_stat        = new_handle_var_dlength();
diff --git a/build/includes/file_access_actor/partition_actor.hpp b/build/includes/file_access_actor/partition_actor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4385d8e4bcf6ec20783cf22063b4015ffb487bd
--- /dev/null
+++ b/build/includes/file_access_actor/partition_actor.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "caf/all.hpp"
+namespace caf {
+
+/*
+* This struct stores the information about a specific HRU
+*/
+struct hru_output_info {
+    caf::actor hru_actor;
+    int local_hru_index;
+    int local_gru_index;
+    bool ready_to_write;
+};
+
+
+struct partition_actor_state {
+    int start_local_gru_index; // The index of the first GRU in the partition
+    int num_local_grus; // The number of GRUs in the partition
+    int num_timesteps_simulation; // The number of timesteps in the simulation
+    int num_timesteps_buffer; // The number of timesteps this actor can hold before needing to write
+    int num_non_failed_grus = 0; // The number of GRUs that have not failed
+    bool grus_ready_to_write = false; // Whether or not all GRUs in the partition are ready to write
+
+    std::vector<std::unique_ptr<hru_output_info>> gru_list; // The GRU actors and their data
+
+
+};
+
+
+behavior partition_actor(stateful_actor<partition_actor_state>* self, int start_local_gru_index, 
+    int num_local_grus, int num_timesteps_simulation, int num_timesteps_buffer);
+
+
+}
\ No newline at end of file
diff --git a/build/includes/global/settings_functions.hpp b/build/includes/global/settings_functions.hpp
index 2c3720861806168319373a032d5447b62e6d98aa..706b7cfb383972b7b1931bf25877030a667b7e9e 100644
--- a/build/includes/global/settings_functions.hpp
+++ b/build/includes/global/settings_functions.hpp
@@ -83,12 +83,14 @@ File_Access_Actor_Settings readFileAccessActorSettings(std::string json_settings
 
 struct Job_Actor_Settings {
     std::string file_manager_path;
+    int max_run_attempts; // maximum number of times to attempt to run each HRU in a job
 };
 
 template<class Inspector>
 bool inspect(Inspector& inspector, Job_Actor_Settings& job_actor_settings) {
     return inspector.object(job_actor_settings).fields(
-                inspector.field("file_manager_path", job_actor_settings.file_manager_path));
+                inspector.field("file_manager_path", job_actor_settings.file_manager_path),
+                inspector.field("max_run_attempts",  job_actor_settings.max_run_attempts));
 }
 
 Job_Actor_Settings readJobActorSettings(std::string json_settings_file);
@@ -100,13 +102,15 @@ Job_Actor_Settings readJobActorSettings(std::string json_settings_file);
 struct HRU_Actor_Settings {
     bool print_output;
     int output_frequency;
+    int dt_init_factor; // factor to multiply the initial timestep by
 };
 
 template<class Inspector>
 bool inspect(Inspector& inspector, HRU_Actor_Settings& hru_actor_settings) {
     return inspector.object(hru_actor_settings).fields(
                 inspector.field("print_output",     hru_actor_settings.print_output),
-                inspector.field("output_frequency", hru_actor_settings.output_frequency));
+                inspector.field("output_frequency", hru_actor_settings.output_frequency),
+                inspector.field("dt_init_factor",   hru_actor_settings.dt_init_factor));
 }
 
 HRU_Actor_Settings readHRUActorSettings(std::string json_settings_file);
diff --git a/build/includes/job_actor/GRU.hpp b/build/includes/job_actor/GRU.hpp
index 6f6589e458d194d32573627b9d613eec6615d7ef..8123f21d9627e4f52a6fd6947e72940f8541b96d 100644
--- a/build/includes/job_actor/GRU.hpp
+++ b/build/includes/job_actor/GRU.hpp
@@ -63,6 +63,8 @@ class GRU {
     double getAttemptsLeft();
     gru_state getStatus();
 
+    bool isFailed();
+
 
     // Setters
     void setRunTime(double run_time);
@@ -73,7 +75,10 @@ class GRU {
 
     void setSuccess();
     void setFailed();
+    void setRunning();
 
     void decrementAttemptsLeft();
 
+    void setGRUActor(caf::actor gru_actor);
+
 };
diff --git a/build/includes/job_actor/job_actor.hpp b/build/includes/job_actor/job_actor.hpp
index 1bb27143d71d87eebf10e0a7d98c07e89b1e7dca..e92a7a1f15ab3601090057a106436b2654255177 100644
--- a/build/includes/job_actor/job_actor.hpp
+++ b/build/includes/job_actor/job_actor.hpp
@@ -17,6 +17,7 @@ struct GRU_Container {
     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
 };
 
 struct job_state {
@@ -46,11 +47,6 @@ struct job_state {
     
     std::string hostname;
 
-    // Output File Names for Timings
-    std::string success_output_file;
-    std::string failed_output_file = "failedHRU";
-    std::string file_access_actor_stats = "fileAccessActor.csv";
-
     // settings for all child actors (save in case we need to recover)
     File_Access_Actor_Settings file_access_actor_settings;
     Job_Actor_Settings job_actor_settings; 
diff --git a/build/source/actors/file_access_actor/cpp_code/file_access_actor.cpp b/build/source/actors/file_access_actor/cpp_code/file_access_actor.cpp
index f09d17df34289b7476e1853f4f75d1408c23296f..c9c5deecc52df644f8f76b55932aa641c17de09d 100644
--- a/build/source/actors/file_access_actor/cpp_code/file_access_actor.cpp
+++ b/build/source/actors/file_access_actor/cpp_code/file_access_actor.cpp
@@ -33,17 +33,12 @@ behavior file_access_actor(stateful_actor<file_access_state>* self, int start_gr
         
     initalizeFileAccessActor(self);
 
-    if (self->state.file_access_actor_settings.num_partitions_in_output_buffer > num_gru) {
-        // Prevents a division with a remainder
-        self->state.file_access_actor_settings.num_partitions_in_output_buffer = num_gru;
-    }
-
-    // Setup output container
-    initArrayOfOuputPartitions(self->state.output_partitions,
+    // Set up the output container
+    self->state.output_container = new Output_Container(
         self->state.file_access_actor_settings.num_partitions_in_output_buffer,
         self->state.num_gru,
         self->state.file_access_actor_settings.num_timesteps_in_output_buffer,
-        self->state.num_steps);
+        self->state.num_steps); 
 
     return {
         [=](write_param, int index_gru, int index_hru, std::vector<double> attr_struct, 
@@ -160,45 +155,69 @@ behavior file_access_actor(stateful_actor<file_access_state>* self, int start_gr
 
         [=](write_output, int index_gru, int index_hru, caf::actor hru_actor) {
             self->state.file_access_timing.updateStartPoint("write_duration");
-            // We need to handle the partitioning of the output data
-            std::optional<int> partition_index = addReadyToWriteHRU(self->state.output_partitions, hru_actor, index_gru, index_hru);
-            if (partition_index.has_value()) {
-                // We have a partition that is ready to write
-                int max_gru = self->state.output_partitions[partition_index.value()]->start_gru + self->state.output_partitions[partition_index.value()]->num_gru -1;
-                writeOutput(self->state.handle_ncid, &self->state.output_partitions[partition_index.value()]->num_timesteps,
-                    &self->state.output_partitions[partition_index.value()]->start_gru, &max_gru, &self->state.err);
+
+            Output_Partition *output_partition = self->state.output_container->getOutputPartition(index_gru);
+
+            output_partition->setGRUReadyToWrite(hru_actor);
+        
+    
+            if (output_partition->isReadyToWrite()) {
+                int num_timesteps_to_write = output_partition->getNumStoredTimesteps();
+                int start_gru = output_partition->getStartGRUIndex();
+                int max_gru = output_partition->getMaxGRUIndex();
                 
-                updateSimulationTimestepsRemaining(self->state.output_partitions[partition_index.value()]);
-                updateNumTimeForPartition(self->state.output_partitions[partition_index.value()]);                 
-                resetReadyToWrite(self->state.output_partitions[partition_index.value()]);
-                for (auto hru_output_info : self->state.output_partitions[partition_index.value()]->hru_info_and_data) {
-                    self->send(hru_output_info->hru_actor, num_steps_before_write_v, self->state.output_partitions[partition_index.value()]->num_timesteps);
-                    self->send(hru_output_info->hru_actor, run_hru_v);
+                writeOutput(self->state.handle_ncid, &num_timesteps_to_write,
+                    &start_gru, &max_gru, &self->state.err);
+                
+                output_partition->updateTimeSteps();
+
+                int num_steps_before_next_write = output_partition->getNumStoredTimesteps();
+
+                std::vector<caf::actor> hrus_to_update = output_partition->getReadyToWriteList();
+                
+                for (int i = 0; i < hrus_to_update.size(); i++) {
+                    self->send(hrus_to_update[i], num_steps_before_write_v, num_steps_before_next_write);
+                    self->send(hrus_to_update[i], run_hru_v);
                 }
+            
+                output_partition->resetReadyToWriteList();
             }
+
             self->state.file_access_timing.updateEndPoint("write_duration");
         },
 
+        [=](restart_failures) {
+            self->state.output_container->reconstruct();
+        },
+
         [=](run_failure, int local_gru_index) {
+            Output_Partition *output_partition = self->state.output_container->getOutputPartition(local_gru_index);
             
-            std::optional<int> partition_index = updatePartitionWithFailedHRU(self->state.output_partitions, local_gru_index);
-            
-            if (partition_index.has_value() && self->state.output_partitions[partition_index.value()]->num_gru < 0) {
-                self->state.file_access_timing.updateStartPoint("write_duration");
+            output_partition->addFailedGRUIndex(local_gru_index);
+
+            int active_grus = output_partition->getNumActiveGRUs();
+
+            if (output_partition->isReadyToWrite() && active_grus > 0) {
+                int num_timesteps_to_write = output_partition->getNumStoredTimesteps();
+                int start_gru = output_partition->getMaxGRUIndex();
+                int max_gru = output_partition->getStartGRUIndex();
+                
+                writeOutput(self->state.handle_ncid, &num_timesteps_to_write,
+                    &start_gru, &max_gru, &self->state.err);
                 
-                // We have a partition that is ready to write
-                int max_gru = self->state.output_partitions[partition_index.value()]->start_gru + self->state.output_partitions[partition_index.value()]->num_gru -1;
-                writeOutput(self->state.handle_ncid, &self->state.output_partitions[partition_index.value()]->num_timesteps,
-                    &self->state.output_partitions[partition_index.value()]->start_gru, &max_gru, &self->state.err);
+                output_partition->updateTimeSteps();
+
+                int num_steps_before_next_write = output_partition->getNumStoredTimesteps();
+
+                std::vector<caf::actor> hrus_to_update = output_partition->getReadyToWriteList();
                 
-                updateSimulationTimestepsRemaining(self->state.output_partitions[partition_index.value()]);
-                updateNumTimeForPartition(self->state.output_partitions[partition_index.value()]);                 
-                resetReadyToWrite(self->state.output_partitions[partition_index.value()]);
-                for (auto hru_output_info : self->state.output_partitions[partition_index.value()]->hru_info_and_data) {
-                    self->send(hru_output_info->hru_actor, num_steps_before_write_v, self->state.output_partitions[partition_index.value()]->num_timesteps);
-                    self->send(hru_output_info->hru_actor, run_hru_v);
+                for (int i = 0; i < hrus_to_update.size(); i++) {
+                    self->send(hrus_to_update[i], num_steps_before_write_v, num_steps_before_next_write);
+                    self->send(hrus_to_update[i], run_hru_v);
                 }
-                self->state.file_access_timing.updateEndPoint("write_duration");
+            
+                output_partition->resetReadyToWriteList();
+            
             }
           
         },
@@ -209,6 +228,10 @@ behavior file_access_actor(stateful_actor<file_access_state>* self, int start_gr
             WriteGRUStatistics(self->state.handle_ncid, &self->state.gru_actor_stats, 
                     netcdf_gru_info.data(), &num_gru, &self->state.err);
 
+            
+            // call output_container deconstructor
+            self->state.output_container->~Output_Container();
+
 
             aout(self) << "Deallocating Structure" << std::endl;
             FileAccessActor_DeallocateStructures(self->state.handle_forcing_file_info, self->state.handle_ncid);
diff --git a/build/source/actors/file_access_actor/cpp_code/output_container.cpp b/build/source/actors/file_access_actor/cpp_code/output_container.cpp
index b594243c2d7a2c300428b54217fe3850461d62c5..ba2a68a4070d5dd933d3903b00629f78686bd6db 100644
--- a/build/source/actors/file_access_actor/cpp_code/output_container.cpp
+++ b/build/source/actors/file_access_actor/cpp_code/output_container.cpp
@@ -1,105 +1,180 @@
 #include "output_container.hpp"
 
 
+//###################################################################
+// Output_Partition
+//###################################################################
+Output_Partition::Output_Partition(int start_local_gru_index, int num_local_grus, int num_timesteps_simulation, int num_stored_timesteps) {
+    this->start_local_gru_index = start_local_gru_index;
+    this->num_local_grus = num_local_grus;
+    this->num_timesteps_simulation = num_timesteps_simulation;
+    this->num_stored_timesteps = num_stored_timesteps;
 
-void initArrayOfOuputPartitions(std::vector<std::shared_ptr<output_partition>>& output_partitions, 
-    int num_partitions, int num_gru_run_domain, int num_timesteps,  int simulation_timesteps_remaining) {
+}
 
-    int start_gru_counter = 1;
-    int num_gru_per_partition = std::round(num_gru_run_domain / num_partitions);
-    for (int i = 0; i < num_partitions - 1; i++) {
-        output_partitions.push_back(std::make_shared<output_partition>());
-        output_partitions[i]->start_gru = start_gru_counter;
-        output_partitions[i]->num_gru = num_gru_per_partition;
-        output_partitions[i]->num_active_gru = num_gru_per_partition;
-        output_partitions[i]->num_timesteps = num_timesteps;
-        output_partitions[i]->simulation_timesteps_remaining = simulation_timesteps_remaining;
-        output_partitions[i]->grus_ready_to_write = 0;
-        for (int a = 0; a < num_gru_per_partition; a++) {
-            output_partitions[i]->hru_info_and_data.push_back(std::make_shared<hru_output_info>());
-        }
+Output_Partition::~Output_Partition() {
+    // TODO Auto-generated destructor stub
+}
 
-        start_gru_counter += num_gru_per_partition;
-    }
-    // The last partition may not easily divide with the number of GRUs
-    output_partitions.push_back(std::make_shared<output_partition>());
-    output_partitions[num_partitions - 1]->start_gru = start_gru_counter;
-    output_partitions[num_partitions - 1]->num_gru = num_gru_run_domain - start_gru_counter + 1;
-    output_partitions[num_partitions - 1]->num_active_gru = num_gru_run_domain - start_gru_counter + 1;
-    output_partitions[num_partitions - 1]->num_timesteps = num_timesteps;
-    output_partitions[num_partitions - 1]->simulation_timesteps_remaining = simulation_timesteps_remaining;
-    output_partitions[num_partitions - 1]->grus_ready_to_write = 0;
-    for (int a = 0; a < num_gru_run_domain - start_gru_counter + 1; a++) {
-        output_partitions[num_partitions - 1]->hru_info_and_data.push_back(std::make_shared<hru_output_info>());
-    }
+void Output_Partition::setGRUReadyToWrite(caf::actor gru_actor) {
+    this->ready_to_write_list.push_back(gru_actor);
+}
+
+bool Output_Partition::isReadyToWrite() {
+    return (this->ready_to_write_list.size() + this->failed_gru_index_list.size()) 
+        == this->num_local_grus;
+}
 
+int Output_Partition::getMaxGRUIndex() {
+    return this->start_local_gru_index + this->num_local_grus - 1;
 }
 
-std::optional<int> addReadyToWriteHRU(std::vector<std::shared_ptr<output_partition>>& output_partitions, 
-    caf::actor hru_actor, int gru_index, int hru_index) {
+int Output_Partition::getNumStoredTimesteps() {
+    return this->num_stored_timesteps;
+}
+
+int Output_Partition::getStartGRUIndex() {
+    return this->start_local_gru_index;
+}
+
+void Output_Partition::updateTimeSteps() {
     
-    int partition_index = findPatritionIndex(output_partitions[0]->num_gru, gru_index, output_partitions.size());
-    int gru_index_in_partition = gru_index - output_partitions[partition_index]->start_gru;
-
-    output_partitions[partition_index]->hru_info_and_data[gru_index_in_partition]->hru_actor = hru_actor;
-    output_partitions[partition_index]->hru_info_and_data[gru_index_in_partition]->index_hru = hru_index;
-    output_partitions[partition_index]->hru_info_and_data[gru_index_in_partition]->index_gru = gru_index;
-    output_partitions[partition_index]->hru_info_and_data[gru_index_in_partition]->ready_to_write = true;
-    output_partitions[partition_index]->grus_ready_to_write += 1;
-    // If all grus are ready to write then return the partition index
-    if (output_partitions[partition_index]->grus_ready_to_write == output_partitions[partition_index]->num_active_gru) {
-        return partition_index;
-    }
-    else {
-        return {};
+    // Update the number of timesteps remaining in the simulation
+    this->num_timesteps_simulation -= this->num_stored_timesteps;
+    
+    // Reset the number of timesteps to store for the next run
+    if (this->num_timesteps_simulation < this->num_stored_timesteps) {
+        this->num_stored_timesteps = this->num_timesteps_simulation;
     }
 
 }
 
-int findPatritionIndex(int grus_per_partition, int gru_index, int num_partitions) {
-    int partition_index;
+std::vector<caf::actor> Output_Partition::getReadyToWriteList() {
+    return this->ready_to_write_list;
+}
 
-    partition_index = (gru_index - 1) / grus_per_partition;
-    // The last partion will not be the same size as the others in some cases
-    // So we have to correct the value
-    if (partition_index >= num_partitions) {
-        partition_index = num_partitions - 1;
-    }
+void Output_Partition::resetReadyToWriteList() {
+    this->ready_to_write_list.clear();
+}
 
-    return partition_index;
+void Output_Partition::addFailedGRUIndex(int local_gru_index) {
+    this->failed_gru_index_list.push_back(local_gru_index);
 }
 
-void resetReadyToWrite(std::shared_ptr<output_partition>& output_partition) {
-    for (auto &hru_info_and_data : output_partition->hru_info_and_data) {
-        hru_info_and_data->ready_to_write = false;
-    }
-    output_partition->grus_ready_to_write = 0;
+int Output_Partition::getNumActiveGRUs() {
+    return this->num_local_grus - this->failed_gru_index_list.size();
+}
+
+int Output_Partition::getNumLocalGRUs() {
+    return this->num_local_grus;
+}
+
+int Output_Partition::getRemainingTimesteps() {
+    return this->num_timesteps_simulation;
 }
 
+std::vector<int> Output_Partition::getFailedGRUIndexList() {
+    return this->failed_gru_index_list;
+}
+
+
+//###################################################################
+// Output_Container
+//###################################################################
+
+Output_Container::Output_Container(int num_partitions, int num_grus, int num_stored_timesteps, int num_timesteps_simulation) {
+    this->num_grus = num_grus;
+    this->num_timesteps_simulation = num_timesteps_simulation;
+    this->num_stored_timesteps = num_stored_timesteps;
 
-void updateSimulationTimestepsRemaining(std::shared_ptr<output_partition>& output_partition) {
-    output_partition->simulation_timesteps_remaining -= output_partition->num_timesteps;
+    // Set the number of partitions - avoiding division with a remainder
+    if (num_partitions > num_grus) {
+        this->num_partitions = num_grus;
+    } else {
+        this->num_partitions = num_partitions;
+    }
+
+    // Initialize the output partitions
+    int start_gru_counter = 1;
+    this->num_grus_per_partition = std::round(num_grus / num_partitions);
+    for (int i = 0; i < num_partitions - 1; i++) {
+        this->output_partitions.push_back(new Output_Partition(start_gru_counter, this->num_grus_per_partition, num_timesteps_simulation, num_stored_timesteps));
+        start_gru_counter += this->num_grus_per_partition;
+    }
+    // The last partition will have the remainder of the GRUs
+    this->output_partitions.push_back(new Output_Partition(start_gru_counter, num_grus - start_gru_counter + 1, num_timesteps_simulation, num_stored_timesteps));
 }
 
-void updateNumTimeForPartition(std::shared_ptr<output_partition> &output_partition) {
-    if (output_partition->simulation_timesteps_remaining < output_partition->num_timesteps) {
-        output_partition->num_timesteps = output_partition->simulation_timesteps_remaining;
+Output_Container::~Output_Container() {
+
+    for (int i = 0; i < this->num_partitions; i++) {
+        delete this->output_partitions[i];
     }
 }
 
-std::optional<int> updatePartitionWithFailedHRU(std::vector<std::shared_ptr<output_partition>>& output_partitions, 
-    int local_gru_index) {
-    int partition_index = findPatritionIndex(output_partitions[0]->num_gru, local_gru_index, output_partitions.size());
-    output_partitions[partition_index]->num_active_gru -= 1;    
+Output_Partition* Output_Container::getOutputPartition(int local_gru_index) {
+    int partition_index = this->findPartition(local_gru_index);
+    return this->output_partitions[partition_index];
+}
 
-    // Check if the partition is now ready to write
-    if (output_partitions[partition_index]->grus_ready_to_write == output_partitions[partition_index]->num_active_gru) {
+int Output_Container::findPartition(int local_gru_index) {
+    // If we are not rerunning failed GRUs, then the partition index can be found within a block of GRUs
+    if (!this->rerunning_failed_hrus) {
+        int partition_index = (local_gru_index - 1) / this->num_grus_per_partition;
+        // correct the value if too large (more than the number of partitions)
+        if (partition_index > this->num_partitions - 1) {
+            partition_index = this->num_partitions - 1;
+        }
         return partition_index;
+    } else {
+        // If we are rerunning failed GRUs, they may not be grouped in blocks, so we need to use the failed GRU index list
+        std::vector<int>::iterator it = std::find(this->failed_gru_index_list.begin(), this->failed_gru_index_list.end(), local_gru_index);
+        if (it != this->failed_gru_index_list.end()) {
+            return std::distance(this->failed_gru_index_list.begin(), it);
+        } else {
+            throw std::runtime_error("GRU index not found in failed GRU index list");
+        }
     }
-    else {
-        return {};
-    }
 
+ 
+}
+
+int Output_Container::getNumPartitions() {
+    return this->num_partitions;
+}
+
+std::vector<int> Output_Container::getFailedGRUIndexList() {
+    return this->failed_gru_index_list;
+}
+
+void Output_Container::reconstruct() {
+
+    this->failed_gru_index_list;
+
+    // Loop over all partitions getting the failed GRU index list
+    for (int i = 0; i < this->num_partitions; i++) {
+        std::vector<int> partition_failed_gru_index_list = this->output_partitions[i]->getFailedGRUIndexList();
+        failed_gru_index_list.insert(
+            failed_gru_index_list.end(), 
+            partition_failed_gru_index_list.begin(), 
+            partition_failed_gru_index_list.end());
+        delete this->output_partitions[i];
+    }
+    this->output_partitions.clear();
+
+    std::sort(this->failed_gru_index_list.begin(), this->failed_gru_index_list.end());
+    // Reconstruct the output partitions
+    this->num_partitions = failed_gru_index_list.size();
+    this->num_grus = failed_gru_index_list.size();
+    this->num_grus_per_partition = 1;
+    for (int i = 0; i < failed_gru_index_list.size(); i++){
+        this->output_partitions.push_back(new 
+            Output_Partition(failed_gru_index_list[i], 1, 
+                            this->num_timesteps_simulation, 
+                            this->num_stored_timesteps));
+    }
 
+    this->rerunning_failed_hrus = true;
 }
 
+
diff --git a/build/source/actors/file_access_actor/cpp_code/partition_actor.cpp b/build/source/actors/file_access_actor/cpp_code/partition_actor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a226c7aef77ea1859b37d9930b58bbcafbccfe8
--- /dev/null
+++ b/build/source/actors/file_access_actor/cpp_code/partition_actor.cpp
@@ -0,0 +1,18 @@
+#include "partition_actor.hpp"
+
+
+namespace caf {
+
+behavior partition_actor(stateful_actor<partition_actor_state>* self, int start_local_gru_index, 
+    int num_local_grus, int num_timesteps_simulation, int num_timesteps_buffer) {
+    
+    self->state.start_local_gru_index = start_local_gru_index;
+    self->state.num_local_grus = num_local_grus;
+    self->state.num_timesteps_simulation = num_timesteps_simulation;
+    self->state.num_timesteps_buffer = num_timesteps_buffer;
+    
+    
+    return {
+    };
+}
+}
\ No newline at end of file
diff --git a/build/source/actors/global/settings_functions.cpp b/build/source/actors/global/settings_functions.cpp
index aae1a97682b0cc4fafd94d6073f24d40a5c76bee..ad69d90eda8ce8b36dd7b9fb03398177abbc1502 100644
--- a/build/source/actors/global/settings_functions.cpp
+++ b/build/source/actors/global/settings_functions.cpp
@@ -95,6 +95,9 @@ Job_Actor_Settings readJobActorSettings(std::string json_settings_file) {
     std::string parent_key = "Job_Actor";
     job_actor_settings.file_manager_path = getSettings(json_settings_file, parent_key,
         "file_manager_path", job_actor_settings.file_manager_path).value_or("");
+    
+    job_actor_settings.max_run_attempts = getSettings(json_settings_file, parent_key,
+        "max_run_attempts", job_actor_settings.max_run_attempts).value_or(1);
 
     return job_actor_settings;
 }
@@ -110,6 +113,9 @@ HRU_Actor_Settings readHRUActorSettings(std::string json_settings_file) {
     hru_actor_settings.output_frequency = getSettings(json_settings_file, parent_key,
         "output_frequency", hru_actor_settings.output_frequency).value_or(250);
 
+    hru_actor_settings.dt_init_factor = getSettings(json_settings_file, parent_key,
+        "dt_init_factor", hru_actor_settings.dt_init_factor).value_or(1);
+
     return hru_actor_settings;
 }
 
diff --git a/build/source/actors/hru_actor/cpp_code/hru_actor.cpp b/build/source/actors/hru_actor/cpp_code/hru_actor.cpp
index e1c82a4ed642a773414c303e26646dce3f96cf16..b9ad0d10ce3f0e107b31853c38e58377b591dad6 100644
--- a/build/source/actors/hru_actor/cpp_code/hru_actor.cpp
+++ b/build/source/actors/hru_actor/cpp_code/hru_actor.cpp
@@ -26,6 +26,8 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
     self->state.iFile             = 1;
     // Get the settings for the HRU
     self->state.hru_actor_settings = hru_actor_settings;
+    self->state.dt_init_factor = hru_actor_settings.dt_init_factor;
+
 
     initHRU(&self->state.indxGRU, &self->state.num_steps, self->state.handle_lookupStruct, self->state.handle_forcStat,
         self->state.handle_progStat, self->state.handle_diagStat, self->state.handle_fluxStat, self->state.handle_indxStat, 
@@ -195,7 +197,6 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
 
         [=](dt_init_factor, int dt_init_factor) {
             aout(self) << "Recieved New dt_init_factor to attempt on next run \n";
-            self->state.dt_init_factor = dt_init_factor;
         },
     };
 }
diff --git a/build/source/actors/job_actor/GRU.cpp b/build/source/actors/job_actor/GRU.cpp
index 3138692f3456e34c9d7b8cbcbd74073f003c6c86..520c36d973425ab5225bed179d3db4303731cd8c 100644
--- a/build/source/actors/job_actor/GRU.cpp
+++ b/build/source/actors/job_actor/GRU.cpp
@@ -56,6 +56,10 @@ 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;
@@ -76,11 +80,17 @@ void GRU::setWriteOutputDuration(double write_output_duration) {
 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
diff --git a/build/source/actors/job_actor/job_actor.cpp b/build/source/actors/job_actor/job_actor.cpp
index 73d2918bca0231d2f35a904958546cfc06516a16..06c811819f48a414d80ce04ba28eaeb25ea9d9b0 100644
--- a/build/source/actors/job_actor/job_actor.cpp
+++ b/build/source/actors/job_actor/job_actor.cpp
@@ -45,6 +45,7 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
     self->state.file_access_actor_settings = file_access_actor_settings;
     self->state.job_actor_settings = job_actor_settings;
     self->state.hru_actor_settings = hru_actor_settings;
+    self->state.max_run_attempts = job_actor_settings.max_run_attempts;
 
     // Init the GRU Container
     self->state.gru_container.num_gru_in_run_domain = num_gru;
@@ -120,7 +121,7 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
           if (self->state.gru_container.num_gru_done >= self->state.gru_container.num_gru_in_run_domain) {
             
             // Check for failures
-            if(self->state.gru_container.num_gru_failed == 0 || self->state.max_run_attempts == 1) {
+            if(self->state.gru_container.num_gru_failed == 0 || self->state.gru_container.run_attempts_left == 0) {
               //TODO: RENAME DEALLOCATE_STURCTURES this is more of a finalize
               std::vector<serializable_netcdf_gru_actor_info> netcdf_gru_info = getGruNetcdfInfo(
                                                                                     self->state.max_run_attempts,
@@ -128,7 +129,29 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
               self->send(self->state.file_access_actor, deallocate_structures_v, netcdf_gru_info);
             
             } else {
-              // TODO: Handle failures
+              aout(self) << "Job_Actor: Restarting GRUs that Failed\n";
+              self->state.gru_container.num_gru_done = 0;
+              self->state.gru_container.num_gru_in_run_domain = self->state.gru_container.num_gru_failed;
+              self->state.gru_container.num_gru_failed = 0;
+              self->send(self->state.file_access_actor, restart_failures_v);
+
+              for(auto GRU : self->state.gru_container.gru_list) {
+                if(GRU->isFailed()) {
+                    GRU->setRunning();
+                    GRU->decrementAttemptsLeft();
+                    self->state.hru_actor_settings.dt_init_factor *= 2;
+                    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);
+                }
+              }
+
 
             }
           }
@@ -181,7 +204,8 @@ behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
 
 void initGRUs(stateful_actor<job_state>* self) {
   self->state.gru_container.gru_start_time = std::chrono::high_resolution_clock::now();
-  
+  self->state.gru_container.run_attempts_left = self->state.max_run_attempts;
+  self->state.gru_container.run_attempts_left--;
   for(int i = 0; i < self->state.gru_container.num_gru_in_run_domain; i++) {
       // Spawn the GRU Actor
       auto global_gru_index = self->state.gru_container.gru_list.size() + self->state.start_gru;
@@ -246,7 +270,27 @@ void handleGRUError(stateful_actor<job_state>* self, const error& err, caf::acto
                     self->send(self->state.file_access_actor, deallocate_structures_v, netcdf_gru_info);
                 
                 } else {
-                // TODO: Handle failures
+                    aout(self) << "Job_Actor: Restarting GRUs that Failed\n";
+                    self->send(self->state.file_access_actor, restart_failures_v);
+                    self->state.gru_container.num_gru_done = 0;
+                    self->state.gru_container.num_gru_in_run_domain = self->state.gru_container.num_gru_failed;
+                    self->state.gru_container.num_gru_failed = 0;
+                    for(auto GRU : self->state.gru_container.gru_list) {
+                        if(GRU->isFailed()) {
+                            GRU->setRunning();
+                            GRU->decrementAttemptsLeft();
+                            self->state.hru_actor_settings.dt_init_factor *= 2;
+                            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);
+                        }
+                    }
 
                 }
             }
diff --git a/build/source/testing/containers/output_container/makefile b/build/source/testing/containers/output_container/makefile
index 075fc3e828ba5372cbde33c9b6ed6750bd8b142f..d93385f3f323d6cd8830b9a1cdeded18f60f96a1 100644
--- a/build/source/testing/containers/output_container/makefile
+++ b/build/source/testing/containers/output_container/makefile
@@ -1,39 +1,29 @@
+
+ROOT_DIR = /u1/kck540/Summa-Projects/Summa-Actors
+
 FC = gfortran
 CC = g++	  # C++
-INCLUDES=-I/usr/local/include 
-LIBRARIES=-L/usr/local/lib -L/Summa-Actors/build/source/testing/containers/output_container -lcaf_core -lcaf_io -lcppwrap_datatypes
+INCLUDES=-I/usr/local/actor-framework/debug/include
+LIBRARIES=-L/usr/local/actor-framework/debug/lib -lcaf_core -lcaf_io
 FLAGS = -g -O0 -Wfatal-errors -std=c++17
 
 
-Fortran_Data_Types = /Summa-Actors/build/source/actors/global/cppwrap_datatypes.f90
-DATA_TYPES = /Summa-Actors/build/source/dshare/data_types.f90
-NR_TYPE = /Summa-Actors/build/source/engine/nrtype.f90
-VAR_LOOKUP = /Summa-Actors/build/source/dshare/var_lookup.f90
 
-SOURCE_DIR = /Summa-Actors/build/source/actors/file_access_actor/cpp_code
+SOURCE_DIR = $(ROOT_DIR)/build/source/actors/file_access_actor/cpp_code
 
-CONTAINER_INCLUDES = -I/Summa-Actors/build/includes/file_access_actor
-GLOBAL_INCLUDES = -I/Summa-Actors/build/includes/global
+CONTAINER_INCLUDES = -I$(ROOT_DIR)/build/includes/file_access_actor
+GLOBAL_INCLUDES = -I$(ROOT_DIR)/build/includes/global
 
 Output_Container = $(SOURCE_DIR)/output_container.cpp
 
 
-all: compile_fortran link_fortran clean_fortran compile_cpp link_cpp clean_cpp
-
-compile_fortran:
-	$(FC) -c $(NR_TYPE) $(VAR_LOOKUP) $(DATA_TYPES) $(Fortran_Data_Types) 
-
-link_fortran:
-	$(FC) -shared *.o -o libcppwrap_datatypes.so
-
-clean_fortran:
-	rm -f *.o *.mod 
+all: compile_cpp link_cpp clean_cpp
 
 
 compile_cpp:
 	$(CC) $(FLAGS) -c main.cpp test.cpp $(Output_Container) $(CONTAINER_INCLUDES) $(GLOBAL_INCLUDES)
 link_cpp:
-	$(CC) $(FLAGS) -Wl,-rpath='/usr/local/lib:/Summa-Actors/build/source/testing/containers/output_container' -o main *.o $(LIBRARIES)
+	$(CC) $(FLAGS) -Wl,-rpath='/usr/local/actor-framework/debug/lib' -o main *.o $(LIBRARIES)
 
 clean_cpp:
 	rm *.o
\ No newline at end of file
diff --git a/build/source/testing/containers/output_container/test.cpp b/build/source/testing/containers/output_container/test.cpp
index 8fd4a4f2d550f26636c28c5bc1f8cff52dbeb9f2..69653b8deaaaeab4b06c15091f63653c17dc39eb 100644
--- a/build/source/testing/containers/output_container/test.cpp
+++ b/build/source/testing/containers/output_container/test.cpp
@@ -3,440 +3,231 @@
 
 void TEST_CLIENT() {
     std::cout << "Testing Output Container\n";
-    std::vector<std::shared_ptr<hru_output_handles>> dummy_data;
-    for (int i = 0; i < 50; i++) {
-        dummy_data.push_back(std::make_shared<hru_output_handles>());
-    }
-    // // Test insertOutput
-    // std::vector<hru_output_handles> dummy_data(50);
-
-    std::vector<std::shared_ptr<output_partition>> output_partitions_vectors;
-    int num_partitions = 4;
-    int num_gru = 50;
-    int num_timestep = 50;
-    int simulation_timesteps_remaining = 100;
-    initArrayOfOuputPartitions(output_partitions_vectors, num_partitions, num_gru, num_timestep, 
-        simulation_timesteps_remaining);
+
+    int num_partitions = 5;
+    int num_grus = 10;
+    int num_timesteps_simulation = 100;
+    int num_stored_timesteps = 10;
+    
+    Output_Container *output_container = new Output_Container(
+        num_partitions, num_grus, num_stored_timesteps, num_timesteps_simulation);
     
-    IS_TRUE(output_partitions_vectors.size() == 4);
-    IS_TRUE(output_partitions_vectors[0]->start_gru == 1);
-    IS_TRUE(output_partitions_vectors[0]->num_gru == 12);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 50);
-    IS_TRUE(output_partitions_vectors[0]->hru_info_and_data.size() == 12);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 100);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 50);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 50);
-
-    IS_TRUE(output_partitions_vectors[1]->start_gru == 13);
-    IS_TRUE(output_partitions_vectors[1]->num_gru == 12);
-    IS_TRUE(output_partitions_vectors[1]->num_timesteps == 50);
-    IS_TRUE(output_partitions_vectors[1]->hru_info_and_data.size() == 12);
-    IS_TRUE(output_partitions_vectors[1]->simulation_timesteps_remaining == 100);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[1]);
-    IS_TRUE(output_partitions_vectors[1]->simulation_timesteps_remaining == 50);
-    updateNumTimeForPartition(output_partitions_vectors[1]);
-    IS_TRUE(output_partitions_vectors[1]->num_timesteps == 50);
-
-    IS_TRUE(output_partitions_vectors[2]->start_gru == 25);
-    IS_TRUE(output_partitions_vectors[2]->num_gru == 12);
-    IS_TRUE(output_partitions_vectors[2]->num_timesteps == 50);
-    IS_TRUE(output_partitions_vectors[2]->hru_info_and_data.size() == 12);
-    IS_TRUE(output_partitions_vectors[2]->simulation_timesteps_remaining == 100);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[2]);
-    IS_TRUE(output_partitions_vectors[2]->simulation_timesteps_remaining == 50);
-    updateNumTimeForPartition(output_partitions_vectors[2]);
-    IS_TRUE(output_partitions_vectors[2]->num_timesteps == 50);
-
-    IS_TRUE(output_partitions_vectors[3]->start_gru == 37);
-    IS_TRUE(output_partitions_vectors[3]->num_gru == 14);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 50);
-    IS_TRUE(output_partitions_vectors[3]->hru_info_and_data.size() == 14);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 100);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 50);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 50);
-
-    std::cout << "Testing Output Container: DONE TEST 1\n";
-
-    std::cout << "Testing Partitions indexes\n";
-    int partition_size = 12;
-    IS_TRUE(findPatritionIndex(partition_size, 1, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 2, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 3, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 4, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 5, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 6, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 7, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 8, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 9, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 10, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 11, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 12, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 13, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 14, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 15, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 16, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 17, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 18, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 19, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 20, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 21, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 22, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 23, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 24, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 25, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 26, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 27, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 28, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 29, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 30, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 31, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 32, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 33, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 34, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 35, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 36, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 37, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 38, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 39, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 40, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 41, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 42, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 43, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 44, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 45, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 46, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 47, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 48, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 49, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 50, num_partitions) == 3);
-    std::cout << "Testing Partitions indexes: DONE TEST 1\n";
-
-    std::cout << "Testing finding GRU index in a partition\n";
-    // partition = 1
-    int gru_index = 1;
-    int start_gru = 1;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 12;
-    start_gru = 1;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 11);
-    gru_index = 13;
-    start_gru = 13;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 24;
-    start_gru = 13;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 11);
-    gru_index = 25;
-    start_gru = 25;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 36;
-    start_gru = 25;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 11);
-    gru_index = 37;
-    start_gru = 37;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 50;
-    start_gru = 37;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 13);
-
-
-
-    output_partitions_vectors.clear();
-    int num_partitions2 = 8;
-    int num_gru2 = 80;
-    int num_timestep2 = 80;
-    simulation_timesteps_remaining = 600;
-    initArrayOfOuputPartitions(output_partitions_vectors, num_partitions2, num_gru2, num_timestep2, simulation_timesteps_remaining);
-    IS_TRUE(output_partitions_vectors.size() == 8);
-    IS_TRUE(output_partitions_vectors[0]->start_gru == 1);
-    IS_TRUE(output_partitions_vectors[0]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[0]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 600);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 520);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 440);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 360);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 280);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 200);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 120);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 40);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 40);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->simulation_timesteps_remaining == 0);
-    updateNumTimeForPartition(output_partitions_vectors[0]);
-    IS_TRUE(output_partitions_vectors[0]->num_timesteps == 0);
-
-
-
-    IS_TRUE(output_partitions_vectors[1]->start_gru == 11);
-    IS_TRUE(output_partitions_vectors[1]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[1]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[1]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[1]->simulation_timesteps_remaining == 600);
-
-    IS_TRUE(output_partitions_vectors[2]->start_gru == 21);
-    IS_TRUE(output_partitions_vectors[2]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[2]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[2]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[2]->simulation_timesteps_remaining == 600);
-
-    IS_TRUE(output_partitions_vectors[3]->start_gru == 31);
-    IS_TRUE(output_partitions_vectors[3]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[3]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 600);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 520);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 440);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 360);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 280);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 200);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 120);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 80);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 40);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 40);
-    updateSimulationTimestepsRemaining(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->simulation_timesteps_remaining == 0);
-    updateNumTimeForPartition(output_partitions_vectors[3]);
-    IS_TRUE(output_partitions_vectors[3]->num_timesteps == 0);
-
-    IS_TRUE(output_partitions_vectors[4]->start_gru == 41);
-    IS_TRUE(output_partitions_vectors[4]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[4]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[4]->simulation_timesteps_remaining == 600);
-
-    IS_TRUE(output_partitions_vectors[5]->start_gru == 51);
-    IS_TRUE(output_partitions_vectors[5]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[5]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[5]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[5]->simulation_timesteps_remaining == 600);
-    IS_TRUE(output_partitions_vectors[6]->start_gru == 61);
-    IS_TRUE(output_partitions_vectors[6]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[6]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[6]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[6]->simulation_timesteps_remaining == 600);
-    IS_TRUE(output_partitions_vectors[7]->start_gru == 71);
-    IS_TRUE(output_partitions_vectors[7]->num_gru == 10);
-    IS_TRUE(output_partitions_vectors[7]->num_timesteps == 80);
-    IS_TRUE(output_partitions_vectors[7]->hru_info_and_data.size() == 10);
-    IS_TRUE(output_partitions_vectors[7]->simulation_timesteps_remaining == 600);
-
-    std::cout << "Testing Output Container: DONE TEST 2\n";
-    partition_size = 10;
-    num_partitions = 8;
-    IS_TRUE(findPatritionIndex(partition_size, 1, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 10, num_partitions) == 0);
-    IS_TRUE(findPatritionIndex(partition_size, 11, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 20, num_partitions) == 1);
-    IS_TRUE(findPatritionIndex(partition_size, 21, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 30, num_partitions) == 2);
-    IS_TRUE(findPatritionIndex(partition_size, 31, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 40, num_partitions) == 3);
-    IS_TRUE(findPatritionIndex(partition_size, 41, num_partitions) == 4);
-    IS_TRUE(findPatritionIndex(partition_size, 50, num_partitions) == 4);
-    IS_TRUE(findPatritionIndex(partition_size, 51, num_partitions) == 5);
-    IS_TRUE(findPatritionIndex(partition_size, 60, num_partitions) == 5);
-    IS_TRUE(findPatritionIndex(partition_size, 61, num_partitions) == 6);
-    IS_TRUE(findPatritionIndex(partition_size, 70, num_partitions) == 6);
-    IS_TRUE(findPatritionIndex(partition_size, 71, num_partitions) == 7);
-    IS_TRUE(findPatritionIndex(partition_size, 80, num_partitions) == 7);
-    std::cout << "Testing Partitions indexes: DONE TEST 2\n";
-
-
-    std::cout << "Testing findGRUIndexInPartition2: START\n";
-    gru_index = 4;
-    start_gru = 1;
-    // partition index = 0
+    // Test getNumPartitions
+    IS_TRUE(output_container->getNumPartitions() == 5);
     
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 3);
-    gru_index = 10;
-    start_gru = 1;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 9);
-    // partition index = 1
-    gru_index = 11;
-    start_gru = 11;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 20;
-    start_gru = 11;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 9);
-    // partition index = 2
-    gru_index = 21;
-    start_gru = 21;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 30;
-    start_gru = 21;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 9);
-    // partition index = 3
-    gru_index = 31;
-    start_gru = 31;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    // partition index = 7
-    gru_index = 71;
-    start_gru = 71;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 0);
-    gru_index = 80;
-    start_gru = 71;
-    IS_TRUE(findGRUIndexInPartition(gru_index, start_gru) == 9);
-    std::cout << "Testing findGRUIndexInPartition2: DONE\n";
-
-
-
-
-    // Test adding output to the output structure
-    std::cout << "Testing addOutputToOutputStructure: START\n";
-    output_partitions_vectors.clear();
-    num_partitions = 5;
-    num_gru = 8;
-    num_timestep = 2;
-    simulation_timesteps_remaining = 10;
-    caf::actor actor0; // index_gru = 1, hru_index = 1
-    caf::actor actor1; // index_gru = 2, hru_index = 1
-    caf::actor actor2; // index_gru = 3, hru_index = 1
-    caf::actor actor3; // index_gru = 4, hru_index = 1
-    caf::actor actor4; // index_gru = 5, hru_index = 1
-    caf::actor actor5; // index_gru = 6, hru_index = 1
-    caf::actor actor6; // index_gru = 7, hru_index = 1
-    caf::actor actor7; // index_gru = 8, hru_index = 1
-    initArrayOfOuputPartitions(output_partitions_vectors, num_partitions, 
-        num_gru, num_timestep, simulation_timesteps_remaining);
-    std::optional<int> return_value;
-    gru_index = 1;
-    int hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor0, gru_index, hru_index, dummy_data[0]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[0]->hru_info_and_data[0]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[0]->hru_info_and_data[0]->index_gru == 1);
-    IS_TRUE(output_partitions_vectors[0]->hru_info_and_data[0]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[0]->hru_info_and_data[0]->hru_actor == actor0);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor0, gru_index, hru_index, dummy_data[8]).value() == 0);
-
-    gru_index = 2;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor1, gru_index, hru_index, dummy_data[1]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[1]->hru_info_and_data[0]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[1]->hru_info_and_data[0]->index_gru == 2);
-    IS_TRUE(output_partitions_vectors[1]->hru_info_and_data[0]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[1]->hru_info_and_data[0]->hru_actor == actor1);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor1, gru_index, hru_index, dummy_data[9]).value() == 1);
-
-    gru_index = 3;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor2, gru_index, hru_index, dummy_data[2]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[2]->hru_info_and_data[0]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[2]->hru_info_and_data[0]->index_gru == 3);
-    IS_TRUE(output_partitions_vectors[2]->hru_info_and_data[0]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[2]->hru_info_and_data[0]->hru_actor == actor2);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor2, gru_index, hru_index, dummy_data[10]).value() == 2);
-
-    gru_index = 4;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor3, gru_index, hru_index, dummy_data[3]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[3]->hru_info_and_data[0]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[3]->hru_info_and_data[0]->index_gru == 4);
-    IS_TRUE(output_partitions_vectors[3]->hru_info_and_data[0]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[3]->hru_info_and_data[0]->hru_actor == actor3);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor3, gru_index, hru_index, dummy_data[11]).value() == 3);
-
-    gru_index = 5;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor4, gru_index, hru_index, dummy_data[4]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[0]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[0]->index_gru == 5);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[0]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[0]->hru_actor == actor4);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor4, gru_index, hru_index, dummy_data[12]).has_value() == false);
-
-    gru_index = 6;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor5, gru_index, hru_index, dummy_data[5]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[1]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[1]->index_gru == 6);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[1]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[1]->hru_actor == actor5);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor5, gru_index, hru_index, dummy_data[13]).has_value() == false);
-
-    gru_index = 7;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor6, gru_index, hru_index, dummy_data[6]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[2]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[2]->index_gru == 7);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[2]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[2]->hru_actor == actor6);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor6, gru_index, hru_index, dummy_data[14]).has_value() == false);
-
-    gru_index = 8;
-    hru_index = 1;
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor7, gru_index, hru_index, dummy_data[7]).has_value() == false);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[3]->output_data.size() == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[3]->index_gru == 8);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[3]->index_hru == 1);
-    IS_TRUE(output_partitions_vectors[4]->hru_info_and_data[3]->hru_actor == actor7);
-    IS_TRUE(addHRUOutput(output_partitions_vectors, actor7, gru_index, hru_index, dummy_data[15]).value() == 4);
+    // Test findPartition
+    IS_TRUE(output_container->findPartition(1) == 0);
+    IS_TRUE(output_container->findPartition(2) == 0);
+    IS_TRUE(output_container->findPartition(3) == 1);
+    IS_TRUE(output_container->findPartition(4) == 1);
+    IS_TRUE(output_container->findPartition(5) == 2);
+    IS_TRUE(output_container->findPartition(6) == 2);
+    IS_TRUE(output_container->findPartition(7) == 3);
+    IS_TRUE(output_container->findPartition(8) == 3);
+    IS_TRUE(output_container->findPartition(9) == 4);
+    IS_TRUE(output_container->findPartition(10) == 4);
+
+    // Test getOutputPartition
+    Output_Partition* output_partition_1 = output_container->getOutputPartition(1);
+    Output_Partition* output_partition_2 = output_container->getOutputPartition(2);
+    Output_Partition* output_partition_3 = output_container->getOutputPartition(3);
+    Output_Partition* output_partition_4 = output_container->getOutputPartition(4);
+    Output_Partition* output_partition_5 = output_container->getOutputPartition(5);
+    Output_Partition* output_partition_6 = output_container->getOutputPartition(6);
+    Output_Partition* output_partition_7 = output_container->getOutputPartition(7);
+    Output_Partition* output_partition_8 = output_container->getOutputPartition(8);
+    Output_Partition* output_partition_9 = output_container->getOutputPartition(9);
+    Output_Partition* output_partition_10 = output_container->getOutputPartition(10);
+
+    IS_TRUE(output_partition_1->getStartGRUIndex() == 1);
+    IS_TRUE(output_partition_1->getMaxGRUIndex() == 2);
+    IS_TRUE(output_partition_1->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_1->getNumStoredTimesteps()  == 10);
+    IS_TRUE(output_partition_1->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_2->getStartGRUIndex() == 1);
+    IS_TRUE(output_partition_2->getMaxGRUIndex() == 2);
+    IS_TRUE(output_partition_2->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_2->getNumStoredTimesteps()  == 10);
+    IS_TRUE(output_partition_2->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_3->getStartGRUIndex() == 3);
+    IS_TRUE(output_partition_3->getMaxGRUIndex() == 4);
+    IS_TRUE(output_partition_3->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_3->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_3->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_4->getStartGRUIndex() == 3);
+    IS_TRUE(output_partition_4->getMaxGRUIndex() == 4);
+    IS_TRUE(output_partition_4->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_4->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_4->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_5->getStartGRUIndex() == 5);
+    IS_TRUE(output_partition_5->getMaxGRUIndex() == 6);
+    IS_TRUE(output_partition_5->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_5->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_5->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_6->getStartGRUIndex() == 5);
+    IS_TRUE(output_partition_6->getMaxGRUIndex() == 6);
+    IS_TRUE(output_partition_6->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_6->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_6->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_7->getStartGRUIndex() == 7);
+    IS_TRUE(output_partition_7->getMaxGRUIndex() == 8);
+    IS_TRUE(output_partition_7->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_7->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_7->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_8->getStartGRUIndex() == 7);
+    IS_TRUE(output_partition_8->getMaxGRUIndex() == 8);
+    IS_TRUE(output_partition_8->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_8->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_8->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_9->getStartGRUIndex() == 9);
+    IS_TRUE(output_partition_9->getMaxGRUIndex() == 10);
+    IS_TRUE(output_partition_9->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_9->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_9->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_10->getStartGRUIndex() == 9);
+    IS_TRUE(output_partition_10->getMaxGRUIndex() == 10);
+    IS_TRUE(output_partition_10->getNumLocalGRUs() == 2);
+    IS_TRUE(output_partition_10->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_10->getRemainingTimesteps() == 100);
+
+
+
+    // Test ready to write
+    caf::actor actor_1; caf::actor actor_2; caf::actor actor_3; caf::actor actor_4;
+    caf::actor actor_5; caf::actor actor_6; caf::actor actor_7; caf::actor actor_8;
+    caf::actor actor_9; caf::actor actor_10; caf::actor actor_11; caf::actor actor_12;
+    caf::actor actor_13; caf::actor actor_14; caf::actor actor_15; caf::actor actor_16;
+    caf::actor actor_17; caf::actor actor_18; caf::actor actor_19; caf::actor actor_20;
+
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_1);
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_2);
+    IS_TRUE(output_partition_1->isReadyToWrite());
+
+    output_partition_1->updateTimeSteps();
+    IS_TRUE(output_partition_1->getRemainingTimesteps() == 90);
+    IS_TRUE(output_partition_1->getNumStoredTimesteps() == 10);
+
+    std::vector<caf::actor> actors = output_partition_1->getReadyToWriteList();
+    IS_TRUE(actors.size() == 2);
+    IS_TRUE(actors[0] == actor_1);
+    IS_TRUE(actors[1] == actor_2);
+    output_partition_1->resetReadyToWriteList();
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+
+    output_container->~Output_Container();
+
+
+    // Test Failures
+    num_partitions = 3;
+    num_grus = 20;
+    num_timesteps_simulation = 100;
+    num_stored_timesteps = 10;
+    
+    output_container = new Output_Container(
+        num_partitions, num_grus, num_stored_timesteps, num_timesteps_simulation);
+
+    output_partition_1 = output_container->getOutputPartition(3);
+    IS_TRUE(output_partition_1->getStartGRUIndex() == 1);
+    IS_TRUE(output_partition_1->getMaxGRUIndex() == 6);
+    IS_TRUE(output_partition_1->getNumLocalGRUs() == 6);
+    IS_TRUE(output_partition_1->getNumStoredTimesteps() == 10);
+
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_1);
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_2);
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->addFailedGRUIndex(3);
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_4);
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_5);
+    IS_TRUE(!output_partition_1->isReadyToWrite());
+    output_partition_1->setGRUReadyToWrite(actor_6);
+    IS_TRUE(output_partition_1->isReadyToWrite());
+
+    output_partition_2 = output_container->getOutputPartition(8);
+    output_partition_2->addFailedGRUIndex(7);
+    output_partition_2->addFailedGRUIndex(8);
+    output_partition_2->addFailedGRUIndex(12);
+
+    output_partition_3 = output_container->getOutputPartition(13);
+    output_partition_3->addFailedGRUIndex(14);
+    output_partition_3->addFailedGRUIndex(17);
+
+
+    output_container->reconstruct();
+
+    std::vector<int> comparison_vector = {3, 7, 8, 12, 14, 17};
+    std::vector<int> failed_gru_indices = output_container->getFailedGRUIndexList();
+    IS_TRUE(failed_gru_indices.size() == 6);
+    for (int i = 0; i < failed_gru_indices.size(); i++) {
+        IS_TRUE(failed_gru_indices[i] == comparison_vector[i]);
+    }
 
+    output_partition_1 = output_container->getOutputPartition(3);
+    output_partition_2 = output_container->getOutputPartition(7);
+    output_partition_3 = output_container->getOutputPartition(8);
+    output_partition_4 = output_container->getOutputPartition(12);
+    output_partition_5 = output_container->getOutputPartition(14);
+    output_partition_6 = output_container->getOutputPartition(17);
+
+    IS_TRUE(output_partition_1->getStartGRUIndex() == 3);
+    IS_TRUE(output_partition_1->getMaxGRUIndex() == 3);
+    IS_TRUE(output_partition_1->getNumLocalGRUs() == 1);
+    IS_TRUE(output_partition_1->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_1->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_2->getStartGRUIndex() == 7);
+    IS_TRUE(output_partition_2->getMaxGRUIndex() == 7);
+    IS_TRUE(output_partition_2->getNumLocalGRUs() == 1);
+    IS_TRUE(output_partition_2->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_2->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_3->getStartGRUIndex() == 8);
+    IS_TRUE(output_partition_3->getMaxGRUIndex() == 8);
+    IS_TRUE(output_partition_3->getNumLocalGRUs() == 1);
+    IS_TRUE(output_partition_3->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_3->getRemainingTimesteps() == 100);
+    
+    IS_TRUE(output_partition_4->getStartGRUIndex() == 12);
+    IS_TRUE(output_partition_4->getMaxGRUIndex() == 12);
+    IS_TRUE(output_partition_4->getNumLocalGRUs() == 1);
+    IS_TRUE(output_partition_4->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_4->getRemainingTimesteps() == 100);
 
+    IS_TRUE(output_partition_5->getStartGRUIndex() == 14);
+    IS_TRUE(output_partition_5->getMaxGRUIndex() == 14);
+    IS_TRUE(output_partition_5->getNumLocalGRUs() == 1);
+    IS_TRUE(output_partition_5->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_5->getRemainingTimesteps() == 100);
+
+    IS_TRUE(output_partition_6->getStartGRUIndex() == 17);
+    IS_TRUE(output_partition_6->getMaxGRUIndex() == 17);
+    IS_TRUE(output_partition_6->getNumLocalGRUs() == 1);
+    IS_TRUE(output_partition_6->getNumStoredTimesteps() == 10);
+    IS_TRUE(output_partition_6->getRemainingTimesteps() == 100);
 
 
 
-}
 
 
-void TEST_OUTPUT_CONTAINER() {
 
 
-    // Output_Container output_container = Output_Container(num_hrus, num_steps);
 
 
-    // output_container.insertOutput(1, hru_output2);
-    // output_container.insertOutput(1, hru_output3);
-    // output_container.insertOutput(2, hru_output0);
-    // output_container.insertOutput(2, hru_output3);
-    // std::cout << "\nTesting for out of bounds errors - for 0\n";
-    // output_container.insertOutput(0, hru_output0);
-    // output_container.insertOutput(0, hru_output1);
-    // std::cout << "\nTesting for out of bounds errors - for above max_hru\n";
-    // output_container.insertOutput(5, hru_output2);
-    // std::cout << "\nTesting for buffer full errors\n";
-    // output_container.insertOutput(1, hru_output3);
     
-}
\ No newline at end of file
+
+
+}
diff --git a/build/summa_old b/build/summa_old
new file mode 160000
index 0000000000000000000000000000000000000000..3640d3a30a438396480f8f115a51139bc4d8708e
--- /dev/null
+++ b/build/summa_old
@@ -0,0 +1 @@
+Subproject commit 3640d3a30a438396480f8f115a51139bc4d8708e