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
|
||||
"""
|
||||
import copy
|
||||
import os
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
import hub.helpers.constants as 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.building_demand.layer import Layer
|
||||
|
||||
@ -30,7 +32,7 @@ class CercIdf:
|
||||
target_buildings=None):
|
||||
self._city = city
|
||||
self._output_path = str(output_path.resolve())
|
||||
self._output_file_path = str((output_path / f'{city.name}.idf').resolve())
|
||||
self._output_file_path = str((output_path / f'{city.name}.idf').resolve())
|
||||
|
||||
self._file_paths = {
|
||||
'schedules': str((output_path / 'schedules.idf').resolve()),
|
||||
@ -43,11 +45,13 @@ class CercIdf:
|
||||
'occupancy': str((output_path / 'occupancy.idf').resolve()),
|
||||
'lighting': str((output_path / 'lights.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()),
|
||||
'ventilation': str((output_path / 'ventilation.idf').resolve()),
|
||||
'thermostat': str((output_path / 'thermostat.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 = {}
|
||||
for key, value in self._file_paths.items():
|
||||
@ -55,7 +59,9 @@ class CercIdf:
|
||||
|
||||
self._idd_file_path = str(idd_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._target_buildings = target_buildings
|
||||
self._adjacent_buildings = []
|
||||
|
||||
@ -83,6 +89,13 @@ class CercIdf:
|
||||
with open(path, 'r') as file:
|
||||
lines = file.readlines()
|
||||
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):
|
||||
file = self._files['zones']
|
||||
@ -330,13 +343,6 @@ class CercIdf:
|
||||
self._write_to_idf_format(file, thermal_opening.g_value, 'Solar Heat Gain Coefficient', ';')
|
||||
|
||||
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:
|
||||
thermal_boundary.layers = [self._add_default_material()]
|
||||
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):
|
||||
schedule_name = f'Ventilation schedules {thermal_zone.usage_name}'
|
||||
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']
|
||||
self._write_to_idf_format(file, idf_cte.VENTILATION)
|
||||
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.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):
|
||||
start = datetime.now()
|
||||
for building in self._city.buildings:
|
||||
is_target = building.name in self._target_buildings or building.name in self._adjacent_buildings
|
||||
for internal_zone in building.internal_zones:
|
||||
if internal_zone.thermal_zones_from_internal_zones is None:
|
||||
self._target_buildings.remove(building.name)
|
||||
is_target = False
|
||||
continue
|
||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
||||
if is_target:
|
||||
start = datetime.now()
|
||||
|
||||
service_temperature = thermal_zone.domestic_hot_water.service_temperature
|
||||
usage = thermal_zone.usage_name
|
||||
occ = thermal_zone.occupancy
|
||||
@ -624,9 +682,14 @@ class CercIdf:
|
||||
self._add_ventilation(thermal_zone, building.name)
|
||||
self._add_thermostat(thermal_zone)
|
||||
self._add_heating_system(thermal_zone, building.name)
|
||||
self._add_dhw(thermal_zone, building.name)
|
||||
if is_target:
|
||||
self._add_surfaces(building, building.name)
|
||||
else:
|
||||
self._add_shading(building)
|
||||
|
||||
self._create_output_control_lighting() # Add lighting control to the lighting
|
||||
# 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'
|
||||
THERMOSTAT = '\nHVACTEMPLATE:THERMOSTAT,\n'
|
||||
IDEAL_LOAD_SYSTEM = '\nHVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM,\n'
|
||||
|
||||
DHW = '\nWATERUSE:EQUIPMENT,\n'
|
||||
SHADING = '\nSHADING:BUILDING:DETAILED,\n'
|
||||
|
||||
AUTOCALCULATE = 'autocalculate'
|
||||
ROUGHNESS = 'MediumRough'
|
||||
|
Loading…
Reference in New Issue
Block a user