Coverage for teaser/logic/archetypebuildings/urbanrenet/est1a.py: 94%

162 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-04-29 16:01 +0000

1# created June 2015 

2# by TEASER4 Development Team 

3 

4from teaser.logic.archetypebuildings.residential \ 

5 import Residential 

6from teaser.logic.buildingobjects.useconditions \ 

7 import UseConditions as UseCond 

8from teaser.logic.buildingobjects.buildingphysics.ceiling import Ceiling 

9from teaser.logic.buildingobjects.buildingphysics.floor import Floor 

10from teaser.logic.buildingobjects.buildingphysics.groundfloor \ 

11 import GroundFloor 

12from teaser.logic.buildingobjects.buildingphysics.innerwall import InnerWall 

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

14from teaser.logic.buildingobjects.buildingphysics.rooftop import Rooftop 

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

16from teaser.logic.buildingobjects.thermalzone import ThermalZone 

17import teaser.data.utilities as datahandling 

18 

19class EST1a(Residential): 

20 """Archetype for Urban Fabric Type EST1a. 

21 

22 Subclass from Residential for urban fabric type EST1a. Boundary values 

23 for this archetype are taken from :cite:`Hegger.2014`. The archetype 

24 calculation 

25 is adapted from :cite:`KurzverfahrenIWU`, with the change of using the 

26 facade area to volume ratio of the building. For further information see 

27 :cite:`Lauster.2016`. 

28 

29 Parameters 

30 ---------- 

31 parent: Project() 

32 The parent class of this object, the Project the Building belongs 

33 to. Allows for better control of hierarchical structures. If not None it 

34 adds this Building instance to Project.buildings. 

35 name : str 

36 Individual name 

37 height_of_floors : float [m] 

38 Average height of the buildings' floors 

39 number_of_floors : int 

40 Number of building's floors above ground 

41 year_of_construction : int 

42 Year of first construction 

43 net_leased_area : float [m2] 

44 Total net leased area of building. This is area is NOT the footprint 

45 of a building 

46 with_ahu : Boolean 

47 If set to True, an empty instance of BuildingAHU is instantiated and 

48 assigned to attribute central_ahu. This instance holds information for 

49 central Air Handling units. Default is False. 

50 internal_gains_mode: int [1, 2, 3] 

51 mode for the internal gains calculation done in AixLib: 

52 

53 1. Temperature and activity degree dependent heat flux calculation for persons. The 

54 calculation is based on SIA 2024 (default) 

55 2. Temperature and activity degree independent heat flux calculation for persons, the max. 

56 heatflowrate is prescribed by the parameter 

57 fixed_heat_flow_rate_persons. 

58 3. Temperature and activity degree dependent calculation with 

59 consideration of moisture and co2. The moisture calculation is 

60 based on SIA 2024 (2015) and regards persons and non-persons, the co2 calculation is based on 

61 Engineering ToolBox (2004) and regards only persons. 

62 

63 neighbour_buildings : int 

64 Number of neighbour buildings. CAUTION: this will not change 

65 the orientation of the buildings wall, but just the overall 

66 exterior wall and window area(!) (default = 0) 

67 

68 0. no neighbour 

69 1. one neighbour 

70 2. two neighbours 

71 

72 construction_data : str 

73 Construction type of used wall constructions default is "heavy") 

74 iwu_heavy: heavy construction 

75 iwu_light: light construction 

76 inner_wall_approximation_approach : str 

77 'teaser_default' (default) sets length of inner walls = typical 

78 length * height of floors + 2 * typical width * height of floors 

79 'typical_minus_outer' sets length of inner walls = 2 * typical 

80 length * height of floors + 2 * typical width * height of floors 

81 - length of outer or interzonal walls 

82 'typical_minus_outer_extended' like 'typical_minus_outer', but also 

83 considers that 

84 a) a non-complete "average room" reduces its circumference 

85 proportional to the square root of the area 

86 b) rooftops, windows and ground floors (= walls with border to 

87 soil) may have a vertical share 

88 

89 Notes 

90 ----- 

91 The listed attributes are just the ones that are set by the user 

92 calculated values are not included in this list. Changing these values is 

93 expert mode. 

94 

95 Attributes 

96 ---------- 

97 

98 zone_area_factors : dict 

99 This dictionary contains the name of the zone (str), the 

100 zone area factor (float), the zone usage from BoundaryConditions json 

101 (str) (Default see doc string above), and may contain a dictionary with 

102 keyword-attribute-like changes to zone parameters that are usually 

103 inherited from parent: 'number_of_floors', 'height_of_floors' 

104 outer_wall_names : dict 

105 This dictionary contains a random name for the outer walls, 

106 their orientation and tilt. Default is a building in north-south 

107 orientation) 

108 roof_names : dict 

109 This dictionary contains the name of the roofs, their orientation 

110 and tilt. Default is one flat roof. 

111 ground_floor_names : dict 

112 This dictionary contains the name of the ground floors, their 

113 orientation and tilt. Default is one ground floor. 

114 window_names : dict 

115 This dictionary contains the name of the window, their 

116 orientation and tilt. Default is a building in north-south 

117 orientation) 

118 inner_wall_names : dict 

119 This dictionary contains the name of the inner walls, their 

120 orientation and tilt. Default is one cumulated inner wall. 

121 ceiling_names : dict 

122 This dictionary contains the name of the ceilings, their 

123 orientation and tilt. Default is one cumulated ceiling. 

124 floor_names : dict 

125 This dictionary contains the name of the floors, their 

126 orientation and tilt. Default is one cumulated floor. 

127 est_factor_win_area : float 

128 Estimation factor to calculate window area 

129 est_factor_facade_to_volume : float 

130 Estimation factor to describe the facade area to volume ratio 

131 

132 """ 

