Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jd/radial branch reduction #1033

Merged
merged 82 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
54d707f
add radial_lines to network models
jd-lara Dec 28, 2023
df8f361
add radial branches to model
jd-lara Dec 28, 2023
fdba9ba
add bus maps
jd-lara Dec 29, 2023
040b150
add missing sort! call
jd-lara Jan 2, 2024
b8f9629
updates to network model
jd-lara Jan 2, 2024
2deda19
updates to the container
jd-lara Jan 2, 2024
d18aaea
updates to branch modeling
jd-lara Jan 2, 2024
c393f81
remove debugging assertion
jd-lara Jan 2, 2024
c8845f1
fix tests
jd-lara Jan 3, 2024
4d2c34c
fix bug with serialize function
jd-lara Jan 3, 2024
fbcd7da
bump power models
jd-lara Jan 3, 2024
51260df
remove assertion for multiconductor
jd-lara Jan 3, 2024
21b0ae4
update branch constructors to ignore radial branches
rodrigomha Jan 3, 2024
8154c9a
update slack expressions
rodrigomha Jan 3, 2024
d1dd6b1
add radial test
rodrigomha Jan 3, 2024
492aee9
Update LICENSE
jd-lara Jan 4, 2024
b77ecc5
add nothing check
jd-lara Jan 5, 2024
c927047
add assert
jd-lara Jan 5, 2024
954a916
use summary
jd-lara Jan 5, 2024
8e960bd
use power limits
jd-lara Jan 5, 2024
37d05db
fix function
jd-lara Jan 5, 2024
cfef00b
Update src/devices_models/devices/thermal_generation.jl
jd-lara Jan 5, 2024
bf24077
add new test
jd-lara Jan 8, 2024
f5e52bd
update testing
jd-lara Jan 8, 2024
a8be7cf
Merge pull request #1036 from NREL-Sienna/jd/ntp_debug
jd-lara Jan 8, 2024
a3af6b3
change internal
jd-lara Jan 10, 2024
86e3fc8
device_hvdc and network_const updates
Jan 10, 2024
b8cac7f
parametrize internal
jd-lara Jan 10, 2024
6976b14
separate outer constructor
jd-lara Jan 10, 2024
7833677
removing HydroPowerSimulations from Project.toml
lpstreitmatter Jan 10, 2024
4826380
Merge pull request #1041 from NREL-Sienna/ls/power_models_test_updates
rodrigomha Jan 10, 2024
32c7e03
abstract container
jd-lara Jan 10, 2024
8ac313f
use getter function
jd-lara Jan 10, 2024
4fa2a15
Merge pull request #1042 from NREL-Sienna/jd/multicontainer
jd-lara Jan 11, 2024
82b8115
Update Project.toml
jd-lara Jan 11, 2024
4f50cc8
bump PNM version
jd-lara Jan 11, 2024
2c4d558
Merge pull request #1034 from NREL-Sienna/jd/bump_power_models
jd-lara Jan 11, 2024
c1972c8
Update Project.toml
jd-lara Jan 11, 2024
b50e02c
bump PNM dependency
jd-lara Jan 11, 2024
5aefd0a
add radial_lines to network models
jd-lara Dec 28, 2023
1ee92de
add radial branches to model
jd-lara Dec 28, 2023
2cb0c36
add bus maps
jd-lara Dec 29, 2023
869042f
add missing sort! call
jd-lara Jan 2, 2024
72ae721
updates to network model
jd-lara Jan 2, 2024
4e9d046
updates to the container
jd-lara Jan 2, 2024
b3d7511
updates to branch modeling
jd-lara Jan 2, 2024
8e1a85c
remove debugging assertion
jd-lara Jan 2, 2024
e1aab9e
fix tests
jd-lara Jan 3, 2024
55704f1
fix bug with serialize function
jd-lara Jan 3, 2024
67cf974
update branch constructors to ignore radial branches
rodrigomha Jan 3, 2024
b9195ea
update slack expressions
rodrigomha Jan 3, 2024
1901f14
add radial test
rodrigomha Jan 3, 2024
46122d5
add new test
jd-lara Jan 8, 2024
f2a2a88
update testing
jd-lara Jan 8, 2024
6ea9724
bump PNM version
jd-lara Jan 11, 2024
ed843d5
Merge branch 'jd/radial_branch_reduction' of https://github.com/NREL-…
jd-lara Jan 11, 2024
5983103
bump ts version
jd-lara Jan 11, 2024
74a643c
formatter and test fixes
jd-lara Jan 15, 2024
d00ad50
update te testing code
jd-lara Jan 15, 2024
32b40cb
rename PNM object
jd-lara Jan 15, 2024
f0a7c76
replace radial_branches to radial_network_reduction
jd-lara Jan 15, 2024
2f6b9f0
replace field names
jd-lara Jan 15, 2024
82865ab
field name change
jd-lara Jan 15, 2024
a5764c3
more name replace
jd-lara Jan 15, 2024
0770442
implement name changes
jd-lara Jan 15, 2024
f856011
fix usage of dot access
jd-lara Jan 15, 2024
5a5e9b8
fix incompatible models
jd-lara Jan 15, 2024
4a5a05e
fix typo
jd-lara Jan 15, 2024
035ef78
use radial network reduction in slacks specs
jd-lara Jan 15, 2024
2ab1dd4
remove code duplication
jd-lara Jan 15, 2024
c9a7b5a
formatter run
jd-lara Jan 15, 2024
3bb6e78
fix eliminated variable
jd-lara Jan 15, 2024
4c1ccbd
variable rename
jd-lara Jan 15, 2024
c92e073
add missing docstring entry
jd-lara Jan 16, 2024
c046be7
fix deleted line
jd-lara Jan 16, 2024
db9e04c
rename field
jd-lara Jan 18, 2024
c6539e3
use bus
jd-lara Jan 19, 2024
d2ba948
fix network instantiation
jd-lara Jan 22, 2024
e356d1e
limit PNM version
jd-lara Jan 22, 2024
9f1c16d
fix typo
jd-lara Jan 22, 2024
782e017
add comment on sorting
jd-lara Jan 22, 2024
f93f740
Update src/core/optimization_container.jl
jd-lara Jan 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2018, 2023 Alliance for Sustainable Energy, LLC
Copyright (c) 2018, 2023 Alliance for Sustainable Energy, LLC and The Regents of the University of California
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PowerSimulations"
uuid = "e690365d-45e2-57bb-ac84-44ba829e73c4"
authors = ["Jose Daniel Lara", "Clayton Barrows", "Daniel Thom", "Dheepak Krishnamurthy", "Sourabh Dalvi"]
version = "0.25.2"
version = "0.26.0"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Expand Down Expand Up @@ -45,13 +45,13 @@ JuMP = "1"
LinearAlgebra = "1"
Logging = "1"
MathOptInterface = "1"
PowerModels = "~0.19"
PowerNetworkMatrices = "^0.9"
PowerModels = "^0.20"
PowerNetworkMatrices = "^0.10"
PowerSystems = "^3"
PrettyTables = "2"
ProgressMeter = "^1.5"
SHA = "0.7"
Serialization = "1"
TimeSeries = "~0.23"
TimeSeries = "~0.23, ~0.24"
TimerOutputs = "~0.5"
julia = "^1.6"
3 changes: 0 additions & 3 deletions src/core/definitions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ const KiB = 1024
const MiB = KiB * KiB
const GiB = MiB * KiB

