Merge pull request 'reviewing_units' (#41) from reviewing_units into main

Reviewed-on: https://nextgenerations-cities.encs.concordia.ca/gitea/CERC/hub/pulls/41
This commit is contained in:
Guille Gutierrez 2023-08-08 11:35:26 -04:00
commit 8502efc710
53 changed files with 115 additions and 1658 deletions

View File

@ -15,6 +15,7 @@ from hub.catalog_factories.data_models.construction.archetype import Archetype
from hub.catalog_factories.data_models.construction.window import Window
from hub.catalog_factories.data_models.construction.material import Material
from hub.catalog_factories.data_models.construction.layer import Layer
import hub.helpers.constants as cte
class EilatCatalog(Catalog):
@ -120,8 +121,8 @@ class EilatCatalog(Catalog):
construction_period = archetype['period_of_construction']
average_storey_height = archetype['average_storey_height']
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off']
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
archetype_constructions = []
for archetype_construction in archetype['constructions']:

View File

@ -15,6 +15,7 @@ from hub.catalog_factories.data_models.construction.archetype import Archetype
from hub.catalog_factories.data_models.construction.window import Window
from hub.catalog_factories.data_models.construction.material import Material
from hub.catalog_factories.data_models.construction.layer import Layer
import hub.helpers.constants as cte
class NrcanCatalog(Catalog):
@ -121,8 +122,8 @@ class NrcanCatalog(Catalog):
average_storey_height = archetype['average_storey_height']
thermal_capacity = float(archetype['thermal_capacity']) * 1000
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off']
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
archetype_constructions = []
for archetype_construction in archetype['constructions']:

View File

@ -15,6 +15,7 @@ from hub.catalog_factories.data_models.construction.construction import Construc
from hub.catalog_factories.data_models.construction.content import Content
from hub.catalog_factories.data_models.construction.archetype import Archetype
from hub.catalog_factories.construction.construction_helper import ConstructionHelper
import hub.helpers.constants as cte
class NrelCatalog(Catalog):
@ -124,10 +125,10 @@ class NrelCatalog(Catalog):
indirect_heated_ratio = float(archetype['indirect_heated_ratio']['#text'])
infiltration_rate_for_ventilation_system_off = float(
archetype['infiltration_rate_for_ventilation_system_off']['#text']
)
) / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = float(
archetype['infiltration_rate_for_ventilation_system_on']['#text']
)
) / cte.HOUR_TO_SECONDS
archetype_constructions = []
for archetype_construction in archetype['constructions']['construction']:

View File

