Added the full functionality to create meb

This commit is contained in:
Guille Gutierrez 2023-02-08 13:40:06 -05:00
parent 11e8949b30
commit 22cbede8d5
10 changed files with 159 additions and 12 deletions

View File

@ -14,6 +14,8 @@ class LevelOfDetail:
self._geometry = None
self._construction = None
self._usage = None
self._weather = None
self._surface_radiation = None
@property
def geometry(self):
@ -59,3 +61,33 @@ class LevelOfDetail:
Set the city minimal usage level of detail, 1 or 2
"""
self._usage = value
@property
def weather(self):
"""
Get the city minimal weather level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
:return: int
"""
return self._weather
@weather.setter
def weather(self, value):
"""
Set the city minimal weather level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
"""
self._usage = value
@property
def surface_radiation(self):
"""
Get the city minimal surface radiation level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
:return: int
"""
return self._surface_radiation
@surface_radiation.setter
def surface_radiation(self, value):
"""
Set the city minimal surface radiation level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
"""
self._surface_radiation = value

View File

@ -152,3 +152,7 @@ FULL_HVAC = 'Heating and cooling and ventilation'
# Floats
MAX_FLOAT = float('inf')
MIN_FLOAT = float('-inf')
# Tools
SRA = 'sra'
INSEL_MEB = 'insel meb'

View File

@ -0,0 +1,53 @@
"""
Insel monthly energy balance
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guillermo.GutierrezMorote@concordia.ca
"""
from pathlib import Path
import pandas as pd
import csv
import hub.helpers.constants as cte
class InselMonthlyEnergyBalance:
"""
Import SRA results
"""
def __init__(self, city, base_path):
self._city = city
self._base_path = base_path
@staticmethod
def _demand(insel_output_file_path):
heating = []
cooling = []
with open(Path(insel_output_file_path).resolve()) as csv_file:
csv_reader = csv.reader(csv_file)
for line in csv_reader:
demand = str(line).replace("['", '').replace("']", '').split()
for i in range(0, 2):
if demand[i] != 'NaN':
aux = float(demand[i]) * 1000 # kWh to Wh
demand[i] = str(aux)
else:
demand[i] = '0'
heating.append(demand[0])
cooling.append(demand[1])
monthly_heating = pd.DataFrame(heating, columns=[cte.INSEL_MEB])
monthly_cooling = pd.DataFrame(cooling, columns=[cte.INSEL_MEB])
return monthly_heating, monthly_cooling
def enrich(self):
for building in self._city.buildings:
file_name = building.name + '.out'
insel_output_file_path = Path(self._base_path / file_name).resolve()
if insel_output_file_path.is_file():
building.heating[cte.MONTH], building.cooling[cte.MONTH] = self._demand(insel_output_file_path)
building.heating[cte.YEAR] = pd.DataFrame(
[building.heating[cte.MONTH][cte.INSEL_MEB].sum()], columns=[cte.INSEL_MEB]
)
building.cooling[cte.YEAR] = pd.DataFrame(
[building.cooling[cte.MONTH][cte.INSEL_MEB].sum()], columns=[cte.INSEL_MEB]
)

View File

@ -32,7 +32,7 @@ class SimplifiedRadiosityAlgorithm:
array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=[cte.MONTH])
def _get_mean_values(self, values):
def _get_monthly_mean_values(self, values):
out = None
if values is not None:
if cte.MONTH not in values.columns:
@ -41,6 +41,9 @@ class SimplifiedRadiosityAlgorithm:
del out[cte.MONTH]
return out
def _get_yearly_mean_values(self, values):
return values.mean()
def _read_results(self):
try:
return pd.read_csv(self._input_file_path, sep='\s+', header=0)
@ -79,9 +82,8 @@ class SimplifiedRadiosityAlgorithm:
header_id = column
surface_id = header_id.split(':')[2]
surface = building.surface_by_id(surface_id)
new_value = pd.DataFrame(radiation[[header_id]].to_numpy(), columns=['sra'])
month_new_value = self._get_mean_values(new_value)
new_value = pd.DataFrame(radiation[[header_id]].to_numpy(), columns=[cte.SRA])
month_new_value = self._get_monthly_mean_values(new_value)
if cte.MONTH not in surface.global_irradiance:
surface.global_irradiance[cte.MONTH] = month_new_value
else:
@ -90,3 +92,6 @@ class SimplifiedRadiosityAlgorithm:
surface.global_irradiance[cte.HOUR] = new_value
else:
pd.concat([surface.global_irradiance[cte.HOUR], new_value], axis=1)
if cte.YEAR not in surface.global_irradiance:
surface.global_irradiance[cte.YEAR] = self._get_yearly_mean_values(new_value)
self._city.level_of_detail.surface_radiation = 2

View File

@ -10,6 +10,7 @@ from pathlib import Path
from hub.helpers.utils import validate_import_export_type
from hub.hub_logger import logger
from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance
class ResultFactory:
@ -34,6 +35,12 @@ class ResultFactory:
"""
SimplifiedRadiosityAlgorithm(self._city, self._base_path).enrich()
def _insel_meb(self):
"""
Enrich the city with insel monthly energy balance results
"""
InselMonthlyEnergyBalance(self._city, self._base_path).enrich()
def enrich(self):
"""
Enrich the city given to the class using the usage factory given handler

View File

@ -9,6 +9,7 @@ import sys
from pathlib import Path
import pandas as pd
import hub.helpers.constants as cte
from hub.imports.weather.helpers.weather import Weather as wh
class EpwWeatherParameters:
@ -110,3 +111,10 @@ class EpwWeatherParameters:
building.beam[cte.HOUR] = new_value
else:
pd.concat([building.beam[cte.HOUR], new_value], axis=1)
# create the monthly and yearly values out of the hourly
for building in self._city.buildings:
if cte.MONTH not in building.external_temperature:
building.external_temperature[cte.MONTH] = wh().get_monthly_mean_values(building.external_temperature[cte.HOUR][['epw']])
if cte.YEAR not in building.external_temperature:
building.external_temperature[cte.YEAR] = wh(). get_yearly_mean_values(building.external_temperature[cte.HOUR][['epw']])
self._city.level_of_detail.weather = 2

View File

@ -6,6 +6,9 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import math
import hub.helpers.constants as cte
import pandas as pd
import calendar as cal
import numpy as np
class Weather:
@ -28,3 +31,38 @@ class Weather:
+ 0.32 * (temperature + cte.KELVIN) - cte.KELVIN
values.append(value)
return values
def get_monthly_mean_values(self, values):
out = None
if values is not None:
if 'month' not in values.columns:
values = pd.concat([self.month_hour, pd.DataFrame(values)], axis=1)
out = values.groupby('month', as_index=False).mean()
del out['month']
return out
def get_yearly_mean_values(self, values):
return values.mean()
def get_total_month(self, values):
out = None
if values is not None:
if 'month' not in values.columns:
values = pd.concat([self.month_hour, pd.DataFrame(values)], axis=1)
out = pd.DataFrame(values).groupby('month', as_index=False).sum()
del out['month']
return out
@property
def month_hour(self):
"""
returns a DataFrame that has x values of the month number (January = 1, February = 2...),
being x the number of hours of the corresponding month
:return: DataFrame(int)
"""
array = []
for i in range(0, 12):
days_of_month = cal.monthrange(2015, i+1)[1]
total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=['month'])

View File

@ -16,7 +16,7 @@ class CityObject(Models):
A model representation of an application
"""
__tablename__ = 'city_object'
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
id = Column(Integer, Sequence('city_object_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
name = Column(String, nullable=False)
alias = Column(String, nullable=True)

View File

@ -17,7 +17,7 @@ class SimulationResults(Models):
A model representation of an application
"""
__tablename__ = 'simulation_results'
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
id = Column(Integer, Sequence('simulation_results_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=True)
city_object_id = Column(Integer, ForeignKey('city_object.id'), nullable=True)
name = Column(String, nullable=False)

View File

@ -47,7 +47,7 @@ class City(Repository):
pickle.dumps(city),
city.name,
city.level_of_detail.geometry,
'None' if city.climate_file is None else city.climate_file,
'None' if city.climate_file is None else str(city.climate_file),
application_id,
user_id,
__version__)