133 

134 def __init__( 

135 self, 

136 parent, 

137 name=None, 

138 year_of_construction=None, 

139 number_of_floors=None, 

140 height_of_floors=None, 

141 net_leased_area=None, 

142 with_ahu=False, 

143 internal_gains_mode=1, 

144 neighbour_buildings=None, 

145 construction_data=None, 

146 inner_wall_approximation_approach='teaser_default' 

147 ): 

148 """Constructor of EST1a 

149 """ 

150 

151 super(EST1a, self).__init__( 

152 parent, 

153 name, 

154 year_of_construction, 

155 net_leased_area, 

156 with_ahu, 

157 internal_gains_mode, 

158 inner_wall_approximation_approach) 

159 

160 self.neighbour_buildings = neighbour_buildings 

161 self.construction_data = construction_data 

162 self.number_of_apartments = 1 

163 self.number_of_floors = number_of_floors 

164 self.height_of_floors = height_of_floors 

165 

166 # Parameters are default values for current calculation following 

167 # Hegger 

168 

169 # [area factor, usage type(has to be set)] 

170 self.zone_area_factors = {} 

171 for value in range(1, self._number_of_apartments + 1): 

172 zone_name = "Apartment " + str(value) 

173 zone = {zone_name: [1 / self._number_of_apartments, "Living"]} 

174 self.zone_area_factors.update(zone) 

175 

176 self.outer_wall_names = {"Exterior Facade North": [90.0, 0.0], 

177 "Exterior Facade East": [90.0, 90.0], 

178 "Exterior Facade South": [90.0, 180.0], 

179 "Exterior Facade West": [90.0, 270.0]} 

180 # [tilt, orientation] 

181 

182 self.roof_names = {"Rooftop": [0, -1]} # [0, -1] 

183 

184 self.ground_floor_names = {"Ground Floor": [0, -2]} # [0, -2] 

185 

186 self.window_names = {"Window Facade North": [90.0, 0.0], 

187 "Window Facade East": [90.0, 90.0], 

188 "Window Facade South": [90.0, 180.0], 

189 "Window Facade West": [90.0, 270.0]} 

190 # [tilt, orientation] 

191 

192 self.inner_wall_names = {"InnerWall": [90.0, 0.0]} 

193 

194 self.ceiling_names = {"Ceiling": [0.0, -1]} 

195 

196 self.floor_names = {"Floor": [0.0, -2]} 

197 

