From 1256662456024f146aa7661b148cc2ca86f61168 Mon Sep 17 00:00:00 2001 From: Willem van Verseveld Date: Wed, 11 Dec 2024 13:53:04 +0100 Subject: [PATCH] Change vegetation model parameters Rename these parameters to standard names. Additionally, made a start with standard name mapping (external standard name => internal model name). It makes use of `Wflow.param` functionality as much as possible, allowing to write any model output variable with the former TOML keys. --- server/test/sbm_config.toml | 30 +++++------------- src/Wflow.jl | 1 + src/io.jl | 5 +-- src/parameters.jl | 16 +++++----- src/standard_name.jl | 5 +++ src/vegetation/canopy.jl | 2 +- test/run_sbm.jl | 8 ++--- test/sbm_config.toml | 19 +++++------ test/sbm_gw.toml | 45 ++++++++++++--------------- test/sbm_gwf_config.toml | 13 +++----- test/sbm_gwf_piave_demand_config.toml | 20 +++++------- test/sbm_piave_config.toml | 20 +++++------- test/sbm_piave_demand_config.toml | 20 +++++------- test/sbm_simple.toml | 12 ++++--- test/sbm_swf_config.toml | 19 +++++------ 15 files changed, 103 insertions(+), 132 deletions(-) create mode 100644 src/standard_name.jl diff --git a/server/test/sbm_config.toml b/server/test/sbm_config.toml index d84ae379a..850520ef0 100644 --- a/server/test/sbm_config.toml +++ b/server/test/sbm_config.toml @@ -75,6 +75,13 @@ soil_water_sat-zone_bottom__max_leakage_volume_flux = "MaxLeakage" "soil_root~wet__sigmoid_function_shape_parameter" = "rootdistpar" soil__thickness = "SoilThickness" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" + # specify the internal IDs of the parameters which vary over time # the external name mapping needs to be below together with the other mappings forcing = [ @@ -83,14 +90,7 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -cyclic = ["vertical.vegetation_parameter_set.leaf_area_index"] - -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" +cyclic = ["vegetation__leaf-area_index"] [input.vertical.runoff.parameters] waterfrac = "WaterFrac" @@ -103,20 +103,6 @@ potential_evaporation = "pet" precipitation = "precip" temperature = "temp" -[input.vertical.soil.parameters] -c = "c" -cf_soil = "cf_soil" -f = "f" -infiltcappath = "InfiltCapPath" -infiltcapsoil = "InfiltCapSoil" -water_holding_capacity = "WHC" -theta_r = "thetaR" -theta_s = "thetaS" -maxleakage = "MaxLeakage" -pathfrac = "PathFrac" -rootdistpar = "rootdistpar" -soilthickness = "SoilThickness" - [input.soil_surface_water__vertical_saturated_hydraulic_conductivity] netcdf.variable.name = "KsatVer" scale = 1.0 diff --git a/src/Wflow.jl b/src/Wflow.jl index 2f19e7585..f07ec4edd 100644 --- a/src/Wflow.jl +++ b/src/Wflow.jl @@ -112,6 +112,7 @@ function Clock(config, reader) return Clock(starttime, 0, dt) end +include("standard_name.jl") include("io.jl") """ diff --git a/src/io.jl b/src/io.jl index 90d2da595..1b3f041da 100644 --- a/src/io.jl +++ b/src/io.jl @@ -26,6 +26,7 @@ function param(obj, fields, default) return default end end +get_fields(name) = haskey(standard_name_map, name) ? standard_name_map[name] : name """ Config(path::AbstractString) @@ -718,8 +719,8 @@ function prepare_reader(config) cyclic_parameters = Dict{Tuple{Symbol, Vararg{Symbol}}, NamedTuple}() cyclic_times = Dict{Tuple{Symbol, Vararg{Symbol}}, Vector{Tuple{Int, Int}}}() for par in config.input.cyclic - fields = symbols(par) - ncname, mod = ncvar_name_modifier(param(config.input, fields)) + fields = symbols(get_fields(par)) #TODO: make this more restrict (only allow variables in `standard_name_map`) + ncname, mod = ncvar_name_modifier(param(config.input, par)) i = findfirst(x -> startswith(x, "time"), dimnames(cyclic_dataset[ncname])) dimname = dimnames(cyclic_dataset[ncname])[i] cyclic_nc_times = collect(cyclic_dataset[dimname]) diff --git a/src/parameters.jl b/src/parameters.jl index 0200feb2c..63254d89b 100644 --- a/src/parameters.jl +++ b/src/parameters.jl @@ -24,7 +24,7 @@ function VegetationParameters(dataset, config, indices) rootingdepth = ncread( dataset, config, - "vertical.vegetation_parameter_set.rootingdepth"; + "vegetation_root__depth"; sel = indices, defaults = 750.0, type = Float, @@ -32,16 +32,16 @@ function VegetationParameters(dataset, config, indices) kc = ncread( dataset, config, - "vertical.vegetation_parameter_set.kc"; + "vegetation__crop_factor"; sel = indices, defaults = 1.0, type = Float, ) - if haskey(config.input.vertical.vegetation_parameter_set, "leaf_area_index") + if haskey(config.input, "vegetation__leaf-area_index") storage_specific_leaf = ncread( dataset, config, - "vertical.vegetation_parameter_set.storage_specific_leaf"; + "vegetation__specific-leaf_storage"; optional = false, sel = indices, type = Float, @@ -49,7 +49,7 @@ function VegetationParameters(dataset, config, indices) storage_wood = ncread( dataset, config, - "vertical.vegetation_parameter_set.storage_wood"; + "vegetation_woody-part__storage_capacity"; optional = false, sel = indices, type = Float, @@ -57,7 +57,7 @@ function VegetationParameters(dataset, config, indices) kext = ncread( dataset, config, - "vertical.vegetation_parameter_set.kext"; + "vegetation_canopy__light-extinction_coefficient"; optional = false, sel = indices, type = Float, @@ -76,7 +76,7 @@ function VegetationParameters(dataset, config, indices) canopygapfraction = ncread( dataset, config, - "vertical.vegetation_parameter_set.canopygapfraction"; + "vegetation_canopy__gap_fraction"; sel = indices, defaults = 0.1, type = Float, @@ -84,7 +84,7 @@ function VegetationParameters(dataset, config, indices) cmax = ncread( dataset, config, - "vertical.vegetation_parameter_set.cmax"; + "vegetation_water__storage_capacity"; sel = indices, defaults = 1.0, type = Float, diff --git a/src/standard_name.jl b/src/standard_name.jl new file mode 100644 index 000000000..a1dc9c7c8 --- /dev/null +++ b/src/standard_name.jl @@ -0,0 +1,5 @@ + +const standard_name_map = Dict{String,String}( + "vegetation__leaf-area_index" => "vertical.vegetation_parameter_set.leaf_area_index", + "river_water__volume_inflow_rate"=> "lateral.river.boundary_conditions.inflow", +) \ No newline at end of file diff --git a/src/vegetation/canopy.jl b/src/vegetation/canopy.jl index 2ab44e7ce..d8af07f08 100644 --- a/src/vegetation/canopy.jl +++ b/src/vegetation/canopy.jl @@ -43,7 +43,7 @@ function GashInterceptionModel(dataset, config, indices, vegetation_parameter_se e_r = ncread( dataset, config, - "vertical.interception.parameters.e_r"; + "vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio"; sel = indices, defaults = 0.1, type = Float, diff --git a/test/run_sbm.jl b/test/run_sbm.jl index b50108db2..53a5b49d9 100644 --- a/test/run_sbm.jl +++ b/test/run_sbm.jl @@ -185,7 +185,7 @@ config.input.vertical.atmospheric_forcing.potential_evaporation = Dict( "offset" => 1.50, "netcdf" => Dict("variable" => Dict("name" => "pet")), ) -config.input.vertical.vegetation_parameter_set.leaf_area_index = +config.input["vegetation__leaf-area_index"] = Dict("scale" => 1.6, "netcdf" => Dict("variable" => Dict("name" => "LAI"))) model = Wflow.initialize_sbm_model(config) @@ -208,10 +208,10 @@ tomlpath = joinpath(@__DIR__, "sbm_config.toml") config = Wflow.Config(tomlpath) config.input.cyclic = [ - "vertical.vegetation_parameter_set.leaf_area_index", - "lateral.river.boundary_conditions.inflow", + "vegetation__leaf-area_index", + "river_water__volume_inflow_rate", ] -Dict(config.input.lateral.river)["boundary_conditions"] = Dict("inflow" => "inflow") +config.input.river_water__volume_inflow_rate = "inflow" model = Wflow.initialize_sbm_model(config) Wflow.run_timestep!(model) diff --git a/test/sbm_config.toml b/test/sbm_config.toml index 259b78296..4d93d5dad 100644 --- a/test/sbm_config.toml +++ b/test/sbm_config.toml @@ -75,6 +75,13 @@ soil_water_sat-zone_bottom__max_leakage_volume_flux = "MaxLeakage" "soil_root~wet__sigmoid_function_shape_parameter" = "rootdistpar" soil__thickness = "SoilThickness" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" + # specify the internal IDs of the parameters which vary over time # the external name mapping needs to be below together with the other mappings forcing = [ @@ -83,21 +90,11 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -cyclic = ["vertical.vegetation_parameter_set.leaf_area_index"] - -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" +cyclic = ["vegetation__leaf-area_index"] [input.vertical.runoff.parameters] waterfrac = "WaterFrac" -[input.vertical.interception.parameters] -e_r = "EoverR" - [input.vertical.atmospheric_forcing] potential_evaporation = "pet" precipitation = "precip" diff --git a/test/sbm_gw.toml b/test/sbm_gw.toml index 1912b9321..675e85792 100644 --- a/test/sbm_gw.toml +++ b/test/sbm_gw.toml @@ -58,6 +58,25 @@ atmosphere_air__snowfall_temperature_interval = "TTI" snowpack__melting_temperature_threshold = "TTM" snowpack__degree-day_coefficient = "Cfmax" +soil_water__brooks-corey_epsilon_parameter = "c" +soil_surface_water__infiltration_reduction_parameter = "cf_soil" +soil_water__vertical_saturated_hydraulic_conductivity_scale_parameter = "f" +"soil~compacted_surface_water__infiltration_capacity" = "InfiltCapPath" +"soil~non-compacted_surface_water__infiltration_capacity" = "InfiltCapSoil" +soil_water__residual_volume_fraction = "thetaR" +soil_water__saturated_volume_fraction = "thetaS" +soil_water_sat-zone_bottom__max_leakage_volume_flux = "MaxLeakage" +"soil~compacted__area_fraction" = "PathFrac" +"soil_root~wet__sigmoid_function_shape_parameter" = "rootdistpar" +soil__thickness = "SoilThickness" + +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" + # specify the internal IDs of the parameters which vary over time # the external name mapping needs to be below together with the other mappings forcing = [ @@ -66,40 +85,16 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -cyclic = ["vertical.vegetation_parameter_set.leaf_area_index"] +cyclic = ["vegetation__leaf-area_index"] [input.vertical.atmospheric_forcing] potential_evaporation = "pet" precipitation = "precip" temperature = "temp" -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" - [input.vertical.runoff.parameters] waterfrac = "WaterFrac" -[input.vertical.soil.parameters] -c = "c" -cf_soil = "cf_soil" -cfmax = "Cfmax" -e_r = "EoverR" -f = "f" -infiltcappath = "InfiltCapPath" -infiltcapsoil = "InfiltCapSoil" -kv_0 = "KsatVer" -maxleakage = "MaxLeakage" -pathfrac = "PathFrac" -rootdistpar = "rootdistpar" -rootingdepth = "RootingDepth" -soilthickness = "SoilThickness" -theta_r = "thetaR" -theta_s = "thetaS" - [input.lateral.river] length = "wflow_riverlength" mannings_n = "N_River" diff --git a/test/sbm_gwf_config.toml b/test/sbm_gwf_config.toml index bfd72592a..08906e109 100644 --- a/test/sbm_gwf_config.toml +++ b/test/sbm_gwf_config.toml @@ -55,6 +55,11 @@ soil_water__saturated_volume_fraction = "thetaS" "soil~compacted__area_fraction" = "PathFrac" soil__thickness = "soilthickness" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation_root__depth = "rootingdepth" +vegetation_canopy__gap_fraction = "canopygapfraction" +vegetation_water__storage_capacity = "cmax" + # specify the internal IDs of the parameters which vary over time # the external name mapping needs to be below together with the other mappings forcing = [ @@ -62,14 +67,6 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -[input.vertical.vegetation_parameter_set] -rootingdepth = "rootingdepth" -canopygapfraction = "canopygapfraction" -cmax = "cmax" - -[input.vertical.interception.parameters] -e_r = "EoverR" - [input.vertical.atmospheric_forcing] potential_evaporation = "PET" precipitation = "P" diff --git a/test/sbm_gwf_piave_demand_config.toml b/test/sbm_gwf_piave_demand_config.toml index d0fa2a59a..703ad565f 100644 --- a/test/sbm_gwf_piave_demand_config.toml +++ b/test/sbm_gwf_piave_demand_config.toml @@ -52,6 +52,13 @@ soil_water__vertical_saturated_hydraulic_conductivity_factor = "kvfrac" "vegetation_root__feddes_critial_pressure_head_h~3~high" = "h3_high" "vegetation_root__feddes_critial_pressure_head_h~3~low" = "h3_low" "vegetation_root__feddes_critial_pressure_head_h~4" = "h4" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" +vegetation__crop_factor = "crop_factor" forcing = [ "vertical.atmospheric_forcing.precipitation", @@ -59,7 +66,7 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] cyclic = [ - "vertical.vegetation_parameter_set.leaf_area_index", + "vegetation__leaf-area_index", "vertical.demand.domestic.demand.demand_gross", "vertical.demand.domestic.demand.demand_net", "vertical.demand.industry.demand.demand_gross", @@ -109,17 +116,6 @@ head = "head" [input.vertical.glacier.variables] glacier_store = "wflow_glacierstore" -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" -kc = "crop_factor" - -[input.vertical.interception.parameters] -e_r = "EoverR" - [input.vertical.atmospheric_forcing] potential_evaporation = "pet" precipitation = "precip" diff --git a/test/sbm_piave_config.toml b/test/sbm_piave_config.toml index 5f82ec756..778e49f7b 100644 --- a/test/sbm_piave_config.toml +++ b/test/sbm_piave_config.toml @@ -49,6 +49,13 @@ soil__thickness = "SoilThickness" "vegetation_root__feddes_critial_pressure_head_h~3~high" = "h3_high" "vegetation_root__feddes_critial_pressure_head_h~3~low" = "h3_low" "vegetation_root__feddes_critial_pressure_head_h~4" = "h4" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" +vegetation__crop_factor = "crop_factor" forcing = [ "vertical.atmospheric_forcing.precipitation", @@ -56,7 +63,7 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -cyclic = ["vertical.vegetation_parameter_set.leaf_area_index"] +cyclic = ["vegetation__leaf-area_index"] [model] type = "sbm" @@ -90,17 +97,6 @@ glacier_store = "glacierstore" [input.vertical.glacier.variables] glacier_store = "wflow_glacierstore" -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" -kc = "crop_factor" - -[input.vertical.interception.parameters] -e_r = "EoverR" - [input.vertical.atmospheric_forcing] potential_evaporation = "pet" precipitation = "precip" diff --git a/test/sbm_piave_demand_config.toml b/test/sbm_piave_demand_config.toml index f7920b04d..af893d552 100644 --- a/test/sbm_piave_demand_config.toml +++ b/test/sbm_piave_demand_config.toml @@ -50,6 +50,13 @@ soil_water__vertical_saturated_hydraulic_conductivity_factor = "kvfrac" "vegetation_root__feddes_critial_pressure_head_h~3~high" = "h3_high" "vegetation_root__feddes_critial_pressure_head_h~3~low" = "h3_low" "vegetation_root__feddes_critial_pressure_head_h~4" = "h4" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" +vegetation__crop_factor = "crop_factor" forcing = [ "vertical.atmospheric_forcing.precipitation", @@ -57,7 +64,7 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] cyclic = [ - "vertical.vegetation_parameter_set.leaf_area_index", + "vegetation__leaf-area_index", "vertical.demand.domestic.demand.demand_gross", "vertical.demand.domestic.demand.demand_net", "vertical.demand.industry.demand.demand_gross", @@ -103,17 +110,6 @@ h = "h_paddy" [input.vertical.glacier.variables] glacier_store = "wflow_glacierstore" -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" -kc = "crop_factor" - -[input.vertical.interception.parameters] -e_r = "EoverR" - [input.vertical.atmospheric_forcing] potential_evaporation = "pet" precipitation = "precip" diff --git a/test/sbm_simple.toml b/test/sbm_simple.toml index 0347e232c..f65da17bc 100644 --- a/test/sbm_simple.toml +++ b/test/sbm_simple.toml @@ -35,6 +35,13 @@ soil_water_sat-zone_bottom__max_leakage_volume_flux = "MaxLeakage" "soil_root~wet__sigmoid_function_shape_parameter" = "rootdistpar" soil__thickness = "SoilThickness" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" + # specify the internal IDs of the parameters which vary over time # the external name mapping needs to be below together with the other mappings forcing = [ @@ -43,7 +50,7 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -cyclic = ["vertical.vegetation_parameter_set.leaf_area_index"] +cyclic = ["vegetation__leaf-area_index"] [input.vertical.vegetation_parameter_set] leaf_area_index = "LAI" @@ -52,9 +59,6 @@ storage_specific_leaf = "Sl" storage_wood = "Swood" rootingdepth = "RootingDepth" -[input.vertical.interception.parameters] -e_r = "EoverR" - [input.vertical.atmospheric_forcing] potential_evaporation = "pet" precipitation = "precip" diff --git a/test/sbm_swf_config.toml b/test/sbm_swf_config.toml index 788f345eb..8c23f2b82 100644 --- a/test/sbm_swf_config.toml +++ b/test/sbm_swf_config.toml @@ -71,6 +71,13 @@ soil_water_sat-zone_bottom__max_leakage_volume_flux = "MaxLeakage" "soil_root~wet__sigmoid_function_shape_parameter" = "rootdistpar" soil__thickness = "SoilThickness" +vegetation_canopy_water__mean_evaporation-to-mean_precipitation_ratio = "EoverR" +vegetation__leaf-area_index = "LAI" +vegetation_canopy__light-extinction_coefficient = "Kext" +vegetation__specific-leaf_storage = "Sl" +vegetation_woody-part__storage_capacity = "Swood" +vegetation_root__depth = "RootingDepth" + # specify the internal IDs of the parameters which vary over time # the external name mapping needs to be below together with the other mappings forcing = [ @@ -79,17 +86,7 @@ forcing = [ "vertical.atmospheric_forcing.potential_evaporation", ] -cyclic = ["vertical.vegetation_parameter_set.leaf_area_index"] - -[input.vertical.vegetation_parameter_set] -leaf_area_index = "LAI" -kext = "Kext" -storage_specific_leaf = "Sl" -storage_wood = "Swood" -rootingdepth = "RootingDepth" - -[input.vertical.interception.parameters] -e_r = "EoverR" +cyclic = ["vegetation__leaf-area_index"] [input.vertical.atmospheric_forcing] potential_evaporation = "pet"