diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a17d1d6876ad80c9a6fc714a70a4770410257745 --- /dev/null +++ b/build/CMakeLists.txt @@ -0,0 +1,284 @@ +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) + +set(PARENT_DIR /Summa-Actors) +set(EXEC_DIR ${PARENT_DIR}/bin) + +set(EXEC_NAME summa_actors) + +project(summa_actors LANGUAGES CXX Fortran) +enable_language(C) +SET (CMAKE_Fortran_COMPILER gfortran) +include(FortranCInterface) +FortranCInterface_VERIFY(CXX) + +set(ACTORS_DIR ${PARENT_DIR}/build/source/actors) +set(DRIVER_DIR ${PARENT_DIR}/build/source/driver) +set(DSHARE_DIR ${PARENT_DIR}/build/source/dshare) +set(ENGINE_DIR ${PARENT_DIR}/build/source/engine) +set(HOOKUP_DIR ${PARENT_DIR}/build/source/hookup) +set(NETCDF_DIR ${PARENT_DIR}/build/source/netcdf) +set(NOAHMP_DIR ${PARENT_DIR}/build/source/noah-mp) +set(FILE_ACCESS_DIR ${ACTORS_DIR}/file_acces_actor) +set(JOB_ACTOR_DIR ${ACTORS_DIR}/job_actor) +set(HRU_ACTOR_DIR ${ACTORS_DIR}/hru_actor) +set(GRU_ACTOR_DIR ${ACTORS_DIR}/gru_actor) + +set(NRUTIL + ${ENGINE_DIR}/nrtype.f90 + ${ENGINE_DIR}/f2008funcs.f90 + ${ENGINE_DIR}/nr_utility.f90) + +set(NRPROC + ${ENGINE_DIR}/expIntegral.f90 + ${ENGINE_DIR}/spline_int.f90) + +SET(HOOKUP + ${HOOKUP_DIR}/ascii_util.f90 + ${HOOKUP_DIR}/summaActors_FileManager.f90) + +SET(DATAMS + ${DSHARE_DIR}/multiconst.f90 + ${DSHARE_DIR}/var_lookup.f90 + ${DSHARE_DIR}/data_types.f90 + ${DSHARE_DIR}/globalData.f90 + ${DSHARE_DIR}/flxMapping.f90 + ${DSHARE_DIR}/get_ixname.f90) + +SET(DEPENDS_ON_FILEMANAGER + ${DSHARE_DIR}/popMetadat.f90 + ${DSHARE_DIR}/outpt_stat.f90) + +SET(UTILMS + ${ENGINE_DIR}/time_utils.f90 + ${ENGINE_DIR}/mDecisions.f90 + ${ENGINE_DIR}/snow_utils.f90 + ${ENGINE_DIR}/soil_utils.f90 + ${ENGINE_DIR}/updatState.f90 + ${ENGINE_DIR}/matrixOper.f90) + +set(SOLVER + ${ENGINE_DIR}/vegPhenlgy.f90 + ${ENGINE_DIR}/diagn_evar.f90 + ${ENGINE_DIR}/stomResist.f90 + ${ENGINE_DIR}/groundwatr.f90 + ${ENGINE_DIR}/vegSWavRad.f90 + ${ENGINE_DIR}/vegNrgFlux.f90 + ${ENGINE_DIR}/ssdNrgFlux.f90 + ${ENGINE_DIR}/vegLiqFlux.f90 + ${ENGINE_DIR}/snowLiqFlx.f90 + ${ENGINE_DIR}/soilLiqFlx.f90 + ${ENGINE_DIR}/bigAquifer.f90 + ${ENGINE_DIR}/computFlux.f90 + ${ENGINE_DIR}/computResid.f90 + ${ENGINE_DIR}/computJacob.f90 + ${ENGINE_DIR}/eval8summa.f90 + ${ENGINE_DIR}/summaSolve.f90 + ${ENGINE_DIR}/systemSolv.f90 + ${ENGINE_DIR}/varSubstep.f90 + ${ENGINE_DIR}/opSplittin.f90 + ${ENGINE_DIR}/coupled_em.f90) + +set(INTERFACE + ${ACTORS_DIR}/global/cppwrap_datatypes.f90 + ${ACTORS_DIR}/global/cppwrap_auxiliary.f90 + ${ACTORS_DIR}/global/cppwrap_metadata.f90) + +set(FILE_ACCESS_INTERFACE + ${FILE_ACCESS_DIR}/initOutputStruc.f90 + ${FILE_ACCESS_DIR}/deallocateOutputStruc.f90 + ${FILE_ACCESS_DIR}/cppwrap_fileAccess.f90) + +set(JOB_INTERFACE + ${JOB_ACTOR_DIR}/job_actor.f90) + +set(HRU_INTERFACE + ${HRU_ACTOR_DIR}/cppwrap_hru.f90) + +set(GRU_INTERFACE + ${GRU_ACTOR_DIR}/gru_actor.f90) + +set(PRELIM + ${ENGINE_DIR}/conv_funcs.f90 + ${ENGINE_DIR}/sunGeomtry.f90 + ${ENGINE_DIR}/convE2Temp.f90 + ${ENGINE_DIR}/allocspaceActors.f90 + ${ENGINE_DIR}/alloc_file_access.f90 + ${ENGINE_DIR}/checkStruc.f90 + ${ENGINE_DIR}/childStruc.f90 + ${ENGINE_DIR}/ffile_info.f90 + ${ENGINE_DIR}/read_attribute.f90 + ${ENGINE_DIR}/read_pinit.f90 + ${ENGINE_DIR}/pOverwrite.f90 + ${ENGINE_DIR}/read_paramActors.f90 + ${ENGINE_DIR}/paramCheck.f90 + ${ENGINE_DIR}/check_icondActors.f90) + +set(NOAHMP + ${NOAHMP_DIR}/module_model_constants.F + ${NOAHMP_DIR}/module_sf_noahutl.F + ${NOAHMP_DIR}/module_sf_noahlsm.F + ${NOAHMP_DIR}/module_sf_noahmplsm.F) + +set(MODRUN + ${ENGINE_DIR}/indexState.f90 + ${ENGINE_DIR}/getVectorz.f90 + ${ENGINE_DIR}/updateVars.f90 + ${ENGINE_DIR}/var_derive.f90 + ${ENGINE_DIR}/read_forcingActors.f90 + ${ENGINE_DIR}/access_forcing.f90 + ${ENGINE_DIR}/access_write.f90 + ${ENGINE_DIR}/derivforce.f90 + ${ENGINE_DIR}/snowAlbedo.f90 + ${ENGINE_DIR}/canopySnow.f90 + ${ENGINE_DIR}/tempAdjust.f90 + ${ENGINE_DIR}/snwCompact.f90 + ${ENGINE_DIR}/layerMerge.f90 + ${ENGINE_DIR}/layerDivide.f90 + ${ENGINE_DIR}/volicePack.f90 + ${ENGINE_DIR}/qTimeDelay.f90) + +set(NETCDF + ${NETCDF_DIR}/netcdf_util.f90 + ${NETCDF_DIR}/def_output.f90 + ${NETCDF_DIR}/outputStrucWrite.f90 + ${NETCDF_DIR}/writeOutput.f90 + ${NETCDF_DIR}/read_icondActors.f90) + +set(DRIVER + ${DRIVER_DIR}/summaActors_type.f90 + ${DRIVER_DIR}/summaActors_util.f90 + ${DRIVER_DIR}/summaActors_globalData.f90 + ${DRIVER_DIR}/summaActors_init.f90 + ${DRIVER_DIR}/SummaActors_setup.f90 + ${DRIVER_DIR}/summaActors_restart.f90 + ${DRIVER_DIR}/summaActors_forcing.f90 + ${DRIVER_DIR}/SummaActors_modelRun.f90 + ${DRIVER_DIR}/summaActors_alarms.f90 + ${DRIVER_DIR}/summaActors_wOutputStruc.f90) + +set(COMM_ALL + ${NRUTIL} + ${NRPROC} + ${DATAMS} + ${INTERFACE} + ${HOOKUP} + ${DEPENDS_ON_FILEMANAGER} + ${UTILMS}) + +set(SUMMA_ALL + ${NETCDF} + ${PRELIM} + ${MODRUN} + ${SOLVER} + ${DRIVER} + ${JOB_INTERFACE} + ${HRU_INTERFACE} + ${GRU_INTERFACE}) + +set(ACTORS_GLOBAL + ${ACTORS_DIR}/global/global.cpp + ${ACTORS_DIR}/global/timing_info.cpp) + +set(HRU_ACTOR + ${ACTORS_DIR}/hru_actor/hru_actor.cpp) + +set(GRU_ACTOR + ${ACTORS_DIR}/gru_actor/gru_actor.cpp) + +set(FILE_ACCESS_ACTOR + ${ACTORS_DIR}/file_access_actor/file_access_actor.cpp + ${ACTORS_DIR}/file_access_actor/forcing_file_info.cpp + ${ACTORS_DIR}/file_access_actor/output_manager.cpp) + +set(JOB_ACTOR + ${ACTORS_DIR}/job_actor/job_actor.cpp + ${ACTORS_DIR}/job_actor/GRUinfo.cpp) + +set(SUMMA_ACTOR + ${ACTORS_DIR}/summa_actor/summa_actor.cpp) + +set(SUMMA_CLIENT + ${ACTORS_DIR}/summa_actor/summa_client.cpp) + +set(SUMMA_SERVER + ${ACTORS_DIR}/summa_actor/summa_server.cpp + ${ACTORS_DIR}/summa_actor/batch_manager.cpp + ${ACTORS_DIR}/summa_actor/client.cpp) + +set(MAIN + ${ACTORS_DIR}/main.cpp) + + + + +add_library(SUMMA_NOAHMP OBJECT + ${NOAHMP} + ${NRUTIL}) + target_compile_options(SUMMA_NOAHMP PRIVATE + -g -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors) + +add_library(SUMMA_COMM OBJECT + ${COMM_ALL}) + target_compile_options(SUMMA_COMM PRIVATE + -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors) + target_include_directories(SUMMA_COMM PRIVATE + "/usr/include" + ${netCDF_INCLUDES} + ${LAPACK_INCLUDES}) + target_link_libraries(SUMMA_COMM PUBLIC + ${netCDF_LIBRARIES} + ${LAPACK_LIBRARIES} + SUMMA_NOAHMP) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXEC_DIR}) + +add_library(summa SHARED + ${SUMMA_ALL}) + target_compile_options(summa PRIVATE + -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors) + target_include_directories(summa PRIVATE + "/usr/include" + ${netCDF_INCLUDES} + ${LAPACK_INCLUDES}) + target_link_libraries(summa PUBLIC + ${netCDF_LIBRARIES} + ${LAPACK_LIBRARIES} + SUMMA_COMM) + +set(CMAKE_CXX_FLAGS "-g -O3 -Wfatal-errors -std=c++17") + +find_package(CAF REQUIRED) +find_package(netCDF REQUIRED) +find_package(LAPACK REQUIRED) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXEC_DIR}) + +add_executable(${EXEC_NAME} + ${ACTORS_GLOBAL} + ${HRU_ACTOR} + ${GRU_ACTOR} + ${FILE_ACCESS_ACTOR} + ${JOB_ACTOR} + ${SUMMA_ACTOR} + ${SUMMA_CLIENT} + ${SUMMA_SERVER} + ${MAIN}) + set_property(TARGET ${EXEC_NAME} PROPERTY LINKER_LANGUAGE Fortran) + target_include_directories(${EXEC_NAME} PUBLIC + ${CAF_INCLUDES} + ${netCDF_INCLUDES} + ${LAPACK_INCLUDES} + "/Summa-Actors/build/includes/global" + "/Summa-Actors/build/includes/summa_actor" + "/Summa-Actors/build/includes/gru_actor" + "/Summa-Actors/build/includes/job_actor" + "/Summa-Actors/build/includes/file_access_actor" + "/Summa-Actors/build/includes/hru_actor") + target_link_libraries( ${EXEC_NAME} + ${CAF_LIBRARIES} + ${netCDF_LIBRARIES} + ${LAPACK_LIBRARIES} + -lcaf_core + -lcaf_io + summa + -lsumma) \ No newline at end of file diff --git a/build/includes/file_access_actor/file_access_actor_subroutine_wrappers.hpp b/build/includes/file_access_actor/file_access_actor_subroutine_wrappers.hpp index 9df279923786024d24759f1386a59091458f432a..2b633826ef4d52ea68cd892695af06aeb3e11cfc 100644 --- a/build/includes/file_access_actor/file_access_actor_subroutine_wrappers.hpp +++ b/build/includes/file_access_actor/file_access_actor_subroutine_wrappers.hpp @@ -31,4 +31,10 @@ extern "C" { void def_output(void* handle_ncid, int* startGRU, int* numGRU, int* numHRU, int* err); void Write_HRU_Param(void* handle_ncid, int* indxGRU, int* indxHRU, int* err); + + void readAttributeFileAccessActor(int* num_gru, int* err); + + void overwriteParam(int* num_gru, int* err); + + void readParamFileAccessActor(int* start_gru, int* num_gru, int* err); } diff --git a/build/includes/global/fortran_data_types.hpp b/build/includes/global/fortran_data_types.hpp index 7552b971c55fe790187cb7445494de767a40529b..e6833991804632b599eac275b055d8c48deeaf13 100644 --- a/build/includes/global/fortran_data_types.hpp +++ b/build/includes/global/fortran_data_types.hpp @@ -96,4 +96,7 @@ extern "C" { void* new_handle_file_info(); void delete_handle_file_info(void* handle); + // zLookup + void* new_handle_z_lookup(); + } \ No newline at end of file diff --git a/build/includes/global/global.hpp b/build/includes/global/global.hpp index 69b695bae52f83121c48f10cc2974ebc649992f1..3d2914c44c958258e69f185ba5bf395063540f1c 100644 --- a/build/includes/global/global.hpp +++ b/build/includes/global/global.hpp @@ -21,6 +21,7 @@ int getSettingsTest(std::vector<std::string> keys, T return_value) { return 0; } + /** * Return the time between to time points */ diff --git a/build/includes/global/message_atoms.hpp b/build/includes/global/message_atoms.hpp index 11b425b48f07f462246d5e795dd44bd411066765..93f1b8f2e40b472a40095155c3e568ed805e3c86 100644 --- a/build/includes/global/message_atoms.hpp +++ b/build/includes/global/message_atoms.hpp @@ -7,6 +7,9 @@ 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) + CAF_ADD_ATOM(summa, done_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/global/var_lookup.hpp b/build/includes/global/var_lookup.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e7dfc23f8f4e8aee020e6579aaa7a70154929720 --- /dev/null +++ b/build/includes/global/var_lookup.hpp @@ -0,0 +1,18 @@ +#pragma once + +struct iLookVarType { + // These values should be one index less than the Fortran structure + // This is so they align with C++ vectors that start at 0 + int scalarv = -9999; + int wLength = -9999; + int midSnow = -9999; + int midSoil = -9999; + int midToto = -9999; + int ifcSnow = -9999; + int ifcSoil = -9999; + int ifcToto = -9999; + int parSoil = -9999; + int routing = -9999; + int outstat = -9999; + int unknown = -9999; +}; \ No newline at end of file diff --git a/build/includes/gru_actor/gru_actor.hpp b/build/includes/gru_actor/gru_actor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a08047552238b1b097e760302d1434bf8d53ae98 --- /dev/null +++ b/build/includes/gru_actor/gru_actor.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "caf/all.hpp" +#include "fortran_data_types.hpp" +#include "timing_info.hpp" +#include "global.hpp" +#include <vector> +#include <array> +#include <chrono> +#include <string> +#include "var_lookup.hpp" + +namespace caf{ +struct gru_state { + // GRU Initalization + int ref_gru; + int indx_gru; + std::string config_path; + caf::actor file_access_actor; + int output_struc_size; + caf::actor parent; + + // HRU information + std::vector<caf::actor> hru_list; + int num_hrus; + int hrus_complete = 0; + + // Global Data + int nTimeDelay = 2000; // number of hours in the time delay histogram (default: ~1 season = 24*365/4) + struct iLookVarType var_type_lookup; + + // Data Structure local to the GRU + int num_bpar_vars; // number of variables in the fortran structure for bpar_struct + std::vector<double> bpar_struct; + std::vector<int> bpar_struct_var_type_list; // The types to the variable at each element in bpar_struct + + int num_bvar_vars; // number of variables in the fortran structure for bvar_struct + std::vector<std::vector<double>> bvar_struct; + std::vector<int> bvar_struct_var_type_list; + + int num_var_types; + std::vector<int> i_look_var_type_list; // The types to the variable at each element in bvar_struct +}; + +behavior gru_actor(stateful_actor<gru_state>* self, + int ref_gru, + int indx_gru, + std::string config_path, + caf::actor file_access_actor, + int output_struc_size, + caf::actor parent); +} \ No newline at end of file diff --git a/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp b/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp new file mode 100644 index 0000000000000000000000000000000000000000..49114c56d19e2b61b47324d272d156da6984a044 --- /dev/null +++ b/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp @@ -0,0 +1,14 @@ +#pragma once + +extern "C" { + + void getVarSizes(int* num_var_types, int* num_bpar_vars, int* num_bvar_vars); + + void initVarType(void* var_type_lookup); + + void fillVarTypeLists( int* num_bpar_vars, int* num_bvar_vars, + void* bpar_struct_var_type_list, void* bvar_struct_var_type_list, int* err); + + int getNumHRU(int* indx_gru); + +} \ 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/includes/hru_actor/hru_actor.hpp b/build/includes/hru_actor/hru_actor.hpp index 2f4c8d9b6bd3f01cb23826997be4750ffc2d82cb..cb0b7257ebc1748af3cc530fffbc9f2a2fa058bb 100644 --- a/build/includes/hru_actor/hru_actor.hpp +++ b/build/includes/hru_actor/hru_actor.hpp @@ -53,7 +53,11 @@ struct hru_state { void *handle_bvarStruct = new_handle_var_dlength(); // basin-average variables // ancillary data structures void *handle_dparStruct = new_handle_var_d(); // default model parameters - // Local hru data + // sundials type + void *handle_lookupStruct = new_handle_z_lookup(); + + + // Local hru data void *handle_ncid = new_handle_var_i(); // output file ids void *handle_statCounter = new_handle_var_i(); void *handle_outputTimeStep = new_handle_var_i(); diff --git a/build/includes/hru_actor/hru_actor_subroutine_wrappers.hpp b/build/includes/hru_actor/hru_actor_subroutine_wrappers.hpp index 577b3f2ebc15385db58f588f47a2b5e89de10fcd..c625ca30cd0f9bea11b4ad86b3dea8aae5dd0099 100644 --- a/build/includes/hru_actor/hru_actor_subroutine_wrappers.hpp +++ b/build/includes/hru_actor/hru_actor_subroutine_wrappers.hpp @@ -2,8 +2,8 @@ extern "C" { // Initialize HRU data_structures - void summaActors_initialize( - int* indxGRU, int* num_steps, + void initHRU( + int* indxGRU, int* num_steps, void* lookupStruct, // Statistics Structures void* forcStat, void* progStat, void* diagStat, void* fluxStat, void* indxStat, void* bvarStat, // Primary Data Structures (scalars) @@ -16,10 +16,8 @@ extern "C" { void* dparStruct, // local HRU data void* startTime, void* finshTime, void* refTime, void* oldTime, int* err); - - // SetupParam for HRU - void SetupParam( - int* indxGRU, int* indxHRU, + + void setupHRUParam( int* indxGRU, int* indxHRU, // primary data structures (scalars) void* attrStruct, void* typeStruct, void* idStruct, // primary data structures (variable length vectors) diff --git a/build/includes/job_actor/job_actor.hpp b/build/includes/job_actor/job_actor.hpp index f4f8ef5fe1c1985e5ffe28637e4f00749e5334d3..1c89afbab61bd65ea76aa239c079a596d2cf3f18 100644 --- a/build/includes/job_actor/job_actor.hpp +++ b/build/includes/job_actor/job_actor.hpp @@ -11,42 +11,41 @@ struct job_state { caf::actor parent; // actor reference to the top-level SummaActor // Job Parameters - int startGRU; // Starting GRU for this job - int numGRU; // Number of GRUs for this job - std::string configPath; + int start_gru; // Starting GRU for this job + int num_gru; // Number of GRUs for this job + int num_hru; + std::string config_path; - std::string fileManager; // Path of the fileManager.txt file + std::string file_manager; // Path of the fileManager.txt file // Variables for GRU monitoring int dt_init_start_factor = 1; // Initial Factor for dt_init (coupled_em) - int maxRunAttempts = 3; // Max number of attemtps to solve a GRU - std::vector<GRUinfo*> GRUList; // List of all GRUs under this job actor - int numGRUDone = 0; // The number of GRUs that have completed - int GRUInit = 0; // Number of GRUs initalized + int max_run_attempts = 3; // Max number of attemtps to solve a GRU + std::vector<GRUinfo*> gru_list; // List of all GRUs under this job actor + int num_gru_done = 0; // The number of GRUs that have completed + int gru_init = 0; // Number of GRUs initalized int err = 0; // Error Code - int numGRUFailed = 0; // Number of GRUs that have failed - int outputStrucSize; + int num_gru_failed = 0; // Number of GRUs that have failed + int output_struct_size; // Timing Variables TimingInfo job_timing; // Output File Names for Timings - bool outputCSV; - std::string csvOut; - std::string csvPath; - std::string successOutputFile; - std::string failedOutputFile = "failedHRU"; - std::string fileAccessActorStats = "fileAccessActor.csv"; + bool output_csv; + std::string csv_out; + std::string csv_path; + std::string success_output_file; + std::string failed_output_file = "failedHRU"; + std::string file_access_actor_stats = "fileAccessActor.csv"; }; -behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, - std::string configPath, int outputStrucSize, actor parent); +behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru, + std::string config_path, int output_struct_size, actor parent); -int parseSettings(stateful_actor<job_state>* self, std::string configPath); - -void initJob(stateful_actor<job_state>* self); +void initCsvOutputFile(stateful_actor<job_state>* self); void initalizeGRU(stateful_actor<job_state>* self); diff --git a/build/includes/job_actor/job_actor_subroutine_wrappers.hpp b/build/includes/job_actor/job_actor_subroutine_wrappers.hpp index df66a121eccd367fdb5b4981aa1a1d14b3f0e042..d215986be4fb30a84b4c880066e32b848e65c9c8 100644 --- a/build/includes/job_actor/job_actor_subroutine_wrappers.hpp +++ b/build/includes/job_actor/job_actor_subroutine_wrappers.hpp @@ -4,6 +4,16 @@ extern "C" { void initGlobals(char const*str1, int* totalGRUs, int* totalHRUs, int* numGRUs, int* numHRUs, int* startGRUIndex, int* err); - void cleanUpJobActor(int* err); + void setTimesDirsAndFiles(char const* file_manager, int* err); + + void defineGlobalData(int* start_gru_index, int* err); + + void readDimension(int* num_gru, int* num_hru, int* start_gru_index, int* err); + + void readIcondNLayers(int* num_gru, int* err); + + void allocateTimeStructure(int* err); + + void deallocateJobActor(int* err); } \ No newline at end of file diff --git a/build/makefile b/build/makefile index d42c2ece7046c500fbf43bfb8507aa912240e0bb..9b984db055949643e91dc36e78d8fe33c0932a2b 100644 --- a/build/makefile +++ b/build/makefile @@ -14,10 +14,10 @@ ACTORS_LIBRARIES = -L/usr/lib -L/usr/local/lib -L/Summa-Actors/bin -lcaf_core -l # Production runs -FLAGS_NOAH = -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors -FLAGS_COMM = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors -FLAGS_SUMMA = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors -FLAGS_ACTORS = -O3 -Wfatal-errors -std=c++17 +FLAGS_NOAH = -g -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors +FLAGS_COMM = -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors +FLAGS_SUMMA = -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors +FLAGS_ACTORS = -g -O3 -Wfatal-errors -std=c++17 # Debug runs # FLAGS_NOAH = -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC @@ -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= \ @@ -83,10 +84,13 @@ SUMMA_DATAMS= \ data_types.f90 \ globalData.f90 \ flxMapping.f90 \ - get_ixname.f90 \ + get_ixname.f90 +DATAMS = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DATAMS)) + +SUMMA_DEPEND_ON_FILEMANAGER= \ popMetadat.f90 \ outpt_stat.f90 -DATAMS = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DATAMS)) +DEPEND_ON_FILEMANAGER = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DEPEND_ON_FILEMANAGER)) # utility modules SUMMA_UTILMS= \ @@ -135,15 +139,18 @@ SUMMA_INTERFACE= \ INTERFACE = $(patsubst %, $(ACTORS_DIR)/global/%, $(SUMMA_INTERFACE)) + SUMMA_FILEACCESS_INTERFACE = \ initOutputStruc.f90 \ deallocateOutputStruc.f90 \ - cppwrap_fileAccess.f90 + cppwrap_fileAccess.f90 \ + read_attribute_all_hru.f90 \ + read_param_all_hru.f90 FILEACCESS_INTERFACE = $(patsubst %, $(FILE_ACCESS_DIR)/%, $(SUMMA_FILEACCESS_INTERFACE)) SUMMA_JOB_INTERFACE = \ - cppwrap_job.f90 + job_actor.f90 JOB_INTERFACE = $(patsubst %, $(JOB_ACTOR_DIR)/%, $(SUMMA_JOB_INTERFACE)) @@ -151,6 +158,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 @@ -212,7 +224,7 @@ SUMMA_NETCDF = \ NETCDF = $(patsubst %, $(NETCDF_DIR)/%, $(SUMMA_NETCDF)) # ... stitch together common programs -COMM_ALL = $(NRUTIL) $(NRPROC) $(HOOKUP) $(DATAMS) $(UTILMS) +COMM_ALL = $(NRUTIL) $(NRPROC) $(DATAMS) $(INTERFACE) $(HOOKUP) $(DEPEND_ON_FILEMANAGER) $(UTILMS) # ... stitch together SUMMA programs SUMMA_ALL = $(NETCDF) $(PRELIM) $(MODRUN) $(SOLVER) @@ -222,7 +234,7 @@ SUMMA_DRIVER= \ summaActors_type.f90 \ summaActors_util.f90 \ summaActors_globalData.f90 \ - summaActors_init.f90 \ + init_hru_actor.f90 \ SummaActors_setup.f90 \ summaActors_restart.f90 \ summaActors_forcing.f90 \ @@ -252,11 +264,14 @@ TIMEINFO = $(SOURCE_DIR)/global/timing_info.cpp SUMMA_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/summa_actor SUMMA_ACTOR = $(SOURCE_DIR)/summa_actor/summa_actor.cpp SUMMA_CLIENT = $(SOURCE_DIR)/summa_actor/summa_client.cpp -SUMMA_SERVER = $(SOURCE_DIR)/summa_actor/summa_server.cpp +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 +299,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 +316,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) $(JOB_INTERFACE) $(FILEACCESS_INTERFACE) $(HRU_INTERFACE) $(GRU_INTERFACE) $(INCLUDES) # generate library link: @@ -322,6 +337,9 @@ clean_fortran: compile_globals: $(CC) $(FLAGS_ACTORS) -c $(GLOBAL) $(TIMEINFO) $(GLOBAL_INCLUDES) +compile_gru_actor: + $(CC) $(FLAGS_ACTORS) -c $(GRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(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 +349,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/makefile_sundials b/build/makefile_sundials new file mode 100644 index 0000000000000000000000000000000000000000..fdb0785c1d581c58e6814372a0e206271c3d3acd --- /dev/null +++ b/build/makefile_sundials @@ -0,0 +1,397 @@ +#### parent directory of the 'build' directory #### +ROOT_DIR = /Summa-Actors + +#### Compilers #### +FC = gfortran # Fortran +CC = g++ # C++ + +DIR_SUNDIALS=/code/sundials/instdir +INC_SUNDIALS=-I$(DIR_SUNDIALS)/include -I$(DIR_SUNDIALS)/fortran +LIB_SUNDIALS=-L$(DIR_SUNDIALS)/lib -lsundials_fnvecmanyvector_mod -lsundials_fida_mod -lsundials_fnvecserial_mod -lsundials_fsunlinsoldense_mod -lsundials_fsunmatrixdense_mod + + +#### Includes AND Libraries #### +INCLUDES = -I/usr/include -I/usr/local/include $(INC_SUNDIALS) +LIBRARIES = -L/usr/lib -L/usr/local/lib -lnetcdff -lopenblas $(LIB_SUNDIALS) + +ACTORS_INCLUDES = -I/usr/include -I/usr/local/include $(INC_SUNDIALS) +ACTORS_LIBRARIES = -L/usr/lib -L/usr/local/lib -L/Summa-Actors/bin -lcaf_core -lcaf_io -lsumma -lopenblas -lnetcdff $(LIB_SUNDIALS) + + +# Production runs +FLAGS_NOAH = -g -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors +FLAGS_COMM = -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors +FLAGS_SUMMA = -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors +FLAGS_ACTORS = -g -O3 -Wfatal-errors -std=c++17 + +# Debug runs +# FLAGS_NOAH = -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC +# FLAGS_COMM = -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC +# FLAGS_SUMMA = -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC +# FLAGS_ACTORS = -g -O0 -Wall -std=c++17 + + + +#======================================================================== +# PART 1: Define directory paths +#======================================================================== + +# Core directory that contains source code +F_KORE_DIR = $(ROOT_DIR)/build/source + +# Location of the compiled modules +MOD_PATH = $(ROOT_DIR)/build + +# Define the directory for the executables +EXE_PATH = $(ROOT_DIR)/bin + +#################################################################################################### +###################################### Assemble Fortran Files ###################################### +#################################################################################################### +# Define directories +DRIVER_DIR = $(F_KORE_DIR)/driver +HOOKUP_DIR = $(F_KORE_DIR)/hookup +NETCDF_DIR = $(F_KORE_DIR)/netcdf +DSHARE_DIR = $(F_KORE_DIR)/dshare +NUMREC_DIR = $(F_KORE_DIR)/numrec +NOAHMP_DIR = $(F_KORE_DIR)/noah-mp +ENGINE_DIR = $(F_KORE_DIR)/engine +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= \ + nrtype.f90 \ + f2008funcs.f90 \ + nr_utility.f90 +NRUTIL = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_NRUTIL)) + +# Numerical recipes procedures +# NOTE: all numerical recipes procedures are now replaced with free versions +SUMMA_NRPROC= \ + expIntegral.f90 \ + spline_int.f90 +NRPROC = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_NRPROC)) + +# Hook-up modules (set files and directory paths) +SUMMA_HOOKUP= \ + ascii_util.f90 \ + summaActors_FileManager.f90 +HOOKUP = $(patsubst %, $(HOOKUP_DIR)/%, $(SUMMA_HOOKUP)) + +# Data modules +SUMMA_DATAMS= \ + multiconst.f90 \ + var_lookup.f90 \ + data_types.f90 \ + globalData.f90 \ + flxMapping.f90 \ + get_ixname.f90 +DATAMS = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DATAMS)) + +SUMMA_DEPEND_ON_FILEMANAGER= \ + popMetadat.f90 \ + outpt_stat.f90 +DEPEND_ON_FILEMANAGER = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DEPEND_ON_FILEMANAGER)) + +# utility modules +SUMMA_UTILMS= \ + time_utils.f90 \ + mDecisions.f90 \ + snow_utils.f90 \ + soil_utils.f90 \ + updatState.f90 \ + matrixOper.f90 +UTILMS = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_UTILMS)) + +# Model guts +SUMMA_MODGUT= \ + MODGUT = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_MODGUT)) + +# Solver +SUMMA_SOLVER= \ + vegPhenlgy.f90 \ + diagn_evar.f90 \ + stomResist.f90 \ + groundwatr.f90 \ + vegSWavRad.f90 \ + vegNrgFlux.f90 \ + ssdNrgFlux.f90 \ + vegLiqFlux.f90 \ + snowLiqFlx.f90 \ + soilLiqFlx.f90 \ + bigAquifer.f90 \ + computFlux.f90 \ + computResid.f90 \ + computJacob.f90 \ + eval8summa.f90 \ + summaSolve.f90 \ + systemSolv.f90 \ + varSubstep.f90 \ + opSplittin.f90 \ + coupled_em.f90 + +SOLVER = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_SOLVER)) + +# Interface code for Fortran-C++ +SUMMA_INTERFACE= \ + cppwrap_datatypes.f90 \ + cppwrap_auxiliary.f90 \ + cppwrap_metadata.f90 \ + +INTERFACE = $(patsubst %, $(ACTORS_DIR)/global/%, $(SUMMA_INTERFACE)) + + +SUMMA_FILEACCESS_INTERFACE = \ + initOutputStruc.f90 \ + deallocateOutputStruc.f90 \ + cppwrap_fileAccess.f90 \ + read_attribute_all_hru.f90 \ + read_param_all_hru.f90 + +FILEACCESS_INTERFACE = $(patsubst %, $(FILE_ACCESS_DIR)/%, $(SUMMA_FILEACCESS_INTERFACE)) + +SUMMA_JOB_INTERFACE = \ + job_actor.f90 + +JOB_INTERFACE = $(patsubst %, $(JOB_ACTOR_DIR)/%, $(SUMMA_JOB_INTERFACE)) + +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 +SUMMA_PRELIM= \ + conv_funcs.f90 \ + sunGeomtry.f90 \ + convE2Temp.f90 \ + allocspaceActors.f90 \ + alloc_file_access.f90\ + checkStruc.f90 \ + childStruc.f90 \ + ffile_info.f90 \ + read_attribute.f90 \ + read_pinit.f90 \ + pOverwrite.f90 \ + read_paramActors.f90 \ + paramCheck.f90 \ + check_icondActors.f90 \ + # allocspace.f90 +PRELIM = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_PRELIM)) + +SUMMA_NOAHMP= \ + module_model_constants.F \ + module_sf_noahutl.F \ + module_sf_noahlsm.F \ + module_sf_noahmplsm.F + +NOAHMP = $(patsubst %, $(NOAHMP_DIR)/%, $(SUMMA_NOAHMP)) + +# Define routines for the SUMMA model runs +SUMMA_MODRUN = \ + indexState.f90 \ + getVectorz.f90 \ + updateVars.f90 \ + var_derive.f90 \ + read_forcingActors.f90 \ + access_forcing.f90\ + access_write.f90 \ + derivforce.f90 \ + snowAlbedo.f90 \ + canopySnow.f90 \ + tempAdjust.f90 \ + snwCompact.f90 \ + layerMerge.f90 \ + layerDivide.f90 \ + volicePack.f90 \ + qTimeDelay.f90 +MODRUN = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_MODRUN)) + +# Define NetCDF routines +# OutputStrucWrite is not a netcdf subroutine and should be +# moved +SUMMA_NETCDF = \ + netcdf_util.f90 \ + def_output.f90 \ + outputStrucWrite.f90 \ + writeOutput.f90 \ + read_icondActors.f90 +NETCDF = $(patsubst %, $(NETCDF_DIR)/%, $(SUMMA_NETCDF)) + +# ... stitch together common programs +COMM_ALL = $(NRUTIL) $(NRPROC) $(DATAMS) $(INTERFACE) $(HOOKUP) $(DEPEND_ON_FILEMANAGER) $(UTILMS) + +# ... stitch together SUMMA programs +SUMMA_ALL = $(NETCDF) $(PRELIM) $(MODRUN) $(SOLVER) + +# Define the driver routine +SUMMA_DRIVER= \ + summaActors_type.f90 \ + summaActors_util.f90 \ + summaActors_globalData.f90 \ + init_hru_actor.f90 \ + SummaActors_setup.f90 \ + summaActors_restart.f90 \ + summaActors_forcing.f90 \ + SummaActors_modelRun.f90 \ + summaActors_alarms.f90 \ + summaActors_wOutputStruc.f90 + + +DRIVER = $(patsubst %, $(DRIVER_DIR)/%, $(SUMMA_DRIVER)) + +#################################################################################################### +###################################### Assemble Fortran Files ###################################### +#################################################################################################### + +#################################################################################################### +######################################## Assemble C++ Files ######################################## +#################################################################################################### + +INCLUDE_DIR = /Summa-Actors/build/includes +SOURCE_DIR = /Summa-Actors/build/source/actors + + +GLOBAL_INCLUDES = -I$(INCLUDE_DIR)/global +GLOBAL = $(SOURCE_DIR)/global/global.cpp +TIMEINFO = $(SOURCE_DIR)/global/timing_info.cpp + +SUMMA_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/summa_actor +SUMMA_ACTOR = $(SOURCE_DIR)/summa_actor/summa_actor.cpp +SUMMA_CLIENT = $(SOURCE_DIR)/summa_actor/summa_client.cpp + +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 + +FILE_ACCESS_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/file_access_actor +FILE_ACCESS_ACTOR = $(SOURCE_DIR)/file_access_actor/file_access_actor.cpp +FORCING_FILE_INFO = $(SOURCE_DIR)/file_access_actor/forcing_file_info.cpp +OUTPUT_MANAGER = $(SOURCE_DIR)/file_access_actor/output_manager.cpp + +HRU_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/hru_actor +HRU_ACTOR = $(SOURCE_DIR)/hru_actor/hru_actor.cpp + +MAIN = $(F_KORE_DIR)/actors/main.cpp + +ACTOR_TEST = $(F_KORE_DIR)/testing/testing_main.cc +#################################################################################################### +######################################## Assemble C++ Files ######################################## +#################################################################################################### + + +#======================================================================== +# PART 3: compilation +#====================================================================== +all: fortran cpp + +fortran: compile_noah compile_comm compile_summa link clean_fortran + +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 + +################################################################################################################### +############################################## COMPILE SUMMA-Fortran ############################################## +################################################################################################################### +compile_noah: + $(FC) $(FLAGS_NOAH) -c $(NRUTIL) $(NOAHMP) + +# compile common routines +compile_comm: + $(FC) $(FLAGS_COMM) -c $(COMM_ALL) $(INCLUDES) + +# compile SUMMA routines +compile_summa: + $(FC) $(FLAGS_SUMMA) -c $(SUMMA_ALL) $(DRIVER) $(JOB_INTERFACE) $(FILEACCESS_INTERFACE) $(HRU_INTERFACE) $(GRU_INTERFACE) $(INCLUDES) + +# generate library +link: + $(FC) -shared *.o -o libsumma.so + mv libsumma.so $(ROOT_DIR)/bin + +# Remove object files +clean_fortran: + rm -f *.o *.mod soil_veg_gen_parm__genmod.f90 +################################################################################################################### +############################################## COMPILE SUMMA-Fortran ############################################## +################################################################################################################### + + +################################################################################################################### +################################################ COMPILE SUMMA-C++ ################################################ +################################################################################################################### +compile_globals: + $(CC) $(FLAGS_ACTORS) -c $(GLOBAL) $(TIMEINFO) $(GLOBAL_INCLUDES) + +compile_gru_actor: + $(CC) $(FLAGS_ACTORS) -c $(GRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(GRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) + +compile_hru_actor: + $(CC) $(FLAGS_ACTORS) -c $(HRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) + +compile_file_access_actor: + $(CC) $(FLAGS_ACTORS) -c $(FILE_ACCESS_ACTOR) $(FORCING_FILE_INFO) $(OUTPUT_MANAGER) \ + $(FILE_ACCESS_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) + +compile_job_actor: + $(CC) $(FLAGS_ACTORS) -c $(JOB_ACTOR) $(GRUinfo) $(JOB_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_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) \ + $(JOB_ACTOR_INCLUDES) + +compile_summa_client: + $(CC) $(FLAGS_ACTORS) -c $(SUMMA_CLIENT) $(SUMMA_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) + +compile_summa_server: + $(CC) $(FLAGS_ACTORS) -c $(SUMMA_SERVER) $(BATCH_MANGER) $(CLIENT_MANAGER) $(SUMMA_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) + +compile_main: + $(CC) $(FLAGS_ACTORS) -c $(MAIN) $(GLOBAL_INCLUDES) $(SUMMA_ACTOR_INCLUDES) $(JOB_ACTOR_INCLUDES) + +link_cpp: + $(CC) $(FLAGS_ACTORS) -o summaMain *.o $(ACTORS_LIBRARIES) + mv summaMain $(ROOT_DIR)/bin + +clean_cpp: + rm *.o +################################################################################################################### +################################################ COMPILE SUMMA-C++ ################################################ +################################################################################################################### + + +################################################################################################################### +################################################## COMPILE TESTS ################################################## +################################################################################################################### +actors_test: + $(CC) $(FLAGS_ACTORS) -c $(ACTOR_TEST) -std=c++17 $(ACTORS_INCLUDES) + +actors_testLink: + $(CC) -o summaTest *.o $(ACTORS_LIBRARIES) + +clean_lib: + rm *.so + + + + diff --git a/build/source/actors/file_access_actor/file_access_actor.cpp b/build/source/actors/file_access_actor/file_access_actor.cpp index dad7a6326c2ebed738ef89fb9ff47d6d3bbaf880..fd9842f010b98e75c1fa91fc92c440baa665c834 100644 --- a/build/source/actors/file_access_actor/file_access_actor.cpp +++ b/build/source/actors/file_access_actor/file_access_actor.cpp @@ -43,6 +43,13 @@ behavior file_access_actor(stateful_actor<file_access_state>* self, int startGRU aout(self) << "Initalizing Output Structure" << std::endl; Init_OutputStruct(self->state.handle_forcing_file_info, &self->state.outputStrucSize, &self->state.numGRU, &self->state.err); + if (self->state.err != 0) { + aout(self) << "ERROR: FILE_ACCESS_ACTOR init_OutputStruct \n"; + std::string function = "init_OutputStruc"; + self->send(self->state.parent, file_access_actor_err_v, function); + self->quit(); + return; + } }, [=](write_param, int indxGRU, int indxHRU) { @@ -240,6 +247,36 @@ void initalizeFileAccessActor(stateful_actor<file_access_state>* self) { Init_OutputStruct(self->state.handle_forcing_file_info, &self->state.outputStrucSize, &self->state.numGRU, &self->state.err); + // Read In all of the attribres for the number of GRUs in the run Domian + readAttributeFileAccessActor(&self->state.numGRU, &err); + if (err != 0) { + aout(self) << "ERROR: FILE_ACCESS_ACTOR readAttributeFilAccessActor() \n"; + std::string function = "readAttributeFileAccessActor"; + self->send(self->state.parent, file_access_actor_err_v, function); + self->quit(); + return; + } + + overwriteParam(&self->state.numGRU, &err); + if (err != 0) { + aout(self) << "ERROR: FILE_ACCESS_ACTOR overwriteParam() \n"; + std::string function = "overwriteParam"; + self->send(self->state.parent, file_access_actor_err_v, function); + self->quit(); + return; + } + + + // Read in all of the parmeters for the number of GRUs in the run Domain + readParamFileAccessActor(&self->state.startGRU, &self->state.numGRU, &err); + if (err != 0) { + aout(self) << "ERROR: FILE_ACCESS_ACTOR readParamFileAccessActor() \n"; + std::string function = "readParamFileAccessActor"; + self->send(self->state.parent, file_access_actor_err_v, function); + self->quit(); + return; + } + // Initalize the output manager self->state.output_manager = new OutputManager(self->state.num_vectors_in_output_manager, self->state.numGRU); diff --git a/build/source/actors/file_access_actor/initOutputStruc.f90 b/build/source/actors/file_access_actor/initOutputStruc.f90 index 111ad6a391c0d180d962da2423fbc894daff12f9..d46015a19fe9be33fd89348c64f19716779822c0 100644 --- a/build/source/actors/file_access_actor/initOutputStruc.f90 +++ b/build/source/actors/file_access_actor/initOutputStruc.f90 @@ -4,7 +4,7 @@ module summaActors_initOutputStruct public::initalizeOutput contains -subroutine initalizeOutput(forcFileInfo, maxSteps, nGRU, err) +subroutine initalizeOutput(forcFileInfo, maxSteps, num_gru, err) USE globalData,only:outputStructure USE globalData,only:time_meta,forc_meta,attr_meta,type_meta ! metadata structures USE globalData,only:prog_meta,diag_meta,flux_meta,id_meta ! metadata structures @@ -26,192 +26,210 @@ subroutine initalizeOutput(forcFileInfo, maxSteps, nGRU, err) implicit none type(file_info_array), pointer :: forcFileInfo integer(i4b), intent(in) :: maxSteps - integer(i4b), intent(in) :: nGRU + integer(i4b), intent(in) :: num_gru integer(i4b), intent(inout) :: err ! local variables integer(i4b) :: nVars integer(i4b) :: iGRU + integer(i4b) :: iHRU integer(i4b) :: iStep integer(i4b) :: nSnow integer(i4b) :: nSoil integer(i4b) :: iStruct character(len=256) :: message + integer(i4b) :: num_hru ! Allocate structure to hold output files if (.not.allocated(outputStructure))then allocate(outputStructure(1)) end if + ! Statistics Structures allocate(outputStructure(1)%forcStat(1)) - allocate(outputStructure(1)%forcStat(1)%gru(nGRU)) - allocate(outputStructure(1)%progStat(1)) - allocate(outputStructure(1)%progStat(1)%gru(nGRU)) - allocate(outputStructure(1)%diagStat(1)) - allocate(outputStructure(1)%diagStat(1)%gru(nGRU)) - allocate(outputStructure(1)%fluxStat(1)) - allocate(outputStructure(1)%fluxStat(1)%gru(nGRU)) - allocate(outputStructure(1)%indxStat(1)) - allocate(outputStructure(1)%indxStat(1)%gru(nGRU)) - allocate(outputStructure(1)%bvarStat(1)) - allocate(outputStructure(1)%bvarStat(1)%gru(nGRU)) + allocate(outputStructure(1)%forcStat(1)%gru(num_gru)) + allocate(outputStructure(1)%progStat(1)%gru(num_gru)) + allocate(outputStructure(1)%diagStat(1)%gru(num_gru)) + allocate(outputStructure(1)%fluxStat(1)%gru(num_gru)) + allocate(outputStructure(1)%indxStat(1)%gru(num_gru)) + allocate(outputStructure(1)%bvarStat(1)%gru(num_gru)) + ! Primary Data Structures (scalars) allocate(outputStructure(1)%timeStruct(1)) - allocate(outputStructure(1)%timeStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%forcStruct(1)) - allocate(outputStructure(1)%forcStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%attrStruct(1)) - allocate(outputStructure(1)%attrStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%typeStruct(1)) - allocate(outputStructure(1)%typeStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%idStruct(1)) - allocate(outputStructure(1)%idStruct(1)%gru(nGRU)) + allocate(outputStructure(1)%timeStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%forcStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%attrStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%typeStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%idStruct(1)%gru(num_gru)) + ! Primary Data Structures (variable length vectors) allocate(outputStructure(1)%indxStruct(1)) allocate(outputStructure(1)%mparStruct(1)) allocate(outputStructure(1)%progStruct(1)) allocate(outputStructure(1)%diagStruct(1)) allocate(outputStructure(1)%fluxStruct(1)) - allocate(outputStructure(1)%indxStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%mparStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%progStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%diagStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%fluxStruct(1)%gru(nGRU)) + allocate(outputStructure(1)%indxStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%mparStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%progStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%diagStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%fluxStruct(1)%gru(num_gru)) + ! Basin-Average structures allocate(outputStructure(1)%bparStruct(1)) allocate(outputStructure(1)%bvarStruct(1)) - allocate(outputStructure(1)%bparStruct(1)%gru(nGRU)) - allocate(outputStructure(1)%bvarStruct(1)%gru(nGRU)) + allocate(outputStructure(1)%bparStruct(1)%gru(num_gru)) + allocate(outputStructure(1)%bvarStruct(1)%gru(num_gru)) + + ! define the ancillary data structures + allocate(outputStructure(1)%dparStruct(1)) + allocate(outputStructure(1)%dparStruct(1)%gru(num_gru)) + ! Finalize Stats for writing allocate(outputStructure(1)%finalizeStats(1)) - allocate(outputStructure(1)%finalizeStats(1)%gru(nGRU)) - ! - ! Allocate space for HRUs - ! - do iGRU = 1, nGRU - - ! Get the maximum number of steps needed to initalize the output structure - nVars = maxval(forcFileInfo%ffile_list(:)%nVars) - nSnow = gru_struc(iGRU)%hruInfo(1)%nSnow - nSoil = gru_struc(iGRU)%hruInfo(1)%nSoil - - do iStruct=1,size(structInfo) - ! allocate space structures - select case(trim(structInfo(iStruct)%structName)) - case('time') - allocate(outputStructure(1)%timeStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(time_meta,outputStructure(1)%timeStruct(1)%gru(iGRU)%hru(1), & + allocate(outputStructure(1)%finalizeStats(1)%gru(num_gru)) + + + do iGRU = 1, num_gru + num_hru = gru_struc(iGRU)%hruCount + ! Statistics Structures + allocate(outputStructure(1)%forcStat(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%progStat(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%diagStat(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%fluxStat(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%indxStat(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%bvarStat(1)%gru(iGRU)%hru(num_hru)) + + ! Primary Data Structures (scalars) + allocate(outputStructure(1)%timeStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%forcStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%attrStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%idStruct(1)%gru(iGRU)%hru(num_hru)) + + ! Primary Data Structures (variable length vectors) + allocate(outputStructure(1)%indxStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%progStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%diagStruct(1)%gru(iGRU)%hru(num_hru)) + allocate(outputStructure(1)%fluxStruct(1)%gru(iGRU)%hru(num_hru)) + + ! Basin-Average structures + allocate(outputStructure(1)%bvarStruct(1)%gru(iGRU)%hru(num_hru)) + + ! define the ancillary data structures + allocate(outputStructure(1)%dparStruct(1)%gru(iGRU)%hru(num_hru)) + + ! Finalize Stats for writing + allocate(outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(num_hru)) + + end do + + do iGRU=1,num_gru + do iHRU=1,gru_struc(iGRU)%hruCount + + ! Get the maximum number of steps needed to initalize the output structure + nVars = maxval(forcFileInfo%ffile_list(:)%nVars) + nSnow = gru_struc(iGRU)%hruInfo(iHRU)%nSnow + nSoil = gru_struc(iGRU)%hruInfo(iHRU)%nSoil + + do iStruct=1,size(structInfo) + ! allocate space structures + select case(trim(structInfo(iStruct)%structName)) + case('time') + call alloc_outputStruc(time_meta,outputStructure(1)%timeStruct(1)%gru(iGRU)%hru(iHRU), & maxSteps,err=err,message=message) ! model forcing data - case('forc') - allocate(outputStructure(1)%forcStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(forc_meta,outputStructure(1)%forcStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model forcing data - case('attr') - allocate(outputStructure(1)%attrStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(attr_meta,outputStructure(1)%attrStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! local attributes for each HRU - case('type') - allocate(outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(type_meta,outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! classification of soil veg etc. - case('id' ) - allocate(outputStructure(1)%idStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(id_meta,outputStructure(1)%idStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! local values of hru and gru IDs - case('mpar') - allocate(outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(mpar_meta,outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model parameters - case('indx') - allocate(outputStructure(1)%indxStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(indx_meta,outputStructure(1)%indxStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model variables - case('prog') - allocate(outputStructure(1)%progStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(prog_meta,outputStructure(1)%progStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model prognostic (state) variables - case('diag') - allocate(outputStructure(1)%diagStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(diag_meta,outputStructure(1)%diagStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model diagnostic variables - case('flux') - allocate(outputStructure(1)%fluxStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(flux_meta,outputStructure(1)%fluxStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model fluxes - case('bpar') - call alloc_outputStruc(bpar_meta,outputStructure(1)%bparStruct(1)%gru(iGRU), & - maxSteps,nSnow=0,nSoil=0,err=err,message=message); ! basin-average params - case('bvar') - allocate(outputStructure(1)%bvarStruct(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(bvar_meta,outputStructure(1)%bvarStruct(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow=0,nSoil=0,err=err,message=message); ! basin-average variables - case('deriv'); cycle - case default; err=20; message='unable to find structure name: '//trim(structInfo(iStruct)%structName) - end select - ! check errors - if(err/=0)then - message=trim(message)//'[structure = '//trim(structInfo(iStruct)%structName)//']' - return - endif - end do ! looping through data structures - - do iStruct=1,size(structInfo) - - ! allocate space for statistics structures - select case(trim(structInfo(iStruct)%structName)) - case('forc') - allocate(outputStructure(1)%forcStat(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(statForc_meta(:)%var_info,outputStructure(1)%forcStat(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model forcing data - case('prog') - allocate(outputStructure(1)%progStat(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(statProg_meta(:)%var_info,outputStructure(1)%progStat(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model prognostic - case('diag') - allocate(outputStructure(1)%diagStat(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(statDiag_meta(:)%var_info,outputStructure(1)%diagStat(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model diagnostic - case('flux') - allocate(outputStructure(1)%fluxStat(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(statFlux_meta(:)%var_info,outputStructure(1)%fluxStat(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! model fluxes - case('indx') - allocate(outputStructure(1)%indxStat(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(statIndx_meta(:)%var_info,outputStructure(1)%indxStat(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow,nSoil,err,message); ! index vars - case('bvar') - allocate(outputStructure(1)%bvarStat(1)%gru(iGRU)%hru(1)) - call alloc_outputStruc(statBvar_meta(:)%var_info,outputStructure(1)%bvarStat(1)%gru(iGRU)%hru(1), & - maxSteps,nSnow=0,nSoil=0,err=err,message=message); ! basin-average variables - case default; cycle - end select - - ! check errors - if(err/=0)then - message=trim(message)//'[statistics for = '//trim(structInfo(iStruct)%structName)//']' - return - endif + case('forc') + ! Structure + call alloc_outputStruc(forc_meta,outputStructure(1)%forcStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model forcing data + ! Statistics + call alloc_outputStruc(statForc_meta(:)%var_info,outputStructure(1)%forcStat(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model forcing data + case('attr') + call alloc_outputStruc(attr_meta,outputStructure(1)%attrStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! local attributes for each HRU + case('type') + call alloc_outputStruc(type_meta,outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! classification of soil veg etc. + case('id' ) + call alloc_outputStruc(id_meta,outputStructure(1)%idStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! local values of hru gru IDs + case('mpar') ! model parameters + call alloc_outputStruc(mpar_meta,outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); + + call alloc_outputStruc(mpar_meta, outputStructure(1)%dparStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,err=err,message=message) + case('indx') + ! Structure + call alloc_outputStruc(indx_meta,outputStructure(1)%indxStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model variables + ! Statistics + call alloc_outputStruc(statIndx_meta(:)%var_info,outputStructure(1)%indxStat(1)%gru(iGRU)%hru(1), & + maxSteps,nSnow,nSoil,err,message); ! index vars + case('prog') + ! Structure + call alloc_outputStruc(prog_meta,outputStructure(1)%progStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model prognostic (state) variables + ! Statistics + call alloc_outputStruc(statProg_meta(:)%var_info,outputStructure(1)%progStat(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model prognostic + case('diag') + ! Structure + call alloc_outputStruc(diag_meta,outputStructure(1)%diagStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model diagnostic variables + ! Statistics + call alloc_outputStruc(statDiag_meta(:)%var_info,outputStructure(1)%diagStat(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model diagnostic + case('flux') + ! Structure + call alloc_outputStruc(flux_meta,outputStructure(1)%fluxStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model fluxes + ! Statistics + call alloc_outputStruc(statFlux_meta(:)%var_info,outputStructure(1)%fluxStat(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow,nSoil,err,message); ! model fluxes + case('bpar') + call alloc_outputStruc(bpar_meta,outputStructure(1)%bparStruct(1)%gru(iGRU), & + maxSteps,nSnow=0,nSoil=0,err=err,message=message); ! basin-average params + case('bvar') + ! Structure + call alloc_outputStruc(bvar_meta,outputStructure(1)%bvarStruct(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow=0,nSoil=0,err=err,message=message); ! basin-average variables + ! Statistics + call alloc_outputStruc(statBvar_meta(:)%var_info,outputStructure(1)%bvarStat(1)%gru(iGRU)%hru(iHRU), & + maxSteps,nSnow=0,nSoil=0,err=err,message=message); ! basin-average variables + case('deriv'); cycle + case('lookup'); cycle + case default; err=20; message='unable to find structure name: '//trim(structInfo(iStruct)%structName) + end select + + ! check errors + if(err/=0)then + message=trim(message)//'initOutputStruc.f90 - [structure = '//trim(structInfo(iStruct)%structName)//']' + print*, "message" + return + endif + end do ! looping through data structures - end do ! iStruct - ! Finalize stats structure for writing to output file - allocate(outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)) - allocate(outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(maxSteps)) - do iStep = 1, maxSteps - allocate(outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(1:maxVarFreq)) - end do ! timeSteps - end do ! Looping through GRUs + ! Finalize stats structure for writing to output file + print*, "HERE" + allocate(outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(iHRU)%tim(maxSteps)) + do iStep = 1, maxSteps + allocate(outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(iHRU)%tim(iStep)%dat(1:maxVarFreq)) + end do ! timeSteps + end do ! Looping through GRUs + end do end subroutine initalizeOutput - end module \ No newline at end of file diff --git a/build/source/actors/file_access_actor/read_attribute_all_hru.f90 b/build/source/actors/file_access_actor/read_attribute_all_hru.f90 new file mode 100644 index 0000000000000000000000000000000000000000..f0912a65236817dddd59c5ee22b09ecc97d2150a --- /dev/null +++ b/build/source/actors/file_access_actor/read_attribute_all_hru.f90 @@ -0,0 +1,291 @@ +module read_attribute_all_hru + USE, intrinsic :: iso_c_binding + USE nrtype + implicit none + private + public::read_attribute_file_access_actor +contains +subroutine read_attribute_file_access_actor(num_gru,err) bind(C, name="readAttributeFileAccessActor") + USE globalData,only:outputStructure ! Using the output structure as global input for the attribute data. This is so we can hrus can setup params in parallel. + USE netcdf + USE netcdf_util_module,only:nc_file_open ! open netcdf file + USE netcdf_util_module,only:nc_file_close ! close netcdf file + USE netcdf_util_module,only:netcdf_err ! netcdf error handling function + ! provide access to derived data types + USE data_types,only:var_d ! x%var(:) (i4b) + USE data_types,only:var_i ! x%var(:) integer(8) + USE data_types,only:var_i8 ! x%var(:) (dp) + ! provide access to global data + USE globalData,only:gru_struc ! gru-hru mapping structure + USE globalData,only:attr_meta,type_meta,id_meta ! metadata structures + USE get_ixname_module,only:get_ixAttr,get_ixType,get_ixId ! access function to find index of elements in structure + ! Attribute File + USE summaActors_FileManager,only:SETTINGS_PATH ! define path to settings files (e.g., parameters, soil and veg. tables) + USE summaActors_FileManager,only:LOCAL_ATTRIBUTES ! name of model initial attributes file + + + implicit none + + integer(c_int),intent(in) :: num_gru ! id of the HRU + integer(c_int),intent(out) :: err ! error code + + ! Local Variables + character(len=256) :: message ! error message + character(len=256) :: cmessage ! error message for downwind routine + integer(i4b) :: iVar ! loop through varibles in the netcdf file + integer(i4b) :: varType ! type of variable (categorica, numerical, idrelated) + integer(i4b) :: varIndx ! index of variable within its data structure + + ! check structures + integer(i4b) :: iCheck ! index of an attribute name + logical(lgt),allocatable :: checkType(:) ! vector to check if we have all desired categorical values + logical(lgt),allocatable :: checkId(:) ! vector to check if we have all desired IDs + logical(lgt),allocatable :: checkAttr(:) ! vector to check if we have all desired local attributes + + ! netcdf variables + integer(i4b) :: ncID ! netcdf file id + character(LEN=nf90_max_name) :: varName ! character array of netcdf variable name + integer(i4b) :: nVar ! number of variables in netcdf local attribute file + integer(i4b),parameter :: categorical=101 ! named variable to denote categorical data + integer(i4b),parameter :: numerical=102 ! named variable to denote numerical data + integer(i4b),parameter :: idrelated=103 ! named variable to denote ID related data + integer(i4b) :: categorical_var(1) ! temporary categorical variable from local attributes netcdf file + real(dp) :: numeric_var(1) ! temporary numeric variable from local attributes netcdf file + integer(8) :: idrelated_var(1) ! temporary ID related variable from local attributes netcdf file + + integer(i4b) :: iGRU + integer(i4b) :: iHRU + ! attribute file + character(len=256) :: attrFile ! attributes file name + + + ! define mapping variables + + ! Start procedure here + err=0; message="read_attriute_all_hru " + + attrFile = trim(SETTINGS_PATH)//trim(LOCAL_ATTRIBUTES) + + + ! ********************************************************************************************** + ! (1) prepare check vectors + ! ********************************************************************************************** + allocate(checkType(size(type_meta)),checkAttr(size(attr_meta)),checkId(size(id_meta)),stat=err) + if(err/=0)then + err=20 + message=trim(message)//'problem allocating space for variable check vectors' + print*, message + return + endif + checkType(:) = .false. + checkAttr(:) = .false. + checkId(:) = .false. + + ! ********************************************************************************************** + ! (2) open netcdf file + ! ********************************************************************************************** + ! open file + call nc_file_open(trim(attrFile),nf90_noWrite,ncID,err,cmessage) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif + + ! get number of variables total in netcdf file + err = nf90_inquire(ncID,nvariables=nVar) + call netcdf_err(err,message) + if (err/=0) then + message=trim(message)//'problem with nf90_inquire' + return + endif + ! ********************************************************************************************** + ! (3) read local attributes + ! ********************************************************************************************** + ! loop through variables in netcdf file and pull out local attributes + iCheck = 1 + do iVar = 1,nVar + + ! inqure about current variable name, type, number of dimensions + err = nf90_inquire_variable(ncID,iVar,name=varName) + if(err/=nf90_noerr)then; + message=trim(message)//'problem inquiring variable: '//trim(varName)//'/'//trim(nf90_strerror(err)); + print*, message + return + endif + + ! find attribute name + select case(trim(varName)) + + ! ** categorical data + case('vegTypeIndex','soilTypeIndex','slopeTypeIndex','downHRUindex') + + ! get the index of the variable + varType = categorical + varIndx = get_ixType(varName) + checkType(varIndx) = .true. + + ! check that the variable could be identified in the data structure + if(varIndx < 1)then + err=20; + message=trim(message)//'unable to find variable ['//trim(varName)//'] in data structure'; + print*, message + return; + endif + + + do iGRU=1,num_gru + do iHRU = 1,gru_struc(iGRU)%hruCount + err = nf90_get_var(ncID,iVar,categorical_var,start=(/gru_struc(iGRU)%hruInfo(iHRU)%hru_nc/),count=(/1/)) + if(err/=nf90_noerr)then + message=trim(message)//'problem reading: '//trim(varName) + print*, message + return + end if + outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(iHRU)%var(varIndx) = categorical_var(1) + end do + end do + + ! ** ID related data + case('hruId') + ! get the index of the variable + varType = idrelated + varIndx = get_ixId(varName) + checkId(varIndx) = .true. + + ! check that the variable could be identified in the data structure + if(varIndx < 1)then + err=20 + message=trim(message)//'unable to find variable ['//trim(varName)//'] in data structure' + print*, message + return + endif + + ! get data from netcdf file and store in vector + do iGRU=1,num_gru + do iHRU = 1,gru_struc(iGRU)%hruCount + err = nf90_get_var(ncID,iVar,idrelated_var,start=(/gru_struc(iGRU)%hruInfo(iHRU)%hru_nc/),count=(/1/)) + if(err/=nf90_noerr)then + message=trim(message)//'problem reading: '//trim(varName) + print*, message + return + end if + outputStructure(1)%idStruct(1)%gru(iGRU)%hru(iHRU)%var(varIndx) = idrelated_var(1) + end do + end do + + ! ** numerical data + case('latitude','longitude','elevation','tan_slope','contourLength','HRUarea','mHeight') + + ! get the index of the variable + varType = numerical + varIndx = get_ixAttr(varName) + checkAttr(varIndx) = .true. + + ! check that the variable could be identified in the data structure + if(varIndx < 1)then + err=20; message=trim(message)//'unable to find variable ['//trim(varName)//'] in data structure' + print*, message + return + endif + ! get data from netcdf file and store in vector + + do iGRU=1,num_gru + do iHRU = 1,gru_struc(iGRU)%hruCount + err = nf90_get_var(ncID,iVar,numeric_var,start=(/gru_struc(iGRU)%hruInfo(iHRU)%hru_nc/),count=(/1/)) + if(err/=nf90_noerr)then + message=trim(message)//'problem reading: '//trim(varName) + print*, message + return + end if + outputStructure(1)%attrStruct(1)%gru(iGRU)%hru(iHRU)%var(varIndx) = numeric_var(1) + end do + end do + + ! for mapping varibles, do nothing (information read above) + case('hru2gruId','gruId'); cycle + + ! check that variables are what we expect + case default + message=trim(message)//'unknown variable ['//trim(varName)//'] in local attributes file' + print*,message + err=20 + return + + end select ! select variable + + end do ! (looping through netcdf local attribute file) + + ! ** now handle the optional aspect variable if it's missing + varIndx = get_ixAttr('aspect') + ! check that the variable was not found in the attribute file + if(.not. checkAttr(varIndx)) then + write(*,*) NEW_LINE('A')//'INFO: aspect not found in the input attribute file, continuing ...'//NEW_LINE('A') + do iGRU=1,num_gru + do iHRU = 1, gru_struc(iGRU)%hruCount + outputStructure(1)%attrStruct(1)%gru(iGRU)%hru(iHRU)%var(varIndx) = nr_realMissing ! populate variable with out-of-range value, used later + end do + end do + checkAttr(varIndx) = .true. + endif + + ! TODO: find out why this is here, probably for the lateral flows + varIndx = get_ixTYPE('downkHRU') + checkType(varIndx) = .true. + ! outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(iHRU)%var(varIndx) = 0 + + ! ********************************************************************************************** + ! (4) check that we have all the desired varaibles + ! ********************************************************************************************** + ! check that we have all desired categorical variables + if(any(.not.checkType))then + do iCheck = 1,size(type_meta) + if(.not.checkType(iCheck))then + err=20 + message=trim(message)//'missing variable ['//trim(type_meta(iCheck)%varname)//'] in local attributes file' + print*, message + return + endif + end do + endif + + ! check that we have all desired ID variables + if(any(.not.checkId))then + do iCheck = 1,size(id_meta) + if(.not.checkId(iCheck))then + err=20 + message=trim(message)//'missing variable ['//trim(id_meta(iCheck)%varname)//'] in local attributes file' + print*, message + return + endif + end do + endif + + ! check that we have all desired local attributes + if(any(.not.checkAttr))then + do iCheck = 1,size(attr_meta) + if(.not.checkAttr(iCheck))then; + err=20 + message=trim(message)//'missing variable ['//trim(attr_meta(iCheck)%varname)//'] in local attributes file' + print*, message + return + endif + end do + endif + + ! ********************************************************************************************** + ! (5) close netcdf file + ! ********************************************************************************************** + + call nc_file_close(ncID,err,cmessage) + if (err/=0)then; message=trim(message)//trim(cmessage); return; end if + + ! free memory + deallocate(checkType) + deallocate(checkId) + deallocate(checkAttr) + +end subroutine + + +end module \ No newline at end of file diff --git a/build/source/actors/file_access_actor/read_param_all_hru.f90 b/build/source/actors/file_access_actor/read_param_all_hru.f90 new file mode 100644 index 0000000000000000000000000000000000000000..10bc4b388414a4650b4d9ac70475ab82b833272a --- /dev/null +++ b/build/source/actors/file_access_actor/read_param_all_hru.f90 @@ -0,0 +1,320 @@ +module read_param_all_hru + USE, intrinsic :: iso_c_binding + USE nrtype + implicit none + private + public::read_param_file_access_actor + public::overwriteParam +contains +subroutine overwriteParam(num_gru, err) bind(C, name="overwriteParam") + USE globalData,only:outputStructure + USE pOverwrite_module,only:pOverwrite ! module to overwrite default parameter values with info from the Noah tables + USE globalData,only:gru_struc + USE globalData,only:localParFallback ! local column default parameters + USE globalData,only:basinParFallback ! basin-average default parameter + USE var_lookup,only:iLookTYPE ! look-up values for classification of veg, soils etc. + + implicit none + integer(c_int),intent(in) :: num_gru ! number of GRUs in the run_domain + integer(c_int),intent(out) :: err ! error code + + ! local + integer(i4b) :: iGRU + integer(i4b) :: iHRU + integer(i4b) :: iVar + integer(i4b) :: iDat + character(len=256) :: message + + err=0; message="overwriteParam" + + ! Need to set the basin parameters with the default values for when we copy + do iGRU=1,num_gru + do iHRU=1,gru_struc(iGRU)%hruCount + do iVar=1, size(localParFallback) + outputStructure(1)%dparStruct(1)%gru(iGRU)%hru(iHRU)%var(iVar) = localParFallback(iVar)%default_val + end do + ! overwrite default model parameters with information from the Noah-MP tables + call pOverwrite(outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(iHRU)%var(iLookTYPE%vegTypeIndex), & ! vegetation category + outputStructure(1)%typeStruct(1)%gru(iGRU)%hru(iHRU)%var(iLookTYPE%soilTypeIndex), & ! soil category + outputStructure(1)%dparStruct(1)%gru(iGRU)%hru(iHRU)%var(:), & ! default model parameters + err,message) + + do iVar=1, size(localParFallback) + do iDat=1, size(outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(iHRU)%var(iVar)%dat) + outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(iHRU)%var(iVar)%dat(iDat) = outputStructure(1)%dparStruct(1)%gru(iGRU)%hru(iHRU)%var(iVar) + end do + end do + end do + do iVar=1,size(basinParFallback) + outputStructure(1)%bparStruct(1)%gru(iGRU)%var(iVar) = basinParFallback(iVar)%default_val + end do + end do + +end subroutine +subroutine read_param_file_access_actor(startGRU,num_gru,err) bind(C, name="readParamFileAccessActor") + ! used to read model initial conditions + USE summaActors_FileManager,only:SETTINGS_PATH ! path for metadata files + USE summaActors_FileManager,only:PARAMETER_TRIAL ! file with parameter trial values + USE get_ixname_module,only:get_ixparam,get_ixbpar ! access function to find index of elements in structure + USE globalData,only:index_map,gru_struc ! mapping from global HRUs to the elements in the data structures + USE var_lookup,only:iLookPARAM,iLookTYPE,iLookID ! named variables to index elements of the data vectors + USE globalData,only:integerMissing ! missing integer + USE globalData,only:realMissing ! missing real number + + USE netcdf + USE netcdf_util_module,only:nc_file_close ! close netcdf file + USE netcdf_util_module,only:nc_file_open ! open netcdf file + USE netcdf_util_module,only:netcdf_err ! netcdf error handling function + + USE globalData,only:outputStructure + + implicit none + ! define input + + integer(c_int),intent(in) :: startGRU ! starting Index of gru Batch + integer(c_int),intent(in) :: num_gru ! number of GRUs in the run_domain + integer(c_int),intent(out) :: err ! error code + + ! define local variables + character(len=256) :: message ! error message + character(len=1024) :: cmessage ! error message for downwind routine + character(LEN=1024) :: infile ! input filename + integer(i4b) :: localHRU_ix ! index of HRU within data structure + integer(i4b) :: ixParam ! index of the model parameter in the data structure + ! indices/metadata in the NetCDF file + integer(i4b) :: ncid ! netcdf id + integer(i4b) :: nDims ! number of dimensions + integer(i4b) :: nVars ! number of variables + integer(i4b) :: idimid ! dimension index + integer(i4b) :: ivarid ! variable index + character(LEN=64) :: dimName ! dimension name + character(LEN=64) :: parName ! parameter name + integer(i4b) :: dimLength ! dimension length + integer(i4b) :: nHRU_file ! number of HRUs in the parafile + integer(i4b) :: nGRU_file ! number of GRUs in the parafile + integer(i4b) :: nSoil_file ! number of soil layers in the file + integer(i4b) :: idim_list(2) ! list of dimension ids + ! data in the netcdf file + integer(i4b) :: parLength ! length of the parameter data + integer(8),allocatable :: hruId(:) ! HRU identifier in the file + real(dp),allocatable :: parVector(:) ! model parameter vector + logical :: fexist ! inquire whether the parmTrial file exists + integer(i4b) :: fHRU ! index of HRU in input file + integer(i4b) :: iGRU + integer(i4b) :: iHRU + integer(i4b) :: iVar + + err=0; message="read_param_all_hru.f90/" + ! ********************************************************************************************** + ! * open files, etc. + ! ********************************************************************************************** + + infile = trim(SETTINGS_PATH)//trim(PARAMETER_TRIAL) ! build filename + + ! check whether the user-specified file exists and warn if it does not + inquire(file=trim(infile),exist=fexist) + if (.not.fexist) then + write(*,'(A)') NEW_LINE('A')//'!! WARNING: trial parameter file not found; proceeding instead with other default parameters; check path in file manager input if this was not the desired behavior'//NEW_LINE('A') + return + endif + + ! open trial parameters file if it exists + call nc_file_open(trim(infile),nf90_nowrite,ncid,err,cmessage) + if(err/=0)then; message=trim(message)//trim(cmessage); return; end if + + ! get the number of variables in the parameter file + err=nf90_inquire(ncid, nDimensions=nDims, nVariables=nVars) + call netcdf_err(err,message); if (err/=0) then; err=20; return; end if + + ! initialize the number of HRUs + nHRU_file=integerMissing + nGRU_file=integerMissing + + ! get the length of the dimensions + do idimid=1,nDims + ! get the dimension name and length + err=nf90_inquire_dimension(ncid, idimid, name=dimName, len=dimLength) + if(err/=0)then; message=trim(message)//trim(cmessage); return; end if + ! get the number of HRUs + if(trim(dimName)=='hru') nHRU_file=dimLength + if(trim(dimName)=='gru') nGRU_file=dimLength + end do + + ! allocate hruID vector + allocate(hruId(nHRU_file)) + + ! check HRU dimension exists + if(nHRU_file==integerMissing)then + message=trim(message)//'unable to identify HRU dimension in file '//trim(infile) + err=20; return + endif + ! ********************************************************************************************** + ! * read the HRU index + ! ********************************************************************************************** + ! loop through the parameters in the NetCDF file + do ivarid=1,nVars + + ! get the parameter name + err=nf90_inquire_variable(ncid, ivarid, name=parName) + call netcdf_err(err,message) + if (err/=0) then + err=20 + print*, message + return + end if + + ! special case of the HRU id + if(trim(parName)=='hruIndex' .or. trim(parName)=='hruId')then + + ! read HRUs + err=nf90_get_var(ncid, ivarid, hruId) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if + + endif ! if the HRU id + + end do ! looping through variables in the file + + ! ********************************************************************************************** + ! * read the local parameters and the basin parameters + ! ********************************************************************************************** + do ivarid=1,nVars + ! get the parameter name + err=nf90_inquire_variable(ncid, ivarid, name=parName) + call netcdf_err(err,message); if (err/=0) then; err=20; return; end if + + ! get the local parameters + ixParam = get_ixparam( trim(parName) ) + if(ixParam/=integerMissing)then + ! ********************************************************************************************** + ! * read the local parameters + ! ********************************************************************************************** + + ! get the variable shape + err=nf90_inquire_variable(ncid, ivarid, nDims=nDims, dimids=idim_list) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if + + ! get the length of the depth dimension (if it exists) + if(nDims==2)then + ! get the information on the 2nd dimension for 2-d variables + err=nf90_inquire_dimension(ncid, idim_list(2), dimName, nSoil_file) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if + + ! check that it is the depth dimension + if(trim(dimName)/='depth')then + message=trim(message)//'expect 2nd dimension of 2-d variable to be depth (dimension name = '//trim(dimName)//')' + err=20; return + endif + + ! TODO: implement this check + ! ! check that the dimension length is correct + ! if(size(outputStructur(1)%mparStruct%var(ixParam)%dat) /= nSoil_file)then + ! message=trim(message)//'unexpected number of soil layers in parameter file' + ! err=20; return + ! endif + + ! define parameter length + parLength = nSoil_file + else + parLength = 1 + endif ! if two dimensions + + ! allocate space for model parameters + allocate(parVector(parLength),stat=err) + if(err/=0)then + message=trim(message)//'problem allocating space for parameter vector' + err=20; return + endif + + ! loop through all hrus + do iGRU=1, num_gru + do iHRU=1, gru_struc(iGRU)%hruCount + localHRU_ix=index_map(iHRU)%localHRU_ix + fHRU = gru_struc(iGRU)%hruInfo(localHRU_ix)%hru_nc + ! read parameter data + select case(nDims) + case(1); err=nf90_get_var(ncid, ivarid, parVector, start=(/fHRU/), count=(/1/) ) + case(2); err=nf90_get_var(ncid, ivarid, parVector, start=(/fHRU,1/), count=(/1,nSoil_file/) ) + case default; err=20; message=trim(message)//'unexpected number of dimensions for parameter '//trim(parName) + end select + + ! error check for the parameter read + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if + + ! populate parameter structures + select case(nDims) + case(1); outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(localHRU_ix)%var(ixParam)%dat(:) = parVector(1) ! also distributes scalar across depth dimension + case(2); outputStructure(1)%mparStruct(1)%gru(iGRU)%hru(localHRU_ix)%var(ixParam)%dat(:) = parVector(:) + case default; err=20; message=trim(message)//'unexpected number of dimensions for parameter '//trim(parName) + end select + end do + end do + + ! deallocate space for model parameters + deallocate(parVector,stat=err) + if(err/=0)then + message=trim(message)//'problem deallocating space for parameter vector' + print*, message + err=20; return + endif + + ! ********************************************************************************************** + ! * read the basin parameters + ! ********************************************************************************************** + + ! get the basin parameters + else + ! get the parameter index + ixParam = get_ixbpar( trim(parName) ) + + ! allow extra variables in the file that are not used + if(ixParam==integerMissing) cycle + + ! allocate space for model parameters + allocate(parVector(nGRU_file),stat=err) + if(err/=0)then + message=trim(message)//'problem allocating space for parameter vector' + print*, message + err=20; return + endif + + ! read parameter data + err=nf90_get_var(ncid, ivarid, parVector ) + if(err/=0)then; message=trim(message)//trim(cmessage); return; end if + + ! populate parameter structures + do iGRU=1, num_gru + outputStructure(1)%bparStruct(1)%gru(iGRU)%var(ixParam) = parVector(iGRU+startGRU-1) + end do + + ! deallocate space for model parameters + deallocate(parVector,stat=err) + if(err/=0)then + message=trim(message)//'problem deallocating space for parameter vector' + print*, message + err=20; return + endif + endif + + end do ! (looping through the parameters in the NetCDF file) + + ! Now we must close the netcdf file + call nc_file_close(ncid,err,message) + if(err/=0)then;message=trim(message)//trim(cmessage);return;end if +end subroutine read_param_file_access_actor +end module read_param_all_hru \ No newline at end of file diff --git a/build/source/actors/global/cppwrap_datatypes.f90 b/build/source/actors/global/cppwrap_datatypes.f90 index b53ad96c61e744792ebada9cd6e3c3861adc7d69..418b6f4b17411f8e24b4c230f40a020f0c91973b 100644 --- a/build/source/actors/global/cppwrap_datatypes.f90 +++ b/build/source/actors/global/cppwrap_datatypes.f90 @@ -1057,6 +1057,15 @@ subroutine delete_handle_file_info(handle) bind(C, name='delete_handle_file_info end subroutine delete_handle_file_info ! ***************************** file_info *************************** + +! ****************************** z_lookup **************************** +function new_handle_z_lookup() result(handle) bind(C, name="new_handle_z_lookup") + type(c_ptr) :: handle + type(zLookup), pointer :: p + + allocate(p) + handle = c_loc(p) +end function end module cppwrap_datatypes diff --git a/build/source/actors/global/global.cpp b/build/source/actors/global/global.cpp index dff7bf4d1fb978d6d7b4e9eb15c59f3f2accdbc4..0ef698918431e2ebc9d0b716a04030e5e5ca4b6c 100644 --- a/build/source/actors/global/global.cpp +++ b/build/source/actors/global/global.cpp @@ -2,6 +2,7 @@ #include <chrono> + double calculateTime(std::chrono::time_point<std::chrono::system_clock> start, std::chrono::time_point<std::chrono::system_clock> end) { diff --git a/build/source/actors/gru_actor/gru_actor.cpp b/build/source/actors/gru_actor/gru_actor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef0e1cabc0bbc632d57b122e402ab51fe22f19d6 --- /dev/null +++ b/build/source/actors/gru_actor/gru_actor.cpp @@ -0,0 +1,153 @@ +#include "caf/all.hpp" +#include "gru_actor.hpp" +#include "global.hpp" +#include "hru_actor.hpp" +#include "message_atoms.hpp" +#include <vector> +#include "gru_actor_subroutine_wrappers.hpp" + +namespace caf { + +behavior gru_actor(stateful_actor<gru_state>* self, + int ref_gru, int indx_gru, + std::string config_path, caf::actor file_access_actor, int output_struc_size, + caf::actor parent) { + + aout(self) << "GRU Actor Has Started\n"; + self->state.parent = parent; + self->state.ref_gru = ref_gru; + self->state.indx_gru = indx_gru; + self->state.config_path = config_path; + self->state.file_access_actor = file_access_actor; + self->state.output_struc_size = output_struc_size; + self->state.parent = parent; + + self->state.num_hrus = getNumHRU(&self->state.indx_gru); + + self->send(self, init_hru_v); + + return { + + [=](init_hru) { + for (int i = 0; i < self->state.num_hrus; i++) { + auto hru = self->spawn(hru_actor, + self->state.ref_gru, self->state.indx_gru, + self->state.config_path, self->state.file_access_actor, + self->state.output_struc_size, + self); + self->state.hru_list.push_back(hru); + } + }, + + [=](done_hru, int indx_gru, double total_duration, double init_duration, + double forcing_duration, double run_physics_duration, double write_output_duration) { + aout(self) << "GRU Received HRU is Done\n"; + + self->state.hrus_complete++; + if (self->state.hrus_complete >= self->state.num_hrus) { + aout(self) << "All HRUs have finished"; + + self->send(self->state.parent, + done_hru_v, + indx_gru, + total_duration, + init_duration, + forcing_duration, + run_physics_duration, + write_output_duration); + } + + }, + + // 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 \n"; + int integer_missing_value = -9999; + + // Get the sizes we need for the lists from Fortran + getVarSizes(&self->state.num_var_types, + &self->state.num_bpar_vars, + &self->state.num_bvar_vars); + + aout(self) << "GRU: GOT VAR SIZES\n"; + aout(self) << "NUM VAR Type = " << self->state.num_var_types << "\n"; + aout(self) << "NUM BPAR = " << self->state.num_bpar_vars << "\n"; + aout(self) << "NUM BVAR = " << self->state.num_bvar_vars << "\n"; + + for (int i = 0; i < self->state.num_var_types; i++) { + self->state.i_look_var_type_list.push_back(integer_missing_value); + } + for (int i = 0; i < self->state.num_bpar_vars; i++) { + self->state.bpar_struct_var_type_list.push_back(integer_missing_value); + } + for (int i = 0; i < self->state.num_bvar_vars; i++) { + self->state.bvar_struct_var_type_list.push_back(integer_missing_value); + } + + initVarType(&self->state.var_type_lookup); + // aout(self) << "************C++************\n"; + // aout(self) << self->state.var_type_lookup.scalarv << "\n"; + // aout(self) << self->state.var_type_lookup.wLength << "\n"; + // aout(self) << self->state.var_type_lookup.midSnow << "\n"; + // aout(self) << self->state.var_type_lookup.midSoil << "\n"; + // aout(self) << self->state.var_type_lookup.midToto << "\n"; + // aout(self) << self->state.var_type_lookup.ifcSnow << "\n"; + // aout(self) << self->state.var_type_lookup.ifcSoil << "\n"; + // aout(self) << self->state.var_type_lookup.ifcToto << "\n"; + // aout(self) << self->state.var_type_lookup.parSoil << "\n"; + // aout(self) << self->state.var_type_lookup.routing << "\n"; + // aout(self) << self->state.var_type_lookup.outstat << "\n"; + // aout(self) << self->state.var_type_lookup.unknown << "\n"; + // aout(self) << "************C++************\n"; + + // Fill The lists with the values from the fortran lists + int err = 0; + fillVarTypeLists(&self->state.num_bpar_vars, + &self->state.num_bvar_vars, + &self->state.bpar_struct_var_type_list[0], + &self->state.bvar_struct_var_type_list[0], + &err); + // aout(self) << "Printing BPAR\n"; + // for(int i = 0; i < self->state.num_bpar_vars; i++) { + // aout(self) << i << ": " << self->state.bpar_struct_var_type_list[i] << "\n"; + // } + // aout(self) << "Printing BVAR\n"; + // for(int i = 0; i < self->state.num_bvar_vars; i++) { + // aout(self) << i << ": " << self->state.bvar_struct_var_type_list[i] << "\n"; + // } + + // Now we can allocate space for the structures + for(int i = 0; i < self->state.num_bpar_vars; i++) { + if (self->state.bpar_struct_var_type_list[i] == self->state.var_type_lookup.scalarv) { + self->state.bpar_struct.push_back(0.0); + } else { + aout(self) << "ERROR: GRU - bpar_struct contains type that is not a scalar\n"; + } + } + for(int i = 0; i < self->state.num_bvar_vars; i++) { + if (self->state.bvar_struct_var_type_list[i] == self->state.var_type_lookup.scalarv) { + std::vector<double> temp; + self->state.bvar_struct.push_back(temp); + self->state.bvar_struct[i].push_back(0.0); + + } else if(self->state.bvar_struct_var_type_list[i] == self->state.var_type_lookup.routing) { + std::vector<double> temp; + self->state.bvar_struct.push_back(temp); + for (int x = 0; x < self->state.nTimeDelay; x++) { + self->state.bvar_struct[i].push_back(0.0); + } + } else { + aout(self) << "ERROR: GRU - bvar_struct contains type that is not a scalar or routing\n"; + + } + } + + self->send(self->state.parent, done_init_gru_v); + } + + + }; +} + +} \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..e2f2a2fc76359aca3fcdae98d34d6424eead4bae --- /dev/null +++ b/build/source/actors/gru_actor/gru_actor.f90 @@ -0,0 +1,222 @@ +!!! Lets try and build this for only the lateral flows case. +!!! If lateral flows exits use the code +module gru_actor +USE,intrinsic :: iso_c_binding +USE nrtype + +implicit none + +! public::run_gru +public::getVarSizes +public::fillvarTypeLists +public::getNumHRU + +contains + +subroutine getVarSizes(num_var_types, & + num_bpar_vars, & + num_bvar_vars) bind(C,name="getVarSizes") + USE var_lookup,only:maxvarBpar, maxvarBvar, maxvarVarType + implicit none + + integer(c_int), intent(out) :: num_var_types + integer(c_int), intent(out) :: num_bpar_vars + integer(c_int), intent(out) :: num_bvar_vars + + num_var_types = maxvarVarType + num_bpar_vars = maxvarBpar + num_bvar_vars = maxvarBvar + +end subroutine getVarSizes + +subroutine initVarType(var_type_lookup) bind(C, name="initVarType") + USE var_lookup,only:iLookVarType + USE var_lookup,only:iLook_VarType + + implicit none + type(iLook_VarType) :: var_type_lookup + + ! Get the indexes to match C++ offset starting at 0 + var_type_lookup%scalarv = iLookVarType%scalarv - 1 + var_type_lookup%wLength = iLookVarType%wLength - 1 + var_type_lookup%midSnow = iLookVarType%midSnow - 1 + var_type_lookup%midSoil = iLookVarType%midSoil - 1 + var_type_lookup%midToto = iLookVarType%midToto - 1 + var_type_lookup%ifcSnow = iLookVarType%ifcSnow - 1 + var_type_lookup%ifcSoil = iLookVarType%ifcSoil - 1 + var_type_lookup%ifcToto = iLookVarType%ifcToto - 1 + var_type_lookup%parSoil = iLookVarType%parSoil - 1 + var_type_lookup%routing = iLookVarType%routing - 1 + var_type_lookup%outstat = iLookVarType%outstat - 1 + var_type_lookup%unknown = iLookVarType%unknown - 1 + + ! check the values + ! print*, "************FORTRAN************" + ! print*, "iLookVarType%scalarv", iLookVarType%scalarv + ! print*, "iLookVarType%wLength", iLookVarType%wLength + ! print*, "iLookVarType%midSnow", iLookVarType%midSnow + ! print*, "iLookVarType%midSoil", iLookVarType%midSoil + ! print*, "iLookVarType%midToto", iLookVarType%midToto + ! print*, "iLookVarType%ifcSnow", iLookVarType%ifcSnow + ! print*, "iLookVarType%ifcSoil", iLookVarType%ifcSoil + ! print*, "iLookVarType%ifcToto", iLookVarType%ifcToto + ! print*, "iLookVarType%parSoil", iLookVarType%parSoil + ! print*, "iLookVarType%routing", iLookVarType%routing + ! print*, "iLookVarType%outstat", iLookVarType%outstat + ! print*, "iLookVarType%unknown", iLookVarType%unknown + ! print*, "************FORTRAN************" + + +end subroutine +subroutine fillVarTypeLists(num_bpar_vars, & + num_bvar_vars, & + bpar_struct_var_type_list, & + bvar_struct_var_type_list, & + err) bind(C, name="fillVarTypeLists") + + USE globalData,only:type_meta,bpar_meta,bvar_meta + USE var_lookup,only:iLookBVAR,iLookBPAR,iLookVarType + implicit none + integer(c_int), intent(in) :: num_bpar_vars + integer(c_int), intent(in) :: num_bvar_vars + integer(c_int), intent(out), dimension(num_bpar_vars) :: bpar_struct_var_type_list + integer(c_int), intent(out), dimension(num_bvar_vars) :: bvar_struct_var_type_list + integer(c_int), intent(out) :: err + integer(i4b) :: iVar + + + ! Get the types of the variables for bparStruct + ! Index in bpar_struct_var_type_list will match bpar_Struct + do iVar=1, num_bpar_vars + select case(bpar_meta(iVar)%vartype) + case(iLookVarType%scalarv); bpar_struct_var_type_list(iVar) = iLookVarType%scalarv - 1 + case(iLookVarType%wLength); bpar_struct_var_type_list(iVar) = iLookVarType%wLength - 1 + case(iLookVarType%midSnow); bpar_struct_var_type_list(iVar) = iLookVarType%midSnow - 1 + case(iLookVarType%midSoil); bpar_struct_var_type_list(iVar) = iLookVarType%midSoil - 1 + case(iLookVarType%midToto); bpar_struct_var_type_list(iVar) = iLookVarType%midToto - 1 + case(iLookVarType%ifcSnow); bpar_struct_var_type_list(iVar) = iLookVarType%ifcSnow - 1 + case(iLookVarType%ifcSoil); bpar_struct_var_type_list(iVar) = iLookVarType%ifcSoil - 1 + case(iLookVarType%ifcToto); bpar_struct_var_type_list(iVar) = iLookVarType%ifcToto - 1 + case(iLookVarType%parSoil); bpar_struct_var_type_list(iVar) = iLookVarType%parSoil - 1 + case(iLookVarType%routing); bpar_struct_var_type_list(iVar) = iLookVarType%routing - 1 + case(iLookVarType%outstat); bpar_struct_var_type_list(iVar) = iLookVarType%outstat - 1 + case(iLookVarType%unknown); bpar_struct_var_type_list(iVar) = iLookVarType%unknown - 1 + case default + err = 40; + return + end select + end do + + do iVar=1, num_bvar_vars + select case(bvar_meta(iVar)%vartype) + case(iLookVarType%scalarv); bvar_struct_var_type_list(iVar) = iLookVarType%scalarv - 1 + case(iLookVarType%wLength); bvar_struct_var_type_list(iVar) = iLookVarType%wLength - 1 + case(iLookVarType%midSnow); bvar_struct_var_type_list(iVar) = iLookVarType%midSnow - 1 + case(iLookVarType%midSoil); bvar_struct_var_type_list(iVar) = iLookVarType%midSoil - 1 + case(iLookVarType%midToto); bvar_struct_var_type_list(iVar) = iLookVarType%midToto - 1 + case(iLookVarType%ifcSnow); bvar_struct_var_type_list(iVar) = iLookVarType%ifcSnow - 1 + case(iLookVarType%ifcSoil); bvar_struct_var_type_list(iVar) = iLookVarType%ifcSoil - 1 + case(iLookVarType%ifcToto); bvar_struct_var_type_list(iVar) = iLookVarType%ifcToto - 1 + case(iLookVarType%parSoil); bvar_struct_var_type_list(iVar) = iLookVarType%parSoil - 1 + case(iLookVarType%routing); bvar_struct_var_type_list(iVar) = iLookVarType%routing - 1 + case(iLookVarType%outstat); bvar_struct_var_type_list(iVar) = iLookVarType%outstat - 1 + case(iLookVarType%unknown); bvar_struct_var_type_list(iVar) = iLookVarType%unknown - 1 + case default + err = 40; + return + end select + end do +end subroutine fillVarTypeLists + + + +! 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) + +! ! ----- 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 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 + +! 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) ) + +! ! 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 + +! 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 + +integer function getNumHRU(indx_gru) bind(C, name="getNumHRU") + USE globalData,only:gru_struc + implicit none + integer(c_int), intent(in) :: indx_gru + integer(c_int) :: num_hru + + num_hru = gru_struc(indx_gru)%hruCount + + getNumHRU = num_hru + +end function + + +end module gru_actor + +! the way the lateral flow interface should work seems to be at the level of the hru. +! The HRU would have an interface where it has a donwslope compontent. It would then ask +! for this downslope component. This all does have to be setup before hand so the gru needs to +! set these up because the hrus all need to comptue +! a grus timestep depends on all the hrus + +! So the Gru needs to be controlling the hrus. It needs to know which ones have lateral flows and which ones do not. +! This is so the other hrus know they do not need to contact another actor. Otherwise they will have to. \ No newline at end of file diff --git a/build/source/actors/hru_actor/cppwrap_hru.f90 b/build/source/actors/hru_actor/cppwrap_hru.f90 index 11b27e42a0427b2f57d6d7aa5cccdd225395d9d2..baededc065726ce80b580e371a4ada64c64f9b75 100644 --- a/build/source/actors/hru_actor/cppwrap_hru.f90 +++ b/build/source/actors/hru_actor/cppwrap_hru.f90 @@ -8,7 +8,7 @@ USE globalData implicit none ! public::Initialize ! This is called Directly by the actors code ! The above is here just in case I look here again -public::SetupParam +! public::SetupParam ! This is now called directly by the actors code as setupHRUParam public::Restart public::Forcing public::RunPhysics @@ -17,95 +17,8 @@ public::Write_Param_C contains -! ********************************************************************************************************** -! public subroutine SetupParam: initializes parameter data structures (e.g. vegetation and soil parameters). -! ********************************************************************************************************** -subroutine SetupParam(& - indxGRU, & ! Index of the parent GRU of the HRU - indxHRU, & ! ID to get the correct HRU data - ! primary data structures (scalars) - handle_attrStruct, & ! local attributes for each HRU - handle_typeStruct, & ! local classification of soil veg etc. for each HRU - handle_idStruct, & ! local classification of soil veg etc. for each HRU - ! primary data structures (variable length vectors) - handle_mparStruct, & ! model parameters - handle_bparStruct, & ! basin-average parameters - handle_bvarStruct, & ! basin-average variables - handle_dparStruct, & ! default model parameters - ! local HRU data - handle_startTime, & ! start time for the model simulation - handle_oldTime, & ! time for the previous model time step - ! miscellaneous variables - upArea, & ! area upslope of each HRU, - err) bind(C,name='SetupParam') - - USE SummaActors_setup,only:SummaActors_paramSetup - - implicit none - ! calling variables - integer(c_int),intent(in) :: indxGRU ! Index of the parent GRU of the HRU - integer(c_int),intent(in) :: indxHRU ! ID to locate correct HRU from netcdf file - type(c_ptr), intent(in), value :: handle_attrStruct ! local attributes for each HRU - type(c_ptr), intent(in), value :: handle_typeStruct ! local classification of soil veg etc. for each HRU - type(c_ptr), intent(in), value :: handle_idStruct ! - type(c_ptr), intent(in), value :: handle_mparStruct ! model parameters - type(c_ptr), intent(in), value :: handle_bparStruct ! basin-average parameters - type(c_ptr), intent(in), value :: handle_bvarStruct ! basin-average variables - type(c_ptr), intent(in), value :: handle_dparStruct ! default model parameters - type(c_ptr), intent(in), value :: handle_startTime ! start time for the model simulation - type(c_ptr), intent(in), value :: handle_oldTime ! time for the previous model time step - real(c_double),intent(inout) :: upArea - integer(c_int),intent(inout) :: err - !--------------------------------------------------------------------------------------------------- - ! local variables - type(var_d),pointer :: attrStruct ! local attributes for each HRU - type(var_i),pointer :: typeStruct ! local classification of soil veg etc. for each HRU - type(var_i8),pointer :: idStruct ! - type(var_dlength),pointer :: mparStruct ! model parameters - type(var_d),pointer :: bparStruct ! basin-average parameters - type(var_dlength),pointer :: bvarStruct ! basin-average variables - type(var_d),pointer :: dparStruct ! default model parameters - type(var_i),pointer :: startTime ! start time for the model simulation - type(var_i),pointer :: oldTime ! time for the previous model time step - character(len=256) :: message - ! getting data - call c_f_pointer(handle_attrStruct, attrStruct) - call c_f_pointer(handle_typeStruct, typeStruct) - call c_f_pointer(handle_idStruct, idStruct) - call c_f_pointer(handle_mparStruct, mparStruct) - call c_f_pointer(handle_bparStruct, bparStruct) - call c_f_pointer(handle_bvarStruct, bvarStruct) - call c_f_pointer(handle_dparStruct, dparStruct) - call c_f_pointer(handle_startTime, startTime) - call c_f_pointer(handle_oldTime, oldTime) - - call SummaActors_paramSetup(& - indxHRU, & ! ID of hru to obtain from netcdf file - indxGRU, & ! Index of the parent GRU of the HRU - ! primary data structures (scalars) - attrStruct, & ! local attributes for each HRU - typeStruct, & ! local classification of soil veg etc. for each HRU - idStruct, & ! local classification of soil veg etc. for each HRU - ! primary data structures (variable length vectors) - mparStruct, & ! model parameters - bparStruct, & ! basin-average parameters - bvarStruct, & ! basin-average variables - dparStruct, & ! default model parameters - ! local HRU data - startTime, & ! start time for the model simulation - oldTime, & ! time for the previous model time step - ! miscellaneous variables - upArea, & ! area upslope of each HRU, - err, message) - if(err/=0)then - message=trim(message) - print*, message - endif - -end subroutine SetupParam - ! ********************************************************************************************************** ! public subroutine Restart: ! ********************************************************************************************************** diff --git a/build/source/actors/hru_actor/hru_actor.cpp b/build/source/actors/hru_actor/hru_actor.cpp index 90b60db61a71e33454bc90879e4f4324e14342ae..0a62507f66e85c3bae0febc950c3b573e9e39521 100644 --- a/build/source/actors/hru_actor/hru_actor.cpp +++ b/build/source/actors/hru_actor/hru_actor.cpp @@ -56,7 +56,7 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU, Initialize_HRU(self); self->state.hru_timing.updateEndPoint("total_duration"); - self->send(self->state.parent, done_init_hru_v); + self->send(self, start_hru_v); return { // Starts the HRU and tells it to ask for data from the file_access_actor @@ -152,8 +152,9 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU, void Initialize_HRU(stateful_actor<hru_state>* self) { self->state.hru_timing.updateStartPoint("init_duration"); - summaActors_initialize(&self->state.indxGRU, + initHRU(&self->state.indxGRU, &self->state.num_steps, + self->state.handle_lookupStruct, self->state.handle_forcStat, self->state.handle_progStat, self->state.handle_diagStat, @@ -188,7 +189,7 @@ void Initialize_HRU(stateful_actor<hru_state>* self) { return; } - SetupParam(&self->state.indxGRU, + setupHRUParam(&self->state.indxGRU, &self->state.indxHRU, self->state.handle_attrStruct, self->state.handle_typeStruct, diff --git a/build/source/actors/hru_actor/hru_actor.f90 b/build/source/actors/hru_actor/hru_actor.f90 new file mode 100644 index 0000000000000000000000000000000000000000..2ae7bab059d99f8c4f479b7e0202578c2456e613 --- /dev/null +++ b/build/source/actors/hru_actor/hru_actor.f90 @@ -0,0 +1,151 @@ +module hru_actor + implicit none + + + public::run_hru_for_timestep() + + contains + subroutine run_hru_for_timestep() + + + ! local variables: + integer(i4b) :: nSnow + integer(i4b) :: nSoil + integer(i4b) :: nLayers + + ! ******************************************************************************************* + ! *** initialize computeVegFlux (flag to indicate if we are computing fluxes over vegetation) + ! ******************************************************************************************* + + ! if computeVegFlux changes, then the number of state variables changes, and we need to reoranize the data structures + if(modelTimeStep==1)then + ! get vegetation phenology + ! (compute the exposed LAI and SAI and whether veg is buried by snow) + call vegPhenlgy(& + ! input/output: data structures + model_decisions, & ! intent(in): model decisions + typeStruct, & ! intent(in): type of vegetation and soil + attrStruct, & ! intent(in): spatial attributes + mparStruct, & ! intent(in): model parameters + progStruct, & ! intent(in): model prognostic variables for a local HRU + diagStruct, & ! intent(inout): model diagnostic variables for a local HRU + ! output + computeVegFluxFlag, & ! intent(out): flag to indicate if we are computing fluxes over vegetation (.false. means veg is buried with snow) + notUsed_canopyDepth, & ! intent(out): NOT USED: canopy depth (m) + notUsed_exposedVAI, & ! intent(out): NOT USED: exposed vegetation area index (m2 m-2) + fracJulDay, & + yearLength, & + err,cmessage) ! intent(out): error control + if(err/=0)then; message=trim(message)//trim(cmessage); return; endif + + ! save the flag for computing the vegetation fluxes + if(computeVegFluxFlag) computeVegFlux = yes + if(.not.computeVegFluxFlag) computeVegFlux = no + ! define the green vegetation fraction of the grid box (used to compute LAI) + diagStruct%var(iLookDIAG%scalarGreenVegFraction)%dat(1) = greenVegFrac_monthly(timeStruct%var(iLookTIME%im)) + end if ! if first timestep + + ! initialize total inflow for each layer in a soil column + fluxStruct%var(iLookFLUX%mLayerColumnInflow)%dat(:) = 0._dp + + ! convienence variables + nSnow = indxStruct%var(iLookINDEX%nSnow)%dat(1) ! number of snow layers + nSoil = indxStruct%var(iLookINDEX%nSoil)%dat(1) ! number of soil layers + nLayers = indxStruct%var(iLookINDEX%nLayers)%dat(1) ! total number of layers + + computeVegFluxFlag = (ComputeVegFlux == yes) + + ! water pixel: do nothing + if (typeStruct%var(iLookTYPE%vegTypeIndex) == isWater) return + + ! get height at bottom of each soil layer, negative downwards (used in Noah MP) + allocate(zSoilReverseSign(nSoil),stat=err) + if(err/=0)then + message=trim(message)//'problem allocating space for zSoilReverseSign' + err=20; return + endif + zSoilReverseSign(:) = -progStruct%var(iLookPROG%iLayerHeight)%dat(nSnow+1:nLayers) + + ! populate parameters in Noah-MP modules + ! Passing a maxSoilLayer in order to pass the check for NROOT, that is done to avoid making any changes to Noah-MP code. + ! --> NROOT from Noah-MP veg tables (as read here) is not used in SUMMA + call REDPRM(typeStruct%var(iLookTYPE%vegTypeIndex), & ! vegetation type index + typeStruct%var(iLookTYPE%soilTypeIndex), & ! soil type + typeStruct%var(iLookTYPE%slopeTypeIndex), & ! slope type index + zSoilReverseSign, & ! * not used: height at bottom of each layer [NOTE: negative] (m) + maxSoilLayers, & ! number of soil layers + urbanVegCategory) ! vegetation category for urban areas + + ! deallocate height at bottom of each soil layer(used in Noah MP) + deallocate(zSoilReverseSign,stat=err) + if(err/=0)then + message=trim(message)//'problem deallocating space for zSoilReverseSign' + err=20; return + endif + + ! overwrite the minimum resistance + if(overwriteRSMIN) RSMIN = mparStruct%var(iLookPARAM%minStomatalResistance)%dat(1) + + ! overwrite the vegetation height + HVT(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyTop)%dat(1) + HVB(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyBottom)%dat(1) + + ! overwrite the tables for LAI and SAI + if(model_decisions(iLookDECISIONS%LAI_method)%iDecision == specified)then + SAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%winterSAI)%dat(1) + LAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%summerLAI)%dat(1)*greenVegFrac_monthly + end if + + ! compute derived forcing variables + call derivforce(& + timeStruct%var, & ! vector of time information + forcStruct%var, & ! vector of model forcing data + attrStruct%var, & ! vector of model attributes + mparStruct, & ! data structure of model parameters + progStruct, & ! data structure of model prognostic variables + diagStruct, & ! data structure of model diagnostic variables + fluxStruct, & ! data structure of model fluxes + tmZoneOffsetFracDay,& + err,cmessage) ! error control + if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif + + ! initialize the number of flux calls + diagStruct%var(iLookDIAG%numFluxCalls)%dat(1) = 0._dp + + ! run the model for a single HRU + call coupled_em(& + ! model control + indxHRU, & ! intent(in): hruID + dt_init, & ! intent(inout): initial time step + dt_init_factor, & ! Used to adjust the length of the timestep in the event of a failure + computeVegFluxFlag, & ! intent(inout): flag to indicate if we are computing fluxes over vegetation + ! data structures (input) + typeStruct, & ! intent(in): local classification of soil veg etc. for each HRU + attrStruct, & ! intent(in): local attributes for each HRU + forcStruct, & ! intent(in): model forcing data + mparStruct, & ! intent(in): model parameters + bvarStruct, & ! intent(in): basin-average model variables + ! data structures (input-output) + indxStruct, & ! intent(inout): model indices + progStruct, & ! intent(inout): model prognostic variables for a local HRU + diagStruct, & ! intent(inout): model diagnostic variables for a local HRU + fluxStruct, & ! intent(inout): model fluxes for a local HRU + fracJulDay, & + yearLength, & + ! error control + err,cmessage) ! intent(out): error control + if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif + + ! save the flag for computing the vegetation fluxes + if(computeVegFluxFlag) ComputeVegFlux = yes + if(.not.computeVegFluxFlag) ComputeVegFlux = no + + ! The gru_actor will need the following information + fracHRU = attrStruct%var(iLookATTR%HRUarea) / bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1) + fluxStruct%var(iLookFLUX%scalarSurfaceRunoff)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) + fluxStruct%var(iLookFLUX%scalarAquiferTranspire)%dat(1) + fluxStruct%var(iLookFLUX%scalarAquiferBaseflow)%dat(1) + end subroutine + +end module hru_actor \ No newline at end of file diff --git a/build/source/actors/job_actor/cppwrap_job.f90 b/build/source/actors/job_actor/cppwrap_job.f90 deleted file mode 100644 index 8ece46e9231f10f37655b5edfcffa77b11e38a7c..0000000000000000000000000000000000000000 --- a/build/source/actors/job_actor/cppwrap_job.f90 +++ /dev/null @@ -1,184 +0,0 @@ -module cppwrap_job - USE, intrinsic :: iso_c_binding - USE nrtype - USE data_types - USE globalData - - implicit none - public::initGlobals - public::cleanUpJobActor - private::allocTime - - contains -! ********************************************************************************************************** -! public subroutine initGlobals: set global vars and directories, -! ********************************************************************************************************** -subroutine initGlobals(file_manager, totalGRUs, totalHRUs, numGRUs, numHRUs, startGRUIndex, err) bind(C, name='initGlobals') - ! subroutines and functions: initial priming - ! USE summa4chm_util, only:getCommandArguments4chm ! process command line arguments - USE summaActors_FileManager,only:summa_SetTimesDirsAndFiles ! sets directories and filenames - USE summa_globalData,only:summa_defineGlobalData ! used to define global summa data structures - ! subroutines and functions: read dimensions (NOTE: NetCDF) - USE read_attribute_module,only:read_dimension ! module to read dimensions of GRU and HRU - USE read_icond4chm_module,only:read_icond_nlayers ! module to read initial condition dimensions - ! provide access to file paths - USE summaActors_FileManager,only:SETTINGS_PATH ! define path to settings files (e.g., parameters, soil and veg. tables) - USE summaActors_FileManager,only:STATE_PATH ! optional path to state/init. condition files (defaults to SETTINGS_PATH) - USE summaActors_FileManager,only:MODEL_INITCOND ! name of model initial conditions file - USE summaActors_FileManager,only:LOCAL_ATTRIBUTES ! name of model initial attributes file - ! set up forcing data, needed here to avoid concurrent access - USE ffile_info_module,only:ffile_info ! module to read information on forcing datafile - USE mDecisions_module,only:mDecisions ! module to read model decisions - USE allocspace4chm_module,only:allocLocal - - USE cppwrap_auxiliary,only:c_f_string - - implicit none - ! dummy variables - character(kind=c_char,len=1),intent(in) :: file_manager(*) - integer(c_int),intent(inout) :: totalGRUs ! Variable to return total number of GRUs (not really needed) - integer(c_int),intent(inout) :: totalHRUs ! Variable to return total number of HRUs (not really needed) - integer(c_int),intent(in) :: numGRUs ! Number of GRUs for this current run - integer(c_int),intent(out) :: numHRUs ! Number of HRUs for this current run - integer(c_int),intent(in) :: startGRUIndex ! Index of the starting GRU - integer(c_int),intent(out) :: err ! Error Code - - ! local variables - character(len=256) :: file_manager_path ! path/name of file defining directories and files - character(len=256) :: message ! error message - character(LEN=256) :: cmessage ! error message of downwind routine - character(len=256) :: restartFile ! restart file name - character(len=256) :: attrFile ! attributes file name - integer(i4b) :: fileGRU ! [used for filenames] number of GRUs in the input file - integer(i4b) :: fileHRU ! [used for filenames] number of HRUs in the input file - character(len=256) :: summaFileManagerFile ! path/name of file defining directories and files - - call c_f_string(file_manager, file_manager_path, 256) - - ! Conver the fileManager path to format needed for summa_SetTimesDirsAndFIles - summaFileManagerFile = trim(file_manager_path) - ! set directories and files -- summaFileManager used as command-line argument - call summa_SetTimesDirsAndFiles(summaFileManagerFile,err,cmessage) - ! if(err/=0)then; message=trim(message)//trim(cmessage); return; endif; - if(err/=0)then - message=trim(message)//trim(cmessage) - print*, cmessage - return - endif - - ! define global data (parameters, metadata) - call summa_defineGlobalData(err, cmessage) - ! if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - if(err/=0)then - message=trim(message)//trim(cmessage) - print*, cmessage - return - endif - ! Set the index of the start GRU - startGRU = startGRUIndex - - ! ***************************************************************************** - ! *** read the number of GRUs and HRUs - ! ***************************************************************************** - attrFile = trim(SETTINGS_PATH)//trim(LOCAL_ATTRIBUTES) - call read_dimension(trim(attrFile),fileGRU,fileHRU,numGRUs,numHRUs,startGRUIndex,err,cmessage) - if(err/=0)then - message=trim(message)//trim(cmessage) - print*, cmessage - return - endif - totalGRUs = fileGRU - totalHRUs = fileHRU - - ! ***************************************************************************** - ! *** read the number of snow and soil layers - ! ***************************************************************************** - ! set restart filename and read the number of snow and soil layers from the initial conditions (restart) file - if(STATE_PATH == '') then - restartFile = trim(SETTINGS_PATH)//trim(MODEL_INITCOND) - else - restartFile = trim(STATE_PATH)//trim(MODEL_INITCOND) - endif - - call read_icond_nlayers(trim(restartFile),numGRUs,indx_meta,err,cmessage) - if(err/=0)then - message=trim(message)//trim(cmessage) - print*, cmessage - return - endif - - ! Initalize time structures - call allocTime(err) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - -end subroutine initGlobals - - -subroutine allocTime(err) - USE globalData,only:startTime,finshTime,refTime,oldTime - USE allocspace4chm_module,only:allocLocal - USE globalData,only:time_meta - - implicit none - ! dummy variables - integer(i4b),intent(inout) :: err - ! local variables - character(len=256) :: cmessage - - call allocLocal(time_meta, startTime, err=err, message=cmessage) - call allocLocal(time_meta, finshTime, err=err, message=cmessage) - call allocLocal(time_meta, refTime, err=err, message=cmessage) - call allocLocal(time_meta, oldTime, err=err, message=cmessage) - -end subroutine allocTime - - -subroutine cleanUpJobActor(err) bind(C, name='cleanUpJobActor') - USE globalData,only:structInfo ! information on the data structures - USE globalData,only:statForc_meta ! child metadata for stats - USE globalData,only:statProg_meta ! child metadata for stats - USE globalData,only:statDiag_meta ! child metadata for stats - USE globalData,only:statFlux_meta ! child metadata for stats - USE globalData,only:statIndx_meta ! child metadata for stats - USE globalData,only:statBvar_meta ! child metadata for stats - USE globalData,only:forcChild_map ! index of the child data structure: stats forc - USE globalData,only:progChild_map ! index of the child data structure: stats prog - USE globalData,only:diagChild_map ! index of the child data structure: stats diag - USE globalData,only:fluxChild_map ! index of the child data structure: stats flux - USE globalData,only:indxChild_map ! index of the child data structure: stats indx - USE globalData,only:bvarChild_map ! index of the child data structure: stats bvar - USE globalData,only:gru_struc ! gru->hru mapping structure - USE globalData,only:index_map - USE globalData,only:startTime,finshTime,refTime,oldTime - USE var_lookup,only:childFLUX_MEAN ! look-up values for timestep-average model fluxes - - implicit none - integer(c_int), intent(inout) :: err - err=0 - - ! Deallocate Time Varaibles - deallocate(startTime%var); - deallocate(finshTime%var); - deallocate(refTime%var); - deallocate(oldTime%var); - - if(allocated(averageFlux_meta)) then; deallocate(averageFlux_meta); endif - if(allocated(statForc_meta)) then; deallocate(statForc_meta); endif - if(allocated(statProg_meta)) then; deallocate(statProg_meta); endif - if(allocated(statDiag_meta)) then; deallocate(statDiag_meta); endif - if(allocated(statFlux_meta)) then; deallocate(statFlux_meta); endif - if(allocated(statIndx_meta)) then; deallocate(statIndx_meta); endif - if(allocated(statBvar_meta)) then; deallocate(statBvar_meta); endif - if(allocated(forcChild_map)) then; deallocate(forcChild_map); endif - if(allocated(progChild_map)) then; deallocate(progChild_map); endif - if(allocated(diagChild_map)) then; deallocate(diagChild_map); endif - if(allocated(fluxChild_map)) then; deallocate(fluxChild_map); endif - if(allocated(indxChild_map)) then; deallocate(indxChild_map); endif - if(allocated(bvarChild_map)) then; deallocate(bvarChild_map); endif - if(allocated(childFLUX_MEAN))then; deallocate(childFLUX_MEAN);endif - if(allocated(gru_struc))then; deallocate(gru_struc);endif - if(allocated(index_map))then; deallocate(index_map);endif - -end subroutine cleanUpJobActor - -end module cppwrap_job \ 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 1fb5f5e1f0760b9cc140fd2168c0011a66731104..57c7dff149e7160e3aa3afa50538005a263198bf 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; @@ -18,8 +19,8 @@ namespace caf { * @param self * @return behavior */ -behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, - std::string configPath, int outputStrucSize, caf::actor parent) { +behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru, + std::string config_path, int output_struct_size, caf::actor parent) { // Timinig Information self->state.job_timing = TimingInfo(); self->state.job_timing.addTimePoint("total_duration"); @@ -27,39 +28,71 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, // Set Job Variables - self->state.startGRU = startGRU; - self->state.numGRU = numGRU; - self->state.configPath = configPath; + self->state.start_gru = start_gru; + self->state.num_gru = num_gru; + self->state.config_path = config_path; self->state.parent = parent; - self->state.outputStrucSize = outputStrucSize; + self->state.output_struct_size = output_struct_size; // Get All Settings - self->state.fileManager = getSettings(self->state.configPath, "JobActor", "FileManagerPath", - self->state.fileManager).value_or(""); - self->state.outputCSV = getSettings(self->state.configPath, "JobActor", "outputCSV", - self->state.outputCSV).value_or(false); - if (self->state.outputCSV) { - self->state.csvPath = getSettings(self->state.configPath, "JobActor", "csvPath", - self->state.csvPath).value_or(""); - if (self->state.csvPath == ""){ // check if we found the value if not set outputCSV to false - self->state.outputCSV = false; + self->state.file_manager = getSettings(self->state.config_path, "JobActor", "FileManagerPath", + self->state.file_manager).value_or(""); + if(self->state.file_manager == "") { + aout(self) << "ERROR: Job_Actor - getSettings() - file_manager_path\n"; + self->quit(); + return {}; // Failure + } + self->state.output_csv = getSettings(self->state.config_path, "JobActor", "outputCSV", + self->state.output_csv).value_or(false); + if (self->state.output_csv) { + self->state.csv_path = getSettings(self->state.config_path, "JobActor", "csvPath", + self->state.csv_path).value_or(""); + if (self->state.csv_path == ""){ // check if we found the value if not set output_csv to false + self->state.output_csv = false; } } // Print Settings aout(self) << "\nSETTINGS FOR JOB_ACTOR\n" << - "File Manager Path = " << self->state.fileManager << "\n" << - "outputCSV = " << self->state.outputCSV << "\n"; - if (self->state.outputCSV) { - aout(self) << "csvPath = " << self->state.csvPath << "\n"; + "File Manager Path = " << self->state.file_manager << "\n" << + "output_csv = " << self->state.output_csv << "\n"; + if (self->state.output_csv) { + aout(self) << "csv_path = " << self->state.csv_path << "\n"; } // Initalize global variables - initJob(self); + int err = 0; + setTimesDirsAndFiles(self->state.file_manager.c_str(), &err); + if (err != 0) { + aout(self) << "ERROR: Job_Actor - setTimesDirsAndFiles\n"; + return {}; // Failure + } + defineGlobalData(&self->state.start_gru, &err); + if (err != 0) { + aout(self) << "ERROR: Job_Actor - defineGlobalData\n"; + return {}; // Failure + } + readDimension(&self->state.num_gru, &self->state.num_hru, &self->state.start_gru, &err); + if (err != 0) { + aout(self) << "ERROR: Job_Actor - readDimension\n"; + return {}; // Failure + } + readIcondNLayers(&self->state.num_gru, &err); + if (err != 0) { + aout(self) << "ERROR: Job_Actor - readIcondNLayers\n"; + return {}; // Failure + } + allocateTimeStructure(&err); + if (err != 0) { + aout(self) << "ERROR: Job_Actor - allocateTimeStructure\n"; + return {}; // Failure + } + + initCsvOutputFile(self); // Spawn the file_access_actor. This will return the number of forcing files we are working with - self->state.file_access_actor = self->spawn(file_access_actor, self->state.startGRU, self->state.numGRU, - self->state.outputStrucSize, self->state.configPath, self); + self->state.file_access_actor = self->spawn(file_access_actor, self->state.start_gru, self->state.num_gru, + self->state.output_struct_size, self->state.config_path, self); aout(self) << "Job Actor Initalized \n"; @@ -75,35 +108,33 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, aout(self) << "Done Init\n"; } // aout(self) << "Done init\n"; - self->state.GRUInit++; - if (self->state.GRUInit < self->state.numGRU) { - self->send(self, init_hru_v); - } else { + self->state.gru_init++; + if (self->state.gru_init >= self->state.num_gru) { aout(self) << "All GRUs are initalized\n"; - self->state.GRUInit = 0; // reset counter in case we have failures + self->state.gru_init = 0; // reset counter in case we have failures runGRUs(self); } }, [=](done_hru, int indx_gru, double total_duration, double init_duration, double forcing_duration, double run_physics_duration, double write_output_duration) { - aout(self) << "\nDone - GRU:" << self->state.GRUList[indx_gru - 1]->getRefGRU() + aout(self) << "\nDone - GRU:" << self->state.gru_list[indx_gru - 1]->getRefGRU() << " - IndexInJob = " << indx_gru << "\n"; - self->state.GRUList[indx_gru - 1]->doneRun(total_duration, init_duration, forcing_duration, + self->state.gru_list[indx_gru - 1]->doneRun(total_duration, init_duration, forcing_duration, run_physics_duration, write_output_duration); - if (self->state.outputCSV) { - self->state.GRUList[indx_gru - 1]->writeSuccess(self->state.successOutputFile); + if (self->state.output_csv) { + self->state.gru_list[indx_gru - 1]->writeSuccess(self->state.success_output_file); } - self->state.numGRUDone++; + self->state.num_gru_done++; // Check if we are done - if (self->state.numGRUDone >= self->state.numGRU) { - self->state.numGRUDone = 0; // just in case there were failures + if (self->state.num_gru_done >= self->state.num_gru) { + self->state.num_gru_done = 0; // just in case there were failures - if (self->state.numGRUFailed == 0) { + if (self->state.num_gru_failed == 0) { self->send(self->state.file_access_actor, deallocate_structures_v); } else { restartFailures(self); @@ -111,20 +142,20 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, } }, - [=](run_failure, caf::actor actorRef, int indxGRU, int err) { - aout(self) << "GRU:" << self->state.GRUList[indxGRU - 1]->getRefGRU() - << "indxGRU = " << indxGRU << "Failed \n" + [=](run_failure, caf::actor actorRef, int indx_gru, int err) { + aout(self) << "GRU:" << self->state.gru_list[indx_gru - 1]->getRefGRU() + << "indx_gru = " << indx_gru << "Failed \n" << "Will have to wait until all GRUs are done before it can be re-tried\n"; - self->state.numGRUFailed++; - self->state.numGRUDone++; - self->state.GRUList[indxGRU - 1]->updateFailed(); + self->state.num_gru_failed++; + self->state.num_gru_done++; + self->state.gru_list[indx_gru - 1]->updateFailed(); // Let the file_access_actor know this actor failed - self->send(self->state.file_access_actor, run_failure_v, indxGRU); + self->send(self->state.file_access_actor, run_failure_v, indx_gru); // check if we are the last hru to complete - if (self->state.numGRUDone >= self->state.numGRU) { + if (self->state.num_gru_done >= self->state.num_gru) { restartFailures(self); } }, @@ -132,6 +163,16 @@ 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); + // auto gru = self->spawn(gru_actor, 1, 1, + // self->state.config_path, + // self->state.output_struct_size, self); + // self->send(gru, init_gru_v); + }, + + [=](done_init_gru) { + aout(self) << "GRU is Initialized\n"; + self->quit(); + return; }, [=](file_access_actor_done, double read_duration, double write_duration) { @@ -140,16 +181,16 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, aout(self) << "\n********************************\n"; aout(self) << "Outputing Timing Info for HRUs\n"; - for(auto gru : self->state.GRUList) { + for(auto gru : self->state.gru_list) { gru->printOutput(); } aout(self) << "********************************\n"; } // Delete GRUs - for (auto GRU : self->state.GRUList) { + for (auto GRU : self->state.gru_list) { delete GRU; } - self->state.GRUList.clear(); + self->state.gru_list.clear(); self->state.job_timing.updateEndPoint("total_duration"); @@ -159,11 +200,11 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, aout(self) << "Total Duration = " << self->state.job_timing.getDuration("total_duration").value_or(-1.0) / 60 << " Minutes\n"; aout(self) << "Total Duration = " << (self->state.job_timing.getDuration("total_duration").value_or(-1.0) / 60) / 60 << " Hours\n\n"; - cleanUpJobActor(&err); + deallocateJobActor(&err); // Tell Parent we are done self->send(self->state.parent, done_job_v, - self->state.numGRUFailed, + self->state.num_gru_failed, self->state.job_timing.getDuration("total_duration").value_or(-1.0), read_duration, write_duration); self->quit(); @@ -174,8 +215,8 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, if (function == "def_output") { aout(self) << "Error with the output file, will try creating it agian\n"; std::this_thread::sleep_for(std::chrono::seconds(5)); - self->state.file_access_actor = self->spawn(file_access_actor, self->state.startGRU, self->state.numGRU, - self->state.outputStrucSize, self->state.configPath, self); + self->state.file_access_actor = self->spawn(file_access_actor, self->state.start_gru, self->state.num_gru, + self->state.output_struct_size, self->state.config_path, self); } else { aout(self) << "Letting Parent Know we are quitting\n"; self->send(self->state.parent, err_v); @@ -191,13 +232,13 @@ behavior job_actor(stateful_actor<job_state>* self, int startGRU, int numGRU, }; } -void initJob(stateful_actor<job_state>* self) { +void initCsvOutputFile(stateful_actor<job_state>* self) { std::string success = "Success"; // allows us to build the string - if (self->state.outputCSV) { + if (self->state.output_csv) { std::ofstream file; - self->state.successOutputFile = self->state.csvPath += success += - std::to_string(self->state.startGRU) += ".csv"; - file.open(self->state.successOutputFile, std::ios_base::out); + self->state.success_output_file = self->state.csv_path += success += + std::to_string(self->state.start_gru) += ".csv"; + file.open(self->state.success_output_file, std::ios_base::out); file << "GRU," << "totalDuration," << @@ -209,38 +250,28 @@ void initJob(stateful_actor<job_state>* self) { "numAttemtps\n"; file.close(); } - - int totalGRUs = 0; - int totalHRUs = 0; - int numHRUs = 0; - int err = 0; - - // aout(self) << "Initalizing Globals \n"; - initGlobals(self->state.fileManager.c_str(), - &totalGRUs, - &totalHRUs, - &self->state.numGRU, - &numHRUs, - &self->state.startGRU, - &err); - if (err != 0) { - aout(self) << "Error: initGlobals" << std::endl; - self->quit(); - } } void initalizeGRU(stateful_actor<job_state>* self) { - int startGRU = self->state.GRUList.size() + self->state.startGRU; - int indexGRU = self->state.GRUList.size() + 1; // Fortran reference starts at 1 - auto gru = self->spawn(hru_actor, startGRU, indexGRU, - self->state.configPath, self->state.file_access_actor, - self->state.outputStrucSize, self); - self->state.GRUList.push_back(new GRUinfo(startGRU, indexGRU, gru, - self->state.dt_init_start_factor, self->state.maxRunAttempts)); + + for(int i = 0; i < self->state.num_gru; i++) { + int start_gru = self->state.gru_list.size() + self->state.start_gru; + int index_gru = self->state.gru_list.size() + 1; // Fortran reference starts at 1 + auto gru = self->spawn(gru_actor, + start_gru, + index_gru, + self->state.config_path, + self->state.file_access_actor, + self->state.output_struct_size, + self); + self->state.gru_list.push_back(new GRUinfo(start_gru, index_gru, gru, + self->state.dt_init_start_factor, self->state.max_run_attempts)); + } + } void runGRUs(stateful_actor<job_state>* self) { - for(auto gru : self->state.GRUList) { + for(auto gru : self->state.gru_list) { if(!gru->isCompleted() && !gru->isFailed()) { self->send(gru->getActor(), start_hru_v); } @@ -251,17 +282,17 @@ void restartFailures(stateful_actor<job_state>* self) { // Need to let the file_access_actor know so it can set up the new output Manager self->send(self->state.file_access_actor, restart_failures_v); - self->state.numGRU = self->state.numGRUFailed; - self->state.numGRUFailed = 0; - self->state.numGRUDone = 0; - for(auto gru : self->state.GRUList) { + self->state.num_gru = self->state.num_gru_failed; + self->state.num_gru_failed = 0; + self->state.num_gru_done = 0; + for(auto gru : self->state.gru_list) { if (gru->isFailed() && !gru->isMaxAttemptsReached()) { gru->updateFailed(); self->send(self->state.file_access_actor, reset_outputCounter_v, gru->getIndxGRU()); gru->updateDt_init(); auto newGRU = self->spawn(hru_actor, gru->getRefGRU(), gru->getIndxGRU(), - self->state.configPath,self->state.file_access_actor, - self->state.outputStrucSize, self); + self->state.config_path,self->state.file_access_actor, + self->state.output_struct_size, self); gru->updateGRU(newGRU); gru->updateCurrentAttempt(); self->send(gru->getActor(), dt_init_factor_v, gru->getDt_init()); diff --git a/build/source/actors/job_actor/job_actor.f90 b/build/source/actors/job_actor/job_actor.f90 new file mode 100644 index 0000000000000000000000000000000000000000..eaffeb8cd1ab9434302892985cd734d79376ec1d --- /dev/null +++ b/build/source/actors/job_actor/job_actor.f90 @@ -0,0 +1,78 @@ +module job_actor + USE, intrinsic :: iso_c_binding + + + implicit none + public::allocateTimeStructure + public::deallocateJobActor + + contains + +subroutine allocateTimeStructure(err) bind(C, name="allocateTimeStructure") + USE globalData,only:startTime,finshTime,refTime,oldTime + USE allocspace4chm_module,only:allocLocal + USE globalData,only:time_meta + + implicit none + ! dummy variables + integer(c_int),intent(inout) :: err + ! local variables + character(len=256) :: cmessage + + call allocLocal(time_meta, startTime, err=err, message=cmessage) + call allocLocal(time_meta, finshTime, err=err, message=cmessage) + call allocLocal(time_meta, refTime, err=err, message=cmessage) + call allocLocal(time_meta, oldTime, err=err, message=cmessage) +end subroutine + +subroutine deallocateJobActor(err) bind(C, name="deallocateJobActor") + USE globalData,only:structInfo ! information on the data structures + USE globalData,only:statForc_meta ! child metadata for stats + USE globalData,only:statProg_meta ! child metadata for stats + USE globalData,only:statDiag_meta ! child metadata for stats + USE globalData,only:statFlux_meta ! child metadata for stats + USE globalData,only:statIndx_meta ! child metadata for stats + USE globalData,only:statBvar_meta ! child metadata for stats + USE globalData,only:forcChild_map ! index of the child data structure: stats forc + USE globalData,only:progChild_map ! index of the child data structure: stats prog + USE globalData,only:diagChild_map ! index of the child data structure: stats diag + USE globalData,only:fluxChild_map ! index of the child data structure: stats flux + USE globalData,only:indxChild_map ! index of the child data structure: stats indx + USE globalData,only:bvarChild_map ! index of the child data structure: stats bvar + USE globalData,only:gru_struc ! gru->hru mapping structure + USE globalData,only:averageFlux_meta + USE globalData,only:index_map + USE globalData,only:startTime,finshTime,refTime,oldTime + USE var_lookup,only:childFLUX_MEAN ! look-up values for timestep-average model fluxes + + implicit none + integer(c_int), intent(out) :: err + err=0 + + ! Deallocate Time Varaibles + deallocate(startTime%var); + deallocate(finshTime%var); + deallocate(refTime%var); + deallocate(oldTime%var); + + if(allocated(averageFlux_meta)) then; deallocate(averageFlux_meta); endif + if(allocated(statForc_meta)) then; deallocate(statForc_meta); endif + if(allocated(statProg_meta)) then; deallocate(statProg_meta); endif + if(allocated(statDiag_meta)) then; deallocate(statDiag_meta); endif + if(allocated(statFlux_meta)) then; deallocate(statFlux_meta); endif + if(allocated(statIndx_meta)) then; deallocate(statIndx_meta); endif + if(allocated(statBvar_meta)) then; deallocate(statBvar_meta); endif + if(allocated(forcChild_map)) then; deallocate(forcChild_map); endif + if(allocated(progChild_map)) then; deallocate(progChild_map); endif + if(allocated(diagChild_map)) then; deallocate(diagChild_map); endif + if(allocated(fluxChild_map)) then; deallocate(fluxChild_map); endif + if(allocated(indxChild_map)) then; deallocate(indxChild_map); endif + if(allocated(bvarChild_map)) then; deallocate(bvarChild_map); endif + if(allocated(childFLUX_MEAN))then; deallocate(childFLUX_MEAN);endif + if(allocated(gru_struc))then; deallocate(gru_struc);endif + if(allocated(index_map))then; deallocate(index_map);endif +end subroutine + + + +end module \ No newline at end of file diff --git a/build/source/driver/SummaActors_setup.f90 b/build/source/driver/SummaActors_setup.f90 index 801be8f172f8a473ba3d368461064df1aa7ba41e..c2f860ee9bd07c6d3746c6d7aac7a00481034afb 100755 --- a/build/source/driver/SummaActors_setup.f90 +++ b/build/source/driver/SummaActors_setup.f90 @@ -19,6 +19,8 @@ ! along with this program. If not, see <http://www.gnu.org/licenses/>. module SummaActors_setup +USE,intrinsic :: iso_c_binding + ! initializes parameter data structures (e.g. vegetation and soil parameters). USE data_types,only:& @@ -58,217 +60,229 @@ USE mDecisions_module,only:& ! safety: set private unless specified otherwise implicit none private -public::SummaActors_paramSetup +public::setupHRUParam public::SOIL_VEG_GEN_PARM contains - ! initializes parameter data structures (e.g. vegetation and soil parameters). - subroutine SummaActors_paramSetup(& +! initializes parameter data structures (e.g. vegetation and soil parameters). +subroutine setupHRUParam(& indxHRU, & ! ID of hru indxGRU, & ! Index of the parent GRU of the HRU ! primary data structures (scalars) - attrStruct, & ! local attributes for each HRU - typeStruct, & ! local classification of soil veg etc. for each HRU - idStruct, & ! local classification of soil veg etc. for each HRU + handle_attrStruct, & ! local attributes for each HRU + handle_typeStruct, & ! local classification of soil veg etc. for each HRU + handle_idStruct, & ! local classification of soil veg etc. for each HRU ! primary data structures (variable length vectors) - mparStruct, & ! model parameters - bparStruct, & ! basin-average parameters - bvarStruct, & ! basin-average variables - dparStruct, & ! default model parameters + handle_mparStruct, & ! model parameters + handle_bparStruct, & ! basin-average parameters + handle_bvarStruct, & ! basin-average variables + handle_dparStruct, & ! default model parameters ! local HRU data - startTime, & ! start time for the model simulation - oldTime, & ! time for the previous model time step + handle_startTime, & ! start time for the model simulation + handle_oldTime, & ! time for the previous model time step ! miscellaneous variables upArea, & ! area upslope of each HRU, - err, message) - ! --------------------------------------------------------------------------------------- - ! * desired modules - ! --------------------------------------------------------------------------------------- - USE nrtype ! variable types, etc. - ! subroutines and functions - use time_utils_module,only:elapsedSec ! calculate the elapsed time - USE mDecisions_module,only:mDecisions ! module to read model decisions - USE ffile_info_module,only:ffile_info ! module to read information on forcing datafile - USE read_attribute_module,only:read_attribute ! module to read local attributes - USE paramCheck_module,only:paramCheck ! module to check consistency of model parameters - USE pOverwrite_module,only:pOverwrite ! module to overwrite default parameter values with info from the Noah tables - USE read_param4chm_module,only:read_param4chm ! module to read model parameter sets - USE ConvE2Temp_module,only:E2T_lookup ! module to calculate a look-up table for the temperature-enthalpy conversion - USE var_derive_module,only:fracFuture ! module to calculate the fraction of runoff in future time steps (time delay histogram) - USE module_sf_noahmplsm,only:read_mp_veg_parameters ! module to read NOAH vegetation tables - ! global data structures - USE globalData,only:gru_struc ! gru-hru mapping structures - USE globalData,only:localParFallback ! local column default parameters - USE globalData,only:basinParFallback ! basin-average default parameters - USE globalData,only:model_decisions ! model decision structure - USE globalData,only:greenVegFrac_monthly ! fraction of green vegetation in each month (0-1) - ! USE globalData,only:numtim ! number of time steps in the simulation - ! run time options - USE globalData,only:startGRU ! index of the starting GRU for parallelization run - USE globalData,only:iRunMode ! define the current running mode - ! output constraints - USE globalData,only:maxLayers ! maximum number of layers - USE globalData,only:maxSnowLayers ! maximum number of snow layers - ! timing variables - USE globalData,only:startSetup,endSetup ! date/time for the start and end of the parameter setup - USE globalData,only:elapsedSetup ! elapsed time for the parameter setup - ! file paths - USE summaActors_FileManager,only:SETTINGS_PATH ! define path to settings files (e.g., parameters, soil and veg. tables) - USE summaActors_FileManager,only:LOCAL_ATTRIBUTES ! name of model initial attributes file - ! Noah-MP parameters - USE NOAHMP_VEG_PARAMETERS,only:SAIM,LAIM ! 2-d tables for stem area index and leaf area index (vegType,month) - USE NOAHMP_VEG_PARAMETERS,only:HVT,HVB ! height at the top and bottom of vegetation (vegType) - - ! USE globalData,only:startTime - - ! --------------------------------------------------------------------------------------- - ! * variables - ! --------------------------------------------------------------------------------------- - implicit none - ! dummy variables - integer(i4b),intent(in) :: indxHRU ! ID of HRU - integer(i4b),intent(in) :: indxGRU ! Index of the parent GRU of the HRU - type(var_d),intent(inout) :: attrStruct ! local attributes for each HRU - type(var_i),intent(inout) :: typeStruct ! local classification of soil veg etc. for each HRU - type(var_i8),intent(inout) :: idStruct ! - type(var_dlength),intent(inout) :: mparStruct ! model parameters - type(var_d),intent(inout) :: bparStruct ! basin-average parameters - type(var_dlength),intent(inout) :: bvarStruct ! basin-average variables - type(var_d),intent(inout) :: dparStruct ! default model parameter - type(var_i),intent(inout) :: startTime ! start time for the model simulation - type(var_i),intent(inout) :: oldTime ! time for the previous model time step - real(dp),intent(inout) :: upArea ! area upslope of each HRU - integer(i4b),intent(out) :: err ! error code - character(*),intent(out) :: message ! error message - ! local variables - character(len=256) :: cmessage ! error message of downwind routine - character(len=256) :: attrFile ! attributes file name - integer(i4b) :: iVar ! looping variables - ! --------------------------------------------------------------------------------------- - ! initialize error control - err=0; message='summa4chm_paramSetup/' - ! initialize the start of the initialization - call date_and_time(values=startSetup) - - ! ffile_info and mDecisions moved to their own seperate subroutine call - - !numTimeSteps = numtim - oldTime%var(:) = startTime%var(:) - - ! get the maximum number of snow layers - select case(model_decisions(iLookDECISIONS%snowLayers)%iDecision) - case(sameRulesAllLayers); maxSnowLayers = 100 - case(rulesDependLayerIndex); maxSnowLayers = 5 - case default; err=20; message=trim(message)//'unable to identify option to combine/sub-divide snow layers'; return - end select ! (option to combine/sub-divide snow layers) - - ! get the maximum number of layers - maxLayers = gru_struc(1)%hruInfo(1)%nSoil + maxSnowLayers - - ! ***************************************************************************** - ! *** read local attributes for each HRU - ! ***************************************************************************** - - ! define the attributes file - attrFile = trim(SETTINGS_PATH)//trim(LOCAL_ATTRIBUTES) - - ! read local attributes for each HRU - call read_attribute(indxHRU,indxGRU,trim(attrFile),attrStruct,typeStruct,idStruct,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - - ! ***************************************************************************** - ! *** read Noah vegetation and soil tables - ! ***************************************************************************** - - ! define monthly fraction of green vegetation - greenVegFrac_monthly = (/0.01_dp, 0.02_dp, 0.03_dp, 0.07_dp, 0.50_dp, 0.90_dp, 0.95_dp, 0.96_dp, 0.65_dp, 0.24_dp, 0.11_dp, 0.02_dp/) - - - - ! define urban vegetation category - select case(trim(model_decisions(iLookDECISIONS%vegeParTbl)%cDecision)) - case('USGS'); urbanVegCategory = 1 - case('MODIFIED_IGBP_MODIS_NOAH'); urbanVegCategory = 13 - case('plumberCABLE'); urbanVegCategory = -999 - case('plumberCHTESSEL'); urbanVegCategory = -999 - case('plumberSUMMA'); urbanVegCategory = -999 - case default; message=trim(message)//'unable to identify vegetation category'; return - end select - - ! set default model parameters - ! set parmameters to their default value - dparStruct%var(:) = localParFallback(:)%default_val ! x%var(:) - ! overwrite default model parameters with information from the Noah-MP tables - call pOverwrite(typeStruct%var(iLookTYPE%vegTypeIndex), & ! vegetation category - typeStruct%var(iLookTYPE%soilTypeIndex), & ! soil category - dparStruct%var, & ! default model parameters - err,cmessage) ! error control - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - - - ! copy over to the parameter structure - ! NOTE: constant for the dat(:) dimension (normally depth) - do ivar=1,size(localParFallback) - mparStruct%var(ivar)%dat(:) = dparStruct%var(ivar) - end do ! looping through variables + err) bind(C, name='setupHRUParam') + ! --------------------------------------------------------------------------------------- + ! * desired modules + ! --------------------------------------------------------------------------------------- + USE nrtype ! variable types, etc. + ! subroutines and functions + use time_utils_module,only:elapsedSec ! calculate the elapsed time + USE mDecisions_module,only:mDecisions ! module to read model decisions + USE ffile_info_module,only:ffile_info ! module to read information on forcing datafile + USE read_attribute_module,only:read_attribute ! module to read local attributes + USE paramCheck_module,only:paramCheck ! module to check consistency of model parameters + USE pOverwrite_module,only:pOverwrite ! module to overwrite default parameter values with info from the Noah tables + USE read_param4chm_module,only:read_param ! module to read model parameter sets + USE ConvE2Temp_module,only:E2T_lookup ! module to calculate a look-up table for the temperature-enthalpy conversion + USE var_derive_module,only:fracFuture ! module to calculate the fraction of runoff in future time steps (time delay histogram) + USE module_sf_noahmplsm,only:read_mp_veg_parameters ! module to read NOAH vegetation tables + ! global data structures + USE globalData,only:gru_struc ! gru-hru mapping structures + USE globalData,only:localParFallback ! local column default parameters + USE globalData,only:basinParFallback ! basin-average default parameters + USE globalData,only:model_decisions ! model decision structure + USE globalData,only:greenVegFrac_monthly ! fraction of green vegetation in each month (0-1) + ! USE globalData,only:numtim ! number of time steps in the simulation + ! run time options + USE globalData,only:startGRU ! index of the starting GRU for parallelization run + USE globalData,only:iRunMode ! define the current running mode + ! output constraints + USE globalData,only:maxLayers ! maximum number of layers + USE globalData,only:maxSnowLayers ! maximum number of snow layers + ! timing variables + USE globalData,only:startSetup,endSetup ! date/time for the start and end of the parameter setup + USE globalData,only:elapsedSetup ! elapsed time for the parameter setup + ! Noah-MP parameters + USE NOAHMP_VEG_PARAMETERS,only:SAIM,LAIM ! 2-d tables for stem area index and leaf area index (vegType,month) + USE NOAHMP_VEG_PARAMETERS,only:HVT,HVB ! height at the top and bottom of vegetation (vegType) + + ! USE globalData,only:startTime + + ! --------------------------------------------------------------------------------------- + ! * variables + ! --------------------------------------------------------------------------------------- + implicit none + ! dummy variables + ! calling variables + integer(c_int),intent(in) :: indxGRU ! Index of the parent GRU of the HRU + integer(c_int),intent(in) :: indxHRU ! ID to locate correct HRU from netcdf file + type(c_ptr), intent(in), value :: handle_attrStruct ! local attributes for each HRU + type(c_ptr), intent(in), value :: handle_typeStruct ! local classification of soil veg etc. for each HRU + type(c_ptr), intent(in), value :: handle_idStruct ! + type(c_ptr), intent(in), value :: handle_mparStruct ! model parameters + type(c_ptr), intent(in), value :: handle_bparStruct ! basin-average parameters + type(c_ptr), intent(in), value :: handle_bvarStruct ! basin-average variables + type(c_ptr), intent(in), value :: handle_dparStruct ! default model parameters + type(c_ptr), intent(in), value :: handle_startTime ! start time for the model simulation + type(c_ptr), intent(in), value :: handle_oldTime ! time for the previous model time step + real(c_double),intent(inout) :: upArea + integer(c_int),intent(inout) :: err + + ! local variables + type(var_d),pointer :: attrStruct ! local attributes for each HRU + type(var_i),pointer :: typeStruct ! local classification of soil veg etc. for each HRU + type(var_i8),pointer :: idStruct ! + type(var_dlength),pointer :: mparStruct ! model parameters + type(var_d),pointer :: bparStruct ! basin-average parameters + type(var_dlength),pointer :: bvarStruct ! basin-average variables + type(var_d),pointer :: dparStruct ! default model parameters + type(var_i),pointer :: startTime ! start time for the model simulation + type(var_i),pointer :: oldTime ! time for the previous model time step + character(len=256) :: message ! error message + character(len=256) :: cmessage ! error message of downwind routine + integer(i4b) :: iVar ! looping variables + ! --------------------------------------------------------------------------------------- + ! initialize error control + err=0; message='setupHRUParam/' + ! initialize the start of the initialization + call date_and_time(values=startSetup) + + ! convert to fortran pointer from C++ pointer + call c_f_pointer(handle_attrStruct, attrStruct) + call c_f_pointer(handle_typeStruct, typeStruct) + call c_f_pointer(handle_idStruct, idStruct) + call c_f_pointer(handle_mparStruct, mparStruct) + call c_f_pointer(handle_bparStruct, bparStruct) + call c_f_pointer(handle_bvarStruct, bvarStruct) + call c_f_pointer(handle_dparStruct, dparStruct) + call c_f_pointer(handle_startTime, startTime) + call c_f_pointer(handle_oldTime, oldTime) + + ! ffile_info and mDecisions moved to their own seperate subroutine call + + !numTimeSteps = numtim + oldTime%var(:) = startTime%var(:) + + ! get the maximum number of snow layers + select case(model_decisions(iLookDECISIONS%snowLayers)%iDecision) + case(sameRulesAllLayers); maxSnowLayers = 100 + case(rulesDependLayerIndex); maxSnowLayers = 5 + case default; err=20; + message=trim(message)//'unable to identify option to combine/sub-divide snow layers' + print*, message + return + end select ! (option to combine/sub-divide snow layers) + + ! get the maximum number of layers + maxLayers = gru_struc(1)%hruInfo(1)%nSoil + maxSnowLayers + + ! ***************************************************************************** + ! *** read local attributes for each HRU + ! ***************************************************************************** + call read_attribute(indxHRU,indxGRU,attrStruct,typeStruct,idStruct,err,cmessage) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif + + ! define monthly fraction of green vegetation + greenVegFrac_monthly = (/0.01_dp, 0.02_dp, 0.03_dp, 0.07_dp, 0.50_dp, 0.90_dp, 0.95_dp, 0.96_dp, 0.65_dp, 0.24_dp, 0.11_dp, 0.02_dp/) + + ! define urban vegetation category + select case(trim(model_decisions(iLookDECISIONS%vegeParTbl)%cDecision)) + case('USGS'); urbanVegCategory = 1 + case('MODIFIED_IGBP_MODIS_NOAH'); urbanVegCategory = 13 + case('plumberCABLE'); urbanVegCategory = -999 + case('plumberCHTESSEL'); urbanVegCategory = -999 + case('plumberSUMMA'); urbanVegCategory = -999 + case default + message=trim(message)//'unable to identify vegetation category' + print*, message + return + end select - ! set default for basin-average parameters - bparStruct%var(:) = basinParFallback(:)%default_val - ! ***************************************************************************** - ! *** read trial model parameter values for each HRU, and populate initial data structures - ! ***************************************************************************** - call read_param4chm(indxHRU,indxGRU,iRunMode,startGRU, & - mparStruct,bparStruct,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - ! ***************************************************************************** - ! *** compute derived model variables that are pretty much constant for the basin as a whole - ! ***************************************************************************** - ! calculate the fraction of runoff in future time steps - call fracFuture(bparStruct%var, & ! vector of basin-average model parameters - bvarStruct, & ! data structure of basin-average variables - err,cmessage) ! error control - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - - ! check that the parameters are consistent - call paramCheck(mparStruct,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - - ! calculate a look-up table for the temperature-enthalpy conversion - call E2T_lookup(mparStruct,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - - ! overwrite the vegetation height - HVT(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyTop)%dat(1) - HVB(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyBottom)%dat(1) - - ! overwrite the tables for LAI and SAI - if(model_decisions(iLookDECISIONS%LAI_method)%iDecision == specified)then - SAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%winterSAI)%dat(1) - LAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%summerLAI)%dat(1)*greenVegFrac_monthly - endif - - ! compute total area of the upstream HRUS that flow into each HRU - upArea = 0._dp - ! Check if lateral flows exists within the HRU - if(typeStruct%var(iLookTYPE%downHRUindex)==typeStruct%var(iLookID%hruId))then - upArea = upArea + attrStruct%var(iLookATTR%HRUarea) - endif - - - ! identify the total basin area for a GRU (m2) - associate(totalArea => bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1) ) - totalArea = 0._dp - totalArea = totalArea + attrStruct%var(iLookATTR%HRUarea) - end associate - - ! identify the end of the initialization - call date_and_time(values=endSetup) - - ! aggregate the elapsed time for the initialization - elapsedSetup = elapsedSec(startSetup, endSetup) - - end subroutine SummaActors_paramSetup + ! ***************************************************************************** + ! *** read trial model parameter values for each HRU, and populate initial data structures + ! ***************************************************************************** + call read_param(indxHRU,indxGRU,mparStruct,bparStruct,dparStruct,err) + if(err/=0)then + message=trim(message)//trim(cmessage) + return + endif + ! ***************************************************************************** + ! *** compute derived model variables that are pretty much constant for the basin as a whole + ! ***************************************************************************** + ! calculate the fraction of runoff in future time steps + call fracFuture(bparStruct%var, & ! vector of basin-average model parameters + bvarStruct, & ! data structure of basin-average variables + err,cmessage) ! error control + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif + + ! check that the parameters are consistent + call paramCheck(mparStruct,err,cmessage) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif + + ! calculate a look-up table for the temperature-enthalpy conversion + call E2T_lookup(mparStruct,err,cmessage) + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif + + ! overwrite the vegetation height + HVT(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyTop)%dat(1) + HVB(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyBottom)%dat(1) + + ! overwrite the tables for LAI and SAI + if(model_decisions(iLookDECISIONS%LAI_method)%iDecision == specified)then + SAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%winterSAI)%dat(1) + LAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%summerLAI)%dat(1)*greenVegFrac_monthly + endif + + ! compute total area of the upstream HRUS that flow into each HRU + upArea = 0._dp + ! Check if lateral flows exists within the HRU + if(typeStruct%var(iLookTYPE%downHRUindex)==typeStruct%var(iLookID%hruId))then + upArea = upArea + attrStruct%var(iLookATTR%HRUarea) + endif + + + ! identify the total basin area for a GRU (m2) + associate(totalArea => bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1) ) + totalArea = 0._dp + totalArea = totalArea + attrStruct%var(iLookATTR%HRUarea) + end associate + + ! identify the end of the initialization + call date_and_time(values=endSetup) + + ! aggregate the elapsed time for the initialization + elapsedSetup = elapsedSec(startSetup, endSetup) + +end subroutine setupHRUParam ! ================================================================================================= diff --git a/build/source/driver/summaActors_init.f90 b/build/source/driver/init_hru_actor.f90 similarity index 95% rename from build/source/driver/summaActors_init.f90 rename to build/source/driver/init_hru_actor.f90 index c95de9daa4c37fd1eaa4fe1adc5378f7bea7de71..961c385b8f38cc61728999188103af433913ddc4 100755 --- a/build/source/driver/summaActors_init.f90 +++ b/build/source/driver/init_hru_actor.f90 @@ -1,4 +1,4 @@ -module summaActors_init +module INIT_HRU_ACTOR ! used to declare and allocate summa data structures and initialize model state to known values USE,intrinsic :: iso_c_binding USE nrtype ! variable types, etc. @@ -8,7 +8,8 @@ USE data_types,only:& var_i8, & ! x%var(:) (i8b) var_d, & ! x%var(:) (dp) var_ilength, & ! x%var(:)%dat (i4b) - var_dlength ! x%var(:)%dat (dp) + var_dlength, & ! x%var(:)%dat (dp) + zLookup ! x%z(:)%var(:)%lookup(:) -- lookup tables ! access missing values USE globalData,only:integerMissing ! missing integer @@ -21,6 +22,8 @@ USE globalData,only:prog_meta,diag_meta,flux_meta,id_meta ! metadata structure USE globalData,only:mpar_meta,indx_meta ! metadata structures USE globalData,only:bpar_meta,bvar_meta ! metadata structures USE globalData,only:averageFlux_meta ! metadata for time-step average fluxes +USE globalData,only:lookup_meta + ! statistics metadata structures USE globalData,only:statForc_meta ! child metadata for stats USE globalData,only:statProg_meta ! child metadata for stats @@ -34,13 +37,14 @@ USE var_lookup,only:maxVarFreq ! # of available ou ! safety: set private unless specified otherwise implicit none private -public::summaActors_initialize +public::initHRU contains ! used to declare and allocate summa data structures and initialize model state to known values - subroutine summaActors_initialize(& + subroutine initHRU(& indxGRU, & ! Index of HRU's GRU parent num_steps, & + handle_lookupStruct,& ! statistics structures handle_forcStat, & ! model forcing data handle_progStat, & ! model prognostic (state) variables @@ -71,7 +75,7 @@ contains handle_refTime, & ! reference time for the model simulation handle_oldTime, & ! time for the previous model time step ! miscellaneous variables - err) bind(C,name='summaActors_initialize') + err) bind(C,name='initHRU') ! --------------------------------------------------------------------------------------- ! * desired modules ! --------------------------------------------------------------------------------------- @@ -100,7 +104,9 @@ contains ! --------------------------------------------------------------------------------------- integer(c_int),intent(in) :: indxGRU ! indx of the parent GRU integer(c_int),intent(out) :: num_steps ! number of steps in model, local to the HRU - ! statistics structures + + type(c_ptr), intent(in), value :: handle_lookupStruct ! z(:)%var(:)%lookup(:) -- lookup tables + ! statistics structures type(c_ptr), intent(in), value :: handle_forcStat ! model forcing data type(c_ptr), intent(in), value :: handle_progStat ! model prognostic (state) variables type(c_ptr), intent(in), value :: handle_diagStat ! model diagnostic variables @@ -133,6 +139,7 @@ contains ! --------------------------------------------------------------------------------------- ! * Fortran Variables For Conversion ! --------------------------------------------------------------------------------------- + type(zLookup),pointer :: lookupStruct ! z(:)%var(:)%lookup(:) -- lookup tables type(var_dlength),pointer :: forcStat ! model forcing data type(var_dlength),pointer :: progStat ! model prognostic (state) variables type(var_dlength),pointer :: diagStat ! model diagnostic variables @@ -170,6 +177,7 @@ contains ! --------------------------------------------------------------------------------------- ! * Convert From C++ to Fortran ! --------------------------------------------------------------------------------------- + call c_f_pointer(handle_lookupStruct, lookupStruct) call c_f_pointer(handle_forcStat, forcStat) call c_f_pointer(handle_progStat, progStat) call c_f_pointer(handle_diagStat, diagStat) @@ -252,12 +260,14 @@ contains case('flux'); call allocLocal(flux_meta,fluxStruct,nSnow,nSoil,err,cmessage); ! model fluxes case('bpar'); call allocLocal(bpar_meta,bparStruct,nSnow=0,nSoil=0,err=err,message=cmessage); ! basin-average params case('bvar'); call allocLocal(bvar_meta,bvarStruct,nSnow=0,nSoil=0,err=err,message=cmessage); ! basin-average variables + case('lookup'); call allocLocal(lookup_meta,lookupStruct,err=err,message=cmessage) ! basin-average variables case('deriv'); cycle case default; err=20; message='unable to find structure name: '//trim(structInfo(iStruct)%structName) end select ! check errors if(err/=0)then message=trim(message)//trim(cmessage)//'[structure = '//trim(structInfo(iStruct)%structName)//']' + print*, message return endif end do ! looping through data structures @@ -267,6 +277,7 @@ contains call allocLocal(mpar_meta,dparStruct,nSnow,nSoil,err,cmessage); ! default model parameters if(err/=0)then message=trim(message)//trim(cmessage)//' [problem allocating dparStruct]' + print*, message return endif @@ -288,6 +299,7 @@ contains ! check errors if(err/=0)then message=trim(message)//trim(cmessage)//'[statistics for = '//trim(structInfo(iStruct)%structName)//']' + print*, message return endif end do ! iStruct @@ -298,6 +310,6 @@ contains ! end association to info in data structures end associate - end subroutine summaActors_initialize + end subroutine initHRU -end module summaActors_init +end module INIT_HRU_ACTOR diff --git a/build/source/driver/summaActors_globalData.f90 b/build/source/driver/summaActors_globalData.f90 index 69e2f7fba341514f5c9de18ec5a2ca0ae206ee05..efd6b18169b19d2c698843770dc5074a0bd6e894 100755 --- a/build/source/driver/summaActors_globalData.f90 +++ b/build/source/driver/summaActors_globalData.f90 @@ -20,6 +20,7 @@ module summa_globalData ! used to declare and allocate global summa data structures +USE, intrinsic :: iso_c_binding ! access missing values USE globalData,only:integerMissing ! missing integer @@ -56,13 +57,14 @@ USE globalData,only:fluxChild_map ! index of the child USE globalData,only:indxChild_map ! index of the child data structure: stats indx USE globalData,only:bvarChild_map ! index of the child data structure: stats bvar +USE globalData,only:startGRU ! safety: set private unless specified otherwise implicit none private public::summa_defineGlobalData contains -subroutine summa_defineGlobalData(err, message) +subroutine summa_defineGlobalData(start_gru_index, err) bind(C, name="defineGlobalData") ! --------------------------------------------------------------------------------------- ! * desired modules ! --------------------------------------------------------------------------------------- @@ -87,9 +89,10 @@ subroutine summa_defineGlobalData(err, message) ! --------------------------------------------------------------------------------------- implicit none ! dummy variables - integer(i4b),intent(out) :: err ! error code - character(*),intent(out) :: message ! error message + integer(c_int),intent(in) :: start_gru_index ! Index of the starting GRU (-g option from user) + integer(c_int),intent(out) :: err ! error code ! local variables + character(len=256) :: message ! error message character(LEN=256) :: cmessage ! error message of downwind routine logical(lgt), dimension(maxvarFlux) :: flux_mask ! mask defining desired flux variables logical(lgt), dimension(maxvarForc) :: statForc_mask ! mask defining forc stats @@ -111,22 +114,38 @@ subroutine summa_defineGlobalData(err, message) ! populate metadata for all model variables call popMetadat(err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif ! define mapping between fluxes and states call flxMapping(err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif ! check data structures call checkStruc(err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif ! define the mask to identify the subset of variables in the "child" data structure (just scalar variables) flux_mask = (flux_meta(:)%vartype==iLookVarType%scalarv) ! create the averageFlux metadata structure call childStruc(flux_meta, flux_mask, averageFlux_meta, childFLUX_MEAN, err, cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + endif ! child metadata structures - so that we do not carry full stats structures around everywhere ! only carry stats for variables with output frequency > model time step @@ -148,7 +167,11 @@ subroutine summa_defineGlobalData(err, message) case('bvar'); call childStruc(bvar_meta,statBvar_mask,statBvar_meta,bvarChild_map,err,cmessage) end select ! check errors - if(err/=0)then; message=trim(message)//trim(cmessage)//'[statistics for = '//trim(structInfo(iStruct)%structName)//']'; return; endif + if(err/=0)then + message=trim(message)//trim(cmessage)//'[statistics for = '//trim(structInfo(iStruct)%structName)//']' + print*, message + return + endif end do ! iStruct ! set all stats metadata to correct var types @@ -159,6 +182,9 @@ subroutine summa_defineGlobalData(err, message) statIndx_meta(:)%vartype = iLookVarType%outstat statBvar_meta(:)%vartype = iLookVarType%outstat + ! Set the startGRU + startGRU = start_gru_index + end subroutine summa_defineGlobalData end module summa_globalData diff --git a/build/source/driver/summaActors_util.f90 b/build/source/driver/summaActors_util.f90 index 51505657612329adbf0b6bc7a9625d4561d22d01..0b761071dc6c4ce7ebb79b7a75f61e157d373dd0 100755 --- a/build/source/driver/summaActors_util.f90 +++ b/build/source/driver/summaActors_util.f90 @@ -36,236 +36,10 @@ implicit none private ! routines to make public -! public::getCommandArguments4chm public::stop_program public::handle_err contains - ! ************************************************************************************************** - ! * obtain the command line arguments - ! ************************************************************************************************** -! subroutine getCommandArguments4chm(file_manager_path,summaFileManagerFile,err,message) -! ! data types -! USE summa4chm_type, only:summa4chm_type_dec ! master summa data type -! ! provide access to named parameters -! USE globalData,only:iRunModeFull,iRunModeGRU,iRunModeHRU -! USE globalData,only:ixProgress_it,ixProgress_im,ixProgress_id,ixProgress_ih,ixProgress_never -! USE globalData,only:ixRestart_iy,ixRestart_im,ixRestart_id,ixRestart_end,ixRestart_never -! USE globalData,only:noNewFiles,newFileEveryOct1 -! ! provide access to runtime options -! USE globalData,only: startGRU ! index of the starting GRU for parallelization run -! USE globalData,only: checkHRU ! index of the HRU for a single HRU run -! USE globalData,only: iRunMode ! define the current running mode -! USE globalData,only: newOutputFile ! define option for new output file -! USE globalData,only: ixProgress ! define frequency to write progress -! USE globalData,only: ixRestart ! define frequency to write restart files -! USE globalData,only: output_fileSuffix ! suffix for the output file -! implicit none -! ! dummy variables -! character(len=256),intent(in) :: file_manager_path ! path/name of file defining directories and files -! character(len=256),intent(inout) :: summaFileManagerFile ! path/name of file defining directories and files -! integer(i4b),intent(out) :: err ! error code -! character(*),intent(out) :: message ! error message -! ! local variables -! integer(i4b) :: nGRU ! number of grouped response units -! integer(i4b) :: nHRU ! number of global hydrologic response units -! integer(i4b) :: iArgument ! index of command line argument -! integer(i4b) :: nArgument ! number of command line arguments -! character(len=256),allocatable :: argString(:) ! string to store command line arguments -! integer(i4b) :: nLocalArgument ! number of command line arguments to read for a switch -! character(len=70), parameter :: spaces = '' ! setting a blank string -! ! version information generated during compiling -! INCLUDE 'summaversion.inc' -! ! --------------------------------------------------------------------------------------- -! ! initialize error control -! err=0; message='getCommandArguments4chm/' - -! nArgument = 6 -! allocate(argString(nArgument)) -! argString(1) = '-p' -! argString(2) = 'never' -! argString(3) = '-s' -! argString(4) = '_testSumma' -! argString(5) = '-m' -! argString(6) = file_manager_path - -! ! initialize command line argument variables -! startGRU = integerMissing; checkHRU = integerMissing -! nGRU = integerMissing; nHRU = integerMissing -! newOutputFile = noNewFiles -! iRunMode = iRunModeFull - -! ! loop through all command arguments -! nLocalArgument = 0 -! do iArgument = 1,nArgument -! if (nLocalArgument>0) then; nLocalArgument = nLocalArgument -1; cycle; end if ! skip the arguments have been read -! select case (trim(argString(iArgument))) - -! case ('-m', '--master') -! ! update arguments -! nLocalArgument = 1 -! if (iArgument+nLocalArgument>nArgument)then -! message="missing argument file_suffix; type 'summa.exe --help' for correct usage" -! err=1; return -! endif -! ! get name of master control file -! summaFileManagerFile=trim(argString(iArgument+1)) -! print "(A)", "file_master is '"//trim(summaFileManagerFile)//"'." - -! ! define the formation of new output files -! case ('-n', '--newFile') -! ! check that the number of command line arguments is correct -! nLocalArgument = 1 ! expect just one argument for new output files -! if (iArgument+nLocalArgument>nArgument)then -! message="missing argument file_suffix; type 'summa.exe --help' for correct usage" -! err=1; return -! endif -! ! get the decision for the formation of new output files -! select case( trim(argString(iArgument+1)) ) -! case('noNewFiles'); newOutputFile = noNewFiles -! case('newFileEveryOct1'); newOutputFile = newFileEveryOct1 -! case default -! message='unknown option for new output file: expect "noNewFiles" or "newFileEveryOct1"' -! err=1; return -! end select - -! case ('-s', '--suffix') -! ! define file suffix -! nLocalArgument = 1 -! ! check if the number of command line arguments is correct -! if (iArgument+nLocalArgument>nArgument) then -! message="missing argument file_suffix; type 'summa.exe --help' for correct usage" -! err=1; return -! endif -! output_fileSuffix=trim(argString(iArgument+1)) -! print "(A)", "file_suffix is '"//trim(output_fileSuffix)//"'." - -! case ('-h', '--hru') -! ! define a single HRU run -! if (iRunMode == iRunModeGRU)then -! message="single-HRU run and GRU-parallelization run cannot be both selected." -! err=1; return -! endif -! iRunMode=iRunModeHRU -! nLocalArgument = 1 -! ! check if the number of command line arguments is correct -! if (iArgument+nLocalArgument>nArgument) call handle_err(1,"missing argument checkHRU; type 'summa.exe --help' for correct usage") -! read(argString(iArgument+1),*) checkHRU ! read the index of the HRU for a single HRU run -! nHRU=1; nGRU=1 ! nHRU and nGRU are both one in this case -! ! examines the checkHRU is correct -! if (checkHRU<1) then -! message="illegal iHRU specification; type 'summa.exe --help' for correct usage" -! err=1; return -! else -! print '(A)',' Single-HRU run activated. HRU '//trim(argString(iArgument+1))//' is selected for simulation.' -! end if - -! case ('-g','--gru') -! ! define a GRU parallelization run; get the starting GRU and countGRU -! if (iRunMode == iRunModeHRU)then -! message="single-HRU run and GRU-parallelization run cannot be both selected." -! err=1; return -! endif -! iRunMode=iRunModeGRU -! nLocalArgument = 2 -! ! check if the number of command line arguments is correct -! if (iArgument+nLocalArgument>nArgument)then -! message="missing argument startGRU or countGRU; type 'summa.exe --help' for correct usage" -! err=1; return -! endif -! read(argString(iArgument+1),*) startGRU ! read the argument of startGRU -! read(argString(iArgument+2),*) nGRU ! read the argument of countGRU -! if (startGRU<1 .or. nGRU<1) then -! message='startGRU and countGRU must be larger than 1.' -! err=1; return -! else -! print '(A)', ' GRU-Parallelization run activated. '//trim(argString(iArgument+2))//' GRUs are selected for simulation.' -! end if - -! case ('-p', '--progress') -! ! define the frequency to print progress -! nLocalArgument = 1 -! ! check if the number of command line arguments is correct -! if (iArgument+nLocalArgument>nArgument)then -! message="missing argument freqProgress; type 'summa.exe --help' for correct usage" -! err=1; return -! endif -! select case (trim(argString(iArgument+1))) -! case ('t' , 'timestep'); ixProgress = ixProgress_it -! case ('h' , 'hour'); ixProgress = ixProgress_ih -! case ('d' , 'day'); ixProgress = ixProgress_id ! default -! case ('m' , 'month'); ixProgress = ixProgress_im -! case ('n' , 'never'); ixProgress = ixProgress_never -! case default -! message='unknown frequency to print progress' -! err=1; return -! end select - -! case ('-r', '--restart') -! ! define the frequency to write restart files -! nLocalArgument = 1 -! ! check if the number of command line arguments is correct -! if (iArgument+nLocalArgument>nArgument)then -! message="missing argument freqRestart; type 'summa.exe --help' for correct usage" -! err=1; return -! endif -! select case (trim(argString(iArgument+1))) -! case ('y' , 'year'); ixRestart = ixRestart_iy -! case ('m' , 'month'); ixRestart = ixRestart_im -! case ('d' , 'day'); ixRestart = ixRestart_id -! case ('e' , 'end'); ixRestart = ixRestart_end -! case ('n' , 'never'); ixRestart = ixRestart_never -! case default -! message='unknown frequency to write restart files' -! err=1; return -! end select - -! ! do nothing -! case ('-v','--version') - -! ! print help message -! case ('--help') -! call printCommandHelp - -! case default -! call printCommandHelp -! message='unknown command line option' -! err=1; return - -! end select -! end do ! looping through command line arguments - -! ! check if master_file has been received. -! if (len(trim(summaFileManagerFile))==0)then -! message="master_file is not received; type 'summa.exe --help' for correct usage" -! err=1; return -! endif - -! ! set startGRU for full run -! if (iRunMode==iRunModeFull) startGRU=1 - -! end subroutine getCommandArguments4chm - - ! ************************************************************************************************** - ! print the correct command line usage of SUMMA - ! ************************************************************************************************** -! subroutine printCommandHelp() -! implicit none -! ! command line usage -! print "(//A)",'Usage: summa.exe -m master_file [-s fileSuffix] [-g startGRU countGRU] [-h iHRU] [-r freqRestart] [-p freqProgress] [-c]' -! print "(A,/)", ' summa.exe summa executable' -! print "(A)", 'Running options:' -! print "(A)", ' -m --master Define path/name of master file (required)' -! print "(A)", ' -n --newFile Define frequency [noNewFiles,newFileEveryOct1] of new output files' -! print "(A)", ' -s --suffix Add fileSuffix to the output files' -! print "(A)", ' -g --gru Run a subset of countGRU GRUs starting from index startGRU' -! print "(A)", ' -h --hru Run a single HRU with index of iHRU' -! print "(A)", ' -r --restart Define frequency [y,m,d,e,never] to write restart files' -! print "(A)", ' -p --progress Define frequency [m,d,h,never] to print progress' -! print "(A)", ' -v --version Display version information of the current build' -! stop -! end subroutine printCommandHelp - ! ************************************************************************************************** ! error handler ! ************************************************************************************************** diff --git a/build/source/driver/summaActors_wOutputStruc.f90 b/build/source/driver/summaActors_wOutputStruc.f90 index 34f78b4478b38f98ebd0f93d39d749af650294bc..0d5a53416ea4190e527293f07d45b649e28214f1 100644 --- a/build/source/driver/summaActors_wOutputStruc.f90 +++ b/build/source/driver/summaActors_wOutputStruc.f90 @@ -168,6 +168,7 @@ subroutine summaActors_writeToOutputStruc(& integer(i4b) :: nHRU integer(i4b) :: iFreq ! index of the output frequency integer(i4b) :: iGRU ! Temporary index for GRU + integer(i4b) :: iDat nGRU = 1 nHRU = 1 iGRU = 1 @@ -233,9 +234,8 @@ subroutine summaActors_writeToOutputStruc(& outputTimeStep%var(:)=1 end if ! if defining a new file - ! copy finalized stats to output structure + ! If we do not do this looping we segfault - I am not sure why outputStructure(1)%finalizeStats(1)%gru(indxGRU)%hru(indxHRU)%tim(outputStep)%dat(:) = finalizeStats%dat(:) - ! **************************************************************************** ! *** calculate output statistics ! **************************************************************************** diff --git a/build/source/dshare/data_types.f90 b/build/source/dshare/data_types.f90 index c2551e0720aa5c601999e6c7af6a9d299e33c52e..6ec72bf0f42544261c91b0d6bcb2466234ff0fd3 100755 --- a/build/source/dshare/data_types.f90 +++ b/build/source/dshare/data_types.f90 @@ -412,38 +412,53 @@ endtype var_time_ilength type(hru_time_intVec),allocatable :: gru(:) endtype gru_hru_time_intVec + ! Sundials lookup table type + type, public :: dLookup + real(rkind),allocatable :: lookup(:) ! lookup(:) + endtype dLookup + ! ** double precision type for a variable number of soil layers; variable length + type, public :: vLookup + type(dLookup),allocatable :: var(:) ! var(:)%lookup(:) + endtype vLookup + type, public :: zLookup + type(vLookup),allocatable :: z(:) ! z(:)%var(:)%lookup(:) + endtype zLookup + type, public :: summa_output_type -! define the statistics structures -type(gru_hru_time_doubleVec),allocatable :: forcStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model forcing data -type(gru_hru_time_doubleVec),allocatable :: progStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model prognostic (state) variables -type(gru_hru_time_doubleVec),allocatable :: diagStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model diagnostic variables -type(gru_hru_time_doubleVec),allocatable :: fluxStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model fluxes -type(gru_hru_time_doubleVec),allocatable :: indxStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model indices -type(gru_hru_time_doubleVec),allocatable :: bvarStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- basin-average variabl - -! define the primary data structures (scalars) -type(gru_hru_time_int),allocatable :: timeStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- model time data -type(gru_hru_time_double),allocatable :: forcStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- model forcing data -type(gru_hru_double),allocatable :: attrStruct(:) ! x%gru(:)%hru(:)%var(:) -- local attributes for each HRU, DOES NOT CHANGE OVER TIMESTEPS -type(gru_hru_int),allocatable :: typeStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- local classification of soil veg etc. for each HRU, DOES NOT CHANGE OVER TIMESTEPS -type(gru_hru_time_int8),allocatable :: idStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- - -! define the primary data structures (variable length vectors) -type(gru_hru_time_intVec),allocatable :: indxStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model indices -type(gru_hru_doubleVec),allocatable :: mparStruct(:) ! x%gru(:)%hru(:)%var(:)%dat -- model parameters, DOES NOT CHANGE OVER TIMESTEPS TODO: MAYBE -type(gru_hru_time_doubleVec),allocatable :: progStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model prognostic (state) variables -type(gru_hru_time_doubleVec),allocatable :: diagStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model diagnostic variables -type(gru_hru_time_doubleVec),allocatable :: fluxStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model fluxes - -! define the basin-average structures -type(gru_double),allocatable :: bparStruct(:) ! x%gru(:)%var(:) -- basin-average parameters, DOES NOT CHANGE OVER TIMESTEPS -type(gru_hru_time_doubleVec),allocatable :: bvarStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- basin-average variables - -! finalize stats structure -type(gru_hru_time_flagVec),allocatable :: finalizeStats(:) ! x%gru(:)%hru(:)%tim(:)%dat -- flags on when to write to file - -integer(i4b) :: nTimeSteps + ! define the statistics structures + type(gru_hru_time_doubleVec),allocatable :: forcStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model forcing data + type(gru_hru_time_doubleVec),allocatable :: progStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model prognostic (state) variables + type(gru_hru_time_doubleVec),allocatable :: diagStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model diagnostic variables + type(gru_hru_time_doubleVec),allocatable :: fluxStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model fluxes + type(gru_hru_time_doubleVec),allocatable :: indxStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model indices + type(gru_hru_time_doubleVec),allocatable :: bvarStat(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- basin-average variabl + + ! define the primary data structures (scalars) + type(gru_hru_time_int),allocatable :: timeStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- model time data + type(gru_hru_time_double),allocatable :: forcStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- model forcing data + type(gru_hru_double),allocatable :: attrStruct(:) ! x%gru(:)%hru(:)%var(:) -- local attributes for each HRU, DOES NOT CHANGE OVER TIMESTEPS + type(gru_hru_int),allocatable :: typeStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:) -- local classification of soil veg etc. for each HRU, DOES NOT CHANGE OVER TIMESTEPS + type(gru_hru_int8),allocatable :: idStruct(:) ! x%gru(:)%hru(:)%var(:) + + ! define the primary data structures (variable length vectors) + type(gru_hru_time_intVec),allocatable :: indxStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model indices + type(gru_hru_doubleVec),allocatable :: mparStruct(:) ! x%gru(:)%hru(:)%var(:)%dat -- model parameters, DOES NOT CHANGE OVER TIMESTEPS TODO: MAYBE + type(gru_hru_time_doubleVec),allocatable :: progStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model prognostic (state) variables + type(gru_hru_time_doubleVec),allocatable :: diagStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model diagnostic variables + type(gru_hru_time_doubleVec),allocatable :: fluxStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- model fluxes + + ! define the basin-average structures + type(gru_double),allocatable :: bparStruct(:) ! x%gru(:)%var(:) -- basin-average parameters, DOES NOT CHANGE OVER TIMESTEPS + type(gru_hru_time_doubleVec),allocatable :: bvarStruct(:) ! x%gru(:)%hru(:)%var(:)%tim(:)%dat -- basin-average variables + + ! define the ancillary data structures + type(gru_hru_double),allocatable :: dparStruct(:) ! x%gru(:)%hru(:)%var(:) + + ! finalize stats structure + type(gru_hru_time_flagVec),allocatable :: finalizeStats(:) ! x%gru(:)%hru(:)%tim(:)%dat -- flags on when to write to file + + integer(i4b) :: nTimeSteps end type summa_output_type END MODULE data_types diff --git a/build/source/dshare/get_ixname.f90 b/build/source/dshare/get_ixname.f90 index fbf9c4e3e37d3ac67a9c823f8e57f243f2379990..a7866a4b1d7f1fa3bcc96be8b038e689fc6f5060 100755 --- a/build/source/dshare/get_ixname.f90 +++ b/build/source/dshare/get_ixname.f90 @@ -997,6 +997,7 @@ contains case ('bpar' ); vDex = get_ixBpar(trim(varName)) case ('bvar' ); vDex = get_ixBvar(trim(varName)) case ('deriv'); vDex = get_ixDeriv(trim(varName)) + case ('lookup'); vDex = get_ixLookup(trim(varName)) end select if (vDex>0) then; typeName=trim(structInfo(iStruc)%structName); return; end if end do @@ -1006,6 +1007,26 @@ contains end subroutine get_ixUnknown +! ******************************************************************************************************************* +! public function get_ixfreq: get the index of the named variables for the output frequencies +! ******************************************************************************************************************* +function get_ixLookup(varName) + USE var_lookup,only:iLookLOOKUP ! indices of the named variables + implicit none + ! define dummy variables + character(*), intent(in) :: varName ! variable name + integer(i4b) :: get_ixLookup ! index of the named variable + ! get the index of the named variables + select case(trim(varName)) + case('temperature'); get_ixLookup = iLookLOOKUP%temperature ! temperature (K) + case('enthalpy' ); get_ixLookup = iLookLOOKUP%enthalpy ! enthalpy (J m-3) + case('deriv2' ); get_ixLookup = iLookLOOKUP%deriv2 ! secind derivative of the interpolating function + ! get to here if cannot find the variable + case default + get_ixLookup = integerMissing + end select + end function get_ixLookup + ! ******************************************************************************************************************* ! public function get_ixfreq: get the index of the named variables for the output frequencies ! ******************************************************************************************************************* diff --git a/build/source/dshare/globalData.f90 b/build/source/dshare/globalData.f90 index eb26ac31d61bb80327ede372a34974f55dee015c..205788e200250c50aa5686176dc792977edccae1 100755 --- a/build/source/dshare/globalData.f90 +++ b/build/source/dshare/globalData.f90 @@ -60,6 +60,7 @@ MODULE globalData USE var_lookup,only:maxvarBpar ! basin-average parameters: maximum number variables USE var_lookup,only:maxvarDecisions ! maximum number of decisions USE var_lookup,only:maxvarFreq ! maximum number of output files + USE var_lookup,only:maxvarLookup implicit none private @@ -148,9 +149,9 @@ MODULE globalData real(rkind),parameter,public :: dx = 1.e-8_dp ! finite difference increment ! define summary information on all data structures - integer(i4b),parameter :: nStruct=13 ! number of data structures + integer(i4b),parameter :: nStruct=14 ! number of data structures type(struct_info),parameter,public,dimension(nStruct) :: structInfo=(/& - struct_info('time', 'TIME' , maxvarTime ), & ! the time data structure + struct_info('time', 'TIME' , maxvarTime ), & ! the time data structure struct_info('forc', 'FORCE', maxvarForc ), & ! the forcing data structure struct_info('attr', 'ATTR' , maxvarAttr ), & ! the attribute data structure struct_info('type', 'TYPE' , maxvarType ), & ! the type data structure @@ -162,8 +163,8 @@ MODULE globalData struct_info('prog', 'PROG', maxvarProg ), & ! the prognostic (state) variable data structure struct_info('diag', 'DIAG' , maxvarDiag ), & ! the diagnostic variable data structure struct_info('flux', 'FLUX' , maxvarFlux ), & ! the flux data structure - struct_info('deriv', 'DERIV', maxvarDeriv) /) ! the model derivative data structure - + struct_info('deriv', 'DERIV', maxvarDeriv), & ! the model derivative data structure + struct_info('lookup', 'LOOKUP',maxvarLookup) /) ! fixed model decisions logical(lgt) , parameter, public :: overwriteRSMIN=.false. ! flag to overwrite RSMIN integer(i4b) , parameter, public :: maxSoilLayers=10000 ! Maximum Number of Soil Layers @@ -191,6 +192,7 @@ MODULE globalData type(var_info),save,public :: diag_meta(maxvarDiag) ! local diagnostic variables for each HRU type(var_info),save,public :: flux_meta(maxvarFlux) ! local model fluxes for each HRU type(var_info),save,public :: deriv_meta(maxvarDeriv) ! local model derivatives for each HRU + type(var_info),save,public :: lookup_meta(maxvarLookup) ! local lookup tables for each HRU type(var_info),save,public :: bpar_meta(maxvarBpar) ! basin parameters for aggregated processes type(var_info),save,public :: bvar_meta(maxvarBvar) ! basin variables for aggregated processes diff --git a/build/source/dshare/popMetadat.f90 b/build/source/dshare/popMetadat.f90 index 4c2b371e64ea8dcb3f5294d6966f10242bc75e52..3ec9511f0bb717cd798eb9ff20bd5d96cc6c1df6 100755 --- a/build/source/dshare/popMetadat.f90 +++ b/build/source/dshare/popMetadat.f90 @@ -31,6 +31,7 @@ subroutine popMetadat(err,message) USE globalData, only: diag_meta ! data structure for local diagnostic variables USE globalData, only: flux_meta ! data structure for local flux variables USE globalData, only: deriv_meta ! data structure for local flux derivatives + USE globalData, only: lookup_meta ! data structure for lookup tables ! structures of named variables USE var_lookup, only: iLookTIME ! named variables for time data structure USE var_lookup, only: iLookFORCE ! named variables for forcing data structure @@ -45,6 +46,7 @@ subroutine popMetadat(err,message) USE var_lookup, only: iLookDIAG ! named variables for local diagnostic variables USE var_lookup, only: iLookFLUX ! named variables for local flux variables USE var_lookup, only: iLookDERIV ! named variables for local flux derivatives + USE var_lookup, only: iLookLOOKUP ! named variables for lookup tables USE var_lookup, only: maxvarFreq ! number of output frequencies USE var_lookup, only: maxvarStat ! number of statistics USE get_ixName_module,only:get_ixVarType ! to turn vartype strings to integers @@ -595,6 +597,15 @@ subroutine popMetadat(err,message) bvar_meta(iLookBVAR%averageInstantRunoff) = var_info('averageInstantRunoff' , 'instantaneous runoff' , 'm s-1' , get_ixVarType('scalarv'), iMissVec, iMissVec, .false.) bvar_meta(iLookBVAR%averageRoutedRunoff) = var_info('averageRoutedRunoff' , 'routed runoff' , 'm s-1' , get_ixVarType('scalarv'), iMissVec, iMissVec, .false.) + ! ----- + ! * lookup tables... + ! ------------------ + + ! temperature and enthalpy + lookup_meta(iLookLOOKUP%temperature) = var_info('temperature' , 'value of temperature in the lookup table' , 'K' , get_ixVarType('unknown'), iMissVec, iMissVec, .false.) + lookup_meta(iLookLOOKUP%enthalpy) = var_info('enthalpy' , 'value of enthalpy in the lookup table' , 'J m-3' , get_ixVarType('unknown'), iMissVec, iMissVec, .false.) + lookup_meta(iLookLOOKUP%deriv2) = var_info('deriv2' , 'second derivatives of the interpolating function' , 'mixed' , get_ixVarType('unknown'), iMissVec, iMissVec, .false.) + ! ----- ! * model indices... ! ------------------ diff --git a/build/source/dshare/var_lookup.f90 b/build/source/dshare/var_lookup.f90 index b1ae8c0ad725c0c80862e549b26dc1e118ac482d..f1657613547a75f7a31b354caf2d9d743be0b063 100755 --- a/build/source/dshare/var_lookup.f90 +++ b/build/source/dshare/var_lookup.f90 @@ -20,6 +20,7 @@ MODULE var_lookup ! defines named variables used to index array elements + USE, intrinsic :: iso_c_binding USE nrtype, integerMissing=>nr_integerMissing implicit none private @@ -719,19 +720,19 @@ MODULE var_lookup ! (13) structure for looking up the type of a model variable (this is only needed for backward ! compatability, and should be removed eventually) ! *********************************************************************************************************** - type, public :: iLook_varType - integer(i4b) :: scalarv = integerMissing ! scalar variables - integer(i4b) :: wLength = integerMissing ! # spectral bands - integer(i4b) :: midSnow = integerMissing ! mid-layer snow variables - integer(i4b) :: midSoil = integerMissing ! mid-layer soil variables - integer(i4b) :: midToto = integerMissing ! mid-layer, both snow and soil - integer(i4b) :: ifcSnow = integerMissing ! interface snow variables - integer(i4b) :: ifcSoil = integerMissing ! interface soil variables - integer(i4b) :: ifcToto = integerMissing ! interface, snow and soil - integer(i4b) :: parSoil = integerMissing ! soil depth - integer(i4b) :: routing = integerMissing ! routing variables - integer(i4b) :: outstat = integerMissing ! output statistic - integer(i4b) :: unknown = integerMissing ! cath-cal alternative type + type, public, bind(C) :: iLook_varType + integer(c_int) :: scalarv = integerMissing ! scalar variables + integer(c_int) :: wLength = integerMissing ! # spectral bands + integer(c_int) :: midSnow = integerMissing ! mid-layer snow variables + integer(c_int) :: midSoil = integerMissing ! mid-layer soil variables + integer(c_int) :: midToto = integerMissing ! mid-layer, both snow and soil + integer(c_int) :: ifcSnow = integerMissing ! interface snow variables + integer(c_int) :: ifcSoil = integerMissing ! interface soil variables + integer(c_int) :: ifcToto = integerMissing ! interface, snow and soil + integer(c_int) :: parSoil = integerMissing ! soil depth + integer(c_int) :: routing = integerMissing ! routing variables + integer(c_int) :: outstat = integerMissing ! output statistic + integer(c_int) :: unknown = integerMissing ! cath-cal alternative type endtype iLook_varType ! *********************************************************************************************************** @@ -757,6 +758,17 @@ MODULE var_lookup integer(i4b) :: timestep = integerMissing ! timestep-level output (no temporal aggregation) endtype iLook_freq + ! *********************************************************************************************************** + ! (16) structure for looking up lookup tables + ! *********************************************************************************************************** + type, public :: iLook_vLookup + integer(i4b) :: temperature = integerMissing ! temperature (K) + integer(i4b) :: enthalpy = integerMissing ! enthalpy (J m-3) + integer(i4b) :: deriv2 = integerMissing ! second derivatives of the interpolating function + endtype iLook_vLookup + + + ! *********************************************************************************************************** ! (X) define data structures and maximum number of variables of each type ! *********************************************************************************************************** @@ -856,6 +868,7 @@ MODULE var_lookup ! number of possible output frequencies type(iLook_freq), public,parameter :: iLookFreq =ilook_freq ( 1, 2, 3, 4) + type(iLook_vLookup), public,parameter :: iLookLOOKUP =ilook_vLookup ( 1, 2, 3) ! define maximum number of variables of each type integer(i4b),parameter,public :: maxvarDecisions = storage_size(iLookDECISIONS)/iLength integer(i4b),parameter,public :: maxvarTime = storage_size(iLookTIME)/iLength @@ -874,6 +887,7 @@ MODULE var_lookup integer(i4b),parameter,public :: maxvarVarType = storage_size(iLookVarType)/iLength integer(i4b),parameter,public :: maxvarStat = storage_size(iLookStat)/iLength integer(i4b),parameter,public :: maxvarFreq = storage_size(iLookFreq)/iLength + integer(i4b),parameter,public :: maxvarLookup = storage_size(iLookLOOKUP)/iLength ! *********************************************************************************************************** ! (Y) define ancillary look-up structures diff --git a/build/source/engine/alloc_file_access.f90 b/build/source/engine/alloc_file_access.f90 index 5a83a89ae1d081355e06dc4b5f93995e7c6cbfa7..139982fa4e7f34f6fe73e34533bd80148790e9cf 100644 --- a/build/source/engine/alloc_file_access.f90 +++ b/build/source/engine/alloc_file_access.f90 @@ -5,6 +5,7 @@ USE data_types,only:var_time_ilength USE data_types,only:var_time_i USE data_types,only:var_time_d USE data_types,only:var_time_i8 +USE data_types,only:var_i8 USE data_types,only:var_d USE data_types,only:var_i USE data_types,only:var_dlength @@ -41,105 +42,114 @@ subroutine alloc_outputStruc(metaStruct,dataStruct,nSteps,nSnow,nSoil,err,messag integer(i4b) :: iVar character(len=256) :: cmessage ! error message of the downwind routine ! initalize error control - err=0; message='alloc_outputStruc' + message='alloc_outputStruc' nVars = size(metaStruct) - if(present(nSnow) .or. present(nSoil))then - ! check both are present - if(.not.present(nSoil))then; err=20; message=trim(message)//'expect nSoil to be present when nSnow is present'; return; end if - if(.not.present(nSnow))then; err=20; message=trim(message)//'expect nSnow to be present when nSoil is present'; return; end if - nLayers = nSnow+nSoil + if(present(nSnow) .or. present(nSoil))then + ! check both are present + if(.not.present(nSoil))then; err=20; message=trim(message)//'expect nSoil to be present when nSnow is present'; return; end if + if(.not.present(nSnow))then; err=20; message=trim(message)//'expect nSnow to be present when nSoil is present'; return; end if + nLayers = nSnow+nSoil - ! It is possible that nSnow and nSoil are actually needed here, so we return an error if the optional arguments are missing when needed - else - select type(dataStruct) - ! class is (var_flagVec); err=20 - class is (var_time_ilength); err=20 - class is (var_time_dlength); err=20 - end select - if(err/=0)then; message=trim(message)//'expect nSnow and nSoil to be present for variable-length data structures'; return; end if - end if + ! It is possible that nSnow and nSoil are actually needed here, so we return an error if the optional arguments are missing when needed + else + select type(dataStruct) + ! class is (var_flagVec); err=20 + class is (var_time_ilength); err=20 + class is (var_time_dlength); err=20 + end select + if(err/=0)then; message=trim(message)//'expect nSnow and nSoil to be present for variable-length data structures'; return; end if + end if - check=.false. + check=.false. ! allocate the dimension for model variables - select type(dataStruct) + select type(dataStruct) - class is (var_time_i) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - do iVar=1, nVars - allocate(dataStruct%var(iVar)%tim(nSteps)) - end do - return + class is (var_time_i) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + + do iVar=1, nVars + allocate(dataStruct%var(iVar)%tim(nSteps)) + end do + return - class is (var_time_i8) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - do iVar=1, nVars - allocate(dataStruct%var(iVar)%tim(nSteps)) - end do - return + class is (var_time_i8) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + do iVar=1, nVars + allocate(dataStruct%var(iVar)%tim(nSteps)) + end do + return - class is (var_time_d) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - do iVar=1, nVars - allocate(dataStruct%var(iVar)%tim(nSteps)) - end do - return - - class is (var_d) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - return - - class is (var_i) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - return - - class is (var_dlength) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - ! class is (var_flagVec); if(allocated(dataStruct%var))then; check=.true.; else; allocate(dataStruct%var(nVars),stat=err); end if + class is (var_time_d) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + do iVar=1, nVars + allocate(dataStruct%var(iVar)%tim(nSteps)) + end do + return + + class is (var_d) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + return + + class is (var_i) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + return + + class is (var_i8) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars), stat=err) + end if + return + + class is (var_dlength) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + ! class is (var_flagVec); if(allocated(dataStruct%var))then; check=.true.; else; allocate(dataStruct%var(nVars),stat=err); end if - class is (var_time_ilength) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - do iVar=1, nVars - allocate(dataStruct%var(iVar)%tim(nSteps)) - end do + class is (var_time_ilength) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + do iVar=1, nVars + allocate(dataStruct%var(iVar)%tim(nSteps)) + end do - class is (var_time_dlength) - if(allocated(dataStruct%var))then - check=.true. - else - allocate(dataStruct%var(nVars),stat=err) - end if - do iVar=1, nVars - allocate(dataStruct%var(iVar)%tim(nSteps)) - end do + class is (var_time_dlength) + if(allocated(dataStruct%var))then + check=.true. + else + allocate(dataStruct%var(nVars),stat=err) + end if + do iVar=1, nVars + allocate(dataStruct%var(iVar)%tim(nSteps)) + end do class default; err=20; message=trim(message)//'unable to identify derived data type for the variable dimension'; return end select diff --git a/build/source/engine/allocspaceActors.f90 b/build/source/engine/allocspaceActors.f90 index f10d43a342c637095a54e68f3de963d41484f559..fcc30740e2eb3f758f243270126659f2ecd3fe19 100755 --- a/build/source/engine/allocspaceActors.f90 +++ b/build/source/engine/allocspaceActors.f90 @@ -25,6 +25,7 @@ USE nrtype ! provide access to the derived types to define the data structures USE data_types,only:& + zLookup, & ! final data vectors dlength, & ! var%dat ilength, & ! var%dat @@ -133,6 +134,7 @@ contains logical(lgt) :: check ! .true. if the variables are allocated integer(i4b) :: nVars ! number of variables in the metadata structure integer(i4b) :: nLayers ! total number of layers + logical(lgt) :: spatial character(len=256) :: cmessage ! error message of the downwind routine ! initialize error control err=0; message='allocLocal/' @@ -168,6 +170,7 @@ contains class is (var_flagVec); if(allocated(dataStruct%var))then; check=.true.; else; allocate(dataStruct%var(nVars),stat=err); end if class is (var_ilength); if(allocated(dataStruct%var))then; check=.true.; else; allocate(dataStruct%var(nVars),stat=err); end if class is (var_dlength); if(allocated(dataStruct%var))then; check=.true.; else; allocate(dataStruct%var(nVars),stat=err); end if + class is (zLookup); spatial=.true. class default; err=20; message=trim(message)//'unable to identify derived data type for the variable dimension'; return end select ! check errors @@ -179,6 +182,7 @@ contains class is (var_flagVec); call allocateDat_flag(metaStruct,nSnow,nSoil,nLayers,dataStruct,err,cmessage) class is (var_ilength); call allocateDat_int( metaStruct,nSnow,nSoil,nLayers,dataStruct,err,cmessage) class is (var_dlength); call allocateDat_dp( metaStruct,nSnow,nSoil,nLayers,dataStruct,err,cmessage) + class is (zLookup); spatial=.true. class default; err=20; message=trim(message)//'unable to identify derived data type for the data dimension'; return end select diff --git a/build/source/engine/checkStruc.f90 b/build/source/engine/checkStruc.f90 index 3d723a367f3e07189eae00fa46efff605ff398aa..8d7aa5da1e426f056b89c69755f26a0abe61f607 100755 --- a/build/source/engine/checkStruc.f90 +++ b/build/source/engine/checkStruc.f90 @@ -40,11 +40,13 @@ contains USE globalData,only:prog_meta,diag_meta,flux_meta,deriv_meta ! metadata structures USE globalData,only:mpar_meta,indx_meta ! metadata structures USE globalData,only:bpar_meta,bvar_meta ! metadata structures + USE globalData,only:lookup_meta ! metadata structures ! named variables defining strructure elements USE var_lookup,only:iLookTIME,iLookFORCE,iLookATTR,iLookTYPE,iLookID ! named variables showing the elements of each data structure USE var_lookup,only:iLookPROG,iLookDIAG,iLookFLUX,iLookDERIV ! named variables showing the elements of each data structure USE var_lookup,only:iLookPARAM,iLookINDEX ! named variables showing the elements of each data structure USE var_lookup,only:iLookBPAR,iLookBVAR ! named variables showing the elements of each data structure + USE var_lookup,only:iLookLOOKUP ! named variables showing the elements of each data structure implicit none ! dummy variables integer(i4b),intent(out) :: err ! error code @@ -83,6 +85,7 @@ contains case('diag'); write(longString,*) iLookDIAG case('flux'); write(longString,*) iLookFLUX case('deriv'); write(longString,*) iLookDERIV + case('lookup'); write(longString,*) iLookLOOKUP case default; err=20; message=trim(message)//'unable to identify lookup structure'; return end select ! check that the length of the lookup structure matches the number of variables in the data structure @@ -119,6 +122,7 @@ contains case('diag'); call checkPopulated(iStruct,diag_meta,err,cmessage) case('flux'); call checkPopulated(iStruct,flux_meta,err,cmessage) case('deriv'); call checkPopulated(iStruct,deriv_meta,err,cmessage) + case('lookup'); call checkPopulated(iStruct,lookup_meta,err,cmessage) case default; err=20; message=trim(message)//'unable to identify lookup structure'; return end select if(err/=0)then; message=trim(message)//trim(cmessage); return; end if ! (check for errors) diff --git a/build/source/engine/nrtype.mod b/build/source/engine/nrtype.mod index 66827afb4ddef1dc3741a7481196b45284785e98..cb753b75bed2441f7d23ae5b89340b7015376d91 100644 Binary files a/build/source/engine/nrtype.mod and b/build/source/engine/nrtype.mod differ diff --git a/build/source/engine/read_attribute.f90 b/build/source/engine/read_attribute.f90 index 1c74a541c4dce38022907eeffb788c91dba60940..cb5f3d5faa0e043059c4c26e9ea24c28f0327db9 100644 --- a/build/source/engine/read_attribute.f90 +++ b/build/source/engine/read_attribute.f90 @@ -19,6 +19,7 @@ ! along with this program. If not, see <http://www.gnu.org/licenses/>. module read_attribute_module +USE, intrinsic :: iso_c_binding USE nrtype implicit none private @@ -29,7 +30,8 @@ contains ! ************************************************************************************************ ! public subroutine read_dimension: read HRU and GRU dimension information on local attributes ! ************************************************************************************************ -subroutine read_dimension(attrFile,fileGRU,fileHRU,numGRUs,numHRUs,startGRU,err,message) +subroutine read_dimension(numGRUs,numHRUs,startGRU,err) bind(C, name="readDimension") + USE netcdf USE netcdf_util_module,only:nc_file_open ! open netcdf file USE netcdf_util_module,only:nc_file_close ! close netcdf file @@ -37,24 +39,31 @@ subroutine read_dimension(attrFile,fileGRU,fileHRU,numGRUs,numHRUs,startGRU,err, ! provide access to global data USE globalData,only:gru_struc ! gru->hru mapping structure USE globalData,only:index_map ! hru->gru mapping structure + ! file paths for attribute file + USE summaActors_FileManager,only:SETTINGS_PATH ! define path to settings files (e.g., parameters, soil and veg. tables) + USE summaActors_FileManager,only:LOCAL_ATTRIBUTES ! name of model initial attributes file + + implicit none ! Dummy Variables - character(*),intent(in) :: attrFile ! name of attributed file - integer(i4b),intent(out) :: fileGRU ! number of GRUs in the input file - integer(i4b),intent(out) :: fileHRU ! number of HRUs in the input file - integer(i4b),intent(in) :: numGRUs ! number of GRUs for the run domain - integer(i4b),intent(out) :: numHRUs ! number of HRUs for the run domain (value filled in this subroutine) - integer(i4b),intent(in) :: startGRU ! Index of the starting GRU - integer(i4b),intent(out) :: err ! error code - character(*),intent(out) :: message ! error message + + integer(c_int),intent(in) :: numGRUs ! number of GRUs for the run domain + integer(c_int),intent(out) :: numHRUs ! number of HRUs for the run domain (value filled in this subroutine) + integer(c_int),intent(in) :: startGRU ! Index of the starting GRU + integer(c_int),intent(out) :: err ! error code ! Local Variables + character(len=256) :: attrFile ! name of attributed file + integer(i4b) :: fileGRU ! number of GRUs in the input file + integer(i4b) :: fileHRU ! number of HRUs in the input file integer(i4b) :: iHRU ! HRU couinting index integer(i4b) :: iGRU ! GRU loop index integer(8),allocatable :: gru_id(:),hru_id(:)! read gru/hru IDs in from attributes file integer(8),allocatable :: hru2gru_id(:) ! read hru->gru mapping in from attributes file integer(i4b),allocatable :: hru_ix(:) ! hru index for search + character(len=256) :: message ! error message + ! define variables for NetCDF file operation integer(i4b) :: ncID ! NetCDF file ID @@ -64,6 +73,8 @@ subroutine read_dimension(attrFile,fileGRU,fileHRU,numGRUs,numHRUs,startGRU,err, character(len=256) :: cmessage ! error message for downwind routine err=0; message="read_dimension/" + attrFile = trim(SETTINGS_PATH)//trim(LOCAL_ATTRIBUTES) + ! open nc file call nc_file_open(trim(attrFile),nf90_noWrite,ncID,err,cmessage) if(err/=0)then; message=trim(message)//trim(cmessage); return; end if @@ -148,193 +159,127 @@ subroutine read_dimension(attrFile,fileGRU,fileHRU,numGRUs,numHRUs,startGRU,err, end subroutine read_dimension -subroutine read_attribute(indxHRU, indxGRU, attrFile, attrStruct, typeStruct, idStruct, err, message) - USE netcdf - USE netcdf_util_module,only:nc_file_open ! open netcdf file - USE netcdf_util_module,only:nc_file_close ! close netcdf file - USE netcdf_util_module,only:netcdf_err ! netcdf error handling function - ! provide access to derived data types - USE data_types,only:var_d ! x%var(:) (i4b) - USE data_types,only:var_i ! x%var(:) integer(8) - USE data_types,only:var_i8 ! x%var(:) (dp) - ! provide access to global data - USE globalData,only:gru_struc ! gru-hru mapping structure - USE globalData,only:attr_meta,type_meta,id_meta ! metadata structures - USE get_ixname_module,only:get_ixAttr,get_ixType,get_ixId ! access function to find index of elements in structure - implicit none - - integer(i4b),intent(in) :: indxHRU ! id of the HRU - integer(i4b),intent(in) :: indxGRU ! id of the parent GRU - ! io vars - character(*) :: attrFile ! input filename - type(var_d),intent(inout) :: attrStruct ! local attributes for each HRU - type(var_i),intent(inout) :: typeStruct ! local classification of soil veg etc. for each HRU - type(var_i8),intent(inout) :: idStruct ! - integer(i4b),intent(out) :: err ! error code - character(*),intent(out) :: message ! error message - - ! define local variables - character(len=256) :: cmessage ! error message for downwind routine - integer(i4b) :: iVar ! loop through varibles in the netcdf file - integer(i4b) :: varType ! type of variable (categorica, numerical, idrelated) - integer(i4b) :: varIndx ! index of variable within its data structure - - ! check structures - integer(i4b) :: iCheck ! index of an attribute name - logical(lgt),allocatable :: checkType(:) ! vector to check if we have all desired categorical values - logical(lgt),allocatable :: checkId(:) ! vector to check if we have all desired IDs - logical(lgt),allocatable :: checkAttr(:) ! vector to check if we have all desired local attributes - - ! netcdf variables - integer(i4b) :: ncID ! netcdf file id - character(LEN=nf90_max_name) :: varName ! character array of netcdf variable name - integer(i4b) :: nVar ! number of variables in netcdf local attribute file - integer(i4b),parameter :: categorical=101 ! named variable to denote categorical data - integer(i4b),parameter :: numerical=102 ! named variable to denote numerical data - integer(i4b),parameter :: idrelated=103 ! named variable to denote ID related data - integer(i4b) :: categorical_var(1) ! temporary categorical variable from local attributes netcdf file - real(dp) :: numeric_var(1) ! temporary numeric variable from local attributes netcdf file - integer(8) :: idrelated_var(1) ! temporary ID related variable from local attributes netcdf file - - ! define mapping variables - - ! Start procedure here - err=0; message="read_attrb4chm/" - - ! ********************************************************************************************** - ! (1) prepare check vectors - ! ********************************************************************************************** - allocate(checkType(size(type_meta)),checkAttr(size(attr_meta)),checkId(size(id_meta)),stat=err) - if(err/=0)then; err=20; message=trim(message)//'problem allocating space for variable check vectors'; return; endif - checkType(:) = .false. - checkAttr(:) = .false. - checkId(:) = .false. - - ! ********************************************************************************************** - ! (2) open netcdf file - ! ********************************************************************************************** - ! open file - call nc_file_open(trim(attrFile),nf90_noWrite,ncID,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; endif - - ! get number of variables total in netcdf file - err = nf90_inquire(ncID,nvariables=nVar) - call netcdf_err(err,message); if (err/=0) return - - ! ********************************************************************************************** - ! (3) read local attributes - ! ********************************************************************************************** - ! loop through variables in netcdf file and pull out local attributes - iCheck = 1 - do iVar = 1,nVar - - ! inqure about current variable name, type, number of dimensions - err = nf90_inquire_variable(ncID,iVar,name=varName) - if(err/=nf90_noerr)then; message=trim(message)//'problem inquiring variable: '//trim(varName)//'/'//trim(nf90_strerror(err)); return; endif - - ! find attribute name - select case(trim(varName)) - - ! ** categorical data - case('vegTypeIndex','soilTypeIndex','slopeTypeIndex','downHRUindex') - - ! get the index of the variable - varType = categorical - varIndx = get_ixType(varName) - checkType(varIndx) = .true. - - ! check that the variable could be identified in the data structure - if(varIndx < 1)then; err=20; message=trim(message)//'unable to find variable ['//trim(varName)//'] in data structure'; return; endif +subroutine read_attribute(indxHRU, indxGRU, attrStruct, typeStruct, idStruct, err, message) + USE netcdf + USE netcdf_util_module,only:nc_file_open ! open netcdf file + USE netcdf_util_module,only:nc_file_close ! close netcdf file + USE netcdf_util_module,only:netcdf_err ! netcdf error handling function + ! provide access to derived data types + USE data_types,only:var_d ! x%var(:) (i4b) + USE data_types,only:var_i ! x%var(:) integer(8) + USE data_types,only:var_i8 ! x%var(:) (dp) + ! provide access to global data + USE globalData,only:attr_meta,type_meta,id_meta ! metadata structures + USE get_ixname_module,only:get_ixAttr,get_ixType,get_ixId ! access function to find index of elements in structure + ! get the settings from the output stucture so we do not have to go to file + USE globalData,only:outputStructure + implicit none - ! get data from netcdf file and store in vector - err = nf90_get_var(ncID,iVar,categorical_var,start=(/gru_struc(indxGRU)%hruInfo(indxHRU)%hru_nc/),count=(/1/)) - if(err/=nf90_noerr)then; message=trim(message)//'problem reading: '//trim(varName); return; end if - typeStruct%var(varIndx) = categorical_var(1) + integer(i4b),intent(in) :: indxHRU ! id of the HRU + integer(i4b),intent(in) :: indxGRU ! id of the parent GRU + ! io vars + type(var_d),intent(inout) :: attrStruct ! local attributes for each HRU + type(var_i),intent(inout) :: typeStruct ! local classification of soil veg etc. for each HRU + type(var_i8),intent(inout) :: idStruct ! + integer(i4b),intent(out) :: err ! error code + character(*),intent(out) :: message ! error message - ! ** ID related data - case('hruId') - ! get the index of the variable - varType = idrelated - varIndx = get_ixId(varName) - checkId(varIndx) = .true. + ! define local variables + integer(i4b) :: iVar ! loop through varibles in the netcdf file - ! check that the variable could be identified in the data structure - if(varIndx < 1)then; err=20; message=trim(message)//'unable to find variable ['//trim(varName)//'] in data structure'; return; endif + ! check structures + integer(i4b) :: iCheck ! index of an attribute name + logical(lgt),allocatable :: checkType(:) ! vector to check if we have all desired categorical values + logical(lgt),allocatable :: checkId(:) ! vector to check if we have all desired IDs + logical(lgt),allocatable :: checkAttr(:) ! vector to check if we have all desired local attributes - ! get data from netcdf file and store in vector - err = nf90_get_var(ncID,iVar,idrelated_var,start=(/gru_struc(indxGRU)%hruInfo(indxHRU)%hru_nc/),count=(/1/)) - if(err/=nf90_noerr)then; message=trim(message)//'problem reading: '//trim(varName); return; end if - idStruct%var(varIndx) = idrelated_var(1) + ! netcdf variables + integer(i4b),parameter :: categorical=101 ! named variable to denote categorical data + integer(i4b),parameter :: numerical=102 ! named variable to denote numerical data + integer(i4b),parameter :: idrelated=103 ! named variable to denote ID related data - ! ** numerical data - case('latitude','longitude','elevation','tan_slope','contourLength','HRUarea','mHeight') + ! define mapping variables - ! get the index of the variable - varType = numerical - varIndx = get_ixAttr(varName) - checkAttr(varIndx) = .true. + ! Start procedure here + err=0; message="read_attribute.f90/" - ! check that the variable could be identified in the data structure - if(varIndx < 1)then; err=20; message=trim(message)//'unable to find variable ['//trim(varName)//'] in data structure'; return; endif - ! get data from netcdf file and store in vector - err = nf90_get_var(ncID,iVar,numeric_var,start=(/gru_struc(indxGRU)%hruInfo(indxHRU)%hru_nc/),count=(/1/)) - if(err/=nf90_noerr)then; message=trim(message)//'problem reading: '//trim(varName); return; end if - attrStruct%var(varIndx) = numeric_var(1) + ! ********************************************************************************************** + ! (1) prepare check vectors + ! ********************************************************************************************** + allocate(checkType(size(type_meta)),checkAttr(size(attr_meta)),checkId(size(id_meta)),stat=err) + if(err/=0)then + err=20 + message=trim(message)//'problem allocating space for variable check vectors' + print*, message + return + endif - ! for mapping varibles, do nothing (information read above) - case('hru2gruId','gruId'); cycle + checkType(:) = .false. + checkAttr(:) = .false. + checkId(:) = .false. + + ! Copy the attribute data that was filled in read_attribute_all_hru.f90 - ! check that variables are what we expect - case default; message=trim(message)//'unknown variable ['//trim(varName)//'] in local attributes file'; err=20; return + ! ** categorical data (typeStruct) + do iVar = 1, size(type_meta) + checkType(iVar) = .true. + typeStruct%var(iVar) = outputStructure(1)%typeStruct(1)%gru(indxGRU)%hru(indxHRU)%var(iVar) + end do - end select ! select variable + ! ** ID related data (idStruct) + do iVar=1, size(id_meta) + checkId(iVar) = .true. + idStruct%var(iVar) = outputStructure(1)%idStruct(1)%gru(indxGRU)%hru(indxHRU)%var(iVar) + end do - end do ! (looping through netcdf local attribute file) + ! ** numerical data (attrStruct) + do iVar=1, size(attr_meta) + checkAttr(iVar) = .true. + attrStruct%var(iVar) = outputStructure(1)%attrStruct(1)%gru(indxGRU)%hru(indxHRU)%var(iVar) + end do - ! ** now handle the optional aspect variable if it's missing - varIndx = get_ixAttr('aspect') - ! check that the variable was not found in the attribute file - if(.not. checkAttr(varIndx)) then - ! write(*,*) NEW_LINE('A')//'INFO: aspect not found in the input attribute file, continuing ...'//NEW_LINE('A') - attrStruct%var(varIndx) = nr_realMissing ! populate variable with out-of-range value, used later - checkAttr(varIndx) = .true. - endif - - varIndx = get_ixTYPE('downkHRU') - checkType(varIndx) = .true. - typeStruct%var(varIndx) = 0 +! TODO: downkHRU can cause issues do not know how to hanlde yet +! varIndx = get_ixTYPE('downkHRU') +! checkType(varIndx) = .true. +! typeStruct%var(varIndx) = 0 ! ********************************************************************************************** ! (4) check that we have all the desired varaibles ! ********************************************************************************************** ! check that we have all desired categorical variables - if(any(.not.checkType))then - do iCheck = 1,size(type_meta) - if(.not.checkType(iCheck))then; err=20; message=trim(message)//'missing variable ['//trim(type_meta(iCheck)%varname)//'] in local attributes file'; return; endif - end do + if(any(.not.checkType))then + do iCheck = 1,size(type_meta) + if(.not.checkType(iCheck))then + err=20; message=trim(message)//'missing variable ['//trim(type_meta(iCheck)%varname)//'] in local attributes file' + print*, message + return + endif + end do endif - ! check that we have all desired ID variables - if(any(.not.checkId))then - do iCheck = 1,size(id_meta) - if(.not.checkId(iCheck))then; err=20; message=trim(message)//'missing variable ['//trim(id_meta(iCheck)%varname)//'] in local attributes file'; return; endif - end do - endif + ! check that we have all desired ID variables + if(any(.not.checkId))then + do iCheck = 1,size(id_meta) + if(.not.checkId(iCheck))then + err=20 + message=trim(message)//'missing variable ['//trim(id_meta(iCheck)%varname)//'] in local attributes file' + print*, message + return + endif + end do + endif ! check that we have all desired local attributes - if(any(.not.checkAttr))then - do iCheck = 1,size(attr_meta) - if(.not.checkAttr(iCheck))then; err=20; message=trim(message)//'missing variable ['//trim(attr_meta(iCheck)%varname)//'] in local attributes file'; return; endif - end do + if(any(.not.checkAttr))then + do iCheck = 1,size(attr_meta) + if(.not.checkAttr(iCheck))then + err=20 + message=trim(message)//'missing variable ['//trim(attr_meta(iCheck)%varname)//'] in local attributes file' + return + endif + end do endif - ! ********************************************************************************************** - ! (5) close netcdf file - ! ********************************************************************************************** - - call nc_file_close(ncID,err,cmessage) - if (err/=0)then; message=trim(message)//trim(cmessage); return; end if - ! free memory deallocate(checkType) deallocate(checkId) diff --git a/build/source/engine/read_paramActors.f90 b/build/source/engine/read_paramActors.f90 index bac913f655b518ad01e13a62af73c283e461b7aa..661ffe63d577a98c83ac7a03b138d5dcb9a1723e 100755 --- a/build/source/engine/read_paramActors.f90 +++ b/build/source/engine/read_paramActors.f90 @@ -41,319 +41,50 @@ USE data_types,only:var_dlength ! spatial double data type: x%gru(:)%hru(: implicit none private -public::read_param4chm +public::read_param contains - ! ************************************************************************************************ - ! public subroutine read_param4chm: read trial model parameter values - ! ************************************************************************************************ - subroutine read_param4chm(indxHRU,indxGRU,iRunMode,startGRU,mparStruct,bparStruct,err,message) - ! used to read model initial conditions - USE summaActors_FileManager,only:SETTINGS_PATH ! path for metadata files - USE summaActors_FileManager,only:PARAMETER_TRIAL ! file with parameter trial values - USE get_ixname_module,only:get_ixparam,get_ixbpar ! access function to find index of elements in structure - USE globalData,only:index_map,gru_struc ! mapping from global HRUs to the elements in the data structures - USE var_lookup,only:iLookPARAM,iLookTYPE,iLookID ! named variables to index elements of the data vectors - implicit none - ! define input - integer(i4b),intent(in) :: indxHRU - integer(i4b),intent(in) :: indxGRU - integer(i4b),intent(in) :: iRunMode ! run mode - integer(i4b),intent(in) :: startGRU ! index of single GRU if runMode = startGRU -! type(var_i8),intent(in) :: idStruct ! local labels for hru and gru IDs - ! define output - type(var_dlength),intent(inout) :: mparStruct ! model parameters - type(var_d),intent(inout) :: bparStruct ! basin parameters - integer(i4b),intent(out) :: err ! error code - character(*),intent(out) :: message ! error message - ! define local variables - character(len=1024) :: cmessage ! error message for downwind routine - character(LEN=1024) :: infile ! input filename - integer(i4b) :: localHRU_ix ! index of HRU within data structure - integer(i4b) :: ixParam ! index of the model parameter in the data structure - ! indices/metadata in the NetCDF file - integer(i4b) :: ncid ! netcdf id - integer(i4b) :: nDims ! number of dimensions - integer(i4b) :: nVars ! number of variables - integer(i4b) :: idimid ! dimension index - integer(i4b) :: ivarid ! variable index - character(LEN=64) :: dimName ! dimension name - character(LEN=64) :: parName ! parameter name - integer(i4b) :: dimLength ! dimension length - integer(i4b) :: nHRU_file ! number of HRUs in the parafile - integer(i4b) :: nGRU_file ! number of GRUs in the parafile - integer(i4b) :: nSoil_file ! number of soil layers in the file - integer(i4b) :: idim_list(2) ! list of dimension ids - ! data in the netcdf file - integer(i4b) :: parLength ! length of the parameter data - integer(8),allocatable :: hruId(:) ! HRU identifier in the file - real(dp),allocatable :: parVector(:) ! model parameter vector - logical :: fexist ! inquire whether the parmTrial file exists - integer(i4b) :: fHRU ! index of HRU in input file - - ! Start procedure here - err=0; message="read_param4chm/" - - ! ********************************************************************************************** - ! * open files, etc. - ! ********************************************************************************************** - - ! build filename - infile = trim(SETTINGS_PATH)//trim(PARAMETER_TRIAL) - - ! check whether the user-specified file exists and warn if it does not - inquire(file=trim(infile),exist=fexist) - if (.not.fexist) then - write(*,'(A)') NEW_LINE('A')//'!! WARNING: trial parameter file not found; proceeding instead with other default parameters; check path in file manager input if this was not the desired behavior'//NEW_LINE('A') - return - endif - - ! open trial parameters file if it exists - call nc_file_open(trim(infile),nf90_nowrite,ncid,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if - - ! get the number of variables in the parameter file - err=nf90_inquire(ncid, nDimensions=nDims, nVariables=nVars) - call netcdf_err(err,message); if (err/=0) then; err=20; return; end if - - ! initialize the number of HRUs - nHRU_file=integerMissing - nGRU_file=integerMissing - - ! get the length of the dimensions - do idimid=1,nDims - ! get the dimension name and length - err=nf90_inquire_dimension(ncid, idimid, name=dimName, len=dimLength) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if - ! get the number of HRUs - if(trim(dimName)=='hru') nHRU_file=dimLength - if(trim(dimName)=='gru') nGRU_file=dimLength - end do - - ! allocate hruID vector - allocate(hruId(nHRU_file)) - - ! check HRU dimension exists - if(nHRU_file==integerMissing)then - message=trim(message)//'unable to identify HRU dimension in file '//trim(infile) - err=20; return - endif - -! check have the correct number of HRUs -! if ((irunMode==irunModeFull).and.(nHRU_file/=nHRU)) then -! message=trim(message)//'incorrect number of HRUs in file '//trim(infile) -! err=20; return -! endif -! if ((irunMode==irunModeHRU).and.(nHRU_file<checkHRU)) then -! message=trim(message)//'not enough HRUs in file '//trim(infile) -! err=20; return -! endif - -! ! check have the correct number of GRUs -! if ((irunMode==irunModeGRU).and.(nGRU_file<startGRU).and.(nGRU_file/=integerMissing)) then -! message=trim(message)//'not enough GRUs in file '//trim(infile) -! err=20; return -! endif -! if ((irunMode==irunModeFull).and.(nGRU_file/=nGRU).and.(nGRU_file/=integerMissing)) then -! message=trim(message)//'incorrect number of GRUs in file '//trim(infile) -! err=20; return -! endif - - ! ********************************************************************************************** - ! * read the HRU index - ! ********************************************************************************************** - - ! loop through the parameters in the NetCDF file - do ivarid=1,nVars - - ! get the parameter name - err=nf90_inquire_variable(ncid, ivarid, name=parName) - call netcdf_err(err,message); if (err/=0) then; err=20; return; end if - - ! special case of the HRU id - if(trim(parName)=='hruIndex' .or. trim(parName)=='hruId')then - - ! read HRUs - err=nf90_get_var(ncid, ivarid, hruId) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if - - ! check HRUs -- expect HRUs to be in the same order as the local attributes -! if (iRunMode==iRunModeFull) then -! !iGRU=index_map(indxHRU)%gru_ix -! localHRU_ix=index_map(indxHRU)%localHRU_ix -! if((hruId(indxHRU)>0).and.(hruId(indxHRU)/=idStruct%var(iLookID%hruId)))then -! write(message,'(a,i0,a,i0,a)') trim(message)//'mismatch for HRU ', idStruct%var(iLookID%hruId), '(param HRU = ', hruId(indxHRU), ')' -! err=20; return -! endif - -! else if (iRunMode==iRunModeGRU) then -! ! do iHRU=1,nHRU -! !iGRU=index_map(indxHRU)%gru_ix -! localHRU_ix=index_map(indxHRU)%localHRU_ix -! fHRU = gru_struc(indxGRU)%hruInfo(localHRU_ix)%hru_nc -! if(hruId(fHRU)/=idStruct%var(iLookID%hruId))then -! write(message,'(a,i0,a,i0,a)') trim(message)//'mismatch for HRU ', idStruct%var(iLookID%hruId), '(param HRU = ', hruId(indxHRU), ')' -! err=20; return -! endif -! ! enddo - -! else if (iRunMode==iRunModeHRU) then -! !iGRU=index_map(1)%gru_ix -! localHRU_ix=index_map(indxHRU)%localHRU_ix -! if(hruId(checkHRU)/=idStruct%var(iLookID%hruId))then -! write(message,'(a,i0,a,i0,a)') trim(message)//'mismatch for HRU ', idStruct%var(iLookID%hruId), '(param HRU = ', hruId(indxHRU), ')' -! err=20; return -! endif - - ! error check -! else -! err = 20; message = 'run mode not recognized'; return; -! end if - - endif ! if the HRU id - - end do ! looping through variables in the file - - ! ********************************************************************************************** - ! * read the local parameters and the basin parameters - ! ********************************************************************************************** - - ! loop through the parameters in the NetCDF file - do ivarid=1,nVars - - ! get the parameter name - err=nf90_inquire_variable(ncid, ivarid, name=parName) - call netcdf_err(err,message); if (err/=0) then; err=20; return; end if - - ! get the local parameters - ixParam = get_ixparam( trim(parName) ) - if(ixParam/=integerMissing)then - - ! ********************************************************************************************** - ! * read the local parameters - ! ********************************************************************************************** - - ! get the variable shape - err=nf90_inquire_variable(ncid, ivarid, nDims=nDims, dimids=idim_list) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if - - ! get the length of the depth dimension (if it exists) - if(nDims==2)then - - ! get the information on the 2nd dimension for 2-d variables - err=nf90_inquire_dimension(ncid, idim_list(2), dimName, nSoil_file) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if - - ! check that it is the depth dimension - if(trim(dimName)/='depth')then - message=trim(message)//'expect 2nd dimension of 2-d variable to be depth (dimension name = '//trim(dimName)//')' - err=20; return - endif - - ! check that the dimension length is correct - if(size(mparStruct%var(ixParam)%dat) /= nSoil_file)then - message=trim(message)//'unexpected number of soil layers in parameter file' - err=20; return - endif - - ! define parameter length - parLength = nSoil_file - - else - parLength = 1 - endif ! if two dimensions - - ! allocate space for model parameters - allocate(parVector(parLength),stat=err) - if(err/=0)then - message=trim(message)//'problem allocating space for parameter vector' - err=20; return - endif - - ! map to the GRUs and HRUs - !iGRU=index_map(indxHRU)%gru_ix - localHRU_ix=index_map(indxHRU)%localHRU_ix - fHRU = gru_struc(indxGRU)%hruInfo(localHRU_ix)%hru_nc - - ! read parameter data - select case(nDims) - case(1); err=nf90_get_var(ncid, ivarid, parVector, start=(/fHRU/), count=(/1/) ) - case(2); err=nf90_get_var(ncid, ivarid, parVector, start=(/fHRU,1/), count=(/1,nSoil_file/) ) - case default; err=20; message=trim(message)//'unexpected number of dimensions for parameter '//trim(parName) - end select - - ! error check for the parameter read - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if - - ! populate parameter structures - select case(nDims) - case(1); mparStruct%var(ixParam)%dat(:) = parVector(1) ! also distributes scalar across depth dimension - case(2); mparStruct%var(ixParam)%dat(:) = parVector(:) - case default; err=20; message=trim(message)//'unexpected number of dimensions for parameter '//trim(parName) - end select - - ! end do ! looping through HRUs - - ! deallocate space for model parameters - deallocate(parVector,stat=err) - if(err/=0)then - message=trim(message)//'problem deallocating space for parameter vector' - err=20; return - endif - - ! ********************************************************************************************** - ! * read the basin parameters - ! ********************************************************************************************** - - ! get the basin parameters - else - - ! get the parameter index - ixParam = get_ixbpar( trim(parName) ) - - ! allow extra variables in the file that are not used - if(ixParam==integerMissing) cycle - - ! allocate space for model parameters - allocate(parVector(nGRU_file),stat=err) - if(err/=0)then - message=trim(message)//'problem allocating space for parameter vector' - err=20; return - endif - - ! read parameter data - err=nf90_get_var(ncid, ivarid, parVector ) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if +! ************************************************************************************************ +! public subroutine read_param4chm: read trial model parameter values +! ************************************************************************************************ +subroutine read_param(indxHRU,indxGRU,mparStruct,bparStruct,dparStruct,err) + USE globalData,only:outputStructure + USE globalData,only:mpar_meta,bpar_meta + USE globalData,only:localParFallback ! local column default parameters + + implicit none + ! define input + integer(i4b),intent(in) :: indxHRU + integer(i4b),intent(in) :: indxGRU + ! define output + type(var_dlength),intent(inout) :: mparStruct ! model parameters + type(var_d),intent(inout) :: bparStruct ! basin parameters + type(var_d),intent(inout) :: dparStruct ! default model parameters + integer(i4b),intent(out) :: err ! error code + ! + character(len=256) :: message ! error message + integer(i4b) :: iVar ! + + ! Start procedure here + err=0; message="read_paramActors.f90/" + ! do iVar=1, size(mpar_meta) + dparStruct%var(:) = outputStructure(1)%dparStruct(1)%gru(indxGRU)%hru(indxHRU)%var(:) + ! end do + + ! do iVar=1, size(localParFallback) + ! mparStruct%var(iVar)%dat(:) = dparStruct%var(iVar) + ! end do ! populate parameter structures - if (iRunMode==iRunModeGRU) then - !do iGRU=1,nGRU - bparStruct%var(ixParam) = parVector(indxGRU+startGRU-1) - !end do ! looping through GRUs - else if (iRunMode==iRunModeFull) then - !do iGRU=1,nGRU - bparStruct%var(ixParam) = parVector(indxGRU) - !end do ! looping through GRUs - else if (iRunMode==iRunModeHRU) then - err = 20; message='checkHRU run mode not working'; return; - endif - - ! deallocate space for model parameters - deallocate(parVector,stat=err) - if(err/=0)then - message=trim(message)//'problem deallocating space for parameter vector' - err=20; return - endif - - endif ! reading the basin parameters - - end do ! (looping through the parameters in the NetCDF file) + do iVar=1, size(mpar_meta) + mparStruct%var(iVar)%dat(:) = outputStructure(1)%mparStruct(1)%gru(indxGRU)%hru(indxHRU)%var(iVar)%dat(:) + end do - ! Now we must close the netcdf file - call nc_file_close(ncid,err,message) - if(err/=0)then;message=trim(message)//trim(cmessage);return;end if + do iVar=1, size(bpar_meta) + bparStruct%var(iVar) = outputStructure(1)%bparStruct(1)%gru(indxGRU)%var(iVar) + end do - end subroutine read_param4chm + end subroutine read_param end module read_param4chm_module diff --git a/build/source/hookup/summaActors_FileManager.f90 b/build/source/hookup/summaActors_FileManager.f90 index 041984fe422944b5a5fa490df1c25571f8195614..07d202e7db107e7c1b87ec49294e339cb6fccddf 100755 --- a/build/source/hookup/summaActors_FileManager.f90 +++ b/build/source/hookup/summaActors_FileManager.f90 @@ -23,77 +23,91 @@ ! (C) Copyright 2009-2010 --- Dmitri Kavetski and Martyn Clark --- All rights reserved !****************************************************************** MODULE summaActors_FileManager -use nrtype -implicit none -public -! summa-wide pathlength -integer(i4b),parameter :: summaPathLen=4096 -! defines the time of the run -CHARACTER(LEN=summaPathLen) :: CONTROL_VRS = 'SUMMA_FILE_MANAGER_V3.0.0' ! control version -CHARACTER(LEN=summaPathLen) :: SIM_START_TM = '2000-01-01 00:00' ! simulation start time -CHARACTER(LEN=summaPathLen) :: SIM_END_TM = '2000-01-01 00:00' ! simulation end time -CHARACTER(LEN=summaPathLen) :: NC_TIME_ZONE = 'utcTime' ! time zone info -! defines the path for data files (and default values) -CHARACTER(LEN=summaPathLen) :: SETTINGS_PATH = 'settings/' ! settings dir path -CHARACTER(LEN=summaPathLen) :: STATE_PATH = '' ! state file / init. cond. dir path (if omitted, defaults - ! to SETTINGS_PATH for input, OUTPATH for output) -CHARACTER(LEN=summaPathLen) :: FORCING_PATH = 'forcing/default/' ! input_dir_path -CHARACTER(LEN=summaPathLen) :: OUTPUT_PATH = 'output/default/' ! output_dir_path -CHARACTER(LEN=summaPathLen) :: FORCING_FREQ = 'month' ! Frequency of forcing files (input) -CHARACTER(LEN=summaPathLen) :: FORCING_START = '2000-01-01' ! Number of Forcing Files -! define name of control files (and default values) -CHARACTER(LEN=summaPathLen) :: M_DECISIONS = 'summa_zDecisions.txt' ! definition of model decisions -CHARACTER(LEN=summaPathLen) :: OUTPUT_CONTROL = 'summa_zLocalModelVarMeta.txt' ! metadata for model variables -CHARACTER(LEN=summaPathLen) :: LOCAL_ATTRIBUTES = 'summa_zLocalAttributes.txt' ! local attributes -CHARACTER(LEN=summaPathLen) :: LOCALPARAM_INFO = 'summa_zLocalParamInfo.txt' ! default values and constraints for local model parameters -CHARACTER(LEN=summaPathLen) :: BASINPARAM_INFO = 'summa_zBasinParamInfo.txt' ! default values and constraints for basin model parameters -CHARACTER(LEN=summaPathLen) :: VEGPARM = 'VEGPARM.TBL' ! noah vegetation parameter table -CHARACTER(LEN=summaPathLen) :: SOILPARM = 'SOILPARM.TBL' ! noah soil parameter table -CHARACTER(LEN=summaPathLen) :: GENPARM = 'GENPARM.TBL' ! noah general parameter table -CHARACTER(LEN=summaPathLen) :: MPTABLE = 'MPTABLE.TBL' ! noah mp parameter table -CHARACTER(LEN=summaPathLen) :: FORCING_FILELIST = 'summa_zForcingFileList.txt' ! list of focing files for each HRU -CHARACTER(LEN=summaPathLen) :: MODEL_INITCOND = 'summa_zInitialCond.txt' ! model initial conditions -CHARACTER(LEN=summaPathLen) :: PARAMETER_TRIAL = 'summa_zParamTrial.txt' ! trial values for model parameters -CHARACTER(LEN=summaPathLen) :: OUTPUT_PREFIX = 'summa_output_' ! prefix for the output file - -contains + USE, intrinsic :: iso_c_binding + use nrtype + implicit none + public + ! summa-wide pathlength + integer(i4b),parameter :: summaPathLen=4096 + ! defines the time of the run + CHARACTER(LEN=summaPathLen) :: CONTROL_VRS = 'SUMMA_FILE_MANAGER_V3.0.0' ! control version + CHARACTER(LEN=summaPathLen) :: SIM_START_TM = '2000-01-01 00:00' ! simulation start time + CHARACTER(LEN=summaPathLen) :: SIM_END_TM = '2000-01-01 00:00' ! simulation end time + CHARACTER(LEN=summaPathLen) :: NC_TIME_ZONE = 'utcTime' ! time zone info + ! defines the path for data files (and default values) + CHARACTER(LEN=summaPathLen) :: SETTINGS_PATH = 'settings/' ! settings dir path + CHARACTER(LEN=summaPathLen) :: STATE_PATH = '' ! state file / init. cond. dir path (if omitted, defaults + ! to SETTINGS_PATH for input, OUTPATH for output) + CHARACTER(LEN=summaPathLen) :: FORCING_PATH = 'forcing/default/' ! input_dir_path + CHARACTER(LEN=summaPathLen) :: OUTPUT_PATH = 'output/default/' ! output_dir_path + CHARACTER(LEN=summaPathLen) :: FORCING_FREQ = 'month' ! Frequency of forcing files (input) + CHARACTER(LEN=summaPathLen) :: FORCING_START = '2000-01-01' ! Number of Forcing Files + ! define name of control files (and default values) + CHARACTER(LEN=summaPathLen) :: M_DECISIONS = 'summa_zDecisions.txt' ! definition of model decisions + CHARACTER(LEN=summaPathLen) :: OUTPUT_CONTROL = 'summa_zLocalModelVarMeta.txt' ! metadata for model variables + CHARACTER(LEN=summaPathLen) :: LOCAL_ATTRIBUTES = 'summa_zLocalAttributes.txt' ! local attributes + CHARACTER(LEN=summaPathLen) :: LOCALPARAM_INFO = 'summa_zLocalParamInfo.txt' ! default values and constraints for local model parameters + CHARACTER(LEN=summaPathLen) :: BASINPARAM_INFO = 'summa_zBasinParamInfo.txt' ! default values and constraints for basin model parameters + CHARACTER(LEN=summaPathLen) :: VEGPARM = 'VEGPARM.TBL' ! noah vegetation parameter table + CHARACTER(LEN=summaPathLen) :: SOILPARM = 'SOILPARM.TBL' ! noah soil parameter table + CHARACTER(LEN=summaPathLen) :: GENPARM = 'GENPARM.TBL' ! noah general parameter table + CHARACTER(LEN=summaPathLen) :: MPTABLE = 'MPTABLE.TBL' ! noah mp parameter table + CHARACTER(LEN=summaPathLen) :: FORCING_FILELIST = 'summa_zForcingFileList.txt' ! list of focing files for each HRU + CHARACTER(LEN=summaPathLen) :: MODEL_INITCOND = 'summa_zInitialCond.txt' ! model initial conditions + CHARACTER(LEN=summaPathLen) :: PARAMETER_TRIAL = 'summa_zParamTrial.txt' ! trial values for model parameters + CHARACTER(LEN=summaPathLen) :: OUTPUT_PREFIX = 'summa_output_' ! prefix for the output file + + contains ! ************************************************************************************************** ! public subroutine summa_SetTimesDirsAndFiles: Sets times, directories and filenames for summa run ! ************************************************************************************************** -subroutine summa_SetTimesDirsAndFiles(summaFileManagerIn,err,message) +subroutine summa_SetTimesDirsAndFiles(file_manager,err) bind(C, name="setTimesDirsAndFiles") ! Purpose: Sets run times, directories and filenames for summa. ! --- USE ascii_util_module,only:file_open ! function to open file USE ascii_util_module,only:linewidth ! max character number for one line USE ascii_util_module,only:get_vlines ! function to get a vector of non-comment lines + USE cppwrap_auxiliary,only:c_f_string + + implicit none ! input/output vars - character(*),intent(in) :: summaFileManagerIn - integer(i4b),intent(out) :: err - character(*),intent(out) :: message + character(kind=c_char,len=1),intent(in) :: file_manager + integer(c_int),intent(out) :: err ! local vars - character(*),parameter :: summaFileManagerHeader='SUMMA_FILE_MANAGER_V3.0.0' - integer(i4b),parameter :: runinfo_fileunit=67 ! file unit for run time information - character(len=8) :: cdate - character(len=10) :: ctime - character(len=256) :: cmessage ! error message for downwind routine - integer(i4b) :: unt ! file unit (free unit output from file_open) - character(LEN=linewidth),allocatable :: charline(:) ! vector of character strings - integer(i4b) :: iControl, nControl ! number of model info - character(len=summaPathLen) :: varEntry ! name of model info - character(len=32) :: option ! option for model info + character(len=256) :: summaFileManagerIn + character(len=256) :: message + character(*),parameter :: summaFileManagerHeader='SUMMA_FILE_MANAGER_V3.0.0' + integer(i4b),parameter :: runinfo_fileunit=67 ! file unit for run time information + character(len=8) :: cdate + character(len=10) :: ctime + character(len=256) :: cmessage ! error message for downwind routine + integer(i4b) :: unt ! file unit (free unit output from file_open) + character(LEN=linewidth),allocatable :: charline(:) ! vector of character strings + integer(i4b) :: iControl, nControl ! number of model info + character(len=summaPathLen) :: varEntry ! name of model info + character(len=32) :: option ! option for model info err=0; message="summa_SetTimesDirsAndFiles/" + call c_f_string(file_manager, summaFileManagerIn, 256) + summaFileManagerIn = trim(summaFileManagerIn) + + ! read information from model control file, and populate model control structure ! populates global control information structure ! open file, read non-comment lines, close file call file_open(trim(summaFileManagerIn),unt,err,cmessage) - if(err/=0) then; message=trim(message)//trim(cmessage)//"/Failed to open control file [''"//trim(summaFileManagerIn)//"']"; err=-10; return; end if + if(err/=0) then + message=trim(message)//trim(cmessage)//"/Failed to open control file [''"//trim(summaFileManagerIn)//"']" + print*, message + err=-10 + return + end if call get_vlines(unt,charline,err,cmessage) ! 'charline' is a list of strings from non-comment lines if(err/=0) then; message=trim(message)//trim(cmessage)//"/Control file read issue in get_vlines()"; return; end if close(unt) diff --git a/build/source/netcdf/def_output.f90 b/build/source/netcdf/def_output.f90 index 59a6cae5264e43e22e8643c23ec79a2690f82b06..f4859f7c3b06243265bfd4e1845270dd503dcfdf 100755 --- a/build/source/netcdf/def_output.f90 +++ b/build/source/netcdf/def_output.f90 @@ -154,7 +154,11 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp do iFreq=1,maxvarFreq if (ncid%var(iFreq)/=integerMissing) then call nc_file_close(ncid%var(iFreq),err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if endif end do @@ -171,39 +175,58 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp fstring = get_freqName(iFreq) fname = trim(fileout)//'_'//trim(fstring)//'.nc' call ini_create(nGRU,nHRU,gru_struc(1)%hruInfo(1)%nSoil,trim(fname),ncid%var(iFreq),err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if ! define model decisions do iVar = 1,size(model_decisions) if(model_decisions(iVar)%iDecision.ne.integerMissing)then call put_attrib(ncid%var(iFreq),model_decisions(iVar)%cOption,model_decisions(iVar)%cDecision,err,cmessage) - if(err/=0)then; message=trim(message)//trim(cmessage); return; end if + if(err/=0)then + message=trim(message)//trim(cmessage) + print*, message + return + end if end if end do ! define variables do iStruct = 1,size(structInfo) select case (trim(structInfo(iStruct)%structName)) - case('attr' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,attr_meta, outputPrecision, err,cmessage) ! local attributes HRU - case('type' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,type_meta, nf90_int, err,cmessage) ! local classification - case('mpar' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,mpar_meta, outputPrecision, err,cmessage) ! model parameters - case('bpar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU, noTime,bpar_meta, outputPrecision, err,cmessage) ! basin-average param - case('indx' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,indx_meta, nf90_int, err,cmessage) ! model variables - case('deriv'); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,deriv_meta,outputPrecision, err,cmessage) ! model derivatives - case('time' ); call def_variab(ncid%var(iFreq),iFreq, noHRU,needTime,time_meta, nf90_int, err,cmessage) ! model derivatives - case('forc' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,forc_meta, outputPrecision, err,cmessage) ! model forcing data - case('prog' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,prog_meta, outputPrecision, err,cmessage) ! model prognostics - case('diag' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,diag_meta, outputPrecision, err,cmessage) ! model diagnostic variables - case('flux' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,flux_meta, outputPrecision, err,cmessage) ! model fluxes - case('bvar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU,needTime,bvar_meta, outputPrecision, err,cmessage) ! basin-average variables - case('id' ); cycle ! ids -- see write_hru_info() + case('attr' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,attr_meta, outputPrecision, err,cmessage) ! local attributes HRU + case('type' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,type_meta, nf90_int, err,cmessage) ! local classification + case('mpar' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,mpar_meta, outputPrecision, err,cmessage) ! model parameters + case('bpar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU, noTime,bpar_meta, outputPrecision, err,cmessage) ! basin-average param + case('indx' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,indx_meta, nf90_int, err,cmessage) ! model variables + case('deriv' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,deriv_meta,outputPrecision, err,cmessage) ! model derivatives + case('time' ); call def_variab(ncid%var(iFreq),iFreq, noHRU,needTime,time_meta, nf90_int, err,cmessage) ! model derivatives + case('forc' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,forc_meta, outputPrecision, err,cmessage) ! model forcing data + case('prog' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,prog_meta, outputPrecision, err,cmessage) ! model prognostics + case('diag' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,diag_meta, outputPrecision, err,cmessage) ! model diagnostic variables + case('flux' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,flux_meta, outputPrecision, err,cmessage) ! model fluxes + case('bvar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU,needTime,bvar_meta, outputPrecision, err,cmessage) ! basin-average variables + case('id' ); cycle + case('lookup'); cycle ! ids -- see write_hru_info() case default; err=20; message=trim(message)//'unable to identify lookup structure'; end select ! error handling - if(err/=0)then;err=20;message=trim(message)//trim(cmessage)//'[structure = '//trim(structInfo(iStruct)%structName);return;end if + if(err/=0)then + err=20 + message=trim(message)//trim(cmessage)//'[structure = '//trim(structInfo(iStruct)%structName) + print*, message + return + end if end do ! iStruct ! write HRU dimension and ID for each output file - call write_hru_info(ncid%var(iFreq), err, cmessage); if(err/=0) then; message=trim(message)//trim(cmessage); return; end if + call write_hru_info(ncid%var(iFreq), err, cmessage) + if(err/=0) then + message=trim(message)//trim(cmessage) + print*, message + return + end if end do end subroutine def_output diff --git a/build/source/netcdf/read_icondActors.f90 b/build/source/netcdf/read_icondActors.f90 index c0560a0c28605eabf2e437dbdaa8cc19440e97e4..52bf5a11ac741436c5cd62f011f63b6641abac8a 100644 --- a/build/source/netcdf/read_icondActors.f90 +++ b/build/source/netcdf/read_icondActors.f90 @@ -19,6 +19,7 @@ ! along with this program. If not, see <http://www.gnu.org/licenses/>. module read_icond4chm_module +USE, intrinsic :: iso_c_binding USE nrtype USE netcdf USE globalData,only: ixHRUfile_min,ixHRUfile_max @@ -36,104 +37,120 @@ contains ! ************************************************************************************************ ! public subroutine read_icond_nlayers: read model initial conditions file for number of snow/soil layers ! ************************************************************************************************ - subroutine read_icond_nlayers(iconFile,nGRU,indx_meta,err,message) - ! -------------------------------------------------------------------------------------------------------- - ! modules - USE nrtype - USE var_lookup,only:iLookIndex ! variable lookup structure - USE globalData,only:gru_struc ! gru-hru mapping structures - USE netcdf_util_module,only:nc_file_close ! close netcdf file - USE netcdf_util_module,only:nc_file_open ! close netcdf file - USE netcdf_util_module,only:netcdf_err ! netcdf error handling - USE data_types,only:gru_hru_intVec ! actual data - USE data_types,only:var_info ! metadata - implicit none - - ! -------------------------------------------------------------------------------------------------------- - ! variable declarations - ! dummies - character(*) ,intent(in) :: iconFile ! name of input (restart) file - integer(i4b) ,intent(in) :: nGRU ! total # of GRUs in run domain - type(var_info) ,intent(in) :: indx_meta(:) ! metadata - integer(i4b) ,intent(out) :: err ! error code - character(*) ,intent(out) :: message ! returned error message - - ! locals - integer(i4b) :: ncID ! netcdf file id - integer(i4b) :: dimID ! netcdf file dimension id - integer(i4b) :: fileHRU ! number of HRUs in netcdf file - integer(i4b) :: snowID, soilID ! netcdf variable ids - integer(i4b) :: iGRU, iHRU ! loop indexes - integer(i4b) :: iHRU_global ! index of HRU in the netcdf file - integer(i4b),allocatable :: snowData(:) ! number of snow layers in all HRUs - integer(i4b),allocatable :: soilData(:) ! number of soil layers in all HRUs - character(len=256) :: cmessage ! downstream error message - - ! -------------------------------------------------------------------------------------------------------- - ! initialize error message - err=0 - message = 'read_icond_nlayers/' - - ! open netcdf file - call nc_file_open(iconFile,nf90_nowrite,ncid,err,cmessage); - if (err/=0) then; message=trim(message)//trim(cmessage); return; end if - - - ! get number of HRUs in file (the GRU variable(s), if present, are processed at the end) - err = nf90_inq_dimid(ncID,"hru",dimId); if(err/=nf90_noerr)then; message=trim(message)//'problem finding hru dimension/'//trim(nf90_strerror(err)); return; end if - err = nf90_inquire_dimension(ncID,dimId,len=fileHRU); if(err/=nf90_noerr)then; message=trim(message)//'problem reading hru dimension/'//trim(nf90_strerror(err)); return; end if - - ! allocate storage for reading from file (allocate entire file size, even when doing subdomain run) - allocate(snowData(fileHRU)) - allocate(soilData(fileHRU)) - snowData = 0 - soilData = 0 - - ! get netcdf ids for the variables holding number of snow and soil layers in each hru - err = nf90_inq_varid(ncid,trim(indx_meta(iLookIndex%nSnow)%varName),snowid); call netcdf_err(err,message) - err = nf90_inq_varid(ncid,trim(indx_meta(iLookIndex%nSoil)%varName),soilid); call netcdf_err(err,message) - - ! get nSnow and nSoil data (reads entire state file) - err = nf90_get_var(ncid,snowid,snowData); call netcdf_err(err,message) - err = nf90_get_var(ncid,soilid,soilData); call netcdf_err(err,message) - - ixHRUfile_min=huge(1) - ixHRUfile_max=0 - ! find the min and max hru indices in the state file - do iGRU = 1,nGRU - do iHRU = 1,gru_struc(iGRU)%hruCount - if(gru_struc(iGRU)%hruInfo(iHRU)%hru_nc < ixHRUfile_min) ixHRUfile_min = gru_struc(iGRU)%hruInfo(iHRU)%hru_nc - if(gru_struc(iGRU)%hruInfo(iHRU)%hru_nc > ixHRUfile_max) ixHRUfile_max = gru_struc(iGRU)%hruInfo(iHRU)%hru_nc - end do - end do - - - ! loop over grus in current run to update snow/soil layer information - do iGRU = 1,nGRU - do iHRU = 1,gru_struc(iGRU)%hruCount - iHRU_global = gru_struc(iGRU)%hruInfo(iHRU)%hru_nc - - ! single HRU (Note: 'restartFileType' is hardwired above to multiHRU) - if(restartFileType==singleHRU) then - gru_struc(iGRU)%hruInfo(iHRU)%nSnow = snowData(1) - gru_struc(iGRU)%hruInfo(iHRU)%nSoil = soilData(1) - - ! multi HRU - else - gru_struc(iGRU)%hruInfo(iHRU)%nSnow = snowData(iHRU_global) - gru_struc(iGRU)%hruInfo(iHRU)%nSoil = soilData(iHRU_global) - endif - - end do - end do - - - ! close file - call nc_file_close(ncid,err,cmessage) - if(err/=0)then;message=trim(message)//trim(cmessage);return;end if - - ! cleanup - deallocate(snowData,soilData) +subroutine read_icond_nlayers(nGRU,err) bind(C, name="readIcondNLayers") + ! -------------------------------------------------------------------------------------------------------- + ! modules + USE nrtype + USE var_lookup,only:iLookIndex ! variable lookup structure + USE globalData,only:gru_struc ! gru-hru mapping structures + USE netcdf_util_module,only:nc_file_close ! close netcdf file + USE netcdf_util_module,only:nc_file_open ! close netcdf file + USE netcdf_util_module,only:netcdf_err ! netcdf error handling + USE data_types,only:gru_hru_intVec ! actual data + USE data_types,only:var_info ! metadata + + USE globalData,only:indx_meta + + ! file paths + USE summaActors_FileManager,only:STATE_PATH ! optional path to state/init. condition files (defaults to SETTINGS_PATH) + USE summaActors_FileManager,only:SETTINGS_PATH ! define path to settings files (e.g., parameters, soil and veg. tables) + USE summaActors_FileManager,only:MODEL_INITCOND ! name of model initial conditions file + + implicit none + + ! -------------------------------------------------------------------------------------------------------- + ! variable declarations + ! dummies + integer(c_int) ,intent(in) :: nGRU ! total # of GRUs in run domain + integer(c_int) ,intent(out) :: err ! error code + + ! locals + integer(i4b) :: ncID ! netcdf file id + integer(i4b) :: dimID ! netcdf file dimension id + integer(i4b) :: fileHRU ! number of HRUs in netcdf file + integer(i4b) :: snowID, soilID ! netcdf variable ids + integer(i4b) :: iGRU, iHRU ! loop indexes + integer(i4b) :: iHRU_global ! index of HRU in the netcdf file + integer(i4b),allocatable :: snowData(:) ! number of snow layers in all HRUs + integer(i4b),allocatable :: soilData(:) ! number of soil layers in all HRUs + + character(len=256) :: iconFile ! restart file name + + + character(len=256) :: message ! returned error message + character(len=256) :: cmessage ! downstream error message + + ! -------------------------------------------------------------------------------------------------------- + ! initialize error message + err=0 + message = 'read_icond_nlayers/' + + if(STATE_PATH == '') then + iconFile = trim(SETTINGS_PATH)//trim(MODEL_INITCOND) + else + iconFile = trim(STATE_PATH)//trim(MODEL_INITCOND) + endif + + ! open netcdf file + call nc_file_open(iconFile,nf90_nowrite,ncid,err,cmessage); + if (err/=0) then; message=trim(message)//trim(cmessage); return; end if + + + ! get number of HRUs in file (the GRU variable(s), if present, are processed at the end) + err = nf90_inq_dimid(ncID,"hru",dimId); if(err/=nf90_noerr)then; message=trim(message)//'problem finding hru dimension/'//trim(nf90_strerror(err)); return; end if + err = nf90_inquire_dimension(ncID,dimId,len=fileHRU); if(err/=nf90_noerr)then; message=trim(message)//'problem reading hru dimension/'//trim(nf90_strerror(err)); return; end if + + ! allocate storage for reading from file (allocate entire file size, even when doing subdomain run) + allocate(snowData(fileHRU)) + allocate(soilData(fileHRU)) + snowData = 0 + soilData = 0 + + ! get netcdf ids for the variables holding number of snow and soil layers in each hru + err = nf90_inq_varid(ncid,trim(indx_meta(iLookIndex%nSnow)%varName),snowid); call netcdf_err(err,message) + err = nf90_inq_varid(ncid,trim(indx_meta(iLookIndex%nSoil)%varName),soilid); call netcdf_err(err,message) + + ! get nSnow and nSoil data (reads entire state file) + err = nf90_get_var(ncid,snowid,snowData); call netcdf_err(err,message) + err = nf90_get_var(ncid,soilid,soilData); call netcdf_err(err,message) + + ixHRUfile_min=huge(1) + ixHRUfile_max=0 + ! find the min and max hru indices in the state file + do iGRU = 1,nGRU + do iHRU = 1,gru_struc(iGRU)%hruCount + if(gru_struc(iGRU)%hruInfo(iHRU)%hru_nc < ixHRUfile_min) ixHRUfile_min = gru_struc(iGRU)%hruInfo(iHRU)%hru_nc + if(gru_struc(iGRU)%hruInfo(iHRU)%hru_nc > ixHRUfile_max) ixHRUfile_max = gru_struc(iGRU)%hruInfo(iHRU)%hru_nc + end do + end do + + + ! loop over grus in current run to update snow/soil layer information + do iGRU = 1,nGRU + do iHRU = 1,gru_struc(iGRU)%hruCount + iHRU_global = gru_struc(iGRU)%hruInfo(iHRU)%hru_nc + + ! single HRU (Note: 'restartFileType' is hardwired above to multiHRU) + if(restartFileType==singleHRU) then + gru_struc(iGRU)%hruInfo(iHRU)%nSnow = snowData(1) + gru_struc(iGRU)%hruInfo(iHRU)%nSoil = soilData(1) + + ! multi HRU + else + gru_struc(iGRU)%hruInfo(iHRU)%nSnow = snowData(iHRU_global) + gru_struc(iGRU)%hruInfo(iHRU)%nSoil = soilData(iHRU_global) + endif + + end do + end do + + + ! close file + call nc_file_close(ncid,err,cmessage) + if(err/=0)then;message=trim(message)//trim(cmessage);return;end if + + ! cleanup + deallocate(snowData,soilData) end subroutine read_icond_nlayers diff --git a/build/source/netcdf/writeOutput.f90 b/build/source/netcdf/writeOutput.f90 index 3b7ce4951b311a082601b4fbcb0f5c3cb5b73c35..5eb8af2cfb71dae6be6fc0bca01d68bcce36c89b 100644 --- a/build/source/netcdf/writeOutput.f90 +++ b/build/source/netcdf/writeOutput.f90 @@ -247,7 +247,7 @@ subroutine writeData(ncid,outputTimestep,outputTimestepUpdate,maxLayers,nSteps, if(meta(iVar)%varType==iLookVarType%scalarv) then call writeScalar(ncid, outputTimeStep, outputTimeStepUpdate, nSteps, minGRU, maxGRU, numGRU, iFreq, iVar, meta, stat, map, err, message) else ! non-scalar variables: regular data structures - call writeVector(ncid, outputTimeStep, outputTimeStepUpdate, maxLayers, nSteps, minGRU, maxGRU, numGRU, iFreq, iVar, meta, dat, & + call writeVector(ncid, outputTimeStep, maxLayers, nSteps, minGRU, maxGRU, numGRU, iFreq, iVar, meta, dat, & indx, err, message) end if ! not scalarv @@ -317,7 +317,7 @@ subroutine writeScalar(ncid, outputTimestep, outputTimestepUpdate, nSteps, minGR end subroutine -subroutine writeVector(ncid, outputTimestep, outputTimestepUpdate, maxLayers, nSteps, minGRU, maxGRU, & +subroutine writeVector(ncid, outputTimestep, maxLayers, nSteps, minGRU, maxGRU, & numGRU, iFreq, iVar, meta, dat, indx, err, message) USE data_types,only:var_info ! metadata type USE var_lookup,only:iLookIndex ! index into index structure @@ -326,7 +326,6 @@ subroutine writeVector(ncid, outputTimestep, outputTimestepUpdate, maxLayers, nS implicit none type(var_i) ,intent(in) :: ncid ! fileid integer(i4b) ,intent(inout) :: outputTimestep(:) ! output time step - integer(i4b) ,intent(inout) :: outputTimestepUpdate(:) ! number of HRUs in the run domain integer(i4b) ,intent(in) :: maxLayers ! maximum number of layers integer(i4b) ,intent(in) :: nSteps ! number of timeSteps integer(i4b) ,intent(in) :: minGRU ! minGRU index to write @@ -434,12 +433,6 @@ subroutine writeVector(ncid, outputTimestep, outputTimestepUpdate, maxLayers, nS end select ! data type stepCounter = stepCounter + 1 end do ! iStep - ! if (outputTimeStepUpdate(iFreq) /= stepCounter ) then - ! print*, "ERROR Missmatch in Steps: for non scalar case" - ! print*, " outputTimeStepUpdate(iFreq) = ", outputTimeStepUpdate(iFreq) - ! print*, " stepCounter = ", stepCounter - ! return - ! endif end subroutine ! ************************************************************************************** diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..69fe55ecfa9aade66e1412aef0ee7d04a9bcde86 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/actors.md b/docs/actors.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..543c6b13b473ff3c586d5d97ae418d267ee795c4 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/modules.rst b/docs/modules.rst new file mode 100644 index 0000000000000000000000000000000000000000..52eef36cb8c37aa7a99fda47ed13f97e8aa31153 --- /dev/null +++ b/docs/modules.rst @@ -0,0 +1,6 @@ +Summa-Actors +============ + +.. toctree:: + :maxdepth: 4 + diff --git a/docs/SUMMA-Actors_documentation.md b/docs/source/SUMMA-Actors.md similarity index 90% rename from docs/SUMMA-Actors_documentation.md rename to docs/source/SUMMA-Actors.md index a62bb59b123f469bab4aa1dbbe5eb57e54ef4c11..d3658a9d166cbd1ecf9f908f49a7bfaba4d24650 100644 --- a/docs/SUMMA-Actors_documentation.md +++ b/docs/source/SUMMA-Actors.md @@ -3,4 +3,6 @@ SUMMA-Actors is a beta software that currently does not have the full capabilities of the original version of SUMMA. The most notable feature not currently implemented is the simulation of lateral flows. SUMMA-Actors can solve for HRUs that do not have any dependencies on other HRUs. Although we are working to implement the full functionality of SUMMA into SUMMA-Actors. -The documentation is organized as follows. We provide information for installing SUMMA-Actors on your system as well as some information for how to install SUMMA-Actors on Clusters such as the ones provided by Compute Canada. \ No newline at end of file +The documentation is organized as follows. We provide information for installing SUMMA-Actors on your system as well as some information for how to install SUMMA-Actors on Clusters such as the ones provided by Compute Canada. + +[The Actor Model](actors.md) \ No newline at end of file diff --git a/docs/source/actors.md b/docs/source/actors.md new file mode 100644 index 0000000000000000000000000000000000000000..2de16208c059ffac63354970752e167049378c4d --- /dev/null +++ b/docs/source/actors.md @@ -0,0 +1,3 @@ +# Introduction to Actors + +The actor model is a concurrency model where the fundemental unit of computation is the actor. The actor is considered the fundemental unit of computation because it encapulates what it means to compute inside the actor. Specifically, this means an actor has a thread of execution, the ability to save state, and the ability to message actors. This is what is fundemental to a computer, where a computer has the ability to execute instructions, save state in either RAM (volitle) or HDD/SDD (non-volitle), and connected to a network in which it can communicate with other computers. \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..e723e8e07bd63302e95726bfe613b3f3fb339716 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'SUMMA-Actors' +copyright = '2022, Kyle Klenk, Kevin R. Green, Raymond Spiteri' +author = 'Kyle Klenk, Kevin R. Green, Raymond Spiteri' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'myst_parser', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.md' + +# The master toctree document. +master_doc = 'SUMMA-Actors' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'SUMMA-Actorsdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'SUMMA-Actors.tex', 'SUMMA-Actors Documentation', + 'Kyle Klenk, Kevin R. Green, Raymond Spiteri', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'summa-actors', 'SUMMA-Actors Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'SUMMA-Actors', 'SUMMA-Actors Documentation', + author, 'SUMMA-Actors', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- diff --git a/docs/contact.md b/docs/source/contact.md similarity index 100% rename from docs/contact.md rename to docs/source/contact.md diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..e12722fea140c27a68862adaf3325a7b98dd826d --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,20 @@ +.. SUMMA-Actors documentation master file, created by + sphinx-quickstart on Tue Aug 23 17:21:15 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +SUMMA-Actors Documentation +======================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/utils/containers/sundials/Dockerfile b/utils/containers/sundials/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..6351587729933050b0f2746b70eadf79de31445b --- /dev/null +++ b/utils/containers/sundials/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:20.04 + +WORKDIR /code + +# Get library dependencies +RUN apt-get update -y && \ + apt-get upgrade -y && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y software-properties-common \ + libnetcdf-dev \ + libnetcdff-dev \ + liblapack-dev \ + libopenblas-dev \ + cmake \ + g++ \ + git \ + libssl-dev \ + make \ + gfortran \ + wget \ + python3-pip \ + gdb &&\ + apt-get autoclean + +RUN pip3 install xarray +RUN pip3 install netcdf4 + +# Install the C++ Actor Framework From Git +RUN git clone https://github.com/actor-framework/actor-framework.git +WORKDIR /code/actor-framework +RUN ./configure +WORKDIR /code/actor-framework/build +RUN make +RUN make test +RUN make install + +WORKDIR /code + +# Install Sundials +RUN wget https://github.com/LLNL/sundials/releases/download/v5.8.0/sundials-5.8.0.tar.gz +RUN tar -xzf sundials-5.8.0.tar.gz +RUN mkdir sundials +WORKDIR /code/sundials +RUN mkdir instdir +RUN mkdir builddir +WORKDIR /code/sundials/builddir +RUN cmake ../../sundials-5.8.0 -DBUILD_FORTRAN_MODULE_INTERFACE=ON -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_INSTALL_PREFIX=/code/sundials/instdir -DEXAMPLES_INSTALL_PATH=/code/sundials/instdir/examples +RUN make +RUN make install + +# Change workdir for when we attach to this container +WORKDIR /Summa-Actors +ENV LD_LIBRARY_PATH=/Summa-Actors/bin:/usr/local/lib:/code/sundials/instdir/lib \ No newline at end of file diff --git a/utils/containers/sundials/build_docker_container.sh b/utils/containers/sundials/build_docker_container.sh new file mode 100755 index 0000000000000000000000000000000000000000..f67064f8902c0569b5b3b4ede949bdcceccb513e --- /dev/null +++ b/utils/containers/sundials/build_docker_container.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +docker build -t summa-sundials . \ No newline at end of file diff --git a/utils/containers/sundials/launch_docker_container.sh b/utils/containers/sundials/launch_docker_container.sh new file mode 100755 index 0000000000000000000000000000000000000000..5d8de7e55a5932a71004caa5b1c74757e6af968c --- /dev/null +++ b/utils/containers/sundials/launch_docker_container.sh @@ -0,0 +1,7 @@ +#! /bin/bash + +export PROJECT_DIR=/Users/kyleklenk/SUMMA-Projects/Summa-Actors +export NA_TEST=/home/local/kck540/NA_Summa_Test +export SUMMA=/Users/kyleklenk/SUMMA-Projects/Summa-Sundials/summa +docker run -d -it --ulimit memlock=32768:32768 --name SUMMA-Sundials --mount type=bind,source=${PROJECT_DIR},target=/Summa-Actors \ + --mount type=bind,source=${SUMMA},target=/SUMMA summa-sundials:latest diff --git a/utils/laugh_tests/celia1990/output/runinfo.txt b/utils/laugh_tests/celia1990/output/runinfo.txt deleted file mode 100644 index 3bdf9dca0db5e67d7f65e281dd9aad18332981d9..0000000000000000000000000000000000000000 --- a/utils/laugh_tests/celia1990/output/runinfo.txt +++ /dev/null @@ -1 +0,0 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=16 - hh=21 - mi=31 - ss=01.667 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 deleted file mode 100644 index d173a6235ac81f1f920965a1ab7d4091db3dcb0a..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/celia1990/output/summa-actors_celia1990GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/celia1990/verification_data/runinfo.txt b/utils/laugh_tests/celia1990/verification_data/runinfo.txt index a4397e2edc523fc1a3bb76f702aaaa11af1ddba9..feeb3b8df05117586f9255a5b3f954fb08236900 100644 --- a/utils/laugh_tests/celia1990/verification_data/runinfo.txt +++ b/utils/laugh_tests/celia1990/verification_data/runinfo.txt @@ -1 +1 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=15 - hh=02 - mi=49 - ss=51.739 + Run start time on system: ccyy=2022 - mm=08 - dd=27 - hh=02 - mi=48 - ss=23.700 diff --git a/utils/laugh_tests/celia1990/verification_data/summa_celia1990_G1-1_timestep.nc b/utils/laugh_tests/celia1990/verification_data/summa_celia1990_G1-1_timestep.nc index e1319892d362595775ea3f6668ad8dd00667cf1e..ba51c0e9abb84add6c3aed5b8a142efa26b4817f 100644 Binary files a/utils/laugh_tests/celia1990/verification_data/summa_celia1990_G1-1_timestep.nc and b/utils/laugh_tests/celia1990/verification_data/summa_celia1990_G1-1_timestep.nc differ diff --git a/utils/laugh_tests/colbeck1976/output/colbeck1976-exp1GRU1-1_timestep.nc b/utils/laugh_tests/colbeck1976/output/colbeck1976-exp1GRU1-1_timestep.nc deleted file mode 100644 index 5c4b9adb2d00c716208b87546a6e3806fe85208f..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/colbeck1976/output/colbeck1976-exp1GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/colbeck1976/output/colbeck1976-exp2GRU1-1_timestep.nc b/utils/laugh_tests/colbeck1976/output/colbeck1976-exp2GRU1-1_timestep.nc deleted file mode 100644 index ce00720f1b5a90c8340bd4de76367f035f977b60..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/colbeck1976/output/colbeck1976-exp2GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/colbeck1976/output/colbeck1976-exp3GRU1-1_timestep.nc b/utils/laugh_tests/colbeck1976/output/colbeck1976-exp3GRU1-1_timestep.nc deleted file mode 100644 index cee21d14a88c0a1c36adf2d91b369fcf84eea934..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/colbeck1976/output/colbeck1976-exp3GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/colbeck1976/output/runinfo.txt b/utils/laugh_tests/colbeck1976/output/runinfo.txt deleted file mode 100644 index 390c561e4cf795063e2f5bec9066ba19b30a6de8..0000000000000000000000000000000000000000 --- a/utils/laugh_tests/colbeck1976/output/runinfo.txt +++ /dev/null @@ -1 +0,0 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=16 - hh=21 - mi=31 - ss=26.957 diff --git a/utils/laugh_tests/miller1998/output/millerClayGRU1-1_timestep.nc b/utils/laugh_tests/miller1998/output/millerClayGRU1-1_timestep.nc deleted file mode 100644 index 9d300d43aca06babe931ddc2ad3e57c26be239f5..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/miller1998/output/millerClayGRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/miller1998/output/millerLoamGRU1-1_timestep.nc b/utils/laugh_tests/miller1998/output/millerLoamGRU1-1_timestep.nc deleted file mode 100644 index aa63590c28a5d07dd82904425de6e93e002a85b8..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/miller1998/output/millerLoamGRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/miller1998/output/millerSandGRU1-1_timestep.nc b/utils/laugh_tests/miller1998/output/millerSandGRU1-1_timestep.nc deleted file mode 100644 index a11227dc290f563ca87bc949bf9c0a3550fb64a3..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/miller1998/output/millerSandGRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/miller1998/output/runinfo.txt b/utils/laugh_tests/miller1998/output/runinfo.txt deleted file mode 100644 index 57d180b81da4d5169ffc62f88f3673fcef30e9a5..0000000000000000000000000000000000000000 --- a/utils/laugh_tests/miller1998/output/runinfo.txt +++ /dev/null @@ -1 +0,0 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=16 - hh=21 - mi=32 - ss=00.868 diff --git a/utils/laugh_tests/miller1998/run_test_summa_actors.sh b/utils/laugh_tests/miller1998/run_test_summa_actors.sh index 864e583b8aa024e5655c409fd77279f2a00b6088..43659c6449ae6e32a974efb2c0e4abf31b9a91e0 100755 --- a/utils/laugh_tests/miller1998/run_test_summa_actors.sh +++ b/utils/laugh_tests/miller1998/run_test_summa_actors.sh @@ -1,5 +1,4 @@ #! /bin/bash /Summa-Actors/bin/summaMain -g 1 -n 1 -c /Summa-Actors/utils/laugh_tests/miller1998/config/clay -/Summa-Actors/bin/summaMain -g 1 -n 1 -c /Summa-Actors/utils/laugh_tests/miller1998/config/loam -/Summa-Actors/bin/summaMain -g 1 -n 1 -c /Summa-Actors/utils/laugh_tests/miller1998/config/sand \ No newline at end of file +/Summa-Actors/bin/summaMain -g 1 -n 1 -c /Summa-Actors/utils/laugh_tests/miller1998/config/loam \ No newline at end of file diff --git a/utils/laugh_tests/mizoguchi1990/output/mizoguchi1990GRU1-1_timestep.nc b/utils/laugh_tests/mizoguchi1990/output/mizoguchi1990GRU1-1_timestep.nc deleted file mode 100644 index 80d2ac17f8e003d6c6e59a7d165dd59cec28c438..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/mizoguchi1990/output/mizoguchi1990GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/mizoguchi1990/output/runinfo.txt b/utils/laugh_tests/mizoguchi1990/output/runinfo.txt deleted file mode 100644 index 816ded9a32347f2ef8854d0783aa1d4fa704e0fa..0000000000000000000000000000000000000000 --- a/utils/laugh_tests/mizoguchi1990/output/runinfo.txt +++ /dev/null @@ -1 +0,0 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=16 - hh=21 - mi=32 - ss=42.965 diff --git a/utils/laugh_tests/run_all_summa_actors.sh b/utils/laugh_tests/run_all_summa_actors.sh new file mode 100755 index 0000000000000000000000000000000000000000..6f6719cc679734e830cfbd1fe6b3ec5a42706d4b --- /dev/null +++ b/utils/laugh_tests/run_all_summa_actors.sh @@ -0,0 +1,36 @@ +#! /bin/bash + +echo "Starting Celia" +cd celia1990 +./run_test_summa_actors.sh +python3 verify_celia.py +cd .. +sleep 3 + +echo "Starting Colbeck" +cd colbeck1976 +./run_test_summa_actors.sh +python3 verify_colbeck.py +cd .. +sleep 3 + +echo "Starting Miller" +cd miller1998 +./run_test_summa_actors.sh +python3 verify_miller.py +cd .. +sleep 3 + +echo "Starting Mizoguchi" +cd mizoguchi1990 +./run_test_summa_actors.sh +python3 verify_mizoguchi.py +cd .. +sleep 3 + +echo "Starting Vanderborght" +cd vanderborght2005 +./run_test_summa_actors.sh +python3 verify_vanderborght.py +cd .. +sleep 3 diff --git a/utils/laugh_tests/vanderborght2005/output/runinfo.txt b/utils/laugh_tests/vanderborght2005/output/runinfo.txt deleted file mode 100644 index 5151e7cd7c083f6e6f2ec66c000ccd868bb86520..0000000000000000000000000000000000000000 --- a/utils/laugh_tests/vanderborght2005/output/runinfo.txt +++ /dev/null @@ -1 +0,0 @@ - Run start time on system: ccyy=2022 - mm=08 - dd=16 - hh=21 - mi=33 - ss=47.978 diff --git a/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp1GRU1-1_timestep.nc b/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp1GRU1-1_timestep.nc deleted file mode 100644 index 389efb9d6fdd3efa2fce4c47f99dbb34e9164bbf..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp1GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp2GRU1-1_timestep.nc b/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp2GRU1-1_timestep.nc deleted file mode 100644 index 9ed72de5cbe91cc37bbea9af33127f011e576243..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp2GRU1-1_timestep.nc and /dev/null differ diff --git a/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp3GRU1-1_timestep.nc b/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp3GRU1-1_timestep.nc deleted file mode 100644 index 06a160724b61e8833821c158c2d00e720e21db49..0000000000000000000000000000000000000000 Binary files a/utils/laugh_tests/vanderborght2005/output/vanderborght2005_exp3GRU1-1_timestep.nc and /dev/null differ