Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
gijsber committed Jan 29, 2024
1 parent 9e04353 commit 8cde41a
Show file tree
Hide file tree
Showing 3 changed files with 313 additions and 126 deletions.
7 changes: 7 additions & 0 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ website:
navbar:
logo: https://user-images.githubusercontent.com/4471859/224825908-bee7e044-bc6b-4561-8b08-5d330cce3ed5.png
left:
- text: "Model concept"
file: modelconcept/index.qmd
- text: "Julia core"
file: core/index.qmd
- text: "Python tooling"
Expand All @@ -23,6 +25,11 @@ website:
aria-label: GitHub

sidebar:
- title: "Model concept"
contents:
- modelconcept/index.qmd
- core/equations.qmd
- core/allocation.qmd
- title: "Julia core"
contents:
- core/index.qmd
Expand Down
310 changes: 184 additions & 126 deletions docs/index.qmd
Original file line number Diff line number Diff line change
@@ -1,171 +1,229 @@
---
title: "Ribasim"
title: Ribasim
---

Ribasim is a water resources model, designed to be the replacement of the regional surface
water modules Mozart and SIMRES in the Netherlands Hydrological Instrument (NHI). Ribasim is
a work in progress, it is a prototype that demonstrates all essential functionalities.
Further development of the prototype in a software release is planned in 2022 and 2023.
# Introduction {#sec-introduction}