@ -120,7 +120,7 @@ class Archetype:
@property
def infiltration_rate_for_ventilation_system_off(self):
"""
Get archetype infiltration rate for ventilation system off in ACH
Get archetype infiltration rate for ventilation system off in 1/s
:return: float
"""
return self._infiltration_rate_for_ventilation_system_off
@ -128,7 +128,7 @@ class Archetype:
@property
def infiltration_rate_for_ventilation_system_on(self):
"""
Get archetype infiltration rate for ventilation system on in ACH
Get archetype infiltration rate for ventilation system on in 1/s
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
@ -147,8 +147,8 @@ class Archetype:
'thermal capacity [J/m3K]': self.thermal_capacity,
'extra loses due to thermal bridges [W/m2K]': self.extra_loses_due_to_thermal_bridges,
'indirect heated ratio': self.indirect_heated_ratio,
'infiltration rate for ventilation off [ACH]': self.infiltration_rate_for_ventilation_system_off,
'infiltration rate for ventilation on [ACH]': self.infiltration_rate_for_ventilation_system_on,
'infiltration rate for ventilation off [1/s]': self.infiltration_rate_for_ventilation_system_off,
'infiltration rate for ventilation on [1/s]': self.infiltration_rate_for_ventilation_system_on,
'constructions': _constructions
}
}

View File

@ -27,7 +27,7 @@ class Income:
@property
def construction_subsidy(self) -> Union[None, float]:
"""
Get subsidy for construction in percentage
Get subsidy for construction in percentage %
:return: None or float
"""
return self._construction_subsidy
@ -35,7 +35,7 @@ class Income:
@property
def hvac_subsidy(self) -> Union[None, float]:
"""
Get subsidy for HVAC system in percentage
Get subsidy for HVAC system in percentage %
:return: None or float
"""
return self._hvac_subsidy

View File

@ -24,7 +24,7 @@ class Appliances:
@property
def density(self) -> Union[None, float]:
"""
Get appliances density in Watts per m2
Get appliances density in W/m2
:return: None or float
"""
return self._density

View File

@ -65,7 +65,7 @@ class Usage:
@property
def mechanical_air_change(self) -> Union[None, float]:
"""
Get usage zone mechanical air change in air change per hour (ACH)
Get usage zone mechanical air change in air change per second (1/s)
:return: None or float
"""
return self._mechanical_air_change

View File

@ -134,8 +134,8 @@ class NrcanCatalog(Catalog):
hvac_availability = self._get_schedules(hvac_schedule_name)
domestic_hot_water_load_schedule = self._get_schedules(domestic_hot_water_schedule_name)
# ACH
mechanical_air_change = space_type['ventilation_air_changes']
# ACH -> 1/s
mechanical_air_change = space_type['ventilation_air_changes'] / cte.HOUR_TO_SECONDS
# cfm/ft2 to m3/m2.s
ventilation_rate = space_type['ventilation_per_area'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)
# cfm/person to m3/m2.s

View File

@ -114,8 +114,7 @@ class Building(CityObject):
:return: [InternalZone]
"""
if self._internal_zones is None:
_number_of_storeys = self.eave_height * self.volume / self.floor_area
self._internal_zones = [InternalZone(self.surfaces, self.floor_area, self.volume, _number_of_storeys)]
self._internal_zones = [InternalZone(self.surfaces, self.floor_area, self.volume)]
return self._internal_zones
@property
@ -318,7 +317,7 @@ class Building(CityObject):
@property
def heating_demand(self) -> dict:
"""
Get heating demand in Wh
Get heating demand in J
:return: dict{[float]}
"""
return self._heating_demand
@ -326,7 +325,7 @@ class Building(CityObject):
@heating_demand.setter
def heating_demand(self, value):
"""
Set heating demand in Wh
Set heating demand in J
:param value: dict{[float]}
"""
self._heating_demand = value
@ -334,7 +333,7 @@ class Building(CityObject):
@property
def cooling_demand(self) -> dict:
"""
Get cooling demand in Wh
Get cooling demand in J
:return: dict{[float]}
"""
return self._cooling_demand
@ -342,7 +341,7 @@ class Building(CityObject):
@cooling_demand.setter
def cooling_demand(self, value):
"""
Set cooling demand in Wh
Set cooling demand in J
:param value: dict{[float]}
"""
self._cooling_demand = value
@ -350,7 +349,7 @@ class Building(CityObject):
@property
def lighting_electrical_demand(self) -> dict:
"""
Get lighting electrical demand in Wh
Get lighting electrical demand in J
:return: dict{[float]}
"""
return self._lighting_electrical_demand
@ -358,7 +357,7 @@ class Building(CityObject):
@lighting_electrical_demand.setter
def lighting_electrical_demand(self, value):
"""
Set lighting electrical demand in Wh
Set lighting electrical demand in J
:param value: dict{[float]}
"""
self._lighting_electrical_demand = value
@ -366,7 +365,7 @@ class Building(CityObject):
@property
def appliances_electrical_demand(self) -> dict:
"""
Get appliances electrical demand in Wh
Get appliances electrical demand in J
:return: dict{[float]}
"""
return self._appliances_electrical_demand
@ -374,7 +373,7 @@ class Building(CityObject):
@appliances_electrical_demand.setter
def appliances_electrical_demand(self, value):
"""
Set appliances electrical demand in Wh
Set appliances electrical demand in J
:param value: dict{[float]}
"""
self._appliances_electrical_demand = value
@ -382,7 +381,7 @@ class Building(CityObject):
@property
def domestic_hot_water_heat_demand(self) -> dict:
"""
Get domestic hot water heat demand in Wh
Get domestic hot water heat demand in J
:return: dict{[float]}
"""
return self._domestic_hot_water_heat_demand
@ -390,7 +389,7 @@ class Building(CityObject):
@domestic_hot_water_heat_demand.setter
def domestic_hot_water_heat_demand(self, value):
"""
Set domestic hot water heat demand in Wh
Set domestic hot water heat demand in J
:param value: dict{[float]}
"""
self._domestic_hot_water_heat_demand = value
@ -447,7 +446,7 @@ class Building(CityObject):
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
if monthly_values is None:
return None
results[cte.MONTH] = monthly_values
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)]
return results
@ -464,7 +463,7 @@ class Building(CityObject):
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
if monthly_values is None:
return None
results[cte.MONTH] = monthly_values
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)]
return results
@ -618,7 +617,7 @@ class Building(CityObject):
@property
def heating_consumption(self):
"""
Get energy consumption for heating according to the heating system installed in Wh
Get energy consumption for heating according to the heating system installed in J
return: dict
"""
if len(self._heating_consumption) == 0:
@ -634,7 +633,7 @@ class Building(CityObject):
@property
def cooling_consumption(self):
"""
Get energy consumption for cooling according to the cooling system installed in Wh
Get energy consumption for cooling according to the cooling system installed in J
return: dict
"""
if len(self._cooling_consumption) == 0:
@ -650,7 +649,7 @@ class Building(CityObject):
@property
def domestic_hot_water_consumption(self):
"""
Get energy consumption for domestic according to the domestic hot water system installed in Wh
Get energy consumption for domestic according to the domestic hot water system installed in J
return: dict
"""
if len(self._domestic_hot_water_consumption) == 0:
@ -692,7 +691,7 @@ class Building(CityObject):
@property
def distribution_systems_electrical_consumption(self):
"""
Get total electricity consumption for distribution and emission systems in Wh
Get total electricity consumption for distribution and emission systems in J
return: dict
"""
if len(self._distribution_systems_electrical_consumption) != 0:
@ -767,11 +766,9 @@ class Building(CityObject):
@property
def onsite_electrical_production(self):
"""
Get total electricity produced onsite in Wh
Get total electricity produced onsite in J
return: dict
"""
# Add other systems whenever new ones appear
orientation_losses_factor = {cte.MONTH: {'north': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'east': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'south': [2.137931, 1.645503, 1.320946, 1.107817, 0.993213, 0.945175,
@ -782,6 +779,8 @@ class Building(CityObject):
'south': [1.212544],
'west': [0]}
}
# Add other systems whenever new ones appear
if self.energy_systems is None:
return self._onsite_electrical_production
for energy_system in self.energy_systems:

View File

@ -12,24 +12,21 @@ from hub.city_model_structure.building_demand.thermal_archetype import ThermalAr
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
from hub.city_model_structure.building_demand.thermal_boundary import ThermalBoundary
from hub.city_model_structure.attributes.polyhedron import Polyhedron
from hub.city_model_structure.energy_systems.hvac_system import HvacSystem
class InternalZone:
"""
InternalZone class
"""
def __init__(self, surfaces, area, volume, number_of_storeys=None):
def __init__(self, surfaces, area, volume):
self._surfaces = surfaces
self._id = None
self._geometry = None
self._volume = volume
self._area = area
self._number_of_storeys = number_of_storeys
self._thermal_zones_from_internal_zones = None
self._usages = None
self._thermal_archetype = None
self._hvac_system = None
@property
def id(self):
@ -118,22 +115,6 @@ class InternalZone:
"""
self._thermal_archetype = value
@property
def hvac_system(self) -> Union[None, HvacSystem]:
"""
Get HVAC system installed for this thermal zone
:return: None or HvacSystem
"""
return self._hvac_system
@hvac_system.setter
def hvac_system(self, value):
"""
Set HVAC system installed for this thermal zone
:param value: HvacSystem
"""
self._hvac_system = value
@property
def thermal_zones_from_internal_zones(self) -> Union[None, List[ThermalZone]]:
"""
@ -150,7 +131,8 @@ class InternalZone:
windows_areas.append(hole.area)
_thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas)
_thermal_boundaries.append(_thermal_boundary)
_thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, self._number_of_storeys)
_number_of_storeys = int(self.volume / self.area / self.thermal_archetype.average_storey_height)
_thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, _number_of_storeys)
for thermal_boundary in _thermal_zone.thermal_boundaries:
thermal_boundary.thermal_zones = [_thermal_zone]
self._thermal_zones_from_internal_zones = [_thermal_zone]

View File

