Source code for dragonfly_energy.des.connector

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

from .._base import _GeometryBase

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


[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) Properties: * buried_depth * diameter_ratio * pressure_drop_per_meter * insulation_conductivity * insulation_thickness * heat_capacity * roughness """ __slots__ = ('_buried_depth', '_diameter_ratio', '_pressure_drop_per_meter', '_insulation_conductivity', '_insulation_thickness', '_heat_capacity', '_roughness') 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): """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
[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 } """ 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 return cls(bur_d, d_ratio, pd, cond, thick, cap, rough)
@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 = \ float_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')
[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 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)
[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)