cerc idf implementation refactoring and added systems
This commit is contained in:
parent
5e384c8185
commit
27514d4d77
@ -7,10 +7,12 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
|
|||||||
Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
|
Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
|
||||||
"""
|
"""
|
||||||
import copy
|
import copy
|
||||||
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import hub.helpers.constants as cte
|
|
||||||
import hub.exports.building_energy.idf_helper as idf_cte
|
import hub.exports.building_energy.idf_helper as idf_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.layer import Layer
|
from hub.city_model_structure.building_demand.layer import Layer
|
||||||
|
|
||||||
@ -43,11 +45,13 @@ class CercIdf:
|
|||||||
'occupancy': str((output_path / 'occupancy.idf').resolve()),
|
'occupancy': str((output_path / 'occupancy.idf').resolve()),
|
||||||
'lighting': str((output_path / 'lights.idf').resolve()),
|
'lighting': str((output_path / 'lights.idf').resolve()),
|
||||||
'appliances': str((output_path / 'appliances.idf').resolve()),
|
'appliances': str((output_path / 'appliances.idf').resolve()),
|
||||||
|
'surfaces': str((output_path / 'surfaces.idf').resolve()),
|
||||||
|
'shading': str((output_path / 'shading.idf').resolve()),
|
||||||
'infiltration': str((output_path / 'infiltration.idf').resolve()),
|
'infiltration': str((output_path / 'infiltration.idf').resolve()),
|
||||||
'ventilation': str((output_path / 'ventilation.idf').resolve()),
|
'ventilation': str((output_path / 'ventilation.idf').resolve()),
|
||||||
'thermostat': str((output_path / 'thermostat.idf').resolve()),
|
'thermostat': str((output_path / 'thermostat.idf').resolve()),
|
||||||
'ideal_load_system': str((output_path / 'ideal_load_system.idf').resolve()),
|
'ideal_load_system': str((output_path / 'ideal_load_system.idf').resolve()),
|
||||||
'surfaces': str((output_path / 'surfaces.idf').resolve()) # todo: move surface to the right position after appliances
|
'dhw': str((output_path / 'dhw.idf').resolve()),
|
||||||
}
|
}
|
||||||
self._files = {}
|
self._files = {}
|
||||||
for key, value in self._file_paths.items():
|
for key, value in self._file_paths.items():
|
||||||
@ -55,7 +59,9 @@ class CercIdf:
|
|||||||
|
|
||||||
self._idd_file_path = str(idd_file_path)
|
self._idd_file_path = str(idd_file_path)
|
||||||
self._idf_file_path = str(idf_file_path)
|
self._idf_file_path = str(idf_file_path)
|
||||||
|
self._outputs_file_path = str(Path(idf_file_path).parent / 'outputs.idf')
|
||||||
self._epw_file_path = str(epw_file_path)
|
self._epw_file_path = str(epw_file_path)
|
||||||
|
|
||||||
self._target_buildings = target_buildings
|
self._target_buildings = target_buildings
|
||||||
self._adjacent_buildings = []
|
self._adjacent_buildings = []
|
||||||
|
|
||||||
@ -83,6 +89,13 @@ class CercIdf:
|
|||||||
with open(path, 'r') as file:
|
with open(path, 'r') as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
self._idf_file.writelines(lines)
|
self._idf_file.writelines(lines)
|
||||||
|
for path in self._file_paths.values():
|
||||||
|
os.unlink(path)
|
||||||
|
|
||||||
|
def _add_outputs(self):
|
||||||
|
with open(self._outputs_file_path, 'r') as base_idf:
|
||||||
|
lines = base_idf.readlines()
|
||||||
|
self._idf_file.writelines(lines)
|
||||||
|
|
||||||
def _create_geometry_rules(self):
|
def _create_geometry_rules(self):
|
||||||
file = self._files['zones']
|
file = self._files['zones']
|
||||||
@ -330,13 +343,6 @@ class CercIdf:
|
|||||||
self._write_to_idf_format(file, thermal_opening.g_value, 'Solar Heat Gain Coefficient', ';')
|
self._write_to_idf_format(file, thermal_opening.g_value, 'Solar Heat Gain Coefficient', ';')
|
||||||
|
|
||||||
def _add_constructions(self, thermal_boundary):
|
def _add_constructions(self, thermal_boundary):
|
||||||
"""
|
|
||||||
CONSTRUCTION,
|
|
||||||
1000_1900_6 Roof, !- Name
|
|
||||||
Asphalt 1, !- Outside Layer
|
|
||||||
virtual_no_mass_13, !- Layer 2
|
|
||||||
MW Glass Wool (rolls); !- Layer 3
|
|
||||||
"""
|
|
||||||
if thermal_boundary.layers is None:
|
if thermal_boundary.layers is None:
|
||||||
thermal_boundary.layers = [self._add_default_material()]
|
thermal_boundary.layers = [self._add_default_material()]
|
||||||
name = f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}'
|
name = f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}'
|
||||||
@ -493,7 +499,6 @@ class CercIdf:
|
|||||||
def _add_ventilation(self, thermal_zone, zone_name):
|
def _add_ventilation(self, thermal_zone, zone_name):
|
||||||
schedule_name = f'Ventilation schedules {thermal_zone.usage_name}'
|
schedule_name = f'Ventilation schedules {thermal_zone.usage_name}'
|
||||||
air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
|
air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
|
||||||
infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS
|
|
||||||
file = self._files['ventilation']
|
file = self._files['ventilation']
|
||||||
self._write_to_idf_format(file, idf_cte.VENTILATION)
|
self._write_to_idf_format(file, idf_cte.VENTILATION)
|
||||||
self._write_to_idf_format(file, f'{zone_name}_ventilation', 'Name')
|
self._write_to_idf_format(file, f'{zone_name}_ventilation', 'Name')
|
||||||
@ -572,17 +577,70 @@ class CercIdf:
|
|||||||
self._write_to_idf_format(file, 0.70, 'Sensible Heat Recovery Effectiveness')
|
self._write_to_idf_format(file, 0.70, 'Sensible Heat Recovery Effectiveness')
|
||||||
self._write_to_idf_format(file, 0.65, 'Latent Heat Recovery Effectiveness', ';')
|
self._write_to_idf_format(file, 0.65, 'Latent Heat Recovery Effectiveness', ';')
|
||||||
|
|
||||||
|
def _add_dhw(self, thermal_zone, zone_name):
|
||||||
|
name = f'DHW {zone_name}'
|
||||||
|
peak_flow_rate = thermal_zone.domestic_hot_water.peak_flow * thermal_zone.total_floor_area
|
||||||
|
flow_rate_schedule = f'DHW_prof schedules {thermal_zone.usage_name}'
|
||||||
|
dhw_schedule = f'DHW_temp schedules {thermal_zone.usage_name}'
|
||||||
|
cold_temp_schedule = f'cold_temp schedules {thermal_zone.usage_name}'
|
||||||
|
file = self._files['dhw']
|
||||||
|
self._write_to_idf_format(file, idf_cte.DHW)
|
||||||
|
self._write_to_idf_format(file, name, 'Name')
|
||||||
|
self._write_to_idf_format(file, name, 'EndUse Subcategory')
|
||||||
|
self._write_to_idf_format(file, peak_flow_rate, 'Peak Flow Rate')
|
||||||
|
self._write_to_idf_format(file, flow_rate_schedule, 'Flow Rate Fraction Schedule Name')
|
||||||
|
self._write_to_idf_format(file, dhw_schedule, 'Target Temperature Schedule Name')
|
||||||
|
self._write_to_idf_format(file, dhw_schedule, 'Hot Water Supply Temperature Schedule Name')
|
||||||
|
self._write_to_idf_format(file, cold_temp_schedule, 'Cold Water Supply Temperature Schedule Name')
|
||||||
|
self._write_to_idf_format(file, zone_name, 'Zone Name', ';')
|
||||||
|
|
||||||
|
def _add_shading(self, building):
|
||||||
|
name = building.name
|
||||||
|
file = self._files['shading']
|
||||||
|
for s, surface in enumerate(building.surfaces):
|
||||||
|
|
||||||
|
self._write_to_idf_format(file, idf_cte.SHADING)
|
||||||
|
self._write_to_idf_format(file, f'{name}_{s}', 'Name')
|
||||||
|
self._write_to_idf_format(file, idf_cte.EMPTY, 'Transmittance Schedule Name')
|
||||||
|
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Number of Vertices')
|
||||||
|
eol = ','
|
||||||
|
coordinates = self._matrix_to_list(surface.solid_polygon.coordinates, self._city.lower_corner)
|
||||||
|
coordinates_length = len(coordinates)
|
||||||
|
for i, coordinate in enumerate(coordinates):
|
||||||
|
vertex = i + 1
|
||||||
|
if vertex == coordinates_length:
|
||||||
|
eol = ';'
|
||||||
|
self._write_to_idf_format(file, coordinate[0], f'Vertex {vertex} Xcoordinate')
|
||||||
|
self._write_to_idf_format(file, coordinate[1], f'Vertex {vertex} Ycoordinate')
|
||||||
|
self._write_to_idf_format(file, coordinate[2], f'Vertex {vertex} Zcoordinate', eol)
|
||||||
|
|
||||||
|
def _add_window_construction_and_material(self, thermal_opening):
|
||||||
|
for window_material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]:
|
||||||
|
if window_material['UFactor'] == thermal_opening.overall_u_value and \
|
||||||
|
window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value:
|
||||||
|
return
|
||||||
|
|
||||||
|
order = str(len(self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]) + 1)
|
||||||
|
material_name = 'glazing_' + order
|
||||||
|
_kwargs = {'Name': material_name, 'UFactor': thermal_opening.overall_u_value,
|
||||||
|
'Solar_Heat_Gain_Coefficient': thermal_opening.g_value}
|
||||||
|
self._idf.newidfobject(self._WINDOW_MATERIAL_SIMPLE, **_kwargs)
|
||||||
|
|
||||||
|
window_construction_name = 'window_construction_' + order
|
||||||
|
_kwargs = {'Name': window_construction_name, 'Outside_Layer': material_name}
|
||||||
|
self._idf.newidfobject(self._CONSTRUCTION, **_kwargs)
|
||||||
|
|
||||||
def _export(self):
|
def _export(self):
|
||||||
|
start = datetime.now()
|
||||||
for building in self._city.buildings:
|
for building in self._city.buildings:
|
||||||
is_target = building.name in self._target_buildings or building.name in self._adjacent_buildings
|
is_target = building.name in self._target_buildings or building.name in self._adjacent_buildings
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
if internal_zone.thermal_zones_from_internal_zones is None:
|
if internal_zone.thermal_zones_from_internal_zones is None:
|
||||||
self._target_buildings.remove(building.name)
|
|
||||||
is_target = False
|
is_target = False
|
||||||
continue
|
continue
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
||||||
if is_target:
|
if is_target:
|
||||||
start = datetime.now()
|
|
||||||
service_temperature = thermal_zone.domestic_hot_water.service_temperature
|
service_temperature = thermal_zone.domestic_hot_water.service_temperature
|
||||||
usage = thermal_zone.usage_name
|
usage = thermal_zone.usage_name
|
||||||
occ = thermal_zone.occupancy
|
occ = thermal_zone.occupancy
|
||||||
@ -624,9 +682,14 @@ class CercIdf:
|
|||||||
self._add_ventilation(thermal_zone, building.name)
|
self._add_ventilation(thermal_zone, building.name)
|
||||||
self._add_thermostat(thermal_zone)
|
self._add_thermostat(thermal_zone)
|
||||||
self._add_heating_system(thermal_zone, building.name)
|
self._add_heating_system(thermal_zone, building.name)
|
||||||
|
self._add_dhw(thermal_zone, building.name)
|
||||||
if is_target:
|
if is_target:
|
||||||
self._add_surfaces(building, building.name)
|
self._add_surfaces(building, building.name)
|
||||||
|
else:
|
||||||
|
self._add_shading(building)
|
||||||
|
|
||||||
self._create_output_control_lighting() # Add lighting control to the lighting
|
self._create_output_control_lighting() # Add lighting control to the lighting
|
||||||
# Merge files
|
# Merge files
|
||||||
self._merge_files()
|
self._merge_files()
|
||||||
|
self._add_outputs()
|
||||||
|
print(f'Export completed in: {datetime.now() - start}')
|
||||||
|
64
hub/exports/building_energy/idf_files/outputs.idf
Normal file
64
hub/exports/building_energy/idf_files/outputs.idf
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
Output:Table:SummaryReports,
|
||||||
|
AnnualBuildingUtilityPerformanceSummary, !- Report 1 Name
|
||||||
|
DemandEndUseComponentsSummary, !- Report 2 Name
|
||||||
|
SensibleHeatGainSummary, !- Report 3 Name
|
||||||
|
InputVerificationandResultsSummary, !- Report 4 Name
|
||||||
|
AdaptiveComfortSummary, !- Report 5 Name
|
||||||
|
Standard62.1Summary, !- Report 6 Name
|
||||||
|
ClimaticDataSummary, !- Report 7 Name
|
||||||
|
EquipmentSummary, !- Report 8 Name
|
||||||
|
EnvelopeSummary, !- Report 9 Name
|
||||||
|
LightingSummary, !- Report 10 Name
|
||||||
|
HVACSizingSummary, !- Report 11 Name
|
||||||
|
SystemSummary, !- Report 12 Name
|
||||||
|
ComponentSizingSummary, !- Report 13 Name
|
||||||
|
OutdoorAirSummary, !- Report 14 Name
|
||||||
|
ObjectCountSummary, !- Report 15 Name
|
||||||
|
EndUseEnergyConsumptionOtherFuelsMonthly, !- Report 16 Name
|
||||||
|
PeakEnergyEndUseOtherFuelsMonthly; !- Report 17 Name
|
||||||
|
|
||||||
|
OutputControl:Table:Style,
|
||||||
|
CommaAndHTML, !- Column Separator
|
||||||
|
JtoKWH; !- Unit Conversion
|
||||||
|
|
||||||
|
OUTPUT:VARIABLE,
|
||||||
|
*, !- Key Value
|
||||||
|
Zone Ideal Loads Supply Air Total Heating Energy, !- Variable Name
|
||||||
|
Hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
OUTPUT:VARIABLE,
|
||||||
|
*, !- Key Value
|
||||||
|
Zone Ideal Loads Supply Air Total Cooling Energy, !- Variable Name
|
||||||
|
Hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
OUTPUT:VARIABLE,
|
||||||
|
*, !- Key Value
|
||||||
|
Water Use Equipment Heating Rate, !- Variable Name
|
||||||
|
Hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
OUTPUT:VARIABLE,
|
||||||
|
*, !- Key Value
|
||||||
|
Zone Lights Electricity Rate, !- Variable Name
|
||||||
|
Hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
OUTPUT:VARIABLE,
|
||||||
|
*, !- Key Value
|
||||||
|
Other Equipment Electricity Rate, !- Variable Name
|
||||||
|
Hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
Output:Meter,
|
||||||
|
DISTRICTHEATING:Facility, !- Key Name
|
||||||
|
hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
Output:Meter,
|
||||||
|
DISTRICTCOOLING:Facility, !- Key Name
|
||||||
|
hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
Output:Meter,
|
||||||
|
InteriorEquipment:Electricity, !- Key Name
|
||||||
|
hourly; !- Reporting Frequency
|
||||||
|
|
||||||
|
Output:Meter,
|
||||||
|
InteriorLights:Electricity, !- Key Name
|
||||||
|
hourly; !- Reporting Frequency
|
@ -17,7 +17,8 @@ INFILTRATION = '\nZONEINFILTRATION:DESIGNFLOWRATE,\n'
|
|||||||
VENTILATION = '\nZONEVENTILATION:DESIGNFLOWRATE,\n'
|
VENTILATION = '\nZONEVENTILATION:DESIGNFLOWRATE,\n'
|
||||||
THERMOSTAT = '\nHVACTEMPLATE:THERMOSTAT,\n'
|
THERMOSTAT = '\nHVACTEMPLATE:THERMOSTAT,\n'
|
||||||
IDEAL_LOAD_SYSTEM = '\nHVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM,\n'
|
IDEAL_LOAD_SYSTEM = '\nHVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM,\n'
|
||||||
|
DHW = '\nWATERUSE:EQUIPMENT,\n'
|
||||||
|
SHADING = '\nSHADING:BUILDING:DETAILED,\n'
|
||||||
|
|
||||||
AUTOCALCULATE = 'autocalculate'
|
AUTOCALCULATE = 'autocalculate'
|
||||||
ROUGHNESS = 'MediumRough'
|
ROUGHNESS = 'MediumRough'
|
||||||
|
Loading…
Reference in New Issue
Block a user