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

district_heating_supply_2   A

Complexity

Total Complexity 0

Size/Duplication

Total Lines 235
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 0
eloc 144
dl 0
loc 235
rs 10
c 0
b 0
f 0
1
import pandas as pd
2
from helpers import LCOH, epc
3
4
import oemof.solph as solph
5
6
# %%[sec_1_start]
7
data = pd.read_csv("input_data.csv", sep=";", index_col=0, parse_dates=True)
8
# %%[sec_1_end]
9
10
district_heating_system = solph.EnergySystem(
11
    timeindex=data.index, infer_last_interval=False
12
)
13
14
heat_bus = solph.Bus(label="heat network")
15
gas_bus = solph.Bus(label="gas network")
16
17
district_heating_system.add(heat_bus, gas_bus)
18
# %%[sec_2_start]
19
waste_heat_bus = solph.Bus(label="waste heat network")
20
electricity_bus = solph.Bus(label="electricity network")
21
22
district_heating_system.add(waste_heat_bus, electricity_bus)
23
# %%[sec_2_end]
24
25
gas_source = solph.components.Source(
26
    label="gas source",
27
    outputs={gas_bus: solph.flows.Flow(variable_costs=data["gas price"])},
28
)
29
30
# nominal_value -> nominal_capacity
31
heat_sink = solph.components.Sink(
32
    label="heat sink",
33
    inputs={
34
        heat_bus: solph.flows.Flow(
35
            nominal_value=data["heat demand"].max(),
36
            fix=data["heat demand"] / data["heat demand"].max(),
37
        )
38
    },
39
)
40
41
district_heating_system.add(heat_sink, gas_source)
42
43
# %%[sec_3_start]
44
# ist die waste heat source fix oder unendlich?
45
waste_heat_source = solph.components.Source(
46
    label="waste heat source", outputs={waste_heat_bus: solph.flows.Flow()}
47
)
48
49
electricity_source = solph.components.Source(
50
    label="electricity source",
51
    outputs={
52
        electricity_bus: solph.flows.Flow(variable_costs=data["el_spot_price"])
53
    },
54
)
55
56
district_heating_system.add(waste_heat_source, electricity_source)
57
# %%[sec_3_end]
58
spec_inv_gas_boiler = 60000
59
var_cost_gas_boiler = 1.10
60
61
gas_boiler = solph.components.Converter(
62
    label="gas boiler",
63
    inputs={gas_bus: solph.flows.Flow()},
64
    outputs={
65
        heat_bus: solph.flows.Flow(
66
            nominal_value=solph.Investment(
67
                ep_costs=epc(spec_inv_gas_boiler), maximum=50
68
            ),
69
            variable_costs=var_cost_gas_boiler,
70
        )
71
    },
72
    conversion_factors={gas_bus: 0.95},
73
)
74
75
district_heating_system.add(gas_boiler)
76
77
# %%[sec_4_start]
78
cop = 3.5
79
spec_inv_heat_pump = 500000
80
var_cost_heat_pump = 1.2
81
82
heat_pump = solph.components.Converter(
83
    label="heat pump",
84
    inputs={
85
        electricity_bus: solph.flows.Flow(),
86
        waste_heat_bus: solph.flows.Flow(),
87
    },
88
    outputs={
89
        heat_bus: solph.flows.Flow(
90
            nominal_value=solph.Investment(ep_costs=epc(spec_inv_heat_pump)),
91
            variable_costs=1.2,
92
        )
93
    },
94
    conversion_factors={
95
        electricity_bus: 1 / cop,
96
        waste_heat_bus: (cop - 1) / cop,
97
    },
98
)
99
district_heating_system.add(heat_pump)
100
# %%[sec_4_end]
101
102
# %%[sec_5_start]
103
spec_inv_storage = 1060
104
var_cost_storage = 0.1
105
106
heat_storage = solph.components.GenericStorage(
107
    label="heat storage",
108
    nominal_capacity=solph.Investment(ep_costs=epc(spec_inv_storage)),
109
    inputs={heat_bus: solph.flows.Flow(variable_costs=var_cost_storage)},
110
    outputs={heat_bus: solph.flows.Flow(variable_costs=var_cost_storage)},
111
    invest_relation_input_capacity=1 / 24,
112
    invest_relation_output_capacity=1 / 24,
113
    balanced=True,
114
    loss_rate=0.001,
115
)
116
117
district_heating_system.add(heat_storage)
118
# %%[sec_5_end]
119
120
# solve model
121
model = solph.Model(district_heating_system)
122
model.solve(solver="cbc", solve_kwargs={"tee": True})
123
124
# results
125
results = solph.processing.results(model)
126
127
data_gas_bus = solph.views.node(results, "gas network")["sequences"]
128
data_heat_bus = solph.views.node(results, "heat network")["sequences"]
129
130
# %%[sec_6_start]
131
data_el_bus = solph.views.node(results, "electricity network")["sequences"]
132
data_caps = solph.views.node(results, "heat network")["scalars"]
133
134
cap_gas_boiler = data_caps[("gas boiler", "heat network"), "invest"]
135
cap_heat_pump = data_caps[("heat pump", "heat network"), "invest"]
136
cap_storage = solph.views.node(results, "heat storage")["scalars"][
137
    (("heat storage", "None"), "invest")
138
]
139
cap_storage_out = data_caps[("heat storage", "heat network"), "invest"]
140
141
print(f"capacity gas boiler: {cap_gas_boiler:.1f} MW")
142
print(f"capacity heat pump: {cap_heat_pump:.1f} MW")
143
print(f"capacity heat storage: {cap_storage:.1f} MWh")
144
print(f"capacity heat storage (out): {cap_storage_out:.1f} MW")
145
# %%[sec_6_end]
146
147
# %%[sec_7_start]
148
invest_cost = (
149
    spec_inv_gas_boiler * cap_gas_boiler
150
    + spec_inv_heat_pump * cap_heat_pump
151
    + spec_inv_storage * cap_storage
152
)
153
operation_cost = (
154
    var_cost_gas_boiler
155
    * data_heat_bus[(("gas boiler", "heat network"), "flow")].sum()
156
    + (
157
        data["gas price"]
158
        * data_gas_bus[(("gas network", "gas boiler"), "flow")]
159
    ).sum()
160
    + var_cost_heat_pump
161
    * data_heat_bus[(("heat pump", "heat network"), "flow")].sum()
162
    + (
163
        data["el_spot_price"]
164
        * data_el_bus[(("electricity network", "heat pump"), "flow")]
165
    ).sum()
166
    + var_cost_storage
167
    * data_heat_bus[(("heat storage", "heat network"), "flow")].sum()
168
    + var_cost_storage
169
    * data_heat_bus[(("heat network", "heat storage"), "flow")].sum()
170
)
171
heat_produced = data_heat_bus[(("heat network", "heat sink"), "flow")].sum()
172
173
lcoh = LCOH(invest_cost, operation_cost, heat_produced)
174
print(f"LCOH: {lcoh:.2f} €/MWh")
175
# %%[sec_7_end]
176
177
import matplotlib.pyplot as plt
178
179
# plt.style.use('dark_background')
180
181
# %%[sec_8_start]
182
unit_colors = {
183
    "gas boiler": "#EC6707",
184
    "heat pump": "#B54036",
185
    "heat storage (discharge)": "#BFBFBF",
186
    "heat storage (charge)": "#696969",
187
}
188
189
fig, ax = plt.subplots(figsize=[10, 6])
190
191
bottom = 0
192
for unit in ["heat pump", "gas boiler", "heat storage"]:
193
    unit_label = f"{unit} (discharge)" if "storage" in unit else unit
