ConniKLu commited on
Commit
1bc3235
·
verified ·
1 Parent(s): fedcf94

Upload 3 files

Browse files
Files changed (2) hide show
  1. app.py +424 -347
  2. sourced.py +215 -205
app.py CHANGED
@@ -1,347 +1,424 @@
1
- # %%
2
- # -*- coding: utf-8 -*-
3
- """
4
- Spyder Editor
5
-
6
- This is a temporary script file.
7
- """
8
-
9
-
10
-
11
-
12
- from numpy import arange
13
- import xarray as xr
14
- import highspy
15
- from linopy import Model, EQUAL
16
- import pandas as pd
17
- import plotly.express as px
18
- import streamlit as st
19
- import sourced as src
20
- st.set_page_config(layout="wide")
21
- # you can create columns to better manage the flow of your page
22
- # this command makes 3 columns of equal width
23
- col1, col2, col3, col4 = st.columns(4)
24
- col1.header("Data Input")
25
- col4.header("Download Results")
26
-
27
- # Color dictionary for figures
28
- color_dict = {'Biomass': 'lightgreen',
29
- 'Lignite': 'brown',
30
- 'Fossil Gas': 'grey',
31
- 'Fossil Hard coal': 'darkgrey',
32
- 'Fossil Oil': 'maroon',
33
- 'RoR': 'aquamarine',
34
- 'Hydro Water Reservoir': 'azure',
35
- 'Nuclear': 'orange',
36
- 'PV': 'yellow',
37
- 'WindOff': 'darkblue',
38
- 'WindOn': 'green',
39
- 'H2': 'crimson',
40
- 'Pumped Hydro Storage': 'lightblue',
41
- 'Battery storages': 'red',
42
- 'Electrolyzer': 'olive'}
43
-
44
- # %%
45
- with col1:
46
- with open('Input_Jahr_2021.xlsx', 'rb') as f:
47
- st.download_button('Download Excel Template', f, file_name='Input_Jahr_2021.xlsx') # Defaults to 'application/octet-stream'
48
-
49
- #url_excel = r'Input_Jahr_2021.xlsx'
50
- url_excel = st.file_uploader(label = 'Excel Upload')
51
-
52
-
53
- if url_excel == None:
54
- url_excel = r'Input_Jahr_2021.xlsx'
55
- sets_dict, params_dict= src.load_data_from_excel(url_excel, load_from_pickle_flag = True)
56
- with col4:
57
- st.write('Running with standard data')
58
- else:
59
- sets_dict, params_dict= src.load_data_from_excel(url_excel, load_from_pickle_flag = False)
60
- with col4:
61
- st.write('Running with user data')
62
-
63
- # # %%
64
-
65
- def timstep_aggregate(time_steps_aggregate, xr ):
66
- return xr.rolling( t = time_steps_aggregate).mean().sel(t = t[0::time_steps_aggregate])
67
-
68
- #s_t_r_iRes = timstep_aggregate(6,s_t_r_iRes)
69
-
70
-
71
-
72
- # %%
73
- #sets_dict, params_dict= src.load_data_from_excel(url_excel,write_to_pickle_flag=True)
74
-
75
- # %%
76
-
77
-
78
-
79
- #sets_dict, params_dict= load_data_from_excel(url_excel, load_from_pickle_flag = False)
80
-
81
-
82
- dt = 6
83
- # Unpack sets_dict into the workspace
84
- t = sets_dict['t']
85
- i = sets_dict['i']
86
- iSto = sets_dict['iSto']
87
- iConv = sets_dict['iConv']
88
- iPtG = sets_dict['iPtG']
89
- iRes = sets_dict['iRes']
90
- iHyRes = sets_dict['iHyRes']
91
-
92
- # Unpack params_dict into the workspace
93
- l_co2 = params_dict['l_co2']
94
- p_co2 = params_dict['p_co2']
95
-
96
- eff_i = params_dict['eff_i']
97
- c_fuel_i = params_dict['c_fuel_i']
98
- c_other_i = params_dict['c_other_i']
99
- c_inv_i = params_dict['c_inv_i']
100
- co2_factor_i = params_dict['co2_factor_i']
101
- #c_var_i = params_dict['c_var_i']
102
- K_0_i = params_dict['K_0_i']
103
- e2p_iSto = params_dict['e2p_iSto']
104
- # Aggregate time series
105
- D_t = timstep_aggregate(dt,params_dict['D_t'])
106
- s_t_r_iRes = timstep_aggregate(dt,params_dict['s_t_r_iRes'])
107
- h_t = timstep_aggregate(dt,params_dict['h_t'])
108
- t = D_t.get_index('t')
109
- partial_year_factor = (8760/len(t))/dt
110
-
111
- # Sliders and input boxes for parameters
112
- with col2:
113
- # Slider for CO2 limit [mio. t]
114
- l_co2 = st.slider(value=int(params_dict['l_co2']), min_value=0, max_value=750, label="CO2 limit [mio. t]", step=50)
115
-
116
- # Slider for H2 price / usevalue [€/MWH_th]
117
- price_h2 = st.slider(value=100, min_value=0, max_value=300, label="Hydrogen price [€/MWh]", step=10)
118
-
119
- for i_idx in c_fuel_i.get_index('i'):
120
- if i_idx in ['Lignite']:
121
- c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + ' Price' , step=10)
122
-
123
- dt = st.number_input(label="Length of timesteps [int]", min_value=1, max_value=len(t), value=6, help="Enter only integers between 1 and 8760 (or 8784 for leap years).")
124
-
125
- with col3:
126
- # Slider for CO2 limit [mio. t]
127
- for i_idx in c_fuel_i.get_index('i'):
128
- if i_idx in ['Fossil Hard coal', 'Fossil Oil','Fossil Gas']:
129
- c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + ' Price' , step=10)
130
-
131
- technologies_invest = st.multiselect(label='Technologies for investment', options=i, default=['Lignite','Fossil Gas','Fossil Hard coal','Fossil Oil','PV','WindOff','WindOn','H2','Pumped Hydro Storage','Battery storages'])
132
- technologies_no_invest = [x for x in i if x not in technologies_invest]
133
-
134
- #time_steps_aggregate = 6
135
- #= xr_profiles.rolling( time_step = time_steps_aggregate).mean().sel(time_step = time[0::time_steps_aggregate])
136
- price_co2 = 0
137
-
138
- # Aggregate time series
139
- #D_t = timstep_aggregate(dt,params_dict['D_t'])
140
- #s_t_r_iRes = timstep_aggregate(dt,params_dict['s_t_r_iRes'])
141
- #h_t = timstep_aggregate(dt,params_dict['h_t'])
142
- #t = D_t.get_index('t')
143
- #partial_year_factor = (8760/len(t))/dt
144
-
145
- #technologies_no_invest = st.multiselect(label='Technolgy invest', options=i)
146
- #technologies_no_invest = ['Electrolyzer','Biomass','RoR','Hydro Water Reservoir','Nuclear']
147
- # %%
148
- ### Variables
149
- m = Model()
150
-
151
- C_tot = m.add_variables(name = 'C_tot') # Total costs
152
- C_op = m.add_variables(name = 'C_op', lower = 0) # Operational costs
153
- C_inv = m.add_variables(name = 'C_inv', lower = 0) # Investment costs
154
-
155
- K = m.add_variables(coords = [i], name = 'K', lower = 0) # Endogenous capacity
156
- y = m.add_variables(coords = [t,i], name = 'y', lower = 0) # Electricity production --> für Elektrolyseure ausschließen
157
- y_ch = m.add_variables(coords = [t,i], name = 'y_ch', lower = 0) # Electricity consumption --> für alles außer Elektrolyseure und Speicher ausschließen
158
- l = m.add_variables(coords = [t,i], name = 'l', lower = 0) # Storage filling level
159
- w = m.add_variables(coords = [t], name = 'w', lower = 0) # RES curtailment
160
- y_curt = m.add_variables(coords = [t,i], name = 'y_curt', lower = 0)
161
- y_h2 = m.add_variables(coords = [t,i], name = 'y_h2', lower = 0)
162
-
163
- ## Objective function
164
- C_tot = C_op + C_inv
165
- m.add_objective(C_tot)
166
-
167
- ## Costs terms for objective function
168
- # Operational costs minus revenue for produced hydrogen
169
- C_op_sum = m.add_constraints((y * c_fuel_i/eff_i).sum() * dt - (y_h2.sel(i = iPtG) * price_h2).sum() * dt == C_op, name = 'C_op_sum')
170
-
171
- # Investment costs
172
- C_inv_sum = m.add_constraints((K * c_inv_i).sum() == C_inv, name = 'C_inv_sum')
173
-
174
- ## Load serving
175
- loadserve_t = m.add_constraints((((y ).sum(dims = 'i') - y_ch.sum(dims = 'i')) * dt == D_t.sel(t = t) * dt), name = 'load')
176
-
177
- ## Maximum capacity limit
178
- maxcap_i_t = m.add_constraints((y - K <= K_0_i), name = 'max_cap')
179
-
180
- ## Maximum capacity limit
181
- maxcap_invest_i = m.add_constraints((K.sel(i = technologies_no_invest) <= 0), name = 'max_cap_invest')
182
-
183
- ## Prevent power production by PtG
184
- no_power_prod_iPtG_t = m.add_constraints((y.sel(i = iPtG) <= 0), name = 'prevent_ptg_prod')
185
-
186
- ## Maximum storage charging and discharging
187
- maxcha_iSto_t = m.add_constraints((y.sel(i = iSto) + y_ch.sel(i = iSto) - K.sel(i = iSto) <= K_0_i.sel(i = iSto)), name = 'max_cha')
188
-
189
- ## Maximum electrolyzer capacity
190
- ptg_prod_iPtG_t = m.add_constraints((y_ch.sel(i = iPtG) - K.sel(i = iPtG) <= K_0_i.sel(i = iPtG)), name = 'max_cha_ptg')
191
-
192
- ## PtG H2 production
193
- h2_prod_iPtG_t = m.add_constraints(y_ch.sel(i = iPtG) * eff_i.sel(i = iPtG) == y_h2.sel(i = iPtG), name = 'ptg_h2_prod')
194
-
195
- ## Infeed of renewables
196
- infeed_iRes_t = m.add_constraints((y.sel(i = iRes) - s_t_r_iRes.sel(i = iRes).sel(t = t) * K.sel(i = iRes) + y_curt.sel(i = iRes) == s_t_r_iRes.sel(i = iRes).sel(t = t) * K_0_i.sel(i = iRes)), name = 'infeed')
197
-
198
- ## Maximum filling level restriction storage power plant
199
- maxcapsto_iSto_t = m.add_constraints((l.sel(i = iSto) - K.sel(i = iSto) * e2p_iSto.sel(i = iSto) <= K_0_i.sel(i = iSto) * e2p_iSto.sel(i = iSto)), name = 'max_sto_filling')
200
-
201
- ## Filling level restriction hydro reservoir
202
- filling_iHydro_t = m.add_constraints(l.sel(i = iHyRes) - l.sel(i = iHyRes).roll(t = -1) + y.sel(i = iHyRes) * dt == h_t.sel(t = t) * dt, name = 'filling_level_hydro')
203
-
204
- ## Filling level restriction other storages
205
- filling_iSto_t = m.add_constraints(l.sel(i = iSto) - (l.sel(i = iSto).roll(t = -1) + (y.sel(i = iSto) / eff_i.sel(i = iSto)) * dt - y_ch.sel(i = iSto) * eff_i.sel(i = iSto) * dt) == 0, name = 'filling_level')
206
-
207
- ## CO2 limit
208
- CO2_limit = m.add_constraints(((y / eff_i) * co2_factor_i * dt).sum() <= l_co2 * 1_000_000 , name = 'CO2_limit')
209
-
210
-
211
- # %%
212
- m.solve(solver_name = 'highs')
213
-
214
- st.markdown("---")
215
-
216
- colb1, colb2 = st.columns(2)
217
-
218
- # %%
219
- #c_var_i.to_dataframe(name='VarCosts')
220
- # %%
221
- # Installed Cap
222
- # Assuming df_excel has columns 'All' and 'Capacities'
223
-
224
- fig = px.bar((m.solution['K']+K_0_i).to_dataframe(name='K').reset_index(), \
225
- y='i', x='K', orientation='h', title='Total Installed Capacities [MW]', color='i')
226
-
227
- #fig
228
-
229
- # %%
230
- total_costs = float(m.solution['C_inv'].values) + float(m.solution['C_op'].values)
231
- total_costs_rounded = round(total_costs/1e9, 2)
232
- df_total_costs = pd.DataFrame({'Total costs':[total_costs]})
233
-
234
- with colb1:
235
- st.write('Total costs: ' + str(total_costs_rounded) + ' bn. €')
236
-
237
- # %%
238
- #df_Co2_price = pd.DataFrame({'CO2_Price: ':[float(m.constraints['CO2_limit'].dual.values) * (-1)]})
239
- CO2_price = float(m.constraints['CO2_limit'].dual.values) * (-1)
240
- CO2_price_rounded = round(CO2_price, 2)
241
- df_CO2_price = pd.DataFrame({'CO2 price':[CO2_price]})
242
-
243
- with colb2:
244
- #st.write(str(df_Co2_price))
245
- st.write('CO2 price: ' + str(CO2_price_rounded) + ' €/t')
246
-
247
- # %%
248
- df_new_capacities = m.solution['K'].to_dataframe().reset_index()
249
- fig = px.bar(m.solution['K'].to_dataframe().reset_index(), y='i', x='K', orientation='h', title='New Capacities [MW]', color='i', color_discrete_map=color_dict)
250
-
251
- with colb1:
252
- fig
253
-
254
- # %%
255
- i_with_capacity = m.solution['K'].where( m.solution['K'] > 0).dropna(dim = 'i').get_index('i')
256
- df_production = m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index()
257
- fig = px.area(m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index(), y='y', x='t', title='Production [MWh]', color='i', color_discrete_map=color_dict)
258
- fig.update_traces(line=dict(width=0))
259
- fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
260
-
261
- with colb2:
262
- fig
263
-
264
- # %%
265
-
266
- df_price = m.constraints['load'].dual.to_dataframe().reset_index()
267
- #df_price['dual'] = df_price['dual']
268
-
269
- # %%
270
- fig = px.line(df_price, y='dual', x='t', title='Electricity prices [€/MWh]', range_y=[0,250])
271
- with colb1:
272
- fig
273
-
274
- # %%
275
-
276
- df_contr_marg = m.constraints['max_cap'].dual.to_dataframe().reset_index()
277
- df_contr_marg['dual'] = df_contr_marg['dual'] / dt * (-1)
278
-
279
- # %%
280
-
281
- fig = px.line(df_contr_marg, y='dual', x='t',title='Contribution margin [€]', color='i', range_y=[0,250], color_discrete_map=color_dict)
282
- with colb2:
283
- fig
284
-
285
- # %%
286
-
287
- # curtailment
288
- df_curtailment = m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index()
289
- fig = px.area(m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index(), y='y_curt', x='t', title='Curtailment [MWh]', color='i', color_discrete_map=color_dict)
290
- fig.update_traces(line=dict(width=0))
291
- fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
292
-
293
- with colb1:
294
- fig
295
-
296
- # %%
297
- df_charging = m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index()
298
- fig = px.area(m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index(), y='y_ch', x='t', title='Storage charging [MWh]', color='i', color_discrete_map=color_dict)
299
- fig.update_traces(line=dict(width=0))
300
- fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
301
-
302
- with colb2:
303
- fig
304
-
305
- # %%
306
- df_h2_prod = m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index()
307
- fig = px.area(m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index(), y='y_h2', x='t', title='Hydrogen production [MWh_th]', color='i', color_discrete_map=color_dict)
308
- fig.update_traces(line=dict(width=0))
309
- fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
310
-
311
- with colb2:
312
- fig
313
-
314
- # %%
315
- ((m.solution['y'] / eff_i) * co2_factor_i * dt).sum()
316
- # %%
317
-
318
- import pandas as pd
319
- from io import BytesIO
320
- #from pyxlsb import open_workbook as open_xlsb
321
- import streamlit as st
322
- import xlsxwriter
323
- # %%
324
- output = BytesIO()
325
-
326
-
327
- # Create a Pandas Excel writer using XlsxWriter as the engine
328
- with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
329
- # Write each DataFrame to a different sheet
330
- df_total_costs.to_excel(writer, sheet_name='Total costs', index=False)
331
- df_CO2_price.to_excel(writer, sheet_name='CO2 price', index=False)
332
- df_price.to_excel(writer, sheet_name='Prices', index=False)
333
- df_contr_marg.to_excel(writer, sheet_name='Contribution Margin', index=False)
334
- df_new_capacities.to_excel(writer, sheet_name='Capacities', index=False)
335
- df_production.to_excel(writer, sheet_name='Production', index=False)
336
- df_charging.to_excel(writer, sheet_name='Charging', index=False)
337
- D_t.to_dataframe().reset_index().to_excel(writer, sheet_name='Demand', index=False)
338
- df_curtailment.to_excel(writer, sheet_name='Curtailment', index=False)
339
- df_h2_prod.to_excel(writer, sheet_name='H2 production', index=False)
340
-
341
- with col4:
342
- st.download_button(
343
- label="Download Excel workbook Results",
344
- data=output.getvalue(),
345
- file_name="workbook.xlsx",
346
- mime="application/vnd.ms-excel"
347
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # %%
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Spyder Editor
5
+
6
+ This is a temporary script file.
7
+ """
8
+
9
+
10
+
11
+ from numpy import arange
12
+ import xarray as xr
13
+ import highspy
14
+ from linopy import Model, EQUAL
15
+ import pandas as pd
16
+ import plotly.express as px
17
+ import streamlit as st
18
+ import sourced as src
19
+ import numpy as np
20
+
21
+ ## Setting
22
+ write_pickle_from_standard_excel = True
23
+
24
+
25
+ st.set_page_config(layout="wide")
26
+ # you can create columns to better manage the flow of your page
27
+ # this command makes 3 columns of equal width
28
+ col1, col2, col3, col4 = st.columns(4)
29
+ col1.header("Data Input")
30
+ col4.header("Download Results")
31
+
32
+ # Color dictionary for figures
33
+ color_dict = {'Biomass': 'lightgreen',
34
+ 'Lignite': 'brown',
35
+ 'Fossil Gas': 'grey',
36
+ 'Fossil Hard coal': 'darkgrey',
37
+ 'Fossil Oil': 'maroon',
38
+ 'RoR': 'aquamarine',
39
+ 'Hydro Water Reservoir': 'azure',
40
+ 'Nuclear': 'orange',
41
+ 'PV': 'yellow',
42
+ 'WindOff': 'darkblue',
43
+ 'WindOn': 'green',
44
+ 'H2': 'crimson',
45
+ 'Pumped Hydro Storage': 'lightblue',
46
+ 'Battery storages': 'red',
47
+ 'Electrolyzer': 'olive'}
48
+
49
+ # %%
50
+ with col1:
51
+ with open('Input_Jahr_2021.xlsx', 'rb') as f:
52
+ st.download_button('Download Excel Template', f, file_name='Input_Jahr_2021.xlsx') # Defaults to 'application/octet-stream'
53
+
54
+ #url_excel = r'Input_Jahr_2021.xlsx'
55
+ url_excel = st.file_uploader(label = 'Excel Upload')
56
+
57
+
58
+ if url_excel == None:
59
+ if write_pickle_from_standard_excel:
60
+ url_excel = r'Input_Jahr_2021.xlsx'
61
+ sets_dict, params_dict= src.load_data_from_excel(url_excel, write_to_pickle_flag= True)
62
+ sets_dict, params_dict = src.load_from_pickle()
63
+ with col4:
64
+ st.write('Running with standard data')
65
+ else:
66
+ sets_dict, params_dict= src.load_data_from_excel(url_excel, load_from_pickle_flag = False)
67
+
68
+ with col4:
69
+ st.write('Running with user data')
70
+
71
+ # # %%
72
+
73
+ def timstep_aggregate(time_steps_aggregate, xr ):
74
+ return xr.rolling( t = time_steps_aggregate).mean().sel(t = t[0::time_steps_aggregate])
75
+
76
+ #s_t_r_iRes = timstep_aggregate(6,s_t_r_iRes)
77
+
78
+
79
+
80
+ # %%
81
+ #sets_dict, params_dict= src.load_data_from_excel(url_excel,write_to_pickle_flag=True)
82
+
83
+ # %%
84
+
85
+
86
+
87
+ #sets_dict, params_dict= load_data_from_excel(url_excel, load_from_pickle_flag = False)
88
+
89
+
90
+ # Unpack sets_dict into the workspace
91
+ t = sets_dict['t']
92
+ t_original = sets_dict['t']
93
+ i = sets_dict['i']
94
+ iSto = sets_dict['iSto']
95
+ iConv = sets_dict['iConv']
96
+ iPtG = sets_dict['iPtG']
97
+ iRes = sets_dict['iRes']
98
+ iHyRes = sets_dict['iHyRes']
99
+
100
+ # Unpack params_dict into the workspace
101
+ l_co2 = params_dict['l_co2']
102
+ p_co2 = params_dict['p_co2']
103
+
104
+ eff_i = params_dict['eff_i']
105
+ life_i = params_dict['life_i']
106
+ c_fuel_i = params_dict['c_fuel_i']
107
+ c_other_i = params_dict['c_other_i']
108
+ c_inv_i = params_dict['c_inv_i']
109
+ co2_factor_i = params_dict['co2_factor_i']
110
+ #c_var_i = params_dict['c_var_i']
111
+ K_0_i = params_dict['K_0_i']
112
+ e2p_iSto = params_dict['e2p_iSto']
113
+
114
+ # Sliders and input boxes for parameters
115
+ with col2:
116
+ # Slider for CO2 limit [mio. t]
117
+ l_co2 = st.slider(value=int(params_dict['l_co2']), min_value=0, max_value=750, label="CO2 limit [mio. t]", step=50)
118
+
119
+ # Slider for H2 price / usevalue [€/MWH_th]
120
+ price_h2 = st.slider(value=100, min_value=0, max_value=300, label="Hydrogen price [€/MWh]", step=10)
121
+
122
+ for i_idx in c_fuel_i.get_index('i'):
123
+ if i_idx in ['Lignite']:
124
+ c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + ' Price' , step=10)
125
+
126
+ dt = st.number_input(label="Length of timesteps [int]", min_value=1, max_value=len(t), value=6, help="Enter only integers between 1 and 8760 (or 8784 for leap years).")
127
+
128
+ with col3:
129
+ # Slider for CO2 limit [mio. t]
130
+ for i_idx in c_fuel_i.get_index('i'):
131
+ if i_idx in ['Fossil Hard coal', 'Fossil Oil','Fossil Gas']:
132
+ c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + ' Price' , step=10)
133
+
134
+ technologies_invest = st.multiselect(label='Technologies for investment', options=i, default=['Lignite','Fossil Gas','Fossil Hard coal','Fossil Oil','PV','WindOff','WindOn','H2','Pumped Hydro Storage','Battery storages'])
135
+ technologies_no_invest = [x for x in i if x not in technologies_invest]
136
+
137
+ # Aggregate time series
138
+ D_t = timstep_aggregate(dt,params_dict['D_t'])
139
+ s_t_r_iRes = timstep_aggregate(dt,params_dict['s_t_r_iRes'])
140
+ h_t = timstep_aggregate(dt,params_dict['h_t'])
141
+ t = D_t.get_index('t')
142
+ partial_year_factor = (8760/len(t))/dt
143
+
144
+
145
+
146
+ #time_steps_aggregate = 6
147
+ #= xr_profiles.rolling( time_step = time_steps_aggregate).mean().sel(time_step = time[0::time_steps_aggregate])
148
+ price_co2 = 0
149
+
150
+ # Aggregate time series
151
+ #D_t = timstep_aggregate(dt,params_dict['D_t'])
152
+ #s_t_r_iRes = timstep_aggregate(dt,params_dict['s_t_r_iRes'])
153
+ #h_t = timstep_aggregate(dt,params_dict['h_t'])
154
+ #t = D_t.get_index('t')
155
+ #partial_year_factor = (8760/len(t))/dt
156
+
157
+ #technologies_no_invest = st.multiselect(label='Technology invest', options=i)
158
+ #technologies_no_invest = ['Electrolyzer','Biomass','RoR','Hydro Water Reservoir','Nuclear']
159
+ # %%
160
+ ### Variables
161
+ m = Model()
162
+
163
+ C_tot = m.add_variables(name = 'C_tot') # Total costs
164
+ C_op = m.add_variables(name = 'C_op', lower = 0) # Operational costs
165
+ C_inv = m.add_variables(name = 'C_inv', lower = 0) # Investment costs
166
+
167
+ K = m.add_variables(coords = [i], name = 'K', lower = 0) # Endogenous capacity
168
+ y = m.add_variables(coords = [t,i], name = 'y', lower = 0) # Electricity production --> für Elektrolyseure ausschließen
169
+ y_ch = m.add_variables(coords = [t,i], name = 'y_ch', lower = 0) # Electricity consumption --> für alles außer Elektrolyseure und Speicher ausschließen
170
+ l = m.add_variables(coords = [t,i], name = 'l', lower = 0) # Storage filling level
171
+ w = m.add_variables(coords = [t], name = 'w', lower = 0) # RES curtailment
172
+ y_curt = m.add_variables(coords = [t,i], name = 'y_curt', lower = 0)
173
+ y_h2 = m.add_variables(coords = [t,i], name = 'y_h2', lower = 0)
174
+
175
+ ## Objective function
176
+ C_tot = C_op + C_inv
177
+ m.add_objective(C_tot)
178
+
179
+ ## Costs terms for objective function
180
+ # Operational costs minus revenue for produced hydrogen
181
+ C_op_sum = m.add_constraints((y * c_fuel_i/eff_i).sum() * dt - (y_h2.sel(i = iPtG) * price_h2).sum() * dt == C_op, name = 'C_op_sum')
182
+
183
+ # Investment costs
184
+ C_inv_sum = m.add_constraints((K * c_inv_i).sum() == C_inv, name = 'C_inv_sum')
185
+
186
+ ## Load serving
187
+ loadserve_t = m.add_constraints((((y ).sum(dims = 'i') - y_ch.sum(dims = 'i')) * dt == D_t.sel(t = t) * dt), name = 'load')
188
+
189
+ ## Maximum capacity limit
190
+ maxcap_i_t = m.add_constraints((y - K <= K_0_i), name = 'max_cap')
191
+
192
+ ## Maximum capacity limit
193
+ maxcap_invest_i = m.add_constraints((K.sel(i = technologies_no_invest) <= 0), name = 'max_cap_invest')
194
+
195
+ ## Prevent power production by PtG
196
+ no_power_prod_iPtG_t = m.add_constraints((y.sel(i = iPtG) <= 0), name = 'prevent_ptg_prod')
197
+
198
+ ## Maximum storage charging and discharging
199
+ maxcha_iSto_t = m.add_constraints((y.sel(i = iSto) + y_ch.sel(i = iSto) - K.sel(i = iSto) <= K_0_i.sel(i = iSto)), name = 'max_cha')
200
+
201
+ ## Maximum electrolyzer capacity
202
+ ptg_prod_iPtG_t = m.add_constraints((y_ch.sel(i = iPtG) - K.sel(i = iPtG) <= K_0_i.sel(i = iPtG)), name = 'max_cha_ptg')
203
+
204
+ ## PtG H2 production
205
+ h2_prod_iPtG_t = m.add_constraints(y_ch.sel(i = iPtG) * eff_i.sel(i = iPtG) == y_h2.sel(i = iPtG), name = 'ptg_h2_prod')
206
+
207
+ ## Infeed of renewables
208
+ infeed_iRes_t = m.add_constraints((y.sel(i = iRes) - s_t_r_iRes.sel(i = iRes).sel(t = t) * K.sel(i = iRes) + y_curt.sel(i = iRes) == s_t_r_iRes.sel(i = iRes).sel(t = t) * K_0_i.sel(i = iRes)), name = 'infeed')
209
+
210
+ ## Maximum filling level restriction storage power plant
211
+ maxcapsto_iSto_t = m.add_constraints((l.sel(i = iSto) - K.sel(i = iSto) * e2p_iSto.sel(i = iSto) <= K_0_i.sel(i = iSto) * e2p_iSto.sel(i = iSto)), name = 'max_sto_filling')
212
+
213
+ ## Filling level restriction hydro reservoir
214
+ filling_iHydro_t = m.add_constraints(l.sel(i = iHyRes) - l.sel(i = iHyRes).roll(t = -1) + y.sel(i = iHyRes) * dt == h_t.sel(t = t) * dt, name = 'filling_level_hydro')
215
+
216
+ ## Filling level restriction other storages
217
+ filling_iSto_t = m.add_constraints(l.sel(i = iSto) - (l.sel(i = iSto).roll(t = -1) + (y.sel(i = iSto) / eff_i.sel(i = iSto)) * dt - y_ch.sel(i = iSto) * eff_i.sel(i = iSto) * dt) == 0, name = 'filling_level')
218
+
219
+ ## CO2 limit
220
+ CO2_limit = m.add_constraints(((y / eff_i) * co2_factor_i * dt).sum() <= l_co2 * 1_000_000 , name = 'CO2_limit')
221
+
222
+
223
+ # %%
224
+ m.solve(solver_name = 'highs')
225
+
226
+ st.markdown("---")
227
+
228
+ colb1, colb2 = st.columns(2)
229
+
230
+ # %%
231
+ #c_var_i.to_dataframe(name='VarCosts')
232
+ # %%
233
+ # Installed Cap
234
+ # Assuming df_excel has columns 'All' and 'Capacities'
235
+
236
+ fig = px.bar((m.solution['K']+K_0_i).to_dataframe(name='K').reset_index(), \
237
+ y='i', x='K', orientation='h', title='Total Installed Capacities [MW]', color='i')
238
+
239
+ #fig
240
+
241
+ # %%
242
+ total_costs = float(m.solution['C_inv'].values) + float(m.solution['C_op'].values)
243
+ total_costs_rounded = round(total_costs/1e9, 2)
244
+ df_total_costs = pd.DataFrame({'Total costs':[total_costs]})
245
+
246
+ with colb1:
247
+ st.write('Total costs: ' + str(total_costs_rounded) + ' bn. €')
248
+
249
+ # %%
250
+ #df_Co2_price = pd.DataFrame({'CO2_Price: ':[float(m.constraints['CO2_limit'].dual.values) * (-1)]})
251
+ CO2_price = float(m.constraints['CO2_limit'].dual.values) * (-1)
252
+ CO2_price_rounded = round(CO2_price, 2)
253
+ df_CO2_price = pd.DataFrame({'CO2 price':[CO2_price]})
254
+
255
+ with colb2:
256
+ #st.write(str(df_Co2_price))
257
+ st.write('CO2 price: ' + str(CO2_price_rounded) + ' €/t')
258
+
259
+ # %%
260
+ df_new_capacities = m.solution['K'].to_dataframe().reset_index()
261
+ fig = px.bar(m.solution['K'].to_dataframe().reset_index(), y='i', x='K', orientation='h', title='New Capacities [MW]', color='i', color_discrete_map=color_dict)
262
+
263
+ with colb1:
264
+ fig
265
+
266
+ # %%
267
+ #add pie chart which shows new capacities
268
+ #round number of new capacities
269
+ df_new_capacities_rounded = m.solution['K'].round(0).to_dataframe()
270
+ #drop all technologies with K<= 0
271
+ df_new_capacities_rounded = df_new_capacities_rounded[df_new_capacities_rounded["K"] > 0].reset_index()
272
+
273
+ total_k_sum = df_new_capacities_rounded["K"].sum()
274
+
275
+ #df_new_capacities_rounded["percentage"] = df_new_capacities_rounded["K"].apply(lambda x: (x/total_k_sum)*100).abs().round(2)
276
+
277
+ fig = px.pie(df_new_capacities_rounded, names='i', values='K', title='New Capacities [MW] as pie chart',
278
+ color='i', color_discrete_map=color_dict)
279
+
280
+ with colb1:
281
+ fig
282
+
283
+
284
+
285
+
286
+ # %%
287
+ i_with_capacity = m.solution['K'].where( m.solution['K'] > 0).dropna(dim = 'i').get_index('i')
288
+ df_production = m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index()
289
+ fig = px.area(m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index(), y='y', x='t', title='Production [MW]', color='i', color_discrete_map=color_dict)
290
+ fig.update_traces(line=dict(width=0))
291
+ fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
292
+
293
+ with colb2:
294
+ fig
295
+ # %%
296
+ #Add pie chart of total production per technology type in GWh(divide by 1000)
297
+ df_production_sum = (df_production.groupby('i')['y'].sum() * dt / 1000 ).round(0).sort_values(ascending=False).reset_index()
298
+
299
+ fig = px.pie(df_production_sum, names="i", values='y', title='Total Production [GWh] as pie chart',
300
+ color='i', color_discrete_map=color_dict)
301
+
302
+ with colb2:
303
+ fig
304
+
305
+ # %%
306
+
307
+ df_price = m.constraints['load'].dual.to_dataframe().reset_index()
308
+ #df_price['dual'] = df_price['dual']
309
+
310
+ # %%
311
+ fig = px.line(df_price, y='dual', x='t', title='Electricity prices [€/MWh]', range_y=[0,250])
312
+ with colb1:
313
+ fig
314
+
315
+
316
+ # %%
317
+ df_sorted_price = df_price["dual"].repeat(dt).sort_values(ascending=False).reset_index(drop=True)/int(dt)
318
+
319
+ fig = px.line(y=df_sorted_price, x=df_sorted_price.index, title='Price duration curve [€/MWh]', labels={"x": "Hours of the year"},range_y=[0,250])
320
+ with colb1:
321
+ fig
322
+
323
+ # %%
324
+
325
+ df_contr_marg = m.constraints['max_cap'].dual.to_dataframe().reset_index()
326
+ df_contr_marg['dual'] = df_contr_marg['dual'] / dt * (-1)
327
+
328
+
329
+ # %%
330
+
331
+ fig = px.line(df_contr_marg, y='dual', x='t',title='Contribution margin [€]', color='i', range_y=[0,250], color_discrete_map=color_dict)
332
+ with colb2:
333
+ fig
334
+
335
+ # %%
336
+
337
+ # curtailment
338
+ df_curtailment = m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index()
339
+ fig = px.area(m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index(), y='y_curt', x='t', title='Curtailment [MWh]', color='i', color_discrete_map=color_dict)
340
+ fig.update_traces(line=dict(width=0))
341
+ fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
342
+
343
+ with colb1:
344
+ fig
345
+
346
+ # %%
347
+ df_charging = m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index()
348
+ fig = px.area(m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index(), y='y_ch', x='t', title='Storage charging [MWh]', color='i', color_discrete_map=color_dict)
349
+ fig.update_traces(line=dict(width=0))
350
+ fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
351
+
352
+ with colb2:
353
+ fig
354
+
355
+ # %%
356
+ df_h2_prod = m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index()
357
+ fig = px.area(m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index(), y='y_h2', x='t', title='Hydrogen production [MWh_th]', color='i', color_discrete_map=color_dict)
358
+ fig.update_traces(line=dict(width=0))
359
+ fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
360
+
361
+ with colb2:
362
+ fig
363
+
364
+ # %%
365
+ ((m.solution['y'] / eff_i) * co2_factor_i * dt).sum()
366
+ # %%
367
+
368
+ import pandas as pd
369
+ from io import BytesIO
370
+ #from pyxlsb import open_workbook as open_xlsb
371
+ import streamlit as st
372
+ import xlsxwriter
373
+ # %%
374
+ output = BytesIO()
375
+
376
+
377
+ # ##
378
+
379
+
380
+ def disaggregate_df(df):
381
+
382
+
383
+ if not "t" in list(df.columns):
384
+ return df
385
+
386
+ #df_repeated = df.iloc[idx_repeat,:].reset_index(drop = True).drop('t', axis = 1)
387
+ df_t_all = pd.DataFrame({"t_all": t_original.to_series(), 't': t.repeat(dt)}).reset_index(drop=True)
388
+
389
+ # %%
390
+ df_output = df.merge(df_t_all,on = 't').drop('t',axis = 1).rename({'t_all':'t'}, axis = 1)
391
+ # last column to first column
392
+ cols = list(df_output.columns)
393
+ cols = [cols[-1]] + cols[:-1]
394
+ df_output = df_output[cols]
395
+ return df_output.sort_values('t')
396
+
397
+
398
+
399
+
400
+ # Create a Pandas Excel writer using XlsxWriter as the engine
401
+ with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
402
+ # Write each DataFrame to a different sheet
403
+ disaggregate_df(df_total_costs).to_excel(writer, sheet_name='Total costs', index=False)
404
+ disaggregate_df(df_CO2_price).to_excel(writer, sheet_name='CO2 price', index=False)
405
+ disaggregate_df(df_price).to_excel(writer, sheet_name='Prices', index=False)
406
+ disaggregate_df(df_contr_marg).to_excel(writer, sheet_name='Contribution Margin', index=False)
407
+ disaggregate_df(df_new_capacities).to_excel(writer, sheet_name='Capacities', index=False)
408
+ disaggregate_df(df_production).to_excel(writer, sheet_name='Production', index=False)
409
+ disaggregate_df(df_charging).to_excel(writer, sheet_name='Charging', index=False)
410
+ disaggregate_df(D_t.to_dataframe().reset_index()).to_excel(writer, sheet_name='Demand', index=False)
411
+ disaggregate_df(df_curtailment).to_excel(writer, sheet_name='Curtailment', index=False)
412
+ disaggregate_df(df_h2_prod).to_excel(writer, sheet_name='H2 production', index=False)
413
+
414
+ with col4:
415
+ st.download_button(
416
+ label="Download Excel workbook Results",
417
+ data=output.getvalue(),
418
+ file_name="workbook.xlsx",
419
+ mime="application/vnd.ms-excel"
420
+ )
421
+
422
+ # %%
423
+
424
+
sourced.py CHANGED
@@ -1,205 +1,215 @@
1
- # %%
2
- import pandas as pd
3
-
4
- import pickle
5
-
6
- # Define the file path for the pickle file
7
- pickle_file_path = 'model_data.pkl'
8
-
9
- # Function to save dictionaries to a pickle file
10
- def save_to_pickle(sets_dict, params_dict):
11
- with open(pickle_file_path, 'wb') as file:
12
- pickle.dump({'sets': sets_dict, 'params': params_dict}, file)
13
-
14
- # Function to load dictionaries from a pickle file
15
- def load_from_pickle():
16
- with open(pickle_file_path, 'rb') as file:
17
- data = pickle.load(file)
18
- return data['sets'], data['params']
19
-
20
-
21
-
22
- def load_data_from_excel(url_excel,load_from_pickle_flag = False, write_to_pickle_flag = True):
23
-
24
-
25
- if load_from_pickle_flag:
26
- # Load dictionaries from the pickle file
27
- loaded_sets_dict, loaded_params_dict = load_from_pickle()
28
- return loaded_sets_dict, loaded_params_dict
29
-
30
- # Timesteps
31
- df_excel = pd.read_excel(url_excel, sheet_name='Timesteps_All', header=None)
32
- t = pd.Index(df_excel.iloc[:, 0], name='t')
33
-
34
- # Technologies
35
- df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
36
- i = pd.Index(df_excel.iloc[:, 0], name='i')
37
-
38
-
39
-
40
-
41
- df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
42
- iConv = pd.Index(df_excel.iloc[0:7, 2], name='iConv')
43
-
44
- df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
45
- iRes = pd.Index(df_excel.iloc[0:4, 4], name='iRes')
46
-
47
- df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
48
- iSto = pd.Index(df_excel.iloc[0:2, 6], name='iSto')
49
-
50
- df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
51
- iPtG = pd.Index(df_excel.iloc[0:1, 8], name='iPtG')
52
-
53
-
54
- df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
55
- iHyRes = pd.Index(df_excel.iloc[0:1, 10], name='iHyRes')
56
-
57
- # Parameters
58
- l_co2 = pd.read_excel(url_excel, sheet_name='CO2_Cap').iloc[0,0]
59
- p_co2 = 0
60
- dt = 1
61
-
62
-
63
- # Demand
64
- df_excel= pd.read_excel(url_excel, sheet_name = 'Demand')
65
- #df_melt = pd.melt(df_excel, id_vars='Zeit')
66
- df_excel = df_excel.rename(columns = {'Timesteps':'t', 'Unnamed: 1':'Demand'})
67
- #df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
68
- df_excel = df_excel.fillna(0)
69
- df_excel = df_excel.set_index('t')
70
- D_t = df_excel.iloc[:,0].to_xarray()
71
- ## Efficiencies
72
- df_excel = pd.read_excel(url_excel, sheet_name = 'Efficiency')
73
- df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'Efficiency'})
74
- df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
75
- df_excel = df_excel.fillna(0)
76
- df_excel = df_excel.set_index('i')
77
- eff_i = df_excel.iloc[:,0].to_xarray()
78
-
79
- ## Variable costs
80
- # Fuel costs
81
- df_excel = pd.read_excel(url_excel, sheet_name = 'FuelCosts')
82
- df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'FuelCosts'})
83
- df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
84
- df_excel = df_excel.fillna(0)
85
- df_excel = df_excel.set_index('i')
86
- c_fuel_i = df_excel.iloc[:,0].to_xarray()
87
- # Apply slider value
88
- #c_fuel_i.loc[dict(i = 'Fossil Gas')] = price_gas
89
- #c_fuel_i.loc[dict(i = 'H2')] = price_h2
90
-
91
- # Other var. costs
92
- df_excel = pd.read_excel(url_excel, sheet_name = 'OtherVarCosts')
93
- df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'OtherVarCosts'})
94
- df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
95
- df_excel = df_excel.fillna(0)
96
- df_excel = df_excel.set_index('i')
97
- c_other_i = df_excel.iloc[:,0].to_xarray()
98
-
99
- # Investment costs
100
- df_excel = pd.read_excel(url_excel, sheet_name = 'InvCosts')
101
- df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'InvCosts'})
102
- df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
103
- df_excel = df_excel.fillna(0)
104
- df_excel = df_excel.set_index('i')
105
- c_inv_i = df_excel.iloc[:,0].to_xarray()*1000*0.1 # kw to MW and annuity factor
106
-
107
- # Emission factor
108
- df_excel = pd.read_excel(url_excel, sheet_name = 'EmFactor')
109
- df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'EmFactor'})
110
- df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
111
- df_excel = df_excel.fillna(0)
112
- df_excel = df_excel.set_index('i')
113
- co2_factor_i = df_excel.iloc[:,0].to_xarray()
114
-
115
- ## Calculation of variable costs
116
- c_var_i = (c_fuel_i.sel(i = iConv) + p_co2 * co2_factor_i.sel(i = iConv)) / eff_i.sel(i = iConv) + c_other_i.sel(i = iConv)
117
-
118
- # RES capacity factors
119
- #df_excel = pd.read_excel(url_excel, sheet_name = 'RES',header=[0,1])
120
- #df_excel = pd.read_excel(url_excel, sheet_name = 'RES', index_col=['Timesteps'], columns=['PV', 'WindOn', 'WindOff', 'RoR'])
121
- df_excel = pd.read_excel(url_excel, sheet_name = 'RES')
122
- df_excel = df_excel.set_index(['Timesteps'])
123
- df_test = df_excel
124
- df_excel = df_excel.stack()
125
- #df_excel = df_excel.rename(columns={'PV', 'WindOn', 'WindOff', 'RoR'})
126
- df_test2 = df_excel
127
- #df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
128
- #df_excel = df_excel.fillna(0)
129
-
130
- #df_test = df_excel.set_index(['Timesteps', 'PV', 'WindOn', 'WindOff', 'RoR']).stack([0])
131
- #df_test.index = df_test.index.set_names(['t','i'])
132
- s_t_r_iRes = df_excel.to_xarray().rename({'level_1': 'i','Timesteps':'t'})
133
-
134
- #s_t_r_iRes = df_excel.iloc[:,0].to_xarray()
135
-
136
- # Base capacities
137
- df_excel = pd.read_excel(url_excel, sheet_name = 'InstalledCap')
138
- df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'InstalledCap'})
139
- df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
140
- df_excel = df_excel.fillna(0)
141
- df_excel = df_excel.set_index('i')
142
- K_0_i = df_excel.iloc[:,0].to_xarray()
143
-
144
- # Energy-to-power ratio storages
145
- df_excel = pd.read_excel(url_excel, sheet_name = 'E2P')
146
- df_excel = df_excel.rename(columns = {'Storage':'i', 'Unnamed: 1':'E2P ratio'})
147
- #df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
148
- df_excel = df_excel.fillna(0)
149
- df_excel = df_excel.set_index('i')
150
- e2p_iSto = df_excel.iloc[:,0].to_xarray()
151
-
152
- # Inflow for hydro reservoir
153
- df_excel = pd.read_excel(url_excel, sheet_name = 'HydroInflow')
154
- df_excel = df_excel.rename(columns = {'Timesteps':'t', 'Hydro Water Reservoir':'Inflow'})
155
- df_excel = df_excel.fillna(0)
156
- df_excel = df_excel.set_index('t')
157
- h_t = df_excel.iloc[:,0].to_xarray()
158
-
159
-
160
-
161
- sets_dict = {}
162
- params_dict = {}
163
- # Append parameters to the dictionary
164
- sets_dict['t'] = t
165
- sets_dict['i'] = i
166
- sets_dict['iSto'] = iSto
167
- sets_dict['iConv'] = iConv
168
- sets_dict['iPtG'] = iPtG
169
- sets_dict['iRes'] = iRes
170
- sets_dict['iHyRes'] = iHyRes
171
- # Append parameters to the dictionary
172
- params_dict['l_co2'] = l_co2
173
- params_dict['p_co2'] = p_co2
174
- params_dict['dt'] = dt
175
- params_dict['D_t'] = D_t
176
- params_dict['eff_i'] = eff_i
177
- params_dict['c_fuel_i'] = c_fuel_i
178
- params_dict['c_other_i'] = c_other_i
179
- params_dict['c_inv_i'] = c_inv_i
180
- params_dict['co2_factor_i'] = co2_factor_i
181
- params_dict['c_var_i'] = c_var_i
182
- params_dict['s_t_r_iRes'] = s_t_r_iRes
183
- params_dict['K_0_i'] = K_0_i
184
- params_dict['e2p_iSto'] = e2p_iSto
185
- params_dict['h_t'] = h_t
186
-
187
- if write_to_pickle_flag:
188
- save_to_pickle(sets_dict, params_dict)
189
-
190
- return sets_dict, params_dict
191
-
192
-
193
- # %%
194
- # # Example usage:
195
- # url_excel = "Input_Jahr_2021.xlsx" # Replace with your actual file path
196
- # limit_co2 = 0.5
197
- # price_co2 = 50
198
- # price_gas = 3
199
- # price_h2 = 5
200
-
201
- # sets, params = load_data_from_excel(url_excel,write_to_pickle_flag=True)
202
-
203
- # # %%
204
- # sets, params = load_data_from_excel(url_excel,load_from_pickle_flag=True)
205
- # # %%
 
 
 
 
 
 
 
 
 
 
 
1
+ # %%
2
+ import pandas as pd
3
+
4
+ import pickle
5
+
6
+
7
+ # %%
8
+ # Define the file path for the pickle file
9
+ pickle_file_path = 'model_data.pkl'
10
+
11
+ # Function to save dictionaries to a pickle file
12
+ def save_to_pickle(sets_dict, params_dict):
13
+ with open(pickle_file_path, 'wb') as file:
14
+ pickle.dump({'sets': sets_dict, 'params': params_dict}, file)
15
+
16
+ # Function to load dictionaries from a pickle file
17
+ def load_from_pickle():
18
+ with open(pickle_file_path, 'rb') as file:
19
+ data = pickle.load(file)
20
+ return data['sets'], data['params']
21
+
22
+
23
+
24
+ def load_data_from_excel(url_excel, write_to_pickle_flag = True):
25
+
26
+
27
+
28
+ # Timesteps
29
+ df_excel = pd.read_excel(url_excel, sheet_name='Timesteps_All', header=None)
30
+ t = pd.Index(df_excel.iloc[:, 0], name='t')
31
+
32
+ # Technologies
33
+ df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
34
+ i = pd.Index(df_excel.iloc[:, 0], name='i')
35
+
36
+ df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
37
+ iConv = pd.Index(df_excel.iloc[0:7, 2], name='iConv')
38
+
39
+ df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
40
+ iRes = pd.Index(df_excel.iloc[0:4, 4], name='iRes')
41
+
42
+ df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
43
+ iSto = pd.Index(df_excel.iloc[0:2, 6], name='iSto')
44
+
45
+ df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
46
+ iPtG = pd.Index(df_excel.iloc[0:1, 8], name='iPtG')
47
+
48
+ df_excel = pd.read_excel(url_excel, sheet_name='Technologies')
49
+ iHyRes = pd.Index(df_excel.iloc[0:1, 10], name='iHyRes')
50
+
51
+ # Parameters
52
+ l_co2 = pd.read_excel(url_excel, sheet_name='CO2_Cap').iloc[0,0]
53
+ p_co2 = 0
54
+ dt = 1
55
+
56
+ # Demand
57
+ df_excel= pd.read_excel(url_excel, sheet_name = 'Demand')
58
+ #df_melt = pd.melt(df_excel, id_vars='Zeit')
59
+ df_excel = df_excel.rename(columns = {'Timesteps':'t', 'Unnamed: 1':'Demand'})
60
+ #df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
61
+ df_excel = df_excel.fillna(0)
62
+ df_excel = df_excel.set_index('t')
63
+ D_t = df_excel.iloc[:,0].to_xarray()
64
+
65
+ ## Efficiencies
66
+ df_excel = pd.read_excel(url_excel, sheet_name = 'Efficiency')
67
+ df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'Efficiency'})
68
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
69
+ df_excel = df_excel.fillna(0)
70
+ df_excel = df_excel.set_index('i')
71
+ eff_i = df_excel.iloc[:,0].to_xarray()
72
+
73
+ ## Lifespan
74
+ df_excel = pd.read_excel(url_excel, sheet_name = 'Lifespan')
75
+ df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'Lifespan'})
76
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
77
+ df_excel = df_excel.fillna(0)
78
+ df_excel = df_excel.set_index('i')
79
+ life_i = df_excel.iloc[:,0].to_xarray()
80
+
81
+ ## Variable costs
82
+ # Fuel costs
83
+ df_excel = pd.read_excel(url_excel, sheet_name = 'FuelCosts')
84
+ df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'FuelCosts'})
85
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
86
+ df_excel = df_excel.fillna(0)
87
+ df_excel = df_excel.set_index('i')
88
+ c_fuel_i = df_excel.iloc[:,0].to_xarray()
89
+ # Apply slider value
90
+ #c_fuel_i.loc[dict(i = 'Fossil Gas')] = price_gas
91
+ #c_fuel_i.loc[dict(i = 'H2')] = price_h2
92
+
93
+ # Other var. costs
94
+ df_excel = pd.read_excel(url_excel, sheet_name = 'OtherVarCosts')
95
+ df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'OtherVarCosts'})
96
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
97
+ df_excel = df_excel.fillna(0)
98
+ df_excel = df_excel.set_index('i')
99
+ c_other_i = df_excel.iloc[:,0].to_xarray()
100
+
101
+ # Investment costs
102
+ df_excel = pd.read_excel(url_excel, sheet_name = 'InvCosts')
103
+ df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'InvCosts'})
104
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
105
+ df_excel = df_excel.fillna(0)
106
+ df_excel = df_excel.set_index('i')
107
+ interest_rate = 0.07
108
+ annuity_factor_i = (interest_rate * (1 + interest_rate)**life_i) / ((1 + interest_rate)**life_i - 1)
109
+ c_inv_i = df_excel.iloc[:,0].to_xarray()*1000*annuity_factor_i
110
+
111
+ # Emission factor
112
+ df_excel = pd.read_excel(url_excel, sheet_name = 'EmFactor')
113
+ df_excel = df_excel.rename(columns = {'Conventionals':'i', 'Unnamed: 1':'EmFactor'})
114
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
115
+ df_excel = df_excel.fillna(0)
116
+ df_excel = df_excel.set_index('i')
117
+ co2_factor_i = df_excel.iloc[:,0].to_xarray()
118
+
119
+ ## Calculation of variable costs
120
+ c_var_i = (c_fuel_i.sel(i = iConv) + p_co2 * co2_factor_i.sel(i = iConv)) / eff_i.sel(i = iConv) + c_other_i.sel(i = iConv)
121
+
122
+ # RES capacity factors
123
+ #df_excel = pd.read_excel(url_excel, sheet_name = 'RES',header=[0,1])
124
+ #df_excel = pd.read_excel(url_excel, sheet_name = 'RES', index_col=['Timesteps'], columns=['PV', 'WindOn', 'WindOff', 'RoR'])
125
+ df_excel = pd.read_excel(url_excel, sheet_name = 'RES')
126
+ df_excel = df_excel.set_index(['Timesteps'])
127
+ df_test = df_excel
128
+ df_excel = df_excel.stack()
129
+ #df_excel = df_excel.rename(columns={'PV', 'WindOn', 'WindOff', 'RoR'})
130
+ df_test2 = df_excel
131
+ #df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
132
+ #df_excel = df_excel.fillna(0)
133
+
134
+ #df_test = df_excel.set_index(['Timesteps', 'PV', 'WindOn', 'WindOff', 'RoR']).stack([0])
135
+ #df_test.index = df_test.index.set_names(['t','i'])
136
+ s_t_r_iRes = df_excel.to_xarray().rename({'level_1': 'i','Timesteps':'t'})
137
+
138
+ #s_t_r_iRes = df_excel.iloc[:,0].to_xarray()
139
+
140
+ # Base capacities
141
+ df_excel = pd.read_excel(url_excel, sheet_name = 'InstalledCap')
142
+ df_excel = df_excel.rename(columns = {'All':'i', 'Unnamed: 1':'InstalledCap'})
143
+ df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
144
+ df_excel = df_excel.fillna(0)
145
+ df_excel = df_excel.set_index('i')
146
+ K_0_i = df_excel.iloc[:,0].to_xarray()
147
+
148
+ # Energy-to-power ratio storages
149
+ df_excel = pd.read_excel(url_excel, sheet_name = 'E2P')
150
+ df_excel = df_excel.rename(columns = {'Storage':'i', 'Unnamed: 1':'E2P ratio'})
151
+ #df_excel = i.to_frame().reset_index(drop=True).merge(df_excel, how = 'left')
152
+ df_excel = df_excel.fillna(0)
153
+ df_excel = df_excel.set_index('i')
154
+ e2p_iSto = df_excel.iloc[:,0].to_xarray()
155
+
156
+ # Inflow for hydro reservoir
157
+ df_excel = pd.read_excel(url_excel, sheet_name = 'HydroInflow')
158
+ df_excel = df_excel.rename(columns = {'Timesteps':'t', 'Hydro Water Reservoir':'Inflow'})
159
+ df_excel = df_excel.fillna(0)
160
+ df_excel = df_excel.set_index('t')
161
+ h_t = df_excel.iloc[:,0].to_xarray()
162
+
163
+
164
+
165
+ sets_dict = {}
166
+ params_dict = {}
167
+ # Append parameters to the dictionary
168
+ sets_dict['t'] = t
169
+ sets_dict['i'] = i
170
+ sets_dict['iSto'] = iSto
171
+ sets_dict['iConv'] = iConv
172
+ sets_dict['iPtG'] = iPtG
173
+ sets_dict['iRes'] = iRes
174
+ sets_dict['iHyRes'] = iHyRes
175
+ # Append parameters to the dictionary
176
+ params_dict['l_co2'] = l_co2
177
+ params_dict['p_co2'] = p_co2
178
+ params_dict['dt'] = dt
179
+ params_dict['D_t'] = D_t
180
+ params_dict['eff_i'] = eff_i
181
+ params_dict['life_i'] = life_i
182
+ params_dict['c_fuel_i'] = c_fuel_i
183
+ params_dict['c_other_i'] = c_other_i
184
+ params_dict['c_inv_i'] = c_inv_i
185
+ params_dict['co2_factor_i'] = co2_factor_i
186
+ params_dict['c_var_i'] = c_var_i
187
+ params_dict['s_t_r_iRes'] = s_t_r_iRes
188
+ params_dict['K_0_i'] = K_0_i
189
+ params_dict['e2p_iSto'] = e2p_iSto
190
+ params_dict['h_t'] = h_t
191
+
192
+ if write_to_pickle_flag:
193
+ save_to_pickle(sets_dict, params_dict)
194
+
195
+ return sets_dict, params_dict
196
+
197
+
198
+ # %%
199
+ # # Example usage:
200
+ # url_excel = "Input_Jahr_2021.xlsx" # Replace with your actual file path
201
+ # limit_co2 = 0.5
202
+ # price_co2 = 50
203
+ # price_gas = 3
204
+ # price_h2 = 5
205
+
206
+ # sets, params = load_data_from_excel(url_excel,write_to_pickle_flag=True)
207
+
208
+ # # %%
209
+ # sets, params = load_data_from_excel(url_excel,load_from_pickle_flag=True)
210
+ # # %%
211
+
212
+
213
+ if __name__ == "__main__":
214
+ url_excel = r'Input_Jahr_2021.xlsx'
215
+ sets_dict, params_dict= load_data_from_excel(url_excel, write_to_pickle_flag= False)