Example scenarios
Example scenarios of the co-simulation of the heat pump, hot water tank and controller models are available in the examples folder.
There are cyclic dependencies between the models for each time step, for ex., the hot water tank needing the information from the controller regarding the demands and the water flows, and the controller needing information from the hot water tank regarding the temperature of the water to calculate the flows. mosaik offers two different ways to resolve such cyclic dependencies. The first is the time-shifted resolution, where the information from one model is passed to the other model in the next time step. The second is the same-time-loop resolution, where the information exchange between the models is done in the same time step before progressing the simulation to the next time step. The mosaik documentation describes these two ways of dealing with cyclic dependencies in detail (cyclic-data-flows).
The user can choose between the two types of execution, by specifying the parameter ‘same_time_loop’, while initializing the simulators for each of the models. The default execution mode is the time-shifted resolution. For the same-time-loop resolution, the parameter ‘same_time_loop’ has to be set to ‘True’. Depending on the type of execution, the way the connections between the different models are setup varies, and can be seen in the example scenarios below.
Note
All the simulators must be set to the same type of execution
Time-shifted resolution
The first example scenario uses the time-based resolution of the cyclic dependencies offered by mosaik. The different heat pumps, and calculation modes available in the heat pump model are simulated along with the hot water tank, with the controller model matching both the space heating and domestic hot water demand with the heat available in the hot water tank and controlling the operation of the heat pump.
The simulation is configured as shown below. The inputs/outputs to/from the models are handled by ‘mosaik-csv’.
5sim_config = {
6 'CSV': {
7 'python': 'mosaik_csv:CSV',
8 },
9 'CSV_writer': {
10 'python': 'mosaik_csv_writer:CSVWriter'
11 },
12 'HeatPumpSim': {
13 'python': 'mosaik_components.heatpump.Heat_Pump_mosaik:HeatPumpSimulator',
14 },
15 'HotWaterTankSim': {
16 'python': 'mosaik_components.heatpump.hotwatertank.hotwatertank_mosaik:HotWaterTankSimulator',
17 },
18 'ControllerSim': {
19 'python': 'mosaik_components.heatpump.controller.controller_mosaik:ControllerSimulator',
20 },
21}
22
23# The start date, duration, and step size for the simulation
24END = 10 * 60
25START = '01.01.2020 00:00'
26STEP_SIZE = 60 * 1
The parameters and/or initial values for the different models are specified.
28#Parameters for mosaik-heatpump
29params_hp = {'hp_model': 'Air_30kW_1stage',
30 'heat_source': 'Air',
31 'cons_T': 35,
32 'Q_Demand': 19780,
33 'cond_in_T': 30,
34 'heat_source_T': 7,
35 }
36#Parameters for hot water tank model
37params_hwt = {
38 'height': 3600,
39 'volume': 4000,
40 'T_env': 20.0,
41 'htc_walls': 0.28,
42 'htc_layers': 0.897,
43 'n_layers': 6,
44 'n_sensors': 6,
45 'connections': {
46 'sh_in': {'pos': 10},
47 'sh_out': {'pos': 2150},
48 'dhw_in': {'pos': 10},
49 'dhw_out': {'pos': 3400},
50 'hp_in': {'pos': 10},
51 'hp_out': {'pos': 500},
52 },
53 }
54init_vals_hwt = {
55 'layers': {'T': [40.0, 40.0, 40.0, 40.0, 40.0, 40.0]}
56 }
57#Parameters for controller model
58params_ctrl = {
59 'T_hp_sp_h': 50,
60 'T_hp_sp_l': 40,
61 'T_hr_sp_dhw': 40,
62 'T_hr_sp_sh': 35,
63 'dhw_in_T': 10,
64 'sh_dT': 7,
65 'operation_mode': 'heating',
66 'control_strategy': '1'
67}
The different types of heat pumps and calculation modes that are simulated are specified.
28# The different types of heat pumps and calculation modes that are simulated
29model_list = ['Air_30kW_1stage', 'Air_30kW_1stage', 'LW 300(L)', None]
30calc_mode_list = ['detailed', 'fast', 'hplib', 'fixed']
31filename_list = ['detailed', 'fast', 'hplib', 'fixed']
The mosaik ‘world’, and the simulators of the different models are initialized. The inputs required for the different models – domestic hot water demand (DHW Demand); space heating demand (SH Demand); the heat source temperature, which is the ambient air in this case (T_amb); and the temperature of the cold water replacing the domestic hot water supplied from the tank (dhw_in_T) – are available in the ‘scenario_data.csv’ file. The inputs and the outputs are handled by ‘mosaik-csv’ and the output data is saved in csv files.
78 # Initialize the world and the simulators.
79
80 world = mosaik.World(sim_config)
81
82 heatpumpsim = world.start('HeatPumpSim', step_size=STEP_SIZE)
83
84 hwtsim = world.start('HotWaterTankSim', step_size=STEP_SIZE, config=params_hwt)
85
86 ctrlsim = world.start('ControllerSim', step_size=STEP_SIZE)
87
88 heat_load_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'scenario_data.csv')
89 heat_load_sim = world.start('CSV', sim_start=START, datafile=heat_load_file)
90
91 CSV_File = 'Scenario_' + filename_list[i] + '_time_shifted.csv'
92 csv_sim_writer = world.start('CSV_writer', start_date='01.01.2020 00:00', date_format='%d.%m.%Y %H:%M',
93 output_file=CSV_File)
The specific parameters for the different heat pump models and calculation modes are added to the parameters.
95 params_hp['calc_mode'] = calc_mode_list[i]
96 params_hp['hp_model'] = model_list[i]
97
98 if 'hplib' in params_hp['calc_mode']:
99 params_hp['equivalent_hp_model'] = 'Air_30kW_1stage'
100 elif 'fixed' in params_hp['calc_mode']:
101 params_hp['COP'] = 3.5
102 params_hp['heating capacity'] = 15000
103 params_hp['cond_m'] = 0.5
The different models are instantiated.
105 # Instantiate the models
106 heatpumps = heatpumpsim.HeatPump.create(1, params=params_hp)
107
108 hwts = hwtsim.HotWaterTank.create(1, params=params_hwt, init_vals=init_vals_hwt)
109
110 ctrls = ctrlsim.Controller.create(1, params=params_ctrl)
111
112 heat_load = heat_load_sim.HEATLOAD.create(1)
113
114 csv_writer = csv_sim_writer.CSVWriter(buff_size=60 * 60)
The cyclic data flows between the different models are then set up in the time-shifted manner and the simulation is executed.
116 # connections between the different models
117 world.connect(heat_load[0], ctrls[0], 'T_amb', ('T_amb', 'heat_source_T'), ('SH Demand [kW]', 'sh_demand'),
118 ('DHW Demand [L]', 'dhw_demand'), 'dhw_in_T')
119
120 world.connect(hwts[0], ctrls[0], ('T_mean', 'T_mean_hwt'), ('mass', 'hwt_mass'),
121 ('sensor_00.T', 'bottom_layer_T'), ('sensor_04.T', 'top_layer_T'),
122 ('dhw_out.T', 'dhw_out_T'), ('sh_out.T', 'sh_out_T'), ('hp_out.T', 'hp_out_T'))
123
124 world.connect(ctrls[0], hwts[0], ('sh_in_F', 'sh_in.F'), ('sh_in_T', 'sh_in.T'), ('sh_out_F', 'sh_out.F'),
125 ('dhw_in_F', 'dhw_in.F'), ('dhw_in_T', 'dhw_in.T'), ('dhw_out_F', 'dhw_out.F'), ('T_amb', 'T_env'),
126 time_shifted=True,
127 initial_data={'sh_in_F': 0, 'sh_in_T': 0, 'sh_out_F': 0,
128 'dhw_in_F': 0, 'dhw_in_T': 0, 'dhw_out_F': 0,
129 'T_amb': 0,
130 },
131 )
132
133 world.connect(heatpumps[0], ctrls[0], ('Q_Supplied', 'hp_supply'), ('on_fraction', 'hp_on_fraction'),
134 ('cond_m', 'hp_cond_m'))
135
136 world.connect(ctrls[0], heatpumps[0], ('hp_demand', 'Q_Demand'),
137 'T_amb', 'heat_source_T', time_shifted=True,
138 initial_data={'hp_demand': 0, 'T_amb': 5, 'heat_source_T': 5})
139
140 world.connect(hwts[0], heatpumps[0], ('hp_out.T', 'cond_in_T'))
141
142 world.connect(heatpumps[0], hwts[0], ('cons_T', 'hp_in.T'), ('cond_m', 'hp_in.F'), ('cond_m_neg', 'hp_out.F'),
143 time_shifted=True, initial_data={'cons_T': 0, 'cond_m': 0, 'cond_m_neg': 0})
144
145 world.connect(heat_load[0], csv_writer, 'T_amb', 'SH Demand [kW]', 'DHW Demand [L]')
146 world.connect(heatpumps[0], csv_writer, 'Q_Demand', 'Q_Supplied', 'T_amb', 'heat_source_T', 'cons_T', 'P_Required',
147 'COP', 'cond_m', 'cond_in_T', 'on_fraction')
148
149 world.connect(ctrls[0], csv_writer, 'heat_demand', 'heat_supply', 'hp_demand', 'sh_supply', 'sh_demand', 'hp_supply',
150 'sh_in_F', 'sh_in_T', 'sh_out_F', 'sh_out_T', 'dhw_in_F', 'dhw_in_T', 'dhw_out_F', 'dhw_out_T',
151 'hp_in_F', 'hp_in_T', 'hp_out_F', 'hp_out_T', 'P_hr_sh', 'P_hr_dhw', 'dhw_demand', 'dhw_supply')
152 world.connect(hwts[0], csv_writer, 'sensor_00.T', 'sensor_01.T', 'sensor_02.T', 'sensor_03.T', 'sensor_04.T',
153 'sensor_05.T', 'sh_out.T', 'sh_out.F', 'dhw_out.T', 'dhw_out.F', 'hp_in.T', 'hp_in.F', 'hp_out.T', 'hp_out.F',
154 'T_mean', 'sh_in.T', 'sh_in.F', 'dhw_in.T', 'dhw_in.F')
155
156 #Run
157 world.run(until=END)
Same-time-loop resolution
The second example scenario uses the event-based resolution of the same-time-loop cycles offered by mosaik. Only the things that need to be changed when compared to the time-based resolution are shown below.
While initializing the model simulators, the ‘same_time_loop’ parameter has to be set to ‘True’ for all the models.
82 heatpumpsim = world.start('HeatPumpSim', step_size=STEP_SIZE, same_time_loop=True)
83
84 hwtsim = world.start('HotWaterTankSim', step_size=STEP_SIZE, config=params_hwt, same_time_loop=True)
85
86 ctrlsim = world.start('ControllerSim', step_size=STEP_SIZE, same_time_loop=True)
The cyclic data flows between the different models are then set up in the same-time-loop manner.
116 # connections between the different models
117 world.connect(heat_load[0], ctrls[0], 'T_amb', ('T_amb', 'heat_source_T'), ('SH Demand [kW]', 'sh_demand'),
118 ('DHW Demand [L]', 'dhw_demand'), 'dhw_in_T')
119
120 world.connect(hwts[0], ctrls[0], ('T_mean', 'T_mean_hwt'), ('mass', 'hwt_mass'),
121 ('sensor_00.T', 'bottom_layer_T'), ('sensor_04.T', 'top_layer_T'),
122 ('dhw_out.T', 'dhw_out_T'), ('sh_out.T', 'sh_out_T'),
123 ('hp_out.T', 'hp_out_T'))
124
125 world.connect(ctrls[0], hwts[0], ('sh_in_F', 'sh_in.F'), ('sh_in_T', 'sh_in.T'), ('sh_out_F', 'sh_out.F'),
126 ('dhw_in_F', 'dhw_in.F'), ('dhw_in_T', 'dhw_in.T'), ('dhw_out_F', 'dhw_out.F'), ('T_amb_hwt', 'T_env'),
127 ('hp_in_T', 'hp_in.T'), ('hp_in_F', 'hp_in.F'), ('hp_out_F', 'hp_out.F'), weak=True)
128
129 world.connect(heatpumps[0], ctrls[0], ('Q_Supplied', 'hp_supply'), ('on_fraction', 'hp_on_fraction'),
130 ('cond_m', 'hp_in_F'), ('cond_m_neg', 'hp_out_F'), ('cons_T', 'hp_in_T'), weak=True)
131
132 world.connect(ctrls[0], heatpumps[0], ('hp_demand', 'Q_Demand'), ('hp_out_T', 'cond_in_T'),
133 'T_amb', 'heat_source_T')
134
135
136 world.connect(heat_load[0], csv_writer, 'T_amb', 'SH Demand [kW]', 'DHW Demand [L]')
137 world.connect(heatpumps[0], csv_writer, 'Q_Demand', 'Q_Supplied', 'T_amb', 'heat_source_T', 'cons_T', 'P_Required',
138 'COP', 'cond_m', 'cond_in_T', 'on_fraction')
139
140 world.connect(ctrls[0], csv_writer, 'heat_demand', 'heat_supply', 'hp_demand', 'sh_supply', 'sh_demand', 'hp_supply',
141 'sh_in_F', 'sh_in_T', 'sh_out_F', 'sh_out_T','dhw_in_F', 'dhw_in_T', 'dhw_out_F', 'dhw_out_T',
142 'hp_in_F', 'hp_in_T', 'hp_out_F', 'hp_out_T', 'P_hr_sh', 'P_hr_dhw', 'dhw_demand', 'dhw_supply')
143 world.connect(hwts[0], csv_writer, 'sensor_00.T', 'sensor_01.T', 'sensor_02.T','sensor_03.T', 'sensor_04.T', 'sensor_05.T',
144 'sh_out.T', 'sh_out.F', 'dhw_out.T', 'dhw_out.F', 'hp_in.T', 'hp_in.F', 'hp_out.T', 'hp_out.F',
145 'T_mean', 'sh_in.T', 'sh_in.F', 'dhw_in.T', 'dhw_in.F')
For the same-time-loop execution, it is important to set the initial event that kick-starts the simulation, which is the simulation of the hot water tank for this scenario. The simulation is then executed.
147 # To start hwts as first simulator
148 world.set_initial_event(hwts[0].sid)
149
150 #Run
151 world.run(until=END)