|
|
@ -5,12 +5,12 @@
|
|
|
|
function _add_flexiramp_vars!(model::JuMP.Model, g::Unit)::Nothing
|
|
|
|
function _add_flexiramp_vars!(model::JuMP.Model, g::Unit)::Nothing
|
|
|
|
upflexiramp = _init(model, :upflexiramp)
|
|
|
|
upflexiramp = _init(model, :upflexiramp)
|
|
|
|
upflexiramp_shortfall = _init(model, :upflexiramp_shortfall)
|
|
|
|
upflexiramp_shortfall = _init(model, :upflexiramp_shortfall)
|
|
|
|
mfg=_init(model,:mfg)
|
|
|
|
mfg = _init(model, :mfg)
|
|
|
|
dwflexiramp = _init(model, :dwflexiramp)
|
|
|
|
dwflexiramp = _init(model, :dwflexiramp)
|
|
|
|
dwflexiramp_shortfall = _init(model, :dwflexiramp_shortfall)
|
|
|
|
dwflexiramp_shortfall = _init(model, :dwflexiramp_shortfall)
|
|
|
|
for t in 1:model[:instance].time
|
|
|
|
for t in 1:model[:instance].time
|
|
|
|
# maximum feasible generation, \bar{g_{its}} in Wang & Hobbs (2016)
|
|
|
|
# maximum feasible generation, \bar{g_{its}} in Wang & Hobbs (2016)
|
|
|
|
mfg[g.name,t]=@variable(model, lower_bound = 0)
|
|
|
|
mfg[g.name, t] = @variable(model, lower_bound = 0)
|
|
|
|
if g.provides_flexiramp_reserves[t]
|
|
|
|
if g.provides_flexiramp_reserves[t]
|
|
|
|
upflexiramp[g.name, t] = @variable(model) # up-flexiramp, ur_{it} in Wang & Hobbs (2016)
|
|
|
|
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)
|
|
|
|
dwflexiramp[g.name, t] = @variable(model) # down-flexiramp, dr_{it} in Wang & Hobbs (2016)
|
|
|
@ -28,8 +28,6 @@ function _add_flexiramp_vars!(model::JuMP.Model, g::Unit)::Nothing
|
|
|
|
return
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function _add_ramp_eqs!(
|
|
|
|
function _add_ramp_eqs!(
|
|
|
|
model::JuMP.Model,
|
|
|
|
model::JuMP.Model,
|
|
|
|
g::Unit,
|
|
|
|
g::Unit,
|
|
|
@ -43,109 +41,144 @@ function _add_ramp_eqs!(
|
|
|
|
RU = g.ramp_up_limit
|
|
|
|
RU = g.ramp_up_limit
|
|
|
|
RD = g.ramp_down_limit
|
|
|
|
RD = g.ramp_down_limit
|
|
|
|
gn = g.name
|
|
|
|
gn = g.name
|
|
|
|
minp=g.min_power
|
|
|
|
minp = g.min_power
|
|
|
|
maxp=g.max_power
|
|
|
|
maxp = g.max_power
|
|
|
|
initial_power=g.initial_power
|
|
|
|
initial_power = g.initial_power
|
|
|
|
|
|
|
|
|
|
|
|
is_on = model[:is_on]
|
|
|
|
is_on = model[:is_on]
|
|
|
|
prod_above = model[:prod_above]
|
|
|
|
prod_above = model[:prod_above]
|
|
|
|
upflexiramp=model[:upflexiramp]
|
|
|
|
upflexiramp = model[:upflexiramp]
|
|
|
|
dwflexiramp=model[:dwflexiramp]
|
|
|
|
dwflexiramp = model[:dwflexiramp]
|
|
|
|
mfg=model[:mfg]
|
|
|
|
mfg = model[:mfg]
|
|
|
|
|
|
|
|
|
|
|
|
for t in 1:model[:instance].time
|
|
|
|
for t in 1:model[:instance].time
|
|
|
|
|
|
|
|
@constraint(
|
|
|
|
@constraint(model, prod_above[gn, t] + (is_on[gn,t]*minp[t])
|
|
|
|
model,
|
|
|
|
<=mfg[gn,t]) # Eq. (19) in Wang & Hobbs (2016)
|
|
|
|
prod_above[gn, t] + (is_on[gn, t] * minp[t]) <= mfg[gn, t]
|
|
|
|
@constraint(model, mfg[gn,t]<= is_on[gn,t]* maxp[t]) # Eq. (22) in Wang & Hobbs (2016)
|
|
|
|
) # Eq. (19) in Wang & Hobbs (2016)
|
|
|
|
if t!=model[:instance].time
|
|
|
|
@constraint(model, mfg[gn, t] <= is_on[gn, t] * maxp[t]) # Eq. (22) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, minp[t] * (is_on[gn,t+1]+is_on[gn,t]-1) <=
|
|
|
|
if t != model[:instance].time
|
|
|
|
prod_above[gn, t] - dwflexiramp[gn,t] +(is_on[gn,t]*minp[t])
|
|
|
|
@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)
|
|
|
|
) # first inequality of Eq. (20) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, prod_above[gn, t] - dwflexiramp[gn,t] + (is_on[gn,t]*minp[t]) <=
|
|
|
|
@constraint(
|
|
|
|
mfg[gn,t+1]
|
|
|
|
model,
|
|
|
|
+ (maxp[t] * (1-is_on[gn,t+1]))
|
|
|
|
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)
|
|
|
|
) # second inequality of Eq. (20) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, minp[t] * (is_on[gn,t+1]+is_on[gn,t]-1) <=
|
|
|
|
@constraint(
|
|
|
|
prod_above[gn, t] + upflexiramp[gn,t] + (is_on[gn,t]*minp[t])
|
|
|
|
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)
|
|
|
|
) # first inequality of Eq. (21) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, prod_above[gn, t] + upflexiramp[gn,t] +(is_on[gn,t]*minp[t]) <=
|
|
|
|
@constraint(
|
|
|
|
mfg[gn,t+1] + (maxp[t] * (1-is_on[gn,t+1]))
|
|
|
|
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)
|
|
|
|
) # second inequality of Eq. (21) in Wang & Hobbs (2016)
|
|
|
|
if t!=1
|
|
|
|
if t != 1
|
|
|
|
@constraint(model, mfg[gn,t]<=prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t])
|
|
|
|
@constraint(
|
|
|
|
+ (RU * is_on[gn,t-1])
|
|
|
|
model,
|
|
|
|
+ (SU*(is_on[gn,t] - is_on[gn,t-1]))
|
|
|
|
mfg[gn, t] <=
|
|
|
|
+ maxp[t] * (1-is_on[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)
|
|
|
|
) # Eq. (23) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, (prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t]))
|
|
|
|
@constraint(
|
|
|
|
- (prod_above[gn,t] + (is_on[gn,t]*minp[t]))
|
|
|
|
model,
|
|
|
|
<= RD * is_on[gn,t]
|
|
|
|
(prod_above[gn, t-1] + (is_on[gn, t-1] * minp[t])) -
|
|
|
|
+ SD * (is_on[gn,t-1] - is_on[gn,t])
|
|
|
|
(prod_above[gn, t] + (is_on[gn, t] * minp[t])) <=
|
|
|
|
+ maxp[t] * (1-is_on[gn,t-1])
|
|
|
|
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)
|
|
|
|
) # Eq. (25) in Wang & Hobbs (2016)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
@constraint(model, mfg[gn,t]<=initial_power
|
|
|
|
@constraint(
|
|
|
|
+ (RU * is_initially_on)
|
|
|
|
model,
|
|
|
|
+ (SU*(is_on[gn,t] - is_initially_on))
|
|
|
|
mfg[gn, t] <=
|
|
|
|
+ maxp[t] * (1-is_on[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
|
|
|
|
) # Eq. (23) in Wang & Hobbs (2016) for the first time period
|
|
|
|
@constraint(model, initial_power
|
|
|
|
@constraint(
|
|
|
|
- (prod_above[gn,t] + (is_on[gn,t]*minp[t]))
|
|
|
|
model,
|
|
|
|
<= RD * is_on[gn,t]
|
|
|
|
initial_power -
|
|
|
|
+ SD * (is_initially_on - is_on[gn,t])
|
|
|
|
(prod_above[gn, t] + (is_on[gn, t] * minp[t])) <=
|
|
|
|
+ maxp[t] * (1-is_initially_on)
|
|
|
|
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
|
|
|
|
) # Eq. (25) in Wang & Hobbs (2016) for the first time period
|
|
|
|
end
|
|
|
|
end
|
|
|
|
@constraint(model, mfg[gn,t]<=
|
|
|
|
@constraint(
|
|
|
|
(SD*(is_on[gn,t] - is_on[gn,t+1]))
|
|
|
|
model,
|
|
|
|
+ (maxp[t] * is_on[gn,t+1])
|
|
|
|
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)
|
|
|
|
) # Eq. (24) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, -RD * is_on[gn,t+1]
|
|
|
|
@constraint(
|
|
|
|
-SD * (is_on[gn,t]-is_on[gn,t+1])
|
|
|
|
model,
|
|
|
|
-maxp[t] * (1-is_on[gn,t])
|
|
|
|
-RD * is_on[gn, t+1] - SD * (is_on[gn, t] - is_on[gn, t+1]) -
|
|
|
|
<= upflexiramp[gn,t]
|
|
|
|
maxp[t] * (1 - is_on[gn, t]) <= upflexiramp[gn, t]
|
|
|
|
) # first inequality of Eq. (26) in Wang & Hobbs (2016)
|
|
|
|
) # first inequality of Eq. (26) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, upflexiramp[gn,t] <=
|
|
|
|
@constraint(
|
|
|
|
RU * is_on[gn,t]
|
|
|
|
model,
|
|
|
|
+ SU * (is_on[gn,t+1]-is_on[gn,t])
|
|
|
|
upflexiramp[gn, t] <=
|
|
|
|
+ maxp[t] * (1-is_on[gn,t+1])
|
|
|
|
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)
|
|
|
|
) # second inequality of Eq. (26) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, -RU * is_on[gn,t]
|
|
|
|
@constraint(
|
|
|
|
-SU * (is_on[gn,t+1]-is_on[gn,t])
|
|
|
|
model,
|
|
|
|
-maxp[t] * (1-is_on[gn,t+1])
|
|
|
|
-RU * is_on[gn, t] - SU * (is_on[gn, t+1] - is_on[gn, t]) -
|
|
|
|
<= dwflexiramp[gn,t]
|
|
|
|
maxp[t] * (1 - is_on[gn, t+1]) <= dwflexiramp[gn, t]
|
|
|
|
) # first inequality of Eq. (27) in Wang & Hobbs (2016)
|
|
|
|
) # first inequality of Eq. (27) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, dwflexiramp[gn,t] <=
|
|
|
|
@constraint(
|
|
|
|
RD * is_on[gn,t+1]
|
|
|
|
model,
|
|
|
|
+ SD * (is_on[gn,t]-is_on[gn,t+1])
|
|
|
|
dwflexiramp[gn, t] <=
|
|
|
|
+ maxp[t] * (1-is_on[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)
|
|
|
|
) # second inequality of Eq. (27) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, -maxp[t] * is_on[gn,t]
|
|
|
|
@constraint(
|
|
|
|
+minp[t] * is_on[gn,t+1]
|
|
|
|
model,
|
|
|
|
<= upflexiramp[gn,t]
|
|
|
|
-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)
|
|
|
|
) # first inequality of Eq. (28) in Wang & Hobbs (2016)
|
|
|
|
@constraint(model, upflexiramp[gn,t] <=
|
|
|
|
@constraint(model, upflexiramp[gn, t] <= maxp[t] * is_on[gn, t+1]) # second inequality of Eq. (28) in Wang & Hobbs (2016)
|
|
|
|
maxp[t] * is_on[gn,t+1]
|
|
|
|
@constraint(model, -maxp[t] * is_on[gn, t+1] <= dwflexiramp[gn, t]) # first inequality of Eq. (29) in Wang & Hobbs (2016)
|
|
|
|
) # second inequality of Eq. (28) in Wang & Hobbs (2016)
|
|
|
|
@constraint(
|
|
|
|
@constraint(model, -maxp[t] * is_on[gn,t+1]
|
|
|
|
model,
|
|
|
|
<= dwflexiramp[gn,t]
|
|
|
|
dwflexiramp[gn, t] <=
|
|
|
|
) # first inequality of Eq. (29) in Wang & Hobbs (2016)
|
|
|
|
(maxp[t] * is_on[gn, t]) - (minp[t] * is_on[gn, t+1])
|
|
|
|
@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)
|
|
|
|
) # second inequality of Eq. (29) in Wang & Hobbs (2016)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
@constraint(model, mfg[gn,t]<=prod_above[gn,t-1] + (is_on[gn,t-1]*minp[t])
|
|
|
|
@constraint(
|
|
|
|
+ (RU * is_on[gn,t-1])
|
|
|
|
model,
|
|
|
|
+ (SU*(is_on[gn,t] - is_on[gn,t-1]))
|
|
|
|
mfg[gn, t] <=
|
|
|
|
+ maxp[t] * (1-is_on[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
|
|
|
|
) # 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]))
|
|
|
|
@constraint(
|
|
|
|
- (prod_above[gn,t] + (is_on[gn,t]*minp[t]))
|
|
|
|
model,
|
|
|
|
<= RD * is_on[gn,t]
|
|
|
|
(prod_above[gn, t-1] + (is_on[gn, t-1] * minp[t])) -
|
|
|
|
+ SD * (is_on[gn,t-1] - is_on[gn,t])
|
|
|
|
(prod_above[gn, t] + (is_on[gn, t] * minp[t])) <=
|
|
|
|
+ maxp[t] * (1-is_on[gn,t-1])
|
|
|
|
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
|
|
|
|
) # Eq. (25) in Wang & Hobbs (2016) for the last time period
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|