mirror of
https://github.com/ANL-CEEESA/UnitCommitment.jl.git
synced 2025-12-06 08:18:51 -06:00
Add KnuOstWat18
This commit is contained in:
@@ -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
|
||||||
|
|||||||
102
src/model/formulations/KnuOstWat18/pwlcosts.jl
Normal file
102
src/model/formulations/KnuOstWat18/pwlcosts.jl
Normal file
@@ -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
|
||||||
12
src/model/formulations/KnuOstWat18/structs.jl
Normal file
12
src/model/formulations/KnuOstWat18/structs.jl
Normal file
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user