Coverage for teaser/logic/archetypebuildings/tabula/de/singlefamilyhouse.py: 97%

191 statements  

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

1# created April 2017 

2# by TEASER Development Team 

3import teaser.data.utilities as datahandling 

4from teaser.logic.archetypebuildings.residential import Residential 

5from teaser.logic.buildingobjects.useconditions import UseConditions as UseCond 

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

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

8from teaser.logic.buildingobjects.buildingphysics.groundfloor import GroundFloor 

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

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

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

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

13from teaser.logic.buildingobjects.buildingphysics.door import Door 

14from teaser.logic.buildingobjects.thermalzone import ThermalZone 

15 

16 

17class SingleFamilyHouse(Residential): 

18 """Archetype for German TABULA Single Family House. 

19 

20 This is an archetype building for german single family house according to 

21 TABULA building typology (http://webtool.building-typology.eu/#bm). As 

22 TABULA defines one reference building, whereas TEASER wants to provide a 

23 methodology to generate individual building information, this archetype 

24 underlies some assumptions. The made assumptions are explained in the 

25 following: 

26 

27 Each building has four orientations for outer walls and windows (north, 

28 east, south and west), two orientations for rooftops (south and north), with 

29 tilt of 35 degree and one orientation for ground floors and one door ( 

30 default 

31 orientation is west). The area of each surface is calculated using the 

32 product of the given net_leased_area and specific estimation factors. These 

33 estimation factors where build by dividing the given 'surface area' by the 

34 'reference floor area' in TABULA. The estimation factors are calculated for 

35 each building period ('construction year class'). Please note that the 

36 number and height of the floors given in TEASER does not have any effect on 

37 the surface area for heat transmission, but is only used to calculate the 

38 interior wall area, which is not specified in TABULA at all. Further, TABULA 

39 does not specify any specific user profile, by default the SingleFamilyHouse 

40 class has exactly one usage zone, which is 'Living'. TABULA also does not 

41 always specify the exact construction of building elements, but always 

42 provides a prescribed U-Value. We used the U-Value and the given material 

43 information to determine thickness of each layer and implemented it into 

44 elements json ('teaser.data.input.inputdata.TypeElements_TABULA_DE.json'). The 

45 material properties have been taken from MASEA Material data base 

46 (http://www.masea-ensan.de/). As there might be some differences in the 

47 assumptions for material properties from TABULA and MASEA the U-Value might 

48 not always be exactly the same as in TABULA but is always in an acceptable 

49 range. The U-Value has been calculated using combined constant values for 

50 interior and exterior heat transmission, we used a resistance of 0.17 

51 (m2*K)/W for outer walls, windows, flat roofs and doors; 0.34 (m2*K)/W for 

52 ground floors to unheated cellars and 0.17 (m2*K)/W to direct ground 

53 coupled floors, 0.21 (m2*K)/W was taken for pitched roofs. 

54 

55 Parameters 

56 ---------- 

57 

58 parent: Project() 

59 The parent class of this object, the Project the Building belongs to. 

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

61 adds this Building instance to Project.buildings. 

62 (default: None) 

63 name : str 

64 Individual name 

65 year_of_construction : int 

66 Year of first construction 

67 height_of_floors : float [m] 

68 Average height of the buildings' floors 

69 number_of_floors : int 

70 Number of building's floors above ground 

71 net_leased_area : float [m2] 

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

73 of a building 

74 with_ahu : Boolean 

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

76 assigned to attribute central_ahu. This instance holds information for 

77 central Air Handling units. Default is False. 

78 internal_gains_mode: int [1, 2, 3] 

79 mode for the internal gains calculation done in AixLib: 

80 

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

82 calculation is based on SIA 2024 (default) 

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

84 heatflowrate is prescribed by the parameter 

85 fixed_heat_flow_rate_persons. 

86 3. Temperature and activity degree dependent calculation with 

87 consideration of moisture and co2. The moisture calculation is 

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

89 Engineering ToolBox (2004) and regards only persons. 

90 inner_wall_approximation_approach : str 

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

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

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

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

95 - length of outer or interzonal walls 

96 'typical_minus_outer_extended' like 'typical_minus_outer', but also 

97 considers that 

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

99 proportional to the square root of the area 

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

101 soil) may have a vertical share 

102 

103 construction_data : str 

104 Construction type of used wall constructions default is "existing 

105 state" 

106 

107 - existing state: 

108 construction of walls according to existing state in TABULA 

109 - usual refurbishment: 

110 construction of walls according to usual refurbishment in TABULA 

111 - advanced refurbishment: 

112 construction of walls according to advanced refurbishment in 

113 TABULA 

114 

115""" 

