The internal heat gain data for every building is now exported into a text file named Input_internal_heat_gain_CityLayer.txt to be read from CityBEM.

This commit is contained in:
saeed-rayegan 2024-07-08 14:19:14 -04:00
parent d40e013e74
commit b560287a54

View File

@ -36,6 +36,8 @@ def CityBEM_workflow(city):
export_building_info(city, CityBEM_path,geojson_data)
export_weather_data(city, CityBEM_path)
export_comprehensive_building_data(city, CityBEM_path)
export_indoor_temperature_setpoint_data(city, CityBEM_path)
export_internal_heat_gain_data(city, CityBEM_path)
run_CityBEM(CityBEM_path)
def export_geometry(city, CityBEM_path):
"""
@ -65,7 +67,6 @@ def get_building_info(geojson_data, building_id):
center = polygon.centroid
return function_code, (center.x, center.y)
return None, None
def export_building_info(city, CityBEM_path, geojson_file):
"""
@ -121,13 +122,13 @@ def export_weather_data(city, CityBEM_path):
def export_comprehensive_building_data(city, CityBEM_path):
"""
Export all other information from buildings (both physical and thermal properties)
Extract and export detailed individual building data from the hub to replace CityBEM input archetypes, including both physical and thermal properties.
:param city: City object containing necessary attributes for the workflow.
:param CityBEM_path: Path where CityBEM input and output files are stored.
"""
with open(CityBEM_path / 'comprehensive_building_data.csv', 'w', newline='') as textfile:
with open(CityBEM_path / 'Input_comprehensive_building_data_CityLayer.txt', 'w') as textfile:
writer = csv.writer(textfile, delimiter=',')
header_row=[
header_row="\t".join([
#building general information
"buildingName",
"constructionYear",
@ -144,18 +145,30 @@ def export_comprehensive_building_data(city, CityBEM_path):
"roofExternalH",
"roofInternalH",
"roofUvalue",
"roofLongWaveEmittance",
"roofShortWaveReflectance",
"roofDensity",
"roofSpecificHeat",
"roofWWR",
#floor details
"floorThickness",
"floorExternalH",
"floorInternalH",
"floorUvalue",
"floorLongWaveEmittance",
"floorShortWaveReflectance",
"floorDensity",
"floorSpecificHeat",
"floorWWR",
#wall details
"wallThickness",
"wallExternalH",
"wallInternalH",
"wallUValue",
"wallLongWaveEmittance",
"wallShortWaveReflectance",
"wallDensity",
"wallSpecificHeat",
"wallWWRNorth",
"wallWWREast",
"wallWWRSouth",
@ -168,9 +181,8 @@ def export_comprehensive_building_data(city, CityBEM_path):
"thermalBridgesExtraLoses",
"infiltrationRateOff",
"infiltrationRateOn"
]
writer.writerow(header_row) #write the header row
])
textfile.write(header_row + "\n") #write the header row
#extract and write comprehensive building data from the CityLayer's hub
for building in city.buildings:
#data should be appended based on the order of the headers.
@ -206,28 +218,72 @@ def export_comprehensive_building_data(city, CityBEM_path):
for boundary in internal_zone.thermal_zones_from_internal_zones:
for thermal_boundary in boundary.thermal_boundaries:
if thermal_boundary.type == "Roof":
layers = thermal_boundary.layers #access the roof construction layers
non_zero_layers = [layer for layer in layers if layer.thickness > 0] #filter out layers with zero thickness
total_thickness = thermal_boundary.thickness
if total_thickness > 0:
weighted_density = sum(layer.thickness * layer.density for layer in non_zero_layers) / total_thickness #weighted average represneting the entire layer.
weighted_specific_heat = sum(
layer.thickness * layer.specific_heat for layer in non_zero_layers) / total_thickness
else:
weighted_specific_heat = 0 #handle the case where total_thickness is zero to avoid division by zero
weighted_density = 0
row_roof = [
thermal_boundary.thickness,
thermal_boundary.he,
thermal_boundary.hi,
thermal_boundary.u_value,
thermal_boundary.external_surface.long_wave_emittance,
thermal_boundary.external_surface.short_wave_reflectance,
weighted_density,
weighted_specific_heat,
thermal_boundary.window_ratio
]
elif thermal_boundary.type == "Ground":
elif thermal_boundary.type == "Ground": #ground means floor in CityBEM based on the legacy in CityBEM.
layers = thermal_boundary.layers # access the roof construction layers
non_zero_layers = [layer for layer in layers if layer.thickness > 0] # filter out layers with zero thickness
total_thickness = thermal_boundary.thickness
if total_thickness > 0:
weighted_density = sum(
layer.thickness * layer.density for layer in non_zero_layers) / total_thickness
weighted_specific_heat = sum(
layer.thickness * layer.specific_heat for layer in non_zero_layers) / total_thickness
else:
weighted_specific_heat = 0 # Handle the case where total_thickness is zero to avoid division by zero
weighted_density = 0
row_ground = [
thermal_boundary.thickness,
thermal_boundary.he,
thermal_boundary.hi,
thermal_boundary.u_value,
thermal_boundary.external_surface.long_wave_emittance,
thermal_boundary.external_surface.short_wave_reflectance,
weighted_density,
weighted_specific_heat,
thermal_boundary.window_ratio
]
elif thermal_boundary.type == "Wall" and wallCount == 0:
wallCount += 1
wallCount += 1 #wall counter. So far, it is assumed that all the walls have a similar properties to be exported to CityBEM, except the WWR
layers = thermal_boundary.layers # access the roof construction layers
non_zero_layers = [layer for layer in layers if
layer.thickness > 0] # filter out layers with zero thickness
total_thickness = thermal_boundary.thickness
if total_thickness > 0:
weighted_density = sum(layer.thickness * layer.density for layer in non_zero_layers) / total_thickness
weighted_specific_heat = sum(
layer.thickness * layer.specific_heat for layer in non_zero_layers) / total_thickness
else:
weighted_specific_heat = 0 # Handle the case where total_thickness is zero to avoid division by zero
weighted_density = 0
row_wall = [
thermal_boundary.thickness,
thermal_boundary.he,
thermal_boundary.hi,
thermal_boundary.u_value,
thermal_boundary.external_surface.long_wave_emittance,
thermal_boundary.external_surface.short_wave_reflectance,
weighted_density,
weighted_specific_heat,
northWWR,
eastWWR,
southWWR,
@ -244,21 +300,88 @@ def export_comprehensive_building_data(city, CityBEM_path):
row.append(thermalBridgesExtraLoses)
row.append(infiltrationRateOff)
row.append(infiltrationRateOn)
writer.writerow(row)
#convert each item in row to string (if needed) and join with tabs (tab separated data)
row_str = "\t".join(map(str, row))
#write the final row to the text file
textfile.write(row_str + "\n")
print("Individual building data is exported into a file named comprehensive_building_data.txt")
def export_indoor_temperature_setpoint_data(city, CityBEM_path):
"""
Extract and export individual building data on indoor temperature setpoints
:param city: City object containing necessary attributes for the workflow.
:param CityBEM_path: Path where CityBEM input and output files are stored.
"""
#open a text file in write mode (write mode removes the content if there is any)
with open(CityBEM_path /'Input_indoor_setpoint_temperature_CityLayer.txt', 'w') as textfile:
#iterate through each building
for building in city.buildings:
#write the building name
textfile.write("building"+building.name + '\t')
#iterate through each internal zone in the building
for internal_zone in building.internal_zones:
#iterate through each boundary in the internal zone
for boundary in internal_zone.thermal_zones_from_internal_zones:
#gather all indoor setpoint values for both cooling and heating
indoorSetpointValues = []
indoorSetpointValues.extend(boundary.thermal_control.cooling_set_point_schedules[0].values)#cooling on working days
indoorSetpointValues.extend(boundary.thermal_control.cooling_set_point_schedules[1].values)#cooling on Saturday
indoorSetpointValues.extend(boundary.thermal_control.cooling_set_point_schedules[2].values)#cooling on Sunday/holidays
indoorSetpointValues.extend(boundary.thermal_control.heating_set_point_schedules[0].values)#heating on working days
indoorSetpointValues.extend(boundary.thermal_control.heating_set_point_schedules[1].values)#heating on Saturday
indoorSetpointValues.extend(boundary.thermal_control.heating_set_point_schedules[2].values)#heating on Sunday/holidays
#convert values to a tab-separated strings
values_str = '\t'.join(map(str, indoorSetpointValues))
#write the values to the text file for this building
textfile.write(values_str + '\n')
print("Indoor temperature setpoints for every building is successfully exported into a text file named Input_indoor_setpoint_temperature_CityLayer.txt")
def export_internal_heat_gain_data(city, CityBEM_path):
"""
Extract and export individual building data on internal heat gains (occupant, lighting, and equipment)
:param city: City object containing necessary attributes for the workflow.
:param CityBEM_path: Path where CityBEM input and output files are stored.
"""
# open a text file in write mode (write mode removes the content if there is any)
with open(CityBEM_path / 'Input_internal_heat_gain_CityLayer.txt', 'w') as textfile:
# iterate through each building
for building in city.buildings:
# write the building name
textfile.write("building" + building.name + '\t') # (1) building name
# gather all internal heat gains for every building
internalHeatGains = []
# iterate through each internal zone in the building
for internal_zone in building.internal_zones:
# iterate through each internal usage in the internal zone
for usage in internal_zone.usages:
# iterate through internal heat gains
for internalGain in usage.internal_gains: # order: Occupancy, Lighting, and Appliances
internalHeatGains.append(internalGain.average_internal_gain) # (2) average_internal_gain
internalHeatGains.append(internalGain.convective_fraction) # (3) convective_fraction
internalHeatGains.append(internalGain.latent_fraction) # (4) latent_fraction
internalHeatGains.append(internalGain.radiative_fraction) # (5) radiative_fraction
internalHeatGains.extend(internalGain.schedules[0].values) # (6-29) Working day
internalHeatGains.extend(internalGain.schedules[1].values) # (30-54) Saturday
internalHeatGains.extend(internalGain.schedules[2].values) # (55-79)Sunday
# convert values to a tab-separated strings
values_str = '\t'.join(map(str, internalHeatGains))
# write the values to the text file for this building
textfile.write(values_str + '\n')
print("Internal heat gains for every building is successfully exported into a text file named Input_internal_heat_gain_CityLayer.txt")
def run_CityBEM(CityBEM_path):
"""
Run the CityBEM executable after all inputs are processed.
:param CityBEM_path: Path where CityBEM input and output files are stored.
Run the CityBEM executable after all inputs are processed.
:param CityBEM_path: Path where CityBEM input and output files are stored.
"""
try:
print('CityBEM execution began:')
CityBEM_exe = CityBEM_path / 'CityBEM.exe' #path to the CityBEM executable
#check if the executable file exists
CityBEM_exe = CityBEM_path / 'CityBEM.exe' # path to the CityBEM executable
# check if the executable file exists
if not CityBEM_exe.exists():
print(f"Error: {CityBEM_exe} does not exist.")
subprocess.run(str(CityBEM_exe), check=True, cwd=str(CityBEM_path)) #execute the CityBEM executable
subprocess.run(str(CityBEM_exe), check=True, cwd=str(CityBEM_path)) # execute the CityBEM executable
print("CityBEM executable has finished successfully.")
except Exception as ex:
print(ex)