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

ADD: Alternative methods for defining line constants #425

Merged
merged 11 commits into from
Jan 23, 2023
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## staged

- Added support for computing line constants from WireData, LineGeometry, LineSpacing, TSData and CNData
- Added Julia library SpecialFunctions for `besselj0` implementation
- Changed message that line is "being treated as superconducting" from `@info` to `@debug`
- Added support for WireData, LineGeometry, LineSpacing, TSData, and CNData dss objects
- Fixed bug in dss parser where when properties were assigned via `assign_property!`, the `prop_order` was not updated
- Updated CI workflows to used Nodejs v16 scripts
- Added UBF matrix power variables for switches [#423](https://github.com/lanl-ansi/PowerModelsDistribution.jl/issues/423)

Expand Down
9 changes: 5 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36"
PolyhedralRelaxations = "2e741578-48fa-11ea-2d62-b52c946f73a0"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
CSV = "0.8.5, 0.9, 0.10"
FilePaths = "0.8.3"
Glob = "1.3"
InfrastructureModels = "0.7.3"
Ipopt = "0.9, 1.0.2"
InfrastructureModels = "0.7.3, 0.7.5"
Ipopt = "0.9, 1.0.2, 1.1"
LoggingExtras = "0.4.7, 1"
JSON = "0.18, 0.19, 0.20, 0.21"
JuMP = "0.22, 0.23, 1"
LoggingExtras = "0.4.7, 1"
PolyhedralRelaxations = "0.3.3"
PolyhedralRelaxations = "0.3.5"
SCS = "0.9, 1.0, 1.1"
julia = "1.6"

Expand Down
3 changes: 3 additions & 0 deletions src/PowerModelsDistribution.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ module PowerModelsDistribution

import InfrastructureModels

import SpecialFunctions

# Logging Utilities
import Logging
import LoggingExtras
Expand Down Expand Up @@ -79,6 +81,7 @@ module PowerModelsDistribution
include("core/relaxation_scheme.jl")

include("io/utils.jl")
include("io/dss/line_constants.jl")
include("io/dss/dss_parse.jl")
include("io/dss/dss_data_structs.jl")
include("io/dss/dss_node_structs.jl")
Expand Down
4 changes: 2 additions & 2 deletions src/core/constraint_template.jl
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ function constraint_mc_ohms_yt_from(pm::AbstractUnbalancedPowerModel, i::Int; nw
t_idx = (i, t_bus, f_bus)

if all(all(isapprox.(branch[k], 0.0)) for k in ["br_r", "br_x", "g_fr", "g_to", "b_fr", "b_to"])
@info "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)"
@debug "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)"
if !haskey(con(pm, nw), :branch_flow)
con(pm, nw)[:branch_flow] = Dict{Int,Vector{Vector{<:JuMP.ConstraintRef}}}()
end
Expand Down Expand Up @@ -502,7 +502,7 @@ function constraint_mc_ohms_yt_to(pm::AbstractUnbalancedPowerModel, i::Int; nw::
t_idx = (i, t_bus, f_bus)

if all(all(isapprox.(branch[k], 0.0)) for k in ["br_r", "br_x", "g_fr", "g_to", "b_fr", "b_to"])
@info "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)"
@debug "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)"
if !haskey(con(pm, nw), :branch_flow)
con(pm, nw)[:branch_flow] = Dict{Int,Vector{Vector{<:JuMP.ConstraintRef}}}()
end
Expand Down
3 changes: 2 additions & 1 deletion src/core/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ An Enum to describe whether an object is enabled or disabled

An Enum to describe the type of capcontrol, e.g., kvar, voltage etc.
"""
@enum CapControlType CAP_CURRENT CAP_VOLTAGE CAP_REACTIVE_POWER CAP_DISABLED
@enum CapControlType CAP_CURRENT CAP_VOLTAGE CAP_REACTIVE_POWER CAP_DISABLED CAP_TIME
@doc "Capacitor control based on current" CAP_CURRENT
@doc "Capacitor control based on voltage" CAP_VOLTAGE
@doc "Capacitor control based on total reactive power (directional)" CAP_REACTIVE_POWER
@doc "Capacitor control disabled" CAP_DISABLED
@doc "Capacitor control based on time" CAP_TIME

"Collection of the built-in Enums for PowerModelsDistribution"
const PowerModelsDistributionEnums = Union{DataModel,LoadModel,ShuntModel,SwitchState,ControlMode,ConnConfig,Dispatchable,Status,CapControlType}
Expand Down
8 changes: 8 additions & 0 deletions src/data_model/eng2math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,14 @@ function _map_eng2math_shunt!(data_math::Dict{String,<:Any}, data_eng::Dict{Stri
"t_bus" => data_math["switch"][elem_id]["t_bus"]
)
end
elseif dss_obj_type == "capacitor"
elem_id = first(filter(x->x.second["source_id"] == replace(math_obj["controls"]["element"], "capacitor"=>"shunt"), data_math["shunt"])).first
math_obj["controls"]["element"] = Dict{String,Any}(
"type" => "shunt",
"index" => data_math["shunt"][elem_id]["index"],
"f_bus" => data_math["shunt"][elem_id]["shunt_bus"],
"t_bus" => data_math["shunt"][elem_id]["shunt_bus"]
)
else
elem_id = first(filter(x->x.second["source_id"] == math_obj["controls"]["element"], data_math["transformer"])).first
math_obj["controls"]["element"] = Dict{String,Any}(
Expand Down
2 changes: 2 additions & 0 deletions src/data_model/units.jl
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ function _rebase_pu_shunt!(shunt::Dict{String,<:Any}, vbase::Real, sbase::Real,
shunt["controls"]["vmin"] = shunt["controls"]["vmin"]*shunt["controls"]["ptratio"]/(vbase*voltage_scale_factor)
shunt["controls"]["vmax"] = shunt["controls"]["vmax"]*shunt["controls"]["ptratio"]/(vbase*voltage_scale_factor)
end
elseif shunt["controls"]["type"] == CAP_TIME
# do nothing
else
for (idx,val) in enumerate(shunt["controls"]["type"])
if shunt["controls"]["voltoverride"][idx]
Expand Down
34 changes: 30 additions & 4 deletions src/io/dss/dss2eng.jl
Original file line number Diff line number Diff line change
Expand Up @@ -480,15 +480,33 @@ function _dss2eng_line!(data_eng::Dict{String,<:Any}, data_dss::Dict{String,<:An
eng_obj["cm_ub"] = fill(defaults["emergamps"], ncond)
end

if any(haskey(dss_obj, key) && _is_after_linecode(dss_obj["prop_order"], key) for key in ["r0", "r1", "rg", "rmatrix"]) || !haskey(dss_obj, "linecode")
from_geometry = haskey(dss_obj, "geometry") && _is_after_linecode(dss_obj["prop_order"], "geometry")
from_spacing = haskey(dss_obj, "wires") && _is_after_linecode(dss_obj["prop_order"], "wires")
from_cncables = haskey(dss_obj, "cndata") && _is_after_linecode(dss_obj["prop_order"], "cncables")
from_tscables = haskey(dss_obj, "tsdata") && _is_after_linecode(dss_obj["prop_order"], "tscables")
if from_geometry || from_spacing || from_cncables || from_tscables
z, y = calculate_line_constants(data_dss, defaults)

rs, xs = real(z), imag(z)
g, b = real(y), imag(y)

eng_obj["rs"] = rs
eng_obj["xs"] = xs
eng_obj["b_fr"] = b ./ 2.0
eng_obj["b_to"] = b ./ 2.0
eng_obj["g_fr"] = g ./ 2.0
eng_obj["g_to"] = g ./ 2.0
end

if any(haskey(dss_obj, key) && (_is_after_linecode(dss_obj["prop_order"], key) && _is_after(dss_obj["prop_order"], key, "geometry")) for key in ["r0", "r1", "rg", "rmatrix"]) || (!haskey(dss_obj, "linecode") && !haskey(dss_obj, "geometry") && !haskey(dss_obj, "wires"))
eng_obj["rs"] = reshape(defaults["rmatrix"], nphases, nphases)
end

if any(haskey(dss_obj, key) && _is_after_linecode(dss_obj["prop_order"], key) for key in ["x0", "x1", "xg", "xmatrix"]) || !haskey(dss_obj, "linecode")
if any(haskey(dss_obj, key) && _is_after_linecode(dss_obj["prop_order"], key) && _is_after(dss_obj["prop_order"], key, "geometry") for key in ["x0", "x1", "xg", "xmatrix"]) || (!haskey(dss_obj, "linecode") && !haskey(dss_obj, "geometry") && !haskey(dss_obj, "wires"))
eng_obj["xs"] = reshape(defaults["xmatrix"], nphases, nphases)
end

if any(haskey(dss_obj, key) && _is_after_linecode(dss_obj["prop_order"], key) for key in ["b0", "b1", "c0", "c1", "cmatrix"]) || !haskey(dss_obj, "linecode")
if any(haskey(dss_obj, key) && _is_after_linecode(dss_obj["prop_order"], key) && _is_after(dss_obj["prop_order"], key, "geometry") for key in ["b0", "b1", "c0", "c1", "cmatrix"]) || (!haskey(dss_obj, "linecode") && !haskey(dss_obj, "geometry") && !haskey(dss_obj, "wires"))
eng_obj["b_fr"] = reshape(defaults["cmatrix"], nphases, nphases) ./ 2.0
eng_obj["b_to"] = reshape(defaults["cmatrix"], nphases, nphases) ./ 2.0
eng_obj["g_fr"] = fill(0.0, nphases, nphases)
Expand Down Expand Up @@ -857,7 +875,7 @@ function _dss2eng_regcontrol!(data_eng::Dict{String,<:Any}, data_dss::Dict{Strin
defaults = _apply_ordered_properties(_create_regcontrol(id; _to_kwargs(dss_obj)...), dss_obj)

nrw = get(data_dss["transformer"]["$(dss_obj["transformer"])"],"windings",2)
nphases = data_dss["transformer"]["$(dss_obj["transformer"])"]["phases"]
nphases = get(data_dss["transformer"]["$(dss_obj["transformer"])"], "phases", 3)

eng_obj = Dict{String,Any}(
"vreg" => [[w == defaults["winding"] && p == defaults["ptphase"] ? defaults["vreg"] : 0.0 for p in 1:nphases] for w in 1:nrw],
Expand Down Expand Up @@ -911,6 +929,9 @@ function _dss2eng_capcontrol!(data_eng::Dict{String,<:Any}, data_dss::Dict{Strin
eng_obj["onsetting"] = [p == defaults["ctphase"] ? defaults["onsetting"] : 0.0 for p in 1:nphases]
eng_obj["offsetting"] = [p == defaults["ctphase"] ? defaults["offsetting"] : 0.0 for p in 1:nphases]
eng_obj["ctratio"] = [p == defaults["ctphase"] ? defaults["ctratio"] : 0.0 for p in 1:nphases]
elseif type == CAP_TIME
eng_obj["type"] = type
eng_obj["terminal"] = defaults["terminal"]
end

if defaults["voltoverride"]
Expand Down Expand Up @@ -941,6 +962,11 @@ function _dss2eng_capcontrol!(data_eng::Dict{String,<:Any}, data_dss::Dict{Strin
eng_obj["offsetting"][defaults["ctphase"]] = defaults["offsetting"]
eng_obj["ctratio"][defaults["ptphase"]] = defaults["ctratio"]
end
if type == CAP_TIME
eng_obj["type"] = type
eng_obj["terminal"] = defaults["terminal"]
end

if defaults["voltoverride"]
eng_obj["voltoverride"][defaults["ptphase"]] = defaults["voltoverride"]
eng_obj["ptratio"][defaults["ptphase"]] = defaults["ptratio"]
Expand Down
Loading