Skip to content

Commit ee497e5

Browse files
Condensed min up & downtime constraints.
1 parent 6dbbd2b commit ee497e5

File tree

1 file changed

+44
-56
lines changed

1 file changed

+44
-56
lines changed

switch_model/generators/core/commit/operate.py

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@
1919
'switch_model.generators.core.build', 'switch_model.generators.core.dispatch'
2020
)
2121

22+
def _min_up_tp_window(m, g, tp):
23+
"""
24+
how many timepoints must the project stay on once it's started?
25+
note: StartupGenCapacity and ShutdownGenCapacity are assumed to occur
26+
at the start of the timepoint
27+
"""
28+
return int(round(m.gen_min_uptime[g] / m.ts_duration_of_tp[m.tp_ts[tp]]))
29+
def _min_down_tp_window(m, g, tp):
30+
"""
31+
how many timepoints must the project stay off once it's shutdown?
32+
note: StartupGenCapacity and ShutdownGenCapacity are assumed to occur
33+
at the start of the timepoint
34+
"""
35+
return int(round(m.gen_min_downtime[g] / m.ts_duration_of_tp[m.tp_ts[tp]]))
36+
37+
2238
def define_components(mod):
2339
"""
2440
@@ -291,73 +307,45 @@ def define_components(mod):
291307
default=0.0)
292308
mod.UPTIME_CONSTRAINED_GEN_TPS = Set(dimen=2, initialize=lambda m: [
293309
(g, tp)
294-
for g in m.GENERATION_PROJECTS if m.gen_min_uptime[g] > 0.0
295-
for tp in m.TPS_FOR_GEN[g]
310+
for g in m.GENERATION_PROJECTS
311+
if m.gen_min_uptime[g] > 0.0
312+
for tp in m.TPS_FOR_GEN[g]
313+
if _min_up_tp_window(m, g ,tp) >= 0
296314
])
297315
mod.DOWNTIME_CONSTRAINED_GEN_TPS = Set(dimen=2, initialize=lambda m: [
298316
(g, tp)
299-
for g in m.GENERATION_PROJECTS if m.gen_min_downtime[g] > 0.0
300-
for tp in m.TPS_FOR_GEN[g]
317+
for g in m.GENERATION_PROJECTS
318+
if m.gen_min_downtime[g] > 0.0
319+
for tp in m.TPS_FOR_GEN[g]
320+
if _min_down_tp_window(m, g, tp) >= 0
301321
])
302322

303323
def tp_prev(m, tp, n=1):
304324
# find nth previous timepoint, wrapping from start to end of day
305325
return m.TPS_IN_TS[m.tp_ts[tp]].prevw(tp, n)
306-
# min_time_projects = set()
307-
def min_time_rule(m, g, tp, up):
308-
""" This uses a simple rule: all capacity turned on in the last x
309-
hours must still be on now (or all capacity recently turned off
310-
must still be off)."""
311-
312-
# how many timepoints must the project stay on/off once it's
313-
# started/shutdown?
314-
# note: StartupGenCapacity and ShutdownGenCapacity are assumed to occur at the start of
315-
# the timepoint
316-
n_tp = int(round(
317-
(m.gen_min_uptime[g] if up else m.gen_min_downtime[g])
318-
/ m.ts_duration_of_tp[m.tp_ts[tp]]
319-
))
320-
if n_tp == 0:
321-
# project can be shutdown and restarted in the same timepoint
322-
rule = Constraint.Skip
323-
else:
324-
# note: this rule stops one short of n_tp steps back (normal
325-
# behavior of range()), because the current timepoint is
326-
# included in the duration when the capacity will be on/off.
327-
if up:
328-
rule = (
329-
# online capacity >= recent startups
330-
# (all recent startups are still online)
331-
m.CommitGen[g, tp]
332-
>=
333-
sum(m.StartupGenCapacity[g, tp_prev(m, tp, i)] for i in range(n_tp))
334-
)
335-
else:
336-
# Find the largest fraction of capacity that could have
337-
# been committed in the last x hours, including the
338-
# current hour. We assume that everything above this band
339-
# must remain turned off (e.g., on maintenance outage).
340-
# Note: this band extends one step prior to the first
341-
# relevant shutdown, since that capacity could have been
342-
# online in the prior step.
343-
committable_fraction = m.gen_availability[g] * max(
344-
m.gen_max_commit_fraction[g, tp_prev(m, tp, i)]
345-
for i in range(n_tp+1)
346-
)
347-
rule = (
348-
# committable capacity - committed >= recent shutdowns
349-
# (all recent shutdowns are still offline)
350-
m.GenCapacityInTP[g, tp] * committable_fraction
351-
- m.CommitGen[g, tp]
352-
>=
353-
sum(m.ShutdownGenCapacity[g, tp_prev(m, tp, i)] for i in range(n_tp))
354-
)
355-
return rule
356326
mod.Enforce_Min_Uptime = Constraint(
357-
mod.UPTIME_CONSTRAINED_GEN_TPS, rule=lambda *a: min_time_rule(*a, up=True)
327+
mod.UPTIME_CONSTRAINED_GEN_TPS,
328+
doc="All capacity turned on in the last x hours must still be on now",
329+
rule=lambda m, g, tp: (
330+
m.CommitGen[g, tp]
331+
>=
332+
sum(m.StartupGenCapacity[g, tp_prev(m, tp, i)]
333+
for i in range(_min_up_tp_window(m, g ,tp))
334+
)
335+
)
358336
)
359337
mod.Enforce_Min_Downtime = Constraint(
360-
mod.DOWNTIME_CONSTRAINED_GEN_TPS, rule=lambda *a: min_time_rule(*a, up=False)
338+
mod.DOWNTIME_CONSTRAINED_GEN_TPS,
339+
doc=("All recently shutdown capacity remains offline: "
340+
"committed <= committable capacity - recent shutdowns"),
341+
rule=lambda m, g, tp: (
342+
m.CommitGen[g, tp]
343+
<=
344+
m.CommitUpperLimit[g, tp]
345+
- sum(m.ShutdownGenCapacity[g, tp_prev(m, tp, i)]
346+
for i in range(_min_down_tp_window(m, g, tp))
347+
)
348+
)
361349
)
362350

363351
# Dispatch limits relative to committed capacity.

0 commit comments

Comments
 (0)