diff --git a/build/includes/global/message_atoms.hpp b/build/includes/global/message_atoms.hpp index 11b425b48f07f462246d5e795dd44bd411066765..e185dcfc20776e2854e0e109f98c5e0654037383 100644 --- a/build/includes/global/message_atoms.hpp +++ b/build/includes/global/message_atoms.hpp @@ -7,6 +7,8 @@ CAF_BEGIN_TYPE_ID_BLOCK(summa, first_custom_type_id) CAF_ADD_ATOM(summa, start_summa) CAF_ADD_ATOM(summa, done_job) CAF_ADD_ATOM(summa, err) + // GRU Actor + CAF_ADD_ATOM(summa, init_gru) // Job Actor CAF_ADD_ATOM(summa, done_reading_forcingFile) CAF_ADD_ATOM(summa, done_reading_first_forcing_file) diff --git a/build/includes/gru_actor/gru_actor.hpp b/build/includes/gru_actor/gru_actor.hpp index 00afc6905645dbd6a88406d3351833283824800d..95c257c1a1c0ab1b7680c282e5fa3f5878cc3e9b 100644 --- a/build/includes/gru_actor/gru_actor.hpp +++ b/build/includes/gru_actor/gru_actor.hpp @@ -3,7 +3,8 @@ #include "caf/all.hpp" #include "fortran_data_types.hpp" #include "timing_info.hpp" - +#include <vector> +#include <array> #include <chrono> #include <string> @@ -11,9 +12,21 @@ namespace caf{ struct gru_state { caf::actor file_access_actor; caf::actor parent; + + std::vector<caf::actor> hru_list; + + int indx_gru; // index for gru part of derived types in FORTRAN + int ref_gru; // The actual ID of the GRU we are + int num_hrus; - int indxGRU; // index for gru part of derived types in FORTRAN - int refGRU; // The actual ID of the GRU we are - int numHRUs; + int num_bpar_vars; // number of variables in the fortran structure for bpar_struct + int num_bvar_vars; // number of variables in the fortran structure for bvar_struct + int n_time_delay = 2000; // number of timesteps in the time delay historgram. + std::vector<double> bpar_struct; + std::vector<std::vector<double>> bvar_struct; }; + +behavior gru_actor(stateful_actor<gru_state>* self, int refGRU, int indxGRU, + std::string configPath, + int outputStrucSize, caf::actor parent); } \ No newline at end of file diff --git a/build/includes/gru_actor/gru_actor_subroutine_wrapper.hpp b/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp similarity index 52% rename from build/includes/gru_actor/gru_actor_subroutine_wrapper.hpp rename to build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp index 8ac785596a086f427ff2eebbf995f096ecd25e71..fea4861fa1ff1389fe9828f4b9d6c760ca6abdbb 100644 --- a/build/includes/gru_actor/gru_actor_subroutine_wrapper.hpp +++ b/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp @@ -1,4 +1,7 @@ #pragma once extern "C" { + + void getVarSize(); + } \ No newline at end of file diff --git a/build/includes/gru_actor/gru_data_structure.hpp b/build/includes/gru_actor/gru_data_structure.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3f59c932d39b02caf58f2abac65bdd9246f0a7da --- /dev/null +++ b/build/includes/gru_actor/gru_data_structure.hpp @@ -0,0 +1,2 @@ +#pragma once + diff --git a/build/makefile b/build/makefile index d42c2ece7046c500fbf43bfb8507aa912240e0bb..1154336f25231682e01e1b161facb039b64252cc 100644 --- a/build/makefile +++ b/build/makefile @@ -55,6 +55,7 @@ ACTORS_DIR = $(F_KORE_DIR)/actors JOB_ACTOR_DIR = $(ACTORS_DIR)/job_actor FILE_ACCESS_DIR = $(ACTORS_DIR)/file_access_actor HRU_ACTOR_DIR = $(ACTORS_DIR)/hru_actor +GRU_ACTOR_DIR = $(ACTORS_DIR)/gru_actor # utilities SUMMA_NRUTIL= \ @@ -151,6 +152,11 @@ SUMMA_HRU_INTERFACE = \ cppwrap_hru.f90 HRU_INTERFACE = $(patsubst %, $(HRU_ACTOR_DIR)/%, $(SUMMA_HRU_INTERFACE)) + +SUMMA_GRU_INTERFACE = \ + gru_actor.f90 + +GRU_INTERFACE = $(patsubst %, $(GRU_ACTOR_DIR)/%, $(SUMMA_GRU_INTERFACE)) # Define routines for SUMMA preliminaries @@ -257,6 +263,9 @@ SUMMA_SERVER = $(SOURCE_DIR)/summa_actor/summa_server.cpp BATCH_MANGER = $(SOURCE_DIR)/summa_actor/batch_manager.cpp CLIENT_MANAGER = $(SOURCE_DIR)/summa_actor/client.cpp +GRU_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/gru_actor +GRU_ACTOR = $(SOURCE_DIR)/gru_actor/gru_actor.cpp + JOB_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/job_actor JOB_ACTOR = $(SOURCE_DIR)/job_actor/job_actor.cpp GRUinfo = $(SOURCE_DIR)/job_actor/GRUinfo.cpp @@ -284,7 +293,7 @@ all: fortran cpp fortran: compile_noah compile_comm compile_summa link clean_fortran -cpp: compile_globals compile_hru_actor compile_file_access_actor compile_job_actor compile_summa_actor \ +cpp: compile_globals compile_hru_actor compile_gru_actor compile_file_access_actor compile_job_actor compile_summa_actor \ compile_summa_client compile_summa_server compile_main link_cpp clean_cpp test: actors_test actors_testLink actorsClean @@ -301,7 +310,7 @@ compile_comm: # compile SUMMA routines compile_summa: - $(FC) $(FLAGS_SUMMA) -c $(SUMMA_ALL) $(DRIVER) $(INTERFACE) $(JOB_INTERFACE) $(FILEACCESS_INTERFACE) $(HRU_INTERFACE) $(INCLUDES) + $(FC) $(FLAGS_SUMMA) -c $(SUMMA_ALL) $(DRIVER) $(INTERFACE) $(JOB_INTERFACE) $(FILEACCESS_INTERFACE) $(HRU_INTERFACE) $(GRU_INTERFACE) $(INCLUDES) # generate library link: @@ -322,6 +331,9 @@ clean_fortran: compile_globals: $(CC) $(FLAGS_ACTORS) -c $(GLOBAL) $(TIMEINFO) $(GLOBAL_INCLUDES) +compile_gru_actor: + $(CC) $(FLAGS_ACTORS) -c $(GRU_ACTOR) $(GRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) + compile_hru_actor: $(CC) $(FLAGS_ACTORS) -c $(HRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) @@ -331,7 +343,7 @@ compile_file_access_actor: compile_job_actor: $(CC) $(FLAGS_ACTORS) -c $(JOB_ACTOR) $(GRUinfo) $(JOB_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) \ - $(FILE_ACCESS_ACTOR_INCLUDES) $(HRU_ACTOR_INCLUDES) + $(FILE_ACCESS_ACTOR_INCLUDES) $(HRU_ACTOR_INCLUDES) $(GRU_ACTOR_INCLUDES) compile_summa_actor: $(CC) $(FLAGS_ACTORS) -c $(SUMMA_ACTOR) $(SUMMA_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) \ diff --git a/build/source/actors/gru_actor/gru_actor.cpp b/build/source/actors/gru_actor/gru_actor.cpp index 84610cc8c5b8f9a323535eed9a0829b4dbf9afcc..5c19f1895a5909d9365e63953bdc18e0c1978981 100644 --- a/build/source/actors/gru_actor/gru_actor.cpp +++ b/build/source/actors/gru_actor/gru_actor.cpp @@ -7,8 +7,22 @@ namespace caf { behavior gru_actor(stateful_actor<gru_state>* self, int refGRU, int indxGRU, - std::string configPath, int outputStrucSize, caf::actor parent) + std::string configPath, int outputStrucSize, caf::actor parent) { + aout(self) << "GRU Actor Has Started\n"; + return { + + + // What does a GRU need to assemble its data structure? + // + [=](init_gru) { + // Get the variable data length, we also need the type information + aout(self) << "init GRU"; + } + + + }; +} } \ No newline at end of file diff --git a/build/source/actors/gru_actor/gru_actor.f90 b/build/source/actors/gru_actor/gru_actor.f90 index 6b371417206238cb95d211d43c445a2e23d2597c..98d8fb4cf7d5c02396b216971527cbad9974af0d 100644 --- a/build/source/actors/gru_actor/gru_actor.f90 +++ b/build/source/actors/gru_actor/gru_actor.f90 @@ -4,91 +4,85 @@ module gru_actor implicit none ! public::run_gru -public::init_basin_for_timestep +public::getVarSizes +! public::run_gru_for_timestep() contains -subroutine init_basin_for_timestep() + +subroutine getVarSizes() bind(C,name="getVarSizes") + USE globalData,only:bpar_meta,bvar_meta implicit none - ! initialize runoff variables - bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = 0._dp ! surface runoff (m s-1) - bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = 0._dp - bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1) = 0._dp ! outflow from all "outlet" HRUs (those with no downstream HRU) - bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = 0._dp +end subroutine getVarSizes - ! initialize baseflow variables - bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = 0._dp ! recharge to the aquifer (m s-1) - bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = 0._dp ! baseflow from the aquifer (m s-1) - bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = 0._dp ! transpiration loss from the aquifer (m s-1) - -end subroutine -subroutine run_hru_for_timestep() - implicit none - ! initialize runoff variables - bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = 0._dp ! surface runoff (m s-1) - bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = 0._dp - bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1) = 0._dp ! outflow from all "outlet" HRUs (those with no downstream HRU) - bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = 0._dp +! subroutine run_gru_for_timestep() +! implicit none + +! ! initialize runoff variables +! bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = 0._dp ! surface runoff (m s-1) +! bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = 0._dp +! bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1) = 0._dp ! outflow from all "outlet" HRUs (those with no downstream HRU) +! bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = 0._dp - ! initialize baseflow variables - bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = 0._dp ! recharge to the aquifer (m s-1) - bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = 0._dp ! baseflow from the aquifer (m s-1) - bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = 0._dp ! transpiration loss from the aquifer (m s-1) +! ! initialize baseflow variables +! bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = 0._dp ! recharge to the aquifer (m s-1) +! bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = 0._dp ! baseflow from the aquifer (m s-1) +! bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = 0._dp ! transpiration loss from the aquifer (m s-1) - ! ----- calculate weighted basin (GRU) fluxes -------------------------------------------------------------------------------------- +! ! ----- calculate weighted basin (GRU) fluxes -------------------------------------------------------------------------------------- - ! increment basin surface runoff (m s-1) - bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + fluxStruct%var(iLookFLUX%scalarSurfaceRunoff)%dat(1) * fracHRU +! ! increment basin surface runoff (m s-1) +! bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + fluxStruct%var(iLookFLUX%scalarSurfaceRunoff)%dat(1) * fracHRU - !increment basin soil drainage (m s-1) - bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) * fracHRU +! !increment basin soil drainage (m s-1) +! bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) * fracHRU - ! increment aquifer variables -- ONLY if aquifer baseflow is computed individually for each HRU and aquifer is run - ! NOTE: groundwater computed later for singleBasin - if(model_decisions(iLookDECISIONS%spatial_gw)%iDecision == localColumn .and. model_decisions(iLookDECISIONS%groundwatr)%iDecision == bigBucket) then +! ! increment aquifer variables -- ONLY if aquifer baseflow is computed individually for each HRU and aquifer is run +! ! NOTE: groundwater computed later for singleBasin +! if(model_decisions(iLookDECISIONS%spatial_gw)%iDecision == localColumn .and. model_decisions(iLookDECISIONS%groundwatr)%iDecision == bigBucket) then - bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) * fracHRU - bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) + fluxStruct%var(iLookFLUX%scalarAquiferTranspire)%dat(1) * fracHRU - bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) & - + fluxStruct%var(iLookFLUX%scalarAquiferBaseflow)%dat(1) * fracHRU - end if +! bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) * fracHRU +! bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) + fluxStruct%var(iLookFLUX%scalarAquiferTranspire)%dat(1) * fracHRU +! bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) & +! + fluxStruct%var(iLookFLUX%scalarAquiferBaseflow)%dat(1) * fracHRU +! end if - ! perform the routing - associate(totalArea => bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1) ) +! ! perform the routing +! associate(totalArea => bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1) ) - ! compute water balance for the basin aquifer - if(model_decisions(iLookDECISIONS%spatial_gw)%iDecision == singleBasin)then - message=trim(message)//'multi_driver/bigBucket groundwater code not transferred from old code base yet' - err=20; return - end if +! ! compute water balance for the basin aquifer +! if(model_decisions(iLookDECISIONS%spatial_gw)%iDecision == singleBasin)then +! message=trim(message)//'multi_driver/bigBucket groundwater code not transferred from old code base yet' +! err=20; return +! end if - ! calculate total runoff depending on whether aquifer is connected - if(model_decisions(iLookDECISIONS%groundwatr)%iDecision == bigBucket) then - ! aquifer - bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1)/totalArea + bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) - else - ! no aquifer - bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1)/totalArea + bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) - endif +! ! calculate total runoff depending on whether aquifer is connected +! if(model_decisions(iLookDECISIONS%groundwatr)%iDecision == bigBucket) then +! ! aquifer +! bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1)/totalArea + bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) +! else +! ! no aquifer +! bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1)/totalArea + bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) +! endif - call qOverland(& - ! input - model_decisions(iLookDECISIONS%subRouting)%iDecision, & ! intent(in): index for routing method - bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1), & ! intent(in): total runoff to the channel from all active components (m s-1) - bvarStruct%var(iLookBVAR%routingFractionFuture)%dat, & ! intent(in): fraction of runoff in future time steps (m s-1) - bvarStruct%var(iLookBVAR%routingRunoffFuture)%dat, & ! intent(in): runoff in future time steps (m s-1) - ! output - bvarStruct%var(iLookBVAR%averageInstantRunoff)%dat(1), & ! intent(out): instantaneous runoff (m s-1) - bvarStruct%var(iLookBVAR%averageRoutedRunoff)%dat(1), & ! intent(out): routed runoff (m s-1) - err,message) ! intent(out): error control - if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif - end associate +! call qOverland(& +! ! input +! model_decisions(iLookDECISIONS%subRouting)%iDecision, & ! intent(in): index for routing method +! bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1), & ! intent(in): total runoff to the channel from all active components (m s-1) +! bvarStruct%var(iLookBVAR%routingFractionFuture)%dat, & ! intent(in): fraction of runoff in future time steps (m s-1) +! bvarStruct%var(iLookBVAR%routingRunoffFuture)%dat, & ! intent(in): runoff in future time steps (m s-1) +! ! output +! bvarStruct%var(iLookBVAR%averageInstantRunoff)%dat(1), & ! intent(out): instantaneous runoff (m s-1) +! bvarStruct%var(iLookBVAR%averageRoutedRunoff)%dat(1), & ! intent(out): routed runoff (m s-1) +! err,message) ! intent(out): error control +! if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif +! end associate -end subroutine +! end subroutine diff --git a/build/source/actors/job_actor/job_actor.cpp b/build/source/actors/job_actor/job_actor.cpp index 1fb5f5e1f0760b9cc140fd2168c0011a66731104..8cbb5a93959e4d746f126073a7f80cfabe29dee7 100644 --- a/build/source/actors/job_actor/job_actor.cpp +++ b/build/source/actors/job_actor/job_actor.cpp @@ -7,6 +7,7 @@ #include "global.hpp" #include "job_actor_subroutine_wrappers.hpp" #include "hru_actor.hpp" +#include "gru_actor.hpp" using json = nlohmann::json; @@ -131,7 +132,11 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, [=](done_file_access_actor_init) { // Init GRU Actors and the Output Structure - self->send(self, init_hru_v); + // self->send(self, init_hru_v);s + auto gru = self->spawn(gru_actor, 1, 1, + self->state.configPath, + self->state.outputStrucSize, self); + self->send(gru, init_gru_v); }, [=](file_access_actor_done, double read_duration, double write_duration) { diff --git a/utils/laugh_tests/celia1990/output/runinfo.txt b/utils/laugh_tests/celia1990/output/runinfo.txt index 3bdf9dca0db5e67d7f65e281dd9aad18332981d9..61332a3ae36c8c0bc08fed05630c3e216ac1c2f5 100644 --- a/utils/laugh_tests/celia1990/output/runinfo.txt +++ b/utils/laugh_tests/celia1990/output/runinfo.txt @@ -1 +1 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=16 - hh=21 - mi=31 - ss=01.667 + Run start time on system: ccyy=2022 - mm=08 - dd=17 - hh=22 - mi=42 - ss=53.312 diff --git a/utils/laugh_tests/celia1990/output/summa-actors_celia1990GRU1-1_timestep.nc b/utils/laugh_tests/celia1990/output/summa-actors_celia1990GRU1-1_timestep.nc index d173a6235ac81f1f920965a1ab7d4091db3dcb0a..0fb39e4297953022c8a5873cd1dcfe2bd1b056c9 100644 Binary files a/utils/laugh_tests/celia1990/output/summa-actors_celia1990GRU1-1_timestep.nc and b/utils/laugh_tests/celia1990/output/summa-actors_celia1990GRU1-1_timestep.nc differ