116 

117 def __init__( 

118 self, 

119 parent, 

120 name=None, 

121 year_of_construction=None, 

122 number_of_floors=None, 

123 height_of_floors=None, 

124 net_leased_area=None, 

125 with_ahu=False, 

126 internal_gains_mode=1, 

127 inner_wall_approximation_approach='teaser_default', 

128 construction_data=None, 

129 ): 

130 

131 super(SingleFamilyHouse, self).__init__( 

132 parent, 

133 name, 

134 year_of_construction, 

135 net_leased_area, 

136 with_ahu, 

137 internal_gains_mode, 

138 inner_wall_approximation_approach 

139 ) 

140 

141 self.construction_data = construction_data 

142 self.number_of_floors = number_of_floors 

143 self.height_of_floors = height_of_floors 

144 

145 if self.construction_data.is_kfw(): 

146 self._construction_data_1 = self.construction_data.value 

147 self._construction_data_2 = self.construction_data.value 

148 else: 

149 self._construction_data_1 = self.construction_data.value + "_1_SFH" 

150 self._construction_data_2 = self.construction_data.value + "_2_SFH" 

151 

152 self.zone_area_factors = {"SingleDwelling": [1, "Living"]} 

153 

154 self._outer_wall_names_1 = { 

155 "ExteriorFacadeNorth_1": [90.0, 0.0], 

156 "ExteriorFacadeEast_1": [90.0, 90.0], 

157 "ExteriorFacadeSouth_1": [90.0, 180.0], 

158 "ExteriorFacadeWest_1": [90.0, 270.0], 

159 } 

160 

161 self._outer_wall_names_2 = { 

162 "ExteriorFacadeNorth_2": [90.0, 0.0], 

163 "ExteriorFacadeEast_2": [90.0, 90.0], 

164 "ExteriorFacadeSouth_2": [90.0, 180.0], 

165 "ExteriorFacadeWest_2": [90.0, 270.0], 

166 } 

167 

168 self.roof_names_1 = { 

169 "RooftopNorth_1": [35.0, 0.0], 

170 "RooftopSouth_1": [35.0, 90.0], 

171 } 

172 

173 self.roof_names_2 = { 

174 "RooftopNorth_2": [35.0, 0.0], 

175 "RooftopSouth_2": [35.0, 90.0], 

176 } 

177 

178 self.ground_floor_names_1 = {"GroundFloor_1": [0, -2]} 

179 

180 self.ground_floor_names_2 = {"GroundFloor_2": [0, -2]} 

181 

182 self.door_names = {"Door": [90.0, 270]} 

183 

184 self.window_names_1 = { 

185 "WindowFacadeNorth_1": [90.0, 0.0], 

186 "WindowFacadeEast_1": [90.0, 90.0], 

187 "WindowFacadeSouth_1": [90.0, 180.0], 

188 "WindowFacadeWest_1": [90.0, 270.0], 

189 } 

190 self.window_names_2 = { 

191 "WindowFacadeNorth_2": [90.0, 0.0], 

192 "WindowFacadeEast_2": [90.0, 90.0], 

193 "WindowFacadeSouth_2": [90.0, 180.0], 

194 "WindowFacadeWest_2": [90.0, 270.0], 

195 } 

