Skip to content

Commit

Permalink
Begin implementing routine to update a System from a PowerFlowData
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielKS committed Jul 22, 2024
1 parent fb1b917 commit 9ea7e16
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 10 deletions.
27 changes: 27 additions & 0 deletions src/post_processing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,30 @@ function write_results(

return Dict("bus_results" => bus_df, "flow_results" => branch_df)
end

"""
Modify the values in the given `System` to correspond to the given `PowerFlowData` such that
if a new `PowerFlowData` is constructed from the resulting system it is the same as `data`.
See also `write_powerflow_solution!`.
"""
function update_system!(sys::PSY.System, data::PowerFlowData)
for bus in PSY.get_components(PSY.Bus, sys)
if bus.bustype == PSY.ACBusTypes.REF
P_gen = data.bus_activepower_injection[data.bus_lookup[PSY.get_number(bus)]]
Q_gen = data.bus_reactivepower_injection[data.bus_lookup[PSY.get_number(bus)]]
_power_redistribution_ref(sys, P_gen, Q_gen, bus)
# elseif bus.bustype == PSY.ACBusTypes.PV
# # TODO. This is the write_powerflow_solution! logic:
# Q_gen = result[2 * ix - 1]
# bus.angle = result[2 * ix]
# _reactive_power_redistribution_pv(sys, Q_gen, bus)
# elseif bus.bustype == PSY.ACBusTypes.PQ
# # TODO. This is the write_powerflow_solution! logic:
# Vm = result[2 * ix - 1]
# θ = result[2 * ix]
# PSY.set_magnitude!(bus, Vm)
# PSY.set_angle!(bus, θ)
end
end
# TODO
end
37 changes: 37 additions & 0 deletions test/test_powerflow_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,40 @@ end
PowerFlowData(PTDFDCPowerFlow(), sys; timesteps = timesteps)
PowerFlowData(vPTDFDCPowerFlow(), sys; timesteps = timesteps)
end

@testset "System <-> PowerFlowData round trip" begin
# TODO currently only tested with ACPowerFlow
# TODO test that update_system! errors if the PowerFlowData doesn't correspond to the system

sys_original = build_system(PSISystems, "RTS_GMLC_DA_sys")
data_original = PowerFlowData(ACPowerFlow(), sys_original)

sys_modified = deepcopy(sys_original)
modify_rts_system!(sys_modified)
data_modified = PowerFlowData(ACPowerFlow(), sys_original)
modify_rts_powerflow!(data_modified)

# update_system! with unmodified PowerFlowData should result in system that yields unmodified PowerFlowData
# (NOTE does NOT necessarily yield original system due to power redistribution)
sys_null_updated = deepcopy(sys_original)
PF.update_system!(sys_null_updated, data_original)
data_null_updated = PowerFlowData(ACPowerFlow(), sys_null_updated)
@test IS.compare_values(data_null_updated, data_original; match_fn = powerflow_match_fn)

# Modified versions should not be the same as unmodified versions
@test !@test_logs((:error, r"values do not match"),
match_mode = :any, min_level = Logging.Error,
IS.compare_values(data_original, data_modified; match_fn = powerflow_match_fn))
@test !@test_logs((:error, r"values do not match"),
match_mode = :any, min_level = Logging.Error,
IS.compare_values(sys_original, sys_modified; match_fn = powerflow_match_fn))

# Constructing PowerFlowData from modified system should result in data_modified
@test IS.compare_values(PowerFlowData(ACPowerFlow(), sys_modified), data_modified;
match_fn = powerflow_match_fn)

# The big one: update_system! with modified PowerFlowData should result in sys_modified
sys_modify_updated = deepcopy(sys_original)
PF.update_system!(sys_modify_updated, data_modified)
@test IS.compare_values(sys_modify_updated, sys_modified)
end
10 changes: 0 additions & 10 deletions test/test_psse_export.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
const SYSTEM_REIMPORT_COMPARISON_TOLERANCE = 1e-10
const POWERFLOW_COMPARISON_TOLERANCE = 1e-9

test_psse_export_dir = joinpath(TEST_FILES_DIR, "test_psse_exports") # at some point could move this to temp files
isdir(test_psse_export_dir) && rm(test_psse_export_dir; recursive = true)

Expand Down Expand Up @@ -231,13 +228,6 @@ function compare_systems_wrapper(sys1::System, sys2::System, sys2_metadata = not
return first_result && second_result
end

# TODO temporary hack, see https://github.com/NREL-Sienna/PowerFlows.jl/issues/39
function PowerSystems.get_reactive_power_limits(gen::RenewableNonDispatch)
gen_pf = get_power_factor(gen)
gen_q = get_max_active_power(gen) * sqrt((1 / gen_pf^2) - 1)
return (min = 0.0, max = gen_q)
end

function test_power_flow(sys1::System, sys2::System)
result1 = solve_powerflow(ACPowerFlow(), sys1)
result2 = solve_powerflow(ACPowerFlow(), sys2)
Expand Down
36 changes: 36 additions & 0 deletions test/test_utils/common.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const SYSTEM_REIMPORT_COMPARISON_TOLERANCE = 1e-10
const POWERFLOW_COMPARISON_TOLERANCE = 1e-9

powerflow_match_fn(
a::T,
b::T,
) where {T <: Union{AbstractFloat, AbstractArray{<:AbstractFloat}}} =
isapprox(a, b; atol = POWERFLOW_COMPARISON_TOLERANCE) || IS.isequivalent(a, b)
powerflow_match_fn(a, b) = IS.isequivalent(a, b)

# TODO temporary hack, see https://github.com/NREL-Sienna/PowerFlows.jl/issues/39
function PowerSystems.get_reactive_power_limits(gen::RenewableNonDispatch)
gen_pf = get_power_factor(gen)
gen_q = get_max_active_power(gen) * sqrt((1 / gen_pf^2) - 1)
return (min = 0.0, max = gen_q)
end

"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
ref_bus = get_component(ACBus, sys, "Arne") # bus number 113
@assert get_bustype(ref_bus) == ACBusTypes.REF
# NOTE: we are not testing the correctness of _power_redistribution_ref here, it is used on both sides of the test
PF._power_redistribution_ref(sys, 2.4375, 0.1875, ref_bus)

# For PV bus, active and voltage are fixed; update reactive and angle

# For PQ bus, active and reactive are fixed; update voltage and angle

end

"Make the same changes to the PowerFlowData that modify_rts_system! makes to the System"
function modify_rts_powerflow!(data::PowerFlowData)
data.bus_activepower_injection[data.bus_lookup[113]] -= 1.0
data.bus_reactivepower_injection[data.bus_lookup[113]] -= 1.0
end

0 comments on commit 9ea7e16

Please sign in to comment.