@@ -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 (
0 commit comments