modifications in classes for energyADE

This commit is contained in:
Pilar 2021-03-16 12:19:35 -04:00
parent b8e5d74e39
commit 4e4875392f
11 changed files with 322 additions and 300 deletions

View File

@ -1,149 +0,0 @@
"""
Building module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Sanam Dabirian sanam.dabirian@mail.concordia.ca
Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
"""
import calendar as cal
class Occupancy:
"""
Occupancy class
"""
def __init__(self):
"""
Constructor
"""
self._internal_heat_gain = None
self._heat_dissipation = None
self._occupant_rate = None
self._occupant_type = None
self._occupant_zone = None
self._occupant_schedule = None
self._number_of_occupants = None
self._arrival_time = None
self._departure_time = None
self._break_time = None
self._day_of_week = None
self._pd_of_meetings_duration = None
self._complete_year_schedule = None
@property
def internal_heat_gain(self):
"""
Get internal heat gain of occupants
:return: occupant heat gain
"""
return self._internal_heat_gain
@property
def heat_dissipation(self):
"""
Get heat dissipation of occupants
:return: heat dissipation
"""
return self._heat_dissipation
@property
def occupant_rate(self):
"""
Get rate of occupancy
:return: rate of occupancy
"""
return self._occupant_rate
@property
def occupant_type(self):
"""
Get type of occupancy
:return: type of occupancy
"""
return self._occupant_type
@property
def occupant_zone(self):
"""
Get the zone that occupant is in it
:return: occupant zone
"""
return self._occupant_zone
@property
def occupant_schedule(self):
"""
Get the schedule when an occupant is in a zone
:return: occupant schedule
"""
return self._occupant_schedule
@property
def number_of_occupants(self):
"""
Get the number of occupants
:return: number of occupants
"""
return self._number_of_occupants
@property
def arrival_time(self):
"""
Get the arrival time of the occupant (for office building)
:return: arrival time
"""
return self._arrival_time
@property
def departure_time(self):
"""
Get the departure time of the occupant (for office building)
:return: departure time
"""
return self._departure_time
@property
def break_time(self):
"""
Get the lunch or break time of the occupant (for office building)
:return: break time
"""
return self._break_time
@property
def day_of_week(self):
"""
Get the day of the week
:return: day of the week
"""
return self._day_of_week
@property
def pd_of_meetings_duration(self):
"""
Get the probability distribution of the meeting duration
:return: probability distribution of the meeting duration
"""
return self._pd_of_meetings_duration
def get_complete_year_schedule(self, schedules):
if self._complete_year_schedule is None:
self._complete_year_schedule = []
for i in range(1, 13):
month_range = cal.monthrange(2015, i)
for day in range(1, month_range[1]+1):
if cal.weekday(2015, i, day) < 5:
for j in range(0, 24):
week_schedule = schedules['WD'][j]
self._complete_year_schedule.append(week_schedule)
elif cal.weekday(2015, i, day) == 5:
for j in range(0, 24):
week_schedule = schedules['Sat'][j]
self._complete_year_schedule.append(week_schedule)
else:
for j in range(0, 24):
week_schedule = schedules['Sun'][j]
self._complete_year_schedule.append(week_schedule)
return self._complete_year_schedule

View File

