Issues (108)

tests/test_processing.py (2 issues)

1
# -*- coding: utf-8 -
2
3
"""Tests the processing module of solph.
4
5
This file is part of project oemof (github.com/oemof/oemof). It's copyrighted
6
by the contributors recorded in the version control history of the file,
7
available from its original location oemof/tests/test_processing.py
8
9
SPDX-License-Identifier: MIT
10
"""
11
12
import pandas
13
import pytest
14
from pandas.testing import assert_frame_equal
15
from pandas.testing import assert_series_equal
16
17
from oemof.solph import EnergySystem
18
from oemof.solph import Investment
19
from oemof.solph import Model
20
from oemof.solph import processing
21
from oemof.solph import views
22
from oemof.solph.buses import Bus
23
from oemof.solph.components import Converter
24
from oemof.solph.components import GenericStorage
25
from oemof.solph.components import Sink
26
from oemof.solph.flows import Flow
27
28
29
class TestParameterResult:
30
    @classmethod
31
    def setup_class(cls):
32
        cls.period = 24
33
        cls.es = EnergySystem(
34
            timeindex=pandas.date_range(
35
                "2016-01-01",
36
                periods=cls.period,
37
                freq="h",
38
            ),
39
            infer_last_interval=True,
40
        )
41
42
        # BUSSES
43
        b_el1 = Bus(label="b_el1")
44
        b_el2 = Bus(label="b_el2")
45
        b_diesel = Bus(label="b_diesel", balanced=False)
46
        cls.es.add(b_el1, b_el2, b_diesel)
47
48
        # TEST DIESEL:
49
        dg = Converter(
50
            label="diesel",
51
            inputs={b_diesel: Flow(variable_costs=2)},
52
            outputs={
53
                b_el1: Flow(
54
                    variable_costs=1, nominal_capacity=Investment(ep_costs=0.5)
55
                )
56
            },
57
            conversion_factors={b_el1: 2},
58
        )
59
60
        batt = GenericStorage(
61
            label="storage",
62
            inputs={b_el1: Flow(variable_costs=3)},
63
            outputs={b_el2: Flow(variable_costs=2.5)},
64
            loss_rate=0.00,
65
            initial_storage_level=0,
66
            invest_relation_input_capacity=1 / 6,
67
            invest_relation_output_capacity=1 / 6,
68
            inflow_conversion_factor=1,
69
            outflow_conversion_factor=0.8,
70
            nominal_capacity=Investment(ep_costs=0.4),
71
        )
72
73
        cls.demand_values = [0.0] + [100] * 23
74
        demand = Sink(
75
            label="demand_el",
76
            inputs={
77
                b_el2: Flow(
78
                    nominal_capacity=1,
79
                    fix=cls.demand_values,
80
                )
81
            },
82
        )
83
        cls.es.add(dg, batt, demand)
84
        cls.om = Model(cls.es)
85
        cls.om.receive_duals()
86
        cls.om.solve()
87
        cls.mod = Model(cls.es)
88
        cls.mod.solve()
89
90
    def test_flows_with_none_exclusion(self):
91
        b_el2 = self.es.groups["b_el2"]
92
        demand = self.es.groups["demand_el"]
93
        param_results = processing.parameter_as_dict(
94
            self.es, exclude_none=True
95
        )
96
        assert_series_equal(
97
            param_results[(b_el2, demand)]["scalars"].sort_index(),
98
            pandas.Series(
99
                {
100
                    "bidirectional": False,
101
                    "integer": False,
102
                    "nominal_capacity": 1,
103
                    "max": 1,
104
                    "min": 0,
105
                    "variable_costs": 0,
106
                    "label": str(b_el2.outputs[demand].label),
107
                }
108
            ).sort_index(),
109
        )
110
        assert_frame_equal(
111
            param_results[(b_el2, demand)]["sequences"],
112
            pandas.DataFrame({"fix": self.demand_values}),
113
            check_like=True,
114
        )
115
116
    def test_flows_without_none_exclusion(self):
117
        b_el2 = self.es.groups["b_el2"]
118
        demand = self.es.groups["demand_el"]
119
        param_results = processing.parameter_as_dict(
120
            self.es, exclude_none=False
121
        )
