@@ 250-321 (lines=72) @@ | ||
247 | ), |
|
248 | ) |
|
249 | ||
250 | def _inputs_tsam(): |
|
251 | INPUTS = po.Set(initialize=input_levels.keys()) |
|
252 | setattr(model, f"{name}_INPUTS", INPUTS) |
|
253 | ||
254 | inactive_input = po.Var( |
|
255 | INPUTS, |
|
256 | model.TIMEINDEX_TYPICAL_CLUSTER_OFFSET, |
|
257 | domain=po.Binary, |
|
258 | bounds=(0, 1), |
|
259 | ) |
|
260 | setattr(model, f"{name}_active_input", inactive_input) |
|
261 | ||
262 | constraint_name = f"{name}_input_active_constraint" |
|
263 | ||
264 | def _input_active_rule(m): |
|
265 | r""" |
|
266 | .. math:: |
|
267 | \hat{y}_n \ge (E(t) - E_n) / E_{max} |
|
268 | """ |
|
269 | for p, i, g in m.TIMEINDEX_CLUSTER: |
|
270 | k = m.es.tsa_parameters[p]["order"][i] |
|
271 | t = m.get_timestep_from_tsam_timestep(p, k, g) |
|
272 | tk = m.get_timestep_from_tsam_timestep(p, k, g) |
|
273 | for inp in input_levels: |
|
274 | getattr(m, constraint_name).add( |
|
275 | (inp, p, i, g), |
|
276 | ( |
|
277 | m.GenericStorageBlock.intra_storage_delta[ |
|
278 | storage_component, p, k, g + 1 |
|
279 | ] |
|
280 | + m.GenericStorageBlock.inter_storage_content[ |
|
281 | storage_component, i |
|
282 | ] |
|
283 | * (1 - storage_component.loss_rate[t]) |
|
284 | ** (g * m.timeincrement[tk]) |
|
285 | ) |
|
286 | / storage_component.nominal_storage_capacity |
|
287 | - input_levels[inp] |
|
288 | <= inactive_input[inp, p, k, g], |
|
289 | ) |
|
290 | ||
291 | setattr( |
|
292 | model, |
|
293 | constraint_name, |
|
294 | po.Constraint( |
|
295 | INPUTS, |
|
296 | model.TIMEINDEX_CLUSTER, |
|
297 | noruleinit=True, |
|
298 | ), |
|
299 | ) |
|
300 | setattr( |
|
301 | model, |
|
302 | constraint_name + "build", |
|
303 | po.BuildAction(rule=_input_active_rule), |
|
304 | ) |
|
305 | ||
306 | # Define constraints on the input flows |
|
307 | def _constraint_input_rule(m, i, p, k, g): |
|
308 | t = m.get_timestep_from_tsam_timestep(p, k, g) |
|
309 | return ( |
|
310 | m.flow[i, multiplexer_bus, p, t] |
|
311 | / m.flows[i, multiplexer_bus].nominal_value |
|
312 | <= 1 - inactive_input[i, p, k, g] |
|
313 | ) |
|
314 | ||
315 | setattr( |
|
316 | model, |
|
317 | f"{name}_input_constraint", |
|
318 | po.Constraint( |
|
319 | INPUTS, |
|
320 | model.TIMEINDEX_TYPICAL_CLUSTER, |
|
321 | rule=_constraint_input_rule, |
|
322 | ), |
|
323 | ) |
|
324 | ||
@@ 108-178 (lines=71) @@ | ||
105 | ), |
|
106 | ) |
|
107 | ||
108 | def _outputs_tsam(): |
|
109 | OUTPUTS = po.Set(initialize=output_levels.keys()) |
|
110 | setattr(model, f"{name}_OUTPUTS", OUTPUTS) |
|
111 | ||
112 | active_output = po.Var( |
|
113 | OUTPUTS, |
|
114 | model.TIMEINDEX_TYPICAL_CLUSTER_OFFSET, |
|
115 | domain=po.Binary, |
|
116 | bounds=(0, 1), |
|
117 | ) |
|
118 | setattr(model, f"{name}_active_output", active_output) |
|
119 | ||
120 | constraint_name = f"{name}_output_active_constraint" |
|
121 | ||
122 | def _output_active_rule(m): |
|
123 | r""" |
|
124 | .. math:: |
|
125 | y_n \le E(t) / E_n |
|
126 | """ |
|
127 | for p, i, g in m.TIMEINDEX_CLUSTER: |
|
128 | k = m.es.tsa_parameters[p]["order"][i] |
|
129 | t = m.get_timestep_from_tsam_timestep(p, k, g) |
|
130 | tk = m.get_timestep_from_tsam_timestep(p, k, g) |
|
131 | for o in output_levels: |
|
132 | getattr(m, constraint_name).add( |
|
133 | (o, p, i, g), |
|
134 | ( |
|
135 | m.GenericStorageBlock.intra_storage_delta[ |
|
136 | storage_component, p, k, g + 1 |
|
137 | ] |
|
138 | + m.GenericStorageBlock.inter_storage_content[ |
|
139 | storage_component, i |
|
140 | ] |
|
141 | * (1 - storage_component.loss_rate[t]) |
|
142 | ** (g * m.timeincrement[tk]) |
|
143 | ) |
|
144 | / storage_component.nominal_storage_capacity |
|
145 | >= active_output[o, p, k, g] * output_levels[o], |
|
146 | ) |
|
147 | ||
148 | setattr( |
|
149 | model, |
|
150 | constraint_name, |
|
151 | po.Constraint( |
|
152 | OUTPUTS, |
|
153 | model.TIMEINDEX_CLUSTER, |
|
154 | noruleinit=True, |
|
155 | ), |
|
156 | ) |
|
157 | setattr( |
|
158 | model, |
|
159 | constraint_name + "build", |
|
160 | po.BuildAction(rule=_output_active_rule), |
|
161 | ) |
|
162 | ||
163 | # Define constraints on the output flows |
|
164 | def _constraint_output_rule(m, o, p, k, g): |
|
165 | t = m.get_timestep_from_tsam_timestep(p, k, g) |
|
166 | return ( |
|
167 | m.flow[multiplexer_bus, o, p, t] |
|
168 | / m.flows[multiplexer_bus, o].nominal_value |
|
169 | <= active_output[o, p, k, g] |
|
170 | ) |
|
171 | ||
172 | setattr( |
|
173 | model, |
|
174 | f"{name}_output_constraint", |
|
175 | po.Constraint( |
|
176 | OUTPUTS, |
|
177 | model.TIMEINDEX_TYPICAL_CLUSTER, |
|
178 | rule=_constraint_output_rule, |
|
179 | ), |
|
180 | ) |
|
181 |