Skip to content

Commit 16d4086

Browse files
authored
Merge pull request #110 from switch-model/set_updates
Minor updates to sets for functionality, speed and API conformity
2 parents abad6ec + 1f4caba commit 16d4086

File tree

2 files changed

+50
-14
lines changed

2 files changed

+50
-14
lines changed

switch_model/generators/core/build.py

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,23 @@ def define_components(mod):
205205
mod.min_data_check('GENERATION_PROJECTS', 'gen_tech', 'gen_energy_source',
206206
'gen_load_zone', 'gen_max_age', 'gen_is_variable')
207207

208+
"""Construct GENS_* indexed sets efficiently with a
209+
'construction dictionary' pattern: on the first call, make a single
210+
traversal through all generation projects to generate a complete index,
211+
use that for subsequent lookups, and clean up at the last call."""
212+
def GENS_IN_ZONE_init(m, z):
213+
if not hasattr(m, 'GENS_IN_ZONE_dict'):
214+
m.GENS_IN_ZONE_dict = {_z: [] for _z in m.LOAD_ZONES}
215+
for g in m.GENERATION_PROJECTS:
216+
m.GENS_IN_ZONE_dict[m.gen_load_zone[g]].append(g)
217+
result = m.GENS_IN_ZONE_dict.pop(z)
218+
if not m.GENS_IN_ZONE_dict:
219+
del m.GENS_IN_ZONE_dict
220+
return result
208221
mod.GENS_IN_ZONE = Set(
209222
mod.LOAD_ZONES,
210-
initialize=lambda m, z: set(
211-
g for g in m.GENERATION_PROJECTS if m.gen_load_zone[g] == z))
223+
initialize=GENS_IN_ZONE_init
224+
)
212225
mod.VARIABLE_GENS = Set(
213226
initialize=mod.GENERATION_PROJECTS,
214227
filter=lambda m, g: m.gen_is_variable[g])
@@ -218,12 +231,19 @@ def define_components(mod):
218231
mod.BASELOAD_GENS = Set(
219232
initialize=mod.GENERATION_PROJECTS,
220233
filter=lambda m, g: m.gen_is_baseload[g])
221-
# TODO: use a construction dictionary or closure to create all the GENS_BY_...
222-
# indexed sets more efficiently
234+
235+
def GENS_BY_TECHNOLOGY_init(m, t):
236+
if not hasattr(m, 'GENS_BY_TECH_dict'):
237+
m.GENS_BY_TECH_dict = {_t: [] for _t in m.GENERATION_TECHNOLOGIES}
238+
for g in m.GENERATION_PROJECTS:
239+
m.GENS_BY_TECH_dict[m.gen_tech[g]].append(g)
240+
result = m.GENS_BY_TECH_dict.pop(t)
241+
if not m.GENS_BY_TECH_dict:
242+
del m.GENS_BY_TECH_dict
243+
return result
223244
mod.GENS_BY_TECHNOLOGY = Set(
224245
mod.GENERATION_TECHNOLOGIES,
225-
initialize=lambda m, t:
226-
[g for g in m.GENERATION_PROJECTS if m.gen_tech[g] == t]
246+
initialize=GENS_BY_TECHNOLOGY_init
227247
)
228248

229249
mod.CAPACITY_LIMITED_GENS = Set(within=mod.GENERATION_PROJECTS)
@@ -263,15 +283,30 @@ def define_components(mod):
263283
if g in m.MULTIFUEL_GENS
264284
else [m.gen_energy_source[g]]))
265285

286+
def GENS_BY_ENERGY_SOURCE_init(m, e):
287+
if not hasattr(m, 'GENS_BY_ENERGY_dict'):
288+
m.GENS_BY_ENERGY_dict = {_e: [] for _e in m.ENERGY_SOURCES}
289+
for g in m.GENERATION_PROJECTS:
290+
if g in m.FUEL_BASED_GENS:
291+
for f in m.FUELS_FOR_GEN[g]:
292+
m.GENS_BY_ENERGY_dict[f].append(g)
293+
else:
294+
m.GENS_BY_ENERGY_dict[m.gen_energy_source[g]].append(g)
295+
result = m.GENS_BY_ENERGY_dict.pop(e)
296+
if not m.GENS_BY_ENERGY_dict:
297+
del m.GENS_BY_ENERGY_dict
298+
return result
299+
mod.GENS_BY_ENERGY_SOURCE = Set(
300+
mod.ENERGY_SOURCES,
301+
initialize=GENS_BY_ENERGY_SOURCE_init
302+
)
266303
mod.GENS_BY_NON_FUEL_ENERGY_SOURCE = Set(
267304
mod.NON_FUEL_ENERGY_SOURCES,
268-
initialize=lambda m, s:
269-
[g for g in m.NON_FUEL_BASED_GENS if m.gen_energy_source[g] == s]
305+
initialize=lambda m, s: m.GENS_BY_ENERGY_SOURCE[s]
270306
)
271307
mod.GENS_BY_FUEL = Set(
272308
mod.FUELS,
273-
initialize=lambda m, f:
274-
[g for g in m.FUEL_BASED_GENS if f in m.FUELS_FOR_GEN[g]]
309+
initialize=lambda m, f: m.GENS_BY_ENERGY_SOURCE[f]
275310
)
276311

277312
mod.PREDETERMINED_GEN_BLD_YRS = Set(

switch_model/generators/core/dispatch.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,12 @@ def period_active_gen_rule(m, period):
164164
mod.TPS_FOR_GEN = Set(
165165
mod.GENERATION_PROJECTS,
166166
within=mod.TIMEPOINTS,
167-
rule=lambda m, g: (
167+
initialize=lambda m, g: (
168168
tp for p in m.PERIODS_FOR_GEN[g] for tp in m.TPS_IN_PERIOD[p]
169169
)
170170
)
171171

172-
def rule(m, gen, period):
172+
def init(m, gen, period):
173173
try:
174174
d = m._TPS_FOR_GEN_IN_PERIOD_dict
175175
except AttributeError:
@@ -181,8 +181,9 @@ def rule(m, gen, period):
181181
if not d: # all gone, delete the attribute
182182
del m._TPS_FOR_GEN_IN_PERIOD_dict
183183
return result
184-
mod.TPS_FOR_GEN_IN_PERIOD = Set(mod.GENERATION_PROJECTS, mod.PERIODS,
185-
within=mod.TIMEPOINTS, rule=rule)
184+
mod.TPS_FOR_GEN_IN_PERIOD = Set(
185+
mod.GENERATION_PROJECTS, mod.PERIODS,
186+
within=mod.TIMEPOINTS, initialize=init)
186187

187188
mod.GEN_TPS = Set(
188189
dimen=2,

0 commit comments

Comments
 (0)