Skip to content

Commit

Permalink
Merge pull request #2448 from architecture-building-systems/2366-heat…
Browse files Browse the repository at this point in the history
…ing-and-cooling-season

Ventilation to avoid unrealistically high temperatures during heating season
  • Loading branch information
jimenofonseca committed Nov 14, 2019
2 parents eca86f8 + 7f1348d commit 049b9a6
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 32 deletions.
3 changes: 3 additions & 0 deletions cea/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
declare the constants closest to the point of usage.
"""
from __future__ import absolute_import

__author__ = "Sreepathi Bhargava Krishna"
__copyright__ = "Copyright 2017, Architecture and Building Systems - ETH Zurich"
__credits__ = ["Sreepathi Bhargava Krishna"]
Expand All @@ -28,6 +29,8 @@
HOURS_IN_DAY = 24
HOURS_IN_YEAR = 8760
MONTHS_IN_YEAR = 12
HOURS_PRE_CONDITIONING = 720 # number of hours that the building will be thermally pre-conditioned,
# the results of these hours will be overwritten

# Specific heat
HEAT_CAPACITY_OF_WATER_JPERKGK = 4185 # [J/kg K]
Expand Down
Binary file modified cea/databases/CH/archetypes/construction_properties.xlsx
Binary file not shown.
2 changes: 1 addition & 1 deletion cea/demand/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
P_FAN = 0.55 # specific fan consumption in W/m3/h
MIN_VENTILATION_RATE = 0.6 # l/s/m2 [https://escholarship.org/content/qt7k1796zv/qt7k1796zv.pdf]
TEMPERATURE_ZONE_CONTROL_NIGHT_FLUSHING = 26 # (°C) night flushing only if temperature is higher than 26 # TODO review and make dynamic
DELTA_T_NIGHT_FLUSHING = 2 # (°C) night flushing only if outdoor temperature is two degrees lower than indoor # TODO review and make dynamic
DELTA_T_NIGHT_FLUSHING = 2 # (°C) night flushing only if outdoor temperature is two degrees lower than indoor according to SIA 382/1
SHIELDING_CLASS = 2 # according to ISO 16798-7, 0 = open terrain, 1 = partly shielded from wind,
# 2 = fully shielded from wind
TER_CLASS = 2 # terrain class of surroundings according to ISO 16798-7: 0 = open, 1 = rural, 2 = urban
Expand Down
20 changes: 9 additions & 11 deletions cea/demand/control_ventilation_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ def is_mechanical_ventilation_heat_recovery_active(bpr, tsd, t):
if is_mechanical_ventilation_active(bpr, tsd, t)\
and has_mechanical_ventilation_heat_recovery(bpr)\
and control_heating_cooling_systems.is_heating_season(t, bpr):

# heat recovery is always active if mechanical ventilation is active (no intelligent by pass)
# this is the usual system configuration according to Clayton Miller
return True
if is_night_flushing_active(bpr, tsd, t) or is_economizer_active(bpr, tsd, t):
return False
else:
return True

elif is_mechanical_ventilation_active(bpr, tsd, t)\
and has_mechanical_ventilation_heat_recovery(bpr)\
Expand All @@ -87,7 +87,7 @@ def is_mechanical_ventilation_heat_recovery_active(bpr, tsd, t):
and tsd['T_int'][t-1] >= tsd['T_ext'][t]:

# heat recovery is deactivated in the cooling case,
# if outdoor air conditions are colder than indoor (free cooling)
# if outdoor air conditions are colder than indoor (free cooling)

return False

Expand All @@ -98,10 +98,9 @@ def is_mechanical_ventilation_heat_recovery_active(bpr, tsd, t):
def is_night_flushing_active(bpr, tsd, t):

# night flushing is available for window ventilation (manual) and mechanical ventilation (automatic)
# night flushing is active during the night in the cooling season, if the outdoor conditions are favourable
# night flushing is active during the night if the outdoor conditions are favourable

if has_night_flushing(bpr) \
and control_heating_cooling_systems.is_cooling_season(t, bpr) \
and is_night_time(t) \
and tsd['T_int'][t-1] > TEMPERATURE_ZONE_CONTROL_NIGHT_FLUSHING \
and tsd['T_int'][t-1] > tsd['T_ext'][t] + DELTA_T_NIGHT_FLUSHING \
Expand All @@ -118,8 +117,8 @@ def is_economizer_active(bpr, tsd, t):
Control of activity of economizer of mechanical ventilation system
Economizer of mechanical ventilation is controlled via zone set point temperatures, indoor air temperature and
outdoor air temperature.
Economizer is active during cooling season if the indoor air temperature exceeds the set point and the outdoor
temperatures are lower than the set point.
Economizer is active if the indoor air temperature exceeds the set point and the outdoor temperatures are lower
than the set point.
Economizer increases mechanical ventilation flow rate to the maximum.
Author: Gabriel Happle
Expand All @@ -136,8 +135,7 @@ def is_economizer_active(bpr, tsd, t):
"""