196 

197 # [tilt, orientation] 

198 

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

200 

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

202 

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

204 

205 # Rooftop1, Rooftop2, Wall1, Wall2, GroundFloor1, GroundFloor2, 

206 # Window1, Window2, Door 

207 # Area/ReferenceFloorArea 

208 self.facade_estimation_factors = { 

209 (0, 1859): { 

210 "rt1": 0.613, 

211 "rt2": 0.0, 

212 "ow1": 0.7753, 

213 "ow2": 0.0, 

214 "gf1": 0.0, 

215 "gf2": 0.3904, 

216 "win1": 0.1315, 

217 "win2": 0.0, 

218 "door": 0.009, 

219 }, 

220 (1860, 1918): { 

221 "rt1": 0.585, 

222 "rt2": 0.0, 

223 "ow1": 1.366, 

224 "ow2": 0.0, 

225 "gf1": 0.3211, 

226 "gf2": 0.2303, 

227 "win1": 0.157, 

228 "win2": 0.0, 

229 "door": 0.014, 

230 }, 

231 (1919, 1948): { 

232 "rt1": 0.7063, 

233 "rt2": 0.0, 

234 "ow1": 0.7766, 

235 "ow2": 0.0, 

236 "gf1": 0.47822, 

237 "gf2": 0.0, 

238 "win1": 0.173, 

239 "win2": 0.0, 

240 "door": 0.0066, 

241 }, 

242 (1949, 1957): { 

243 "rt1": 1.13, 

244 "rt2": 0.0, 

245 "ow1": 1.0613, 

246 "ow2": 0.0, 

247 "gf1": 0.559, 

248 "gf2": 0.161, 

249 "win1": 0.166, 

250 "win2": 0.0, 

251 "door": 0.018, 

252 }, 

253 (1958, 1968): { 

254 "rt1": 1.396, 

255 "rt2": 0.0, 

256 "ow1": 1.167, 

257 "ow2": 0.072, 

258 "gf1": 0.957, 

259 "gf2": 0.0, 

260 "win1": 0.224, 

261 "win2": 0.0, 

262 "door": 0.017, 

263 }, 

264 (1969, 1978): { 

265 "rt1": 1.05838, 

266 "rt2": 0.0, 

267 "ow1": 1.0266, 

268 "ow2": 0.0, 

269 "gf1": 0.4526, 

270 "gf2": 0.4277, 

271 "win1": 0.1977, 

272 "win2": 0.0, 

273 "door": 0.01156, 

274 }, 

275 (1979, 1983): { 

276 "rt1": 0.46667, 

277 "rt2": 0.0, 

278 "ow1": 0.738, 

279 "ow2": 0.0, 

280 "gf1": 0.386, 

281 "gf2": 0.0, 

282 "win1": 0.125, 

283 "win2": 0.0, 

284 "door": 0.00926, 

285 }, 

286 (1984, 1994): { 

287 "rt1": 0.8213, 

288 "rt2": 0.0, 

289 "ow1": 1.409, 

290 "ow2": 0.0, 

291 "gf1": 0.502, 

292 "gf2": 0.0, 

293 "win1": 0.198, 

294 "win2": 0.0, 

295 "door": 0.01333, 

296 }, 

297 (1995, 2001): { 

298 "rt1": 0.947, 

299 "rt2": 0.0, 

300 "ow1": 1.038, 

301 "ow2": 0.0, 

302 "gf1": 0.691, 

303 "gf2": 0.0, 

304 "win1": 0.266, 

305 "win2": 0.0, 

306 "door": 0.016, 

307 }, 

308 (2002, 2009): { 

309 "rt1": 0.58435, 

310 "rt2": 0.0, 

311 "ow1": 1.285, 

312 "ow2": 0.0, 

313 "gf1": 0.543, 

314 "gf2": 0.0, 

315 "win1": 0.1925, 

316 "win2": 0.0, 

317 "door": 0.0136, 

318 }, 

319 (2010, 2015): { 

320 "rt1": 0.70535, 

321 "rt2": 0.0, 

322 "ow1": 1.217, 

323 "ow2": 0.0, 

324 "gf1": 0.57647, 

325 "gf2": 0.0, 

326 "win1": 0.2246, 

327 "win2": 0.0, 

328 "door": 0.014, 

329 }, 

330 (2016, 2100): { 

331 "rt1": 0.70535, 

332 "rt2": 0.0, 

333 "ow1": 1.217, 

334 "ow2": 0.0, 

335 "gf1": 0.57647, 

336 "gf2": 0.0, 

337 "win1": 0.2246, 

338 "win2": 0.0, 

339 "door": 0.014, 

340 }, 

341 } 

