Skip to content

Commit

Permalink
Merge branch 'main' into partition_basin_struct
Browse files Browse the repository at this point in the history
  • Loading branch information
evetion authored Nov 15, 2024
2 parents 7f0cc99 + 47b4fa7 commit dd87076
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 56 deletions.
35 changes: 35 additions & 0 deletions build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,38 @@ pixi run build
```

> :warning: If the build is failing, because it cannot find certain files, chances are high that you need to enable long paths in Windows.
## Ribasim CLI

In order to find out about it's usage call `ribasim --help`

## Libribasim

Libribasim is a shared library that exposes Ribasim functionality to external (non-Julian)
programs. It can be compiled using [PackageCompiler's
create_lib](https://julialang.github.io/PackageCompiler.jl/stable/libs.html), which is set
up in this directory. The C API that is offered to control Ribasim is the C API of the
[Basic Model Interface](https://bmi.readthedocs.io/en/latest/), also known as BMI.

Not all BMI functions are implemented yet.
Couplings to other models are implemented in [`imod_coupler`](https://github.com/Deltares/imod_coupler).

Here is an example of using libribasim from Python:

```python
In [1]: from ctypes import CDLL, c_int, c_char_p, create_string_buffer, byref

In [2]: c_dll = CDLL("libribasim", winmode=0x08) # winmode for Windows

In [3]: argument = create_string_buffer(0)
...: c_dll.init_julia(c_int(0), byref(argument))
Out[3]: 1

In [4]: config_path = "ribasim.toml"

In [5]: c_dll.initialize(c_char_p(config_path.encode()))
Out[5]: 0

In [6]: c_dll.update()
Out[6]: 0
```
51 changes: 11 additions & 40 deletions build/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,6 @@ using PackageCompiler
using TOML
using LibGit2

"""
# Ribasim CLI
In order to find out about it's usage call `ribasim --help`
# Libribasim
Libribasim is a shared library that exposes Ribasim functionality to external (non-Julian)
programs. It can be compiled using [PackageCompiler's
create_lib](https://julialang.github.io/PackageCompiler.jl/stable/libs.html), which is set
up in this directory. The C API that is offered to control Ribasim is the C API of the
[Basic Model Interface](https://bmi.readthedocs.io/en/latest/), also known as BMI.
Not all BMI functions are implemented yet, this has been set up as a proof of concept to
demonstrate that we can use other software such as
[`imod_coupler`](https://github.com/Deltares/imod_coupler) to control Ribasim and couple it to
other models.
Here is an example of using libribasim from Python:
```python
In [1]: from ctypes import CDLL, c_int, c_char_p, create_string_buffer, byref
In [2]: c_dll = CDLL("libribasim", winmode=0x08) # winmode for Windows
In [3]: argument = create_string_buffer(0)
...: c_dll.init_julia(c_int(0), byref(argument))
Out[3]: 1
In [4]: config_path = "ribasim.toml"
In [5]: c_dll.initialize(c_char_p(config_path.encode()))
Out[5]: 0
In [6]: c_dll.update()
Out[6]: 0
```
"""
function main()
project_dir = "../core"
license_file = "../LICENSE"
Expand All @@ -61,13 +23,22 @@ function main()
force = true,
)

readme = @doc(build_app)
add_metadata(project_dir, license_file, output_dir, git_repo, readme)
add_metadata(project_dir, license_file, output_dir, git_repo, readme_start)
run(Cmd(`cargo build --release`; dir = "cli"))
ribasim = Sys.iswindows() ? "ribasim.exe" : "ribasim"
cp("cli/target/release/$ribasim", "ribasim/$ribasim"; force = true)
end

readme_start = """
# Ribasim
Ribasim is a water resources model to simulate the physical behavior of a managed open water system
based on a set of control rules and a prioritized water allocation strategy.
Usage: `ribasim path/to/model/ribasim.toml`
Documentation: https://ribasim.org/
"""

function set_version(filename, version; group = nothing)
data = TOML.parsefile(filename)
if !isnothing(group)
Expand Down
8 changes: 4 additions & 4 deletions core/src/parameter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,6 @@ for discrete control
itp_update::Vector{ParameterUpdate{ScalarInterpolation}} = []
end

abstract type AbstractParameterNode end

abstract type AbstractDemandNode <: AbstractParameterNode end

"""
In-memory storage of saved mean flows for writing to results.
Expand Down Expand Up @@ -307,6 +303,10 @@ In-memory storage of saved instantaneous storages and levels for writing to resu
t::Float64
end

abstract type AbstractParameterNode end

abstract type AbstractDemandNode <: AbstractParameterNode end

"""
Caches of current basin properties
"""
Expand Down
1 change: 1 addition & 0 deletions core/src/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ function FlatVector(saveval::Vector{<:SavedFlow}, sym::Symbol)
v = isempty(saveval) ? Vector{Float64}[] : getfield.(saveval, sym)
FlatVector(v)
end
FlatVector(v::Vector{Matrix{Float64}}) = FlatVector(vec.(v))

"""
Function that goes smoothly from 0 to 1 in the interval [0,threshold],
Expand Down
11 changes: 1 addition & 10 deletions core/src/write.jl
Original file line number Diff line number Diff line change
Expand Up @@ -276,18 +276,9 @@ function concentration_table(
ntsteps = length(data.time) - 1
nbasin = length(data.node_id)
nsubstance = length(basin.concentration_data.substances)
nrows = ntsteps * nbasin * nsubstance

substances = String.(basin.concentration_data.substances)
concentration = zeros(nrows)

idx_row = 0
for cvec in saved.flow.saveval
for concentration_ in vec(cvec.concentration)
idx_row += 1
concentration[idx_row] = concentration_
end
end
concentration = FlatVector(saved.flow.saveval, :concentration)

time = repeat(data.time[begin:(end - 1)]; inner = nbasin * nsubstance)
substance = repeat(substances; inner = nbasin, outer = ntsteps)
Expand Down
5 changes: 5 additions & 0 deletions core/test/run_models_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ end

# flows are recorded at the end of each period, and are undefined at the start
@test unique(table.time) == Ribasim.datetimes(model)[1:(end - 1)]

@test isfile(joinpath(dirname(toml_path), "results/concentration.arrow"))
table = Ribasim.concentration_table(model)
@test "Continuity" in table.substance
@test all(isapprox.(table.concentration[table.substance .== "Continuity"], 1.0))
end

@testitem "basic arrow model" begin
Expand Down
3 changes: 2 additions & 1 deletion python/ribasim_testmodels/ribasim_testmodels/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np
import pandas as pd
import ribasim
from ribasim.config import Node
from ribasim.config import Experimental, Node
from ribasim.input_base import TableModel
from ribasim.nodes import (
basin,
Expand All @@ -26,6 +26,7 @@ def basic_model() -> ribasim.Model:
starttime="2020-01-01",
endtime="2021-01-01",
crs="EPSG:28992",
experimental=Experimental(concentration=True),
)
model.logging = ribasim.Logging(verbosity="debug")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import pandas as pd
from ribasim.config import Node
from ribasim.config import Experimental, Node
from ribasim.model import Model, Solver
from ribasim.nodes import (
basin,
Expand Down Expand Up @@ -604,6 +604,7 @@ def continuous_concentration_condition_model() -> Model:
endtime="2020-02-01",
crs="EPSG:28992",
solver=Solver(saveat=86400 / 8),
experimental=Experimental(concentration=True),
)

basi = model.basin.add(
Expand Down

0 comments on commit dd87076

Please sign in to comment.