Break down model.jl

This commit is contained in:
2021-05-29 18:33:16 -05:00
parent 4e8426beba
commit 483c793d49
17 changed files with 545 additions and 465 deletions

75
src/transform/initcond.jl Normal file
View File

@@ -0,0 +1,75 @@
# 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 JuMP
"""
generate_initial_conditions!(instance, optimizer)
Generates feasible initial conditions for the given instance, by constructing
and solving a single-period mixed-integer optimization problem, using the given
optimizer. The instance is modified in-place.
"""
function generate_initial_conditions!(
instance::UnitCommitmentInstance,
optimizer,
)::Nothing
G = instance.units
B = instance.buses
t = 1
mip = JuMP.Model(optimizer)
# Decision variables
@variable(mip, x[G], Bin)
@variable(mip, p[G] >= 0)
# Constraint: Minimum power
@constraint(mip, min_power[g in G], p[g] >= g.min_power[t] * x[g])
# Constraint: Maximum power
@constraint(mip, max_power[g in G], p[g] <= g.max_power[t] * x[g])
# Constraint: Production equals demand
@constraint(
mip,
power_balance,
sum(b.load[t] for b in B) == sum(p[g] for g in G)
)
# Constraint: Must run
for g in G
if g.must_run[t]
@constraint(mip, x[g] == 1)
end
end
# Objective function
function cost_slope(g)
mw = g.min_power[t]
c = g.min_power_cost[t]
for k in g.cost_segments
mw += k.mw[t]
c += k.mw[t] * k.cost[t]
end
if mw < 1e-3
return 0.0
else
return c / mw
end
end
@objective(mip, Min, sum(p[g] * cost_slope(g) for g in G))
JuMP.optimize!(mip)
for g in G
if JuMP.value(x[g]) > 0
g.initial_power = JuMP.value(p[g])
g.initial_status = 24
else
g.initial_power = 0
g.initial_status = -24
end
end
return
end

52
src/transform/slice.jl Normal file
View File

@@ -0,0 +1,52 @@
# 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.
"""
slice(instance, range)
Creates a new instance, with only a subset of the time periods.
This function does not modify the provided instance. The initial
conditions are also not modified.
Example
-------
# Build a 2-hour UC instance
instance = UnitCommitment.read_benchmark("test/case14")
modified = UnitCommitment.slice(instance, 1:2)
"""
function slice(
instance::UnitCommitmentInstance,
range::UnitRange{Int},
)::UnitCommitmentInstance
modified = deepcopy(instance)
modified.time = length(range)
modified.power_balance_penalty = modified.power_balance_penalty[range]
modified.reserves.spinning = modified.reserves.spinning[range]
for u in modified.units
u.max_power = u.max_power[range]
u.min_power = u.min_power[range]
u.must_run = u.must_run[range]
u.min_power_cost = u.min_power_cost[range]
u.provides_spinning_reserves = u.provides_spinning_reserves[range]
for s in u.cost_segments
s.mw = s.mw[range]
s.cost = s.cost[range]
end
end
for b in modified.buses
b.load = b.load[range]
end
for l in modified.lines
l.normal_flow_limit = l.normal_flow_limit[range]
l.emergency_flow_limit = l.emergency_flow_limit[range]
l.flow_limit_penalty = l.flow_limit_penalty[range]
end
for ps in modified.price_sensitive_loads
ps.demand = ps.demand[range]
ps.revenue = ps.revenue[range]
end
return modified
end