Conditions | 5 |
Total Lines | 366 |
Code Lines | 249 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | # -*- coding: utf-8 -*- |
||
112 | def main(optimize=True): |
||
113 | # Read data file |
||
114 | filename = os.path.join(os.getcwd(), "variable_chp.csv") |
||
115 | try: |
||
116 | data = pd.read_csv(filename) |
||
117 | except FileNotFoundError: |
||
118 | msg = "Data file not found: {0}. Only one value used!" |
||
119 | warnings.warn(msg.format(filename), UserWarning) |
||
120 | data = pd.DataFrame( |
||
121 | { |
||
122 | "pv": [0.3], |
||
123 | "wind": [0.6], |
||
124 | "demand_el": [500], |
||
125 | "demand_th": [344], |
||
126 | } |
||
127 | ) |
||
128 | |||
129 | logger.define_logging() |
||
130 | logging.info("Initialize the energy system") |
||
131 | |||
132 | # create time index for 192 hours in May. |
||
133 | date_time_index = solph.create_time_index(2012, number=len(data)) |
||
134 | |||
135 | energysystem = solph.EnergySystem( |
||
136 | timeindex=date_time_index, infer_last_interval=False |
||
137 | ) |
||
138 | |||
139 | ########################################################################## |
||
140 | # Create oemof.solph objects |
||
141 | ########################################################################## |
||
142 | logging.info("Create oemof.solph objects") |
||
143 | |||
144 | # container for instantiated nodes |
||
145 | noded = dict() |
||
146 | |||
147 | # create natural gas bus |
||
148 | noded["bgas"] = solph.Bus(label="natural_gas") |
||
149 | |||
150 | # create commodity object for gas resource |
||
151 | noded["rgas"] = solph.components.Source( |
||
152 | label="rgas", outputs={noded["bgas"]: solph.Flow(variable_costs=50)} |
||
153 | ) |
||
154 | |||
155 | # create two electricity buses and two heat buses |
||
156 | noded["bel"] = solph.Bus(label="electricity") |
||
157 | noded["bel2"] = solph.Bus(label="electricity_2") |
||
158 | noded["bth"] = solph.Bus(label="heat") |
||
159 | noded["bth2"] = solph.Bus(label="heat_2") |
||
160 | |||
161 | # create excess components for the elec/heat bus to allow overproduction |
||
162 | noded["excess_bth_2"] = solph.components.Sink( |
||
163 | label="excess_bth_2", inputs={noded["bth2"]: solph.Flow()} |
||
164 | ) |
||
165 | noded["excess_therm"] = solph.components.Sink( |
||
166 | label="excess_therm", inputs={noded["bth"]: solph.Flow()} |
||
167 | ) |
||
168 | noded["excess_bel_2"] = solph.components.Sink( |
||
169 | label="excess_bel_2", inputs={noded["bel2"]: solph.Flow()} |
||
170 | ) |
||
171 | noded["excess_elec"] = solph.components.Sink( |
||
172 | label="excess_elec", inputs={noded["bel"]: solph.Flow()} |
||
173 | ) |
||
174 | |||
175 | # create simple sink object for electrical demand for each electrical bus |
||
176 | noded["demand_elec"] = solph.components.Sink( |
||
177 | label="demand_elec", |
||
178 | inputs={ |
||
179 | noded["bel"]: solph.Flow(fix=data["demand_el"], nominal_capacity=1) |
||
180 | }, |
||
181 | ) |
||
182 | noded["demand_el_2"] = solph.components.Sink( |
||
183 | label="demand_el_2", |
||
184 | inputs={ |
||
185 | noded["bel2"]: solph.Flow( |
||
186 | fix=data["demand_el"], nominal_capacity=1 |
||
187 | ) |
||
188 | }, |
||
189 | ) |
||
190 | |||
191 | # create simple sink object for heat demand for each thermal bus |
||
192 | noded["demand_therm"] = solph.components.Sink( |
||
193 | label="demand_therm", |
||
194 | inputs={ |
||
195 | noded["bth"]: solph.Flow( |
||
196 | fix=data["demand_th"], nominal_capacity=741000 |
||
197 | ) |
||
198 | }, |
||
199 | ) |
||
200 | noded["demand_therm_2"] = solph.components.Sink( |
||
201 | label="demand_th_2", |
||
202 | inputs={ |
||
203 | noded["bth2"]: solph.Flow( |
||
204 | fix=data["demand_th"], nominal_capacity=741000 |
||
205 | ) |
||
206 | }, |
||
207 | ) |
||
208 | |||
209 | # This is just a dummy Converter with a nominal input of zero |
||
210 | noded["fixed_chp_gas"] = solph.components.Converter( |
||
211 | label="fixed_chp_gas", |
||
212 | inputs={noded["bgas"]: solph.Flow(nominal_capacity=0)}, |
||
213 | outputs={noded["bel"]: solph.Flow(), noded["bth"]: solph.Flow()}, |
||
214 | conversion_factors={noded["bel"]: 0.3, noded["bth"]: 0.5}, |
||
215 | ) |
||
216 | |||
217 | # create a fixed Converter to distribute to the heat_2 and elec_2 buses |
||
218 | noded["fixed_chp_gas_2"] = solph.components.Converter( |
||
219 | label="fixed_chp_gas_2", |
||
220 | inputs={noded["bgas"]: solph.Flow(nominal_capacity=10e10)}, |
||
221 | outputs={noded["bel2"]: solph.Flow(), noded["bth2"]: solph.Flow()}, |
||
222 | conversion_factors={noded["bel2"]: 0.3, noded["bth2"]: 0.5}, |
||
223 | ) |
||
224 | |||
225 | # create a fixed Converter to distribute to the heat and elec buses |
||
226 | noded["variable_chp_gas"] = solph.components.ExtractionTurbineCHP( |
||
227 | label="variable_chp_gas", |
||
228 | inputs={noded["bgas"]: solph.Flow(nominal_capacity=10e10)}, |
||
229 | outputs={noded["bel"]: solph.Flow(), noded["bth"]: solph.Flow()}, |
||
230 | conversion_factors={noded["bel"]: 0.3, noded["bth"]: 0.5}, |
||
231 | conversion_factor_full_condensation={noded["bel"]: 0.5}, |
||
232 | ) |
||
233 | |||
234 | ########################################################################## |
||
235 | # Optimise the energy system |
||
236 | ########################################################################## |
||
237 | |||
238 | if optimize is False: |
||
239 | return energysystem |
||
240 | |||
241 | logging.info("Optimise the energy system") |
||
242 | |||
243 | energysystem.add(*noded.values()) |
||
244 | |||
245 | om = solph.Model(energysystem) |
||
246 | |||
247 | # If uncomment the following line you can store the lp file but you should |
||
248 | # use less timesteps (3) to make it better readable and smaller. |
||
249 | # write_lp_file(om) |
||
250 | |||
251 | logging.info("Solve the optimization problem") |
||
252 | om.solve(solver="cbc", solve_kwargs={"tee": False}) |
||
253 | |||
254 | results = solph.processing.results(om) |
||
255 | |||
256 | ########################################################################## |
||
257 | # Plot the results |
||
258 | ########################################################################## |
||
259 | |||
260 | myresults = solph.views.node(results, "natural_gas") |
||
261 | myresults = myresults["sequences"].sum(axis=0) |
||
262 | myresults = myresults.drop(myresults.index[0]).reset_index(drop=True) |
||
263 | myresults.rename({0: "fixed", 1: "variable", 2: "total"}, inplace=True) |
||
264 | myresults.plot(kind="bar", rot=0, title="Usage of natural gas") |
||
265 | plt.show() |
||
266 | |||
267 | # Create a plot with 6 tiles that shows the difference between the |
||
268 | # Converter and the ExtractionTurbineCHP used for chp plants. |
||
269 | smooth_plot = True |
||
270 | |||
271 | if oeplot: |
||
272 | logging.info("Plot the results") |
||
273 | |||
274 | cdict = { |
||
275 | (("variable_chp_gas", "electricity"), "flow"): "#42c77a", |
||
276 | (("fixed_chp_gas_2", "electricity_2"), "flow"): "#20b4b6", |
||
277 | (("fixed_chp_gas", "electricity"), "flow"): "#20b4b6", |
||
278 | (("fixed_chp_gas", "heat"), "flow"): "#20b4b6", |
||
279 | (("variable_chp_gas", "heat"), "flow"): "#42c77a", |
||
280 | (("heat", "demand_therm"), "flow"): "#5b5bae", |
||
281 | (("heat_2", "demand_th_2"), "flow"): "#5b5bae", |
||
282 | (("electricity", "demand_elec"), "flow"): "#5b5bae", |
||
283 | (("electricity_2", "demand_el_2"), "flow"): "#5b5bae", |
||
284 | (("heat", "excess_therm"), "flow"): "#f22222", |
||
285 | (("heat_2", "excess_bth_2"), "flow"): "#f22222", |
||
286 | (("electricity", "excess_elec"), "flow"): "#f22222", |
||
287 | (("electricity_2", "excess_bel_2"), "flow"): "#f22222", |
||
288 | (("fixed_chp_gas_2", "heat_2"), "flow"): "#20b4b6", |
||
289 | } |
||
290 | |||
291 | fig = plt.figure(figsize=(18, 9)) |
||
292 | plt.rc("legend", **{"fontsize": 13}) |
||
293 | plt.rcParams.update({"font.size": 13}) |
||
294 | fig.subplots_adjust( |
||
295 | left=0.07, |
||
296 | bottom=0.12, |
||
297 | right=0.86, |
||
298 | top=0.93, |
||
299 | wspace=0.03, |
||
300 | hspace=0.2, |
||
301 | ) |
||
302 | |||
303 | # subplot of electricity bus (fixed chp) [1] |
||
304 | electricity_2 = solph.views.node(results, "electricity_2") |
||
305 | x_length = len(electricity_2["sequences"].index) |
||
306 | myplot = oeplot.io_plot( |
||
307 | bus_label="electricity_2", |
||
308 | df=electricity_2["sequences"], |
||
309 | cdict=cdict, |
||
310 | smooth=smooth_plot, |
||
311 | line_kwa={"linewidth": 4}, |
||
312 | ax=fig.add_subplot(3, 2, 1), |
||
313 | inorder=[(("fixed_chp_gas_2", "electricity_2"), "flow")], |
||
314 | outorder=[ |
||
315 | (("electricity_2", "demand_el_2"), "flow"), |
||
316 | (("electricity_2", "excess_bel_2"), "flow"), |
||
317 | ], |
||
318 | ) |
||
319 | myplot["ax"].set_ylabel("Power in MW") |
||
320 | myplot["ax"].set_xlabel("") |
||
321 | myplot["ax"].get_xaxis().set_visible(False) |
||
322 | myplot["ax"].set_xlim(0, x_length) |
||
323 | myplot["ax"].set_title("Electricity output (fixed chp)") |
||
324 | myplot["ax"].legend_.remove() |
||
325 | |||
326 | # subplot of electricity bus (variable chp) [2] |
||
327 | electricity = solph.views.node(results, "electricity") |
||
328 | myplot = oeplot.io_plot( |
||
329 | bus_label="electricity", |
||
330 | df=electricity["sequences"], |
||
331 | cdict=cdict, |
||
332 | smooth=smooth_plot, |
||
333 | line_kwa={"linewidth": 4}, |
||
334 | ax=fig.add_subplot(3, 2, 2), |
||
335 | inorder=[ |
||
336 | (("fixed_chp_gas", "electricity"), "flow"), |
||
337 | (("variable_chp_gas", "electricity"), "flow"), |
||
338 | ], |
||
339 | outorder=[ |
||
340 | (("electricity", "demand_elec"), "flow"), |
||
341 | (("electricity", "excess_elec"), "flow"), |
||
342 | ], |
||
343 | ) |
||
344 | myplot["ax"].get_yaxis().set_visible(False) |
||
345 | myplot["ax"].set_xlabel("") |
||
346 | myplot["ax"].get_xaxis().set_visible(False) |
||
347 | myplot["ax"].set_title("Electricity output (variable chp)") |
||
348 | myplot["ax"].set_xlim(0, x_length) |
||
349 | shape_legend("electricity", plotshare=1, **myplot) |
||
350 | |||
351 | # subplot of heat bus (fixed chp) [3] |
||
352 | heat_2 = solph.views.node(results, "heat_2") |
||
353 | myplot = oeplot.io_plot( |
||
354 | bus_label="heat_2", |
||
355 | df=heat_2["sequences"], |
||
356 | cdict=cdict, |
||
357 | smooth=smooth_plot, |
||
358 | line_kwa={"linewidth": 4}, |
||
359 | ax=fig.add_subplot(3, 2, 3), |
||
360 | inorder=[(("fixed_chp_gas_2", "heat_2"), "flow")], |
||
361 | outorder=[ |
||
362 | (("heat_2", "demand_th_2"), "flow"), |
||
363 | (("heat_2", "excess_bth_2"), "flow"), |
||
364 | ], |
||
365 | ) |
||
366 | myplot["ax"].set_ylabel("Power in MW") |
||
367 | myplot["ax"].set_ylim([0, 600000]) |
||
368 | myplot["ax"].get_xaxis().set_visible(False) |
||
369 | myplot["ax"].set_title("Heat output (fixed chp)") |
||
370 | myplot["ax"].set_xlim(0, x_length) |
||
371 | myplot["ax"].legend_.remove() |
||
372 | |||
373 | # subplot of heat bus (variable chp) [4] |
||
374 | heat = solph.views.node(results, "heat") |
||
375 | myplot = oeplot.io_plot( |
||
376 | bus_label="heat", |
||
377 | df=heat["sequences"], |
||
378 | cdict=cdict, |
||
379 | smooth=smooth_plot, |
||
380 | line_kwa={"linewidth": 4}, |
||
381 | ax=fig.add_subplot(3, 2, 4), |
||
382 | inorder=[ |
||
383 | (("fixed_chp_gas", "heat"), "flow"), |
||
384 | (("variable_chp_gas", "heat"), "flow"), |
||
385 | ], |
||
386 | outorder=[ |
||
387 | (("heat", "demand_therm"), "flow"), |
||
388 | (("heat", "excess_therm"), "flow"), |
||
389 | ], |
||
390 | ) |
||
391 | myplot["ax"].set_ylim([0, 600000]) |
||
392 | myplot["ax"].get_yaxis().set_visible(False) |
||
393 | myplot["ax"].get_xaxis().set_visible(False) |
||
394 | myplot["ax"].set_title("Heat output (variable chp)") |
||
395 | myplot["ax"].set_xlim(0, x_length) |
||
396 | shape_legend("heat", plotshare=1, **myplot) |
||
397 | |||
398 | if smooth_plot: |
||
399 | style = None |
||
400 | else: |
||
401 | style = "steps-mid" |
||
402 | |||
403 | # subplot of efficiency (fixed chp) [5] |
||
404 | fix_chp_gas2 = solph.views.node(results, "fixed_chp_gas_2") |
||
405 | ngas = fix_chp_gas2["sequences"][ |
||
406 | (("natural_gas", "fixed_chp_gas_2"), "flow") |
||
407 | ] |
||
408 | elec = fix_chp_gas2["sequences"][ |
||
409 | (("fixed_chp_gas_2", "electricity_2"), "flow") |
||
410 | ] |
||
411 | heat = fix_chp_gas2["sequences"][ |
||
412 | (("fixed_chp_gas_2", "heat_2"), "flow") |
||
413 | ] |
||
414 | e_ef = elec.div(ngas) |
||
415 | h_ef = heat.div(ngas) |
||
416 | df = pd.DataFrame(pd.concat([h_ef, e_ef], axis=1)) |
||
417 | my_ax = df.reset_index(drop=True).plot( |
||
418 | drawstyle=style, ax=fig.add_subplot(3, 2, 5), linewidth=2 |
||
419 | ) |
||
420 | my_ax.set_ylabel("efficiency") |
||
421 | my_ax.set_ylim([0, 0.55]) |
||
422 | my_ax.set_xlabel("May 2012") |
||
423 | my_ax = oeplot.set_datetime_ticks( |
||
424 | my_ax, |
||
425 | df.index, |
||
426 | tick_distance=24, |
||
427 | date_format="%d", |
||
428 | offset=12, |
||
429 | tight=True, |
||
430 | ) |
||
431 | my_ax.set_title("Efficiency (fixed chp)") |
||
432 | my_ax.legend_.remove() |
||
433 | |||
434 | # subplot of efficiency (variable chp) [6] |
||
435 | var_chp_gas = solph.views.node(results, "variable_chp_gas") |
||
436 | ngas = var_chp_gas["sequences"][ |
||
437 | (("natural_gas", "variable_chp_gas"), "flow") |
||
438 | ] |
||
439 | elec = var_chp_gas["sequences"][ |
||
440 | (("variable_chp_gas", "electricity"), "flow") |
||
441 | ] |
||
442 | heat = var_chp_gas["sequences"][(("variable_chp_gas", "heat"), "flow")] |
||
443 | e_ef = elec.div(ngas) |
||
444 | h_ef = heat.div(ngas) |
||
445 | e_ef.name = "electricity " |
||
446 | h_ef.name = "heat" |
||
447 | df = pd.DataFrame(pd.concat([h_ef, e_ef], axis=1)) |
||
448 | my_ax = df.reset_index(drop=True).plot( |
||
449 | drawstyle=style, ax=fig.add_subplot(3, 2, 6), linewidth=2 |
||
450 | ) |
||
451 | my_ax.set_ylim([0, 0.55]) |
||
452 | my_ax = oeplot.set_datetime_ticks( |
||
453 | my_ax, |
||
454 | df.index, |
||
455 | tick_distance=24, |
||
456 | date_format="%d", |
||
457 | offset=12, |
||
458 | tight=True, |
||
459 | ) |
||
460 | my_ax.get_yaxis().set_visible(False) |
||
461 | my_ax.set_xlabel("May 2012") |
||
462 | |||
463 | my_ax.set_title("Efficiency (variable chp)") |
||
464 | my_box = my_ax.get_position() |
||
465 | my_ax.set_position( |
||
466 | [my_box.x0, my_box.y0, my_box.width * 1, my_box.height] |
||
467 | ) |
||
468 | my_ax.legend(loc="center left", bbox_to_anchor=(1, 0.5), ncol=1) |
||
469 | |||
470 | plt.show() |
||
471 | |||
472 | else: |
||
473 | logging.warning( |
||
474 | "You have to install 'oemof-visio' to see the i/o-plot" |
||
475 | ) |
||
476 | logging.warning( |
||
477 | "Use: pip install git+https://github.com/oemof/oemof_visio.git" |
||
478 | ) |
||
483 |