198 self.est_factor_win_area = 0.2 

199 self.est_factor_facade_to_volume = 0.87 

200 

201 self.nr_of_orientation = len(self.outer_wall_names) 

202 

203 # estimated intermediate calculated values 

204 self._est_roof_area = 0 

205 self._est_ground_floor_area = 0.0 

206 self._est_win_area = 0 

207 self._est_outer_wall_area = 0.0 

208 

209 self.est_factor_neighbour = 0.0 

210 

211 if self.neighbour_buildings == 0: 

212 self._est_factor_neighbour = 0.0 

213 elif self.neighbour_buildings == 1: 

214 self._est_factor_neighbour = 1.0 

215 elif self.neighbour_buildings == 2: 

216 self._est_factor_neighbour = 2.0 

217 

218 if self.with_ahu is True: 

219 self.central_ahu.temperature_profile = (7 * [293.15] + 

220 12 * [295.15] + 

221 5 * [293.15]) 

222 # according to :cite:`DeutschesInstitutfurNormung.2016` 

223 self.central_ahu.min_relative_humidity_profile = (24 * [0.45]) 

224 # according to :cite:`DeutschesInstitutfurNormung.2016b` and 

225 # :cite:`DeutschesInstitutfurNormung.2016` 

226 self.central_ahu.max_relative_humidity_profile = (24 * [0.65]) 

227 self.central_ahu.v_flow_profile = ( 

228 7 * [0.0] + 12 * [1.0] + 5 * [0.0]) # according to user # 

229 # profile in :cite:`DeutschesInstitutfurNormung.2016` 

230 

231 def generate_archetype(self): 

232 """Generates a residential building. 

233 

234 With given values, this class generates a type residential 

235 building according to TEASER requirements. 

236 

237 """ 

238 # help area for the correct building area setting while using typeBldgs 

239 self.thermal_zones = None 

240 type_bldg_area = self.net_leased_area 

241 self.net_leased_area = 0.0 

242 

243 self._est_ground_floor_area = type_bldg_area / self.number_of_floors 

244 

245 self._est_roof_area = type_bldg_area / self.number_of_floors 

246 

247 self._est_win_area = self.est_factor_win_area * type_bldg_area * \ 

248 (1 - self._est_factor_neighbour / 4) 

249 

250 self._est_outer_wall_area = (self.est_factor_facade_to_volume * 

251 type_bldg_area * 

252 self.height_of_floors - 

253 self._est_ground_floor_area - 

254 self._est_roof_area - 

255 self._est_win_area) *\ 

256 (1 - self._est_factor_neighbour / 4) 

257 

258 for key, value in self.zone_area_factors.items(): 

259 zone = ThermalZone(self) 

260 zone.name = key 

261 zone.area = type_bldg_area * value[0] 

262 try: 

263 zone.number_of_floors = value[2]['number_of_floors'] 

264 except (KeyError, IndexError): 

265 pass 

266 try: 

267 zone.height_of_floors = value[2]['height_of_floors'] 

268 except (KeyError, IndexError): 

269 pass 

270 use_cond = UseCond(zone) 

271 use_cond.load_use_conditions(value[1]) 

272 

273 zone.use_conditions = use_cond 

274 

275 for key, value in self.outer_wall_names.items(): 

276 # North and South 

277 

278 if value[1] == 0 or value[1] == 180.0: 

279 self.outer_area[value[1]] = self._est_outer_wall_area / \ 

280 self.nr_of_orientation 

281 # East and West 

282 elif value[1] == 90 or value[1] == 270: 

283 

284 self.outer_area[value[1]] = self._est_outer_wall_area / \ 

285 self.nr_of_orientation 

286 

287 for zone in self.thermal_zones: 

288 # create wall and set building elements 

289 outer_wall = OuterWall(zone) 

290 outer_wall.load_type_element(self.year_of_construction, 

291 self.construction_data.value) 

292 outer_wall.name = key 

293 outer_wall.tilt = value[0] 

294 outer_wall.orientation = value[1] 

295 

296 for key, value in self.window_names.items(): 

297 

298 if value[1] == 0 or value[1] == 180: 

