Skip to content

Commit 481eedd

Browse files
committed
Improved complex_example.py
1 parent 8491269 commit 481eedd

File tree

2 files changed

+156
-226
lines changed

2 files changed

+156
-226
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Created on Thu Jun 16 11:19:17 2022
4+
developed by Felix Panitz* and Peter Stange*
5+
* at Chair of Building Energy Systems and Heat Supply, Technische Universität Dresden
6+
"""
7+
8+
import numpy as np
9+
10+
import flixOpt as fx
11+
12+
check_penalty = False
13+
excess_penalty = 1e5
14+
15+
electricity_demand = np.array([70., 80., 90., 90, 90, 90, 90, 90, 90])
16+
heat_demand = np.array([30., 0., 90., 110, 2000, 20, 20, 20, 20]) if check_penalty else np.array([30., 0., 90., 110, 110, 20, 20, 20, 20])
17+
electricity_price = np.array([40., 40., 40., 40, 40, 40, 40, 40, 40])
18+
19+
time_series = fx.create_datetime_array('2020-01-01', len(heat_demand), freq='h')
20+
21+
22+
# ## Bus-Definition: ##
23+
#######################
24+
# Typ Name
25+
Strom = fx.Bus('Strom', excess_penalty_per_flow_hour=excess_penalty)
26+
Fernwaerme = fx.Bus('Fernwärme', excess_penalty_per_flow_hour=excess_penalty)
27+
Gas = fx.Bus('Gas', excess_penalty_per_flow_hour=excess_penalty)
28+
29+
# Effect-Definition:
30+
Costs = fx.Effect('costs', '€', 'Kosten', is_standard=True, is_objective=True)
31+
CO2 = fx.Effect('CO2', 'kg', 'CO2_e-Emissionen', specific_share_to_other_effects_operation={Costs: 0.2})
32+
PE = fx.Effect('PE', 'kWh_PE', 'Primärenergie', maximum_total=3.5e3)
33+
34+
################################
35+
# ## definition of components ##
36+
################################
37+
38+
# 1. definition of boiler #
39+
Gaskessel = fx.linear_converters.Boiler(
40+
'Kessel', eta=0.5, # efficiency ratio
41+
on_off_parameters=fx.OnOffParameters(effects_per_running_hour={Costs: 0, CO2: 1000}), # 1000 kg_CO2/h (just for testing)
42+
# defining flows:
43+
Q_th=fx.Flow(label='Q_th', # name
44+
bus=Fernwaerme, # linked bus
45+
size=fx.InvestParameters(fix_effects=1000, # 1000 € investment costs
46+
fixed_size=50, # fixed size
47+
optional=False, # forced investment
48+
specific_effects={Costs: 10, PE: 2}), # specific costs: 10 €/kW; 2 kWh_PE/kW
49+
load_factor_max=1.0, # maximal mean power 50 kW
50+
load_factor_min=0.1, # minimal mean power 5 kW
51+
relative_minimum=5 / 50, # 10 % part load
52+
relative_maximum=1, # 50 kW
53+
previous_flow_rate=50, # 50 kW is value before start
54+
flow_hours_total_max=1e6, # kWh, overall maximum "flow-work"
55+
can_be_off=fx.OnOffParameters(
56+
on_hours_total_min=0, # minimum of working hours
57+
on_hours_total_max=1000, # maximum of working hours
58+
consecutive_on_hours_max=10, # maximum of working hours in one step
59+
consecutive_off_hours_max=10, # maximum of off hours in one step
60+
# consecutive_on_hours_min = 2, # minimum on hours in one step
61+
# consecutive_off_hours_min = 4, # minimum off hours in one step
62+
effects_per_switch_on=0.01, # € per start
63+
switch_on_total_max=1000), # max nr of starts
64+
),
65+
Q_fu=fx.Flow(label='Q_fu', # name
66+
bus=Gas, # linked bus
67+
size=200, # kW
68+
relative_minimum=0,
69+
relative_maximum=1))
70+
71+
# 2. defining of CHP-unit:
72+
aKWK = fx.linear_converters.CHP(
73+
'BHKW2', eta_th=0.5, eta_el=0.4, on_off_parameters=fx.OnOffParameters(effects_per_switch_on=0.01),
74+
P_el=fx.Flow('P_el', bus=Strom, size=60, relative_minimum=5 / 60),
75+
Q_th=fx.Flow('Q_th', bus=Fernwaerme, size=1e3),
76+
Q_fu=fx.Flow('Q_fu', bus=Gas, size=1e3, previous_flow_rate=20)) # The CHP was ON previously
77+
78+
# 3. defining a alternative CHP-unit with linear segments :
79+
# (Flows mst be defined before the segmented_conversion_factors can be defined)
80+
P_el = fx.Flow('P_el', bus=Strom, size=60, previous_flow_rate=20)
81+
Q_th = fx.Flow('Q_th', bus=Fernwaerme)
82+
Q_fu = fx.Flow('Q_fu', bus=Gas)
83+
segmented_conversion_factors = ({P_el: [(5, 30), (40, 60)], # elements can also be a time series (can change over time)
84+
Q_th: [(6, 35), (45, 100)],
85+
Q_fu: [(12, 70), (90, 200)]})
86+
87+
aKWK2 = fx.LinearConverter('BHKW2', inputs=[Q_fu], outputs=[P_el, Q_th], segmented_conversion_factors=segmented_conversion_factors,
88+
on_off_parameters=fx.OnOffParameters(effects_per_switch_on=0.01))
89+
90+
# 4. definition of storage:
91+
# segmented_investment_effects: [start1, end1, start2, end2, ...] If start and end are equal, then its a point
92+
segmented_investment_effects = ([(5, 25), (25, 100)], # size
93+
{Costs: [(50, 250), (250, 800)], # €
94+
PE: [(5, 25), (25, 100)] # kWh_PE
95+
})
96+
97+
aSpeicher = fx.Storage('Speicher', # defining flows:
98+
charging=fx.Flow('Q_th_load', bus=Fernwaerme, size=1e4),
99+
discharging=fx.Flow('Q_th_unload', bus=Fernwaerme, size=1e4),
100+
capacity_in_flow_hours=fx.InvestParameters(
101+
fix_effects=0, # no fix costs
102+
fixed_size=None, # variable size
103+
effects_in_segments=segmented_investment_effects, # see above
104+
optional=False, # forced invest
105+
specific_effects={Costs: 0.01, CO2: 0.01}, # €/kWh; kg_CO2/kWh
106+
minimum_size=0, maximum_size=1000), # optimizing between 0...1000 kWh
107+
initial_charge_state=0, # empty storage at beginning
108+
# minimal_final_charge_state = 3, # min charge state and end
109+
maximal_final_charge_state=10, # max charge state and end
110+
eta_charge=0.9, eta_discharge=1, # efficiency of (un)-loading
111+
relative_loss_per_hour=0.08, # loss of storage per time
112+
prevent_simultaneous_charge_and_discharge=True) # no parallel loading and unloading
113+
114+
# 5. definition of sinks and sources:
115+
# 5.a) heat load profile:
116+
Waermelast = fx.Sink('Wärmelast', sink=fx.Flow('Q_th_Last', # name
117+
bus=Fernwaerme, # linked bus
118+
size=1, relative_maximum=max(heat_demand), fixed_relative_value=heat_demand)) # fixed values fixed_relative_value * size
119+
# 5.b) gas tarif:
120+
Gasbezug = fx.Source('Gastarif', source=fx.Flow('Q_Gas', bus=Gas, # linked bus
121+
size=1000, # defining nominal size
122+
effects_per_flow_hour={Costs: 0.04, CO2: 0.3}))
123+
# 5.c) feed-in of electricity:
124+
Stromverkauf = fx.Sink('Einspeisung', sink=fx.Flow('P_el', bus=Strom, # linked bus
125+
effects_per_flow_hour=-1 * np.array(electricity_price))) # feed-in tariff
126+
127+
##########################
128+
# ## Build energysystem ##
129+
##########################
130+
131+
flow_system = fx.FlowSystem(time_series, last_time_step_hours=None) # creating FlowSystem
132+
133+
flow_system.add_effects(Costs, CO2, PE) # adding effects
134+
flow_system.add_components(Gaskessel, Waermelast, Gasbezug) # adding components
135+
flow_system.add_components(Stromverkauf) # adding components
136+
flow_system.add_components(aSpeicher) # adding components
137+
flow_system.add_components(aKWK2) # adding components
138+
#flow_system.add_components(aKWK) # adding components
139+
140+
141+
time_indices = None
142+
# time_indices = [1,3,5]
143+
144+
calculation = fx.FullCalculation('Sim1', flow_system, 'pyomo', time_indices)
145+
calculation.do_modeling()
146+
147+
print(calculation.system_model.description_of_equations())
148+
print(calculation.system_model.description_of_variables())
149+
150+
151+
calculation.solve(fx.solvers.HighsSolver(mip_gap=0.005, time_limit_seconds=30), save_results=True)
152+
153+
results = fx.results.CalculationResults(calculation.name, folder='results')
154+
155+
results.plot_operation('Fernwärme')
156+

examples/Ex02_complex/example_complex_ModelAndSolve.py

Lines changed: 0 additions & 226 deletions
This file was deleted.

0 commit comments

Comments
 (0)