Skip to content

Enable total capacity constraints#1417

Merged
tsmbland merged 7 commits into
mainfrom
add-total-capacity-constraint
Jul 17, 2026
Merged

Enable total capacity constraints#1417
tsmbland merged 7 commits into
mainfrom
add-total-capacity-constraint

Conversation

@dc2917

@dc2917 dc2917 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Description

This PR enables the option to provide total capacity constraints.

  • The csv reader looks for an optional total_capacity_limit column
  • If found, the entries are parsed with a custom deserialiser, which handles empty total_capacity_limit entries and treats them as None.
  • These are then stored in a new total_capacity_limit field of the ProcessInvestmentConstraintRaw struct.
  • Simple input validation takes place to check that the values, if not None are non-negative and finite.
    • Tests have been added for this validation
  • ProcessInvestmentConstraint now has a total_capacity_limit field, for use in get_addition_limit (not yet implemented)
  • get_addition_limit now also takes an Asset's current capacity for use in the calculation
  • Total capacity constraints for the MUSE1 default example have been added to examples/muse1_default/process_investment_constraints.csv
  • The schema for process_investment_constraints.csv input files has been updated with details of this new column

Fixes #1414

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 Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.79%. Comparing base (252421b) to head (e598605).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1417      +/-   ##
==========================================
- Coverage   86.80%   86.79%   -0.02%     
==========================================
  Files          59       59              
  Lines        8384     8375       -9     
  Branches     8384     8375       -9     
==========================================
- Hits         7278     7269       -9     
  Misses        790      790              
  Partials      316      316              

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

@dc2917
dc2917 requested a review from tsmbland July 14, 2026 14:28
Comment thread examples/muse1_default/process_investment_constraints.csv
Comment thread src/process.rs Outdated

@tsmbland tsmbland left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good start.

I've realised that my original plan wasn't as solid as I thought, so the actual implementation will be quite different. The input/validation code is nearly there though so I'd focus on tidying that up in this PR. If you put a note in the schema about the new parameter, mentioning that it's currently unused, then we could merge this and worry about the implementation later

Comment thread src/input/process/investment_constraints.rs Outdated
Comment thread src/input/process/investment_constraints.rs
Comment thread src/input/process/investment_constraints.rs Outdated
Comment thread src/asset.rs Outdated
.get(&(self.region_id.clone(), self.commission_year))
.and_then(|c| c.get_addition_limit().map(|l| l * commodity_portion))
.and_then(|c| {
c.get_addition_limit(self.capacity())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The capacity here isn't what we need in this context. This is the capacity of an individual candidate asset, which is the amount of capacity that we consider installing at a time (we may install multiple of these).

What we'd need to know is the total amount of capacity already installed, so we know how much wiggle room we have above this to install in the current year.

That said, this is more complicated than I originally thought. Because we decide how much of the existing capacity to keep (and how much to get rid of) as part of the investment process, which hasn't happened yet, we have a bit of a chicken and egg situation as we don't know how much capacity is installed (or, rather, how much of this will actually be kept).

Hope is not all lost, but this will require a different approach.

If you look at what happens currently with the addition limits, we store these in a map keyed by asset, and gradually trim from this as we install new capacity (i.e. coming from candidate assets). One way to implement the total capacity limit would be to have another map, keyed by process instead of asset, then gradually trim from this with all selected assets (both new assets and those chosen to be retained).

If this doesn't make any sense, or you don't want to worry about this, you can just focus this PR on the inputs/validation, but I'd remove the self.capacity() arg in any case as it's not right.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've removed this now, so get_addition_limit and ProcessInvestmentConstraint are as they were:

f577577

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

More quick thoughts on implementing this:

  • select_best_assets currently takes investment_limits (containing the addition limits), which we use to cap the capacities of candidate assets (i.e. not-yet-commissioned assets), and gets whittled down every time a candidate is selected
  • The simplest approach to implement total capacity limits would be to take another map HashMap<ProcessID, AssetCapacity> containing the total capacity limits. This would cap candidate assets in the same way as above, and also exclude any existing (non-candidate) assets with capacities higher than the current limit. (note that existing assets have fixed capacities so cannot have their capacities trimmed in the same way). This limit would get whittled down with every selected asset (candidate or existing). The initial limit would have to be scaled by the agent share, like we currently do for addition limits. Note that this should be keyed by ProcessID, so you'll need to extract the process that each asset corresponds to.
  • Could be a nicer way to do this like passing HashMap<ProcessID, ProcessInvestmentConstraint>. Would take a bit of creativity but I think it could work and probably cleaner than taking two separate maps.

Comment thread src/process.rs Outdated
@dc2917
dc2917 requested a review from tsmbland July 16, 2026 10:31

@tsmbland tsmbland left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is good! And a definite improvements to the tests.

The only think I might do is to mention the new parameter in the input file schema (schemas/input/process_investment_constraints.yaml), with a note that it's currently unused. I can see the argument for leaving it out though. In that case, I'd exclude it from muse1_default for now so we don't have undocumented parameters in the example models. Your call!

@dc2917
dc2917 force-pushed the add-total-capacity-constraint branch from 62561ab to e598605 Compare July 16, 2026 15:12
@tsmbland

Copy link
Copy Markdown
Collaborator

@dc2917 Think this is ready shall I merge?

@dc2917

dc2917 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

@dc2917 Think this is ready shall I merge?

Yes please!

@tsmbland
tsmbland merged commit 882d40d into main Jul 17, 2026
7 of 8 checks passed
@tsmbland
tsmbland deleted the add-total-capacity-constraint branch July 17, 2026 10:23
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.

Add total capacity constraint

2 participants