if has_mechanical_ventilation_economizer(bpr) \
and control_heating_cooling_systems.is_cooling_season(t, bpr) \
and tsd['T_int'][t-1] > tsd['ta_cs_set'][t] >= tsd['T_ext'][t]:
and tsd['T_int'][t-1] > bpr.comfort['Tcs_set_C'] >= tsd['T_ext'][t]:

return True

Expand Down
3 changes: 1 addition & 2 deletions cea/demand/demand_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ def calc_buildings_less_100m2(building_properties):

list_buildings_less_100m2 = calc_buildings_less_100m2(building_properties)
if list_buildings_less_100m2 != []:
print(
'Warning! The following list of buildings have less than 100 m2 of gross floor area, CEA might fail: %s' % list_buildings_less_100m2)
print('Warning! The following list of buildings have less than 100 m2 of gross floor area, CEA might fail: %s' % list_buildings_less_100m2)

# SPECIFY NUMBER OF BUILDINGS TO SIMULATE
if not building_names:
Expand Down
2 changes: 1 addition & 1 deletion cea/demand/hourly_procedure_heating_cooling_system_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def calc_heating_cooling_loads(bpr, tsd, t):

else:
# message and no heating system
warnings.warn('Unknown cooling system. Calculation without system.')
warnings.warn('Unknown heating system. Calculation without system.')

# no system = no loads
rc_model_temperatures = calc_rc_no_loads(bpr, tsd, t)
Expand Down
2 changes: 1 addition & 1 deletion cea/demand/schedule_maker/schedule_maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def schedule_maker_main(locator, config, building=None):

if buildings == []:
buildings = locator.get_zone_building_names()
if building !=None:
if building != None:
buildings = [building] #this is to run the tests

# get variables of indoor comfort and internal loads
Expand Down
24 changes: 10 additions & 14 deletions cea/demand/thermal_loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from __future__ import division