@ -0,0 +1,240 @@
"""
Occupants module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Sanam Dabirian sanam.dabirian@mail.concordia.ca
Contributors Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import calendar as cal
from city_model_structure.attributes.usage_zone import UsageZone
class Occupants:
"""
Occupants class
"""
def __init__(self):
"""
Constructor
"""
self._internal_heat_gain = None
self._heat_dissipation = None
self._occupancy_rate = None
self._occupant_type = None
self._occupant_zone = None
self._occupant_schedule = None
self._number_of_occupants = None
self._arrival_time = None
self._departure_time = None
self._break_time = None
self._day_of_week = None
self._pd_of_meetings_duration = None
self._complete_year_schedule = None
@property
def internal_heat_gain(self):
"""
Get internal heat gain of occupants in W/person
:return: float
"""
return self._internal_heat_gain
@internal_heat_gain.setter
def internal_heat_gain(self, value):
"""
Set internal heat gain of occupants in W/person
:param value: float
:return:
"""
self._internal_heat_gain = value
@property
def heat_dissipation(self):
"""
Get heat dissipation of occupants in W/person
:return: float
"""
return self._heat_dissipation
@heat_dissipation.setter
def heat_dissipation(self, value):
"""
Set heat dissipation of occupants in W/person
:param value: float
:return:
"""
self._heat_dissipation = value
@property
def occupancy_rate(self):
"""
Get rate of occupancy
:return: float
"""
return self._occupancy_rate
@occupancy_rate.setter
def occupancy_rate(self, value):
"""
Set rate of occupancy
:param value: float
:return:
"""
self._occupancy_rate = value
@property
def occupant_type(self):
"""
Get type of occupancy
:return: string
"""
return self._occupant_type
@occupant_type.setter
def occupant_type(self, value):
"""
Set type of occupancy
:param value: float
:return:
"""
self._occupant_type = value
@property
def occupant_zone(self) -> UsageZone:
"""
Get the zone an occupant is in
:return: UsageZone
"""
return self._occupant_zone
@property
def occupant_schedule(self):
"""
Get the schedule when an occupant is in a zone (24 values, 1 per hour of the day)
:return: [float]
"""
return self._occupant_schedule
@occupant_schedule.setter
def occupant_schedule(self, value):
"""
Set the schedule when an occupant is in a zone (24 values, 1 per hour of the day)
:param value: [float]
:return:
"""
self._occupant_schedule = value
@property
def number_of_occupants(self):
"""
Get the number of occupants
:return: int
"""
return self._number_of_occupants
@number_of_occupants.setter
def number_of_occupants(self, value):
"""
Set the number of occupants
:param value: int
:return:
"""
self._number_of_occupants = value
@property
def arrival_time(self):
"""
Get the arrival time of the occupant (for office building) in UTC with format YYYYMMDD HH:mm:ss
:return: time
"""
return self._arrival_time
@arrival_time.setter
def arrival_time(self, value):
"""
Set the arrival time of the occupant (for office building) in UTC with format YYYYMMDD HH:mm:ss
:param value: time
:return:
"""
self._arrival_time = value
@property
def departure_time(self):
"""
Get the departure time of the occupant (for office building) in UTC with format YYYYMMDD HH:mm:ss
:return: time
"""
return self._departure_time
@departure_time.setter
def departure_time(self, value):
"""
Set the departure time of the occupant (for office building) in UTC with format YYYYMMDD HH:mm:ss
:param value: time
:return:
"""
self._departure_time = value
@property
def break_time(self):
"""
Get the lunch or break time of the occupant (for office building) in UTC with format ????
:return: break time
"""
# todo @Sanam: define this format, is it the starting time? is it a list with both, starting and ending time?
return self._break_time
@property
def day_of_week(self):
"""
Get the day of the week (MON, TUE, WED, THU, FRI, SAT, SUN)
:return: string
"""
# todo @Sanam: is this a property or should it be a function
# to get the day of the week of an specific day of the year?
return self._day_of_week
@property
def pd_of_meetings_duration(self):
"""
Get the probability distribution of the meeting duration
:return: ??
"""
# todo @Sanam: what format are you expecting here??
return self._pd_of_meetings_duration
@pd_of_meetings_duration.setter
def pd_of_meetings_duration(self, value):
"""
Get the probability distribution of the meeting duration
:param value: ??
:return:
"""
# todo @Sanam: what format are you expecting here??
self._pd_of_meetings_duration = value
def get_complete_year_schedule(self, schedules):
"""
Get the a non-leap year (8760 h), starting on Monday schedule out of archetypal days of week
:return: [float]
"""
if self._complete_year_schedule is None:
self._complete_year_schedule = []
for i in range(1, 13):
month_range = cal.monthrange(2018, i)
for day in range(1, month_range[1]+1):
if cal.weekday(2018, i, day) < 5:
for j in range(0, 24):
week_schedule = schedules['WD'][j]
self._complete_year_schedule.append(week_schedule)
elif cal.weekday(2018, i, day) == 5:
for j in range(0, 24):
week_schedule = schedules['Sat'][j]
self._complete_year_schedule.append(week_schedule)
else:
for j in range(0, 24):
week_schedule = schedules['Sun'][j]
self._complete_year_schedule.append(week_schedule)
return self._complete_year_schedule

View File

@ -4,12 +4,13 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
Contributors Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import List
from typing import List, TypeVar
from city_model_structure.attributes.layer import Layer
from city_model_structure.attributes.thermal_opening import ThermalOpening
from city_model_structure.attributes.thermal_zone import ThermalZone
from city_model_structure.attributes.surface import Surface
ThermalZone = TypeVar('ThermalZone')
class ThermalBoundary:
"""
@ -24,26 +25,21 @@ class ThermalBoundary:
self._outside_solar_absorptance = None
self._outside_thermal_absorptance = None
self._outside_visible_absorptance = None
self._window_ratio = None
self._u_value = None
# todo: no sense -> window area in thermal opening?? Check in geometry_factory -> due to the definition of
# window as surface_area * window_ratio
self._window_area = None
self._shortwave_reflectance = None
self._construction_name = None
self._hi = None
self._he = None
# todo: to discuss with @Guille
self._azimuth = None
self._inclination = None
self._area = None
self._window_ratio = None
self._refurbishment_measure = None
# todo: to discuss with @Guille: 1. emissivity is a function of absorptance
# 2. pg 17: fraction and surface -> NO
self._emissivity = None
# todo: @Guille
self._polygon = None
@property
def surface(self) -> Surface:
"""
@ -224,24 +220,6 @@ class ThermalBoundary:
"""
self._window_ratio = value
@property
def window_area(self):
"""
Thermal boundary window area in square meters
:return: float
"""
if self._window_area is None:
try:
if self.surface.hole_polygons is None:
self._window_area = float(self.surface.perimeter_polygon.area) * float(self.window_ratio)
else:
self._window_area = 0
for hole_polygon in self.surface.hole_polygons:
self._window_area += hole_polygon.area
except TypeError:
raise Exception('Window ratio is not defined or invalid surface area')
return self._window_area
# todo: what if I just want to assign a number??
@property
def u_value(self):