@ -90,7 +90,9 @@ class Storey:
:return: ThermalZone
"""
if self._thermal_zone is None:
self._thermal_zone = ThermalZone(self.thermal_boundaries, self._internal_zone, self.volume, self.floor_area)
_number_of_storeys = 1
self._thermal_zone = ThermalZone(self.thermal_boundaries, self._internal_zone,
self.volume, self.floor_area, _number_of_storeys)
return self._thermal_zone
@property

View File

@ -178,7 +178,7 @@ class Surface:
@property
def global_irradiance(self) -> dict:
"""
Get global irradiance on surface in Wh/m2
Get global irradiance on surface in J/m2
:return: dict
"""
return self._global_irradiance
@ -186,7 +186,7 @@ class Surface:
@global_irradiance.setter
def global_irradiance(self, value):
"""
Set global irradiance on surface in Wh/m2
Set global irradiance on surface in J/m2
:param value: dict
"""
self._global_irradiance = value

View File

@ -151,7 +151,7 @@ class ThermalZone:
@property
def infiltration_rate_system_on(self):
"""
Get thermal zone infiltration rate system on in air changes per hour (ACH)
Get thermal zone infiltration rate system on in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_on
@ -160,7 +160,7 @@ class ThermalZone:
@property
def infiltration_rate_system_off(self):
"""
Get thermal zone infiltration rate system off in air changes per hour (ACH)
Get thermal zone infiltration rate system off in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off
@ -289,7 +289,7 @@ class ThermalZone:
@property
def mechanical_air_change(self) -> Union[None, float]:
"""
Get thermal zone mechanical air change in air change per hour (ACH)
Get thermal zone mechanical air change in air change per second (1/s)
:return: None or float
"""
if self.usages is None:
@ -657,7 +657,7 @@ class ThermalZone:
@property
def total_floor_area(self):
"""
Get the total floor area of this thermal zone
Get the total floor area of this thermal zone in m2
:return: float
"""
self._total_floor_area = self.footprint_area * self._number_of_storeys

View File

@ -173,7 +173,7 @@ class Usage:
@property
def mechanical_air_change(self) -> Union[None, float]:
"""
Get usage zone mechanical air change in air change per hour (ACH)
Get usage zone mechanical air change in air change per second (1/s)
:return: None or float
"""
return self._mechanical_air_change
@ -181,7 +181,7 @@ class Usage:
@mechanical_air_change.setter
def mechanical_air_change(self, value):
"""
Set usage zone mechanical air change in air change per hour (ACH)
Set usage zone mechanical air change in air change per second (1/s)
:param value: float
"""
if value is not None:

View File

@ -1,57 +0,0 @@
"""
Bus system module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List
from hub.city_model_structure.city_object import CityObject
from hub.city_model_structure.attributes.polygon import Polygon
from hub.city_model_structure.transport.bus_network import BusNetwork
from hub.city_model_structure.transport.bus_node import BusNode
from hub.city_model_structure.transport.bus import Bus
class BusSystem(CityObject):
"""
BusSystem(CityObject) class
"""
def __init__(self, name, surfaces):
super().__init__(name, surfaces)
self._bus_routes = None
self._bus_network = None
self._buses = None
self._restricted_polygons = None
@property
def bus_routes(self) -> List[BusNode]:
"""
Add explanation here
:return: [BusNode]
"""
return self._bus_routes
@property
def bus_network(self) -> BusNetwork:
"""
Add explanation here
:return: BusNetwork
"""
return self._bus_network
@property
def buses(self) -> List[Bus]:
"""
Add explanation here
:return: [Bus]
"""
return self._buses
@property
def restricted_polygons(self) -> List[Polygon]:
"""
Add explanation here
:return: [Polygon]
"""
return self._restricted_polygons

View File

@ -81,6 +81,10 @@ class CityObject:
@volume.setter
def volume(self, value):
"""
Set city object volume in cubic meters
:param value: float
"""
self._volume = value
@property
@ -204,7 +208,7 @@ class CityObject:
@property
def global_horizontal(self) -> dict:
"""
Get global horizontal radiation surrounding the city object in W/m2
Get global horizontal radiation surrounding the city object in J/m2
:return: dict{dict{[float]}}
"""
return self._global_horizontal
@ -212,7 +216,7 @@ class CityObject:
@global_horizontal.setter
def global_horizontal(self, value):
"""
Set global horizontal radiation surrounding the city object in W/m2
Set global horizontal radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}}
"""
self._global_horizontal = value
@ -220,7 +224,7 @@ class CityObject:
@property
def diffuse(self) -> dict:
"""
Get diffuse radiation surrounding the city object in W/m2
Get diffuse radiation surrounding the city object in J/m2
:return: dict{dict{[float]}}
"""
return self._diffuse
@ -228,7 +232,7 @@ class CityObject:
@diffuse.setter
def diffuse(self, value):
"""
Set diffuse radiation surrounding the city object in W/m2
Set diffuse radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}}
"""
self._diffuse = value
@ -236,7 +240,7 @@ class CityObject:
@property
def beam(self) -> dict:
"""
Get beam radiation surrounding the city object in W/m2
Get beam radiation surrounding the city object in J/m2
:return: dict{dict{[float]}}
"""
return self._beam
@ -244,7 +248,7 @@ class CityObject:
@beam.setter
def beam(self, value):
"""
Set beam radiation surrounding the city object in W/m2
Set beam radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}}
"""
self._beam = value

View File

@ -69,7 +69,7 @@ class GenericDistributionSystem:
def distribution_consumption_variable_flow(self):
"""
Get distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (Wh/Wh)
over energy produced (J/J)
:return: float
"""
return self._distribution_consumption_variable_flow
@ -78,7 +78,7 @@ class GenericDistributionSystem:
def distribution_consumption_variable_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (Wh/Wh)
over energy produced (J/J)
:return: float
"""
self._distribution_consumption_variable_flow = value

View File

@ -1,50 +0,0 @@
"""
HvacSystem module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import Union, List
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
class HvacSystem:
"""
HvacSystem class
"""
def __init__(self):
self._type = None
self._thermal_zones = None
@property
def type(self) -> Union[None, str]:
"""
Get hvac system type
:return: None or str
"""
return self._type
@type.setter
def type(self, value):
"""
Set hvac system type
:param value: str
"""
if value is not None:
self._type = str(value)
@property
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
"""
Get list of zones that this unit serves
:return: None or [ThermalZone]
"""
return self._thermal_zones
@thermal_zones.setter
def thermal_zones(self, value):
"""
Set list of zones that this unit serves
:param value: [ThermalZone]
"""
self._thermal_zones = value

View File

