Skip to content

Use TimeSliceSelection for demand maps - #1549

Merged
tsmbland merged 5 commits into
mainfrom
demand_map_v2
Sep 21, 2026
Merged

tsmbland merged 5 commits into
mainfrom
demand_map_v2

Conversation

@tsmbland

Copy link
Copy Markdown
Collaborator

Description

Changes demand maps to store commodity demands at the balance level of the commodity. The previous approach of storing demands at the time-slice level, regardless of the balance-level of the commodity, was just a hack, which involved arbitrarily splitting demands up and adding them back together again.

Note that "demand" and "consumption" are not the same thing. Consumption is always defined at the time-slice level, but this consumption generates demands at the balance level of the commodity (i.e. at the season level for a seasonally balanced commodity). This is what we should store in these maps.

The only slightly messy thing is with the debug_appraisal_results_time_slices.csv file, which is structured around having timeslice-level rows, including reporting demand and unmet demand at the timeslice-level. Since timeslice-level demands are undefined for seasonal/annual commodities, the approach I've gone for for now is to report the whole demand/unmet demand for the timeslice selection (e.g. for the season) and report the time_slice_level of the commodity alongside this. This is just a developer debug file, so not a huge deal anyway.

Fixes # (issue)

Type of change

  • Bug fix (non-breaking change to fix an issue)
  • New feature (non-breaking change to add functionality)
  • Refactoring (non-breaking, non-functional change to improve maintainability)
  • Optimization (non-breaking change to speed up the code)
  • Breaking change (whatever its nature)
  • Documentation (improve or add documentation)

Key checklist

  • All tests pass: $ cargo test
  • The documentation builds and looks OK: $ cargo doc
  • Update release notes for the latest release if this PR adds a new feature or fixes a bug
    present in the previous release

Further checks

  • Code is commented, particularly in hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@tsmbland
tsmbland marked this pull request as ready for review September 16, 2026 09:05
Copilot AI lite review requested due to automatic review settings September 16, 2026 09:05
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.43750% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 90.83%. Comparing base (c8215b8) to head (200ed77).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/output.rs 92.85% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1549      +/-   ##
==========================================
- Coverage   90.84%   90.83%   -0.02%     
==========================================
  Files          61       61              
  Lines        9019     9019              
  Branches     9019     9019              
==========================================
- Hits         8193     8192       -1     
- Misses        507      508       +1     
  Partials      319      319              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Outstanding documentation, release-note, and parameterised test coverage updates remain.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR changes investment demand maps to use commodity balance-level TimeSliceSelection values instead of individual time slices.

Changes:

  • Updates demand aggregation, market selection, and appraisal calculations.
  • Adjusts debug output and serialization.
  • Refreshes fixtures, benchmarks, and regression data.
File summaries
File Description
tests/data/simple/debug_appraisal_results.csv Updates regression output.
src/time_slice.rs Enables TimeSliceLevel serialization.
src/simulation/market.rs Selects demand by commodity balance level.
src/simulation/investment/appraisal/optimisation.rs Computes selection-level unmet demand.
src/simulation/investment/appraisal/constraints.rs Applies selection-level demand constraints.
src/simulation/investment.rs Stores and aggregates selection-level demand.
src/output.rs Reports selection-level debug demand.
src/fixture.rs Updates appraisal fixtures.
benches/assets.rs Updates benchmark demand handling.
Review details

Suppressed comments (4)

src/output.rs:518

  • The new Season and Annual key-mapping branches are not covered by the writer test, which currently passes only TimeSliceLevel::DayNight. Add parameterised coverage for all three levels; otherwise a wrong selection lookup could make the developer debug output panic or report incorrect repeated demand while the existing test still passes.
                let selection = match time_slice_level {
                    TimeSliceLevel::Annual => TimeSliceSelection::Annual,
                    TimeSliceLevel::Season => TimeSliceSelection::Season(time_slice.season.clone()),
                    TimeSliceLevel::DayNight => TimeSliceSelection::Single(time_slice.clone()),
                };

src/simulation/investment.rs:134

  • This changes the demand representation used by investment appraisal for seasonal and annual commodities, so it is a correctness/behaviour change rather than a purely internal refactor. AGENTS.md:7-8 requires a note in docs/release_notes/upcoming.md for fixes present in the last release; please add that release-note entry to this PR.
/// Demand for each commodity is stored at its natural time-slice selection level, matching the
/// balance level at which the investment appraisal operates.

src/simulation/investment/appraisal/constraints.rs:55

  • This changes the appraisal constraint to read one demand value per balance bucket, but the existing investment tests only construct TimeSliceSelection::Single entries. Please add a parameterised regression test for seasonal and annual commodities, proving that a single bucket demand is used for the aggregate constraint and unmet-demand calculation.
    for ts_selection in time_slice_info.iter_selections_at_level(commodity.time_slice_level) {
        let demand_for_ts_selection = demand[&ts_selection];
        let terms: Vec<_> = ts_selection
            .iter(time_slice_info)
            .map(|(time_slice, _)| {
                let flow_coeff = asset.get_flow(&commodity.id).unwrap().coeff;

src/simulation/investment/appraisal/optimisation.rs:73

  • ResultsMap::unmet_demand is still documented above as being per time slice, but this change stores one residual per time-slice selection. Please update that public field documentation so it matches the new DemandMap representation.
/// Computes remaining unmet demand per time-slice selection after a solve.
///
/// For each time-slice selection at the commodity's balance level, the selection-level residual
/// (`demand - supply`, clamped to zero) is stored directly. Downstream consumers operate at the
/// selection level (e.g. the next round's demand constraint and `is_any_remaining_demand`), so
/// there is no need to distribute values across individual time slices.
  • Files reviewed: 9/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/simulation/investment.rs Outdated
@tsmbland tsmbland mentioned this pull request Sep 16, 2026
11 tasks
@tsmbland
tsmbland merged commit 3f551aa into main Sep 21, 2026
9 checks passed
@tsmbland
tsmbland deleted the demand_map_v2 branch September 21, 2026 13:15
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.

2 participants