Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/PowerOperationsModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ include("core/definitions.jl")
include("core/interfaces.jl")
include("core/default_interface_methods.jl")
include("core/physical_constant_definitions.jl")
include("core/reserve_traits.jl")
include("core/variables.jl")
include("core/expressions.jl")
include("core/constraints.jl")
Expand Down Expand Up @@ -266,6 +267,10 @@ include("services_models/reserve_group.jl")
include("services_models/transmission_interface.jl")
include("services_models/services_constructor.jl")

# Hybrid System Models (after services_models since they share reserve infrastructure)
include("hybrid_system_models/hybrid_systems.jl")
include("hybrid_system_models/hybridsystem_constructor.jl")

# Two-Terminal HVDC Models
# NOTE: AC_branches.jl and branch_constructor.jl in twoterminal_hvdc_models/ are
# identical copies of the files in ac_transmission_models/ — do NOT include them.
Expand Down Expand Up @@ -647,6 +652,67 @@ export ReserveDeploymentBalanceDownCharge
export EnergyLimitParameter
export EnergyTargetParameter

######## Hybrid System Formulations ########
export AbstractHybridFormulation
export AbstractHybridFormulationWithReserves
export HybridDispatchWithReserves

# Reserve / constraint marker traits used to parametrize hybrid + storage families.
# ConstraintBound (and UpperBound/LowerBound) come from IOM via `using InfrastructureOptimizationModels`
# and are not re-exported here to avoid name collisions with the IOM-rooted symbols.
export ReserveDirection, Up, Down
export ReserveScale, UnscaledReserve, DeployedReserve
export ReserveSide, DischargeSide, ChargeSide
export ConstraintBound

# variables
export ChargeRegularizationVariable
export DischargeRegularizationVariable
export HybridChargingReserveVariable
export HybridDischargingReserveVariable
export HybridRenewableActivePower
export HybridRenewableReserveVariable
export HybridReserveVariableIn
export HybridReserveVariableOut
export HybridStorageChargePower
export HybridStorageDischargePower
export HybridStorageReservation
export HybridThermalActivePower
export HybridThermalReserveVariable

# expressions
export HybridServedReserveInDownExpression
export HybridServedReserveInUpExpression
export HybridServedReserveOutDownExpression
export HybridServedReserveOutUpExpression
export HybridTotalReserveInDownExpression
export HybridTotalReserveInUpExpression
export HybridTotalReserveOutDownExpression
export HybridTotalReserveOutUpExpression

# constraints
export ChargeRegularizationConstraint
export DischargeRegularizationConstraint
export HybridEnergyAssetBalanceConstraint
export HybridRenewableActivePowerLimitConstraint
export HybridRenewableReserveLimitConstraint
export HybridReserveAssignmentConstraint
export HybridReserveBalanceConstraint
export HybridStatusInOnConstraint
export HybridStatusOutOnConstraint
export HybridStorageBalanceConstraint
export HybridStorageChargingReservePowerLimitConstraint
export HybridStorageDischargingReservePowerLimitConstraint
export HybridStorageStatusChargeOnConstraint
export HybridStorageStatusDischargeOnConstraint
export HybridThermalOnVariableLbConstraint
export HybridThermalOnVariableUbConstraint
export HybridThermalReserveLimitConstraint

# parameters
export HybridElectricLoadTimeSeriesParameter
export HybridRenewableActivePowerTimeSeriesParameter

