mirror of
https://github.com/ANL-CEEESA/UnitCommitment.jl.git
synced 2025-12-06 16:28:51 -06:00
Updated randomize, validate and initial conditions
This commit is contained in:
@@ -17,24 +17,29 @@ function generate_initial_conditions!(
|
|||||||
)::Nothing
|
)::Nothing
|
||||||
G = sc.thermal_units
|
G = sc.thermal_units
|
||||||
B = sc.buses
|
B = sc.buses
|
||||||
|
PU = sc.profiled_units
|
||||||
t = 1
|
t = 1
|
||||||
mip = JuMP.Model(optimizer)
|
mip = JuMP.Model(optimizer)
|
||||||
|
|
||||||
# Decision variables
|
# Decision variables
|
||||||
@variable(mip, x[G], Bin)
|
@variable(mip, x[G], Bin)
|
||||||
@variable(mip, p[G] >= 0)
|
@variable(mip, p[G] >= 0)
|
||||||
|
@variable(mip, pu[PU])
|
||||||
|
|
||||||
# Constraint: Minimum power
|
# Constraint: Minimum power
|
||||||
@constraint(mip, min_power[g in G], p[g] >= g.min_power[t] * x[g])
|
@constraint(mip, min_power[g in G], p[g] >= g.min_power[t] * x[g])
|
||||||
|
@constraint(mip, pu_min_power[k in PU], pu[k] >= k.min_power[t])
|
||||||
|
|
||||||
# Constraint: Maximum power
|
# Constraint: Maximum power
|
||||||
@constraint(mip, max_power[g in G], p[g] <= g.max_power[t] * x[g])
|
@constraint(mip, max_power[g in G], p[g] <= g.max_power[t] * x[g])
|
||||||
|
@constraint(mip, pu_max_power[k in PU], pu[k] <= k.capacity[t])
|
||||||
|
|
||||||
# Constraint: Production equals demand
|
# Constraint: Production equals demand
|
||||||
@constraint(
|
@constraint(
|
||||||
mip,
|
mip,
|
||||||
power_balance,
|
power_balance,
|
||||||
sum(b.load[t] for b in B) == sum(p[g] for g in G)
|
sum(b.load[t] for b in B) ==
|
||||||
|
sum(p[g] for g in G) + sum(pu[k] for k in PU)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Constraint: Must run
|
# Constraint: Must run
|
||||||
@@ -58,7 +63,12 @@ function generate_initial_conditions!(
|
|||||||
return c / mw
|
return c / mw
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@objective(mip, Min, sum(p[g] * cost_slope(g) for g in G))
|
@objective(
|
||||||
|
mip,
|
||||||
|
Min,
|
||||||
|
sum(p[g] * cost_slope(g) for g in G) +
|
||||||
|
sum(pu[k] * k.cost[t] for k in PU)
|
||||||
|
)
|
||||||
|
|
||||||
JuMP.optimize!(mip)
|
JuMP.optimize!(mip)
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,10 @@ function _randomize_costs(
|
|||||||
s.cost *= α
|
s.cost *= α
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
for pu in sc.profiled_units
|
||||||
|
α = rand(rng, distribution)
|
||||||
|
pu.cost *= α
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -305,6 +305,35 @@ function _validate_units(instance::UnitCommitmentInstance, solution; tol = 0.01)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
for pu in sc.profiled_units
|
||||||
|
production = solution[sc.name]["Profiled production (MW)"][pu.name]
|
||||||
|
|
||||||
|
for t in 1:instance.time
|
||||||
|
# Unit must produce at least its minimum power
|
||||||
|
if production[t] < pu.min_power[t] - tol
|
||||||
|
@error @sprintf(
|
||||||
|
"Profiled unit %s produces below its minimum limit at time %d (%.2f < %.2f)",
|
||||||
|
pu.name,
|
||||||
|
t,
|
||||||
|
production[t],
|
||||||
|
pu.min_power[t]
|
||||||
|
)
|
||||||
|
err_count += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unit must produce at most its maximum power
|
||||||
|
if production[t] > pu.capacity[t] + tol
|
||||||
|
@error @sprintf(
|
||||||
|
"Profiled unit %s produces above its maximum limit at time %d (%.2f > %.2f)",
|
||||||
|
pu.name,
|
||||||
|
t,
|
||||||
|
production[t],
|
||||||
|
pu.capacity[t]
|
||||||
|
)
|
||||||
|
err_count += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return err_count
|
return err_count
|
||||||
end
|
end
|
||||||
@@ -316,16 +345,25 @@ function _validate_reserve_and_demand(instance, solution, tol = 0.01)
|
|||||||
load_curtail = 0
|
load_curtail = 0
|
||||||
fixed_load = sum(b.load[t] for b in sc.buses)
|
fixed_load = sum(b.load[t] for b in sc.buses)
|
||||||
ps_load = 0
|
ps_load = 0
|
||||||
|
production = 0
|
||||||
if length(sc.price_sensitive_loads) > 0
|
if length(sc.price_sensitive_loads) > 0
|
||||||
ps_load = sum(
|
ps_load = sum(
|
||||||
solution[sc.name]["Price-sensitive loads (MW)"][ps.name][t]
|
solution[sc.name]["Price-sensitive loads (MW)"][ps.name][t]
|
||||||
for ps in sc.price_sensitive_loads
|
for ps in sc.price_sensitive_loads
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
if length(sc.thermal_units) > 0
|
||||||
production = sum(
|
production = sum(
|
||||||
solution[sc.name]["Thermal production (MW)"][g.name][t] for
|
solution[sc.name]["Thermal production (MW)"][g.name][t]
|
||||||
g in sc.thermal_units
|
for g in sc.thermal_units
|
||||||
)
|
)
|
||||||
|
end
|
||||||
|
if length(sc.profiled_units) > 0
|
||||||
|
production += sum(
|
||||||
|
solution[sc.name]["Profiled production (MW)"][pu.name][t]
|
||||||
|
for pu in sc.profiled_units
|
||||||
|
)
|
||||||
|
end
|
||||||
if "Load curtail (MW)" in keys(solution)
|
if "Load curtail (MW)" in keys(solution)
|
||||||
load_curtail = sum(
|
load_curtail = sum(
|
||||||
solution[sc.name]["Load curtail (MW)"][b.name][t] for
|
solution[sc.name]["Load curtail (MW)"][b.name][t] for
|
||||||
|
|||||||
@@ -62,4 +62,22 @@ test_approx(x, y) = @test isapprox(x, y, atol = 1e-3)
|
|||||||
@test round.(system_load(sc), 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]
|
[4854.7, 4849.2, 4732.7, 4848.2, 4948.4, 5231.1, 5874.8, 5934.8]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@testset "profiled unit cost" begin
|
||||||
|
sc =
|
||||||
|
UnitCommitment.read("$FIXTURES/case14-profiled.json.gz").scenarios[1]
|
||||||
|
# Check original costs
|
||||||
|
pu1 = sc.profiled_units[1]
|
||||||
|
pu2 = sc.profiled_units[2]
|
||||||
|
test_approx(pu1.cost[1], 100.0)
|
||||||
|
test_approx(pu2.cost[1], 50.0)
|
||||||
|
randomize!(
|
||||||
|
sc,
|
||||||
|
XavQiuAhm2021.Randomization(randomize_load_profile = false),
|
||||||
|
rng = MersenneTwister(42),
|
||||||
|
)
|
||||||
|
# Check randomized costs
|
||||||
|
test_approx(pu1.cost[1], 98.039)
|
||||||
|
test_approx(pu2.cost[1], 48.385)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user