diff --git a/city_model_structure/EnergySystem.py b/city_model_structure/EnergySystem.py new file mode 100644 index 00000000..6df539d6 --- /dev/null +++ b/city_model_structure/EnergySystem.py @@ -0,0 +1,22 @@ +""" +EnergySystem module +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + +from city_model_structure.city_object import CityObject +from city_model_structure.energy_systems.heat_pump import HeatPump + + +class EnergySystem(CityObject): + """ + EnergySystem(CityObject) class + """ + def __init__(self, name, lod, surfaces, city_lower_corner): + super().__init__(name, lod, surfaces, city_lower_corner) + self._heat_pump = None + + @property + def heat_pump(self) -> HeatPump: + return self._heat_pump + diff --git a/city_model_structure/building.py b/city_model_structure/building.py index 7605dc03..9e144141 100644 --- a/city_model_structure/building.py +++ b/city_model_structure/building.py @@ -13,6 +13,7 @@ from city_model_structure.building_demand.thermal_boundary import ThermalBoundar from city_model_structure.building_demand.usage_zone import UsageZone from city_model_structure.building_demand.storey import Storey from city_model_structure.city_object import CityObject +from city_model_structure.building_demand.household import Household class Building(CityObject): @@ -22,6 +23,7 @@ class Building(CityObject): def __init__(self, name, lod, surfaces, year_of_construction, function, city_lower_corner, terrains=None): super().__init__(name, lod, surfaces, city_lower_corner) + self._households = None self._basement_heated = None self._attic_heated = None self._terrains = terrains @@ -352,3 +354,11 @@ class Building(CityObject): else: self._thermal_boundaries.append(thermal_boundary) return self._thermal_boundaries + + @property + def households(self) -> List[Household]: + """ + Get the list of households inside the building + :return: List[Household] + """ + return self._households diff --git a/city_model_structure/building_demand/household.py b/city_model_structure/building_demand/household.py new file mode 100644 index 00000000..251c8dbd --- /dev/null +++ b/city_model_structure/building_demand/household.py @@ -0,0 +1,31 @@ +""" +Household module +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + + +class Household: + """ + Household class + """ + + def __init__(self): + self._number_of_people = None + self._number_of_cars = None + + @property + def number_of_people(self): + """ + Get number of people leaving in the household + :return: int + """ + return self._number_of_people + + @property + def number_of_cars(self): + """ + Get number of cars owned by the householders + :return: int + """ + return self._number_of_cars diff --git a/city_model_structure/energy_systems/heat_pump.py b/city_model_structure/energy_systems/heat_pump.py index 753fa2ee..7c22f0b3 100644 --- a/city_model_structure/energy_systems/heat_pump.py +++ b/city_model_structure/energy_systems/heat_pump.py @@ -12,39 +12,35 @@ class HeatPump: HeatPump class """ def __init__(self): - self._seasonal_mean_cop = None - self._seasonal_mean_coverage_factor = None + self._model = None + self._cooling_pf = None + self._cooling_pa = None + self._cooling_qw = None + self._heating_pf = None + self._heating_pa = None + self._heating_qw = None @property - def seasonal_mean_cop(self) -> Union[None, float]: + def model(self): """ - Get seasonal mean COP (-) - :return: None or float + Get model name + :return: str """ - return self._seasonal_mean_cop - - @seasonal_mean_cop.setter - def seasonal_mean_cop(self, value): - """ - Set seasonal mean COP (-) - :param value: float - """ - if value is not None: - self._seasonal_mean_cop = float(value) + return self._model @property - def seasonal_mean_coverage_factor(self) -> Union[None, float]: + def cooling_pf(self): """ - Get percentage of demand covered by the hp (-) - :return: None or float + Get cooling capacity in kW + :return: [[float]] """ - return self._seasonal_mean_coverage_factor + return self._cooling_pf - @seasonal_mean_coverage_factor.setter - def seasonal_mean_coverage_factor(self, value): + @cooling_pf.setter + def cooling_pf(self, value): """ - Set percentage of demand covered by the hp (-) - :return: float + Set cooling capacity in kW + :param value: [[float]] """ - if value is not None: - self._seasonal_mean_coverage_factor = float(value) + if self._cooling_pf is None: + self._cooling_pf = value diff --git a/city_model_structure/transport/origin_destination_edge.py b/city_model_structure/transport/origin_destination_edge.py new file mode 100644 index 00000000..c3d3f3c1 --- /dev/null +++ b/city_model_structure/transport/origin_destination_edge.py @@ -0,0 +1,37 @@ +""" +Origin-Destination edge module +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca + +""" + +from city_model_structure.attributes.edge import Edge +from city_model_structure.attributes.schedule import Schedule + + +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 movement_schedule(self) -> Schedule: + """ + Get the schedule of the movement of people along this edge + :return: Schedule + """ + return self._movement_schedule diff --git a/city_model_structure/transport/origin_destination_network.py b/city_model_structure/transport/origin_destination_network.py new file mode 100644 index 00000000..b23bb01c --- /dev/null +++ b/city_model_structure/transport/origin_destination_network.py @@ -0,0 +1,24 @@ +""" +Origin-Destination network module +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + +from city_model_structure.network import Network + + +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 diff --git a/city_model_structure/transport/origin_destination_node.py b/city_model_structure/transport/origin_destination_node.py new file mode 100644 index 00000000..5e46e92d --- /dev/null +++ b/city_model_structure/transport/origin_destination_node.py @@ -0,0 +1,74 @@ +""" +Origin-Destination node module +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" +from typing import List + +from city_model_structure.attributes.node import Node +from city_model_structure.attributes.point import Point +from city_model_structure.attributes.polygon import Polygon +from city_model_structure.city_object import CityObject + + +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 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 diff --git a/city_model_structure/transport/traffic_edge.py b/city_model_structure/transport/traffic_edge.py index 5f8578e5..1fd77299 100644 --- a/city_model_structure/transport/traffic_edge.py +++ b/city_model_structure/transport/traffic_edge.py @@ -1,5 +1,5 @@ """ -Edge module +Traffic edge module SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Contributor Milad milad.aghamohamadnia@concordia.ca @@ -13,7 +13,7 @@ from city_model_structure.transport.lane import Lane class TrafficEdge(Edge): """ - Edge class + TrafficEdge class Each edge is unidirectional and starts at the "from" node and ends at the "to" node """ diff --git a/city_model_structure/transport/traffic_network.py b/city_model_structure/transport/traffic_network.py index 5b5406d1..27e30096 100644 --- a/city_model_structure/transport/traffic_network.py +++ b/city_model_structure/transport/traffic_network.py @@ -11,7 +11,7 @@ from city_model_structure.network import Network class TrafficNetwork(Network): """ - TrafficNetwork(CityObject) class + TrafficNetwork(Network) class """ def __init__(self, name, edges=None, nodes=None): super().__init__(name, edges, nodes) diff --git a/city_model_structure/transport/traffic_node.py b/city_model_structure/transport/traffic_node.py index 375660bb..3008cf97 100644 --- a/city_model_structure/transport/traffic_node.py +++ b/city_model_structure/transport/traffic_node.py @@ -1,5 +1,5 @@ """ -Node module +TrafficNode module SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Contributor Milad milad.aghamohamadnia@concordia.ca @@ -17,7 +17,7 @@ from city_model_structure.transport.connection import Connection class TrafficNode(Node): """ - Node class + TrafficNode class """ def __init__(self, name, coordinates, node_type='TrafficNode', edges=None, prohibitions=None, connections=None): diff --git a/data/energy_systems/heat_pumps/Air Source.xlsx b/data/energy_systems/heat_pumps/Air Source.xlsx new file mode 100644 index 00000000..c0ea122f Binary files /dev/null and b/data/energy_systems/heat_pumps/Air Source.xlsx differ diff --git a/imports/energy_systems/xlsx_heat_pump_parameters.py b/imports/energy_systems/xlsx_heat_pump_parameters.py new file mode 100644 index 00000000..a93e52d3 --- /dev/null +++ b/imports/energy_systems/xlsx_heat_pump_parameters.py @@ -0,0 +1,26 @@ +""" +XlsxHeatPumpParameters import the heat pump information +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author +Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + + +class XlsxHeatPumpParameters: + """ + XlsxHeatPumpParameters class + """ + def __init__(self, city, base_path): + self._city = city + self._base_path = (base_path / 'heat_pumps/Air source.xlsx') + + def _read_file(self): + """ + reads xlsx file containing the heat pump information + """ + + def enrich_city(self): + """ + Enriches the city with information from file + """ + return self._city diff --git a/imports/energy_systems_factory.py b/imports/energy_systems_factory.py new file mode 100644 index 00000000..ecc2f30d --- /dev/null +++ b/imports/energy_systems_factory.py @@ -0,0 +1,33 @@ +""" +EnergySystemsFactory retrieve the energy system module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete pilar.monsalvete@concordi.ca +""" +from pathlib import Path +from imports.energy_systems.xlsx_heat_pump_parameters import XlsxHeatPumpParameters + + +class EnergySystemsFactory: + """ + EnergySystemsFactory class + """ + def __init__(self, handler, city, base_path=None): + if base_path is None: + base_path = Path(Path(__file__).parent.parent / 'data/energy_systems') + self._handler = '_' + handler.lower().replace(' ', '_') + self._city = city + self._base_path = base_path + + def _xlsxheatpump(self): + """ + Enrich the city by using xlsx heat pump information + """ + XlsxHeatPumpParameters(self._city, self._base_path).enrich_city() + + def enrich(self): + """ + Enrich the city given to the class using the class given handler + :return: None + """ + getattr(self, self._handler, lambda: None)() + diff --git a/imports/usage/ashrae_usage_parameters.py b/imports/usage/ashrae_usage_parameters.py new file mode 100644 index 00000000..1bfb98bd --- /dev/null +++ b/imports/usage/ashrae_usage_parameters.py @@ -0,0 +1,55 @@ +""" +AshraeUsageParameters model the usage properties +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" +import sys + +from imports.geometry.helpers.geometry_helper import GeometryHelper as gh +from city_model_structure.building_demand.usage_zone import UsageZone + + +class AshraeUsageParameters: + """ + AshraeUsageParameters class + """ + def __init__(self, city, base_path): + super().__init__(base_path, 'ashrae_archetypes.xml') + self._city = city + self._usage_archetypes = None + + def enrich_buildings(self): + """ + Returns the city with the usage parameters assigned to the buildings + :return: + """ + city = self._city + for building in city.buildings: + archetype = self._search_archetype(building.function) + if archetype is None: + sys.stderr.write(f'Building {building.name} has unknown archetype for building function:' + f' {building.function}, that assigns building usage as ' + f'{gh.usage_from_function(building.function)}\n') + continue + # todo: what to do with mix-usage usage from gml? + mix_usage = False + if not mix_usage: + # just one usage_zone + for thermal_zone in building.thermal_zones: + usage_zone = UsageZone() + usage_zone.volume = thermal_zone.volume + self._assign_values(usage_zone, archetype) + thermal_zone.usage_zones = [usage_zone] + + def _search_archetype(self, building_usage): + for building_archetype in self._usage_archetypes: + if building_archetype.usage == building_usage: + return building_archetype + return None + + @staticmethod + def _assign_values(usage_zone, archetype): + usage_zone.usage = archetype.usage + usage_zone.occupancy_density = archetype.occupancy_density + # todo: should I use this value: self._min_air_change?? + usage_zone.minimum_ventilation_rate = archetype.minimum_ventilation_rate diff --git a/imports/usage_factory.py b/imports/usage_factory.py index 8e99c6e9..763a6dba 100644 --- a/imports/usage_factory.py +++ b/imports/usage_factory.py @@ -3,11 +3,12 @@ UsageFactory retrieve the specific usage module for the given region This factory can only be called after calling the construction factory so the thermal zones are created. SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ from pathlib import Path from imports.usage.hft_usage_parameters import HftUsageParameters from imports.usage.ca_usage_parameters import CaUsageParameters - +from imports.usage.ashrae_usage_parameters import AshraeUsageParameters # todo: handle missing lambda and rise error. @@ -38,6 +39,12 @@ class UsageFactory: """ return CaUsageParameters(self._city, self._base_path).enrich_buildings() + def _ashrae(self): + """ + Enrich the city by using ASHRAE information + """ + AshraeUsageParameters(self._city, self._base_path).enrich_buildings() + def enrich(self): """ Enrich the city given to the class using the usage factory given handler