Merge branch 'bug_in_idf_exporter_wwr' into 'master'
Bug in idf exporter wwr See merge request Guille/hub!43
This commit is contained in:
commit
2dbaaefd74
|
@ -30,6 +30,7 @@ from helpers.location import Location
|
|||
from city_model_structure.energy_system import EnergySystem
|
||||
from city_model_structure.lca_material import LcaMaterial
|
||||
|
||||
|
||||
class City:
|
||||
"""
|
||||
City class
|
||||
|
@ -82,8 +83,6 @@ class City:
|
|||
if self._location is None:
|
||||
gps = pyproj.CRS('EPSG:4326') # LatLon with WGS84 datum used by GPS units and Google Earth
|
||||
try:
|
||||
if self._srs_name in GeometryHelper.srs_transformations.keys():
|
||||
self._srs_name = GeometryHelper.srs_transformations[self._srs_name]
|
||||
input_reference = pyproj.CRS(self.srs_name) # Projected coordinate system from input data
|
||||
except pyproj.exceptions.CRSError:
|
||||
sys.stderr.write('Invalid projection reference system, please check the input data. '
|
||||
|
@ -108,9 +107,7 @@ class City:
|
|||
Get city name
|
||||
:return: str
|
||||
"""
|
||||
if self._name is None:
|
||||
return self._get_location().city
|
||||
return self._name
|
||||
return self._get_location().city
|
||||
|
||||
@property
|
||||
def climate_reference_city(self) -> Union[None, str]:
|
||||
|
@ -455,5 +452,5 @@ class City:
|
|||
return _merge_city
|
||||
|
||||
@property
|
||||
def level_of_detail(self) -> LevelOfDetail:
|
||||
def level_of_detail(self):
|
||||
return self._level_of_detail
|
||||
|
|
|
@ -5,6 +5,7 @@ Copyright © 2022 Concordia CERC group
|
|||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
|
||||
class LevelOfDetail:
|
||||
"""
|
||||
Level of detail for the city class
|
||||
|
@ -17,41 +18,44 @@ class LevelOfDetail:
|
|||
@property
|
||||
def geometry(self):
|
||||
"""
|
||||
Get the city minimal geometry level of detail
|
||||
Get the city minimal geometry level of detail from 0 to 4
|
||||
:return: int
|
||||
"""
|
||||
return self._geometry
|
||||
|
||||
@geometry.setter
|
||||
def geometry(self, value):
|
||||
"""
|
||||
Set the city minimal geometry level of detail
|
||||
Set the city minimal geometry level of detail from 0 to 4
|
||||
"""
|
||||
self._geometry = value
|
||||
|
||||
@property
|
||||
def construction(self):
|
||||
"""
|
||||
Get the city minimal construction level of detail
|
||||
Get the city minimal construction level of detail, 1 or 2
|
||||
:return: int
|
||||
"""
|
||||
return self._construction
|
||||
|
||||
@construction.setter
|
||||
def construction(self, value):
|
||||
"""
|
||||
Set the city minimal construction level of detail
|
||||
Set the city minimal construction level of detail, 1 or 2
|
||||
"""
|
||||
self._construction = value
|
||||
|
||||
@property
|
||||
def usage(self):
|
||||
"""
|
||||
Get the city minimal usage level of detail
|
||||
Get the city minimal usage level of detail, 1 or 2
|
||||
:return: int
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@usage.setter
|
||||
def usage(self, value):
|
||||
"""
|
||||
Set the city minimal usage level of detail
|
||||
Set the city minimal usage level of detail, 1 or 2
|
||||
"""
|
||||
self._usage = value
|
||||
|
|
|
@ -7,7 +7,6 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
|
|||
Soroush Samareh Abolhassani soroush.samarehabolhassani@mail.concordia.ca
|
||||
"""
|
||||
import copy
|
||||
import math
|
||||
from pathlib import Path
|
||||
from geomeppy import IDF
|
||||
import helpers.constants as cte
|
||||
|
@ -57,10 +56,6 @@ class Idf:
|
|||
cte.GROUND: 'floor',
|
||||
cte.ROOF: 'roof'
|
||||
}
|
||||
idf_usage = {
|
||||
# todo: make an enum for all the usage types
|
||||
cte.RESIDENTIAL: 'residential_building'
|
||||
}
|
||||
idf_type_limits = {
|
||||
cte.ON_OFF: 'on/off',
|
||||
cte.FRACTION: 'Fraction',
|
||||
|
@ -80,20 +75,6 @@ class Idf:
|
|||
cte.WINTER_DESIGN_DAY: 'WinterDesignDay',
|
||||
cte.SUMMER_DESIGN_DAY: 'SummerDesignDay'
|
||||
}
|
||||
idf_schedule_types = {
|
||||
'compact': 'Compact',
|
||||
cte.DAY: 'Day',
|
||||
cte.WEEK: 'Week',
|
||||
cte.YEAR: 'Year',
|
||||
'file': 'File'
|
||||
}
|
||||
idf_schedule_data_type = {
|
||||
'compact': 'Compact',
|
||||
'hourly': 'Hourly',
|
||||
'daily': 'Daily',
|
||||
'interval': 'Interval',
|
||||
'list': 'List',
|
||||
}
|
||||
|
||||
def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, export_type="Surfaces",
|
||||
target_buildings=None, adjacent_buildings=None):
|
||||
|
@ -395,6 +376,7 @@ class Idf:
|
|||
self._remove_location()
|
||||
self._remove_sizing_periods()
|
||||
self._rename_building(self._city.name)
|
||||
self._lod = self._city.level_of_detail.geometry
|
||||
for building in self._city.buildings:
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
|
@ -518,19 +500,22 @@ class Idf:
|
|||
self._city.lower_corner)
|
||||
|
||||
surface.setcoords(coordinates)
|
||||
self._add_windows(boundary)
|
||||
|
||||
def _add_windows(self, boundary):
|
||||
for opening in boundary.thermal_openings:
|
||||
for construction in self._idf.idfobjects[self._CONSTRUCTION]:
|
||||
if construction['Outside_Layer'].split('_')[0] == 'glazing':
|
||||
window_construction = construction
|
||||
if self._compare_window_constructions(window_construction, opening):
|
||||
opening_name = 'window_' + str(len(self._idf.idfobjects[self._WINDOW]) + 1)
|
||||
opening_length = math.sqrt(opening.area)
|
||||
self._idf.newidfobject(self._WINDOW, Name=f'{opening_name}', Construction_Name=window_construction['Name'],
|
||||
Building_Surface_Name=boundary.parent_surface.name, Multiplier='1',
|
||||
Length=opening_length, Height=opening_length)
|
||||
if self._lod >= 3:
|
||||
for internal_zone in building.internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
for boundary in thermal_zone.thermal_boundaries:
|
||||
self._add_windows_by_vertices(boundary)
|
||||
else:
|
||||
# idf only allows setting wwr for external walls
|
||||
wwr = 0
|
||||
for surface in building.surfaces:
|
||||
if surface.type == cte.WALL:
|
||||
wwr = surface.associated_thermal_boundaries[0].window_ratio
|
||||
self._idf.set_wwr(wwr, construction='glazing_1')
|
||||
|
||||
def _add_windows_by_vertices(self, boundary):
|
||||
raise NotImplementedError
|
||||
|
||||
def _compare_window_constructions(self, window_construction, opening):
|
||||
glazing = window_construction['Outside_Layer']
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
"""
|
||||
Building test
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez Morote Guillermo.GutierrezMorote@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
|
||||
|
||||
|
||||
class TestBuildings(TestCase):
|
||||
"""
|
||||
TestBuilding TestCase 1
|
||||
"""
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Test setup
|
||||
:return: None
|
||||
"""
|
||||
self._city_gml = None
|
||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||
|
||||
def test_doe_idf(self):
|
||||
city_file = "../unittests/tests_data/one_building_in_kelowna.gml"
|
||||
output_path = Path('../unittests/tests_outputs/').resolve()
|
||||
city = GeometryFactory('citygml', path=city_file).city
|
||||
for building in city.buildings:
|
||||
building.year_of_construction = 2006
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
UsageFactory('comnet', city).enrich()
|
||||
EnergyBuildingsExportsFactory('idf', city, output_path).export()
|
||||
|
||||
self.assertEqual(1, len(city.buildings))
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertTrue(len(internal_zone.usage_zones) > 0)
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self.assertIsNot(len(usage_zone.occupancy.occupancy_schedules), 0, 'no occupancy schedules defined')
|
||||
for schedule in usage_zone.occupancy.occupancy_schedules:
|
||||
self.assertIsNotNone(schedule.type)
|
||||
self.assertIsNotNone(schedule.values)
|
||||
self.assertIsNotNone(schedule.data_type)
|
||||
self.assertIsNotNone(schedule.time_step)
|
||||
self.assertIsNotNone(schedule.time_range)
|
||||
self.assertIsNotNone(schedule.day_types)
|
||||
self.assertIsNot(len(usage_zone.lighting.schedules), 0, 'no lighting schedules defined')
|
||||
for schedule in usage_zone.lighting.schedules:
|
||||
self.assertIsNotNone(schedule.type)
|
||||
self.assertIsNotNone(schedule.values)
|
||||
self.assertIsNotNone(schedule.data_type)
|
||||
self.assertIsNotNone(schedule.time_step)
|
||||
self.assertIsNotNone(schedule.time_range)
|
||||
self.assertIsNotNone(schedule.day_types)
|
|
@ -14,6 +14,7 @@ from imports.geometry.helpers.geometry_helper import GeometryHelper
|
|||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from exports.exports_factory import ExportsFactory
|
||||
from exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
|
||||
import helpers.constants as cte
|
||||
from city_model_structure.city import City
|
||||
|
||||
|
@ -102,8 +103,9 @@ class TestExports(TestCase):
|
|||
ConstructionFactory('nrel', city).enrich()
|
||||
UsageFactory('comnet', city).enrich()
|
||||
try:
|
||||
ExportsFactory('idf', city, self._output_path).export()
|
||||
ExportsFactory('idf', city, self._output_path, target_buildings=['gml_1066158', 'gml_1066159']).export()
|
||||
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
||||
EnergyBuildingsExportsFactory('idf', city, self._output_path,
|
||||
target_buildings=['gml_1066158', 'gml_1066159']).export()
|
||||
except Exception:
|
||||
self.fail("Idf ExportsFactory raised ExceptionType unexpectedly!")
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user