Source code for dragonfly_uwg.simulation.parameter

# coding=utf-8
"""Complete set of UWG Simulation Settings."""
from __future__ import division

from .runperiod import UWGRunPeriod
from .vegetation import VegetationParameter
from .refsite import ReferenceEPWSite
from .boundary import BoundaryLayerParameter

from honeybee.altnumber import autocalculate
from honeybee.typing import int_positive
from ladybug.epw import EPW


[docs]class UWGSimulationParameter(object): """Complete set of UWG Simulation Settings. Args: climate_zone: Text for the ASHRAE climate zone, including the letter for humidity classification (eg. "4A"). This is used to set default constructions for various buildings. If set to autocalculate, the climate zone will be estimated from analysis of the epw to be morphed for simulation. (Default: autocalculate). run_period: A UWGRunPeriod object to describe the time period over which to run the simulation. If None, the simulation will be run for the whole year. (Default: None). timestep: An integer for the number of timesteps per hour at which the calculation will be run. (Default: 12). vegetation_parameter: A VegetationParameter to specify the behavior of vegetation in the urban area. If None, generic vegetation parameters will be generated. (Default: None). reference_epw_site: A ReferenceEPWSite to specify the properties of the reference site where the input rural EPW was recorded. If None, generic airport properties will be generated. (Default: None). boundary_layer_parameter: A BoundaryLayerParameter to specify the properties of the urban boundary layer. If None, generic boundary layer parameters will be generated. (Default: None). """ __slots__ = ('_climate_zone', '_run_period', '_timestep', '_vegetation_parameter', '_reference_epw_site', '_boundary_layer_parameter') VALIDTIMESTEPS = (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60) VALIDZONES = ('1A', '1B', '2A', '2B', '3A', '3B', '3C', '4A', '4B', '4C', '5A', '5B', '5C', '6A', '6B', '7', '8') def __init__(self, climate_zone=autocalculate, run_period=None, timestep=12, vegetation_parameter=None, reference_epw_site=None, boundary_layer_parameter=None): """Initialize UWGSimulationParameter""" self.climate_zone = climate_zone self.run_period = run_period self.timestep = timestep self.vegetation_parameter = vegetation_parameter self.reference_epw_site = reference_epw_site self.boundary_layer_parameter = boundary_layer_parameter @property def climate_zone(self): """Get or set a text for the ASHRAE climate zone.""" return self._climate_zone if self._climate_zone is not None else autocalculate @climate_zone.setter def climate_zone(self, value): if value == autocalculate: self._climate_zone = None else: assert value in self.VALIDZONES, 'UWGSimulationParameter climate_zone ' \ '"{}" is invalid.\nMust be one of the following:{}'.format( value, self.VALIDZONES) self._climate_zone = value @property def run_period(self): """Get or set a UWGRunPeriod object for the time period to run the simulation.""" return self._run_period @run_period.setter def run_period(self, value): if value is not None: assert isinstance(value, UWGRunPeriod), 'Expected UWGRunPeriod for ' \ 'UWGSimulationParameter run_period. Got {}.'.format(type(value)) self._run_period = value else: self._run_period = UWGRunPeriod() @property def timestep(self): """Get or set a integer for the number of simulation timesteps per hour.""" return self._timestep @timestep.setter def timestep(self, value): value = int_positive(value, 'simulation parameter timestep') assert value in self.VALIDTIMESTEPS, 'UWGSimulationParameter timestep "{}" is ' \ 'invalid. Must be one of the following:{}'.format(value, self.VALIDTIMESTEPS) self._timestep = value @property def vegetation_parameter(self): """Get or set a VegetationParameter object for the behavior of vegetation.""" return self._vegetation_parameter @vegetation_parameter.setter def vegetation_parameter(self, value): if value is not None: assert isinstance(value, VegetationParameter), 'Expected ' \ 'VegetationParameter. Got {}.'.format(type(value)) self._vegetation_parameter = value else: self._vegetation_parameter = VegetationParameter() @property def reference_epw_site(self): """Get or set a ReferenceEPWSite object for the properties of the rural EPW.""" return self._reference_epw_site @reference_epw_site.setter def reference_epw_site(self, value): if value is not None: assert isinstance(value, ReferenceEPWSite), 'Expected ReferenceEPWSite ' \ 'for UWGSimulationParameter. Got {}.'.format(type(value)) self._reference_epw_site = value else: self._reference_epw_site = ReferenceEPWSite() @property def boundary_layer_parameter(self): """Get or set a BoundaryLayerParameter object for the boundary layer properties. """ return self._boundary_layer_parameter @boundary_layer_parameter.setter def boundary_layer_parameter(self, value): if value is not None: assert isinstance(value, BoundaryLayerParameter), 'Expected ' \ 'BoundaryLayerParameter. Got {}.'.format(type(value)) self._boundary_layer_parameter = value else: self._boundary_layer_parameter = BoundaryLayerParameter()
[docs] @classmethod def from_dict(cls, data): """Create a UWGSimulationParameter object from a dictionary. Args: data: A UWGSimulationParameter dictionary in following the format below. .. code-block:: python { "type": "UWGSimulationParameter", "climate_zone": "5A", # Text for ASHRAE climate zone "run_period": {}, # Dragonfly UWGRunPeriod dictionary "timestep": 20, # Integer for the simulation timestep "vegetation_parameter": {}, # Dragonfly VegetationParameter dictionary "reference_epw_site": {}, # Dragonfly ReferenceEPWSite dictionary "boundary_layer_parameter": {} # Dragonfly BoundaryLayerParameter dictionary } """ assert data['type'] == 'UWGSimulationParameter', \ 'Expected UWGSimulationParameter dictionary. Got {}.'.format(data['type']) cz = autocalculate if 'climate_zone' not in data or \ data['climate_zone'] == autocalculate.to_dict() else data['climate_zone'] timestep = data['timestep'] if 'timestep' in data else 12 run_period = None if 'run_period' in data and data['run_period'] is not None: run_period = UWGRunPeriod.from_dict(data['run_period']) veg_par = None if 'vegetation_parameter' in data and data['vegetation_parameter'] is not None: veg_par = VegetationParameter.from_dict(data['vegetation_parameter']) ref_site = None if 'reference_epw_site' in data and data['reference_epw_site'] is not None: ref_site = ReferenceEPWSite.from_dict(data['reference_epw_site']) bnd_par = None if 'boundary_layer_parameter' in data and \ data['boundary_layer_parameter'] is not None: bnd_par = BoundaryLayerParameter.from_dict(data['boundary_layer_parameter']) return cls(cz, run_period, timestep, veg_par, ref_site, bnd_par)
[docs] def to_dict(self): """UWGSimulationParameter dictionary representation.""" base = { 'type': 'UWGSimulationParameter', 'run_period': self.run_period.to_dict(), 'timestep': self.timestep, 'vegetation_parameter': self.vegetation_parameter.to_dict(), 'reference_epw_site': self.reference_epw_site.to_dict(), 'boundary_layer_parameter': self.boundary_layer_parameter.to_dict()} if self._climate_zone is not None: base['climate_zone'] = self.climate_zone return base
[docs] def to_uwg_dict(self, epw_file): """Get a dictionary following the input schema of the UWG. Note that this dictionary will only include the properties that the UWGSimulationParameter object possesses and will lack all of those provided by the Model object. For fully simulate-able UWG input, the Model.to.uwg method should be used. The keys of the dictionary output by this method include the following. * zone * month * day * nday * dtsim * rurvegcover * vegstart * vegend * albveg * latgrss * lattree * h_ubl1 * h_ubl2 * h_ref * h_temp * h_wind * c_circ * c_exch * h_obs Args: epw_file: File path to the EPW that will be morphed by the UWG. This will be used to fill all autocalculated fields like the ASHRAE climate zone and vegetation start/end. """ # autocalculate any missing values from the epw_file climate_zone = self._climate_zone veg_start = self.vegetation_parameter._start_month veg_end = self.vegetation_parameter._end_month if climate_zone is None or veg_start is None or veg_end is None: epw_obj = EPW(epw_file) start_def, end_def = self._autocalc_start_end_vegetation(epw_obj) veg_start = start_def if veg_start is None else veg_start veg_end = end_def if veg_end is None else veg_end climate_zone = epw_obj.ashrae_climate_zone if climate_zone is None \ else climate_zone # create the uwg dictionary base = {} base['zone'] = climate_zone base['month'] = self.run_period.start_date.month base['day'] = self.run_period.start_date.day base['nday'] = self.run_period.day_count base['dtsim'] = int((60 / self.timestep) * 60) base['vegstart'] = veg_start base['vegend'] = veg_end base['albveg'] = self.vegetation_parameter.vegetation_albedo base['latgrss'] = self.vegetation_parameter.grass_latent_fraction base['lattree'] = self.vegetation_parameter.tree_latent_fraction base['h_ubl1'] = self.boundary_layer_parameter.day_boundary_layer_height base['h_ubl2'] = self.boundary_layer_parameter.night_boundary_layer_height base['h_ref'] = self.boundary_layer_parameter.inversion_height base['c_circ'] = self.boundary_layer_parameter.circulation_coefficient base['c_exch'] = self.boundary_layer_parameter.exchange_coefficient base['rurvegcover'] = self.reference_epw_site.vegetation_coverage base['h_temp'] = self.reference_epw_site.temp_measure_height base['h_wind'] = self.reference_epw_site.wind_measure_height base['h_obs'] = self.reference_epw_site.average_obstacle_height return base
[docs] def duplicate(self): """Get a copy of this object.""" return self.__copy__()
@staticmethod def _autocalc_start_end_vegetation(epw_obj, threshold_temp=10): """Autocalculate the vegetation start and end month from an EPW.""" month_temps = epw_obj.dry_bulb_temperature.average_monthly() veg_start, veg_end, veg_start_set = 1, 12, False for i, t in enumerate(month_temps): if t > threshold_temp and not veg_start_set: veg_start, veg_start_set = i + 1, True elif t < threshold_temp and veg_start_set: veg_end, veg_start_set = i + 1, False return veg_start, veg_end def __copy__(self): return UWGSimulationParameter( self.climate_zone, self.run_period.duplicate(), self.timestep, self.vegetation_parameter.duplicate(), self.reference_epw_site.duplicate(), self.boundary_layer_parameter.duplicate())
[docs] def ToString(self): """Overwrite .NET ToString method.""" return self.__repr__()
def __repr__(self): return 'UWG SimulationParameter:'