Passed
Pull Request — dev (#850)
by Uwe
01:29
created

dual_variable_example.main()   B

Complexity

Conditions 1

Size

Total Lines 259
Code Lines 181

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 181
dl 0
loc 259
rs 7
c 0
b 0
f 0
cc 1
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
7
A basic example to show how to get the dual variables from the system. Try
8
to understand the plot.
9
10
11
Installation requirements
12
-------------------------
13
14
This example requires the version v0.5.x of oemof.solph:
15
16
    pip install 'oemof.solph[examples]>=0.5,<0.6'
17
18
SPDX-FileCopyrightText: Uwe Krien <[email protected]>
19
20
SPDX-License-Identifier: MIT
21
"""
22
23
24
def main():
25
    # *************************************************************************
26
    # ********** PART 1 - Define and optimise the energy system ***************
27
    # *************************************************************************
28
29
    ###########################################################################
30
    # imports
31
    ###########################################################################
32
33
    import pandas as pd
34
    from matplotlib import pyplot as plt
35
    from oemof.tools import logger
36
37
    from oemof.solph import EnergySystem
38
    from oemof.solph import Model
39
    from oemof.solph import buses
40
    from oemof.solph import components as cmp
41
    from oemof.solph import flows
42
    from oemof.solph import processing
43
44
    solver = "cbc"  # 'glpk', 'gurobi',....
45
    number_of_time_steps = 48
46
    solver_verbose = False  # show/hide solver output
47
48
    # initiate the logger (see the API docs for more information)
49
    logger.define_logging()
50
51
    date_time_index = pd.date_range(
52
        "1/1/2012", periods=number_of_time_steps, freq="H"
53
    )
54
55
    energysystem = EnergySystem(
56
        timeindex=date_time_index, infer_last_interval=True
57
    )
58
59
    demand = [
60
        209,
61
        207,
62
        200,
63
        191,
64
        185,
65
        180,
66
        172,
67
        170,
68
        171,
69
        179,
70
        189,
71
        201,
72
        208,
73
        207,
74
        205,
75
        206,
76
        217,
77
        232,
78
        237,
79
        232,
80
        224,
81
        219,
82
        223,
83
        213,
84
        201,
85
        192,
86
        187,
87
        184,
88
        184,
89
        182,
90
        180,
91
        191,
92
        207,
93
        222,
94
        231,
95
        238,
96
        241,
97
        237,
98
        234,
99
        235,
100
        242,
101
        264,
102
        265,
103
        260,
104
        245,
105
        238,
106
        241,
107
        231,
108
    ]
109
    pv = [
110
        0.18,
111
        0.11,
112
        0.05,
113
        0.05,
114
        0.0,
115
        0.0,
116
        0.0,
117
        0.0,
118
        0.0,
119
        0.0,
120
        0.0,
121
        0.0,
122
        0.0,
123
        0.05,
124
        0.07,
125
        0.11,
126
        0.13,
127
        0.15,
128
        0.22,
129
        0.28,
130
        0.33,
131
        0.25,
132
        0.17,
133
        0.09,
134
        0.09,
135
        0.07,
136
        0.05,
137
        0.05,
138
        0.0,
139
        0.0,
140
        0.0,
141
        0.0,
142
        0.0,
143
        0.0,
144
        0.0,
145
        0.0,
146
        0.0,
147
        0.09,
148
        0.21,
149
        0.33,
150
        0.44,
151
        0.54,
152
        0.61,
153
        0.65,
154
        0.67,
155
        0.64,
156
        0.59,
157
        0.52,
158
    ]
159
160
    ##########################################################################
161
    # Create oemof object
162
    ##########################################################################
163
164
    # create natural gas bus
165
    bus_gas = buses.Bus(label="natural_gas")
166
167
    # create electricity bus
168
    bus_elec = buses.Bus(label="electricity")
169
170
    # adding the buses to the energy system
171
    energysystem.add(bus_gas, bus_elec)
172
173
    # create excess component for the electricity bus to allow overproduction
174
    energysystem.add(
175
        cmp.Sink(label="excess_bel", inputs={bus_elec: flows.Flow()})
176
    )
177
178
    # create source object representing the gas commodity (annual limit)
179
    energysystem.add(
180
        cmp.Source(
181
            label="rgas",
182
            outputs={bus_gas: flows.Flow(variable_costs=38)},
183
        )
184
    )
185
186
    # create fixed source object representing pv power plants
187
    energysystem.add(
188
        cmp.Source(
189
            label="pv",
190
            outputs={bus_elec: flows.Flow(fix=pv, nominal_value=700)},
191
        )
192
    )
193
194
    # create simple sink object representing the electrical demand
195
    energysystem.add(
196
        cmp.Sink(
197
            label="demand",
198
            inputs={bus_elec: flows.Flow(fix=demand, nominal_value=1)},
199
        )
200
    )
201
202
    # create simple transformer object representing a gas power plant
203
    energysystem.add(
204
        cmp.Transformer(
205
            label="pp_gas",
206
            inputs={bus_gas: flows.Flow()},
207
            outputs={bus_elec: flows.Flow(nominal_value=400)},
208
            conversion_factors={bus_elec: 0.5},
209
        )
210
    )
211
212
    # create storage object representing a battery
213
    cap = 400
214
    storage = cmp.GenericStorage(
215
        nominal_storage_capacity=cap,
216
        label="storage",
217
        inputs={bus_elec: flows.Flow(nominal_value=cap / 6)},
218
        outputs={
219
            bus_elec: flows.Flow(nominal_value=cap / 6, variable_costs=0.001)
220
        },
221
        loss_rate=0.00,
222
        initial_storage_level=0,
223
        inflow_conversion_factor=1,
224
        outflow_conversion_factor=0.8,
225
    )
226
227
    energysystem.add(storage)
228
229
    ##########################################################################
230
    # Optimise the energy system and plot the results
231
    ##########################################################################
232
233
    # initialise the operational model
234
    model = Model(energysystem)
235
236
    model.receive_duals()
237
238
    # if tee_switch is true solver messages will be displayed
239
    model.solve(solver=solver, solve_kwargs={"tee": solver_verbose})
240
241
    # add results to the energy system to make it possible to store them.
242
    results = processing.results(model)
243
244
    flows_to_bus = pd.DataFrame(
245
        {
246
            str(k[0].label): v["sequences"]["flow"]
247
            for k, v in results.items()
248
            if k[1] is not None and k[1] == bus_elec
249
        }
250
    )
251
    flows_from_bus = pd.DataFrame(
252
        {
253
            str(k[1].label): v["sequences"]["flow"]
254
            for k, v in results.items()
255
            if k[1] is not None and k[0] == bus_elec
256
        }
257
    )
258
259
    storage = pd.DataFrame(
260
        {
261
            str(k[0].label): v["sequences"]["storage_content"]
262
            for k, v in results.items()
263
            if k[1] is None and k[0] == storage
264
        }
265
    )
266
267
    duals = pd.DataFrame(
268
        {
269
            str(k[0].label): v["sequences"]["duals"]
270
            for k, v in results.items()
271
            if k[1] is None and isinstance(k[0], buses.Bus)
272
        }
273
    )
274
275
    my_flows = pd.concat(
276
        [flows_to_bus, flows_from_bus, storage, duals],
277
        keys=["to_bus", "from_bus", "content", "duals"],
278
        axis=1,
279
    )
280
281
    my_flows.plot()
282
    plt.show()
283
284
285
if __name__ == "__main__":
286
    main()
287