Coverage for bim2sim/plugins/PluginTEASER/bim2sim_teaser/task/simulate_dymola_ebcpy.py: 0%
44 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
1import re
2from pathlib import Path
4from ebcpy import DymolaAPI
6import bim2sim
7from bim2sim.tasks.base import ITask
10class SimulateModelEBCPy(ITask):
11 """Simulate TEASER model, run() method holds detailed information."""
12 reads = ('bldg_names',)
13 touches = ('sim_results_path',)
14 final = True
16 def run(self, bldg_names):
17 """Simulates the exported TEASER model by using ebcpy.
19 The Modelica model that is created through TEASER is simulated by using
20 ebcpy and its DymolaAPI. Modelica/Dymola stores simulation results
21 in .mat files which are stored in the export folder of the `bim2sim`
22 project.
24 Args:
25 bldg_names: bldg_names: list of names of all buildings in project
27 Returns:
28 teaser_mat_result_paths: dict[bldg_name: mat result path] where for
29 each building the corresponding result is stored
30 sim_results_path: path where the sim results are stored, including
31 the subdirectory with the model name
32 """
33 if not self.playground.sim_settings.dymola_simulation:
34 self.logger.warning(
35 f"Skipping task {self.name} as sim_setting 'dymola_simulation' "
36 f"is set to {self.playground.sim_settings.dymola_simulation} "
37 f"and no simulation should be performed.")
38 return None,
39 else:
40 if self.playground.sim_settings.path_aixlib:
41 dir_aixlib = self.playground.sim_settings.path_aixlib
42 else:
43 # if aixlib not provided by setting, try using the path from
44 # regression testing
45 self.logger.warning(
46 f'The sim_setting "path_aixlib" is not set, trying to use'
47 f'the regression test path for AixLib library.')
48 dir_aixlib = (
49 Path(bim2sim.__file__).parent / 'plugins' /
50 f'Plugin{self.playground.project.plugin_cls.name}'
51 / 'test' / 'regression' / 'library' /
52 'library_AixLib' / 'AixLib' / 'package.mo')
53 if not dir_aixlib.exists():
54 raise FileNotFoundError(
55 f'AixLib directory not found. The sim_setting '
56 f'"path_aixlib" is not set and library for regression '
57 f'testing was not downloaded yet. Please either set the '
58 f'"path_aixlib" sim_setting or run '
59 f'prepare_regression_tests.py for '
60 f'Plugin{self.playground.project.plugin_cls.name}.')
61 # needed because teaser removes special characters
62 regex = re.compile("[^a-zA-z0-9]")
63 model_export_name = regex.sub("", self.prj_name)
64 dir_model_package = Path(
65 self.paths.export / 'TEASER' / 'Model' / model_export_name /
66 'package.mo')
67 sim_results_path = Path(
68 self.paths.export / 'TEASER' / 'SimResults' /
69 model_export_name)
70 packages = [
71 dir_model_package,
72 dir_aixlib
73 ]
75 simulation_setup = {"start_time": 0,
76 "stop_time": 3.1536e+07,
77 "output_interval": 3600,
78 "solver": "Cvode",
79 "tolerance": 0.001}
80 n_success = 0
81 for n_sim, bldg_name in enumerate(bldg_names):
82 self.logger.info(f"Starting simulation for model "
83 f"{bldg_name}. "
84 f"Simulation {n_sim}/{len(bldg_names)}")
85 sim_model = \
86 model_export_name + '.' + bldg_name + '.' + bldg_name
87 bldg_result_dir = sim_results_path / bldg_name
88 bldg_result_dir.mkdir(parents=True, exist_ok=True)
90 try:
91 dym_api = DymolaAPI(
92 model_name=sim_model,
93 working_directory=bldg_result_dir,
94 packages=packages,
95 show_window=True,
96 n_restart=-1,
97 equidistant_output=True,
98 debug=True
99 )
100 except Exception:
101 raise Exception(
102 "Dymola API could not be initialized, there"
103 "are several possible reasons."
104 " One could be a missing Dymola license.")
105 dym_api.set_sim_setup(sim_setup=simulation_setup)
106 # activate spare solver as TEASER models are mostly sparse
107 dym_api.dymola.ExecuteCommand(
108 "Advanced.SparseActivate=true")
109 teaser_mat_result_path = dym_api.simulate(
110 return_option="savepath",
111 savepath=str(sim_results_path / bldg_name),
112 result_file_name="teaser_results"
113 )
114 if teaser_mat_result_path:
115 n_success += 1
116 self.playground.sim_settings.simulated = True
117 self.logger.info(f"Successfully simulated "
118 f"{n_success}/{len(bldg_names)}"
119 f" Simulations.")
120 self.logger.info(f"You can find the results under "
121 f"{str(sim_results_path)}")
122 return sim_results_path,