dual_variable_example   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 303
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 2
eloc 188
dl 0
loc 303
rs 10
c 0
b 0
f 0

1 Function

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