added commitment status to thermal

pull/28/head
Jun He 2 years ago
parent b71a1c3d5f
commit baf529a15d

@ -90,6 +90,7 @@ This section describes all generators in the system, including thermal units, re
| `Initial power (MW)` | Amount of power the generator at time step `-1`, immediately before the planning horizon starts. | Required | N | `Initial power (MW)` | Amount of power the generator at time step `-1`, immediately before the planning horizon starts. | Required | N
| `Must run?` | If `true`, the generator should be committed, even if that is not economical (Boolean). | `false` | Y | `Must run?` | If `true`, the generator should be committed, even if that is not economical (Boolean). | `false` | Y
| `Reserve eligibility` | List of reserve products this generator is eligibe to provide. By default, the generator is not eligible to provide any reserves. | `[]` | N | `Reserve eligibility` | List of reserve products this generator is eligibe to provide. By default, the generator is not eligible to provide any reserves. | `[]` | N
| `Commitment status` | List of commitment status over the time horizon. At time `t`, if `true`, the generator must be commited at that time period; if `false`, the generator must not be commited at that time period. If `null` at time `t`, the generator's commitment status is then decided by the model. By default, the status is a list of `null` values. | `[null]` | Y
#### Profiled Units #### Profiled Units
@ -151,7 +152,8 @@ Note that this curve also specifies the production limits. Specifically, the fir
"Production cost curve ($)": [0.0, 0.0], "Production cost curve ($)": [0.0, 0.0],
"Initial status (h)": -100, "Initial status (h)": -100,
"Initial power (MW)": 0, "Initial power (MW)": 0,
"Reserve eligibility": ["r1", "r2"] "Reserve eligibility": ["r1", "r2"],
"Commitment status": [true, false, null, true]
}, },
"gen3": { "gen3": {
"Bus": "b6", "Bus": "b6",

@ -282,6 +282,12 @@ function _from_json(json; repair = true)::UnitCommitmentScenario
initial_status *= time_multiplier initial_status *= time_multiplier
end end
# Read commitment status
commitment_status = scalar(
dict["Commitment status"],
default = Vector{Union{Bool,Nothing}}(nothing, T),
)
unit = ThermalUnit( unit = ThermalUnit(
unit_name, unit_name,
bus, bus,
@ -302,6 +308,7 @@ function _from_json(json; repair = true)::UnitCommitmentScenario
initial_power, initial_power,
startup_categories, startup_categories,
unit_reserves, unit_reserves,
commitment_status,
) )
push!(bus.thermal_units, unit) push!(bus.thermal_units, unit)
for r in unit_reserves for r in unit_reserves

@ -47,6 +47,7 @@ mutable struct ThermalUnit
initial_power::Union{Float64,Nothing} initial_power::Union{Float64,Nothing}
startup_categories::Vector{StartupCategory} startup_categories::Vector{StartupCategory}
reserves::Vector{Reserve} reserves::Vector{Reserve}
commitment_status::Vector{Union{Bool,Nothing}}
end end
mutable struct TransmissionLine mutable struct TransmissionLine

@ -61,6 +61,7 @@ function _add_unit_dispatch!(
sc, sc,
) )
_add_startup_shutdown_limit_eqs!(model, g, sc) _add_startup_shutdown_limit_eqs!(model, g, sc)
_add_commitment_status_eqs!(model, g, sc)
return return
end end
@ -270,6 +271,26 @@ function _add_min_uptime_downtime_eqs!(
end end
end end
function _add_commitment_status_eqs!(
model::JuMP.Model,
g::ThermalUnit,
sc::UnitCommitmentScenario,
)::Nothing
is_on = model[:is_on]
T = model[:instance].time
eq_commitment_status = _init(model, :eq_commitment_status)
for t in 1:T
# Fix commitment status
if g.commitment_status[t] !== nothing
eq_commitment_status[sc.name, g.name, t] = @constraint(
model,
is_on[g.name, t] == (g.commitment_status[t] ? 1.0 : 0.0)
)
end
end
return
end
function _add_net_injection_eqs!( function _add_net_injection_eqs!(
model::JuMP.Model, model::JuMP.Model,
g::ThermalUnit, g::ThermalUnit,

@ -153,3 +153,14 @@ end
@test second_pu.capacity == [120.0 for t in 1:4] @test second_pu.capacity == [120.0 for t in 1:4]
@test sc.profiled_units_by_name["g8"].name == "g8" @test sc.profiled_units_by_name["g8"].name == "g8"
end end
@testset "read_benchmark commitmemt-status" begin
instance = UnitCommitment.read("$FIXTURES/case14-fixed-status.json.gz")
sc = instance.scenarios[1]
@test sc.thermal_units[1].commitment_status == [nothing for t in 1:4]
@test sc.thermal_units[2].commitment_status == [true for t in 1:4]
@test sc.thermal_units[4].commitment_status == [false for t in 1:4]
@test sc.thermal_units[6].commitment_status ==
[false, nothing, true, nothing]
end

Loading…
Cancel
Save