Passed
Pull Request — dev (#850)
by Uwe
08:28 queued 07:10
created

startup_shutdown   A

Complexity

Total Complexity 0

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 0
eloc 67
dl 0
loc 122
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
3
"""
4
General description
5
-------------------
6
Example that illustrates how to model startup and shutdown costs attributed
7
to a binary flow.
8
9
Installation requirements
10
-------------------------
11
This example requires oemof.solph (v0.5.x), install by:
12
13
    pip install oemof.solph[examples]
14
15
License
16
-------
17
`MIT license <https://github.com/oemof/oemof-solph/blob/dev/LICENSE>`_
18
19
"""
20
import pandas as pd
21
from oemof import solph
22
import matplotlib.pyplot as plt
23
24
25
demand_el = [
26
    0,
27
    0,
28
    0,
29
    1,
30
    1,
31
    1,
32
    0,
33
    0,
34
    1,
35
    1,
36
    1,
37
    0,
38
    0,
39
    1,
40
    1,
41
    1,
42
    0,
43
    0,
44
    1,
45
    1,
46
    1,
47
    1,
48
    0,
49
    0,
50
]
51
# create an energy system
52
idx = solph.create_time_index(2017, number=len(demand_el))
53
es = solph.EnergySystem(timeindex=idx, infer_last_interval=False)
54
55
# power bus and components
56
bel = solph.Bus(label="bel")
57
58
demand_el = solph.components.Sink(
59
    label="demand_el",
60
    inputs={bel: solph.Flow(fix=demand_el, nominal_value=10)},
61
)
62
63
# pp1 and pp2 are competing to serve overall 12 units load at lowest cost
64
# summed costs for pp1 = 12 * 10 * 10.25 = 1230
65
# summed costs for pp2 = 4*5 + 4*5 + 12 * 10 * 10 = 1240
66
# => pp1 serves the load despite of higher variable costs since
67
#    the start and shutdown costs of pp2 change its marginal costs
68
pp1 = solph.components.Source(
69
    label="power_plant1",
70
    outputs={bel: solph.Flow(nominal_value=10, variable_costs=10.25)},
71
)
72
73
# shutdown costs only work in combination with a minimum load
74
# since otherwise the status variable is "allowed" to be active i.e.
75
# it permanently has a value of one which does not allow to set the shutdown
76
# variable which is set to one if the status variable changes from one to zero
77
pp2 = solph.components.Source(
78
    label="power_plant2",
79
    outputs={
80
        bel: solph.Flow(
81
            nominal_value=10,
82
            min=0.5,
83
            max=1.0,
84
            variable_costs=10,
85
            nonconvex=solph.NonConvex(startup_costs=5, shutdown_costs=5),
86
        )
87
    },
88
)
89
es.add(bel, demand_el, pp1, pp2)
90
# create an optimization problem and solve it
91
om = solph.Model(es)
92
93
# debugging
94
# om.write('problem.lp', io_options={'symbolic_solver_labels': True})
95
96
# solve model
97
om.solve(solver="cbc", solve_kwargs={"tee": True})
98
99
# create result object
100
results = solph.processing.results(om)
101
102
# plot electrical bus
103
to_bus = pd.DataFrame(
104
    {
105
        k[0].label: v["sequences"]["flow"]
106
        for k, v in results.items()
107
        if k[1] == bel
108
    }
109
)
110
from_bus = pd.DataFrame(
111
    {
112
        k[1].label: v["sequences"]["flow"] * -1
113
        for k, v in results.items()
114
        if k[0] == bel
115
    }
116
)
117
data = pd.concat([from_bus, to_bus], axis=1)
118
ax = data.plot(kind="line", drawstyle="steps-post", grid=True, rot=0)
119
ax.set_xlabel("Hour")
120
ax.set_ylabel("P (MW)")
121
plt.show()
122