Completed
Push — dev ( 68ddc7...49e927 )
by Patrik
58s queued 48s
created

test_simple_dispatch   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 2
eloc 112
dl 0
loc 198
rs 10
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B test_dispatch_example() 0 166 2
1
# -*- coding: utf-8 -*-
2
3
"""This example shows how to create an energysystem with oemof objects and
4
solve it with the solph module.
5
6
Data: example_data.csv
7
8
This file is part of project oemof (github.com/oemof/oemof). It's copyrighted
9
by the contributors recorded in the version control history of the file,
10
available from its original location
11
oemof/tests/test_scripts/test_solph/test_simple_dispatch/test_simple_dispatch.py
12
13
SPDX-License-Identifier: MIT
14
"""
15
16
import os
17
18
import pandas as pd
19
import pytest
20
21
from oemof.solph import EnergySystem
22
from oemof.solph import Model
23
from oemof.solph import processing
24
from oemof.solph import views
25
from oemof.solph.buses import Bus
26
from oemof.solph.components import Converter
27
from oemof.solph.components import Sink
28
from oemof.solph.components import Source
29
from oemof.solph.flows import Flow
30
31
32
def test_dispatch_example(solver="cbc", periods=24 * 5):
33
    """Create an energy system and optimize the dispatch at least costs."""
34
35
    filename = os.path.join(os.path.dirname(__file__), "input_data.csv")
36
    data = pd.read_csv(filename, sep=",")
37
38
    # ######################### create energysystem components ################
39
40
    # resource buses
41
    bcoal = Bus(label="coal", balanced=False)
42
    bgas = Bus(label="gas", balanced=False)
43
    boil = Bus(label="oil", balanced=False)
44
    blig = Bus(label="lignite", balanced=False)
45
46
    # electricity and heat
47
    bel = Bus(label="b_el")
48
    bth = Bus(label="b_th")
49
50
    # an excess and a shortage variable can help to avoid infeasible problems
51
    excess_el = Sink(label="excess_el", inputs={bel: Flow()})
52
    # shortage_el = Source(label='shortage_el',
53
    #                      outputs={bel: Flow(variable_costs=200)})
54
55
    # sources
56
    wind = Source(
57
        label="wind",
58
        outputs={bel: Flow(fix=data["wind"], nominal_capacity=66.3)},
59
    )
60
61
    pv = Source(
62
        label="pv", outputs={bel: Flow(fix=data["pv"], nominal_capacity=65.3)}
63
    )
64
65
    # demands (electricity/heat)
66
    demand_el = Sink(
67
        label="demand_elec",
68
        inputs={bel: Flow(nominal_capacity=85, fix=data["demand_el"])},
69
    )
70
71
    demand_th = Sink(
72
        label="demand_therm",
73
        inputs={bth: Flow(nominal_capacity=40, fix=data["demand_th"])},
74
    )
75
76
    # power plants
77
    pp_coal = Converter(
78
        label="pp_coal",
79
        inputs={bcoal: Flow()},
80
        outputs={bel: Flow(nominal_capacity=20.2, variable_costs=25)},
81
        conversion_factors={bel: 0.39},
82
    )
83
84
    pp_lig = Converter(
85
        label="pp_lig",
86
        inputs={blig: Flow()},
87
        outputs={bel: Flow(nominal_capacity=11.8, variable_costs=19)},
88
        conversion_factors={bel: 0.41},
89
    )
90
91
    pp_gas = Converter(
92
        label="pp_gas",
93
        inputs={bgas: Flow()},
94
        outputs={bel: Flow(nominal_capacity=41, variable_costs=40)},
95
        conversion_factors={bel: 0.50},
96
    )
97
98
    pp_oil = Converter(
99
        label="pp_oil",
100
        inputs={boil: Flow()},
101
        outputs={bel: Flow(nominal_capacity=5, variable_costs=50)},
102
        conversion_factors={bel: 0.28},
103
    )
104
105
    # combined heat and power plant (chp)
106
    pp_chp = Converter(
107
        label="pp_chp",
108
        inputs={bgas: Flow()},
109
        outputs={
110
            bel: Flow(nominal_capacity=30, variable_costs=42),
111
            bth: Flow(nominal_capacity=40),
112
        },
113
        conversion_factors={bel: 0.3, bth: 0.4},
114
    )
115
116
    # heatpump with a coefficient of performance (COP) of 3
117
    b_heat_source = Bus(label="b_heat_source")
118
119
    heat_source = Source(label="heat_source", outputs={b_heat_source: Flow()})
120
121
    cop = 3
122
    heat_pump = Converter(
123
        label="heat_pump",
124
        inputs={bel: Flow(), b_heat_source: Flow()},
125
        outputs={bth: Flow(nominal_capacity=10)},
126
        conversion_factors={bel: 1 / 3, b_heat_source: (cop - 1) / cop},
127
    )
128
129
    datetimeindex = pd.date_range("1/1/2012", periods=periods, freq="h")
130
    energysystem = EnergySystem(
131
        timeindex=datetimeindex, infer_last_interval=True
132
    )
133
    energysystem.add(
134
        bcoal,
135
        bgas,
136
        boil,
137
        bel,
138
        bth,
139
        blig,
140
        excess_el,
141
        wind,
142
        pv,
143
        demand_el,
144
        demand_th,
145
        pp_coal,
146
        pp_lig,
147
        pp_oil,
148
        pp_gas,
149
        pp_chp,
150
        b_heat_source,
151
        heat_source,
152
        heat_pump,
153
    )
154
155
    # ################################ optimization ###########################
156
157
    # create optimization model based on energy_system
158
    optimization_model = Model(energysystem=energysystem)
159
160
    optimization_model.receive_duals()
161
162
    # solve problem
163
    optimization_model.solve(solver=solver)
164
165
    # write back results from optimization object to energysystem
166
    optimization_model.results()
167
168
    # ################################ results ################################
169
170
    # generic result object
171
    results = processing.results(model=optimization_model)
172
173
    # subset of results that includes all flows into and from electrical bus
174
    # sequences are stored within a pandas.DataFrames and scalars e.g.
175
    # investment values within a pandas.Series object.
176
    # in this case the entry data['scalars'] does not exist since no investment
177
    # variables are used
178
    data = views.node(results, "b_el")
179
180
    # generate results to be evaluated in tests
181
    results = data["sequences"].sum(axis=0).to_dict()
182
183
    test_results = {
184
        (("wind", "b_el"), "flow"): 1773,
185
        (("pv", "b_el"), "flow"): 605,
186
        (("b_el", "demand_elec"), "flow"): 7440,
187
        (("b_el", "excess_el"), "flow"): 139,
188
        (("pp_chp", "b_el"), "flow"): 666,
189
        (("pp_lig", "b_el"), "flow"): 1210,
190
        (("pp_gas", "b_el"), "flow"): 1519,
191
        (("pp_coal", "b_el"), "flow"): 1925,
192
        (("pp_oil", "b_el"), "flow"): 0,
193
        (("b_el", "heat_pump"), "flow"): 118,
194
    }
195
196
    for key in test_results.keys():
197
        assert results[key] == pytest.approx(test_results[key], abs=0.5)
198