#################################################################################
# Exports - Constraint Types (defined in core/constraints.jl)
#################################################################################
Expand Down
86 changes: 86 additions & 0 deletions src/core/constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1100,3 +1100,89 @@ The specified constraints are formulated as:
```
"""
struct ShiftDownActivePowerVariableLimitsConstraint <: PowerVariableLimitsConstraint end

#################################################################################
# Hybrid System Constraints
#################################################################################

"""
Couples the hybrid PCC reserve variables (out + in) to the system-level
`ActivePowerReserveVariable` of each service the hybrid participates in.
"""
struct HybridReserveAssignmentConstraint <: ConstraintType end

"""
Couples the hybrid PCC reserve variables (out + in) to the sum of per-subcomponent reserve
allocations (thermal + renewable + charging + discharging).
"""
struct HybridReserveBalanceConstraint <: ConstraintType end

"""
Equates the hybrid's PCC active-power injection to the sum of internal subcomponent
flows (thermal + renewable + storage discharge - storage charge - load) net of served
reserves.
"""
struct HybridEnergyAssetBalanceConstraint <: ConstraintType end

"""
Status link between a hybrid PCC active-power variable and the reservation variable.
Parametric on [`ReserveSide`](@ref): `HybridStatusOnConstraint{DischargeSide}` is the
historical `HybridStatusOutOnConstraint`, `{ChargeSide}` is `HybridStatusInOnConstraint`.
"""
struct HybridStatusOnConstraint{Sd <: ReserveSide} <: ConstraintType end
const HybridStatusOutOnConstraint = HybridStatusOnConstraint{DischargeSide}
const HybridStatusInOnConstraint = HybridStatusOnConstraint{ChargeSide}

"""
Bound between thermal subcomponent power and its commitment status (no-reserves case).
Parametric on [`ConstraintBound`](@ref): `HybridThermalOnVariableConstraint{UpperBound}`
is the historical `HybridThermalOnVariableUbConstraint`.
"""
struct HybridThermalOnVariableConstraint{B <: ConstraintBound} <: ConstraintType end
const HybridThermalOnVariableUbConstraint = HybridThermalOnVariableConstraint{UpperBound}
const HybridThermalOnVariableLbConstraint = HybridThermalOnVariableConstraint{LowerBound}

"Range constraint on thermal subcomponent power including up/down reserves."
struct HybridThermalReserveLimitConstraint <: ConstraintType end

"Upper bound on renewable subcomponent power from the time-series forecast."
struct HybridRenewableActivePowerLimitConstraint <: ConstraintType end

"Range constraint on renewable subcomponent power including up/down reserves."
struct HybridRenewableReserveLimitConstraint <: ConstraintType end

"Energy balance for the storage subcomponent of a hybrid system, including reserve deployment."
struct HybridStorageBalanceConstraint <: ConstraintType end

"""
Mutually-exclusive charge/discharge limit for the hybrid storage subcomponent
(no-reserves case). Parametric on [`ReserveSide`](@ref):
`HybridStorageStatusOnConstraint{ChargeSide}` is the historical
`HybridStorageStatusChargeOnConstraint`.
"""
struct HybridStorageStatusOnConstraint{Sd <: ReserveSide} <: ConstraintType end
const HybridStorageStatusChargeOnConstraint = HybridStorageStatusOnConstraint{ChargeSide}
const HybridStorageStatusDischargeOnConstraint =
HybridStorageStatusOnConstraint{DischargeSide}

"""
Charge- or discharge-side power limit for the hybrid storage subcomponent including
reserve carve-outs. Parametric on [`ReserveSide`](@ref):
`HybridStorageReservePowerLimitConstraint{ChargeSide}` is the historical
`HybridStorageChargingReservePowerLimitConstraint`.
"""
struct HybridStorageReservePowerLimitConstraint{Sd <: ReserveSide} <: ConstraintType end
const HybridStorageChargingReservePowerLimitConstraint =
HybridStorageReservePowerLimitConstraint{ChargeSide}
const HybridStorageDischargingReservePowerLimitConstraint =
HybridStorageReservePowerLimitConstraint{DischargeSide}

"""
Bounds the absolute charge- or discharge-power step change between consecutive time
steps, penalizing oscillation. Active only when the hybrid `\"regularization\"`
attribute is set. Parametric on [`ReserveSide`](@ref):
`RegularizationConstraint{ChargeSide}` is the historical `ChargeRegularizationConstraint`.
"""
struct RegularizationConstraint{Sd <: ReserveSide} <: ConstraintType end
const ChargeRegularizationConstraint = RegularizationConstraint{ChargeSide}
const DischargeRegularizationConstraint = RegularizationConstraint{DischargeSide}
107 changes: 90 additions & 17 deletions src/core/expressions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,25 +78,98 @@ of the energy balance for the system in medium term planning
struct EnergyBalanceExpression <: ExpressionType end

#################################################################################
# Energy Storage Expressions
# Energy Storage / Hybrid Reserve Aggregation Expressions
#
# A single parametric family covers both the hybrid PCC boundary aggregation
# (HybridPCCReserveExpression) and the storage-subcomponent balance aggregation
# (StorageReserveBalanceExpression). The three axes are:
# D <: ReserveDirection : Up | Down
# S <: ReserveScale : UnscaledReserve (multiplier 1.0)
# | DeployedReserve (multiplier = get_deployed_fraction(s))
# Sd <: ReserveSide : DischargeSide (PCC "Out" / storage "Discharge")
# | ChargeSide (PCC "In" / storage "Charge")
# Each of the 16 historical singletons is retained as a const alias for an exact
# parametrization, so all existing imports and `get_expression(container, T, V)`
# calls continue to work unchanged.
#################################################################################

"""
Per-device, per-service aggregation of the reserve quantity offered by a storage device
(or the storage subcomponent of a hybrid system). One container is created per service
participated in, and the per-component reserve variables (charging + discharging) are
summed into it. Consumed by [`HybridReserveBalanceConstraint`](@ref) and used as the
right-hand side of the system-level reserve balance.
"""
struct TotalReserveOffering <: ExpressionType end

abstract type StorageReserveDischargeExpression <: ExpressionType end
abstract type StorageReserveChargeExpression <: ExpressionType end

# Used for the Power Limits constraints
struct ReserveAssignmentBalanceUpDischarge <: StorageReserveDischargeExpression end
struct ReserveAssignmentBalanceUpCharge <: StorageReserveChargeExpression end
struct ReserveAssignmentBalanceDownDischarge <: StorageReserveDischargeExpression end
struct ReserveAssignmentBalanceDownCharge <: StorageReserveChargeExpression end

# Used for the SoC estimates
struct ReserveDeploymentBalanceUpDischarge <: StorageReserveDischargeExpression end
struct ReserveDeploymentBalanceUpCharge <: StorageReserveChargeExpression end
struct ReserveDeploymentBalanceDownDischarge <: StorageReserveDischargeExpression end
struct ReserveDeploymentBalanceDownCharge <: StorageReserveChargeExpression end
abstract type ReserveAggregationExpression{
D <: ReserveDirection,
S <: ReserveScale,
Sd <: ReserveSide,
} <: ExpressionType end

"""
Hybrid-boundary aggregation of reserve quantities offered through the discharge (out) and
charge (in) sides of a `PSY.HybridSystem`. Concrete parametrizations of the three axes
(Direction / Scale / Side) are exposed as the historical alias names below.
"""
struct HybridPCCReserveExpression{D, S, Sd} <:
ReserveAggregationExpression{D, S, Sd} end

"""
Aggregation of reserve variables allocated to the storage subcomponent of a hybrid system
(or a standalone storage device). Concrete parametrizations of the three axes
(Direction / Scale / Side) are exposed as the historical alias names below.
"""
struct StorageReserveBalanceExpression{D, S, Sd} <:
ReserveAggregationExpression{D, S, Sd} end

# Historical hybrid PCC names retained as const aliases.
const HybridTotalReserveOutUpExpression =
HybridPCCReserveExpression{Up, UnscaledReserve, DischargeSide}
const HybridTotalReserveOutDownExpression =
HybridPCCReserveExpression{Down, UnscaledReserve, DischargeSide}
const HybridTotalReserveInUpExpression =
HybridPCCReserveExpression{Up, UnscaledReserve, ChargeSide}
const HybridTotalReserveInDownExpression =
HybridPCCReserveExpression{Down, UnscaledReserve, ChargeSide}
const HybridServedReserveOutUpExpression =
HybridPCCReserveExpression{Up, DeployedReserve, DischargeSide}
const HybridServedReserveOutDownExpression =
HybridPCCReserveExpression{Down, DeployedReserve, DischargeSide}
const HybridServedReserveInUpExpression =
HybridPCCReserveExpression{Up, DeployedReserve, ChargeSide}
const HybridServedReserveInDownExpression =
HybridPCCReserveExpression{Down, DeployedReserve, ChargeSide}

# Historical storage balance names retained as const aliases.
const ReserveAssignmentBalanceUpDischarge =
StorageReserveBalanceExpression{Up, UnscaledReserve, DischargeSide}
const ReserveAssignmentBalanceDownDischarge =
StorageReserveBalanceExpression{Down, UnscaledReserve, DischargeSide}
const ReserveAssignmentBalanceUpCharge =
StorageReserveBalanceExpression{Up, UnscaledReserve, ChargeSide}
const ReserveAssignmentBalanceDownCharge =
StorageReserveBalanceExpression{Down, UnscaledReserve, ChargeSide}
const ReserveDeploymentBalanceUpDischarge =
StorageReserveBalanceExpression{Up, DeployedReserve, DischargeSide}
const ReserveDeploymentBalanceDownDischarge =
StorageReserveBalanceExpression{Down, DeployedReserve, DischargeSide}
const ReserveDeploymentBalanceUpCharge =
StorageReserveBalanceExpression{Up, DeployedReserve, ChargeSide}
const ReserveDeploymentBalanceDownCharge =
StorageReserveBalanceExpression{Down, DeployedReserve, ChargeSide}

# Role-based Union aliases retained for callers that match by scale (Total/Served)
# or by storage side (Charge/Discharge) rather than by direction.
const HybridTotalReserveExpression =
HybridPCCReserveExpression{<:ReserveDirection, UnscaledReserve, <:ReserveSide}
const HybridServedReserveExpression =
HybridPCCReserveExpression{<:ReserveDirection, DeployedReserve, <:ReserveSide}
const StorageReserveDischargeExpression =
StorageReserveBalanceExpression{<:ReserveDirection, <:ReserveScale, DischargeSide}
const StorageReserveChargeExpression =
StorageReserveBalanceExpression{<:ReserveDirection, <:ReserveScale, ChargeSide}

# Method extensions for output writing
should_write_resulting_value(::Type{InterfaceTotalFlow}) = true
Expand All @@ -108,8 +181,8 @@ should_write_resulting_value(::Type{HydroServedReserveDownExpression}) = true
should_write_resulting_value(::Type{TotalHydroFlowRateReservoirOutgoing}) = true
should_write_resulting_value(::Type{TotalHydroFlowRateTurbineOutgoing}) = true

should_write_resulting_value(::Type{StorageReserveDischargeExpression}) = true
should_write_resulting_value(::Type{StorageReserveChargeExpression}) = true
should_write_resulting_value(::Type{<:StorageReserveBalanceExpression}) = true
should_write_resulting_value(::Type{<:HybridServedReserveExpression}) = true

# Method extensions for unit conversion
convert_output_to_natural_units(::Type{InterfaceTotalFlow}) = true
Expand Down
Loading
Loading