Passed
Pull Request — dev (#1208)
by Patrik
04:04 queued 02:13
created

test_piecewiselineartransformer   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 3
eloc 63
dl 0
loc 104
rs 10
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B test_pwltf() 0 78 3
1
# -*- coding: utf-8 -*-
2
"""
3
Example that illustrates how to use custom component
4
`PiecewiseLinearConverter` can be used.
5
6
This file is part of project oemof (github.com/oemof/oemof). It's copyrighted
7
by the contributors recorded in the version control history of the file,
8
available from its original location
9
oemof/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py
10
11
SPDX-License-Identifier: GPL-3.0-or-later
12
"""
13
14
import numpy as np
15
import pandas as pd
16
17
import oemof.solph as solph
18
from oemof.solph import EnergySystem
19
from oemof.solph import Model
20
from oemof.solph import processing
21
from oemof.solph.buses import Bus
22
from oemof.solph.components import Sink
23
from oemof.solph.flows import Flow
24
25
26
def test_pwltf():
27
    # Set timeindex and create data
28
    periods = 20
29
    datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="h")
30
    step = 5
31
    demand = np.arange(0, step * periods, step)
32
33
    # Set up EnergySystem, buses and sink
34
    energysystem = EnergySystem(
35
        timeindex=datetimeindex, infer_last_interval=True
36
    )
37
    b_gas = Bus(label="biogas", balanced=False)
38
    b_el = Bus(label="electricity")
39
    demand_el = Sink(
40
        label="demand",
41
        inputs={b_el: Flow(nominal_capacity=1, fix=demand)},
42
    )
43
44
    energysystem.add(b_gas, b_el, demand_el)
45
46
    # Define conversion function and breakpoints
47
    def conv_func(x):
48
        return 0.01 * x**2
49
50
    in_breakpoints = np.arange(0, 110, 25)
51
52
    # Create and add PiecewiseLinearConverter
53
    pwltf = solph.components.experimental.PiecewiseLinearConverter(
54
        label="pwltf",
55
        inputs={
56
            b_gas: solph.flows.Flow(nominal_capacity=100, variable_costs=1)
57
        },
58
        outputs={b_el: solph.flows.Flow()},
59
        in_breakpoints=in_breakpoints,
60
        conversion_function=conv_func,
61
        pw_repn="CC",
62
    )
63
64
    energysystem.add(pwltf)
65
66
    # Create and solve the optimization model
67
    optimization_model = Model(energysystem)
68
    optimization_model.solve(solver="cbc")
69
70
    # Get results
71
    results = processing.results(
72
        optimization_model, remove_last_time_point=True
73
    )
74
    string_results = processing.convert_keys_to_strings(results)
75
    sequences = {k: v["sequences"] for k, v in string_results.items()}
76
    df = pd.concat(sequences, axis=1)
77
    df[("efficiency", None, None)] = df[("pwltf", "electricity")].divide(
78
        df[("biogas", "pwltf")]
79
    )
80
81
    # Test: Compare results with piecewise linearized function
82
    def linearized_func(func, x_break, x):
83
        y_break = func(x_break)
84
        condlist = [
85
            (x_l <= x) & (x < x_u)
86
            for x_l, x_u in zip(x_break[:-1], x_break[1:])
87
        ]
88
        funclist = []
89
        for i in range(len(x_break) - 1):
90
            b = y_break[i]
91
            a = (
92
                (y_break[i + 1] - y_break[i])
93
                * 1
94
                / (x_break[i + 1] - x_break[i])
95
            )
96
            funclist.append(lambda x, b=b, a=a, i=i: b + a * (x - x_break[i]))
97
        return np.piecewise(x, condlist, funclist)
98
99
    production_expected = linearized_func(
100
        conv_func, in_breakpoints, df[("biogas", "pwltf")]["flow"].values
101
    )
102
    production_modeled = df[("pwltf", "electricity")]["flow"].values
103
    assert np.allclose(production_modeled, production_expected)
104