342 

343 self.building_age_group = None 

344 

345 if self.with_ahu is True: 

346 self.central_ahu.temperature_profile = ( 

347 7 * [293.15] + 12 * [295.15] + 5 * [293.15] 

348 ) 

349 self.central_ahu.min_relative_humidity_profile = 24 * [0.45] 

350 self.central_ahu.max_relative_humidity_profile = 24 * [0.55] 

351 self.central_ahu.v_flow_profile = 7 * [0.0] + 12 * [1.0] + 5 * [0.0] 

352 

353 self.internal_gains_mode = internal_gains_mode 

354 

355 def _check_year_of_construction(self): 

356 """Assigns the bldg age group according to year of construction""" 

357 

358 for key in self.facade_estimation_factors: 

359 if ( 

360 self.year_of_construction in range(key[0], key[1]) 

361 or self.year_of_construction == key[1] 

362 ): 

363 self.building_age_group = (key[0], key[1]) 

364 

365 if self.building_age_group is None: 

366 raise RuntimeError( 

367 "Year of construction not supported for this archetype" "building" 

368 ) 

369 

370 def generate_archetype(self): 

371 """Generates a SingleFamilyHouse archetype buildings 

372 

373 With given values, this function generates an archetype building for 

374 Tabula Single Family House. 

375 """ 

376 self.thermal_zones = None 

377 self._check_year_of_construction() 

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

379 type_bldg_area = self.net_leased_area 

380 self.net_leased_area = 0.0 

381 

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

383 zone = ThermalZone(parent=self) 

384 zone.name = key 

385 zone.area = type_bldg_area * value[0] 

386 try: 

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

388 except (KeyError, IndexError): 

389 pass 

390 try: 

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

392 except (KeyError, IndexError): 

393 pass 

394 use_cond = UseCond(parent=zone) 

395 use_cond.load_use_conditions(zone_usage=value[1]) 

396 zone.use_conditions = use_cond 

397 

398 zone.use_conditions.with_ahu = False 

399 

400 if self.facade_estimation_factors[self.building_age_group]["ow1"] != 0: 

401 for key, value in self._outer_wall_names_1.items(): 

402 for zone in self.thermal_zones: 

403 outer_wall = OuterWall(zone) 

404 outer_wall.load_type_element( 

405 year=self.year_of_construction, 

406 construction=self._construction_data_1, 

407 data_class=self.parent.data, 

408 ) 

409 outer_wall.name = key 

410 outer_wall.tilt = value[0] 

411 outer_wall.orientation = value[1] 

412 outer_wall.area = ( 

413 self.facade_estimation_factors[self.building_age_group]["ow1"] 

414 * zone.area 

415 ) / len(self._outer_wall_names_1) 

416 

417 if self.facade_estimation_factors[self.building_age_group]["ow2"] != 0: 

418 for key, value in self._outer_wall_names_2.items(): 

419 for zone in self.thermal_zones: 