import numpy as np
from cea.constants import HOURS_IN_YEAR
from cea.constants import HOURS_IN_YEAR, HOURS_PRE_CONDITIONING
import pandas as pd
from cea.demand.latent_loads import convert_rh_to_moisture_content
from cea.demand import demand_writers
Expand Down Expand Up @@ -86,14 +86,14 @@ def calc_thermal_loads(building_name, bpr, weather_data, date_range, locator,

if np.isclose(bpr.rc_model['Af'], 0.0): # if building does not have conditioned area
tsd['T_int'] = tsd['T_ext']
tsd['x_int'] = np.vectorize(convert_rh_to_moisture_content)(tsd['rh_ext'] , tsd['T_int'])
print("building () does not have an air-conditioned area").format(bpr.name)
tsd['x_int'] = np.vectorize(convert_rh_to_moisture_content)(tsd['rh_ext'], tsd['T_int'])
print("building () does not have an air-conditioned area".format(bpr.name))
else:

#CALCULATE PROCESS HEATING
# CALCULATE PROCESS HEATING
tsd['Qhpro_sys'] = schedules['Qhpro_W'] # in Wh

#CALCULATE PROCESS COOLING
# CALCULATE PROCESS COOLING
tsd['Qcpro_sys'] = schedules['Qcpro_W'] # in Wh

# CALCULATE DATA CENTER LOADS
Expand Down Expand Up @@ -150,18 +150,18 @@ def calc_thermal_loads(building_name, bpr, weather_data, date_range, locator,
tsd = electrical_loads.calc_E_sys(tsd) # system (incl. losses)
tsd = electrical_loads.calc_Ef(bpr, tsd) # final (incl. self. generated)

#WRITE SOLAR RESULTS
# WRITE SOLAR RESULTS
write_results(bpr, building_name, date_range, loads_output, locator, massflows_output,
resolution_outputs, temperatures_output, tsd, debug)

return


def calc_QH_sys_QC_sys(tsd):
tsd['QH_sys'] = tsd['Qww_sys'] + tsd['Qhs_sys'] + tsd['Qhpro_sys']
tsd['QC_sys'] = tsd['Qcs_sys'] + tsd['Qcdata_sys'] + tsd['Qcre_sys'] + tsd['Qcpro_sys']
tsd['QH_sys'] = tsd['Qww_sys'] + tsd['Qhs_sys'] + tsd['Qhpro_sys']
tsd['QC_sys'] = tsd['Qcs_sys'] + tsd['Qcdata_sys'] + tsd['Qcre_sys'] + tsd['Qcpro_sys']

return tsd
return tsd


def write_results(bpr, building_name, date, loads_output, locator, massflows_output,
Expand Down Expand Up @@ -397,7 +397,7 @@ def initialize_inputs(bpr, weather_data, locator):
occupancy_yearly_schedules = pd.read_csv(locator.get_schedule_model_file(building_name))

tsd['people'] = occupancy_yearly_schedules['people_pax']
tsd['ve'] = occupancy_yearly_schedules['Ve_lps'] * 3.6 #m3/h
tsd['ve'] = occupancy_yearly_schedules['Ve_lps'] * 3.6 # m3/h
tsd['Qs'] = occupancy_yearly_schedules['Qs_W']

return occupancy_yearly_schedules, tsd
Expand Down Expand Up @@ -587,10 +587,6 @@ def update_timestep_data_no_conditioned_area(tsd):
return tsd


HOURS_IN_YEAR = HOURS_IN_YEAR
HOURS_PRE_CONDITIONING = 720 # number of hours that the building will be thermally pre-conditioned, the results of these hours will be overwritten


def get_hours(bpr):
"""
Expand Down
2 changes: 1 addition & 1 deletion cea/tests/create_unittest_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def main(output_file):
print("data for test_calc_thermal_loads:")
print(building_properties.list_building_names())

schedule_maker_main(locator, config, building='B01')
schedule_maker_main(locator, config, building=None)

bpr = building_properties['B01']
result = calc_thermal_loads('B01', bpr, weather_data, date_range, locator,
Expand Down
2 changes: 1 addition & 1 deletion cea/tests/test_calc_thermal_loads.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ value_columns = ["E_sys_kWh", "Qcdata_sys_kWh", "Qcre_sys_kWh", "Qcs_sys_kWh", "
values = [397332.706, 0.0, 0.0, 54493.56, 96284.527, 19784.978, 0.0, 0.0, 26186.16, 0.0, 0.0, 171600.0]

[test_calc_thermal_loads_other_buildings]
results = {"B01": [96284.527, 54493.56, 19784.978], "B03": [60941.42700000001, 101654.203, 117381.388], "B02": [299345.566, 25872.039, 312647.82999999996], "B05": [127871.16, 0.0, 73559.536], "B04": [153030.22400000002, 36521.226, 17519.388000000003], "B07": [158362.75199999998, 49693.31, 31347.407], "B06": [66017.055, 79389.545, 168321.332], "B09": [136263.101, 18328.773999999998, 15160.633999999998], "B08": [164834.07100000003, 29106.078999999998, 400109.881]}
results = {"B01": [96284.527, 54493.56, 19784.978], "B03": [61270.984, 103288.264, 117428.537], "B02": [299345.566, 25872.039, 312647.82999999996], "B05": [127871.16, 0.0, 73559.536], "B04": [153030.22400000002, 36404.417, 17519.653000000002], "B07": [158375.001, 46013.644, 31350.313], "B06": [66140.078, 80270.72899999999, 168329.153], "B09": [136263.101, 18254.959000000003, 15161.161], "B08": [164841.764, 27644.819, 400112.534]}

0 comments on commit 049b9a6

Please sign in to comment.