From 6cab334485ed9df8712fd97da605a3592885925c Mon Sep 17 00:00:00 2001 From: GabrielKS <23368820+GabrielKS@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:45:07 -0600 Subject: [PATCH 1/6] Begin to accomodate PSY4 changes (simulation currently errors) --- src/get_data.jl | 3 +- test/test_data/results_data.jl | 54 ++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/get_data.jl b/src/get_data.jl index 2c0dc49..2da8a7e 100644 --- a/src/get_data.jl +++ b/src/get_data.jl @@ -419,8 +419,7 @@ function _get_loads(system::PSY.System, sys::PSY.System) end get_base_power(system::PSY.System) = PSY.get_base_power(system) -get_base_power(results::PSI.SimulationProblemResults) = IS.get_base_power(results) -get_base_power(results::PSI.ProblemResults) = results.base_power +get_base_power(results::IS.Results) = IS.get_base_power(results) function get_load_data( system::PSY.System; diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index d4c0245..b6dfb59 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -9,7 +9,7 @@ function add_re!(sys) PrimeMovers.WT, (min = 0.0, max = 0.0), 1.0, - TwoPartCost(0.220, 0.0), + RenewableGenerationCost(CostCurve(LinearCurve(0.220))), 100.0, ) add_component!(sys, re) @@ -31,9 +31,10 @@ function add_re!(sys) for g in get_components(HydroEnergyReservoir, sys) tpc = get_operation_cost(g) - smc = StorageManagementCost(; - variable = get_variable(tpc), - fixed = get_fixed(tpc), + smc = StorageCost(; + charge_variable_cost = PSY.get_variable(tpc), + discharge_variable_cost = PSY.get_variable(tpc), + fixed = PSY.get_fixed(tpc), start_up = 0.0, shut_down = 0.0, energy_shortage_cost = 10.0, @@ -42,21 +43,22 @@ function add_re!(sys) set_operation_cost!(g, smc) end - batt = GenericBattery( - "test_batt", - true, - get_component(ACBus, sys, "bus4"), - PrimeMovers.BA, - 0.0, - (min = 0.0, max = 1.0), - 1.0, - 0.0, - (min = 0.0, max = 1.0), - (min = 0.0, max = 1.0), - (in = 1.0, out = 1.0), - 0.0, - nothing, - 10.0, + batt = EnergyReservoirStorage(; + name = "test_batt", + available = true, + bus = get_component(ACBus, sys, "bus4"), + prime_mover_type = PrimeMovers.BA, + storage_technology_type = StorageTech.OTHER_CHEM, + initial_energy = 0.0, + state_of_charge_limits = (min = 0.0, max = 1.0), + rating = 1.0, + active_power = 0.0, + input_active_power_limits = (min = 0.0, max = 1.0), + output_active_power_limits = (min = 0.0, max = 1.0), + efficiency = (in = 1.0, out = 1.0), + reactive_power = 0.0, + reactive_power_limits = nothing, + base_power = 10.0, ) add_component!(sys, batt) end @@ -100,13 +102,17 @@ function _execute_simulation(base_path, sim_name) set_device_model!(template_hydro_st_uc, RenewableFix, FixedOutput) set_device_model!(template_hydro_st_uc, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_uc, HydroDispatch, FixedOutput) - set_device_model!(template_hydro_st_uc, GenericBattery, StorageDispatchWithReserves) + set_device_model!( + template_hydro_st_uc, + EnergyReservoirStorage, + StorageDispatchWithReserves, + ) set_device_model!( template_hydro_st_uc, HydroEnergyReservoir, HydroDispatchReservoirStorage, ) - set_service_model!(template_hydro_st_uc, VariableReserve{ReserveUp}, RangeReserve) + set_service_model!(template_hydro_st_uc, VariableReserve{ReserveUp}, RangeReserve) # TODO this is causing some sort of failure template_hydro_st_ed = ProblemTemplate( NetworkModel( @@ -120,7 +126,11 @@ function _execute_simulation(base_path, sim_name) set_device_model!(template_hydro_st_ed, RenewableFix, FixedOutput) set_device_model!(template_hydro_st_ed, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_ed, HydroDispatch, FixedOutput) - set_device_model!(template_hydro_st_ed, GenericBattery, StorageDispatchWithReserves) + set_device_model!( + template_hydro_st_ed, + EnergyReservoirStorage, + StorageDispatchWithReserves, + ) set_device_model!( template_hydro_st_ed, HydroEnergyReservoir, From e2ac3b471196cb73ad9559bdbb23655ed4198474 Mon Sep 17 00:00:00 2001 From: GabrielKS <23368820+GabrielKS@users.noreply.github.com> Date: Thu, 6 Jun 2024 13:27:31 -0600 Subject: [PATCH 2/6] Make test data simulation work with current PSI Co-authored-by: Jose Daniel Lara --- test/test_data/results_data.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index b6dfb59..74a9153 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -102,6 +102,8 @@ function _execute_simulation(base_path, sim_name) set_device_model!(template_hydro_st_uc, RenewableFix, FixedOutput) set_device_model!(template_hydro_st_uc, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_uc, HydroDispatch, FixedOutput) + # TODO uncomment when PSI is fixed + #= set_device_model!( template_hydro_st_uc, EnergyReservoirStorage, @@ -112,7 +114,8 @@ function _execute_simulation(base_path, sim_name) HydroEnergyReservoir, HydroDispatchReservoirStorage, ) - set_service_model!(template_hydro_st_uc, VariableReserve{ReserveUp}, RangeReserve) # TODO this is causing some sort of failure + =# + set_service_model!(template_hydro_st_uc, VariableReserve{ReserveUp}, RangeReserve) template_hydro_st_ed = ProblemTemplate( NetworkModel( @@ -126,6 +129,8 @@ function _execute_simulation(base_path, sim_name) set_device_model!(template_hydro_st_ed, RenewableFix, FixedOutput) set_device_model!(template_hydro_st_ed, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_ed, HydroDispatch, FixedOutput) + # TODO uncomment when PSI is fixed + #= set_device_model!( template_hydro_st_ed, EnergyReservoirStorage, @@ -136,7 +141,7 @@ function _execute_simulation(base_path, sim_name) HydroEnergyReservoir, HydroDispatchReservoirStorage, ) - + =# models = SimulationModels(; decision_models = [ DecisionModel( @@ -243,10 +248,9 @@ function run_test_prob() template_hydro_st_uc, c_sys5_hy_uc; optimizer = GLPK_optimizer, - horizon = 12, ) build!(prob; output_dir = mktempdir()) solve!(prob) - res = ProblemResults(prob) + res = OptimizationProblemResults(prob) return res end From 592aff79edf5e1131807026d51399d32e9f3eb0c Mon Sep 17 00:00:00 2001 From: GabrielKS <23368820+GabrielKS@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:27:15 -0600 Subject: [PATCH 3/6] Fix test answers given altered simulation --- test/test_result_sorting.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_result_sorting.jl b/test/test_result_sorting.jl index e63207d..2bcb5f3 100644 --- a/test/test_result_sorting.jl +++ b/test/test_result_sorting.jl @@ -3,7 +3,7 @@ problem_results = run_test_prob() @testset "test filter results" begin gen = PA.get_generation_data(results_uc; curtailment = false) - @test length(gen.data) == 7 + @test length(gen.data) == 4 # TODO will be 7 when storage and hydro are reenabled @test length(gen.time) == 48 gen = PA.get_generation_data( @@ -65,7 +65,7 @@ problem_results = run_test_prob() # TODO: make tests for subsetting data sub_gen = get_generation_data(results_uc; filter_func = x -> get_name(get_bus(x)) == "bus1") - @test length(sub_gen.data) == 8 + @test length(sub_gen.data) == 5 # TODO will be 8 when storage and hydro are reenabled end @testset "test curtailment calculations" begin @@ -94,10 +94,10 @@ end ) fuel = categorize_data(gen.data, cat) - @test length(fuel) == 8 + @test length(fuel) == 7 # TODO will be 8 when storage and hydro are reenabled fuel_agg = PA.combine_categories(fuel) - @test size(fuel_agg) == (48, 8) + @test size(fuel_agg) == (48, 7) # TODO will be (48, 8) when storage and hydro are reenabled end @testset "Test system data getters" begin From 7089648939e6ba6020e2e22b8a08c0efe3bd2dcf Mon Sep 17 00:00:00 2001 From: GabrielKS <23368820+GabrielKS@users.noreply.github.com> Date: Thu, 6 Jun 2024 17:39:32 -0600 Subject: [PATCH 4/6] Accommodate new time series interface in `get_load_data` --- src/get_data.jl | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/get_data.jl b/src/get_data.jl index 2da8a7e..dab9b66 100644 --- a/src/get_data.jl +++ b/src/get_data.jl @@ -440,30 +440,53 @@ function get_load_data( initial_time = get(kwargs, :initial_time, PSY.get_forecast_initial_timestamp(system)) parameters = Dict{Symbol, DataFrames.DataFrame}() PSY.set_units_base_system!(system, "SYSTEM_BASE") + resolution = nothing + len = nothing for agg in aggregation_components loads = _get_loads(system, agg) length(loads) == 0 && continue colname = aggregation == PSY.System ? "System" : PSY.get_name(agg) load_values = DataFrames.DataFrame() for load in loads + # TODO awaiting methods in PSY to make this simpler + keys = filter( + key -> + PSY.get_time_series_type(key) == PSY.Deterministic && + PSY.get_name(key) == "max_active_power", + PSY.get_time_series_keys(load), + ) + @assert length(keys) == 1 + my_resolution = first(keys).resolution + if isnothing(resolution) + resolution = my_resolution + len = (horizon isa Dates.Period) ? Int64(horizon / resolution) : horizon + else + (resolution != my_resolution) && + throw(error("Load time series have mismatched resolutions")) + end + f = PSY.get_time_series_values( # TODO: this isn't applying the scaling factors PSY.Deterministic, load, "max_active_power"; start_time = initial_time, - len = horizon, + len = len, ) load_values[:, PSY.get_name(load)] = f end parameters[Symbol(colname)] = load_values end - time_range = collect( - range( - initial_time; - step = PSY.get_time_series_resolution(system), - length = horizon, - ), - ) + time_range = if isnothing(len) + Dates.DateTime[] + else + collect( + range( + initial_time; + step = resolution, + length = len, + ), + ) + end return PowerData(parameters, time_range) end From 6c41314da20f349dbef45bade14066b1af69bd7d Mon Sep 17 00:00:00 2001 From: GabrielKS <23368820+GabrielKS@users.noreply.github.com> Date: Thu, 6 Jun 2024 18:03:16 -0600 Subject: [PATCH 5/6] Reenable storage --- test/test_data/results_data.jl | 4 ++-- test/test_result_sorting.jl | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index 74a9153..89613b8 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -103,12 +103,12 @@ function _execute_simulation(base_path, sim_name) set_device_model!(template_hydro_st_uc, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_uc, HydroDispatch, FixedOutput) # TODO uncomment when PSI is fixed - #= set_device_model!( template_hydro_st_uc, EnergyReservoirStorage, StorageDispatchWithReserves, ) + #= set_device_model!( template_hydro_st_uc, HydroEnergyReservoir, @@ -130,12 +130,12 @@ function _execute_simulation(base_path, sim_name) set_device_model!(template_hydro_st_ed, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_ed, HydroDispatch, FixedOutput) # TODO uncomment when PSI is fixed - #= set_device_model!( template_hydro_st_ed, EnergyReservoirStorage, StorageDispatchWithReserves, ) + #= set_device_model!( template_hydro_st_ed, HydroEnergyReservoir, diff --git a/test/test_result_sorting.jl b/test/test_result_sorting.jl index 2bcb5f3..199894c 100644 --- a/test/test_result_sorting.jl +++ b/test/test_result_sorting.jl @@ -3,7 +3,7 @@ problem_results = run_test_prob() @testset "test filter results" begin gen = PA.get_generation_data(results_uc; curtailment = false) - @test length(gen.data) == 4 # TODO will be 7 when storage and hydro are reenabled + @test length(gen.data) == 6 # TODO will be 7 when storage and hydro are reenabled @test length(gen.time) == 48 gen = PA.get_generation_data( @@ -65,7 +65,7 @@ problem_results = run_test_prob() # TODO: make tests for subsetting data sub_gen = get_generation_data(results_uc; filter_func = x -> get_name(get_bus(x)) == "bus1") - @test length(sub_gen.data) == 5 # TODO will be 8 when storage and hydro are reenabled + @test length(sub_gen.data) == 7 # TODO will be 8 when storage and hydro are reenabled end @testset "test curtailment calculations" begin @@ -94,10 +94,10 @@ end ) fuel = categorize_data(gen.data, cat) - @test length(fuel) == 7 # TODO will be 8 when storage and hydro are reenabled + @test length(fuel) == 8 fuel_agg = PA.combine_categories(fuel) - @test size(fuel_agg) == (48, 7) # TODO will be (48, 8) when storage and hydro are reenabled + @test size(fuel_agg) == (48, 8) end @testset "Test system data getters" begin From aa054840e5cc829d77f354de915e4adafbc55a12 Mon Sep 17 00:00:00 2001 From: GabrielKS <23368820+GabrielKS@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:16:31 -0600 Subject: [PATCH 6/6] Reinstate horizon limit for reduction in run time --- test/test_data/results_data.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index 89613b8..81d59bf 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -248,6 +248,7 @@ function run_test_prob() template_hydro_st_uc, c_sys5_hy_uc; optimizer = GLPK_optimizer, + horizon = Hour(12), ) build!(prob; output_dir = mktempdir()) solve!(prob)