Skip to content

feat(clearing): support directional transfer capacities in complex clearing - #812

Open
isaac-gumbrell wants to merge 6 commits into
assume-framework:mainfrom
isaac-gumbrell:pr/directional-constraints
Open

feat(clearing): support directional transfer capacities in complex clearing#812
isaac-gumbrell wants to merge 6 commits into
assume-framework:mainfrom
isaac-gumbrell:pr/directional-constraints

Conversation

@isaac-gumbrell

Copy link
Copy Markdown
Contributor

Description

This PR adds directional transfer-capacity support to complex_clearing.

Previously, transfer limits were treated symmetrically. This change allows users to specify different forward and reverse capacities and applies those asymmetric limits during complex market clearing. This is useful for zonal studies where commercial transfer limits differ by direction.

If directional capacity columns are not provided, the existing symmetric-capacity behaviour is retained.

Changes in this PR:

  • add directional line-capacity aggregation
  • integrate directional constraints into complex_clearing
  • add an example scenario demonstrating directional capacities
  • document the new behaviour in the market-mechanism docs

Checklist

  • Documentation updated (docstrings, READMEs, user guides, inline comments, doc folder updates etc.)
  • New unit/integration tests added (if applicable)
  • Changes noted in release notes (if any)
  • Consent to release this PR's code under the GNU Affero General Public License v3.0

Additional Notes (optional)

igumbrell_deloitte and others added 2 commits May 25, 2026 11:12
…ex clearing

- Implemented aggregate_line_capacities function to compute forward and reverse capacities for lines based on directional columns or aggregated by node pairs.
- Updated complex_clearing.py to utilize precomputed directional capacities in market clearing constraints.
- Enhanced market clearing optimization to accept directional capacities as an argument.
- Added example scenario to showcase and test directional constraint functionality.
@codecov

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 37.31343% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.18%. Comparing base (c330ab5) to head (fd836b9).

Files with missing lines Patch % Lines
assume/common/utils.py 28.57% 35 Missing ⚠️
...me/markets/clearing_algorithms/complex_clearing.py 61.11% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #812      +/-   ##
==========================================
- Coverage   80.51%   80.18%   -0.33%     
==========================================
  Files          56       56              
  Lines        9056     9118      +62     
==========================================
+ Hits         7291     7311      +20     
- Misses       1765     1807      +42     
Flag Coverage Δ
pytest 80.18% <37.31%> (-0.33%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 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.

@isaac-gumbrell
isaac-gumbrell force-pushed the pr/directional-constraints branch from 55a7565 to fd836b9 Compare May 27, 2026 09:00

@gugrimm gugrimm 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.

Thank you for this useful initiative! I don't have any fundamental objection. The development also does not block the time dependent s_max_pu (dynamic line rating) that we would potentially like to introduce in future. But I have three comments:

  • I think s_max_pu should also apply to the directional limits
  • the aggregation function (sum) is only correct in a transport model, not in a PF. So I would like to be sure users do not mis-use or mis-interpret the function as a way of clustering /simplyfying networks. Which is what I could think it is, if I hear "aggregation".
  • tests are missing

Comment thread assume/common/utils.py
return incidence_matrix


def aggregate_line_capacities(

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.

I have a small problem with the name of this function. It sums the capacities. This addition is only valid if we consider a transport model, not if we consider a powerflow. The function is intended to be used within the complex clearing, which uses a transport model and which is therefore ok. But I would appreciate a way to rename this function in a way that makes clear that it is not intended to be used for aggregation of lines for an PF. What about "sum_line_capacities"?

directional_capacities is not None
and line in directional_capacities.index
):
cap_forward = directional_capacities.at[line, "cap_forward"]

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.

for consistency I would multiply by s_max_pu here too. s_max_pu defaults to 1. But if people explicitly use it (e.g. setting to 0.7 to approximate n-1 security or setting to high values to mimic unconstrained networks without needing to adjust s_nom), it should not only apply to non-directional capacities but also to directional ones.

and line in directional_capacities.index
):
cap_forward = directional_capacities.at[line, "cap_forward"]
cap_reverse = directional_capacities.at[line, "cap_reverse"]

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.

same here: multiply by s_max_pu


-NTC_{l} \leq F_{l, t} \leq NTC_{l} \quad \forall \: l \in \mathcal{L}, t \in \mathcal{T}

If ``lines.csv`` additionally provides ``s_nom_forward`` and/or ``s_nom_reverse``, the complex clearing uses these directional limits instead. This allows transport constraints to differ by flow direction, which is useful for zonal representations with asymmetric commercial transfer capacities.

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.

add sth like: s_max_pu is still applied.


**New Features:**
- **Generic Forecasting Interface**: This interface enables to specify different forecast algorithms for preprocess, initialization and update during runtime. They can be specified in the config.yaml or unit csv files. For more information about currently implemented algorithms and how to specify them please read the documentation on Unit forecasts.
- **Directional transfer capacities in complex clearing**: ``complex_clearing`` can now use asymmetric line limits from ``s_nom_forward`` and ``s_nom_reverse`` instead of assuming the same transfer capacity in both directions.

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.

add sth like: s_max_pu is still applied.

@gugrimm

gugrimm commented May 27, 2026

Copy link
Copy Markdown
Contributor

I added some tests with support by LLM. Could you have a look?
The one with s_max_pu still fails because we do not consider it yet, but as mentioned, I think we should.

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.

3 participants