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
4351# switch_model.hydro.simple, and the advanced components into
4452# switch_model.hydro.water_network. That should set a good example
4553# for other people who want to do other custom handling of hydro.
54+ import os .path
4655
4756from pyomo .environ import *
4857
5867
5968def define_components (mod ):
6069 """
61-
6270 HYDRO_GENS is the set of dispatchable hydro projects. This is a subet
6371 of GENERATION_PROJECTS, and is determined by the inputs file hydro_timeseries.csv.
6472 Members of this set can be called either g, or hydro_g.
6573
66- HYDRO_GEN_TS is the set of Hydro projects and timeseries for which
74+ HYDRO_TS is the set of hydro timeseries over which the average flow constraint is defined.
75+ These hydro timeseries are different from the timeseries used in the reset of SWITCH
76+ and are defined by the input file hydro_timepoints.csv. If hydro_timepoints.csv doesn't exist,
77+ the default is for the timeseries to be the same as the SWITCH timeseries from timeseries.csv.
78+ Members of this set can be abbreviated as hts.
79+
80+ HYDRO_GEN_TS is the set of Hydro projects and hydro timeseries for which
6781 minimum and average flow are specified. Members of this set can be
68- abbreviated as (project, timeseries ) or (g, ts ).
82+ abbreviated as (project, hydro_timeseries ) or (g, hts ).
6983
7084 HYDRO_GEN_TPS is the set of Hydro projects and available
7185 dispatch points. This is a filtered version of GEN_TPS that
7286 only includes hydro projects.
7387
74- hydro_min_flow_mw[(g, ts) in HYDRO_GEN_TS] is a parameter that
88+ tp_to_hts[tp in TIMEPOINTS] is a parameter that returns the hydro timeseries
89+ for a given timepoint. It is defined in hydro_timepoints.csv and if unspecified
90+ it defaults to be equal to tp_ts.
91+
92+ hydro_min_flow_mw[(g, hts) in HYDRO_GEN_TS] is a parameter that
7593 determines minimum flow levels, specified in units of MW dispatch.
7694
77- hydro_avg_flow_mw[(g, ts ) in HYDRO_GEN_TS] is a parameter that
95+ hydro_avg_flow_mw[(g, hts ) in HYDRO_GEN_TS] is a parameter that
7896 determines average flow levels, specified in units of MW dispatch.
7997
8098 Enforce_Hydro_Min_Flow[(g, t) in HYDRO_GEN_TPS] is a
8199 constraint that enforces minimum flow levels for each timepoint.
82100
83- Enforce_Hydro_Avg_Flow[(g, ts) in HYDRO_GEN_TS] is a constraint
84- that enforces average flow levels across each timeseries.
85-
101+ Enforce_Hydro_Avg_Flow[(g, hts) in HYDRO_GEN_TS] is a constraint
102+ that enforces average flow levels across each hydro timeseries.
86103 """
104+ mod .tp_to_hts = Param (
105+ mod .TIMEPOINTS ,
106+ input_file = "hydro_timepoints.csv" ,
107+ default = lambda m , tp : m .tp_ts [tp ],
108+ doc = "Mapping of timepoints to a hydro series." ,
109+ within = Any ,
110+ )
111+
112+ mod .HYDRO_TS = Set (
113+ dimen = 1 ,
114+ ordered = False ,
115+ initialize = lambda m : set (m .tp_to_hts [tp ] for tp in m .TIMEPOINTS ),
116+ doc = "Set of hydro timeseries as defined in the mapping." ,
117+ )
118+
119+ mod .TPS_IN_HTS = Set (
120+ mod .HYDRO_TS ,
121+ within = mod .TIMEPOINTS ,
122+ ordered = False ,
123+ initialize = lambda m , hts : set (t for t in m .TIMEPOINTS if m .tp_to_hts [t ] == hts ),
124+ doc = "Set of timepoints in each hydro timeseries" ,
125+ )
87126
88127 mod .HYDRO_GEN_TS_RAW = Set (
89128 dimen = 2 ,
90129 input_file = "hydro_timeseries.csv" ,
91130 input_optional = True ,
92- validate = lambda m , g , ts : (g in m .GENERATION_PROJECTS ) & (ts in m .TIMESERIES ),
131+ validate = lambda m , g , hts : (g in m .GENERATION_PROJECTS ) & (hts in m .HYDRO_TS ),
93132 )
94133
95134 mod .HYDRO_GENS = Set (
96135 dimen = 1 ,
97136 ordered = False ,
98- initialize = lambda m : set (g for (g , ts ) in m .HYDRO_GEN_TS_RAW ),
137+ initialize = lambda m : set (g for (g , hts ) in m .HYDRO_GEN_TS_RAW ),
99138 doc = "Dispatchable hydro projects" ,
100139 )
101- mod .HYDRO_GEN_TS = Set (
102- dimen = 2 ,
103- initialize = lambda m : set (
104- (g , m .tp_ts [tp ]) for g in m .HYDRO_GENS for tp in m .TPS_FOR_GEN [g ]
105- ),
106- )
140+
107141 mod .HYDRO_GEN_TPS = Set (
108142 initialize = mod .GEN_TPS , filter = lambda m , g , t : g in m .HYDRO_GENS
109143 )
110144
145+ mod .HYDRO_GEN_TS = Set (
146+ dimen = 2 ,
147+ initialize = lambda m : set ((g , m .tp_to_hts [tp ]) for (g , tp ) in m .HYDRO_GEN_TPS ),
148+ )
149+
111150 # Validate that a timeseries data is specified for every hydro generator /
112151 # timeseries that we need. Extra data points (ex: outside of planning
113152 # horizon or beyond a plant's lifetime) can safely be ignored to make it
114153 # easier to create input files.
115154 mod .have_minimal_hydro_params = BuildCheck (
116- mod .HYDRO_GEN_TS , rule = lambda m , g , ts : (g , ts ) in m .HYDRO_GEN_TS_RAW
155+ mod .HYDRO_GEN_TS , rule = lambda m , g , hts : (g , hts ) in m .HYDRO_GEN_TS_RAW
117156 )
118157
119- # To do: Add validation check that timeseries data are specified for every
120- # valid timepoint.
158+ # Todo: Add validation check that timeseries data are specified for every valid timepoint.
121159
122160 mod .hydro_min_flow_mw = Param (
123161 mod .HYDRO_GEN_TS_RAW ,
@@ -127,16 +165,13 @@ def define_components(mod):
127165 )
128166 mod .Enforce_Hydro_Min_Flow = Constraint (
129167 mod .HYDRO_GEN_TPS ,
130- rule = lambda m , g , t : (
131- m . DispatchGen [ g , t ] >= m . hydro_min_flow_mw [g , m .tp_ts [t ]]
132- ) ,
168+ rule = lambda m , g , t : Constraint . Skip
169+ if m . hydro_min_flow_mw [g , m .tp_to_hts [t ]] == 0
170+ else m . DispatchGen [ g , t ] >= m . hydro_min_flow_mw [ g , m . tp_to_hts [ t ]] ,
133171 )
134172
135173 mod .hydro_avg_flow_mw = Param (
136- mod .HYDRO_GEN_TS_RAW ,
137- within = NonNegativeReals ,
138- input_file = "hydro_timeseries.csv" ,
139- default = 0.0 ,
174+ mod .HYDRO_GEN_TS_RAW , within = NonNegativeReals , input_file = "hydro_timeseries.csv"
140175 )
141176
142177 # We use a scaling factor to improve the numerical properties
@@ -146,12 +181,11 @@ def define_components(mod):
146181 enforce_hydro_avg_flow_scaling_factor = 1e1
147182 mod .Enforce_Hydro_Avg_Flow = Constraint (
148183 mod .HYDRO_GEN_TS ,
149- rule = lambda m , g , ts : (
150- enforce_hydro_avg_flow_scaling_factor
151- * sum (m .DispatchGen [g , t ] for t in m .TPS_IN_TS [ts ])
152- / m .ts_num_tps [ts ]
153- == m .hydro_avg_flow_mw [g , ts ] * enforce_hydro_avg_flow_scaling_factor
154- ),
184+ rule = lambda m , g , hts : enforce_hydro_avg_flow_scaling_factor *
185+ # Compute the weighted average of the dispatch
186+ sum (m .DispatchGen [g , t ] * m .tp_weight [t ] for t in m .TPS_IN_HTS [hts ])
187+ / sum (m .tp_weight [tp ] for tp in m .TPS_IN_HTS [hts ])
188+ <= m .hydro_avg_flow_mw [g , hts ] * enforce_hydro_avg_flow_scaling_factor ,
155189 )
156190
157191 mod .min_data_check ("hydro_min_flow_mw" , "hydro_avg_flow_mw" )
0 commit comments