solved bug in nrcan catalog and partially cleaned ep exporter
This commit is contained in:
parent
d4029aee10
commit
d82ada6240
|
@ -131,10 +131,9 @@ class NrcanCatalog(Catalog):
|
|||
mechanical_air_change = space_type['ventilation_air_changes']
|
||||
# cfm/ft2 to m3/m2.s
|
||||
ventilation_rate = space_type['ventilation_per_area'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)
|
||||
if ventilation_rate == 0:
|
||||
# cfm/person to m3/m2.s
|
||||
ventilation_rate = space_type['ventilation_per_person'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)\
|
||||
/ occupancy_density
|
||||
# cfm/person to m3/m2.s
|
||||
ventilation_rate += space_type['ventilation_per_person'] / (pow(cte.METERS_TO_FEET, 3) * cte.MINUTES_TO_SECONDS)\
|
||||
* occupancy_density
|
||||
|
||||
lighting_radiative_fraction = space_type['lighting_fraction_radiant']
|
||||
lighting_convective_fraction = 0
|
||||
|
|
|
@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Guillermo.GutierrezMorote@concordia.ca
|
||||
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Oriol Gavaldà Torrellas oriol.gavalda@concordia.ca
|
||||
"""
|
||||
import copy
|
||||
from pathlib import Path
|
||||
|
@ -100,7 +101,6 @@ class Idf:
|
|||
self._adjacent_buildings = adjacent_buildings
|
||||
if self._adjacent_buildings is None:
|
||||
self._adjacent_buildings = []
|
||||
|
||||
self._export()
|
||||
|
||||
@staticmethod
|
||||
|
@ -202,9 +202,13 @@ class Idf:
|
|||
_infiltration_values = []
|
||||
for hvac_value in hvac_availability_schedule.values:
|
||||
if hvac_value == 0:
|
||||
_infiltration_values.append(thermal_zone.infiltration_rate_system_off)
|
||||
_infiltration_values.append(1.0)
|
||||
else:
|
||||
_infiltration_values.append(thermal_zone.infiltration_rate_system_on)
|
||||
if thermal_zone.infiltration_rate_system_off == 0:
|
||||
_infiltration_values.append(0.0)
|
||||
else:
|
||||
_infiltration_values.append(
|
||||
thermal_zone.infiltration_rate_system_on / thermal_zone.infiltration_rate_system_off)
|
||||
_schedule.values = _infiltration_values
|
||||
_infiltration_schedules.append(_schedule)
|
||||
for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
|
||||
|
@ -315,7 +319,6 @@ class Idf:
|
|||
for zone in self._idf.idfobjects['ZONE']:
|
||||
if zone.Name == name:
|
||||
return
|
||||
# todo: what do we need to define a zone in energy plus?
|
||||
self._idf.newidfobject(self._ZONE, Name=name, Volume=thermal_zone.volume)
|
||||
self._add_heating_system(thermal_zone, name)
|
||||
|
||||
|
@ -362,13 +365,9 @@ class Idf:
|
|||
|
||||
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
|
||||
storeys_number = int(thermal_zone.total_floor_area / thermal_zone.footprint_area)
|
||||
watts_per_zone_floor_area = thermal_zone.lighting.density * storeys_number
|
||||
subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#GeneralLights'
|
||||
|
||||
self._idf.newidfobject(self._LIGHTS,
|
||||
|
@ -378,21 +377,17 @@ class Idf:
|
|||
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
|
||||
fraction_latent = thermal_zone.appliances.latent_fraction
|
||||
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
|
||||
storeys_number = int(thermal_zone.total_floor_area / thermal_zone.footprint_area)
|
||||
watts_per_zone_floor_area = thermal_zone.appliances.density * storeys_number
|
||||
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',
|
||||
|
@ -406,36 +401,30 @@ class Idf:
|
|||
)
|
||||
|
||||
def _add_infiltration(self, thermal_zone, zone_name):
|
||||
# for zone in self._idf.idfobjects["ZONE"]:
|
||||
# if zone.Name == f'{zone_name}_infiltration':
|
||||
# return
|
||||
|
||||
for zone in self._idf.idfobjects["ZONE"]:
|
||||
if zone.Name == f'{zone_name}_infiltration':
|
||||
return
|
||||
schedule = f'Infiltration schedules {thermal_zone.usage_name}'
|
||||
# if schedule not in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
|
||||
# return
|
||||
# todo: eliminate the factor
|
||||
factorreduct = 0.5
|
||||
if schedule not in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
|
||||
return
|
||||
self._idf.newidfobject(self._INFILTRATION,
|
||||
Name=f'{zone_name}_infiltration',
|
||||
Zone_or_ZoneList_Name=zone_name,
|
||||
Schedule_Name=schedule,
|
||||
Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
|
||||
Air_Changes_per_Hour=thermal_zone.infiltration_rate_system_off * factorreduct
|
||||
Air_Changes_per_Hour=thermal_zone.infiltration_rate_system_off
|
||||
)
|
||||
|
||||
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
|
||||
def _add_dhw(self, building, thermal_zone, zone_name):
|
||||
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}',
|
||||
Cold_Water_Supply_Temperature_Schedule_Name=f'cold_temp schedules {building.name}',
|
||||
EndUse_Subcategory=f'DHW {zone_name}',
|
||||
Zone_Name=zone_name
|
||||
)
|
||||
|
@ -489,7 +478,7 @@ class Idf:
|
|||
self._add_schedules(usage, 'Lighting', thermal_zone.lighting.schedules)
|
||||
self._add_schedules(usage, 'Appliance', thermal_zone.appliances.schedules)
|
||||
self._add_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules)
|
||||
# self._add_service_temp_schedules(thermal_zone)
|
||||
# todo self._add_service_temp_schedules(thermal_zone)
|
||||
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)
|
||||
|
@ -519,8 +508,6 @@ class Idf:
|
|||
Variable_Name="Zone Ideal Loads Supply Air Total Heating Energy",
|
||||
Reporting_Frequency="Monthly",
|
||||
)
|
||||
# _object = self._idf.newidfobject("OUTPUT:VARIABLE")
|
||||
# print(vars(_object))
|
||||
|
||||
self._idf.newidfobject(
|
||||
"OUTPUT:VARIABLE",
|
||||
|
@ -534,18 +521,6 @@ class Idf:
|
|||
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
|
||||
# pass
|
||||
|
||||
# post-process to erase windows associated to adiabatic walls
|
||||
windows_list = []
|
||||
for window in self._idf.idfobjects[self._WINDOW]:
|
||||
|
@ -598,15 +573,12 @@ class Idf:
|
|||
Fraction_of_Shading_Surface_That_Is_Glazed=0)
|
||||
|
||||
def _add_pure_geometry(self, building, zone_name):
|
||||
|
||||
for surface in building.surfaces:
|
||||
outside_boundary_condition = 'Outdoors'
|
||||
sun_exposure = 'SunExposed'
|
||||
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:
|
||||
if surface.percentage_shared is not None and surface.percentage_shared > 0.5:
|
||||
outside_boundary_condition = 'Surface'
|
||||
outside_boundary_condition_object = surface.name
|
||||
sun_exposure = 'NoSun'
|
||||
|
@ -645,8 +617,7 @@ class Idf:
|
|||
sun_exposure = 'SunExposed'
|
||||
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:
|
||||
if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared >= 0.5:
|
||||
outside_boundary_condition = 'Surface'
|
||||
outside_boundary_condition_object = boundary.parent_surface.name
|
||||
sun_exposure = 'NoSun'
|
||||
|
@ -659,7 +630,6 @@ class Idf:
|
|||
construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}'
|
||||
else:
|
||||
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_Type=idf_surface_type,
|
||||
Zone_Name=zone_name,
|
||||
|
|
|
@ -45,12 +45,12 @@ class NrcanUsageParameters:
|
|||
sys.stderr.write(f'Building {building.name} has unknown usage archetype for usage: {usage_name}\n')
|
||||
continue
|
||||
|
||||
usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
|
||||
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
|
||||
try:
|
||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, usage_name)
|
||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
||||
except KeyError:
|
||||
logger.error(f'Building {building.name} has unknown usage archetype for usage: {usage_name}\n')
|
||||
sys.stderr.write(f'Building {building.name} has unknown usage archetype for usage: {usage_name}\n')
|
||||
logger.error(f'Building {building.name} has unknown usage archetype for usage: {comnet_usage_name}\n')
|
||||
sys.stderr.write(f'Building {building.name} has unknown usage archetype for usage: {comnet_usage_name}\n')
|
||||
continue
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
|
@ -81,8 +81,10 @@ class NrcanUsageParameters:
|
|||
@staticmethod
|
||||
def _assign_values(usage, archetype, volume_per_area, cold_water_temperature):
|
||||
if archetype.mechanical_air_change > 0:
|
||||
# ACH
|
||||
usage.mechanical_air_change = archetype.mechanical_air_change
|
||||
elif archetype.ventilation_rate > 0:
|
||||
# m3/m2.s to ACH
|
||||
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area * cte.HOUR_TO_SECONDS
|
||||
else:
|
||||
usage.mechanical_air_change = 0
|
||||
|
|
Loading…
Reference in New Issue
Block a user