| Conditions | 1 |
| Total Lines | 98 |
| Code Lines | 63 |
| 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 -*- |
||
| 25 | def main(): |
||
| 26 | demand_el = [ |
||
| 27 | 0, |
||
| 28 | 0, |
||
| 29 | 0, |
||
| 30 | 1, |
||
| 31 | 1, |
||
| 32 | 1, |
||
| 33 | 0, |
||
| 34 | 0, |
||
| 35 | 1, |
||
| 36 | 1, |
||
| 37 | 1, |
||
| 38 | 0, |
||
| 39 | 0, |
||
| 40 | 1, |
||
| 41 | 1, |
||
| 42 | 1, |
||
| 43 | 0, |
||
| 44 | 0, |
||
| 45 | 1, |
||
| 46 | 1, |
||
| 47 | 1, |
||
| 48 | 1, |
||
| 49 | 0, |
||
| 50 | 0, |
||
| 51 | ] |
||
| 52 | # create an energy system |
||
| 53 | idx = solph.create_time_index(2017, number=len(demand_el)) |
||
| 54 | es = solph.EnergySystem(timeindex=idx, infer_last_interval=False) |
||
| 55 | |||
| 56 | # power bus and components |
||
| 57 | bel = solph.Bus(label="bel") |
||
| 58 | |||
| 59 | demand_el = solph.components.Sink( |
||
| 60 | label="demand_el", |
||
| 61 | inputs={bel: solph.Flow(fix=demand_el, nominal_value=10)}, |
||
| 62 | ) |
||
| 63 | |||
| 64 | # pp1 and pp2 are competing to serve overall 12 units load at lowest cost |
||
| 65 | # summed costs for pp1 = 12 * 10 * 10.25 = 1230 |
||
| 66 | # summed costs for pp2 = 4*5 + 4*5 + 12 * 10 * 10 = 1240 |
||
| 67 | # => pp1 serves the load despite of higher variable costs since |
||
| 68 | # the start and shutdown costs of pp2 change its marginal costs |
||
| 69 | pp1 = solph.components.Source( |
||
| 70 | label="power_plant1", |
||
| 71 | outputs={bel: solph.Flow(nominal_value=10, variable_costs=10.25)}, |
||
| 72 | ) |
||
| 73 | |||
| 74 | # shutdown costs only work in combination with a minimum load |
||
| 75 | # since otherwise the status variable is "allowed" to be active i.e. |
||
| 76 | # it permanently has a value of one which does not allow to set the shutdown |
||
| 77 | # variable which is set to one if the status variable changes from one to zero |
||
| 78 | pp2 = solph.components.Source( |
||
| 79 | label="power_plant2", |
||
| 80 | outputs={ |
||
| 81 | bel: solph.Flow( |
||
| 82 | nominal_value=10, |
||
| 83 | min=0.5, |
||
| 84 | max=1.0, |
||
| 85 | variable_costs=10, |
||
| 86 | nonconvex=solph.NonConvex(startup_costs=5, shutdown_costs=5), |
||
| 87 | ) |
||
| 88 | }, |
||
| 89 | ) |
||
| 90 | es.add(bel, demand_el, pp1, pp2) |
||
| 91 | # create an optimization problem and solve it |
||
| 92 | om = solph.Model(es) |
||
| 93 | |||
| 94 | # debugging |
||
| 95 | # om.write('problem.lp', io_options={'symbolic_solver_labels': True}) |
||
| 96 | |||
| 97 | # solve model |
||
| 98 | om.solve(solver="cbc", solve_kwargs={"tee": True}) |
||
| 99 | |||
| 100 | # create result object |
||
| 101 | results = solph.processing.results(om) |
||
| 102 | |||
| 103 | # plot electrical bus |
||
| 104 | to_bus = pd.DataFrame( |
||
| 105 | { |
||
| 106 | k[0].label: v["sequences"]["flow"] |
||
| 107 | for k, v in results.items() |
||
| 108 | if k[1] == bel |
||
| 109 | } |
||
| 110 | ) |
||
| 111 | from_bus = pd.DataFrame( |
||
| 112 | { |
||
| 113 | k[1].label: v["sequences"]["flow"] * -1 |
||
| 114 | for k, v in results.items() |
||
| 115 | if k[0] == bel |
||
| 116 | } |
||
| 117 | ) |
||
| 118 | data = pd.concat([from_bus, to_bus], axis=1) |
||
| 119 | ax = data.plot(kind="line", drawstyle="steps-post", grid=True, rot=0) |
||
| 120 | ax.set_xlabel("Hour") |
||
| 121 | ax.set_ylabel("P (MW)") |
||
| 122 | plt.show() |
||
| 123 | |||
| 127 |