Skip to content

Commit

Permalink
FIX: apply_voltage_bounds! for multinetwork data
Browse files Browse the repository at this point in the history
Creates the following functions to separate out the functionality for ENGINEERING vs MATHEMATICAL data models

- discover_math_voltage_zones
- discover_eng_voltage_zones
- calc_math_voltage_bases
- calc_eng_voltage_bases

Fixes #388
  • Loading branch information
pseudocubic committed May 10, 2022
1 parent 1ef95d0 commit 0fbf5f7
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## staged

- Fixed bug in `apply_voltage_bounds!` for multinetwork data
- Added compat for JuMP v1
- Fixed bug in `_map_eng2math` where global keys were not being propagated in multinetwork
- Fixed bug/typo in `_create_storage` where `kwhstored` was derived from `:stored` instead of `Symbol("%stored")`
Expand Down
2 changes: 1 addition & 1 deletion src/data_model/transformations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ end
add voltage bounds to all buses based on per-unit upper (`vm_ub`) and lower (`vm_lb`), scaled by the bus's voltage based
"""
function _apply_voltage_bounds!(data_eng::Dict{String,<:Any}; vm_lb::Union{Real,Missing}=0.9, vm_ub::Union{Real,Missing}=1.1, exclude::Vector{String}=!isempty(get(data_eng, "voltage_source", Dict())) ? String[x.second["bus"] for x in data_eng["voltage_source"]] : String[])
(bus_vbases, edge_vbases) = calc_voltage_bases(data_eng, data_eng["settings"]["vbases_default"])
(bus_vbases, _) = calc_eng_voltage_bases(data_eng, data_eng["settings"]["vbases_default"])
for (id, bus) in filter(x->!(x.first in exclude), get(data_eng, "bus", Dict{String,Any}()))
vbase = bus_vbases[id]
if !ismissing(vm_lb) && !ismissing(vbase)
Expand Down
61 changes: 55 additions & 6 deletions src/data_model/units.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,37 @@ end
"""
discover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}
finds voltage zones by walking through the network and analyzing the transformers
finds voltage zones by walking through the network and analyzing the transformers, attempting to decern the type of `data_model`
"""
function discover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}
@assert iseng(data_model) || ismath(data_model) "unsupported data model"
edge_elements = ismath(data_model) ? _math_edge_elements : _eng_edge_elements

return ismath(data_model) ? discover_math_voltage_zones(data_model) : discover_eng_voltage_zones(data_model)
end


"""
discover_math_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}
finds voltage zones by walking through the network and analyzing the transformers for a MATHEMATICAL `data_model`
"""
discover_math_voltage_zones(data_model::Dict{String,Any})::Dict{Int,Set{Any}} = _discover_voltage_zones(data_model, _math_edge_elements)


"""
discover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}
finds voltage zones by walking through the network and analyzing the transformers for a ENGINEERING `data_model`
"""
discover_eng_voltage_zones(data_model::Dict{String,Any})::Dict{Int,Set{Any}} = _discover_voltage_zones(data_model, _eng_edge_elements)


"""
discover_voltage_zones(data_model::Dict{String,<:Any}, edge_elements::Vector{String})::Dict{Int,Set{Any}}
finds voltage zones by walking through the network and analyzing the transformers
"""
function _discover_voltage_zones(data_model::Dict{String,<:Any}, edge_elements::Vector{String})::Dict{Int,Set{Any}}
unused_components = Set("$comp_type.$id" for comp_type in edge_elements[edge_elements .!= "transformer"] for id in keys(get(data_model, comp_type, Dict())))
bus_connectors = Dict([(id,Set()) for id in keys(get(data_model, "bus", Dict()))])
for comp_type in edge_elements[edge_elements .!= "transformer"]
Expand Down Expand Up @@ -147,15 +172,40 @@ function discover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{An
return zones
end

"""
calc_math_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}
Calculates voltage bases for each voltage zone for buses and branches for a MATHEMATICAL `data_model`
"""
calc_math_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict} = _calc_voltage_bases(data_model, vbase_sources, _math_edge_elements)


"""
calc_eng_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}
Calculates voltage bases for each voltage zone for buses and branches for a ENGINEERING `data_model`
"""
calc_eng_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict} = _calc_voltage_bases(data_model, vbase_sources, _eng_edge_elements)


"""
calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}
Calculates voltage bases for each voltage zone for buses and branches
Calculates voltage bases for each voltage zone for buses and branches, attempting to automatically decern the `data_model` type
"""
function calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}
return ismath(data_model) ? calc_math_voltage_bases(data_model, vbase_sources) : calc_eng_voltage_bases(data_model, vbase_sources)
end


"""
_calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real}, edge_elements::Vector{String})::Tuple{Dict,Dict}
Calculates voltage bases for each voltage zone for buses and branches given a list of `edge_elements`
"""
function _calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real}, edge_elements::Vector{String})::Tuple{Dict,Dict}
# find zones of buses connected by lines
zones = discover_voltage_zones(data_model)
zones = _discover_voltage_zones(data_model, edge_elements)
bus_to_zone = Dict([(bus,zone) for (zone, buses) in zones for bus in buses])

# assign specified vbase to corresponding zones
Expand Down Expand Up @@ -214,10 +264,9 @@ function calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{
end
end

edge_elements = ismath(data_model) ? _math_edge_elements : _eng_edge_elements

bus_vbase = Dict([(bus,zone_vbase[zone]) for (bus,zone) in bus_to_zone])
edge_vbase = Dict([("$edge_type.$id", bus_vbase["$(obj["f_bus"])"]) for edge_type in edge_elements[edge_elements .!= "transformer"] if haskey(data_model, edge_type) for (id,obj) in data_model[edge_type]])

return (bus_vbase, edge_vbase)
end

Expand Down
12 changes: 12 additions & 0 deletions test/multinetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,16 @@

@test result_mn["termination_status"] == LOCALLY_SOLVED
end

@testset "apply_voltage_bounds! to multinetworks" begin
mn_eng = make_multinetwork(case3_balanced)

apply_voltage_bounds!(mn_eng)
for (n,nw) in mn_eng["nw"]
vbases, _ = calc_eng_voltage_bases(mn_eng["nw"]["1"], mn_eng["nw"]["1"]["settings"]["vbases_default"])

@test all(all(isapprox.(bus["vm_ub"][filter(x->xbus["grounded"],bus["terminals"])]/vbases[id], 1.1; atol=1e-6)) for (id,bus) in filter(x->x.first!="sourcebus",nw["bus"]))
@test all(all(isapprox.(bus["vm_lb"][filter(x->xbus["grounded"],bus["terminals"])]/vbases[id], 0.9; atol=1e-6)) for (id,bus) in filter(x->x.first!="sourcebus",nw["bus"]))
end
end
end

0 comments on commit 0fbf5f7

Please sign in to comment.