Parse new reserves

feature/reserves
Alinson S. Xavier 4 years ago
parent 2bd68b49a5
commit ca0d250dfa

Binary file not shown.

@ -66,6 +66,7 @@ function _from_json(json; repair = true)
contingencies = Contingency[] contingencies = Contingency[]
lines = TransmissionLine[] lines = TransmissionLine[]
loads = PriceSensitiveLoad[] loads = PriceSensitiveLoad[]
reserves2 = Reserve[]
function scalar(x; default = nothing) function scalar(x; default = nothing)
x !== nothing || return default x !== nothing || return default
@ -86,6 +87,7 @@ function _from_json(json; repair = true)
name_to_bus = Dict{String,Bus}() name_to_bus = Dict{String,Bus}()
name_to_line = Dict{String,TransmissionLine}() name_to_line = Dict{String,TransmissionLine}()
name_to_unit = Dict{String,Unit}() name_to_unit = Dict{String,Unit}()
name_to_reserve = Dict{String,Reserve}()
function timeseries(x; default = nothing) function timeseries(x; default = nothing)
x !== nothing || return default x !== nothing || return default
@ -116,6 +118,19 @@ function _from_json(json; repair = true)
push!(buses, bus) push!(buses, bus)
end end
# Read reserves
if "Reserves2" in keys(json)
for (reserve_name, dict) in json["Reserves2"]
reserve = Reserve(
name = reserve_name,
type = lowercase(dict["Type"]),
amount = timeseries(dict["Amount (MW)"]),
)
name_to_reserve[reserve_name] = reserve
push!(reserves2, reserve)
end
end
# Read units # Read units
for (unit_name, dict) in json["Generators"] for (unit_name, dict) in json["Generators"]
bus = name_to_bus[dict["Bus"]] bus = name_to_bus[dict["Bus"]]
@ -153,6 +168,12 @@ function _from_json(json; repair = true)
) )
end end
# Read reserves
unit_reserves = Reserve[]
if "Reserve eligibility" in keys(dict)
unit_reserves = [name_to_reserve[n] for n in dict["Reserve eligibility"]]
end
# Read and validate initial conditions # Read and validate initial conditions
initial_power = scalar(dict["Initial power (MW)"], default = nothing) initial_power = scalar(dict["Initial power (MW)"], default = nothing)
initial_status = scalar(dict["Initial status (h)"], default = nothing) initial_status = scalar(dict["Initial status (h)"], default = nothing)
@ -191,6 +212,7 @@ function _from_json(json; repair = true)
default = [true for t in 1:T], default = [true for t in 1:T],
), ),
startup_categories, startup_categories,
unit_reserves,
) )
push!(bus.units, unit) push!(bus.units, unit)
name_to_unit[unit_name] = unit name_to_unit[unit_name] = unit
@ -276,6 +298,8 @@ function _from_json(json; repair = true)
price_sensitive_loads_by_name = Dict(ps.name => ps for ps in loads), price_sensitive_loads_by_name = Dict(ps.name => ps for ps in loads),
price_sensitive_loads = loads, price_sensitive_loads = loads,
reserves = reserves, reserves = reserves,
reserves2 = reserves2,
reserves_by_name = name_to_reserve,
shortfall_penalty = shortfall_penalty, shortfall_penalty = shortfall_penalty,
time = T, time = T,
units_by_name = Dict(g.name => g for g in units), units_by_name = Dict(g.name => g for g in units),

@ -20,6 +20,12 @@ mutable struct StartupCategory
cost::Float64 cost::Float64
end end
Base.@kwdef mutable struct Reserve
name::String
type::String
amount::Vector{Float64}
end
mutable struct Unit mutable struct Unit
name::String name::String
bus::Bus bus::Bus
@ -38,6 +44,7 @@ mutable struct Unit
initial_power::Union{Float64,Nothing} initial_power::Union{Float64,Nothing}
provides_spinning_reserves::Vector{Bool} provides_spinning_reserves::Vector{Bool}
startup_categories::Vector{StartupCategory} startup_categories::Vector{StartupCategory}
reserves::Vector{Reserve}
end end
mutable struct TransmissionLine mutable struct TransmissionLine
@ -80,6 +87,8 @@ Base.@kwdef mutable struct UnitCommitmentInstance
price_sensitive_loads_by_name::Dict{AbstractString,PriceSensitiveLoad} price_sensitive_loads_by_name::Dict{AbstractString,PriceSensitiveLoad}
price_sensitive_loads::Vector{PriceSensitiveLoad} price_sensitive_loads::Vector{PriceSensitiveLoad}
reserves::Reserves reserves::Reserves
reserves2::Vector{Reserve}
reserves_by_name::Dict{AbstractString,Reserve}
shortfall_penalty::Vector{Float64} shortfall_penalty::Vector{Float64}
time::Int time::Int
units_by_name::Dict{AbstractString,Unit} units_by_name::Dict{AbstractString,Unit}

@ -12,6 +12,7 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@test length(instance.units) == 6 @test length(instance.units) == 6
@test length(instance.contingencies) == 19 @test length(instance.contingencies) == 19
@test length(instance.price_sensitive_loads) == 1 @test length(instance.price_sensitive_loads) == 1
@test length(instance.reserves2) == 1
@test instance.time == 4 @test instance.time == 4
@test instance.lines[5].name == "l5" @test instance.lines[5].name == "l5"
@ -37,6 +38,11 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@test instance.buses[9].load == [35.36638, 33.25495, 31.67138, 31.14353] @test instance.buses[9].load == [35.36638, 33.25495, 31.67138, 31.14353]
@test instance.buses_by_name["b9"].name == "b9" @test instance.buses_by_name["b9"].name == "b9"
@test instance.reserves2[1].name == "r1"
@test instance.reserves2[1].type == "spinning"
@test instance.reserves2[1].amount == [100.0, 100.0, 100.0, 100.0]
@test instance.reserves_by_name["r1"].name == "r1"
unit = instance.units[1] unit = instance.units[1]
@test unit.name == "g1" @test unit.name == "g1"
@test unit.bus.name == "b1" @test unit.bus.name == "b1"
@ -64,11 +70,13 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@test unit.startup_categories[1].cost == 1000.0 @test unit.startup_categories[1].cost == 1000.0
@test unit.startup_categories[2].cost == 1500.0 @test unit.startup_categories[2].cost == 1500.0
@test unit.startup_categories[3].cost == 2000.0 @test unit.startup_categories[3].cost == 2000.0
@test length(unit.reserves) == 0
@test instance.units_by_name["g1"].name == "g1" @test instance.units_by_name["g1"].name == "g1"
unit = instance.units[2] unit = instance.units[2]
@test unit.name == "g2" @test unit.name == "g2"
@test unit.must_run == [false for t in 1:4] @test unit.must_run == [false for t in 1:4]
@test length(unit.reserves) == 1
unit = instance.units[3] unit = instance.units[3]
@test unit.name == "g3" @test unit.name == "g3"
@ -90,6 +98,7 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@test unit.cost_segments[2].cost[t] 38.04 @test unit.cost_segments[2].cost[t] 38.04
@test unit.cost_segments[3].cost[t] 44.77853 @test unit.cost_segments[3].cost[t] 44.77853
end end
@test length(unit.reserves) == 1
@test instance.reserves.spinning == zeros(4) @test instance.reserves.spinning == zeros(4)

Loading…
Cancel
Save