122
        default_attributes = {
123
            "age": None,
124
            "lifetime": None,
125
            "integer": False,
126
            "investment": None,
127
            "nominal_capacity": 1,
128
            "nonconvex": None,
129
            "bidirectional": False,
130
            "full_load_time_max": None,
131
            "full_load_time_min": None,
132
            "max": 1,
133
            "min": 0,
134
            "negative_gradient_limit": None,
135
            "positive_gradient_limit": None,
136
            "variable_costs": 0,
137
            "fixed_costs": None,
138
            "flow": None,
139
            "values": None,
140
            "label": str(b_el2.outputs[demand].label),
141
        }
142
        assert_series_equal(
143
            param_results[(b_el2, demand)]["scalars"].sort_index(),
144
            pandas.Series(default_attributes).sort_index(),
145
        )
146
        sequences_attributes = {
147
            "fix": self.demand_values,
148
        }
149
150
        assert_frame_equal(
151
            param_results[(b_el2, demand)]["sequences"],
152
            pandas.DataFrame(sequences_attributes),
153
            check_like=True,
154
        )
155
156 View Code Duplication
    def test_nodes_with_none_exclusion(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
157
        param_results = processing.parameter_as_dict(
158
            self.es, exclude_none=True
159
        )
160
        param_results = processing.convert_keys_to_strings(param_results)
161
        assert_series_equal(
162
            param_results[("storage", "None")]["scalars"],
163
            pandas.Series(
164
                {
165
                    "balanced": True,
166
                    "initial_storage_level": 0,
167
                    "investment_age": 0,
168
                    "investment_existing": 0,
169
                    "investment_nonconvex": False,
170
                    "investment_ep_costs": 0.4,
171
                    "investment_maximum": float("inf"),
172
                    "investment_minimum": 0,
173
                    "investment_nonconvex": False,
174
                    "investment_offset": 0,
175
                    "label": "storage",
176
                    "fixed_costs": 0,
177
                    "fixed_losses_absolute": 0,
178
                    "fixed_losses_relative": 0,
179
                    "inflow_conversion_factor": 1,
180
                    "invest_relation_input_capacity": 1 / 6,
181
                    "invest_relation_output_capacity": 1 / 6,
182
                    "loss_rate": 0,
183
                    "max_storage_level": 1,
184
                    "min_storage_level": 0,
185
                    "outflow_conversion_factor": 0.8,
186
                }
187
            ),
188
        )
189
        assert_frame_equal(
190
            param_results[("storage", "None")]["sequences"], pandas.DataFrame()
191
        )
192
193 View Code Duplication
    def test_nodes_with_none_exclusion_old_name(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
194
        param_results = processing.parameter_as_dict(
195
            self.es, exclude_none=True
196
        )
197
        param_results = processing.convert_keys_to_strings(
198
            param_results, keep_none_type=True
199
        )
200
        assert_series_equal(
201
            param_results[("storage", None)]["scalars"],
202
            pandas.Series(
203
                {
204
                    "balanced": True,
205
                    "initial_storage_level": 0,
206
                    "investment_age": 0,
207
                    "investment_existing": 0,
208
                    "investment_nonconvex": False,
209
                    "investment_ep_costs": 0.4,
210
                    "investment_maximum": float("inf"),
211
                    "investment_minimum": 0,
212
                    "investment_nonconvex": False,
213
                    "investment_offset": 0,
214
                    "label": "storage",
215
                    "fixed_costs": 0,
216
                    "fixed_losses_absolute": 0,
217
                    "fixed_losses_relative": 0,
218
                    "inflow_conversion_factor": 1,
219
                    "invest_relation_input_capacity": 1 / 6,
220
                    "invest_relation_output_capacity": 1 / 6,
221
                    "loss_rate": 0,
222
                    "max_storage_level": 1,
223
                    "min_storage_level": 0,
224
                    "outflow_conversion_factor": 0.8,
225
                }
226
            ),
227
        )
228
        assert_frame_equal(
229
            param_results[("storage", None)]["sequences"], pandas.DataFrame()
230
        )
231
232
    def test_nodes_without_none_exclusion(self):
233
        diesel = self.es.groups["diesel"]
234
        param_results = processing.parameter_as_dict(
235
            self.es, exclude_none=False
236
        )
237
        assert_series_equal(
238
            param_results[(diesel, None)]["scalars"],
239
            pandas.Series(
240
                {
241
                    "label": "diesel",
242
                    "conversion_factors_b_el1": 2,
243
                    "conversion_factors_b_diesel": 1,
244
                }
245
            ),
246
        )
247
        assert_frame_equal(
248
            param_results[(diesel, None)]["sequences"], pandas.DataFrame()
249
        )
250
251
    def test_nodes_with_excluded_attrs(self):
252
        diesel = self.es.groups["diesel"]
253
        param_results = processing.parameter_as_dict(
254
            self.es, exclude_attrs=["conversion_factors"]
255
        )
256
        assert_series_equal(
257
            param_results[(diesel, None)]["scalars"],
258
            pandas.Series(
259
                {
260
                    "label": "diesel",
261
                }
262
            ),
263
        )
264
        assert_frame_equal(
265
            param_results[(diesel, None)]["sequences"], pandas.DataFrame()
266
        )
267
268
    def test_parameter_with_node_view(self):
269
        param_results = processing.parameter_as_dict(
270
            self.es, exclude_none=True
271
        )
272
        bel1 = views.node(param_results, "b_el1")
273
        assert (
274
            bel1["scalars"][[(("b_el1", "storage"), "variable_costs")]].values
275
            == 3
276
        )
277
278
        bel1_m = views.node(param_results, "b_el1", multiindex=True)
279
        assert bel1_m["scalars"][("b_el1", "storage", "variable_costs")] == 3
280
281
    def test_multiindex_sequences(self):
282
        results = processing.results(self.om)
283
        bel1 = views.node(results, "b_el1", multiindex=True)
284
        assert (
285
            int(bel1["sequences"][("diesel", "b_el1", "flow")].sum()) == 2875
286
        )
287
288
    def test_error_from_nan_values(self):
289
        trsf = self.es.groups["diesel"]
290
        bus = self.es.groups["b_el1"]
291
        self.mod.flow[trsf, bus, 5] = float("nan")
292
        with pytest.raises(ValueError):
293
            processing.results(self.mod)
294
295
    def test_duals(self):
296
        results = processing.results(self.om)
297
        bel = views.node(results, "b_el1", multiindex=True)
298
        assert int(bel["sequences"]["b_el1", "None", "duals"].sum()) == 48
299
300
    def test_node_weight_by_type(self):
301
        results = processing.results(self.om)
302
        storage_content = views.node_weight_by_type(
303
            results, node_type=GenericStorage
304
        )
305
        assert (
306
            storage_content.sum().iloc[0] == pytest.approx(1437.5, abs=0.1)
307
        ).all()
308
309
    def test_output_by_type_view(self):
310
        results = processing.results(self.om)
311
        converter_output = views.node_output_by_type(
312
            results, node_type=Converter
313
        )
314
        compare = views.node(results, "diesel", multiindex=True)["sequences"][
315
            ("diesel", "b_el1", "flow")
316
        ]
317
        assert converter_output.sum().iloc[0] == pytest.approx(compare.sum())
318
319
    def test_input_by_type_view(self):
320
        results = processing.results(self.om)
321
        sink_input = views.node_input_by_type(results, node_type=Sink)
322
        compare = views.node(results, "demand_el", multiindex=True)
323
        assert sink_input.sum().iloc[0] == pytest.approx(
324
            compare["sequences"][("b_el2", "demand_el", "flow")].sum()
325
        )
326
327
    def test_net_storage_flow(self):
328
        results = processing.results(self.om)
329
        storage_flow = views.net_storage_flow(
330
            results, node_type=GenericStorage
331
        )
332
333
        compare = views.node(results, "storage", multiindex=True)["sequences"]
334
335
        assert (
336
            (
337
                (
338
                    compare[("storage", "b_el2", "flow")]
339
                    - compare[("b_el1", "storage", "flow")]
340
                )
341
                .to_frame()
342
                .fillna(0)
343
                == storage_flow.values
344
            )
345
            .all()
346
            .iloc[0]
347
        )
348
349
    def test_output_by_type_view_empty(self):
350
        results = processing.results(self.om)
351
        view = views.node_output_by_type(results, node_type=Flow)
352
        assert view is None
353
354
    def test_input_by_type_view_empty(self):
355
        results = processing.results(self.om)
356
        view = views.node_input_by_type(results, node_type=Flow)
357
        assert view is None
358
359
    def test_net_storage_flow_empty(self):
360
        results = processing.results(self.om)
361
        view = views.net_storage_flow(results, node_type=Sink)
362
        assert view is None
363
        view2 = views.net_storage_flow(results, node_type=Flow)
364
        assert view2 is None
365
366
    def test_node_weight_by_type_empty(self):
367
        results = processing.results(self.om)
368
        view = views.node_weight_by_type(results, node_type=Flow)
369
        assert view is None
370