Skip to content

Farewell, cumulative flow states#3039

Draft
verheem wants to merge 79 commits into
mainfrom
basin-storage-states
Draft

Farewell, cumulative flow states#3039
verheem wants to merge 79 commits into
mainfrom
basin-storage-states

Conversation

@verheem

@verheem verheem commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #3037

convergence was removed from flow.nc, only basin.nc now has convergence (breaking change)

Cosmetic storage removal was done in commit 351936b.

verheem added 4 commits April 16, 2026 15:00
- Updated the Parameters function to streamline state handling and remove unnecessary variables.
- Modified water_balance! to work directly with the full state vector, eliminating the need for reduced state vectors.
- Enhanced set_current_basin_properties! to directly use basin storage from the state vector.
- Introduced apply_flow_to_basins! to manage flow contributions to basin storage more effectively.
- Removed redundant state reduction and flow limit functions, simplifying the flow management logic.
- Improved cache handling for flow rates in various node types, ensuring accurate flow tracking.
- Updated basin and flow data functions to reflect changes in state handling and removed deprecated variables.
@verheem verheem changed the title Back to storages Farwell, cummulative flows Apr 17, 2026
@verheem verheem changed the title Farwell, cummulative flows Farewell, cummulative flows Apr 17, 2026
@visr visr changed the title Farewell, cummulative flows Farewell, cumulative flows Apr 17, 2026
@verheem verheem changed the title Farewell, cumulative flows Farewell, cumulative flow states Apr 17, 2026
Comment thread core/src/config.jl Outdated
@visr

visr commented Apr 19, 2026

Copy link
Copy Markdown
Member

I just tried a binary from this branch on a large part of the LHM model, and whereas the release finished in 2 hours, I killed this after a night, with an ETA of around 2 days. We'd need to profile to see if anything stands out.

@verheem

verheem commented Apr 20, 2026

Copy link
Copy Markdown
Contributor Author

I just tried a binary from this branch on a large part of the LHM model, and whereas the release finished in 2 hours, I killed this after a night, with an ETA of around 2 days. We'd need to profile to see if anything stands out.

Probably due to the level difference threshold of 1e-4. This also made HWS extremely slow. Lets try again with 2cm

visr and others added 14 commits June 23, 2026 15:25
Fixes #2979

Strips ANSI escape sequences that triggered newlines, at the cost of
colors and bold text, but keeping it simple.

Also updates the quarto filter we use, and refer to it in a less bugged
way, with a relative path.

Now looks like:

<img width="583" height="785" alt="Screenshot 2026-06-15 163156"
src="https://github.com/user-attachments/assets/22753d5f-613a-49ae-abf0-604a2fe8e8c0"
/>
So users can just do `generate`, run Delwaq, and run `parse`, instead of
having to keep their session open, or rerun `generate` to have the
mandatory variables for `parse`.

I have dropped the visualization from the docs, but the description is
still there, as is the printer substances (just a bit later). I'm
currently testing this approach on the latest LHM, I can confirm the
presence of (good looking) variables in the `ribasim.nc`.

CC @DanielTollenaar
Fixes #2951

Adds support for comparing observed vs. simulated timeseries in the QGIS
plugin's timeseries plot. When a model has
[Observation](https://ribasim.org/reference/node/observation.html)
nodes, selecting one (via the `node` button) plots its observed input
series alongside the matching simulated series from the results.

<img width="657" height="467" alt="timeseries-plot-observation"
src="https://github.com/user-attachments/assets/d7ecafa6-c636-4175-b222-32171d619b47"
/>

- **Observation input reader** (observations.py): reads the `Observation
/ time` table from the model GeoPackage — the plugin's first read of
input timeseries data.
- **Observed vs. simulated traces**: for each selected Observation node,
the observed series (read from input) is drawn in **black** and the
corresponding simulated series in **red**, sharing a single dropdown
entry so one checkbox toggles both.
- **Unit-grouped subplots**: observation variables borrow their unit
from the matching result variable, so observed and simulated land on the
same unit-grouped subplot. Observation variables are merged into the
existing root variable groups (`level`, `storage`, `flow_rate`).
- **Simulated-target resolution**: resolves the observed target node via
the `observation` link and derives the simulated series — node-indexed
lookups for Basin variables, and connected-flow-link sums for flow
variables (`flow_rate`, `inflow_rate`, `outflow_rate`).
- **Works without results**: if results aren't loaded, the observed
series is still plotted on its own (all observation root groups are
checked by default, so flow_rate/level/etc. all show).
- **Default x-axis = simulated period**: plots open on the model's
`starttime`/`endtime` (from the TOML) rather than auto-fitting, so an
observed series extending beyond the simulation doesn't stretch the
view.

- **Retaining the zoom**: the user's pan/zoom is preserved across
redraws (e.g. changing the node/link selection) via plotly's
`uirevision`, and the "Reset axes" button returns to the simulated
period rather than the full data span. Zoom resets only when a different
model/period is loaded.
- **Retaining the figure (no flicker)**: redraws update the existing
plot in place with `Plotly.react` instead of reloading the page,
eliminating flicker. A transient empty selection (e.g. a misclick) hides
the plot but keeps its DOM alive, so the zoom survives.

- Added a section to the QGIS guide (qgis.qmd) describing the
observation comparison.
- New unit tests for the observation reader and plot widget (72 QGIS
tests passing).
Not as big as the last release, but it is better to get these usability
improvements out there and not have to worry about the docs and release
being out of sync.

This also gives us a bit less pressure to land the storage formulation
quickly.
v1.8.1 has our changes
…3126)

