1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
|
3
|
|
|
""" |
4
|
|
|
This example gives a simplified idea how Facades and SubNetworks |
5
|
|
|
might be used to work with discretised temperatures. |
6
|
|
|
|
7
|
|
|
SPDX-FileCopyrightText: Patrik Schönfeldt <[email protected]> |
8
|
|
|
SPDX-FileCopyrightText: Deutsches Zentrum für Luft- und Raumfahrt (DLR) |
9
|
|
|
|
10
|
|
|
SPDX-License-Identifier: MIT |
11
|
|
|
""" |
12
|
|
|
|
13
|
|
|
import numpy as np |
14
|
|
|
|
15
|
|
|
from oemof.network import SubNetwork |
16
|
|
|
|
17
|
|
|
from oemof import solph |
18
|
|
|
|
19
|
|
|
|
20
|
|
|
class HeatPump(solph.Facade): |
21
|
|
|
|
22
|
|
|
def __init__( |
23
|
|
|
self, |
24
|
|
|
label: str, |
25
|
|
|
el_supply: solph.Bus, |
26
|
|
|
heat_demand: dict[solph.Bus, float], |
27
|
|
|
source_temperature: float | list[float], |
28
|
|
|
cpf: float = 0.5, |
29
|
|
|
el_power_limit: float = None, |
30
|
|
|
): |
31
|
|
|
self.el_supply_bus = el_supply |
32
|
|
|
self.heat_demand_buses = heat_demand |
33
|
|
|
self.temperature = np.array(source_temperature) |
34
|
|
|
|
35
|
|
|
self.cpf = cpf |
36
|
|
|
self.el_power_limit = el_power_limit |
37
|
|
|
|
38
|
|
|
super().__init__(label=label, facade_type=type(self)) |
39
|
|
|
|
40
|
|
|
def define_subnetwork(self): |
41
|
|
|
el_bus = self.subnode( |
42
|
|
|
solph.Bus, |
43
|
|
|
label="el", |
44
|
|
|
inputs={ |
45
|
|
|
self.el_supply_bus: solph.Flow( |
46
|
|
|
nominal_capacity=self.el_power_limit, |
47
|
|
|
), |
48
|
|
|
}, |
49
|
|
|
) |
50
|
|
|
|
51
|
|
|
for target, temperature in self.heat_demand_buses.items(): |
52
|
|
|
cop = self.cpf * temperature / (temperature - self.temperature) |
53
|
|
|
|
54
|
|
|
self.subnode( |
55
|
|
|
solph.components.Converter, |
56
|
|
|
label=f"hp_{temperature}", |
57
|
|
|
inputs={el_bus: solph.Flow()}, |
58
|
|
|
outputs={target: solph.Flow()}, |
59
|
|
|
conversion_factors={el_bus: cop}, |
60
|
|
|
) |
61
|
|
|
|
62
|
|
|
|
63
|
|
|
def main(): |
64
|
|
|
|
65
|
|
|
date_time_index = solph.create_time_index(2025, number=2) |
66
|
|
|
|
67
|
|
|
# create the energysystem and assign the time index |
68
|
|
|
es = solph.EnergySystem( |
69
|
|
|
timeindex=date_time_index, infer_last_interval=False |
70
|
|
|
) |
71
|
|
|
|
72
|
|
|
el_bus = solph.Bus(label="el") |
73
|
|
|
el_source = solph.components.Source( |
74
|
|
|
label="el_grid", |
75
|
|
|
outputs={el_bus: solph.Flow(variable_costs=0.3)}, |
76
|
|
|
) |
77
|
|
|
es.add(el_bus, el_source) |
78
|
|
|
|
79
|
|
|
heat_demands = SubNetwork("heat demand") |
80
|
|
|
demand_bus_dhw = heat_demands.subnode(solph.Bus, "b_dhw") |
81
|
|
|
demand_bus_sh = heat_demands.subnode(solph.Bus, "b_sh") |
82
|
|
|
|
83
|
|
|
heat_demands.subnode( |
84
|
|
|
solph.components.Sink, |
85
|
|
|
label="d_dhw", |
86
|
|
|
inputs={demand_bus_dhw: solph.Flow(nominal_capacity=1, fix=[0, 0.2])}, |
87
|
|
|
) |
88
|
|
|
heat_demands.subnode( |
89
|
|
|
solph.components.Sink, |
90
|
|
|
label="d_sh", |
91
|
|
|
inputs={demand_bus_sh: solph.Flow(nominal_capacity=1, fix=[0.4, 2.1])}, |
92
|
|
|
) |
93
|
|
|
es.add(heat_demands) |
94
|
|
|
hp = HeatPump( |
95
|
|
|
"hp", |
96
|
|
|
el_supply=el_bus, |
97
|
|
|
heat_demand={demand_bus_dhw: 60.0, demand_bus_sh: 30}, |
98
|
|
|
source_temperature=[3, 0], |
99
|
|
|
cpf=0.45, |
100
|
|
|
) |
101
|
|
|
es.add(hp) |
102
|
|
|
|
103
|
|
|
model = solph.Model(es) |
104
|
|
|
model.solve() |
105
|
|
|
|
106
|
|
|
results = solph.Results(model) |
107
|
|
|
|
108
|
|
|
print(results.flow) |
109
|
|
|
|
110
|
|
|
|
111
|
|
|
if __name__ == "__main__": |
112
|
|
|
main() |
113
|
|
|
|