Coverage for bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/openfoam_elements/heater.py: 0%

67 statements  

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

1from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox 

2from OCC.Core.TopoDS import TopoDS_Compound, TopoDS_Builder 

3from OCC.Core.gp import gp_Pnt 

4 

5from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.openfoam_elements.openfoam_base_boundary_conditions import \ 

6 OpenFOAMBaseBoundaryFields 

7from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.openfoam_elements.openfoam_base_element import \ 

8 OpenFOAMBaseElement 

9from bim2sim.utilities.pyocc_tools import PyOCCTools 

10 

11 

12class HeaterSurface(OpenFOAMBaseBoundaryFields, OpenFOAMBaseElement): 

13 def __init__(self, name_prefix, heater_shape, triSurface_path, 

14 radiative_power): 

15 super().__init__() 

16 self.tri_geom = PyOCCTools.triangulate_bound_shape(heater_shape) 

17 self.power = radiative_power 

18 self.bound_element_type = 'SpaceHeater' 

19 self.patch_info_type = 'wall' 

20 self.solid_name = name_prefix + '_surface' 

21 self.stl_name = self.solid_name + '.stl' 

22 self.temperature = 40.0 

23 self.stl_file_path_name = (triSurface_path.as_posix() + '/' + 

24 self.stl_name) 

25 self.refinement_level = [2, 3] 

26 self.bound_area = PyOCCTools.get_shape_area(self.tri_geom) 

27 

28 

29class PorousMedia(OpenFOAMBaseBoundaryFields, OpenFOAMBaseElement): 

30 def __init__(self, name_prefix, heater_shape, triSurface_path, 

31 convective_power): 

32 super().__init__() 

33 self.solid_name = name_prefix + '_porous_media' 

34 self.stl_name = self.solid_name + '.stl' 

35 self.stl_file_path_name = (triSurface_path.as_posix() + '/' + 

36 self.stl_name) 

37 self.power = convective_power 

38 self.refinement_level = [2, 3] 

39 self.tri_geom, self.bbox_min_max = ( 

40 self.create_porous_media_tri_geom(heater_shape)) 

41 

42 @staticmethod 

43 def create_porous_media_tri_geom(heater_shape): 

44 # todo: change for oriented boxes? 

45 # todo: move to PyOCCTools? 

46 # add porous media 

47 porous_media_geom_min_max = PyOCCTools.simple_bounding_box( 

48 heater_shape) 

49 porous_media_geom = BRepPrimAPI_MakeBox( 

50 gp_Pnt(*porous_media_geom_min_max[0]), 

51 gp_Pnt(*porous_media_geom_min_max[1])).Shape() 

52 # todo: check why compound is created from bounding box shape ( 

53 # additional computational overhead, redundant?) 

54 porous_face_list = PyOCCTools.get_faces_from_shape(porous_media_geom) 

55 porous_shape = TopoDS_Compound() 

56 builder = TopoDS_Builder() 

57 builder.MakeCompound(porous_shape) 

58 for shape in porous_face_list: 

59 builder.Add(porous_shape, shape) 

60 porous_media_geom = porous_shape 

61 

62 porous_media_tri_geom = PyOCCTools.triangulate_bound_shape( 

63 porous_media_geom) 

64 

65 return porous_media_tri_geom, porous_media_geom_min_max 

66 

67 

68class Heater: 

69 def __init__(self, name, heater_shape, triSurface_path, radiation_model, 

70 total_heating_power=0, 

71 increase_small_refinement=0.05, increase_large_refinement=0.1): 

72 self.solid_name = name 

73 self.radiation_model = radiation_model 

74 self.radiation_power = 0 # total_heating_power * 0.3 

75 self.convective_power = 0 # total_heating_power * 0.7 

76 self.bound_element_type = 'SpaceHeater' 

77 self.heater_surface = HeaterSurface(self.solid_name, heater_shape, 

78 triSurface_path, 

79 self.radiation_power) 

80 self.porous_media = PorousMedia(self.solid_name, heater_shape, 

81 triSurface_path, 

82 self.convective_power) 

83 

84 self.refinement_level = [1, 3] 

85 self.refinement_zone_small = [] 

86 self.refinement_zone_small.append([c - increase_small_refinement for c 

87 in 

88 self.porous_media.bbox_min_max[0]]) 

89 self.refinement_zone_small.append([c + increase_small_refinement for c 

90 in 

91 self.porous_media.bbox_min_max[1]]) 

92 self.refinement_zone_large = [] 

93 self.refinement_zone_large.append( 

94 [c - increase_large_refinement for c in 

95 self.porous_media.bbox_min_max[0]]) 

96 self.refinement_zone_large.append( 

97 [c + increase_large_refinement for c in 

98 self.porous_media.bbox_min_max[1]]) 

99 

100 def set_boundary_conditions(self, total_heating_power, percent_radiation): 

101 if self.radiation_model == 'none': 

102 qr = 'none' 

103 else: 

104 qr = 'qr' 

105 self.radiation_power = total_heating_power * percent_radiation 

106 self.convective_power = total_heating_power * (1-percent_radiation) 

107 

108 self.porous_media.power = self.convective_power 

109 # radiation 

110 self.heater_surface.power = self.radiation_power 

111 self.heater_surface.heat_flux = self.radiation_power / (self.heater_surface.bound_area * 2) 

112 self.heater_surface.T = \ 

113 {'type': 'externalWallHeatFluxTemperature', 

114 'mode': 'power', 

115 'qr': f"{qr}", 

116 'Q': f'{self.heater_surface.power}', 

117 'qrRelaxation': 0.003, 

118 'relaxation': 1.0, 

119 'kappaMethod': 'fluidThermo', 

120 'kappa': 'fluidThermo', 

121 'value': f'uniform {self.heater_surface.temperature + 273.15}' 

122 }