Skip to content

Equalise equivalent assets in dispatch - #1477

Open
tsmbland wants to merge 6 commits into
mainfrom
asset_equalisation
Open

Equalise equivalent assets in dispatch#1477
tsmbland wants to merge 6 commits into
mainfrom
asset_equalisation

Conversation

@tsmbland

@tsmbland tsmbland commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Description

Following on from #1478, this PR constrains equivalent assets to have equal utilisation in every timeslice, to prevent it from arbitrarily utilising one asset over another. Equivalent assets are defined as assets of the same process in the same region.

There's a slight issue here that, since we allow process parameters and availability constraints to vary by commission year, assets of the same process/region, but with different commission years, may in fact not be equivalent. If costs are different, these constraints may result in a higher overall system cost. If availability constraints are different, these constraints may render the problem infeasible (although that's probably quite unlikely). We've thought about removing the ability of process costs/availabilities to vary by year, or otherwise being more strict in the way we do the grouping. We need to come up with a decision here before we can proceed with this. EDIT: the plan (see below) is to disallow process parameters/flows/limits from varying by year. Nothing needs to change in this PR, it will just have a slight pitfall until this change is made. We still might want to equalise different processes that are effectively the same for the purposes of dispatch, which we might be able to do by individually checking the relevant parameters (see 06d87e3 for a rough idea). That's way in the future though.

Fixes #1174. Hard to be absolutely sure, but the problem is now much more constrained so it's less likely that there's a space of equally good solutions for the solver to choose between. One positive sign is that the results are no longer impacted by updating highs (#1471), which was not the case before.

Fixes #1399. I've confirmed this using the example models in the issue.

You can see in debug_solver.csv that this has no impact on the objective value (look at the rows for 2020), until the point where the simulations diverge, in which case it's not comparable.

Screenshot from documentation

Screenshot 2026-08-11 at 14 39 17

Performance discussion

The number of constraints added to the optimisation depends on the structure/state of the model (i.e. how many equivalent assets exist). For each group of n equivalent assets, this adds (n - 1) * n_timeslices constraints. This will be at worst (n_assets - 1) * n_timeslices if all assets are equivalent. No extra variables are added. For the example models the performance hit is on the order of 0-5%. Similarly, for simple_modified the performance impact is negligible.

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

@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.43590% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 90.04%. Comparing base (6046c6b) to head (35c6a53).
⚠️ Report is 23 commits behind head on main.

Files with missing lines Patch % Lines
src/simulation/optimisation/constraints.rs 97.43% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1477      +/-   ##
==========================================
+ Coverage   89.91%   90.04%   +0.12%     
==========================================
  Files          60       60              
  Lines        8556     8597      +41     
  Branches     8556     8597      +41     
==========================================
+ Hits         7693     7741      +48     
+ Misses        543      537       -6     
+ Partials      320      319       -1     

☔ 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.

@tsmbland
tsmbland force-pushed the asset_equalisation branch from 0bd50cf to 0dc2c19 Compare August 11, 2026 13:03
@tsmbland
tsmbland changed the base branch from main to timeslice_equalisation August 11, 2026 13:03
@tsmbland tsmbland changed the title Asset equalisation Equalise equivalent assets in dispatch Aug 11, 2026
@tsmbland
tsmbland requested a lite review from Copilot August 11, 2026 13:22

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.

Pull request overview

This PR extends the dispatch optimisation model to prevent arbitrary selection among equivalent assets by constraining assets with the same (region, process) to have equal utilisation in each time slice, and documents the new constraint in the dispatch optimisation docs.

Changes:

  • Add “equal utilisation” constraints across fixed-capacity assets sharing the same process and region for every time slice.
  • Exclude flexible-capacity assets from these constraints (since their maximum activity depends on a decision variable).
  • Document the equal-utilisation concept and equations in the dispatch optimisation documentation.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/simulation/optimisation/constraints.rs Adds equal-utilisation constraint rows tying activity variables across equivalent assets per time slice.
docs/model/dispatch_optimisation.md Documents the equal-process-utilisation constraint and utilisation definition used by dispatch.

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

Comment thread src/simulation/optimisation/constraints.rs
Comment thread docs/model/dispatch_optimisation.md
Comment thread src/simulation/optimisation/constraints.rs
@tsmbland

Copy link
Copy Markdown
Collaborator Author

@ahawkes This seems to work well (see description above for details), but we need to decide what to do about process parameters/availabilities potentially varying by commission year. What do you think we should do?

@ahawkes

ahawkes commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