@ -1,115 +0,0 @@
"""
Bus module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from hub.city_model_structure.attributes.schedule import Schedule
class Bus:
"""
Bus class
"""
def __init__(self):
self._maintenance_time = None
self._charging_time = None
self._recovery_time = None
self._vehicle_type = None
self._energy_consumption = None
self._trips_schedule = None
self._capacity = None
self._maintenance_cost = None
self._investment_cost = None
self._charging_range = None
self._maximum_travel_range = None
@property
def maintenance_time(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._maintenance_time
@property
def charging_time(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._charging_time
@property
def recovery_time(self):
"""
Add explanation here
:return: add type of variable here
"""
return self.maintenance_time + self.charging_time
@property
def vehicle_type(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._vehicle_type
@property
def energy_consumption(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._energy_consumption
@property
def trips_schedule(self) -> Schedule:
"""
Add explanation here
:return: add type of variable here
"""
return self._trips_schedule
@property
def capacity(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._capacity
@property
def maintenance_cost(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._maintenance_cost
@property
def investment_cost(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._investment_cost
@property
def charging_range(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._charging_range
@property
def maximum_travel_range(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._maximum_travel_range

View File

@ -1,35 +0,0 @@
"""
Bus depot module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from hub.city_model_structure.transport.bus_node import BusNode
class BusDepot(BusNode):
"""
BusDepot class
"""
def __init__(self, name, coordinates, edges=None):
super().__init__(name, coordinates, edges=edges, node_type='BusDepot')
self._number_of_charging_poles = None
self._number_of_available_buses = None
@property
def number_of_charging_poles(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._number_of_charging_poles
@property
def number_of_available_buses(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._number_of_available_buses

View File

@ -1,47 +0,0 @@
"""
Bus edge module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List, TypeVar
from hub.city_model_structure.attributes.edge import Edge
BusNode = TypeVar('BusNode')
class BusEdge(Edge):
"""
BusEdge class
Each edge is unidirectional and starts at the "from" node and ends at the "to" node
"""
def __init__(self, name, nodes, edge_type='BusEdge'):
super().__init__(name, nodes)
self._edge_type = edge_type
self._average_travel_time = None
@property
def edge_type(self):
"""
Get the edge type
:return: str
"""
return self._edge_type
@property
def nodes(self) -> List[BusNode]:
"""
Get delimiting nodes for the edge
:return: [BusNode]
"""
return self._nodes
@property
def average_travel_time(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._average_travel_time

View File

@ -1,44 +0,0 @@
"""
Bus network module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List
from hub.city_model_structure.network import Network
from hub.city_model_structure.transport.bus_edge import BusEdge
from hub.city_model_structure.transport.bus_node import BusNode
class BusNetwork(Network):
"""
BusNetwork(Network) class
"""
def __init__(self, name, edges=None, nodes=None):
super().__init__(name, edges, nodes)
self._type = "BusNetwork"
@property
def type(self):
"""
Get network type
:return: str
"""
return self._type
@property
def edges(self) -> List[BusEdge]:
"""
Get network edges
:return: [BusEdge]
"""
return self._edges
@property
def nodes(self) -> List[BusNode]:
"""
Get network nodes
:return: [BusNode]
"""
return self._nodes

View File

@ -1,56 +0,0 @@
"""
Bus node module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List, TypeVar
from hub.city_model_structure.attributes.node import Node
from hub.city_model_structure.attributes.point import Point
BusEdge = TypeVar('BusEdge')
class BusNode(Node):
"""
BusNode class
"""
def __init__(self, name, coordinates, node_type='BusNode', edges=None):
super().__init__(name, edges)
self._coordinates = coordinates
self._node_type = node_type
@property
def node_type(self):
"""
Get node type
:return: str
"""
return self._node_type
@property
def coordinates(self) -> Point:
"""
Get node coordinates
:return: Point
"""
return self._coordinates
@coordinates.setter
def coordinates(self, value):
"""
Set node coordinates
:param value: Point
"""
self._coordinates = value
@property
def edges(self) -> List[BusEdge]:
"""
get edges delimited by the node
:return: [BusEdge]
"""
return self._edges

View File

@ -1,56 +0,0 @@
"""
Bus stop module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import Union
from hub.city_model_structure.transport.bus_node import BusNode
from hub.city_model_structure.transport.fast_charging_infrastructure import FastChargingInfrastructure
from hub.city_model_structure.attributes.schedule import Schedule
class BusStop(BusNode):
"""
BusStop class
"""
def __init__(self, name, coordinates, edges=None):
super().__init__(name, coordinates, edges=edges, node_type='BusStop')
self._time_table = None
self._average_hourly_passengers_demand = None
self._fast_charging_infrastructure = None
self._waiting_time = None
@property
def time_table(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._time_table
@property
def average_hourly_passengers_demand(self) -> Schedule:
"""
Add explanation here
:return: Schedule
"""
return self._average_hourly_passengers_demand
@property
def fast_charging_infrastructure(self) -> Union[None, FastChargingInfrastructure]:
"""
Add explanation here
:return: FastChargingInfrastructure
"""
return self._fast_charging_infrastructure
@property
def waiting_time(self):
"""
Add explanation here
:return: add type of variable here
"""
return self._waiting_time

View File

@ -1,125 +0,0 @@
"""
Connection module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
import ast
from typing import Union
from hub.city_model_structure.attributes.edge import Edge
from hub.city_model_structure.transport.lane import Lane
class Connection:
"""
Connection class
"""
def __init__(self):
self._from_edge = None
self._to_edge = None
self._from_lane = None
self._to_lane = None
self._pass = None
self._keep_clear = None
@property
def from_edge(self) -> Edge:
"""
Get "from" edge
:return: Edge
"""
return self._from_edge
@from_edge.setter
def from_edge(self, value):
"""
Set "from" edge
:param value: Edge
"""
self._from_edge = value
@property
def to_edge(self) -> Edge:
"""
Get "to" edge
:return: Edge
"""
return self._to_edge
@to_edge.setter
def to_edge(self, value):
"""
Set "to" edge
:param value: Edge
"""
self._to_edge = value
@property
def from_lane(self) -> Lane:
"""
Get "from" lane
:return: Lane
"""
return self._to_lane
@from_lane.setter
def from_lane(self, value):
"""
Set "from" lane
:param value: Lane
"""
self._from_lane = value
@property
def to_lane(self) -> Lane:
"""
Get "to" lane
:return: Lane
"""
return self._to_lane
@to_lane.setter
def to_lane(self, value):
"""
Set "to" lane
:param value: Lane
"""
self._to_lane = value
@property
def pass_not_wait(self) -> Union[None, bool]:
"""
Get if the vehicles which pass this (lane to lane) connection will not wait
:return: None or Boolean
"""
return self._pass
@pass_not_wait.setter
def pass_not_wait(self, value):
"""
Set if the vehicles which pass this (lane to lane) connection will not wait
:param value: Boolean
"""
if value is not None:
self._pass = ast.literal_eval(value)
@property
def keep_clear(self) -> Union[None, bool]:
"""
Get if vehicles which pass this (lane to lane) connection should keep the intersection clear
:return: None or Boolean
"""
return self._keep_clear
@keep_clear.setter
def keep_clear(self, value):
"""
Set if vehicles which pass this (lane to lane) connection should keep the intersection clear
:param value: Boolean
"""
if value is not None:
self._keep_clear = ast.literal_eval(value)

View File

@ -1,74 +0,0 @@
"""
Crossing module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
import ast
from typing import List, Union
from hub.city_model_structure.transport.traffic_node import TrafficNode
class Crossing(TrafficNode):
"""
Crossing class
"""
def __init__(self, name, coordinates, priority, width, shape=None, edges=None):
super().__init__(name, coordinates, edges=edges, node_type='Crossing')
self._priority = priority
self._width = width
self._shape = shape
@property
def priority(self) -> Union[None, bool]:
"""
Get whether the pedestrians have priority over the vehicles
:return: None or bool
"""
return self._priority
@priority.setter
def priority(self, value):
"""
Set whether the pedestrians have priority over the vehicles
:param value: bool
"""
if value is not None:
self._priority = ast.literal_eval(value)
@property
def width(self) -> Union[None, float]:
"""
Get crossing width in meters
:return: None or float
"""
return self._width
@width.setter
def width(self, value):
"""
Set crossing width in meters
:param value: float
"""
if value is not None:
self._width = float(value)
@property
def shape(self) -> Union[None, List[List[float]]]:
"""
Get the list of positions
:return: None or [[x, y, (z)]]
"""
return self._shape
@shape.setter
def shape(self, value):
"""
Set the list of positions
:param value: [[x, y, (z)]]
"""
if value is not None:
self._shape = [[float(i) for i in value]]

View File

@ -1,27 +0,0 @@
"""
Join module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
from hub.city_model_structure.transport.traffic_node import TrafficNode
class Join(TrafficNode):
"""
Join class
"""
def __init__(self, name, coordinates, nodes):
self._nodes = nodes
edges = []
prohibitions = []
connections = []
for node in self._nodes:
edges = edges + node.edges
prohibitions = prohibitions + node.prohibitions
connections = connections + node.connections
super().__init__(name, coordinates, edges=edges, prohibitions=prohibitions, connections=connections,
node_type='Join')

View File

@ -1,144 +0,0 @@
"""
Lane module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List, Union
class Lane:
"""
Lane class
"""
def __init__(self):
self._index = None
self._allow = None
self._disallow = None
self._change_left = None
self._change_right = None
self._speed = None
self._width = None
@property
def index(self) -> Union[None, int]:
"""
Get lane index
The enumeration index of the lane (0 is the rightmost lane, <NUMBER_LANES>-1 is the leftmost one)
:return: None or int
"""
return self._index
@index.setter
def index(self, value):
"""
Set lane index
The enumeration index of the lane (0 is the rightmost lane, <NUMBER_LANES>-1 is the leftmost one)
:param value: int
"""
if value is not None:
self._index = int(value)
@property
def allow(self) -> Union[None, List[str]]:
"""
Get the list of allowed vehicle classes
:return: None or [str]
"""
return self._allow
@allow.setter
def allow(self, value):
"""
Set the list of allowed vehicle classes setter
:param value: [str]
"""
if value is not None:
self._allow = [str(i) for i in value]
@property
def disallow(self) -> Union[None, List[str]]:
"""
Get the list of not allowed vehicle classes
:return: None or [str]
"""
return self._disallow
@disallow.setter
def disallow(self, value):
"""
Get the list of not allowed vehicle classes setter
:param value: [str]
"""
if value is not None:
self._disallow = [str(i) for i in value]
@property
def change_left(self) -> Union[None, List[str]]:
"""
Get the list of vehicle classes that may change left from this lane
:return: None or [str]
"""
return self._change_left
@change_left.setter
def change_left(self, value):
"""
Set the list of vehicle classes that may change left from this lane
:param value: [str]
"""
if value is not None:
self._change_left = [str(i) for i in value]
@property
def change_right(self) -> Union[None, List[str]]:
"""
Get the list of vehicle classes that may change right from this lane
:return: None or [str]
"""
return self._change_right
@change_right.setter
def change_right(self, value):
"""
Set the list of vehicle classes that may change right from this lane
:param value: [str]
"""
if value is not None:
self._change_right = [str(i) for i in value]
@property
def speed(self) -> Union[None, float]:
"""
Get the lane speed in m/s
:return: None or float
"""
return self._speed
@speed.setter
def speed(self, value):
"""
Set the lane speed in m/s
:param value: float
"""
if value is not None:
self._speed = float(value)
@property
def width(self) -> Union[None, float]:
"""
Get the lane width in meters
:return: None or float
"""
return self._width
@width.setter
def width(self, value):
"""
Set the lane width in meters
:param value: float
"""
if value is not None:
self._width = float(value)

View File

@ -1,48 +0,0 @@
"""
Origin-Destination edge module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List, TypeVar
from hub.city_model_structure.attributes.edge import Edge
from hub.city_model_structure.attributes.schedule import Schedule
OriginDestinationNode = TypeVar('OriginDestinationNode')
class OriginDestinationEdge(Edge):
"""
OriginDestinationEdge class
Each edge is unidirectional and starts at the "from" node and ends at the "to" node
"""
def __init__(self, name, nodes, edge_type='OriginDestinationEdge'):
super().__init__(name, nodes)
self._edge_type = edge_type
self._movement_schedule = None
@property
def edge_type(self):
"""
Get the edge type
:return: str
"""
return self._edge_type
@property
def nodes(self) -> List[OriginDestinationNode]:
"""
Get delimiting nodes for the edge
:return: [OriginDestinationNode]
"""
return self._nodes
@property
def movement_schedule(self) -> Schedule:
"""
Get the schedule of the movement of people along this edge
:return: Schedule
"""
return self._movement_schedule

View File

@ -1,44 +0,0 @@
"""
Origin-Destination network module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List
from hub.city_model_structure.network import Network
from hub.city_model_structure.transport.origin_destination_edge import OriginDestinationEdge
from hub.city_model_structure.transport.origin_destination_node import OriginDestinationNode
class OriginDestinationNetwork(Network):
"""
OriginDestinationNetwork(Network) class
"""
def __init__(self, name, edges=None, nodes=None):
super().__init__(name, edges, nodes)
self._type = "OriginDestinationNetwork"
@property
def type(self):
"""
Get network type
:return: str
"""
return self._type
@property
def edges(self) -> List[OriginDestinationEdge]:
"""
Get network edges
:return: [OriginDestinationEdge]
"""
return self._edges
@property
def nodes(self) -> List[OriginDestinationNode]:
"""
Get network nodes
:return: [OriginDestinationNode]
"""
return self._nodes

View File

@ -1,85 +0,0 @@
"""
Origin-Destination node module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List, TypeVar
from hub.city_model_structure.attributes.node import Node
from hub.city_model_structure.attributes.point import Point
from hub.city_model_structure.attributes.polygon import Polygon
from hub.city_model_structure.city_object import CityObject
OriginDestinationEdge = TypeVar('OriginDestinationEdge')
class OriginDestinationNode(Node):
"""
OriginDestinationNode class
"""
def __init__(self, name, coordinates, node_type='OriginDestinationNode', edges=None, polygon=None):
super().__init__(name, edges)
self._coordinates = coordinates
self._node_type = node_type
self._polygon = polygon
self._land_use_types = None
self._city_objects = None
@property
def node_type(self):
"""
Get node type
:return: str
"""
return self._node_type
@property
def coordinates(self) -> Point:
"""
Get node coordinates
:return: Point
"""
return self._coordinates
@coordinates.setter
def coordinates(self, value):
"""
Set node coordinates
:param value: Point
"""
self._coordinates = value
@property
def edges(self) -> List[OriginDestinationEdge]:
"""
get edges delimited by the node
:return: [OriginDestinationEdge]
"""
return self._edges
@property
def polygon(self) -> Polygon:
"""
Get node polygon that defines the zone represented by the node
:return: Polygon
"""
return self._polygon
@property
def land_use_types(self) -> dict:
"""
Get land use types inside the node polygon. It returns a dictionary with the types of land use together with the
percentage of the land that corresponds to each type
:return: {string : float}
"""
return self._land_use_types
@property
def city_objects(self) -> List[CityObject]:
"""
Get the list of city objects place inside the zone
:return: List[CityObject]
"""
return self._city_objects

View File

@ -1,134 +0,0 @@
"""
Phase module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List, Union
class Phase:
"""
Phase class
"""
def __init__(self):
self._duration = None
self._state = None
self._min_duration = None
self._max_duration = None
self._name = None
self._next = None
@property
def duration(self) -> Union[None, int]:
"""
Get phase duration in seconds
:return: None or int
"""
return self._duration
@duration.setter
def duration(self, value):
"""
Set phase duration in seconds
:param value: int
"""
if value is not None:
self._duration = int(value)
@property
def state(self) -> Union[None, List[str]]:
"""
Get the list of signal states
:return: None or [str]
"""
return self._state
@state.setter
def state(self, value):
"""
Set the list of signal states
:param value: [str]
"""
if value is not None:
self._state = [str(i) for i in value]
@property
def min_duration(self) -> Union[None, int]:
"""
Get phase minimum duration in seconds
:return: None or int
"""
if self._min_duration is None:
self._min_duration = self._duration
return self._min_duration
@min_duration.setter
def min_duration(self, value):
"""
Set phase minimum duration in seconds
:param value: int
"""
if value is not None:
self._min_duration = int(value)
@property
def max_duration(self) -> Union[None, int]:
"""
Get phase maximum duration in seconds
:return: None or int
"""
if self._max_duration is None:
self._max_duration = self._duration
return self._max_duration
@max_duration.setter
def max_duration(self, value):
"""
Set phase maximum duration in seconds
:param value: int
"""
if value is not None:
self._max_duration = int(value)
@property
def name(self) -> Union[None, str]:
"""
Get phase name
:return: None or str
"""
return self._name
@name.setter
def name(self, value):
"""
Set phase name
:param value: str
"""
if value is not None:
self._name = str(value)
@property
def next(self) -> Union[None, List[int]]:
"""
Get the next phase in the cycle after the current.
This is useful when adding extra transition phases to a traffic light plan which are not part of every cycle.
Traffic lights of type 'actuated' can make use of a list of indices for selecting among alternative
successor phases.
:return: None or [int]
"""
return self._next
@next.setter
def next(self, value):
"""
Get the next phase in the cycle after the current.
This is useful when adding extra transition phases to a traffic light plan which are not part of every cycle.
Traffic lights of type 'actuated' can make use of a list of indices for selecting among alternative
successor phases.
:param value: [int]
"""
if value is not None:
self._next = [int(i) for i in value]

View File

@ -1,150 +0,0 @@
"""
Traffic edge module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
from typing import List, Union
from hub.city_model_structure.attributes.edge import Edge
from hub.city_model_structure.transport.traffic_node import TrafficNode
from hub.city_model_structure.transport.lane import Lane
class TrafficEdge(Edge):
"""
TrafficEdge class
Each edge is unidirectional and starts at the "from" node and ends at the "to" node
"""
def __init__(self, name, nodes, priority, speed, lanes, length, allows=None, disallows=None, sidewalk_width=None,
edge_type='TrafficEdge'):
super().__init__(name, nodes)
self._edge_type = edge_type
self._lanes = lanes
self._priority = priority
self._speed = speed
self._length = length
self._allows = allows
self._disallows = disallows
self._sidewalk_width = sidewalk_width
@property
def edge_type(self):
"""
Get the edge type
:return: str
"""
return self._edge_type
@property
def nodes(self) -> List[TrafficNode]:
"""
Get delimiting nodes for the edge
:return: [TrafficNode]
"""
return self._nodes
@property
def lanes(self) -> List[Lane]:
"""
Get the lanes on an edge
:return: List[Lane]
"""
return self._lanes
@lanes.setter
def lanes(self, value):
"""
Set the lanes on an edge
:param value: List[Lane]
"""
self._lanes = value
@property
def priority(self) -> Union[None, int]:
"""
Get the priority between different road types.
It starts with one; higher numbers represent more important roads.
:return: None or int
"""
return self._priority
@priority.setter
def priority(self, value):
"""
Set the priority between different road types.
It starts with one; higher numbers represent more important roads.
:param value: int
"""
if value is not None:
self._priority = int(value)
@property
def speed(self) -> Union[None, float]:
"""
Get he speed limit in m/s
:return: None or float
"""
return self._speed
@speed.setter
def speed(self, value):
"""
Set the speed limit in m/s
:param value: float
"""
if value is not None:
self._speed = float(value)
@property
def length(self) -> Union[None, float]:
"""
Get the lane length in meters
:return: None or float
"""
return self._length
@length.setter
def length(self, value):
"""
Set the lane length in meters
:param value: float
"""
if value is not None:
self._length = float(value)
@property
def allows(self) -> Union[None, List[str]]:
"""
Get the list of allowed vehicle classes
:return: None or [str]
"""
return self._allows
@allows.setter
def allows(self, value):
"""
Set the list of allowed vehicle classes
:param value: [str]
"""
if value is not None:
self._allows = [str(i) for i in value]
@property
def disallows(self) -> Union[None, List[str]]:
"""
Get the list of not allowed vehicle classes
:return: None or [str]
"""
return self._disallows
@disallows.setter
def disallows(self, value):
"""
Set the list of not allowed vehicle classes
:param value: [str]
"""
if value is not None:
self._disallows = [str(i) for i in value]

View File

@ -1,75 +0,0 @@
"""
Traffic light module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
import ast
from typing import List, Union
from hub.city_model_structure.transport.phase import Phase
from hub.city_model_structure.transport.traffic_node import TrafficNode
class TrafficLight(TrafficNode):
"""
Traffic light class
"""
def __init__(self, name, coordinates, offset, phases=None, edges=None, right_on_red=False):
super().__init__(name, coordinates, edges=edges, node_type='TrafficLight')
if phases is None:
phases = []
self._right_on_red = right_on_red
self._offset = offset
self._phases = phases
@property
def right_on_red(self) -> Union[None, bool]:
"""
Get if is possible to turn right when the traffic light is red
:return: None or Boolean
"""
return self._right_on_red
@right_on_red.setter
def right_on_red(self, value):
"""
Get if is possible to turn right when the traffic light is red
:param value: Boolean
"""
if value is not None:
self._right_on_red = ast.literal_eval(value)
@property
def offset(self) -> Union[None, int]:
"""
Get program initial time offset
:return: None or int
"""
return self._offset
@offset.setter
def offset(self, value):
"""
Set program initial time offset
:param value: int
"""
if value is not None:
self._offset = int(value)
@property
def phases(self) -> List[Phase]:
"""
Get traffic light logic phases
:return: [Phase]
"""
return self._phases
@phases.setter
def phases(self, value):
"""
Set traffic light logic phases
:param value: [Phase]
"""
self._phases = value

View File

@ -1,45 +0,0 @@
"""
Traffic network module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
from typing import List
from hub.city_model_structure.network import Network
from hub.city_model_structure.transport.traffic_edge import TrafficEdge
from hub.city_model_structure.transport.traffic_node import TrafficNode
class TrafficNetwork(Network):
"""
TrafficNetwork(Network) class
"""
def __init__(self, name, edges=None, nodes=None):
super().__init__(name, edges, nodes)
self._type = "TrafficNetwork"
@property
def type(self):
"""
Get network type
:return: str
"""
return self._type
@property
def edges(self) -> List[TrafficEdge]:
"""
Get network edges
:return: [TrafficEdge]
"""
return self._edges
@property
def nodes(self) -> List[TrafficNode]:
"""
Get network nodes
:return: [TrafficNode]
"""
return self._nodes

View File

@ -1,97 +0,0 @@
"""
TrafficNode module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
from typing import List, TypeVar
from hub.city_model_structure.attributes.edge import Edge
from hub.city_model_structure.attributes.node import Node
from hub.city_model_structure.attributes.point import Point
Connection = TypeVar('Connection')
TrafficEdge = TypeVar('TrafficEdge')
class TrafficNode(Node):
"""
TrafficNode class
"""
def __init__(self, name, coordinates, node_type='TrafficNode', edges=None, prohibitions=None, connections=None):
super().__init__(name, edges)
if connections is None:
connections = []
if prohibitions is None:
prohibitions = []
self._coordinates = coordinates
self._prohibitions = prohibitions
self._connections = connections
self._node_type = node_type
@property
def node_type(self):
"""
Get node type
:return: str
"""
return self._node_type
@property
def coordinates(self) -> Point:
"""
Get node coordinates
:return: Point
"""
return self._coordinates
@coordinates.setter
def coordinates(self, value):
"""
Set node coordinates
:param value: Point
"""
self._coordinates = value
@property
def edges(self) -> List[TrafficEdge]:
"""
get edges delimited by the node
:return: [TrafficEdge]
"""
return self._edges
@property
def prohibitions(self) -> [(Edge, Edge)]:
"""
Get node prohibitions
:return: [(Edge, Edge)]
"""
return self._prohibitions
@prohibitions.setter
def prohibitions(self, value):
"""
Set node prohibitions
:param value: [(Edge, Edge)]
"""
self._prohibitions = value
@property
def connections(self) -> List[Connection]:
"""
Get node connections
:return: [Connection]
"""
return self._connections
@connections.setter
def connections(self, value):
"""
Set node connections
:param value: [Connection]
"""
self._connections = value

View File

@ -1,37 +0,0 @@
"""
Walkway node module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille guille.gutierrezmorote@concordia.ca
"""
from typing import List, Union
from hub.city_model_structure.transport.traffic_node import TrafficNode
class WalkwayNode(TrafficNode):
"""
WalkwayNode class
"""
def __init__(self, name, coordinates, edges=None, shape=None):
super().__init__(name, coordinates, edges=edges, node_type='WalkwayNode')
self._shape = shape
@property
def shape(self) -> Union[None, List[List[float]]]:
"""
Get the list of positions
:return: None or [[x, y, (z)]]
"""
return self._shape
@shape.setter
def shape(self, value):
"""
Set the list of positions
:param value: [[x, y, (z)]]
"""
if value is not None:
self._shape = [[float(i) for i in value]]

View File

@ -448,22 +448,24 @@ class Idf:
def _add_infiltration(self, thermal_zone, zone_name):
schedule = f'Infiltration schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=thermal_zone.infiltration_rate_system_off
Air_Changes_per_Hour=_infiltration
)
def _add_ventilation(self, thermal_zone, zone_name):
schedule = f'Ventilation schedules {thermal_zone.usage_name}'
_air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._VENTILATION,
Name=f'{zone_name}_ventilation',
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=thermal_zone.mechanical_air_change
Air_Changes_per_Hour=_air_change
)
def _add_dhw(self, thermal_zone, zone_name):

View File

@ -167,11 +167,11 @@ class InselMonthlyEnergyBalance:
infiltration_day = 0
for value in schedule.values:
if value == 0:
infiltration_day += internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off / 24
infiltration_day += internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off / 24 * cte.HOUR_TO_SECONDS
ventilation_day += 0
else:
ventilation_value = usage.mechanical_air_change * value
infiltration_value = internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off * value
ventilation_value = usage.mechanical_air_change * value * cte.HOUR_TO_SECONDS
infiltration_value = internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off * value * cte.HOUR_TO_SECONDS
if ventilation_value >= infiltration_value:
ventilation_day += ventilation_value / 24
infiltration_day += 0
@ -225,7 +225,7 @@ class InselMonthlyEnergyBalance:
parameters.append(thermal_opening.overall_u_value)
parameters.append(thermal_opening.g_value)
if thermal_boundary.type is not cte.GROUND:
parameters.append(thermal_boundary.parent_surface.short_wave_reflectance)
parameters.append(thermal_boundary.external_surface.short_wave_reflectance)
else:
parameters.append(0.0)
file = InselMonthlyEnergyBalance._add_block(file, i_block, custom_insel_block, inputs=inputs, parameters=parameters)
@ -262,7 +262,7 @@ class InselMonthlyEnergyBalance:
global_irradiance = surface.global_irradiance[cte.MONTH]
for j in range(0, len(global_irradiance)):
parameters.append(f'{j + 1} '
f'{global_irradiance[j] / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
f'{global_irradiance[j] * cte.WATTS_HOUR_TO_JULES / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
else:
for j in range(0, 12):
parameters.append(f'{j + 1} 0.0')

View File

@ -66,8 +66,9 @@ class SimplifiedRadiosityAlgorithm:
else:
i = (total_days + day - 1) * 24 + hour - 1
representative_building = self._city.buildings[0]
content += f'{day} {month} {hour} {representative_building.global_horizontal[cte.HOUR][i]} ' \
f'{representative_building.beam[cte.HOUR][i]}\n'
_global = representative_building.global_horizontal[cte.HOUR][i] * cte.WATTS_HOUR_TO_JULES
_beam = representative_building.beam[cte.HOUR][i] * cte.WATTS_HOUR_TO_JULES
content += f'{day} {month} {hour} {_global} {_beam}\n'
with open(file, 'w', encoding='utf-8') as file:
file.write(content)

View File

@ -22,6 +22,7 @@ HOUR_TO_SECONDS = 3600
METERS_TO_FEET = 3.28084
BTU_H_TO_WATTS = 0.29307107
KILO_WATTS_HOUR_TO_JULES = 3600000
WATTS_HOUR_TO_JULES = 3600
GALLONS_TO_QUBIC_METERS = 0.0037854117954011185
# time

View File

@ -46,12 +46,11 @@ class LoadsCalculation:
load_renovation_sensible = 0
for usage in thermal_zone.usages:
load_renovation_sensible += cte.AIR_DENSITY * cte.AIR_HEAT_CAPACITY * usage.mechanical_air_change \
* thermal_zone.volume / cte.HOUR_TO_MINUTES / cte.MINUTES_TO_SECONDS \
* (internal_temperature - ambient_temperature)
* thermal_zone.volume * (internal_temperature - ambient_temperature)
load_infiltration_sensible = (
cte.AIR_DENSITY * cte.AIR_HEAT_CAPACITY * thermal_zone.infiltration_rate_system_off * thermal_zone.volume /
cte.HOUR_TO_MINUTES / cte.MINUTES_TO_SECONDS * (internal_temperature - ambient_temperature)
cte.AIR_DENSITY * cte.AIR_HEAT_CAPACITY * thermal_zone.infiltration_rate_system_off * thermal_zone.volume
* (internal_temperature - ambient_temperature)
)
load_ventilation = load_renovation_sensible + load_infiltration_sensible
@ -142,7 +141,7 @@ class LoadsCalculation:
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
for thermal_opening in thermal_boundary.thermal_openings:
radiation = thermal_boundary.parent_surface.global_irradiance[cte.HOUR][hour]
radiation = thermal_boundary.parent_surface.global_irradiance[cte.HOUR][hour] * cte.WATTS_HOUR_TO_JULES
cooling_load_radiation += (
thermal_opening.area * (1 - thermal_opening.frame_ratio) * thermal_opening.g_value * radiation
)

View File

@ -30,7 +30,7 @@ class InselMonthlyEnergyBalance:
demand = str(line).replace("['", '').replace("']", '').split()
for i in range(0, 2):
if demand[i] != 'NaN':
aux = float(demand[i]) * 1000 # kWh to Wh
aux = float(demand[i]) * cte.WATTS_HOUR_TO_JULES * 1000 # kWh to J
demand[i] = str(aux)
else:
demand[i] = '0'
@ -66,7 +66,8 @@ class InselMonthlyEnergyBalance:
for value in schedule.values:
total_day += value
for day_type in schedule.day_types:
total_lighting += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] * lighting_density
total_lighting += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] \
* lighting_density / cte.WATTS_HOUR_TO_JULES
lighting_demand.append(total_lighting * area)
for schedule in thermal_zone.appliances.schedules:
@ -74,7 +75,8 @@ class InselMonthlyEnergyBalance:
for value in schedule.values:
total_day += value
for day_type in schedule.day_types:
total_appliances += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] * appliances_density
total_appliances += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] \
* appliances_density / cte.WATTS_HOUR_TO_JULES
appliances_demand.append(total_appliances * area)
for schedule in thermal_zone.domestic_hot_water.schedules:
@ -83,7 +85,8 @@ class InselMonthlyEnergyBalance:
total_day += value
for day_type in schedule.day_types:
demand = (
peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY * (service_temperature - cold_water[month])
peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY
* (service_temperature - cold_water[month]) / cte.WATTS_HOUR_TO_JULES
)
total_dhw_demand += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] * demand
domestic_hot_water_demand.append(total_dhw_demand * area)
@ -97,14 +100,15 @@ class InselMonthlyEnergyBalance:
def enrich(self):
"""
Enrich the city by using the insel monthly energy balance output files
Enrich the city by using the insel monthly energy balance output files (J)
:return: None
"""
for building in self._city.buildings:
file_name = building.name + '.out'
insel_output_file_path = Path(self._base_path / file_name).resolve()
if insel_output_file_path.is_file():
building.heating_demand[cte.MONTH], building.cooling_demand[cte.MONTH] = self._conditioning_demand(insel_output_file_path)
building.heating_demand[cte.MONTH], building.cooling_demand[cte.MONTH] \
= self._conditioning_demand(insel_output_file_path)
building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])]
building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])]
self._dhw_and_electric_demand()

