Coverage for bim2sim/plugins/PluginTEASER/bim2sim_teaser/task/create_teaser_prj.py: 0%

76 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-12 17:09 +0000

1from teaser.data.dataclass import DataClass 

2from teaser.data.utilities import ConstructionData 

3from teaser.logic.buildingobjects.building import Building 

4from teaser.logic.buildingobjects.buildingphysics.outerwall import OuterWall 

5from teaser.logic.buildingobjects.buildingphysics.window import Window 

6from teaser.project import Project 

7 

8from bim2sim.plugins.PluginTEASER.bim2sim_teaser import export, models 

9from bim2sim.elements.base_elements import ProductBased 

10from bim2sim.tasks.base import ITask 

11from bim2sim.utilities.common_functions import filter_elements 

12 

13 

14class CreateTEASER(ITask): 

15 """Creates the TEASER project, run() method holds detailed information.""" 

16 reads = ('libraries', 'elements', 'weather_file') 

17 touches = ('teaser_prj', 'bldg_names', 'orig_heat_loads', 

18 'orig_cool_loads') 

19 

20 def run(self, libraries, elements, weather_file): 

21 """Creates the TEASER project based on `bim2sim` elements. 

22 

23 The previous created and enriched `bim2sim` elements are used to 

24 parametrize a TEASER project instance. Therefore we map each `bim2sim` 

25 element to it's corresponding TEASER element. 

26 

27 Args: 

28 libraries: previous loaded libraries. In the case this is the 

29 TEASER library 

30 elements: dict[guid: element] with `bim2sim` elements 

31 weather_file: path to weather file 

32 

33 Returns: 

34 teaser_prj: teaser project instance 

35 bldg_names: list of names of all buildings in project, needed to 

36 maintain the information for later tasks 

37 orig_heat_loads: dict[tz.name: heat_load] with original heat loads 

38 as they get overwritten 

39 orig_cool_loads: dict[tz.name: cool_load] with original cool loads 

40 as they get overwritten 

41 tz_mapping: dict that holds mapping between thermal zones in TEASER 

42 and thermal zones in IFC for later post-processing 

43 """ 

44 self.logger.info("Start creating the TEASER project from the derived " 

45 "building") 

46 

47 export.TEASERExportInstance.init_factory(libraries) 

48 

49 teaser_prj = self._create_project() 

50 bldg_elements = filter_elements(elements, 'Building') 

51 exported_buildings = [] 

52 

53 # Create the building and adds thermal zones and building elements 

54 # This is performed recursively through starting with the Building 

55 # instance which holds the zones which again hold the single elements 

56 for bldg in bldg_elements: 

57 exported_buildings.append(models.Building(bldg, parent=teaser_prj)) 

58 

59 (r_elements, e_elements) = (export.TEASERExportInstance.requested_elements, 

60 export.TEASERExportInstance.export_elements) 

61 

62 # Perform decisions for requested but not existing attributes 

63 yield from ProductBased.get_pending_attribute_decisions(r_elements) 

64 

65 # All parameters are checked against the specified check function and 

66 # exported with the correct unit 

67 for instance in e_elements: 

68 instance.collect_params() 

69 

70 self.prepare_export(exported_buildings) 

71 teaser_prj.calc_all_buildings() 

72 orig_heat_loads, orig_cool_loads =\ 

73 self.overwrite_heatloads(exported_buildings) 

74 teaser_prj.weather_file_path = weather_file 

75 

76 bldg_names = [] 

77 for bldg in exported_buildings: 

78 bldg_names.append(bldg.name) 

79 

80 return teaser_prj, bldg_names, orig_heat_loads, orig_cool_loads 

81 

82 def _create_project(self): 

83 """Creates a project in TEASER by a given `bim2sim` instance 

84 Parent: None""" 

85 prj = Project() 

86 prj.name = self.prj_name 

87 # iwu_heavy is not used later and just a dummy as material information 

88 # are generated in bim2sim already and parsed into TEASER 

89 prj.data = DataClass(construction_data=ConstructionData.iwu_heavy) 

90 return prj 

91 

92 @classmethod 

93 def prepare_export(cls, exported_buildings:list): 

94 """Export preparations for all thermal zones. 

95 

96 The preparation includes running the calc_building_parameter function 

97 of TEASER for all buildings. 

98 Args: 

99 exported_buildings: list of all buildings that will be exported 

100 """ 

101 

102 for bldg in exported_buildings: 

103 for tz in bldg.thermal_zones: 

104 cls.min_admissible_elements(tz, bldg) 

105 t_inside_profile_max = max(tz.use_conditions.heating_profile) 

106 tz.t_inside = t_inside_profile_max 

107 bldg.calc_building_parameter() 

108 

109 @staticmethod 

110 def overwrite_heatloads(exported_buildings:list): 

111 """Overwrites the original heating and cooling loads for robustness. 

112 

113 The original loads are saved and returned. 

114 """ 

115 orig_heat_loads = {} 

116 orig_cool_loads = {} 

117 for bldg in exported_buildings: 

118 bldg.calc_building_parameter() 

119 for tz in bldg.thermal_zones: 

120 orig_heat_loads[tz.name] = tz.model_attr.heat_load 

121 orig_cool_loads[tz.name] = tz.model_attr.cool_load 

122 # hardcode to prevent too low heat/cooling loads 

123 tz.model_attr.heat_load = 100000 

124 tz.model_attr.cool_load = -100000 

125 return orig_heat_loads, orig_cool_loads 

126 

127 @staticmethod 

128 def min_admissible_elements(tz, bldg): 

129 # WORKAROUND: Teaser doesn't allow thermal zones without 

130 # outer elements or without windows, causes singularity problem 

131 if len(tz.outer_walls + tz.rooftops) == 0: 

132 ow_min = OuterWall(parent=tz) 

133 ow_min.name = 'min_outer_wall' 

134 ow_min.area = 0.01 

135 ow_min.load_type_element( 

136 year=2000, 

137 construction='iwu_heavy', 

138 ) 

139 ow_min.tilt = 90 

140 ow_min.orientation = 0 

141 if len(tz.windows) == 0: 

142 win_min = Window(parent=tz) 

143 win_min.name = 'min_window' 

144 win_min.area = 0.01 

145 win_min.load_type_element( 

146 year=2000, 

147 construction='EnEv', 

148 ) 

149 win_min.orientation = 0 

150 

151 @staticmethod 

152 def rotate_teaser_building(bldg: Building, true_north: float): 

153 """rotates entire building and its components for a given true north 

154 value, only necessary if ifc file true north information its not 

155 given, but want to rotate before exporting""" 

156 bldg.rotate_building(true_north)