Coverage for teaser/logic/archetypebuildings/tabula/dk/singlefamilyhouse.py: 84%

181 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 

3 

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 

15import teaser.data.utilities as datahandling 

16 

17 

18class SingleFamilyHouse(Residential): 

19 """Archetype for Danish TABULA Single Family House. 

20 

21 This is an archetype building for danish single family house according to 

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

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

24 methodology to generate individual building information, this archetype 

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

26 following: 

27 

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

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

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

31 default 

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

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

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

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

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

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

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

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

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

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

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

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

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

45 elements json ('teaser.data.input.inputdata.TypeElements_TABULA_DK.json'). The 

46 material properties have been assumed from the "Handbook for Energy 

47 Consultants - HB2016" (http://www.hbemo.dk/). As there might be some 

48 differences in the assumptions for material properties from TABULA and 

49 HB2016 the U-Value might not always be exactly the same as in TABULA but is 

50 always in an acceptable range. The U-Value has been calculated using 

51 combined constant values for interior and exterior heat transmission, we 

52 used a resistance of 0.17 (m2*K)/W for outer walls, windows, flat roofs and 

53 doors; 0.34 (m2*K)/W for ground floors to unheated cellars and 0.17 (m2*K)/W 

54 to direct ground coupled floors, 0.21 (m2*K)/W was taken for pitched roofs. 

55 

56 Parameters 

57 ---------- 

58 

59 parent: Project() 

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

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

62 adds this Building instance to Project.buildings. 

63 (default: None) 

64 name : str 

65 Individual name 

66 year_of_construction : int 

67 Year of first construction 

68 height_of_floors : float [m] 

69 Average height of the buildings' floors 

70 number_of_floors : int 

71 Number of building's floors above ground 

72 net_leased_area : float [m2] 

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

74 of a building 

75 with_ahu : Boolean 

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

77 assigned to attribute central_ahu. This instance holds information for 

78 central Air Handling units. Default is False. 

79 internal_gains_mode: int [1, 2, 3] 

80 mode for the internal gains calculation done in AixLib: 

81 

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

83 calculation is based on SIA 2024 (default) 

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

85 heatflowrate is prescribed by the parameter 

86 fixed_heat_flow_rate_persons. 

87 3. Temperature and activity degree dependent calculation with 

88 consideration of moisture and co2. The moisture calculation is 

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

90 Engineering ToolBox (2004) and regards only persons. 

91 inner_wall_approximation_approach : str 

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

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

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

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

96 - length of outer or interzonal walls 

97 'typical_minus_outer_extended' like 'typical_minus_outer', but also 

98 considers that 

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

100 proportional to the square root of the area 

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

102 soil) may have a vertical share 

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 

111 TABULA 

112 - advanced refurbishment: 

113 construction of walls according to advanced refurbishment in 

114 TABULA 

115 

116 """ 

117 

118 def __init__( 

119 self, 

120 parent, 

121 name=None, 

122 year_of_construction=None, 

123 number_of_floors=None, 

124 height_of_floors=None, 

125 net_leased_area=None, 

126 with_ahu=False, 

127 internal_gains_mode=1, 

128 inner_wall_approximation_approach='teaser_default', 

129 construction_data=None, 

130 ): 

131 

132 super(SingleFamilyHouse, self).__init__( 

133 parent, 

134 name, 

135 year_of_construction, 

136 net_leased_area, 

137 with_ahu, 

138 internal_gains_mode, 

139 inner_wall_approximation_approach 

140 ) 

141 

142 self.construction_data = construction_data 

143 self.number_of_floors = number_of_floors 

144 self.height_of_floors = height_of_floors 

145 

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

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

148 

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

150 

151 self._outer_wall_names_1 = { 

152 "ExteriorFacadeNorth_1": [90.0, 0.0], 

153 "ExteriorFacadeEast_1": [90.0, 90.0], 

154 "ExteriorFacadeSouth_1": [90.0, 180.0], 

155 "ExteriorFacadeWest_1": [90.0, 270.0], 

156 } 

157 

