diff --git a/src/devices_models/devices/AC_branches.jl b/src/devices_models/devices/AC_branches.jl index 1176f83700..bf24ae3c3c 100644 --- a/src/devices_models/devices/AC_branches.jl +++ b/src/devices_models/devices/AC_branches.jl @@ -168,14 +168,55 @@ function add_constraints!( container::OptimizationContainer, cons_type::Type{RateLimitConstraint}, devices::IS.FlattenIteratorWrapper{T}, - model::DeviceModel{T, U}, - ::NetworkModel{X}, + ::DeviceModel{T, U}, + network_model::NetworkModel{V}, ) where { T <: PSY.ACBranch, U <: AbstractBranchFormulation, - X <: PM.AbstractActivePowerModel, + V <: PM.AbstractActivePowerModel, } - add_range_constraints!(container, cons_type, FlowActivePowerVariable, devices, model, X) + time_steps = get_time_steps(container) + radial_branches = get_radial_branches(network_model) + if isempty(radial_branches) + device_names = [PSY.get_name(d) for d in devices] + else + device_names = PNM.get_meshed_branches(radial_branches) + end + + con_lb = + add_constraints_container!( + container, + cons_type(), + T, + device_names, + time_steps; + meta = "lb", + ) + con_ub = + add_constraints_container!( + container, + cons_type(), + T, + device_names, + time_steps; + meta = "ub", + ) + + array = get_variable(container, FlowActivePowerVariable(), T) + + for device in devices + ci_name = PSY.get_name(device) + if ci_name ∈ PNM.get_radial_branches(radial_branches) + continue + end + limits = get_min_max_limits(device, RateLimitConstraint, U) # depends on constraint type and formulation type + for t in time_steps + con_ub[ci_name, t] = + JuMP.@constraint(container.JuMPmodel, array[ci_name, t] <= limits.max) + con_lb[ci_name, t] = + JuMP.@constraint(container.JuMPmodel, array[ci_name, t] >= limits.min) + end + end return end diff --git a/src/devices_models/devices/common/add_to_expression.jl b/src/devices_models/devices/common/add_to_expression.jl index 54aa14a590..22b56059b2 100644 --- a/src/devices_models/devices/common/add_to_expression.jl +++ b/src/devices_models/devices/common/add_to_expression.jl @@ -79,7 +79,7 @@ function add_to_expression!( ::Type{U}, devices::IS.FlattenIteratorWrapper{V}, model::DeviceModel{V, W}, - ::NetworkModel{X}, + network_model::NetworkModel{X}, ) where { T <: SystemBalanceExpressions, U <: TimeSeriesParameter, @@ -89,11 +89,12 @@ function add_to_expression!( } param_container = get_parameter(container, U(), V) multiplier = get_multiplier_array(param_container) + radial_branches = get_radial_branches(network_model) for d in devices, t in get_time_steps(container) - bus_number = PSY.get_number(PSY.get_bus(d)) + bus_no = PNM.get_mapped_bus_number(radial_branches, PSY.get_number(PSY.get_bus(d))) name = PSY.get_name(d) _add_to_jump_expression!( - get_expression(container, T(), PSY.ACBus)[bus_number, t], + get_expression(container, T(), PSY.ACBus)[bus_no, t], get_parameter_column_refs(param_container, name)[t], multiplier[name, t], ) @@ -107,7 +108,7 @@ function add_to_expression!( ::Type{U}, devices::IS.FlattenIteratorWrapper{V}, ::DeviceModel{V, W}, - ::NetworkModel{X}, + network_model::NetworkModel{X}, ) where { T <: ActivePowerBalance, U <: OnStatusParameter, @@ -116,13 +117,13 @@ function add_to_expression!( X <: PM.AbstractPowerModel, } parameter = get_parameter_array(container, U(), V) - + radial_branches = get_radial_branches(network_model) for d in devices, t in get_time_steps(container) - bus_number = PSY.get_number(PSY.get_bus(d)) + bus_no = PNM.get_mapped_bus_number(radial_branches, PSY.get_number(PSY.get_bus(d))) name = PSY.get_name(d) mult = get_expression_multiplier(U(), T(), d, W()) _add_to_jump_expression!( - get_expression(container, T(), PSY.ACBus)[bus_number, t], + get_expression(container, T(), PSY.ACBus)[bus_no, t], parameter[name, t], mult, ) @@ -139,7 +140,7 @@ function add_to_expression!( ::Type{U}, devices::IS.FlattenIteratorWrapper{V}, ::DeviceModel{V, W}, - ::NetworkModel{X}, + network_model::NetworkModel{X}, ) where { T <: SystemBalanceExpressions, U <: VariableType, @@ -149,11 +150,12 @@ function add_to_expression!( } variable = get_variable(container, U(), V) expression = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices, t in get_time_steps(container) name = PSY.get_name(d) - bus_number = PSY.get_number(PSY.get_bus(d)) + bus_no = PNM.get_mapped_bus_number(radial_branches, PSY.get_number(PSY.get_bus(d))) _add_to_jump_expression!( - expression[bus_number, t], + expression[bus_no, t], variable[name, t], get_variable_multiplier(U(), V, W()), ) @@ -215,8 +217,10 @@ function add_to_expression!( var = get_variable(container, U(), V) nodal_expr = get_expression(container, T(), PSY.ACBus) sys_expr = get_expression(container, T(), PSY.System) + radial_branches = get_radial_branches(network_model) for d in devices - bus_no_to = PSY.get_number(PSY.get_arc(d).to) + bus_no_to_ = PSY.get_number(PSY.get_arc(d).to) + bus_no_to = PNM.get_mapped_bus_number(radial_branches, bus_no_to_) ref_bus_from = get_reference_bus(network_model, PSY.get_arc(d).from) ref_bus_to = get_reference_bus(network_model, PSY.get_arc(d).to) for t in get_time_steps(container) @@ -250,8 +254,10 @@ function add_to_expression!( var = get_variable(container, U(), V) nodal_expr = get_expression(container, T(), PSY.ACBus) sys_expr = get_expression(container, T(), PSY.System) + radial_branches = get_radial_branches(network_model) for d in devices - bus_no_from = PSY.get_number(PSY.get_arc(d).from) + bus_no_from_ = PSY.get_number(PSY.get_arc(d).from) + bus_no_from = PNM.get_mapped_bus_number(radial_branches, bus_no_from_) ref_bus_to = get_reference_bus(network_model, PSY.get_arc(d).to) ref_bus_from = get_reference_bus(network_model, PSY.get_arc(d).from) for t in get_time_steps(container) @@ -352,12 +358,14 @@ function add_to_expression!( } variable = get_variable(container, U(), V) expression = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices name = PSY.get_name(d) - bus_number = PSY.get_number(PSY.get_arc(d).from) + bus_no_ = PSY.get_number(PSY.get_arc(d).from) + bus_no = PNM.get_mapped_bus_number(radial_branches, bus_no_) for t in get_time_steps(container) _add_to_jump_expression!( - expression[bus_number, t], + expression[bus_no, t], variable[name, t], get_variable_multiplier(U(), V, W()), ) @@ -385,12 +393,14 @@ function add_to_expression!( } variable = get_variable(container, U(), V) expression = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices name = PSY.get_name(d) - bus_number = PSY.get_number(PSY.get_arc(d).to) + bus_no_ = PSY.get_number(PSY.get_arc(d).to) + bus_no = PNM.get_mapped_bus_number(radial_branches, bus_no_) for t in get_time_steps(container) _add_to_jump_expression!( - expression[bus_number, t], + expression[bus_no, t], variable[name, t], get_variable_multiplier(U(), V, W()), ) @@ -415,11 +425,13 @@ function add_to_expression!( } variable = get_variable(container, U(), V) expression = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices, t in get_time_steps(container) name = PSY.get_name(d) - bus_number = PSY.get_number(PSY.get_bus(d)) + bus_no_ = PSY.get_number(PSY.get_bus(d)) + PNM.get_mapped_bus_number(radial_branches, bus_no_) _add_to_jump_expression!( - expression[bus_number, t], + expression[bus_no, t], variable[name, t], get_variable_multiplier(U(), d, W()), ) @@ -574,10 +586,12 @@ function add_to_expression!( multiplier = get_multiplier_array(param_container) sys_expr = get_expression(container, T(), PSY.System) nodal_expr = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices name = PSY.get_name(d) device_bus = PSY.get_bus(d) - bus_no = PSY.get_number(device_bus) + bus_no_ = PSY.get_number(device_bus) + bus_no = PNM.get_mapped_bus_number(radial_branches, bus_no_) ref_bus = get_reference_bus(network_model, device_bus) param = get_parameter_column_refs(param_container, name) for t in get_time_steps(container) @@ -605,9 +619,11 @@ function add_to_expression!( parameter = get_parameter_array(container, U(), V) sys_expr = get_expression(container, T(), PSY.System) nodal_expr = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices, t in get_time_steps(container) name = PSY.get_name(d) - bus_no = PSY.get_number(PSY.get_bus(d)) + bus_no_ = PSY.get_number(PSY.get_bus(d)) + bus_no = PNM.get_mapped_bus_number(radial_branches, bus_no_) mult = get_expression_multiplier(U(), T(), d, W()) device_bus = PSY.get_bus(d) ref_bus = get_reference_bus(network_model, device_bus) @@ -637,10 +653,13 @@ function add_to_expression!( variable = get_variable(container, U(), V) sys_expr = get_expression(container, T(), PSY.System) nodal_expr = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) + @assert !isempty(radial_branches) for d in devices name = PSY.get_name(d) device_bus = PSY.get_bus(d) - bus_no = PSY.get_number(device_bus) + bus_no_ = PSY.get_number(device_bus) + bus_no = PNM.get_mapped_bus_number(radial_branches, bus_no_) ref_bus = get_reference_bus(network_model, device_bus) for t in get_time_steps(container) _add_to_jump_expression!( @@ -675,10 +694,12 @@ function add_to_expression!( variable = get_variable(container, U(), V) sys_expr = get_expression(container, T(), PSY.System) nodal_expr = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices name = PSY.get_name(d) device_bus = PSY.get_bus(d) - bus_no = PSY.get_number(device_bus) + bus_no_ = PSY.get_number(device_bus) + bus_no = PNM.get_mapped_bus_number(radial_branches, bus_no_) ref_bus = get_reference_bus(network_model, device_bus) for t in get_time_steps(container) _add_to_jump_expression!( @@ -715,16 +736,21 @@ function add_to_expression!( } var = get_variable(container, U(), V) expression = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices + bus_no_from_ = PSY.get_number(PSY.get_arc(d).from) + bus_no_from = PNM.get_mapped_bus_number(radial_branches, bus_no_from_) + bus_no_to_ = PSY.get_number(PSY.get_arc(d).to) + bus_no_to = PNM.get_mapped_bus_number(radial_branches, bus_no_to_) for t in get_time_steps(container) flow_variable = var[PSY.get_name(d), t] _add_to_jump_expression!( - expression[PSY.get_number(PSY.get_arc(d).from), t], + expression[bus_no_from, t], flow_variable, -1.0, ) _add_to_jump_expression!( - expression[PSY.get_number(PSY.get_arc(d).to), t], + expression[bus_no_to, t], flow_variable, 1.0, ) @@ -752,9 +778,12 @@ function add_to_expression!( var = get_variable(container, U(), V) nodal_expr = get_expression(container, T(), PSY.ACBus) sys_expr = get_expression(container, T(), PSY.System) + radial_branches = get_radial_branches(network_model) for d in devices - bus_no_from = PSY.get_number(PSY.get_arc(d).from) - bus_no_to = PSY.get_number(PSY.get_arc(d).to) + bus_no_from_ = PSY.get_number(PSY.get_arc(d).from) + bus_no_from = PNM.get_mapped_bus_number(radial_branches, bus_no_from_) + bus_no_to_ = PSY.get_number(PSY.get_arc(d).to) + bus_no_to = PNM.get_mapped_bus_number(radial_branches, bus_no_to_) ref_bus_from = get_reference_bus(network_model, PSY.get_arc(d).from) ref_bus_to = get_reference_bus(network_model, PSY.get_arc(d).to) for t in get_time_steps(container) @@ -826,16 +855,21 @@ function add_to_expression!( ) where {T <: ActivePowerBalance, U <: PhaseShifterAngle, V <: PhaseAngleControl} var = get_variable(container, U(), PSY.PhaseShiftingTransformer) expression = get_expression(container, T(), PSY.ACBus) + radial_branches = get_radial_branches(network_model) for d in devices + bus_no_from_ = PSY.get_number(PSY.get_arc(d).from) + bus_no_from = PNM.get_mapped_bus_number(radial_branches, bus_no_from_) + bus_no_to_ = PSY.get_number(PSY.get_arc(d).to) + bus_no_to = PNM.get_mapped_bus_number(radial_branches, bus_no_to_) for t in get_time_steps(container) flow_variable = var[PSY.get_name(d), t] _add_to_jump_expression!( - expression[PSY.get_number(PSY.get_arc(d).from), t], + expression[bus_no_from, t], flow_variable, -get_variable_multiplier(U(), d, V()), ) _add_to_jump_expression!( - expression[PSY.get_number(PSY.get_arc(d).to), t], + expression[bus_no_to, t], flow_variable, get_variable_multiplier(U(), d, V()), ) @@ -1079,6 +1113,7 @@ function add_to_expression!( variable = get_variable(container, U(), PSY.ACBus) expression = get_expression(container, T(), PSY.ACBus) @assert_op length(axes(variable, 1)) == length(axes(expression, 1)) + # We uses axis here to avoid double addition of the slacks to the aggregated buses for t in get_time_steps(container), n in axes(variable, 1) _add_to_jump_expression!( expression[n, t], @@ -1102,8 +1137,8 @@ function add_to_expression!( } variable = get_variable(container, U(), PSY.ACBus, "P") expression = get_expression(container, T(), PSY.ACBus) - bus_numbers = PSY.get_number.(get_available_components(PSY.ACBus, sys)) - for t in get_time_steps(container), n in bus_numbers + # We uses axis here to avoid double addition of the slacks to the aggregated buses + for t in get_time_steps(container), n in axes(variable, 1) _add_to_jump_expression!( expression[n, t], variable[n, t], @@ -1126,8 +1161,8 @@ function add_to_expression!( } variable = get_variable(container, U(), PSY.ACBus, "Q") expression = get_expression(container, T(), PSY.ACBus) - bus_numbers = PSY.get_number.(get_available_components(PSY.ACBus, sys)) - for t in get_time_steps(container), n in bus_numbers + # We uses axis here to avoid double addition of the slacks to the aggregated buses + for t in get_time_steps(container), n in axes(variable, 1) _add_to_jump_expression!( expression[n, t], variable[n, t],