View File

@ -34,7 +34,7 @@ class SimplifiedRadiosityAlgorithm:
for key in self._results:
_irradiance = {}
header_name = key.split(':')
result = self._results[key]
result = [x / cte.WATTS_HOUR_TO_JULES for x in self._results[key]]
city_object_name = header_name[1]
building = self._city.city_object(city_object_name)
surface_id = header_name[2]

View File

@ -71,8 +71,7 @@ class ComnetUsageParameters:
# Due to the fact that python is not a typed language, the wrong object type is assigned to
# usage.occupancy when writing usage.occupancy = archetype.occupancy.
# Same happens for lighting and appliances. Therefore, this walk around has been done.
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area \
* cte.HOUR_TO_SECONDS
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area
_occupancy = Occupancy()
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain

View File

@ -71,8 +71,7 @@ class EilatUsageParameters:
# Due to the fact that python is not a typed language, the wrong object type is assigned to
# usage.occupancy when writing usage.occupancy = archetype.occupancy.
# Same happens for lighting and appliances. Therefore, this walk around has been done.
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area \
* cte.HOUR_TO_SECONDS
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area
_occupancy = Occupancy()
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain

View File

@ -92,11 +92,11 @@ class NrcanUsageParameters:
@staticmethod
def _assign_values(usage, archetype, volume_per_area, cold_water_temperature):
if archetype.mechanical_air_change > 0:
# ACH
# 1/s
usage.mechanical_air_change = archetype.mechanical_air_change
elif archetype.ventilation_rate > 0:
# m3/m2.s to ACH
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area * cte.HOUR_TO_SECONDS
# m3/m2.s to 1/s
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area
else:
usage.mechanical_air_change = 0
_occupancy = Occupancy()

