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

BMI docs page #1521

Merged
merged 6 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
18 changes: 9 additions & 9 deletions core/src/callback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,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 @@ -131,15 +140,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 @@ -63,6 +63,7 @@ website:
- contribute/python.qmd
- contribute/qgis.qmd
- contribute/addnode.qmd
- contribute/bmi.qmd
- contribute/ci.qmd
- contribute/release.qmd

Expand Down
46 changes: 46 additions & 0 deletions docs/contribute/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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please indicate if array is row or column major sorted

`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/contribute/index.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