diff --git a/hub/exports/building_energy/cerc_idf.py b/hub/exports/building_energy/cerc_idf.py index ff3d9df6..4f4a138e 100644 --- a/hub/exports/building_energy/cerc_idf.py +++ b/hub/exports/building_energy/cerc_idf.py @@ -13,16 +13,24 @@ from datetime import datetime 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.exports.building_energy.idf_helper.idf_appliance import IdfAppliance from hub.exports.building_energy.idf_helper.idf_base import IdfBase -from hub.exports.building_energy.idf_helper.idf_constructions import IdfConstructions -from hub.exports.building_energy.idf_helper.idf_file_schedules import IdfFileSchedules +from hub.exports.building_energy.idf_helper.idf_construction import IdfConstruction +from hub.exports.building_energy.idf_helper.idf_dhw import IdfDhw +from hub.exports.building_energy.idf_helper.idf_file_schedule import IdfFileSchedule +from hub.exports.building_energy.idf_helper.idf_heating_system import IdfHeatingSystem +from hub.exports.building_energy.idf_helper.idf_infiltration import IdfInfiltration from hub.exports.building_energy.idf_helper.idf_lighting import IdfLighting -from hub.exports.building_energy.idf_helper.idf_materials import IdfMaterials +from hub.exports.building_energy.idf_helper.idf_material import IdfMaterial from hub.exports.building_energy.idf_helper.idf_occupancy import IdfOccupancy -from hub.exports.building_energy.idf_helper.idf_schedules import IdfSchedules +from hub.exports.building_energy.idf_helper.idf_schedule import IdfSchedule +from hub.exports.building_energy.idf_helper.idf_shading import IdfShading from hub.exports.building_energy.idf_helper.idf_surfaces import IdfSurfaces +from hub.exports.building_energy.idf_helper.idf_thermostat import IdfThermostat +from hub.exports.building_energy.idf_helper.idf_ventilation import IdfVentilation from hub.exports.building_energy.idf_helper.idf_windows_constructions import IdfWindowsConstructions -from hub.exports.building_energy.idf_helper.idf_windows_materials import IdfWindowsMaterials +from hub.exports.building_energy.idf_helper.idf_windows_material import IdfWindowsMaterial +from hub.exports.building_energy.idf_helper.idf_zone import IdfZone class CercIdf(IdfBase): @@ -39,15 +47,23 @@ class CercIdf(IdfBase): def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, target_buildings=None): super().__init__(city, output_path, idf_file_path, idd_file_path, epw_file_path, target_buildings) self._add_surfaces = IdfSurfaces.add - self._add_schedules = IdfSchedules.add - self._add_file_schedules = IdfFileSchedules.add - self._add_idf_schedules = IdfSchedules.add - self._add_constructions = IdfConstructions.add - self._add_materials = IdfMaterials.add - self._add_windows_materials = IdfWindowsMaterials.add + self._add_schedule = IdfSchedule.add + self._add_file_schedule = IdfFileSchedule.add + self._add_idf_schedule = IdfSchedule.add + self._add_construction = IdfConstruction.add + self._add_material = IdfMaterial.add + self._add_windows_material = IdfWindowsMaterial.add self._add_windows_constructions = IdfWindowsConstructions.add self._add_occupancy = IdfOccupancy.add self._add_lighting = IdfLighting.add + self._add_appliance = IdfAppliance.add + self._add_infiltration = IdfInfiltration.add + self._add_ventilation = IdfVentilation.add + self._add_zone = IdfZone.add + self._add_thermostat = IdfThermostat.add + self._add_heating_system = IdfHeatingSystem.add + self._add_dhw = IdfDhw.add + self._add_shading = IdfShading.add with open(self._idf_file_path, 'r') as base_idf: lines = base_idf.readlines() @@ -142,181 +158,6 @@ class CercIdf(IdfBase): _schedule.values = [value for _ in range(0, amount)] return [_schedule] - - - def _add_appliances(self, thermal_zone, zone_name): - schedule_name = f'Appliance schedules {thermal_zone.usage_name}' - 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' - file = self._files['appliances'] - self._write_to_idf_format(file, idf_cte.APPLIANCES) - self._write_to_idf_format(file, f'{zone_name}_appliance', 'Name') - self._write_to_idf_format(file, 'Electricity', 'Fuel Type') - self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name') - self._write_to_idf_format(file, schedule_name, 'Schedule Name') - self._write_to_idf_format(file, 'Watts/Area', 'Design Level Calculation Method') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Level') - self._write_to_idf_format(file, watts_per_zone_floor_area, 'Power per Zone Floor Area') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Power per Person') - self._write_to_idf_format(file, thermal_zone.appliances.latent_fraction, 'Fraction Latent') - self._write_to_idf_format(file, thermal_zone.appliances.radiative_fraction, 'Fraction Radiant') - self._write_to_idf_format(file, 0, 'Fraction Lost') - self._write_to_idf_format(file, 0, 'Carbon Dioxide Generation Rate') - self._write_to_idf_format(file, subcategory, 'EndUse Subcategory', ';') - - def _add_infiltration(self, thermal_zone, zone_name): - schedule_name = f'Infiltration schedules {thermal_zone.usage_name}' - infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS - file = self._files['infiltration'] - self._write_to_idf_format(file, idf_cte.INFILTRATION) - self._write_to_idf_format(file, f'{zone_name}_infiltration', 'Name') - self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name') - self._write_to_idf_format(file, schedule_name, 'Schedule Name') - self._write_to_idf_format(file, 'AirChanges/Hour', 'Design Flow Rate Calculation Method') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Flow Rate') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Floor Area') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Exterior Surface Area') - self._write_to_idf_format(file, infiltration, 'Air Changes per Hour') - self._write_to_idf_format(file, 1, 'Constant Term Coefficient') - self._write_to_idf_format(file, 0, 'Temperature Term Coefficient') - self._write_to_idf_format(file, 0, 'Velocity Term Coefficient') - self._write_to_idf_format(file, 0, 'Velocity Squared Term Coefficient', ';') - - 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 - file = self._files['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, zone_name, 'Zone or ZoneList or Space or SpaceList Name') - self._write_to_idf_format(file, schedule_name, 'Schedule Name') - self._write_to_idf_format(file, 'AirChanges/Hour', 'Design Flow Rate Calculation Method') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Flow Rate') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Floor Area') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Person') - self._write_to_idf_format(file, air_change, 'Air Changes per Hour') - self._write_to_idf_format(file, 'Natural', 'Ventilation Type') - self._write_to_idf_format(file, 0, 'Fan Pressure Rise') - self._write_to_idf_format(file, 1, 'Fan Total Efficiency') - self._write_to_idf_format(file, 1, 'Constant Term Coefficient') - self._write_to_idf_format(file, 0, 'Temperature Term Coefficient') - self._write_to_idf_format(file, 0, 'Velocity Term Coefficient') - self._write_to_idf_format(file, 0, 'Velocity Squared Term Coefficient') - self._write_to_idf_format(file, -100, 'Minimum Indoor Temperature') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Minimum Indoor Temperature Schedule Name') - self._write_to_idf_format(file, 100, 'Maximum Indoor Temperature') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Indoor Temperature Schedule Name') - self._write_to_idf_format(file, -100, 'Delta Temperature') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Delta Temperature Schedule Name') - self._write_to_idf_format(file, -100, 'Minimum Outdoor Temperature') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Minimum Outdoor Temperature Schedule Name') - self._write_to_idf_format(file, 100, 'Maximum Outdoor Temperature') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Outdoor Temperature Schedule Name') - self._write_to_idf_format(file, 40, 'Maximum Wind Speed', ';') - - def _add_thermostat(self, thermal_zone): - thermostat_name = f'Thermostat {thermal_zone.usage_name}' - heating_schedule = f'Heating thermostat schedules {thermal_zone.usage_name}' - cooling_schedule = f'Cooling thermostat schedules {thermal_zone.usage_name}' - if thermostat_name not in self._thermostat_added_to_idf: - self._thermostat_added_to_idf[thermostat_name] = True - file = self._files['thermostat'] - self._write_to_idf_format(file, idf_cte.THERMOSTAT) - self._write_to_idf_format(file, thermostat_name, 'Name') - self._write_to_idf_format(file, heating_schedule, 'Heating Setpoint Schedule Name') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Constant Heating Setpoint') - self._write_to_idf_format(file, cooling_schedule, 'Cooling Setpoint Schedule Name', ';') - - def _add_heating_system(self, thermal_zone, zone_name): - availability_schedule = f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}' - thermostat_name = f'Thermostat {thermal_zone.usage_name}' - file = self._files['ideal_load_system'] - self._write_to_idf_format(file, idf_cte.IDEAL_LOAD_SYSTEM) - self._write_to_idf_format(file, zone_name, 'Zone Name') - self._write_to_idf_format(file, thermostat_name, 'Template Thermostat Name') - self._write_to_idf_format(file, availability_schedule, 'System Availability Schedule Name') - self._write_to_idf_format(file, 50, 'Maximum Heating Supply Air Temperature') - self._write_to_idf_format(file, 13, 'Minimum Cooling Supply Air Temperature') - self._write_to_idf_format(file, 0.0156, 'Maximum Heating Supply Air Humidity Ratio') - self._write_to_idf_format(file, 0.0077, 'Minimum Cooling Supply Air Humidity Ratio') - self._write_to_idf_format(file, 'NoLimit', 'Heating Limit') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Heating Air Flow Rate') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Sensible Heating Capacity') - self._write_to_idf_format(file, 'NoLimit', 'Cooling Limit') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Cooling Air Flow Rate') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Total Cooling Capacity') - self._write_to_idf_format(file, availability_schedule, 'Heating Availability Schedule Name') - self._write_to_idf_format(file, availability_schedule, 'Cooling Availability Schedule Name') - self._write_to_idf_format(file, 'ConstantSensibleHeatRatio', 'Dehumidification Control Type') - self._write_to_idf_format(file, 0.7, 'Cooling Sensible Heat Ratio') - self._write_to_idf_format(file, 60, 'Dehumidification Setpoint') - self._write_to_idf_format(file, 'None', 'Humidification Control Type') - self._write_to_idf_format(file, 30, 'Humidification Setpoint') - self._write_to_idf_format(file, 'None', 'Outdoor Air Method') - self._write_to_idf_format(file, 0.00944, 'Outdoor Air Flow Rate per Person') - self._write_to_idf_format(file, 0.0, 'Outdoor Air Flow Rate per Zone Floor Area') - self._write_to_idf_format(file, 0, 'Outdoor Air Flow Rate per Zone') - self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Specification Outdoor Air Object Name') - self._write_to_idf_format(file, 'None', 'Demand Controlled Ventilation Type') - self._write_to_idf_format(file, 'NoEconomizer', 'Outdoor Air Economizer Type') - self._write_to_idf_format(file, 'None', 'Heat Recovery Type') - 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: @@ -338,32 +179,32 @@ class CercIdf(IdfBase): occ.sensible_radiative_internal_gain + occ.latent_internal_gain ) / occ.occupancy_density - self._add_idf_schedules(usage, 'Infiltration', self._create_infiltration_schedules(thermal_zone)) - self._add_idf_schedules(usage, 'Ventilation', self._create_ventilation_schedules(thermal_zone)) - self._add_idf_schedules(usage, 'Occupancy', thermal_zone.occupancy.occupancy_schedules) - self._add_idf_schedules(usage, 'HVAC AVAIL', thermal_zone.thermal_control.hvac_availability_schedules) - self._add_idf_schedules(usage, 'Heating thermostat', - thermal_zone.thermal_control.heating_set_point_schedules) - self._add_idf_schedules(usage, 'Cooling thermostat', - thermal_zone.thermal_control.cooling_set_point_schedules) - self._add_idf_schedules(usage, 'Lighting', thermal_zone.lighting.schedules) - self._add_idf_schedules(usage, 'Appliance', thermal_zone.appliances.schedules) - self._add_idf_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules) - self._add_idf_schedules(usage, 'DHW_temp', self._create_constant_value_schedules(service_temperature, 24)) - self._add_idf_schedules(usage, 'Activity Level', self._create_constant_value_schedules(total_heat, 24)) - self._add_file_schedules(usage, 'cold_temp', - self._create_constant_value_schedules(building.cold_water_temperature[cte.HOUR], - 24)) + self._add_idf_schedule(usage, 'Infiltration', self._create_infiltration_schedules(thermal_zone)) + self._add_idf_schedule(usage, 'Ventilation', self._create_ventilation_schedules(thermal_zone)) + self._add_idf_schedule(usage, 'Occupancy', thermal_zone.occupancy.occupancy_schedules) + self._add_idf_schedule(usage, 'HVAC AVAIL', thermal_zone.thermal_control.hvac_availability_schedules) + self._add_idf_schedule(usage, 'Heating thermostat', + thermal_zone.thermal_control.heating_set_point_schedules) + self._add_idf_schedule(usage, 'Cooling thermostat', + thermal_zone.thermal_control.cooling_set_point_schedules) + self._add_idf_schedule(usage, 'Lighting', thermal_zone.lighting.schedules) + self._add_idf_schedule(usage, 'Appliance', thermal_zone.appliances.schedules) + self._add_idf_schedule(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules) + self._add_idf_schedule(usage, 'DHW_temp', self._create_constant_value_schedules(service_temperature, 24)) + self._add_idf_schedule(usage, 'Activity Level', self._create_constant_value_schedules(total_heat, 24)) + self._add_file_schedule(usage, 'cold_temp', + self._create_constant_value_schedules(building.cold_water_temperature[cte.HOUR], + 24)) for thermal_boundary in thermal_zone.thermal_boundaries: - self._add_materials(thermal_boundary) - self._add_constructions(thermal_boundary) + self._add_material(thermal_boundary) + self._add_construction(thermal_boundary) for thermal_opening in thermal_boundary.thermal_openings: - self._add_window_materials(thermal_opening) + self._add_windows_material(thermal_opening) self._add_windows_constructions() self._add_zone(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_appliance(thermal_zone, building.name) self._add_infiltration(thermal_zone, building.name) self._add_ventilation(thermal_zone, building.name) self._add_thermostat(thermal_zone) diff --git a/hub/exports/building_energy/idf_helper/idf_appliance.py b/hub/exports/building_energy/idf_helper/idf_appliance.py new file mode 100644 index 00000000..2da1485b --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_appliance.py @@ -0,0 +1,25 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte + + +class IdfAppliance(CercIdf): + def add(self, thermal_zone, zone_name): + schedule_name = f'Appliance schedules {thermal_zone.usage_name}' + 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' + file = self._files['appliances'] + self._write_to_idf_format(file, idf_cte.APPLIANCES) + self._write_to_idf_format(file, f'{zone_name}_appliance', 'Name') + self._write_to_idf_format(file, 'Electricity', 'Fuel Type') + self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name') + self._write_to_idf_format(file, schedule_name, 'Schedule Name') + self._write_to_idf_format(file, 'Watts/Area', 'Design Level Calculation Method') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Level') + self._write_to_idf_format(file, watts_per_zone_floor_area, 'Power per Zone Floor Area') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Power per Person') + self._write_to_idf_format(file, thermal_zone.appliances.latent_fraction, 'Fraction Latent') + self._write_to_idf_format(file, thermal_zone.appliances.radiative_fraction, 'Fraction Radiant') + self._write_to_idf_format(file, 0, 'Fraction Lost') + self._write_to_idf_format(file, 0, 'Carbon Dioxide Generation Rate') + self._write_to_idf_format(file, subcategory, 'EndUse Subcategory', ';') \ No newline at end of file diff --git a/hub/exports/building_energy/idf_helper/idf_constructions.py b/hub/exports/building_energy/idf_helper/idf_construction.py similarity index 98% rename from hub/exports/building_energy/idf_helper/idf_constructions.py rename to hub/exports/building_energy/idf_helper/idf_construction.py index f9ebbafd..b6974f45 100644 --- a/hub/exports/building_energy/idf_helper/idf_constructions.py +++ b/hub/exports/building_energy/idf_helper/idf_construction.py @@ -3,7 +3,7 @@ from hub.exports.building_energy.cerc_idf import CercIdf import hub.exports.building_energy.idf_helper as idf_cte -class IdfConstructions(CercIdf): +class IdfConstruction(CercIdf): def _add_solid_material(self, layer): file = self._files['solid_materials'] self._write_to_idf_format(file, idf_cte.SOLID_MATERIAL) diff --git a/hub/exports/building_energy/idf_helper/idf_dhw.py b/hub/exports/building_energy/idf_helper/idf_dhw.py new file mode 100644 index 00000000..e8def02a --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_dhw.py @@ -0,0 +1,21 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte + + +class IdfDhw(CercIdf): + def add(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', ';') diff --git a/hub/exports/building_energy/idf_helper/idf_file_schedules.py b/hub/exports/building_energy/idf_helper/idf_file_schedule.py similarity index 97% rename from hub/exports/building_energy/idf_helper/idf_file_schedules.py rename to hub/exports/building_energy/idf_helper/idf_file_schedule.py index 573f98fc..229c22cf 100644 --- a/hub/exports/building_energy/idf_helper/idf_file_schedules.py +++ b/hub/exports/building_energy/idf_helper/idf_file_schedule.py @@ -4,7 +4,7 @@ import hub.exports.building_energy.idf_helper as idf_cte from hub.exports.building_energy.cerc_idf import CercIdf -class IdfFileSchedules(CercIdf): +class IdfFileSchedule(CercIdf): def add(self, usage, schedule_type, schedules): schedule_name = f'{schedule_type} schedules {usage}' for schedule in schedules: diff --git a/hub/exports/building_energy/idf_helper/idf_heating_system.py b/hub/exports/building_energy/idf_helper/idf_heating_system.py new file mode 100644 index 00000000..c7f34b5c --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_heating_system.py @@ -0,0 +1,40 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte + + +class IdfHeatingSystem(CercIdf): + def add(self, thermal_zone, zone_name): + availability_schedule = f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}' + thermostat_name = f'Thermostat {thermal_zone.usage_name}' + file = self._files['ideal_load_system'] + self._write_to_idf_format(file, idf_cte.IDEAL_LOAD_SYSTEM) + self._write_to_idf_format(file, zone_name, 'Zone Name') + self._write_to_idf_format(file, thermostat_name, 'Template Thermostat Name') + self._write_to_idf_format(file, availability_schedule, 'System Availability Schedule Name') + self._write_to_idf_format(file, 50, 'Maximum Heating Supply Air Temperature') + self._write_to_idf_format(file, 13, 'Minimum Cooling Supply Air Temperature') + self._write_to_idf_format(file, 0.0156, 'Maximum Heating Supply Air Humidity Ratio') + self._write_to_idf_format(file, 0.0077, 'Minimum Cooling Supply Air Humidity Ratio') + self._write_to_idf_format(file, 'NoLimit', 'Heating Limit') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Heating Air Flow Rate') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Sensible Heating Capacity') + self._write_to_idf_format(file, 'NoLimit', 'Cooling Limit') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Cooling Air Flow Rate') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Total Cooling Capacity') + self._write_to_idf_format(file, availability_schedule, 'Heating Availability Schedule Name') + self._write_to_idf_format(file, availability_schedule, 'Cooling Availability Schedule Name') + self._write_to_idf_format(file, 'ConstantSensibleHeatRatio', 'Dehumidification Control Type') + self._write_to_idf_format(file, 0.7, 'Cooling Sensible Heat Ratio') + self._write_to_idf_format(file, 60, 'Dehumidification Setpoint') + self._write_to_idf_format(file, 'None', 'Humidification Control Type') + self._write_to_idf_format(file, 30, 'Humidification Setpoint') + self._write_to_idf_format(file, 'None', 'Outdoor Air Method') + self._write_to_idf_format(file, 0.00944, 'Outdoor Air Flow Rate per Person') + self._write_to_idf_format(file, 0.0, 'Outdoor Air Flow Rate per Zone Floor Area') + self._write_to_idf_format(file, 0, 'Outdoor Air Flow Rate per Zone') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Specification Outdoor Air Object Name') + self._write_to_idf_format(file, 'None', 'Demand Controlled Ventilation Type') + self._write_to_idf_format(file, 'NoEconomizer', 'Outdoor Air Economizer Type') + self._write_to_idf_format(file, 'None', 'Heat Recovery Type') + self._write_to_idf_format(file, 0.70, 'Sensible Heat Recovery Effectiveness') + self._write_to_idf_format(file, 0.65, 'Latent Heat Recovery Effectiveness', ';') \ No newline at end of file diff --git a/hub/exports/building_energy/idf_helper/idf_infiltration.py b/hub/exports/building_energy/idf_helper/idf_infiltration.py new file mode 100644 index 00000000..9e7a97a3 --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_infiltration.py @@ -0,0 +1,23 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte + + +class IdfInfiltration(CercIdf): + + def add(self, thermal_zone, zone_name): + schedule_name = f'Infiltration schedules {thermal_zone.usage_name}' + infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS + file = self._files['infiltration'] + self._write_to_idf_format(file, idf_cte.INFILTRATION) + self._write_to_idf_format(file, f'{zone_name}_infiltration', 'Name') + self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name') + self._write_to_idf_format(file, schedule_name, 'Schedule Name') + self._write_to_idf_format(file, 'AirChanges/Hour', 'Design Flow Rate Calculation Method') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Flow Rate') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Floor Area') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Exterior Surface Area') + self._write_to_idf_format(file, infiltration, 'Air Changes per Hour') + self._write_to_idf_format(file, 1, 'Constant Term Coefficient') + self._write_to_idf_format(file, 0, 'Temperature Term Coefficient') + self._write_to_idf_format(file, 0, 'Velocity Term Coefficient') + self._write_to_idf_format(file, 0, 'Velocity Squared Term Coefficient', ';') \ No newline at end of file diff --git a/hub/exports/building_energy/idf_helper/idf_materials.py b/hub/exports/building_energy/idf_helper/idf_material.py similarity index 98% rename from hub/exports/building_energy/idf_helper/idf_materials.py rename to hub/exports/building_energy/idf_helper/idf_material.py index 17fe3517..1c1c8037 100644 --- a/hub/exports/building_energy/idf_helper/idf_materials.py +++ b/hub/exports/building_energy/idf_helper/idf_material.py @@ -2,7 +2,7 @@ from hub.exports.building_energy.cerc_idf import CercIdf import hub.exports.building_energy.idf_helper as idf_cte -class IdfMaterials(CercIdf): +class IdfMaterial(CercIdf): def _add_solid_material(self, layer): file = self._files['solid_materials'] self._write_to_idf_format(file, idf_cte.SOLID_MATERIAL) diff --git a/hub/exports/building_energy/idf_helper/idf_schedules.py b/hub/exports/building_energy/idf_helper/idf_schedule.py similarity index 97% rename from hub/exports/building_energy/idf_helper/idf_schedules.py rename to hub/exports/building_energy/idf_helper/idf_schedule.py index 4abca7c3..d72a7162 100644 --- a/hub/exports/building_energy/idf_helper/idf_schedules.py +++ b/hub/exports/building_energy/idf_helper/idf_schedule.py @@ -2,7 +2,7 @@ from hub.exports.building_energy.cerc_idf import CercIdf import hub.exports.building_energy.idf_helper as idf_cte -class IdfSchedules(CercIdf): +class IdfSchedule(CercIdf): def add(self, usage, schedule_type, schedules): if len(schedules) < 1: return diff --git a/hub/exports/building_energy/idf_helper/idf_shading.py b/hub/exports/building_energy/idf_helper/idf_shading.py new file mode 100644 index 00000000..0c109ac3 --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_shading.py @@ -0,0 +1,24 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte + + +class IdfShading(CercIdf): + def add(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) diff --git a/hub/exports/building_energy/idf_helper/idf_thermostat.py b/hub/exports/building_energy/idf_helper/idf_thermostat.py new file mode 100644 index 00000000..267bcbc6 --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_thermostat.py @@ -0,0 +1,18 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte + + +class IdfThermostat(CercIdf): + + def add(self, thermal_zone): + thermostat_name = f'Thermostat {thermal_zone.usage_name}' + heating_schedule = f'Heating thermostat schedules {thermal_zone.usage_name}' + cooling_schedule = f'Cooling thermostat schedules {thermal_zone.usage_name}' + if thermostat_name not in self._thermostat_added_to_idf: + self._thermostat_added_to_idf[thermostat_name] = True + file = self._files['thermostat'] + self._write_to_idf_format(file, idf_cte.THERMOSTAT) + self._write_to_idf_format(file, thermostat_name, 'Name') + self._write_to_idf_format(file, heating_schedule, 'Heating Setpoint Schedule Name') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Constant Heating Setpoint') + self._write_to_idf_format(file, cooling_schedule, 'Cooling Setpoint Schedule Name', ';') diff --git a/hub/exports/building_energy/idf_helper/idf_ventilation.py b/hub/exports/building_energy/idf_helper/idf_ventilation.py new file mode 100644 index 00000000..cbc2d285 --- /dev/null +++ b/hub/exports/building_energy/idf_helper/idf_ventilation.py @@ -0,0 +1,37 @@ +from hub.exports.building_energy.cerc_idf import CercIdf +import hub.exports.building_energy.idf_helper as idf_cte +import hub.helpers.constants as cte + + +class IdfVentilation(CercIdf): + def add(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 + file = self._files['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, zone_name, 'Zone or ZoneList or Space or SpaceList Name') + self._write_to_idf_format(file, schedule_name, 'Schedule Name') + self._write_to_idf_format(file, 'AirChanges/Hour', 'Design Flow Rate Calculation Method') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Flow Rate') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Floor Area') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Person') + self._write_to_idf_format(file, air_change, 'Air Changes per Hour') + self._write_to_idf_format(file, 'Natural', 'Ventilation Type') + self._write_to_idf_format(file, 0, 'Fan Pressure Rise') + self._write_to_idf_format(file, 1, 'Fan Total Efficiency') + self._write_to_idf_format(file, 1, 'Constant Term Coefficient') + self._write_to_idf_format(file, 0, 'Temperature Term Coefficient') + self._write_to_idf_format(file, 0, 'Velocity Term Coefficient') + self._write_to_idf_format(file, 0, 'Velocity Squared Term Coefficient') + self._write_to_idf_format(file, -100, 'Minimum Indoor Temperature') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Minimum Indoor Temperature Schedule Name') + self._write_to_idf_format(file, 100, 'Maximum Indoor Temperature') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Indoor Temperature Schedule Name') + self._write_to_idf_format(file, -100, 'Delta Temperature') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Delta Temperature Schedule Name') + self._write_to_idf_format(file, -100, 'Minimum Outdoor Temperature') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Minimum Outdoor Temperature Schedule Name') + self._write_to_idf_format(file, 100, 'Maximum Outdoor Temperature') + self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Outdoor Temperature Schedule Name') + self._write_to_idf_format(file, 40, 'Maximum Wind Speed', ';') diff --git a/hub/exports/building_energy/idf_helper/idf_windows_materials.py b/hub/exports/building_energy/idf_helper/idf_windows_material.py similarity index 91% rename from hub/exports/building_energy/idf_helper/idf_windows_materials.py rename to hub/exports/building_energy/idf_helper/idf_windows_material.py index 3ba01144..6b8cbcac 100644 --- a/hub/exports/building_energy/idf_helper/idf_windows_materials.py +++ b/hub/exports/building_energy/idf_helper/idf_windows_material.py @@ -2,7 +2,7 @@ from hub.exports.building_energy.cerc_idf import CercIdf import hub.exports.building_energy.idf_helper as idf_cte -class IdfWindowsMaterials(CercIdf): +class IdfWindowsMaterial(CercIdf): def add(self, thermal_opening): name = f'{thermal_opening.overall_u_value}_{thermal_opening.g_value}' if name not in self._windows_added_to_idf: diff --git a/hub/exports/building_energy/idf_helper/idf_zones.py b/hub/exports/building_energy/idf_helper/idf_zone.py similarity index 96% rename from hub/exports/building_energy/idf_helper/idf_zones.py rename to hub/exports/building_energy/idf_helper/idf_zone.py index 91e06921..8cb950c4 100644 --- a/hub/exports/building_energy/idf_helper/idf_zones.py +++ b/hub/exports/building_energy/idf_helper/idf_zone.py @@ -2,7 +2,7 @@ from hub.exports.building_energy.cerc_idf import CercIdf import hub.exports.building_energy.idf_helper as idf_cte -class IdfZones(CercIdf): +class IdfZone(CercIdf): def add(self, thermal_zone, zone_name): file = self._files['zones'] self._write_to_idf_format(file, idf_cte.ZONE)