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

68 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-18 09:34 +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 

10from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.utils.openfoam_utils import \ 

11 OpenFOAMUtils as of_utils 

12 

13 

14class HeaterSurface(OpenFOAMBaseBoundaryFields, OpenFOAMBaseElement): 

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

16 radiative_power): 

17 super().__init__() 

18 self.tri_geom = PyOCCTools.triangulate_bound_shape(heater_shape) 

19 self.power = radiative_power 

20 self.bound_element_type = 'SpaceHeater' 

21 self.patch_info_type = 'wall' 

22 self.solid_name = name_prefix + '_surface' 

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

24 self.temperature = 40.0 

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

26 self.stl_name) 

27 self.refinement_level = [2, 3] 

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

29 

30 

31class PorousMedia(OpenFOAMBaseBoundaryFields, OpenFOAMBaseElement): 

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

33 convective_power): 

34 super().__init__() 

35 self.solid_name = name_prefix + '_porous_media' 

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

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

38 self.stl_name) 

39 self.power = convective_power 

40 self.refinement_level = [2, 3] 

41 self.tri_geom, self.bbox_min_max = ( 

42 self.create_porous_media_tri_geom(heater_shape)) 

43 

44 @staticmethod 

45 def create_porous_media_tri_geom(heater_shape): 

46 # todo: change for oriented boxes? 

47 # todo: move to PyOCCTools? 

48 # add porous media 

49 porous_media_geom_min_max = PyOCCTools.simple_bounding_box( 

50 heater_shape) 

51 porous_media_geom = BRepPrimAPI_MakeBox( 

52 gp_Pnt(*porous_media_geom_min_max[0]), 

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

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

55 # additional computational overhead, redundant?) 

56 porous_face_list = PyOCCTools.get_faces_from_shape(porous_media_geom) 

57 porous_shape = TopoDS_Compound() 

58 builder = TopoDS_Builder() 

59 builder.MakeCompound(porous_shape) 

60 for shape in porous_face_list: 

61 builder.Add(porous_shape, shape) 

62 porous_media_geom = porous_shape 

63 

64 porous_media_tri_geom = PyOCCTools.triangulate_bound_shape( 

65 porous_media_geom) 

66 

67 return porous_media_tri_geom, porous_media_geom_min_max 

68 

69 

70class Heater: 

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

72 total_heating_power=0, 

73 increase_small_refinement=0.05, increase_large_refinement=0.1): 

74 self.solid_name = name 

75 self.radiation_model = radiation_model 

76 self.radiation_power = 0 # total_heating_power * 0.3 

77 self.convective_power = 0 # total_heating_power * 0.7 

78 self.bound_element_type = 'SpaceHeater' 

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

80 triSurface_path, 

81 self.radiation_power) 

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

83 triSurface_path, 

84 self.convective_power) 

85 

86 self.refinement_level = [1, 3] 

87 self.refinement_zone_small = [] 

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

89 in 

90 self.porous_media.bbox_min_max[0]]) 

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

92 in 

93 self.porous_media.bbox_min_max[1]]) 

94 self.refinement_zone_large = [] 

95 self.refinement_zone_large.append( 

96 [c - increase_large_refinement for c in 

97 self.porous_media.bbox_min_max[0]]) 

98 self.refinement_zone_large.append( 

99 [c + increase_large_refinement for c in 

100 self.porous_media.bbox_min_max[1]]) 

101 

102 def set_boundary_conditions(self, total_heating_power, percent_radiation): 

103 if self.radiation_model == 'none': 

104 qr = 'none' 

105 else: 

106 qr = 'qr' 

107 self.radiation_power = total_heating_power * percent_radiation 

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

109 

110 self.porous_media.power = self.convective_power 

111 # radiation 

112 self.heater_surface.power = self.radiation_power 

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

114 self.heater_surface.T = \ 

115 {'type': 'externalWallHeatFluxTemperature', 

116 'mode': 'power', 

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

118 'Q': f'{of_utils.float_cutoff(self.heater_surface.power)}', 

119 'qrRelaxation': 0.003, 

120 'relaxation': 1.0, 

121 'kappaMethod': 'fluidThermo', 

122 'kappa': 'fluidThermo', 

123 'value': f'uniform ' 

124 f'{of_utils.float_cutoff(self.heater_surface.temperature + 273.15)}' 

125 }