Reformat source code

feature/reserves
Alinson S. Xavier 3 years ago
parent dc693896a3
commit fd25580967

@ -30,7 +30,9 @@ function _add_ramp_eqs!(
end
for r in g.reserves
if r.type !== "flexiramp"
error("This formulation only supports flexiramp reserves, not $(r.type)")
error(
"This formulation only supports flexiramp reserves, not $(r.type)",
)
end
rn = r.name
for t in 1:model[:instance].time
@ -110,7 +112,8 @@ function _add_ramp_eqs!(
) # Eq. (24) in Wang & Hobbs (2016)
@constraint(
model,
-RD * is_on[gn, t+1] - SD * (is_on[gn, t] - is_on[gn, t+1]) -
-RD * is_on[gn, t+1] -
SD * (is_on[gn, t] - is_on[gn, t+1]) -
maxp[t] * (1 - is_on[gn, t]) <= upflexiramp[rn, gn, t]
) # first inequality of Eq. (26) in Wang & Hobbs (2016)
@constraint(
@ -137,8 +140,14 @@ function _add_ramp_eqs!(
-maxp[t] * is_on[gn, t] + minp[t] * is_on[gn, t+1] <=
upflexiramp[rn, gn, t]
) # first inequality of Eq. (28) in Wang & Hobbs (2016)
@constraint(model, upflexiramp[rn, gn, t] <= maxp[t] * is_on[gn, t+1]) # second inequality of Eq. (28) in Wang & Hobbs (2016)
@constraint(model, -maxp[t] * is_on[gn, t+1] <= dwflexiramp[rn, gn, t]) # first inequality of Eq. (29) in Wang & Hobbs (2016)
@constraint(
model,
upflexiramp[rn, gn, t] <= maxp[t] * is_on[gn, t+1]
) # second inequality of Eq. (28) in Wang & Hobbs (2016)
@constraint(
model,
-maxp[t] * is_on[gn, t+1] <= dwflexiramp[rn, gn, t]
) # first inequality of Eq. (29) in Wang & Hobbs (2016)
@constraint(
model,
dwflexiramp[rn, gn, t] <=

@ -72,14 +72,12 @@ function _add_flexiramp_reserve_eqs!(model::JuMP.Model)::Nothing
# Eq. (17) in Wang & Hobbs (2016)
eq_min_upflexiramp[r.name, t] = @constraint(
model,
sum(model[:upflexiramp][r.name, g.name, t] for g in r.units) +
model[:upflexiramp_shortfall][r.name, t] >= r.amount[t]
sum(model[:upflexiramp][r.name, g.name, t] for g in r.units) + model[:upflexiramp_shortfall][r.name, t] >= r.amount[t]
)
# Eq. (18) in Wang & Hobbs (2016)
eq_min_dwflexiramp[r.name, t] = @constraint(
model,
sum(model[:dwflexiramp][r.name, g.name, t] for g in r.units) +
model[:dwflexiramp_shortfall][r.name, t] >= r.amount[t]
sum(model[:dwflexiramp][r.name, g.name, t] for g in r.units) + model[:dwflexiramp_shortfall][r.name, t] >= r.amount[t]
)
# Account for flexiramp shortfall contribution to objective

@ -75,8 +75,10 @@ function _add_flexiramp_reserve_vars!(model::JuMP.Model, g::Unit)::Nothing
upflexiramp[r.name, g.name, t] = @variable(model) # up-flexiramp, ur_{it} in Wang & Hobbs (2016)
dwflexiramp[r.name, g.name, t] = @variable(model) # down-flexiramp, dr_{it} in Wang & Hobbs (2016)
if (r.name, t) keys(upflexiramp_shortfall)
upflexiramp_shortfall[r.name, t] = @variable(model, lower_bound = 0)
dwflexiramp_shortfall[r.name, t] = @variable(model, lower_bound = 0)
upflexiramp_shortfall[r.name, t] =
@variable(model, lower_bound = 0)
dwflexiramp_shortfall[r.name, t] =
@variable(model, lower_bound = 0)
if r.shortfall_penalty < 0
set_upper_bound(upflexiramp_shortfall[r.name, t], 0.0)
set_upper_bound(dwflexiramp_shortfall[r.name, t], 0.0)
@ -204,14 +206,16 @@ function _add_min_uptime_downtime_eqs!(model::JuMP.Model, g::Unit)::Nothing
eq_min_uptime[g.name, 0] = @constraint(
model,
sum(
switch_off[g.name, i] for i in 1:(g.min_uptime-g.initial_status) if i <= T
switch_off[g.name, i] for
i in 1:(g.min_uptime-g.initial_status) if i <= T
) == 0
)
else
eq_min_downtime[g.name, 0] = @constraint(
model,
sum(
switch_on[g.name, i] for i in 1:(g.min_downtime+g.initial_status) if i <= T
switch_on[g.name, i] for
i in 1:(g.min_downtime+g.initial_status) if i <= T
) == 0
)
end

@ -15,7 +15,8 @@ function solution(model::JuMP.Model)::OrderedDict
value(model[:is_on][g.name, t]) * g.min_power_cost[t] + sum(
Float64[
value(model[:segprod][g.name, t, k]) *
g.cost_segments[k].cost[t] for k in 1:length(g.cost_segments)
g.cost_segments[k].cost[t] for
k in 1:length(g.cost_segments)
],
) for t in 1:T
]
@ -24,7 +25,8 @@ function solution(model::JuMP.Model)::OrderedDict
return [
value(model[:is_on][g.name, t]) * g.min_power[t] + sum(
Float64[
value(model[:segprod][g.name, t, k]) for k in 1:length(g.cost_segments)
value(model[:segprod][g.name, t, k]) for
k in 1:length(g.cost_segments)
],
) for t in 1:T
]
@ -61,42 +63,44 @@ function solution(model::JuMP.Model)::OrderedDict
sol["Spinning reserve (MW)"] = OrderedDict(
r.name => OrderedDict(
g.name => [
value(model[:reserve][r.name, g.name, t]) for t in 1:instance.time
value(model[:reserve][r.name, g.name, t]) for
t in 1:instance.time
] for g in r.units
) for r in instance.reserves if r.type == "spinning"
)
sol["Spinning reserve shortfall (MW)"] = OrderedDict(
r.name => [
value(model[:reserve_shortfall][r.name, t]) for t in 1:instance.time
value(model[:reserve_shortfall][r.name, t]) for
t in 1:instance.time
] for r in instance.reserves if r.type == "spinning"
)
sol["Up-flexiramp (MW)"] = OrderedDict(
r.name => OrderedDict(
g.name => [
value(model[:upflexiramp][r.name, g.name, t])
for t in 1:instance.time
value(model[:upflexiramp][r.name, g.name, t]) for
t in 1:instance.time
] for g in r.units
) for r in instance.reserves if r.type == "flexiramp"
)
sol["Up-flexiramp shortfall (MW)"] = OrderedDict(
r.name => [
value(model[:upflexiramp_shortfall][r.name, t])
for t in 1:instance.time
] for r in instance.reserves if r.type == "flexiramp"
value(model[:upflexiramp_shortfall][r.name, t]) for
t in 1:instance.time
] for r in instance.reserves if r.type == "flexiramp"
)
sol["Down-flexiramp (MW)"] = OrderedDict(
r.name => OrderedDict(
g.name => [
value(model[:dwflexiramp][r.name, g.name, t])
for t in 1:instance.time
value(model[:dwflexiramp][r.name, g.name, t]) for
t in 1:instance.time
] for g in r.units
) for r in instance.reserves if r.type == "flexiramp"
)
sol["Down-flexiramp shortfall (MW)"] = OrderedDict(
r.name => [
value(model[:upflexiramp_shortfall][r.name, t])
for t in 1:instance.time
] for r in instance.reserves if r.type == "flexiramp"
value(model[:upflexiramp_shortfall][r.name, t]) for
t in 1:instance.time
] for r in instance.reserves if r.type == "flexiramp"
)
return sol
end

