From fc8995eff1ba43270e6dbae1dea2f20c927afb38 Mon Sep 17 00:00:00 2001 From: Alinson S Xavier Date: Tue, 1 Jun 2021 12:48:34 -0500 Subject: [PATCH] Add KnuOstWat18 --- benchmark/benchmark.jl | 8 ++ benchmark/scripts/table.py | 7 +- src/UnitCommitment.jl | 4 +- src/model/formulations/CarArr06/pwlcosts.jl | 7 +- .../formulations/KnuOstWat18/pwlcosts.jl | 102 ++++++++++++++++++ src/model/formulations/KnuOstWat18/structs.jl | 12 +++ test/model/formulations_test.jl | 1 + 7 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 src/model/formulations/KnuOstWat18/pwlcosts.jl create mode 100644 src/model/formulations/KnuOstWat18/structs.jl diff --git a/benchmark/benchmark.jl b/benchmark/benchmark.jl index 31cb458..4f1f3f9 100644 --- a/benchmark/benchmark.jl +++ b/benchmark/benchmark.jl @@ -61,9 +61,17 @@ function main() formulations = Dict( "ArrCon00" => UnitCommitment.Formulation(ramping = UnitCommitment.ArrCon00()), + "CarArr06" => UnitCommitment.Formulation( + pwl_costs = UnitCommitment.CarArr06(), + ), "DamKucRajAta16" => UnitCommitment.Formulation( ramping = UnitCommitment.DamKucRajAta16(), ), + "Gar62" => + UnitCommitment.Formulation(pwl_costs = UnitCommitment.Gar62()), + "KnuOstWat18" => UnitCommitment.Formulation( + pwl_costs = UnitCommitment.KnuOstWat18(), + ), "MorLatRam13" => UnitCommitment.Formulation( ramping = UnitCommitment.MorLatRam13(), ), diff --git a/benchmark/scripts/table.py b/benchmark/scripts/table.py index 59b1cb1..a7c4a6d 100644 --- a/benchmark/scripts/table.py +++ b/benchmark/scripts/table.py @@ -197,9 +197,10 @@ def generate_chart(): table.loc[:, "Filename"] = f tables += [table] benchmark = pd.concat(tables, sort=True) - benchmark = benchmark.sort_values(by="Instance") - k = len(benchmark.groupby("Instance")) - plt.figure(figsize=(12, k)) + benchmark = benchmark.sort_values(by=["Group", "Instance"]) + k1 = len(benchmark.groupby("Instance")) + k2 = len(benchmark.groupby("Group")) + plt.figure(figsize=(12, 0.25 * k1 * k2)) sns.barplot( y="Instance", x="Total time (s)", diff --git a/src/UnitCommitment.jl b/src/UnitCommitment.jl index 3a7c529..ae53e5f 100644 --- a/src/UnitCommitment.jl +++ b/src/UnitCommitment.jl @@ -9,11 +9,12 @@ include("model/formulations/base/structs.jl") include("solution/structs.jl") include("model/formulations/ArrCon00/structs.jl") +include("model/formulations/CarArr06/structs.jl") include("model/formulations/DamKucRajAta16/structs.jl") include("model/formulations/Gar62/structs.jl") +include("model/formulations/KnuOstWat18/structs.jl") include("model/formulations/MorLatRam13/structs.jl") include("model/formulations/PanGua16/structs.jl") -include("model/formulations/CarArr06/structs.jl") include("solution/methods/XavQiuWanThi19/structs.jl") include("import/egret.jl") @@ -29,6 +30,7 @@ include("model/formulations/base/unit.jl") include("model/formulations/CarArr06/pwlcosts.jl") include("model/formulations/DamKucRajAta16/ramp.jl") include("model/formulations/Gar62/pwlcosts.jl") +include("model/formulations/KnuOstWat18/pwlcosts.jl") include("model/formulations/MorLatRam13/ramp.jl") include("model/formulations/PanGua16/ramp.jl") include("model/jumpext.jl") diff --git a/src/model/formulations/CarArr06/pwlcosts.jl b/src/model/formulations/CarArr06/pwlcosts.jl index de7d6c7..a235bce 100644 --- a/src/model/formulations/CarArr06/pwlcosts.jl +++ b/src/model/formulations/CarArr06/pwlcosts.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!( model::JuMP.Model, g::Unit, @@ -30,8 +34,7 @@ function _add_production_piecewise_linear_eqs!( # 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) + prod_above[gn, t] == sum(segprod[gn, t, k] for k in 1:K) ) # Objective function diff --git a/src/model/formulations/KnuOstWat18/pwlcosts.jl b/src/model/formulations/KnuOstWat18/pwlcosts.jl new file mode 100644 index 0000000..ceef659 --- /dev/null +++ b/src/model/formulations/KnuOstWat18/pwlcosts.jl @@ -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 diff --git a/src/model/formulations/KnuOstWat18/structs.jl b/src/model/formulations/KnuOstWat18/structs.jl new file mode 100644 index 0000000..6fd9a84 --- /dev/null +++ b/src/model/formulations/KnuOstWat18/structs.jl @@ -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 diff --git a/test/model/formulations_test.jl b/test/model/formulations_test.jl index 1649dc6..4c6ba81 100644 --- a/test/model/formulations_test.jl +++ b/test/model/formulations_test.jl @@ -17,4 +17,5 @@ end _test(UnitCommitment.Formulation(ramping = UnitCommitment.PanGua16())) _test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.Gar62())) _test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.CarArr06())) + _test(UnitCommitment.Formulation(pwl_costs = UnitCommitment.KnuOstWat18())) end