I think we should not allow process parameters to vary by commission year. If user want such variation they can create a new process for it. Suggest we make this change.

Two notes worth thinking about for the future:

  1. availabilities could change over asset lifetimes - particularly true for wind/solar where climate change might impact availability in future.
  2. if a user creates an almost-identical new process, and e.g. only changes a parameter that doesn't influence dispatch, then from dispatch perspective the two processes are identical and we might end up with the same/similar problem?

@tsmbland

tsmbland commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author

I think we should not allow process parameters to vary by commission year. If user want such variation they can create a new process for it. Suggest we make this change.

This is fine, but just so you're aware this is not a small change in terms of the code (unless we're happy to leave a load of dead code littering the codebase, which I wouldn't advise unless we might want to restore this later). Would ultimately simplify things though.

Would you also want to remove the ability for process parameters to vary by region? (Not needed for this issue, but if we did want to change this as well it would be worth doing at the same time)

Two notes worth thinking about for the future:

  1. availabilities could change over asset lifetimes - particularly true for wind/solar where climate change might impact availability in future.

As it stands, availabilities can vary by year, but these always apply to the commission year of the asset. What you're saying is that we should still allow availabilities to vary by year, but assets should always use parameters for the current year, regardless of commission year? Right?

  1. if a user creates an almost-identical new process, and e.g. only changes a parameter that doesn't influence dispatch, then from dispatch perspective the two processes are identical and we might end up with the same/similar problem?

Correct.

@ahawkes

ahawkes commented Aug 11, 2026 via email

Copy link
Copy Markdown
Contributor

@tsmbland

Copy link
Copy Markdown
Collaborator Author

Right. Maybe we hold off on this then? How much does it undermine the solution? Users can still make new processes with one parameter changed…

If we kept the current ability to let process parameters vary by year, then we could group any assets from the same process/region that have equal activity coefficients. If, in addition, we change availability limits so that they represent the current year rather than the commission year of the asset, then there's no issue about conflicts there.

Base automatically changed from timeslice_equalisation to main August 12, 2026 13:53
@ahawkes

ahawkes commented Aug 13, 2026 via email

Copy link
Copy Markdown
Contributor

@tsmbland

tsmbland commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

OK. The first bit sounds good, I think. The availability point is more complicated. For some processes this can vary per MSY (wind, solar). But for others like a nuclear power station it is fixed by the commission year. In general models like this fix all process parameters to commission year values. Can we not just group assets that have the same process/region and activity coefficient AND time-sliced availability? Or is that too many checks to perform?

Could do. Or could redefine what we're equalising so it takes availability limits into account. So, for example, if you had two assets, one with an upper availability limit of 1.0 and the other with 0.5, rather than equalising their utilisation (e.g. 50 activity for both), you'd equalise their utilisation relative to their availability limits (i.e. 66.6 and 33.3). Might work - would have to try.

@ahawkes

ahawkes commented Aug 13, 2026 via email

Copy link
Copy Markdown
Contributor

@tsmbland

Copy link
Copy Markdown
Collaborator Author

I guess availability could be defined at time slice level, seasonal level and/or annual level. Could get complicated right?

This is true... yeah may be too complicated

I’m not that keen on the extensive change to code you mentioned, but I think ultimately the likely best route is that process parameters are fixed for each process. That should include availabilities. That way we know for sure when processes are identical, and results clearer for users as they know the underlying parameters for each process without needing to refer to the commission year.

It's not impossible and would ultimately make the code simpler. I still think we should be absolutely sure this is what we want before proceeding.

The extra layer we probably want is to group assets that have the same activity coefficient as well. So if a user changes a parameter that doesn’t influence dispatch, the assets still get grouped and utilisation distributed. But would only be reliable where availabilities are identical, I think.

Yes, only reliable when availabilities and identical, and difficult to define "identical" when availabilities can be defined at different levels (unless you're really strict about it). You'd also have to check input/output commodities and flow coefficients to be sure that you're grouping equivalent processes. Quite fiddly.

@tsmbland tsmbland mentioned this pull request Aug 13, 2026
11 tasks
@tsmbland

Copy link
Copy Markdown
Collaborator Author

I think for now the easiest approach is just to check availability limits, flows (coefficients and costs) and variable operating costs, and group assets for which all of these are identical

@ahawkes

ahawkes commented Aug 13, 2026 via email

Copy link
Copy Markdown
Contributor

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.

Price differences when calculated for individual assets in multi agent model Potential for different dispatch results on different platforms

3 participants