Ribasim is written in the [Julia programming language](https://julialang.org/) and is built
on top of the [SciML: Open Source Software for Scientific Machine Learning](https://sciml.ai/)
libraries, notably [DifferentialEquations.jl](https://docs.sciml.ai/DiffEqDocs/stable/).
Decision makers need to balance the supply and demand of water in complex situations at the river basin scale and under increasing pressure from
climate change. RIBASIM provides a free software tool to visualize, evaluate and prioritize water allocation strategies based on their impact.
This provides insights to decision makers, enabling them to build consensus amongst water users and make smart decisions about how to manage
water resources optimally considering uncertainties now and in the future.

::: {layout-ncol=2 layout-valign="bottom"}
<a href="https://www.deltares.nl/">
<img alt="Deltares logo"
src="https://user-images.githubusercontent.com/4471859/187672447-adb9cb11-16ca-488b-bef9-08e059fe6d55.svg"
height="60">
</a>
RIBASIM is a water resources simulator composed of 3 conceptual layers:
a physical layer representing water bodies and associated infrastructure,
a rule-based control layer to manage the infrastructure, and
a priority-based allocation layer to take centralized decisions on user abstractions.

<a href="https://nhi.nu/">
<img alt="NHI logo"
src="https://user-images.githubusercontent.com/4471859/187672456-874b344a-9ad3-42b5-af6a-93517f7fbbe8.png"
height="60">
</a>
:::
Typically hydrological processes on land will be represented by other models which can be coupled (online) to Ribasim. Currently, an online
coupling with MODFLOW 6 (groundwater) and with Metaswap + MODFLOW 6 (unsaturated zone + groundwater) is available.
This version of Ribasim is the follow up of the legacy fortran kernel of Ribasim (version 7) applied world wide, the fortran kernel SIMRES
applied in the Netherlands, and the surface water models Distribution Model and Mozart of the Dutch National Hydrologhical Instrument.

# Download {#sec-download}

- Ribasim executable - Linux: [ribasim_cli_linux.zip](https://github.com/Deltares/Ribasim/releases/latest/download/ribasim_cli_linux.zip)
- Ribasim executable - Windows: [ribasim_cli_windows.zip](https://github.com/Deltares/Ribasim/releases/latest/download/ribasim_cli_windows.zip)
- QGIS plugin: [ribasim_qgis.zip](https://github.com/Deltares/Ribasim/releases/latest/download/ribasim_qgis.zip).
- Generated testmodels: [generated_testmodels.zip](https://github.com/Deltares/Ribasim/releases/latest/download/generated_testmodels.zip)
# Conceptualization {#sec-conceptualization}

The nightly builds contain the latest developments and can be found below. It is important to either use the release or nightly for all components.
## The physical layer {#sec-physical}

- Ribasim executable: [ribasim_cli.zip](https://ribasim.s3.eu-west-3.amazonaws.com/teamcity/Ribasim_Ribasim/BuildRibasimCliWindows/latest/ribasim_cli.zip).
- QGIS plugin: [ribasim_qgis.zip](https://ribasim.s3.eu-west-3.amazonaws.com/teamcity/Ribasim_Ribasim/BuildRibasimCliWindows/latest/ribasim_qgis.zip).
To represent the physical characteristics of the water system in an area, Ribasim allows you to divide the area into a network of connected
representative elementary watersheds ([Reggiani, Sivapalan, and Majid Hassanizadeh 1998](https://deltares.github.io/Ribasim/#ref-REGGIANI1998367)).
Within Ribasim, these elements are called basins, which are essentially buckets or reservoirs holding an aggregated volume of water bodies in an
area. Basins are chained in a graph with connector nodes determining the exchange of water between the basins. These connector nodes can represent
open water connections (e.g. bifurcations or resistance in a free flowing open water channel) or infrastructure elements such as pumps, gates or
weirs.

Currently only Windows builds for `ribasim_cli.zip` are available.
## The control layer {#sec-control}

Infrastructure elements are often controlled by humans to implement a certain water management strategy. Ribasim allows the configuration of
conditional rules to influence the exchange of water between basins, either by setting inflow or outflow, or by controlling a water level.
Control rules evaluate one or multiple conditions to change a parameter setting of an infrastructure element when the conditional criteria are met.
Conditions can be either calculated values within the network as well as boundary conditions or (todo) external observations, i.e. observation
values external to the model.

## The allocation layer {#sec-allocation}

See [Usage](core/usage.qmd) for more information.
Ribasim allows water users (water demands) to abstract water from the basins (i.e. from the physical layer) unless the water level drops below a
minimum level. Under dry conditions, water managers may want to prioritize some abstractions over other abstractions. The Ribasim allocation layer
can take care of this prioritization by reducing the abstraction rates of lower-priority demands to ensure that sufficient water remains available
in the system for the higher-priority demands.

The layers and the main components and dataflows between the layers are shown in the next figure:

```{mermaid}
%%| file: assets/c4_system.mmd
%%| fig-cap: "System overview of Ribasim"
flowchart TB
physical:::layer
rbc:::layer
allocation:::layer
user
basin
connector[basin connector]
control[control rules]
condition
alloc[global allocation]
subgraph physical[physical layer]
user-->|abstraction| basin
basin<-->|flow| connector
end
subgraph rbc[rule based control layer]
condition --> control
end
subgraph allocation[allocation layer]
alloc
end
user-->|request demand| alloc
alloc-->|assign allocation| user
basin-->|volume| alloc
basin --> |volume or level| condition
alloc --> |optional flow update| control
control --> |action| connector
%% class definitions for C4 model
classDef layer fill:transparent,stroke-dasharray:5 5
```

# Status
**Nested allocation**

The initial focus is on being able to
reproduce the Mozart regional surface water reservoir results. Each component is defined by
a set of symbolic equations, and can be connected to each other. From this a simplified
system of equations is generated automatically. We use solvers with adaptive time stepping
from [DifferentialEquations.jl](https://diffeq.sciml.ai/stable/) to get results.
Since water systems may be extensive, like in the Netherlands, Ribasim models may become massive networks with multiple 10,000’s of nodes.
To keep a proper functioning allocation concept under these circumstances, the modeller can decompose the network domain into a main network
and multiple sub-networks. The allocation will then be conducted in three steps:

![Example timeseries of a single basin, the Hupselse Beek, with the input and output fluxes on the top, and the storage volume (the state) below.](https://user-images.githubusercontent.com/4471859/179259333-070dfe18-8f43-4ac4-bb38-013b252e2e4b.png)
1. conduct an inventory of demands from the sub-networks to inlets from the main network,
2. allocate the available water in the main network to the subnetworks inlets,
3. allocate the assigned water within each subnetwork to the individual water users.

![Example bar plot of the daily waterbalance for the Hupselse Beek, comparing results of Mozart (left) and Ribasim (right).](https://user-images.githubusercontent.com/4471859/179259174-0caccd4a-c51b-449e-873c-17d48cfc8870.png)
The users then will request this updated demand from the rule-based simulation. Whether this updated demand is indeed abstracted depends on
all dry-fall control mechanism implemented in the rule-based simulation.

The following sequence diagram illustrates this calculation process.

# Introduction
## Water balance equations
```{mermaid}
sequenceDiagram
participant boundary
participant basin
participant user
participant allocation_subNetwork
participant allocation_mainNetwork
user->>allocation_subNetwork: demand
loop
allocation_subNetwork-->>allocation_mainNetwork: demand inventory at inlets
end
user->>allocation_mainNetwork: demand
boundary->>allocation_mainNetwork: source availability
basin->>allocation_mainNetwork: source availability
allocation_mainNetwork-->>allocation_mainNetwork: allocate to inlets (and users)
allocation_mainNetwork->>user: allocated
allocation_mainNetwork->>allocation_subNetwork: allocated
loop
allocation_subNetwork-->>allocation_subNetwork: allocate to users
end
allocation_subNetwork->>user: allocated
user->>basin: abstracted
```

The water balance equation for a drainage basin [@enwiki:1099736933] can be
defined by a first-order ordinary differential equation (ODE), where the change of
the storage $S$ over time is determined by the inflow fluxes minus the outflow
fluxes.
# Development planning {#sec-planning}
Remember: reality may deviate from this planning

$$
\frac{\mathrm{d}S}{\mathrm{d}t} = Q_{in} - Q_{out}
$$
- Online coupling with MODFLOW6-Metaswap - 2024
- Offline coupling with Delwaq - 2024
- Online coupling with Delwaq – 2024
- Release ready for project application – 2nd half 2024
- Offline coupling with wflow
- Online coupling with wflow

We can split out the fluxes into separate terms, such as precipitation $P$,
evapotranspiration $ET$ and runoff $R$. For now other fluxes are combined into
$Q_{rest}$. If we define all fluxes entering our reservoir as positive, and those
leaving the system as negative, all fluxes can be summed up.
# About the code {#sec-code}
The figure below illustrates the relation between the various components of the Ribasim software package.

$$
\frac{\mathrm{d}S}{\mathrm{d}t} = R + P + ET + Q_{rest}
$$
```{mermaid}
flowchart TB
modeler([Modeler]):::user
## Time
api["Ribasim Python\n[python]"]
modeler-->|prepare model|api
The water balance equation can be applied on many timescales; years, weeks, days or hours.
Depending on the application and available data any of these can be the best choice.
In Ribasim, we make use of DifferentialEquations.jl and its [ODE solvers](https://diffeq.sciml.ai/stable/solvers/ode_solve/).
Many of these solvers are based on adaptive time stepping, which means the solver will
decide how large the time steps can be depending on the state of the system.
ribasim["Ribasim\n[julia]"]
modeler-->|start|ribasim
The forcing, like precipitation, is generally provided as a time series. Ribasim is set up
to support unevenly spaced timeseries. The solver will stop on timestamps where new forcing
values are available, so they can be loaded as the new value.
subgraph qgisBoundary[QGIS]
QGIS[QGIS Application]:::system_ext
qgisPlugin["Ribasim QGIS plugin\n[python]"]
QGIS-->qgisPlugin
end
modeler-->|prepare model|qgisBoundary
Ribasim is essentially a continuous model, rather than daily or hourly. If you want to use
hourly forcing, you only need to make sure that your forcing data contains hourly updates.
The output frequency can be configured independently. To be able to write a closed water
balance, we accumulate the fluxes. This way any variations in between timesteps are also
included, and we can output in `` rather than `m³s⁻¹`.
model[("input model data\n[toml + geopackage + arrow]")]
qgisPlugin-->|read/write|model
api-->|read/write|model
ribasim-->|simulate|model
## Space {#sec-space}
output[("simulation results\n[arrow]")]
ribasim-->|write|output
The water balance equation can be applied on different spatial scales. Besides modelling a
single lumped watershed, it allows you to divide the area into a network of connected
representative elementary watersheds (REWs) [@REGGIANI1998367]. At this scale global water
balance laws can be formulated by means of integration of point-scale conservation equations
over control volumes. Such an approach makes Ribasim a semi-distributed model. In this document
we typically use the term "basin" to refer to the REW. (In Mozart the spatial unit was called
Local Surface Water (LSW)). Each basin has an associated polygon, and the set of basins is
connected to each other as described by a graph, which we call the network. Below is a
representation of both on the map.
class qgisBoundary boundary
![Mozart Local Surface Water polygons and their drainage.](https://user-images.githubusercontent.com/4471859/185932183-62c305e6-bc14-4f3c-a74c-437f831c9145.png)
%% class definitions for C4 model
classDef user fill:#ABD0BC
classDef system_ext fill:#D2D2D2
classDef boundary fill:transparent,stroke-dasharray:5 5
```

The network is described as graph. Flow can be bi-directional, and the graph does not have
to be acyclic.
The kernel of Ribasim is written in the [Julia programming language](https://julialang.org/) and is built on top of the [SciML: Open Source
Software for Scientific Machine Learning](https://sciml.ai/) libraries, notably [DifferentialEquations.jl](https://docs.sciml.ai/DiffEqDocs/stable/).

```{mermaid}
graph LR;
A["basin A"] --- B["basin B"];
A --- C["basin C"];
B --- D["basin D"];
C --- D;
```
Ribasim has two API’s, both written in the Python programming language. The [Ribasim python package](https://deltares.github.io/Ribasim/python/)
offers an API to build, update and analyze Ribasim models programmatically.
For runtime data exchange and coupling with other models, ribasim_api is utilized which implements the Basic Modelling Interface
[BMI](https://bmi-spec.readthedocs.io/en/latest/).

Internally a directed graph is used. The direction is defined to be the
positive flow direction, and is generally set in the dominant flow direction.
The basins are the nodes of the network graph. Basin states and properties such
storage volume and wetted area are associated with the nodes (A, B, C, D), as are
most forcing data such as precipitation, evaporation, or water demand. Basin
connection properties and interbasin flows are associated with the edges (the
lines between A, B, C, and D) instead.
The Ribasim QGIS plugin allows users to construct a model from scratch without programming.
For specific tasks, like adding observed rainfall timeseries, it can be faster to use Python instead.

Multiple basins may exist within the same spatial polygon, representing
different aspects of the surface water system (perennial ditches, ephemeral
ditches, or even surface ponding). @fig-p, @fig-s, @fig-t show the 25.0 m
rasterized primary, secondary, and tertiary surface waters as identified by BRT
TOP10NL [@pdoktopnl] in the Hupsel basin (as defined in the Mozart LSW's).
These systems may represented in multiple ways.
One can also use Ribasim Python to build entire models from base data, such that your model
setup is fully reproducible.

![Hupsel: primary surface water.](https://user-images.githubusercontent.com/13662783/187625163-d0a81bb6-7f55-4ad1-83e2-90ec1ee79740.PNG){#fig-p}
See [Usage](https://deltares.github.io/Ribasim/core/usage.html) for more information.

![Hupsel: secondary surface water.](https://user-images.githubusercontent.com/13662783/187625170-1acdfb41-7077-443f-b140-ae18cbf21e53.PNG){#fig-s}
# Download {#sec-download}

![Hupsel: tertiary surface water.](https://user-images.githubusercontent.com/13662783/187625174-3eec28b5-ddbb-4870-94c3-d9e9a43f8eb4.PNG){#fig-t}
- Ribasim executable - Linux: [ribasim_cli_linux.zip](https://github.com/Deltares/Ribasim/releases/latest/download/ribasim_cli_linux.zip)
- Ribasim executable - Windows: [ribasim_cli_windows.zip](https://github.com/Deltares/Ribasim/releases/latest/download/ribasim_cli_windows.zip)
- QGIS plugin: [ribasim_qgis.zip](https://github.com/Deltares/Ribasim/releases/latest/download/ribasim_qgis.zip).
- Generated testmodels: [generated_testmodels.zip](https://github.com/Deltares/Ribasim/releases/latest/download/generated_testmodels.zip)

As a single basin (A) containing all surface water, discharging to its
downstream basin to the west (B):
The nightly builds contain the latest developments and can be found below. It is important to either use the release or nightly for all components.

```{mermaid}
graph LR;
A["basin A"] --> B["basin B"];
```
- Ribasim executable: [ribasim_cli.zip](https://ribasim.s3.eu-west-3.amazonaws.com/teamcity/Ribasim_Ribasim/BuildRibasimCliWindows/latest/ribasim_cli.zip).
- QGIS plugin: [ribasim_qgis.zip](https://ribasim.s3.eu-west-3.amazonaws.com/teamcity/Ribasim_Ribasim/BuildRibasimCliWindows/latest/ribasim_qgis.zip).

Such a system may be capable of representing discharge, but it cannot represent
residence times or differences in solute concentrations: within a single basin,
drop of water is mixed instantaneously. Instead, we may the group primary (P),
secondary (S), and tertiary (T) surface waters. Then T may flow into S, S into
P, and P discharges to the downstream basin (B.)
Currently only Windows builds for `ribasim_cli.zip` are available.

```{mermaid}
graph LR;
T["basin T"] --> S["basin S"];
S --> P["basin P"];
P --> B["basin B"];
The Ribasim python package is [registered in PyPI](https://pypi.org/project/ribasim/) and can therefore
be installed with [pip](https://docs.python.org/3/installing/index.html):
```
pip install ribasim
```
For wheel (`.whl`) downloads, including nightly builds, see the [download section](../index.qmd#sec-download).
After downloading wheels can be installed by referring to the correct path:
```
pip install path/to/ribasim-*.whl
```

As each (sub)basin has its own volume, low throughput (high volume, low
discharge, long residence time) and high throughput (low volume, high
discharge, short residence time) systems can be represented in a lumped manner;
of course, more detail requires more parameters.
# Acknowledgment
Ribasim is supported by:

::: {layout-ncol=2 layout-valign="bottom"}
<a href="https://www.deltares.nl/">
<img alt="Deltares logo"
src="https://user-images.githubusercontent.com/4471859/187672447-adb9cb11-16ca-488b-bef9-08e059fe6d55.svg"
height="60">
</a>

<a href="https://nhi.nu/">
<img alt="NHI logo"
src="https://user-images.githubusercontent.com/4471859/187672456-874b344a-9ad3-42b5-af6a-93517f7fbbe8.png"
height="60">
</a>
:::
Loading

0 comments on commit 8cde41a

Please sign in to comment.