Skip to content

Commit

Permalink
Merge branch 'NOAA-OWP:master' into aet_rootzone_name_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
madMatchstick authored Sep 6, 2024
2 parents 5572ea6 + 91d8fdb commit 919996b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 65 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/add_to_project.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
name: Add to Project

on:
#pull_request_target:
#pull_request:
# types:
# - opened
pull_request:
types:
- opened
issues:
types:
- opened

jobs:
add-to-project:
name: Add issues to formulation project
name: Add issues and PRs to formulation project
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
with:
project-url: https://github.com/orgs/NOAA-OWP/projects/30
github-token: ${{ secrets.TEST-CFE-2 }}
github-token: ${{ secrets.FORMULATION_PROJECT_ADD_TOKEN }}
45 changes: 26 additions & 19 deletions configs/README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,49 @@
## Configuration File
Example configuration files are provided in this directory. To build and run the given examples see the instructions [here](https://github.com/NOAA-OWP/cfe/blob/master/INSTALL.md). A detailed description of the parameters for model configuration (i.e., initialize/setup) is provided below. The asterisk (*) denotes calibratable parameters.
Example configuration files are provided in this directory. To build and run the given examples see the instructions [here](https://github.com/NOAA-OWP/cfe/blob/master/INSTALL.md). A detailed description of the parameters for model configuration (i.e., initialize/setup) is provided below.


**Key**:

<sup>*</sup>: denotes parameter is calibratable

<sup>1</sup>: denotes the parameters only used when `surface_runoff_scheme` is `NASH_CASCADE`.

| Variable | Datatype | Limits | Units | Role | Process | Description |
| -------- | -------- | ------ | ----- | ---- | ------- | ----------- |
| forcing_file | *char* | 256 | | filename | | path to forcing inputs csv; set to `BMI` if passed via `bmi.set_value*()` |
| soil_params.depth | *double* | | meters [m]| state | | soil depth |
| *soil_params.b | *double* | | | state | | beta exponent on Clapp-Hornberger (1978) soil water relations |
| *soil_params.satdk | *double* | | meters/second [m s-1] | state | | saturated hydraulic conductivity |
| *soil_params.satpsi | *double* | | meters [m] | state | | saturated capillary head |
| *soil_params.slop | *double* | | meters/meters [m/m]| state | | this factor (0-1) modifies the gradient of the hydraulic head at the soil bottom. 0=no-flow. |
| *soil_params.smcmax | *double* | | meters/meters [m/m] | state | | saturated soil moisture content |
| soil_params.b<sup>*</sup> | *double* | | | state | | beta exponent on Clapp-Hornberger (1978) soil water relations |
| soil_params.satdk<sup>*</sup> | *double* | | meters/second [m s-1] | state | | saturated hydraulic conductivity |
| soil_params.satpsi<sup>*</sup> | *double* | | meters [m] | state | | saturated capillary head |
| soil_params.slop<sup>*</sup> | *double* | | meters/meters [m/m]| state | | this factor (0-1) modifies the gradient of the hydraulic head at the soil bottom. 0=no-flow. |
| soil_params.smcmax<sup>*</sup> | *double* | | meters/meters [m/m] | state | | saturated soil moisture content |
| soil_params.wltsmc | *double* | | meters/meters [m/m] | state | | wilting point soil moisture content |
| soil_params.expon | *double* | | | parameter_adjustable | | optional; defaults to `1.0` |
| soil_params.expon_secondary | *double* | | | parameter_adjustable | | optional; defaults to `1.0` |
| *max_gw_storage | *double* | | meters [m] | parameter_adjustable | | maximum storage in the conceptual reservoir |
| *Cgw | *double* | | meters/hour [m h-1] | parameter_adjustable | | the primary outlet coefficient |
| *expon | *double* | | | parameter_adjustable | | exponent parameter (1.0 for linear reservoir) |
| max_gw_storage<sup>*</sup> | *double* | | meters [m] | parameter_adjustable | | maximum storage in the conceptual reservoir |
| Cgw<sup>*</sup> | *double* | | meters/hour [m h-1] | parameter_adjustable | | the primary outlet coefficient |
| expon<sup>*</sup> | *double* | | | parameter_adjustable | | exponent parameter (1.0 for linear reservoir) |
| gw_storage | *double* | | meters/meters [m/m] | parameter_adjustable | | initial condition for groundwater reservoir - it is the ground water as a decimal fraction of the maximum groundwater storage (max_gw_storage) for the initial timestep |
| alpha_fc | *double* | | | parameter_adjustable | | field capacity |
| soil_storage| *double* | | meters/meters [m/m] | parameter_adjustable | | initial condition for soil reservoir - it is the water in the soil as a decimal fraction of maximum soil water storage (smcmax * depth) for the initial timestep |
| N_nash_subsurface | *int* | | | parameter_adjustable | | number of Nash lf reservoirs (optional, defaults to 2, ignored if storage values present) |
| K_nash_subsurface | *double* | | 1/meters [m^-1] | parameter_adjustable | subsurface runoff | Nash Config param for lateral subsurface runoff |
| *K_lf | *double* | | | parameter_adjustable | | Nash Config param - primary reservoir |
| K_lf<sup>*</sup> | *double* | | | parameter_adjustable | | Nash Config param - primary reservoir |
| nash_storage_subsurface | 1D array (*double*) | | | parameter_adjustable | | Nash Config param - secondary reservoir |
| giuh_ordinates | 1D array (*double*) | | | parameter_adjustable | | Giuh ordinates in dt time steps |
| num_timesteps | *int* | | | time_info | | set to `1` if `forcing_file=BMI` |
| verbosity | *int* | `0`-`3` | | optional | | prints various debug and bmi info (defaults to 0) |
| surface_water_partitioning_scheme | *char* | `Xinanjiang` or `Schaake` | | parameter_adjustable | infiltraton excess | |
| surface_runoff_scheme | *char* | GIUH or NASH_CASCADE | | parameter_adjustable | surface runoff | also supports 1 for GIUH and 2 for NASH_CASCADE; default is GIUH |
| N_nash_surface | *int* | | | parameter_adjustable | surface runoff | number of Nash reservoirs for surface runoff |
| K_nash_surface | *double* | | 1/hour [h^-1] | parameter_adjustable | surface runoff | Nash Config param for surface runoff |
| nash_storage_surface | 1D array (*double*) | | meters [m] | parameter_adjustable | surface runoff | Nash Config param; reservoir surface storage; default is zero storage |
| nsubsteps_nash_surface | *int* | | | parameter_adjustable | surface runoff | optional (default = 10); number of subtimstep for Nash runoff |
| Kinf_nash_surface | *double* | | 1/hour [h^-1] | parameter_adjustable | surface runoff | optional (default = 0.05); storage fraction per hour that moves from reservoirs to soil |
| retention_depth_nash_surface | *double* | | m | parameter_adjustable | surface runoff | optional (default = 0.001); water retention depth threshold (only applied to the first reservoir) |
| *a_Xinanjiang_inflection_point_parameter | *double* | | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| *b_Xinanjiang_shape_parameter=1 | *double* | | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| *x_Xinanjiang_shape_parameter=1 | *double* | | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| N_nash_surface<sup>1</sup> | *int* | | | parameter_adjustable | surface runoff | number of Nash reservoirs for surface runoff |
| K_nash_surface<sup>1</sup> | *double* | | 1/hour [h^-1] | parameter_adjustable | surface runoff | Nash Config param for surface runoff |
| nash_storage_surface<sup>1</sup> | 1D array (*double*) | | meters [m] | parameter_adjustable | surface runoff | Nash Config param; reservoir surface storage; default is zero storage |
| nsubsteps_nash_surface<sup>1</sup> | *int* | | | parameter_adjustable | surface runoff | optional (default = 10); number of subtimstep for Nash runoff |
| Kinf_nash_surface<sup>*,1</sup> | *double* | | 1/hour [h^-1] | parameter_adjustable | surface runoff | optional (default = 0.05); storage fraction per hour that moves from reservoirs to soil |
| retention_depth_nash_surface<sup>*,1</sup> | *double* | | m | parameter_adjustable | surface runoff | optional (default = 0.001); water retention depth threshold (only applied to the first reservoir) |
| a_Xinanjiang_inflection_point_parameter<sup>*</sup> | *double* | | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| b_Xinanjiang_shape_parameter<sup>*</sup> | *double* | | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| x_Xinanjiang_shape_parameter<sup>*</sup> | *double* | | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| urban_decimal_fraction | *double* | 0.0 - 1.0 | | parameter_adjustable | infiltration excess runoff | when `surface_water_partitioning_scheme=Xinanjiang` |
| is_aet_rootzone | *boolean* | True, true or 1 | | coupling parameter | `rootzone-based AET` | when `CFE coupled to SoilMoistureProfile` |
| max_rootzone_layer | *double* | | meters [m] | parameter_adjustable | AET | layer of the soil that is the maximum root zone depth. That is, the depth of the layer where the AET is drawn from |
Expand Down
28 changes: 3 additions & 25 deletions src/bmi_cfe.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,23 @@
#define STATE_VAR_NAME_COUNT 94 // must match var_info array size


#define PARAM_VAR_NAME_COUNT 19
#define PARAM_VAR_NAME_COUNT 18
// NOTE: If you update the params, also update the unit test in ../test/main_unit_test_bmi.c
static const char *param_var_names[PARAM_VAR_NAME_COUNT] = {
"maxsmc", "satdk", "slope", "b", "Klf",
"Kn", "Cgw", "expon", "max_gw_storage",
"satpsi","wltsmc","alpha_fc","refkdt",
"a_Xinanjiang_inflection_point_parameter","b_Xinanjiang_shape_parameter","x_Xinanjiang_shape_parameter",
"Kinf_nash_surface",
"retention_depth_nash_surface",
"N_nash_subsurface"
"retention_depth_nash_surface"
};

static const char *param_var_types[PARAM_VAR_NAME_COUNT] = {
"double", "double", "double", "double", "double",
"double", "double", "double", "double",
"double", "double", "double", "double",
"double","double","double", "double",
"double", "int"
"double"
};
//----------------------------------------------
// Put variable info into a struct to simplify
Expand Down Expand Up @@ -1956,13 +1955,6 @@ static int Get_value_ptr (Bmi *self, const char *name, void **dest)
return BMI_SUCCESS;
}

if (strcmp (name, "N_nash_subsurface") == 0) {
cfe_state_struct *cfe_ptr;
cfe_ptr = (cfe_state_struct *) self->data;
*dest = (void*)&cfe_ptr->N_nash_subsurface;
return BMI_SUCCESS;
}

if (strcmp (name, "Kinf_nash_surface") == 0) {
cfe_state_struct *cfe_ptr;
cfe_ptr = (cfe_state_struct *) self->data;
Expand Down Expand Up @@ -2199,20 +2191,6 @@ static int Set_value (Bmi *self, const char *name, void *src)

}

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++)
cfe_ptr->nash_storage_subsurface[j] = 0.0;
}

