""" Monthly energy balance main SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca """ import sys from pathlib import Path from argparse import ArgumentParser import ast import pandas as pd import datetime import helpers.constants as cte from helpers import monthly_values as mv 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 from monthly_demand_calculation import MonthlyDemandCalculation from helpers.enrich_city import EnrichCity parser = ArgumentParser(description='Monthly energy balance workflow v0.1.') 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_pickle_file', '-p', help='Use pickle file instead of importing geometry file', default=False, required=True) parser.add_argument('--populated_step_in_pickle', '-ps', help='Physics and usage parameters already in pickle file', default=False, required=True) parser.add_argument('--weather_step_in_pickle', '-ws', help='Weather parameters already in pickle file', default=False, 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) 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) try: args = parser.parse_args() except SystemExit: sys.exit() keep_files = True print('begin_time', datetime.datetime.now()) # Step 1: Initialize the city model pickle_file = '' if ast.literal_eval(args.use_pickle_file): pickle_file = Path(args.input_geometry_file).resolve() city = City.load(pickle_file) else: file = Path(args.input_geometry_file).resolve() pickle_file = Path(str(file).replace('.gml', '.pickle')) city = GeometryFactory(args.geometry_type, file).city print(len(city.buildings)) 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) city.save(pickle_file) print('begin_populating_time', datetime.datetime.now()) # Step 2: Populate city adding thermal- and usage-related parameters populated_step_in_pickle = ast.literal_eval(args.populated_step_in_pickle) if populated_step_in_pickle: populated_city = city else: populated_city = EnrichCity(city).enriched_city(construction_format='nrcan', usage_format='hft') pickle_file = Path(str(pickle_file).replace('.pickle', '_populated.pickle')) populated_city.save(pickle_file) if populated_city.buildings is None: print('No building to be calculated') sys.exit() print('begin_weather_time', datetime.datetime.now()) # Step 3: Populate city adding climate-related parameters weather_format = 'epw' weather_step_in_pickle = ast.literal_eval(args.weather_step_in_pickle) if not weather_step_in_pickle: city.climate_reference_city = args.climate_reference_city path = (Path(args.project_folder) / 'tmp').resolve() city.climate_file = (path / f'{args.climate_reference_city}.cli').resolve() WeatherFactory(weather_format, populated_city, file_name=args.weather_file_name).enrich() for building in populated_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 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) 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(populated_city, building_name=building.name) else: sra.call_sra(weather_format, keep_files=keep_files) sra.set_irradiance_surfaces(populated_city) pickle_file = Path(str(pickle_file).replace('.pickle', '_weather.pickle')) populated_city.save(pickle_file) print('begin_user_assignment_time', datetime.datetime.now()) # Step 4: Assign user defined parameters for building in populated_city.buildings: building.attic_heated = 2 building.basement_heated = 0 print('begin_insel_time', datetime.datetime.now()) # Step 5: Demand calculation calling INSEL MonthlyDemandCalculation(city, args.project_folder, weather_format).monthly_demand() print('begin_write_results_time', datetime.datetime.now()) # Step 6: Print results print_results = None file = 'city name: ' + city.name + '\n' for building in populated_city.buildings: insel_file_name = building.name + '.insel' building_results = building.heating[cte.MONTH].rename(columns={'INSEL': building.name}) if print_results is None: print_results = building_results else: print_results = pd.concat([print_results, building_results], axis='columns') file += '\n' file += 'name: ' + building.name + '\n' file += 'year of construction: ' + building.year_of_construction + '\n' file += 'function: ' + building.function + '\n' file += 'floor area: ' + str(building.thermal_zones[0].floor_area) + '\n' file += 'storeys: ' + str(building.storeys_above_ground) + '\n' file += 'heated_volume: ' + str(building.volume) + '\n' file += 'volume: ' + str(building.volume) + '\n' full_path_results = Path(args.project_folder + '/outputs/heating_demand.csv').resolve() 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) pickle_file = Path(str(pickle_file).replace('.pickle', '_demand.pickle')) populated_city.save(pickle_file) print('end_time', datetime.datetime.now())