mirror of
https://github.com/ANL-CEEESA/UnitCommitment.jl.git
synced 2025-12-06 00:08:52 -06:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
@@ -6,13 +6,17 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
|
||||
@testset "read v0.2" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/ucjl-0.2.json.gz")
|
||||
@test length(instance.reserves_by_name["r1"].amount) == 4
|
||||
@test instance.units_by_name["g2"].reserves[1].name == "r1"
|
||||
@test length(instance.scenarios) == 1
|
||||
sc = instance.scenarios[1]
|
||||
@test length(sc.reserves_by_name["r1"].amount) == 4
|
||||
@test sc.units_by_name["g2"].reserves[1].name == "r1"
|
||||
end
|
||||
|
||||
@testset "read v0.3" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/ucjl-0.3.json.gz")
|
||||
@test length(instance.units) == 6
|
||||
@test length(instance.buses) == 14
|
||||
@test length(instance.lines) == 20
|
||||
@test length(instance.scenarios) == 1
|
||||
sc = instance.scenarios[1]
|
||||
@test length(sc.units) == 6
|
||||
@test length(sc.buses) == 14
|
||||
@test length(sc.lines) == 20
|
||||
end
|
||||
|
||||
@@ -7,42 +7,49 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@testset "read_benchmark" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
|
||||
@test length(instance.lines) == 20
|
||||
@test length(instance.buses) == 14
|
||||
@test length(instance.units) == 6
|
||||
@test length(instance.contingencies) == 19
|
||||
@test length(instance.price_sensitive_loads) == 1
|
||||
@test repr(instance) == (
|
||||
"UnitCommitmentInstance(1 scenarios, 6 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.units) == 6
|
||||
@test length(sc.contingencies) == 19
|
||||
@test length(sc.price_sensitive_loads) == 1
|
||||
@test instance.time == 4
|
||||
|
||||
@test instance.lines[5].name == "l5"
|
||||
@test instance.lines[5].source.name == "b2"
|
||||
@test instance.lines[5].target.name == "b5"
|
||||
@test instance.lines[5].reactance ≈ 0.17388
|
||||
@test instance.lines[5].susceptance ≈ 10.037550333
|
||||
@test instance.lines[5].normal_flow_limit == [1e8 for t in 1:4]
|
||||
@test instance.lines[5].emergency_flow_limit == [1e8 for t in 1:4]
|
||||
@test instance.lines[5].flow_limit_penalty == [5e3 for t in 1:4]
|
||||
@test instance.lines_by_name["l5"].name == "l5"
|
||||
@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 instance.lines[1].name == "l1"
|
||||
@test instance.lines[1].source.name == "b1"
|
||||
@test instance.lines[1].target.name == "b2"
|
||||
@test instance.lines[1].reactance ≈ 0.059170
|
||||
@test instance.lines[1].susceptance ≈ 29.496860773945
|
||||
@test instance.lines[1].normal_flow_limit == [300.0 for t in 1:4]
|
||||
@test instance.lines[1].emergency_flow_limit == [400.0 for t in 1:4]
|
||||
@test instance.lines[1].flow_limit_penalty == [1e3 for t in 1:4]
|
||||
@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 instance.buses[9].name == "b9"
|
||||
@test instance.buses[9].load == [35.36638, 33.25495, 31.67138, 31.14353]
|
||||
@test instance.buses_by_name["b9"].name == "b9"
|
||||
@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 instance.reserves[1].name == "r1"
|
||||
@test instance.reserves[1].type == "spinning"
|
||||
@test instance.reserves[1].amount == [100.0, 100.0, 100.0, 100.0]
|
||||
@test instance.reserves_by_name["r1"].name == "r1"
|
||||
@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 = instance.units[1]
|
||||
unit = sc.units[1]
|
||||
@test unit.name == "g1"
|
||||
@test unit.bus.name == "b1"
|
||||
@test unit.ramp_up_limit == 1e6
|
||||
@@ -69,14 +76,14 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@test unit.startup_categories[2].cost == 1500.0
|
||||
@test unit.startup_categories[3].cost == 2000.0
|
||||
@test length(unit.reserves) == 0
|
||||
@test instance.units_by_name["g1"].name == "g1"
|
||||
@test sc.units_by_name["g1"].name == "g1"
|
||||
|
||||
unit = instance.units[2]
|
||||
unit = sc.units[2]
|
||||
@test unit.name == "g2"
|
||||
@test unit.must_run == [false for t in 1:4]
|
||||
@test length(unit.reserves) == 1
|
||||
|
||||
unit = instance.units[3]
|
||||
unit = sc.units[3]
|
||||
@test unit.name == "g3"
|
||||
@test unit.bus.name == "b3"
|
||||
@test unit.ramp_up_limit == 70.0
|
||||
@@ -98,23 +105,23 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@test length(unit.reserves) == 1
|
||||
@test unit.reserves[1].name == "r1"
|
||||
|
||||
@test instance.contingencies[1].lines == [instance.lines[1]]
|
||||
@test instance.contingencies[1].units == []
|
||||
@test instance.contingencies[1].name == "c1"
|
||||
@test instance.contingencies_by_name["c1"].name == "c1"
|
||||
@test sc.contingencies[1].lines == [sc.lines[1]]
|
||||
@test sc.contingencies[1].units == []
|
||||
@test sc.contingencies[1].name == "c1"
|
||||
@test sc.contingencies_by_name["c1"].name == "c1"
|
||||
|
||||
load = instance.price_sensitive_loads[1]
|
||||
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 instance.price_sensitive_loads_by_name["ps1"].name == "ps1"
|
||||
@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.units[1]
|
||||
unit = instance.scenarios[1].units[1]
|
||||
@test unit.name == "g1"
|
||||
@test unit.min_uptime == 2
|
||||
@test unit.min_downtime == 2
|
||||
|
||||
@@ -7,13 +7,13 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
|
||||
@testset "_ViolationFilter" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
sc = instance.scenarios[1]
|
||||
filter = UnitCommitment._ViolationFilter(max_per_line = 1, max_total = 2)
|
||||
|
||||
_offer(
|
||||
filter,
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
monitored_line = sc.lines[1],
|
||||
outage_line = nothing,
|
||||
amount = 100.0,
|
||||
),
|
||||
@@ -22,8 +22,8 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
filter,
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[1],
|
||||
monitored_line = sc.lines[1],
|
||||
outage_line = sc.lines[1],
|
||||
amount = 300.0,
|
||||
),
|
||||
)
|
||||
@@ -31,8 +31,8 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
filter,
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[5],
|
||||
monitored_line = sc.lines[1],
|
||||
outage_line = sc.lines[5],
|
||||
amount = 500.0,
|
||||
),
|
||||
)
|
||||
@@ -40,8 +40,8 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
filter,
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[4],
|
||||
monitored_line = sc.lines[1],
|
||||
outage_line = sc.lines[4],
|
||||
amount = 400.0,
|
||||
),
|
||||
)
|
||||
@@ -49,8 +49,8 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
filter,
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[2],
|
||||
outage_line = instance.lines[1],
|
||||
monitored_line = sc.lines[2],
|
||||
outage_line = sc.lines[1],
|
||||
amount = 200.0,
|
||||
),
|
||||
)
|
||||
@@ -58,8 +58,8 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
filter,
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[2],
|
||||
outage_line = instance.lines[8],
|
||||
monitored_line = sc.lines[2],
|
||||
outage_line = sc.lines[8],
|
||||
amount = 100.0,
|
||||
),
|
||||
)
|
||||
@@ -68,14 +68,14 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
expected = [
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[2],
|
||||
outage_line = instance.lines[1],
|
||||
monitored_line = sc.lines[2],
|
||||
outage_line = sc.lines[1],
|
||||
amount = 200.0,
|
||||
),
|
||||
_Violation(
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[5],
|
||||
monitored_line = sc.lines[1],
|
||||
outage_line = sc.lines[5],
|
||||
amount = 500.0,
|
||||
),
|
||||
]
|
||||
|
||||
@@ -7,23 +7,25 @@ import UnitCommitment: _Violation, _offer, _query
|
||||
|
||||
@testset "find_violations" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
for line in instance.lines, t in 1:instance.time
|
||||
sc = instance.scenarios[1]
|
||||
for line in sc.lines, t in 1:instance.time
|
||||
line.normal_flow_limit[t] = 1.0
|
||||
line.emergency_flow_limit[t] = 1.0
|
||||
end
|
||||
isf = UnitCommitment._injection_shift_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
)
|
||||
lodf = UnitCommitment._line_outage_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
isf = isf,
|
||||
)
|
||||
inj = [1000.0 for b in 1:13, t in 1:instance.time]
|
||||
overflow = [0.0 for l in instance.lines, t in 1:instance.time]
|
||||
overflow = [0.0 for l in sc.lines, t in 1:instance.time]
|
||||
violations = UnitCommitment._find_violations(
|
||||
instance = instance,
|
||||
sc = sc,
|
||||
net_injections = inj,
|
||||
overflow = overflow,
|
||||
isf = isf,
|
||||
|
||||
@@ -6,7 +6,8 @@ using UnitCommitment, Test, LinearAlgebra
|
||||
|
||||
@testset "_susceptance_matrix" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
actual = UnitCommitment._susceptance_matrix(instance.lines)
|
||||
sc = instance.scenarios[1]
|
||||
actual = UnitCommitment._susceptance_matrix(sc.lines)
|
||||
@test size(actual) == (20, 20)
|
||||
expected = Diagonal([
|
||||
29.5,
|
||||
@@ -35,9 +36,10 @@ end
|
||||
|
||||
@testset "_reduced_incidence_matrix" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
sc = instance.scenarios[1]
|
||||
actual = UnitCommitment._reduced_incidence_matrix(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
)
|
||||
@test size(actual) == (20, 13)
|
||||
@test actual[1, 1] == -1.0
|
||||
@@ -82,9 +84,10 @@ end
|
||||
|
||||
@testset "_injection_shift_factors" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
sc = instance.scenarios[1]
|
||||
actual = UnitCommitment._injection_shift_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
)
|
||||
@test size(actual) == (20, 13)
|
||||
@test round.(actual, digits = 2) == [
|
||||
@@ -113,25 +116,26 @@ end
|
||||
|
||||
@testset "_line_outage_factors" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
sc = instance.scenarios[1]
|
||||
isf_before = UnitCommitment._injection_shift_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
)
|
||||
lodf = UnitCommitment._line_outage_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
isf = isf_before,
|
||||
)
|
||||
for contingency in instance.contingencies
|
||||
for contingency in sc.contingencies
|
||||
for lc in contingency.lines
|
||||
prev_susceptance = lc.susceptance
|
||||
lc.susceptance = 0.0
|
||||
isf_after = UnitCommitment._injection_shift_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
lines = sc.lines,
|
||||
buses = sc.buses,
|
||||
)
|
||||
lc.susceptance = prev_susceptance
|
||||
for lm in instance.lines
|
||||
for lm in sc.lines
|
||||
expected = isf_after[lm.offset, :]
|
||||
actual =
|
||||
isf_before[lm.offset, :] +
|
||||
|
||||
@@ -8,18 +8,18 @@ using UnitCommitment, Cbc, JuMP
|
||||
# Load instance
|
||||
instance = UnitCommitment.read("$FIXTURES/case118-initcond.json.gz")
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
|
||||
sc = instance.scenarios[1]
|
||||
# All units should have unknown initial conditions
|
||||
for g in instance.units
|
||||
for g in sc.units
|
||||
@test g.initial_power === nothing
|
||||
@test g.initial_status === nothing
|
||||
end
|
||||
|
||||
# Generate initial conditions
|
||||
UnitCommitment.generate_initial_conditions!(instance, optimizer)
|
||||
UnitCommitment.generate_initial_conditions!(sc, optimizer)
|
||||
|
||||
# All units should now have known initial conditions
|
||||
for g in instance.units
|
||||
for g in sc.units
|
||||
@test g.initial_power !== nothing
|
||||
@test g.initial_status !== nothing
|
||||
end
|
||||
|
||||
@@ -9,30 +9,31 @@ using Distributions
|
||||
using Random
|
||||
using UnitCommitment, Cbc, JuMP
|
||||
|
||||
get_instance() = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
|
||||
system_load(instance) = sum(b.load for b in instance.buses)
|
||||
function get_scenario()
|
||||
return UnitCommitment.read_benchmark(
|
||||
"matpower/case118/2017-02-01",
|
||||
).scenarios[1]
|
||||
end
|
||||
system_load(sc) = sum(b.load for b in sc.buses)
|
||||
test_approx(x, y) = @test isapprox(x, y, atol = 1e-3)
|
||||
|
||||
@testset "XavQiuAhm2021" begin
|
||||
@testset "cost and load share" begin
|
||||
instance = get_instance()
|
||||
|
||||
sc = get_scenario()
|
||||
# Check original costs
|
||||
unit = instance.units[10]
|
||||
unit = sc.units[10]
|
||||
test_approx(unit.min_power_cost[1], 825.023)
|
||||
test_approx(unit.cost_segments[1].cost[1], 36.659)
|
||||
test_approx(unit.startup_categories[1].cost[1], 7570.42)
|
||||
|
||||
# Check original load share
|
||||
bus = instance.buses[1]
|
||||
prev_system_load = system_load(instance)
|
||||
bus = sc.buses[1]
|
||||
prev_system_load = system_load(sc)
|
||||
test_approx(bus.load[1] / prev_system_load[1], 0.012)
|
||||
|
||||
randomize!(
|
||||
instance,
|
||||
method = XavQiuAhm2021.Randomization(
|
||||
randomize_load_profile = false,
|
||||
),
|
||||
sc,
|
||||
XavQiuAhm2021.Randomization(randomize_load_profile = false),
|
||||
rng = MersenneTwister(42),
|
||||
)
|
||||
|
||||
@@ -42,7 +43,7 @@ test_approx(x, y) = @test isapprox(x, y, atol = 1e-3)
|
||||
test_approx(unit.startup_categories[1].cost[1], 7634.226)
|
||||
|
||||
# Check randomized load share
|
||||
curr_system_load = system_load(instance)
|
||||
curr_system_load = system_load(sc)
|
||||
test_approx(bus.load[1] / curr_system_load[1], 0.013)
|
||||
|
||||
# System load should not change
|
||||
@@ -50,20 +51,15 @@ test_approx(x, y) = @test isapprox(x, y, atol = 1e-3)
|
||||
end
|
||||
|
||||
@testset "load profile" begin
|
||||
instance = get_instance()
|
||||
|
||||
sc = get_scenario()
|
||||
# Check original load profile
|
||||
@test round.(system_load(instance), digits = 1)[1:8] ≈
|
||||
@test round.(system_load(sc), digits = 1)[1:8] ≈
|
||||
[3059.5, 2983.2, 2937.5, 2953.9, 3073.1, 3356.4, 4068.5, 4018.8]
|
||||
|
||||
randomize!(
|
||||
instance,
|
||||
XavQiuAhm2021.Randomization(),
|
||||
rng = MersenneTwister(42),
|
||||
)
|
||||
randomize!(sc, XavQiuAhm2021.Randomization(); rng = MersenneTwister(42))
|
||||
|
||||
# Check randomized load profile
|
||||
@test round.(system_load(instance), digits = 1)[1:8] ≈
|
||||
@test round.(system_load(sc), digits = 1)[1:8] ≈
|
||||
[4854.7, 4849.2, 4732.7, 4848.2, 4948.4, 5231.1, 5874.8, 5934.8]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,12 +7,13 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@testset "slice" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
modified = UnitCommitment.slice(instance, 1:2)
|
||||
sc = modified.scenarios[1]
|
||||
|
||||
# Should update all time-dependent fields
|
||||
@test modified.time == 2
|
||||
@test length(modified.power_balance_penalty) == 2
|
||||
@test length(modified.reserves_by_name["r1"].amount) == 2
|
||||
for u in modified.units
|
||||
@test length(sc.power_balance_penalty) == 2
|
||||
@test length(sc.reserves_by_name["r1"].amount) == 2
|
||||
for u in sc.units
|
||||
@test length(u.max_power) == 2
|
||||
@test length(u.min_power) == 2
|
||||
@test length(u.must_run) == 2
|
||||
@@ -22,18 +23,19 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@test length(s.cost) == 2
|
||||
end
|
||||
end
|
||||
for b in modified.buses
|
||||
for b in sc.buses
|
||||
@test length(b.load) == 2
|
||||
end
|
||||
for l in modified.lines
|
||||
for l in sc.lines
|
||||
@test length(l.normal_flow_limit) == 2
|
||||
@test length(l.emergency_flow_limit) == 2
|
||||
@test length(l.flow_limit_penalty) == 2
|
||||
end
|
||||
for ps in modified.price_sensitive_loads
|
||||
for ps in sc.price_sensitive_loads
|
||||
@test length(ps.demand) == 2
|
||||
@test length(ps.revenue) == 2
|
||||
end
|
||||
|
||||
# Should be able to build model without errors
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
model = UnitCommitment.build_model(
|
||||
|
||||
@@ -4,34 +4,59 @@
|
||||
|
||||
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON
|
||||
|
||||
@testset "usage" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
for line in instance.lines, t in 1:4
|
||||
line.normal_flow_limit[t] = 10.0
|
||||
function _set_flow_limits!(instance)
|
||||
for sc in instance.scenarios
|
||||
sc.power_balance_penalty = [100_000 for _ in 1:instance.time]
|
||||
for line in sc.lines, t in 1:4
|
||||
line.normal_flow_limit[t] = 10.0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "usage" begin
|
||||
@testset "deterministic" begin
|
||||
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
|
||||
_set_flow_limits!(instance)
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
model = UnitCommitment.build_model(
|
||||
instance = instance,
|
||||
optimizer = optimizer,
|
||||
variable_names = true,
|
||||
)
|
||||
@test name(model[:is_on]["g1", 1]) == "is_on[g1,1]"
|
||||
|
||||
# Optimize and retrieve solution
|
||||
UnitCommitment.optimize!(model)
|
||||
solution = UnitCommitment.solution(model)
|
||||
|
||||
# Write solution to a file
|
||||
filename = tempname()
|
||||
UnitCommitment.write(filename, solution)
|
||||
loaded = JSON.parsefile(filename)
|
||||
@test length(loaded["Is on"]) == 6
|
||||
|
||||
# Verify solution
|
||||
@test UnitCommitment.validate(instance, solution)
|
||||
|
||||
# Reoptimize with fixed solution
|
||||
UnitCommitment.fix!(model, solution)
|
||||
UnitCommitment.optimize!(model)
|
||||
@test UnitCommitment.validate(instance, solution)
|
||||
end
|
||||
|
||||
@testset "stochastic" begin
|
||||
instance = UnitCommitment.read([
|
||||
"$FIXTURES/case14.json.gz",
|
||||
"$FIXTURES/case14.json.gz",
|
||||
])
|
||||
_set_flow_limits!(instance)
|
||||
@test length(instance.scenarios) == 2
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
model = UnitCommitment.build_model(
|
||||
instance = instance,
|
||||
optimizer = optimizer,
|
||||
)
|
||||
UnitCommitment.optimize!(model)
|
||||
solution = UnitCommitment.solution(model)
|
||||
end
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
model = UnitCommitment.build_model(
|
||||
instance = instance,
|
||||
optimizer = optimizer,
|
||||
variable_names = true,
|
||||
)
|
||||
@test name(model[:is_on]["g1", 1]) == "is_on[g1,1]"
|
||||
|
||||
# Optimize and retrieve solution
|
||||
UnitCommitment.optimize!(model)
|
||||
solution = UnitCommitment.solution(model)
|
||||
|
||||
# Write solution to a file
|
||||
filename = tempname()
|
||||
UnitCommitment.write(filename, solution)
|
||||
loaded = JSON.parsefile(filename)
|
||||
@test length(loaded["Is on"]) == 6
|
||||
|
||||
# Verify solution
|
||||
@test UnitCommitment.validate(instance, solution)
|
||||
|
||||
# Reoptimize with fixed solution
|
||||
UnitCommitment.fix!(model, solution)
|
||||
UnitCommitment.optimize!(model)
|
||||
@test UnitCommitment.validate(instance, solution)
|
||||
end
|
||||
|
||||
@@ -16,8 +16,8 @@ end
|
||||
json = parse_case14()
|
||||
json["Generators"]["g1"]["Production cost curve (MW)"] = [100, 150, 200]
|
||||
json["Generators"]["g1"]["Production cost curve (\$)"] = [10, 25, 30]
|
||||
instance = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(instance) == 4
|
||||
sc = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(sc) == 4
|
||||
end
|
||||
|
||||
@testset "Startup limit must be greater than Pmin" begin
|
||||
@@ -25,15 +25,15 @@ end
|
||||
json["Generators"]["g1"]["Production cost curve (MW)"] = [100, 150]
|
||||
json["Generators"]["g1"]["Production cost curve (\$)"] = [100, 150]
|
||||
json["Generators"]["g1"]["Startup limit (MW)"] = 80
|
||||
instance = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(instance) == 1
|
||||
sc = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(sc) == 1
|
||||
end
|
||||
|
||||
@testset "Startup costs and delays must be increasing" begin
|
||||
json = parse_case14()
|
||||
json["Generators"]["g1"]["Startup costs (\$)"] = [300, 200, 100]
|
||||
json["Generators"]["g1"]["Startup delays (h)"] = [8, 4, 2]
|
||||
instance = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(instance) == 4
|
||||
sc = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(sc) == 4
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user