def categorize_residential_building(self): """ Categorizes building according to TABULA typologies. Construction year class and building type are calculated by comparing the residential building ground floor area (gfa) with the GFA of typical buildings (from TABULA). Values are adapted to building stock statistics. returns: self.class_year <tuple> (int, str) self.btype <tuple> (int, str) """ gfa = self.env_areas[2] # get size of GFA matrix rows = len(self.GFA) # construction year class cols = len(self.GFA[0]) # building type # initialize distance vectors distance = np.zeros(rows * cols) distance_inv = np.zeros(rows * cols) row_col = [[] for _ in range(rows * cols)] t_distance_inv = 0 kkk = 0 # calculate inverse of distances # 1/d is used so that the minimum distance has a higher probability for iii in range(0, rows): for jjj in range(0, cols): distance[kkk] = abs(self.GFA[iii][jjj] - gfa) + 0.01 # "+ 0.001" to avoid having x/0 distance_inv[kkk] = (1.0 / distance[kkk]) * self.STOCK_RES[iii, jjj] row_col[kkk] = [iii, jjj] t_distance_inv += distance_inv[kkk] kkk += 1 # normalize inverse distance norm_distance = distance_inv / t_distance_inv # get cumulative density function cdf = np.cumsum(norm_distance) # generate random number rnd = np.random.uniform(0, 1, 1) # check random number with cdf index = np.argmax(rnd < cdf) # Construction year class self.year_class = UrbanHeatPro.year_class_to_tuple(self.use[0], row_col[index][0]) # Building type self.btype = UrbanHeatPro.building_type_to_tuple(self.use[0], row_col[index][1])
def categorize_non_residential_building(self): """ int construction year class 0 < 1918 1 1919 - 1976 2 1977 - 1983 3 1984 - 1994 4 > 1995 >>> Statistics on the non-residential buildings stock are missing """ # assign random construction year class year_class_int = randint(0, 4) self.year_class = UrbanHeatPro.year_class_to_tuple(self.use[0], year_class_int) self.btype = UrbanHeatPro.building_type_to_tuple(self.use[0], self.btype_int)
def calculate_building_envelope_areas(self): """ Calculates building envelope areas (wall, roof and window) depending on the building use: Residential: areas are calculated according to building typologies in TABULA. To obtain the typology (construction year class and building type) the gfa is matched to the typology GFA. Non-residential: number of floors and window-to-wall ratio are derived from statistics and used to calculate the building areas. Construction year class is also derived from statistics. An area_correction_factor is included since not the whole floor area is heated. From VDI 3807-2. returns: self.env_areas <list> [Roof, Walls, Floor (gfa), Window] in m2 self.heated_area <float> Total building heated area """ if (self.use[0] == 3): # RESIDENTIAL # Area correction factor for calculating heated areas area_correction_factor = 0.85 # Conditioned (heated) GFA self.gfa_h = self.env_areas[2] * area_correction_factor # check if building typology is given if self.building_typology: self.year_class = UrbanHeatPro.year_class_to_tuple(self.use[0], self.year_class_int) # Construction year class (int, str) self.btype = UrbanHeatPro.building_type_to_tuple(self.use[0], self.btype_int) # Building type (int, str) else: # assign building typology from statistics # check that the building data exists as C-values are not available for all buildings building_exists = False while building_exists == False: self.categorize_residential_building() a = self.C_RES[2][self.year_class[0]][self.btype[0]] # C_floor value b = self.GFA[self.year_class[0]][self.btype[0]] if (a > 0.0 and b > 0.0): building_exists = True # Floor-to-floor height # from http://www.ctbuh.org/HighRiseInfo/TallestDatabase/Criteria/HeightCalculator/tabid/1007/language/en-GB/Default.aspx # self.f2f_height = (randint(30, 32) / 10.0) # m # from TABULA self.f2f_height = 2.5 # m # Number of floors self.floors = self.FLOORS[self.year_class[0]][self.btype[0]] * (1 + (1 - area_correction_factor)) # Building areas ### Roof self.env_areas[0] = self.ARATIO[0][self.year_class[0]][self.btype[0]] * self.gfa_h ### Wall self.env_areas[1] = self.ARATIO[1][self.year_class[0]][self.btype[0]] * self.gfa_h * self.free_walls ### Window self.env_areas[3] = self.ARATIO[2][self.year_class[0]][self.btype[0]] * self.gfa_h for j in range(4): self.window_areas[j] = self.env_areas[3] * self.WRATIO_ORIENTATION[5 * j + self.btype[0]] else: # NON-RESIDENTIAL # Area correction factor for calculating heated areas area_correction_factor = (randint(6, 8) / 10.0) # Conditioned (heated) GFA self.gfa_h = self.env_areas[2] * area_correction_factor # Construction year class self.categorize_non_residential_building() # Floor-to-floor height # from http://www.ctbuh.org/HighRiseInfo/TallestDatabase/Criteria/HeightCalculator/tabid/1007/language/en-GB/Default.aspx self.f2f_height = (randint(30, 39) / 10.0) # m # Number of floors # >>> Source missing lower_limit = 1 upper_limit = 3 self.calculate_number_of_floors(lower_limit, upper_limit) # Building areas ### Roof self.env_areas[0] = self.gfa_h ### Wall width = np.sqrt(self.gfa_h) # [m] building is assumed to be a cube self.env_areas[1] = self.free_walls * self.floors * self.f2f_height * width ### Window # >>> Add Window-to-Wall ratio for the different building types # >>> Source missing self.env_areas[3] = (randint(1, 4) / 10.0) * self.env_areas[1] # Window areas oriented to [east, south, west, north] for j in range(4): self.window_areas[j] = self.env_areas[3] * self.WRATIO_ORIENTATION[5 * j + 4] # Total heated area (reference area in TABULA) in m2 self.heated_area = self.gfa_h * self.floors # Total living space self.living_area = self.gfa_h * self.floors * (1 + (1 - area_correction_factor))