Completed
Push — dev ( 468d85...f4c061 )
by Patrik
23s queued 17s
created

saturating_storage.saturating_storage_example()   B

Complexity

Conditions 2

Size

Total Lines 102
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 69
dl 0
loc 102
rs 8.0145
c 0
b 0
f 0
cc 2
nop 0

How to fix   Long Method   

Long Method

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:

1
# -*- coding: utf-8 -*-
2
3
"""
4
General description
5
-------------------
6
Example that shows the how to implement a `GenericStorage`
7
that charges at reduced rates for high storage contents.
8
9
Code
10
----
11
Download source code: :download:`saturating_storage.py </../examples/flexible_modelling/saturating_storage.py>`
12
13
.. dropdown:: Click to display code
14
15
    .. literalinclude:: /../examples/flexible_modelling/saturating_storage.py
16
        :language: python
17
        :lines: 34-140
18
19
20
Installation requirements
21
-------------------------
22
This example requires oemof.solph (v0.6.x), install by:
23
24
.. code:: bash
25
26
    pip install oemof.solph[examples]
27
28
29
License
30
-------
31
`MIT license <https://github.com/oemof/oemof-solph/blob/dev/LICENSE>`_
32
"""
33
34
import pandas as pd
35
from matplotlib import pyplot as plt
36
from pyomo import environ as po
37
38
from oemof import solph
39
40
41
def main(optimize=True):
42
    # create an energy system
43
    idx = pd.date_range("1/1/2023", periods=100, freq="h")
44
    es = solph.EnergySystem(timeindex=idx, infer_last_interval=False)
45
46
    # power bus
47
    bel = solph.Bus(label="bel")
48
    es.add(bel)
49
50
    es.add(
51
        solph.components.Source(
52
            label="source_el",
53
            outputs={bel: solph.Flow(nominal_capacity=1, fix=1)},
54
        )
55
    )
56
57
    es.add(
58
        solph.components.Sink(
59
            label="sink_el",
60
            inputs={
61
                bel: solph.Flow(
62
                    nominal_capacity=1,
63
                    variable_costs=1,
64
                )
65
            },
66
        )
67
    )
68
69
    # Electric Storage
70
71
    inflow_capacity = 0.5
72
    full_charging_limit = 0.4
73
    storage_capacity = 10
74
    battery = solph.components.GenericStorage(
75
        label="battery",
76
        nominal_capacity=storage_capacity,
77
        inputs={bel: solph.Flow(nominal_capacity=inflow_capacity)},
78
        outputs={bel: solph.Flow(variable_costs=2)},
79
        initial_storage_level=0,
80
        balanced=False,
81
        loss_rate=0.0001,
82
    )
83
    es.add(battery)
84
85
    if optimize is False:
86
        return es
87
88
    # create an optimization problem and solve it
89
    model = solph.Model(es)
90
91
    def soc_limit_rule(m):
92
        for ts in m.TIMESTEPS:
93
            soc = (
94
                m.GenericStorageBlock.storage_content[battery, ts + 1]
95
                / storage_capacity
96
            )
97
            expr = (1 - soc) / (1 - full_charging_limit) >= m.flow[
98
                bel, battery, ts
99
            ] / inflow_capacity
100
            getattr(m, "soc_limit").add(ts, expr)
101
102
    setattr(
103
        model,
104
        "soc_limit",
105
        po.Constraint(
106
            model.TIMESTEPS,
107
            noruleinit=True,
108
        ),
109
    )
110
    setattr(
111
        model,
112
        "soc_limit_build",
113
        po.BuildAction(rule=soc_limit_rule),
114
    )
115
116
    # solve model
117
    model.solve(solver="cbc")
118
119
    # create result object
120
    results = solph.processing.results(model)
121
122
    plt.plot(
123
        results[(battery, None)]["sequences"]["storage_content"],
124
        "r--",
125
        label="content",
126
    )
127
    plt.step(
128
        20 * results[(bel, battery)]["sequences"]["flow"],
129
        "b-",
130
        label="20*inflow",
131
    )
132
    plt.legend()
133
    plt.grid()
134
135
    plt.figure()
136
    plt.plot(
137
        results[(battery, None)]["sequences"]["storage_content"][1:],
138
        results[(bel, battery)]["sequences"]["flow"][:-1],
139
        "b-",
140
    )
141
    plt.grid()
142
    plt.xlabel("Storage content")
143
    plt.ylabel("Charging power")
144
145
    plt.show()
146
147
148
if __name__ == "__main__":
149
    main()
150