|
6 | 6 | """
|
7 | 7 |
|
8 | 8 | import pathlib
|
9 |
| -import time |
10 |
| - |
11 |
| -import matplotlib.pyplot as plt |
12 | 9 | import numpy as np
|
13 | 10 | import pandas as pd
|
14 |
| -import yaml |
15 | 11 |
|
16 | 12 | import flixOpt as fx
|
17 | 13 | from flixOpt import OnOffParameters
|
|
35 | 31 |
|
36 | 32 | # ###################### Data Import ####################################
|
37 | 33 | data_import = pd.read_csv(pathlib.Path('Zeitreihen2020.csv'), index_col=0).sort_index()
|
38 |
| -filtered_data = data_import['2020-01-01':'2020-01-15 23:45:00'] # Only use data from specific dates |
| 34 | +filtered_data = data_import['2020-01-01':'2020-01-2 23:45:00'] # Only use data from specific dates |
39 | 35 | # filtered_data = data_import[0:500] # Alternatively filter by index
|
40 | 36 |
|
41 | 37 | filtered_data = filtered_data.set_index(pd.to_datetime(filtered_data.index)) # Convert index to datetime
|
|
206 | 202 | )
|
207 | 203 |
|
208 | 204 | # ###################### Calculations ####################################
|
209 |
| - |
210 |
| -list_of_calculations = [] |
| 205 | +calculations = {'Full': None, 'Segmented': None, 'Aggregated': None} |
211 | 206 | # Full Calculation
|
212 | 207 | if full:
|
213 | 208 | calculation = fx.FullCalculation('fullModel', flow_system, 'pyomo', None)
|
214 | 209 | calculation.do_modeling()
|
215 | 210 | calculation.solve(fx.solvers.HighsSolver())
|
216 |
| - list_of_calculations.append(calculation) |
| 211 | + calculations['Full'] = calculation |
217 | 212 |
|
218 | 213 | # Segmented Calculation
|
219 | 214 | if segmented:
|
220 | 215 | calculation = fx.SegmentedCalculation('segModel', flow_system, segment_length, overlap_length)
|
221 | 216 | calculation.do_modeling_and_solve(fx.solvers.HighsSolver())
|
222 |
| - list_of_calculations.append(calculation) |
| 217 | + calculations['Segmented'] = calculation |
223 | 218 |
|
224 | 219 | # Aggregated Calculation
|
225 | 220 | if aggregated:
|
226 | 221 | if keep_extreme_periods:
|
227 |
| - aggregation_parameters.time_series_for_high_peaks = [TS_heat_demand], |
| 222 | + aggregation_parameters.time_series_for_high_peaks = [TS_heat_demand] |
228 | 223 | aggregation_parameters.time_series_for_low_peaks = [TS_electricity_demand, TS_heat_demand]
|
229 | 224 | calculation = fx.AggregatedCalculation(
|
230 | 225 | 'aggModel', flow_system,
|
231 | 226 | aggregation_parameters= aggregation_parameters)
|
232 | 227 | calculation.do_modeling()
|
233 | 228 | calculation.solve(fx.solvers.HighsSolver())
|
234 |
| - list_of_calculations.append(calculation) |
235 |
| - |
| 229 | + calculations['Aggregated'] = calculation |
| 230 | + |
| 231 | + |
| 232 | +# Compare Results between modeling types |
| 233 | +if full and segmented and aggregated: |
| 234 | + data = pd.DataFrame({'Full': calculations['Full'].results()['Components']['Speicher']['charge_state'], |
| 235 | + 'Aggregated': calculations['Aggregated'].results()['Components']['Speicher']['charge_state'], |
| 236 | + 'Segmented': calculations['Segmented'].results(combined_arrays=True)['Components']['Speicher']['charge_state']}, |
| 237 | + index = calculations['Full'].system_model.time_series_with_end) |
| 238 | + fig = fx.plotting.with_plotly(data, 'line') |
| 239 | + fig.update_layout(title="Compared Charge state of Storage for different Calculation types", |
| 240 | + xaxis_title="Time", yaxis_title="Charge state") |
| 241 | + fig.write_html('results/Charge State.html') |
| 242 | + |
| 243 | + |
| 244 | + data = pd.DataFrame({'Full': calculations['Full'].results()['Components']['BHKW2']['Q_th']['flow_rate'], |
| 245 | + 'Aggregated': calculations['Aggregated'].results()['Components']['BHKW2']['Q_th']['flow_rate'], |
| 246 | + 'Segmented': calculations['Segmented'].results(combined_arrays=True)['Components']['BHKW2']['Q_th']['flow_rate']}, |
| 247 | + index=calculations['Full'].system_model.time_series) |
| 248 | + fig = fx.plotting.with_plotly(data, 'line') |
| 249 | + fig.update_layout(title="Compared flow_rate of BHKW2__Q_th for different Calculation types", |
| 250 | + xaxis_title="Time", yaxis_title="flow rate") |
| 251 | + fig.write_html('results/BHKW2 Thermal Power.html') |
| 252 | + |
| 253 | + |
| 254 | + data = pd.DataFrame({'Full': calculations['Full'].results()['Effects']['costs']['operation']['operation_sum_TS'], |
| 255 | + 'Aggregated': calculations['Aggregated'].results()['Effects']['costs']['operation']['operation_sum_TS'], |
| 256 | + 'Segmented': |
| 257 | + calculations['Segmented'].results(combined_arrays=True)['Effects']['costs']['operation']['operation_sum_TS']}, |
| 258 | + index=calculations['Full'].system_model.time_series) |
| 259 | + fig = fx.plotting.with_plotly(data, 'line') |
| 260 | + fig.update_layout(title="Compared cost for different Calculation types", xaxis_title="Time", yaxis_title="Costs in €") |
| 261 | + fig.write_html('results/Operation Costs.html') |
| 262 | + |
| 263 | + |
| 264 | + data = pd.DataFrame(data.sum()).T |
| 265 | + fig = fx.plotting.with_plotly(data, 'bar') |
| 266 | + fig.update_layout(barmode='group',title="Compared Total costs for different Calculation types", |
| 267 | + xaxis_title="",yaxis_title="Costs in €") |
| 268 | + fig.write_html('results/Total Costs.html') |
| 269 | + |
| 270 | + data = pd.DataFrame({'Full': [calculations['Full'].durations.get(key, 0) for key in calculations['Aggregated'].durations], |
| 271 | + 'Aggregated': [calculations['Aggregated'].durations.get(key, 0) for key in calculations['Aggregated'].durations], |
| 272 | + 'Segmented': [calculations['Segmented'].durations.get(key, 0) for key in calculations['Aggregated'].durations]}, |
| 273 | + index=list(calculations['Aggregated'].durations.keys())).T |
| 274 | + fig = fx.plotting.with_plotly(data, 'bar') |
| 275 | + fig.update_layout(title="Compared Durations for different Calculation types", |
| 276 | + xaxis_title="Calculation type", yaxis_title="Time in seconds") |
| 277 | + fig.write_html('results/Speed Comparison.html') |
236 | 278 |
|
237 |
| -# Segment Plot |
238 |
| -if calc_segs and calc_full: |
239 |
| - fig, ax = plt.subplots(figsize=(10, 5)) |
240 |
| - plt.plot( |
241 |
| - calc_segs.time_series_with_end, |
242 |
| - calc_segs.results_struct.Speicher.charge_state, |
243 |
| - '-', |
244 |
| - label='chargeState (complete)' |
245 |
| - ) |
246 |
| - for system_model in calc_segs.system_models: |
247 |
| - plt.plot( |
248 |
| - system_model.time_series_with_end, |
249 |
| - system_model.results_struct.Speicher.charge_state, |
250 |
| - ':', |
251 |
| - label='chargeState' |
252 |
| - ) |
253 |
| - plt.legend() |
254 |
| - plt.grid() |
255 |
| - plt.show() |
256 |
| - |
257 |
| - # Q_th_BHKW Plot |
258 |
| - fig, ax = plt.subplots(figsize=(10, 5)) |
259 |
| - for system_model in calc_segs.system_models: |
260 |
| - plt.plot(system_model.time_series, system_model.results_struct.BHKW2.Q_th.val, label='Q_th_BHKW') |
261 |
| - plt.plot(calc_full.time_series, calc_full.results_struct.BHKW2.Q_th.val, label='Q_th_BHKW') |
262 |
| - plt.legend() |
263 |
| - plt.grid() |
264 |
| - plt.show() |
265 |
| - |
266 |
| - # Costs Plot |
267 |
| - fig, ax = plt.subplots(figsize=(10, 5)) |
268 |
| - for system_model in calc_segs.system_models: |
269 |
| - plt.plot( |
270 |
| - system_model.time_series, |
271 |
| - system_model.results_struct.global_comp.costs.operation.sum_TS, |
272 |
| - label='costs' |
273 |
| - ) |
274 |
| - plt.plot( |
275 |
| - calc_full.time_series, |
276 |
| - calc_full.results_struct.global_comp.costs.operation.sum_TS, |
277 |
| - ':', |
278 |
| - label='costs (full)' |
279 |
| - ) |
280 |
| - plt.legend() |
281 |
| - plt.grid() |
282 |
| - plt.show() |
283 |
| - |
284 |
| -# Penalty Variables |
285 |
| -print('######### Sum Korr_... (wenn vorhanden) #########') |
286 |
| -if calc_agg: |
287 |
| - aggregation_element = list(calc_agg.flow_system.other_elements)[0] |
288 |
| - for var in aggregation_element.model.variables: |
289 |
| - print(f"{var.label_full}: {sum(var.result())}") |
290 |
| - |
291 |
| -# Time Durations |
292 |
| -print('') |
293 |
| -print('############ Time Durations #####################') |
294 |
| -for a_result in list_of_calcs: |
295 |
| - print(f"{a_result.label}:") |
296 |
| - a_result.listOfModbox[0].describe() |
297 |
| - # print(a_result.infos) |
298 |
| - # print(a_result.duration) |
299 |
| - print(f"costs: {a_result.results_struct.global_comp.costs.all.sum}") |
300 |
| - |
301 |
| -# ########################################################################## |
302 |
| -# ###################### Post Processing ################################ |
303 |
| - |
304 |
| -import flixOpt.postprocessing as flix_post |
305 |
| - |
306 |
| -list_of_results = [] |
307 |
| - |
308 |
| -if do_full_calc: |
309 |
| - full = flix_post.flix_results(calc_full.label) |
310 |
| - list_of_results.append(full) |
311 |
| - costs = full.results_struct.global_comp.costs.all.sum |
312 |
| - |
313 |
| -if do_aggregated_calc: |
314 |
| - agg = flix_post.flix_results(calc_agg.label) |
315 |
| - list_of_results.append(agg) |
316 |
| - costs = agg.results_struct.global_comp.costs.all.sum |
317 |
| - |
318 |
| -if do_segmented_calc: |
319 |
| - seg = flix_post.flix_results(calc_segs.label) |
320 |
| - list_of_results.append(seg) |
321 |
| - costs = seg.results_struct.global_comp.costs.all.sum |
322 |
| - |
323 |
| -# ###### Plotting ####### |
324 |
| - |
325 |
| -# Overview Plot |
326 |
| -def uebersichts_plot(a_calc): |
327 |
| - fig, ax = plt.subplots(figsize=(10, 5)) |
328 |
| - plt.title(a_calc.name) |
329 |
| - |
330 |
| - plot_flow(a_calc, a_calc.results_struct.BHKW2.P_el.val, 'P_el') |
331 |
| - plot_flow(a_calc, a_calc.results_struct.BHKW2.Q_th.val, 'Q_th_BHKW') |
332 |
| - plot_flow(a_calc, a_calc.results_struct.Kessel.Q_th.val, 'Q_th_Kessel') |
333 |
| - |
334 |
| - plot_on(a_calc, a_calc.results_struct.Kessel.Q_th, 'Q_th_Kessel', -5) |
335 |
| - plot_on(a_calc, a_calc.results_struct.Kessel, 'Kessel', -10) |
336 |
| - plot_on(a_calc, a_calc.results_struct.BHKW2, 'BHKW ', -15) |
337 |
| - |
338 |
| - plot_flow(a_calc, a_calc.results_struct.Waermelast.Q_th_Last.val, 'Q_th_Last') |
339 |
| - |
340 |
| - plt.plot( |
341 |
| - a_calc.time_series, |
342 |
| - a_calc.results_struct.global_comp.costs.operation.sum_TS, |
343 |
| - '--', |
344 |
| - label='costs (operating)' |
345 |
| - ) |
346 | 279 |
|
347 |
| - if hasattr(a_calc.results_struct, 'Speicher'): |
348 |
| - plt.step( |
349 |
| - a_calc.time_series, |
350 |
| - a_calc.results_struct.Speicher.Q_th_unload.val, |
351 |
| - where='post', |
352 |
| - label='Speicher_unload' |
353 |
| - ) |
354 |
| - plt.step( |
355 |
| - a_calc.time_series, |
356 |
| - a_calc.results_struct.Speicher.Q_th_load.val, |
357 |
| - where='post', |
358 |
| - label='Speicher_load' |
359 |
| - ) |
360 |
| - plt.plot( |
361 |
| - a_calc.time_series_with_end, |
362 |
| - a_calc.results_struct.Speicher.charge_state, |
363 |
| - label='charge_state' |
364 |
| - ) |
365 |
| - |
366 |
| - plt.grid(axis='y') |
367 |
| - plt.legend(loc='center left', bbox_to_anchor=(1., 0.5)) |
368 |
| - plt.show() |
369 |
| - |
370 |
| -# Generate Plots |
371 |
| -for a_result in list_of_results: |
372 |
| - uebersichts_plot(a_result) |
373 |
| - |
374 |
| -# Component-Specific Plots |
375 |
| -for a_result in list_of_results: |
376 |
| - # Ensure type hint for better IDE support |
377 |
| - a_result: flix_post.flix_results |
378 |
| - a_result.plot_in_and_outs('Fernwaerme', stacked=True) |
379 |
| - |
380 |
| -# Penalty Costs |
381 |
| -print('## Penalty: ##') |
382 |
| -for a_result in list_of_results: |
383 |
| - print(f"Kosten penalty Sim1: {sum(a_result.results_struct.global_comp.penalty.sum_TS)}") |
384 |
| - |
385 |
| -# Load YAML File |
386 |
| -with open(agg.filename_infos, 'rb') as f: |
387 |
| - infos = yaml.safe_load(f) |
388 |
| - |
389 |
| -# Periods Order of Aggregated Calculation |
390 |
| -print(f"periods_order of aggregated calc: {infos['calculation']['aggregatedProps']['periods_order']}") |
0 commit comments