Skip to content

Commit

Permalink
BMI docs page (#1521)
Browse files Browse the repository at this point in the history
Fixes #1328.
  • Loading branch information
SouthEndMusic authored Jun 12, 2024
1 parent edd7f87 commit a596627
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 10 deletions.
18 changes: 9 additions & 9 deletions core/src/callback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ function integrate_flows!(u, t, integrator)::Nothing
user_demand.realized_bmi[i] += 0.5 * (flow[flow_idx] + flow_prev[flow_idx]) * dt
end

# *Demand realized flow for output
for (edge, value) in allocation.mean_realized_flows
if edge[1] !== edge[2]
value +=
0.5 * (get_flow(graph, edge..., 0) + get_flow_prev(graph, edge..., 0)) * dt
allocation.mean_realized_flows[edge] = value
end
end

# Allocation source flows
for (edge, value) in allocation.mean_input_flows
if edge[1] == edge[2]
Expand All @@ -128,15 +137,6 @@ function integrate_flows!(u, t, integrator)::Nothing
end
end

# Realized demand flows
for (edge, value) in allocation.mean_realized_flows
if edge[1] !== edge[2]
value +=
0.5 * (get_flow(graph, edge..., 0) + get_flow_prev(graph, edge..., 0)) * dt
allocation.mean_realized_flows[edge] = value
end
end

copyto!(flow_prev, flow)
copyto!(vertical_flux_prev, vertical_flux)
return nothing
Expand Down
1 change: 1 addition & 0 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ website:
- dev/python.qmd
- guides/addnode.qmd
- guides/release.qmd
- guides/bmi.qmd

- title: "Background"
contents:
Expand Down
46 changes: 46 additions & 0 deletions docs/guides/bmi.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Basic Model Interface (BMI)

For runtime data exchange and coupling with other kernels, the Julia kernel is wrapped in a Python API (`ribasim_api`) which implements the Basic Modelling Interface [BMI](https://bmi-spec.readthedocs.io/en/latest/).

## Functions

The following functions are available to interact with the Ribasim model"

signature | description
------------------------- | -------------
`initialize(config_path)` | Initialize a model from the path to the TOML configuration file
`finalize()` | Write all results to the configured files
`get_current_time()` | Get the current time of the Ribasim simulation
`get_end_time()` | Get the final time of the Ribasim simulation in seconds
`get_start_time()` | Get the start time of the Ribasim simulation (`0.0`)
`get_time_step()` | Get the proposed next internal Ribasim timestep
`get_time_units()` | Get the time unit (`s`)
`get_value_ptr(string)` | Get the pointer to a Ribasim internal array (see below)
`update()` | Perform a Ribasim internal time step
`update_until(time)` | Set Ribasim internal timesteps until the specified time

Depending on what is specified in the Ribasim TOML configuration file, Ribasim can internally have adaptive (non-constant) timesteps. `update_until` will always try to progress the Ribasim simulation to exactly the time specified. This however can fail for algorithms that only support a fixed timestep if that timestep does not fit into the interval until the specified time an integer amount of times.

## Memory pointers

The following pointers to memory containing Ribasim internal arrays are given via the BMI using `get_value_ptr(string)`:

string | meaning | type | unit | temporal type | writable | sorted by
------------------------------- | -------------------------------------- | ------- | ------------ | --------------------- | -------- |----------
`basin.storage` | storage per basin | Float64 | $m^3$ | instantaneous | no | basin node ID
`basin.level` | level per basin | Float64 | $m$ | instantaneous | no | basin node ID
`basin.infiltration` | infiltration flux per basin | Float64 | $m^3 s^{-1}$ | forward fill | yes | basin node ID
`basin.drainage` | drainage flux per basin | Float64 | $m^3 s^{-1}$ | forward fill | yes | basin node ID
`basin.infiltration_integrated` | cumulative infiltration per basin | Float64 | $m^3$ | integrated from start | yes | basin node ID
`basin.drainage_integrated` | cumulative drainage per basin | Float64 | $m^3$ | integrated from start | yes | basin node ID
`basin.subgrid_level` | subgrid level | Float64 | $m$ | instantaneous | no | subgrid ID
`user_demand.demand` | demand per node ID per priority | Float64 | $m^3 s^{-1}$ | forward fill | yes | user_demand node ID, priority index
`user_demand.realized` | cumulative intake flow per user | Float64 | $m^3$ | integrated from start | yes | user_demand node ID

Additional notes:

- `user_demand.demand` yields the only 2D array, the other arrays are 1D. This array is indexed as `(node_idx, priority_idx)` in Julia, which stores arrays column-major
- The index of e.g. basins and user demand nodes needs to be inferred from the Ribasim input. The same holds for `priority_idx`, which is global over all subnetworks
- The data being writable means that Ribasim takes into account the possibility that the data is updated outiside the Ribasim core
- Although the `*_integrated` and `*_realized` data is writable, this doesn't affect the Ribasim simulation. This integrated data is only computed for the BMI, and can be set to $0$ via the BMI to avoid accuracy problems when the values get too large.
- Different from what is exposed via the BMI, the basin forcings and realized user demands are averaged over the allocation timestep and saveat interval respectively.
2 changes: 1 addition & 1 deletion docs/guides/contributing.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: "Contributing"

Ribasim welcomes contributions.

There is developer documentation for the [Julia core](core.qmd), [Python tooling](python.qmd), and the [QGIS plugin](qgis.qmd).
There is developer documentation for the [Julia core](core.qmd), the [Basic Model Interface (BMI)](bmi.qmd), [Python tooling](python.qmd), and the [QGIS plugin](qgis.qmd).
A guide on how to add a new node type to both is written in [adding node types](addnode.qmd).
[Release process](release.qmd) describes the steps to follow when creating a new Ribasim release.

Expand Down

0 comments on commit a596627

Please sign in to comment.