Source code for dragonfly_energy.des.connector

# coding=utf-8
"""Thermal connector in a District Energy System."""
from __future__ import division

from ladybug_geometry.geometry2d.line import LineSegment2D
from ladybug_geometry.geometry2d.polyline import Polyline2D
from honeybee.typing import float_positive, float_in_range, int_positive
from honeybee_energy.altnumber import autosize
from dragonfly.projection import polygon_to_lon_lat

from .._base import _GeometryBase


[docs] class ThermalConnector(_GeometryBase): """Represents a thermal connector carrying hot, chilled or ambient water in a DES. Args: identifier: Text string for a unique thermal connector ID. Must contain only characters that are acceptable in a DES. This will be used to identify the object across the exported geoJSON and DES files. geometry: A LineSegment2D or Polyline2D representing the geometry of the thermal connector. Properties: * identifier * display_name * geometry """ __slots__ = () def __init__(self, identifier, geometry): """Initialize ThermalConnector.""" _GeometryBase.__init__(self, identifier) # process the identifier assert isinstance(geometry, (LineSegment2D, Polyline2D)), 'Expected ' \ 'ladybug_geometry LineSegment2D or Polyline2D. Got {}'.format(type(geometry)) self._geometry = geometry
[docs] @classmethod def from_dict(cls, data): """Initialize an ThermalConnector from a dictionary. Args: data: A dictionary representation of an ThermalConnector object. """ # check the type of dictionary assert data['type'] == 'ThermalConnector', 'Expected ThermalConnector ' \ 'dictionary. Got {}.'.format(data['type']) geo = LineSegment2D.from_dict(data['geometry']) \ if data['geometry']['type'] == 'LineSegment2D' \ else Polyline2D.from_dict(data['geometry']) con = cls(data['identifier'], geo) if 'display_name' in data and data['display_name'] is not None: con.display_name = data['display_name'] return con
[docs] @classmethod def from_dict_abridged(cls, data): """Initialize an ThermalConnector from an abridged dictionary. Args: data: A ThermalConnector dictionary. """ return cls.from_dict(data)
[docs] @classmethod def from_geojson_dict( cls, data, origin_lon_lat, conversion_factors): """Get a ThermalConnector from a dictionary as it appears in a GeoJSON. Args: data: A GeoJSON dictionary representation of an ThermalConnector feature. origin_lon_lat: An array of two numbers in degrees. The first value represents the longitude of the scene origin in degrees (between -180 and +180). The second value represents latitude of the scene origin in degrees (between -90 and +90). Note that the "scene origin" is the (0, 0) coordinate in the 2D space of the input polygon. conversion_factors: A tuple with two values used to translate between meters and longitude, latitude. """ geo = cls._geojson_coordinates_to_line2d( data['geometry']['coordinates'], origin_lon_lat, conversion_factors) return cls(data['properties']['id'], geo)
@property def geometry(self): """Get a LineSegment2D or Polyline2D representing the thermal connector.""" return self._geometry
[docs] def reverse(self): """Reverse the direction of this object's geometry. This is useful when trying to orient the connector to the direction of flow within a larger loop. """ self._geometry = self._geometry.flip() \ if isinstance(self._geometry, LineSegment2D) else self._geometry.reverse()
[docs] def to_dict(self): """ThermalConnector dictionary representation.""" base = {'type': 'ThermalConnector'} base['identifier'] = self.identifier base['geometry'] = self.geometry.to_dict() if self._display_name is not None: base['display_name'] = self.display_name return base
[docs] def to_geojson_dict(self, start_id, end_id, origin_lon_lat, conversion_factors, start_feature_id=None, end_feature_id=None): """Get ThermalConnector dictionary as it appears in an URBANopt geoJSON. Args: start_id: Identifier of the junction at the start of the pipe. end_id: Identifier of the junction at the end of the pipe. origin_lon_lat: An array of two numbers in degrees. The first value represents the longitude of the scene origin in degrees (between -180 and +180). The second value represents latitude of the scene origin in degrees (between -90 and +90). Note that the "scene origin" is the (0, 0) coordinate in the 2D space of the input polygon. conversion_factors: A tuple with two values used to translate between meters and longitude, latitude. start_feature_id: Optional identifier for a feature (Building or GHE field) at the start of the pipe. end_feature_id: Optional identifier for a feature (Building or GHE field) at the end of the pipe. """ # translate the geometry coordinates to latitude and longitude if isinstance(self.geometry, LineSegment2D): pts = [(pt.x, pt.y) for pt in (self.geometry.p1, self.geometry.p2)] else: # it's a polyline pts = [(pt.x, pt.y) for pt in self.geometry.vertices] coords = polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors) # assign all of the properties to the connector conn_props = { 'id': self.identifier, 'type': 'ThermalConnector', 'name': self.display_name, 'startJunctionId': start_id, 'endJunctionId': end_id, 'total_length': round(self.geometry.length, 2), 'connector_type': 'OnePipe', 'fluid_temperature_type': 'Ambient', 'flow_direction': 'Unspecified' } if start_feature_id is not None: conn_props['startFeatureId'] = start_feature_id if end_feature_id is not None: conn_props['endFeatureId'] = end_feature_id # return the full dictionary return { 'type': 'Feature', 'properties': conn_props, 'geometry': { 'type': 'LineString', 'coordinates': coords } }
def __copy__(self): new_con = ThermalConnector(self.identifier, self.geometry) new_con._display_name = self._display_name return new_con def __repr__(self): return 'ThermalConnector: {}'.format(self.display_name)
[docs] class HorizontalPipeParameter(object): """Represents the properties of horizontal pipes contained within ThermalConnectors. Args: buried_depth: The buried depth of the pipes in meters. (Default: 1.5) diameter_ratio: A number for the ratio of pipe outer diameter to pipe wall thickness. (Default: 11). pressure_drop_per_meter: A number for the pressure drop in pascals per meter of pipe. (Default: 300). insulation_conductivity: A positive number for the conductivity of the pipe insulation material in W/m-K. If no insulation exists, this value should be a virtual insulation layer of soil since this value must be greater than zero. (Default: 3.0). insulation_thickness: A positive number for the thickness of pipe insulation in meters. If no insulation exists, this value should be a virtual insulation layer of soil since this value must be greater than zero. (Default: 0.2) heat_capacity: A number for the volumetric heat capacity of the pipe wall material in J/m3-K. (Default: 2,139,000). roughness: A number for the linear dimension of bumps on the pipe surface in meters. (Default: 1e-06) hydraulic_diameter: A number to specify the size of the hydraulic diameter in meters. This can also be an Autosize object to indicate that the hydraulic diameter should be autosized. (Default: Autosize). pump_design_head: A number for the design pressure of the ambient loop pump in Pa. This can also be an Autosize object to indicate that the pump pressure should be autosized. (Default: Autosize). pump_flow_rate: A number for the design volume flow rate of the ambient loop pump in m3/s. This can also be an Autosize object to indicate that the pump flow rate should be autosized. (Default: Autosize). Properties: * buried_depth * diameter_ratio * pressure_drop_per_meter * insulation_conductivity * insulation_thickness * heat_capacity * roughness * hydraulic_diameter * pump_design_head * pump_flow_rate """ __slots__ = ( '_buried_depth', '_diameter_ratio', '_pressure_drop_per_meter', '_insulation_conductivity', '_insulation_thickness', '_heat_capacity', '_roughness', '_hydraulic_diameter', '_pump_design_head', '_pump_flow_rate' ) def __init__( self, buried_depth=1.5, diameter_ratio=11, pressure_drop_per_meter=300, insulation_conductivity=3.0, insulation_thickness=0.2, heat_capacity=2139000, roughness=1e-06, hydraulic_diameter=autosize, pump_design_head=autosize, pump_flow_rate=autosize): """Initialize HorizontalPipeParameter.""" self.buried_depth = buried_depth self.diameter_ratio = diameter_ratio self.pressure_drop_per_meter = pressure_drop_per_meter self.insulation_conductivity = insulation_conductivity self.insulation_thickness = insulation_thickness self.heat_capacity = heat_capacity self.roughness = roughness self.hydraulic_diameter = hydraulic_diameter self.pump_design_head = pump_design_head self.pump_flow_rate = pump_flow_rate
[docs] @classmethod def from_dict(cls, data): """Create a HorizontalPipeParameter object from a dictionary Args: data: A dictionary representation of an HorizontalPipeParameter object in the format below. .. code-block:: python { 'type': 'HorizontalPipeParameter', 'buried_depth': 2.0, # float for buried depth in meters 'diameter_ratio': 11, # float for diameter ratio 'pressure_drop_per_meter': 250, # float for pressure drop in Pa/m 'insulation_conductivity': 0.6, # float in W/m2-K 'insulation_thickness': 0.3, # float for thickness in meters 'heat_capacity': 1542000, # float in J/m3-K 'roughness': 1e-06, # float for the dimension of the surface bumps in meters 'pump_design_head': 60000, # float for design pressure in Pa 'pump_flow_rate': 0.01 # float for design flow rate in m3/s } """ bur_d = data['buried_depth'] if 'buried_depth' in data else 1.5 d_ratio = data['diameter_ratio'] if 'diameter_ratio' in data else 11 pd = data['pressure_drop_per_meter'] \ if 'pressure_drop_per_meter' in data else 300 cond = data['insulation_conductivity'] \ if 'insulation_conductivity' in data else 3.0 thick = data['insulation_thickness'] \ if 'insulation_thickness' in data else 0.2 cap = data['heat_capacity'] if 'heat_capacity' in data else 2139000 rough = data['roughness'] if 'roughness' in data else 1e-06 if 'hydraulic_diameter' not in data or \ data['hydraulic_diameter'] == autosize.to_dict(): hd = autosize else: hd = data['hydraulic_diameter'] if 'pump_design_head' not in data or \ data['pump_design_head'] == autosize.to_dict(): ph = autosize else: ph = data['pump_design_head'] if 'pump_flow_rate' not in data or \ data['pump_flow_rate'] == autosize.to_dict(): pfr = autosize else: pfr = data['pump_flow_rate'] return cls(bur_d, d_ratio, pd, cond, thick, cap, rough, hd, ph, pfr)
@property def buried_depth(self): """Get or set a number for the buried depth of the pipes in meters.""" return self._buried_depth @buried_depth.setter def buried_depth(self, value): self._buried_depth = float_positive(value, 'pipe buried depth') @property def diameter_ratio(self): """Get or set a number for the ratio of pipe outer diameter to pipe wall thickness. """ return self._diameter_ratio @diameter_ratio.setter def diameter_ratio(self, value): self._diameter_ratio = float_in_range(value, 11, 17, 'pipe diameter ratio') @property def pressure_drop_per_meter(self): """Get or set a number for the pressure drop in pascals per meter of pipe.""" return self._pressure_drop_per_meter @pressure_drop_per_meter.setter def pressure_drop_per_meter(self, value): self._pressure_drop_per_meter = \ int_positive(value, 'pipe pressure drop per meter') @property def insulation_conductivity(self): """Get or set a number for the conductivity of the insulation material in W/m-K. """ return self._insulation_conductivity @insulation_conductivity.setter def insulation_conductivity(self, value): self._insulation_conductivity = \ float_positive(value, 'pipe insulation conductivity') assert self._insulation_conductivity != 0, \ 'Insulation conductivity cannot be zero.' @property def insulation_thickness(self): """Get or set a number for the thickness of the insulation material in meters. """ return self._insulation_thickness @insulation_thickness.setter def insulation_thickness(self, value): self._insulation_thickness = \ float_positive(value, 'pipe insulation thickness') assert self._insulation_thickness != 0, 'Insulation thickness cannot be zero.' @property def heat_capacity(self): """Get or set a number for the volumetric heat capacity of the pipe in J/m3-K.""" return self._heat_capacity @heat_capacity.setter def heat_capacity(self, value): self._heat_capacity = float_positive(value, 'pipe heat capacity') @property def roughness(self): """Get or set a number for the dimension of the pipe surface bumps in meters.""" return self._roughness @roughness.setter def roughness(self, value): self._roughness = float_positive(value, 'pipe roughness') @property def hydraulic_diameter(self): """Get or set a number for the hydraulic diameter in meters.""" return self._hydraulic_diameter @hydraulic_diameter.setter def hydraulic_diameter(self, value): if value == autosize or value is None: self._hydraulic_diameter = autosize else: self._hydraulic_diameter = float_positive(value, 'hydraulic diameter') @property def pump_design_head(self): """Get or set a number for the pump design pressure in Pa.""" return self._pump_design_head @pump_design_head.setter def pump_design_head(self, value): if value == autosize or value is None: self._pump_design_head = autosize else: self._pump_design_head = float_positive(value, 'pump design head') @property def pump_flow_rate(self): """Get or set a number for the pump flow rate in m3/s.""" return self._pump_flow_rate @pump_flow_rate.setter def pump_flow_rate(self, value): if value == autosize or value is None: self._pump_flow_rate = autosize else: self._pump_flow_rate = float_positive(value, 'pump design head')
[docs] def to_dict(self): """Get HorizontalPipeParameter dictionary.""" base = {'type': 'HorizontalPipeParameter'} base['buried_depth'] = self.buried_depth base['diameter_ratio'] = self.diameter_ratio base['pressure_drop_per_meter'] = self.pressure_drop_per_meter base['insulation_conductivity'] = self.insulation_conductivity base['insulation_thickness'] = self.insulation_thickness base['heat_capacity'] = self.heat_capacity base['roughness'] = self.roughness base['hydraulic_diameter'] = self.hydraulic_diameter if \ isinstance(self.hydraulic_diameter, float) else \ self.hydraulic_diameter.to_dict() base['pump_design_head'] = self.pump_design_head if \ isinstance(self.pump_design_head, float) else \ self.pump_design_head.to_dict() base['pump_flow_rate'] = self.pump_flow_rate if \ isinstance(self.pump_flow_rate, float) else \ self.pump_flow_rate.to_dict() return base
[docs] def duplicate(self): """Get a copy of this object.""" return self.__copy__()
def __copy__(self): return HorizontalPipeParameter( self.buried_depth, self.diameter_ratio, self.pressure_drop_per_meter, self.insulation_conductivity, self.insulation_thickness, self.heat_capacity, self.roughness, self.hydraulic_diameter, self.pump_design_head, self.pump_flow_rate )
[docs] def ToString(self): """Overwrite .NET ToString method.""" return self.__repr__()
def __repr__(self): """Represent HorizontalPipeParameter.""" return 'HorizontalPipeParameter: [pressure drop: {} Pa/m]'.format( self.pressure_drop_per_meter)