158 self._outer_wall_names_2 = { 

159 "ExteriorFacadeNorth_2": [90.0, 0.0], 

160 "ExteriorFacadeEast_2": [90.0, 90.0], 

161 "ExteriorFacadeSouth_2": [90.0, 180.0], 

162 "ExteriorFacadeWest_2": [90.0, 270.0], 

163 } 

164 

165 self.roof_names_1 = { 

166 "RooftopNorth_1": [35.0, 0.0], 

167 "RooftopSouth_1": [35.0, 90.0], 

168 } 

169 

170 self.roof_names_2 = { 

171 "RooftopNorth_2": [35.0, 0.0], 

172 "RooftopSouth_2": [35.0, 90.0], 

173 } 

174 

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

176 

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

178 

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

180 

181 self.window_names_1 = { 

182 "WindowFacadeNorth_1": [90.0, 0.0], 

183 "WindowFacadeEast_1": [90.0, 90.0], 

184 "WindowFacadeSouth_1": [90.0, 180.0], 

185 "WindowFacadeWest_1": [90.0, 270.0], 

186 } 

187 self.window_names_2 = { 

188 "WindowFacadeNorth_2": [90.0, 0.0], 

189 "WindowFacadeEast_2": [90.0, 90.0], 

190 "WindowFacadeSouth_2": [90.0, 180.0], 

191 "WindowFacadeWest_2": [90.0, 270.0], 

192 } 

193 

194 # [tilt, orientation] 

195 

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

197 

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

199 

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

201 

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

203 # Window1, Window2, Door 

204 # Area/ReferenceFloorArea 

205 self.facade_estimation_factors = { 

206 (2007, 2010): { 

207 "rt1": 1.179, 

208 "rt2": 0.0, 

209 "ow1": 1.0345, 

210 "ow2": 0.0, 

211 "gf1": 1.0276, 

212 "gf2": 0.0, 

213 "win1": 0.17, 

214 "win2": 0.0, 

215 "door": 0.009, 

216 }, 

217 (1999, 2006): { 

218 "rt1": 0.8054, 

219 "rt2": 0.0, 

220 "ow1": 0.7852, 

221 "ow2": 0.0, 

222 "gf1": 0.6040, 

223 "gf2": 0.0, 

224 "win1": 0.1839, 

225 "win2": 0.0, 

226 "door": 0.009, 

227 }, 

228 (1979, 1998): { 

229 "rt1": 1.1721, 

230 "rt2": 0.0, 

231 "ow1": 1.0164, 

232 "ow2": 0.0, 

233 "gf1": 1.0000, 

234 "gf2": 0.0, 

235 "win1": 0.2025, 

236 "win2": 0.0, 

237 "door": 0.009, 

238 }, 

239 (1973, 1978): { 

240 "rt1": 1.1197, 

241 "rt2": 0.0, 

242 "ow1": 0.6154, 

243 "ow2": 0.2137, 

244 "gf1": 1.0085, 

245 "gf2": 0.0, 

246 "win1": 0.1906, 

247 "win2": 0.0, 

248 "door": 0.009, 

249 }, 

250 (1961, 1972): { 

251 "rt1": 1.1765, 

252 "rt2": 0.0, 

253 "ow1": 0.7908, 

254 "ow2": 0.0, 

255 "gf1": 1.0458, 

256 "gf2": 0.0, 

257 "win1": 0.2203, 

258 "win2": 0.0, 

259 "door": 0.009, 

260 }, 

261 (1951, 1960): { 

262 "rt1": 1.1778, 

263 "rt2": 0.0, 

264 "ow1": 1.1222, 

265 "ow2": 0.0, 

266 "gf1": 1.1778, 

267 "gf2": 0.0, 

268 "win1": 0.3133, 

269 "win2": 0.0, 

270 "door": 0.009, 

271 }, 

272 (1931, 1950): { 

273 "rt1": 0.7479, 

274 "rt2": 0.0, 

275 "ow1": 0.6891, 

276 "ow2": 0.2269, 

277 "gf1": 0.7395, 

278 "gf2": 0.0, 

279 "win1": 0.1824, 

280 "win2": 0.0, 

281 "door": 0.009, 

282 }, 

283 (1851, 1930): { 

284 "rt1": 0.9895, 

285 "rt2": 0.0, 

286 "ow1": 1.0316, 

287 "ow2": 0.0, 

288 "gf1": 0.6947, 

289 "gf2": 0.0, 

290 "win1": 0.1589, 

291 "win2": 0.0, 

292 "door": 0.009, 

293 }, 

294 (0, 1850): { 

295 "rt1": 1.1742, 

296 "rt2": 0.0, 

297 "ow1": 1.1061, 

298 "ow2": 0.0, 

299 "gf1": 0.9621, 

300 "gf2": 0.0, 

301 "win1": 0.2045, 

302 "win2": 0.0, 

303 "door": 0.009, 

304 }, 

305 } 

