Coverage for bim2sim/plugins/PluginOpenFOAM/test/integration/test_openfoam.py: 0%

111 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-01 10:24 +0000

1import sys 

2import unittest 

3from shutil import copyfile, copytree, rmtree 

4from pathlib import Path 

5 

6import os 

7 

8from OCC.Core.gp import gp_Pnt 

9 

10import bim2sim 

11from bim2sim.kernel.decision.decisionhandler import DebugDecisionHandler 

12from bim2sim.tasks import common, bps 

13from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam import task as of_tasks 

14from bim2sim.tasks import common, bps 

15from bim2sim.utilities.common_functions import filter_elements 

16from bim2sim.utilities.pyocc_tools import PyOCCTools 

17from bim2sim.utilities.test import IntegrationBase 

18from bim2sim.utilities.types import IFCDomain 

19 

20# raise unittest.SkipTest("Integration tests not reliable for automated use") 

21sample_root = Path(__file__).parent.parent.parent / 'test/resources/arch/ifc' 

22DEBUG_CASE = True 

23 

24 

25class IntegrationBaseOF(IntegrationBase): 

26 # HACK: We have to remember stderr because eppy resets it currently. 

27 def setUp(self): 

28 self.old_stderr = sys.stderr 

29 self.working_dir = os.getcwd() 

30 super().setUp() 

31 

32 def tearDown(self): 

33 os.chdir(self.working_dir) 

34 sys.stderr = self.old_stderr 

35 if not DEBUG_CASE: 

36 super().tearDown() 

37 

38 def model_domain_path(self) -> str: 

39 return 'arch' 

40 

41 def weather_file_path(self) -> Path: 

42 return (self.test_resources_path() / 

43 'weather_files/DEU_NW_Aachen.105010_TMYx.epw') 

44 

45 

46class TestOFIntegration(IntegrationBaseOF, unittest.TestCase): 

47 """ 

48 Integration tests for multiple IFC example files. 

49 """ 

50 

51 # @unittest.skip("") 

52 

53 def validate_positions(self, position_type, elements, openfoam_elements, 

54 openfoam_case, valid_amount): 

55 positioned_objects = filter_elements(openfoam_elements, position_type) 

56 if positioned_objects: 

57 objs_bbox = PyOCCTools.simple_bounding_box_shape( 

58 [obj.tri_geom for obj in 

59 positioned_objects]) 

60 min_objs_bbox, max_objs_bbox = PyOCCTools.simple_bounding_box([ 

61 obj.tri_geom for obj in 

62 positioned_objects]) 

63 another_zone = None 

64 for tz in filter_elements(elements, 'ThermalZone'): 

65 if tz.guid != openfoam_case.current_zone.guid: 

66 another_zone = tz 

67 break 

68 with self.subTest("Center of Furniture Compound in Space Shape"): 

69 self.assertEqual(True, PyOCCTools.obj2_in_obj1( 

70 openfoam_case.current_zone.space_shape, objs_bbox)) 

71 with self.subTest("Center of Furniture Compound not in other " 

72 "Space"): 

73 if another_zone is not None: 

74 self.assertEqual(False, PyOCCTools.obj2_in_obj1( 

75 another_zone.space_shape, objs_bbox)) 

76 else: 

77 self.assertEqual(True, False) 

78 with self.subTest("Min and Max of Bounding Box in Space Shape."): 

79 self.assertEqual(True, PyOCCTools.check_pnt_in_solid( 

80 PyOCCTools.make_solid_from_shape( 

81 PyOCCTools, openfoam_case.current_zone.space_shape), 

82 gp_Pnt(*min_objs_bbox))) 

83 self.assertEqual(True, PyOCCTools.check_pnt_in_solid( 

84 PyOCCTools.make_solid_from_shape( 

85 PyOCCTools, openfoam_case.current_zone.space_shape), 

86 gp_Pnt(*max_objs_bbox))) 

87 with self.subTest("Resulting number of positioned objects as " 

88 "expected."): 

89 self.assertEqual(valid_amount, len(positioned_objects)) 

90 

91 def run_test_furniture_setup_with_people(self, project, space_guid, 

92 furniture_orientation, 

93 furniture_setting, 

94 furniture_amount=0, 

95 add_people=False, 

96 people_amount=1, 

97 people_setting='Seated', 

98 add_furniture=True, 

99 valid_number_furniture=0, 

100 valid_number_people=0): 

101 with self.subTest(f"Testing space_guid={space_guid}, " 

102 f"setting={furniture_setting}, " 

103 f"orientation={furniture_orientation}, add_people=" 

104 f"{add_people}, " 

105 f"{f'people_amount={people_amount}, people_setting={people_setting}' if add_people else ''}"): 

106 if 'openfoam_case' in project.playground.state: 

107 openfoam_case = project.playground.state['openfoam_case'] 

108 # remove openfoam directory from previous test 

109 if os.path.exists(openfoam_case.openfoam_dir): 

110 rmtree(openfoam_case.openfoam_dir) 

111 

112 ### redefine default tasks for OpenFOAM Plugin testing 

113 project.plugin_cls.default_tasks = [ 

114 of_tasks.InitializeOpenFOAMSetup, 

115 of_tasks.CreateOpenFOAMGeometry, 

116 ] 

117 

118 project.sim_settings.add_airterminals = False 

