first version of peak loads
This commit is contained in:
parent
af0f965575
commit
cd5f56d48e
@ -1,4 +1,5 @@
|
||||
# peak_demands
|
||||
|
||||
This project includes model to calculate the fillowing yearly peak demands of a building:
|
||||
This project includes model to calculate the following yearly peak demands of a building:
|
||||
- heating
|
||||
- cooling
|
||||
|
116
loads_calculation.py
Normal file
116
loads_calculation.py
Normal file
@ -0,0 +1,116 @@
|
||||
"""
|
||||
Calculation of loads for peak heating and cooling
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
|
||||
import helpers.constants as cte
|
||||
|
||||
AIR_DENSITY = 1.293 # kg/m3
|
||||
AIR_HEAT_CAPACITY = 1005.2 # J/kgK
|
||||
|
||||
|
||||
class LoadsCalculation:
|
||||
"""
|
||||
LoadsCalculation class
|
||||
"""
|
||||
def __init__(self, building):
|
||||
self._building = building
|
||||
|
||||
@staticmethod
|
||||
def _get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature, ground_temperature):
|
||||
load_transmitted_opaque = 0
|
||||
load_transmitted_transparent = 0
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
if thermal_boundary.type == cte.GROUND:
|
||||
external_temperature = ground_temperature
|
||||
elif thermal_boundary.type == cte.INTERIOR_WALL:
|
||||
external_temperature = internal_temperature
|
||||
else:
|
||||
external_temperature = ambient_temperature
|
||||
|
||||
load_transmitted_opaque += thermal_boundary.u_value * thermal_boundary.opaque_area \
|
||||
* (internal_temperature - external_temperature)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
load_transmitted_transparent += thermal_opening.overall_u_value \
|
||||
* (internal_temperature - external_temperature)
|
||||
load_transmitted_opaque += thermal_zone.additional_thermal_bridge_u_value * thermal_zone.footprint_area \
|
||||
* (internal_temperature - ambient_temperature)
|
||||
|
||||
load_transmitted = load_transmitted_opaque + load_transmitted_transparent
|
||||
return load_transmitted
|
||||
|
||||
@staticmethod
|
||||
def _get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature):
|
||||
load_renovation_sensible = 0
|
||||
for usage in thermal_zone.usage_zones:
|
||||
load_renovation_sensible += AIR_DENSITY * AIR_HEAT_CAPACITY * usage.mechanical_air_change \
|
||||
* thermal_zone.volume * cte.HOUR_TO_MINUTES * cte.MINUTES_TO_SECONDS \
|
||||
* (internal_temperature - ambient_temperature)
|
||||
|
||||
load_infiltration_sensible = AIR_DENSITY * AIR_HEAT_CAPACITY * thermal_zone.infiltration_rate_system_off \
|
||||
* thermal_zone.volume * cte.HOUR_TO_MINUTES * cte.MINUTES_TO_SECONDS \
|
||||
* (internal_temperature - ambient_temperature)
|
||||
|
||||
load_ventilation = load_renovation_sensible + load_infiltration_sensible
|
||||
|
||||
return load_ventilation
|
||||
|
||||
def get_heating_transmitted_load(self, ambient_temperature, ground_temperature):
|
||||
heating_load_transmitted = 0
|
||||
for thermal_zone in self._building.thermal_zones:
|
||||
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
|
||||
heating_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
|
||||
ground_temperature)
|
||||
return heating_load_transmitted
|
||||
|
||||
def get_cooling_transmitted_load(self, ambient_temperature, ground_temperature):
|
||||
cooling_load_transmitted = 0
|
||||
for thermal_zone in self._building.thermal_zones:
|
||||
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
|
||||
cooling_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
|
||||
ground_temperature)
|
||||
return cooling_load_transmitted
|
||||
|
||||
def get_heating_ventilation_load_sensible(self, ambient_temperature):
|
||||
heating_ventilation_load = 0
|
||||
for thermal_zone in self._building.thermal_zones:
|
||||
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
|
||||
heating_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
|
||||
return heating_ventilation_load
|
||||
|
||||
def get_cooling_ventilation_load_sensible(self, ambient_temperature):
|
||||
cooling_ventilation_load = 0
|
||||
for thermal_zone in self._building.thermal_zones:
|
||||
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
|
||||
cooling_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
|
||||
return cooling_ventilation_load
|
||||
|
||||
def get_internal_load_sensible(self):
|
||||
cooling_load_occupancy_sensible = 0
|
||||
cooling_load_lighting = 0
|
||||
cooling_load_equipment_sensible = 0
|
||||
for thermal_zone in self._building.thermal_zones:
|
||||
cooling_load_occupancy_sensible += (thermal_zone.occupancy.sensible_convective_internal_gain
|
||||
+ thermal_zone.occupancy.sensible_radiative_internal_gain) \
|
||||
* thermal_zone.footprint_area
|
||||
cooling_load_lighting += (thermal_zone.lighting.density * thermal_zone.lighting.convective_fraction
|
||||
+ thermal_zone.lighting.density * thermal_zone.lighting.radiative_fraction) \
|
||||
* thermal_zone.footprint_area
|
||||
cooling_load_equipment_sensible += (thermal_zone.appliances.density * thermal_zone.appliances.convective_fraction
|
||||
+ thermal_zone.appliances.density * thermal_zone.appliances.radiative_fraction) \
|
||||
* thermal_zone.footprint_area
|
||||
internal_load = cooling_load_occupancy_sensible + cooling_load_lighting + cooling_load_equipment_sensible
|
||||
return internal_load
|
||||
|
||||
def get_radiation_load(self, hour):
|
||||
cooling_load_radiation = 0
|
||||
for thermal_zone in self._building.thermal_zones:
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
radiation = thermal_boundary.parent_surface.radiation[hour]
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
cooling_load_radiation += thermal_opening.area * (1 - thermal_opening.frame_ratio) * thermal_opening.g_value \
|
||||
* radiation
|
||||
return cooling_load_radiation
|
87
main.py
Normal file
87
main.py
Normal file
@ -0,0 +1,87 @@
|
||||
"""
|
||||
Peak loads calculation workflow
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import helpers.constants as cte
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from loads_calculation import LoadsCalculation
|
||||
|
||||
try:
|
||||
gml = ''
|
||||
for argument_tuple in sys.argv[1:]:
|
||||
print(argument_tuple)
|
||||
argument = argument_tuple.split(' ')
|
||||
option = argument[0]
|
||||
value = argument[1]
|
||||
if option == '-g':
|
||||
gml = value
|
||||
out_path = (Path(__file__).parent.parent / 'out_files')
|
||||
files = glob.glob(f'{out_path}/*')
|
||||
for file in files:
|
||||
if file != '.gitignore':
|
||||
os.remove(file)
|
||||
|
||||
print('[simulation start]')
|
||||
city = GeometryFactory('citygml', gml).city
|
||||
print(f'city created from {gml}')
|
||||
for building in city.buildings:
|
||||
building.year_of_construction = 2006
|
||||
if building.function is None:
|
||||
building.function = 'large office'
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
print('enrich constructions... done')
|
||||
UsageFactory('comnet', city).enrich()
|
||||
print('enrich usage... done')
|
||||
|
||||
print('calculating:')
|
||||
|
||||
weather_format = 'epw'
|
||||
|
||||
for building in city.buildings:
|
||||
ambient_temperature = building.external_temperature[cte.HOUR][[weather_format]]
|
||||
ground_temperature = 0
|
||||
heating_ambient_temperature = 100
|
||||
cooling_ambient_temperature = -100
|
||||
heating_calculation_hour = -1
|
||||
cooling_calculation_hour = -1
|
||||
for hour, temperature in enumerate(ambient_temperature):
|
||||
ground_temperature += temperature / 8760
|
||||
if temperature < heating_ambient_temperature:
|
||||
heating_ambient_temperature = temperature
|
||||
heating_calculation_hour = hour
|
||||
if temperature > cooling_ambient_temperature:
|
||||
cooling_ambient_temperature = temperature
|
||||
cooling_calculation_hour = hour
|
||||
|
||||
loads = LoadsCalculation(building)
|
||||
heating_load_transmitted = loads.get_heating_transmitted_load(heating_ambient_temperature, ground_temperature)
|
||||
heating_load_ventilation_sensible = loads.get_heating_ventilation_load_sensible(heating_ambient_temperature)
|
||||
heating_load_ventilation_latent = 0
|
||||
heating_load = heating_load_transmitted + heating_load_ventilation_sensible + heating_load_ventilation_latent
|
||||
|
||||
cooling_load_transmitted = loads.get_cooling_transmitted_load(cooling_ambient_temperature, ground_temperature)
|
||||
cooling_load_renovation_sensible = loads.get_cooling_ventilation_load_sensible(cooling_ambient_temperature)
|
||||
cooling_load_internal_gains_sensible = loads.get_internal_load_sensible()
|
||||
cooling_load_radiation = loads.get_radiation_load(cooling_calculation_hour)
|
||||
cooling_load_sensible = cooling_load_transmitted + cooling_load_renovation_sensible + cooling_load_radiation \
|
||||
+ cooling_load_internal_gains_sensible
|
||||
cooling_load_latent = 0
|
||||
cooling_load = cooling_load_sensible + cooling_load_latent
|
||||
|
||||
print('[calculation end]')
|
||||
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print('error: ', ex)
|
||||
print('[simulation abort]')
|
||||
sys.stdout.flush()
|
Loading…
Reference in New Issue
Block a user