-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathsimple_example.py
More file actions
127 lines (106 loc) · 5.25 KB
/
simple_example.py
File metadata and controls
127 lines (106 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
This script shows how to use the flixopt framework to model a simple energy system.
"""
import numpy as np
import pandas as pd
import flixopt as fx
if __name__ == '__main__':
fx.CONFIG.exploring()
# --- Create Time Series Data ---
# Heat demand profile (e.g., kW) over time and corresponding power prices
heat_demand_per_h = np.array([30, 0, 90, 110, 110, 20, 20, 20, 20])
power_prices = 1 / 1000 * np.array([80, 80, 80, 80, 80, 80, 80, 80, 80])
# Create datetime array starting from '2020-01-01' for the given time period
timesteps = pd.date_range('2020-01-01', periods=len(heat_demand_per_h), freq='h')
flow_system = fx.FlowSystem(timesteps=timesteps)
# --- Define Energy Buses ---
# These represent nodes, where the used medias are balanced (electricity, heat, and gas)
flow_system.add_elements(fx.Bus(label='Strom'), fx.Bus(label='Fernwärme'), fx.Bus(label='Gas'))
# --- Define Effects (Objective and CO2 Emissions) ---
# Cost effect: used as the optimization objective --> minimizing costs
costs = fx.Effect(
label='costs',
unit='€',
description='Kosten',
is_standard=True, # standard effect: no explicit value needed for costs
is_objective=True, # Minimizing costs as the optimization objective
share_from_temporal={'CO2': 0.2},
)
# CO2 emissions effect with an associated cost impact
CO2 = fx.Effect(
label='CO2',
unit='kg',
description='CO2_e-Emissionen',
maximum_per_hour=1000, # Max CO2 emissions per hour
)
# --- Define Flow System Components ---
# Boiler: Converts fuel (gas) into thermal energy (heat)
boiler = fx.linear_converters.Boiler(
label='Boiler',
thermal_efficiency=0.5,
thermal_flow=fx.Flow(label='Q_th', bus='Fernwärme', size=50, relative_minimum=0.1, relative_maximum=1),
fuel_flow=fx.Flow(label='Q_fu', bus='Gas'),
)
# Combined Heat and Power (CHP): Generates both electricity and heat from fuel
chp = fx.linear_converters.CHP(
label='CHP',
thermal_efficiency=0.5,
electrical_efficiency=0.4,
electrical_flow=fx.Flow('P_el', bus='Strom', size=60, relative_minimum=5 / 60),
thermal_flow=fx.Flow('Q_th', bus='Fernwärme'),
fuel_flow=fx.Flow('Q_fu', bus='Gas'),
)
# Storage: Energy storage system with charging and discharging capabilities
storage = fx.Storage(
label='Storage',
charging=fx.Flow('Q_th_load', bus='Fernwärme', size=1000),
discharging=fx.Flow('Q_th_unload', bus='Fernwärme', size=1000),
capacity_in_flow_hours=fx.InvestParameters(effects_of_investment=20, fixed_size=30, mandatory=True),
initial_charge_state=0, # Initial storage state: empty
relative_maximum_charge_state=1 / 100 * np.array([80, 70, 80, 80, 80, 80, 80, 80, 80]),
relative_maximum_final_charge_state=0.8,
eta_charge=0.9,
eta_discharge=1, # Efficiency factors for charging/discharging
relative_loss_per_hour=0.08, # 8% loss per hour. Absolute loss depends on current charge state
prevent_simultaneous_charge_and_discharge=True, # Prevent charging and discharging at the same time
)
# Heat Demand Sink: Represents a fixed heat demand profile
heat_sink = fx.Sink(
label='Heat Demand',
inputs=[fx.Flow(label='Q_th_Last', bus='Fernwärme', size=1, fixed_relative_profile=heat_demand_per_h)],
)
# Gas Source: Gas tariff source with associated costs and CO2 emissions
gas_source = fx.Source(
label='Gastarif',
outputs=[
fx.Flow(label='Q_Gas', bus='Gas', size=1000, effects_per_flow_hour={costs.label: 0.04, CO2.label: 0.3})
],
)
# Power Sink: Represents the export of electricity to the grid
power_sink = fx.Sink(
label='Einspeisung', inputs=[fx.Flow(label='P_el', bus='Strom', effects_per_flow_hour=-1 * power_prices)]
)
# --- Build the Flow System ---
# Add all defined components and effects to the flow system
flow_system.add_elements(costs, CO2, boiler, storage, chp, heat_sink, gas_source, power_sink)
# Visualize the flow system for validation purposes
flow_system.plot_network()
# --- Define and Run Calculation ---
# Create a calculation object to model the Flow System
optimization = fx.Optimization(name='Sim1', flow_system=flow_system)
optimization.do_modeling() # Translate the model to a solvable form, creating equations and Variables
# --- Solve the Calculation and Save Results ---
optimization.solve(fx.solvers.HighsSolver(mip_gap=0, time_limit_seconds=30))
# --- Analyze Results ---
# Colors are automatically assigned using default colormap
# Optional: Configure custom colors with
optimization.results.setup_colors()
optimization.results['Fernwärme'].plot_node_balance_pie()
optimization.results['Fernwärme'].plot_node_balance()
optimization.results['Storage'].plot_charge_state()
optimization.results.plot_heatmap('CHP(Q_th)|flow_rate')
# Convert the results for the storage component to a dataframe and display
df = optimization.results['Storage'].node_balance_with_charge_state()
print(df)
# Save results to file for later usage
optimization.results.to_file()