Merge remote-tracking branch 'origin/geojson' into geojson

This commit is contained in:
Pilar Monsalvete 2023-04-25 10:00:18 -04:00
commit a3f0478558
35 changed files with 27963 additions and 2146 deletions

View File

@ -20,7 +20,7 @@ from hub.catalog_factories.data_models.cost.cost_helper import CostHelper
class MontrealCustomCatalog(Catalog): class MontrealCustomCatalog(Catalog):
def __init__(self, path): def __init__(self, path):
path = str(path / 'montreal_costs.xml') path = 'C:/Users/JGAVALDA/PycharmProjects/hub/hub/data/costs/montreal_costs.xml'
with open(path) as xml: with open(path) as xml:
self._archetypes = xmltodict.parse(xml.read(), force_list='archetype') self._archetypes = xmltodict.parse(xml.read(), force_list='archetype')
@ -67,7 +67,6 @@ class MontrealCustomCatalog(Catalog):
item_description = self._item_with_refurbishment_values(shell['B30_roofing'], item_type) item_description = self._item_with_refurbishment_values(shell['B30_roofing'], item_type)
items_list.append(item_description) items_list.append(item_description)
general_chapters.append(Chapter('B_shell', items_list)) general_chapters.append(Chapter('B_shell', items_list))
items_list = [] items_list = []
item_type = 'D301010_photovoltaic_system' item_type = 'D301010_photovoltaic_system'
services = entry['D_services'] services = entry['D_services']
@ -82,7 +81,6 @@ class MontrealCustomCatalog(Catalog):
item_description = self._item_with_threesome(services['D50_electrical'], item_type) item_description = self._item_with_threesome(services['D50_electrical'], item_type)
items_list.append(item_description) items_list.append(item_description)
general_chapters.append(Chapter('D_services', items_list)) general_chapters.append(Chapter('D_services', items_list))
allowances = entry['Z_allowances_overhead_profit'] allowances = entry['Z_allowances_overhead_profit']
design_allowance = float(allowances['Z10_design_allowance']['#text']) / 100 design_allowance = float(allowances['Z10_design_allowance']['#text']) / 100
overhead_and_profit = float(allowances['Z20_overhead_profit']['#text']) / 100 overhead_and_profit = float(allowances['Z20_overhead_profit']['#text']) / 100
@ -127,9 +125,9 @@ class MontrealCustomCatalog(Catalog):
for archetype in archetypes: for archetype in archetypes:
function = archetype['@function'] function = archetype['@function']
municipality = archetype['@municipality'] municipality = archetype['@municipality']
country = archetype['@country'] country = 'CA'#archetype['@country']
lod = float(archetype['@lod']) lod = 0 #float(archetype['@lod'])
currency = archetype['currency'] currency = 'CAD'#archetype['currency']
capital_cost = self._get_capital_costs(archetype['capital_cost']) capital_cost = self._get_capital_costs(archetype['capital_cost'])
operational_cost = self._get_operational_costs(archetype['operational_cost']) operational_cost = self._get_operational_costs(archetype['operational_cost'])
end_of_life_cost = float(archetype['end_of_life_cost']['#text']) end_of_life_cost = float(archetype['end_of_life_cost']['#text'])

View File

@ -19,7 +19,7 @@ class CostCatalogFactory:
""" """
def __init__(self, file_type, base_path=None): def __init__(self, file_type, base_path=None):
if base_path is None: if base_path is None:
base_path = Path(Path(__file__).parent.parent / 'data/costs') base_path = 'C:/Users/JGAVALDA/PycharmProjects/hub/hub/data/costs'
self._catalog_type = '_' + file_type.lower() self._catalog_type = '_' + file_type.lower()
self._path = base_path self._path = base_path

View File

@ -18,6 +18,8 @@ class ThermalControl:
hvac_availability_schedules, hvac_availability_schedules,
heating_set_point_schedules, heating_set_point_schedules,
cooling_set_point_schedules): cooling_set_point_schedules):
#todo: eliminate negative value
deltaTsetpoint=0
self._mean_heating_set_point = mean_heating_set_point self._mean_heating_set_point = mean_heating_set_point
self._heating_set_back = heating_set_back self._heating_set_back = heating_set_back
self._mean_cooling_set_point = mean_cooling_set_point self._mean_cooling_set_point = mean_cooling_set_point

View File

@ -49,7 +49,8 @@ class NrcanCatalog(Catalog):
hvac_schedule_name = space_type['exhaust_schedule'] hvac_schedule_name = space_type['exhaust_schedule']
if 'FAN' in hvac_schedule_name: if 'FAN' in hvac_schedule_name:
hvac_schedule_name = hvac_schedule_name.replace('FAN', 'Fan') hvac_schedule_name = hvac_schedule_name.replace('FAN', 'Fan')
heating_setpoint_schedule_name = space_type['heating_setpoint_schedule'] #todo: get -1 out of the setpoint
heating_setpoint_schedule_name = space_type['heating_setpoint_schedule']-1
cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule'] cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule']
occupancy_schedule = self._get_schedules(occupancy_schedule_name) occupancy_schedule = self._get_schedules(occupancy_schedule_name)
lighting_schedule = self._get_schedules(lighting_schedule_name) lighting_schedule = self._get_schedules(lighting_schedule_name)

View File

@ -130,11 +130,11 @@ class NrcanCatalog(Catalog):
# ACH # ACH
mechanical_air_change = space_type['ventilation_air_changes'] mechanical_air_change = space_type['ventilation_air_changes']
# cfm/ft2 to m3/m2.s # cfm/ft2 to m3/m2.s
ventilation_rate = space_type['ventilation_per_area'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS) ventilation_rate = space_type['ventilation_per_area'] * cte.CUBICFEET_TO_CUBIC_METERS_HOUR
if ventilation_rate == 0: if ventilation_rate == 0:
# cfm/person to m3/m2.s # cfm/person to m3/m2.s
ventilation_rate = space_type['ventilation_per_person'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)\ ventilation_rate = space_type['ventilation_per_person'] * cte.CUBICFEET_TO_CUBIC_METERS_HOUR\
/ occupancy_density * occupancy_density
lighting_radiative_fraction = space_type['lighting_fraction_radiant'] lighting_radiative_fraction = space_type['lighting_fraction_radiant']
lighting_convective_fraction = 0 lighting_convective_fraction = 0

View File

@ -44,6 +44,8 @@ class Building(CityObject):
self._lighting_electrical_demand = dict() self._lighting_electrical_demand = dict()
self._appliances_electrical_demand = dict() self._appliances_electrical_demand = dict()
self._domestic_hot_water_heat_demand = dict() self._domestic_hot_water_heat_demand = dict()
self._heating_peak_load = dict()
self._cooling_peak_load = dict()
self._eave_height = None self._eave_height = None
self._grounds = [] self._grounds = []
self._roofs = [] self._roofs = []
@ -362,6 +364,38 @@ class Building(CityObject):
""" """
self._domestic_hot_water_heat_demand = value self._domestic_hot_water_heat_demand = value
@property
def heating_peak_load(self) -> dict:
"""
Get heating peak load in W
:return: dict{DataFrame(float)}
"""
return self._heating_peak_load
@heating_peak_load.setter
def heating_peak_load(self, value):
"""
Set heating peak load in W
:param value: dict{DataFrame(float)}
"""
self._heating_peak_load = value
@property
def cooling_peak_load(self) -> dict:
"""
Get cooling peak load in W
:return: dict{DataFrame(float)}
"""
return self._cooling_peak_load
@cooling_peak_load.setter
def cooling_peak_load(self, value):
"""
Set peak load in W
:param value: dict{DataFrame(float)}
"""
self._cooling_peak_load = value
@property @property
def eave_height(self): def eave_height(self):
""" """

View File

@ -603,9 +603,11 @@ class ThermalZone:
_mean_peak_flow = 0 _mean_peak_flow = 0
_mean_service_temperature = 0 _mean_service_temperature = 0
for usage in self.usages: for usage in self.usages:
_mean_peak_density_load += usage.percentage * usage.domestic_hot_water.density #todo: change hardcoded density DHW
#_mean_peak_density_load += usage.percentage * 1 #usage.domestic_hot_water.density
_mean_peak_flow += usage.percentage * usage.domestic_hot_water.peak_flow _mean_peak_flow += usage.percentage * usage.domestic_hot_water.peak_flow
_mean_service_temperature += usage.percentage * usage.domestic_hot_water.service_temperature # todo: change hardcoded service temperature
_mean_service_temperature += usage.percentage * 45
self._domestic_hot_water.density = _mean_peak_density_load self._domestic_hot_water.density = _mean_peak_density_load
self._domestic_hot_water.peak_flow = _mean_peak_flow self._domestic_hot_water.peak_flow = _mean_peak_flow
self._domestic_hot_water.service_temperature = _mean_service_temperature self._domestic_hot_water.service_temperature = _mean_service_temperature
@ -630,6 +632,7 @@ class ThermalZone:
schedule.values = new_values schedule.values = new_values
_schedules.append(schedule) _schedules.append(schedule)
self._domestic_hot_water.schedules = _schedules self._domestic_hot_water.schedules = _schedules
return self._domestic_hot_water return self._domestic_hot_water
@property @property

View File

