parent
f59914f265
commit
53052ec895
@ -1,167 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
|
||||||
|
|
||||||
@testset "read_benchmark" begin
|
|
||||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
|
||||||
|
|
||||||
@test repr(instance) == (
|
|
||||||
"UnitCommitmentInstance(1 scenarios, 6 thermal units, 0 profiled units, 14 buses, " *
|
|
||||||
"20 lines, 19 contingencies, 1 price sensitive loads, 4 time steps)"
|
|
||||||
)
|
|
||||||
|
|
||||||
@test length(instance.scenarios) == 1
|
|
||||||
sc = instance.scenarios[1]
|
|
||||||
@test length(sc.lines) == 20
|
|
||||||
@test length(sc.buses) == 14
|
|
||||||
@test length(sc.thermal_units) == 6
|
|
||||||
@test length(sc.contingencies) == 19
|
|
||||||
@test length(sc.price_sensitive_loads) == 1
|
|
||||||
@test instance.time == 4
|
|
||||||
@test sc.time_step == 60
|
|
||||||
|
|
||||||
@test sc.lines[5].name == "l5"
|
|
||||||
@test sc.lines[5].source.name == "b2"
|
|
||||||
@test sc.lines[5].target.name == "b5"
|
|
||||||
@test sc.lines[5].reactance ≈ 0.17388
|
|
||||||
@test sc.lines[5].susceptance ≈ 10.037550333
|
|
||||||
@test sc.lines[5].normal_flow_limit == [1e8 for t in 1:4]
|
|
||||||
@test sc.lines[5].emergency_flow_limit == [1e8 for t in 1:4]
|
|
||||||
@test sc.lines[5].flow_limit_penalty == [5e3 for t in 1:4]
|
|
||||||
@test sc.lines_by_name["l5"].name == "l5"
|
|
||||||
|
|
||||||
@test sc.lines[1].name == "l1"
|
|
||||||
@test sc.lines[1].source.name == "b1"
|
|
||||||
@test sc.lines[1].target.name == "b2"
|
|
||||||
@test sc.lines[1].reactance ≈ 0.059170
|
|
||||||
@test sc.lines[1].susceptance ≈ 29.496860773945
|
|
||||||
@test sc.lines[1].normal_flow_limit == [300.0 for t in 1:4]
|
|
||||||
@test sc.lines[1].emergency_flow_limit == [400.0 for t in 1:4]
|
|
||||||
@test sc.lines[1].flow_limit_penalty == [1e3 for t in 1:4]
|
|
||||||
|
|
||||||
@test sc.buses[9].name == "b9"
|
|
||||||
@test sc.buses[9].load == [35.36638, 33.25495, 31.67138, 31.14353]
|
|
||||||
@test sc.buses_by_name["b9"].name == "b9"
|
|
||||||
|
|
||||||
@test sc.reserves[1].name == "r1"
|
|
||||||
@test sc.reserves[1].type == "spinning"
|
|
||||||
@test sc.reserves[1].amount == [100.0, 100.0, 100.0, 100.0]
|
|
||||||
@test sc.reserves_by_name["r1"].name == "r1"
|
|
||||||
|
|
||||||
unit = sc.thermal_units[1]
|
|
||||||
@test unit.name == "g1"
|
|
||||||
@test unit.bus.name == "b1"
|
|
||||||
@test unit.ramp_up_limit == 1e6
|
|
||||||
@test unit.ramp_down_limit == 1e6
|
|
||||||
@test unit.startup_limit == 1e6
|
|
||||||
@test unit.shutdown_limit == 1e6
|
|
||||||
@test unit.must_run == [false for t in 1:4]
|
|
||||||
@test unit.min_power_cost == [1400.0 for t in 1:4]
|
|
||||||
@test unit.min_uptime == 1
|
|
||||||
@test unit.min_downtime == 1
|
|
||||||
for t in 1:1
|
|
||||||
@test unit.cost_segments[1].mw[t] == 10.0
|
|
||||||
@test unit.cost_segments[2].mw[t] == 20.0
|
|
||||||
@test unit.cost_segments[3].mw[t] == 5.0
|
|
||||||
@test unit.cost_segments[1].cost[t] ≈ 20.0
|
|
||||||
@test unit.cost_segments[2].cost[t] ≈ 30.0
|
|
||||||
@test unit.cost_segments[3].cost[t] ≈ 40.0
|
|
||||||
end
|
|
||||||
@test length(unit.startup_categories) == 3
|
|
||||||
@test unit.startup_categories[1].delay == 1
|
|
||||||
@test unit.startup_categories[2].delay == 2
|
|
||||||
@test unit.startup_categories[3].delay == 3
|
|
||||||
@test unit.startup_categories[1].cost == 1000.0
|
|
||||||
@test unit.startup_categories[2].cost == 1500.0
|
|
||||||
@test unit.startup_categories[3].cost == 2000.0
|
|
||||||
@test length(unit.reserves) == 0
|
|
||||||
@test sc.thermal_units_by_name["g1"].name == "g1"
|
|
||||||
|
|
||||||
unit = sc.thermal_units[2]
|
|
||||||
@test unit.name == "g2"
|
|
||||||
@test unit.must_run == [false for t in 1:4]
|
|
||||||
@test length(unit.reserves) == 1
|
|
||||||
|
|
||||||
unit = sc.thermal_units[3]
|
|
||||||
@test unit.name == "g3"
|
|
||||||
@test unit.bus.name == "b3"
|
|
||||||
@test unit.ramp_up_limit == 70.0
|
|
||||||
@test unit.ramp_down_limit == 70.0
|
|
||||||
@test unit.startup_limit == 70.0
|
|
||||||
@test unit.shutdown_limit == 70.0
|
|
||||||
@test unit.must_run == [true for t in 1:4]
|
|
||||||
@test unit.min_power_cost == [0.0 for t in 1:4]
|
|
||||||
@test unit.min_uptime == 1
|
|
||||||
@test unit.min_downtime == 1
|
|
||||||
for t in 1:4
|
|
||||||
@test unit.cost_segments[1].mw[t] ≈ 33
|
|
||||||
@test unit.cost_segments[2].mw[t] ≈ 33
|
|
||||||
@test unit.cost_segments[3].mw[t] ≈ 34
|
|
||||||
@test unit.cost_segments[1].cost[t] ≈ 33.75
|
|
||||||
@test unit.cost_segments[2].cost[t] ≈ 38.04
|
|
||||||
@test unit.cost_segments[3].cost[t] ≈ 44.77853
|
|
||||||
end
|
|
||||||
@test length(unit.reserves) == 1
|
|
||||||
@test unit.reserves[1].name == "r1"
|
|
||||||
|
|
||||||
@test sc.contingencies[1].lines == [sc.lines[1]]
|
|
||||||
@test sc.contingencies[1].thermal_units == []
|
|
||||||
@test sc.contingencies[1].name == "c1"
|
|
||||||
@test sc.contingencies_by_name["c1"].name == "c1"
|
|
||||||
|
|
||||||
load = sc.price_sensitive_loads[1]
|
|
||||||
@test load.name == "ps1"
|
|
||||||
@test load.bus.name == "b3"
|
|
||||||
@test load.revenue == [100.0 for t in 1:4]
|
|
||||||
@test load.demand == [50.0 for t in 1:4]
|
|
||||||
@test sc.price_sensitive_loads_by_name["ps1"].name == "ps1"
|
|
||||||
end
|
|
||||||
|
|
||||||
@testset "read_benchmark sub-hourly" begin
|
|
||||||
instance = UnitCommitment.read("$FIXTURES/case14-sub-hourly.json.gz")
|
|
||||||
@test instance.time == 4
|
|
||||||
unit = instance.scenarios[1].thermal_units[1]
|
|
||||||
@test unit.name == "g1"
|
|
||||||
@test unit.min_uptime == 2
|
|
||||||
@test unit.min_downtime == 2
|
|
||||||
@test length(unit.startup_categories) == 3
|
|
||||||
@test unit.startup_categories[1].delay == 2
|
|
||||||
@test unit.startup_categories[2].delay == 4
|
|
||||||
@test unit.startup_categories[3].delay == 6
|
|
||||||
@test unit.initial_status == -200
|
|
||||||
end
|
|
||||||
|
|
||||||
@testset "read_benchmark profiled-units" begin
|
|
||||||
instance = UnitCommitment.read("$FIXTURES/case14-profiled.json.gz")
|
|
||||||
sc = instance.scenarios[1]
|
|
||||||
@test length(sc.profiled_units) == 2
|
|
||||||
|
|
||||||
first_pu = sc.profiled_units[1]
|
|
||||||
@test first_pu.name == "g7"
|
|
||||||
@test first_pu.bus.name == "b4"
|
|
||||||
@test first_pu.cost == [100.0 for t in 1:4]
|
|
||||||
@test first_pu.min_power == [60.0 for t in 1:4]
|
|
||||||
@test first_pu.max_power == [100.0 for t in 1:4]
|
|
||||||
@test sc.profiled_units_by_name["g7"].name == "g7"
|
|
||||||
|
|
||||||
second_pu = sc.profiled_units[2]
|
|
||||||
@test second_pu.name == "g8"
|
|
||||||
@test second_pu.bus.name == "b5"
|
|
||||||
@test second_pu.cost == [50.0 for t in 1:4]
|
|
||||||
@test second_pu.min_power == [0.0 for t in 1:4]
|
|
||||||
@test second_pu.max_power == [120.0 for t in 1:4]
|
|
||||||
@test sc.profiled_units_by_name["g8"].name == "g8"
|
|
||||||
end
|
|
||||||
|
|
||||||
@testset "read_benchmark commitmemt-status" begin
|
|
||||||
instance = UnitCommitment.read("$FIXTURES/case14-fixed-status.json.gz")
|
|
||||||
sc = instance.scenarios[1]
|
|
||||||
|
|
||||||
@test sc.thermal_units[1].commitment_status == [nothing for t in 1:4]
|
|
||||||
@test sc.thermal_units[2].commitment_status == [true for t in 1:4]
|
|
||||||
@test sc.thermal_units[4].commitment_status == [false for t in 1:4]
|
|
||||||
@test sc.thermal_units[6].commitment_status ==
|
|
||||||
[false, nothing, true, nothing]
|
|
||||||
end
|
|
@ -1,53 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
using Test
|
|
||||||
using UnitCommitment
|
|
||||||
|
|
||||||
push!(Base.LOAD_PATH, @__DIR__)
|
|
||||||
UnitCommitment._setup_logger(level = Base.CoreLogging.Error)
|
|
||||||
|
|
||||||
FIXTURES = "$(@__DIR__)/fixtures"
|
|
||||||
|
|
||||||
@testset "UnitCommitment" begin
|
|
||||||
include("usage.jl")
|
|
||||||
@testset "import" begin
|
|
||||||
include("import/egret_test.jl")
|
|
||||||
end
|
|
||||||
@testset "instance" begin
|
|
||||||
include("instance/read_test.jl")
|
|
||||||
include("instance/migrate_test.jl")
|
|
||||||
end
|
|
||||||
@testset "model" begin
|
|
||||||
include("model/formulations_test.jl")
|
|
||||||
end
|
|
||||||
@testset "solution" begin
|
|
||||||
@testset "XavQiuWanThi19" begin
|
|
||||||
include("solution/methods/XavQiuWanThi19/filter_test.jl")
|
|
||||||
include("solution/methods/XavQiuWanThi19/find_test.jl")
|
|
||||||
include("solution/methods/XavQiuWanThi19/sensitivity_test.jl")
|
|
||||||
end
|
|
||||||
@testset "TimeDecomposition" begin
|
|
||||||
include("solution/methods/TimeDecomposition/initial_status_test.jl")
|
|
||||||
include(
|
|
||||||
"solution/methods/TimeDecomposition/update_solution_test.jl",
|
|
||||||
)
|
|
||||||
include("solution/methods/TimeDecomposition/optimize_test.jl")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@testset "transform" begin
|
|
||||||
include("transform/initcond_test.jl")
|
|
||||||
include("transform/slice_test.jl")
|
|
||||||
@testset "randomize" begin
|
|
||||||
include("transform/randomize/XavQiuAhm2021_test.jl")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@testset "validation" begin
|
|
||||||
include("validation/repair_test.jl")
|
|
||||||
end
|
|
||||||
@testset "lmp" begin
|
|
||||||
include("lmp/conventional_test.jl")
|
|
||||||
include("lmp/aelmp_test.jl")
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,151 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
using UnitCommitment, DataStructures
|
|
||||||
|
|
||||||
@testset "determine_initial_status" begin
|
|
||||||
hot_start = 100
|
|
||||||
cold_start = -100
|
|
||||||
|
|
||||||
# all on throughout
|
|
||||||
stat_seq = ones(36)
|
|
||||||
# hot start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
|
||||||
@test new_stat == 136
|
|
||||||
# cold start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
|
||||||
@test new_stat == 36
|
|
||||||
|
|
||||||
# off in the last 12 periods
|
|
||||||
stat_seq = ones(36)
|
|
||||||
stat_seq[25:end] .= 0
|
|
||||||
# hot start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
|
||||||
@test new_stat == -12
|
|
||||||
# cold start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
|
||||||
@test new_stat == -12
|
|
||||||
|
|
||||||
# off in one period
|
|
||||||
stat_seq = ones(36)
|
|
||||||
stat_seq[10] = 0
|
|
||||||
# hot start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
|
||||||
@test new_stat == 26
|
|
||||||
# cold start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
|
||||||
@test new_stat == 26
|
|
||||||
|
|
||||||
# off in several of the first 24 periods
|
|
||||||
stat_seq = ones(36)
|
|
||||||
stat_seq[[10, 11, 20]] .= 0
|
|
||||||
# hot start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
|
||||||
@test new_stat == 16
|
|
||||||
# cold start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
|
||||||
@test new_stat == 16
|
|
||||||
|
|
||||||
# all off throughout
|
|
||||||
stat_seq = zeros(36)
|
|
||||||
# hot start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
|
||||||
@test new_stat == -36
|
|
||||||
# cold start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
|
||||||
@test new_stat == -136
|
|
||||||
|
|
||||||
# on in the last 12 periods
|
|
||||||
stat_seq = zeros(36)
|
|
||||||
stat_seq[25:end] .= 1
|
|
||||||
# hot start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
|
||||||
@test new_stat == 12
|
|
||||||
# cold start
|
|
||||||
new_stat = UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
|
||||||
@test new_stat == 12
|
|
||||||
end
|
|
||||||
|
|
||||||
@testset "set_initial_status" begin
|
|
||||||
# read one scenario
|
|
||||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
|
||||||
psuedo_solution = OrderedDict(
|
|
||||||
"Thermal production (MW)" => OrderedDict(
|
|
||||||
"g1" => [0.0, 112.0, 114.0, 116.0],
|
|
||||||
"g2" => [0.0, 102.0, 0.0, 0.0],
|
|
||||||
"g3" => [0.0, 0.0, 0.0, 0.0],
|
|
||||||
"g4" => [0.0, 34.0, 66.0, 99.0],
|
|
||||||
"g5" => [0.0, 34.0, 66.0, 99.0],
|
|
||||||
"g6" => [0.0, 100.0, 100.0, 100.0],
|
|
||||||
),
|
|
||||||
"Is on" => OrderedDict(
|
|
||||||
"g1" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g2" => [0.0, 1.0, 0.0, 0.0],
|
|
||||||
"g3" => [0.0, 0.0, 0.0, 0.0],
|
|
||||||
"g4" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g5" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g6" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
UnitCommitment._set_initial_status!(instance, psuedo_solution, 3)
|
|
||||||
thermal_units = instance.scenarios[1].thermal_units
|
|
||||||
@test thermal_units[1].initial_power == 116.0
|
|
||||||
@test thermal_units[1].initial_status == 3.0
|
|
||||||
@test thermal_units[2].initial_power == 0.0
|
|
||||||
@test thermal_units[2].initial_status == -2.0
|
|
||||||
@test thermal_units[3].initial_power == 0.0
|
|
||||||
@test thermal_units[3].initial_status == -9.0
|
|
||||||
|
|
||||||
# read multiple scenarios
|
|
||||||
instance = UnitCommitment.read([
|
|
||||||
"$FIXTURES/case14.json.gz",
|
|
||||||
"$FIXTURES/case14-profiled.json.gz",
|
|
||||||
])
|
|
||||||
psuedo_solution = OrderedDict(
|
|
||||||
"case14" => OrderedDict(
|
|
||||||
"Thermal production (MW)" => OrderedDict(
|
|
||||||
"g1" => [0.0, 112.0, 114.0, 116.0],
|
|
||||||
"g2" => [0.0, 102.0, 0.0, 0.0],
|
|
||||||
"g3" => [0.0, 0.0, 0.0, 0.0],
|
|
||||||
"g4" => [0.0, 34.0, 66.0, 99.0],
|
|
||||||
"g5" => [0.0, 34.0, 66.0, 99.0],
|
|
||||||
"g6" => [0.0, 100.0, 100.0, 100.0],
|
|
||||||
),
|
|
||||||
"Is on" => OrderedDict(
|
|
||||||
"g1" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g2" => [0.0, 1.0, 0.0, 0.0],
|
|
||||||
"g3" => [0.0, 0.0, 0.0, 0.0],
|
|
||||||
"g4" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g5" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g6" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
"case14-profiled" => OrderedDict(
|
|
||||||
"Thermal production (MW)" => OrderedDict(
|
|
||||||
"g1" => [0.0, 113.0, 116.0, 115.0],
|
|
||||||
"g2" => [0.0, 0.0, 0.0, 0.0],
|
|
||||||
"g3" => [0.0, 0.0, 0.0, 20.0],
|
|
||||||
"g4" => [0.0, 34.0, 66.0, 98.0],
|
|
||||||
"g5" => [0.0, 34.0, 66.0, 97.0],
|
|
||||||
"g6" => [0.0, 100.0, 100.0, 100.0],
|
|
||||||
),
|
|
||||||
"Is on" => OrderedDict(
|
|
||||||
"g1" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g2" => [0.0, 0.0, 0.0, 0.0],
|
|
||||||
"g3" => [0.0, 0.0, 0.0, 1.0],
|
|
||||||
"g4" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g5" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
"g6" => [0.0, 1.0, 1.0, 1.0],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
UnitCommitment._set_initial_status!(instance, psuedo_solution, 3)
|
|
||||||
thermal_units_sc2 = instance.scenarios[2].thermal_units
|
|
||||||
@test thermal_units_sc2[1].initial_power == 115.0
|
|
||||||
@test thermal_units_sc2[1].initial_status == 3.0
|
|
||||||
@test thermal_units_sc2[2].initial_power == 0.0
|
|
||||||
@test thermal_units_sc2[2].initial_status == -11.0
|
|
||||||
@test thermal_units_sc2[3].initial_power == 20.0
|
|
||||||
@test thermal_units_sc2[3].initial_status == 1.0
|
|
||||||
end
|
|
@ -1,52 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
using UnitCommitment, DataStructures, Cbc
|
|
||||||
import UnitCommitment: TimeDecomposition, XavQiuWanThi2019, Formulation
|
|
||||||
|
|
||||||
@testset "optimize_time_decomposition" begin
|
|
||||||
# read one scenario
|
|
||||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
|
||||||
solution = UnitCommitment.optimize!(
|
|
||||||
instance,
|
|
||||||
TimeDecomposition(
|
|
||||||
time_window = 3,
|
|
||||||
time_increment = 2,
|
|
||||||
inner_method = XavQiuWanThi2019.Method(),
|
|
||||||
formulation = Formulation(),
|
|
||||||
),
|
|
||||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0),
|
|
||||||
)
|
|
||||||
@test length(solution["Thermal production (MW)"]["g1"]) == 4
|
|
||||||
@test length(solution["Is on"]["g2"]) == 4
|
|
||||||
@test length(solution["Spinning reserve (MW)"]["r1"]["g2"]) == 4
|
|
||||||
|
|
||||||
# read multiple scenarios
|
|
||||||
instance = UnitCommitment.read([
|
|
||||||
"$FIXTURES/case14.json.gz",
|
|
||||||
"$FIXTURES/case14-profiled.json.gz",
|
|
||||||
])
|
|
||||||
solution = UnitCommitment.optimize!(
|
|
||||||
instance,
|
|
||||||
TimeDecomposition(
|
|
||||||
time_window = 3,
|
|
||||||
time_increment = 2,
|
|
||||||
inner_method = XavQiuWanThi2019.Method(),
|
|
||||||
formulation = Formulation(),
|
|
||||||
),
|
|
||||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0),
|
|
||||||
)
|
|
||||||
@test length(solution["case14"]["Thermal production (MW)"]["g3"]) == 4
|
|
||||||
@test length(solution["case14"]["Is on"]["g4"]) == 4
|
|
||||||
@test length(
|
|
||||||
solution["case14-profiled"]["Thermal production (MW)"]["g5"],
|
|
||||||
) == 4
|
|
||||||
@test length(solution["case14-profiled"]["Is on"]["g6"]) == 4
|
|
||||||
@test length(
|
|
||||||
solution["case14-profiled"]["Profiled production (MW)"]["g7"],
|
|
||||||
) == 4
|
|
||||||
@test length(
|
|
||||||
solution["case14-profiled"]["Spinning reserve (MW)"]["r1"]["g3"],
|
|
||||||
) == 4
|
|
||||||
end
|
|
@ -1,49 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
using UnitCommitment, DataStructures
|
|
||||||
|
|
||||||
@testset "update_solution" begin
|
|
||||||
psuedo_solution = OrderedDict()
|
|
||||||
time_increment = 4
|
|
||||||
psuedo_sub_solution = OrderedDict(
|
|
||||||
"Thermal production (MW)" =>
|
|
||||||
OrderedDict("g1" => [100.0, 200.0, 300.0, 400.0, 500.0, 600.0]),
|
|
||||||
"Is on" => OrderedDict("g1" => [1.0, 0.0, 1.0, 1.0, 0.0, 1.0]),
|
|
||||||
"Profiled production (MW)" =>
|
|
||||||
OrderedDict("g1" => [199.0, 299.0, 399.0, 499.0, 599.0, 699.0]),
|
|
||||||
"Spinning reserve (MW)" => OrderedDict(
|
|
||||||
"r1" => OrderedDict("g1" => [31.0, 32.0, 33.0, 34.0, 35.0, 36.0]),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# first update should directly copy the first 4 entries of sub solution
|
|
||||||
UnitCommitment._update_solution!(
|
|
||||||
psuedo_solution,
|
|
||||||
psuedo_sub_solution,
|
|
||||||
time_increment,
|
|
||||||
)
|
|
||||||
@test psuedo_solution["Thermal production (MW)"]["g1"] ==
|
|
||||||
[100.0, 200.0, 300.0, 400.0]
|
|
||||||
@test psuedo_solution["Is on"]["g1"] == [1.0, 0.0, 1.0, 1.0]
|
|
||||||
@test psuedo_solution["Profiled production (MW)"]["g1"] ==
|
|
||||||
[199.0, 299.0, 399.0, 499.0]
|
|
||||||
@test psuedo_solution["Spinning reserve (MW)"]["r1"]["g1"] ==
|
|
||||||
[31.0, 32.0, 33.0, 34.0]
|
|
||||||
|
|
||||||
# second update should append the first 4 entries of sub solution
|
|
||||||
UnitCommitment._update_solution!(
|
|
||||||
psuedo_solution,
|
|
||||||
psuedo_sub_solution,
|
|
||||||
time_increment,
|
|
||||||
)
|
|
||||||
@test psuedo_solution["Thermal production (MW)"]["g1"] ==
|
|
||||||
[100.0, 200.0, 300.0, 400.0, 100.0, 200.0, 300.0, 400.0]
|
|
||||||
@test psuedo_solution["Is on"]["g1"] ==
|
|
||||||
[1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0]
|
|
||||||
@test psuedo_solution["Profiled production (MW)"]["g1"] ==
|
|
||||||
[199.0, 299.0, 399.0, 499.0, 199.0, 299.0, 399.0, 499.0]
|
|
||||||
@test psuedo_solution["Spinning reserve (MW)"]["r1"]["g1"] ==
|
|
||||||
[31.0, 32.0, 33.0, 34.0, 31.0, 32.0, 33.0, 34.0]
|
|
||||||
end
|
|
@ -0,0 +1,159 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
using UnitCommitment, DataStructures
|
||||||
|
|
||||||
|
function solution_methods_TimeDecomposition_initial_status_test()
|
||||||
|
@testset "determine_initial_status" begin
|
||||||
|
hot_start = 100
|
||||||
|
cold_start = -100
|
||||||
|
|
||||||
|
# all on throughout
|
||||||
|
stat_seq = ones(36)
|
||||||
|
# hot start
|
||||||
|
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
||||||
|
@test new_stat == 136
|
||||||
|
# cold start
|
||||||
|
new_stat =
|
||||||
|
UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
||||||
|
@test new_stat == 36
|
||||||
|
|
||||||
|
# off in the last 12 periods
|
||||||
|
stat_seq = ones(36)
|
||||||
|
stat_seq[25:end] .= 0
|
||||||
|
# hot start
|
||||||
|
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
||||||
|
@test new_stat == -12
|
||||||
|
# cold start
|
||||||
|
new_stat =
|
||||||
|
UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
||||||
|
@test new_stat == -12
|
||||||
|
|
||||||
|
# off in one period
|
||||||
|
stat_seq = ones(36)
|
||||||
|
stat_seq[10] = 0
|
||||||
|
# hot start
|
||||||
|
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
||||||
|
@test new_stat == 26
|
||||||
|
# cold start
|
||||||
|
new_stat =
|
||||||
|
UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
||||||
|
@test new_stat == 26
|
||||||
|
|
||||||
|
# off in several of the first 24 periods
|
||||||
|
stat_seq = ones(36)
|
||||||
|
stat_seq[[10, 11, 20]] .= 0
|
||||||
|
# hot start
|
||||||
|
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
||||||
|
@test new_stat == 16
|
||||||
|
# cold start
|
||||||
|
new_stat =
|
||||||
|
UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
||||||
|
@test new_stat == 16
|
||||||
|
|
||||||
|
# all off throughout
|
||||||
|
stat_seq = zeros(36)
|
||||||
|
# hot start
|
||||||
|
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
||||||
|
@test new_stat == -36
|
||||||
|
# cold start
|
||||||
|
new_stat =
|
||||||
|
UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
||||||
|
@test new_stat == -136
|
||||||
|
|
||||||
|
# on in the last 12 periods
|
||||||
|
stat_seq = zeros(36)
|
||||||
|
stat_seq[25:end] .= 1
|
||||||
|
# hot start
|
||||||
|
new_stat = UnitCommitment._determine_initial_status(hot_start, stat_seq)
|
||||||
|
@test new_stat == 12
|
||||||
|
# cold start
|
||||||
|
new_stat =
|
||||||
|
UnitCommitment._determine_initial_status(cold_start, stat_seq)
|
||||||
|
@test new_stat == 12
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "set_initial_status" begin
|
||||||
|
# read one scenario
|
||||||
|
instance = UnitCommitment.read(fixture("case14.json.gz"))
|
||||||
|
psuedo_solution = OrderedDict(
|
||||||
|
"Thermal production (MW)" => OrderedDict(
|
||||||
|
"g1" => [0.0, 112.0, 114.0, 116.0],
|
||||||
|
"g2" => [0.0, 102.0, 0.0, 0.0],
|
||||||
|
"g3" => [0.0, 0.0, 0.0, 0.0],
|
||||||
|
"g4" => [0.0, 34.0, 66.0, 99.0],
|
||||||
|
"g5" => [0.0, 34.0, 66.0, 99.0],
|
||||||
|
"g6" => [0.0, 100.0, 100.0, 100.0],
|
||||||
|
),
|
||||||
|
"Is on" => OrderedDict(
|
||||||
|
"g1" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g2" => [0.0, 1.0, 0.0, 0.0],
|
||||||
|
"g3" => [0.0, 0.0, 0.0, 0.0],
|
||||||
|
"g4" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g5" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g6" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
UnitCommitment._set_initial_status!(instance, psuedo_solution, 3)
|
||||||
|
thermal_units = instance.scenarios[1].thermal_units
|
||||||
|
@test thermal_units[1].initial_power == 116.0
|
||||||
|
@test thermal_units[1].initial_status == 3.0
|
||||||
|
@test thermal_units[2].initial_power == 0.0
|
||||||
|
@test thermal_units[2].initial_status == -2.0
|
||||||
|
@test thermal_units[3].initial_power == 0.0
|
||||||
|
@test thermal_units[3].initial_status == -9.0
|
||||||
|
|
||||||
|
# read multiple scenarios
|
||||||
|
instance = UnitCommitment.read([
|
||||||
|
fixture("case14.json.gz"),
|
||||||
|
fixture("case14-profiled.json.gz"),
|
||||||
|
])
|
||||||
|
psuedo_solution = OrderedDict(
|
||||||
|
"case14" => OrderedDict(
|
||||||
|
"Thermal production (MW)" => OrderedDict(
|
||||||
|
"g1" => [0.0, 112.0, 114.0, 116.0],
|
||||||
|
"g2" => [0.0, 102.0, 0.0, 0.0],
|
||||||
|
"g3" => [0.0, 0.0, 0.0, 0.0],
|
||||||
|
"g4" => [0.0, 34.0, 66.0, 99.0],
|
||||||
|
"g5" => [0.0, 34.0, 66.0, 99.0],
|
||||||
|
"g6" => [0.0, 100.0, 100.0, 100.0],
|
||||||
|
),
|
||||||
|
"Is on" => OrderedDict(
|
||||||
|
"g1" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g2" => [0.0, 1.0, 0.0, 0.0],
|
||||||
|
"g3" => [0.0, 0.0, 0.0, 0.0],
|
||||||
|
"g4" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g5" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g6" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"case14-profiled" => OrderedDict(
|
||||||
|
"Thermal production (MW)" => OrderedDict(
|
||||||
|
"g1" => [0.0, 113.0, 116.0, 115.0],
|
||||||
|
"g2" => [0.0, 0.0, 0.0, 0.0],
|
||||||
|
"g3" => [0.0, 0.0, 0.0, 20.0],
|
||||||
|
"g4" => [0.0, 34.0, 66.0, 98.0],
|
||||||
|
"g5" => [0.0, 34.0, 66.0, 97.0],
|
||||||
|
"g6" => [0.0, 100.0, 100.0, 100.0],
|
||||||
|
),
|
||||||
|
"Is on" => OrderedDict(
|
||||||
|
"g1" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g2" => [0.0, 0.0, 0.0, 0.0],
|
||||||
|
"g3" => [0.0, 0.0, 0.0, 1.0],
|
||||||
|
"g4" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g5" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
"g6" => [0.0, 1.0, 1.0, 1.0],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
UnitCommitment._set_initial_status!(instance, psuedo_solution, 3)
|
||||||
|
thermal_units_sc2 = instance.scenarios[2].thermal_units
|
||||||
|
@test thermal_units_sc2[1].initial_power == 115.0
|
||||||
|
@test thermal_units_sc2[1].initial_status == 3.0
|
||||||
|
@test thermal_units_sc2[2].initial_power == 0.0
|
||||||
|
@test thermal_units_sc2[2].initial_status == -11.0
|
||||||
|
@test thermal_units_sc2[3].initial_power == 20.0
|
||||||
|
@test thermal_units_sc2[3].initial_status == 1.0
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,60 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
using UnitCommitment, DataStructures, Cbc
|
||||||
|
import UnitCommitment: TimeDecomposition, XavQiuWanThi2019, Formulation
|
||||||
|
|
||||||
|
function solution_methods_TimeDecomposition_optimize_test()
|
||||||
|
@testset "optimize_time_decomposition" begin
|
||||||
|
# read one scenario
|
||||||
|
instance = UnitCommitment.read(fixture("case14.json.gz"))
|
||||||
|
solution = UnitCommitment.optimize!(
|
||||||
|
instance,
|
||||||
|
TimeDecomposition(
|
||||||
|
time_window = 3,
|
||||||
|
time_increment = 2,
|
||||||
|
inner_method = XavQiuWanThi2019.Method(),
|
||||||
|
formulation = Formulation(),
|
||||||
|
),
|
||||||
|
optimizer = optimizer_with_attributes(
|
||||||
|
Cbc.Optimizer,
|
||||||
|
"logLevel" => 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@test length(solution["Thermal production (MW)"]["g1"]) == 4
|
||||||
|
@test length(solution["Is on"]["g2"]) == 4
|
||||||
|
@test length(solution["Spinning reserve (MW)"]["r1"]["g2"]) == 4
|
||||||
|
|
||||||
|
# read multiple scenarios
|
||||||
|
instance = UnitCommitment.read([
|
||||||
|
fixture("case14.json.gz"),
|
||||||
|
fixture("case14-profiled.json.gz"),
|
||||||
|
])
|
||||||
|
solution = UnitCommitment.optimize!(
|
||||||
|
instance,
|
||||||
|
TimeDecomposition(
|
||||||
|
time_window = 3,
|
||||||
|
time_increment = 2,
|
||||||
|
inner_method = XavQiuWanThi2019.Method(),
|
||||||
|
formulation = Formulation(),
|
||||||
|
),
|
||||||
|
optimizer = optimizer_with_attributes(
|
||||||
|
Cbc.Optimizer,
|
||||||
|
"logLevel" => 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@test length(solution["case14"]["Thermal production (MW)"]["g3"]) == 4
|
||||||
|
@test length(solution["case14"]["Is on"]["g4"]) == 4
|
||||||
|
@test length(
|
||||||
|
solution["case14-profiled"]["Thermal production (MW)"]["g5"],
|
||||||
|
) == 4
|
||||||
|
@test length(solution["case14-profiled"]["Is on"]["g6"]) == 4
|
||||||
|
@test length(
|
||||||
|
solution["case14-profiled"]["Profiled production (MW)"]["g7"],
|
||||||
|
) == 4
|
||||||
|
@test length(
|
||||||
|
solution["case14-profiled"]["Spinning reserve (MW)"]["r1"]["g3"],
|
||||||
|
) == 4
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,55 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
using UnitCommitment, DataStructures
|
||||||
|
|
||||||
|
function solution_methods_TimeDecomposition_update_solution_test()
|
||||||
|
@testset "update_solution" begin
|
||||||
|
psuedo_solution = OrderedDict()
|
||||||
|
time_increment = 4
|
||||||
|
psuedo_sub_solution = OrderedDict(
|
||||||
|
"Thermal production (MW)" => OrderedDict(
|
||||||
|
"g1" => [100.0, 200.0, 300.0, 400.0, 500.0, 600.0],
|
||||||
|
),
|
||||||
|
"Is on" => OrderedDict("g1" => [1.0, 0.0, 1.0, 1.0, 0.0, 1.0]),
|
||||||
|
"Profiled production (MW)" => OrderedDict(
|
||||||
|
"g1" => [199.0, 299.0, 399.0, 499.0, 599.0, 699.0],
|
||||||
|
),
|
||||||
|
"Spinning reserve (MW)" => OrderedDict(
|
||||||
|
"r1" => OrderedDict(
|
||||||
|
"g1" => [31.0, 32.0, 33.0, 34.0, 35.0, 36.0],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# first update should directly copy the first 4 entries of sub solution
|
||||||
|
UnitCommitment._update_solution!(
|
||||||
|
psuedo_solution,
|
||||||
|
psuedo_sub_solution,
|
||||||
|
time_increment,
|
||||||
|
)
|
||||||
|
@test psuedo_solution["Thermal production (MW)"]["g1"] ==
|
||||||
|
[100.0, 200.0, 300.0, 400.0]
|
||||||
|
@test psuedo_solution["Is on"]["g1"] == [1.0, 0.0, 1.0, 1.0]
|
||||||
|
@test psuedo_solution["Profiled production (MW)"]["g1"] ==
|
||||||
|
[199.0, 299.0, 399.0, 499.0]
|
||||||
|
@test psuedo_solution["Spinning reserve (MW)"]["r1"]["g1"] ==
|
||||||
|
[31.0, 32.0, 33.0, 34.0]
|
||||||
|
|
||||||
|
# second update should append the first 4 entries of sub solution
|
||||||
|
UnitCommitment._update_solution!(
|
||||||
|
psuedo_solution,
|
||||||
|
psuedo_sub_solution,
|
||||||
|
time_increment,
|
||||||
|
)
|
||||||
|
@test psuedo_solution["Thermal production (MW)"]["g1"] ==
|
||||||
|
[100.0, 200.0, 300.0, 400.0, 100.0, 200.0, 300.0, 400.0]
|
||||||
|
@test psuedo_solution["Is on"]["g1"] ==
|
||||||
|
[1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0]
|
||||||
|
@test psuedo_solution["Profiled production (MW)"]["g1"] ==
|
||||||
|
[199.0, 299.0, 399.0, 499.0, 199.0, 299.0, 399.0, 499.0]
|
||||||
|
@test psuedo_solution["Spinning reserve (MW)"]["r1"]["g1"] ==
|
||||||
|
[31.0, 32.0, 33.0, 34.0, 31.0, 32.0, 33.0, 34.0]
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in new issue