diff --git a/src/InfrastructureOptimizationModels.jl b/src/InfrastructureOptimizationModels.jl index a5e5f6a..10252b5 100644 --- a/src/InfrastructureOptimizationModels.jl +++ b/src/InfrastructureOptimizationModels.jl @@ -524,6 +524,7 @@ include("core/optimization_container_types.jl") # Abstract types (Variable include("core/definitions.jl") # Aliases and enums (needs VariableType) # SimulationInfo is defined in IS.Simulation include("core/optimization_container_keys.jl") # Keys depend on types +include("core/optimization_container_utils.jl") # key <-> type <-> field correspondences include("core/parameter_container.jl") # Parameter container infrastructure include("core/abstract_model_store.jl") # Store depends on keys include("core/optimizer_stats.jl") # Stats standalone diff --git a/src/common_models/add_pwl_methods.jl b/src/common_models/add_pwl_methods.jl index f8fc4d5..8258ea4 100644 --- a/src/common_models/add_pwl_methods.jl +++ b/src/common_models/add_pwl_methods.jl @@ -213,13 +213,13 @@ function _add_generic_incremental_interpolation_constraint!( # Retrieve all required variables from the optimization container # Retrieve original variable for DCVoltage from the Bus x_var = if (R <: DCVoltage) - get_variable(container, R(), PSY.DCBus) # Original variable (domain of function) + get_variable(container, R, PSY.DCBus) # Original variable (domain of function) else - get_variable(container, R(), W) # Original variable (domain of function) + get_variable(container, R, W) # Original variable (domain of function) end # Original variable (domain of function) - y_var = get_variable(container, S(), W) # Approximated variable (range of function) - δ_var = get_variable(container, T(), W) # Interpolation variables (weights for segments) - z_var = get_variable(container, U(), W) # Binary variables (ordering constraints) + y_var = get_variable(container, S, W) # Approximated variable (range of function) + δ_var = get_variable(container, T, W) # Interpolation variables (weights for segments) + z_var = get_variable(container, U, W) # Binary variables (ordering constraints) # Create containers for the two main constraint types # Container for variable interpolation constraints: x = x₁ + Σᵢ δᵢ(xᵢ₊₁ - xᵢ) diff --git a/src/common_models/range_constraint.jl b/src/common_models/range_constraint.jl index c86ecdc..7e8004f 100644 --- a/src/common_models/range_constraint.jl +++ b/src/common_models/range_constraint.jl @@ -37,7 +37,7 @@ function add_range_constraints!( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_variable(container, U(), V) + array = get_variable(container, U, V) _add_bound_range_constraints_impl!(container, T, LowerBound(), array, devices, model) _add_bound_range_constraints_impl!(container, T, UpperBound(), array, devices, model) return @@ -57,7 +57,7 @@ function add_range_constraints!( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_expression(container, U(), V) + array = get_expression(container, U, V) _add_bound_range_constraints_impl!(container, T, LowerBound(), array, devices, model) return end @@ -76,7 +76,7 @@ function add_range_constraints!( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_expression(container, U(), V) + array = get_expression(container, U, V) _add_bound_range_constraints_impl!(container, T, UpperBound(), array, devices, model) return end @@ -143,7 +143,7 @@ function add_semicontinuous_range_constraints!( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_variable(container, U(), V) + array = get_variable(container, U, V) _add_semicontinuous_bound_range_constraints_impl!( container, T, LowerBound(), array, devices, model) _add_semicontinuous_bound_range_constraints_impl!( @@ -165,7 +165,7 @@ function add_semicontinuous_range_constraints!( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_expression(container, U(), V) + array = get_expression(container, U, V) _add_semicontinuous_bound_range_constraints_impl!( container, T, LowerBound(), array, devices, model) return @@ -185,7 +185,7 @@ function add_semicontinuous_range_constraints!( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_expression(container, U(), V) + array = get_expression(container, U, V) _add_semicontinuous_bound_range_constraints_impl!( container, T, UpperBound(), array, devices, model) return @@ -205,7 +205,7 @@ function _add_semicontinuous_bound_range_constraints_impl!( jump_model = get_jump_model(container) con = add_constraints_container!( container, T(), V, names, time_steps; meta = constraint_meta(dir)) - varbin = get_variable(container, OnVariable(), V) + varbin = get_variable(container, OnVariable, V) for device in devices, t in time_steps ci_name = PSY.get_name(device) @@ -231,7 +231,7 @@ function _add_semicontinuous_bound_range_constraints_impl!( jump_model = get_jump_model(container) con = add_constraints_container!( container, T(), V, names, time_steps; meta = constraint_meta(dir)) - varbin = get_variable(container, OnVariable(), V) + varbin = get_variable(container, OnVariable, V) for device in devices ci_name = PSY.get_name(device) @@ -263,7 +263,7 @@ function add_reserve_bound_range_constraints!( con = add_constraints_container!( container, T(), V, names, time_steps; meta = constraint_meta(dir)) - varbin = get_variable(container, ReservationVariable(), V) + varbin = get_variable(container, ReservationVariable, V) for device in devices, t in time_steps ci_name = PSY.get_name(device) @@ -293,7 +293,7 @@ function add_parameterized_bound_range_constraints( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_expression(container, U(), V) + array = get_expression(container, U, V) _add_parameterized_bound_range_constraints_impl!( container, T, dir, array, P(), devices, model) return @@ -316,7 +316,7 @@ function add_parameterized_bound_range_constraints( W <: AbstractDeviceFormulation, X <: AbstractPowerModel, } - array = get_variable(container, U(), V) + array = get_variable(container, U, V) _add_parameterized_bound_range_constraints_impl!( container, T, dir, array, P(), devices, model) return @@ -452,8 +452,8 @@ function _bound_range_with_parameter!( devices::Union{Vector{V}, IS.FlattenIteratorWrapper{V}}, ::DeviceModel{V, W}, ) where {P <: ParameterType, V <: PSY.Component, W <: AbstractDeviceFormulation} - param_array = get_parameter_array(container, param, V) - param_multiplier = get_parameter_multiplier_array(container, P(), V) + param_array = get_parameter_array(container, P, V) + param_multiplier = get_parameter_multiplier_array(container, P, V) jump_model = get_jump_model(container) time_steps = axes(constraint_container)[2] for device in devices, t in time_steps @@ -502,7 +502,7 @@ function _bound_range_with_parameter!( devices::Union{Vector{V}, IS.FlattenIteratorWrapper{V}}, model::DeviceModel{V, W}, ) where {P <: TimeSeriesParameter, V <: PSY.Component, W <: AbstractDeviceFormulation} - param_container = get_parameter(container, param, V) + param_container = get_parameter(container, P, V) mult = get_multiplier_array(param_container) jump_model = get_jump_model(container) time_steps = axes(constraint_container)[2] diff --git a/src/common_models/rateofchange_constraints.jl b/src/common_models/rateofchange_constraints.jl index 1d8d010..01972f9 100644 --- a/src/common_models/rateofchange_constraints.jl +++ b/src/common_models/rateofchange_constraints.jl @@ -41,8 +41,8 @@ function _get_ramp_slack_vars( t::Int, ) where {V <: PSY.Component, W <: AbstractDeviceFormulation} if get_use_slacks(model) - slack_up = get_variable(container, RateofChangeConstraintSlackUp(), V) - slack_dn = get_variable(container, RateofChangeConstraintSlackDown(), V) + slack_up = get_variable(container, RateofChangeConstraintSlackUp, V) + slack_dn = get_variable(container, RateofChangeConstraintSlackDown, V) return (up = slack_up[name, t], down = slack_dn[name, t]) else return (up = 0.0, down = 0.0) @@ -86,17 +86,17 @@ function add_linear_ramp_constraints!( } # common setup for all ramp constraints time_steps = get_time_steps(container) - variable = get_variable(container, U(), V) + variable = get_variable(container, U, V) ramp_devices = _get_ramp_constraint_devices(container, devices) minutes_per_period = _get_minutes_per_period(container) IC = _get_initial_condition_type(T, V, W) - initial_conditions_power = get_initial_condition(container, IC(), V) + initial_conditions_power = get_initial_condition(container, IC, V) jump_model = get_jump_model(container) device_name_set = PSY.get_name.(ramp_devices) cons = add_updown_constraints_containers!(container, T, V, device_name_set, time_steps) - expr_dn = get_expression(container, ActivePowerRangeExpressionLB(), V) - expr_up = get_expression(container, ActivePowerRangeExpressionUB(), V) + expr_dn = get_expression(container, ActivePowerRangeExpressionLB, V) + expr_up = get_expression(container, ActivePowerRangeExpressionUB, V) for ic in initial_conditions_power name = get_component_name(ic) @@ -135,11 +135,11 @@ function _add_linear_ramp_constraints_impl!( ) where {V <: PSY.Component, W <: AbstractDeviceFormulation} # common setup for all ramp constraints time_steps = get_time_steps(container) - variable = get_variable(container, U(), V) + variable = get_variable(container, U, V) ramp_devices = _get_ramp_constraint_devices(container, devices) minutes_per_period = _get_minutes_per_period(container) IC = _get_initial_condition_type(T, V, W) - initial_conditions_power = get_initial_condition(container, IC(), V) + initial_conditions_power = get_initial_condition(container, IC, V) jump_model = get_jump_model(container) device_name_set = PSY.get_name.(ramp_devices) cons = add_updown_constraints_containers!(container, T, V, device_name_set, time_steps) @@ -203,17 +203,17 @@ function add_linear_ramp_constraints!( # common setup for all ramp constraints time_steps = get_time_steps(container) - variable = get_variable(container, U(), V) + variable = get_variable(container, U, V) ramp_devices = _get_ramp_constraint_devices(container, devices) minutes_per_period = _get_minutes_per_period(container) IC = _get_initial_condition_type(T, V, W) - initial_conditions_power = get_initial_condition(container, IC(), V) + initial_conditions_power = get_initial_condition(container, IC, V) jump_model = get_jump_model(container) device_name_set = [PSY.get_name(r) for r in ramp_devices] cons = add_updown_constraints_containers!(container, T, V, device_name_set, time_steps) # Commitment path from UC as a PARAMETER (fixed 0/1) - on_param = get_parameter(container, OnStatusParameter(), V) + on_param = get_parameter(container, OnStatusParameter, V) on_status = on_param.parameter_array # on_status[name, t] ∈ {0,1} (fixed) for dev in ramp_devices @@ -287,19 +287,19 @@ function add_semicontinuous_ramp_constraints!( } # common setup for all ramp constraints time_steps = get_time_steps(container) - variable = get_variable(container, U(), V) + variable = get_variable(container, U, V) ramp_devices = _get_ramp_constraint_devices(container, devices) minutes_per_period = _get_minutes_per_period(container) IC = _get_initial_condition_type(T, V, W) - initial_conditions_power = get_initial_condition(container, IC(), V) + initial_conditions_power = get_initial_condition(container, IC, V) jump_model = get_jump_model(container) device_name_set = PSY.get_name.(ramp_devices) cons = add_updown_constraints_containers!(container, T, V, device_name_set, time_steps) - varstart = get_variable(container, StartVariable(), V) - varstop = get_variable(container, StopVariable(), V) - expr_dn = get_expression(container, ActivePowerRangeExpressionLB(), V) - expr_up = get_expression(container, ActivePowerRangeExpressionUB(), V) + varstart = get_variable(container, StartVariable, V) + varstop = get_variable(container, StopVariable, V) + expr_dn = get_expression(container, ActivePowerRangeExpressionLB, V) + expr_up = get_expression(container, ActivePowerRangeExpressionUB, V) for ic in initial_conditions_power name = get_component_name(ic) diff --git a/src/common_models/set_expression.jl b/src/common_models/set_expression.jl index 1c06b59..2537abd 100644 --- a/src/common_models/set_expression.jl +++ b/src/common_models/set_expression.jl @@ -9,7 +9,7 @@ function set_expression!( time_period::Int, ) where {S <: CostExpressions, T <: PSY.Component} if has_container_key(container, S, T) - device_cost_expression = get_expression(container, S(), T) + device_cost_expression = get_expression(container, S, T) component_name = PSY.get_name(component) device_cost_expression[component_name, time_period] = cost_expression end diff --git a/src/core/abstract_model_store.jl b/src/core/abstract_model_store.jl index 786c62c..e5774c4 100644 --- a/src/core/abstract_model_store.jl +++ b/src/core/abstract_model_store.jl @@ -12,13 +12,18 @@ const STORE_CONTAINERS = ( STORE_CONTAINER_AUX_VARIABLES, STORE_CONTAINER_EXPRESSIONS, ) +const STORE_CONTAINER_TYPES = ( + ConstraintType, + ParameterType, + VariableType, + AuxVariableType, + ExpressionType, +) -# Keep these in sync with the Symbols in src/core/definitions. -get_store_container_type(::AuxVarKey) = STORE_CONTAINER_AUX_VARIABLES -get_store_container_type(::ConstraintKey) = STORE_CONTAINER_DUALS -get_store_container_type(::ExpressionKey) = STORE_CONTAINER_EXPRESSIONS -get_store_container_type(::ParameterKey) = STORE_CONTAINER_PARAMETERS -get_store_container_type(::VariableKey) = STORE_CONTAINER_VARIABLES +# Derives from store_field_for_type in optimization_container_utils.jl +get_store_container_type( + ::OptimizationContainerKey{T, U}, +) where {T <: OptimizationKeyType, U <: InfrastructureSystemsType} = store_field_for_type(T) abstract type AbstractModelStore end @@ -46,6 +51,9 @@ function Base.empty!(store::T) where {T <: AbstractModelStore} end end +# FIXME getproperty allows for more customization than getfield, but we're not actually +# using that flexibility anywhere downstream... +# PERF symbols likely resolve at runtime. Would be better to do type and @generated. get_data_field(store::AbstractModelStore, type::Symbol) = getproperty(store, type) function Base.isempty(store::T) where {T <: AbstractModelStore} @@ -62,51 +70,34 @@ function Base.isempty(store::T) where {T <: AbstractModelStore} return true end -function list_fields(store::AbstractModelStore, container_type::Symbol) - return keys(get_data_field(store, container_type)) -end - -function list_keys(store::AbstractModelStore, container_type::Symbol) - container = get_data_field(store, container_type) - return collect(keys(container)) -end - -function get_value( - store::AbstractModelStore, - ::T, - ::Type{U}, -) where {T <: VariableType, U <: InfrastructureSystemsType} - return get_data_field(store, STORE_CONTAINER_VARIABLES)[VariableKey(T, U)] -end - -function get_value( +@generated function list_fields( store::AbstractModelStore, - ::T, - ::Type{U}, -) where {T <: AuxVariableType, U <: InfrastructureSystemsType} - return get_data_field(store, STORE_CONTAINER_AUX_VARIABLES)[AuxVarKey(T, U)] + ::Type{T}, +) where {T <: OptimizationKeyType} + field = QuoteNode(store_field_for_type(T)) + return :(return keys(getfield(store, $field))) end -function get_value( +@generated function list_keys( store::AbstractModelStore, - ::T, - ::Type{U}, -) where {T <: ConstraintType, U <: InfrastructureSystemsType} - return get_data_field(store, STORE_CONTAINER_DUALS)[ConstraintKey(T, U)] + ::Type{T}, +) where {T <: OptimizationKeyType} + field = QuoteNode(store_field_for_type(T)) + return :(return collect(keys(getfield(store, $field)))) end -function get_value( +@generated function get_value( store::AbstractModelStore, - ::T, + ::Type{T}, ::Type{U}, -) where {T <: ParameterType, U <: InfrastructureSystemsType} - return get_data_field(store, STORE_CONTAINER_PARAMETERS)[ParameterKey(T, U)] +) where {T <: OptimizationKeyType, U <: InfrastructureSystemsType} + K = key_for_type(T) + field = QuoteNode(store_field_for_type(T)) + return :(return getfield(store, $field)[$K(T, U)]) end -function get_value( - store::AbstractModelStore, - ::T, - ::Type{U}, -) where {T <: ExpressionType, U <: InfrastructureSystemsType} - return get_data_field(store, STORE_CONTAINER_EXPRESSIONS)[ExpressionKey(T, U)] -end +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_value( + store::AbstractModelStore, ::T, ::Type{U}, +) where {T <: OptimizationKeyType, U <: InfrastructureSystemsType} = + get_value(store, T, U) diff --git a/src/core/dataset_container.jl b/src/core/dataset_container.jl index 4f18adf..c248532 100644 --- a/src/core/dataset_container.jl +++ b/src/core/dataset_container.jl @@ -93,119 +93,51 @@ function has_dataset(container::DatasetContainer, key::OptimizationContainerKey) return haskey(datasets, key) end -function get_dataset( +@generated function get_dataset( container::DatasetContainer, - ::T, + ::Type{T}, ::Type{U}, ) where { - T <: ConstraintType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, } - return get_dataset(container, ConstraintKey(T, U)) + field = QuoteNode(store_field_for_type(T)) + K = key_for_type(T) + return :(return getfield(container, $field)[$K(T, U)]) end -function get_dataset( - container::DatasetContainer, - ::T, - ::Type{U}, -) where { - T <: VariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset(container, VariableKey(T, U)) -end - -function get_dataset( - container::DatasetContainer, - ::T, - ::Type{U}, -) where { - T <: AuxVariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset(container, AuxVarKey(T, U)) -end - -function get_dataset( - container::DatasetContainer, - ::T, - ::Type{U}, -) where { - T <: ParameterType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset(container, ParameterKey(T, U)) -end - -function get_dataset( - container::DatasetContainer, - ::T, - ::Type{U}, +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_dataset( + container::DatasetContainer, ::T, ::Type{U}, ) where { - T <: ExpressionType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset(container, ExpressionKey(T, U)) -end +} = get_dataset(container, T, U) function get_dataset_values(container::DatasetContainer, key::OptimizationContainerKey) return get_dataset(container, key).values end -function get_dataset_values( +@generated function get_dataset_values( container::DatasetContainer, - ::T, + ::Type{T}, ::Type{U}, ) where { - T <: ConstraintType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, } - return get_dataset_values(container, ConstraintKey(T, U)) + field = QuoteNode(store_field_for_type(T)) + K = key_for_type(T) + return :(return getfield(container, $field)[$K(T, U)].values) end -function get_dataset_values( - container::DatasetContainer, - ::T, - ::Type{U}, -) where { - T <: VariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset_values(container, VariableKey(T, U)) -end - -function get_dataset_values( - container::DatasetContainer, - ::T, - ::Type{U}, +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_dataset_values( + container::DatasetContainer, ::T, ::Type{U}, ) where { - T <: AuxVariableType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset_values(container, AuxVarKey(T, U)) -end - -function get_dataset_values( - container::DatasetContainer, - ::T, - ::Type{U}, -) where { - T <: ParameterType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset_values(container, ParameterKey(T, U)) -end - -function get_dataset_values( - container::DatasetContainer, - ::T, - ::Type{U}, -) where { - T <: ExpressionType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_dataset_values(container, ExpressionKey(T, U)) -end +} = get_dataset_values(container, T, U) function get_dataset_values( container::DatasetContainer, diff --git a/src/core/initial_conditions.jl b/src/core/initial_conditions.jl index 4cf9b1c..35349de 100644 --- a/src/core/initial_conditions.jl +++ b/src/core/initial_conditions.jl @@ -75,66 +75,46 @@ function InitialConditionsData() ) end -function get_initial_condition_value( +@generated function get_initial_condition_value( ic_data::InitialConditionsData, - ::T, - ::Type{U}, -) where {T <: VariableType, U <: Union{PSY.Component, PSY.System}} - return ic_data.variables[VariableKey(T, U)] -end - -function get_initial_condition_value( - ic_data::InitialConditionsData, - ::T, - ::Type{U}, -) where {T <: AuxVariableType, U <: Union{PSY.Component, PSY.System}} - return ic_data.aux_variables[AuxVarKey(T, U)] -end - -function get_initial_condition_value( - ic_data::InitialConditionsData, - ::T, - ::Type{U}, -) where {T <: ConstraintType, U <: Union{PSY.Component, PSY.System}} - return ic_data.duals[ConstraintKey(T, U)] -end - -function get_initial_condition_value( - ic_data::InitialConditionsData, - ::T, - ::Type{U}, -) where {T <: ParameterType, U <: Union{PSY.Component, PSY.System}} - return ic_data.parameters[ParameterKey(T, U)] -end - -function has_initial_condition_value( - ic_data::InitialConditionsData, - ::T, + ::Type{T}, ::Type{U}, -) where {T <: VariableType, U <: Union{PSY.Component, PSY.System}} - return haskey(ic_data.variables, VariableKey(T, U)) +) where { + T <: Union{VariableType, AuxVariableType, ConstraintType, ParameterType}, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} + field = QuoteNode(store_field_for_type(T)) + K = key_for_type(T) + return :(return getfield(ic_data, $field)[$K(T, U)]) end -function has_initial_condition_value( - ic_data::InitialConditionsData, - ::T, - ::Type{U}, -) where {T <: AuxVariableType, U <: Union{PSY.Component, PSY.System}} - return haskey(ic_data.aux_variables, AuxVarKey(T, U)) -end +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_initial_condition_value( + ic_data::InitialConditionsData, ::T, ::Type{U}, +) where { + T <: Union{VariableType, AuxVariableType, ConstraintType, ParameterType}, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = + get_initial_condition_value(ic_data, T, U) -function has_initial_condition_value( +@generated function has_initial_condition_value( ic_data::InitialConditionsData, - ::T, + ::Type{T}, ::Type{U}, -) where {T <: ConstraintType, U <: Union{PSY.Component, PSY.System}} - return haskey(ic_data.duals, ConstraintKey(T, U)) +) where { + T <: Union{VariableType, AuxVariableType, ConstraintType, ParameterType}, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} + field = QuoteNode(store_field_for_type(T)) + K = key_for_type(T) + return :(return haskey(getfield(ic_data, $field), $K(T, U))) end -function has_initial_condition_value( - ic_data::InitialConditionsData, - ::T, - ::Type{U}, -) where {T <: ParameterType, U <: Union{PSY.Component, PSY.System}} - return haskey(ic_data.parameters, ParameterKey(T, U)) -end +# TODO: deprecate once POM is migrated to pass types (issue #18) +has_initial_condition_value( + ic_data::InitialConditionsData, ::T, ::Type{U}, +) where { + T <: Union{VariableType, AuxVariableType, ConstraintType, ParameterType}, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = + has_initial_condition_value(ic_data, T, U) diff --git a/src/core/optimization_container.jl b/src/core/optimization_container.jl index ec5ba1f..16725ab 100644 --- a/src/core/optimization_container.jl +++ b/src/core/optimization_container.jl @@ -184,82 +184,20 @@ function reset_power_flow_is_solved!(container::OptimizationContainer) end end -function has_container_key( +@generated function has_container_key( container::OptimizationContainer, ::Type{T}, ::Type{U}, meta = CONTAINER_KEY_EMPTY_META, ) where { - T <: ExpressionType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, } - key = ExpressionKey(T, U, meta) - return haskey(container.expressions, key) -end - -function has_container_key( - container::OptimizationContainer, - ::Type{T}, - ::Type{U}, - meta = CONTAINER_KEY_EMPTY_META, -) where { - T <: VariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - key = VariableKey(T, U, meta) - return haskey(container.variables, key) -end - -function has_container_key( - container::OptimizationContainer, - ::Type{T}, - ::Type{U}, - meta = CONTAINER_KEY_EMPTY_META, -) where { - T <: AuxVariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - key = AuxVarKey(T, U, meta) - return haskey(container.aux_variables, key) -end - -function has_container_key( - container::OptimizationContainer, - ::Type{T}, - ::Type{U}, - meta = CONTAINER_KEY_EMPTY_META, -) where { - T <: ConstraintType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - key = ConstraintKey(T, U, meta) - return haskey(container.constraints, key) -end - -function has_container_key( - container::OptimizationContainer, - ::Type{T}, - ::Type{U}, - meta = CONTAINER_KEY_EMPTY_META, -) where { - T <: ParameterType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - key = ParameterKey(T, U, meta) - return haskey(container.parameters, key) -end - -function has_container_key( - container::OptimizationContainer, - ::Type{T}, - ::Type{U}, - meta = CONTAINER_KEY_EMPTY_META, -) where { - T <: InitialConditionType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - key = InitialConditionKey(T, U, meta) - return haskey(container.initial_conditions, key) + # without the QuoteNode, we'd get when interpolated, not : + # also, QuoteNode(foo) evaluates foo then quotes, whereas :(foo) quotes first. + field = QuoteNode(field_for_type(T)) + K = key_for_type(T) + return :(return haskey(getfield(container, $field), $K(T, U, meta))) end function is_milp(container::OptimizationContainer)::Bool @@ -599,40 +537,104 @@ function _assign_container!(container::OrderedDict, key::OptimizationContainerKe return end -####################################### Variable Container ################################# -function _add_variable_container!( +########################### Generic Container Access ######################################## + +""" +Generic container entry getter. Dispatches on key type to access the correct field. +Replaces per-type get_variable, get_aux_variable, get_constraint, etc. by key. +""" +@generated function _get_entry( container::OptimizationContainer, - var_key::VariableKey{T, U}, + key::OptimizationContainerKey{T, U}, +) where { + T <: OptimizationKeyType, + U <: InfrastructureSystemsType, +} + field = QuoteNode(field_for_type(T)) + return quote + val = get(getfield(container, $field), key, nothing) + if val === nothing + throw( + IS.InvalidValue( + "$(encode_key(key)) is not stored. $(encode_key.(collect(keys(getfield(container, $field)))))", + ), + ) + end + return val + end +end + +""" +Generic container entry getter by entry type and component type. +Constructs the appropriate key and delegates to the key-based _get_entry. +""" +@generated function _get_entry( + container::OptimizationContainer, + ::Type{T}, + ::Type{U}, + meta = CONTAINER_KEY_EMPTY_META, +) where { + T <: OptimizationKeyType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} + K = key_for_type(T) + return :(return _get_entry(container, $K(T, U, meta))) +end + +########################### Generic Container Creation ###################################### + +@generated function _add_container!( + opt_container::OptimizationContainer, + key::OptimizationContainerKey{T, U}, + ::Type{E}, sparse::Bool, axs..., ) where { - T <: VariableType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, + E, } - if sparse - var_container = sparse_container_spec(JuMP.VariableRef, axs...) - else - var_container = container_spec(JuMP.VariableRef, axs...) + field = QuoteNode(field_for_type(T)) + return quote + if sparse + value = sparse_container_spec(E, axs...) + else + value = container_spec(E, axs...) + end + _assign_container!(getfield(opt_container, $field), key, value) + return value end - _assign_container!(container.variables, var_key, var_container) - return var_container end -function add_variable_container!( - container::OptimizationContainer, - ::T, +""" +Key-constructing overload: builds the key from (T, U, meta) then delegates. +""" +@generated function _add_container!( + opt_container::OptimizationContainer, + ::Type{T}, ::Type{U}, + ::Type{E}, + sparse::Bool, axs...; - sparse = false, meta = CONTAINER_KEY_EMPTY_META, ) where { - T <: VariableType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, + E, } - var_key = VariableKey(T, U, meta) - return _add_variable_container!(container, var_key, sparse, axs...) + K = key_for_type(T) + return :(return _add_container!(opt_container, $K(T, U, meta), E, sparse, axs...)) end +####################################### Variable Container ################################# +add_variable_container!( + container::OptimizationContainer, ::T, ::Type{U}, axs...; + sparse = false, meta = CONTAINER_KEY_EMPTY_META, +) where { + T <: VariableType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = _add_container!(container, T, U, JuMP.VariableRef, sparse, axs...; meta = meta) + function add_variable_container!( container::OptimizationContainer, ::T, @@ -644,8 +646,7 @@ function add_variable_container!( T <: VariableType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, } - var_key = VariableKey(T, U, meta) - return _add_variable_container!(container, var_key, sparse, axs...) + return _add_container!(container, T, U, JuMP.VariableRef, sparse, axs...; meta = meta) end function _get_pwl_variables_container() @@ -671,75 +672,58 @@ function get_variable_keys(container::OptimizationContainer) return collect(keys(container.variables)) end -function get_variable(container::OptimizationContainer, key::VariableKey) - var = get(container.variables, key, nothing) - if var === nothing - name = encode_key(key) - keys = encode_key.(get_variable_keys(container)) - throw(IS.InvalidValue("variable $name is not stored. $keys")) - end - return var -end +get_variable(container::OptimizationContainer, key::VariableKey) = + _get_entry(container, key) -function get_variable( - container::OptimizationContainer, - ::T, - ::Type{U}, +get_variable( + container::OptimizationContainer, ::Type{T}, ::Type{U}, meta::String = CONTAINER_KEY_EMPTY_META, ) where { T <: VariableType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_variable(container, VariableKey(T, U, meta)) -end +} = _get_entry(container, T, U, meta) + +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_variable( + container::OptimizationContainer, ::T, ::Type{U}, + meta::String = CONTAINER_KEY_EMPTY_META, +) where { + T <: VariableType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = _get_entry(container, T, U, meta) ##################################### AuxVariable Container ################################ -function add_aux_variable_container!( - container::OptimizationContainer, - ::T, - ::Type{U}, - axs...; - sparse = false, - meta = CONTAINER_KEY_EMPTY_META, +add_aux_variable_container!( + container::OptimizationContainer, ::T, ::Type{U}, axs...; + sparse = false, meta = CONTAINER_KEY_EMPTY_META, ) where { T <: AuxVariableType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - var_key = AuxVarKey(T, U, meta) - if sparse - aux_variable_container = sparse_container_spec(Float64, axs...) - else - aux_variable_container = container_spec(Float64, axs...) - end - _assign_container!(container.aux_variables, var_key, aux_variable_container) - return aux_variable_container -end +} = _add_container!(container, T, U, Float64, sparse, axs...; meta = meta) function get_aux_variable_keys(container::OptimizationContainer) return collect(keys(container.aux_variables)) end -function get_aux_variable(container::OptimizationContainer, key::AuxVarKey) - aux = get(container.aux_variables, key, nothing) - if aux === nothing - name = encode_key(key) - keys = encode_key.(get_aux_variable_keys(container)) - throw(IS.InvalidValue("Auxiliary variable $name is not stored. $keys")) - end - return aux -end +get_aux_variable(container::OptimizationContainer, key::AuxVarKey) = + _get_entry(container, key) -function get_aux_variable( - container::OptimizationContainer, - ::T, - ::Type{U}, +get_aux_variable( + container::OptimizationContainer, ::Type{T}, ::Type{U}, meta::String = CONTAINER_KEY_EMPTY_META, ) where { T <: AuxVariableType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_aux_variable(container, AuxVarKey(T, U, meta)) -end +} = _get_entry(container, T, U, meta) + +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_aux_variable( + container::OptimizationContainer, ::T, ::Type{U}, + meta::String = CONTAINER_KEY_EMPTY_META, +) where { + T <: AuxVariableType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = _get_entry(container, T, U, meta) ##################################### DualVariable Container ################################ function add_dual_container!( @@ -773,62 +757,37 @@ function get_dual_keys(container::OptimizationContainer) end ##################################### Constraint Container ################################# -function _add_constraints_container!( - container::OptimizationContainer, - cons_key::ConstraintKey, - axs...; - sparse = false, -) - if sparse - cons_container = sparse_container_spec(JuMP.ConstraintRef, axs...) - else - cons_container = container_spec(JuMP.ConstraintRef, axs...) - end - _assign_container!(container.constraints, cons_key, cons_container) - return cons_container -end - -function add_constraints_container!( - container::OptimizationContainer, - ::T, - ::Type{U}, - axs...; - sparse = false, - meta = CONTAINER_KEY_EMPTY_META, +add_constraints_container!( + container::OptimizationContainer, ::T, ::Type{U}, axs...; + sparse = false, meta = CONTAINER_KEY_EMPTY_META, ) where { T <: ConstraintType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - cons_key = ConstraintKey(T, U, meta) - return _add_constraints_container!(container, cons_key, axs...; sparse = sparse) -end +} = _add_container!(container, T, U, JuMP.ConstraintRef, sparse, axs...; meta = meta) function get_constraint_keys(container::OptimizationContainer) return collect(keys(container.constraints)) end -function get_constraint(container::OptimizationContainer, key::ConstraintKey) - var = get(container.constraints, key, nothing) - if var === nothing - name = encode_key(key) - keys = encode_key.(get_constraint_keys(container)) - throw(IS.InvalidValue("constraint $name is not stored. $keys")) - end +get_constraint(container::OptimizationContainer, key::ConstraintKey) = + _get_entry(container, key) - return var -end +get_constraint( + container::OptimizationContainer, ::Type{T}, ::Type{U}, + meta::String = CONTAINER_KEY_EMPTY_META, +) where { + T <: ConstraintType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = _get_entry(container, T, U, meta) -function get_constraint( - container::OptimizationContainer, - ::T, - ::Type{U}, +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_constraint( + container::OptimizationContainer, ::T, ::Type{U}, meta::String = CONTAINER_KEY_EMPTY_META, ) where { T <: ConstraintType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_constraint(container, ConstraintKey(T, U, meta)) -end +} = _get_entry(container, T, U, meta) function read_duals(container::OptimizationContainer) return Dict(k => to_dataframe(jump_value.(v), k) for (k, v) in get_duals(container)) @@ -915,30 +874,25 @@ function get_parameter_keys(container::OptimizationContainer) return collect(keys(container.parameters)) end -function get_parameter(container::OptimizationContainer, key::ParameterKey) - param_container = get(container.parameters, key, nothing) - if param_container === nothing - name = encode_key(key) - throw( - IS.InvalidValue( - "parameter $name is not stored. $(collect(keys(container.parameters)))", - ), - ) - end - return param_container -end +get_parameter(container::OptimizationContainer, key::ParameterKey) = + _get_entry(container, key) -function get_parameter( - container::OptimizationContainer, - ::T, - ::Type{U}, +get_parameter( + container::OptimizationContainer, ::Type{T}, ::Type{U}, meta = CONTAINER_KEY_EMPTY_META, ) where { T <: ParameterType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_parameter(container, ParameterKey(T, U, meta)) -end +} = _get_entry(container, T, U, meta) + +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_parameter( + container::OptimizationContainer, ::T, ::Type{U}, + meta = CONTAINER_KEY_EMPTY_META, +) where { + T <: ParameterType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = _get_entry(container, T, U, meta) function get_parameter_array(container::OptimizationContainer, key) return get_parameter_array(get_parameter(container, key)) @@ -976,7 +930,7 @@ end function get_parameter_array( container::OptimizationContainer, - ::T, + ::Type{T}, ::Type{U}, meta = CONTAINER_KEY_EMPTY_META, ) where { @@ -985,9 +939,19 @@ function get_parameter_array( } return get_parameter_array(container, ParameterKey(T, U, meta)) end + +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_parameter_array( + container::OptimizationContainer, ::T, ::Type{U}, + meta = CONTAINER_KEY_EMPTY_META, +) where { + T <: ParameterType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = get_parameter_array(container, T, U, meta) + function get_parameter_multiplier_array( container::OptimizationContainer, - ::T, + ::Type{T}, ::Type{U}, meta = CONTAINER_KEY_EMPTY_META, ) where { @@ -997,6 +961,15 @@ function get_parameter_multiplier_array( return get_multiplier_array(get_parameter(container, ParameterKey(T, U, meta))) end +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_parameter_multiplier_array( + container::OptimizationContainer, ::T, ::Type{U}, + meta = CONTAINER_KEY_EMPTY_META, +) where { + T <: ParameterType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = get_parameter_multiplier_array(container, T, U, meta) + function get_parameter_attributes( container::OptimizationContainer, ::T, @@ -1041,23 +1014,6 @@ function _calculate_parameter_values( return param_array end ##################################### Expression Container ################################# -function _add_expression_container!( - container::OptimizationContainer, - expr_key::ExpressionKey, - ::Type{T}, - axs...; - sparse = false, -) where {T <: JuMP.AbstractJuMPScalar} - if sparse - expr_container = sparse_container_spec(T, axs...) - else - expr_container = container_spec(T, axs...) - end - remove_undef!(expr_container) - _assign_container!(container.expressions, expr_key, expr_container) - return expr_container -end - function add_expression_container!( container::OptimizationContainer, ::T, @@ -1070,14 +1026,10 @@ function add_expression_container!( T <: ExpressionType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, } - expr_key = ExpressionKey(T, U, meta) - return _add_expression_container!( - container, - expr_key, - expr_type, - axs...; - sparse = sparse, - ) + expr_container = + _add_container!(container, T, U, expr_type, sparse, axs...; meta = meta) + remove_undef!(expr_container) + return expr_container end # NOTE: add_expression_container! for ProductionCostExpression is in standard_variables_expressions.jl @@ -1087,30 +1039,25 @@ function get_expression_keys(container::OptimizationContainer) return collect(keys(container.expressions)) end -function get_expression(container::OptimizationContainer, key::ExpressionKey) - var = get(container.expressions, key, nothing) - if var === nothing - throw( - IS.InvalidValue( - "expression $key is not stored. $(collect(keys(container.expressions)))", - ), - ) - end +get_expression(container::OptimizationContainer, key::ExpressionKey) = + _get_entry(container, key) - return var -end +get_expression( + container::OptimizationContainer, ::Type{T}, ::Type{U}, + meta = CONTAINER_KEY_EMPTY_META, +) where { + T <: ExpressionType, + U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, +} = _get_entry(container, T, U, meta) -function get_expression( - container::OptimizationContainer, - ::T, - ::Type{U}, +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_expression( + container::OptimizationContainer, ::T, ::Type{U}, meta = CONTAINER_KEY_EMPTY_META, ) where { T <: ExpressionType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return get_expression(container, ExpressionKey(T, U, meta)) -end +} = _get_entry(container, T, U, meta) function read_expressions(container::OptimizationContainer) return Dict( @@ -1161,21 +1108,17 @@ function add_initial_condition_container!( return _add_initial_condition_container!(container, ic_key, length(axs)) end -function get_initial_condition( - container::OptimizationContainer, - ::T, - ::Type{D}, -) where {T <: InitialConditionType, D} - return get_initial_condition(container, InitialConditionKey(T, D)) -end +get_initial_condition( + container::OptimizationContainer, ::Type{T}, ::Type{D}, +) where {T <: InitialConditionType, D} = _get_entry(container, T, D) -function get_initial_condition(container::OptimizationContainer, key::InitialConditionKey) - initial_conditions = get(container.initial_conditions, key, nothing) - if initial_conditions === nothing - throw(IS.InvalidValue("initial conditions are not stored for $(key)")) - end - return initial_conditions -end +# TODO: deprecate once POM is migrated to pass types (issue #18) +get_initial_condition( + container::OptimizationContainer, ::T, ::Type{D}, +) where {T <: InitialConditionType, D} = _get_entry(container, T, D) + +get_initial_condition(container::OptimizationContainer, key::InitialConditionKey) = + _get_entry(container, key) function get_initial_conditions_keys(container::OptimizationContainer) return collect(keys(container.initial_conditions)) @@ -1473,50 +1416,21 @@ function calculate_dual_variables!( end ########################### Helper Functions to get keys ################################### -function get_optimization_container_key( - ::T, - ::Type{U}, - meta::String, -) where { - T <: AuxVariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return AuxVarKey(T, U, meta) -end - -function get_optimization_container_key( - ::T, - ::Type{U}, - meta::String, -) where { - T <: VariableType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return VariableKey(T, U, meta) -end - -function get_optimization_container_key( - ::T, - ::Type{U}, - meta::String, -) where { - T <: ParameterType, - U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, -} - return ParameterKey(T, U, meta) -end - -function get_optimization_container_key( +# FIXME this 3-arg version is only called from POM. move it? +@generated function get_optimization_container_key( ::T, ::Type{U}, meta::String, ) where { - T <: ConstraintType, + T <: OptimizationKeyType, U <: Union{IS.InfrastructureSystemsComponent, IS.InfrastructureSystemsContainer}, } - return ConstraintKey(T, U, meta) + K = key_for_type(T) + return :($K(T, U, meta)) end +# note these 3 lazy_container_addition! definitions have different meta handling and adder +# functions, else we'd collapse into one generated function. function lazy_container_addition!( container::OptimizationContainer, var::T, @@ -1530,7 +1444,7 @@ function lazy_container_addition!( if !has_container_key(container, T, U) var_container = add_variable_container!(container, var, U, axs...; kwargs...) else - var_container = get_variable(container, var, U) + var_container = get_variable(container, T, U) end return var_container end @@ -1550,7 +1464,7 @@ function lazy_container_addition!( cons_container = add_constraints_container!(container, constraint, U, axs...; kwargs...) else - cons_container = get_constraint(container, constraint, U, meta) + cons_container = get_constraint(container, T, U, meta) end return cons_container end @@ -1570,7 +1484,7 @@ function lazy_container_addition!( expr_container = add_expression_container!(container, expression, U, axs...; kwargs...) else - expr_container = get_expression(container, expression, U, meta) + expr_container = get_expression(container, T, U, meta) end return expr_container end @@ -1626,13 +1540,14 @@ function get_column_names( end end -lookup_value(container::OptimizationContainer, key::VariableKey) = - get_variable(container, key) -lookup_value(container::OptimizationContainer, key::ParameterKey) = +lookup_value( + container::OptimizationContainer, + key::OptimizationContainerKey{T, U}, +) where {T <: OptimizationKeyType, U <: InfrastructureSystemsType} = + _get_entry(container, key) +# ParameterKey special case: unwrap ParameterContainer via calculate_parameter_values +lookup_value( + container::OptimizationContainer, + key::OptimizationContainerKey{T, U}, +) where {T <: ParameterType, U <: InfrastructureSystemsType} = calculate_parameter_values(get_parameter(container, key)) -lookup_value(container::OptimizationContainer, key::AuxVarKey) = - get_aux_variable(container, key) -lookup_value(container::OptimizationContainer, key::ExpressionKey) = - get_expression(container, key) -lookup_value(container::OptimizationContainer, key::ConstraintKey) = - get_constraint(container, key) diff --git a/src/core/optimization_container_utils.jl b/src/core/optimization_container_utils.jl new file mode 100644 index 0000000..f54dbd1 --- /dev/null +++ b/src/core/optimization_container_utils.jl @@ -0,0 +1,21 @@ +field_for_type(::Type{<:VariableType}) = :variables +field_for_type(::Type{<:AuxVariableType}) = :aux_variables +field_for_type(::Type{<:ConstraintType}) = :constraints +field_for_type(::Type{<:ExpressionType}) = :expressions +field_for_type(::Type{<:ParameterType}) = :parameters +field_for_type(::Type{<:InitialConditionType}) = :initial_conditions + +key_for_type(::Type{<:VariableType}) = VariableKey +key_for_type(::Type{<:AuxVariableType}) = AuxVarKey +key_for_type(::Type{<:ConstraintType}) = ConstraintKey +key_for_type(::Type{<:ExpressionType}) = ExpressionKey +key_for_type(::Type{<:ParameterType}) = ParameterKey +key_for_type(::Type{<:InitialConditionType}) = InitialConditionKey + +# Store field mapping — differs from field_for_type for ConstraintType, +# which maps to :duals in the store (not :constraints). +store_field_for_type(::Type{<:VariableType}) = :variables +store_field_for_type(::Type{<:AuxVariableType}) = :aux_variables +store_field_for_type(::Type{<:ConstraintType}) = :duals +store_field_for_type(::Type{<:ExpressionType}) = :expressions +store_field_for_type(::Type{<:ParameterType}) = :parameters diff --git a/src/core/standard_variables_expressions.jl b/src/core/standard_variables_expressions.jl index c92fb4a..e0e6919 100644 --- a/src/core/standard_variables_expressions.jl +++ b/src/core/standard_variables_expressions.jl @@ -80,15 +80,10 @@ function add_expression_container!( sparse = false, meta = CONTAINER_KEY_EMPTY_META, ) where {T <: ProductionCostExpression, U <: Union{PSY.Component, PSY.System}} - expr_key = ExpressionKey(T, U, meta) - expr_type = JuMP.QuadExpr - return _add_expression_container!( - container, - expr_key, - expr_type, - axs...; - sparse = sparse, - ) + expr_container = + _add_container!(container, T, U, JuMP.QuadExpr, sparse, axs...; meta = meta) + remove_undef!(expr_container) + return expr_container end ################################################################################# diff --git a/src/objective_function/common.jl b/src/objective_function/common.jl index 7a0f117..4675198 100644 --- a/src/objective_function/common.jl +++ b/src/objective_function/common.jl @@ -14,7 +14,7 @@ function add_cost_to_expression!( T <: IS.InfrastructureSystemsComponent, } if has_container_key(container, S, T) - device_cost_expression = get_expression(container, S(), T) + device_cost_expression = get_expression(container, S, T) JuMP.add_to_expression!( device_cost_expression[component_name, time_period], cost_expression, @@ -106,7 +106,7 @@ function _add_time_varying_fuel_variable_cost!( component::V, fuel_cost::IS.TimeSeriesKey, ) where {T <: VariableType, V <: PSY.Component} - expression = get_expression(container, FuelConsumptionExpression(), V) + expression = get_expression(container, FuelConsumptionExpression, V) name = PSY.get_name(component) for t in get_time_steps(container) add_cost_term_variant!( diff --git a/src/objective_function/cost_term_helpers.jl b/src/objective_function/cost_term_helpers.jl index 827b834..c5fba0b 100644 --- a/src/objective_function/cost_term_helpers.jl +++ b/src/objective_function/cost_term_helpers.jl @@ -37,7 +37,7 @@ function add_cost_term_invariant!( ) where {E <: ExpressionType, C <: IS.InfrastructureSystemsComponent} cost = quantity * rate if has_container_key(container, E, C) - expr = get_expression(container, E(), C) + expr = get_expression(container, E, C) JuMP.add_to_expression!(expr[name, t], cost) end add_to_objective_invariant_expression!(container, cost) @@ -68,12 +68,12 @@ function add_cost_term_variant!( name::String, t::Int, ) where {P <: ParameterType, E <: ExpressionType, C <: IS.InfrastructureSystemsComponent} - param = get_parameter_array(container, P(), C) - mult = get_parameter_multiplier_array(container, P(), C) + param = get_parameter_array(container, P, C) + mult = get_parameter_multiplier_array(container, P, C) rate = param[name, t] * mult[name, t] cost = quantity * rate if has_container_key(container, E, C) - expr = get_expression(container, E(), C) + expr = get_expression(container, E, C) JuMP.add_to_expression!(expr[name, t], cost) end add_to_objective_variant_expression!(container, cost) @@ -110,7 +110,7 @@ function add_cost_term_variant!( ) where {E <: ExpressionType, C <: IS.InfrastructureSystemsComponent} cost = quantity * rate if has_container_key(container, E, C) - expr = get_expression(container, E(), C) + expr = get_expression(container, E, C) JuMP.add_to_expression!(expr[name, t], cost) end add_to_objective_variant_expression!(container, cost) @@ -150,7 +150,7 @@ function add_proportional_cost_invariant!( name = get_name(component) rate = cost_per_unit * multiplier * dt for t in get_time_steps(container) - variable = get_variable(container, T(), C)[name, t] + variable = get_variable(container, T, C)[name, t] add_cost_term_invariant!( container, variable, rate, ProductionCostExpression, C, name, t) end @@ -250,7 +250,7 @@ function add_pwl_linking_constraint!( JuMP.Containers.SparseAxisArray(contents), ) end - con_container = get_constraint(container, K(), C) + con_container = get_constraint(container, K, C) jump_model = get_jump_model(container) con_container[name, t] = JuMP.@constraint( jump_model, @@ -292,7 +292,7 @@ function add_pwl_normalization_constraint!( JuMP.Containers.SparseAxisArray(contents), ) end - con_container = get_constraint(container, K(), C) + con_container = get_constraint(container, K, C) jump_model = get_jump_model(container) con_container[name, t] = JuMP.@constraint( jump_model, diff --git a/src/objective_function/market_bid.jl b/src/objective_function/market_bid.jl index 4333d79..b2c6785 100644 --- a/src/objective_function/market_bid.jl +++ b/src/objective_function/market_bid.jl @@ -508,7 +508,7 @@ function _add_pwl_constraint!( ) where {T <: PSY.Component, U <: VariableType, D <: AbstractDeviceFormulation, W <: AbstractPiecewiseLinearBlockOfferConstraint} - variables = get_variable(container, U(), T) + variables = get_variable(container, U, T) const_container = lazy_container_addition!( container, W(), @@ -521,7 +521,7 @@ function _add_pwl_constraint!( jump_fixed_value(first(break_points))::Float64 elseif _include_min_gen_power_in_constraint(T, U(), D()) p1::Float64 = jump_fixed_value(first(break_points)) - on_vars = get_variable(container, OnVariable(), T) + on_vars = get_variable(container, OnVariable, T) p1 * on_vars[name, period] else 0.0 @@ -556,15 +556,15 @@ function _get_pwl_data( name = PSY.get_name(component) SlopeParam = _slope_param(dir) - slope_param_arr = get_parameter_array(container, SlopeParam(), T) - slope_param_mult = get_parameter_multiplier_array(container, SlopeParam(), T) + slope_param_arr = get_parameter_array(container, SlopeParam, T) + slope_param_mult = get_parameter_multiplier_array(container, SlopeParam, T) @assert size(slope_param_arr) == size(slope_param_mult) slope_cost_component = slope_param_arr[name, :, time] .* slope_param_mult[name, :, time] slope_cost_component = slope_cost_component.data BreakpointParam = _breakpoint_param(dir) - breakpoint_param_container = get_parameter(container, BreakpointParam(), T) + breakpoint_param_container = get_parameter(container, BreakpointParam, T) breakpoint_param_arr = get_parameter_column_refs(breakpoint_param_container, name) breakpoint_param_mult = get_multiplier_array(breakpoint_param_container) @assert size(breakpoint_param_arr) == size(breakpoint_param_mult[name, :, :]) diff --git a/src/objective_function/piecewise_linear.jl b/src/objective_function/piecewise_linear.jl index 79b5646..772283a 100644 --- a/src/objective_function/piecewise_linear.jl +++ b/src/objective_function/piecewise_linear.jl @@ -95,13 +95,11 @@ function _determine_bin_lhs( @debug "Using Piecewise Linear cost function but no variable/parameter ref for ON status is passed. Default status will be set to online (1.0)" _group = LOG_GROUP_COST_FUNCTIONS elseif sos_status == SOSStatusVariable.PARAMETER - param = OnStatusParameter() - return get_parameter(container, param, T).parameter_array[name, period] + return get_parameter(container, OnStatusParameter, T).parameter_array[name, period] @debug "Using Piecewise Linear cost function with parameter OnStatusParameter, $T" _group = LOG_GROUP_COST_FUNCTIONS elseif sos_status == SOSStatusVariable.VARIABLE - var = OnVariable() - return get_variable(container, var, T)[name, period] + return get_variable(container, OnVariable, T)[name, period] @debug "Using Piecewise Linear cost function with variable OnVariable $T" _group = LOG_GROUP_COST_FUNCTIONS else @@ -112,10 +110,10 @@ end # Migration note for POM: # Old call: _add_pwl_constraint!(container, component, U(), break_points, sos_val, t) # New call for standard form: -# power_var = get_variable(container, U(), T)[name, t] +# power_var = get_variable(container, U, T)[name, t] # _add_pwl_constraint_standard!(container, component, break_points, sos_val, t, power_var) # New call for compact form (PowerAboveMinimumVariable): -# power_var = get_variable(container, U(), T)[name, t] +# power_var = get_variable(container, U, T)[name, t] # P_min = get_active_power_limits(component).min # _add_pwl_constraint_compact!(container, component, break_points, sos_val, t, power_var, P_min) @@ -142,7 +140,7 @@ function _add_pwl_constraint_standard!( n_points = length(break_points) # Get PWL delta variables - pwl_var_container = get_variable(container, PiecewiseLinearCostVariable(), T) + pwl_var_container = get_variable(container, PiecewiseLinearCostVariable, T) pwl_vars = [pwl_var_container[name, i, period] for i in 1:n_points] # Linking constraint: power_var == sum(pwl_vars * breakpoints) @@ -206,7 +204,7 @@ function _add_pwl_constraint_compact!( end # Get PWL delta variables - pwl_var_container = get_variable(container, PiecewiseLinearCostVariable(), T) + pwl_var_container = get_variable(container, PiecewiseLinearCostVariable, T) pwl_vars = [pwl_var_container[name, i, period] for i in 1:n_points] # Create constraint container if needed @@ -219,7 +217,7 @@ function _add_pwl_constraint_compact!( JuMP.Containers.SparseAxisArray(contents), ) end - con_container = get_constraint(container, PiecewiseLinearCostConstraint(), T) + con_container = get_constraint(container, PiecewiseLinearCostConstraint, T) jump_model = get_jump_model(container) # Compact form linking constraint includes P_min offset @@ -255,7 +253,7 @@ function _get_pwl_cost_expression( cost_data::IS.PiecewiseLinearData, multiplier::Float64, ) where {T <: IS.InfrastructureSystemsComponent} - pwl_var_container = get_variable(container, PiecewiseLinearCostVariable(), T) + pwl_var_container = get_variable(container, PiecewiseLinearCostVariable, T) gen_cost = JuMP.AffExpr(0.0) y_coords_cost_data = IS.get_y_coords(cost_data) for (i, cost) in enumerate(y_coords_cost_data) @@ -379,7 +377,7 @@ function _add_pwl_term!( sos_val = _get_sos_value(container, V, component) for t in time_steps _add_pwl_variables!(container, T, name, t, data) - power_var = get_variable(container, U(), T)[name, t] + power_var = get_variable(container, U, T)[name, t] _add_pwl_constraint_standard!( container, component, @@ -389,7 +387,7 @@ function _add_pwl_term!( power_var, ) if !cost_is_convex - pwl_var_container = get_variable(container, PiecewiseLinearCostVariable(), T) + pwl_var_container = get_variable(container, PiecewiseLinearCostVariable, T) n_points = length(break_points) pwl_vars = [pwl_var_container[name, i, t] for i in 1:n_points] add_pwl_sos2_constraint!(container, T, name, t, pwl_vars) @@ -486,8 +484,8 @@ function add_variable_cost_to_objective!( is_time_variant_ = is_time_variant(IS.get_fuel_cost(cost_function)) for t in get_time_steps(container) fuel_cost_value = if is_time_variant_ - param = get_parameter_array(container, FuelCostParameter(), V) - mult = get_parameter_multiplier_array(container, FuelCostParameter(), V) + param = get_parameter_array(container, FuelCostParameter, V) + mult = get_parameter_multiplier_array(container, FuelCostParameter, V) param[component_name, t] * mult[component_name, t] else get_fuel_cost(component) diff --git a/src/objective_function/proportional.jl b/src/objective_function/proportional.jl index cfe3fde..13132e9 100644 --- a/src/objective_function/proportional.jl +++ b/src/objective_function/proportional.jl @@ -27,7 +27,7 @@ function add_proportional_cost!( name = get_name(d) rate = cost_term * multiplier for t in get_time_steps(container) - variable = get_variable(container, U(), T)[name, t] + variable = get_variable(container, U, T)[name, t] add_cost_term_invariant!( container, variable, @@ -77,7 +77,7 @@ function add_proportional_cost_maybe_time_variant!( t, ) else - variable = get_variable(container, U(), T)[name, t] + variable = get_variable(container, U, T)[name, t] add_as_time_variant = is_time_variant_term(container, op_cost_data, U(), T, V(), t) if add_as_time_variant diff --git a/src/objective_function/quadratic_curve.jl b/src/objective_function/quadratic_curve.jl index 3448fe0..3ffdbee 100644 --- a/src/objective_function/quadratic_curve.jl +++ b/src/objective_function/quadratic_curve.jl @@ -10,7 +10,7 @@ function _add_quadraticcurve_variable_term_to_model!( resolution = get_resolution(container) dt = Dates.value(resolution) / MILLISECONDS_IN_HOUR name = get_name(component) - var = get_variable(container, T(), V)[name, time_period] + var = get_variable(container, T, V)[name, time_period] cost = if quadratic_term_per_unit >= eps() @debug "$name Quadratic Variable Cost" _group = LOG_GROUP_COST_FUNCTIONS name @@ -27,7 +27,7 @@ function _add_quadraticcurve_variable_term_to_model!( # For quadratic case, still need to add to expression (linear case handled by helper) if quadratic_term_per_unit >= eps() && has_container_key(container, ProductionCostExpression, V) - expr = get_expression(container, ProductionCostExpression(), V) + expr = get_expression(container, ProductionCostExpression, V) JuMP.add_to_expression!(expr[name, time_period], cost) end return diff --git a/src/objective_function/start_up_shut_down.jl b/src/objective_function/start_up_shut_down.jl index 49cdd17..08e5dbc 100644 --- a/src/objective_function/start_up_shut_down.jl +++ b/src/objective_function/start_up_shut_down.jl @@ -22,15 +22,16 @@ function add_shut_down_cost!( add_as_time_variant = is_time_variant(get_shut_down(get_operation_cost(d))) for t in get_time_steps(container) cost_term = if add_as_time_variant - param = get_parameter_array(container, ShutdownCostParameter(), T) - mult = get_parameter_multiplier_array(container, ShutdownCostParameter(), T) + param = get_parameter_array(container, ShutdownCostParameter, T) + mult = + get_parameter_multiplier_array(container, ShutdownCostParameter, T) param[name, t] * mult[name, t] else get_shut_down(get_operation_cost(d)) end iszero(cost_term) && continue rate = cost_term * multiplier - variable = get_variable(container, U(), T)[name, t] + variable = get_variable(container, U, T)[name, t] if add_as_time_variant add_cost_term_variant!( container, variable, rate, ProductionCostExpression, T, name, t) @@ -79,7 +80,7 @@ function _add_start_up_cost_to_objective!( container, T(), component, U(), t, add_as_time_variant) iszero(cost_term) && continue rate = cost_term * multiplier - variable = get_variable(container, T(), C)[name, t] + variable = get_variable(container, T, C)[name, t] if add_as_time_variant add_cost_term_variant!( container, variable, rate, ProductionCostExpression, C, name, t) @@ -105,8 +106,8 @@ function get_startup_cost_value( } raw_startup_cost = if is_time_variant_ name = get_name(component) - param = get_parameter_array(container, StartupCostParameter(), V) - mult = get_parameter_multiplier_array(container, StartupCostParameter(), V) + param = get_parameter_array(container, StartupCostParameter, V) + mult = get_parameter_multiplier_array(container, StartupCostParameter, V) param[name, time_period] * mult[name, time_period] else get_start_up(get_operation_cost(component)) diff --git a/src/operation/operation_model_interface.jl b/src/operation/operation_model_interface.jl index da670c9..d264b6f 100644 --- a/src/operation/operation_model_interface.jl +++ b/src/operation/operation_model_interface.jl @@ -278,9 +278,9 @@ function _pre_solve_model_checks(model::OperationModel, optimizer = nothing) return end -function _list_names(model::OperationModel, container_type) +function list_names(model::OperationModel, ::Type{T}) where {T <: OptimizationKeyType} return encode_keys_as_strings( - list_keys(get_store(model), container_type), + list_keys(get_store(model), T), ) end @@ -342,25 +342,20 @@ function instantiate_network_model!(model::OperationModel) return end -list_aux_variable_keys(x::OperationModel) = - list_keys(get_store(x), STORE_CONTAINER_AUX_VARIABLES) -list_aux_variable_names(x::OperationModel) = _list_names(x, STORE_CONTAINER_AUX_VARIABLES) -list_variable_keys(x::OperationModel) = - list_keys(get_store(x), STORE_CONTAINER_VARIABLES) -list_variable_names(x::OperationModel) = _list_names(x, STORE_CONTAINER_VARIABLES) -list_parameter_keys(x::OperationModel) = - list_keys(get_store(x), STORE_CONTAINER_PARAMETERS) -list_parameter_names(x::OperationModel) = _list_names(x, STORE_CONTAINER_PARAMETERS) -list_dual_keys(x::OperationModel) = - list_keys(get_store(x), STORE_CONTAINER_DUALS) -list_dual_names(x::OperationModel) = _list_names(x, STORE_CONTAINER_DUALS) -list_expression_keys(x::OperationModel) = - list_keys(get_store(x), STORE_CONTAINER_EXPRESSIONS) -list_expression_names(x::OperationModel) = _list_names(x, STORE_CONTAINER_EXPRESSIONS) +list_aux_variable_keys(x::OperationModel) = list_keys(get_store(x), AuxVariableType) +list_aux_variable_names(x::OperationModel) = list_names(x, AuxVariableType) +list_variable_keys(x::OperationModel) = list_keys(get_store(x), VariableType) +list_variable_names(x::OperationModel) = list_names(x, VariableType) +list_parameter_keys(x::OperationModel) = list_keys(get_store(x), ParameterType) +list_parameter_names(x::OperationModel) = list_names(x, ParameterType) +list_dual_keys(x::OperationModel) = list_keys(get_store(x), ConstraintType) +list_dual_names(x::OperationModel) = list_names(x, ConstraintType) +list_expression_keys(x::OperationModel) = list_keys(get_store(x), ExpressionType) +list_expression_names(x::OperationModel) = list_names(x, ExpressionType) function list_all_keys(x::OperationModel) return Iterators.flatten( - keys(get_data_field(get_store(x), f)) for f in STORE_CONTAINERS + list_fields(get_store(x), T) for T in STORE_CONTAINER_TYPES ) end diff --git a/src/utils/print_pt_v2.jl b/src/utils/print_pt_v2.jl index 75aac1a..7dc789c 100644 --- a/src/utils/print_pt_v2.jl +++ b/src/utils/print_pt_v2.jl @@ -98,6 +98,7 @@ function _show_method( table = Matrix{String}(undef, length(model.feedforwards), length(header)) for (ix, v) in enumerate(model.feedforwards) table[ix, 1] = string(typeof(v)) + # FIXME this 1-arg version is defined in POM. move it? table[ix, 2] = encode_key_as_string(get_optimization_container_key(v)) table[ix, 3] = first(encode_key_as_string.(get_affected_values(v))) end diff --git a/src/utils/print_pt_v3.jl b/src/utils/print_pt_v3.jl index 6627ebd..3110b45 100644 --- a/src/utils/print_pt_v3.jl +++ b/src/utils/print_pt_v3.jl @@ -99,6 +99,7 @@ function _show_method( table = Matrix{String}(undef, length(model.feedforwards), length(header)) for (ix, v) in enumerate(model.feedforwards) table[ix, 1] = string(typeof(v)) + # FIXME this 1-arg version is defined in POM. move it? table[ix, 2] = encode_key_as_string(get_optimization_container_key(v)) table[ix, 3] = first(encode_key_as_string.(get_affected_values(v))) end diff --git a/test/Project.toml b/test/Project.toml index dd1e7fb..547869d 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -7,6 +7,7 @@ DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" InfrastructureSystems = "2cd47ed4-ca9b-11e9-27f2-ab636a7671f1" +Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -17,6 +18,7 @@ PowerSystemCaseBuilder = "f00506e0-b84f-492a-93c2-c0a9afc4364e" PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" +SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04" @@ -24,9 +26,9 @@ TimeSeries = "9e3dc215-6440-5c97-bce1-76c03772f85e" TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +[sources] +InfrastructureSystems = {rev = "IS4", url = "https://github.com/NREL-Sienna/InfrastructureSystems.jl"} + [compat] HiGHS = "1" julia = "^1.10" - -[sources] -InfrastructureSystems = {url = "https://github.com/NREL-Sienna/InfrastructureSystems.jl", rev = "IS4"} diff --git a/test/test_cost_term_helpers.jl b/test/test_cost_term_helpers.jl index 06a2586..85cafc3 100644 --- a/test/test_cost_term_helpers.jl +++ b/test/test_cost_term_helpers.jl @@ -49,7 +49,7 @@ Test types defined in test_utils/test_types.jl. # Verify expression was updated expr_container = - IOM.get_expression(container, TestCostExpression(), MockThermalGen) + IOM.get_expression(container, TestCostExpression, MockThermalGen) expr = expr_container["gen1", 1] @test JuMP.coefficient(expr, var) ≈ rate end @@ -144,7 +144,7 @@ Test types defined in test_utils/test_types.jl. ) # Verify expression was updated - expr_container = IOM.get_expression(container, TestCostExpression(), MockThermalGen) + expr_container = IOM.get_expression(container, TestCostExpression, MockThermalGen) expr = expr_container["gen1", 1] @test JuMP.coefficient(expr, var) ≈ 15.0 end @@ -172,7 +172,7 @@ Test types defined in test_utils/test_types.jl. end # Verify stored in container - var_container = IOM.get_variable(container, TestPWLVariable(), MockThermalGen) + var_container = IOM.get_variable(container, TestPWLVariable, MockThermalGen) for i in 1:4 @test var_container["gen1", i, 1] === pwl_vars[i] end @@ -227,7 +227,7 @@ Test types defined in test_utils/test_types.jl. # Get the constraint con_container = - IOM.get_constraint(container, TestCostConstraint(), MockThermalGen) + IOM.get_constraint(container, TestCostConstraint, MockThermalGen) con = con_container["gen1", 1] # Verify constraint: power_var == sum(pwl_vars .* breakpoints) @@ -252,7 +252,7 @@ Test types defined in test_utils/test_types.jl. ) con_container = - IOM.get_constraint(container, TestCostConstraint(), MockThermalGen) + IOM.get_constraint(container, TestCostConstraint, MockThermalGen) con = con_container["gen1", 1] # Verify constraint: sum(pwl_vars) == on_status @@ -277,7 +277,7 @@ Test types defined in test_utils/test_types.jl. ) con_container = - IOM.get_constraint(container, TestCostConstraint(), MockThermalGen) + IOM.get_constraint(container, TestCostConstraint, MockThermalGen) con = con_container["gen1", 1] # Verify constraint includes the on_status variable diff --git a/test/test_optimization_container.jl b/test/test_optimization_container.jl index 3b03a31..f8c5fbe 100644 --- a/test/test_optimization_container.jl +++ b/test/test_optimization_container.jl @@ -82,7 +82,7 @@ struct MockExpressionType <: ISOPT.ExpressionType end # Verify dimensions retrieved = - PSI.get_variable(container, PSI.ActivePowerVariable(), MockComponentType) + PSI.get_variable(container, PSI.ActivePowerVariable, MockComponentType) @test size(retrieved) == (length(device_names), length(time_steps)) end diff --git a/test/test_piecewise_linear.jl b/test/test_piecewise_linear.jl index 4c77bfb..c6e3ec7 100644 --- a/test/test_piecewise_linear.jl +++ b/test/test_piecewise_linear.jl @@ -170,7 +170,7 @@ end # Add the PWL constraint break_points = IS.get_x_coords(pwl_data) power_var = - IOM.get_variable(container, TestPWLVariable(), MockThermalGen)["gen1", 1] + IOM.get_variable(container, TestPWLVariable, MockThermalGen)["gen1", 1] InfrastructureOptimizationModels._add_pwl_constraint_standard!( container, device, diff --git a/test/test_pwl_methods.jl b/test/test_pwl_methods.jl index bf23404..ae2249b 100644 --- a/test/test_pwl_methods.jl +++ b/test/test_pwl_methods.jl @@ -183,12 +183,12 @@ function setup_pwl_constraint_test(; return (; container, - x_var = IOM.get_variable(container, TestOriginalVariable(), MockThermalGen), - y_var = IOM.get_variable(container, TestApproximatedVariable(), MockThermalGen), - δ_var = IOM.get_variable(container, TestInterpolationVariable(), MockThermalGen), + x_var = IOM.get_variable(container, TestOriginalVariable, MockThermalGen), + y_var = IOM.get_variable(container, TestApproximatedVariable, MockThermalGen), + δ_var = IOM.get_variable(container, TestInterpolationVariable, MockThermalGen), z_var = IOM.get_variable( container, - TestBinaryInterpolationVariable(), + TestBinaryInterpolationVariable, MockThermalGen, ), jump_model = IOM.get_jump_model(container), @@ -476,7 +476,7 @@ end # Verify PWL variables were created pwl_vars = - IOM.get_variable(container, IOM.PiecewiseLinearCostVariable(), MockThermalGen) + IOM.get_variable(container, IOM.PiecewiseLinearCostVariable, MockThermalGen) for t in time_steps for i in 1:num_points @test pwl_vars[device_name, i, t] isa JuMP.VariableRef diff --git a/test/test_utils/model_checks.jl b/test/test_utils/model_checks.jl index 8ea6025..d76d7cc 100644 --- a/test/test_utils/model_checks.jl +++ b/test/test_utils/model_checks.jl @@ -165,7 +165,7 @@ function check_flow_variable_values( limit::Float64, ) where {T <: PSI.VariableType, U <: PSY.Component} psi_cont = PSI.get_optimization_container(model) - variable = PSI.get_variable(psi_cont, T(), U) + variable = PSI.get_variable(psi_cont, T, U) for var in variable[device_name, :] if !(PSI.jump_value(var) <= (limit + 1e-2)) @error "$device_name out of bounds $(PSI.jump_value(var))" @@ -189,9 +189,9 @@ function check_flow_variable_values( net_formulation = PSI.get_network_formulation(template) if dev_formulation <: Union{PSI.StaticBranch, PSI.StaticBranchUnbounded} && net_formulation <: PSI.PTDFPowerModel - variable = PSI.get_expression(psi_cont, PSI.PTDFBranchFlow(), U) + variable = PSI.get_expression(psi_cont, PSI.PTDFBranchFlow, U) else - variable = PSI.get_variable(psi_cont, T(), U) + variable = PSI.get_variable(psi_cont, T, U) end for var in variable[device_name, :] if !(PSI.jump_value(var) <= (limit + 1e-2)) @@ -211,7 +211,7 @@ function check_flow_variable_values( limit_max::Float64, ) where {T <: PSI.VariableType, U <: PSY.Component} psi_cont = PSI.get_optimization_container(model) - variable = PSI.get_variable(psi_cont, T(), U) + variable = PSI.get_variable(psi_cont, T, U) for var in variable[device_name, :] if !(PSI.jump_value(var) <= (limit_max + 1e-2)) || !(PSI.jump_value(var) >= (limit_min - 1e-2)) @@ -236,9 +236,9 @@ function check_flow_variable_values( net_formulation = PSI.get_network_formulation(template) if dev_formulation <: Union{PSI.StaticBranch, PSI.StaticBranchUnbounded} && net_formulation <: PSI.PTDFPowerModel - variable = PSI.get_expression(psi_cont, PSI.PTDFBranchFlow(), U) + variable = PSI.get_expression(psi_cont, PSI.PTDFBranchFlow, U) else - variable = PSI.get_variable(psi_cont, T(), U) + variable = PSI.get_variable(psi_cont, T, U) end for var in variable[device_name, :] if !(PSI.jump_value(var) <= (limit_max + 1e-2)) || @@ -260,8 +260,8 @@ function check_flow_variable_values( ) where {T <: PSI.VariableType, U <: PSI.VariableType, V <: PSY.Component} psi_cont = PSI.get_optimization_container(model) time_steps = PSI.get_time_steps(psi_cont) - pvariable = PSI.get_variable(psi_cont, T(), V) - qvariable = PSI.get_variable(psi_cont, U(), V) + pvariable = PSI.get_variable(psi_cont, T, V) + qvariable = PSI.get_variable(psi_cont, U, V) for t in time_steps fp = PSI.jump_value(pvariable[device_name, t]) fq = PSI.jump_value(qvariable[device_name, t]) @@ -283,8 +283,8 @@ function check_flow_variable_values( ) where {T <: PSI.VariableType, U <: PSI.VariableType, V <: PSY.Component} psi_cont = PSI.get_optimization_container(model) time_steps = PSI.get_time_steps(psi_cont) - pvariable = PSI.get_variable(psi_cont, T(), V) - qvariable = PSI.get_variable(psi_cont, U(), V) + pvariable = PSI.get_variable(psi_cont, T, V) + qvariable = PSI.get_variable(psi_cont, U, V) for t in time_steps fp = PSI.jump_value(pvariable[device_name, t]) fq = PSI.jump_value(qvariable[device_name, t]) @@ -462,7 +462,7 @@ function check_initialization_constraint_count( ISOPT.get_initial_conditions_model_container(PSI.get_internal(model)) no_component = length(PSY.get_components(filter_func, T, model.sys)) time_steps = PSI.get_time_steps(container)[end] - constraint = PSI.get_constraint(container, S(), T, meta) + constraint = PSI.get_constraint(container, S, T, meta) @test length(constraint) == no_component * time_steps end diff --git a/test/test_utils/objective_function_helpers.jl b/test/test_utils/objective_function_helpers.jl index 0653d10..62ade8c 100644 --- a/test/test_utils/objective_function_helpers.jl +++ b/test/test_utils/objective_function_helpers.jl @@ -47,7 +47,7 @@ function add_test_variable!( time_steps = IOM.get_time_steps(container) IOM.add_variable_container!(container, V(), C, [name], time_steps) end - var_container = IOM.get_variable(container, V(), C) + var_container = IOM.get_variable(container, V, C) jump_model = IOM.get_jump_model(container) var = JuMP.@variable(jump_model, base_name = "$(V)_$(name)_$(t)") var_container[name, t] = var