hub/imports/usage/comnet_usage_parameters.py

163 lines
7.6 KiB
Python

"""
ComnetUsageParameters model the usage properties
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import sys
from typing import Dict
import pandas as pd
import helpers.constants as cte
from helpers.configuration_helper import ConfigurationHelper as ch
from imports.geometry.helpers.geometry_helper import GeometryHelper
from imports.usage.helpers.usage_helper import UsageHelper
from city_model_structure.building_demand.usage_zone import UsageZone
from city_model_structure.building_demand.internal_gains import InternalGains
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa
class ComnetUsageParameters:
"""
ComnetUsageParameters class
"""
def __init__(self, city, base_path):
self._city = city
self._base_path = str(base_path / 'comnet_archetypes.xlsx')
self._usage_archetypes = []
data = self._read_file()
for item in data['lighting']:
for usage in UsageHelper.usage_to_comnet:
comnet_usage = UsageHelper.usage_to_comnet[usage]
if comnet_usage == item:
usage_archetype = self._parse_zone_usage_type(comnet_usage, data)
self._usage_archetypes.append(usage_archetype)
def _read_file(self) -> Dict:
"""
reads xlsx file containing usage information into a dictionary
:return : Dict
"""
number_usage_types = 33
xl_file = pd.ExcelFile(self._base_path)
file_data = pd.read_excel(xl_file, sheet_name="Modeling Data", skiprows=[0, 1, 2],
nrows=number_usage_types, usecols="A:Z")
lighting_data = {}
plug_loads_data = {}
occupancy_data = {}
ventilation_rate = {}
water_heating = {}
process_data = {}
for j in range(0, number_usage_types):
usage_parameters = file_data.iloc[j]
usage_type = usage_parameters[0]
lighting_data[usage_type] = usage_parameters[1:6].values.tolist()
plug_loads_data[usage_type] = usage_parameters[8:13].values.tolist()
occupancy_data[usage_type] = usage_parameters[17:20].values.tolist()
ventilation_rate[usage_type] = usage_parameters[20:21].values.tolist()
water_heating[usage_type] = usage_parameters[23:24].values.tolist()
process_data[usage_type] = usage_parameters[24:26].values.tolist()
return {'lighting': lighting_data,
'plug loads': plug_loads_data,
'occupancy': occupancy_data,
'ventilation rate': ventilation_rate,
'water heating': water_heating,
'process': process_data}
@staticmethod
def _parse_zone_usage_type(usage, data):
if data['occupancy'][usage][0] <= 0:
occupancy_density = 0
else:
occupancy_density = 1 / data['occupancy'][usage][0]
mechanical_air_change = data['ventilation rate'][usage][0]
internal_gains = []
# lighting
latent_fraction = ch().comnet_lighting_latent
convective_fraction = ch().comnet_lighting_convective
radiative_fraction = ch().comnet_lighting_radiant
average_internal_gain = data['lighting'][usage][4]
internal_gains.append(higa(internal_gains_type=cte.LIGHTING, average_internal_gain=average_internal_gain,
convective_fraction=convective_fraction, radiative_fraction=radiative_fraction,
latent_fraction=latent_fraction))
# occupancy
latent_fraction = data['occupancy'][usage][2] / (data['occupancy'][usage][1] + data['occupancy'][usage][2])
sensible_fraction = float(1 - latent_fraction)
convective_fraction = sensible_fraction * ch().comnet_occupancy_sensible_convective
radiative_fraction = sensible_fraction * ch().comnet_occupancy_sensible_radiant
average_internal_gain = (data['occupancy'][usage][1] + data['occupancy'][usage][2]) \
* occupancy_density * cte.BTU_H_TO_WATTS
internal_gains.append(higa(internal_gains_type=cte.OCCUPANCY, average_internal_gain=average_internal_gain,
convective_fraction=convective_fraction, radiative_fraction=radiative_fraction,
latent_fraction=latent_fraction))
# plug loads
if data['plug loads'][usage][0] != 'n.a.':
latent_fraction = ch().comnet_plugs_latent
convective_fraction = ch().comnet_plugs_convective
radiative_fraction = ch().comnet_plugs_radiant
average_internal_gain = data['plug loads'][usage][0]
internal_gains.append(higa(internal_gains_type=cte.RECEPTACLE, average_internal_gain=average_internal_gain,
convective_fraction=convective_fraction, radiative_fraction=radiative_fraction,
latent_fraction=latent_fraction))
usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains,
occupancy_density=occupancy_density,
mechanical_air_change=mechanical_air_change)
return usage_zone_archetype
def enrich_buildings(self):
"""
Returns the city with the usage parameters assigned to the buildings
:return:
"""
city = self._city
for building in city.buildings:
usage = GeometryHelper.usage_from_function(building.function)
height = building.average_storey_height
if height is None:
raise Exception('Average storey height not defined, ACH cannot be calculated')
if height <= 0:
raise Exception('Average storey height is zero, ACH cannot be calculated')
archetype = self._search_archetype(UsageHelper.comnet_from_usage(usage))
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'{GeometryHelper.usage_from_function(building.function)}\n')
continue
# just one usage_zone
for thermal_zone in building.thermal_zones:
usage_zone = UsageZone()
usage_zone.usage = usage
self._assign_values(usage_zone, archetype, height)
usage_zone.volume = thermal_zone.volume
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, height):
# Due to the fact that python is not a typed language, the wrong object type is assigned to
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
# Therefore, this walk around has been done.
internal_gains = []
for archetype_internal_gain in archetype.internal_gains:
internal_gain = InternalGains()
internal_gain.type = archetype_internal_gain.type
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain * cte.METERS_TO_FEET**2
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
internal_gains.append(internal_gain)
usage_zone.internal_gains = internal_gains
usage_zone.occupancy_density = archetype.occupancy_density * cte.METERS_TO_FEET**2
usage_zone.mechanical_air_change = archetype.mechanical_air_change * usage_zone.occupancy_density \
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET**3 / height