parent
483c793d49
commit
bf6d19343e
@ -0,0 +1,12 @@
|
|||||||
|
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Formulation described in:
|
||||||
|
|
||||||
|
Arroyo, J. M., & Conejo, A. J. (2000). Optimal response of a thermal unit
|
||||||
|
to an electricity spot market. IEEE Transactions on power systems, 15(3),
|
||||||
|
1098-1104.
|
||||||
|
"""
|
||||||
|
mutable struct _ArrCon00 <: _RampingFormulation end
|
@ -0,0 +1,92 @@
|
|||||||
|
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
function _add_ramp_eqs!(
|
||||||
|
model::JuMP.Model,
|
||||||
|
g::Unit,
|
||||||
|
formulation::_ArrCon00,
|
||||||
|
)::Nothing
|
||||||
|
# TODO: Move upper case constants to model[:instance]
|
||||||
|
RESERVES_WHEN_START_UP = true
|
||||||
|
RESERVES_WHEN_RAMP_UP = true
|
||||||
|
RESERVES_WHEN_RAMP_DOWN = true
|
||||||
|
RESERVES_WHEN_SHUT_DOWN = true
|
||||||
|
gn = g.name
|
||||||
|
RU = g.ramp_up_limit
|
||||||
|
RD = g.ramp_down_limit
|
||||||
|
SU = g.startup_limit
|
||||||
|
SD = g.shutdown_limit
|
||||||
|
is_on = model[:is_on]
|
||||||
|
prod_above = model[:prod_above]
|
||||||
|
reserve = model[:reserve]
|
||||||
|
switch_off = model[:switch_off]
|
||||||
|
switch_on = model[:switch_on]
|
||||||
|
eq_ramp_down = _init(model, :eq_ramp_down)
|
||||||
|
eq_ramp_up = _init(model, :eq_ramp_up)
|
||||||
|
is_initially_on = (g.initial_status > 0)
|
||||||
|
|
||||||
|
for t in 1:model[:instance].time
|
||||||
|
# Ramp up limit
|
||||||
|
if t == 1
|
||||||
|
if is_initially_on
|
||||||
|
# min power is _not_ multiplied by is_on because if !is_on, then ramp up is irrelevant
|
||||||
|
eq_ramp_up[gn, t] = @constraint(
|
||||||
|
mip,
|
||||||
|
g.min_power[t] +
|
||||||
|
prod_above[gn, t] +
|
||||||
|
(RESERVES_WHEN_RAMP_UP ? reserve[gn, t] : 0.0) <=
|
||||||
|
g.initial_power + RU
|
||||||
|
)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
max_prod_this_period =
|
||||||
|
g.min_power[t] * is_on[gn, t] +
|
||||||
|
prod_above[gn, t] +
|
||||||
|
(
|
||||||
|
RESERVES_WHEN_START_UP || RESERVES_WHEN_RAMP_UP ?
|
||||||
|
reserve[gn, t] : 0.0
|
||||||
|
)
|
||||||
|
min_prod_last_period =
|
||||||
|
g.min_power[t-1] * is_on[gn, t-1] + prod_above[gn, t-1]
|
||||||
|
|
||||||
|
# Equation (24) in Kneuven et al. (2020)
|
||||||
|
eq_ramp_up[gn, t] = @constraint(
|
||||||
|
mip,
|
||||||
|
max_prod_this_period - min_prod_last_period <=
|
||||||
|
RU * is_on[gn, t-1] + SU * switch_on[gn, t]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ramp down limit
|
||||||
|
if t == 1
|
||||||
|
if is_initially_on
|
||||||
|
# TODO If RD < SD, or more specifically if
|
||||||
|
# min_power + RD < initial_power < SD
|
||||||
|
# then the generator should be able to shut down at time t = 1,
|
||||||
|
# but the constraint below will force the unit to produce power
|
||||||
|
eq_ramp_down[gn, t] = @constraint(
|
||||||
|
mip,
|
||||||
|
g.initial_power - (g.min_power[t] + prod_above[gn, t]) <= RD
|
||||||
|
)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
max_prod_last_period =
|
||||||
|
g.min_power[t-1] * is_on[gn, t-1] +
|
||||||
|
prod_above[gn, t-1] +
|
||||||
|
(
|
||||||
|
RESERVES_WHEN_SHUT_DOWN || RESERVES_WHEN_RAMP_DOWN ?
|
||||||
|
reserve[gn, t-1] : 0.0
|
||||||
|
)
|
||||||
|
min_prod_this_period =
|
||||||
|
g.min_power[t] * is_on[gn, t] + prod_above[gn, t]
|
||||||
|
|
||||||
|
# Equation (25) in Kneuven et al. (2020)
|
||||||
|
eq_ramp_down[gn, t] = @constraint(
|
||||||
|
mip,
|
||||||
|
max_prod_last_period - min_prod_this_period <=
|
||||||
|
RD * is_on[gn, t] + SD * switch_off[gn, t]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,57 @@
|
|||||||
|
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
abstract type _RampingFormulation end
|
||||||
|
abstract type _TransmissionFormulation end
|
||||||
|
|
||||||
|
struct _GeneratorFormulation
|
||||||
|
ramping::_RampingFormulation
|
||||||
|
|
||||||
|
function _GeneratorFormulation(
|
||||||
|
ramping::_RampingFormulation = _DamKucRajAta16(),
|
||||||
|
)
|
||||||
|
return new(ramping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
mutable struct _ShiftFactorsFormulation <: _TransmissionFormulation
|
||||||
|
isf_cutoff::Float64
|
||||||
|
lodf_cutoff::Float64
|
||||||
|
precomputed_isf::Union{Nothing,Matrix{Float64}}
|
||||||
|
precomputed_lodf::Union{Nothing,Matrix{Float64}}
|
||||||
|
end
|
||||||
|
|
||||||
|
Transmission formulation based on Injection Shift Factors (ISF) and Line
|
||||||
|
Outage Distribution Factors (LODF). Constraints are enforced in a lazy way.
|
||||||
|
|
||||||
|
Arguments
|
||||||
|
---------
|
||||||
|
- `precomputed_isf::Union{Matrix{Float64},Nothing} = nothing`:
|
||||||
|
the injection shift factors matrix. If not provided, it will be computed.
|
||||||
|
- `precomputed_lodf::Union{Matrix{Float64},Nothing} = nothing`:
|
||||||
|
the line outage distribution factors matrix. If not provided, it will be
|
||||||
|
computed.
|
||||||
|
- `isf_cutoff::Float64 = 0.005`:
|
||||||
|
the cutoff that should be applied to the ISF matrix. Entries with magnitude
|
||||||
|
smaller than this value will be set to zero.
|
||||||
|
- `lodf_cutoff::Float64 = 0.001`:
|
||||||
|
the cutoff that should be applied to the LODF matrix. Entries with magnitude
|
||||||
|
smaller than this value will be set to zero.
|
||||||
|
"""
|
||||||
|
mutable struct _ShiftFactorsFormulation <: _TransmissionFormulation
|
||||||
|
isf_cutoff::Float64
|
||||||
|
lodf_cutoff::Float64
|
||||||
|
precomputed_isf::Union{Nothing,Matrix{Float64}}
|
||||||
|
precomputed_lodf::Union{Nothing,Matrix{Float64}}
|
||||||
|
|
||||||
|
function _ShiftFactorsFormulation(;
|
||||||
|
isf_cutoff = 0.005,
|
||||||
|
lodf_cutoff = 0.001,
|
||||||
|
precomputed_isf = nothing,
|
||||||
|
precomputed_lodf = nothing,
|
||||||
|
)
|
||||||
|
return new(isf_cutoff, lodf_cutoff, precomputed_isf, precomputed_lodf)
|
||||||
|
end
|
||||||
|
end
|
@ -1,5 +0,0 @@
|
|||||||
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
|
|
||||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
|
||||||
|
|
||||||
abstract type Formulation end
|
|
Loading…
Reference in new issue