2021-02-04 11:17:31 -05:00
|
|
|
"""
|
|
|
|
Monthly energy balance main
|
|
|
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
2021-04-13 19:01:30 -04:00
|
|
|
Copyright © 2020 Project Author Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
|
2021-02-04 11:17:31 -05:00
|
|
|
"""
|
|
|
|
|
|
|
|
import sys
|
|
|
|
from pathlib import Path
|
|
|
|
from argparse import ArgumentParser
|
|
|
|
import ast
|
|
|
|
import pandas as pd
|
2021-04-28 15:41:42 -04:00
|
|
|
import datetime
|
2021-02-04 11:17:31 -05:00
|
|
|
|
2021-08-13 12:47:49 -04:00
|
|
|
import helpers.constants as cte
|
2021-02-04 11:17:31 -05:00
|
|
|
from helpers import monthly_values as mv
|
2021-04-15 17:24:30 -04:00
|
|
|
from simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
|
2021-03-02 18:58:06 -05:00
|
|
|
from imports.geometry_factory import GeometryFactory
|
|
|
|
from imports.weather_factory import WeatherFactory
|
2022-11-25 14:20:10 -05:00
|
|
|
from imports.construction_factory import ConstructionFactory
|
|
|
|
from imports.usage_factory import UsageFactory
|
|
|
|
from exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
|
|
|
|
from insel.monthly_demand_calculation import MonthlyDemandCalculation
|
2021-07-12 04:32:10 -04:00
|
|
|
|
2021-02-04 11:17:31 -05:00
|
|
|
|
2022-11-25 14:20:10 -05:00
|
|
|
parser = ArgumentParser(description='Monthly energy balance workflow v1.0.')
|
2021-02-04 11:17:31 -05:00
|
|
|
required = parser.add_argument_group('required arguments')
|
|
|
|
parser.add_argument('--geometry_type', '-g', help='Geometry type {citygml}', default='citygml')
|
|
|
|
required.add_argument('--input_geometry_file', '-i', help='Input geometry file', required=True)
|
|
|
|
parser.add_argument('--use_cached_sra_file', '-u', help='Use sra files from cache, instead of freshly calculated sra '
|
|
|
|
'files', default=False)
|
|
|
|
required.add_argument('--project_folder', '-f', help='Project folder', required=True)
|
2021-04-13 19:01:30 -04:00
|
|
|
required.add_argument('--weather_file_name', '-w', help='Weather file', required=True)
|
|
|
|
required.add_argument('--climate_reference_city', '-c', help='Closest city with climate weather', required=True)
|
2021-02-04 11:17:31 -05:00
|
|
|
|
|
|
|
try:
|
|
|
|
args = parser.parse_args()
|
|
|
|
except SystemExit:
|
|
|
|
sys.exit()
|
|
|
|
keep_files = True
|
2021-03-02 18:58:06 -05:00
|
|
|
|
|
|
|
print('begin_time', datetime.datetime.now())
|
2021-02-04 11:17:31 -05:00
|
|
|
# Step 1: Initialize the city model
|
2022-11-25 14:20:10 -05:00
|
|
|
file = Path(args.input_geometry_file).resolve()
|
|
|
|
city = GeometryFactory(args.geometry_type, file).city
|
|
|
|
for building in city.buildings:
|
|
|
|
volume = building.volume
|
|
|
|
if str(volume) == 'inf':
|
|
|
|
sys.stderr.write(f'Building {building.name} has geometry errors. It has been removed from the city\n')
|
|
|
|
city.remove_city_object(building)
|
2021-02-04 11:17:31 -05:00
|
|
|
|
2021-04-13 19:01:30 -04:00
|
|
|
print('begin_populating_time', datetime.datetime.now())
|
2021-02-04 11:17:31 -05:00
|
|
|
# Step 2: Populate city adding thermal- and usage-related parameters
|
2022-11-25 14:20:10 -05:00
|
|
|
for building in city.buildings:
|
|
|
|
building.year_of_construction = 2006
|
|
|
|
if building.function is None:
|
|
|
|
building.function = 'large office'
|
|
|
|
building.attic_heated = 0
|
|
|
|
building.basement_heated = 1
|
|
|
|
ConstructionFactory('nrel', city).enrich()
|
|
|
|
UsageFactory('comnet', city).enrich()
|
2021-02-04 11:17:31 -05:00
|
|
|
|
2021-04-13 19:01:30 -04:00
|
|
|
print('begin_weather_time', datetime.datetime.now())
|
2021-02-04 11:17:31 -05:00
|
|
|
# Step 3: Populate city adding climate-related parameters
|
2021-06-08 12:50:38 -04:00
|
|
|
weather_format = 'epw'
|
2022-11-25 14:20:10 -05:00
|
|
|
city.climate_reference_city = args.climate_reference_city
|
|
|
|
tmp_path = (Path(args.project_folder) / 'tmp').resolve()
|
|
|
|
city.climate_file = (tmp_path / f'{args.climate_reference_city}.cli').resolve()
|
|
|
|
WeatherFactory(weather_format, city, file_name=args.weather_file_name).enrich()
|
|
|
|
for building in city.buildings:
|
|
|
|
if cte.HOUR not in building.external_temperature:
|
|
|
|
print('No external temperature found')
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
if cte.MONTH not in building.external_temperature:
|
|
|
|
building.external_temperature[cte.MONTH] = mv.MonthlyValues().\
|
|
|
|
get_mean_values(building.external_temperature[cte.HOUR][[weather_format]])
|
|
|
|
|
|
|
|
max_buildings_handled_by_sra = 500
|
|
|
|
sra = SimplifiedRadiosityAlgorithm(city, Path(args.project_folder).resolve(), args.weather_file_name)
|
|
|
|
if ast.literal_eval(args.use_cached_sra_file):
|
|
|
|
sra.set_irradiance_surfaces(city)
|
|
|
|
else:
|
|
|
|
total_number_of_buildings = len(city.buildings)
|
|
|
|
if total_number_of_buildings > max_buildings_handled_by_sra:
|
|
|
|
radius = 80
|
|
|
|
for building in city.buildings:
|
|
|
|
new_city = city.region(building.centroid, radius)
|
|
|
|
sra_new = SimplifiedRadiosityAlgorithm(new_city, Path(args.project_folder).resolve(), args.weather_file_name)
|
|
|
|
sra_new.call_sra(weather_format, keep_files=True)
|
|
|
|
sra_new.set_irradiance_surfaces(city, building_name=building.name)
|
2021-02-04 11:17:31 -05:00
|
|
|
else:
|
2022-11-25 14:20:10 -05:00
|
|
|
sra.call_sra(weather_format, keep_files=keep_files)
|
|
|
|
sra.set_irradiance_surfaces(city)
|
2021-04-28 15:41:42 -04:00
|
|
|
|
2021-03-02 18:58:06 -05:00
|
|
|
print('begin_insel_time', datetime.datetime.now())
|
2021-06-08 12:50:38 -04:00
|
|
|
# Step 5: Demand calculation calling INSEL
|
2022-11-25 14:20:10 -05:00
|
|
|
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, tmp_path).export()
|
|
|
|
insel = MonthlyDemandCalculation(city, tmp_path, weather_format)
|
|
|
|
insel.run()
|
|
|
|
insel.results()
|
2021-04-28 15:41:42 -04:00
|
|
|
|
|
|
|
print('begin_write_results_time', datetime.datetime.now())
|
2021-08-13 12:47:49 -04:00
|
|
|
# Step 6: Print results
|
2021-02-04 11:17:31 -05:00
|
|
|
print_results = None
|
2021-04-13 19:01:30 -04:00
|
|
|
file = 'city name: ' + city.name + '\n'
|
2022-11-25 14:20:10 -05:00
|
|
|
for building in city.buildings:
|
2021-04-28 15:41:42 -04:00
|
|
|
insel_file_name = building.name + '.insel'
|
2022-11-25 14:20:10 -05:00
|
|
|
heating_results = building.heating[cte.MONTH].rename(columns={'INSEL': f'{building.name} heating Wh'})
|
|
|
|
cooling_results = building.cooling[cte.MONTH].rename(columns={'INSEL': f'{building.name} cooling Wh'})
|
2021-04-28 15:41:42 -04:00
|
|
|
if print_results is None:
|
2022-11-25 14:20:10 -05:00
|
|
|
print_results = heating_results
|
2021-04-28 15:41:42 -04:00
|
|
|
else:
|
2022-11-25 14:20:10 -05:00
|
|
|
print_results = pd.concat([print_results, heating_results], axis='columns')
|
|
|
|
print_results = pd.concat([print_results, cooling_results], axis='columns')
|
2021-04-28 15:41:42 -04:00
|
|
|
file += '\n'
|
|
|
|
file += 'name: ' + building.name + '\n'
|
2022-11-25 14:20:10 -05:00
|
|
|
file += 'year of construction: ' + str(building.year_of_construction) + '\n'
|
2021-04-28 15:41:42 -04:00
|
|
|
file += 'function: ' + building.function + '\n'
|
2022-11-25 14:20:10 -05:00
|
|
|
file += 'floor area: ' + str(building.internal_zones[0].area) + '\n'
|
2021-04-28 15:41:42 -04:00
|
|
|
file += 'storeys: ' + str(building.storeys_above_ground) + '\n'
|
|
|
|
file += 'heated_volume: ' + str(building.volume) + '\n'
|
|
|
|
file += 'volume: ' + str(building.volume) + '\n'
|
2021-02-04 11:17:31 -05:00
|
|
|
|
2022-11-25 14:20:10 -05:00
|
|
|
full_path_results = Path(args.project_folder + '/outputs/demand.csv').resolve()
|
2021-02-04 11:17:31 -05:00
|
|
|
print_results.to_csv(full_path_results)
|
|
|
|
full_path_metadata = Path(args.project_folder + '/outputs/metadata.csv').resolve()
|
|
|
|
with open(full_path_metadata, 'w') as metadata_file:
|
|
|
|
metadata_file.write(file)
|
2021-03-02 18:58:06 -05:00
|
|
|
|
|
|
|
print('end_time', datetime.datetime.now())
|