mirror of
https://github.com/ANL-CEEESA/UnitCommitment.jl.git
synced 2025-12-06 08:18:51 -06:00
Format source code with JuliaFormatter; set up GH Actions
This commit is contained in:
@@ -6,14 +6,17 @@ using UnitCommitment
|
||||
|
||||
@testset "convert" begin
|
||||
@testset "EGRET solution" begin
|
||||
solution = UnitCommitment._read_egret_solution("fixtures/egret_output.json.gz")
|
||||
solution =
|
||||
UnitCommitment._read_egret_solution("fixtures/egret_output.json.gz")
|
||||
for attr in ["Is on", "Production (MW)", "Production cost (\$)"]
|
||||
@test attr in keys(solution)
|
||||
@test "115_STEAM_1" in keys(solution[attr])
|
||||
@test length(solution[attr]["115_STEAM_1"]) == 48
|
||||
end
|
||||
@test solution["Production cost (\$)"]["315_CT_6"][15:20] == [0., 0., 884.44, 1470.71, 1470.71, 884.44]
|
||||
@test solution["Startup cost (\$)"]["315_CT_6"][15:20] == [0., 0., 5665.23, 0., 0., 0.]
|
||||
@test solution["Production cost (\$)"]["315_CT_6"][15:20] ==
|
||||
[0.0, 0.0, 884.44, 1470.71, 1470.71, 884.44]
|
||||
@test solution["Startup cost (\$)"]["315_CT_6"][15:20] ==
|
||||
[0.0, 0.0, 5665.23, 0.0, 0.0, 0.0]
|
||||
@test length(keys(solution["Is on"])) == 154
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,21 +8,21 @@ using UnitCommitment, Cbc, JuMP
|
||||
# Load instance
|
||||
instance = UnitCommitment.read("$(pwd())/fixtures/case118-initcond.json.gz")
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
|
||||
|
||||
# All units should have unknown initial conditions
|
||||
for g in instance.units
|
||||
@test g.initial_power === nothing
|
||||
@test g.initial_status === nothing
|
||||
end
|
||||
|
||||
|
||||
# Generate initial conditions
|
||||
UnitCommitment.generate_initial_conditions!(instance, optimizer)
|
||||
|
||||
|
||||
# All units should now have known initial conditions
|
||||
for g in instance.units
|
||||
@test g.initial_power !== nothing
|
||||
@test g.initial_status !== nothing
|
||||
end
|
||||
|
||||
|
||||
# TODO: Check that initial conditions are feasible
|
||||
end
|
||||
|
||||
@@ -15,46 +15,46 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@test length(instance.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].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[5].flow_limit_penalty == [5e3 for t in 1:4]
|
||||
|
||||
@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].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 instance.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]
|
||||
|
||||
unit = instance.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. for t in 1:4]
|
||||
@test unit.min_uptime == 1
|
||||
@test unit.min_downtime == 1
|
||||
@test unit.provides_spinning_reserves == [true for t in 1:4]
|
||||
@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
|
||||
@test unit.provides_spinning_reserves == [true for t in 1:4]
|
||||
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
|
||||
@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
|
||||
@@ -63,42 +63,42 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@test unit.startup_categories[1].cost == 1000.0
|
||||
@test unit.startup_categories[2].cost == 1500.0
|
||||
@test unit.startup_categories[3].cost == 2000.0
|
||||
|
||||
|
||||
unit = instance.units[2]
|
||||
@test unit.name == "g2"
|
||||
@test unit.name == "g2"
|
||||
@test unit.must_run == [false for t in 1:4]
|
||||
|
||||
unit = instance.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. for t in 1:4]
|
||||
@test unit.min_uptime == 1
|
||||
@test unit.min_downtime == 1
|
||||
@test unit.provides_spinning_reserves == [true for t in 1:4]
|
||||
@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
|
||||
@test unit.provides_spinning_reserves == [true for t in 1:4]
|
||||
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].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 instance.reserves.spinning == zeros(4)
|
||||
|
||||
|
||||
@test instance.contingencies[1].lines == [instance.lines[1]]
|
||||
@test instance.contingencies[1].units == []
|
||||
|
||||
|
||||
load = instance.price_sensitive_loads[1]
|
||||
@test load.name == "ps1"
|
||||
@test load.name == "ps1"
|
||||
@test load.bus.name == "b3"
|
||||
@test load.revenue == [100. for t in 1:4]
|
||||
@test load.demand == [50. for t in 1:4]
|
||||
@test load.revenue == [100.0 for t in 1:4]
|
||||
@test load.demand == [50.0 for t in 1:4]
|
||||
end
|
||||
|
||||
@testset "read sub-hourly" begin
|
||||
@@ -114,11 +114,11 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@test unit.startup_categories[3].delay == 6
|
||||
@test unit.initial_status == -200
|
||||
end
|
||||
|
||||
|
||||
@testset "slice" begin
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
modified = UnitCommitment.slice(instance, 1:2)
|
||||
|
||||
|
||||
# Should update all time-dependent fields
|
||||
@test modified.time == 2
|
||||
@test length(modified.power_balance_penalty) == 2
|
||||
@@ -146,11 +146,13 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
|
||||
@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 = build_model(instance=modified,
|
||||
optimizer=optimizer,
|
||||
variable_names=true)
|
||||
model = build_model(
|
||||
instance = modified,
|
||||
optimizer = optimizer,
|
||||
variable_names = true,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,9 +12,9 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP
|
||||
end
|
||||
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
|
||||
model = build_model(
|
||||
instance=instance,
|
||||
optimizer=optimizer,
|
||||
variable_names=true,
|
||||
instance = instance,
|
||||
optimizer = optimizer,
|
||||
variable_names = true,
|
||||
)
|
||||
@test name(model[:is_on]["g1", 1]) == "is_on[g1,1]"
|
||||
|
||||
@@ -27,7 +27,7 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP
|
||||
UnitCommitment.write(filename, solution)
|
||||
loaded = JSON.parsefile(filename)
|
||||
@test length(loaded["Is on"]) == 6
|
||||
|
||||
|
||||
# Verify solution
|
||||
@test UnitCommitment.validate(instance, solution)
|
||||
|
||||
|
||||
@@ -8,81 +8,81 @@ import UnitCommitment: Violation, _offer, _query
|
||||
@testset "Screening" begin
|
||||
@testset "Violation filter" begin
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
filter = UnitCommitment.ViolationFilter(max_per_line=1, max_total=2)
|
||||
filter = UnitCommitment.ViolationFilter(max_per_line = 1, max_total = 2)
|
||||
|
||||
_offer(
|
||||
filter,
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[1],
|
||||
outage_line=nothing,
|
||||
amount=100.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = nothing,
|
||||
amount = 100.0,
|
||||
),
|
||||
)
|
||||
_offer(
|
||||
filter,
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[1],
|
||||
outage_line=instance.lines[1],
|
||||
amount=300.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[1],
|
||||
amount = 300.0,
|
||||
),
|
||||
)
|
||||
_offer(
|
||||
filter,
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[1],
|
||||
outage_line=instance.lines[5],
|
||||
amount=500.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[5],
|
||||
amount = 500.0,
|
||||
),
|
||||
)
|
||||
_offer(
|
||||
filter,
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[1],
|
||||
outage_line=instance.lines[4],
|
||||
amount=400.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[4],
|
||||
amount = 400.0,
|
||||
),
|
||||
)
|
||||
_offer(
|
||||
filter,
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[2],
|
||||
outage_line=instance.lines[1],
|
||||
amount=200.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[2],
|
||||
outage_line = instance.lines[1],
|
||||
amount = 200.0,
|
||||
),
|
||||
)
|
||||
_offer(
|
||||
filter,
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[2],
|
||||
outage_line=instance.lines[8],
|
||||
amount=100.,
|
||||
)
|
||||
time = 1,
|
||||
monitored_line = instance.lines[2],
|
||||
outage_line = instance.lines[8],
|
||||
amount = 100.0,
|
||||
),
|
||||
)
|
||||
|
||||
actual = _query(filter)
|
||||
expected = [
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[2],
|
||||
outage_line=instance.lines[1],
|
||||
amount=200.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[2],
|
||||
outage_line = instance.lines[1],
|
||||
amount = 200.0,
|
||||
),
|
||||
Violation(
|
||||
time=1,
|
||||
monitored_line=instance.lines[1],
|
||||
outage_line=instance.lines[5],
|
||||
amount=500.,
|
||||
time = 1,
|
||||
monitored_line = instance.lines[1],
|
||||
outage_line = instance.lines[5],
|
||||
amount = 500.0,
|
||||
),
|
||||
]
|
||||
@test actual == expected
|
||||
end
|
||||
|
||||
|
||||
@testset "find_violations" begin
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
for line in instance.lines, t in 1:instance.time
|
||||
@@ -90,22 +90,22 @@ import UnitCommitment: Violation, _offer, _query
|
||||
line.emergency_flow_limit[t] = 1.0
|
||||
end
|
||||
isf = UnitCommitment._injection_shift_factors(
|
||||
lines=instance.lines,
|
||||
buses=instance.buses,
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
)
|
||||
lodf = UnitCommitment._line_outage_factors(
|
||||
lines=instance.lines,
|
||||
buses=instance.buses,
|
||||
isf=isf,
|
||||
lines = instance.lines,
|
||||
buses = instance.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]
|
||||
violations = UnitCommitment._find_violations(
|
||||
instance=instance,
|
||||
net_injections=inj,
|
||||
overflow=overflow,
|
||||
isf=isf,
|
||||
lodf=lodf,
|
||||
instance = instance,
|
||||
net_injections = inj,
|
||||
overflow = overflow,
|
||||
isf = isf,
|
||||
lodf = lodf,
|
||||
)
|
||||
@test length(violations) == 20
|
||||
end
|
||||
|
||||
@@ -9,117 +9,137 @@ using UnitCommitment, Test, LinearAlgebra
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
actual = UnitCommitment._susceptance_matrix(instance.lines)
|
||||
@test size(actual) == (20, 20)
|
||||
expected = Diagonal([29.5, 7.83, 8.82, 9.9, 10.04,
|
||||
10.2, 41.45, 8.35, 3.14, 6.93,
|
||||
8.77, 6.82, 13.4, 9.91, 15.87,
|
||||
20.65, 6.46, 9.09, 8.73, 5.02])
|
||||
@test round.(actual, digits=2) == expected
|
||||
expected = Diagonal([
|
||||
29.5,
|
||||
7.83,
|
||||
8.82,
|
||||
9.9,
|
||||
10.04,
|
||||
10.2,
|
||||
41.45,
|
||||
8.35,
|
||||
3.14,
|
||||
6.93,
|
||||
8.77,
|
||||
6.82,
|
||||
13.4,
|
||||
9.91,
|
||||
15.87,
|
||||
20.65,
|
||||
6.46,
|
||||
9.09,
|
||||
8.73,
|
||||
5.02,
|
||||
])
|
||||
@test round.(actual, digits = 2) == expected
|
||||
end
|
||||
|
||||
|
||||
@testset "Reduced incidence matrix" begin
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
actual = UnitCommitment._reduced_incidence_matrix(
|
||||
lines=instance.lines,
|
||||
buses=instance.buses,
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
)
|
||||
@test size(actual) == (20, 13)
|
||||
@test actual[1, 1] == -1.0
|
||||
@test actual[3, 1] == 1.0
|
||||
@test actual[4, 1] == 1.0
|
||||
@test actual[5, 1] == 1.0
|
||||
@test actual[3, 2] == -1.0
|
||||
@test actual[6, 2] == 1.0
|
||||
@test actual[4, 3] == -1.0
|
||||
@test actual[6, 3] == -1.0
|
||||
@test actual[7, 3] == 1.0
|
||||
@test actual[8, 3] == 1.0
|
||||
@test actual[9, 3] == 1.0
|
||||
@test actual[2, 4] == -1.0
|
||||
@test actual[5, 4] == -1.0
|
||||
@test actual[7, 4] == -1.0
|
||||
@test actual[10, 4] == 1.0
|
||||
@test actual[10, 5] == -1.0
|
||||
@test actual[11, 5] == 1.0
|
||||
@test actual[12, 5] == 1.0
|
||||
@test actual[13, 5] == 1.0
|
||||
@test actual[8, 6] == -1.0
|
||||
@test actual[14, 6] == 1.0
|
||||
@test actual[15, 6] == 1.0
|
||||
@test actual[14, 7] == -1.0
|
||||
@test actual[9, 8] == -1.0
|
||||
@test actual[15, 8] == -1.0
|
||||
@test actual[16, 8] == 1.0
|
||||
@test actual[17, 8] == 1.0
|
||||
@test actual[16, 9] == -1.0
|
||||
@test actual[18, 9] == 1.0
|
||||
@test actual[11, 10] == -1.0
|
||||
@test actual[18, 10] == -1.0
|
||||
@test actual[12, 11] == -1.0
|
||||
@test actual[19, 11] == 1.0
|
||||
@test actual[13, 12] == -1.0
|
||||
@test actual[19, 12] == -1.0
|
||||
@test actual[20, 12] == 1.0
|
||||
@test actual[17, 13] == -1.0
|
||||
@test actual[20, 13] == -1.0
|
||||
@test actual[1, 1] == -1.0
|
||||
@test actual[3, 1] == 1.0
|
||||
@test actual[4, 1] == 1.0
|
||||
@test actual[5, 1] == 1.0
|
||||
@test actual[3, 2] == -1.0
|
||||
@test actual[6, 2] == 1.0
|
||||
@test actual[4, 3] == -1.0
|
||||
@test actual[6, 3] == -1.0
|
||||
@test actual[7, 3] == 1.0
|
||||
@test actual[8, 3] == 1.0
|
||||
@test actual[9, 3] == 1.0
|
||||
@test actual[2, 4] == -1.0
|
||||
@test actual[5, 4] == -1.0
|
||||
@test actual[7, 4] == -1.0
|
||||
@test actual[10, 4] == 1.0
|
||||
@test actual[10, 5] == -1.0
|
||||
@test actual[11, 5] == 1.0
|
||||
@test actual[12, 5] == 1.0
|
||||
@test actual[13, 5] == 1.0
|
||||
@test actual[8, 6] == -1.0
|
||||
@test actual[14, 6] == 1.0
|
||||
@test actual[15, 6] == 1.0
|
||||
@test actual[14, 7] == -1.0
|
||||
@test actual[9, 8] == -1.0
|
||||
@test actual[15, 8] == -1.0
|
||||
@test actual[16, 8] == 1.0
|
||||
@test actual[17, 8] == 1.0
|
||||
@test actual[16, 9] == -1.0
|
||||
@test actual[18, 9] == 1.0
|
||||
@test actual[11, 10] == -1.0
|
||||
@test actual[18, 10] == -1.0
|
||||
@test actual[12, 11] == -1.0
|
||||
@test actual[19, 11] == 1.0
|
||||
@test actual[13, 12] == -1.0
|
||||
@test actual[19, 12] == -1.0
|
||||
@test actual[20, 12] == 1.0
|
||||
@test actual[17, 13] == -1.0
|
||||
@test actual[20, 13] == -1.0
|
||||
end
|
||||
|
||||
|
||||
@testset "Injection Shift Factors (ISF)" begin
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
actual = UnitCommitment._injection_shift_factors(
|
||||
lines=instance.lines,
|
||||
buses=instance.buses,
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
)
|
||||
@test size(actual) == (20, 13)
|
||||
@test round.(actual, digits=2) == [
|
||||
-0.84 -0.75 -0.67 -0.61 -0.63 -0.66 -0.66 -0.65 -0.65 -0.64 -0.63 -0.63 -0.64;
|
||||
-0.16 -0.25 -0.33 -0.39 -0.37 -0.34 -0.34 -0.35 -0.35 -0.36 -0.37 -0.37 -0.36;
|
||||
0.03 -0.53 -0.15 -0.1 -0.12 -0.14 -0.14 -0.14 -0.13 -0.13 -0.12 -0.12 -0.13;
|
||||
0.06 -0.14 -0.32 -0.22 -0.25 -0.3 -0.3 -0.29 -0.28 -0.27 -0.25 -0.26 -0.27;
|
||||
0.08 -0.07 -0.2 -0.29 -0.26 -0.22 -0.22 -0.22 -0.23 -0.25 -0.26 -0.26 -0.24;
|
||||
0.03 0.47 -0.15 -0.1 -0.12 -0.14 -0.14 -0.14 -0.13 -0.13 -0.12 -0.12 -0.13;
|
||||
0.08 0.31 0.5 -0.3 -0.03 0.36 0.36 0.28 0.23 0.1 -0.0 0.02 0.17;
|
||||
0.0 0.01 0.02 -0.01 -0.22 -0.63 -0.63 -0.45 -0.41 -0.32 -0.24 -0.25 -0.36;
|
||||
0.0 0.01 0.01 -0.01 -0.12 -0.17 -0.17 -0.26 -0.24 -0.18 -0.14 -0.14 -0.21;
|
||||
-0.0 -0.02 -0.03 0.02 -0.66 -0.2 -0.2 -0.29 -0.36 -0.5 -0.63 -0.61 -0.43;
|
||||
-0.0 -0.01 -0.02 0.01 0.21 -0.12 -0.12 -0.17 -0.28 -0.53 0.18 0.15 -0.03;
|
||||
-0.0 -0.0 -0.0 0.0 0.03 -0.02 -0.02 -0.03 -0.02 0.01 -0.52 -0.17 -0.09;
|
||||
-0.0 -0.01 -0.01 0.01 0.11 -0.06 -0.06 -0.09 -0.05 0.02 -0.28 -0.59 -0.31;
|
||||
-0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -1.0 -0.0 -0.0 -0.0 -0.0 -0.0 0.0 ;
|
||||
0.0 0.01 0.02 -0.01 -0.22 0.37 0.37 -0.45 -0.41 -0.32 -0.24 -0.25 -0.36;
|
||||
0.0 0.01 0.02 -0.01 -0.21 0.12 0.12 0.17 -0.72 -0.47 -0.18 -0.15 0.03;
|
||||
0.0 0.01 0.01 -0.01 -0.14 0.08 0.08 0.12 0.07 -0.03 -0.2 -0.24 -0.6 ;
|
||||
0.0 0.01 0.02 -0.01 -0.21 0.12 0.12 0.17 0.28 -0.47 -0.18 -0.15 0.03;
|
||||
-0.0 -0.0 -0.0 0.0 0.03 -0.02 -0.02 -0.03 -0.02 0.01 0.48 -0.17 -0.09;
|
||||
-0.0 -0.01 -0.01 0.01 0.14 -0.08 -0.08 -0.12 -0.07 0.03 0.2 0.24 -0.4 ]
|
||||
@test round.(actual, digits = 2) == [
|
||||
-0.84 -0.75 -0.67 -0.61 -0.63 -0.66 -0.66 -0.65 -0.65 -0.64 -0.63 -0.63 -0.64
|
||||
-0.16 -0.25 -0.33 -0.39 -0.37 -0.34 -0.34 -0.35 -0.35 -0.36 -0.37 -0.37 -0.36
|
||||
0.03 -0.53 -0.15 -0.1 -0.12 -0.14 -0.14 -0.14 -0.13 -0.13 -0.12 -0.12 -0.13
|
||||
0.06 -0.14 -0.32 -0.22 -0.25 -0.3 -0.3 -0.29 -0.28 -0.27 -0.25 -0.26 -0.27
|
||||
0.08 -0.07 -0.2 -0.29 -0.26 -0.22 -0.22 -0.22 -0.23 -0.25 -0.26 -0.26 -0.24
|
||||
0.03 0.47 -0.15 -0.1 -0.12 -0.14 -0.14 -0.14 -0.13 -0.13 -0.12 -0.12 -0.13
|
||||
0.08 0.31 0.5 -0.3 -0.03 0.36 0.36 0.28 0.23 0.1 -0.0 0.02 0.17
|
||||
0.0 0.01 0.02 -0.01 -0.22 -0.63 -0.63 -0.45 -0.41 -0.32 -0.24 -0.25 -0.36
|
||||
0.0 0.01 0.01 -0.01 -0.12 -0.17 -0.17 -0.26 -0.24 -0.18 -0.14 -0.14 -0.21
|
||||
-0.0 -0.02 -0.03 0.02 -0.66 -0.2 -0.2 -0.29 -0.36 -0.5 -0.63 -0.61 -0.43
|
||||
-0.0 -0.01 -0.02 0.01 0.21 -0.12 -0.12 -0.17 -0.28 -0.53 0.18 0.15 -0.03
|
||||
-0.0 -0.0 -0.0 0.0 0.03 -0.02 -0.02 -0.03 -0.02 0.01 -0.52 -0.17 -0.09
|
||||
-0.0 -0.01 -0.01 0.01 0.11 -0.06 -0.06 -0.09 -0.05 0.02 -0.28 -0.59 -0.31
|
||||
-0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -1.0 -0.0 -0.0 -0.0 -0.0 -0.0 0.0
|
||||
0.0 0.01 0.02 -0.01 -0.22 0.37 0.37 -0.45 -0.41 -0.32 -0.24 -0.25 -0.36
|
||||
0.0 0.01 0.02 -0.01 -0.21 0.12 0.12 0.17 -0.72 -0.47 -0.18 -0.15 0.03
|
||||
0.0 0.01 0.01 -0.01 -0.14 0.08 0.08 0.12 0.07 -0.03 -0.2 -0.24 -0.6
|
||||
0.0 0.01 0.02 -0.01 -0.21 0.12 0.12 0.17 0.28 -0.47 -0.18 -0.15 0.03
|
||||
-0.0 -0.0 -0.0 0.0 0.03 -0.02 -0.02 -0.03 -0.02 0.01 0.48 -0.17 -0.09
|
||||
-0.0 -0.01 -0.01 0.01 0.14 -0.08 -0.08 -0.12 -0.07 0.03 0.2 0.24 -0.4
|
||||
]
|
||||
end
|
||||
|
||||
@testset "Line Outage Distribution Factors (LODF)" begin
|
||||
instance = UnitCommitment.read_benchmark("test/case14")
|
||||
isf_before = UnitCommitment._injection_shift_factors(
|
||||
lines=instance.lines,
|
||||
buses=instance.buses,
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
)
|
||||
lodf = UnitCommitment._line_outage_factors(
|
||||
lines=instance.lines,
|
||||
buses=instance.buses,
|
||||
isf=isf_before,
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
isf = isf_before,
|
||||
)
|
||||
for contingency in instance.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,
|
||||
isf_after = UnitCommitment._injection_shift_factors(
|
||||
lines = instance.lines,
|
||||
buses = instance.buses,
|
||||
)
|
||||
lc.susceptance = prev_susceptance
|
||||
for lm in instance.lines
|
||||
expected = isf_after[lm.offset, :]
|
||||
actual = isf_before[lm.offset, :] +
|
||||
lodf[lm.offset, lc.offset] * isf_before[lc.offset, :]
|
||||
actual =
|
||||
isf_before[lm.offset, :] +
|
||||
lodf[lm.offset, lc.offset] * isf_before[lc.offset, :]
|
||||
@test norm(expected - actual) < 1e-6
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,36 +4,40 @@
|
||||
|
||||
using UnitCommitment, JSON, GZip, DataStructures
|
||||
|
||||
parse_case14() = JSON.parse(GZip.gzopen("../instances/test/case14.json.gz"),
|
||||
dicttype=()->DefaultOrderedDict(nothing))
|
||||
function parse_case14()
|
||||
return JSON.parse(
|
||||
GZip.gzopen("../instances/test/case14.json.gz"),
|
||||
dicttype = () -> DefaultOrderedDict(nothing),
|
||||
)
|
||||
end
|
||||
|
||||
@testset "Validation" begin
|
||||
@testset "repair!" begin
|
||||
|
||||
@testset "Cost curve should be convex" begin
|
||||
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)
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
@testset "Startup limit must be greater than Pmin" begin
|
||||
json = parse_case14()
|
||||
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)
|
||||
instance = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(instance) == 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)
|
||||
instance = UnitCommitment._from_json(json, repair = false)
|
||||
@test UnitCommitment.repair!(instance) == 4
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user