Correct optimize!, add stochastic test case

pull/25/head
Alinson S. Xavier 3 years ago
parent 20939dc4b7
commit 414128cc0b
Signed by: isoron
GPG Key ID: 0DA8E4B9E1109DCA

@ -34,19 +34,21 @@ function _enforce_transmission(;
if violation.outage_line === nothing if violation.outage_line === nothing
limit = violation.monitored_line.normal_flow_limit[violation.time] limit = violation.monitored_line.normal_flow_limit[violation.time]
@info @sprintf( @info @sprintf(
" %8.3f MW overflow in %-5s time %3d (pre-contingency)", " %8.3f MW overflow in %-5s time %3d (pre-contingency, scenario %s)",
violation.amount, violation.amount,
violation.monitored_line.name, violation.monitored_line.name,
violation.time, violation.time,
sc.name,
) )
else else
limit = violation.monitored_line.emergency_flow_limit[violation.time] limit = violation.monitored_line.emergency_flow_limit[violation.time]
@info @sprintf( @info @sprintf(
" %8.3f MW overflow in %-5s time %3d (outage: line %s)", " %8.3f MW overflow in %-5s time %3d (outage: line %s, scenario %s)",
violation.amount, violation.amount,
violation.monitored_line.name, violation.monitored_line.name,
violation.time, violation.time,
violation.outage_line.name, violation.outage_line.name,
sc.name,
) )
end end

@ -15,12 +15,11 @@ function _find_violations(
overflow = model[:overflow] overflow = model[:overflow]
length(sc.buses) > 1 || return [] length(sc.buses) > 1 || return []
violations = [] violations = []
@info "Verifying transmission limits..."
time_screening = @elapsed begin
non_slack_buses = [b for b in sc.buses if b.offset > 0] non_slack_buses = [b for b in sc.buses if b.offset > 0]
net_injection_values = [ net_injection_values = [
value(net_injection[sc.name, b.name, t]) for value(net_injection[sc.name, b.name, t]) for b in non_slack_buses,
b in non_slack_buses, t in 1:instance.time t in 1:instance.time
] ]
overflow_values = [ overflow_values = [
value(overflow[sc.name, lm.name, t]) for lm in sc.lines, value(overflow[sc.name, lm.name, t]) for lm in sc.lines,
@ -36,11 +35,6 @@ function _find_violations(
max_per_line = max_per_line, max_per_line = max_per_line,
max_per_period = max_per_period, max_per_period = max_per_period,
) )
end
@info @sprintf(
"Verified transmission limits in %.2f seconds",
time_screening
)
return violations return violations
end end

@ -10,16 +10,19 @@ function optimize!(model::JuMP.Model, method::XavQiuWanThi2019.Method)::Nothing
JuMP.set_optimizer_attribute(model, "MIPGap", gap) JuMP.set_optimizer_attribute(model, "MIPGap", gap)
@info @sprintf("MIP gap tolerance set to %f", gap) @info @sprintf("MIP gap tolerance set to %f", gap)
end end
for sc in model[:instance].scenarios initial_time = time()
large_gap = false large_gap = false
has_transmission = (length(sc.isf) > 0) has_transmission = false
for sc in model[:instance].scenarios
if length(sc.isf) > 0
has_transmission = true
end
if has_transmission && method.two_phase_gap if has_transmission && method.two_phase_gap
set_gap(1e-2) set_gap(1e-2)
large_gap = true large_gap = true
end end
JuMP.optimize!(model) end
while true while true
initial_time = time()
time_elapsed = time() - initial_time time_elapsed = time() - initial_time
time_remaining = method.time_limit - time_elapsed time_remaining = method.time_limit - time_elapsed
if time_remaining < 0 if time_remaining < 0
@ -33,14 +36,41 @@ function optimize!(model::JuMP.Model, method::XavQiuWanThi2019.Method)::Nothing
JuMP.set_time_limit_sec(model, time_remaining) JuMP.set_time_limit_sec(model, time_remaining)
@info "Solving MILP..." @info "Solving MILP..."
JuMP.optimize!(model) JuMP.optimize!(model)
has_transmission || break has_transmission || break
violations = _find_violations(
@info "Verifying transmission limits..."
time_screening = @elapsed begin
violations = []
for sc in model[:instance].scenarios
push!(
violations,
_find_violations(
model, model,
sc, sc,
max_per_line = method.max_violations_per_line, max_per_line = method.max_violations_per_line,
max_per_period = method.max_violations_per_period, max_per_period = method.max_violations_per_period,
),
)
end
end
@info @sprintf(
"Verified transmission limits in %.2f seconds",
time_screening
) )
if isempty(violations)
violations_found = false
for v in violations
if !isempty(v)
violations_found = true
end
end
if violations_found
for (i, v) in enumerate(violations)
_enforce_transmission(model, v, model[:instance].scenarios[i])
end
else
@info "No violations found" @info "No violations found"
if large_gap if large_gap
large_gap = false large_gap = false
@ -48,9 +78,6 @@ function optimize!(model::JuMP.Model, method::XavQiuWanThi2019.Method)::Nothing
else else
break break
end end
else
_enforce_transmission(model, violations, sc)
end
end end
end end
return return

@ -4,14 +4,19 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON
@testset "usage" begin function _set_flow_limits!(instance)
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
for sc in instance.scenarios for sc in instance.scenarios
sc.power_balance_penalty = [100_000 for _ in 1:instance.time] sc.power_balance_penalty = [100_000 for _ in 1:instance.time]
for line in sc.lines, t in 1:4 for line in sc.lines, t in 1:4
line.normal_flow_limit[t] = 10.0 line.normal_flow_limit[t] = 10.0
end end
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) optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
model = UnitCommitment.build_model( model = UnitCommitment.build_model(
instance = instance, instance = instance,
@ -38,3 +43,20 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON
UnitCommitment.optimize!(model) UnitCommitment.optimize!(model)
@test UnitCommitment.validate(instance, solution) @test UnitCommitment.validate(instance, solution)
end 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
end

Loading…
Cancel
Save