View File

@ -2,7 +2,7 @@
ThermalOpening module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
Contributors Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
"""
@ -23,6 +23,9 @@ class ThermalOpening:
self._hi = None
self._he = None
# todo: discuss with @Guille
self._polygon = None
@property
def area(self):
"""

View File

@ -10,6 +10,7 @@ from city_model_structure.attributes.surface import Surface
from city_model_structure.attributes.usage_zone import UsageZone
ThermalBoundary = TypeVar('ThermalBoundary')
Polyhedron = TypeVar('Polyhedron')
class ThermalZone:
@ -22,14 +23,15 @@ class ThermalZone:
self._bounded = None
self._is_heated = is_heated
self._is_cooled = is_cooled
self._is_mechanically_ventilated = None
self._additional_thermal_bridge_u_value = None
self._effective_thermal_capacity = None
self._indirectly_heated_area_ratio = None
self._infiltration_rate_system_on = None
self._infiltration_rate_system_off = None
self._usage_zones = None
self._volume = None
self._volume_geometry = None
@property
def is_heated(self):
@ -47,6 +49,14 @@ class ThermalZone:
"""
return self._is_cooled
@property
def is_mechanically_ventilated(self):
"""
Get thermal zone mechanical ventilation flag
:return: Boolean
"""
return self._is_mechanically_ventilated
@property
def floor_area(self):
"""
@ -204,3 +214,11 @@ class ThermalZone:
:return: None
"""
self._volume = value
@property
def volume_geometry(self) -> Polyhedron:
"""
Get the polyhedron defined by the thermal zone
:return: Polyhedron
"""
return self._volume_geometry

View File

@ -7,6 +7,7 @@ Contributors Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
from typing import List
from city_model_structure.attributes.internal_gains import InternalGains
from city_model_structure.attributes.lighting import Lighting
from city_model_structure.attributes.occupants import Occupants
class UsageZone:
@ -26,10 +27,10 @@ class UsageZone:
self._dhw_preparation_temperature = None
self._electrical_app_average_consumption_sqm_year = None
self._mechanical_air_change = None
self._occupancy = None
self._schedules = None
self._heating_schedule = None
self._occupants = None
self._lights = None
self._heating_schedule = None
self._cooling_schedule = None
@property
def lights(self) -> List[Lighting]:
@ -172,41 +173,25 @@ class UsageZone:
self._usage = value
@property
def occupancy(self):
def occupants(self) -> [Occupants]:
"""
Get occupancy data
:return: [Occupancy]
"""
return self._occupancy
return self._occupants
@occupancy.setter
def occupancy(self, values):
@occupants.setter
def occupants(self, values):
"""
Set occupancy
:param values: [Occupancy]
"""
self._occupancy = values
@property
def schedules(self):
"""
Get schedules
:return: [Schedule_Values]
"""
return self._schedules
@schedules.setter
def schedules(self, value):
"""
occupancy schedules
:param value: schedules
"""
self._schedules = value
self._occupants = values
@property
def heating_schedule(self):
"""
Get heating schedule
Get heating schedule: list of 0, 1 that define whether the heating system is OFF or ON
:return: dict{DtaFrame(int)}
"""
return self._heating_schedule
@ -219,6 +204,22 @@ class UsageZone:
"""
self._heating_schedule = values
@property
def cooling_schedule(self):
"""
Get cooling schedule: list of 0, 1 that define whether the heating system is OFF or ON
:return: dict{DtaFrame(int)}
"""
return self._cooling_schedule
@cooling_schedule.setter
def cooling_schedule(self, values):
"""
cooling schedule
:param values: dict{DtaFrame(int)}
"""
self._cooling_schedule = values
@property
def occupancy_density(self):
"""

View File

@ -13,7 +13,6 @@ from city_model_structure.attributes.thermal_boundary import ThermalBoundary
from city_model_structure.attributes.thermal_zone import ThermalZone
from city_model_structure.attributes.usage_zone import UsageZone
from city_model_structure.city_object import CityObject
from city_model_structure.building_unit import BuildingUnit
from helpers.geometry_helper import GeometryHelper as gh
@ -37,7 +36,6 @@ class Building(CityObject):
self._storeys_above_ground = None
self._floor_area = None
self._usage_zones = []
self._building_units = []
self._type = 'building'
self._heating = dict()
self._cooling = dict()
@ -209,22 +207,6 @@ class Building(CityObject):
"""
return self._type
@property
def building_units(self) -> [BuildingUnit]:
"""
Building units
:return:
"""
return self._building_units
@building_units.setter
def building_units(self, value):
"""
Building units
:param value: [BuildingUnit]
"""
self._building_units = value
@property
def heating(self) -> dict:
"""

View File

@ -1,48 +0,0 @@
"""
Building module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Sanam Dabirian sanam.dabirian@mail.concordia.ca
"""
from builtins import float
from city_model_structure.city_object import CityObject
class BuildingUnit(CityObject):
"""
BuildingUnit class
"""
def __init__(self, number_of_rooms, floor_area, energy_certificate):
"""
Constructor
"""
self._number_of_rooms = number_of_rooms
self._floor_area = floor_area
self._energy_certificate = energy_certificate
@property
def number_of_rooms(self):
"""
Get building unit number of rooms
:return: number of rooms
"""
return self._number_of_rooms
@property
def floor_area(self):
"""
Building unit floor area in square meters
:return: float
"""
return self._floor_area
@property
def energy_certificate(self):
"""
Building unit energy certificate
:return: energy_certificate
"""
#TODO: This is still not used, check in the future
return self._energy_certificate

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
"""
import pandas as pd
from city_model_structure.attributes.occupancy import Occupancy
from city_model_structure.attributes.occupants import Occupants
import calendar as cal
@ -31,7 +31,7 @@ class MonthlyToHourlyDemand:
for usage_zone in self._building.usage_zones:
temp_set = float(usage_zone.heating_setpoint)
temp_back = float(usage_zone.heating_setback)
occupancy = Occupancy().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
occupancy = Occupants().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
heating_schedule = self._conditioning_seasons['heating']
hourly_heating = []

