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