Source code for honeybee_energy.ventcool.simulation

# coding=utf-8
"""Definitions for global parameters used in the ventilation simulation."""
from __future__ import division
import math

from ladybug_geometry.bounding import bounding_box_extents

from honeybee._lockable import lockable
from honeybee.typing import float_in_range, float_positive, float_in_range_excl_incl


[docs] @lockable class VentilationSimulationControl(object): """Global parameters used to specify the simulation of air flow. Args: vent_control_type: Text indicating type of ventilation control. Choose from the following: * SingleZone * MultiZoneWithDistribution * MultiZoneWithoutDistribution The MultiZone options will model air flow with the AirflowNetwork model, which is generally more accurate then the SingleZone option, but will take considerably longer to simulate, and requires defining more ventilation parameters to explicitly account for weather and building-induced pressure differences, and the leakage geometry corresponding to specific windows, doors, and surface cracks (Default: 'SingleZone'). reference_temperature: Reference temperature measurement in Celsius under which the surface crack data were obtained. This is only used for AFN simulations, when vent_control_type is NOT SingleZone. (Default: 20). reference_pressure: Reference barometric pressure measurement in Pascals under which the surface crack data were obtained. This is only used for AFN simulations, when vent_control_type is NOT SingleZone.(Default: 101325). reference_humidity_ratio: Reference humidity ratio measurement in kgWater/kgDryAir under which the surface crack data were obtained. This is only used for AFN simulations, when vent_control_type is NOT SingleZone. (Default: 0). building_type: Text indicating relationship between building footprint and height. Choose from the following: * LowRise * HighRise LowRise corresponds to a building where the height is less then three times the width AND length of the footprint. HighRise corresponds to a building where height is more than three times the width OR length of the footprint. This parameter is used to estimate building-wide wind pressure coefficients for the AFN by approximating the building geometry as an extruded rectangle. This property can be auto-calculated from Honeybee Room geometry with the geometry_properties_from_rooms method. (Default: 'LowRise'). long_axis_angle: A number between 0 and 180 for the clockwise angle difference in degrees that the long axis of the building is from true North. This parameter is used to estimate building-wide wind pressure coefficients for the AFN by approximating the building geometry as an extruded rectangle. 0 indicates a North-South long axis while 90 indicates an East-West long axis. (Default: 0). aspect_ratio: A number between 0 and 1 for the aspect ratio of the building's footprint, defined as the ratio of length of the short axis divided by the length of the long axis. This parameter is used to estimate building-wide wind pressure coefficients for the AFN by approximating the building geometry as an extruded rectangle (Default: 1). Properties: * vent_control_type * reference_temperature * reference_pressure * reference_humidity_ratio * building_type * long_axis_angle * aspect_ratio """ __slots__ = ('_vent_control_type', '_reference_temperature', '_reference_pressure', '_reference_humidity_ratio', '_building_type', '_long_axis_angle', '_aspect_ratio', '_locked') VENT_CONTROL_TYPES = ('SingleZone', 'MultiZoneWithDistribution', 'MultiZoneWithoutDistribution') BUILDING_TYPES = ('LowRise', 'HighRise') def __init__(self, vent_control_type='SingleZone', reference_temperature=20, reference_pressure=101325, reference_humidity_ratio=0, building_type='LowRise', long_axis_angle=0, aspect_ratio=1): """Initialize VentilationSimulationControl.""" self.vent_control_type = vent_control_type self.reference_temperature = reference_temperature self.reference_pressure = reference_pressure self.reference_humidity_ratio = reference_humidity_ratio self.building_type = building_type self.long_axis_angle = long_axis_angle self.aspect_ratio = aspect_ratio @property def vent_control_type(self): """Get or set text indicating type of ventilation control type.""" return self._vent_control_type @vent_control_type.setter def vent_control_type(self, value): assert value in self.VENT_CONTROL_TYPES, 'vent_control_type {} is not '\ 'recognized.\nChoose from the following:\n{}'.format( value, self.VENT_CONTROL_TYPES) self._vent_control_type = value @property def reference_temperature(self): """Get or set the temperature for the reference crack.""" return self._reference_temperature @reference_temperature.setter def reference_temperature(self, value): self._reference_temperature = \ float_in_range(value, mi=-273.15, input_name='reference_temperature') @property def reference_pressure(self): """Get or set the barometric pressure for the reference crack.""" return self._reference_pressure @reference_pressure.setter def reference_pressure(self, value): self._reference_pressure = \ float_in_range(value, 31000, 120000, 'reference_pressure') @property def reference_humidity_ratio(self): """Get or set the humidity ratio for the reference crack.""" return self._reference_humidity_ratio @reference_humidity_ratio.setter def reference_humidity_ratio(self, value): self._reference_humidity_ratio = \ float_positive(value, 'reference_humidity_ratio') @property def building_type(self): """Get or set text indicating whether the building is high or low rise.""" return self._building_type @building_type.setter def building_type(self, value): assert value in self.BUILDING_TYPES, 'building_type {} is not '\ 'recognized.\nChoose from the following:\n{}'.format( value, self.BUILDING_TYPES) self._building_type = value @property def long_axis_angle(self): """Get or set a number between 0 and 180 for the building long axis angle. The value represents the clockwise difference between the long axis and true North. 0 indicates a North-South long axis while 90 indicates an East-West long axis. """ return self._long_axis_angle @long_axis_angle.setter def long_axis_angle(self, value): self._long_axis_angle = float_in_range(value, 0, 180, 'long_axis_angle') @property def aspect_ratio(self): """Get or set a number between 0 and 1 for the building footprint aspect ratio. """ return self._aspect_ratio @aspect_ratio.setter def aspect_ratio(self, value): self._aspect_ratio = float_in_range_excl_incl(value, 0, 1, 'aspect_ratio')
[docs] def assign_geometry_properties_from_rooms(self, rooms): """Assign the geometry properties of this object using an array of Honeybee Rooms. The building_type (HighRise or LowRise) will be determined by analyzing the bounding box around the Rooms (assessing whether the box is taller than it is wide + long). This object's long_axis_angle will be used to orient the bounding box and compute the aspect ratio of the footprint. If the length of what should be the short axis ends up being longer than the other axis, this object's long_axis_angle will be rotated 90 degrees in order to keep the aspect ratio from being greater than 1. Args: rooms: An array of Honeybee Rooms, which will have their geometry collectively analyzed in order to set the geometry properties of this object. Typically, this should be all of the Rooms of a Honeybee Model. """ l_axis = self.long_axis_angle bldg_type, aspect_r = self.geometry_properties_from_rooms(rooms, l_axis) self.building_type = bldg_type if aspect_r > 1: # rotate the long axis 90 degrees aspect_r = 1 / aspect_r self.long_axis_angle = l_axis + 90 if l_axis < 90 else l_axis - 90 self.aspect_ratio = aspect_r
[docs] @classmethod def from_dict(cls, data): """Create a VentilationSimulationControl object from a dictionary. Args: data: A VentilationSimulationControl dictionary following the format below. .. code-block:: python { "type": "VentilationSimulationControl" "vent_control_type": SingleZone # type of ventilation control "reference_temperature": 20 # reference crack temperature "reference_pressure": 101320 # reference crack barometric pressure "reference_humidity_ratio": 0.5 # reference crack humidity ratio "building_type": 'LowRise' # building type text "long_axis_angle": 0 # angle of building low axis "aspect_ratio": 1 # aspect ratio of building footprint } """ assert data['type'] == 'VentilationSimulationControl', 'Expected ' \ 'VentilationSimulationControl dictionary. Got {}.'.format(data['type']) vent_control_type = data['vent_control_type'] if 'vent_control_type' in data \ and data['vent_control_type'] is not None else 'SingleZone' ref_temp = data['reference_temperature'] if 'reference_temperature' in data \ and data['reference_temperature'] is not None else 20 ref_pres = data['reference_pressure'] if \ 'reference_pressure' in data and \ data['reference_pressure'] is not None else 101320 ref_hum = data['reference_humidity_ratio'] if 'reference_humidity_ratio' in \ data and data['reference_humidity_ratio'] is not None else 0 bld_type = data['building_type'] if 'building_type' in data and \ data['building_type'] is not None else 'LowRise' axis = data['long_axis_angle'] if 'long_axis_angle' in data and \ data['long_axis_angle'] is not None else 0 ratio = data['aspect_ratio'] if 'aspect_ratio' in data and data['aspect_ratio'] \ is not None else 1 return cls(vent_control_type, ref_temp, ref_pres, ref_hum, bld_type, axis, ratio)
[docs] def to_dict(self): """VentilationSimulationControl dictionary representation.""" base = {'type': 'VentilationSimulationControl'} base['vent_control_type'] = self.vent_control_type base['reference_temperature'] = self.reference_temperature base['reference_pressure'] = self.reference_pressure base['reference_humidity_ratio'] = self.reference_humidity_ratio base['building_type'] = self.building_type base['long_axis_angle'] = self.long_axis_angle base['aspect_ratio'] = self.aspect_ratio return base
[docs] def duplicate(self): """Get a copy of this object.""" return self.__copy__()
[docs] @staticmethod def geometry_properties_from_rooms(rooms, axis_angle=0): """Get AFN building geometry properties from an array of Honeybee Rooms. Args: rooms: An array of Honeybee Rooms, which will have their geometry collectively analyzed. axis_angle: The clockwise rotation angle in degrees in the XY plane to represent the orientation of the bounding box. (Default: 0). Returns: A tuple with 2 values for geometry properties. 1) Text indicating the building_type (either Highrise or LowRise) 2) A number for the aspect ratio of the axis_angle-oriented bounding box. Note that the aspect ratio may be greater than 1 if the axis_angle isn't aligned to the long axis of the geometry. """ # process the inputs to be suitable for ladybug_geometry if axis_angle != 0: # convert to counter-clockwise radians for ladybug_geometry axis_angle = -math.radians(axis_angle) geo = [room.geometry for room in rooms] # get ladybug_geometry polyfaces # get the bounding box and return the properties xx, yy, zz = bounding_box_extents(geo) bldg_type = 'LowRise' if zz <= 3 * max(xx, yy) else 'HighRise' return bldg_type, xx / yy
def __copy__(self): return VentilationSimulationControl( self.vent_control_type, self.reference_temperature, self.reference_pressure, self.reference_humidity_ratio, self.building_type, self.long_axis_angle, self.aspect_ratio) def __key(self): """A tuple based on the object properties, useful for hashing.""" return (self.vent_control_type, self.reference_temperature, self.reference_pressure, self.reference_humidity_ratio, self.building_type, self.long_axis_angle, self.aspect_ratio) def __hash__(self): return hash(self.__key()) def __eq__(self, other): return isinstance(other, VentilationSimulationControl) and \ self.__key() == other.__key() def __ne__(self, other): return not self.__eq__(other)
[docs] def ToString(self): """Overwrite .NET ToString.""" return self.__repr__()
def __repr__(self): return 'VentilationSimulationControl: [control type: {}] ' \ '[building_type: {}] [long axis: {}] [aspect_ratio: {}]' .format( self.vent_control_type, self.building_type, round(self.long_axis_angle), round(self.aspect_ratio, 2))