@ -110,6 +110,14 @@ class CityObject:
""" """
return self._surfaces return self._surfaces
@surfaces.setter
def surfaces(self, value):
"""
Set city object surfaces
:return: [Surface]
"""
self._surfaces = value
def surface(self, name) -> Union[Surface, None]: def surface(self, name) -> Union[Surface, None]:
""" """
Get the city object surface with a given name Get the city object surface with a given name

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,166 @@
<archetypes>
<archetype function="residential" municipality="montreal" currency="CAD">
<capital_cost>
<ASubstructure>
<A10sub_structural cost_unit="currency/m2"> 15.89 </A10sub_structural>
<A20structural cost_unit="currency/m3"> 215.90 </A20structural>
</ASubstructure>
<BShell>
<B10superstructure>
<reposition cost_unit="currency/m2"> 0 </reposition>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</B10superstructure>
<B20envelope>
<B2010opaquewalls>
<reposition cost_unit="currency/m2"> 304 </reposition>
<initial_investment cost_unit="currency/m2"> 304 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</B2010opaquewalls>
<B2020transparent>
<reposition cost_unit="currency/m2"> 857.14 </reposition>
<initial_investment cost_unit="currency/m2"> 857.14 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</B2020transparent>
</B20envelope>
<B30roofing>
<B3010opaqueroof>
<reposition cost_unit="currency/m2"> 118 </reposition>
<initial_investment cost_unit="currency/m2"> 118 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</B3010opaqueroof>
<B3020transparentroof>
<reposition cost_unit="currency/m2"> 857.14 </reposition>
<initial_investment cost_unit="currency/m2"> 857.14 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</B3020transparentroof>
</B30roofing>
</BShell>
<CInteriors>
<C10Interiorconstruction>
<reposition cost_unit="currency/m2"> 0 </reposition>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</C10Interiorconstruction>
<C20Stairs>
<reposition cost_unit="currency/m2"> 0 </reposition>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</C20Stairs>
<C30Interiorfinishes>
<C3010Walls>
<reposition cost_unit="currency/m2"> 50 </reposition>
<initial_investment cost_unit="currency/m2"> 50 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</C3010Walls>
<C3020Floors>
<reposition cost_unit="currency/m2"> 62 </reposition>
<initial_investment cost_unit="currency/m2"> 62 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</C3020Floors>
<C3030Ceilings>
<reposition cost_unit="currency/m2"> 70 </reposition>
<initial_investment cost_unit="currency/m2"> 70 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</C3030Ceilings>
</C30Interiorfinishes>
</CInteriors>
<DServices>
<D10Conveying cost_unit="currency/m2"> 0 </D10Conveying>
<D20Plumbing cost_unit="currency/m2"> 100 </D20Plumbing>
<D30HVAC>
<D3010EnergySupply>
<D301010photovoltaic_system>
<initial_investment cost_unit="currency/m2"> 800 </initial_investment>
<reposition cost_unit="currency/m2"> 800 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D301010photovoltaic_system>
</D3010EnergySupply>
<D3020Heatgeneratingsystems>
<initial_investment cost_unit="currency/kW"> 622.86 </initial_investment>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D3020Heatgeneratingsystems>
<D3030Coolinggenerationsystems>
<initial_investment cost_unit="currency/kW"> 622.86 </initial_investment>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3030Coolinggenerationsystems>
<D3040Distributionsystems>
<initial_investment cost_unit="currency/kW"> 0 </initial_investment>
<reposition cost_unit="currency/kW"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3040Distributionsystems>
<D3060Controlsandinstrumentation>
<initial_investment cost_unit="currency/kW"> 0 </initial_investment>
<reposition cost_unit="currency/kW"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3060Controlsandinstrumentation>
<D3080OtherHVAC_AHU>
<initial_investment cost_unit="currency/kW"> 47.62 </initial_investment>
<reposition cost_unit="currency/kW"> 47.62 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3080OtherHVAC_AHU>
</D30HVAC>
<D50Electrical>
<D5010Electricalservicesanddistribution>
<initial_investment cost_unit="currency/m2"> 171.43 </initial_investment>
<reposition cost_unit="currency/m2"> 171.43 </reposition>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</D5010Electricalservicesanddistribution>
<D5020Lightingandbranchwiring>
<initial_investment cost_unit="currency/kW"> 139 </initial_investment>
<reposition cost_unit="currency/kW"> 139 </reposition>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</D5020Lightingandbranchwiring>
</D50Electrical>
</DServices>
<EEquimentsandfurnishing>
<E10Equipments>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<reposition cost_unit="currency/m2"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</E10Equipments>
<E10Furnishing>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<reposition cost_unit="currency/m2"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</E10Furnishing>
</EEquimentsandfurnishing>
<engineer cost_unit="%"> 2.5 </engineer>
</capital_cost>
<operational_cost>
<fuel fuel_type="electricity">
<fixed>
<fixed_monthly cost_unit="currency/month"> 0 </fixed_monthly>
<fixed_power cost_unit="currency/kW"> 0 </fixed_power>
</fixed>
<variable cost_unit="currency/kWh"> 5.6 </variable>
</fuel>
<maintenance>
<heating_equipment cost_unit="currency/kW"> 40 </heating_equipment>
<cooling_equipment cost_unit="currency/kW"> 40 </cooling_equipment>
<general_hvac_equipment cost_unit="currency/(m3/h)"> 0.05 </general_hvac_equipment>
<photovoltaic_system cost_unit="currency/m2"> 1 </photovoltaic_system>
<other_systems cost_unit="currency/m2"> 4.6 </other_systems>
</maintenance>
<CO2_cost cost_unit="currency/kgCO2"> 30 </CO2_cost>
</operational_cost>
<end_of_life_cost cost_unit="currency/m2"> 6.3 </end_of_life_cost>
<incomes>
<subsidies>
<construction_subsidy cost_unit="%"> 2 </construction_subsidy>
<hvac_subsidy cost_unit="%"> 1.5 </hvac_subsidy>
<photovoltaic_subsidy cost_unit="%"> 3.6 </photovoltaic_subsidy>
</subsidies>
<energy_exports>
<electricity cost_unit="currency/kWh"> hourlydatatable </electricity>
<heat cost_unit="currency/kWh"> 0 </heat>
</energy_exports>
<tax_reductions>
<reductions_taxes cost_unit="%"> 2 </reductions_taxes>
</tax_reductions>
<CO2_income cost_unit="currency/kgCO2exported"> 0 </CO2_income>
</incomes>
</archetype>
</archetypes>

View File

@ -0,0 +1,212 @@
<archetypes>
<archetype function="residential" municipality="montreal" currency="CAD">
<capital_cost>
<B_Shell>
<B10_superstructure>
<refurbishment_cost_basement cost_unit="currency/m2"> 0 </refurbishment_cost_basement>
</B10_superstructure>
<B20_envelope>
<B2010_opaquewalls>
<refurbishment_cost cost_unit="currency/m2"> 304 </refurbishment_cost>
</B2010_opaquewalls>
<B2020_transparent>
<refurbishment_cost cost_unit="currency/m2"> 857.14 </refurbishment_cost>
</B2020_transparent>
</B20_envelope>
<B30_roofing>
<B3010_opaqueroof>
<refurbishment_cost cost_unit="currency/m2"> 118 </refurbishment_cost>
</B3010_opaqueroof>
</B30_roofing>
</B_Shell>
<D_Services>
<D30_HVAC>
<D3010_EnergySupply>
<D301010_Photovoltaic_system>
<initial_investment cost_unit="currency/m2"> 800 </initial_investment>
<reposition cost_unit="currency/m2"> 800 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D301010_Photovoltaic_system>
</D3010_EnergySupply>
<D3020_Heat_generating_systems>
<investment_cost cost_unit="currency/kW"> 622.86 </investment_cost>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D3020_Heat_generating_systems>
<D3030_Cooling_generation_systems>
<investment_cost cost_unit="currency/kW"> 622.86 </investment_cost>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3030_Cooling_generation_systems>
<D3040_Distributionsystems>
<investment_cost cost_unit="currency/kW"> 0 </investment_cost>
<reposition cost_unit="currency/kW"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3040_Distributionsystems>
<D3080_OtherHVAC_AHU>
<investment_cost cost_unit="currency/kW"> 47.62 </investment_cost>
<reposition cost_unit="currency/kW"> 47.62 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3080_OtherHVAC_AHU>
</D30_HVAC>
<D50_Electrical>
<D5020Lightingandbranchwiring>
<refurbishmentcost cost_unit="currency/kW"> 139 </refurbishmentcost>
<reposition cost_unit="currency/kW"> 139 </reposition>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</D5020Lightingandbranchwiring>
</D50_Electrical>
</D_Services>
<Z_Allowances_overhead_profit>
<Z10_Design_allowance cost_unit="%"> 2.5 </Z10_Design_allowance>
<Z10_Overhead_and_profit cost_unit="%"> 14 </Z10_Overhead_and_profit>
</Z_Allowances_overhead_profit>
</capital_cost>
<operational_cost>
<fuel fuel_type="electricity">
<fixed>
<fixed_monthly cost_unit="currency/month"> 12.27 </fixed_monthly>
<fixed_power cost_unit="currency/month*kW"> 0 </fixed_power>
</fixed>
<variable cost_unit="currency/kWh"> 0.075 </variable>
</fuel>
<fuel fuel_type="gas">
<fixed>
<fixed_monthly cost_unit="currency/month"> 17.71 </fixed_monthly>
</fixed>
<variable cost_unit="currency/kWh"> 0.640 </variable>
</fuel>
<fuel fuel_type="diesel">
<variable cost_unit="currency/l"> 1.2 </variable>
</fuel>
<fuel fuel_type="biomass">
<variable cost_unit="currency/kg"> 0.09 </variable>
</fuel>
<maintenance>
<heating_equipment cost_unit="currency/kW"> 40 </heating_equipment>
<cooling_equipment cost_unit="currency/kW"> 40 </cooling_equipment>
<photovoltaic_system cost_unit="currency/m2"> 1 </photovoltaic_system>
</maintenance>
<CO2_cost cost_unit="currency/kgCO2"> 30 </CO2_cost>
</operational_cost>
<end_of_life_cost cost_unit="currency/m2"> 6.3 </end_of_life_cost>
<incomes>
<subsidies>
<construction_subsidy cost_unit="%"> 2 </construction_subsidy>
<hvac_subsidy cost_unit="%"> 1.5 </hvac_subsidy>
<photovoltaic_subsidy cost_unit="%"> 3.6 </photovoltaic_subsidy>
</subsidies>
<energy_exports>
<electricity cost_unit="currency/kWh"> 0 </electricity>
</energy_exports>
<tax_reductions>
<reductions_taxes cost_unit="%"> 2 </reductions_taxes>
</tax_reductions>
</incomes>
</archetype>
<archetype function="non-residential" municipality="montreal" currency="CAD">
<capital_cost>
<B_Shell>
<B10_superstructure>
<refurbishmentcostbasement cost_unit="currency/m2"> 0 </refurbishmentcostbasement>
</B10_superstructure>
<B20_envelope>
<B2010_opaque_walls>
<refurbishmentcost cost_unit="currency/m2"> 304 </refurbishmentcost>
</B2010_opaque_walls>
<B2020_transparent>
<refurbishmentcost cost_unit="currency/m2"> 857.14 </refurbishmentcost>
</B2020_transparent>
</B20_envelope>
<B30_roofing>
<B3010_opaqueroof>
<refurbishmentcost cost_unit="currency/m2"> 118 </refurbishmentcost>
</B3010_opaqueroof>
</B30_roofing>
</B_Shell>
<D_Services>
<D30_HVAC>
<D3010EnergySupply>
<D301010photovoltaic_system>
<initial_investment cost_unit="currency/m2"> 800 </initial_investment>
<reposition cost_unit="currency/m2"> 800 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D301010photovoltaic_system>
</D3010EnergySupply>
<D3020Heatgeneratingsystems>
<investment_cost cost_unit="currency/kW"> 622.86 </investment_cost>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D3020Heatgeneratingsystems>
<D3030_Cooling_generation_systems>
<investment_cost cost_unit="currency/kW"> 622.86 </investment_cost>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3030_Cooling_generation_systems>
<D3040_Distribution_systems>
<refurbishmentcost cost_unit="currency/m2"> 0 </refurbishmentcost>
<reposition cost_unit="currency/kW"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3040_Distribution_systems>
<D3080_Other_HVAC_AHU>
<investment_cost cost_unit="currency/kW"> 47.62 </investment_cost>
<reposition cost_unit="currency/kW"> 47.62 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3080_Other_HVAC_AHU>
</D30_HVAC>
<D50_Electrical>
<D5020_Lighting_and_branch_wiring>
<refurbishmentcost cost_unit="currency/kW"> 139 </refurbishmentcost>
<reposition cost_unit="currency/kW"> 139 </reposition>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</D5020_Lighting_and_branch_wiring>
</D50_Electrical>
</D_Services>
<Z_Allowances_overhead_profit>
<Z10_Design_allowance cost_unit="%"> 6 </Z10_Design_allowance>
<Z20_Overhead_profit cost_unit="%"> 14 </Z20_Overhead_profit>
</Z_Allowances_overhead_profit>
</capital_cost>
<operational_cost>
<fuel fuel_type="electricity">
<fixed>
<fixed_monthly cost_unit="currency/month"> 12.27 </fixed_monthly>
<fixed_power cost_unit="currency/(month*kW)"> 0 </fixed_power>
</fixed>
<variable cost_unit="currency/kWh"> 0.075 </variable>
</fuel>
<fuel fuel_type="gas">
<fixed>
<fixed_monthly cost_unit="currency/month"> 17.71 </fixed_monthly>
</fixed>
<variable cost_unit="currency/m3"> 0.640 </variable>
</fuel>
<fuel fuel_type="diesel">
<variable cost_unit="currency/l"> 1.2 </variable>
</fuel>
<fuel fuel_type="biomass">
<variable cost_unit="currency/kg"> 0.09 </variable>
</fuel>
<maintenance>
<heating_equipment cost_unit="currency/kW"> 40 </heating_equipment>
<cooling_equipment cost_unit="currency/kW"> 40 </cooling_equipment>
<photovoltaic_system cost_unit="currency/m2"> 1 </photovoltaic_system>
</maintenance>
<CO2_cost cost_unit="currency/kgCO2"> 30 </CO2_cost>
</operational_cost>
<end_of_life_cost cost_unit="currency/m2"> 6.3 </end_of_life_cost>
<incomes>
<subsidies>
<construction_subsidy cost_unit="%"> 2 </construction_subsidy>
<hvac_subsidy cost_unit="%"> 1.5 </hvac_subsidy>
<photovoltaic_subsidy cost_unit="%"> 3.6 </photovoltaic_subsidy>
</subsidies>
<energy_exports>
<electricity cost_unit="currency/kWh"> 0 </electricity>
</energy_exports>
<tax_reductions>
<reductions_taxes cost_unit="%"> 2 </reductions_taxes>
</tax_reductions>
</incomes>
</archetype>
</archetypes>