420 outer_wall = OuterWall(zone) 

421 outer_wall.load_type_element( 

422 year=self.year_of_construction, 

423 construction=self._construction_data_2, 

424 data_class=self.parent.data, 

425 ) 

426 outer_wall.name = key 

427 outer_wall.tilt = value[0] 

428 outer_wall.orientation = value[1] 

429 outer_wall.area = ( 

430 self.facade_estimation_factors[self.building_age_group]["ow2"] 

431 * zone.area 

432 ) / len(self._outer_wall_names_2) 

433 

434 if self.facade_estimation_factors[self.building_age_group]["win1"] != 0: 

435 for key, value in self.window_names_1.items(): 

436 for zone in self.thermal_zones: 

437 window = Window(zone) 

438 construction = ( 

439 "Waermeschutzverglasung, dreifach" 

440 if self.construction_data.is_kfw() 

441 else self._construction_data_1 

442 ) 

443 window.load_type_element( 

444 self.year_of_construction, 

445 construction=construction, 

446 data_class=self.parent.data, 

447 ) 

448 window.name = key 

449 window.tilt = value[0] 

450 window.orientation = value[1] 

451 window.area = ( 

452 self.facade_estimation_factors[self.building_age_group]["win1"] 

453 * zone.area 

454 ) / len(self.window_names_1) 

455 

456 if self.facade_estimation_factors[self.building_age_group]["win2"] != 0: 

457 for key, value in self.window_names_2.items(): 

458 for zone in self.thermal_zones: 

459 window = Window(zone) 

460 construction = ( 

461 "Waermeschutzverglasung, dreifach" 

462 if self.construction_data.is_kfw() 

463 else self._construction_data_2 

464 ) 

465 window.load_type_element( 

466 self.year_of_construction, 

467 construction=construction, 

468 data_class=self.parent.data, 

469 ) 

470 window.name = key 

471 window.tilt = value[0] 

472 window.orientation = value[1] 

473 window.area = ( 

474 self.facade_estimation_factors[self.building_age_group]["win2"] 

475 * zone.area 

476 ) / len(self.window_names_2) 

477 

478 if self.facade_estimation_factors[self.building_age_group]["gf1"] != 0: 

479 for key, value in self.ground_floor_names_1.items(): 

480 

481 for zone in self.thermal_zones: 

482 gf = GroundFloor(zone) 

483 gf.load_type_element( 

484 year=self.year_of_construction, 

485 construction=self._construction_data_1, 

486 data_class=self.parent.data, 

487 ) 

488 gf.name = key 

489 gf.tilt = value[0] 

490 gf.orientation = value[1] 

491 gf.area = ( 

492 self.facade_estimation_factors[self.building_age_group]["gf1"] 

493 * zone.area 

494 ) / len(self.ground_floor_names_1) 

495 

496 if self.facade_estimation_factors[self.building_age_group]["gf2"] != 0: 

497 for key, value in self.ground_floor_names_2.items(): 

498 

499 for zone in self.thermal_zones: 

500 gf = GroundFloor(zone) 

501 gf.load_type_element( 

502 year=self.year_of_construction, 

503 construction=self._construction_data_2, 

504 data_class=self.parent.data, 

505 ) 

506 gf.name = key 

507 gf.tilt = value[0] 

508 gf.orientation = value[1] 

509 gf.area = ( 

510 self.facade_estimation_factors[self.building_age_group]["gf2"] 

511 * zone.area 

512 ) / len(self.ground_floor_names_2) 

513 

514 if self.facade_estimation_factors[self.building_age_group]["rt1"] != 0: 

515 for key, value in self.roof_names_1.items(): 

516 

517 for zone in self.thermal_zones: 

518 rt = Rooftop(zone) 

519 rt.load_type_element( 

520 year=self.year_of_construction, 

521 construction=self._construction_data_1, 

522 data_class=self.parent.data, 

523 ) 

