From f28db5764ab8145979ca8afc9c366e73553616e2 Mon Sep 17 00:00:00 2001 From: m-bossart Date: Thu, 30 Jul 2026 15:59:02 -0700 Subject: [PATCH] fix: widen event parameter contingency bound to SupplementalAttribute PSY.Contingency subtypes IS.SupplementalAttribute, not IS.InfrastructureSystemsComponent, so the event add_param_container! overload and EventParametersAttributes MethodError on real contingency types. Widen the contingency type parameter's bound and drop the unused affected_devices field, which had no readers. --- src/common_models/add_param_container.jl | 2 +- src/core/parameter_container.jl | 16 +++++++------ test/mocks/mock_components.jl | 7 ++++++ test/test_optimization_container.jl | 30 ++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/common_models/add_param_container.jl b/src/common_models/add_param_container.jl index 930a4c8..1414ca3 100644 --- a/src/common_models/add_param_container.jl +++ b/src/common_models/add_param_container.jl @@ -93,7 +93,7 @@ function add_param_container!( ) where { T <: EventParameter, U <: IS.InfrastructureSystemsComponent, - V <: IS.InfrastructureSystemsComponent, + V <: IS.SupplementalAttribute, } param_key = ParameterKey(T, U, meta) attributes = EventParametersAttributes(V, T) diff --git a/src/core/parameter_container.jl b/src/core/parameter_container.jl index 07de983..e5b0c6b 100644 --- a/src/core/parameter_container.jl +++ b/src/core/parameter_container.jl @@ -80,23 +80,25 @@ get_sos_status(attr::CostFunctionAttributes) = attr.sos_status get_variable_types(attr::CostFunctionAttributes) = attr.variable_types get_uses_compact_power(attr::CostFunctionAttributes) = attr.uses_compact_power +""" +Attributes for event (contingency) parameters. `T` is the `IS.SupplementalAttribute` +subtype describing the contingency and `U` is the parameter type stored in the container. +""" struct EventParametersAttributes{ - T <: IS.InfrastructureSystemsComponent, + T <: IS.SupplementalAttribute, U <: ParameterType, -} <: ParameterAttributes - affected_devices::Vector{T} -end +} <: ParameterAttributes end function EventParametersAttributes( ::Type{T}, ::Type{U}, -) where {T <: IS.InfrastructureSystemsComponent, U <: ParameterType} - return EventParametersAttributes{T, U}(T[]) +) where {T <: IS.SupplementalAttribute, U <: ParameterType} + return EventParametersAttributes{T, U}() end function get_param_type( ::EventParametersAttributes{T, U}, -) where {T <: IS.InfrastructureSystemsComponent, U <: ParameterType} +) where {T <: IS.SupplementalAttribute, U <: ParameterType} return U end diff --git a/test/mocks/mock_components.jl b/test/mocks/mock_components.jl index 2e2881c..b59f1b7 100644 --- a/test/mocks/mock_components.jl +++ b/test/mocks/mock_components.jl @@ -150,6 +150,13 @@ get_rate(b::MockBranch) = b.rating # Subtypes IS.InfrastructureSystemsComponent so it works with VariableKey, ConstraintKey, etc. struct MockComponentType <: IS.InfrastructureSystemsComponent end +# Mock supplemental attribute for testing event parameter containers. +# Subtypes IS.SupplementalAttribute (not IS.InfrastructureSystemsComponent), mirroring +# PSY.Contingency <: SupplementalAttribute. +struct MockContingency <: IS.SupplementalAttribute end + +struct MockEventParameter <: InfrastructureOptimizationModels.EventParameter end + # Structures for the network problem struct MockNetworkNode <: IS.InfrastructureSystemsComponent name::String diff --git a/test/test_optimization_container.jl b/test/test_optimization_container.jl index 69feba6..44099dc 100644 --- a/test/test_optimization_container.jl +++ b/test/test_optimization_container.jl @@ -391,4 +391,34 @@ struct MockExpressionType <: ISOPT.ExpressionType end @test expr1 == expr2 @test JuMP.coefficient(expr2, x) == 5.0 end + + @testset "Event parameter container accepts supplemental-attribute contingency types" begin + mock_sys = MockSystem(100.0) + settings = IOM.Settings( + mock_sys; + horizon = Dates.Hour(24), + resolution = Dates.Hour(1), + time_series_cache_size = 0, + ) + container = IOM.OptimizationContainer( + mock_sys, + settings, + nothing, + MockDeterministic, + ) + IOM.set_time_steps!(container, 1:24) + time_steps = IOM.get_time_steps(container) + + IOM.add_param_container!( + container, + MockEventParameter, + MockComponentType, + MockContingency, + ["dev1", "dev2"], + time_steps, + ) + key = IOM.ParameterKey(MockEventParameter, MockComponentType) + pc = IOM.get_parameter(container, key) + @test IOM.get_attributes(pc) isa IOM.EventParametersAttributes{MockContingency} + end end