const UNSUPPORTED_POWERMODELS =
[PM.SOCBFPowerModel, PM.SOCBFConicPowerModel, PM.IVRPowerModel]

const PSI_NAME_DELIMITER = "__"

const M_VALUE = 1e6
Expand Down
49 changes: 44 additions & 5 deletions src/core/network_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Establishes the model for a particular device specified by type.
- `use_slacks::Bool`: Adds slacks to the network modelings
- `PTDF::PTDF`: PTDF Array calculated using PowerNetworkMatrices
- `duals::Vector{DataType}`: Constraint types to calculate the duals

- `reduce_radial_branches::Bool`: Skips modeling radial branches in the system to reduce problem size
# Example

ptdf_array = PTDF(system)
Expand All @@ -32,21 +32,34 @@ mutable struct NetworkModel{T <: PM.AbstractPowerModel}
subnetworks::Dict{Int, Set{Int}}
bus_area_map::Dict{PSY.ACBus, Int}
duals::Vector{DataType}
radial_network_reduction::PNM.RadialNetworkReduction
reduce_radial_branches::Bool

function NetworkModel(
::Type{T};
use_slacks = false,
PTDF_matrix = nothing,
reduce_radial_branches = false,
jd-lara marked this conversation as resolved.
Show resolved Hide resolved
subnetworks = Dict{Int, Set{Int}}(),
duals = Vector{DataType}(),
) where {T <: PM.AbstractPowerModel}
_check_pm_formulation(T)
new{T}(use_slacks, PTDF_matrix, subnetworks, Dict{PSY.ACBus, Int}(), duals)
new{T}(
use_slacks,
PTDF_matrix,
subnetworks,
Dict{PSY.ACBus, Int}(),
duals,
PNM.RadialNetworkReduction(),
reduce_radial_branches,
)
end
end