119 project.sim_settings.add_heating = False 

120 project.sim_settings.add_furniture = add_furniture 

121 project.sim_settings.furniture_amount = furniture_amount 

122 project.sim_settings.furniture_setting = furniture_setting 

123 project.sim_settings.furniture_orientation = furniture_orientation 

124 project.sim_settings.add_people = add_people 

125 project.sim_settings.people_setting = people_setting 

126 project.sim_settings.people_amount = people_amount 

127 project.sim_settings.select_space_guid = space_guid 

128 handler = DebugDecisionHandler(()) 

129 handler.handle(project.run(cleanup=False)) 

130 

131 openfoam_case = project.playground.state['openfoam_case'] 

132 openfoam_elements = project.playground.state['openfoam_elements'] 

133 # todo: requires debugging, more than 48 should be possible here 

134 self.validate_positions('Furniture', 

135 project.playground.elements, 

136 openfoam_elements, openfoam_case, 

137 valid_number_furniture) 

138 self.validate_positions('People', 

139 project.playground.elements, 

140 openfoam_elements, openfoam_case, 

141 valid_number_people) 

142 self.assertEqual(0, handler.return_value) 

143 

144 def test_furniture_setup(self): 

145 """Test Original IFC File from FZK-Haus (KIT)""" 

146 ifc_names = {IFCDomain.arch: 'AC20-FZK-Haus.ifc'} 

147 project = self.create_project(ifc_names, 'openfoam') 

148 

149 project.plugin_cls.default_tasks = [ 

150 common.LoadIFC, 

151 common.CreateElementsOnIfcTypes, 

152 bps.CreateSpaceBoundaries, 

153 bps.CorrectSpaceBoundaries, 

154 common.CreateRelations, 

155 of_tasks.InitializeOpenFOAMSetup, 

156 of_tasks.CreateOpenFOAMGeometry, 

157 ] 

158 project.sim_settings.add_airterminals = False 

159 project.sim_settings.add_heating = False 

160 project.sim_settings.add_furniture = True 

161 project.sim_settings.furniture_setting = 'Concert' 

162 project.sim_settings.furniture_orientation = 'long_side' 

163 project.sim_settings.furniture_amount = 50 

164 project.sim_settings.add_people = True 

165 project.sim_settings.people_amount = 1 

166 project.sim_settings.people_setting = 'Seated' 

167 # project.sim_settings.ep_install_path = 'C://EnergyPlusV9-4-0/' 

168 project.sim_settings.select_space_guid = '2RSCzLOBz4FAK$_wE8VckM' 

169 answers = () 

170 handler = DebugDecisionHandler(answers) 

171 for decision, answer in handler.decision_answer_mapping(project.run()): 

172 decision.value = answer 

173 

174 self.assertEqual(0, handler.return_value) 

175 

176 def test_furniture_setup_DH(self): 

177 """Test DigitalHub, IFC2SB Version, Furniture setups""" 

178 

179 #### prepare for OpenFOAM Plugin (EnergyPlus is skipped here, 

180 # so no boundary conditions are available in this test) 

181 ifc_names = {IFCDomain.arch: 'FM_ARC_DigitalHub_with_SB89.ifc'} 

182 project = self.create_project(ifc_names, 'openfoam') 

183 project.plugin_cls.default_tasks = [ 

184 common.LoadIFC, 

185 common.CreateElementsOnIfcTypes, 

186 bps.CreateSpaceBoundaries, 

187 bps.CorrectSpaceBoundaries, 

188 common.CreateRelations, 

189 ] 

190 # project.sim_settings.ep_install_path = 'C://EnergyPlusV9-4-0/' 

191 answers = ('Autodesk Revit', 'Autodesk Revit', *(None,) * 12) 

192 handler = DebugDecisionHandler(answers) 

193 handler.handle(project.run(cleanup=False)) 

194 self.run_test_furniture_setup_with_people(project, 

195 '3GmoJyFk9FvAnea6mogixJ', 

196 'west', 

197 'Concert', 

198 200, 

199 valid_number_furniture=153) 

200 self.run_test_furniture_setup_with_people(project, 

201 '3hiy47ppf5B8MyZqbpTfpc', 

202 'door', 

203 'Concert', 

204 200, 

205 valid_number_furniture=50) 

206 self.run_test_furniture_setup_with_people(project, 

207 '2o3MylYZzAnR8q1ofuG3sg', 

208 'window', 

209 'Concert', 

210 200, 

211 valid_number_furniture=48) 

212 self.run_test_furniture_setup_with_people(project, 

213 '2o3MylYZzAnR8q1ofuG3sg', 

214 'south', 

215 'Concert', 

216 200, 

217 valid_number_furniture=103) 

218 self.run_test_furniture_setup_with_people(project, 

219 '2o3MylYZzAnR8q1ofuG3sg', 

220 'door', 

221 'Concert', 

222 200, 

223 valid_number_furniture=48) 

224 self.run_test_furniture_setup_with_people(project, 

225 '2o3MylYZzAnR8q1ofuG3sg', 

226 'door', 

227 'Concert', 

228 30, 

229 add_people=True, 

230 people_amount=2, 

231 valid_number_furniture=30, 

232 valid_number_people=2) 

233 

234 

235if __name__ == '__main__': 

236 unittest.main()