View File

@ -110,16 +110,21 @@ class EpwWeatherParameters:
# new_value = pd.DataFrame(self._weather_values[['dry_bulb_temperature_c']].to_numpy(), columns=['epw'])
# number_invalid_records = new_value[new_value.epw == 99.9].count().epw
building.external_temperature[cte.HOUR] = self._weather_values['dry_bulb_temperature_c']
building.global_horizontal[cte.HOUR] = self._weather_values['global_horizontal_radiation_wh_m2']
building.diffuse[cte.HOUR] = self._weather_values['diffuse_horizontal_radiation_wh_m2']
building.beam[cte.HOUR] = self._weather_values['direct_normal_radiation_wh_m2']
building.global_horizontal[cte.HOUR] = [x / cte.WATTS_HOUR_TO_JULES
for x in self._weather_values['global_horizontal_radiation_wh_m2']]
building.diffuse[cte.HOUR] = [x / cte.WATTS_HOUR_TO_JULES
for x in self._weather_values['diffuse_horizontal_radiation_wh_m2']]
building.beam[cte.HOUR] = [x / cte.WATTS_HOUR_TO_JULES
for x in self._weather_values['direct_normal_radiation_wh_m2']]
building.cold_water_temperature[cte.HOUR] = wh().cold_water_temperature(building.external_temperature[cte.HOUR])
# create the monthly and yearly values out of the hourly
for building in self._city.buildings:
building.external_temperature[cte.MONTH] = MonthlyValues().get_mean_values(building.external_temperature[cte.HOUR])
building.external_temperature[cte.MONTH] = \
MonthlyValues().get_mean_values(building.external_temperature[cte.HOUR])
building.external_temperature[cte.YEAR] = [sum(building.external_temperature[cte.HOUR]) / 9870]
building.cold_water_temperature[cte.MONTH] = MonthlyValues().get_mean_values(building.cold_water_temperature[cte.HOUR])
building.cold_water_temperature[cte.MONTH] = \
MonthlyValues().get_mean_values(building.cold_water_temperature[cte.HOUR])
building.cold_water_temperature[cte.YEAR] = [sum(building.cold_water_temperature[cte.HOUR]) / 9870]
# If the usage has already being imported, the domestic hot water missing values must be calculated here that

