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:
parent
d40e013e74
commit
b560287a54
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user