View File

@ -0,0 +1,178 @@
<archetypes>
<archetype function="residential" municipality="montreal" currency="CAD">
<capital_cost>
<ASubstructure>
<A10sub_structural cost_unit="currency/m2"> 15.89 </A10sub_structural>
<A20structural cost_unit="currency/m3"> 215.90 </A20structural>
</ASubstructure>
<BShell>
<B10superstructure>
<reposition cost_unit="currency/m2"> 0 </reposition>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</B10superstructure>
<B20envelope>
<B2010opaquewalls>
<reposition cost_unit="currency/m2"> 304 </reposition>
<initial_investment cost_unit="currency/m2"> 304 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</B2010opaquewalls>
<B2020transparent>
<reposition cost_unit="currency/m2"> 857.14 </reposition>
<initial_investment cost_unit="currency/m2"> 857.14 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</B2020transparent>
</B20envelope>
<B30roofing>
<B3010opaqueroof>
<reposition cost_unit="currency/m2"> 118 </reposition>
<initial_investment cost_unit="currency/m2"> 118 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</B3010opaqueroof>
<B3020transparentroof>
<reposition cost_unit="currency/m2"> 857.14 </reposition>
<initial_investment cost_unit="currency/m2"> 857.14 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</B3020transparentroof>
</B30roofing>
</BShell>
<CInteriors>
<C10Interiorconstruction>
<reposition cost_unit="currency/m2"> 0 </reposition>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</C10Interiorconstruction>
<C20Stairs>
<reposition cost_unit="currency/m2"> 0 </reposition>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<lifetime_equipment lifetime="years"> 50 </lifetime_equipment>
</C20Stairs>
<C30Interiorfinishes>
<C3010Walls>
<reposition cost_unit="currency/m2"> 50 </reposition>
<initial_investment cost_unit="currency/m2"> 50 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</C3010Walls>
<C3020Floors>
<reposition cost_unit="currency/m2"> 62 </reposition>
<initial_investment cost_unit="currency/m2"> 62 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</C3020Floors>
<C3030Ceilings>
<reposition cost_unit="currency/m2"> 70 </reposition>
<initial_investment cost_unit="currency/m2"> 70 </initial_investment>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</C3030Ceilings>
</C30Interiorfinishes>
</CInteriors>
<DServices>
<D10Conveying cost_unit="currency/m2"> 0 </D10Conveying>
<D20Plumbing cost_unit="currency/m2"> 100 </D20Plumbing>
<D30HVAC>
<D3010EnergySupply>
<D301010photovoltaic_system>
<initial_investment cost_unit="currency/m2"> 800 </initial_investment>
<reposition cost_unit="currency/m2"> 800 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D301010photovoltaic_system>
</D3010EnergySupply>
<D3020Heatgeneratingsystems>
<initial_investment cost_unit="currency/kW"> 622.86 </initial_investment>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 25 </lifetime_equipment>
</D3020Heatgeneratingsystems>
<D3030Coolinggenerationsystems>
<initial_investment cost_unit="currency/kW"> 622.86 </initial_investment>
<reposition cost_unit="currency/kW"> 622.86 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3030Coolinggenerationsystems>
<D3040Distributionsystems>
<initial_investment cost_unit="currency/kW"> 0 </initial_investment>
<reposition cost_unit="currency/kW"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3040Distributionsystems>
<D3060Controlsandinstrumentation>
<initial_investment cost_unit="currency/kW"> 0 </initial_investment>
<reposition cost_unit="currency/kW"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3060Controlsandinstrumentation>
<D3080OtherHVAC_AHU>
<initial_investment cost_unit="currency/kW"> 47.62 </initial_investment>
<reposition cost_unit="currency/kW"> 47.62 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</D3080OtherHVAC_AHU>
</D30HVAC>
<D50Electrical>
<D5010Electricalservicesanddistribution>
<initial_investment cost_unit="currency/m2"> 171.43 </initial_investment>
<reposition cost_unit="currency/m2"> 171.43 </reposition>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</D5010Electricalservicesanddistribution>
<D5020Lightingandbranchwiring>
<initial_investment cost_unit="currency/kW"> 139 </initial_investment>
<reposition cost_unit="currency/kW"> 139 </reposition>
<lifetime_equipment lifetime="years"> 20 </lifetime_equipment>
</D5020Lightingandbranchwiring>
</D50Electrical>
</DServices>
<EEquimentsandfurnishing>
<E10Equipments>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<reposition cost_unit="currency/m2"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</E10Equipments>
<E10Furnishing>
<initial_investment cost_unit="currency/m2"> 0 </initial_investment>
<reposition cost_unit="currency/m2"> 0 </reposition>
<lifetime_equipment lifetime="years"> 15 </lifetime_equipment>
</E10Furnishing>
</EEquimentsandfurnishing>
<engineer cost_unit="%"> 2.5 </engineer>
</capital_cost>
<operational_cost>
<fuel fuel_type="electricity">
<fixed>
<fixed_monthly cost_unit="currency/month"> 12.27 </fixed_monthly>
</fixed>
<variable_base cost_unit="currency/kWh"> hourlydatatable1 </variable_base>
<variable_peak cost_unit="currency/kWh"> hourlydatatable2 </variable_peak>
</fuel>
<fuel fuel_type="gaz">
<fixed>
<fixed_monthly cost_unit="currency/month"> 17.71 </fixed_monthly>
</fixed>
<variable cost_unit="currency/m3"> 0.640 </variable>
</fuel>
<fuel fuel_type="diesel">
<variable cost_unit="currency/l"> 1.2 </variable>
</fuel>
<fuel fuel_type="biomass">
<variable cost_unit="currency/kg"> 0.09 </variable>
</fuel>
<maintenance>
<heating_equipment cost_unit="currency/kW"> 40 </heating_equipment>
<cooling_equipment cost_unit="currency/kW"> 40 </cooling_equipment>
<general_hvac_equipment cost_unit="currency/(m3/h)"> 0.05 </general_hvac_equipment>
<photovoltaic_system cost_unit="currency/m2"> 1 </photovoltaic_system>
<other_systems cost_unit="currency/m2"> 4.6 </other_systems>
</maintenance>
<CO2_cost cost_unit="currency/kgCO2"> 30 </CO2_cost>
</operational_cost>
<end_of_life_cost cost_unit="currency/m2"> 6.3 </end_of_life_cost>
<incomes>
<subsidies>
<construction_subsidy cost_unit="%"> 2 </construction_subsidy>
<hvac_subsidy cost_unit="%"> 1.5 </hvac_subsidy>
<photovoltaic_subsidy cost_unit="%"> 3.6 </photovoltaic_subsidy>
</subsidies>
<energy_exports>
<electricity cost_unit="currency/kWh"> hourlydatatable </electricity>
<heat cost_unit="currency/kWh"> 0 </heat>
</energy_exports>
<tax_reductions>
<reductions_taxes cost_unit="%"> 2 </reductions_taxes>
</tax_reductions>
<CO2_income cost_unit="currency/kgCO2exported"> 0 </CO2_income>
</incomes>
</archetype>
</archetypes>

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@ from pathlib import Path
from geomeppy import IDF from geomeppy import IDF
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.city_model_structure.attributes.schedule import Schedule from hub.city_model_structure.attributes.schedule import Schedule
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
class Idf: class Idf:
@ -20,7 +21,9 @@ class Idf:
_BUILDING = 'BUILDING' _BUILDING = 'BUILDING'
_ZONE = 'ZONE' _ZONE = 'ZONE'
_LIGHTS = 'LIGHTS' _LIGHTS = 'LIGHTS'
_APPLIANCES = 'OTHEREQUIPMENT'
_PEOPLE = 'PEOPLE' _PEOPLE = 'PEOPLE'
_DHW = 'WATERUSE:EQUIPMENT'
_THERMOSTAT = 'HVACTEMPLATE:THERMOSTAT' _THERMOSTAT = 'HVACTEMPLATE:THERMOSTAT'
_IDEAL_LOAD_AIR_SYSTEM = 'HVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM' _IDEAL_LOAD_AIR_SYSTEM = 'HVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM'
_SURFACE = 'BUILDINGSURFACE:DETAILED' _SURFACE = 'BUILDINGSURFACE:DETAILED'
@ -98,6 +101,7 @@ class Idf:
self._adjacent_buildings = adjacent_buildings self._adjacent_buildings = adjacent_buildings
if self._adjacent_buildings is None: if self._adjacent_buildings is None:
self._adjacent_buildings = [] self._adjacent_buildings = []
self._export() self._export()
@staticmethod @staticmethod
@ -186,6 +190,7 @@ class Idf:
_schedule.Minutes_per_Item = 60 _schedule.Minutes_per_Item = 60
def _add_infiltration_schedules(self, thermal_zone): def _add_infiltration_schedules(self, thermal_zone):
# todo: clean the way infiltration is hardcoded
_infiltration_schedules = [] _infiltration_schedules = []
if thermal_zone.thermal_control is None: if thermal_zone.thermal_control is None:
return return
@ -199,9 +204,9 @@ class Idf:
_infiltration_values = [] _infiltration_values = []
for hvac_value in hvac_availability_schedule.values: for hvac_value in hvac_availability_schedule.values:
if hvac_value == 0: if hvac_value == 0:
_infiltration_values.append(thermal_zone.infiltration_rate_system_off) _infiltration_values.append(1)
else: else:
_infiltration_values.append(thermal_zone.infiltration_rate_system_on) _infiltration_values.append(1)
_schedule.values = _infiltration_values _schedule.values = _infiltration_values
_infiltration_schedules.append(_schedule) _infiltration_schedules.append(_schedule)
for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]: for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
@ -244,6 +249,25 @@ class Idf:
return return
return self._add_standard_compact_hourly_schedule(usage, schedule_type, new_schedules) return self._add_standard_compact_hourly_schedule(usage, schedule_type, new_schedules)
def _add_constant_hourly_year_schedules(self, thermal_zone, value, schedule_type):
_schedule = Schedule()
_schedule.type = schedule_type
_schedule.data_type = cte.ANY_NUMBER
_schedule.time_step = cte.HOUR
_schedule.time_range = cte.DAY
_schedule.day_types = ['monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday',
'holiday',
'winter_design_day',
'summer_design_day']
_schedule.values = [value for _ in range(0, 24)]
return self._add_standard_compact_hourly_schedule(thermal_zone.usage_name, schedule_type, [_schedule])
def _add_construction(self, thermal_boundary): def _add_construction(self, thermal_boundary):
for construction in self._idf.idfobjects[self._CONSTRUCTION]: for construction in self._idf.idfobjects[self._CONSTRUCTION]:
if thermal_boundary.parent_surface.vegetation is not None: if thermal_boundary.parent_surface.vegetation is not None:
@ -276,7 +300,7 @@ class Idf:
def _add_window_construction_and_material(self, thermal_opening): def _add_window_construction_and_material(self, thermal_opening):
for window_material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]: for window_material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]:
if window_material['UFactor'] == thermal_opening.overall_u_value and \ if window_material['UFactor'] == thermal_opening.overall_u_value and \
window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value: window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value:
return return
order = str(len(self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]) + 1) order = str(len(self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]) + 1)
@ -338,20 +362,84 @@ class Idf:
Activity_Level_Schedule_Name=f'Activity Level schedules {thermal_zone.usage_name}' Activity_Level_Schedule_Name=f'Activity Level schedules {thermal_zone.usage_name}'
) )
def _add_infiltration(self, thermal_zone, zone_name): def _add_lighting(self, thermal_zone: ThermalZone, zone_name: str):
fraction_radiant = thermal_zone.lighting.radiative_fraction
# todo: fraction visible should come from catalog
fraction_visible = 0.3
method = 'Watts/Area'
factor_size = thermal_zone.total_floor_area / thermal_zone.footprint_area
watts_per_zone_floor_area = thermal_zone.lighting.density * factor_size
# todo: fraction replaceable should come from catalog
fraction_replaceable = 1
subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#GeneralLights'
for zone in self._idf.idfobjects["ZONE"]: self._idf.newidfobject(self._LIGHTS,
if zone.Name == f'{zone_name}_infiltration': Name=f'{zone_name}_lights',
return Zone_or_ZoneList_Name=zone_name,
Schedule_Name=f'Lighting schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method,
Watts_per_Zone_Floor_Area=watts_per_zone_floor_area,
Fraction_Radiant=fraction_radiant,
Fraction_Visible=fraction_visible,
Fraction_Replaceable=fraction_replaceable,
EndUse_Subcategory=subcategory
)
def _add_appliances(self, thermal_zone, zone_name):
fuel_type = 'Electricity'
fraction_radiant = thermal_zone.appliances.radiative_fraction
fraction_latent = 0
method = 'Watts/Area'
factor_size = thermal_zone.total_floor_area / thermal_zone.footprint_area
watts_per_zone_floor_area = thermal_zone.appliances.density * factor_size
subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#InteriorEquipment'
# _object = self._idf.newidfobject(self._APPLIANCES)
# print(vars(_object))
self._idf.newidfobject(self._APPLIANCES,
Fuel_Type=fuel_type,
Name=f'{zone_name}_appliance',
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=f'Appliance schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method,
Power_per_Zone_Floor_Area=watts_per_zone_floor_area,
Fraction_Latent=fraction_latent,
Fraction_Radiant=fraction_radiant,
EndUse_Subcategory=subcategory
)
def _add_infiltration(self, thermal_zone, zone_name):
# for zone in self._idf.idfobjects["ZONE"]:
# if zone.Name == f'{zone_name}_infiltration':
# return
schedule = f'Infiltration schedules {thermal_zone.usage_name}' schedule = f'Infiltration schedules {thermal_zone.usage_name}'
if schedule not in self._idf.idfobjects[self._HOURLY_SCHEDULE]: # if schedule not in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
return # return
# todo: eliminate the factor
factorreduct = 0.5
self._idf.newidfobject(self._INFILTRATION, self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration', Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_Name=zone_name, Zone_or_ZoneList_Name=zone_name,
Schedule_Name=schedule, Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour', Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=thermal_zone.mechanical_air_change Air_Changes_per_Hour=thermal_zone.infiltration_rate_system_off * factorreduct
)
def _add_DHW(self, thermal_zone, zone_name):
fuel_type = 'Electricity'
method = 'Watts/Area'
factor_size = thermal_zone.total_floor_area / thermal_zone.footprint_area
# todo: revision of values of peak flow (too low). Added a factor, but to check original units
peak_flow_rate = thermal_zone.domestic_hot_water.peak_flow * thermal_zone.total_floor_area
# = self._idf.newidfobject(self._DHW)
# print(vars(_object))
self._idf.newidfobject(self._DHW,
Name=f'DHW {zone_name}',
Peak_Flow_Rate=peak_flow_rate,
Flow_Rate_Fraction_Schedule_Name=f'DHW_prof schedules {thermal_zone.usage_name}',
Target_Temperature_Schedule_Name=f'DHW_temp schedules {thermal_zone.usage_name}',
Hot_Water_Supply_Temperature_Schedule_Name=f'DHW_temp schedules {thermal_zone.usage_name}',
EndUse_Subcategory=f'DHW {zone_name}',
Zone_Name=zone_name
) )
def _rename_building(self, city_name): def _rename_building(self, city_name):
@ -396,20 +484,24 @@ class Idf:
usage = thermal_zone.usage_name usage = thermal_zone.usage_name
if building.name in self._target_buildings or building.name in self._adjacent_buildings: if building.name in self._target_buildings or building.name in self._adjacent_buildings:
self._add_infiltration_schedules(thermal_zone) self._add_infiltration_schedules(thermal_zone)
if thermal_zone.occupancy is not None: self._add_schedules(usage, 'Occupancy', thermal_zone.occupancy.occupancy_schedules)
self._add_schedules(usage, 'Occupancy', thermal_zone.occupancy.occupancy_schedules) self._add_schedules(usage, 'HVAC AVAIL', thermal_zone.thermal_control.hvac_availability_schedules)
self._add_people_activity_level_schedules(thermal_zone) self._add_schedules(usage, 'Heating thermostat', thermal_zone.thermal_control.heating_set_point_schedules)
self._add_occupancy(thermal_zone, building.name) self._add_schedules(usage, 'Cooling thermostat', thermal_zone.thermal_control.cooling_set_point_schedules)
self._add_schedules(usage, 'Lighting', thermal_zone.lighting.schedules)
if thermal_zone.thermal_control is not None: self._add_schedules(usage, 'Appliance', thermal_zone.appliances.schedules)
self._add_schedules(usage, 'HVAC AVAIL', thermal_zone.thermal_control.hvac_availability_schedules) self._add_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules)
self._add_schedules(usage, 'Heating thermostat', thermal_zone.thermal_control.heating_set_point_schedules) # self._add_service_temp_schedules(thermal_zone)
self._add_schedules(usage, 'Cooling thermostat', thermal_zone.thermal_control.cooling_set_point_schedules) value = int(thermal_zone.domestic_hot_water.service_temperature)
self._add_constant_hourly_year_schedules(thermal_zone, value, 'DHW_temp')
self._add_people_activity_level_schedules(thermal_zone)
self._add_zone(thermal_zone, building.name) self._add_zone(thermal_zone, building.name)
self._add_heating_system(thermal_zone, building.name) self._add_heating_system(thermal_zone, building.name)
self._add_infiltration(thermal_zone, building.name) self._add_infiltration(thermal_zone, building.name)
self._add_occupancy(thermal_zone, building.name)
self._add_lighting(thermal_zone, building.name)
self._add_appliances(thermal_zone, building.name)
self._add_DHW(thermal_zone, building.name)
if self._export_type == "Surfaces": if self._export_type == "Surfaces":
if building.name in self._target_buildings or building.name in self._adjacent_buildings: if building.name in self._target_buildings or building.name in self._adjacent_buildings:
if building.internal_zones[0].thermal_zones is not None: if building.internal_zones[0].thermal_zones is not None:
@ -421,26 +513,40 @@ class Idf:
else: else:
self._add_block(building) self._add_block(building)
# todo: this should change to specific variables per zone to process only the ones in the buildings_to_calculate # todo: this should change to specific variables per zone to process only the ones in the buildings_to_calculate
for building in self._target_buildings: for _ in self._target_buildings:
continue continue
self._idf.newidfobject( self._idf.newidfobject(
"OUTPUT:VARIABLE", "OUTPUT:VARIABLE",
Variable_Name="Zone Ideal Loads Supply Air Total Heating Energy", Variable_Name="Zone Ideal Loads Supply Air Total Heating Energy",
Reporting_Frequency="Hourly", Reporting_Frequency="Monthly",
) )
# _object = self._idf.newidfobject("OUTPUT:VARIABLE")
# print(vars(_object))
self._idf.newidfobject( self._idf.newidfobject(
"OUTPUT:VARIABLE", "OUTPUT:VARIABLE",
Variable_Name="Zone Ideal Loads Supply Air Total Cooling Energy", Variable_Name="Zone Ideal Loads Supply Air Total Cooling Energy",
Reporting_Frequency="Hourly", Reporting_Frequency="Monthly",
) )
self._idf.match()
try: self._idf.newidfobject(
self._idf.intersect_match() "OUTPUT:VARIABLE",
except IndexError: Variable_Name="Water Use Equipment Heating Rate",
Reporting_Frequency="Monthly",
)
# self._idf.newidfobject(
# "OUTPUTCONTROL:TABLE:STYLE",
# Variable_Name="CommaAndHTML, JtoKWH",
# )
# self._idf.match()
# try:
# self._idf.intersect_match()
# except IndexError:
# seems to be a bug from geomeppy when surfaces cannot be intersected # seems to be a bug from geomeppy when surfaces cannot be intersected
pass # pass
# post-process to erase windows associated to adiabatic walls # post-process to erase windows associated to adiabatic walls
windows_list = [] windows_list = []
@ -494,21 +600,31 @@ class Idf:
Fraction_of_Shading_Surface_That_Is_Glazed=0) Fraction_of_Shading_Surface_That_Is_Glazed=0)
def _add_pure_geometry(self, building, zone_name): def _add_pure_geometry(self, building, zone_name):
for surface in building.surfaces: for surface in building.surfaces:
idf_surface_type = self.idf_surfaces[surface.type]
outside_boundary_condition = 'Outdoors' outside_boundary_condition = 'Outdoors'
sun_exposure = 'SunExposed' sun_exposure = 'SunExposed'
wind_exposure = 'WindExposed' wind_exposure = 'WindExposed'
outside_boundary_condition_object = None
# TODO: set assumption in constants, to select minimun shared area
#print(f'wall {surface.name} {surface.percentage_shared}')
if surface.percentage_shared is not None and surface.percentage_shared > 0.1:
outside_boundary_condition = 'Surface'
outside_boundary_condition_object = surface.name
sun_exposure = 'NoSun'
wind_exposure = 'NoWind'
if surface.type == cte.GROUND: if surface.type == cte.GROUND:
outside_boundary_condition = 'Ground' outside_boundary_condition = 'Ground'
sun_exposure = 'NoSun' sun_exposure = 'NoSun'
wind_exposure = 'NoWind' wind_exposure = 'NoWind'
idf_surface_type = self.idf_surfaces[surface.type]
idf_surface = self._idf.newidfobject(self._SURFACE, Name=f'{surface.name}', idf_surface = self._idf.newidfobject(self._SURFACE, Name=f'{surface.name}',
Surface_Type=idf_surface_type, Surface_Type=idf_surface_type,
Zone_Name=zone_name, Zone_Name=zone_name,
Outside_Boundary_Condition=outside_boundary_condition, Outside_Boundary_Condition=outside_boundary_condition,
Sun_Exposure=sun_exposure, Outside_Boundary_Condition_Object=outside_boundary_condition_object,
Wind_Exposure=wind_exposure) Sun_Exposure=sun_exposure,
Wind_Exposure=wind_exposure)
coordinates = self._matrix_to_list(surface.solid_polygon.coordinates, coordinates = self._matrix_to_list(surface.solid_polygon.coordinates,
self._city.lower_corner) self._city.lower_corner)
idf_surface.setcoords(coordinates) idf_surface.setcoords(coordinates)
@ -530,6 +646,13 @@ class Idf:
outside_boundary_condition = 'Outdoors' outside_boundary_condition = 'Outdoors'
sun_exposure = 'SunExposed' sun_exposure = 'SunExposed'
wind_exposure = 'WindExposed' wind_exposure = 'WindExposed'
outside_boundary_condition_object = ''
# TODO: set assumption in constants, to select minimun shared area
if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared >= 0.1:
outside_boundary_condition = 'Surface'
outside_boundary_condition_object = boundary.parent_surface.name
sun_exposure = 'NoSun'
wind_exposure = 'NoWind'
if boundary.parent_surface.type == cte.GROUND: if boundary.parent_surface.type == cte.GROUND:
outside_boundary_condition = 'Ground' outside_boundary_condition = 'Ground'
sun_exposure = 'NoSun' sun_exposure = 'NoSun'
@ -538,11 +661,13 @@ class Idf:
construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}' construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}'
else: else:
construction_name = boundary.construction_name construction_name = boundary.construction_name
#print(f'shared wall {boundary.parent_surface.name} {outside_boundary_condition_object} {idf_surface_type}')
surface = self._idf.newidfobject(self._SURFACE, Name=f'{boundary.parent_surface.name}', surface = self._idf.newidfobject(self._SURFACE, Name=f'{boundary.parent_surface.name}',
Surface_Type=idf_surface_type, Surface_Type=idf_surface_type,
Zone_Name=zone_name, Zone_Name=zone_name,
Construction_Name=construction_name, Construction_Name=construction_name,
Outside_Boundary_Condition=outside_boundary_condition, Outside_Boundary_Condition=outside_boundary_condition,
Outside_Boundary_Condition_Object=outside_boundary_condition_object,
Sun_Exposure=sun_exposure, Sun_Exposure=sun_exposure,
Wind_Exposure=wind_exposure) Wind_Exposure=wind_exposure)
coordinates = self._matrix_to_list(boundary.parent_surface.solid_polygon.coordinates, coordinates = self._matrix_to_list(boundary.parent_surface.solid_polygon.coordinates,
@ -570,7 +695,7 @@ class Idf:
for material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]: for material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]:
if material['Name'] == glazing: if material['Name'] == glazing:
if material['UFactor'] == opening.overall_u_value and \ if material['UFactor'] == opening.overall_u_value and \
material['Solar_Heat_Gain_Coefficient'] == opening.g_value: material['Solar_Heat_Gain_Coefficient'] == opening.g_value:
return True return True
return False return False

