23
23
24
24
INPUT FILE INFORMATION
25
25
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
38
46
"""
39
47
from __future__ import division
40
48
43
51
# switch_model.hydro.simple, and the advanced components into
44
52
# switch_model.hydro.water_network. That should set a good example
45
53
# for other people who want to do other custom handling of hydro.
54
+ import os .path
46
55
47
56
from pyomo .environ import *
48
57
58
67
59
68
def define_components (mod ):
60
69
"""
61
-
62
70
HYDRO_GENS is the set of dispatchable hydro projects. This is a subet
63
71
of GENERATION_PROJECTS, and is determined by the inputs file hydro_timeseries.csv.
64
72
Members of this set can be called either g, or hydro_g.
65
73
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
67
81
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 ).
69
83
70
84
HYDRO_GEN_TPS is the set of Hydro projects and available
71
85
dispatch points. This is a filtered version of GEN_TPS that
72
86
only includes hydro projects.
73
87
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
75
93
determines minimum flow levels, specified in units of MW dispatch.
76
94
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
78
96
determines average flow levels, specified in units of MW dispatch.
79
97
80
98
Enforce_Hydro_Min_Flow[(g, t) in HYDRO_GEN_TPS] is a
81
99
constraint that enforces minimum flow levels for each timepoint.
82
100
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.
86
103
"""
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
+ )
87
126
88
127
mod .HYDRO_GEN_TS_RAW = Set (
89
128
dimen = 2 ,
90
129
input_file = "hydro_timeseries.csv" ,
91
130
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 ),
93
132
)
94
133
95
134
mod .HYDRO_GENS = Set (
96
135
dimen = 1 ,
97
136
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 ),
99
138
doc = "Dispatchable hydro projects" ,
100
139
)
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
+
107
141
mod .HYDRO_GEN_TPS = Set (
108
142
initialize = mod .GEN_TPS , filter = lambda m , g , t : g in m .HYDRO_GENS
109
143
)
110
144
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
+
111
150
# Validate that a timeseries data is specified for every hydro generator /
112
151
# timeseries that we need. Extra data points (ex: outside of planning
113
152
# horizon or beyond a plant's lifetime) can safely be ignored to make it
114
153
# easier to create input files.
115
154
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
117
156
)
118
157
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.
121
159
122
160
mod .hydro_min_flow_mw = Param (
123
161
mod .HYDRO_GEN_TS_RAW ,
@@ -127,16 +165,13 @@ def define_components(mod):
127
165
)
128
166
mod .Enforce_Hydro_Min_Flow = Constraint (
129
167
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 ]] ,
133
171
)
134
172
135
173
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"
140
175
)
141
176
142
177
# We use a scaling factor to improve the numerical properties
@@ -146,12 +181,11 @@ def define_components(mod):
146
181
enforce_hydro_avg_flow_scaling_factor = 1e1
147
182
mod .Enforce_Hydro_Avg_Flow = Constraint (
148
183
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 ,
155
189
)
156
190
157
191
mod .min_data_check ("hydro_min_flow_mw" , "hydro_avg_flow_mw" )
0 commit comments