From a1deb0bde4b99bfd4f6f7b0d757412a81acdf590 Mon Sep 17 00:00:00 2001 From: Ahmad Jan Date: Tue, 27 Aug 2024 14:39:14 -0400 Subject: [PATCH 1/6] adjustments to get/set values functions. --- src/bmi_cfe.c | 110 +++++++++++++------------------ src/main_cfe_aorc_pet_rz_aet.cxx | 12 ++-- 2 files changed, 51 insertions(+), 71 deletions(-) diff --git a/src/bmi_cfe.c b/src/bmi_cfe.c index c2603d1..8007d13 100644 --- a/src/bmi_cfe.c +++ b/src/bmi_cfe.c @@ -1775,7 +1775,6 @@ static int Get_var_units (Bmi *self, const char *name, char * units) return BMI_FAILURE; } - static int Get_var_nbytes (Bmi *self, const char *name, int * nbytes) { int item_size; @@ -1787,6 +1786,10 @@ static int Get_var_nbytes (Bmi *self, const char *name, int * nbytes) for (i = 0; i < INPUT_VAR_NAME_COUNT; i++) { if (strcmp(name, input_var_names[i]) == 0) { item_count = input_var_item_count[i]; + if (strcmp(name, "soil_moisture_profile") == 0 || strcmp(name, "soil_layer_depths_m") == 0) { + cfe_state_struct *cfe_ptr; + item_count = ((cfe_state_struct *)(self->data))->soil_reservoir.n_soil_layers + 1; + } break; } } @@ -2054,7 +2057,7 @@ static int Get_value_ptr (Bmi *self, const char *name, void **dest) /**************************************************************************************************/ /**********Parameter Derived from config file - root zone adjusted AET development - rlm ***********/ - if (strcmp (name, "soil__num_cells") == 0) { + if (strcmp (name, "soil_num_cells") == 0) { cfe_state_struct *cfe_ptr; cfe_ptr = (cfe_state_struct *) self->data; *dest = (void*)&cfe_ptr->soil_reservoir.n_soil_layers; @@ -2116,51 +2119,51 @@ static int Get_value (Bmi *self, const char *name, void *dest) return Get_value_at_indices(self, name, dest, inds, 1); } - static int Set_value_at_indices (Bmi *self, const char *name, int * inds, int len, void *src) { - if (len < 1) - return BMI_FAILURE; + void * dest = NULL; + int itemsize = 0; - // Get "adjusted_index" for variable - int adjusted_index = Get_adjusted_index_for_variable(name); - if (adjusted_index < 0) + if (self->get_value_ptr(self, name, &dest) == BMI_FAILURE) return BMI_FAILURE; - int var_item_size; - int status = Get_var_itemsize(self, name, &var_item_size); - if (status == BMI_FAILURE) + if (self->get_var_itemsize(self, name, &itemsize) == BMI_FAILURE) return BMI_FAILURE; - // For now, all variables are non-array scalar values, with only 1 item of type double + { /* Copy the data */ + size_t i; + size_t offset; + char * ptr; + for (i=0, ptr=(char*)src; idata))->soil_reservoir.n_soil_layers + 1; - void *ptr = NULL; //(double*) malloc (sizeof (double)* len); - status = Get_value_ptr(self, name, &ptr); +} +static int Set_value (Bmi *self, const char *name, void *array) +{ + void * dest = NULL; + int nbytes = 0; - if (status == BMI_FAILURE) + if (self->get_value_ptr(self, name, &dest) == BMI_FAILURE) return BMI_FAILURE; - memcpy(ptr, src, var_item_size * len); - - return BMI_SUCCESS; - - } - else if (len > 1 || inds[0] != 0) + if (self->get_var_nbytes(self, name, &nbytes) == BMI_FAILURE) return BMI_FAILURE; - void* ptr; - status = Get_value_ptr(self, name, &ptr); - if (status == BMI_FAILURE) - return BMI_FAILURE; - memcpy(ptr, src, var_item_size * len); + memcpy (dest, array, nbytes); + + /* + // Calibratable parameters + - if (strcmp (name, "maxsmc") == 0 || strcmp (name, "alpha_fc") == 0 || strcmp (name, "wltsmc") == 0 || strcmp (name, "maxsmc") == 0 || strcmp (name, "b") == 0 || strcmp (name, "slope") == 0 || strcmp (name, "satpsi") == 0 || strcmp (name, "Klf") == 0 || strcmp (name, "satdk") == 0){ + if (strcmp (name, "maxsmc") == 0 || strcmp (name, "alpha_fc") == 0 || strcmp (name, "wltsmc") == 0 || + strcmp (name, "maxsmc") == 0 || strcmp (name, "b") == 0 || strcmp (name, "slope") == 0 || + strcmp (name, "satpsi") == 0 || strcmp (name, "Klf") == 0 || strcmp (name, "satdk") == 0) { cfe_state_struct* cfe_ptr = (cfe_state_struct *) self->data; init_soil_reservoir(cfe_ptr); @@ -2173,10 +2176,15 @@ static int Set_value_at_indices (Bmi *self, const char *name, int * inds, int le if (strcmp (name, "N_nash_subsurface") == 0) { cfe_state_struct* cfe_ptr = (cfe_state_struct *) self->data; - if( cfe_ptr->nash_storage_subsurface != NULL ) free(cfe_ptr->nash_storage_subsurface); - cfe_ptr->nash_storage_subsurface = malloc(sizeof(double) * cfe_ptr->N_nash_subsurface); - if( cfe_ptr->nash_storage_subsurface == NULL ) return BMI_FAILURE; - for (j = 0; j < cfe_ptr->N_nash_subsurface; j++) + if( cfe_ptr->nash_storage_subsurface != NULL ) + free(cfe_ptr->nash_storage_subsurface); + + cfe_ptr->nash_storage_subsurface = malloc(sizeof(double) * cfe_ptr->N_nash_subsurface); + + if( cfe_ptr->nash_storage_subsurface == NULL ) + return BMI_FAILURE; + + for (j = 0; j < cfe_ptr->N_nash_subsurface; j++) cfe_ptr->nash_storage_subsurface[j] = 0.0; } @@ -2184,37 +2192,9 @@ static int Set_value_at_indices (Bmi *self, const char *name, int * inds, int le cfe_state_struct* cfe_ptr = (cfe_state_struct *) self->data; cfe_ptr->gw_reservoir.storage_m = cfe_ptr->gw_reservoir.gw_storage * cfe_ptr->gw_reservoir.storage_max_m; } - - return BMI_SUCCESS; -} - - -static int Set_value (Bmi *self, const char *name, void *array) -{ - // Avoid using set value, call instead set_value_at_index - // Use nested call to "by index" version - - // Here, for now at least, we know all the variables are scalar, so - int inds[] = {0}; - - // Then we can just ... - return Set_value_at_indices(self, name, inds, 1, array); - - -/* This is the sample code from read the docs - void * dest = NULL; - int nbytes = 0; - - if (self->get_value_ptr(self, name, &dest) == BMI_FAILURE) - return BMI_FAILURE; - - if (self->get_var_nbytes(self, name, &nbytes) == BMI_FAILURE) - return BMI_FAILURE; - - memcpy (dest, array, nbytes); - + */ + return BMI_SUCCESS; -*/ } diff --git a/src/main_cfe_aorc_pet_rz_aet.cxx b/src/main_cfe_aorc_pet_rz_aet.cxx index 02d2494..26ffe56 100644 --- a/src/main_cfe_aorc_pet_rz_aet.cxx +++ b/src/main_cfe_aorc_pet_rz_aet.cxx @@ -180,20 +180,20 @@ int Initializing the BMI model for CFE and AORC and Freeze-thaw model ************************************************************************/ - printf("Initializeing BMI CFE model\n"); + printf("Initializing BMI CFE model\n"); const char *cfg_file_cfe = argv[1]; cfe_bmi_model->initialize(cfe_bmi_model, cfg_file_cfe); - printf("Initializeing BMI AORC model\n"); + printf("Initializing BMI AORC model\n"); const char *cfg_file_aorc = argv[2]; printf("AORC config file %s\n", cfg_file_aorc); aorc_bmi_model->initialize(aorc_bmi_model, cfg_file_aorc); - printf("Initializeing BMI PET model\n"); + printf("Initializing BMI PET model\n"); const char *cfg_file_pet = argv[3]; pet_bmi_model->initialize(pet_bmi_model, cfg_file_pet); - printf("Initializeing BMI Coupler model\n"); + printf("Initializing BMI Coupler model\n"); const char *cfg_file_coupler = argv[4]; coupler_bmi.Initialize(cfg_file_coupler); @@ -231,7 +231,7 @@ int /************************************************************************ Now loop through time and call the models with the intermediate get/set ************************************************************************/ - printf("looping through and calling updata\n"); + printf("looping through and calling update \n"); if (cfe->verbosity > 0) print_cfe_flux_header(); for (int i = 0; i < 24862; i++){ @@ -270,7 +270,7 @@ int printf("PET value from PET is %8.9lf\n", pet->pet_m_per_s); printf("PET value from CFE is %8.9lf\n", cfe->et_struct.potential_et_m_per_s); } - + cfe_bmi_model->update(cfe_bmi_model); // Update model 2 if (cfe->verbosity > 0) From f2964856a216c126482cd38e6fc642f3170adaf1 Mon Sep 17 00:00:00 2001 From: Ahmad Jan Date: Tue, 27 Aug 2024 19:51:40 -0400 Subject: [PATCH 2/6] fixed nbytes for calibratable parameters. --- src/bmi_cfe.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/bmi_cfe.c b/src/bmi_cfe.c index 8007d13..447a0ef 100644 --- a/src/bmi_cfe.c +++ b/src/bmi_cfe.c @@ -1801,10 +1801,19 @@ static int Get_var_nbytes (Bmi *self, const char *name, int * nbytes) } } } + if (item_count < 1) { + for (i = 0; i < PARAM_VAR_NAME_COUNT; i++) { + if (strcmp(name, param_var_names[i]) == 0) { + item_count = 1; + break; + } + } + } if (item_count < 1) item_count = ((cfe_state_struct *) self->data)->num_timesteps; *nbytes = item_size * item_count; + return BMI_SUCCESS; } @@ -2144,8 +2153,10 @@ static int Set_value_at_indices (Bmi *self, const char *name, int * inds, int le } -static int Set_value (Bmi *self, const char *name, void *array) + +static int Set_value (Bmi *self, const char *name, void *src) { + void * dest = NULL; int nbytes = 0; @@ -2155,15 +2166,9 @@ static int Set_value (Bmi *self, const char *name, void *array) if (self->get_var_nbytes(self, name, &nbytes) == BMI_FAILURE) return BMI_FAILURE; - memcpy (dest, array, nbytes); - - /* - // Calibratable parameters - + memcpy (dest, src, nbytes); - if (strcmp (name, "maxsmc") == 0 || strcmp (name, "alpha_fc") == 0 || strcmp (name, "wltsmc") == 0 || - strcmp (name, "maxsmc") == 0 || strcmp (name, "b") == 0 || strcmp (name, "slope") == 0 || - strcmp (name, "satpsi") == 0 || strcmp (name, "Klf") == 0 || strcmp (name, "satdk") == 0) { + if (strcmp (name, "maxsmc") == 0 || strcmp (name, "alpha_fc") == 0 || strcmp (name, "wltsmc") == 0 || strcmp (name, "maxsmc") == 0 || strcmp (name, "b") == 0 || strcmp (name, "slope") == 0 || strcmp (name, "satpsi") == 0 || strcmp (name, "Klf") == 0 || strcmp (name, "satdk") == 0){ cfe_state_struct* cfe_ptr = (cfe_state_struct *) self->data; init_soil_reservoir(cfe_ptr); @@ -2176,10 +2181,10 @@ static int Set_value (Bmi *self, const char *name, void *array) if (strcmp (name, "N_nash_subsurface") == 0) { cfe_state_struct* cfe_ptr = (cfe_state_struct *) self->data; - if( cfe_ptr->nash_storage_subsurface != NULL ) - free(cfe_ptr->nash_storage_subsurface); - cfe_ptr->nash_storage_subsurface = malloc(sizeof(double) * cfe_ptr->N_nash_subsurface); + if( cfe_ptr->nash_storage_subsurface != NULL ) + free(cfe_ptr->nash_storage_subsurface); + cfe_ptr->nash_storage_subsurface = malloc(sizeof(double) * cfe_ptr->N_nash_subsurface); if( cfe_ptr->nash_storage_subsurface == NULL ) return BMI_FAILURE; @@ -2192,7 +2197,6 @@ static int Set_value (Bmi *self, const char *name, void *array) cfe_state_struct* cfe_ptr = (cfe_state_struct *) self->data; cfe_ptr->gw_reservoir.storage_m = cfe_ptr->gw_reservoir.gw_storage * cfe_ptr->gw_reservoir.storage_max_m; } - */ return BMI_SUCCESS; } From 8bd8924c33a1ae45c4c5f98415d81034aa3e0693 Mon Sep 17 00:00:00 2001 From: Ahmad Jan Date: Wed, 28 Aug 2024 09:45:59 -0400 Subject: [PATCH 3/6] added comment for using item_count 1 for calibratable parameters. --- src/bmi_cfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bmi_cfe.c b/src/bmi_cfe.c index 447a0ef..bf6517c 100644 --- a/src/bmi_cfe.c +++ b/src/bmi_cfe.c @@ -1804,7 +1804,7 @@ static int Get_var_nbytes (Bmi *self, const char *name, int * nbytes) if (item_count < 1) { for (i = 0; i < PARAM_VAR_NAME_COUNT; i++) { if (strcmp(name, param_var_names[i]) == 0) { - item_count = 1; + item_count = 1; // all of the calibratable parameters are (and will be?) scalars - AJK break; } } From 3f437498c4da4756381b2469240de4721401cb63 Mon Sep 17 00:00:00 2001 From: AJKhattak-NOAA Date: Fri, 30 Aug 2024 10:46:32 -0400 Subject: [PATCH 4/6] Update src/bmi_cfe.c Co-authored-by: Nels --- src/bmi_cfe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bmi_cfe.c b/src/bmi_cfe.c index bf6517c..d69aaad 100644 --- a/src/bmi_cfe.c +++ b/src/bmi_cfe.c @@ -2143,6 +2143,9 @@ static int Set_value_at_indices (Bmi *self, const char *name, int * inds, int le size_t i; size_t offset; char * ptr; + // iterate over the source pointer, src, by itemsize byte chunks + // and set the destination pointer, dest, to the value in src + // based on the linear offset provided by inds[i] for (i=0, ptr=(char*)src; i Date: Fri, 30 Aug 2024 11:48:25 -0400 Subject: [PATCH 5/6] fixed bug related to +1 in the AET rootzone memory allocation, removed unused variables num_cells and soil_layer_depths. --- src/bmi_cfe.c | 45 +++++++++++++------------------- src/main_cfe_aorc_pet_rz_aet.cxx | 5 ++-- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/bmi_cfe.c b/src/bmi_cfe.c index d69aaad..d3922f9 100644 --- a/src/bmi_cfe.c +++ b/src/bmi_cfe.c @@ -1212,10 +1212,10 @@ int read_init_config_cfe(const char* config_file, cfe_state_struct* model) return BMI_FAILURE; } - model->soil_reservoir.soil_layer_depths_m = malloc(sizeof(double) * (model->soil_reservoir.n_soil_layers + 1)); + model->soil_reservoir.soil_layer_depths_m = malloc(sizeof(double) * (model->soil_reservoir.n_soil_layers)); copy = soil_layer_depths_string_val; - i = 1; + i = 0; while((value = strsep(©, ",")) != NULL) { model->soil_reservoir.soil_layer_depths_m[i++] = strtod(value, NULL); } @@ -1224,7 +1224,7 @@ int read_init_config_cfe(const char* config_file, cfe_state_struct* model) //Check that the last depth read in from the cfe config file (soil_layer_depths) matches the total depth (soil_params.depth) //from the cfe config file. - if(model->NWM_soil_params.D != model->soil_reservoir.soil_layer_depths_m[model->soil_reservoir.n_soil_layers]){ + if(model->NWM_soil_params.D != model->soil_reservoir.soil_layer_depths_m[model->soil_reservoir.n_soil_layers - 1]){ printf("WARNING: soil_params.depth is not equal to the last soil layer depth in the CFE config file! Aborting...\n"); return BMI_FAILURE; } @@ -1234,10 +1234,10 @@ int read_init_config_cfe(const char* config_file, cfe_state_struct* model) // Calculate the thickness (delta) of each soil layer if (is_aet_rootzone_set == TRUE ) { model->soil_reservoir.is_aet_rootzone = TRUE; - model->soil_reservoir.delta_soil_layer_depth_m = malloc(sizeof(double) * (model->soil_reservoir.n_soil_layers + 1)); + model->soil_reservoir.delta_soil_layer_depth_m = malloc(sizeof(double) * (model->soil_reservoir.n_soil_layers)); double previous_depth = 0; double current_depth = 0; - for (int i=1; i <= model->soil_reservoir.n_soil_layers; i++) { + for (int i=0; i soil_reservoir.n_soil_layers; i++) { current_depth = model->soil_reservoir.soil_layer_depths_m[i]; if (current_depth <= previous_depth) printf("WARNING: soil depths may be out of order. One or more soil layer depths is less than or equal to the previous layer. Check CFE config file.\n"); @@ -1474,7 +1474,7 @@ static int Initialize (Bmi *self, const char *file) cfe_bmi_data_ptr->soil_reservoir.ice_fraction_xinanjiang = 0.0; if (cfe_bmi_data_ptr->soil_reservoir.is_aet_rootzone == TRUE) - cfe_bmi_data_ptr->soil_reservoir.smc_profile = malloc(sizeof(double)*cfe_bmi_data_ptr->soil_reservoir.n_soil_layers + 1); + cfe_bmi_data_ptr->soil_reservoir.smc_profile = malloc(sizeof(double)*cfe_bmi_data_ptr->soil_reservoir.n_soil_layers); else cfe_bmi_data_ptr->soil_reservoir.smc_profile = malloc(sizeof(double)*1); @@ -1786,9 +1786,9 @@ static int Get_var_nbytes (Bmi *self, const char *name, int * nbytes) for (i = 0; i < INPUT_VAR_NAME_COUNT; i++) { if (strcmp(name, input_var_names[i]) == 0) { item_count = input_var_item_count[i]; - if (strcmp(name, "soil_moisture_profile") == 0 || strcmp(name, "soil_layer_depths_m") == 0) { + if (strcmp(name, "soil_moisture_profile") == 0) { cfe_state_struct *cfe_ptr; - item_count = ((cfe_state_struct *)(self->data))->soil_reservoir.n_soil_layers + 1; + item_count = ((cfe_state_struct *)(self->data))->soil_reservoir.n_soil_layers; } break; } @@ -2065,15 +2065,8 @@ static int Get_value_ptr (Bmi *self, const char *name, void **dest) } /**************************************************************************************************/ - /**********Parameter Derived from config file - root zone adjusted AET development - rlm ***********/ - if (strcmp (name, "soil_num_cells") == 0) { - cfe_state_struct *cfe_ptr; - cfe_ptr = (cfe_state_struct *) self->data; - *dest = (void*)&cfe_ptr->soil_reservoir.n_soil_layers; - return BMI_SUCCESS; - } + /**********Parameter Derived from config file - root zone adjusted AET development - rlm -ajk ***********/ - //--------------Root zone adjusted AET development -rlm -ajk ------- if (strcmp (name, "soil_moisture_profile") == 0) { *dest = (void *) ((cfe_state_struct *)(self->data))->soil_reservoir.smc_profile; return BMI_SUCCESS; @@ -2139,17 +2132,15 @@ static int Set_value_at_indices (Bmi *self, const char *name, int * inds, int le if (self->get_var_itemsize(self, name, &itemsize) == BMI_FAILURE) return BMI_FAILURE; - { /* Copy the data */ - size_t i; - size_t offset; - char * ptr; - // iterate over the source pointer, src, by itemsize byte chunks - // and set the destination pointer, dest, to the value in src - // based on the linear offset provided by inds[i] - for (i=0, ptr=(char*)src; iset_value(cfe_bmi_model, "soil_moisture_profile", &smct[0]); } - /*************************************************************** Function to pass the forcing data from AORC to PET using BMI. This requires a lot of getters and setters, From 3aaf7d6530223655a379a4e6800dccc6243df072 Mon Sep 17 00:00:00 2001 From: Ahmad Jan Date: Fri, 30 Aug 2024 12:43:50 -0400 Subject: [PATCH 6/6] fixed default n_soil_layers. --- src/bmi_cfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bmi_cfe.c b/src/bmi_cfe.c index d3922f9..c7200b3 100644 --- a/src/bmi_cfe.c +++ b/src/bmi_cfe.c @@ -1252,7 +1252,7 @@ int read_init_config_cfe(const char* config_file, cfe_state_struct* model) } else { model->soil_reservoir.is_aet_rootzone = FALSE; - model->soil_reservoir.n_soil_layers = 0; + model->soil_reservoir.n_soil_layers = 1; } /*--------------------END OF ROOT ZONE ADJUSTED AET DEVELOPMENT -rlm ------------------------------*/