Source code for teaser.logic.buildingobjects.useconditions

"""This module contains UseConditions class."""
import random
import teaser.data.input.usecond_input as usecond_input
import teaser.data.output.usecond_output as usecond_output
import pandas as pd
from itertools import cycle, islice
from collections import OrderedDict
from teaser.logic.utilities import division_from_json


[docs]class UseConditions(object): """UseConditions class contains all zone specific boundary conditions. Class that contains the boundary conditions of use for buildings defined in DIN V 18599-10 ( :cite:`DeutschesInstitutfurNormung.2016`) and VDI 2078 (:cite:`VereinDeutscherIngenieure.2015c`). Profiles for internal gains ( persons, lighting, machines) are taken from SIA2024 ( :cite:`SwissSocietyofEngineersandArchitects.March2006`). In addition some TEASER specific use conditions have been attached to this class. The docstring also contains how the use conditions is used. Note: Most attributes description are translations from DIN V 18599-10 standard Attributes ---------- usage: str usage type AixLib usage: String to distinguish usages of a zone typical_length: float [m] typical length of a room in a usage zone. This value is taken from SIA 2024. Archetype usage: division of usage zones in rooms typical width: float [m] typical width of a usage zone. This value is taken from SIA 2024. Archetype usage: division of usage zones in rooms with_heating: boolean Sets if the zone is heated by ideal heater or not. with_cooling: boolean Sets if the zone is cooled by ideal cooler or not. with_ideal_thresholds: boolean Sets if the threshold temperatures for ideal heater and cooler are used. True = T_threshold_heating and T_threshold_cooling are used. This can, in most cases, prevent simultaneous heating from AHU and cooling from ideal heater and vice versa. This should only be turned on if an AHU exists. T_threshold_heating: float [K] Threshold for the outside temperature above which the ideal heater is permanently shut down regardless the inside temperature. Default is 15 °C which corresponds to the value for all buildings that are not built according to EnEV standard according to DIN EN 18599-5. T_threshold_cooling: float [K] Threshold for the outside temperature below which the ideal cooler is permanently shut down regardless the inside temperature. Default is 22 °C, since there are no european standards for cooling degree days this value is taken from the following paper: "Heating Degree Days, Cooling Degree Days and Precipitation in Europe —analysis for the CELECT-project" by Benestad, 2008. heating_profile : list [K] Heating setpoint, regarding the zone temperature, of ideal static heating for a day or similar. You can set a list of any length, TEASER will multiplicate this list for one whole year. cooling_profile : list [K] Cooling setpoint, regarding the zone temperature, of ideal static cooling for a day or similar. You can set a list of any length, TEASER will multiplicate this list for one whole year. fixed_heat_flow_rate_persons: float [W/person] fixed heat flow rate for one person in case of temperature independent calculation. Default value is 70 W/person and describes the maximum heat flow rate depending on the schedule. persons : float [Persons/m2] Specific number of persons per square area. Annex: Used for internal gains internal_gains_moisture_no_people : float [g/(h m²)] internal moisture production of plants, etc. except from people. activity_degree_persons : float [met] default value is 1.2 met AixLib: used for heat flow rate calculation (internal_gains_mode=1) or heat flow rate, moisture and co2 gains (internal_gains_mode=3). Both are temperature and activity degree depending, calculation based on SIA2024 (2015) and Engineering ToolBox (2004). Annex: not used, heat flow rate is constant value fixed_heat_flow_rate_persons ratio_conv_rad_persons: float describes the ratio between convective and radiative heat transfer of the persons [convective/radiative]. Default values are derived from :cite:`VereinDeutscherIngenieure.2015c`. AixLib: Used in Zone record for internal gains Annex: Used for internal gains persons_profile : list Relative presence of persons 0-1 (e.g. 0.5 means that 50% of the total number of persons are currently in the room). Given for 24h. This value is taken from SIA 2024. You can set a list of any length, TEASER will multiplicate this list for one whole year. AixLib: Used for internal gains profile on top-level Annex: Used for internal gains machines: float [W/m2] area specific eletrical load of machines per m2. This value is taken from SIA 2024 and DIN V 18599-10 for medium occupancy. AixLib: Used in Zone record for internal gains, internalGainsMachinesSpecific Annex: Used for internal gains ratio_conv_rad_machines: float describes the ratio between convective and radiative heat transfer of the machines [convective/radiative]. Default values are derived from :cite:`Davies.2004`. AixLib: Used in Zone record for internal gains Annex: Not used, all machines are convective (see Annex examples) machines_profile: list Relative presence of machines 0-1 (e.g. 0.5 means that 50% of the total number of machines are currently used in the room). Given for 24h. This value is taken from SIA 2024. You can set a list of any length, TEASER will multiplicate this list for one whole year. AixLib: Used for internal gains profile on top-level Annex: Used for internal gains lighting_power: float [W/m2] spec. electr. Power for lighting. This value is taken from SIA 2024. AixLib: Used in Zone record for internal gains Annex: Not used (see Annex examples) ratio_conv_rad_lighting : float describes the ratio between convective and radiative heat transfer of the lighting [convective/radiative]. Default values are derived from :cite:`DiLaura.2011`. AixLib: Used in Zone record for internal gains, lighting lighting_profil : [float] Relative presence of lighting 0-1 (e.g. 0.5 means that 50% of the total lighting power are currently used). Typically given for 24h. This is aligned to the user profile. AixLib: Used for internal gains profile on top-level Annex: Not used (see Annex examples) min_ahu: float [m3/(m2*h)] Zone specific minimum specific air flow supplied by the AHU. AixLib: Used on Multizone level for central AHU to determine total volume flow of each zone. - **Note**: The AixLib parameter "WithProfile" determines whether the (v_flow_profile combined with "min_ahu and max_ahu") or the (persons_profile combined with "min_ahu and max_ahu") is used for the AHU supply flow calculations. Per default: (v_flow_profile combined with "min_ahu and max_ahu") max_ahu : float [m3/(m2*h)] Zone specific maximum specific air flow supplied by the AHU. AixLib: Used on Multizone level for central AHU to determine total volume flow of each zone. - **Note**: The AixLib parameter "WithProfile" determines whether the (v_flow_profile combined with "min_ahu and max_ahu") or the (persons_profile combined with "min_ahu and max_ahu") is used for the AHU supply flow calculations. Per default: (v_flow_profile combined with "min_ahu and max_ahu") with_ahu : boolean Zone is connected to central air handling unit or not AixLib: Used on Multizone level for central AHU. use_constant_infiltration : boolean choose whether window opening should be regarded. true = natural infiltration + ventilation due to a AHU false = natural infiltration + ventilation due to a AHU + window infiltration calculated by window opening model AixLib: Used on Zone level for ventilation. base_infiltration : float [1/h] base value for the natural infiltration without window openings AixLib: Used on Zone level for ventilation. max_user_infiltration : float [1/h] Additional infiltration rate for maximum persons activity AixLib: Used on Zone level for ventilation. max_overheating_infiltration : list [1/h] Additional infiltration rate when overheating appears AixLib: Used on Zone level for ventilation. max_summer_infiltration : list Additional infiltration rate in the summer with [infiltration_rate [1/h], Tmin [K], Tmax [K]]. Default values are aligned to :cite:`DINV1859910`. AixLib: Used on Zone level for ventilation. winter_reduction_infiltration : list Reduction factor of userACH for cold weather with [infiltration_rate [1/h], Tmin [K], Tmax [K]] AixLib: Used on Zone level for ventilation. Default values are aligned to :cite:`DINV1859910`. schedules: pandas.DataFrame All time dependent boundary attributes in one pandas DataFrame, used for export (one year in hourly timestep.) Note: python attribute, not customizable by user (derived from Json) """ def __init__(self, parent=None): """Construct UseConditions.""" self.internal_id = random.random() self.parent = parent self.usage = "Single office" self.typical_length = 6.0 self.typical_width = 6.0 self.with_heating = True self.with_cooling = False self.T_threshold_heating = 288.15 self.T_threshold_cooling = 295.15 self.fixed_heat_flow_rate_persons = 70 self.activity_degree_persons = 1.2 self._persons = 1 / 14 self.internal_gains_moisture_no_people = 0.5 self.ratio_conv_rad_persons = 0.5 self.machines = 7.0 self.ratio_conv_rad_machines = 0.75 self.lighting_power = 15.9 self.ratio_conv_rad_lighting = 0.4 self.use_constant_infiltration = False self.infiltration_rate = 0.2 self.max_user_infiltration = 1.0 self.max_overheating_infiltration = [3.0, 2.0] self.max_summer_infiltration = [1.0, 273.15 + 10, 273.15 + 17] self.winter_reduction_infiltration = [0.5, 273.15, 273.15 + 10] self.min_ahu = 0.0 self.max_ahu = 2.6 self.with_ahu = False self._with_ideal_thresholds = False self._heating_profile = [ 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, ] self._cooling_profile = [ 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, 294.15, ] self._persons_profile = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.6, 0.8, 0.8, 0.4, 0.6, 0.8, 0.8, 0.4, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ] self._machines_profile = [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.4, 0.6, 0.8, 0.8, 0.4, 0.6, 0.8, 0.8, 0.4, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, ] self._lighting_profile = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ] self.schedules = pd.DataFrame( index=pd.date_range("2019-01-01 00:00:00", periods=8760, freq="H") .to_series() .dt.strftime("%m-%d %H:%M:%S"), data={ "heating_profile": list(islice(cycle(self._heating_profile), 8760)), "cooling_profile": list(islice(cycle(self._cooling_profile), 8760)), "persons_profile": list(islice(cycle(self._persons_profile), 8760)), "lighting_profile": list(islice(cycle(self._lighting_profile), 8760)), "machines_profile": list(islice(cycle(self._machines_profile), 8760)), }, )
[docs] def load_use_conditions(self, zone_usage, data_class=None): """Load typical use conditions from JSON data base. Loads Use conditions specified in the JSON. Parameters ---------- zone_usage : str code list for zone_usage according to 18599 or self defined data_class : DataClass() DataClass containing the bindings for Use Conditions (typically this is the data class stored in prj.data, but the user can individually change that. Default is None which leads to an automatic setter to self.parent.parent.parent.data ( which is DataClass in current project) """ if data_class is None: data_class = self.parent.parent.parent.data else: data_class = data_class usecond_input.load_use_conditions( use_cond=self, zone_usage=zone_usage, data_class=data_class )
[docs] def save_use_conditions(self, data_class=None): """Documentation is missing.""" if data_class is None: data_class = self.parent.parent.parent.data else: data_class = data_class usecond_output.save_use_conditions(use_cond=self, data_class=data_class)
@property def persons(self): return self._persons @persons.setter def persons(self, value): if isinstance(value, OrderedDict): self._persons = division_from_json(value) else: self._persons = value @property def with_ideal_thresholds(self): return self._with_ideal_thresholds @with_ideal_thresholds.setter def with_ideal_thresholds(self, value): if self.with_ahu is False and value is True: raise ValueError( "Threshold for ideal heaters should only be used" " when AHU is used in this zone" ) else: self._with_ideal_thresholds = value @property def heating_profile(self): return self._heating_profile @heating_profile.setter def heating_profile(self, value): if not isinstance(value, list): value = [value] self._heating_profile = value self.schedules["heating_profile"] = list(islice(cycle(value), 8760)) @property def cooling_profile(self): return self._cooling_profile @cooling_profile.setter def cooling_profile(self, value): if not isinstance(value, list): value = [value] self._cooling_profile = value self.schedules["cooling_profile"] = list(islice(cycle(value), 8760)) @property def persons_profile(self): return self._persons_profile @persons_profile.setter def persons_profile(self, value): if not isinstance(value, list): value = [value] self._persons_profile = value self.schedules["persons_profile"] = list(islice(cycle(value), 8760)) @property def machines_profile(self): return self._machines_profile @machines_profile.setter def machines_profile(self, value): if not isinstance(value, list): value = [value] self._machines_profile = value self.schedules["machines_profile"] = list(islice(cycle(value), 8760)) @property def lighting_profile(self): return self._lighting_profile @lighting_profile.setter def lighting_profile(self, value): if not isinstance(value, list): value = [value] self._lighting_profile = value self.schedules["lighting_profile"] = list(islice(cycle(value), 8760)) @property def parent(self): return self._parent @parent.setter def parent(self, value): if value is not None: ass_error_1 = "Parent has to be an instance of ThermalZone()" assert type(value).__name__ == "ThermalZone", ass_error_1 self._parent = value self._parent._use_conditions = self else: self._parent = None