306 

307 self.building_age_group = None 

308 

309 if self.with_ahu is True: 

310 self.central_ahu.profile_temperature = ( 

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

312 ) 

313 self.central_ahu.profile_min_relative_humidity = 24 * [0.45] 

314 self.central_ahu.profile_max_relative_humidity = 24 * [0.55] 

315 self.central_ahu.profile_v_flow = 7 * [0.0] + 12 * [1.0] + 5 * [0.0] 

316 

317 def _check_year_of_construction(self): 

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

319 

320 for key in self.facade_estimation_factors: 

321 if ( 

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

323 or self.year_of_construction == key[1] 

324 ): 

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

326 

327 if self.building_age_group is None: 

328 raise RuntimeError( 

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

330 ) 

331 

332 def generate_archetype(self): 

333 """Generates a SingleFamilyHouse archetype buildings 

334 

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

336 Tabula Single Family House. 

337 """ 

338 self.thermal_zones = None 

339 self._check_year_of_construction() 

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

341 type_bldg_area = self.net_leased_area 

342 self.net_leased_area = 0.0 

343 

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

345 zone = ThermalZone(parent=self) 

346 zone.name = key 

347 zone.area = type_bldg_area * value[0] 

348 try: 

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

350 except (KeyError, IndexError): 

351 pass 

352 try: 

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

354 except (KeyError, IndexError): 

355 pass 

356 use_cond = UseCond(parent=zone) 

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

358 zone.use_conditions = use_cond 

359 

360 zone.use_conditions.with_ahu = False 

361 zone.use_conditions.persons *= zone.area * 0.01 

362 zone.use_conditions.machines *= zone.area * 0.01 

363 

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

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

366 for zone in self.thermal_zones: 

367 outer_wall = OuterWall(zone) 

368 outer_wall.load_type_element( 

369 year=self.year_of_construction, 

370 construction=self._construction_data_1, 

371 data_class=self.parent.data, 

372 ) 

373 outer_wall.name = key 

374 outer_wall.tilt = value[0] 

375 outer_wall.orientation = value[1] 

376 outer_wall.area = ( 

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

378 * zone.area 

379 ) / len(self._outer_wall_names_1) 

380 

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

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

383 for zone in self.thermal_zones: 

384 outer_wall = OuterWall(zone) 

385 outer_wall.load_type_element( 

386 year=self.year_of_construction, 

387 construction=self._construction_data_2, 

388 data_class=self.parent.data, 

389 ) 

390 outer_wall.name = key 

391 outer_wall.tilt = value[0] 

392 outer_wall.orientation = value[1] 

393 outer_wall.area = ( 

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

395 * zone.area 

396 ) / len(self._outer_wall_names_2) 

397 

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

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

400 for zone in self.thermal_zones: 

401 window = Window(zone) 

402 window.load_type_element( 

403 self.year_of_construction, 

404 construction=self._construction_data_1, 

405 data_class=self.parent.data, 

406 ) 

407 window.name = key 

408 window.tilt = value[0] 

409 window.orientation = value[1] 

410 window.area = ( 

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

412 * zone.area 

413 ) / len(self.window_names_1) 

414 

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

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

417 for zone in self.thermal_zones: 

418 window = Window(zone) 

419 window.load_type_element( 

420 self.year_of_construction, 

421 construction=self._construction_data_2, 

422 data_class=self.parent.data, 

423 ) 

424 window.name = key 