if (strcmp (name, "storage_max_m") == 0) {
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;
Expand Down
17 changes: 2 additions & 15 deletions test/main_unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,41 +393,28 @@ main(int argc, const char *argv[]){
printf("\nTEST BMI MODEL PARAMETERS\n*************************\n");

//Set number of params -- UPDATE if params changed
#define PARAM_COUNT 19
#define PARAM_COUNT 18

// expected_param_names copied directly from param_var_names[PARAM_VAR_NAME_COUNT] in ../src/bmi_cfe.c
static const char *expected_param_names[PARAM_COUNT] = {
"maxsmc", "satdk", "slope", "b", "Klf",
"Kn", "Cgw", "expon", "max_gw_storage",
"satpsi","wltsmc","alpha_fc","refkdt",
"a_Xinanjiang_inflection_point_parameter","b_Xinanjiang_shape_parameter","x_Xinanjiang_shape_parameter",
"Kinf_nash_surface", "retention_depth_nash_surface",
"N_nash_subsurface"};
"Kinf_nash_surface", "retention_depth_nash_surface"};

double test_set_value = 4.2;
double test_get_value = 0.0;
int test_set_value_int = 5;
int test_get_value_int = 0;

// Loop through params to test get and set
for( int i = 0; i < PARAM_COUNT; i++ ) {
if(strcmp(expected_param_names[i], "N_nash_subsurface") == 0){
status = model->set_value(model, expected_param_names[i], &test_set_value_int);
assert(status == BMI_SUCCESS);
status = model->get_value(model, expected_param_names[i], &test_get_value_int);
assert(status == BMI_SUCCESS);
assert(test_set_value_int == test_get_value_int);
printf(" get & set values match for parameter: %s \n", expected_param_names[i]);
}
else {
status = model->set_value(model, expected_param_names[i], &test_set_value);
//if (status == BMI_FAILURE)return BMI_FAILURE;
assert(status == BMI_SUCCESS);
status = model->get_value(model, expected_param_names[i], &test_get_value);
assert(status == BMI_SUCCESS);
assert(test_set_value == test_get_value);
printf(" get & set values match for parameter: %s \n", expected_param_names[i]);
}
}

// Test BMI: CONTROL FUNCTION update_until()
Expand Down

0 comments on commit 919996b

Please sign in to comment.