Skip to content

fix: PSSE v35 export of systems with no non-transformer branches (#361)#394

Merged
luke-kiernan merged 2 commits into
mainfrom
lk/fix-361-empty-branch-export
Jun 17, 2026
Merged

fix: PSSE v35 export of systems with no non-transformer branches (#361)#394
luke-kiernan merged 2 commits into
mainfrom
lk/fix-361-empty-branch-export

Conversation

@luke-kiernan

Copy link
Copy Markdown
Collaborator

Summary

Fixes the second (still-open) half of #361: exporting a v35 PSS/e file from a system with no non-transformer branches threw

MethodError: no method matching serialize_component_ids(::Dict{Tuple{Tuple{Int64, Int64, Vararg{Int64}}, String}, String})

Root cause

get_branches_with_numbers returned an untyped comprehension. With zero branches, inference widened the bus-number container type to Tuple{Int, Int, Vararg{Int}}, so the empty branch_name_mapping dict matched none of the concrete serialize_component_ids dispatches.

Fix

Pin the comprehension element type to Tuple{PSY.ACBranch, Tuple{Int, Int}} so the empty case keeps concrete Tuple{Int, Int} container ids, which the existing 2-tuple serialize_component_ids method handles. (Matches the issue's suggested "concrete element type" fix and Sienna's concrete-container convention.)

The RATE4–RATE12 type-instability (the first half of #361) was already fixed in #360 via the numeric 0.0 default — this PR adds the missing regression coverage for it.

Tests

Two regression testsets in test_psse_export.jl, mirroring the issue's minimal repros:

  1. v35 Line missing RATE4..RATE12 ext keys — programmatic Line (no RATE keys), asserts export succeeds and extra ratings are written as 0.0.
  2. v35 system with no non-transformer branches — asserts export succeeds and branch_name_mapping is empty.

Both fail on the prior code (they threw before producing files) and pass with this change. Full local test_psse_export.jl suite passes.

Closes #361.

🤖 Generated with Claude Code

When a system has no Lines/MonitoredLines/DiscreteControlledACBranches,
`get_branches_with_numbers` returned an untyped comprehension, so inference
widened the bus-number container type to `Tuple{Int, Int, Vararg{Int}}`. The
resulting empty `branch_name_mapping` matched no `serialize_component_ids`
method and the v35 export threw a `MethodError`.

Pin the comprehension element type to `Tuple{PSY.ACBranch, Tuple{Int, Int}}`
so the empty case keeps concrete `Tuple{Int, Int}` container ids, which the
existing 2-tuple `serialize_component_ids` dispatch handles.

Add two regression tests mirroring the issue's repros:
- v35 export of a programmatic Line missing RATE4..RATE12 ext keys (the
  numeric-default path fixed in #360), asserting extra ratings export as 0.0.
- v35 export of a system with no non-transformer branches.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Performance Results

Precompile Time

Main This Branch Delta
2.603 s 2.579 s -0.9%

Solve Time

Polar AC

Test Main This Branch Delta
NewtonRaphsonACPowerFlow First Solve 15.584 s 15.768 s +1.2%
NewtonRaphsonACPowerFlow Second Solve 88.1 ms 100.4 ms +13.9%
RobustHomotopyPowerFlow First Solve 16.668 s 16.957 s +1.7%
RobustHomotopyPowerFlow Second Solve 8.93 s 9.235 s +3.4%
NewtonRaphsonACPowerFlow(iwamoto) First Solve 202.8 ms 201.2 ms -0.8%
NewtonRaphsonACPowerFlow(iwamoto) Second Solve 88.2 ms 653.2 ms +640.1%
TrustRegionACPowerFlow(iwamoto) First Solve 1.649 s 1.635 s -0.8%
TrustRegionACPowerFlow(iwamoto) Second Solve 714.4 ms 86.8 ms -87.8%
NewtonRaphsonACPowerFlow First Solve 1.227 s 1.087 s -11.4%
NewtonRaphsonACPowerFlow Second Solve 1.046 s 1.118 s +6.8%
TrustRegionACPowerFlow First Solve 1.321 s 1.308 s -1.0%
TrustRegionACPowerFlow Second Solve 1.241 s 1.106 s -10.9%

Rectangular CI

Test Main This Branch Delta
ACRectangularPowerFlow{NR} First Solve 5.198 s 5.81 s +11.8%
ACRectangularPowerFlow{NR} Second Solve 43.4 ms 41.3 ms -5.0%
ACRectangularPowerFlow{NR}(iwamoto) First Solve 162.4 ms 164.2 ms +1.1%
ACRectangularPowerFlow{NR}(iwamoto) Second Solve 41.8 ms 42.1 ms +0.8%
ACRectangularPowerFlow{TR} First Solve 5.569 s 5.59 s +0.4%
ACRectangularPowerFlow{TR} Second Solve 43.1 ms 42.8 ms -0.7%
ACRectangularPowerFlow{TR}(iwamoto_fallback) First Solve 164.6 ms 164.8 ms +0.1%
ACRectangularPowerFlow{TR}(iwamoto_fallback) Second Solve 125.3 ms 63.7 ms -49.2%

Mixed CPB

Test Main This Branch Delta
ACMixedPowerFlow{NR} First Solve 5.105 s 4.866 s -4.7%
ACMixedPowerFlow{NR} Second Solve 44.8 ms 44.1 ms -1.5%
ACMixedPowerFlow{NR}(iwamoto) First Solve 166.6 ms 166.1 ms -0.3%
ACMixedPowerFlow{NR}(iwamoto) Second Solve 44.5 ms 166.2 ms +273.2%
ACMixedPowerFlow{TR} First Solve 5.096 s 5.12 s +0.5%
ACMixedPowerFlow{TR} Second Solve 46.0 ms 45.6 ms -0.7%
ACMixedPowerFlow{TR}(iwamoto_fallback) First Solve 192.3 ms 166.9 ms -13.2%
ACMixedPowerFlow{TR}(iwamoto_fallback) Second Solve 46.1 ms 45.4 ms -1.4%
ACMixedPowerFlow{LM} First Solve 7.279 s 7.188 s -1.3%
ACMixedPowerFlow{LM} Second Solve 1.042 s 982.6 ms -5.7%

DC

Test Main This Branch Delta
DCPowerFlow First Solve 3.853 s 3.831 s -0.6%
DCPowerFlow Second Solve 15.5 ms 15.2 ms -2.0%
PTDFDCPowerFlow First Solve 1.585 s 1.588 s +0.2%
PTDFDCPowerFlow Second Solve 78.1 ms 73.8 ms -5.5%
vPTDFDCPowerFlow First Solve 6.499 s 6.273 s -3.5%
vPTDFDCPowerFlow Second Solve 4.419 s 4.314 s -2.4%
DCPowerFlow First Solve 197.3 ms 190.7 ms -3.4%
DCPowerFlow Second Solve 191.2 ms 197.5 ms +3.3%

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 fixes a PSS/E v35 export failure when exporting systems that have zero non-transformer branches, caused by type-widening in get_branches_with_numbers leading to a serialize_component_ids dispatch miss. It also adds regression tests covering both the empty-branches case and the previously-reported v35 RATE4–RATE12 missing-ext-keys case.

Changes:

  • Make get_branches_with_numbers return a concretely-typed Vector{Tuple{PSY.ACBranch, Tuple{Int, Int}}} even when empty to avoid type-widening.
  • Add regression tests ensuring v35 export succeeds for (1) a programmatically-built Line missing RATE4–RATE12 ext keys and (2) a system with no non-transformer branches.

Reviewed changes

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

File Description
src/psse_export.jl Pins the branch/bus-number tuple vector element type to prevent empty-collection type widening and downstream dispatch failures.
test/test_psse_export.jl Adds two regression testsets reproducing issue #361 scenarios and asserting successful export + expected metadata/RAW output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/test_psse_export.jl Outdated
Comment thread test/test_psse_export.jl
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@luke-kiernan luke-kiernan merged commit 8cdd3cf into main Jun 17, 2026
7 checks passed
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.

PSSEExporter type-instability when Line ext dict missing RATE4–RATE12 keys

3 participants