Skip to content

Commit

Permalink
Add round trip branch name remapping, RTS_GMLC tests, more test tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielKS committed Jul 24, 2024
1 parent 62f3137 commit 698be0b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 7 deletions.
21 changes: 21 additions & 0 deletions src/psse_exporter/psse_exporter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ function make_gen_name_formatter_from_metadata(md::Dict)
return md_gen_name_formatter
end

function make_branch_name_formatter_from_metadata(md::Dict)
branch_map = md["Branch_Name_Mapping"]
function md_bus_name_formatter(
device_dict::Dict,
bus_f::PSY.ACBus,
bus_t::PSY.ACBus,
)::String
sid = device_dict["source_id"]
key = join((length(sid) == 6) ? [sid[2], sid[3], sid[5]] : last(sid, 3), "_")
return branch_map[key]
end
return md_bus_name_formatter
end

# TODO document this function
function Write_Sienna2PSSE(sys::System, scenario_name::String, year::Int64;
export_location::Union{Nothing, String} = nothing, base_case = false, setpoint = false,
Expand Down Expand Up @@ -456,6 +470,13 @@ function Write_Sienna2PSSE(sys::System, scenario_name::String, year::Int64;
sys,
),
)
branch_mapping = OrderedDict{String, String}() # Maps "$(from_bus_number)_$(to_bus_number)" to original PSY name
for branch in psy_branches
key = "$(PSY.get_number(PSY.get_from_bus(branch)))_$(PSY.get_number(PSY.get_to_bus(branch)))_$(last(split(PSY.get_name(branch), "_")))"
@assert !haskey(branch_mapping, key)
branch_mapping[key] = PSY.get_name(branch)
end
push!(raw_file_metadata, "Branch_Name_Mapping" => branch_mapping)

# line_dict = Dict{Tuple{Int64, Int64}, Int64}()
for branch in psy_branches
Expand Down
46 changes: 39 additions & 7 deletions test/test_psse_export.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ function reverse_composite_name(name::String)
return join([parts[2], parts[1], parts[3:end]...], "-")
end

# TODO figure out where these are coming from and fix at the source
# I think it has to do with per-unit conversions creating a division by zero, because `set_[re]active_power!(..., 0.0)` doesn't fix it
"Iterate over all the `Generator`s in the system and, if any `active_power` or `reactive_power` fields are `NaN`, make them `0.0`"
function fix_nans!(sys::PSY.System)
for gen in PSY.get_components(PSY.Generator, sys)
isnan(PSY.get_active_power(gen)) && (gen.active_power = 0.0)
isnan(PSY.get_reactive_power(gen)) && (gen.reactive_power = 0.0)
end
end

loose_system_match_fn(a::Float64, b::Float64) =
isapprox(a, b; atol = SYSTEM_REIMPORT_COMPARISON_TOLERANCE) || IS.isequivalent(a, b)
loose_system_match_fn(a, b) = IS.isequivalent(a, b)
Expand All @@ -125,7 +135,7 @@ function compare_systems_loosely(sys1::PSY.System, sys2::PSY.System;
PSY.Transformer2W,
PSY.ThermalStandard,
],
# TODO when possible, don't exclude: :bustype, :number, :angle, :magnitude, :variable, maybe more
# TODO when possible, don't exclude: :bustype, :number, :angle, :magnitude, :variable, :load_zone, probably more
exclude_fields = Set([
:name,
:ext,
Expand All @@ -135,6 +145,12 @@ function compare_systems_loosely(sys1::PSY.System, sys2::PSY.System;
:active_power_flow,
:reactive_power_flow,
:internal,
:voltage_limits,
:load_zone,
:ramp_limits,
:time_limits,
:services,
:angle_limits,
]),
# TODO when possible, don't exclude these things
exclude_fields_for_type = Dict(
Expand Down Expand Up @@ -216,6 +232,8 @@ end
function compare_systems_wrapper(sys1::System, sys2::System, sys2_metadata = nothing)
first_result = compare_component_values(sys1, sys2)
second_result = compare_systems_loosely(sys1, sys2)
@test first_result
@test second_result
return first_result && second_result
end

Expand All @@ -235,7 +253,9 @@ function read_system_and_metadata(raw_path, metadata_path)
sys =
System(raw_path;
bus_name_formatter = PF.make_bus_name_formatter_from_metadata(md),
gen_name_formatter = PF.make_gen_name_formatter_from_metadata(md))
gen_name_formatter = PF.make_gen_name_formatter_from_metadata(md),
branch_name_formatter = PF.make_branch_name_formatter_from_metadata(md))
fix_nans!(sys)
return sys, md
end

Expand All @@ -258,7 +278,7 @@ function test_psse_round_trip(
@test isfile(metadata_path)

sys2, sys2_metadata = read_system_and_metadata(raw_path, metadata_path)
@test compare_systems_wrapper(sys, sys2, sys2_metadata)
compare_systems_wrapper(sys, sys2, sys2_metadata)
test_power_flow(sys, sys2)
end

Expand Down Expand Up @@ -306,8 +326,8 @@ end
@testset "Test system comparison utilities" begin
sys = load_test_system()

@test compare_systems_wrapper(sys, sys)
@test compare_systems_wrapper(sys, deepcopy(sys))
compare_systems_wrapper(sys, sys)
compare_systems_wrapper(sys, deepcopy(sys))
end

@testset "PSSE Exporter with system_240[32].json, v33" begin
Expand Down Expand Up @@ -345,12 +365,24 @@ end
update_exporter!(exporter, sys2)
write_export(exporter, "basic4", 2024, export_location)
reread_sys2, sys2_metadata = read_system_and_metadata("basic4", 2024, export_location)
@test compare_systems_wrapper(sys2, reread_sys2, sys2_metadata)
compare_systems_wrapper(sys2, reread_sys2, sys2_metadata)
@test_logs((:error, r"Mismatch on rate"), (:error, r"values do not match"),
match_mode = :any, min_level = Logging.Error,
compare_systems_wrapper(sys, reread_sys2, sys2_metadata))
test_power_flow(sys2, reread_sys2)
end

# TODO test with systems from PSB rather than the custom one
@testset "PSSE Exporter with RTS_GMLC_DA_sys, v33" begin
sys = build_system(PSISystems, "RTS_GMLC_DA_sys")
set_units_base_system!(sys, UnitSystem.SYSTEM_BASE)

# PSS/E version must be one of the supported ones
@test_throws ArgumentError PSSEExporter(sys, :vNonexistent)

# Reimported export should be comparable to original system
exporter = PSSEExporter(sys, :v33)
export_location = joinpath(test_psse_export_dir, "v33", "rts_gmlc")
test_psse_round_trip(sys, exporter, "basic", 2024, export_location)
end

# TODO test v34
5 changes: 5 additions & 0 deletions test/test_utils/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ function PowerSystems.get_reactive_power_limits(gen::RenewableNonDispatch)
return (min = 0.0, max = gen_q)
end

# TODO more hacks
PowerSystems.get_r(::TwoTerminalHVDCLine) = 0.001
PowerSystems.get_x(::TwoTerminalHVDCLine) = 0.0
PowerSystems.get_b(::TwoTerminalHVDCLine) = (from = 0.0, to = 0.0)

"Take RTS_GMLC_DA_sys and make some changes to it that are fully captured in the PowerFlowData(ACPowerFlow(), ...)"
function modify_rts_system!(sys::System)
# For REF bus, voltage and angle are fixed; update active and reactive
Expand Down

0 comments on commit 698be0b

Please sign in to comment.