From 909e6669536ec2f29814b8a2d7cdf2d95eefcbff Mon Sep 17 00:00:00 2001
From: Kyle Klenk <kyle.c.klenk@gmail.com>
Date: Fri, 20 May 2022 11:44:30 -0600
Subject: [PATCH] Added failedHRU indicator for the file_access_actor

---
 build/makefile                                | 35 +++++++++---------
 build/source/actors/FileAccessActor.h         |  6 ++++
 build/source/actors/HRUActor.h                |  4 +++
 build/source/dshare/globalData.f90            | 17 ++++-----
 .../file_access_actor/cppwrap_fileAccess.f90  | 22 ++++++++++++
 .../fileAccess_subroutine_wrappers.h          |  4 +++
 build/source/netcdf/writeOutput.f90           | 36 +++++++++++++------
 7 files changed, 89 insertions(+), 35 deletions(-)

diff --git a/build/makefile b/build/makefile
index ab14e95..3b8270d 100644
--- a/build/makefile
+++ b/build/makefile
@@ -1,31 +1,31 @@
 #### parent directory of the 'build' directory ####
-# F_MASTER =
+F_MASTER = /home/kklenk/Summa-Actors
 
 #### fortran compiler ####
-# FC = 
+FC = gfortran 
 
 #### C++ compiler ####
-# CC=g++
+CC=g++
 
 #### Includes AND Libraries ####
-# INCLUDES = 
-# LIBRARIES =
+INCLUDES = -I/usr/include
+LIBRARIES = -L/usr/lib -lnetcdff -lnetcdf -lopenblas
 
-# ACTORS_INCLUDES =
-# ACTORS_LIBRARIES =
+ACTORS_INCLUDES = -I/usr/include -I/usr/local/include
+ACTORS_LIBRARIES = -L/home/linuxbrew.linuxbrew/lib -L/home/kklenk/Summa-Actors/build -lcaf_core -lcaf_io -lsumma -lopenblas -lnetcdff
 
 
-# Production runs
-FLAGS_NOAH = -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC
-FLAGS_COMM = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
-FLAGS_SUMMA = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
-FLAGS_ACTORS = -O3
+# # Production runs
+# FLAGS_NOAH = -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC
+# FLAGS_COMM = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
+# FLAGS_SUMMA = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
+# FLAGS_ACTORS = -O3
 
 # # Debug runs
-# FLAGS_NOAH = -pg -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC
-# FLAGS_COMM = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
-# FLAGS_SUMMA = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
-# FLAGS_ACTORS = -pg -g -O0 -Wall
+FLAGS_NOAH = -pg -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC
+FLAGS_COMM = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
+FLAGS_SUMMA = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
+FLAGS_ACTORS = -pg -g -O0 -Wall
 
 
 #========================================================================
@@ -284,9 +284,12 @@ actors_testLink:
 
 actorsClean:
 	rm *.o
+	mv libsumma.so ../bin
+	mv summaMain ../bin
 # Remove object files
 clean:
 	rm -f *.o *.mod soil_veg_gen_parm__genmod.f90
+
 	
 clean_lib:
 	rm *.so