View File

@ -127,26 +127,31 @@
No, !- Do HVAC Sizing Simulation for Sizing Periods No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes 1; !- Maximum Number of HVAC Sizing Simulation Passes
Output:VariableDictionary,Regular; Output:Table:SummaryReports, AnnualBuildingUtilityPerformanceSummary,
DemandEndUseComponentsSummary,
SensibleHeatGainSummary,
InputVerificationandResultsSummary,
AdaptiveComfortSummary,
Standard62.1Summary,
ClimaticDataSummary,
EquipmentSummary,
EnvelopeSummary,
LightingSummary,
HVACSizingSummary,
SystemSummary,
ComponentSizingSummary,
OutdoorAirSummary,
ObjectCountSummary,
EndUseEnergyConsumptionOtherFuelsMonthly,
PeakEnergyEndUseOtherFuelsMonthly;
Output:Variable,*,Site Outdoor Air Drybulb Temperature,Timestep;
Output:Variable,*,Site Outdoor Air Wetbulb Temperature,Timestep; OutputControl:Table:Style, CommaAndHTML,JtoKWH;
Output:Variable,*,Site Outdoor Air Dewpoint Temperature,Timestep; Output:Meter,DISTRICTHEATING:Facility,monthly;
Output:Meter,DISTRICTCOOLING:Facility,monthly;
Output:Meter,InteriorEquipment:Electricity,monthly;
Output:Meter,InteriorLights:Electricity,monthly;
Output:Variable,*,Site Solar Azimuth Angle,Timestep; OutputControl:IlluminanceMap:Style,
Comma; !- Column separator
Output:Variable,*,Site Solar Altitude Angle,Timestep;
Output:Variable,*,Site Direct Solar Radiation Rate per Area,Timestep;
Output:Variable,*,Site Diffuse Solar Radiation Rate per Area,Timestep;
OutputControl:Table:Style,
HTML; !- Column Separator
Output:Table:SummaryReports,
AllSummary; !- Report 1 Name
Output:Diagnostics,DisplayUnusedSchedules;

