Skip to content

Commit 09a213c

Browse files
authored
Merge pull request #129 from Deltares/kinwave_vars
Kinwave vars
2 parents 67b44da + b2c36fd commit 09a213c

File tree

12 files changed

+78
-52
lines changed

12 files changed

+78
-52
lines changed

docs/src/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
`restrapefficiency` in the sediment model.
1313
- New variables added to the `LandSediment` and `RiverSediment` structs in order to save
1414
more output from the sediment model.
15+
- Added variables `volume` and `inwater` to `SurfaceFlow` struct, this is convenient for the
16+
coupling with the water quality model Delwaq.
1517

1618
### Added
1719
- Modify model parameters and forcing through the TOML file (see [Modify parameters](@ref)).
@@ -22,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2224
### Fixed
2325
- Corrected a bug in sediment deposition in the river (case when incoming sediment load is
2426
more than the river transport capacity).
27+
- Fixed update of `snow` and `glacierstore` fields of HBV and SBM concepts by the
28+
`glacier_hbv` module.
2529

2630
## v0.2.0 - 2021-03-26
2731

src/flow.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
q::Vector{T} | "m3 s-1" # Discharge [m³ s⁻¹]
77
qin::Vector{T} | "m3 s-1" # Inflow from upstream cells [m³ s⁻¹]
88
q_av::Vector{T} | "m3 s-1" # Average discharge [m³ s⁻¹]
9-
qlat::Vector{T} | "m3 s-1" # Lateral discharge [m³ s⁻¹]
9+
qlat::Vector{T} | "m2 s-1" # Lateral inflow per unit length [m² s⁻¹]
10+
inwater::Vector{T} | "m3 s-1" # Lateral inflow [m³ s⁻¹]
11+
volume::Vector{T} | "m3" # Kinematic wave volume [m³] (based on water level h)
1012
h::Vector{T} | "m" # Water level [m]
1113
h_av::Vector{T} | "m" # Average water level [m]
1214
Δt::T | "s" # Model time step [s]
@@ -152,6 +154,7 @@ function update(
152154
sf.q_av .= q_sum ./ its
153155
sf.h_av .= h_sum ./ its
154156
sf.to_river .= sf.to_river ./ its
157+
sf.volume .= sf.dl .* sf.width .* sf.h
155158
end
156159

157160
@get_units @with_kw struct LateralSSF{T}

src/hbv.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ function update_after_snow(hbv::HBV, config)
136136
# Estimate the fraction of snow turned into ice (HBV-light).
137137
# Estimate glacier melt.
138138

139-
drysnow, snow2glacier, glacierstore, glaciermelt = glacier_hbv(
139+
hbv.snow[i], snow2glacier, hbv.glacierstore[i], glaciermelt = glacier_hbv(
140140
hbv.glacierfrac[i],
141141
hbv.glacierstore[i],
142-
hbv.drysnow[i],
142+
hbv.snow[i],
143143
hbv.temperature[i],
144144
hbv.g_tt[i],
145145
hbv.g_cfmax[i],

src/hbv_model.jl

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ function initialize_hbv_model(config::Config)
414414
qin = zeros(Float, n),
415415
q_av = zeros(Float, n),
416416
qlat = zeros(Float, n),
417+
inwater = zeros(Float, n),
418+
volume = zeros(Float, n),
417419
h = zeros(Float, n),
418420
h_av = zeros(Float, n),
419421
Δt = Float(tosecond(Δt)),
@@ -435,12 +437,8 @@ function initialize_hbv_model(config::Config)
435437
pcr_dir = dims_xy ? permute_indices(pcrdir) : pcrdir
436438
graph = flowgraph(ldd, inds, pcr_dir)
437439

438-
riverslope = ncread(
439-
nc,
440-
param(config, "input.lateral.river.slope");
441-
sel = inds_riv,
442-
type = Float,
443-
)
440+
riverslope =
441+
ncread(nc, param(config, "input.lateral.river.slope"); sel = inds_riv, type = Float)
444442
clamp!(riverslope, 0.00001, Inf)
445443
riverlength = riverlength_2d[inds_riv]
446444
riverwidth = riverwidth_2d[inds_riv]
@@ -470,6 +468,8 @@ function initialize_hbv_model(config::Config)
470468
qin = zeros(Float, nriv),
471469
q_av = zeros(Float, nriv),
472470
qlat = zeros(Float, nriv),
471+
inwater = zeros(Float, nriv),
472+
volume = zeros(Float, nriv),
473473
h = zeros(Float, nriv),
474474
h_av = zeros(Float, nriv),
475475
Δt = Float(tosecond(Δt)),
@@ -534,6 +534,10 @@ function initialize_hbv_model(config::Config)
534534
instate_path = joinpath(tomldir, config.state.path_input)
535535
state_ncnames = ncnames(config.state)
536536
set_states(instate_path, model, state_ncnames; type = Float)
537+
# update kinematic wave volume for river and land domain
538+
@unpack lateral = model
539+
lateral.land.volume .= lateral.land.h .* lateral.land.width .* lateral.land.dl
540+
lateral.river.volume .= lateral.river.h .* lateral.river.width .* lateral.river.dl
537541
end
538542

539543
# make sure the forcing is already loaded
@@ -575,9 +579,9 @@ function update(model::Model{N,L,V,R,W}) where {N,L,V<:HBV,R,W}
575579

576580
# determine lateral inflow for overland flow based on vertical runoff [mm] from vertical
577581
# hbv concept
578-
lateral.land.qlat .=
579-
(vertical.runoff .* network.land.xl .* network.land.yl .* 0.001) ./
580-
lateral.land.Δt ./ lateral.land.dl
582+
lateral.land.inwater .=
583+
(vertical.runoff .* network.land.xl .* network.land.yl .* 0.001) ./ lateral.land.Δt
584+
lateral.land.qlat .= lateral.land.inwater ./ lateral.land.dl
581585

582586
# run kinematic wave for overland flow
583587
update(
@@ -588,7 +592,8 @@ function update(model::Model{N,L,V,R,W}) where {N,L,V<:HBV,R,W}
588592
)
589593

590594
# determine lateral inflow (from overland flow) for river flow
591-
lateral.river.qlat .= (lateral.land.to_river[inds_riv]) ./ lateral.river.dl
595+
lateral.river.inwater .= copy(lateral.land.to_river[inds_riv])
596+
lateral.river.qlat .= lateral.river.inwater ./ lateral.river.dl
592597

593598
# run kinematic wave for river flow
594599
# check if reservoirs or lakes are defined, the inflow from overland flow is required

src/reservoir_lake.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
targetminfrac::Vector{T} | "-" # target minimum full fraction (of max storage) [-]
77
targetfullfrac::Vector{T} | "-" # target fraction full (of max storage) [-]
88
volume::Vector{T} | "m3" # reservoir volume [m³]
9-
inflow::Vector{T} | "m3" # inflow into reservoir [m³]
9+
inflow::Vector{T} | "m3" # inflow into reservoir [m³]
1010
outflow::Vector{T} | "m3 s-1" # outflow from reservoir [m³ s⁻¹]
1111
totaloutflow::Vector{T} | "m3" # total outflow from reservoir [m³]
1212
percfull::Vector{T} | "-" # fraction full (of max storage) [-]

src/sbm.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ function update_until_recharge(sbm::SBM, config)
743743
# Estimate the fraction of snow turned into ice (HBV-light).
744744
# Estimate glacier melt.
745745

746-
snow, snow2glacier, glacierstore, glaciermelt = glacier_hbv(
746+
sbm.snow[i], snow2glacier, sbm.glacierstore[i], glaciermelt = glacier_hbv(
747747
sbm.glacierfrac[i],
748748
sbm.glacierstore[i],
749749
sbm.snow[i],

src/sbm_gwf_model.jl

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ function initialize_sbm_gwf_model(config::Config)
5959
ncread(nc, param(config, "input.lateral.river.length"); type = Float, fill = 0)
6060
riverlength = riverlength_2d[inds]
6161

62-
altitude =
63-
ncread(nc, param(config, "input.altitude"); sel = inds, type = Float)
62+
altitude = ncread(nc, param(config, "input.altitude"); sel = inds, type = Float)
6463
# read x, y coordinates and calculate cell length [m]
6564
y_nc = "y" in keys(nc.dim) ? ncread(nc, "y") : ncread(nc, "lat")
6665
x_nc = "x" in keys(nc.dim) ? ncread(nc, "x") : ncread(nc, "lon")
@@ -139,6 +138,8 @@ function initialize_sbm_gwf_model(config::Config)
139138
qin = zeros(Float, n),
140139
q_av = zeros(Float, n),
141140
qlat = zeros(Float, n),
141+
inwater = zeros(Float, n),
142+
volume = zeros(Float, n),
142143
h = zeros(Float, n),
143144
h_av = zeros(Float, n),
144145
Δt = Float(tosecond(Δt)),
@@ -161,12 +162,8 @@ function initialize_sbm_gwf_model(config::Config)
161162
graph = flowgraph(ldd, inds, pcr_dir)
162163

163164
# river flow (kinematic wave)
164-
riverslope = ncread(
165-
nc,
166-
param(config, "input.lateral.river.slope");
167-
sel = inds_riv,
168-
type = Float,
169-
)
165+
riverslope =
166+
ncread(nc, param(config, "input.lateral.river.slope"); sel = inds_riv, type = Float)
170167
clamp!(riverslope, 0.00001, Inf)
171168
riverlength = riverlength_2d[inds_riv]
172169
riverwidth = riverwidth_2d[inds_riv]
@@ -193,6 +190,8 @@ function initialize_sbm_gwf_model(config::Config)
193190
q_av = zeros(Float, nriv),
194191
qin = zeros(Float, nriv),
195192
qlat = zeros(Float, nriv),
193+
inwater = zeros(Float, nriv),
194+
volume = zeros(Float, nriv),
196195
h = zeros(Float, nriv),
197196
h_av = zeros(Float, nriv),
198197
Δt = Float(tosecond(Δt)),
@@ -408,6 +407,10 @@ function initialize_sbm_gwf_model(config::Config)
408407
instate_path = joinpath(tomldir, config.state.path_input)
409408
state_ncnames = ncnames(config.state)
410409
set_states(instate_path, model, state_ncnames, type = Float)
410+
# update kinematic wave volume for river and land domain
411+
@unpack lateral = model
412+
lateral.land.volume .= lateral.land.h .* lateral.land.width .* lateral.land.dl
413+
lateral.river.volume .= lateral.river.h .* lateral.river.width .* lateral.river.dl
411414
end
412415

413416
# make sure the forcing is already loaded
@@ -489,9 +492,9 @@ function update_sbm_gwf(model)
489492

490493
# determine lateral inflow for overland flow based on vertical runoff [mm] from vertical
491494
# sbm concept
492-
lateral.land.qlat .=
493-
(vertical.runoff .* network.land.xl .* network.land.yl .* 0.001) ./
494-
lateral.land.Δt ./ lateral.land.dl
495+
lateral.land.inwater .=
496+
(vertical.runoff .* network.land.xl .* network.land.yl .* 0.001) ./ lateral.land.Δt
497+
lateral.land.qlat .= lateral.land.inwater ./ lateral.land.dl
495498
# run kinematic wave for overland flow
496499
update(
497500
lateral.land,
@@ -516,11 +519,10 @@ function update_sbm_gwf(model)
516519
end
517520

518521
# determine lateral inflow to river from groundwater, drains and overland flow
519-
lateral.river.qlat .=
520-
(
521-
flux_gw[inds_riv] ./ lateral.river.Δt .+ lateral.land.to_river[inds_riv] .+
522-
net_runoff_river
523-
) ./ lateral.river.dl
522+
lateral.river.inwater .=
523+
flux_gw[inds_riv] ./ lateral.river.Δt .+ lateral.land.to_river[inds_riv] .+
524+
net_runoff_river
525+
lateral.river.qlat .= lateral.river.inwater ./ lateral.river.dl
524526

525527
# run kinematic wave for river flow
526528
# check if reservoirs or lakes are defined, then the inflow from overland flow is

src/sbm_model.jl

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ function initialize_sbm_model(config::Config)
177177
qin = zeros(Float, n),
178178
q_av = zeros(Float, n),
179179
qlat = zeros(Float, n),
180+
inwater = zeros(Float, n),
181+
volume = zeros(Float, n),
180182
h = zeros(Float, n),
181183
h_av = zeros(Float, n),
182184
Δt = Float(tosecond(Δt)),
@@ -199,12 +201,8 @@ function initialize_sbm_model(config::Config)
199201
graph = flowgraph(ldd, inds, pcr_dir)
200202

201203

202-
riverslope = ncread(
203-
nc,
204-
param(config, "input.lateral.river.slope");
205-
sel = inds_riv,
206-
type = Float,
207-
)
204+
riverslope =
205+
ncread(nc, param(config, "input.lateral.river.slope"); sel = inds_riv, type = Float)
208206
clamp!(riverslope, 0.00001, Inf)
209207
riverlength = riverlength_2d[inds_riv]
210208
riverwidth = riverwidth_2d[inds_riv]
@@ -234,6 +232,8 @@ function initialize_sbm_model(config::Config)
234232
qin = zeros(Float, nriv),
235233
q_av = zeros(Float, nriv),
236234
qlat = zeros(Float, nriv),
235+
inwater = zeros(Float, nriv),
236+
volume = zeros(Float, nriv),
237237
h = zeros(Float, nriv),
238238
h_av = zeros(Float, nriv),
239239
Δt = Float(tosecond(Δt)),
@@ -310,14 +310,16 @@ function initialize_sbm_model(config::Config)
310310
state_ncnames = ncnames(config.state)
311311
set_states(instate_path, model, state_ncnames; type = Float)
312312
@unpack lateral, vertical = model
313-
# update zi for vertical sbm and α for river and overland flow
313+
# update zi for vertical sbm and kinematic wave volume for river and land domain
314314
zi =
315315
max.(
316316
0.0,
317317
vertical.soilthickness .-
318318
vertical.satwaterdepth ./ (vertical.θₛ .- vertical.θᵣ),
319319
)
320320
vertical.zi .= zi
321+
lateral.land.volume .= lateral.land.h .* lateral.land.width .* lateral.land.dl
322+
lateral.river.volume .= lateral.river.h .* lateral.river.width .* lateral.river.dl
321323
end
322324

323325
# make sure the forcing is already loaded
@@ -405,9 +407,10 @@ function update_after_subsurfaceflow(model::Model{N,L,V,R,W}) where {N,L,V<:SBM,
405407

406408
# determine lateral inflow for overland flow based on vertical runoff [mm] from vertical
407409
# sbm concept
408-
lateral.land.qlat .=
409-
(vertical.runoff .* network.land.xl .* network.land.yl .* 0.001) ./
410-
lateral.land.Δt ./ lateral.land.dl
410+
lateral.land.inwater .=
411+
(vertical.runoff .* network.land.xl .* network.land.yl .* 0.001) ./ lateral.land.Δt
412+
lateral.land.qlat .= lateral.land.inwater ./ lateral.land.dl
413+
411414
# run kinematic wave for overland flow
412415
update(
413416
lateral.land,
@@ -423,11 +426,11 @@ function update_after_subsurfaceflow(model::Model{N,L,V,R,W}) where {N,L,V<:SBM,
423426
vertical.net_runoff_river[inds_riv] .* network.land.xl[inds_riv] .*
424427
network.land.yl[inds_riv] .* 0.001
425428
) ./ vertical.Δt
426-
lateral.river.qlat .=
427-
(
428-
lateral.subsurface.to_river[inds_riv] ./ 1.0e9 ./ lateral.river.Δt .+
429-
lateral.land.to_river[inds_riv] .+ net_runoff_river
430-
) ./ lateral.river.dl
429+
lateral.river.inwater .= (
430+
lateral.subsurface.to_river[inds_riv] ./ 1.0e9 ./ lateral.river.Δt .+
431+
lateral.land.to_river[inds_riv] .+ net_runoff_river
432+
)
433+
lateral.river.qlat .= lateral.river.inwater ./ lateral.river.dl
431434

432435
# run kinematic wave for river flow
433436
# check if reservoirs or lakes are defined, the inflow from lateral subsurface and

test/bmi.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ tomlpath = joinpath(@__DIR__, "sbm_config.toml")
1818

1919
@testset "model information functions" begin
2020
@test BMI.get_component_name(model) == "sbm"
21-
@test BMI.get_input_item_count(model) == 175
22-
@test BMI.get_output_item_count(model) == 175
23-
@test BMI.get_input_var_names(model)[[1, 5, 120, 175]] == [
21+
@test BMI.get_input_item_count(model) == 179
22+
@test BMI.get_output_item_count(model) == 179
23+
@test BMI.get_input_var_names(model)[[1, 5, 120, 179]] == [
2424
"vertical.Δt",
2525
"vertical.n_unsatlayers",
2626
"lateral.land.q_av",
@@ -35,7 +35,7 @@ tomlpath = joinpath(@__DIR__, "sbm_config.toml")
3535
@test_throws ErrorException BMI.get_var_grid(model, "lateral.river.lake.volume")
3636
# Vector{Float64} printing on Julia 1.6+
3737
@test BMI.get_var_type(model, "lateral.river.reservoir.inflow") in
38-
["Array{$Float,1}", "Vector{$Float}"]
38+
["Array{$Float,1}", "Vector{$Float}"]
3939
@test BMI.get_var_type(model, "vertical.n") == "Int64"
4040
@test BMI.get_var_units(model, "vertical.θₛ") == "mm mm-1"
4141
@test BMI.get_var_itemsize(model, "lateral.subsurface.ssf") == sizeof(Float)

test/io.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,14 @@ end
184184
@test Wflow.param(model, "vertical.ustorelayerdepth")[1][1] 16.73013687133789
185185
@test Wflow.param(model, "vertical.snowwater")[41120] 0.42188167572021484
186186
@test Wflow.param(model, "vertical.canopystorage")[1] 0.0
187+
@test Wflow.param(model, "vertical.zi")[1] 380.67793082060416
187188
@test Wflow.param(model, "lateral.subsurface.ssf")[39308] 1.1614302208e11
188189
@test Wflow.param(model, "lateral.river.q")[5501] 111.46229553222656
189190
@test Wflow.param(model, "lateral.river.h")[5501] 8.555977821350098
191+
@test Wflow.param(model, "lateral.river.volume")[5501] 249163.33754433296
190192
@test Wflow.param(model, "lateral.land.q")[39626] 1.0575231313705444
191193
@test Wflow.param(model, "lateral.land.h")[39626] 0.03456519544124603
194+
@test Wflow.param(model, "lateral.land.volume")[39626] 19379.23274404319
192195
end
193196

194197
@testset "reducer" begin

test/run_hbv.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,13 @@ model = Wflow.update(model)
4545
@test hbv.snow[1] == 0.0
4646
end
4747

48-
@testset "overland flow" begin
48+
@testset "overland domain" begin
4949
q = model.lateral.land.q_av
50+
land = model.lateral.land
5051
@test sum(q) 3278.9423039643552f0
5152
@test q[500] 0.2348646912841589f0
53+
@test land.volume[500] 2057.7314802432425f0
54+
@test land.inwater[500] 0.027351853491789667f0
5255
@test q[1566] 0.030463805623037462f0
5356
@test q[network.land.order[end]] 0.296794455575309f0
5457
end

test/run_sbm_gwf.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@ end
4343
@test sum(q) 0.0
4444
end
4545

46-
@testset "river flow" begin
46+
@testset "river domain" begin
4747
q = model.lateral.river.q_av
48+
river = model.lateral.river
4849
@test sum(q) 0.03515257228971982f0
4950
@test q[6] 0.007952670041402076f0
51+
@test river.volume[6] 3.8923529548071025f0
52+
@test river.inwater[6] 0.0003950369148075657f0
5053
@test q[13] 0.0005980549969548235f0
5154
@test q[network.river.order[end]] 0.008482648782941154f0
5255
end

0 commit comments

Comments
 (0)