parent
5e2cdb9e0c
commit
a3a71ff5a9
Binary file not shown.
@ -0,0 +1,152 @@
|
||||
# UnitCommitmentFL.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_flexiramp_vars!(model::JuMP.Model, g::Unit)::Nothing
|
||||
upflexiramp = _init(model, :upflexiramp)
|
||||
upflexiramp_shortfall = _init(model, :upflexiramp_shortfall)
|
||||
mfg=_init(model,:mfg)
|
||||
dwflexiramp = _init(model, :dwflexiramp)
|
||||
dwflexiramp_shortfall = _init(model, :dwflexiramp_shortfall)
|
||||
for t in 1:model[:instance].time
|
||||
# maximum feasible generation, \bar{g_{its}} in Wang & Hobbs (2016)
|
||||
mfg[g.name,t]=@variable(model, lower_bound = 0)
|
||||
if g.provides_flexiramp_reserves[t]
|
||||
upflexiramp[g.name, t] = @variable(model) # up-flexiramp, ur_{it} in Wang & Hobbs (2016)
|
||||
dwflexiramp[g.name, t] = @variable(model) # down-flexiramp, dr_{it} in Wang & Hobbs (2016)
|
||||
else
|
||||
upflexiramp[g.name, t] = 0.0
|
||||
dwflexiramp[g.name, t] = 0.0
|
||||
end
|
||||
upflexiramp_shortfall[t] =
|
||||
(model[:instance].flexiramp_shortfall_penalty[t] >= 0) ?
|
||||
@variable(model, lower_bound = 0) : 0.0
|
||||
dwflexiramp_shortfall[t] =
|
||||
(model[:instance].flexiramp_shortfall_penalty[t] >= 0) ?
|
||||
@variable(model, lower_bound = 0) : 0.0
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
function _add_ramp_eqs!(
|
||||
model::JuMP.Model,
|
||||
g::Unit,
|
||||
formulation_prod_vars::Gar1962.ProdVars,
|
||||
formulation_ramping::WanHob2016.Ramping,
|
||||
formulation_status_vars::Gar1962.StatusVars,
|
||||
)::Nothing
|
||||
is_initially_on = (g.initial_status > 0)
|
||||
SU = g.startup_limit
|
||||
SD = g.shutdown_limit
|
||||
RU = g.ramp_up_limit
|
||||
RD = g.ramp_down_limit
|
||||
gn = g.name
|
||||
minp=g.min_power
|
||||
maxp=g.max_power
|
||||
initial_power=g.initial_power
|
||||
|
||||
is_on = model[:is_on]
|
||||
prod_above = model[:prod_above]
|
||||
upflexiramp=model[:upflexiramp]
|
||||
dwflexiramp=model[:dwflexiramp]
|
||||
mfg=model[:mfg]
|
||||
|
||||
for t in 1:model[:instance].time
|
||||
|
||||
@constraint(model, prod_above[gn, t] + (is_on[gn,t]*minp[t])
|
||||
<=mfg[gn,t]) # Eq. (19) in Wang & Hobbs (2016)
|
||||
@constraint(model, mfg[gn,t]<= is_on[gn,t]* maxp[t]) # Eq. (22) in Wang & Hobbs (2016)
|
||||
if t!=model[:instance].time
|
||||
@constraint(model, minp[t] * (is_on[gn,t+1]+is_on[gn,t]-1) <=
|
||||
prod_above[gn, t] - dwflexiramp[gn,t] +(is_on[gn,t]*minp[t])
|
||||
) # first inequality of Eq. (20) in Wang & Hobbs (2016)
|
||||
@constraint(model, prod_above[gn, t] - dwflexiramp[gn,t] + (is_on[gn,t]*minp[t]) <=
|
||||
mfg[gn,t+1]
|
||||
+ (maxp[t] * (1-is_on[gn,t+1]))
|
||||
) # second inequality of Eq. (20) in Wang & Hobbs (2016)
|
||||
@constraint(model, minp[t] * (is_on[gn,t+1]+is_on[gn,t]-1) <=
|
||||
prod_above[gn, t] + upflexiramp[gn,t] + (is_on[gn,t]*minp[t])
|
||||
) # first inequality of Eq. (21) in Wang & Hobbs (2016)
|
||||
@constraint(model, prod_above[gn, t] + upflexiramp[gn,t] +(is_on[gn,t]*minp[t]) <=
|
||||
mfg[gn,t+1] + (maxp[t] * (1-is_on[gn,t+1]))
|
||||
) # second inequality of Eq. (21) in Wang & Hobbs (2016)
|
||||
if t!=1
|
||||
@constraint(model, mfg[gn,t]<=prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t])
|
||||
+ (RU * is_on[gn,t-1])
|
||||
+ (SU*(is_on[gn,t] - is_on[gn,t-1]))
|
||||
+ maxp[t] * (1-is_on[gn,t])
|
||||
) # Eq. (23) in Wang & Hobbs (2016)
|
||||
@constraint(model, (prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t]))
|
||||
- (prod_above[gn,t] + (is_on[gn,t]*minp[t]))
|
||||
<= RD * is_on[gn,t]
|
||||
+ SD * (is_on[gn,t-1] - is_on[gn,t])
|
||||
+ maxp[t] * (1-is_on[gn,t-1])
|
||||
) # Eq. (25) in Wang & Hobbs (2016)
|
||||
else
|
||||
@constraint(model, mfg[gn,t]<=initial_power
|
||||
+ (RU * is_initially_on)
|
||||
+ (SU*(is_on[gn,t] - is_initially_on))
|
||||
+ maxp[t] * (1-is_on[gn,t])
|
||||
) # Eq. (23) in Wang & Hobbs (2016) for the first time period
|
||||
@constraint(model, initial_power
|
||||
- (prod_above[gn,t] + (is_on[gn,t]*minp[t]))
|
||||
<= RD * is_on[gn,t]
|
||||
+ SD * (is_initially_on - is_on[gn,t])
|
||||
+ maxp[t] * (1-is_initially_on)
|
||||
) # Eq. (25) in Wang & Hobbs (2016) for the first time period
|
||||
end
|
||||
@constraint(model, mfg[gn,t]<=
|
||||
(SD*(is_on[gn,t] - is_on[gn,t+1]))
|
||||
+ (maxp[t] * is_on[gn,t+1])
|
||||
) # Eq. (24) in Wang & Hobbs (2016)
|
||||
@constraint(model, -RD * is_on[gn,t+1]
|
||||
-SD * (is_on[gn,t]-is_on[gn,t+1])
|
||||
-maxp[t] * (1-is_on[gn,t])
|
||||
<= upflexiramp[gn,t]
|
||||
) # first inequality of Eq. (26) in Wang & Hobbs (2016)
|
||||
@constraint(model, upflexiramp[gn,t] <=
|
||||
RU * is_on[gn,t]
|
||||
+ SU * (is_on[gn,t+1]-is_on[gn,t])
|
||||
+ maxp[t] * (1-is_on[gn,t+1])
|
||||
) # second inequality of Eq. (26) in Wang & Hobbs (2016)
|
||||
@constraint(model, -RU * is_on[gn,t]
|
||||
-SU * (is_on[gn,t+1]-is_on[gn,t])
|
||||
-maxp[t] * (1-is_on[gn,t+1])
|
||||
<= dwflexiramp[gn,t]
|
||||
) # first inequality of Eq. (27) in Wang & Hobbs (2016)
|
||||
@constraint(model, dwflexiramp[gn,t] <=
|
||||
RD * is_on[gn,t+1]
|
||||
+ SD * (is_on[gn,t]-is_on[gn,t+1])
|
||||
+ maxp[t] * (1-is_on[gn,t])
|
||||
) # second inequality of Eq. (27) in Wang & Hobbs (2016)
|
||||
@constraint(model, -maxp[t] * is_on[gn,t]
|
||||
+minp[t] * is_on[gn,t+1]
|
||||
<= upflexiramp[gn,t]
|
||||
) # first inequality of Eq. (28) in Wang & Hobbs (2016)
|
||||
@constraint(model, upflexiramp[gn,t] <=
|
||||
maxp[t] * is_on[gn,t+1]
|
||||
) # second inequality of Eq. (28) in Wang & Hobbs (2016)
|
||||
@constraint(model, -maxp[t] * is_on[gn,t+1]
|
||||
<= dwflexiramp[gn,t]
|
||||
) # first inequality of Eq. (29) in Wang & Hobbs (2016)
|
||||
@constraint(model, dwflexiramp[gn,t] <=
|
||||
(maxp[t] * is_on[gn,t])
|
||||
-(minp[t] * is_on[gn,t+1])
|
||||
) # second inequality of Eq. (29) in Wang & Hobbs (2016)
|
||||
else
|
||||
@constraint(model, mfg[gn,t]<=prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t])
|
||||
+ (RU * is_on[gn,t-1])
|
||||
+ (SU*(is_on[gn,t] - is_on[gn,t-1]))
|
||||
+ maxp[t] * (1-is_on[gn,t])
|
||||
) # Eq. (23) in Wang & Hobbs (2016) for the last time period
|
||||
@constraint(model, (prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t]))
|
||||
- (prod_above[gn,t] + (is_on[gn,t]*minp[t]))
|
||||
<= RD * is_on[gn,t]
|
||||
+ SD * (is_on[gn,t-1] - is_on[gn,t])
|
||||
+ maxp[t] * (1-is_on[gn,t-1])
|
||||
) # Eq. (25) in Wang & Hobbs (2016) for the last time period
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,18 @@
|
||||
# UnitCommitmentFL.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:
|
||||
B. Wang and B. F. Hobbs, "Real-Time Markets for Flexiramp: A Stochastic
|
||||
Unit Commitment-Based Analysis," in IEEE Transactions on Power Systems,
|
||||
vol. 31, no. 2, pp. 846-860, March 2016, doi: 10.1109/TPWRS.2015.2411268.
|
||||
"""
|
||||
module WanHob2016
|
||||
|
||||
import ..RampingFormulation
|
||||
|
||||
|
||||
struct Ramping <: RampingFormulation end
|
||||
|
||||
end
|
Loading…
Reference in new issue