299 

300 self.window_area[value[1]] = self._est_win_area / \ 

301 self.nr_of_orientation 

302 

303 elif value[1] == 90 or value[1] == 270: 

304 

305 self.window_area[value[1]] = self._est_win_area / \ 

306 self.nr_of_orientation 

307 

308 ''' 

309 There is no real classification for windows, so this is a bit hard 

310 code - will be fixed sometime 

311 ''' 

312 for zone in self.thermal_zones: 

313 window = Window(zone) 

314 

315 window.load_type_element(self.year_of_construction, 

316 "Kunststofffenster, Isolierverglasung" 

317 ) 

318 window.name = key 

319 window.tilt = value[0] 

320 window.orientation = value[1] 

321 

322 for key, value in self.roof_names.items(): 

323 

324 self.outer_area[value[1]] = self._est_roof_area 

325 

326 for zone in self.thermal_zones: 

327 roof = Rooftop(zone) 

328 roof.load_type_element(self.year_of_construction, 

329 self.construction_data.value) 

330 roof.name = key 

331 roof.tilt = value[0] 

332 roof.orientation = value[1] 

333 

334 for key, value in self.ground_floor_names.items(): 

335 

336 self.outer_area[value[1]] = self._est_ground_floor_area 

337 

338 for zone in self.thermal_zones: 

339 ground_floor = GroundFloor(zone) 

340 ground_floor.load_type_element(self.year_of_construction, 

341 self.construction_data.value) 

342 ground_floor.name = key 

343 ground_floor.tilt = value[0] 

344 ground_floor.orientation = value[1] 

345 

346 for key, value in self.inner_wall_names.items(): 

347 

348 for zone in self.thermal_zones: 

349 inner_wall = InnerWall(zone) 

350 inner_wall.load_type_element(self.year_of_construction, 

351 self.construction_data.value) 

352 inner_wall.name = key 

353 inner_wall.tilt = value[0] 

354 inner_wall.orientation = value[1] 

355 # zone.inner_walls.append(inner_wall) 

356 

357 if self.number_of_floors > 1: 

358 

359 for key, value in self.ceiling_names.items(): 

360 

361 for zone in self.thermal_zones: 

362 ceiling = Ceiling(zone) 

363 ceiling.load_type_element(self.year_of_construction, 

364 self.construction_data.value) 

365 ceiling.name = key 

366 ceiling.tilt = value[0] 

367 ceiling.orientation = value[1] 

368 # zone.inner_walls.append(ceiling) 

369 

370 for key, value in self.floor_names.items(): 

371 

372 for zone in self.thermal_zones: 

373 floor = Floor(zone) 

374 floor.load_type_element(self.year_of_construction, 

375 self.construction_data.value) 

376 floor.name = key 

377 floor.tilt = value[0] 

378 floor.orientation = value[1] 

379 # zone.inner_walls.append(floor) 

380 else: 

381 pass 

382 

383 for key, value in self.outer_area.items(): 

384 self.set_outer_wall_area(value, key) 

385 for key, value in self.window_area.items(): 

386 self.set_window_area(value, key) 

387 

388 for zone in self.thermal_zones: 

389 zone.set_inner_wall_area() 

390 zone.set_volume_zone() 

391 

392 @property 

393 def construction_data(self): 

394 return self._construction_data 

395 

396 @construction_data.setter 

397 def construction_data(self, value): 

398 self._construction_data = datahandling.check_construction_data_setter_iwu(value) 

399 

400 @property 

401 def neighbour_buildings(self): 

402 return self._neighbour_buildings 

403 

404 @neighbour_buildings.setter 

405 def neighbour_buildings(self, value): 

406 if value is not None: 

407 self._neighbour_buildings = value 

408 else: 

409 self._neighbour_buildings = 0 

410 

411 @property 

412 def number_of_apartments(self): 

413 return self._number_of_apartments 

414 

415 @number_of_apartments.setter 

416 def number_of_apartments(self, value): 

417 if value is not None and value >= 1: 

418 self._number_of_apartments = value 

419 else: 

420 self._number_of_apartments = 1