From ad4efb9f6200c0e1db9ae5605a3c92cfe7dd2668 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 12 Dec 2024 20:32:27 -0700 Subject: [PATCH 1/5] update toml file --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index beeabe1..209670e 100644 --- a/Project.toml +++ b/Project.toml @@ -26,7 +26,7 @@ DataFrames = "1" DataStructures = "0.18" InfrastructureSystems = "2" Plots = "1" -PowerAnalytics = "^0.7" +PowerAnalytics = "^0.8" PowerSystems = "4" Reexport = "1" Requires = "1" From 3b1fa56af9b4d4d18f9efc9515bad1ca3ca2267d Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Fri, 13 Dec 2024 16:38:40 -0700 Subject: [PATCH 2/5] fix tests --- test/Project.toml | 2 +- test/runtests.jl | 2 +- test/test_data/results_data.jl | 80 +++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/test/Project.toml b/test/Project.toml index 2aeb23c..7b7a730 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -4,7 +4,7 @@ Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6" +HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" HydroPowerSimulations = "fc1677e0-6ad7-4515-bf3a-bd6bf20a0b1b" InfrastructureSystems = "2cd47ed4-ca9b-11e9-27f2-ab636a7671f1" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" diff --git a/test/runtests.jl b/test/runtests.jl index faa514c..e193d73 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -12,7 +12,7 @@ using PowerAnalytics using PlotlyJS using PowerSimulations using StorageSystemsSimulations -using GLPK +using HiGHS using Weave using TimeSeries using HydroPowerSimulations diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index 24820f7..1b5e4fc 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -30,33 +30,37 @@ function add_re!(sys) copy_time_series!(fx, get_component(PowerLoad, sys, "bus2")) for g in get_components(HydroEnergyReservoir, sys) - tpc = get_operation_cost(g) - smc = StorageManagementCost(; - variable = get_variable(tpc), - fixed = get_fixed(tpc), - start_up = 0.0, - shut_down = 0.0, - energy_shortage_cost = 10.0, - energy_surplus_cost = 10.0, + smc = StorageCost(; + charge_variable_cost = CostCurve(LinearCurve(0.1)), + discharge_variable_cost = CostCurve(LinearCurve(0.2)), ) set_operation_cost!(g, smc) end - batt = GenericBattery( - "test_batt", - true, - get_component(Bus, 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(Bus, sys, "bus4"), + prime_mover_type = PrimeMovers.BA, #::PrimeMovers: Prime mover technology according to EIA 923. Options are listed here + storage_technology_type = StorageTech.OTHER_CHEM, #StorageTech.OTHER_CHEM =::StorageTech: Storage Technology Complementary to EIA 923. Options are listed here + storage_capacity = 2.0, #::Float64: Maximum storage capacity (can be in units of, e.g., MWh for batteries or liters for hydrogen), validation range: (0, nothing) + storage_level_limits = (min = 0.0, max = 1.0), #::MinMax: Minimum and maximum allowable storage levels [0, 1], which can be used to model derates or other restrictions, such as state-of-charge restrictions on battery cycling, validation range: (0, 1) + initial_storage_capacity_level = 0.7, #::Float64: Initial storage capacity level as a ratio [0, 1.0] of storage_capacity, validation range: (0, 1) + rating = 1.0, #::Float64: Maximum output power rating of the unit (MVA)************ + active_power = 0.1, #Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used + input_active_power_limits = (min = 0.0, max = 1.0), #::MinMax: Minimum and maximum limits on the input active power (i.e., charging), validation range: (0, nothing) + output_active_power_limits = (min = 0.0, max = 1.0), #::MinMax: Minimum and maximum limits on the output active power (i.e., discharging), validation range: (0, nothing) + efficiency = (in = 0.9, out = 0.9), #(CSolar)-efficiency::NamedTuple{(:in, :out), Tuple{Float64, Float64}}: Average efficiency [0, 1] in (charging/filling) and out (discharging/consuming) of the storage system, validation range: (0, 1) + reactive_power = 0.0, + reactive_power_limits = (min = -1.0, max = 1.0), #::Union{Nothing, MinMax}: Minimum and maximum reactive power limits. Set to Nothing if not applicable + base_power = 10.0, #::Float64: Base power of the unit (MVA) for per unitization, validation range: (0, nothing) + operation_cost = StorageCost(; + charge_variable_cost = CostCurve(LinearCurve(0.1)), + discharge_variable_cost = CostCurve(LinearCurve(0.2)), + ), + conversion_factor = 1, + storage_target = 0.0, #::Float64: (default: 0.0) Storage target at the end of simulation as ratio of storage capacity + cycle_limits = 5000, #::Int: (default: 1e4) Storage Maximum number of cycles per year ) add_component!(sys, batt) end @@ -93,8 +97,8 @@ function run_test_sim(result_dir::String) to_json(c_sys5_hy_ed, joinpath(sim_path, "..", "c_sys5_hy_ed.json"); force = true) mkpath(result_dir) - GLPK_optimizer = - optimizer_with_attributes(GLPK.Optimizer, "msg_lev" => GLPK.GLP_MSG_OFF) + HiGHS_optimizer = + optimizer_with_attributes(HiGHS.Optimizer) template_hydro_st_uc = template_unit_commitment() set_device_model!(template_hydro_st_uc, HydroDispatch, FixedOutput) @@ -103,7 +107,11 @@ function run_test_sim(result_dir::String) HydroEnergyReservoir, HydroDispatchReservoirStorage, ) - set_device_model!(template_hydro_st_uc, GenericBattery, StorageDispatchWithReserves) + set_device_model!( + template_hydro_st_uc, + EnergyReservoirStorage, + StorageDispatchWithReserves, + ) template_hydro_st_ed = template_economic_dispatch(; network = CopperPlatePowerModel, @@ -116,21 +124,25 @@ function run_test_sim(result_dir::String) HydroEnergyReservoir, HydroDispatchReservoirStorage, ) - set_device_model!(template_hydro_st_ed, GenericBattery, StorageDispatchWithReserves) + set_device_model!( + template_hydro_st_ed, + EnergyReservoirStorage, + StorageDispatchWithReserves, + ) template_hydro_st_ed.services = Dict() #remove ed services models = SimulationModels(; decision_models = [ DecisionModel( template_hydro_st_uc, c_sys5_hy_uc; - optimizer = GLPK_optimizer, + optimizer = HiGHS_optimizer, name = "UC", system_to_file = false, ), DecisionModel( template_hydro_st_ed, c_sys5_hy_ed; - optimizer = GLPK_optimizer, + optimizer = HiGHS_optimizer, name = "ED", system_to_file = false, ), @@ -173,8 +185,8 @@ end function run_test_prob() c_sys5_hy_uc = PSB.build_system(PSB.PSISystems, "5_bus_hydro_uc_sys") add_re!(c_sys5_hy_uc) - GLPK_optimizer = - optimizer_with_attributes(GLPK.Optimizer, "msg_lev" => GLPK.GLP_MSG_OFF) + HiGHS_optimizer = + optimizer_with_attributes(HiGHS.Optimizer) template_hydro_st_uc = template_unit_commitment() set_device_model!(template_hydro_st_uc, HydroDispatch, FixedOutput) @@ -187,11 +199,11 @@ function run_test_prob() prob = DecisionModel( template_hydro_st_uc, c_sys5_hy_uc; - optimizer = GLPK_optimizer, - horizon = 12, + optimizer = HiGHS_optimizer, + horizon = Hour(12), ) build!(prob; output_dir = mktempdir()) solve!(prob) - res = ProblemResults(prob) + res = OptimizationProblemResults(prob) return res end From 690d3063ec24fce26a447f99f74ab4c3d016a715 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Fri, 13 Dec 2024 17:26:21 -0700 Subject: [PATCH 3/5] fix simulation data --- test/test_data/results_data.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index 1b5e4fc..b0cd2c9 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -33,6 +33,8 @@ function add_re!(sys) smc = StorageCost(; charge_variable_cost = CostCurve(LinearCurve(0.1)), discharge_variable_cost = CostCurve(LinearCurve(0.2)), + energy_shortage_cost = 10.0, + energy_surplus_cost = 10.0, ) set_operation_cost!(g, smc) end @@ -53,7 +55,7 @@ function add_re!(sys) efficiency = (in = 0.9, out = 0.9), #(CSolar)-efficiency::NamedTuple{(:in, :out), Tuple{Float64, Float64}}: Average efficiency [0, 1] in (charging/filling) and out (discharging/consuming) of the storage system, validation range: (0, 1) reactive_power = 0.0, reactive_power_limits = (min = -1.0, max = 1.0), #::Union{Nothing, MinMax}: Minimum and maximum reactive power limits. Set to Nothing if not applicable - base_power = 10.0, #::Float64: Base power of the unit (MVA) for per unitization, validation range: (0, nothing) + base_power = 15.0, #::Float64: Base power of the unit (MVA) for per unitization, validation range: (0, nothing) operation_cost = StorageCost(; charge_variable_cost = CostCurve(LinearCurve(0.1)), discharge_variable_cost = CostCurve(LinearCurve(0.2)), @@ -138,6 +140,7 @@ function run_test_sim(result_dir::String) optimizer = HiGHS_optimizer, name = "UC", system_to_file = false, + calculate_conflict = true ), DecisionModel( template_hydro_st_ed, @@ -145,6 +148,7 @@ function run_test_sim(result_dir::String) optimizer = HiGHS_optimizer, name = "ED", system_to_file = false, + calculate_conflict = true ), ], ) From ddfd79b2a824d60ce818548da55c4620a418f3f1 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 17 Dec 2024 14:59:48 -0700 Subject: [PATCH 4/5] formatter --- test/test_data/results_data.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index b0cd2c9..441ef3e 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -140,7 +140,7 @@ function run_test_sim(result_dir::String) optimizer = HiGHS_optimizer, name = "UC", system_to_file = false, - calculate_conflict = true + calculate_conflict = true, ), DecisionModel( template_hydro_st_ed, @@ -148,7 +148,7 @@ function run_test_sim(result_dir::String) optimizer = HiGHS_optimizer, name = "ED", system_to_file = false, - calculate_conflict = true + calculate_conflict = true, ), ], ) From 497683b17135d039870803a5b7f2c7cbf609f8f9 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 17 Dec 2024 15:57:56 -0700 Subject: [PATCH 5/5] remove comments --- test/test_data/results_data.jl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index 441ef3e..1a02214 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -43,26 +43,26 @@ function add_re!(sys) name = "test_batt", available = true, bus = get_component(Bus, sys, "bus4"), - prime_mover_type = PrimeMovers.BA, #::PrimeMovers: Prime mover technology according to EIA 923. Options are listed here - storage_technology_type = StorageTech.OTHER_CHEM, #StorageTech.OTHER_CHEM =::StorageTech: Storage Technology Complementary to EIA 923. Options are listed here - storage_capacity = 2.0, #::Float64: Maximum storage capacity (can be in units of, e.g., MWh for batteries or liters for hydrogen), validation range: (0, nothing) - storage_level_limits = (min = 0.0, max = 1.0), #::MinMax: Minimum and maximum allowable storage levels [0, 1], which can be used to model derates or other restrictions, such as state-of-charge restrictions on battery cycling, validation range: (0, 1) - initial_storage_capacity_level = 0.7, #::Float64: Initial storage capacity level as a ratio [0, 1.0] of storage_capacity, validation range: (0, 1) - rating = 1.0, #::Float64: Maximum output power rating of the unit (MVA)************ - active_power = 0.1, #Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used - input_active_power_limits = (min = 0.0, max = 1.0), #::MinMax: Minimum and maximum limits on the input active power (i.e., charging), validation range: (0, nothing) - output_active_power_limits = (min = 0.0, max = 1.0), #::MinMax: Minimum and maximum limits on the output active power (i.e., discharging), validation range: (0, nothing) - efficiency = (in = 0.9, out = 0.9), #(CSolar)-efficiency::NamedTuple{(:in, :out), Tuple{Float64, Float64}}: Average efficiency [0, 1] in (charging/filling) and out (discharging/consuming) of the storage system, validation range: (0, 1) + prime_mover_type = PrimeMovers.BA, + storage_technology_type = StorageTech.OTHER_CHEM, + storage_capacity = 2.0, + storage_level_limits = (min = 0.0, max = 1.0), + initial_storage_capacity_level = 0.7, + rating = 1.0, + active_power = 0.1, + input_active_power_limits = (min = 0.0, max = 1.0), + output_active_power_limits = (min = 0.0, max = 1.0), + efficiency = (in = 0.9, out = 0.9), reactive_power = 0.0, - reactive_power_limits = (min = -1.0, max = 1.0), #::Union{Nothing, MinMax}: Minimum and maximum reactive power limits. Set to Nothing if not applicable - base_power = 15.0, #::Float64: Base power of the unit (MVA) for per unitization, validation range: (0, nothing) + reactive_power_limits = (min = -1.0, max = 1.0), + base_power = 15.0, operation_cost = StorageCost(; charge_variable_cost = CostCurve(LinearCurve(0.1)), discharge_variable_cost = CostCurve(LinearCurve(0.2)), ), conversion_factor = 1, - storage_target = 0.0, #::Float64: (default: 0.0) Storage target at the end of simulation as ratio of storage capacity - cycle_limits = 5000, #::Int: (default: 1e4) Storage Maximum number of cycles per year + storage_target = 0.0, + cycle_limits = 5000, ) add_component!(sys, batt) end