Skip to content

Commit

Permalink
Introduce experimental config section and use it for concentrations. (#…
Browse files Browse the repository at this point in the history
…1909)

I almost went for StyledStrings, but the underline (here **) seems
enough.

```julia
┌ Info: Starting a Ribasim simulation.
│   toml_path = "/Users/evetion/Downloads/hws_2024_7_x_delwaq/hws_24h.toml"
│   cli.ribasim_version = "2024.11.0"
│   starttime = 2023-01-20T00:00:00
└   endtime = 2023-07-01T00:00:00
┌ Warning: The following *experimental* features are enabled: concentration
└ @ Ribasim /Users/evetion/code/Ribasim/core/src/main.jl:44
```

---------

Co-authored-by: Martijn Visser <[email protected]>
  • Loading branch information
evetion and visr authored Oct 21, 2024
1 parent 4ef4d86 commit 66491af
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 11 deletions.
14 changes: 14 additions & 0 deletions core/src/config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ end
use_allocation::Bool = false
end

@option struct Experimental <: TableOption
concentration::Bool = false
end
# For logging enabled experimental features
function Base.iterate(exp::Experimental, state = 0)
state >= nfields(exp) && return
return Base.getfield(exp, state + 1), state + 1
end
function Base.show(io::IO, exp::Experimental)
fields = (field for field in fieldnames(typeof(exp)) if getfield(exp, field))
print(io, join(fields, " "))
end

@option @addnodetypes struct Toml <: TableOption
starttime::DateTime
endtime::DateTime
Expand All @@ -145,6 +158,7 @@ end
solver::Solver = Solver()
logging::Logging = Logging()
results::Results = Results()
experimental::Experimental = Experimental()
end

struct Config
Expand Down
3 changes: 3 additions & 0 deletions core/src/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ function main(toml_path::AbstractString)::Cint
@warn "The Ribasim version in the TOML config file does not match the used Ribasim CLI version." config.ribasim_version cli.ribasim_version
end
@info "Starting a Ribasim simulation." toml_path cli.ribasim_version starttime endtime
if any(config.experimental)
@warn "The following *experimental* features are enabled: $(config.experimental)"
end

try
model = run(config)
Expand Down
10 changes: 6 additions & 4 deletions core/src/write.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Write all results to the Arrow files as specified in the model configuration.
"""
function write_results(model::Model)::Model
(; config) = model
(; results) = model.config
(; results, experimental) = model.config
compress = get_compressor(results)
remove_empty_table = model.integrator.t != 0

Expand All @@ -25,9 +25,11 @@ function write_results(model::Model)::Model
write_arrow(path, table, compress; remove_empty_table)

# concentrations
table = concentration_table(model)
path = results_path(config, RESULTS_FILENAME.concentration)
write_arrow(path, table, compress; remove_empty_table)
if experimental.concentration
table = concentration_table(model)
path = results_path(config, RESULTS_FILENAME.concentration)
write_arrow(path, table, compress; remove_empty_table)
end

# discrete control
table = discrete_control_table(model)
Expand Down
4 changes: 4 additions & 0 deletions core/test/docs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,7 @@ verbosity = "info" # optional, default "info", can otherwise be "debug", "warn"
# These results files are always written
compression = true # optional, default true, using zstd compression
compression_level = 6 # optional, default 6

[experimental]
# Experimental features, disabled by default
concentration = false # tracer calculations
1 change: 1 addition & 0 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ website:
- install.qmd
- changelog.qmd
- known_issues.qmd
- contact.qmd

- title: "Tutorials"
contents:
Expand Down
20 changes: 14 additions & 6 deletions docs/concept/core.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,29 @@ allocation_subNetwork->>user_demand: allocated
user_demand->>basin: abstracted
```

# Substance (tracer) concentration calculations
# Substance (tracer) concentrations

::: {.callout-caution}
This is an unsupported experimental feature and is disabled by default.
We advise to use the [Delwaq coupling](@sec-waterquality) for tracer calculations.
If you're interested in using this experimental feature, please [contact us](/contact.qmd).
:::

Ribasim can calculate concentrations of conservative tracers (i.e. substances that are non-reactive).
It does so by calculating the mass transports by flows for each timestep, in the `update_cumulative_flows!` callback.
Specifically, for each Basin at each timestep we calculate:
Specifically, for each Basin at each timestep it calculates:

- all mass inflows (flow * source_concentration) given the edge inflows
- update the concentrations in the Basin based on the added storage (previous storage + inflows)
- all mass outflows (flow * basin_concentration_state) give the edge outflows
- all mass inflows ($flow * source\_concentration$) given the edge inflows
- update the concentrations in the Basin based on the added storage ($previous storage + inflows$)
- all mass outflows ($flow * basin\_concentration\_state$) give the edge outflows
- update the concentrations in the Basin based on the current storage

We thus keep track of both mass and concentration of substances for each Basin.
Note that we have not added the substance mass to the states, and we assume that concentrations of flows are piecewise constant over a timestep.
This excludes the use of tracer injections.

By default the following source tracers are enabled.

By default we calculate concentrations for the following source tracers.
- Continuity (mass balance, fraction of all water sources, sum of all other source tracers)
- Initial (fraction of initial storages)
- LevelBoundary, FlowBoundary, UserDemand, Drainage, Precipitation (fraction of different boundaries)
2 changes: 1 addition & 1 deletion docs/guide/coupling.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: "Coupling"

Ribasim can also be (online) coupled to other kernels with the help of iMOD Coupler. The corresponding documentation can be found within the [iMOD Suite Documentation](https://deltares.github.io/iMOD-Documentation/coupler.html).

# Water quality
# Water quality {#sec-waterquality}

Ribasim can be offline coupled to Delwaq, the Deltares Water Quality model.

Expand Down
17 changes: 17 additions & 0 deletions docs/reference/usage.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,23 @@ entry | type | description
----------------- | ------ | -----------
verbosity | String | Verbosity level: debug, info, warn, or error.

## Experimental features

::: {.callout-important}
Experimental features are completely unsupported. They can break at any time
and results will be wrong. **Do not use them in production**. If you're interested
in using an experimental feature, please [contact us](/contact.qmd).
:::

One can enable experimental features in the `[experimental]` section.
Currently the following features can be enabled (all are disabled by default).

entry | type | description
----------------- | ------ | -----------
concentration | Bool | Whether to enable tracer calculations or not.



# GeoPackage database and Arrow tables {#sec-geopackage}

The input and output tables described below all share that they are tabular files. The Node
Expand Down
13 changes: 13 additions & 0 deletions python/ribasim/ribasim/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ class Logging(ChildModel):
verbosity: Verbosity = Verbosity.info


class Experimental(ChildModel):
"""
Defines experimental features.
Attributes
----------
concentration : bool
Whether to enable tracer support (default is False)
"""

concentration: bool = False


class Node(pydantic.BaseModel):
"""
Defines a node for the model.
Expand Down
3 changes: 3 additions & 0 deletions python/ribasim/ribasim/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
Basin,
ContinuousControl,
DiscreteControl,
Experimental,
FlowBoundary,
FlowDemand,
LevelBoundary,
Expand Down Expand Up @@ -86,6 +87,8 @@ class Model(FileModel):

allocation: Allocation = Field(default_factory=Allocation)

experimental: Experimental = Field(default_factory=Experimental)

basin: Basin = Field(default_factory=Basin)
continuous_control: ContinuousControl = Field(default_factory=ContinuousControl)
discrete_control: DiscreteControl = Field(default_factory=DiscreteControl)
Expand Down

0 comments on commit 66491af

Please sign in to comment.