Add KnuOstWat18

bugfix/formulations
Alinson S. Xavier 4 years ago
parent f69d378d47
commit fc8995eff1

@ -61,9 +61,17 @@ function main()
formulations = Dict( formulations = Dict(
"ArrCon00" => "ArrCon00" =>
UnitCommitment.Formulation(ramping = UnitCommitment.ArrCon00()), UnitCommitment.Formulation(ramping = UnitCommitment.ArrCon00()),
"CarArr06" => UnitCommitment.Formulation(
pwl_costs = UnitCommitment.CarArr06(),
),
"DamKucRajAta16" => UnitCommitment.Formulation( "DamKucRajAta16" => UnitCommitment.Formulation(
ramping = UnitCommitment.DamKucRajAta16(), ramping = UnitCommitment.DamKucRajAta16(),
), ),
"Gar62" =>
UnitCommitment.Formulation(pwl_costs = UnitCommitment.Gar62()),
"KnuOstWat18" => UnitCommitment.Formulation(
pwl_costs = UnitCommitment.KnuOstWat18(),
),
"MorLatRam13" => UnitCommitment.Formulation( "MorLatRam13" => UnitCommitment.Formulation(
ramping = UnitCommitment.MorLatRam13(), ramping = UnitCommitment.MorLatRam13(),
), ),

@ -197,9 +197,10 @@ def generate_chart():
table.loc[:, "Filename"] = f table.loc[:, "Filename"] = f
tables += [table] tables += [table]
benchmark = pd.concat(tables, sort=True) benchmark = pd.concat(tables, sort=True)
benchmark = benchmark.sort_values(by="Instance") benchmark = benchmark.sort_values(by=["Group", "Instance"])
k = len(benchmark.groupby("Instance")) k1 = len(benchmark.groupby("Instance"))
plt.figure(figsize=(12, k)) k2 = len(benchmark.groupby("Group"))
plt.figure(figsize=(12, 0.25 * k1 * k2))
sns.barplot( sns.barplot(
y="Instance", y="Instance",
x="Total time (s)", x="Total time (s)",

@ -9,11 +9,12 @@ include("model/formulations/base/structs.jl")
include("solution/structs.jl") include("solution/structs.jl")
include("model/formulations/ArrCon00/structs.jl") include("model/formulations/ArrCon00/structs.jl")
include("model/formulations/CarArr06/structs.jl")
include("model/formulations/DamKucRajAta16/structs.jl") include("model/formulations/DamKucRajAta16/structs.jl")
include("model/formulations/Gar62/structs.jl") include("model/formulations/Gar62/structs.jl")
include("model/formulations/KnuOstWat18/structs.jl")
include("model/formulations/MorLatRam13/structs.jl") include("model/formulations/MorLatRam13/structs.jl")
include("model/formulations/PanGua16/structs.jl") include("model/formulations/PanGua16/structs.jl")
include("model/formulations/CarArr06/structs.jl")
include("solution/methods/XavQiuWanThi19/structs.jl") include("solution/methods/XavQiuWanThi19/structs.jl")
include("import/egret.jl") include("import/egret.jl")
@ -29,6 +30,7 @@ include("model/formulations/base/unit.jl")
include("model/formulations/CarArr06/pwlcosts.jl") include("model/formulations/CarArr06/pwlcosts.jl")
include("model/formulations/DamKucRajAta16/ramp.jl") include("model/formulations/DamKucRajAta16/ramp.jl")
include("model/formulations/Gar62/pwlcosts.jl") include("model/formulations/Gar62/pwlcosts.jl")
include("model/formulations/KnuOstWat18/pwlcosts.jl")
include("model/formulations/MorLatRam13/ramp.jl") include("model/formulations/MorLatRam13/ramp.jl")
include("model/formulations/PanGua16/ramp.jl") include("model/formulations/PanGua16/ramp.jl")
include("model/jumpext.jl") include("model/jumpext.jl")

@ -1,3 +1,7 @@
# 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_production_piecewise_linear_eqs!( function _add_production_piecewise_linear_eqs!(
model::JuMP.Model, model::JuMP.Model,
g::Unit, g::Unit,
@ -30,8 +34,7 @@ function _add_production_piecewise_linear_eqs!(
# Equation (43) in Kneuven et al. (2020) # Equation (43) in Kneuven et al. (2020)
eq_prod_above_def[gn, t] = @constraint( eq_prod_above_def[gn, t] = @constraint(
model, model,
prod_above[gn, t] == prod_above[gn, t] == sum(segprod[gn, t, k] for k in 1:K)
sum(segprod[gn, t, k] for k in 1:K)
) )
# Objective function # Objective function

@ -0,0 +1,102 @@
# 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_production_piecewise_linear_eqs!(
model::JuMP.Model,
g::Unit,
formulation::KnuOstWat18,
)::Nothing
eq_prod_above_def = _init(model, :eq_prod_above_def)
eq_segprod_limit_a = _init(model, :eq_segprod_limit_a)
eq_segprod_limit_b = _init(model, :eq_segprod_limit_b)
eq_segprod_limit_c = _init(model, :eq_segprod_limit_c)
prod_above = model[:prod_above]
segprod = model[:segprod]
is_on = model[:is_on]
switch_on = model[:switch_on]
switch_off = model[:switch_off]
gn = g.name
K = length(g.cost_segments)
T = model[:instance].time
for t in 1:T
for k in 1:K
# Pbar^{k-1)
Pbar0 =
g.min_power[t] +
(k > 1 ? sum(g.cost_segments[ell].mw[t] for ell in 1:k-1) : 0.0)
# Pbar^k
Pbar1 = g.cost_segments[k].mw[t] + Pbar0
Cv = 0.0
SU = g.startup_limit # startup rate
if Pbar1 <= SU
Cv = 0.0
elseif Pbar0 < SU # && Pbar1 > SU
Cv = Pbar1 - SU
else # Pbar0 >= SU
# this will imply that we cannot produce along this segment if
# switch_on = 1
Cv = g.cost_segments[k].mw[t]
end
Cw = 0.0
SD = g.shutdown_limit # shutdown rate
if Pbar1 <= SD
Cw = 0.0
elseif Pbar0 < SD # && Pbar1 > SD
Cw = Pbar1 - SD
else # Pbar0 >= SD
Cw = g.cost_segments[k].mw[t]
end
if g.min_uptime > 1
# Equation (46) in Kneuven et al. (2020)
eq_segprod_limit_a[gn, t, k] = @constraint(
model,
segprod[gn, t, k] <=
g.cost_segments[k].mw[t] * is_on[gn, t] -
Cv * switch_on[gn, t] -
(t < T ? Cw * switch_off[gn, t+1] : 0.0)
)
else
# Equation (47a)/(48a) in Kneuven et al. (2020)
eq_segprod_limit_b[gn, t, k] = @constraint(
model,
segprod[gn, t, k] <=
g.cost_segments[k].mw[t] * is_on[gn, t] -
Cv * switch_on[gn, t] -
(t < T ? max(0, Cv - Cw) * switch_off[gn, t+1] : 0.0)
)
# Equation (47b)/(48b) in Kneuven et al. (2020)
eq_segprod_limit_c[gn, t, k] = @constraint(
model,
segprod[gn, t, k] <=
g.cost_segments[k].mw[t] * is_on[gn, t] -
max(0, Cw - Cv) * switch_on[gn, t] -
(t < T ? Cw * switch_off[gn, t+1] : 0.0)
)
end
# Definition of production
# Equation (43) in Kneuven et al. (2020)
eq_prod_above_def[gn, t] = @constraint(
model,
prod_above[gn, t] == sum(segprod[gn, t, k] for k in 1:K)
)
# Objective function
# Equation (44) in Kneuven et al. (2020)
add_to_expression!(
model[:obj],
segprod[gn, t, k],
g.cost_segments[k].cost[t],
)
# Also add an explicit upper bound on segprod to make the solver's
# work a bit easier
set_upper_bound(segprod[gn, t, k], g.cost_segments[k].mw[t])
end
end
end

@ -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:
Knueven, B., Ostrowski, J., & Watson, J. P. (2018). Exploiting identical
generators in unit commitment. IEEE Transactions on Power Systems, 33(4),
4496-4507.
"""
struct KnuOstWat18 <: PiecewiseLinearCostsFormulation end

@ -17,4 +17,5 @@ end
_test(UnitCommitment.Formulation(ramping = UnitCommitment.PanGua16())) _test(UnitCommitment.Formulation(ramping = UnitCommitment.PanGua16()))
_test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.Gar62())) _test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.Gar62()))
_test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.CarArr06())) _test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.CarArr06()))
_test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.KnuOstWat18()))
end end

Loading…
Cancel
Save