From 7ffe395aa9194ffdfad4570297558f86b6f25a77 Mon Sep 17 00:00:00 2001 From: Guille Date: Thu, 5 Nov 2020 11:11:43 -0500 Subject: [PATCH] Add atributes for constructions materials and layers --- city_model_structure/attributes/material.py | 18 + .../attributes/thermal_boundary.py | 13 + .../us_base_physics_parameters.py | 6 +- .../usage_feeders/us_base_usage_parameters.py | 1 - helpers/idf_helper.py | 26 +- tests/test_idf.py | 22 +- tests/test_physics_factory.py | 1 + tests_data/us_archetypes.xml | 808 ------------------ tests_data/us_constructions.xml | 606 ------------- 9 files changed, 67 insertions(+), 1434 deletions(-) delete mode 100644 tests_data/us_archetypes.xml delete mode 100644 tests_data/us_constructions.xml diff --git a/city_model_structure/attributes/material.py b/city_model_structure/attributes/material.py index ddb23ba9..24b79271 100644 --- a/city_model_structure/attributes/material.py +++ b/city_model_structure/attributes/material.py @@ -10,6 +10,7 @@ class Material: Material class """ def __init__(self): + self._name = None self._conductivity = None self._specific_heat = None self._density = None @@ -19,6 +20,23 @@ class Material: self._no_mass = False self._thermal_resistance = None + @property + def name(self): + """ + Get material conductivity in W/mK + :return: float + """ + return self._name + + @name.setter + def name(self, value): + """ + Set material conductivity in W/mK + :param value: float + :return: None + """ + self._name = value + @property def conductivity(self): """ diff --git a/city_model_structure/attributes/thermal_boundary.py b/city_model_structure/attributes/thermal_boundary.py index 1d7d5dc8..08bb0c83 100644 --- a/city_model_structure/attributes/thermal_boundary.py +++ b/city_model_structure/attributes/thermal_boundary.py @@ -28,6 +28,7 @@ class ThermalBoundary: self._u_value = None self._window_area = None self._shortwave_reflectance = 1 - self._outside_solar_absorptance + self._construction_name = None @property def delimits(self) -> List[ThermalZone]: @@ -146,6 +147,18 @@ class ThermalBoundary: """ self._thermal_openings = value + @property + def construction_name(self): + """ + Get construction name + :return: + """ + return self._construction_name + + @construction_name.setter + def construction_name(self, value): + self._construction_name = value + @property def layers(self) -> List[Layer]: """ diff --git a/factories/physics_feeders/us_base_physics_parameters.py b/factories/physics_feeders/us_base_physics_parameters.py index c3fb461a..066429f3 100644 --- a/factories/physics_feeders/us_base_physics_parameters.py +++ b/factories/physics_feeders/us_base_physics_parameters.py @@ -20,13 +20,11 @@ class UsBasePhysicsParameters: self._buildings = buildings # load US Library path = str(base_path / 'us_constructions.xml') - print('physics construction:', path) with open(path) as xml: self._library = xmltodict.parse(xml.read(), force_list='layer') # load US Archetypes path = str(base_path / 'us_archetypes.xml') - print('physics archetypes:', path) with open(path) as xml: self._archetypes = xmltodict.parse(xml.read(), force_list='layer') for building in self._buildings: @@ -58,12 +56,15 @@ class UsBasePhysicsParameters: construction_type = UsToLibraryTypes.construction_types[thermal_boundary.type] construction = UsBasePhysicsParameters._search_construction_in_archetype(archetype, construction_type) construction_id = construction['@id'] + print(construction) + c_lib = self._search_construction_type('construction', construction_id) if 'outside_solar_absorptance' in c_lib: thermal_boundary.outside_solar_absorptance = c_lib['outside_solar_absorptance']['#text'] thermal_boundary.outside_thermal_absorptance = c_lib['outside_thermal_absorptance']['#text'] thermal_boundary.outside_visible_absorptance = c_lib['outside_visible_absorptance']['#text'] thermal_boundary.window_ratio = construction['window_ratio']['#text'] + thermal_boundary.construction_name = "todo" thermal_boundary.layers = [] for current_layer in c_lib['layers']['layer']: layer = Layer() @@ -79,6 +80,7 @@ class UsBasePhysicsParameters: material.thermal_absorptance = material_lib['thermal_absorptance']['#text'] material.visible_absorptance = material_lib['visible_absorptance']['#text'] material.no_mass = 'no_mass' in material_lib + material.name = material_lib['@name'] if 'thermal_resistance' in material_lib: material.thermal_resistance = material_lib['thermal_resistance']['#text'] layer.material = material diff --git a/factories/usage_feeders/us_base_usage_parameters.py b/factories/usage_feeders/us_base_usage_parameters.py index 4c87a5e9..31a960a7 100644 --- a/factories/usage_feeders/us_base_usage_parameters.py +++ b/factories/usage_feeders/us_base_usage_parameters.py @@ -20,7 +20,6 @@ class UsBaseUsageParameters: # todo: control not archetype found # ToDo: this is using the german library as a temporary approach, need to use/define a library for US path = str(Path(__file__).parent.parent.parent / 'data/usage/de_library.xml') - print('usage:', path) with open(path) as xml: self._library = xmltodict.parse(xml.read(), force_list='zoneUsageVariant') for city_object in self._city.buildings: diff --git a/helpers/idf_helper.py b/helpers/idf_helper.py index 16cbe3e9..00ad664d 100644 --- a/helpers/idf_helper.py +++ b/helpers/idf_helper.py @@ -67,20 +67,21 @@ class IdfHelper: self._idf.intersect_match() def add_surfaces(self, building): - self.add_block(building) - for zone in self._idf.idfobjects['ZONE']: - if zone.Name.find(building.name) != -1: - for surface in building.surfaces: - idf_surface = self.idf_surfaces[surface.type] - wall = self._idf.newidfobject(self._SURFACE, Name=surface.name, Surface_Type=idf_surface, Zone_Name=zone.Name) - coordinates = IdfHelper._matrix_to_list(surface.points) - if surface.area <= 0: - print(surface.area) - wall.setcoords(coordinates) - + index = 0 + for zone in building.thermal_zones: + zone_name = f'Building {building.name} usage zone {index}' + self._idf.newidfobject('ZONE', Name=zone_name) + for surface in zone.surfaces: + idf_surface = self.idf_surfaces[surface.type] + wall = self._idf.newidfobject(self._SURFACE, Name=f'{building.name}-{surface.name}', Surface_Type=idf_surface, + Zone_Name=zone_name) + coordinates = IdfHelper._matrix_to_list(surface.points) + wall.setcoords(coordinates) + index += 1 + self.add_heating_system(building) + self._idf.intersect_match() def run(self, output_directory, window_ratio=0.35, display_render=False, output_prefix=None, keep_file=None): - self._idf.set_default_constructions() self._idf.set_wwr(window_ratio, construction="Project External Window") self._idf.translate_to_origin() @@ -112,4 +113,3 @@ class IdfHelper: heating = [(float(x)) / 3600000.0 for x in list_values[0]] cooling = [(float(x)) / 3600000.0 for x in list_values[1]] return heating, cooling - diff --git a/tests/test_idf.py b/tests/test_idf.py index 8b064d71..cd3a041d 100644 --- a/tests/test_idf.py +++ b/tests/test_idf.py @@ -9,6 +9,8 @@ from factories.geometry_factory import GeometryFactory from factories.physics_factory import PhysicsFactory from factories.usage_factory import UsageFactory from helpers.idf_helper import IdfHelper +import os +import glob class TestIdf(TestCase): @@ -27,7 +29,7 @@ class TestIdf(TestCase): def _get_city(self): if self._city_gml is None: - file_path = (self._example_path / '20buildings.gml').resolve() + file_path = (self._example_path / 'buildings.gml').resolve() self._city_gml = GeometryFactory('citygml', file_path).city PhysicsFactory('us_new_york', self._city_gml) UsageFactory('us_new_york', self._city_gml) @@ -37,17 +39,25 @@ class TestIdf(TestCase): idd_file_path = (self._example_path / 'energy+.idd').resolve() idf_file_path = (self._example_path / 'minimal.idf').resolve() epw_file_path = (self._example_path / 'montreal.epw').resolve() - _idf = IdfHelper(idf_file_path, idd_file_path, epw_file_path) city = self._get_city() for building in city.buildings: _idf.add_block(building) + for thermal_zone in building.thermal_zones: + for bound in thermal_zone.bounded: + for layer in bound.layers: + print(layer.thickness) + print(layer.material.density) + test_prefix = 'test_idf_blocks' _idf.run(self._output_path, output_prefix=test_prefix, keep_file=self._output_path, display_render=True) eso_file_path = (self._output_path / f'{test_prefix}out.eso') heating, cooling = _idf.read_eso(str(eso_file_path)) self.assertEqual(len(heating), len(cooling), "Cooling and Heating doesn't contains the same amount of values") - # todo: clean up the files + self.assertNotEqual(len(heating), 0, "Cooling and Heating series are empty") + file_list = glob.glob(Path(self._output_path / '*').resolve()) + for file_path in file_list: + os.remove(file_path) def test_idf_surfaces(self): idd_file_path = (self._example_path / 'energy+.idd').resolve() @@ -58,9 +68,13 @@ class TestIdf(TestCase): city = self._get_city() for building in city.buildings: _idf.add_surfaces(building) + break test_prefix = 'test_idf_blocks' _idf.run(self._output_path, output_prefix=test_prefix, keep_file=self._output_path) eso_file_path = (self._output_path / f'{test_prefix}out.eso') heating, cooling = _idf.read_eso(str(eso_file_path)) self.assertEqual(len(heating), len(cooling), "Cooling and Heating doesn't contains the same amount of values") - # todo: clean up the files + self.assertNotEqual(len(heating), 0, "Cooling and Heating series are empty") + file_list = glob.glob(str(Path(self._output_path / '*').resolve())) + for file_path in file_list: + os.remove(file_path) diff --git a/tests/test_physics_factory.py b/tests/test_physics_factory.py index 5654c957..922eed11 100644 --- a/tests/test_physics_factory.py +++ b/tests/test_physics_factory.py @@ -57,3 +57,4 @@ class TestPhysicsFactory(TestCase): self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none') self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none') self.assertIsNotNone(thermal_boundary.layers, 'layers is none') + print(thermal_boundary.construction_name) diff --git a/tests_data/us_archetypes.xml b/tests_data/us_archetypes.xml deleted file mode 100644 index c928bf16..00000000 --- a/tests_data/us_archetypes.xml +++ /dev/null @@ -1,808 +0,0 @@ - - - - - - 0.21 - 4 - - - 0 - - - - 0 - - - - 3.05 - 2 - 130 - 0.15 - 0.15 - 0.5 - 0 - - - - - 0.33 - 4 - - - 0 - - - - 0 - - - - 3.34 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.38 - 4 - - - 0 - - - - 0 - - - - 3.34 - 3 - 130 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.35 - 4 - - - 0 - - - - 0.0019 - 2 - - - 3.96 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.33 - 4 - - - 0 - - - - 0.0068 - 2 - - - 3.96 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.07 - 4 - - - 0 - - - - 0.0064 - 2 - - - 6.1 - 3 - 130 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.11 - 4 - - - 0 - - - - 0 - - - - 5.18 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.11 - 4 - - - 0 - - - - 0 - - - - 6.1 - 1 - 130 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.14 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.17 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.11 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.3 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 130 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.15 - 4 - - - 0 - - - - 0 - - - - 4.27 - 3 - 130 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.2 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.006 - 4 - - - 0 - - - - .0032 - 2 - - - 8.53 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.15 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.3 - 4 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.15 - 0.15 - 0.50 - 0 - - - - - 0.21 - 3 - - - 0 - - - - 0 - - - - 3.05 - 2 - 130 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.33 - 3 - - - 0 - - - - 0 - - - - 3.34 - 3 - 90 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.38 - 3 - - - 0 - - - - 0 - - - - 3.34 - 3 - 130 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.35 - 3 - - - 0 - - - - 0.0019 - 1 - - - 3.96 - 3 - 90 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.33 - 3 - - - 0 - - - - 0.0068 - 1 - - - 3.96 - 3 - 90 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.07 - 3 - - - 0 - - - - 0.0064 - 1 - - - 6.1 - 3 - 130 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.11 - 3 - - - 0 - - - - 0 - - - - 5.18 - 3 - 90 - 0.05 - 0.15 - 0.1 - 0 - - - - - 0.11 - 3 - - - 0 - - - - 0 - - - - 6.1 - 1 - 130 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.14 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.17 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.11 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.3 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 130 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.15 - 3 - - - 0 - - - - 0 - - - - 4.27 - 3 - 130 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.2 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.006 - 3 - - - 0 - - - - .0032 - 1 - - - 8.53 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.15 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.3 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - - - - 0.3 - 3 - - - 0 - - - - 0 - - - - 3.05 - 3 - 90 - 0.05 - 0.15 - 0.10 - 0 - - diff --git a/tests_data/us_constructions.xml b/tests_data/us_constructions.xml deleted file mode 100644 index c18ec613..00000000 --- a/tests_data/us_constructions.xml +++ /dev/null @@ -1,606 +0,0 @@ - - - - - 0.32 - 0 - 0.003 - 0.301483 - 0.648517 - 0.648517 - 0.0133144 - - - 0.49 - 0 - 0.003 - 0.481761 - 0.468239 - 0.468239 - 0.03026 - - - 0.35 - 0 - 0.003 - 0.328881 - 0.621119 - 0.621119 - 0.0071399 - - - 0.36 - 0 - 0.003 - 0.354957 - 0.595043 - 0.595043 - 0.0134755 - - - - - 1.311 - 2240 - 836.8 - 0.9 - 0.7 - 0.7 - - - true - 0.21648 - 0.9 - 0.7 - 0.8 - - - 0.045 - 265 - 836.8 - 0.9 - 0.7 - 0.7 - - - 0.6918 - 1858 - 837 - 0.9 - 0.92 - 0.92 - - - 1.7296 - 2243 - 837 - 0.9 - 0.65 - 0.65 - - - 0.0432 - 91 - 837 - 0.9 - 0.5 - 0.5 - - - 0.16 - 784.9 - 830 - 0.9 - 0.92 - 0.92 - - - 0.11 - 544.62 - 1210 - 0.9 - 0.78 - 0.78 - - - 0.115 - 513 - 1255 - 0.9 - 0.78 - 0.78 - - - 0.1211 - 593 - 2510 - 0.9 - 0.78 - 0.78 - - - 0.049 - 265 - 836.8 - 0.9 - 0.7 - 0.7 - - - true - 0.36256 - 0.9 - 0.7 - 0.7 - - - true - 0.36256 - 0.9 - 0.7 - 0.7 - - - 45.006 - 7680 - 418.4 - 0.9 - 0.7 - 0.3 - - - 0.16 - 1121.29 - 1460 - 0.9 - 0.7 - 0.7 - - - true - 0.21648 - 0.9 - 0.7 - 0.8 - - - true - 0.36256 - 0.9 - 0.7 - 0.7 - - - true - 0.21648 - 0.9 - 0.7 - 0.8 - - - true - 0.36256 - 0.9 - 0.7 - 0.7 - - - true - 0.21648 - 0.9 - 0.7 - 0.8 - - - 0.045 - 265 - 836.8 - 0.9 - 0.7 - 0.7 - - - 44.96 - 7688.86 - 410 - 0.9 - 0.2 - 0.2 - - - - - - - - 3 - 0.0795397 - - - 1 - 0.20321 - - - 2 - - - - - 0.92 - 0.9 - 0.92 - - - 4 - 0.0253 - - - 5 - 0.2033 - - - 6 - 0.0680962 - - - 7 - 0.01271 - - - - - 0.92 - 0.9 - 0.92 - - - 8 - 0.01 - - - 3 - 0.0746874 - - - 7 - 0.01271 - - - - - 0.78 - 0.9 - 0.78 - - - 9 - 0.0178 - - - 10 - 0.0254 - - - 11 - 0.375211 - - - 7 - 0.01271 - - - - - 0.78 - 0.9 - 0.78 - - - 9 - 0.0178 - - - 10 - 0.0254 - - - 11 - 0.221604 - - - 7 - 0.01271 - - - - - 0.92 - 0.9 - 0.92 - - - 12 - - - 3 - 0.118387 - - - 7 - 0.01271 - - - - - - - 1 - 0.20321 - - - - - 0.92 - 0.9 - 0.92 - - - 13 - - - 3 - 0.0373223 - - - 7 - 0.01271 - - - - - 0.7 - 0.9 - 0.7 - - - 15 - 0.0095 - - - 11 - 0.210538 - - - 14 - 0.001524 - - - - - - - 1 - 0.1016 - - - - - 0.7 - 0.9 - 0.3 - - - 14 - 0.001524 - - - 11 - 0.23578 - - - - - - - 1 - 0.1016 - - - 16 - - - - - 0.92 - 0.9 - 0.92 - - - 4 - 0.0253 - - - 5 - 0.2033 - - - 6 - 0.0338606 - - - 7 - 0.01271 - - - - - 0.7 - 0.9 - 0.3 - - - 14 - 0.001524 - - - 11 - 0.123533 - - - - - 0.92 - 0.9 - 0.92 - - - 17 - - - 3 - 0.118387 - - - 7 - 0.01271 - - - - - 0.92 - 0.9 - 0.92 - - - 8 - 0.01 - - - 3 - 0.110422 - - - 7 - 0.01271 - - - - - 0.7 - 0.9 - 0.7 - - - 15 - 0.0095 - - - 11 - 0.124958 - - - 14 - 0.001524 - - - - - - - 3 - 0.0463846 - - - 1 - 0.20321 - - - 18 - - - - - 0.92 - 0.9 - 0.92 - - - 19 - - - 3 - 0.0971136 - - - 7 - 0.01271 - - - - - - - 1 - 0.20321 - - - - - - - 1 - 0.1016 - - - - - - - 1 - 0.1016 - - - 20 - - - - - 0.92 - 0.9 - 0.92 - - - 22 - 0.0015 - - - 21 - 0.139618 - - - 7 - 0.01271 - - - - - 0.92 - 0.9 - 0.92 - - - 22 - 0.0015 - - - 21 - 0.0598725 - - - 7 - 0.01271 - - - - - \ No newline at end of file