get_use_slacks(m::NetworkModel) = m.use_slacks
get_PTDF_matrix(m::NetworkModel) = m.PTDF_matrix
get_reduce_radial_branches(m::NetworkModel) = m.reduce_radial_branches
get_radial_network_reduction(m::NetworkModel) = m.radial_network_reduction
get_duals(m::NetworkModel) = m.duals
get_network_formulation(::NetworkModel{T}) where {T} = T
get_reference_buses(m::NetworkModel{T}) where {T <: PM.AbstractPowerModel} =
Expand All @@ -62,13 +75,26 @@ function add_dual!(model::NetworkModel, dual)
return
end

function check_radial_branch_reduction_compatibility(
::Type{T},
) where {T <: PM.AbstractPowerModel}
if T ∈ INCOMPATIBLE_WITH_RADIAL_BRANCHES_POWERMODELS
error("Network Model $T is not compatible with radial branch reduction")
end
return
end

function instantiate_network_model(
model::NetworkModel{T},
sys::PSY.System,
) where {T <: PM.AbstractPowerModel}
if isempty(model.subnetworks)
model.subnetworks = PNM.find_subnetworks(sys)
end
if model.reduce_radial_branches
check_radial_branch_reduction_compatibility(T)
model.radial_network_reduction = PNM.RadialNetworkReduction(sys)
end
return
end