Bumps the all-actions group with 1 update:
[actions/checkout](https://github.com/actions/checkout).

Updates `actions/checkout` from 6.0.3 to 7.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>block checking out fork pr for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
<li>getting ready for checkout v7 release by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li>
<li>update error wording by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v7.0.0</h2>
<ul>
<li>Block checking out fork PR for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
</ul>
<h2>v6.0.3</h2>
<ul>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<h2>v6.0.2</h2>
<ul>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<h2>v6.0.1</h2>
<ul>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
</ul>
<h2>v6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>v5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>v5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>v4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>v4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/checkout/commit/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"><code>9c091bb</code></a>
update error wording (<a
href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/1044a6dea927916f2c38ba5aeffbc0a847b1221a"><code>1044a6d</code></a>
getting ready for checkout v7 release (<a
href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/f0282184c7ce73ab54c7e4ab5a617122602e575f"><code>f028218</code></a>
Bump the minor-npm-dependencies group across 1 directory with 3 updates
(<a
href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/d914b262ffc244530a203ab40decab34c3abf34d"><code>d914b26</code></a>
upgrade module to esm and update dependencies (<a
href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/537c7ef99cef6e5ddb5e7ff5d16d14510503801d"><code>537c7ef</code></a>
Bump <code>@​actions/core</code> and <code>@​actions/tool-cache</code>
and Remove uuid (<a
href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/130a169078a413d3a5246a393625e8e742f387f6"><code>130a169</code></a>
Bump js-yaml from 4.1.0 to 4.2.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/7d09575332117a40b46e5e020664df234cd416f3"><code>7d09575</code></a>
Bump flatted from 3.3.1 to 3.4.2 (<a
href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/0f9f3aa320cb53abeb534aeb54048075d9697a0e"><code>0f9f3aa</code></a>
Bump actions/publish-immutable-action (<a
href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/f9e715a95fcd1f9253f77dd28f11e88d2d6460c7"><code>f9e715a</code></a>
block checking out fork pr for pull_request_target and workflow_run (<a
href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=6.0.3&new-version=7.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@SouthEndMusic

Copy link
Copy Markdown
Collaborator

I realized a few remaining problems:

  • The flow integration doesn't work with control by allocation, because the changes in flow due to allocation control are not taken into account in the $f_0$ term of the integration scheme. As a quick fix, at the end of update_allocation!, call water_balance and update flow_rate_prev
  • The way flows are cached I think is a bit messy; caching them in p_independent in water_balance! and then copying them to state_and_time_dependent_cache in the callbacks; that is not what the state_and_time_dependent_cache is for. I propose:
    • Introducing a CVector for the different types of flows in state_and_time_dependent_cache and caching flows there when formulating;
    • formulating du at the end of water_balance! based on that vector
  • I don't know whether we also did this before, but I think that doing DiscreteControl based on the latest computed instantaneous flows isn't great, because that's highly dependent on with which arguments water_balance! happened to be called last. It would be much better to do DiscreteControl based on the average flow of the last timestep.

I think that with #3113 these things can be handled more cleanly.

@visr

visr commented Jun 29, 2026

Copy link
Copy Markdown
Member

Thanks for pushing on this. If you think these remaining points are better addressed in or after #3113, that is fine with me.

@SouthEndMusic

Copy link
Copy Markdown
Collaborator

@visr I prefer to do it now, to have a proper state of the main branch. I also don't know when #3113 will be planned, there's some time in the current sprint to work on this.

@SouthEndMusic

SouthEndMusic commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Some more notes:

The multiple inflows for UserDemand feature actually adds a bit of complexity for #3113 because with that feature some flows do depend on more than (at most) an upstream and downstream storage.

@SouthEndMusic

Copy link
Copy Markdown
Collaborator

I refactored a lot, and I was able to bring the number of failing tests down to a small amount. Still, I am not happy with this direction. Fundamentally we are back at the same problem we had before the cumulative flow states; the post-solver flow quadrature via Simpson's rule doesn't close the water balance sufficiently (at least to avoid negative tracer masses), and any subsequent step to correct that is either rather expensive (i.e. find a minimal correction of the flows that respects things like non-negativity constraints and return factors) or doesn't take parts of the physics into account (e.g. the correction invents non-existent infiltration to close the water balance).

#3113 really is the way to go; we should not have to guesstimate what flows the solver (implicitly) used internally.

I think that in the new formulation all Basin forcings should be treated as flow states again. I don't think it would significantly drop performance with the custom Jacobian and linear solve (which was the original reason to do exact integration), it cleans up the code, and most importantly it gets rid of all remaining headaches of matching exact integration with the solver results. If we really care about matching the exact integration we can inlcude it in isoutofdomain.

@visr visr mentioned this pull request Jul 6, 2026
visr added a commit that referenced this pull request Jul 6, 2026
This pulls a tiny part of #3039 in already (adding DiffEqBase and
NaNMath as direct deps), which makes it easier to maintain the branch
since the Manifest.toml wouldn't need to change anymore.

Also fixes README headings, and completes the root env deps section.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Core refactor: basin storages as ODE states instead of cumulative flows

6 participants