View File

@ -127,7 +127,7 @@ class InselMonthlyEnergyBalance(Insel):
f'zone {i + 1} (degree Celsius)') f'zone {i + 1} (degree Celsius)')
parameters.append(f'{usage.thermal_control.heating_set_back} % BP(14) #4 Heating setback temperature ' parameters.append(f'{usage.thermal_control.heating_set_back} % BP(14) #4 Heating setback temperature '
f'zone {i + 1} (degree Celsius)') f'zone {i + 1} (degree Celsius)')
parameters.append(f'{usage.thermal_control.mean_cooling_set_point} % BP(15) #5 Cooling setpoint temperature ' parameters.append(f'{usage.thermal_control.mean_cooling_set_point+4} % BP(15) #5 Cooling setpoint temperature '
f'zone {i + 1} (degree Celsius)') f'zone {i + 1} (degree Celsius)')
parameters.append(f'{usage.hours_day} % BP(16) #6 Usage hours per day zone {i + 1}') parameters.append(f'{usage.hours_day} % BP(16) #6 Usage hours per day zone {i + 1}')
parameters.append(f'{usage.days_year} % BP(17) #7 Usage days per year zone {i + 1}') parameters.append(f'{usage.days_year} % BP(17) #7 Usage days per year zone {i + 1}')
@ -153,8 +153,8 @@ class InselMonthlyEnergyBalance(Insel):
for day_type in schedule.day_types: for day_type in schedule.day_types:
infiltration += infiltration_day * cte.DAYS_A_YEAR[day_type] / 365 infiltration += infiltration_day * cte.DAYS_A_YEAR[day_type] / 365
ventilation += ventilation_day * cte.DAYS_A_YEAR[day_type] / 365 ventilation += ventilation_day * cte.DAYS_A_YEAR[day_type] / 365
#todo: eliminate hardcoded coefficient to ventilationinf
ventilation_infiltration = ventilation + infiltration ventilation_infiltration = (ventilation + infiltration)*0.5
parameters.append(f'{ventilation_infiltration} % BP(18) #8 Minimum air change rate zone {i + 1} (ACH)') parameters.append(f'{ventilation_infiltration} % BP(18) #8 Minimum air change rate zone {i + 1} (ACH)')
parameters.append(f'{len(thermal_zone.thermal_boundaries)} % Number of surfaces = BP(11+8z) \n' parameters.append(f'{len(thermal_zone.thermal_boundaries)} % Number of surfaces = BP(11+8z) \n'

View File

@ -31,6 +31,7 @@ class EnergyBuildingsExportsFactory:
self._target_buildings = target_buildings self._target_buildings = target_buildings
self._adjacent_buildings = adjacent_buildings self._adjacent_buildings = adjacent_buildings
@property @property
def _energy_ade(self): def _energy_ade(self):
""" """
@ -54,7 +55,9 @@ class EnergyBuildingsExportsFactory:
""" """
idf_data_path = (Path(__file__).parent / './building_energy/idf_files/').resolve() idf_data_path = (Path(__file__).parent / './building_energy/idf_files/').resolve()
# todo: create a get epw file function based on the city # todo: create a get epw file function based on the city
#print('path', idf_data_path)
weather_path = (Path(__file__).parent / '../data/weather/epw/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve() weather_path = (Path(__file__).parent / '../data/weather/epw/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
#print(weather_path)
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path, return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
target_buildings=self._target_buildings, adjacent_buildings=self._adjacent_buildings) target_buildings=self._target_buildings, adjacent_buildings=self._adjacent_buildings)
@ -71,6 +74,7 @@ class EnergyBuildingsExportsFactory:
Export the city given to the class using the given export type handler Export the city given to the class using the given export type handler
:return: None :return: None
""" """
print(self)
return getattr(self, self._export_type, lambda: None) return getattr(self, self._export_type, lambda: None)
def export_debug(self): def export_debug(self):

View File

@ -23,6 +23,7 @@ METERS_TO_FEET = 3.28084
BTU_H_TO_WATTS = 0.29307107 BTU_H_TO_WATTS = 0.29307107
KILO_WATTS_HOUR_TO_JULES = 3600000 KILO_WATTS_HOUR_TO_JULES = 3600000
GALLONS_TO_QUBIC_METERS = 0.0037854117954011185 GALLONS_TO_QUBIC_METERS = 0.0037854117954011185
CUBICFEET_TO_CUBIC_METERS_HOUR=1.699
# time # time
SECOND = 'second' SECOND = 'second'
@ -184,6 +185,7 @@ MIN_FLOAT = float('-inf')
# Tools # Tools
SRA = 'sra' SRA = 'sra'
INSEL_MEB = 'insel meb' INSEL_MEB = 'insel meb'
PEAK_LOAD = 'peak load'
# Costs units # Costs units
CURRENCY_PER_SQM = 'currency/m2' CURRENCY_PER_SQM = 'currency/m2'

View File

@ -6,9 +6,9 @@ Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import math import math
from pathlib import Path
import numpy as np import numpy as np
import requests
from PIL import Image from PIL import Image
from trimesh import Trimesh from trimesh import Trimesh
from trimesh import intersections from trimesh import intersections
@ -55,16 +55,22 @@ class GeometryHelper:
'urn:adv:crs:ETRS89_UTM32*DE_DHHN92_NH': 'epsg:25832' 'urn:adv:crs:ETRS89_UTM32*DE_DHHN92_NH': 'epsg:25832'
} }
@staticmethod
def factor():
return 0.5
def __init__(self, delta=0, area_delta=0): def __init__(self, delta=0, area_delta=0):
self._delta = delta self._delta = delta
self._area_delta = area_delta self._area_delta = area_delta
@staticmethod @staticmethod
def coordinate_to_map_point(coordinate, city): def coordinate_to_map_point(coordinate, city):
return MapPoint(((city.upper_corner[0] - coordinate[0]) * 0.5), ((city.upper_corner[1] - coordinate[1]) * 0.5)) factor = GeometryHelper.factor()
return MapPoint(((coordinate[0] - city.lower_corner[0]) * factor), ((coordinate[1] - city.lower_corner[1]) * factor))
@staticmethod @staticmethod
def city_mapping(city, building_names=None, plot=False): def city_mapping(city, building_names=None, plot=False):
""" """
Returns a shared_information dictionary like Returns a shared_information dictionary like
@ -75,8 +81,9 @@ class GeometryHelper:
lines_information = {} lines_information = {}
if building_names is None: if building_names is None:
building_names = [b.name for b in city.buildings] building_names = [b.name for b in city.buildings]
x = int((city.upper_corner[0] - city.lower_corner[0]) * 0.5) + 1 factor = GeometryHelper.factor()
y = int((city.upper_corner[1] - city.lower_corner[1]) * 0.5) + 1 x = math.ceil((city.upper_corner[0] - city.lower_corner[0]) * factor) + 1
y = math.ceil((city.upper_corner[1] - city.lower_corner[1]) * factor) + 1
city_map = [['' for _ in range(y + 1)] for _ in range(x + 1)] city_map = [['' for _ in range(y + 1)] for _ in range(x + 1)]
map_info = [[{} for _ in range(y + 1)] for _ in range(x + 1)] map_info = [[{} for _ in range(y + 1)] for _ in range(x + 1)]
img = Image.new('RGB', (x + 1, y + 1), "black") # create a new black image img = Image.new('RGB', (x + 1, y + 1), "black") # create a new black image
@ -92,15 +99,18 @@ class GeometryHelper:
if i == length: if i == length:
j = 0 j = 0
next_coordinate = ground.perimeter_polygon.coordinates[j] next_coordinate = ground.perimeter_polygon.coordinates[j]
point = GeometryHelper.coordinate_to_map_point(coordinate, city) distance = GeometryHelper.distance_between_points(coordinate, next_coordinate)
distance = int(GeometryHelper.distance_between_points(coordinate, next_coordinate))
if distance == 0: if distance == 0:
continue continue
delta_x = (coordinate[0] - next_coordinate[0]) / (distance / 0.5) steps = int(distance * factor * 2)
delta_y = (coordinate[1] - next_coordinate[1]) / (distance / 0.5) delta_x = (next_coordinate[0] - coordinate[0]) / steps
for k in range(0, distance): delta_y = (next_coordinate[1] - coordinate[1]) / steps
x = MapPoint(point.x + (delta_x * k), point.y + (delta_y * k)).x
y = MapPoint(point.x + (delta_x * k), point.y + (delta_y * k)).y for k in range(0, steps):
new_coordinate = (coordinate[0] + (delta_x * k), coordinate[1] + (delta_y * k))
point = GeometryHelper.coordinate_to_map_point(new_coordinate, city)
x = point.x
y = point.y
if city_map[x][y] == '': if city_map[x][y] == '':
city_map[x][y] = building.name city_map[x][y] = building.name
map_info[x][y] = { map_info[x][y] = {
@ -172,48 +182,6 @@ class GeometryHelper:
img.show() img.show()
return lines_information return lines_information
@staticmethod
def fast_city_mapping(city, building_names=None):
lines_information = {}
if building_names is None:
building_names = [b.name for b in city.buildings]
x = int((city.upper_corner[0] - city.lower_corner[0]) * 0.5) + 1
y = int((city.upper_corner[1] - city.lower_corner[1]) * 0.5) + 1
city_map = [['' for _ in range(y + 1)] for _ in range(x + 1)]
for building_name in building_names:
building = city.city_object(building_name)
line = 0
for ground in building.grounds:
length = len(ground.perimeter_polygon.coordinates) - 1
for i, coordinate in enumerate(ground.perimeter_polygon.coordinates):
j = i + 1
if i == length:
j = 0
next_coordinate = ground.perimeter_polygon.coordinates[j]
point = GeometryHelper.coordinate_to_map_point(coordinate, city)
distance = int(GeometryHelper.distance_between_points(coordinate, next_coordinate))
if distance == 0:
continue
delta_x = (coordinate[0] - next_coordinate[0]) / (distance / 0.5)
delta_y = (coordinate[1] - next_coordinate[1]) / (distance / 0.5)
for k in range(0, distance):
x = MapPoint(point.x + (delta_x * k), point.y + (delta_y * k)).x
y = MapPoint(point.x + (delta_x * k), point.y + (delta_y * k)).y
if city_map[x][y] == '':
city_map[x][y] = building.name
elif city_map[x][y] != building.name:
neighbour = city.city_object(city_map[x][y])
if building.neighbours is None:
building.neighbours = [neighbour]
elif neighbour not in building.neighbours:
building.neighbours.append(neighbour)
if neighbour.neighbours is None:
neighbour.neighbours = [building]
elif building not in neighbour.neighbours:
neighbour.neighbours.append(building)
line += 1
return lines_information
@staticmethod @staticmethod
def segment_list_to_trimesh(lines) -> Trimesh: def segment_list_to_trimesh(lines) -> Trimesh:
""" """
@ -298,19 +266,24 @@ class GeometryHelper:
""" """
Get Location from latitude and longitude Get Location from latitude and longitude
""" """
url = 'https://nominatim.openstreetmap.org/reverse?lat={latitude}&lon={longitude}&format=json' _data_path = Path(Path(__file__).parent.parent / 'data/geolocation/cities15000.txt').resolve()
response = requests.get(url.format(latitude=latitude, longitude=longitude)) latitude = float(latitude)
if response.status_code != 200: longitude = float(longitude)
# This means something went wrong. distance = math.inf
raise Exception('GET /tasks/ {}'.format(response.status_code)) country = 'Unknown'
response = response.json()
city = 'Unknown' city = 'Unknown'
country = 'ca' with open(_data_path, 'r', encoding='utf-8') as f:
if 'city' in response['address']: for line_number, line in enumerate(f):
city = response['address']['city'] fields = line.split('\t')
if 'country_code' in response['address']: file_city_name = fields[2]
country = response['address']['country_code'] file_latitude = float(fields[4])
file_longitude = float(fields[5])
file_country_code = fields[8]
new_distance = math.sqrt(pow((latitude - file_latitude), 2) + pow((longitude - file_longitude), 2))
if distance > new_distance:
distance = new_distance
country = file_country_code
city = file_city_name
return Location(country, city) return Location(country, city)
@staticmethod @staticmethod

View File

@ -4,7 +4,6 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import datetime
import math import math
import sys import sys
from hub.hub_logger import logger from hub.hub_logger import logger
@ -23,6 +22,7 @@ class NrcanPhysicsParameters:
NrcanPhysicsParameters class NrcanPhysicsParameters class
""" """
def __init__(self, city, base_path, divide_in_storeys=False): def __init__(self, city, base_path, divide_in_storeys=False):
# create a thread pool with 8 threads
self._city = city self._city = city
self._path = base_path self._path = base_path
self._divide_in_storeys = divide_in_storeys self._divide_in_storeys = divide_in_storeys
@ -67,6 +67,7 @@ class NrcanPhysicsParameters:
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:
for thermal_zone in internal_zone.thermal_zones: for thermal_zone in internal_zone.thermal_zones:
thermal_zone.total_floor_area = thermal_zone.footprint_area thermal_zone.total_floor_area = thermal_zone.footprint_area
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:
self._assign_values(internal_zone.thermal_zones, archetype) self._assign_values(internal_zone.thermal_zones, archetype)
for thermal_zone in internal_zone.thermal_zones: for thermal_zone in internal_zone.thermal_zones:

View File

@ -71,8 +71,11 @@ class Geojson:
polygon = Polygon(points) polygon = Polygon(points)
polygon.area = igh.ground_area(points) polygon.area = igh.ground_area(points)
surface = Surface(polygon, polygon) surface = Surface(polygon, polygon)
surfaces.append(surface) if len(buildings) == 1:
buildings.append(Building(f'{name}_zone_{zone}', surfaces, year_of_construction, function)) buildings[0].surfaces.append(surface)
else:
surfaces.append(surface)
buildings.append(Building(f'{name}', surfaces, year_of_construction, function))
return buildings return buildings
@staticmethod @staticmethod
@ -82,9 +85,10 @@ class Geojson:
buildings = [] buildings = []
for zone, lod0_building in enumerate(lod0_buildings): for zone, lod0_building in enumerate(lod0_buildings):
# print(zone, lod0_building.name)
volume = 0
for surface in lod0_building.grounds: for surface in lod0_building.grounds:
volume = volume + surface.solid_polygon.area * height
volume = surface.solid_polygon.area * height
surfaces.append(surface) surfaces.append(surface)
roof_coordinates = [] roof_coordinates = []
# adding a roof means invert the polygon coordinates and change the Z value # adding a roof means invert the polygon coordinates and change the Z value
@ -112,10 +116,9 @@ class Geojson:
polygon = Polygon(wall_coordinates) polygon = Polygon(wall_coordinates)
wall = Surface(polygon, polygon) wall = Surface(polygon, polygon)
surfaces.append(wall) surfaces.append(wall)
building = Building(f'{name}', surfaces, year_of_construction, function)
building = Building(f'{name}_zone_{zone}', surfaces, year_of_construction, function) building.volume = volume
building.volume = volume buildings.append(building)
buildings.append(building)
return buildings return buildings
@ -159,7 +162,7 @@ class Geojson:
if point[2] < 0.5: if point[2] < 0.5:
ground_line.append(point) ground_line.append(point)
for entry in building_mapped: for entry in building_mapped:
if building_mapped[entry]['shared_points'] <= 3: if building_mapped[entry]['shared_points'] <= 2:
continue continue
line = [building_mapped[entry]['line_start'], building_mapped[entry]['line_end']] line = [building_mapped[entry]['line_start'], building_mapped[entry]['line_end']]
neighbour_line = [building_mapped[entry]['neighbour_line_start'], neighbour_line = [building_mapped[entry]['neighbour_line_start'],
@ -170,6 +173,8 @@ class Geojson:
GeometryHelper.distance_between_points(neighbour_line[0], neighbour_line[1]) - GeometryHelper.distance_between_points(neighbour_line[0], neighbour_line[1]) -
GeometryHelper.distance_between_points(line[1], neighbour_line[0]) - GeometryHelper.distance_between_points(line[1], neighbour_line[0]) -
GeometryHelper.distance_between_points(line[0], neighbour_line[1])) / 2 GeometryHelper.distance_between_points(line[0], neighbour_line[1])) / 2
print(line_shared)
print()
percentage_ground = line_shared / GeometryHelper.distance_between_points(line[0], line[1]) percentage_ground = line_shared / GeometryHelper.distance_between_points(line[0], line[1])
percentage_height = neighbour_height / building.max_height percentage_height = neighbour_height / building.max_height
if percentage_height > 1: if percentage_height > 1:
@ -218,7 +223,7 @@ class Geojson:
polygons = self._get_polygons(polygons, coordinates) polygons = self._get_polygons(polygons, coordinates)
for polygon in polygons: for polygon in polygons:
if extrusion_height == 0: if extrusion_height == 0:
buildings = buildings + Geojson._create_buildings_lod0(f'{building_name}_part_{part}', buildings = buildings + Geojson._create_buildings_lod0(f'{building_name}',
year_of_construction, year_of_construction,
function, function,
[polygon]) [polygon])
@ -226,11 +231,22 @@ class Geojson:
else: else:
if self._max_z < extrusion_height: if self._max_z < extrusion_height:
self._max_z = extrusion_height self._max_z = extrusion_height
buildings = buildings + Geojson._create_buildings_lod1(f'{building_name}_part_{part}', if part == 0:
year_of_construction, buildings = buildings + Geojson._create_buildings_lod1(f'{building_name}',
function, year_of_construction,
extrusion_height, function,
[polygon]) extrusion_height,
[polygon])
else:
new_part = Geojson._create_buildings_lod1(f'{building_name}',
year_of_construction,
function,
extrusion_height,
[polygon])
surfaces = buildings[len(buildings) - 1].surfaces + new_part[0].surfaces
volume = buildings[len(buildings) - 1].volume + new_part[0].volume
buildings[len(buildings) - 1] = Building(f'{building_name}', surfaces, year_of_construction, function)
buildings[len(buildings) - 1].volume = volume
self._city = City([self._min_x, self._min_y, 0.0], [self._max_x, self._max_y, self._max_z], 'epsg:26911') self._city = City([self._min_x, self._min_y, 0.0], [self._max_x, self._max_y, self._max_z], 'epsg:26911')
for building in buildings: for building in buildings:

View File

@ -107,6 +107,9 @@ class GeometryFactory:
Enrich the city given to the class using the class given handler Enrich the city given to the class using the class given handler
:return: City :return: City
""" """
if self._data_frame is None: return Geojson(self._path,
self._data_frame = geopandas.read_file(self._path) self._name_field,
return GPandas(self._data_frame).city self._height_field,
self._year_of_construction_field,
self._function_field,
self._function_to_hub).city

View File

@ -4,7 +4,6 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Guillermo.GutierrezMorote@concordia.ca Project Coder Guillermo.GutierrezMorote@concordia.ca
""" """
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
import csv import csv
@ -40,60 +39,55 @@ class InselMonthlyEnergyBalance:
monthly_cooling = pd.DataFrame(cooling, columns=[cte.INSEL_MEB]).astype(float) monthly_cooling = pd.DataFrame(cooling, columns=[cte.INSEL_MEB]).astype(float)
return monthly_heating, monthly_cooling return monthly_heating, monthly_cooling
def _dhw_demand(self): def _dhw_and_electric_demand(self):
for building in self._city.buildings: for building in self._city.buildings:
domestic_hot_water_demand = [] domestic_hot_water_demand = []
if building.internal_zones[0].thermal_zones is None:
domestic_hot_water_demand = [0] * 12
else:
thermal_zone = building.internal_zones[0].thermal_zones[0]
area = thermal_zone.total_floor_area
cold_water = building.cold_water_temperature[cte.MONTH]['epw']
for month in range(0, 12):
total_dhw_demand = 0
for schedule in thermal_zone.domestic_hot_water.schedules:
total_day = 0
for value in schedule.values:
total_day += value
for day_type in schedule.day_types:
demand = thermal_zone.domestic_hot_water.peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY \
* (thermal_zone.domestic_hot_water.service_temperature - cold_water[month])
total_dhw_demand += total_day * cte.DAYS_A_MONTH[day_type][month] * demand
domestic_hot_water_demand.append(total_dhw_demand * area)
building.domestic_hot_water_heat_demand[cte.MONTH] = \
pd.DataFrame(domestic_hot_water_demand, columns=[cte.INSEL_MEB])
def _electrical_demand(self):
for building in self._city.buildings:
lighting_demand = [] lighting_demand = []
appliances_demand = [] appliances_demand = []
if building.internal_zones[0].thermal_zones is None: if building.internal_zones[0].thermal_zones is None:
domestic_hot_water_demand = [0] * 12
lighting_demand = [0] * 12 lighting_demand = [0] * 12
appliances_demand = [0] * 12 appliances_demand = [0] * 12
else: else:
thermal_zone = building.internal_zones[0].thermal_zones[0] thermal_zone = building.internal_zones[0].thermal_zones[0]
area = thermal_zone.total_floor_area area = thermal_zone.total_floor_area
cold_water = building.cold_water_temperature[cte.MONTH]['epw']
peak_flow = thermal_zone.domestic_hot_water.peak_flow
service_temperature = thermal_zone.domestic_hot_water.service_temperature
lighting_density = thermal_zone.lighting.density
appliances_density = thermal_zone.appliances.density
for month in range(0, 12): for month in range(0, 12):
total_dhw_demand = 0
total_lighting = 0 total_lighting = 0
total_appliances = 0
for schedule in thermal_zone.lighting.schedules: for schedule in thermal_zone.lighting.schedules:
total_day = 0 total_day = 0
for value in schedule.values: for value in schedule.values:
total_day += value total_day += value
for day_type in schedule.day_types: for day_type in schedule.day_types:
total_lighting += total_day * cte.DAYS_A_MONTH[day_type][month] * thermal_zone.lighting.density total_lighting += total_day * cte.DAYS_A_MONTH[day_type][month] * lighting_density
lighting_demand.append(total_lighting * area) lighting_demand.append(total_lighting * area)
total_appliances = 0
for schedule in thermal_zone.appliances.schedules: for schedule in thermal_zone.appliances.schedules:
total_day = 0 total_day = 0
for value in schedule.values: for value in schedule.values:
total_day += value total_day += value
for day_type in schedule.day_types: for day_type in schedule.day_types:
total_appliances += total_day * cte.DAYS_A_MONTH[day_type][month] * thermal_zone.appliances.density total_appliances += total_day * cte.DAYS_A_MONTH[day_type][month] * appliances_density
appliances_demand.append(total_appliances * area) appliances_demand.append(total_appliances * area)
for schedule in thermal_zone.domestic_hot_water.schedules:
total_day = 0
for value in schedule.values:
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])
total_dhw_demand += total_day * cte.DAYS_A_MONTH[day_type][month] * demand
domestic_hot_water_demand.append(total_dhw_demand * area)
building.domestic_hot_water_heat_demand[cte.MONTH] = pd.DataFrame(domestic_hot_water_demand, columns=[cte.INSEL_MEB])
building.lighting_electrical_demand[cte.MONTH] = pd.DataFrame(lighting_demand, columns=[cte.INSEL_MEB]) building.lighting_electrical_demand[cte.MONTH] = pd.DataFrame(lighting_demand, columns=[cte.INSEL_MEB])
building.appliances_electrical_demand[cte.MONTH] = pd.DataFrame(appliances_demand, columns=[cte.INSEL_MEB]) building.appliances_electrical_demand[cte.MONTH] = pd.DataFrame(appliances_demand, columns=[cte.INSEL_MEB])
@ -109,5 +103,4 @@ class InselMonthlyEnergyBalance:
building.cooling[cte.YEAR] = pd.DataFrame( building.cooling[cte.YEAR] = pd.DataFrame(
[building.cooling[cte.MONTH][cte.INSEL_MEB].astype(float).sum()], columns=[cte.INSEL_MEB] [building.cooling[cte.MONTH][cte.INSEL_MEB].astype(float).sum()], columns=[cte.INSEL_MEB]
) )
self._dhw_demand() self._dhw_and_electric_demand()
self._electrical_demand()