diff --git a/build/source/actors/FileAccessActor.h b/build/source/actors/FileAccessActor.h
index 35e0ef9..83a9fb4 100644
--- a/build/source/actors/FileAccessActor.h
+++ b/build/source/actors/FileAccessActor.h
@@ -129,6 +129,10 @@ behavior file_access_actor(stateful_actor<file_access_state>* self, int startGRU
         [=](run_failure, int indxGRU) {
             int listIndex;
 
+            // update the list in Fortran
+            updateFailed(&indxGRU);
+
+
             listIndex = self->state.output_manager->decrementMaxSize(indxGRU);
           
             // Check if this list is now full
@@ -199,6 +203,8 @@ void initalizeFileAccessActor(stateful_actor<file_access_state>* self) {
         return;
     }
 
+    initFailedHRUTracker(&self->state.numGRU);
+
     Create_Output_File(self->state.handle_ncid, &self->state.numGRU, &self->state.startGRU, &err);
     if (err != 0) {
         aout(self) << "ERROR: Create_OutputFile\n";
diff --git a/build/source/actors/HRUActor.h b/build/source/actors/HRUActor.h
index 68fb729..672d8e5 100644
--- a/build/source/actors/HRUActor.h
+++ b/build/source/actors/HRUActor.h
@@ -133,6 +133,10 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
                 self->state.outputStep += 1;
                 self->state.forcingStep += 1;
 
+                if (self->state.timestep == 450 && self->state.indxGRU == 5) {
+                    err = 20;
+                }
+
                 keepRunning = check_HRU(self, err); // check if we are done, need to write
 
             }
diff --git a/build/source/dshare/globalData.f90 b/build/source/dshare/globalData.f90
index e29a40f..eb26ac3 100755
--- a/build/source/dshare/globalData.f90
+++ b/build/source/dshare/globalData.f90
@@ -279,12 +279,12 @@ MODULE globalData
 
 
  ! define elapsed time
-  real(rkind),save,public                         :: elapsedInit             ! elapsed time for the initialization
-  real(rkind),save,public                         :: elapsedSetup            ! elapsed time for the parameter setup
-  real(rkind),save,public                         :: elapsedRestart          ! elapsed time to read restart data
-  real(rkind),save,public                         :: elapsedRead             ! elapsed time for the data read
-  real(rkind),save,public                         :: elapsedWrite            ! elapsed time for the stats/write
-  real(rkind),save,public                         :: elapsedPhysics          ! elapsed time for the physics
+  real(rkind),save,public                        :: elapsedInit             ! elapsed time for the initialization
+  real(rkind),save,public                        :: elapsedSetup            ! elapsed time for the parameter setup
+  real(rkind),save,public                        :: elapsedRestart          ! elapsed time to read restart data
+  real(rkind),save,public                        :: elapsedRead             ! elapsed time for the data read
+  real(rkind),save,public                        :: elapsedWrite            ! elapsed time for the stats/write
+  real(rkind),save,public                        :: elapsedPhysics          ! elapsed time for the physics
 
   ! define ancillary data structures
   type(var_i),save,public                        :: startTime               ! start time for the model simulation
@@ -305,9 +305,10 @@ MODULE globalData
 
 
   !!!!!!!!!!!!!!!!!!GLOBAL DATA STRUCTURES THAT ARE MANAGED BY FILEACCESSACTOR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-  type(var_forc),allocatable,save,public          :: forcingDataStruct(:)            ! forcingDataStruct(:)%var(:)%dataFromFile(:,:)
+  type(var_forc),allocatable,save,public          :: forcingDataStruct(:)      ! forcingDataStruct(:)%var(:)%dataFromFile(:,:)
   type(dlength),allocatable,save,public           :: vecTime(:)
-  type(summa_output_type),allocatable,save,public :: outputStructure(:)             ! summa_OutputStructure(iFile)%struc%var(:)%dat(nTimeSteps) 
+  type(summa_output_type),allocatable,save,public :: outputStructure(:)        ! summa_OutputStructure(iFile)%struc%var(:)%dat(nTimeSteps) 
+  logical(lgt),allocatable,save,public            :: failedHRUs(:)             ! list of true and false values to indicate if an HRU has failed              
   !!!!!!!!!!!!!!!!!!GLOBAL DATA STRUCTURES THAT ARE MANAGED BY FILEACCESSACTOR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
   ! define fixed dimensions
diff --git a/build/source/interface/file_access_actor/cppwrap_fileAccess.f90 b/build/source/interface/file_access_actor/cppwrap_fileAccess.f90
index db39100..1485c65 100644
--- a/build/source/interface/file_access_actor/cppwrap_fileAccess.f90
+++ b/build/source/interface/file_access_actor/cppwrap_fileAccess.f90
@@ -13,6 +13,7 @@ module cppwrap_fileAccess
   public::ffile_info_C
   public::mDecisions_C
   public::Init_OutputStruct
+  public::initFailedHRUTracker
   public::FileAccessActor_ReadForcing
   public::Create_Output_File
   public::FileAccessActor_WriteOutput
@@ -122,6 +123,27 @@ subroutine read_vegitationTables(err) bind(C, name="read_vegitationTables")
   
 end subroutine
 
+! allocate the failedHRU logical array and intialize it with all false values
+subroutine initFailedHRUTracker(numGRU) bind(C, name="initFailedHRUTracker")
+  USE globalData,only:failedHRUs
+  implicit none
+  integer(c_int), intent(in)        :: numGRU
+
+  allocate(failedHRUs(numGRU))
+
+  failedHRUs(:) = .false.
+
+
+end subroutine
+
+subroutine updateFailed(indxHRU) bind(C, name="updateFailed")
+  USE globalData,only:failedHRUs
+  implicit none
+  integer(c_int), intent(in)        :: indxHRU
+
+  failedHRUs(indxHRU) = .true.
+end subroutine
+
 
 subroutine resetOutputCounter(indxGRU) bind(C, name="resetOutputCounter")
   USE globalData,only:outputTimeStep
diff --git a/build/source/interface/file_access_actor/fileAccess_subroutine_wrappers.h b/build/source/interface/file_access_actor/fileAccess_subroutine_wrappers.h
index 4f743e3..15fe94c 100644
--- a/build/source/interface/file_access_actor/fileAccess_subroutine_wrappers.h
+++ b/build/source/interface/file_access_actor/fileAccess_subroutine_wrappers.h
@@ -8,6 +8,10 @@ extern "C" {
 
   void read_vegitationTables(int* err);
 
+  void initFailedHRUTracker(int* numGRU);
+
+  void updateFailed(int* indxHRU);
+
   void resetOutputCounter(int* indxGRU);
   
   void mDecisions_C(int* numSteps, int* err);
diff --git a/build/source/netcdf/writeOutput.f90 b/build/source/netcdf/writeOutput.f90
index f1ff324..0a8929a 100644
--- a/build/source/netcdf/writeOutput.f90
+++ b/build/source/netcdf/writeOutput.f90
@@ -161,6 +161,7 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,indxGRU,
   USE globalData,only:outFreq                        ! output file information
   USE globalData,only:outputStructure
   USE globalData,only:gru_struc
+  USE globalData,only:failedHRUs
   USE get_ixName_module,only:get_varTypeName         ! to access type strings for error messages
   USE get_ixName_module,only:get_statName            ! to access type strings for error messages
 
@@ -202,10 +203,12 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,indxGRU,
   integer(i4b)                     :: dataType          ! type of data
   integer(i4b),parameter           :: ixInteger=1001    ! named variable for integer
   integer(i4b),parameter           :: ixReal=1002       ! named variable for real
-  integer(i4b)                     :: stepCounter     ! counter to know how much data we have to write
+  integer(i4b)                     :: stepCounter       ! counter to know how much data we have to write, needed because we do not always write nSteps
   integer(i4b)                     :: gruCounter
   integer(i4b)                     :: iStep
   integer(i4b)                     :: iGRU
+  integer(i4b)                     :: verifiedGRUIndex    ! index of HRU verified to not have failed
+  integer(i4b)                     :: verifiedStepCounter ! numStepsForStepCounter from HRU that did not fail
   ! initialize error control
   err=0;message="writeData/"
   ! loop through output frequencies
@@ -221,12 +224,22 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,indxGRU,
         ! get variable index
         err = nf90_inq_varid(ncid%var(iFreq),trim(meta(iVar)%varName),ncVarID)
         call netcdf_err(err,message); if (err/=0) return
+        
+        ! make sure the HRU we are using has not failed
+        do iGRU = minGRU, maxGRU
+          if(.not.failedHRUs(iGRU))then
+            verifiedGRUIndex = iGRU
+            exit
+          endif
+        end do
+
         do iStep = 1, nSteps
           ! check if we want this timestep
-          if(.not.outputStructure(1)%finalizeStats(1)%gru(minGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle
+          if(.not.outputStructure(1)%finalizeStats(1)%gru(verifiedGRUIndex)%hru(1)%tim(iStep)%dat(iFreq)) cycle
           stepCounter = stepCounter+1
-          timeVec(stepCounter) = outputStructure(1)%forcStruct(1)%gru(minGRU)%hru(1)%var(iVar)%tim(iStep)
+          timeVec(stepCounter) = outputStructure(1)%forcStruct(1)%gru(verifiedGRUIndex)%hru(1)%var(iVar)%tim(iStep)
         end do ! iStep
+
         err = nf90_put_var(ncid%var(iFreq),ncVarID,timeVec(1:stepCounter),start=(/outputTimestep(iFreq)/),count=(/stepCounter/))
         call netcdf_err(err,message); if (err/=0)then; print*, "err"; return; endif
         ! save the value of the number of steps to update outputTimestep at the end of the function
@@ -244,22 +257,23 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,indxGRU,
           if(meta(iVar)%varType==iLookVarType%scalarv) then
             select type(stat)
               class is (gru_hru_time_doubleVec)
-                
                 gruCounter = 0
                 do iGRU = minGRU, maxGRU
                   stepCounter = 0
                   gruCounter = gruCounter + 1
                   do iStep = 1, nSteps
-                    if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle
+                    if(.not.outputStructure(1)%finalizeStats(1)%gru(verifiedGRUIndex)%hru(1)%tim(iStep)%dat(iFreq)) cycle
                     stepCounter = stepCounter + 1
                     realVec(gruCounter, stepCounter) = stat%gru(iGRU)%hru(1)%var(map(iVar))%tim(iStep)%dat(iFreq)
                   end do ! iStep
-                  
                 end do ! iGRU
 
                 err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),realVec(1:gruCounter, 1:stepCounter),start=(/minGRU,outputTimestep(iFreq)/),count=(/numGRU,stepCounter/))
                 if (outputTimeStepUpdate(iFreq) /= stepCounter ) then
-                  print*, "ERROR Missmatch in Steps"
+                  print*, "ERROR Missmatch in Steps - stat doubleVec"
+                  print*, "iFreq = ", iFreq
+                  print*, "outputTimeStepUpdate(iFreq) = ", outputTimeStepUpdate(iFreq)
+                  print*, "stepCounter = ", stepCounter
                   return
                 endif
               class default; err=20; message=trim(message)//'stats must be scalarv and of type gru_hru_doubleVec'; return
@@ -297,14 +311,14 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,indxGRU,
             select type (dat)
                 class is (gru_hru_time_doubleVec)
                   do iStep = 1, nSteps
-                    if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle
+                    if(.not.outputStructure(1)%finalizeStats(1)%gru(verifiedGRUIndex)%hru(1)%tim(iStep)%dat(iFreq)) cycle
                     stepCounter = stepCounter + 1
                     realArray(stepCounter,1:datLength) = dat%gru(iGRU)%hru(1)%var(iVar)%tim(iStep)%dat(:)
                   end do
 
                 class is (gru_hru_time_intVec)
                   do iStep = 1, nSteps
-                    if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle
+                    if(.not.outputStructure(1)%finalizeStats(1)%gru(verifiedGRUIndex)%hru(1)%tim(iStep)%dat(iFreq)) cycle
                     stepCounter = stepCounter + 1
                     intArray(stepCounter,1:datLength) = dat%gru(iGRU)%hru(1)%var(iVar)%tim(iStep)%dat(:)
                   end do
@@ -329,14 +343,14 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,indxGRU,
 
                 err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),realArray(1:stepCounter,:),start=(/iGRU,1,outputTimestep(iFreq)/),count=(/1,maxLength,stepCounter/))
                 if (outputTimeStepUpdate(iFreq) /= stepCounter ) then
-                  print*, "ERROR Missmatch in Steps"
+                  print*, "ERROR Missmatch in Steps - ixReal"
                   return
                 endif
               case(ixInteger)
 
                 err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),intArray(1:stepCounter,:),start=(/iGRU,1,outputTimestep(iFreq)/),count=(/1,maxLength,stepCounter/))
                 if (outputTimeStepUpdate(iFreq) /= stepCounter ) then
-                  print*, "ERROR Missmatch in Steps"
+                  print*, "ERROR Missmatch in Steps - ixInteger"
                   return
                 endif
               case default; err=20; message=trim(message)//'data must be of type integer or real'; return
-- 
GitLab