Source code for teaser.logic.buildingobjects.buildingphysics.buildingelement

"""This module contains the Base class for all building elements."""

from __future__ import division
from teaser.logic.buildingobjects.buildingphysics.layer import Layer
import teaser.data.input.buildingelement_input_json as buildingelement_input
import numpy as np
import random
import re


[docs] class BuildingElement(object): """Building element class. This is the base class for all building elements. Building elements are all physical elements that may serve as boundaries for a thermal zone or building. Parameters ---------- parent : ThermalZone() The parent class of this object, the ThermalZone the BE belongs to. Allows for better control of hierarchical structures. Default is None. Attributes ---------- internal_id : float Random id for the distinction between different elements. name : str Individual name construction_data : str Type of construction (e.g. "heavy" or "light"). Needed for distinction between different constructions types in the same building age period. year_of_retrofit : int Year of last retrofit year_of_construction : int Year of first construction building_age_group : list Determines the building age period that this building element belongs to [begin, end], e.g. [1984, 1994] area : float [m2] Area of building element tilt : float [degree] Tilt against horizontal orientation : float [degree] Azimuth direction of building element (0 : north, 90: east, 180: south, 270: west) inner_convection : float [W/(m2*K)] Constant heat transfer coefficient of convection inner side (facing the zone) inner_radiation : float [W/(m2*K)] Constant heat transfer coefficient of radiation inner side (facing the zone) outer_convection : float [W/(m2*K)] Constant heat transfer coefficient of convection outer side (facing the ambient or adjacent zone). Currently for all InnerWalls and GroundFloors this value is set to 0.0 outer_radiation : float [W/(m2*K)] Constant heat transfer coefficient of radiation outer side (facing the ambient or adjacent zone). Currently for all InnerWalls and GroundFloors this value is set to 0.0 layer : list List of all layers of a building element (to be filled with Layer objects). Use element.layer = None to delete all layers of the building element Calculated Attributes r1 : float [K/W] equivalent resistance R1 of the analogous model given in VDI 6007 r2 : float [K/W] equivalent resistance R2 of the analogous model given in VDI 6007 r3 : float [K/W] equivalent resistance R3 of the analogous model given in VDI 6007 c1 : float [J/K] equivalent capacity C1 of the analogous model given in VDI 6007 c2 : float [J/K] equivalent capacity C2 of the analogous model given in VDI 6007 c1_korr : float [J/K] corrected capacity C1,korr for building elements in the case of asymmetrical thermal load given in VDI 6007 u_value : float [W/m2K) U-Value of building element ua_value : float [W/K] UA-Value of building element (Area times U-Value) r_inner_conv : float [K/W] Convective resistance of building element on inner side (facing the zone) r_inner_rad : float [K/W] Radiative resistance of building element on inner side (facing the zone) r_inner_comb : float [K/W] Combined convective and radiative resistance of building element on inner side (facing the zone) r_outer_conv : float [K/W] Convective resistance of building element on outer side (facing the ambient or adjacent zone). Currently for all InnerWalls and GroundFloors this value is set to 0.0 r_outer_rad : float [K/W] Radiative resistance of building element on outer side (facing the ambient or adjacent zone). Currently for all InnerWalls and GroundFloors this value is set to 0.0 r_outer_comb : float [K/W] Combined convective and radiative resistance of building element on outer side (facing the ambient or adjacent zone). Currently for all InnerWalls and GroundFloors this value is set to 0.0 wf_out : float Weightfactor of building element ua_value/ua_value_zone """ def __init__(self, parent=None): """Constructor for BuildingElement """ self.parent = parent self.internal_id = random.random() self.name = None self._construction_data = None self._year_of_retrofit = None self._year_of_construction = None self.building_age_group = [None, None] self._area = None self._tilt = None self._orientation = None self._inner_convection = None self._inner_radiation = None self._outer_convection = None self._outer_radiation = None self._layer = [] self.r1 = 0.0 self.r2 = 0.0 self.r3 = 0.0 self.c1 = 0.0 self.c2 = 0.0 self.c1_korr = 0.0 self.ua_value = 0.0 self.r_conduc = 0.0 self.r_inner_conv = 0.0 self.r_inner_rad = 0.0 self.r_inner_comb = 0.0 self.r_outer_conv = 0.0 self.r_outer_rad = 0.0 self.r_outer_comb = 0.0 self.wf_out = 0.0
[docs] def calc_ua_value(self): """U*A value for building element. Calculates the U*A value and resistances for radiative and convective heat transfer of a building element. """ self.ua_value = 0.0 self.r_conduc = 0.0 self.r_inner_conv = 0.0 self.r_inner_rad = 0.0 self.r_inner_comb = 0.0 self.r_outer_conv = 0.0 self.r_outer_rad = 0.0 self.r_outer_comb = 0.0 r_conduc = 0.0 for count_layer in self.layer: r_conduc += ( count_layer.thickness / count_layer.material.thermal_conduc) \ self.r_conduc = r_conduc * (1 / self.area) self.r_inner_conv = (1 / self.inner_convection) * (1 / self.area) self.r_inner_rad = (1 / self.inner_radiation) * (1 / self.area) self.r_inner_comb = 1 / (1 / self.r_inner_conv + 1 / self.r_inner_rad) if self.outer_convection is not None \ and self.outer_radiation is not None: self.r_outer_conv = (1 / self.outer_convection) * (1 / self.area) self.r_outer_rad = (1 / self.outer_radiation) * (1 / self.area) self.r_outer_comb = 1 / \ (1 / self.r_outer_conv + 1 / self.r_outer_rad) self.ua_value = (1 / ( self.r_inner_comb + self.r_conduc + self.r_outer_comb)) self.u_value = self.ua_value / self.area
[docs] def gather_element_properties(self): """Helper function for matrix calculation. Gathers all material properties of the building element and returns them as a np.array. Needed for the calculation of the matrix in equivalent_res(t_bt) especially for walls. Returns ------- number_of_layer : int number of layer (length of layer list) density : np.array Numpy array with length of number of layer, filled with density of each layer thermal_conduc : np.array Numpy array with length of number of layer, filled with thermal_conduc of each layer heat_capac : np.array Numpy array with length of number of layer, filled with heat_capac of each layer thickness : np.array Numpy array with length of number of layer, filled with thickness of each layer """ number_of_layer = len(self.layer) density = np.zeros(number_of_layer) thermal_conduc = np.zeros(number_of_layer) heat_capac = np.zeros(number_of_layer) thickness = np.zeros(number_of_layer) for i in range(number_of_layer): density[i] = self.layer[i].material.density thermal_conduc[i] = self.layer[i].material.thermal_conduc heat_capac[i] = self.layer[i].material.heat_capac thickness[i] = self.layer[i].thickness return number_of_layer, density, thermal_conduc, heat_capac, thickness
[docs] def add_layer(self, layer, position=None): """Adds a layer at a certain position This function adds a Layer instance to the layer list at a given position Parameters ---------- layer : instance of Layer Layer instance of TEASER position : int position in the wall starting from 0 (inner side) """ ass_error_1 = "Layer has to be an instance of Layer()" assert isinstance(layer, Layer), ass_error_1 if position is None: self._layer.append(layer) else: self._layer.insert(position, layer)
[docs] def add_layer_list(self, layer_list): """Appends a layer set to the layer list The layer list has to be in correct order Parameters ---------- layer_list : list list of sorted TEASER Layer instances """ ass_error_1 = "Layer has to be an instance of Layer()" for lay_count in layer_list: assert isinstance(lay_count, Layer), ass_error_1 self._layer.append(lay_count)
[docs] def load_type_element( self, year, construction, data_class=None): """Typical element loader. Loads typical building elements according to their construction year and their construction type from a json. This function will only work if the parents to Building are set. Parameters ---------- year : int Year of construction construction : str Construction type, code list ('heavy', 'light') data_class : DataClass() DataClass containing the bindings for TypeBuildingElement and Material (typically this is the data class stored in prj.data, but the user can individually change that. Default is self.parent.parent.parent.data (which is data_class in current project) """ if data_class is None: data_class = self.parent.parent.parent.data else: data_class = data_class self.layer = None self._inner_convection = None self._inner_radiation = None self._outer_convection = None self._outer_radiation = None buildingelement_input.load_type_element(element=self, year=year, construction=construction, data_class=data_class)
[docs] def save_type_element(self, data_class=None): """Typical element saver. Saves typical building elements according to their construction year and their construction type in the the json file for type building elements. If the Project parent is set, it automatically saves it to the file given in Project.data. Alternatively you can specify a path to a file of TypeBuildingElements. If this file does not exist, a new file is created. Parameters ---------- data_class : DataClass() DataClass containing the bindings for TypeBuildingElement and Material (typically this is the data class stored in prj.data, but the user can individually change that. Default is self.parent.parent.parent.data (which is data_class in current project) """ if data_class is None: data_class = self.parent.parent.parent.data else: data_class = data_class import teaser.data.output.buildingelement_output as \ buildingelement_output buildingelement_output.save_type_element(element=self, data_class=data_class)
[docs] def delete_type_element(self, data_class=None): """Deletes typical element. Deletes typical building elements according to their construction year and their construction type in the the json file for type building elements. If the Project parent is set, it automatically saves it to the file given in Project.data. Alternatively you can specify a path to a file of TypeBuildingElements. If this file does not exist, a new file is created. Parameters ---------- data_class : DataClass() DataClass containing the bindings for TypeBuildingElement and Material (typically this is the data class stored in prj.data, but the user can individually change that. Default is self.parent.parent.parent.data (which is data_class in current project) """ if data_class is None: data_class = self.parent.parent.parent.data else: data_class = data_class import teaser.data.output.buildingelement_output as \ buildingelement_output buildingelement_output.delete_type_element(element=self, data_class=data_class)
[docs] def set_calc_default(self): """Sets all calculated values of the Building Element to zero """ self.r1 = 0.0 self.r2 = 0.0 self.r3 = 0.0 self.c1 = 0.0 self.c2 = 0.0 self.c1_korr = 0.0 self.ua_value = 0.0 self.r_conduc = 0.0 self.r_inner_conv = 0.0 self.r_inner_rad = 0.0 self.r_inner_comb = 0.0 self.r_outer_conv = 0.0 self.r_outer_rad = 0.0 self.r_outer_comb = 0.0
@property def name(self): return self._name @name.setter def name(self, value): if isinstance(value, str): if value: regex = re.compile('[^a-zA-z0-9]') self._name = regex.sub('', value) if self._name == "None": self._name = "BuildinElement" + str( random.randint(1, 500000)) elif value is None: self._value = "BuildinElement" + str(random.randint(1, 500000)) else: try: value = str(value) regex = re.compile('[^a-zA-z0-9]') self._name = regex.sub('', value) except ValueError: print("Can't convert name to string") @property def year_of_retrofit(self): return self._year_of_retrofit @year_of_retrofit.setter def year_of_retrofit(self, value): if isinstance(value, int): pass elif value is None: pass else: try: value = int(value) except: raise ValueError("Can't convert year of retrofit to float") if value is not None: if self.year_of_construction is not None: self._year_of_retrofit = value else: raise ValueError("Specify year of construction first") @property def orientation(self): return self._orientation @orientation.setter def orientation(self, value): self._orientation = value if type(self).__name__ == "OuterWall": if (self.parent is not None and self.parent.parent is not None and self.area is not None): self.parent.parent.fill_outer_area_dict() elif type(self).__name__ == "Window": if (self.parent is not None and self.parent.parent is not None and self.area is not None): self.parent.parent.fill_window_area_dict() @property def layer(self): return self._layer @layer.setter def layer(self, value): if value is None: self._layer = [] if self.inner_convection is not None and\ self.inner_radiation is not None and\ self.area is not None: self.calc_ua_value() @property def inner_convection(self): return self._inner_convection @inner_convection.setter def inner_convection(self, value): if isinstance(value, float): pass elif value is None: pass else: try: value = float(value) except: raise ValueError("Can't convert inner convection to float") if value is not None: self._inner_convection = value if self.inner_convection is not None and\ self.inner_radiation is not None and\ self.area is not None: self.calc_ua_value() @property def inner_radiation(self): return self._inner_radiation @inner_radiation.setter def inner_radiation(self, value): if isinstance(value, float): pass elif value is None: pass else: try: value = float(value) except: raise ValueError("Can't convert inner radiation to float") if value is not None: self._inner_radiation = value if self.inner_convection is not None and\ self.inner_radiation is not None and\ self.area is not None: self.calc_ua_value() @property def outer_convection(self): return self._outer_convection @outer_convection.setter def outer_convection(self, value): if isinstance(value, float): pass elif value is None: pass else: try: value = float(value) except: raise ValueError("Can't convert outer convection to float") if value is not None: self._outer_convection = value if self.inner_convection is not None and\ self.inner_radiation is not None and\ self.area is not None: self.calc_ua_value() @property def outer_radiation(self): return self._outer_radiation @outer_radiation.setter def outer_radiation(self, value): if isinstance(value, float): pass elif value is None: pass else: try: value = float(value) except: raise ValueError("Can't convert outer radiation to float") if value is not None: self._outer_radiation = value if self.inner_convection is not None and\ self.inner_radiation is not None and\ self.area is not None: self.calc_ua_value() @property def area(self): return self._area @area.setter def area(self, value): if isinstance(value, float): pass elif value is None: pass else: try: value = float(value) except: raise ValueError("Can't convert element area to float") if value is not None: self._area = value if type(self).__name__ == "OuterWall"\ or type(self).__name__ == "Rooftop" \ or type(self).__name__ == "GroundFloor": if (self.parent is not None and self.parent.parent is not None and self.orientation is not None): self.parent.parent.fill_outer_area_dict() elif type(self).__name__ == "Window": if self.parent is not None and self.orientation is not None: self.parent.parent.fill_window_area_dict() if self.inner_convection is not None and\ self.inner_radiation is not None and\ self.area is not None: self.calc_ua_value() @property def tilt(self): return self._tilt @tilt.setter def tilt(self, value): if isinstance(value, float): self._tilt = value elif value is None: self._tilt = value else: try: value = float(value) self._tilt = value except: raise ValueError("Can't convert tilt to float") @property def year_of_construction(self): return self._year_of_construction @year_of_construction.setter def year_of_construction(self, value): if isinstance(value, float): self._year_of_construction = value elif value is None: self._year_of_construction = value else: try: value = int(value) self._year_of_construction = value except: raise ValueError("Can't convert year to int") @property def construction_data(self): return self._construction_data @construction_data.setter def construction_data(self, value): self._construction_data = value