From 04e029d4a043e41b876b1314d69618db721b9a9d Mon Sep 17 00:00:00 2001 From: s_ranjbar Date: Wed, 15 May 2024 09:20:10 -0400 Subject: [PATCH] feat: SRA finalized The "beam" attribute in "CityObject" class is renamed to "direct_normal" and new attribute named "beam" is created. SRA inputs are fixed --- hub/city_model_structure/city_object.py | 34 ++++++++++++++----- .../formats/simplified_radiosity_algorithm.py | 2 +- hub/imports/weather/epw_weather_parameters.py | 6 ++-- main.py | 14 +++++--- tests/test_construction_factory.py | 2 +- tests/test_geometry_factory.py | 2 +- tests/test_usage_factory.py | 2 +- 7 files changed, 43 insertions(+), 19 deletions(-) diff --git a/hub/city_model_structure/city_object.py b/hub/city_model_structure/city_object.py index c18a4aa0..d0e6ed02 100644 --- a/hub/city_model_structure/city_object.py +++ b/hub/city_model_structure/city_object.py @@ -41,9 +41,11 @@ class CityObject: self._ground_temperature = {} self._global_horizontal = {} self._diffuse = {} - self._beam = {} + self._direct_normal = {} self._sensors = [] self._neighbours = None + self._beam = {} + @property def level_of_detail(self) -> LevelOfDetail: @@ -238,20 +240,20 @@ class CityObject: self._diffuse = value @property - def beam(self) -> dict: + def direct_normal(self) -> dict: """ - Get beam radiation surrounding the city object in J/m2 + Get direct normal radiation surrounding the city object in J/m2 :return: dict{dict{[float]}} """ - return self._beam + return self._direct_normal - @beam.setter - def beam(self, value): + @direct_normal.setter + def direct_normal(self, value): """ - Set beam radiation surrounding the city object in J/m2 + Set direct normal radiation surrounding the city object in J/m2 :param value: dict{dict{[float]}} """ - self._beam = value + self._direct_normal = value @property def lower_corner(self): @@ -302,3 +304,19 @@ class CityObject: Set the list of neighbour_objects and their properties associated to the current city_object """ self._neighbours = value + + @property + def beam(self) -> dict: + """ + Get beam radiation surrounding the city object in J/m2 + :return: dict{dict{[float]}} + """ + return self._beam + + @beam.setter + def beam(self, value): + """ + Set beam radiation surrounding the city object in J/m2 + :param value: dict{dict{[float]}} + """ + self._beam = value diff --git a/hub/exports/formats/simplified_radiosity_algorithm.py b/hub/exports/formats/simplified_radiosity_algorithm.py index f9ea7f1d..25189419 100644 --- a/hub/exports/formats/simplified_radiosity_algorithm.py +++ b/hub/exports/formats/simplified_radiosity_algorithm.py @@ -67,7 +67,7 @@ class SimplifiedRadiosityAlgorithm: i = (total_days + day - 1) * 24 + hour - 1 representative_building = self._city.buildings[0] _global = representative_building.diffuse[cte.HOUR][i] / cte.WATTS_HOUR_TO_JULES - _beam = representative_building.beam[cte.HOUR][i] / cte.WATTS_HOUR_TO_JULES + _beam = representative_building.direct_normal[cte.HOUR][i] / cte.WATTS_HOUR_TO_JULES content += f'{day} {month} {hour} {_global} {_beam}\n' with open(file, 'w', encoding='utf-8') as file: file.write(content) diff --git a/hub/imports/weather/epw_weather_parameters.py b/hub/imports/weather/epw_weather_parameters.py index c2ed2e8f..972bf860 100644 --- a/hub/imports/weather/epw_weather_parameters.py +++ b/hub/imports/weather/epw_weather_parameters.py @@ -114,8 +114,10 @@ class EpwWeatherParameters: for x in self._weather_values['global_horizontal_radiation_wh_m2']] building.diffuse[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES for x in self._weather_values['diffuse_horizontal_radiation_wh_m2']] - building.beam[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES - for x in self._weather_values['direct_normal_radiation_wh_m2']] + building.direct_normal[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES + for x in self._weather_values['direct_normal_radiation_wh_m2']] + building.beam[cte.HOUR] = [building.global_horizontal[cte.HOUR][i] - building.diffuse[cte.HOUR][i] + for i in range(len(building.global_horizontal[cte.HOUR]))] building.cold_water_temperature[cte.HOUR] = wh().cold_water_temperature(building.external_temperature[cte.HOUR]) # create the monthly and yearly values out of the hourly diff --git a/main.py b/main.py index 8172ce3c..1c21caf4 100644 --- a/main.py +++ b/main.py @@ -12,7 +12,7 @@ from hub.imports.results_factory import ResultFactory from hub.exports.exports_factory import ExportsFactory import hub.helpers.constants as cte # Specify the GeoJSON file path -geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001) +geojson_file = process_geojson(x=-73.58006429386116, y=45.49642202402885, diff=0.0001) file_path = (Path(__file__).parent.parent / 'input_files' / f'{geojson_file}') # Specify the output path for the PDF file output_path = (Path(__file__).parent / 'out_files').resolve() @@ -27,24 +27,28 @@ city = GeometryFactory('geojson', ConstructionFactory('nrcan', city).enrich() UsageFactory('nrcan', city).enrich() -# WeatherFactory('epw', city).enrich() +WeatherFactory('epw', city).enrich() +print('test') ExportsFactory('sra', city, output_path).export() sra_path = (output_path / f'{city.name}_sra.xml').resolve() subprocess.run(['sra', str(sra_path)]) ResultFactory('sra', city, output_path).enrich() +print('test') for building in city.buildings: + direct_normal = [x / 3600 for x in building.direct_normal[cte.HOUR]] beam = [x / 3600 for x in building.beam[cte.HOUR]] diffuse = [x / 3600 for x in building.diffuse[cte.HOUR]] + global_radiation = [x / 3600 for x in building.global_horizontal[cte.HOUR]] roof = building.roofs[0].global_irradiance[cte.HOUR] - data = list(zip(beam, diffuse, roof)) + data = list(zip(direct_normal, beam, diffuse, global_radiation, roof)) file_name = f'solar_radiation_{building.name}.csv' with open(output_path / file_name, 'w', newline='') as csvfile: output_file = csv.writer(csvfile) # Write header - output_file.writerow(['beam_component', 'diffuse_component', 'roof_global_irradiance']) + output_file.writerow(['direct_normal', 'beam_component', 'diffuse_component', 'global', 'roof_global_irradiance']) # Write data output_file.writerows(data) -print('test') + diff --git a/tests/test_construction_factory.py b/tests/test_construction_factory.py index 710894bd..a340594a 100644 --- a/tests/test_construction_factory.py +++ b/tests/test_construction_factory.py @@ -81,7 +81,7 @@ class TestConstructionFactory(TestCase): self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated') self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated') self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated') - self.assertEqual(len(building.beam), 0, 'building beam is calculated') + self.assertEqual(len(building.direct_normal), 0, 'building beam is calculated') self.assertIsNotNone(building.lower_corner, 'building lower corner is none') self.assertEqual(len(building.sensors), 0, 'building sensors are assigned') self.assertIsNotNone(building.internal_zones, 'no internal zones created') diff --git a/tests/test_geometry_factory.py b/tests/test_geometry_factory.py index 3b5bd8f8..d66c815f 100644 --- a/tests/test_geometry_factory.py +++ b/tests/test_geometry_factory.py @@ -52,7 +52,7 @@ class TestGeometryFactory(TestCase): self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated') self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated') self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated') - self.assertEqual(len(building.beam), 0, 'building beam is calculated') + self.assertEqual(len(building.direct_normal), 0, 'building beam is calculated') self.assertIsNotNone(building.lower_corner, 'building lower corner is none') self.assertEqual(len(building.sensors), 0, 'building sensors are assigned') self.assertIsNotNone(building.internal_zones, 'no internal zones created') diff --git a/tests/test_usage_factory.py b/tests/test_usage_factory.py index 6b6d821a..49cb45db 100644 --- a/tests/test_usage_factory.py +++ b/tests/test_usage_factory.py @@ -44,7 +44,7 @@ class TestUsageFactory(TestCase): self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated') self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated') self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated') - self.assertEqual(len(building.beam), 0, 'building beam is calculated') + self.assertEqual(len(building.direct_normal), 0, 'building beam is calculated') self.assertIsNotNone(building.lower_corner, 'building lower corner is none') self.assertEqual(len(building.sensors), 0, 'building sensors are assigned') self.assertIsNotNone(building.internal_zones, 'no internal zones created')