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
« 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
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
19class EST1a(Residential):
20 """Archetype for Urban Fabric Type EST1a.
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`.
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:
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.
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)
68 0. no neighbour
69 1. one neighbour
70 2. two neighbours
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
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.
95 Attributes
96 ----------
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
132 """
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 """
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)
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
166 # Parameters are default values for current calculation following
167 # Hegger
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)
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]
182 self.roof_names = {"Rooftop": [0, -1]} # [0, -1]
184 self.ground_floor_names = {"Ground Floor": [0, -2]} # [0, -2]
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]
192 self.inner_wall_names = {"InnerWall": [90.0, 0.0]}
194 self.ceiling_names = {"Ceiling": [0.0, -1]}
196 self.floor_names = {"Floor": [0.0, -2]}
198 self.est_factor_win_area = 0.2
199 self.est_factor_facade_to_volume = 0.87
201 self.nr_of_orientation = len(self.outer_wall_names)
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
209 self.est_factor_neighbour = 0.0
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
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`
231 def generate_archetype(self):
232 """Generates a residential building.
234 With given values, this class generates a type residential
235 building according to TEASER requirements.
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
243 self._est_ground_floor_area = type_bldg_area / self.number_of_floors
245 self._est_roof_area = type_bldg_area / self.number_of_floors
247 self._est_win_area = self.est_factor_win_area * type_bldg_area * \
248 (1 - self._est_factor_neighbour / 4)
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)
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])
273 zone.use_conditions = use_cond
275 for key, value in self.outer_wall_names.items():
276 # North and South
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:
284 self.outer_area[value[1]] = self._est_outer_wall_area / \
285 self.nr_of_orientation
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]
296 for key, value in self.window_names.items():
298 if value[1] == 0 or value[1] == 180:
300 self.window_area[value[1]] = self._est_win_area / \
301 self.nr_of_orientation
303 elif value[1] == 90 or value[1] == 270:
305 self.window_area[value[1]] = self._est_win_area / \
306 self.nr_of_orientation
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)
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]
322 for key, value in self.roof_names.items():
324 self.outer_area[value[1]] = self._est_roof_area
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]
334 for key, value in self.ground_floor_names.items():
336 self.outer_area[value[1]] = self._est_ground_floor_area
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]
346 for key, value in self.inner_wall_names.items():
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)
357 if self.number_of_floors > 1:
359 for key, value in self.ceiling_names.items():
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)
370 for key, value in self.floor_names.items():
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
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)
388 for zone in self.thermal_zones:
389 zone.set_inner_wall_area()
390 zone.set_volume_zone()
392 @property
393 def construction_data(self):
394 return self._construction_data
396 @construction_data.setter
397 def construction_data(self, value):
398 self._construction_data = datahandling.check_construction_data_setter_iwu(value)
400 @property
401 def neighbour_buildings(self):
402 return self._neighbour_buildings
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
411 @property
412 def number_of_apartments(self):
413 return self._number_of_apartments
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