@ -49,8 +49,8 @@ function _validate_units(instance::UnitCommitmentInstance, solution; tol = 0.01)
spinning_reserves = [r for r in unit.reserves if r.type == "spinning"]
if !isempty(spinning_reserves)
reserve += sum(
solution["Spinning reserve (MW)"][r.name][unit.name]
for r in spinning_reserves
solution["Spinning reserve (MW)"][r.name][unit.name] for
r in spinning_reserves
)
end
actual_production_cost = solution["Production cost (\$)"][unit.name]
@ -109,7 +109,7 @@ function _validate_units(instance::UnitCommitmentInstance, solution; tol = 0.01)
for r in instance.reserves
if r.type == "spinning"
if unit r.units &&
(unit in keys(solution["Spinning reserve (MW)"][r.name]))
(unit in keys(solution["Spinning reserve (MW)"][r.name]))
@error @sprintf(
"Unit %s is not eligible to provide reserve %s",
unit.name,
@ -308,14 +308,16 @@ function _validate_reserve_and_demand(instance, solution, tol = 0.01)
ps_load = 0
if length(instance.price_sensitive_loads) > 0
ps_load = sum(
solution["Price-sensitive loads (MW)"][ps.name][t] for ps in instance.price_sensitive_loads
solution["Price-sensitive loads (MW)"][ps.name][t] for
ps in instance.price_sensitive_loads
)
end
production =
sum(solution["Production (MW)"][g.name][t] for g in instance.units)
if "Load curtail (MW)" in keys(solution)
load_curtail = sum(
solution["Load curtail (MW)"][b.name][t] for b in instance.buses
solution["Load curtail (MW)"][b.name][t] for
b in instance.buses
)
end
balance = fixed_load - load_curtail - production + ps_load
@ -337,9 +339,11 @@ function _validate_reserve_and_demand(instance, solution, tol = 0.01)
for r in instance.reserves
if r.type == "spinning"
provided = sum(
solution["Spinning reserve (MW)"][r.name][g.name][t] for g in r.units
solution["Spinning reserve (MW)"][r.name][g.name][t] for
g in r.units
)
shortfall = solution["Spinning reserve shortfall (MW)"][r.name][t]
shortfall =
solution["Spinning reserve shortfall (MW)"][r.name][t]
required = r.amount[t]
if provided + shortfall < required - tol
@ -354,7 +358,8 @@ function _validate_reserve_and_demand(instance, solution, tol = 0.01)
end
elseif r.type == "flexiramp"
upflexiramp = sum(
solution["Up-flexiramp (MW)"][r.name][g.name][t] for g in r.units
solution["Up-flexiramp (MW)"][r.name][g.name][t] for
g in r.units
)
upflexiramp_shortfall =
solution["Up-flexiramp shortfall (MW)"][r.name][t]
@ -371,9 +376,11 @@ function _validate_reserve_and_demand(instance, solution, tol = 0.01)
end
dwflexiramp = sum(
solution["Down-flexiramp (MW)"][r.name][g.name][t] for g in r.units
solution["Down-flexiramp (MW)"][r.name][g.name][t] for
g in r.units
)
dwflexiramp_shortfall = solution["Down-flexiramp shortfall (MW)"][r.name][t]
dwflexiramp_shortfall =
solution["Down-flexiramp shortfall (MW)"][r.name][t]
if dwflexiramp + dwflexiramp_shortfall < r.amount[t] - tol
@error @sprintf(

@ -20,7 +20,7 @@ import UnitCommitment:
function _test(
formulation::Formulation;
instances=["test/case14"],
instances = ["test/case14"],
dump::Bool = false,
)::Nothing
for instance_name in instances

Loading…
Cancel
Save