425 window.tilt = value[0] 

426 window.orientation = value[1] 

427 window.area = ( 

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

429 * zone.area 

430 ) / len(self.window_names_2) 

431 

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

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

434 

435 for zone in self.thermal_zones: 

436 gf = GroundFloor(zone) 

437 gf.load_type_element( 

438 year=self.year_of_construction, 

439 construction=self._construction_data_1, 

440 data_class=self.parent.data, 

441 ) 

442 gf.name = key 

443 gf.tilt = value[0] 

444 gf.orientation = value[1] 

445 gf.area = ( 

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

447 * zone.area 

448 ) / len(self.ground_floor_names_1) 

449 

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

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

452 

453 for zone in self.thermal_zones: 

454 gf = GroundFloor(zone) 

455 gf.load_type_element( 

456 year=self.year_of_construction, 

457 construction=self._construction_data_2, 

458 data_class=self.parent.data, 

459 ) 

460 gf.name = key 

461 gf.tilt = value[0] 

462 gf.orientation = value[1] 

463 gf.area = ( 

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

465 * zone.area 

466 ) / len(self.ground_floor_names_2) 

467 

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

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

470 

471 for zone in self.thermal_zones: 

472 rt = Rooftop(zone) 

473 rt.load_type_element( 

474 year=self.year_of_construction, 

475 construction=self._construction_data_1, 

476 data_class=self.parent.data, 

477 ) 

478 rt.name = key 

479 rt.tilt = value[0] 

480 rt.orientation = value[1] 

481 rt.area = ( 

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

483 * zone.area 

484 ) / len(self.roof_names_1) 

485 

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

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

488 

489 for zone in self.thermal_zones: 

490 rt = Rooftop(zone) 

491 rt.load_type_element( 

492 year=self.year_of_construction, 

493 construction=self._construction_data_2, 

494 data_class=self.parent.data, 

495 ) 

496 rt.name = key 

497 rt.tilt = value[0] 

498 rt.orientation = value[1] 

499 rt.area = ( 

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

501 * zone.area 

502 ) / len(self.roof_names_2) 

503 

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

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

506 

507 for zone in self.thermal_zones: 

508 door = Door(zone) 

509 door.load_type_element( 

510 year=self.year_of_construction, 

511 construction=self._construction_data_1, 

512 data_class=self.parent.data, 

513 ) 

514 door.name = key 

515 door.tilt = value[0] 

516 door.orientation = value[1] 

517 door.area = ( 

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

519 * zone.area 

520 ) / len(self.door_names) 

521 

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

523 

524 for zone in self.thermal_zones: 

525 inner_wall = InnerWall(zone) 

526 inner_wall.load_type_element( 

527 year=self.year_of_construction, 

528 construction="tabula_dk_standard", 

529 data_class=self.parent.data, 

530 ) 

531 inner_wall.name = key 

532 inner_wall.tilt = value[0] 

533 inner_wall.orientation = value[1] 

534 

535 if self.number_of_floors > 1: 

536 

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

538 

539 for zone in self.thermal_zones: 

540 ceiling = Ceiling(zone) 

541 ceiling.load_type_element( 

542 year=self.year_of_construction, 

543 construction="tabula_dk_standard", 

544 data_class=self.parent.data, 

545 ) 

546 ceiling.name = key 

547 ceiling.tilt = value[0] 

548 ceiling.orientation = value[1] 

549 

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

551 

552 for zone in self.thermal_zones: 

553 floor = Floor(zone) 

554 floor.load_type_element( 

555 year=self.year_of_construction, 

556 construction="tabula_dk_standard", 

557 data_class=self.parent.data, 

558 ) 

559 floor.name = key 

560 floor.tilt = value[0] 

561 floor.orientation = value[1] 

562 

563 for zone in self.thermal_zones: 

564 zone.set_inner_wall_area() 

565 zone.set_volume_zone() 

566 

567 @property 

568 def construction_data(self): 

569 return self._construction_data 

570 

571 @construction_data.setter 

572 def construction_data(self, value): 

573 self._construction_data = datahandling.check_construction_data_setter_tabula_dk(value)