View File

@ -0,0 +1,118 @@
"""
Calculation of loads for peak heating and cooling
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import hub.helpers.constants as cte
class LoadsCalculation:
"""
LoadsCalculation class
"""
def __init__(self, building):
self._building = building
@staticmethod
def _get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature, ground_temperature):
load_transmitted_opaque = 0
load_transmitted_transparent = 0
for thermal_boundary in thermal_zone.thermal_boundaries:
if thermal_boundary.type == cte.GROUND:
external_temperature = ground_temperature
elif thermal_boundary.type == cte.INTERIOR_WALL:
external_temperature = internal_temperature
else:
external_temperature = ambient_temperature
load_transmitted_opaque += thermal_boundary.u_value * thermal_boundary.opaque_area \
* (internal_temperature - external_temperature)
for thermal_opening in thermal_boundary.thermal_openings:
load_transmitted_transparent += thermal_opening.overall_u_value \
* (internal_temperature - external_temperature)
load_transmitted_opaque += thermal_zone.additional_thermal_bridge_u_value * thermal_zone.footprint_area \
* (internal_temperature - ambient_temperature)
load_transmitted = load_transmitted_opaque + load_transmitted_transparent
return load_transmitted
@staticmethod
def _get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature):
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)
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)
load_ventilation = load_renovation_sensible + load_infiltration_sensible
return load_ventilation
def get_heating_transmitted_load(self, ambient_temperature, ground_temperature):
heating_load_transmitted = 0
for internal_zone in self._building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
heating_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
ground_temperature)
return heating_load_transmitted
def get_cooling_transmitted_load(self, ambient_temperature, ground_temperature):
cooling_load_transmitted = 0
for internal_zone in self._building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
cooling_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
ground_temperature)
return cooling_load_transmitted
def get_heating_ventilation_load_sensible(self, ambient_temperature):
heating_ventilation_load = 0
for internal_zone in self._building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
heating_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
return heating_ventilation_load
def get_cooling_ventilation_load_sensible(self, ambient_temperature):
cooling_ventilation_load = 0
for internal_zone in self._building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
cooling_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
return cooling_ventilation_load
def get_internal_load_sensible(self):
cooling_load_occupancy_sensible = 0
cooling_load_lighting = 0
cooling_load_equipment_sensible = 0
for internal_zone in self._building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
cooling_load_occupancy_sensible += (thermal_zone.occupancy.sensible_convective_internal_gain
+ thermal_zone.occupancy.sensible_radiative_internal_gain) \
* thermal_zone.footprint_area
cooling_load_lighting += (thermal_zone.lighting.density * thermal_zone.lighting.convective_fraction
+ thermal_zone.lighting.density * thermal_zone.lighting.radiative_fraction) \
* thermal_zone.footprint_area
cooling_load_equipment_sensible += (thermal_zone.appliances.density * thermal_zone.appliances.convective_fraction
+ thermal_zone.appliances.density * thermal_zone.appliances.radiative_fraction) \
* thermal_zone.footprint_area
internal_load = cooling_load_occupancy_sensible + cooling_load_lighting + cooling_load_equipment_sensible
return internal_load
def get_radiation_load(self, irradiance_format, hour):
cooling_load_radiation = 0
for internal_zone in self._building.internal_zones:
for thermal_zone in internal_zone.thermal_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][irradiance_format][hour]
cooling_load_radiation += thermal_opening.area * (1 - thermal_opening.frame_ratio) * thermal_opening.g_value \
* radiation
return cooling_load_radiation

View File

@ -0,0 +1,61 @@
import hub.helpers.constants as cte
from hub.imports.results.peak_calculation.loads_calculation import LoadsCalculation
class PeakLoad:
_MONTH_STARTING_HOUR = [0, 744, 1416, 2160, 2880, 3624, 4344, 5088, 5832, 6552, 7296, 8016]
def __init__(self, city):
self._city = city
self._weather_format = 'epw'
def enrich(self):
for building in self._city.buildings:
monthly_heating_loads = []
monthly_cooling_loads = []
ambient_temperature = building.external_temperature[cte.HOUR][self._weather_format]
for month in range(0, 12):
ground_temperature = building.ground_temperature[cte.MONTH]['2'][month]
heating_ambient_temperature = 100
cooling_ambient_temperature = -100
heating_calculation_hour = -1
cooling_calculation_hour = -1
start_hour = self._MONTH_STARTING_HOUR[month]
end_hour = 8760
if month < 11:
end_hour = self._MONTH_STARTING_HOUR[month + 1]
for hour in range(start_hour, end_hour):
temperature = ambient_temperature[hour]
if temperature < heating_ambient_temperature:
heating_ambient_temperature = temperature
heating_calculation_hour = hour
if temperature > cooling_ambient_temperature:
cooling_ambient_temperature = temperature
cooling_calculation_hour = hour
loads = LoadsCalculation(building)
heating_load_transmitted = loads.get_heating_transmitted_load(heating_ambient_temperature, ground_temperature)
heating_load_ventilation_sensible = loads.get_heating_ventilation_load_sensible(heating_ambient_temperature)
heating_load_ventilation_latent = 0
heating_load = heating_load_transmitted + heating_load_ventilation_sensible + heating_load_ventilation_latent
cooling_load_transmitted = loads.get_cooling_transmitted_load(cooling_ambient_temperature, ground_temperature)
cooling_load_renovation_sensible = loads.get_cooling_ventilation_load_sensible(cooling_ambient_temperature)
cooling_load_internal_gains_sensible = loads.get_internal_load_sensible()
cooling_load_radiation = loads.get_radiation_load(self._irradiance_format, cooling_calculation_hour)
cooling_load_sensible = cooling_load_transmitted + cooling_load_renovation_sensible - cooling_load_radiation \
- cooling_load_internal_gains_sensible
cooling_load_latent = 0
cooling_load = cooling_load_sensible + cooling_load_latent
if heating_load < 0:
heating_load = 0
if cooling_load > 0:
cooling_load = 0
monthly_heating_loads.append(heating_load)
monthly_cooling_loads.append(cooling_load)
self._results[building.name] = {'monthly heating peak load': monthly_heating_loads,
'monthly cooling peak load': monthly_cooling_loads}
self._print_results()

View File

@ -9,6 +9,7 @@ from pathlib import Path
from hub.helpers.utils import validate_import_export_type from hub.helpers.utils import validate_import_export_type
from hub.hub_logger import logger from hub.hub_logger import logger
from hub.imports.results.peak_load import PeakLoad
from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance
from hub.imports.results.insel_heatpump_energy_demand import InselHeatPumpEnergyDemand from hub.imports.results.insel_heatpump_energy_demand import InselHeatPumpEnergyDemand
@ -59,6 +60,12 @@ class ResultFactory:
""" """
InselMonthlyEnergyBalance(self._city, self._base_path).enrich() InselMonthlyEnergyBalance(self._city, self._base_path).enrich()
def _peak_load(self):
"""
Enrich the city with peak load results
"""
PeakLoad(self._city).enrich()
def enrich(self): def enrich(self):
""" """
Enrich the city given to the class using the usage factory given handler Enrich the city given to the class using the usage factory given handler

View File

@ -83,7 +83,7 @@ class NrcanUsageParameters:
if archetype.mechanical_air_change > 0: if archetype.mechanical_air_change > 0:
usage.mechanical_air_change = archetype.mechanical_air_change usage.mechanical_air_change = archetype.mechanical_air_change
elif archetype.ventilation_rate > 0: elif archetype.ventilation_rate > 0:
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area * cte.HOUR_TO_SECONDS usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area
else: else:
usage.mechanical_air_change = 0 usage.mechanical_air_change = 0
_occupancy = Occupancy() _occupancy = Occupancy()

View File

@ -60,7 +60,7 @@ class CityLayerTest(TestCase):
def _genidf(self, bldgs_group): def _genidf(self, bldgs_group):
buildings_df, target_buildings, adjacent_buildings = self._prepare_buildings(bldgs_group) buildings_df, target_buildings, adjacent_buildings = self._prepare_buildings(bldgs_group)
output_path = (Path(__file__).parent / 'tests_outputs').resolve() #output_path = (Path(__file__).parent / 'tests_outputs').resolve()
city = GeometryFactory('gpandas', data_frame=buildings_df).city city = GeometryFactory('gpandas', data_frame=buildings_df).city
ConstructionFactory('nrel', city).enrich() ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich() UsageFactory('comnet', city).enrich()

View File

@ -18,11 +18,13 @@ class TestCostsCatalog(TestCase):
self.assertIsNotNone(catalog, 'catalog is none') self.assertIsNotNone(catalog, 'catalog is none')
content = catalog.entries() content = catalog.entries()
self.assertTrue(len(content.archetypes) == 2) self.assertTrue(len(content.archetypes) == 2)
print(catalog)
# retrieving all the entries should not raise any exceptions # retrieving all the entries should not raise any exceptions
for category in catalog_categories: for category in catalog_categories:
for value in catalog_categories[category]: for value in catalog_categories[category]:
catalog.get_entry(value) catalog.get_entry(value)
print(value)
with self.assertRaises(IndexError): with self.assertRaises(IndexError):
catalog.get_entry('unknown') catalog.get_entry('unknown')

View File

@ -8,7 +8,10 @@ from pathlib import Path
from unittest import TestCase from unittest import TestCase
import hub.exports.exports_factory import hub.exports.exports_factory
from hub.helpers.dictionaries import MontrealFunctionToHubFunction from hub.imports.usage_factory import UsageFactory
from hub.exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
from hub.helpers.dictionaries import MontrealFunctionToHubFunction, Dictionaries
from hub.helpers.geometry_helper import GeometryHelper from hub.helpers.geometry_helper import GeometryHelper
from hub.imports.construction_factory import ConstructionFactory from hub.imports.construction_factory import ConstructionFactory
from hub.imports.geometry_factory import GeometryFactory from hub.imports.geometry_factory import GeometryFactory
@ -161,7 +164,7 @@ class TestGeometryFactory(TestCase):
year_of_construction_field='ANNEE_CONS', year_of_construction_field='ANNEE_CONS',
function_field='LIBELLE_UT') function_field='LIBELLE_UT')
info_lod0 = GeometryHelper.city_mapping(city, plot=False) # info_lod0 = GeometryHelper.city_mapping(city, plot=False)
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export() hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
self.assertEqual(info_lod0, info_lod1) self.assertEqual(info_lod0, info_lod1)
for building in city.buildings: for building in city.buildings:
@ -173,3 +176,37 @@ class TestGeometryFactory(TestCase):
self.assertEqual('3_part_0_zone_0', city.city_object('2_part_0_zone_0').neighbours[1].name) self.assertEqual('3_part_0_zone_0', city.city_object('2_part_0_zone_0').neighbours[1].name)
self.assertEqual('1_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[0].name) self.assertEqual('1_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[0].name)
self.assertEqual('2_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[1].name) self.assertEqual('2_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[1].name)
def test_neighbours(self):
"""
Test neighbours map creation
"""
file_path = (self._example_path / 'concordia_clean.geojson').resolve()
city = GeometryFactory('geojson',
path=file_path,
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
name_field='OBJECTID_12',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
# print(city.lower_corner, city.upper_corner)
for building in city.buildings:
#for ground in building.grounds:
# print(ground.perimeter_polygon.coordinates)
# print(ground.perimeter_polygon.coordinates[0][0] - city.lower_corner[0], ground.perimeter_polygon.coordinates[0][1] - city.lower_corner[1])
# print(ground.perimeter_polygon.coordinates[1][0] - city.lower_corner[0], ground.perimeter_polygon.coordinates[1][1] - city.lower_corner[1])
break
ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
info_lod1 = GeometryHelper.city_mapping(city, plot=True)
for building in city.buildings:
print(building.name)
ns = ''
for n in building.neighbours:
ns = f'{ns} {n.name}'
for surface in n.surfaces:
print('shared', surface.percentage_shared)
print('\t', ns)
# EnergyBuildingsExportsFactory('idf', city, self._output_path).export()

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,2 @@
# Ignore everything in this directory
.gitignore
# Except this file # Except this file
!.gitignore !.gitignore

View File

@ -25,3 +25,4 @@ triangle
psycopg2-binary psycopg2-binary
Pillow Pillow
pathlib pathlib
pickle5

View File

@ -87,6 +87,7 @@ setup(
('hub/catalog_factories/greenery/ecore_greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')), ('hub/catalog_factories/greenery/ecore_greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')),
('hub/data/construction.', glob.glob('hub/data/construction/*')), ('hub/data/construction.', glob.glob('hub/data/construction/*')),
('hub/data/customized_imports', glob.glob('hub/data/customized_imports/*.xml')), ('hub/data/customized_imports', glob.glob('hub/data/customized_imports/*.xml')),
('data/geolocation', glob.glob('hub/data/geolocation/*.txt')),
('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.xml')), ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.xml')),
('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.insel')), ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.insel')),
('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.xlsx')), ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.xlsx')),