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

1import re 

2from pathlib import Path 

3 

4from ebcpy import DymolaAPI 

5 

6import bim2sim 

7from bim2sim.tasks.base import ITask 

8 

9 

10class SimulateModelEBCPy(ITask): 

11 """Simulate TEASER model, run() method holds detailed information.""" 

12 reads = ('bldg_names',) 

13 touches = ('sim_results_path',) 

14 final = True 

15 

16 def run(self, bldg_names): 

17 """Simulates the exported TEASER model by using ebcpy. 

18 

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. 

23 

24 Args: 

25 bldg_names: bldg_names: list of names of all buildings in project 

26 

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 ] 

74 

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) 

89 

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,