Skip to content

Commit

Permalink
Merge pull request #142 from Breakthrough-Energy/daniel/constraint_fu…
Browse files Browse the repository at this point in the history
…nctions

refactor: simplify _build_model by defining functions that add constraints
  • Loading branch information
danielolsen authored Jul 14, 2021
2 parents f38cb6e + 659da0d commit 5717b13
Show file tree
Hide file tree
Showing 5 changed files with 433 additions and 301 deletions.
47 changes: 23 additions & 24 deletions src/loop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@ function interval_loop(factory_like, model_kwargs::Dict,
storage = model_kwargs["storage"]
demand_flexibility = model_kwargs["demand_flexibility"]
sets = _make_sets(case, storage)
storage_enabled = (sets.num_storage > 0)
unused_load_shed_intervals_turnoff = 14
# Start looping
for i in 1:n_interval
# These must be declared global so that they persist through the loop.
global m, voi, pg0, storage_e0, intervals_without_loadshed
global m, pg0, storage_e0, intervals_without_loadshed
@show ("load_shed_enabled" in keys(model_kwargs))
@show ("BarHomogeneous" in keys(solver_kwargs))
interval_start = start_index + (i - 1) * interval
Expand All @@ -60,22 +59,22 @@ function interval_loop(factory_like, model_kwargs::Dict,
end
if i == 1
# Build a model with no initial ramp constraint
if storage_enabled
if storage.enabled
model_kwargs["storage_e0"] = storage.sd_table.InitialStorage
end
m = new_model(factory_like)
JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
m, voi = _build_model(m; symbolize(model_kwargs)...)
m = _build_model(m; symbolize(model_kwargs)...)
elseif i == 2
# Build a model with an initial ramp constraint
model_kwargs["initial_ramp_enabled"] = true
model_kwargs["initial_ramp_g0"] = pg0
if storage_enabled
if storage.enabled
model_kwargs["storage_e0"] = storage_e0
end
m = new_model(factory_like)
JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
m, voi = _build_model(m; symbolize(model_kwargs)...)
m = _build_model(m; symbolize(model_kwargs)...)
else
# Reassign right-hand-side of constraints to match profiles
bus_demand = _make_bus_demand(case, interval_start, interval_end)
Expand All @@ -87,48 +86,48 @@ function interval_loop(factory_like, model_kwargs::Dict,
case.wind[interval_start:interval_end, 2:end]))
for t in 1:interval, b in sets.load_bus_idx
JuMP.set_normalized_rhs(
voi.powerbalance[b, t], bus_demand[b, t])
m[:powerbalance][b, t], bus_demand[b, t])
end
if (("load_shed_enabled" in keys(model_kwargs))
&& (model_kwargs["load_shed_enabled"] == true))
for t in 1:interval, i in 1:length(sets.load_bus_idx)
JuMP.set_normalized_rhs(
voi.load_shed_ub[i, t], bus_demand[sets.load_bus_idx[i], t]
m[:load_shed_ub][i, t], bus_demand[sets.load_bus_idx[i], t]
)
end
end
for t in 1:interval, g in 1:sets.num_hydro
JuMP.set_normalized_rhs(
voi.hydro_fixed[g, t], simulation_hydro[g, t])
m[:hydro_fixed][g, t], simulation_hydro[g, t])
end
for t in 1:interval, g in 1:sets.num_solar
JuMP.set_normalized_rhs(
voi.solar_max[g, t], simulation_solar[g, t])
m[:solar_max][g, t], simulation_solar[g, t])
end
for t in 1:interval, g in 1:sets.num_wind
JuMP.set_normalized_rhs(
voi.wind_max[g, t], simulation_wind[g, t])
m[:wind_max][g, t], simulation_wind[g, t])
end
# Re-assign right-hand-side for initial conditions
noninf_ramp_idx = findall(case.gen_ramp30 .!= Inf)
for g in noninf_ramp_idx
rhs = case.gen_ramp30[g] * 2 + pg0[g]
JuMP.set_normalized_rhs(voi.initial_rampup[g], rhs)
JuMP.set_normalized_rhs(m[:initial_rampup][g], rhs)
rhs = case.gen_ramp30[g] * 2 - pg0[g]
JuMP.set_normalized_rhs(voi.initial_rampdown[g], rhs)
JuMP.set_normalized_rhs(m[:initial_rampdown][g], rhs)
end
if storage_enabled
if storage.enabled
for s in 1:sets.num_storage
JuMP.set_normalized_rhs(voi.initial_soc[s], storage_e0[s])
JuMP.set_normalized_rhs(m[:initial_soc][s], storage_e0[s])
end
end
if demand_flexibility.enabled
for t in 1:interval, i in 1:length(sets.load_bus_idx)
JuMP.set_upper_bound(
voi.load_shift_up[i, t], bus_flex_amt[sets.load_bus_idx[i], t]
m[:load_shift_up][i, t], bus_flex_amt[sets.load_bus_idx[i], t]
)
JuMP.set_upper_bound(
voi.load_shift_dn[i, t], bus_flex_amt[sets.load_bus_idx[i], t]
m[:load_shift_dn][i, t], bus_flex_amt[sets.load_bus_idx[i], t]
)
end
end
Expand All @@ -143,13 +142,13 @@ function interval_loop(factory_like, model_kwargs::Dict,
status = JuMP.termination_status(m)
if status == JuMP.MOI.OPTIMAL
f = JuMP.objective_value(m)
results = get_results(f, voi, model_kwargs["case"])
results = get_results(f, model_kwargs["case"])
break
elseif ((status == JuMP.MOI.LOCALLY_SOLVED)
& ("load_shed_enabled" in keys(model_kwargs)))
# if load shedding is enabled, we'll accept 'suboptimal'
f = JuMP.objective_value(m)
results = get_results(f, voi, model_kwargs["case"])
results = get_results(f, model_kwargs["case"])
break
elseif ((status in numeric_statuses)
& (JuMP.solver_name(m) == "Gurobi")
Expand All @@ -165,7 +164,7 @@ function interval_loop(factory_like, model_kwargs::Dict,
println("rebuild with load shed")
m = new_model(factory_like)
JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
m, voi = _build_model(m; symbolize(model_kwargs)...)
m = _build_model(m; symbolize(model_kwargs)...)
intervals_without_loadshed = 0
elseif ((JuMP.solver_name(m) == "Gurobi")
& !("BarHomogeneous" in keys(solver_kwargs)))
Expand All @@ -178,7 +177,7 @@ function interval_loop(factory_like, model_kwargs::Dict,
println("rebuild with load shed")
m = new_model(factory_like)
JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
m, voi = _build_model(m; symbolize(model_kwargs)...)
m = _build_model(m; symbolize(model_kwargs)...)
intervals_without_loadshed = 0
else
# Something has gone very wrong
Expand All @@ -189,7 +188,7 @@ function interval_loop(factory_like, model_kwargs::Dict,
if (("load_shed_enabled" in keys(model_kwargs))
&& (model_kwargs["load_shed_enabled"] == true))
# Display where load shedding is occurring
load_shed_values = JuMP.value.(voi.load_shed)
load_shed_values = JuMP.value.(m[:load_shed])
load_shed_indices = findall(load_shed_values .> 1e-6)
if length(load_shed_indices) > 0
@show load_shed_indices
Expand All @@ -203,7 +202,7 @@ function interval_loop(factory_like, model_kwargs::Dict,

# Save initial conditions for next interval
pg0 = results.pg[:,end]
if storage_enabled
if storage.enabled
storage_e0 = results.storage_e[:,end]
end

Expand All @@ -228,7 +227,7 @@ function interval_loop(factory_like, model_kwargs::Dict,
delete!(model_kwargs, "load_shed_enabled")
m = new_model(factory_like)
JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
m, voi = _build_model(m; symbolize(model_kwargs)...)
m = _build_model(m; symbolize(model_kwargs)...)
end
end
end
Expand Down
Loading

0 comments on commit 5717b13

Please sign in to comment.