View File

@ -67,30 +67,30 @@ class IdfHelper:
def add_schedule(self, building):
schedule_occupancy = self._idf.newidfobject("SCHEDULE:DAY:HOURLY".upper())
schedule_occupancy.Name = 'occupant schedule'
schedule_occupancy.Hour_1 = building.usage_zones[0].occupancy.occupant_schedule[0]
schedule_occupancy.Hour_2 = building.usage_zones[0].occupancy.occupant_schedule[1]
schedule_occupancy.Hour_3 = building.usage_zones[0].occupancy.occupant_schedule[2]
schedule_occupancy.Hour_4 = building.usage_zones[0].occupancy.occupant_schedule[3]
schedule_occupancy.Hour_5 = building.usage_zones[0].occupancy.occupant_schedule[4]
schedule_occupancy.Hour_6 = building.usage_zones[0].occupancy.occupant_schedule[5]
schedule_occupancy.Hour_7 = building.usage_zones[0].occupancy.occupant_schedule[6]
schedule_occupancy.Hour_8 = building.usage_zones[0].occupancy.occupant_schedule[7]
schedule_occupancy.Hour_9 = building.usage_zones[0].occupancy.occupant_schedule[8]
schedule_occupancy.Hour_10 = building.usage_zones[0].occupancy.occupant_schedule[9]
schedule_occupancy.Hour_11 = building.usage_zones[0].occupancy.occupant_schedule[10]
schedule_occupancy.Hour_12 = building.usage_zones[0].occupancy.occupant_schedule[11]
schedule_occupancy.Hour_13 = building.usage_zones[0].occupancy.occupant_schedule[12]
schedule_occupancy.Hour_14 = building.usage_zones[0].occupancy.occupant_schedule[13]
schedule_occupancy.Hour_15 = building.usage_zones[0].occupancy.occupant_schedule[14]
schedule_occupancy.Hour_16 = building.usage_zones[0].occupancy.occupant_schedule[15]
schedule_occupancy.Hour_17 = building.usage_zones[0].occupancy.occupant_schedule[16]
schedule_occupancy.Hour_18 = building.usage_zones[0].occupancy.occupant_schedule[17]
schedule_occupancy.Hour_19 = building.usage_zones[0].occupancy.occupant_schedule[18]
schedule_occupancy.Hour_20 = building.usage_zones[0].occupancy.occupant_schedule[19]
schedule_occupancy.Hour_21 = building.usage_zones[0].occupancy.occupant_schedule[20]
schedule_occupancy.Hour_22 = building.usage_zones[0].occupancy.occupant_schedule[21]
schedule_occupancy.Hour_23 = building.usage_zones[0].occupancy.occupant_schedule[22]
schedule_occupancy.Hour_24 = building.usage_zones[0].occupancy.occupant_schedule[23]
schedule_occupancy.Hour_1 = building.usage_zones[0].occupants.occupant_schedule[0]
schedule_occupancy.Hour_2 = building.usage_zones[0].occupants.occupant_schedule[1]
schedule_occupancy.Hour_3 = building.usage_zones[0].occupants.occupant_schedule[2]
schedule_occupancy.Hour_4 = building.usage_zones[0].occupants.occupant_schedule[3]
schedule_occupancy.Hour_5 = building.usage_zones[0].occupants.occupant_schedule[4]
schedule_occupancy.Hour_6 = building.usage_zones[0].occupants.occupant_schedule[5]
schedule_occupancy.Hour_7 = building.usage_zones[0].occupants.occupant_schedule[6]
schedule_occupancy.Hour_8 = building.usage_zones[0].occupants.occupant_schedule[7]
schedule_occupancy.Hour_9 = building.usage_zones[0].occupants.occupant_schedule[8]
schedule_occupancy.Hour_10 = building.usage_zones[0].occupants.occupant_schedule[9]
schedule_occupancy.Hour_11 = building.usage_zones[0].occupants.occupant_schedule[10]
schedule_occupancy.Hour_12 = building.usage_zones[0].occupants.occupant_schedule[11]
schedule_occupancy.Hour_13 = building.usage_zones[0].occupants.occupant_schedule[12]
schedule_occupancy.Hour_14 = building.usage_zones[0].occupants.occupant_schedule[13]
schedule_occupancy.Hour_15 = building.usage_zones[0].occupants.occupant_schedule[14]
schedule_occupancy.Hour_16 = building.usage_zones[0].occupants.occupant_schedule[15]
schedule_occupancy.Hour_17 = building.usage_zones[0].occupants.occupant_schedule[16]
schedule_occupancy.Hour_18 = building.usage_zones[0].occupants.occupant_schedule[17]
schedule_occupancy.Hour_19 = building.usage_zones[0].occupants.occupant_schedule[18]
schedule_occupancy.Hour_20 = building.usage_zones[0].occupants.occupant_schedule[19]
schedule_occupancy.Hour_21 = building.usage_zones[0].occupants.occupant_schedule[20]
schedule_occupancy.Hour_22 = building.usage_zones[0].occupants.occupant_schedule[21]
schedule_occupancy.Hour_23 = building.usage_zones[0].occupants.occupant_schedule[22]
schedule_occupancy.Hour_24 = building.usage_zones[0].occupants.occupant_schedule[23]
def _add_construction(self, thermal_boundary):
for construction in self._idf.idfobjects[self._CONSTRUCTION]:

View File

@ -172,9 +172,6 @@ class TestGeometryFactory(TestCase):
self.assertIsNotNone(thermal_boundary.azimuth, 'thermal_boundary azimuth is none')
self.assertIsNotNone(thermal_boundary.delimits, 'thermal_boundary delimits is none')
self.assertIsNotNone(thermal_boundary.inclination, 'thermal_boundary inclination is none')
# todo: assert exception
self.assertRaises(Exception, lambda: thermal_boundary.window_area,
'thermal_boundary window_area was initialized')
def test_citygml_thermal_opening(self):
"""