diff --git a/insel/templates/monthly_energy_balance.py b/insel/templates/monthly_energy_balance.py deleted file mode 100644 index 59c274f..0000000 --- a/insel/templates/monthly_energy_balance.py +++ /dev/null @@ -1,140 +0,0 @@ -from helpers.library_codes import LibraryCodes - - -class MonthlyEnergyBalance: - @staticmethod - def generate_meb_template(city_object, temperatures, outputs_path): - lc = LibraryCodes() - - file = "" - file += "s 1 do\r\n" - file += "p 1 1 12 1\r\n" - file += "\r\n" - file += "s 4 d18599 1 20 21\r\n" - - surfaces = city_object.surfaces - for i in range(1, len(surfaces) + 1): - file += str(100 + i) + ' % Radiation surface ' + str(i) + '\r\n' - - file += 'p 4' + '\r\n' - # BUILDING PARAMETERS - file += str(city_object.heated_volume) + ' % BP(1) Heated Volume (vBrutto)\r\n' - file += str(city_object.average_storey_height) + ' % BP(2) Average storey height / m\r\n' - file += str(city_object.storeys_above_ground) + ' % BP(3) Number of storeys above ground\r\n' - file += str(city_object.attic_heated) + ' % BP(4) Attic heating type (0=no room, 1=unheated, 2=heated)\r\n' - file += str(city_object.basement_heated) + ' % BP(5) Cellar heating type (0=no room, 1=unheated, ' \ - '2=heated, 99=invalid)\r\n' - # todo: this method and the insel model have to be reviewed for more than one thermal zone - thermal_zone = city_object.thermal_zones[0] - file += str(thermal_zone.indirectly_heated_area_ratio) + ' % BP(6) Indirectly heated area ratio\r\n' - file += str(thermal_zone.effective_thermal_capacity) + ' % BP(7) Effective heat capacity\r\n' - file += str(thermal_zone.additional_thermal_bridge_u_value) + ' % BP(8) Additional U-value for heat bridge\r\n' - # todo: ensure that this line is not needed - # file += str(usage_parameters().standard) + ' % BP(9) Usage type (0=standard, 1=IWU)\r\n' - # ZONES AND SURFACES - file += str(len(city_object.thermal_zones)) + ' % BP(10) Number $z$ of zones\r\n' - - i = 0 - for usage_zone in city_object.usage_zones: - percentage_usage = 1 - file += str(float(city_object.foot_print.area) * percentage_usage) + ' % BP(11) #1 Area of zone ' + \ - str(i + 1) + ' (sqm)' + '\r\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)) - file += str(total_internal_gains) + ' % BP(12) #2 Internal gains of zone ' + str(i + 1) + '\r\n' - file += str(usage_zone.heating_setpoint) + ' % BP(13) #3 Heating setpoint temperature zone ' + \ - str(i + 1) + ' (tSetHeat)' + '\r\n' - file += str(usage_zone.heating_setback) + ' % BP(14) #4 Heating setback temperature zone ' + \ - str(i + 1) + ' (tSetbackHeat)' + '\r\n' - file += str(usage_zone.cooling_setpoint) + ' % BP(15) #5 Cooling setpoint temperature zone ' + \ - str(i + 1) + ' (tSetCool)' + '\r\n' - file += str(usage_zone.hours_day) + ' % BP(16) #6 Usage hours per day zone ' + str(i + 1) + '\r\n' - file += str(usage_zone.days_year) + ' % BP(17) #7 Usage days per year zone ' + str(i + 1) + '\r\n' - if usage_zone.min_air_change is None: - raise Exception('Ventilation air rate is not initialized') - file += str(usage_zone.min_air_change) + ' % BP(18) #8 Minimum air change rate zone ' + \ - str(i + 1) + ' (h^-1)' + '\r\n' - i += 1 - - file += str(len(surfaces)) + ' % Number of surfaces = BP(11+8z)\r\n' - file += '% 1. Surface type (1=wall, 2=ground 3=roof, 4=flat roof)' + '\r\n' - file += '% 2. Areas above ground' + '\r\n' - file += '% 3. Areas below ground' + '\r\n' - file += '% 4. U-value' + '\r\n' - file += '% 5. Window area' + '\r\n' - file += '% 6. Window frame fraction' + '\r\n' - file += '% 7. Window U-value' + '\r\n' - file += '% 8. Window g-value' + '\r\n' - file += '% 9. Short-wave reflectance' + '\r\n' - file += '% #1 #2 #3 #4 #5 #6 #7 #8 #9' + '\r\n' - - # todo: this method has to be reviewed for more than one thermal opening per thermal boundary - for thermal_boundary in city_object.thermal_zones[0].bounded: - type_code = lc.construction_types_to_code(thermal_boundary.type) - string = type_code + ' ' + str(thermal_boundary.area_above_ground) + ' ' + \ - str(thermal_boundary.area_below_ground) + ' ' + str(thermal_boundary.u_value) + ' ' + \ - str(thermal_boundary.window_area) + ' ' - if thermal_boundary.window_area <= 0.001: - string = string + '0 0 0 ' - else: - string = string + str(thermal_boundary.thermal_openings[0].frame_ratio) + ' ' + \ - str(thermal_boundary.thermal_openings[0].u_value) + ' ' + \ - str(thermal_boundary.thermal_openings[0].g_value) + ' ' - if thermal_boundary.outside_solar_absorptance is not None: - string += str(thermal_boundary.shortwave_reflectance) + '\r\n' - else: - string += '0 \r\n' - file += string - - file += '\r\n' - file += 's 20 polyg 1\r\n' - file += 'p 20 12 % Monthly ambient temperature\r\n' - i = 1 - for temperature in temperatures[['temperature']].to_numpy(): - file += str(i) + ' ' + str(temperature[0]) + '\r\n' - i += 1 - - file += '\r\n' - file += 's 21 polyg 1\r\n' - file += 'p 21 12 % Monthly sky temperature\r\n' - i = 1 - for temperature in temperatures[['sky temperature']].to_numpy(): - file += str(i) + ' ' + str(temperature[0]) + '\r\n' - i += 1 - - i = 0 - for surface in surfaces: - file += '\r\n' - file += 's ' + str(101 + i) + ' polyg 1 % Monthly surface radiation (W/sqm)\r\n' - file += 'p ' + str(101 + i) + ' 12 % Azimuth ' + str(surface.azimuth) + \ - ', inclination ' + str(surface.inclination) + ' degrees\r\n' - j = 1 - for global_irradiance_month in surface.global_irradiance_month: - file += str(j) + ' ' + str(global_irradiance_month) + '\r\n' - j += 1 - i += 1 - - file += '\r\n' - file += '% ONE YEAR\r\n' - file += 's 300 cum 4.1 4.2\r\n' - file += 's 303 atend 300.1 300.2\r\n' - file += 's 304 screen 303.1 303.2 4.5\r\n' - file += "p 304 '(''Yearly results: qh = '',F13.2,'' qc = ''F13.2,'' kWh a^-1 meanUvalue = '',F6.3)'\r\n" - - file += '\r\n' - file += '% MONTHLY\r\n' - file += 's 305 screen 4.1 4.2\r\n' - file += "p 305 '(''qh = '',F13.2,'' qc = ''F13.2,'' kWh a^-1'')'\r\n" - - file += '\r\n' - file += 's ' + str(310) + ' WRITE\r\n' - file += '4.1 4.2\r\n' - file += 'p ' + str(301) + '\r\n' - file += '1 % Mode\r\n' - file += '0 % Suppress FNQ inputs\r\n' - file += "'" + str(outputs_path) + "' % File name\r\n" - file += "'*' % Fortran format\r\n" - - return file diff --git a/insel/templates/thermal_demand_dynamic_simulation.py b/insel/templates/thermal_demand_dynamic_simulation.py index 42fa05c..4b14a2a 100644 --- a/insel/templates/thermal_demand_dynamic_simulation.py +++ b/insel/templates/thermal_demand_dynamic_simulation.py @@ -46,7 +46,8 @@ class ThermalDemandDynamicSimulation: # insel template i_block = 0 - new_file, pointers = self._general_blocks(i_block, self._building, self._outputs_paths, self._weather_path, + pointers = [i_block] + new_file, pointers = self._general_blocks(pointers, self._building, self._outputs_paths, self._weather_path, self._ig_path, self._simulation_parameters) file += new_file @@ -56,10 +57,13 @@ class ThermalDemandDynamicSimulation: new_file = self._surfaces_blocks(pointers, self._building) file += new_file + print(file) return file @staticmethod - def _general_blocks(i_block, building, outputs_paths, weather_path, ig_path, simulation_parameters): + def _general_blocks(pointers, building, outputs_paths, weather_path, ig_path, simulation_parameters): + i_block = pointers[0] + # time blocks i_block += 1 n_clock = i_block @@ -125,7 +129,7 @@ class ThermalDemandDynamicSimulation: # internal gains and control blocks i_block += 1 n_ig = i_block - n_records = number_usage_zones * 5 + n_records = number_usage_zones * 6 inputs = [f"{n_hoy}.1"] parameters = [f"{n_records} %[Nrec]", f"{n_records * 12} %[RecLen]", @@ -169,14 +173,14 @@ class ThermalDemandDynamicSimulation: i_block += 1 inputs = [f"{n_hoy}.1"] for i in range(0, number_usage_zones): - inputs.append(f"{n_w_temp + 8 + 10 * i}.2") - inputs.append(f"{n_w_temp + 8 + 10 * i}.3") + inputs.append(f"{n_w_temp + 8 + 9 * i}.2") + inputs.append(f"{n_w_temp + 8 + 9 * i}.3") file = Insel.add_block(file, i_block, 'AVEC', inputs) i_block += 1 inputs = [f"{n_hoy}.1"] for i in range(0, number_usage_zones): - inputs.append(f"{n_w_temp + 8 + 10 * i}.1") + inputs.append(f"{n_w_temp + 8 + 9 * i}.1") file = Insel.add_block(file, i_block, 'AVEC', inputs) i_block += 1 @@ -227,7 +231,7 @@ class ThermalDemandDynamicSimulation: # Zones: n_start_zones = i_block + 1 - n_start_surfaces = n_start_zones + len(building.thermal_zones * 10) + n_start_surfaces = n_start_zones + len(building.thermal_zones * 9) n_zone = [] number_of_windows = [] for i_zone, thermal_zone in enumerate(building.thermal_zones): @@ -251,12 +255,12 @@ class ThermalDemandDynamicSimulation: n_zone.append(i_block) inputs = [f"{n_gain_moy}.1", f"{n_zero}.1", - f"{n_ig}.{1 + 5 * i_zone}", # convective part of IG + f"{n_ig}.{1 + 6 * i_zone}", # convective part of IG f"{n_weather}.1", # ambient temperature - f"{n_zone[i_zone] + 2}.1", # infiltration rate - f"{n_ig}." + str(4 + 5 * i_zone), # set point cooling - f"{n_ig}." + str(5 + 5 * i_zone), # set point heating - f"{n_ig}." + str(3 + 5 * i_zone), # ventilation rate + f"{n_ig}." + str(3 + 6 * i_zone), # infiltration rate + f"{n_ig}." + str(5 + 6 * i_zone), # set point cooling + f"{n_ig}." + str(6 + 6 * i_zone), # set point heating + f"{n_ig}." + str(4 + 6 * i_zone), # ventilation rate f"{n_weather}.1", # ventilation temperature f"{n_zone[i_zone] + 4}.1", # from chs ] @@ -288,11 +292,6 @@ class ThermalDemandDynamicSimulation: parameters = ["20 %[Tini]"] file = Insel.add_block(file, i_block, 'DELAY', inputs, parameters) - # infiltration - i_block += 1 - parameters = [f"{thermal_zone.infiltration_rate_system_off} %[InfiltrationRate]"] - file = Insel.add_block(file, i_block, 'CONST', parameters=parameters) - # SUM convection flux i_block += 1 inputs = [] @@ -431,7 +430,7 @@ class ThermalDemandDynamicSimulation: if (thermal_boundary.surface.type == cte.WALL) or (thermal_boundary.surface.type == cte.ROOF): inputs.append(f"{n_zone[i_tz] + 8}.{i_surface}") inputs.append(f"{n_zone[i_tz] + 6}.{i_surface}") - inputs.append(f"{n_ig}.{i_tz * 5 + 2}") + inputs.append(f"{n_ig}.{i_tz * 6 + 2}") inputs.append(f"{i_block + 2}.1") inputs.append(f"{n_weather}.1") inputs.append(f"{n_weather}.2") @@ -468,7 +467,7 @@ class ThermalDemandDynamicSimulation: elif (thermal_boundary.surface.type == cte.GROUND) or (thermal_boundary.surface.type == cte.GROUND_WALL): inputs.append(f"{n_zone[i_tz] + 8}.{i_surface}") inputs.append(f"{n_zone[i_tz] + 6}.{i_surface}") - inputs.append(f"{n_ig}.{i_tz * 5 + 2}") + inputs.append(f"{n_ig}.{i_tz * 6 + 2}") inputs.append(f"{n_weather}.3") inputs.append(f"{n_zone[i_tz] + 1}.1") parameters = [f"{thermal_boundary.hi} % [ConvCoefiW]", @@ -543,7 +542,7 @@ class ThermalDemandDynamicSimulation: file = Insel.add_block(file, i_block, 'GAIN', inputs=inputs, parameters=parameters) i_block += 1 inputs = [f"{n_zone[i_tz] + 6}.{i_surface}", - f"{n_ig}.{i_tz * 5 + 2}"] + f"{n_ig}.{i_tz * 6 + 2}"] file = Insel.add_block(file, i_block, 'SUM', inputs=inputs) if len(thermal_boundary.thermal_openings) > 0: i_weather_window += 5 @@ -589,7 +588,6 @@ class ThermalDemandDynamicSimulation: ig_path = self._ig_path content = pd.DataFrame() zeros = np.zeros(8760) - # todo: to talk with @Sanam -> where does this information come from? for i_uz, usage_zone in enumerate(building.usage_zones): convective_part = 0 radiative_part = 0 @@ -611,6 +609,7 @@ class ThermalDemandDynamicSimulation: set_point_heating.append(value * usage_zone.cooling_setback) content[f'convective_part_{i_uz}'] = zeros content[f'radiative_part_{i_uz}'] = zeros + content[f'infiltration_rate_{i_uz}'] = zeros content[f'ventilation_rate_{i_uz}'] = zeros content[f'set_point_cooling_{i_uz}'] = zeros content[f'set_point_heating_{i_uz}'] = zeros diff --git a/main.py b/main.py index 8af8e92..397aa21 100644 --- a/main.py +++ b/main.py @@ -1,13 +1,11 @@ import sys from insel.insel import Insel from pathlib import Path -import pandas as pd from helpers.enrich_city import EnrichCity from simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm from imports.weather_factory import WeatherFactory from insel.templates.thermal_demand_dynamic_simulation import ThermalDemandDynamicSimulation as Templates from helpers.simulation_parameters import SimulationParameters as Sp -import helpers.constants as cte from imports.geometry_factory import GeometryFactory from imports.geometry.helpers.geometry_helper import GeometryHelper from city_model_structure.city import City @@ -25,15 +23,15 @@ full_path_gml = (example_path / 'tests' / 'tests_data' / name_gml).resolve() outputs_path = (example_path / 'tests' / 'tests_outputs').resolve() tmp_path = (example_path / 'tests' / 'tmp').resolve() weather_path = (Path(__file__).parent.parent / 'libs' / 'data' / 'weather').resolve() -keep_sra_file = False +keep_sra_file = True keep_insel_file = False keep_weather_file = False keep_ig_file = False -pickle_geometry = True -pickle_weather = True -pickle_construction = True -pickle_usage = True -pickle_schedules = True +pickle_geometry = False +pickle_weather = False +pickle_construction = False +pickle_usage = False +pickle_schedules = False pickle_file = 'tests/tests_data/one_building_in_kelowna.pickle' # Load geometry @@ -65,7 +63,7 @@ if not pickle_weather: for building in city.buildings: new_city = city.region(building.centroid, radius) sra = SimplifiedRadiosityAlgorithm(new_city, path, weather_file_name) - sra.call_sra(weather_format, keep_files=keep_sra_file) + sra.call_sra(weather_format, keep_files=keep_sra_file, selected_buildings=[building]) sra.set_irradiance_surfaces(city, mode=1, building_name=building.name) else: sra = SimplifiedRadiosityAlgorithm(city, path, weather_file_name)