Expand All @@ -90,7 +116,12 @@ end
function instantiate_network_model(model::NetworkModel{StandardPTDFModel}, sys::PSY.System)
if get_PTDF_matrix(model) === nothing
@info "PTDF Matrix not provided. Calculating using PowerNetworkMatrices.PTDF"
model.PTDF_matrix = PNM.PTDF(sys)
model.PTDF_matrix =
PNM.PTDF(sys; reduce_radial_branches = model.reduce_radial_branches)
end
if model.reduce_radial_branches
@assert !isempty(model.PTDF_matrix.radial_network_reduction)
model.radial_network_reduction = model.PTDF_matrix.radial_network_reduction
end
get_PTDF_matrix(model).subnetworks
model.subnetworks = deepcopy(get_PTDF_matrix(model).subnetworks)
Expand All @@ -107,19 +138,27 @@ function _assign_subnetworks_to_buses(
) where {T <: Union{CopperPlatePowerModel, StandardPTDFModel}}
subnetworks = model.subnetworks
temp_bus_map = Dict{Int, Int}()
for bus in get_available_components(PSY.ACBus, sys)
radial_network_reduction = PSI.get_radial_network_reduction(model)
for bus in PSI.get_available_components(PSY.ACBus, sys)
bus_no = PSY.get_number(bus)
mapped_bus_no = PNM.get_mapped_bus_number(radial_network_reduction, bus)
if haskey(temp_bus_map, bus_no)
model.bus_area_map[bus] = temp_bus_map[bus_no]
continue
else
bus_mapped = false
for (subnet, bus_set) in subnetworks
if bus_no ∈ bus_set
if mapped_bus_no ∈ bus_set
temp_bus_map[bus_no] = subnet
model.bus_area_map[bus] = subnet
bus_mapped = true
break
end
end
end
if !bus_mapped
error("Bus $(PSY.summary(bus)) not mapped to any reference bus")
end
end
return
end
Expand Down
31 changes: 25 additions & 6 deletions src/core/optimization_container.jl
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,14 @@ function _make_system_expressions!(
subnetworks::Dict{Int, Set{Int}},
dc_bus_numbers::Vector{Int},
::Type{<:PM.AbstractPowerModel},
bus_reduction_map::Dict{Int64, Set{Int64}},
)
time_steps = get_time_steps(container)
ac_bus_numbers = collect(Iterators.flatten(values(subnetworks)))
if isempty(bus_reduction_map)
ac_bus_numbers = collect(Iterators.flatten(values(subnetworks)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand what bus_reduction_map is, but I'm a little wary of a completely different thing happening when it is empty. If an empty dictionary is meant to be a "null value" signifying that the bus reduction map should not be used, maybe making it nothing (and editing the relevant zero-argument constructor, etc. accordingly) would be a better way to indicate this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bus reduction map keep track of where the components of a bus that has been eliminated a now connected. For instance if a bus A is radially connected to B and A was eliminated, what the map does is to establish the model won't include A and anything connected to A will be connected to B in the model

else
ac_bus_numbers = collect(keys(bus_reduction_map))
end
container.expressions = Dict(
ExpressionKey(ActivePowerBalance, PSY.ACBus) =>
_make_container_array(ac_bus_numbers, time_steps),
Expand All @@ -450,9 +455,14 @@ function _make_system_expressions!(
subnetworks::Dict{Int, Set{Int}},
dc_bus_numbers::Vector{Int},
::Type{<:PM.AbstractActivePowerModel},
bus_reduction_map::Dict{Int64, Set{Int64}},
)
time_steps = get_time_steps(container)
ac_bus_numbers = collect(Iterators.flatten(values(subnetworks)))
if isempty(bus_reduction_map)
ac_bus_numbers = collect(Iterators.flatten(values(subnetworks)))
else
ac_bus_numbers = collect(keys(bus_reduction_map))
end
container.expressions = Dict(
ExpressionKey(ActivePowerBalance, PSY.ACBus) =>
_make_container_array(ac_bus_numbers, time_steps),
Expand All @@ -467,6 +477,7 @@ function _make_system_expressions!(
subnetworks::Dict{Int, Set{Int}},
::Vector{Int},
::Type{CopperPlatePowerModel},
bus_reduction_map::Dict{Int64, Set{Int64}},
)
time_steps = get_time_steps(container)
subnetworks_ref_buses = collect(keys(subnetworks))
Expand All @@ -482,17 +493,24 @@ function _make_system_expressions!(
subnetworks::Dict{Int, Set{Int}},
dc_bus_numbers::Vector{Int},
::Type{T},
bus_reduction_map::Dict{Int64, Set{Int64}},
) where {T <: Union{PTDFPowerModel, StandardPTDFModel}}
time_steps = get_time_steps(container)
ac_bus_numbers = sort!(collect(Iterators.flatten(values(subnetworks))))
if isempty(bus_reduction_map)
ac_bus_numbers = collect(Iterators.flatten(values(subnetworks)))
else
ac_bus_numbers = collect(keys(bus_reduction_map))
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block appears three times and there is further code duplication in the corresponding three methods of _make_system_expressions!; maybe refactor with a helper function

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, with the years some methods have created code duplication. We need to budget for a hygiene clean up of the code base @claytonpbarrows

subnetworks = collect(keys(subnetworks))
container.expressions = Dict(
ExpressionKey(ActivePowerBalance, PSY.System) =>
_make_container_array(subnetworks, time_steps),
ExpressionKey(ActivePowerBalance, PSY.DCBus) =>
_make_container_array(dc_bus_numbers, time_steps),
ExpressionKey(ActivePowerBalance, PSY.ACBus) =>
_make_container_array(ac_bus_numbers, time_steps),
# Bus numbers are sorted to guarantee consistency in the order between the
# containers
_make_container_array(sort!(ac_bus_numbers), time_steps),
jd-lara marked this conversation as resolved.
Show resolved Hide resolved
)
return
end
Expand All @@ -502,9 +520,10 @@ function initialize_system_expressions!(
::Type{T},
subnetworks::Dict{Int, Set{Int}},
system::PSY.System,
bus_reduction_map::Dict{Int64, Set{Int64}},
) where {T <: PM.AbstractPowerModel}
dc_bus_numbers = [PSY.get_number(b) for b in PSY.get_components(PSY.DCBus, system)]
_make_system_expressions!(container, subnetworks, dc_bus_numbers, T)
_make_system_expressions!(container, subnetworks, dc_bus_numbers, T, bus_reduction_map)
return
end

Expand All @@ -520,7 +539,7 @@ function build_impl!(
transmission,
transmission_model.subnetworks,
sys,
)
transmission_model.radial_network_reduction.bus_reduction_map)

# Order is required
for device_model in values(template.devices)
Expand Down
8 changes: 4 additions & 4 deletions src/devices_models/device_constructors/branch_constructor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function construct_device!(
container,
devices,
device_model,
get_network_formulation(network_model),
network_model,
)
end
return
Expand Down Expand Up @@ -273,7 +273,7 @@ function construct_device!(
container,
devices,
device_model,
get_network_formulation(network_model),
network_model,
)
add_constraint_dual!(container, sys, device_model)
return
Expand Down Expand Up @@ -331,7 +331,7 @@ function construct_device!(
) where {T <: PSY.ACBranch}
devices =
get_available_components(T, sys, get_attribute(model, "filter_function"))
branch_rate_bounds!(container, devices, model, get_network_formulation(network_model))
branch_rate_bounds!(container, devices, model, network_model)

add_constraints!(container, RateLimitConstraintFromTo, devices, model, network_model)
add_constraints!(container, RateLimitConstraintToFrom, devices, model, network_model)
Expand All @@ -356,7 +356,7 @@ function construct_device!(
) where {T <: PSY.ACBranch}
devices =
get_available_components(T, sys, get_attribute(model, "filter_function"))
branch_rate_bounds!(container, devices, model, get_network_formulation(network_model))
branch_rate_bounds!(container, devices, model, network_model)
add_constraint_dual!(container, sys, model)
return
end
Expand Down
Loading
Loading