View File

@ -51,7 +51,7 @@ class TestExports(TestCase):
_irradiance = {}
for key in self._results:
header_name = key.split(':')
result = self._results[key]
result = [x / cte.WATTS_HOUR_TO_JULES for x in self._results[key]]
city_object_name = header_name[1]
building = self._city.city_object(city_object_name)
surface_id = header_name[2]

View File

@ -245,8 +245,10 @@ TestDBFactory
cte.MONTH]
yearly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[
cte.YEAR]
monthly_on_site_electrical_production = building.onsite_electrical_production[cte.MONTH]
yearly_on_site_electrical_production = building.onsite_electrical_production[cte.YEAR]
monthly_on_site_electrical_production = [x * cte.WATTS_HOUR_TO_JULES
for x in building.onsite_electrical_production[cte.MONTH]]
yearly_on_site_electrical_production = [x * cte.WATTS_HOUR_TO_JULES
for x in building.onsite_electrical_production[cte.YEAR]]
results = json.dumps({cte.INSEL_MEB: [
{'monthly_cooling_peak_load': monthly_cooling_peak_load},
{'yearly_cooling_peak_load': yearly_cooling_peak_load},

View File

@ -51,7 +51,7 @@ class TestExports(TestCase):
_irradiance = {}
for key in self._results:
header_name = key.split(':')
result = self._results[key]
result = [x / cte.WATTS_HOUR_TO_JULES for x in self._results[key]]
city_object_name = header_name[1]
building = self._city.city_object(city_object_name)
surface_id = header_name[2]

View File

@ -115,4 +115,4 @@ class TestSystemsFactory(TestCase):
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])