2323
2424INPUT FILE INFORMATION
2525
26- The single file hydro_timeseries.csv needs to contain
27- entries for each dispatchable hydro project. The set of hydro projects
28- is derived from this file, and this file should cover all time periods
29- in which the hydro plant can operate.
30-
31- Run-of-River hydro projects should not be included in this file; RoR
32- hydro is treated like any other variable renewable resource, and
33- expects data in variable_capacity_factors.csv.
34-
35- hydro_timeseries.csv
36- hydro_generation_project, timeseries, hydro_min_flow_mw,
37- hydro_avg_flow_mw
26+ The file hydro_timeseries.csv needs to contain
27+ entries for each dispatchable hydro project. The set of hydro projects
28+ is derived from this file, and this file should cover all time periods
29+ in which the hydro plant can operate.
30+
31+ Run-of-River hydro projects should not be included in this file; RoR
32+ hydro is treated like any other variable renewable resource, and
33+ expects data in variable_capacity_factors.csv.
34+
35+ hydro_timeseries.csv
36+ hydro_generation_project, hydro_timeseries, hydro_min_flow_mw,
37+ hydro_avg_flow_mw
38+
39+ The file hydro_timepoints.csv is an optional mapping of timepoints
40+ to a hydro timeseries. Hydro timeseries are different from the SWITCH
41+ timeseries (timeseries.csv) as this allows hydro constraints to be
42+ specified over a different time period.
43+
44+ hydro_timepoints.csv (optional)
45+ timepoint_id,tp_to_hts
3846"""
3947from __future__ import division
4048# ToDo: Refactor this code to move the core components into a
4149# switch_model.hydro.core module, the simplist components into
4250# switch_model.hydro.simple, and the advanced components into
4351# switch_model.hydro.water_network. That should set a good example
4452# for other people who want to do other custom handling of hydro.
53+ import os .path
4554
4655from pyomo .environ import *
4756
5160
5261def define_components (mod ):
5362 """
54-
5563 HYDRO_GENS is the set of dispatchable hydro projects. This is a subet
5664 of GENERATION_PROJECTS, and is determined by the inputs file hydro_timeseries.csv.
5765 Members of this set can be called either g, or hydro_g.
5866
59- HYDRO_GEN_TS is the set of Hydro projects and timeseries for which
67+ HYDRO_TS is the set of hydro timeseries over which the average flow constraint is defined.
68+ These hydro timeseries are different from the timeseries used in the reset of SWITCH
69+ and are defined by the input file hydro_timepoints.csv. If hydro_timepoints.csv doesn't exist,
70+ the default is for the timeseries to be the same as the SWITCH timeseries from timeseries.csv.
71+ Members of this set can be abbreviated as hts.
72+
73+ HYDRO_GEN_TS is the set of Hydro projects and hydro timeseries for which
6074 minimum and average flow are specified. Members of this set can be
61- abbreviated as (project, timeseries ) or (g, ts ).
75+ abbreviated as (project, hydro_timeseries ) or (g, hts ).
6276
6377 HYDRO_GEN_TPS is the set of Hydro projects and available
6478 dispatch points. This is a filtered version of GEN_TPS that
6579 only includes hydro projects.
6680
67- hydro_min_flow_mw[(g, ts) in HYDRO_GEN_TS] is a parameter that
81+ tp_to_hts[tp in TIMEPOINTS] is a parameter that returns the hydro timeseries
82+ for a given timepoint. It is defined in hydro_timepoints.csv and if unspecified
83+ it defaults to be equal to tp_ts.
84+
85+ hydro_min_flow_mw[(g, hts) in HYDRO_GEN_TS] is a parameter that
6886 determines minimum flow levels, specified in units of MW dispatch.
6987
70- hydro_avg_flow_mw[(g, ts ) in HYDRO_GEN_TS] is a parameter that
88+ hydro_avg_flow_mw[(g, hts ) in HYDRO_GEN_TS] is a parameter that
7189 determines average flow levels, specified in units of MW dispatch.
7290
7391 Enforce_Hydro_Min_Flow[(g, t) in HYDRO_GEN_TPS] is a
7492 constraint that enforces minimum flow levels for each timepoint.
7593
76- Enforce_Hydro_Avg_Flow[(g, ts) in HYDRO_GEN_TS] is a constraint
77- that enforces average flow levels across each timeseries.
78-
94+ Enforce_Hydro_Avg_Flow[(g, hts) in HYDRO_GEN_TS] is a constraint
95+ that enforces average flow levels across each hydro timeseries.
7996 """
97+ mod .tp_to_hts = Param (
98+ mod .TIMEPOINTS ,
99+ input_file = 'hydro_timepoints.csv' ,
100+ default = lambda m , tp : m .tp_ts [tp ],
101+ doc = "Mapping of timepoints to a hydro series." ,
102+ within = Any
103+ )
104+
105+ mod .HYDRO_TS = Set (
106+ dimen = 1 ,
107+ ordered = False ,
108+ initialize = lambda m : set (m .tp_to_hts [tp ] for tp in m .TIMEPOINTS ),
109+ doc = "Set of hydro timeseries as defined in the mapping."
110+ )
111+
112+ mod .TPS_IN_HTS = Set (
113+ mod .HYDRO_TS ,
114+ within = mod .TIMEPOINTS ,
115+ ordered = False ,
116+ initialize = lambda m , hts : set (t for t in m .TIMEPOINTS if m .tp_to_hts [t ] == hts ),
117+ doc = "Set of timepoints in each hydro timeseries"
118+ )
80119
81120 mod .HYDRO_GEN_TS_RAW = Set (
82121 dimen = 2 ,
83122 input_file = 'hydro_timeseries.csv' ,
84123 input_optional = True ,
85- validate = lambda m , g , ts : (g in m .GENERATION_PROJECTS ) & (ts in m .TIMESERIES ) )
124+ validate = lambda m , g , hts : (g in m .GENERATION_PROJECTS ) & (hts in m .HYDRO_TS ), )
86125
87126 mod .HYDRO_GENS = Set (
88127 dimen = 1 ,
89128 ordered = False ,
90- initialize = lambda m : set (g for (g , ts ) in m .HYDRO_GEN_TS_RAW ),
129+ initialize = lambda m : set (g for (g , hts ) in m .HYDRO_GEN_TS_RAW ),
91130 doc = "Dispatchable hydro projects" )
92- mod .HYDRO_GEN_TS = Set (
93- dimen = 2 ,
94- initialize = lambda m : set (
95- (g , m .tp_ts [tp ])
96- for g in m .HYDRO_GENS
97- for tp in m .TPS_FOR_GEN [g ]))
131+
98132 mod .HYDRO_GEN_TPS = Set (
99133 initialize = mod .GEN_TPS ,
100134 filter = lambda m , g , t : g in m .HYDRO_GENS )
101135
136+ mod .HYDRO_GEN_TS = Set (
137+ dimen = 2 ,
138+ initialize = lambda m : set ((g , m .tp_to_hts [tp ]) for (g , tp ) in m .HYDRO_GEN_TPS ))
139+
102140 # Validate that a timeseries data is specified for every hydro generator /
103141 # timeseries that we need. Extra data points (ex: outside of planning
104142 # horizon or beyond a plant's lifetime) can safely be ignored to make it
105143 # easier to create input files.
106144 mod .have_minimal_hydro_params = BuildCheck (
107145 mod .HYDRO_GEN_TS ,
108- rule = lambda m , g , ts : (g ,ts ) in m .HYDRO_GEN_TS_RAW )
146+ rule = lambda m , g , hts : (g , hts ) in m .HYDRO_GEN_TS_RAW )
109147
110- # To do: Add validation check that timeseries data are specified for every
111- # valid timepoint.
148+ # Todo: Add validation check that timeseries data are specified for every valid timepoint.
112149
113150 mod .hydro_min_flow_mw = Param (
114151 mod .HYDRO_GEN_TS_RAW ,
@@ -117,14 +154,14 @@ def define_components(mod):
117154 default = 0.0 )
118155 mod .Enforce_Hydro_Min_Flow = Constraint (
119156 mod .HYDRO_GEN_TPS ,
120- rule = lambda m , g , t : (
121- m .DispatchGen [g , t ] >= m .hydro_min_flow_mw [g , m .tp_ts [t ]]))
157+ rule = lambda m , g , t : Constraint .Skip
158+ if m .hydro_min_flow_mw [g , m .tp_to_hts [t ]] == 0
159+ else m .DispatchGen [g , t ] >= m .hydro_min_flow_mw [g , m .tp_to_hts [t ]])
122160
123161 mod .hydro_avg_flow_mw = Param (
124162 mod .HYDRO_GEN_TS_RAW ,
125163 within = NonNegativeReals ,
126- input_file = 'hydro_timeseries.csv' ,
127- default = 0.0 )
164+ input_file = 'hydro_timeseries.csv' )
128165
129166 # We use a scaling factor to improve the numerical properties
130167 # of the model. The scaling factor was determined using trial
@@ -133,8 +170,12 @@ def define_components(mod):
133170 enforce_hydro_avg_flow_scaling_factor = 1e1
134171 mod .Enforce_Hydro_Avg_Flow = Constraint (
135172 mod .HYDRO_GEN_TS ,
136- rule = lambda m , g , ts : (enforce_hydro_avg_flow_scaling_factor *
137- sum (m .DispatchGen [g , t ] for t in m .TPS_IN_TS [ts ]) / m .ts_num_tps [ts ]
138- == m .hydro_avg_flow_mw [g , ts ] * enforce_hydro_avg_flow_scaling_factor ))
173+ rule = lambda m , g , hts :
174+ enforce_hydro_avg_flow_scaling_factor *
175+ # Compute the weighted average of the dispatch
176+ sum (m .DispatchGen [g , t ] * m .tp_weight [t ] for t in m .TPS_IN_HTS [hts ])
177+ / sum (m .tp_weight [tp ] for tp in m .TPS_IN_HTS [hts ])
178+ <= m .hydro_avg_flow_mw [g , hts ] * enforce_hydro_avg_flow_scaling_factor
179+ )
139180
140181 mod .min_data_check ('hydro_min_flow_mw' , 'hydro_avg_flow_mw' )
0 commit comments