Skip to content

Split the units machinery out of ProductionVariableCostCurve; add LossCurve - #603

Closed
luke-kiernan wants to merge 1 commit into
IS4from
lk/issue-1728-loss-curve-units
Closed

Split the units machinery out of ProductionVariableCostCurve; add LossCurve#603
luke-kiernan wants to merge 1 commit into
IS4from
lk/issue-1728-loss-curve-units

Conversation

@luke-kiernan

@luke-kiernan luke-kiernan commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Supports PowerSystems.jl#1728, where loss curves on HVDC lines and converters are bare ValueCurves carrying no units, leaving their axes ambiguous.

Carrying units isn't specific to costs, so that machinery is split out one level:

ValueCurveWithUnits{T, U}          # value_curve + units type parameter
├── ProductionVariableCostCurve    # adds vom_cost
│   ├── CostCurve
│   └── FuelCurve
└── LossCurve

The new supertype owns what both families share (units parameter, value-curve accessors, equality/hashing, serialization, display). ProductionVariableCostCurve keeps only what makes a curve a cost: get_vom_cost and the cost-specific field deserializers.

LossCurve is deliberately not under ProductionVariableCostCurve: ThermalGenerationCost.variable/HydroGenerationCost.variable are typed on it, and get_vom_cost is defined on it — a loss curve has no VOM cost.

No behavior or serialization change for CostCurve/FuelCurve; methods moved, none removed or altered.

Tests: 1462 pass. The Test generated structs failure is pre-existing on IS4 (verified against a clean baseline, unrelated).

Pairs with a PowerSystems.jl PR against psy6.

🤖 Generated with Claude Code

…sCurve

Loss curves on HVDC lines and converters (PowerSystems.jl) were declared as
bare `ValueCurve`s, which carry no units, so whether a curve's axes were in MW,
system base, or device base was ambiguous — and consumers disagreed in practice
(PSB builds an `InterconnectingConverter` loss curve in system base while an
open POM PR reads the same curve as device base).

Carrying units is not specific to costs, so the machinery that does it is now
split out one level:

    ValueCurveWithUnits{T, U}          # value_curve + units type parameter
    ├── ProductionVariableCostCurve    # adds vom_cost
    │   ├── CostCurve
    │   └── FuelCurve
    └── LossCurve

`ValueCurveWithUnits` owns everything the two families share — the units type
parameter and `get_power_units`, the value-curve accessors, convexity,
equality/hashing, `serialize`/`deserialize` including the `power_units` key, and
the expanded `show`. `ProductionVariableCostCurve` keeps only what makes a curve
a *cost*: `get_vom_cost` and the cost-specific per-field deserializers.

That division is load-bearing, not cosmetic. Curve-valued cost fields
(`ThermalGenerationCost.variable`, `HydroGenerationCost.variable`) are typed on
`ProductionVariableCostCurve`, so they still reject a `LossCurve`; and losses
have no VOM cost, so inheriting `get_vom_cost` would have promised a field that
isn't there. Sharing at the `ValueCurveWithUnits` level gets the common
implementation without either problem.

No behavior change for `CostCurve`/`FuelCurve`: the methods moved to the
supertype, none were removed or altered.

Part of the fix for PowerSystems.jl#1728.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@luke-kiernan
luke-kiernan requested review from jd-lara and a lite review from Copilot August 6, 2026 16:07

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 refactors the unit-system type-parameter machinery out of ProductionVariableCostCurve into a new shared supertype (ValueCurveWithUnits) and introduces LossCurve so loss-related curves can carry an explicit (dispatchable) x-axis unit system, addressing ambiguous axes for HVDC loss curves.

Changes:

  • Added ValueCurveWithUnits{T,U} to own shared accessors, equality/hash, serialization, and show behavior for unit-parameterized curves.
  • Updated ProductionVariableCostCurve{T,U} to subtype ValueCurveWithUnits{T,U} and kept only cost-specific functionality (e.g., vom_cost field deserialization).
  • Added LossCurve{T,U} plus new tests covering construction, display, serialization round-trips, and zero behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/test_cost_functions.jl Adds LossCurve test coverage (construction, units typing, show output, serialization, zero).
src/value_curve_with_units.jl Introduces new shared abstract supertype and common methods (accessors, TS helpers, equality/hash, serialization, show).
src/production_variable_cost_curve.jl Re-bases PVCC on ValueCurveWithUnits and moves shared logic out; retains PVCC-specific deserializers and compact show.
src/loss_curve.jl Adds the new LossCurve type, constructors, AnyLossCurve, zero, and compact show.
src/InfrastructureSystems.jl Wires new source files into module load order via include.

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


Base.isequal(a::T, b::T) where {T <: ValueCurveWithUnits} = isequal_from_fields(a, b)

Base.hash(a::ValueCurveWithUnits, h::UInt) = hash_from_fields(a, h)
@luke-kiernan
luke-kiernan marked this pull request as draft August 6, 2026 16:19
@luke-kiernan

Copy link
Copy Markdown
Contributor Author

Reverted to draft--revisit after the schema stuff lands, so that the folks working on integrating that stuff don't have to deal with a moving target.

@jd-lara

jd-lara commented Aug 22, 2026

Copy link
Copy Markdown
Member

@luke-kiernan you can restart this now

@luke-kiernan

Copy link
Copy Markdown
Contributor Author

Superseded by #621, which reimplements this on top of current IS4 (this branch was based on a much older IS4, ~159 commits behind). The Copilot hash feedback here was addressed separately and has already merged into IS4.

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.

4 participants