Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor SBM concept #487

Merged
merged 73 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
de91ed9
Remove vertical concepts `HBV` and `FLEXTopo` (#433)
vers-w Jul 1, 2024
5107824
Cleanup metadata macros (#434)
vers-w Jul 2, 2024
d21c930
Refactor/style guide (#437)
CFBaptista Jul 15, 2024
91b4019
WIP: refactor `SBM` interception
vers-w Jul 10, 2024
627a9e1
WIP: add `AtmosphericForcing` to store meteo input
vers-w Jul 11, 2024
e1a1491
WIP: remove unused type parameter `A` from `SBM`
vers-w Jul 11, 2024
a6f703c
WIP: add `RutterInterceptionModel`
vers-w Jul 11, 2024
4539ddb
WIP: refactor `SBM` snow
vers-w Jul 18, 2024
5ab02bf
Stop using local JULIAUP_DEPOT_PATH (#438) (#440)
vers-w Jul 18, 2024
86371da
WIP: refactor `SBM` glacier
vers-w Jul 18, 2024
4c109ab
WIP: introduce types `NoSnowModel` and `NoGlacierModel`
vers-w Jul 22, 2024
8314006
WIP: `model` in `update` functions and add wrapper methods
vers-w Jul 23, 2024
3b904b4
WIP: start refactor soil model of `SBM` (initialization)
vers-w Jul 23, 2024
6f0c958
Update of `SBM` soil model (until recharge)
vers-w Aug 26, 2024
5d42776
Update run of refactored sbm concept (sbm_model)
vers-w Aug 28, 2024
cf8c3be
Delete `soil` folder
vers-w Aug 28, 2024
9e84d9a
Add `SBM` functions to seperate file (bucket_process.jl)
vers-w Aug 29, 2024
25cad4e
Add water demand functionality
vers-w Sep 3, 2024
9819e21
Merge branch 'master' into v1
vers-w Sep 4, 2024
c4837e1
Merge branch 'v1' into refactor/sbm_concept
vers-w Sep 11, 2024
dcada29
Rename `vegetation_parameters` to `vegetation_parameter_set`
vers-w Sep 11, 2024
cacbe25
Fix test Wflow ZMQ Server
vers-w Sep 11, 2024
0d3644e
Refactor update of `LandHydrologySBM`
vers-w Sep 11, 2024
fc754dd
Further refactor of update `LandHydrologySBM`
vers-w Sep 12, 2024
a70ef57
Rename `bucket` to `soil` and add `SurfaceRunoff` model
vers-w Sep 17, 2024
9a188b1
Include `atmospheric_forcing` as a separate argument
vers-w Sep 18, 2024
2ae54ac
Remove land_parameter_set
vers-w Sep 18, 2024
33f3f38
Rename outer constructors and couple of structs
vers-w Sep 19, 2024
36d6dd4
Add parameter `soil_fraction` to `SbmSoilParameters`
vers-w Sep 19, 2024
37249ec
Move function for `soil_fraction` to soil.jl
vers-w Sep 19, 2024
be6f5b3
Rename model type `SurfaceRunoff` to `OpenWaterRunoff`
vers-w Sep 19, 2024
aea1bc8
Refactor water demand
vers-w Sep 24, 2024
43f0469
Move runoff,jl to separate folder
vers-w Sep 25, 2024
7bf917d
Refactor update `SbmSoilModel`
vers-w Oct 1, 2024
bc7905a
Use types for hydraulic conductivity profiles
vers-w Oct 7, 2024
de712ce
Rename `surface_water_flux` to `water_flux_surface`
vers-w Oct 7, 2024
a673114
Small updates
vers-w Oct 7, 2024
26e704e
Boundary conditions `SbmSoilModel`
vers-w Oct 7, 2024
f9e0050
FIx some non-concrete types
vers-w Oct 8, 2024
974f213
Delete log.txt file
vers-w Oct 9, 2024
326f466
Refactor water demand
vers-w Oct 10, 2024
137338f
Add docstrings to snow model
vers-w Oct 10, 2024
bc7914c
Add docstrings glacier model
vers-w Oct 10, 2024
e838b60
Add docstrings canopy and rename `interception_flux` variable
vers-w Oct 10, 2024
7ccdc7e
Add docstrings open water runoff model
vers-w Oct 14, 2024
18d92cf
Add docstrings SBM soil model
vers-w Oct 15, 2024
02023ff
Add docstrings water demand
vers-w Oct 16, 2024
0e3cb81
Add comment about metadata and BMI (Wflow.jl)
vers-w Oct 16, 2024
4b13ec7
Add docstrings to vegetation parameters
vers-w Oct 16, 2024
07e485c
Add docstrings atmospheric forcing
vers-w Oct 16, 2024
7101d9a
Cleanup metadata `get_units` and `grid_loc`
vers-w Oct 16, 2024
806b716
Update docstrings and comments
vers-w Oct 16, 2024
ae42952
Merge branch 'master' into v1
vers-w Oct 17, 2024
f3b86bc
Merge branch 'v1' into refactor/sbm_concept
vers-w Oct 17, 2024
945b080
Fix ZMQ Server tests
vers-w Oct 17, 2024
2818f68
Ksat_profile tests from PR #474
vers-w Oct 17, 2024
ce97556
Update changelog
vers-w Oct 17, 2024
dad4ffe
Update docstrings
vers-w Oct 18, 2024
09b901f
Add variable `snow_melt` to `SnowVariables`
vers-w Oct 18, 2024
455f1ef
Update changelog
vers-w Oct 21, 2024
429dfd8
Merge branch 'master' into refactor/sbm_concept
vers-w Oct 23, 2024
764ab16
Format Wflow.jl
vers-w Oct 23, 2024
20c4921
Suggestions from code review for water_demand
vers-w Oct 28, 2024
91604d6
Address remaining review comments water_demand
vers-w Oct 28, 2024
cc30210
Remaining suggestions from code review
vers-w Oct 28, 2024
0e06992
Address review comments
vers-w Oct 28, 2024
6612822
Address review comment
vers-w Oct 28, 2024
cdf73b6
Address review comment and bug fix
vers-w Oct 29, 2024
b1925ee
Fix typo
vers-w Oct 29, 2024
fca7d52
Address remaining comments 2nd reviewer
vers-w Oct 29, 2024
e0427b6
Merge branch 'refactor/sbm_concept' of https://github.com/Deltares/Wf…
vers-w Oct 29, 2024
4bc2697
Fix wflow server tests
vers-w Oct 29, 2024
8a999fb
Revert back to using `isnothing`
vers-w Nov 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Options for the JuliaFormatter auto syntax formatting tool.
# https://domluna.github.io/JuliaFormatter.jl/stable/
# https://docs.sciml.ai/SciMLStyle/stable/

# Based on the default style we do pick these non-default options from SciML style:
whitespace_ops_in_indices = true
remove_extra_newlines = true
always_for_in = true
whitespace_typedefs = true

# And add other options we like:
separate_kwargs_with_semicolon = true
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- master
- v1
tags: '*'
jobs:
test:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/CIWflowServer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- master
- v1
tags: '*'
jobs:
test:
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# General
.DS_Store

# VS Code stuff
.vscode

# Packaging stuff
*.jl.*.cov
*.jl.cov
Expand Down
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"[julia]": {
"editor.formatOnSave": true,
},
"julia.lint.disabledDirs": [
".pixi"
],
"julia.lint.run": true,
}
7 changes: 1 addition & 6 deletions build/create_binaries/download_test_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@ end

staticmaps_rhine_path = testdata(v"0.1", "staticmaps.nc", "staticmaps-rhine.nc")
staticmaps_moselle_path =
testdata(v"0.2.8", "staticmaps-moselle.nc", "staticmaps-moselle.nc")
staticmaps_lahn_path = testdata(v"0.2.1", "staticmaps-lahn.nc", "staticmaps-lahn.nc")
staticmaps_meuse_path =
testdata(v"0.2.8", "staticmaps_flex_meuse.nc", "staticmaps_flex_meuse.nc")
testdata(v"0.2.9", "staticmaps-moselle.nc", "staticmaps-moselle.nc")
forcing_moselle_path = testdata(v"0.2.6", "forcing-moselle.nc", "forcing-moselle.nc")
forcing_lahn_path = testdata(v"0.2", "forcing-lahn.nc", "forcing-lahn.nc")
forcing_moselle_sed_path =
testdata(v"0.2.3", "forcing-moselle-sed.nc", "forcing-moselle-sed.nc")
staticmaps_moselle_sed_path =
Expand All @@ -42,7 +38,6 @@ forcing_sbm_gw_path = testdata(
"forcing-sbm-groundwater-part2.nc",
"forcing-sbm-groundwater-part2.nc",
)
forcing_meuse_path = testdata(v"0.2.8", "forcing_meuse.nc", "forcing_meuse.nc")
staticmaps_sbm_gw_path =
testdata(v"0.2.3", "staticmaps-sbm-groundwater.nc", "staticmaps-sbm-groundwater.nc")
instates_sbm_gw_path =
Expand Down
18 changes: 10 additions & 8 deletions build/wflow_cli/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ using Test
using Wflow

extension = Sys.iswindows() ? ".exe" : ""
wflow_exe = normpath(@__DIR__, "../../create_binaries/wflow_bundle/bin/wflow_cli" * extension)
wflow_exe =
normpath(@__DIR__, "../../create_binaries/wflow_bundle/bin/wflow_cli" * extension)

# this assumes that the Wflow tests have already been run, so the data has been downloaded
testdir = abspath(dirname(pathof(Wflow)), "..", "test")
Expand All @@ -14,15 +15,15 @@ outputdir = joinpath(datadir, "output")

@testset "no_config" begin
# Clean output directory
rm(outputdir; force=true, recursive=true)
rm(outputdir; force = true, recursive = true)
@test_throws ProcessFailedException run(`$wflow_exe`)
# Check if no files are being created
@test !(isdir(outputdir))
end

@testset "wflow_sbm" begin
# Clean directory
rm(outputdir; force=true, recursive=true)
rm(outputdir; force = true, recursive = true)
# Run cli with the toml
toml = normpath(testdir, "sbm_config.toml")
run(`$wflow_exe $toml`)
Expand All @@ -43,7 +44,7 @@ end

@testset "wflow_sbm-gwf" begin
# Clean directory
rm(outputdir; force=true, recursive=true)
rm(outputdir; force = true, recursive = true)
# Run cli with the toml
toml = normpath(testdir, "sbm_gwf_config.toml")
run(`$wflow_exe $toml`)
Expand All @@ -63,7 +64,7 @@ end

@testset "wflow_sediment" begin
# Clean directory
rm(outputdir; force=true, recursive=true)
rm(outputdir; force = true, recursive = true)
# Run cli with the toml
toml = normpath(testdir, "sediment_config.toml")
run(`$wflow_exe $toml`)
Expand All @@ -82,11 +83,12 @@ end
end

@testset "wflow_sbm_timing" begin

toml = normpath(testdir, "sbm_config.toml")
time_sbm_1thread = @elapsed run(Cmd(`$wflow_exe $toml`, env=("JULIA_NUM_THREADS" => "1",)))
time_sbm_1thread =
@elapsed run(Cmd(`$wflow_exe $toml`; env = ("JULIA_NUM_THREADS" => "1",)))

time_sbm_4thread = @elapsed run(Cmd(`$wflow_exe $toml`, env=("JULIA_NUM_THREADS" => "4", )))
time_sbm_4thread =
@elapsed run(Cmd(`$wflow_exe $toml`; env = ("JULIA_NUM_THREADS" => "4",)))

# Test if run with more threads is indeed faster
@test time_sbm_4thread < time_sbm_1thread
Expand Down
2 changes: 0 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ pages = [
"model_docs/model_configurations.md",
"Vertical concepts" => [
"model_docs/vertical/sbm.md",
"model_docs/vertical/hbv.md",
"model_docs/vertical/flextopo.md",
"model_docs/vertical/sediment.md",
"model_docs/shared_concepts.md",
],
Expand Down
26 changes: 26 additions & 0 deletions docs/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Fixed
- Initialization of `LateralSSF` variables `ssf` and `ssfmax` with vertical hydraulic
conductivity profile `exponential_constant`. Removed parameter `khfrac` from the
computation, as it is already part of parameter `kh_0`.

### Changed
- Removed vertical concepts `HBV` and `FLEXTopo`.
- Removed metadata macros `exchange` and `grid_type`. The macro `grid_type` is not required
because this functionality is already part of `BMI`. The macro `exchange` is replaced by a
function used by `BMI`. Remaining metadata macros `get_units` and `grid_loc` are only used
by `BMI`.
- Refactor the vertical `SBM` concept: divide the long struct `SBM` into different model
components for interception, snow, glacier, (open water) runoff, soil, water demand and
allocation stored in the struct `LandHydrologySBM`. Additionally, the atmospheric forcing
and a shared vegetation parameterset are stored as separate fields in struct
`LandHydrologySBM` (with soil model `SbmSoilModel`). The model component structs have
model `variables`, `parameters` and `boundary_conditions` (if applicable), including
associated functions for initializing and updating these model components. The original
long update function of the `SBM` soil part has been split into separate functions.

### Added
- Support direct output of snow and glacier melt, and add computation of snow water
equivalent (SWE).

## v0.8.1 - 2024-08-27

### Fixed
Expand Down
Binary file removed docs/src/images/flextopo_julia_1class.png
Binary file not shown.
Binary file removed docs/src/images/flextopo_julia_3class.png
Binary file not shown.
Binary file removed docs/src/images/hbv-soilmoist.png
Binary file not shown.
Binary file removed docs/src/images/hbv-upper.png
Binary file not shown.
Binary file removed docs/src/images/hbv96.png
Binary file not shown.
130 changes: 2 additions & 128 deletions docs/src/model_docs/model_configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,128 +131,6 @@ lateral.land => struct ShallowWaterLand{T}
The local inertial approach is described in more detail in the section [Local inertial
model](@ref local_inertial).

## [wflow\_hbv](@id config_hbv)
The Hydrologiska Byrans Vattenbalansavdelning (HBV) model was introduced back in 1972 by the
Swedish Meteological and Hydrological Institute (SMHI). The HBV model is mainly used for
runoff simulation and hydrological forecasting. The model is particularly useful for
catchments where snow fall and snow melt are dominant factors, but application of the model
is by no means restricted to these type of catchments.

The model is based on the HBV-96 model. However, the hydrological routing represented in HBV
by a triangular function controlled by the MAXBAS parameter has been removed. Instead, the
kinematic wave function is used to route the water downstream. All runoff that is generated
in a cell in one of the HBV reservoirs is added to the kinematic wave reservoir at the end
of a timestep. There is no connection between the different HBV cells within the model.

A catchment is divided into a number of grid cells. For each of the cells individually,
daily runoff is computed through application of the HBV-96 of the HBV model. The use of the
grid cells offers the possibility to turn the HBV modelling concept, which is originally
lumped, into a distributed model.

![wflow_hbv model](../images/hbv96.png)

The figure above shows a schematic view of hydrological response simulation with the
HBV-modelling concept. The land-phase of the hydrological cycle is represented by three
different components: a snow routine, a soil routine and a runoff response routine. Each
component is discussed in more detail below.

The vertical HBV concept is described in section [HBV vertical concept](@ref vert_hbv). The
routing for river and overland flow is described in the section [Kinematic wave](@ref
kin_wave).

Below the mapping for wflow\_hbv (type `hbv`) to the vertical HBV concept (instance of
`struct HBV`) and the different lateral concepts. For an explanation about the type
parameters between curly braces after the `struct` name see the section on model parameters.

```julia
vertical => struct HBV{T}
lateral.subsurface => struct LateralSSF{T}
lateral.land => struct SurfaceFlow{T,R,L}
lateral.river => struct SurfaceFlow{T,R,L}
lateral.river.lake => struct NaturalLake{T} # optional
lateral.river.reservoir => struct SimpleReservoir{T} # optional
```

## [wflow\_flextopo](@id config_flextopo)
The FLEXTopo model is a process-based model, which consists of different parallel classes
connected through their groundwater storage. These classes are usually delineated from
topographical data to represent the variability in hydrological processes across
user-defined Hydrological Response Units (HRU). The main assumption underlying the concept,
which was first introduced by Savenije (2010), is that different parts of the landscape
fulfill different tasks in runoff generation and, hence, can be represented by different
model structures. The strength of the concept is that the definition of classes and
associated model structures is modular and flexible and not fixed to a predefined model
structure. The flexible approach allows to develop process-based models for different
topographic, climatic, geologic and land use conditions, making use of the available data
and expert knowledge.

The kinematic wave function is used to route the water downstream. In a similar way as for
HBV, all runoff that is generated in a cell in one of the FLEXTopo storages is added to the
kinematic wave reservoir at the end of a timestep. There is no connection between the
different vertical FLEXTopo cells within the model. The FLEXTopo model is implemented in a
fully distributed way in the wflow Julia framework.

In wflow\_flextopo, the user is free to determine the number of classes and which model
components to include or exclude for each class, this is done in the TOML file. Currently,
for each storage, it is possible to bypass the storage and pass on the fluxes to the next
model component. Interested users can contribute to the code by adding other
conceptualizations for each storage components.

```julia
[model]
type = "flextopo"
classes = ["h", "p", "w"] #user can set the number and name of each class.

# for each component which is class specific, the user can select which conceptualization
# to apply for each class as defined above in classes = ["h", "p", "w"]
select_snow = ["common_snow_hbv"]
# available options are ["common_snow_hbv", "common_snow_no_storage"]
select_interception = ["interception_overflow", "interception_overflow", "interception_overflow"]
# available options are ["interception_overflow", "interception_no_storage"]
select_hortonponding = ["hortonponding_no_storage", "hortonponding_no_storage", "hortonponding_no_storage"]
# available options are ["hortonponding", "hortonponding_no_storage"]
select_hortonrunoff = ["hortonrunoff_no_storage", "hortonrunoff_no_storage", "hortonrunoff_no_storage"]
# available options are ["hortonrunoff", "hortonrunoff_no_storage"]
select_rootzone = ["rootzone_storage", "rootzone_storage", "rootzone_storage"]
# available options are ["rootzone_storage", "rootzone_no_storage"]
select_fast = ["fast_storage", "fast_storage", "fast_storage"]
# available options are ["fast_storage", "fast_no_storage"]
select_slow = ["common_slow_storage"]
# available options are ["common_slow_storage", "slow_no_storage"]
```

A schematic representation of the most complete model structure including all storage
components, as currently implemented in the code, is shown in the Figure below. When setting
up the model with multiple classes, model structures can be adapted by bypassing storages or
turning parameter values on or off (e.g.: percolation or capillary rise, non-linear versus
linear outflow of the fast runoff etc.), an example of a three class model is shown in
[FLEXTopo vertical concept](@ref vert_flextopo).

![flextopo_julia_1class.png](../images/flextopo_julia_1class.png)
*Schematic representation of the FLEXTopo model for a single class model including all
storages and fluxes. Main parameters are denoted in red.*

In the staticmaps, the user needs to provide maps of the fraction of each class within each
cell, as shown below with `hrufrac`. For each model parameter which is class specific, an
extra dimension `classes` is required in the staticmaps netcdf. For an example model, see
[FLEXTopo example model](@ref wflow_flextopo_data).

```julia
[input.vertical]
hrufrac = "hrufrac_lu"
```

Parameter multiplication of model parameters which are defined for several classes is
possible through the TOML file:

```julia
[input.vertical.kf]
netcdf.variable.name = "kf"
scale = [1.0, 3.0, 4.0]
offset = [0.0, 0.0, 0.0]
class = ["h", "p", "w"]
```

## [wflow\_sediment](@id config_sediment)
The processes and fate of many particles and pollutants impacting water quality at the
catchment level are intricately linked to the processes governing sediment dynamics. Both
Expand Down Expand Up @@ -292,8 +170,7 @@ required dynamic inputs to run wflow\_sediment are:
- River water level in the kinematic wave,
- Rainfall interception by the vegetation.

These inputs can be obtained from other wflow models such as wflow\_sbm, wflow\_hbv or from
other sources.
These inputs can be obtained from wflow\_sbm or from other sources.

Model outputs can be saved for both the inland and the instream part of the model. Some
examples are listed below.
Expand Down Expand Up @@ -331,7 +208,4 @@ Bedconc = "Bedconc"
## References
+ Köhler, L., Mulligan, M., Schellekens, J., Schmid, S., Tobón, C., 2006, Hydrological
impacts of converting tropical montane cloud forest to pasture, with initial reference to
northern Costa Rica. Final Technical Report DFID‐FRP Project No. R799.

+ Savenije, H. H. G. (2010). HESS opinions “topography driven conceptual modelling (FLEX-Topo).”
Hydrology and Earth System Sciences, 14(12), 2681–2692. https://doi.org/10.5194/hess-14-2681-2010
northern Costa Rica. Final Technical Report DFID‐FRP Project No. R799.
Loading
Loading