194
    ax.bar(
195
        data_heat_bus.index,
196
        data_heat_bus[((unit, "heat network"), "flow")],
197
        label=unit_label,
198
        color=unit_colors[unit_label],
199
        bottom=bottom,
200
    )
201
    bottom += data_heat_bus[((unit, "heat network"), "flow")]
202
203
unit_label = "heat storage (charge)"
204
ax.bar(
205
    data_heat_bus.index,
206
    -1 * data_heat_bus[(("heat network", "heat storage"), "flow")],
207
    label=unit_label,
208
    color=unit_colors[unit_label],
209
)
210
211
ax.legend(loc="upper center", ncol=2)
212
ax.grid(axis="y")
213
ax.set_ylabel("Hourly heat production in MWh")
214
215
# plt.tight_layout()
216
# plt.savefig('intro_tut_dhs_2_hourly_heat_production.svg')
217
218
219
fig, ax = plt.subplots(figsize=[10, 6])
220
221
data_heat_storage = solph.views.node(results, "heat storage")["sequences"]
222
223
ax.plot(
224
    data_heat_storage[(("heat storage", "None"), "storage_content")],
225
    color="#00395B",
226
)
227
228
ax.grid(axis="y")
229
ax.set_ylabel("Hourly heat storage content in MWh")
230
231
# plt.tight_layout()
232
# plt.savefig('intro_tut_dhs_2_hourly_storage_content.svg')
233
234
plt.show()
235
# %%[sec_8_end]
236