524 rt.name = key 

525 rt.tilt = value[0] 

526 rt.orientation = value[1] 

527 rt.area = ( 

528 self.facade_estimation_factors[self.building_age_group]["rt1"] 

529 * zone.area 

530 ) / len(self.roof_names_1) 

531 

532 if self.facade_estimation_factors[self.building_age_group]["rt2"] != 0: 

533 for key, value in self.roof_names_2.items(): 

534 

535 for zone in self.thermal_zones: 

536 rt = Rooftop(zone) 

537 rt.load_type_element( 

538 year=self.year_of_construction, 

539 construction=self._construction_data_2, 

540 data_class=self.parent.data, 

541 ) 

542 rt.name = key 

543 rt.tilt = value[0] 

544 rt.orientation = value[1] 

545 rt.area = ( 

546 self.facade_estimation_factors[self.building_age_group]["rt2"] 

547 * zone.area 

548 ) / len(self.roof_names_2) 

549 

550 if self.facade_estimation_factors[self.building_age_group]["door"] != 0: 

551 for key, value in self.door_names.items(): 

552 

553 for zone in self.thermal_zones: 

554 door = Door(zone) 

555 door.load_type_element( 

556 year=self.year_of_construction, 

557 construction=self._construction_data_1, 

558 data_class=self.parent.data, 

559 ) 

560 door.name = key 

561 door.tilt = value[0] 

562 door.orientation = value[1] 

563 door.area = ( 

564 self.facade_estimation_factors[self.building_age_group]["door"] 

565 * zone.area 

566 ) / len(self.door_names) 

567 

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

569 

570 for zone in self.thermal_zones: 

571 inner_wall = InnerWall(zone) 

572 if self.construction_data.is_tabula_de(): 

573 inner_wall.load_type_element( 

574 year=self.year_of_construction, 

575 construction="tabula_de_standard", 

576 data_class=self.parent.data, 

577 ) 

578 else: 

579 inner_wall.load_type_element( 

580 year=self.year_of_construction, 

581 construction=self.construction_data.value, 

582 data_class=self.parent.data, 

583 ) 

584 inner_wall.name = key 

585 inner_wall.tilt = value[0] 

586 inner_wall.orientation = value[1] 

587 

588 if self.number_of_floors > 1: 

589 

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

591 

592 for zone in self.thermal_zones: 

593 ceiling = Ceiling(zone) 

594 if self.construction_data.is_tabula_de(): 

595 ceiling.load_type_element( 

596 year=self.year_of_construction, 

597 construction="tabula_de_standard", 

598 data_class=self.parent.data, 

599 ) 

600 else: 

601 ceiling.load_type_element( 

602 year=self.year_of_construction, 

603 construction=self.construction_data.value, 

604 data_class=self.parent.data, 

605 ) 

606 ceiling.name = key 

607 ceiling.tilt = value[0] 

608 ceiling.orientation = value[1] 

609 

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

611 

612 for zone in self.thermal_zones: 

613 floor = Floor(zone) 

614 if self.construction_data.is_tabula_de(): 

615 floor.load_type_element( 

616 year=self.year_of_construction, 

617 construction="tabula_de_standard", 

618 data_class=self.parent.data, 

619 ) 

620 else: 

621 floor.load_type_element( 

622 year=self.year_of_construction, 

623 construction=self.construction_data.value, 

624 data_class=self.parent.data, 

625 ) 

626 floor.name = key 

627 floor.tilt = value[0] 

628 floor.orientation = value[1] 

629 

630 for zone in self.thermal_zones: 

631 zone.set_inner_wall_area() 

632 zone.set_volume_zone() 

633 

634 @property 

635 def construction_data(self): 

636 return self._construction_data 

637 

638 @construction_data.setter 

639 def construction_data(self, value): 

640 self._construction_data = datahandling.check_construction_data_setter_tabula_de(value)