Skip to content

Commit

Permalink
Merge pull request #23 from NREL-Sienna/psy4
Browse files Browse the repository at this point in the history
Update PowerAnalytics for PSY4 compatibility
  • Loading branch information
GabrielKS authored Jul 9, 2024
2 parents eca7764 + 931298c commit 5898474
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 41 deletions.
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
Dates = "1"
DataFrames = "1"
DataStructures = "0.18"
InfrastructureSystems = "1"
InfrastructureSystems = "2"
InteractiveUtils = "1"
PowerSimulations = "^0.27.1"
PowerSystems = "3"
TimeSeries = "0.23"
PowerSimulations = "^0.28"
PowerSystems = "4"
TimeSeries = "0.24"
YAML = "0.4"
julia = "1.6"
42 changes: 32 additions & 10 deletions src/get_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -441,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
Expand Down
78 changes: 51 additions & 27 deletions test/test_data/results_data.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# Will be superseded by https://github.com/NREL-Sienna/PowerSystems.jl/issues/1143
function linear_fuel_to_linear_cost(fc::FuelCurve{LinearCurve})
fuel_cost = get_fuel_cost(fc)
!(fuel_cost isa Float64) && throw(ArgumentError("fuel_cost must be a scalar"))
old_vc = get_value_curve(fc)
new_vc = LinearCurve(
get_proportional_term(old_vc) * fuel_cost,
get_constant_term(old_vc) * fuel_cost,
)
return CostCurve(new_vc, get_power_units(fc), get_vom_cost(fc))
end

function add_re!(sys)
re = RenewableDispatch(
"WindBusA",
Expand All @@ -9,13 +21,13 @@ 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)
copy_time_series!(re, get_component(PowerLoad, sys, "bus2"))

fx = RenewableFix(
fx = RenewableNonDispatch(
"RoofTopSolar",
true,
get_component(ACBus, sys, "bus5"),
Expand All @@ -31,9 +43,12 @@ 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),
cc = get_variable(tpc)
(cc isa FuelCurve) && (cc = linear_fuel_to_linear_cost(cc))
smc = StorageCost(;
charge_variable_cost = cc,
discharge_variable_cost = cc,
fixed = PSY.get_fixed(tpc),
start_up = 0.0,
shut_down = 0.0,
energy_shortage_cost = 10.0,
Expand All @@ -42,21 +57,23 @@ 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,
storage_capacity = 1.0,
storage_level_limits = (min = 0.0, max = 1.0),
initial_storage_capacity_level = 0.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
Expand Down Expand Up @@ -97,10 +114,14 @@ function _execute_simulation(base_path, sim_name)
ProblemTemplate(NetworkModel(CopperPlatePowerModel; use_slacks = false))
set_device_model!(template_hydro_st_uc, ThermalStandard, ThermalBasicUnitCommitment)
set_device_model!(template_hydro_st_uc, PowerLoad, StaticPowerLoad)
set_device_model!(template_hydro_st_uc, RenewableFix, FixedOutput)
set_device_model!(template_hydro_st_uc, RenewableNonDispatch, 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,
Expand All @@ -117,16 +138,19 @@ function _execute_simulation(base_path, sim_name)
)
set_device_model!(template_hydro_st_ed, ThermalStandard, ThermalBasicDispatch)
set_device_model!(template_hydro_st_ed, PowerLoad, StaticPowerLoad)
set_device_model!(template_hydro_st_ed, RenewableFix, FixedOutput)
set_device_model!(template_hydro_st_ed, RenewableNonDispatch, 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,
HydroDispatchReservoirStorage,
)

models = SimulationModels(;
decision_models = [
DecisionModel(
Expand Down Expand Up @@ -233,10 +257,10 @@ function run_test_prob()
template_hydro_st_uc,
c_sys5_hy_uc;
optimizer = GLPK_optimizer,
horizon = 12,
horizon = Hour(12),
)
build!(prob; output_dir = mktempdir())
solve!(prob)
res = ProblemResults(prob)
res = OptimizationProblemResults(prob)
return res
end

0 comments on commit 5898474

Please sign in to comment.