""" Monthly energy balance main SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es """ import sys from pathlib import Path from argparse import ArgumentParser import ast import pandas as pd 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 imports.geometry_factory import GeometryFactory from imports.weather_factory import WeatherFactory from city_model_structure.city import City import datetime 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('--cli_weather_file', '-c', help='weather cli file', required=True) required.add_argument('--city_name', '-n', help='city name for dat file', 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 city.save(pickle_file) # 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 for building in populated_city.buildings: for usage_zone in building.usage_zones: usage_zone.heating_setpoint = 20 usage_zone.heating_setback = 17 else: populated_city = Populate(city).populated_city 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('populating_time', datetime.datetime.now()) # Step 3: Populate city adding climate-related parameters weather_step_in_pickle = ast.literal_eval(args.weather_step_in_pickle) if not weather_step_in_pickle: city_name = args.city_name WeatherFactory('dat', populated_city, city_name) for building in populated_city.buildings: if 'hour' not in building.external_temperature: print('No external temperature found') sys.exit() if 'month' not in building.external_temperature: building.external_temperature['month'] = mv.MonthlyValues().\ get_mean_values(building.external_temperature['hour'][['inseldb']]) max_buildings_handled_by_sra = 500 sra_file_name = 'SRA' sra = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), sra_file_name, Path(args.cli_weather_file).resolve(), city.city_objects, lower_corner=city.lower_corner) 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 = 100 for building in city.buildings: new_city = city.region(building.location, radius) sra_file_name = 'SRA' sra_new = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), sra_file_name, Path(args.cli_weather_file).resolve(), new_city.city_objects, lower_corner=new_city.lower_corner) sra_new.call_sra(keep_files=True) sra_new.set_irradiance_surfaces(city, building_name=building.name) else: sra.call_sra(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_insel_time', datetime.datetime.now()) # Step 4: Demand calculation (one model per building) print_results = None # todo: city.name needs location and so, internet connection # file = 'city name: ' + city.name + '\n' file = 'city name: Kelowna\n' i = 0 for building in populated_city.buildings: if building.name != 'BLD122177': print(building.name) # todo: default values to be defined at each specific workflow! building.heated = True building.cooled = False building.attic_heated = 2 building.basement_heated = 1 for thermal_boundary in building.thermal_zones[0].bounded: thermal_boundary.hi = 10 thermal_boundary.he = 25 for thermal_opening in thermal_boundary.thermal_openings: thermal_opening.hi = 10 thermal_opening.he = 25 building.thermal_zones[0].indirectly_heated_area_ratio = 0.25 building.thermal_zones[0].additional_thermal_bridge_u_value = 0.05 building.usage_zones[0].mechanical_air_change = 0.35 building.thermal_zones[0].infiltration_rate_system_on = 0 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) 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}) if print_results is None: print_results = new_building else: print_results = pd.concat([print_results, new_building], 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.heated_volume) + '\n' file += 'volume: ' + str(building.volume) + '\n' except ValueError: 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) full_path_metadata = Path(args.project_folder + '/outputs/metadata.csv').resolve() with open(full_path_metadata, 'w') as metadata_file: metadata_file.write(file) print('end_time', datetime.datetime.now())