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
« 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
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
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)
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))
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
64 porous_media_tri_geom = PyOCCTools.triangulate_bound_shape(
65 porous_media_geom)
67 return porous_media_tri_geom, porous_media_geom_min_max
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)
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]])
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)
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 }