diff --git a/cache/.gitignore b/cache/.gitignore new file mode 100644 index 0000000..86d0cb2 --- /dev/null +++ b/cache/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/insel/templates/monthly_energy_balance.py b/insel/templates/monthly_energy_balance.py index 147df07..aeb878d 100644 --- a/insel/templates/monthly_energy_balance.py +++ b/insel/templates/monthly_energy_balance.py @@ -9,7 +9,7 @@ from imports.weather_feeders.helpers.weather import Weather as wt class MonthlyEnergyBalance: @staticmethod - def generate_meb_template(building, insel_outputs_path): + def generate_meb_template(building, insel_outputs_path, key): lc = helpers.library_codes.LibraryCodes() file = "" @@ -47,9 +47,8 @@ class MonthlyEnergyBalance: str(i + 1) + ' (sqm)' + '\n' total_internal_gains = 0 for ig in usage_zone.internal_gains: -# total_internal_gains += float(ig.average_internal_gain) * \ -# (float(ig.convective_fraction) + float(ig.radiative_fraction)) - total_internal_gains += 10.45 * (float(ig.convective_fraction) + float(ig.radiative_fraction)) + total_internal_gains += float(ig.average_internal_gain) * \ + (float(ig.convective_fraction) + float(ig.radiative_fraction)) file += str(total_internal_gains) + ' % BP(12) #2 Internal gains of zone ' + str(i + 1) + '\n' file += str(usage_zone.heating_setpoint) + ' % BP(13) #3 Heating setpoint temperature zone ' + \ str(i + 1) + ' (tSetHeat)' + '\n' @@ -112,14 +111,14 @@ class MonthlyEnergyBalance: file += 'p 20 12 % Monthly ambient temperature\r\n' external_temperature = building.external_temperature['month'] for i in range(0, len(external_temperature)): - file += str(i+1) + ' ' + str(external_temperature.at[i, 'inseldb']) + '\r\n' + file += str(i+1) + ' ' + str(external_temperature.at[i, key]) + '\r\n' file += '\r\n' file += 's 21 polyg 1\r\n' file += 'p 21 12 % Monthly sky temperature\r\n' i = 1 - sky_temperature = wt.sky_temperature(external_temperature[['inseldb']].to_numpy().T[0]) + sky_temperature = wt.sky_temperature(external_temperature[[key]].to_numpy().T[0]) for temperature in sky_temperature: file += str(i) + ' ' + str(temperature) + '\r\n' i += 1 diff --git a/main.py b/main.py index 064b321..df57769 100644 --- a/main.py +++ b/main.py @@ -14,12 +14,11 @@ from helpers import monthly_values as mv from populate import Populate from insel.insel import Insel from insel.templates.monthly_energy_balance import MonthlyEnergyBalance as templates -from simplified_radiosity_algorithm.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm +from simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm from imports.geometry_factory import GeometryFactory from imports.weather_factory import WeatherFactory from city_model_structure.city import City import datetime -import time parser = ArgumentParser(description='Monthly energy balance workflow v0.1.') required = parser.add_argument_group('required arguments') @@ -86,7 +85,10 @@ if not weather_step_in_pickle: get_mean_values(building.external_temperature['hour'][['epw']]) max_buildings_handled_by_sra = 500 - sra = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), city, args.weather_file_name) + for building in city.buildings: + for surface in building.surfaces: + surface.swr = 0.2 + sra = SimplifiedRadiosityAlgorithm(city, Path(args.project_folder).resolve(), args.weather_file_name) if ast.literal_eval(args.use_cached_sra_file): sra.results() sra.set_irradiance_surfaces(populated_city) @@ -96,7 +98,7 @@ if not weather_step_in_pickle: radius = 100 for building in city.buildings: new_city = city.region(building.location, radius) - sra_new = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), city, args.weather_file_name) + sra_new = SimplifiedRadiosityAlgorithm(city, Path(args.project_folder).resolve(), args.weather_file_name) sra_new.call_sra(keep_files=True) sra_new.set_irradiance_surfaces(city, building_name=building.name) else: @@ -109,8 +111,7 @@ print('begin_insel_time', datetime.datetime.now()) # Step 4: Demand calculation (one model per building) print_results = None file = 'city name: ' + city.name + '\n' -i = 0 -init = time.process_time_ns() + for building in populated_city.buildings: if building.name != 'BLD122177': # todo: default values to be defined at each specific workflow! @@ -118,12 +119,13 @@ for building in populated_city.buildings: building.cooled = False building.attic_heated = 1 building.basement_heated = 1 -# building.usage_zones[0].internal_gains[0].average_internal_gain = '10.45' + building.usage_zones[0].internal_gains[0].average_internal_gain = 10.45 full_path_out = Path(args.project_folder + '/outputs/' + building.name + '_insel.out').resolve() full_path_out.parent.mkdir(parents=True, exist_ok=True) insel_file_name = building.name + '.insel' try: - content = templates.generate_meb_template(building, full_path_out) + key = 'epw' + content = templates.generate_meb_template(building, full_path_out, key) insel = Insel(Path(args.project_folder).resolve(), insel_file_name, content, mode=2, keep_files=keep_files).run() building.heating['month'], building.cooling['month'] = templates.demand(full_path_out) new_building = building.heating['month'].rename(columns={'INSEL': building.name}) @@ -151,7 +153,6 @@ for building in populated_city.buildings: print(sys.exc_info()[1]) print('Building ' + building.name + ' could not be processed') continue - i += 1 full_path_results = Path(args.project_folder + '/outputs/heating_demand.csv').resolve() print_results.to_csv(full_path_results) diff --git a/simplified_radiosity_algorithm/simplified_radiosity_algorithm.py b/simplified_radiosity_algorithm/simplified_radiosity_algorithm.py deleted file mode 100644 index 1252a23..0000000 --- a/simplified_radiosity_algorithm/simplified_radiosity_algorithm.py +++ /dev/null @@ -1,151 +0,0 @@ -""" -Simplified Radiosity Algorithm -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es -""" - -import os -import shutil -from pathlib import Path -import pandas as pd -from helpers import monthly_values as mv -import subprocess -from subprocess import SubprocessError, TimeoutExpired, CalledProcessError - -from exports.exports_factory import ExportsFactory -from imports.weather_factory import WeatherFactory - - -class SimplifiedRadiosityAlgorithm: - # todo: define executable as configurable parameter - # _executable = 'citysim_sra' # for linux - _executable = 'shortwave_integer' # for windows - - def __init__(self, sra_working_path, city, weather_file_name): - self._city = city - self._sra_working_path = sra_working_path - self._weather_file_name = weather_file_name - self._tmp_path = (sra_working_path / 'tmp').resolve() - Path(self._tmp_path).mkdir(parents=True, exist_ok=True) - # Ensure tmp file is empty - for child in self._tmp_path.glob('*'): - if child.is_file(): - child.unlink() - self._cache_path = (sra_working_path / 'cache').resolve() - Path(self._cache_path).mkdir(parents=True, exist_ok=True) - self._sra_out_file_name = self._city.name + '_sra_SW.out' - self._out_values = None - self._radiation = [] - - def call_sra(self, keep_files=False): - self._create_cli_file() - ExportsFactory('sra', self._city, self._tmp_path).export() - try: - completed = subprocess.run([self._executable, str(Path(self._tmp_path / f'{self._city.name}_sra.xml').resolve())]) - except (SubprocessError, TimeoutExpired, CalledProcessError) as error: - raise Exception(error) - file = (self._tmp_path / self._sra_out_file_name).resolve() - new_path = (self._cache_path / self._sra_out_file_name).resolve() - try: - shutil.move(str(file), str(new_path)) - except Exception: - raise Exception('No SRA output file found') - self._out_values = self.results() - if not keep_files: - os.remove(Path(self._tmp_path / f'{self._city.name}_sra.xml').resolve()) - return completed - - def results(self): - if self._out_values is None: - try: - path = (self._cache_path / self._sra_out_file_name).resolve() - self._out_values = pd.read_csv(path, sep='\s+', header=0) - except Exception: - raise Exception('No SRA output file found') - return self._out_values - - @property - def radiation(self) -> []: - if len(self._radiation) == 0: - id_building = '' - header_building = [] - for column in self._out_values.columns.values: - if id_building != column.split(':')[1]: - id_building = column.split(':')[1] - if len(header_building) > 0: - self._radiation.append(pd.concat([mv.MonthlyValues().month_hour, self._out_values[header_building]], - axis=1)) - header_building = [column] - else: - header_building.append(column) - self._radiation.append(pd.concat([mv.MonthlyValues().month_hour, self._out_values[header_building]], axis=1)) - return self._radiation - - def set_irradiance_surfaces(self, city, mode=0, building_name=None): - """ - saves in building surfaces the correspondent irradiance at different time-scales depending on the mode - if building is None, it saves all buildings' surfaces in file, if building is specified, it saves only that - specific building values - mode = 0, set only monthly values - mode = 1, set only hourly values - mode = 2, set both - :parameter city: city - :parameter mode: str (time-scale definition) - :parameter building_name: str - :return: none - """ - for radiation in self.radiation: - city_object_name = radiation.columns.values.tolist()[1].split(':')[1] - if building_name is not None: - if city_object_name != building_name: - continue - city_object = city.city_object(city_object_name) - print(city_object.name) - for column in radiation.columns.values: - if column == 'month': - continue - header_name = column - surface_name = header_name.split(':')[2] - surface = city_object.surface(surface_name) - print('surface', surface) - new_value = pd.DataFrame(radiation[[header_name]].to_numpy(), columns=['sra']) - if mode == 0 or mode == 2: - month_new_value = mv.MonthlyValues().get_mean_values(new_value) - print(surface.global_irradiance) - print(month_new_value) - if 'month' not in surface.global_irradiance: - surface.global_irradiance['month'] = month_new_value - print('1', month_new_value) - else: - pd.concat([surface.global_irradiance['month'], month_new_value], axis=1) - print('rest', month_new_value) - if mode == 1 or mode == 2: - if 'hour' not in surface.global_irradiance: - surface.global_irradiance['hour'] = new_value - else: - pd.concat([surface.global_irradiance['hour'], new_value], axis=1) - - def _create_cli_file(self): - file = self._city.climate_file - days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - WeatherFactory('epw', self._city, file_name=self._weather_file_name).enrich() - content = self._city.name + '\n' - content += str(self._city.latitude) + ',' + str(self._city.longitude) + ',0.0,' + str(self._city.time_zone) + '\n' - content += '\ndm m h G_Dh G_Bn\n' - total_days = 0 - for month in range(1, 13): - if month > 1: - total_days += days_in_month[month - 2] - for day in range(1, days_in_month[month-1]+1): - for hour in range(1, 25): - if month == 1: - i = 24 * (day-1) + hour - 1 - else: - i = (total_days+day-1)*24 + hour - 1 - representative_building = self._city.buildings[0] - content += str(day) + ' ' + str(month) + ' ' + str(hour) + ' ' \ - + str(representative_building.global_horizontal['hour'].epw[i]) + ' ' \ - + str(representative_building.beam['hour'].epw[i]) + '\n' - with open(file, "w") as file: - file.write(content) - return