Merge remote-tracking branch 'origin/master' into geojson

# Conflicts:
#	unittests/test_doe_idf.py
#	unittests/test_geometry_factory.py
This commit is contained in:
Guille Gutierrez 2022-11-25 12:49:39 -05:00
commit 629d73662b
14 changed files with 9286 additions and 76 deletions

View File

@ -51,7 +51,6 @@ class Idf:
_LOCATION = 'SITE:LOCATION'
_SIMPLE = 'Simple'
idf_surfaces = {
# todo: make an enum for all the surface types
cte.WALL: 'wall',

View File

@ -0,0 +1,184 @@
import numpy as np
from pathlib import Path
from exports.formats.insel import Insel
from imports.weather.helpers.weather import Weather
import helpers.constants as cte
_CONSTRUCTION_CODE = {
cte.WALL: '1',
cte.GROUND: '2',
cte.ROOF: '3',
cte.INTERIOR_WALL: '5',
cte.GROUND_WALL: '6',
cte.ATTIC_FLOOR: '7',
cte.INTERIOR_SLAB: '8'
}
class InselMonthlyEnergyBalance(Insel):
def __init__(self, city, path, radiation_calculation_method='sra', weather_format='epw'):
super().__init__(city, path)
self._radiation_calculation_method = radiation_calculation_method
self._weather_format = weather_format
self._contents = []
self._insel_files_paths = []
for building in city.buildings:
self._insel_files_paths.append(building.name + '.insel')
file_name_out = building.name + '.out'
output_path = Path(self._path / file_name_out).resolve()
self._contents.append(self.generate_meb_template(building, output_path, self._radiation_calculation_method,
self._weather_format))
self._export()
def _export(self):
for i_file, content in enumerate(self._contents):
file_name = self._insel_files_paths[i_file]
with open(Path(self._path / file_name).resolve(), 'w') as insel_file:
insel_file.write(content)
return
@staticmethod
def generate_meb_template(building, insel_outputs_path, radiation_calculation_method, weather_format):
file = ""
i_block = 1
parameters = ["1", "12", "1"]
file = Insel._add_block(file, i_block, 'DO', parameters=parameters)
i_block = 4
inputs = ["1.1", "20.1", "21.1"]
surfaces = building.surfaces
for i in range(1, len(surfaces) + 1):
inputs.append(f"{str(100 + i)}.1 % Radiation surface {str(i)}")
# BUILDING PARAMETERS
parameters = [f'{0.85 * building.volume} % BP(1) Heated Volume (vBrutto)',
f'{building.average_storey_height} % BP(2) Average storey height / m',
f'{building.storeys_above_ground} % BP(3) Number of storeys above ground',
f'{building.attic_heated} % BP(4) Attic heating type (0=no room, 1=unheated, 2=heated)',
f'{building.basement_heated} % BP(5) Cellar heating type (0=no room, 1=unheated, 2=heated, '
f'99=invalid)']
# todo: this method and the insel model have to be reviewed for more than one internal zone
internal_zone = building.internal_zones[0]
thermal_zone = internal_zone.thermal_zones[0]
parameters.append(f'{thermal_zone.indirectly_heated_area_ratio} % BP(6) Indirectly heated area ratio')
parameters.append(f'{thermal_zone.effective_thermal_capacity} % BP(7) Effective heat capacity')
parameters.append(f'{thermal_zone.additional_thermal_bridge_u_value * thermal_zone.total_floor_area} '
f'% BP(8) Additional U-value for heat bridge')
parameters.append('0 % BP(9) Usage type (0=standard, 1=IWU)')
# ZONES AND SURFACES
parameters.append(f'{len(internal_zone.usage_zones)} % BP(10) Number $z$ of zones')
for i, usage_zone in enumerate(internal_zone.usage_zones):
percentage_usage = usage_zone.percentage
parameters.append(f'{float(internal_zone.area) * percentage_usage} % BP(11) #1 Area of zone {i + 1} (sqm)')
total_internal_gain = 0
for ig in usage_zone.internal_gains:
total_internal_gain += float(ig.average_internal_gain) * \
(float(ig.convective_fraction) + float(ig.radiative_fraction))
parameters.append(f'{total_internal_gain} % BP(12) #2 Internal gains of zone {i + 1}')
parameters.append(f'{usage_zone.thermal_control.mean_heating_set_point} % BP(13) #3 Heating setpoint temperature '
f'zone {i + 1} (tSetHeat)')
parameters.append(f'{usage_zone.thermal_control.heating_set_back} % BP(14) #4 Heating setback temperature '
f'zone {i + 1} (tSetbackHeat)')
parameters.append(f'{usage_zone.thermal_control.mean_cooling_set_point} % BP(15) #5 Cooling setpoint temperature '
f'zone {i + 1} (tSetCool)')
parameters.append(f'{usage_zone.hours_day} % BP(16) #6 Usage hours per day zone {i + 1}')
parameters.append(f'{usage_zone.days_year} % BP(17) #7 Usage days per year zone {i + 1}')
parameters.append(f'{usage_zone.mechanical_air_change} % BP(18) #8 Minimum air change rate zone {i + 1} (h^-1)')
parameters.append(f'{len(thermal_zone.thermal_boundaries)} % Number of surfaces = BP(11+8z) \n'
f'% 1. Surface type (1=wall, 2=ground 3=roof, 4=flat roof)\n'
f'% 2. Areas above ground\n'
f'% 3. Areas below ground\n'
f'% 4. U-value\n'
f'% 5. Window area\n'
f'% 6. Window frame fraction\n'
f'% 7. Window U-value\n'
f'% 8. Window g-value\n'
f'% 9. Short-wave reflectance\n'
f'% #1 #2 #3 #4 #5 #6 #7 #8 #9\n')
for thermal_boundary in thermal_zone.thermal_boundaries:
type_code = _CONSTRUCTION_CODE[thermal_boundary.type]
window_area = thermal_boundary.opaque_area * thermal_boundary.window_ratio / (1 - thermal_boundary.window_ratio)
parameters.append(type_code)
parameters.append(0.85 * thermal_boundary.opaque_area)
parameters.append('0.0')
parameters.append(thermal_boundary.u_value)
parameters.append(0.85 * window_area)
if window_area <= 0.001:
parameters.append(0.0)
parameters.append(0.0)
parameters.append(0.0)
else:
thermal_opening = thermal_boundary.thermal_openings[0]
parameters.append(thermal_opening.frame_ratio)
parameters.append(thermal_opening.overall_u_value)
parameters.append(thermal_opening.g_value)
if thermal_boundary.type is not cte.GROUND:
parameters.append(thermal_boundary.parent_surface.short_wave_reflectance)
else:
parameters.append(0.0)
file = Insel._add_block(file, i_block, 'd18599', inputs=inputs, parameters=parameters)
i_block = 20
inputs = ['1']
parameters = ['12 % Monthly ambient temperature']
external_temperature = building.external_temperature[cte.MONTH]
for i in range(0, len(external_temperature)):
parameters.append(f'{i + 1} {external_temperature.at[i, weather_format]}')
file = Insel._add_block(file, i_block, 'polyg', inputs=inputs, parameters=parameters)
i_block = 21
inputs = ['1']
parameters = ['12 % Monthly sky temperature']
sky_temperature = Weather.sky_temperature(external_temperature[[weather_format]].to_numpy().T[0])
for i, temperature in enumerate(sky_temperature):
parameters.append(f'{i + 1} {temperature}')
file = Insel._add_block(file, i_block, 'polyg', inputs=inputs, parameters=parameters)
for i, surface in enumerate(surfaces):
i_block = 101 + i
inputs = ['1 % Monthly surface radiation (W/sqm)']
parameters = [f'12 % Azimuth {np.rad2deg(surface.azimuth)}, '
f'inclination {np.rad2deg(surface.inclination)} degrees']
if surface.type != 'Ground':
global_irradiance = surface.global_irradiance[cte.MONTH]
for j in range(0, len(global_irradiance)):
parameters.append(f'{j + 1} {global_irradiance.at[j, radiation_calculation_method]}')
else:
for j in range(0, 12):
parameters.append(f'{j + 1} 0.0')
file = Insel._add_block(file, i_block, 'polyg', inputs=inputs, parameters=parameters)
i_block = 300
inputs = ['4.1', '4.2']
file = Insel._add_block(file, i_block, 'cum', inputs=inputs)
i_block = 303
inputs = ['300.1', '300.2']
file = Insel._add_block(file, i_block, 'atend', inputs=inputs)
i_block = 310
inputs = ['4.1', '4.2']
parameters = ['1 % Mode',
'0 % Suppress FNQ inputs',
f"'{str(insel_outputs_path)}' % File name",
"'*' % Fortran format"]
file = Insel._add_block(file, i_block, 'WRITE', inputs=inputs, parameters=parameters)
return file

View File

@ -0,0 +1,74 @@
"""
EnergyBuildingsExportsFactory exports a city into several formats related to energy in buildings
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de uribarri pilar.monsalvete@concordia.ca
"""
from pathlib import Path
from exports.building_energy.energy_ade import EnergyAde
from exports.building_energy.idf import Idf
from exports.building_energy.insel.insel_monthly_energy_balance import InselMonthlyEnergyBalance
class EnergyBuildingsExportsFactory:
"""
Energy Buildings exports factory class
"""
def __init__(self, export_type, city, path, target_buildings=None, adjacent_buildings=None):
self._city = city
self._export_type = '_' + export_type.lower()
if isinstance(path, str):
path = Path(path)
self._path = path
self._target_buildings = target_buildings
self._adjacent_buildings = adjacent_buildings
@property
def _energy_ade(self):
"""
Export to citygml with application domain extensions
:return: None
"""
return EnergyAde(self._city, self._path)
@property
def _idf(self):
"""
Export the city to Energy+ idf format
When target_buildings is set, only those will be calculated and their energy consumption output, non adjacent
buildings will be considered shading objects and adjacent buildings will be considered adiabatic.
Adjacent buildings are provided they will be considered heated so energy plus calculations are more precise but
no results will be calculated to speed up the calculation process.
:return: None
"""
idf_data_path = (Path(__file__).parent / './building_energy/idf_files/').resolve()
# todo: create a get epw file function based on the city
weather_path = (Path(__file__).parent / '../data/weather/epw/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
target_buildings=self._target_buildings, adjacent_buildings=self._adjacent_buildings)
@property
def _insel_monthly_energy_balance(self):
"""
Export to Insel MonthlyEnergyBalance
:return: None
"""
return InselMonthlyEnergyBalance(self._city, self._path)
def export(self):
"""
Export the city given to the class using the given export type handler
:return: None
"""
return getattr(self, self._export_type, lambda: None)
def export_debug(self):
"""
Export the city given to the class using the given export type handler
:return: None
"""
return getattr(self, self._export_type)

View File

@ -6,8 +6,6 @@ Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from pathlib import Path
from exports.formats.energy_ade import EnergyAde
from exports.formats.idf import Idf
from exports.formats.obj import Obj
from exports.formats.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
from exports.formats.stl import Stl
@ -38,14 +36,6 @@ class ExportsFactory:
def _collada(self):
raise NotImplementedError
@property
def _energy_ade(self):
"""
Export to citygml with application domain extensions
:return: None
"""
return EnergyAde(self._city, self._path)
@property
def _stl(self):
"""
@ -70,25 +60,6 @@ class ExportsFactory:
"""
return Obj(self._city, self._path).to_ground_points()
@property
def _idf(self):
"""
Export the city to Energy+ idf format
When target_buildings is set, only those will be calculated and their energy consumption output, non adjacent
buildings will be considered shading objects and adjacent buildings will be considered adiabatic.
Adjacent buildings are provided they will be considered heated so energy plus calculations are more precise but
no results will be calculated to speed up the calculation process.
:return: None
"""
idf_data_path = (Path(__file__).parent / './formats/idf_files/').resolve()
# todo: create a get epw file function based on the city
weather_path = (Path(__file__).parent / '../data/weather/epw/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
target_buildings=self._target_buildings, adjacent_buildings=self._adjacent_buildings)
@property
def _sra(self):
"""

30
exports/formats/insel.py Normal file
View File

@ -0,0 +1,30 @@
"""
Insel export models to insel format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from abc import ABC
class Insel(ABC):
def __init__(self, city, path):
self._city = city
self._path = path
self._results = None
@staticmethod
def _add_block(file, block_number, block_type, inputs='', parameters=''):
file += "S " + str(block_number) + " " + block_type + "\n"
for block_input in inputs:
file += str(block_input) + "\n"
if len(parameters) > 0:
file += "P " + str(block_number) + "\n"
for block_parameter in parameters:
file += str(block_parameter) + "\n"
return file
def _export(self):
raise NotImplementedError

47
helpers/monthly_values.py Normal file
View File

@ -0,0 +1,47 @@
"""
Monthly values
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
"""
import pandas as pd
import numpy as np
import calendar as cal
class MonthlyValues:
def __init__(self):
self._month_hour = None
def get_mean_values(self, values):
out = None
if values is not None:
if 'month' not in values.columns:
values = pd.concat([self.month_hour, pd.DataFrame(values)], axis=1)
out = values.groupby('month', as_index=False).mean()
del out['month']
return out
def get_total_month(self, values):
out = None
if values is not None:
if 'month' not in values.columns:
values = pd.concat([self.month_hour, pd.DataFrame(values)], axis=1)
out = pd.DataFrame(values).groupby('month', as_index=False).sum()
del out['month']
return out
@property
def month_hour(self):
"""
returns a DataFrame that has x values of the month number (January = 1, February = 2...),
being x the number of hours of the corresponding month
:return: DataFrame(int)
"""
array = []
for i in range(0, 12):
days_of_month = cal.monthrange(2015, i+1)[1]
total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1)))
self._month_hour = pd.DataFrame(array, columns=['month'])
return self._month_hour

View File

@ -9,7 +9,7 @@ from unittest import TestCase
from imports.geometry_factory import GeometryFactory
from imports.usage_factory import UsageFactory
from imports.construction_factory import ConstructionFactory
from exports.exports_factory import ExportsFactory
from exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
class TestBuildings(TestCase):
@ -32,7 +32,8 @@ class TestBuildings(TestCase):
building.year_of_construction = 2006
ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich()
ExportsFactory('idf', city, output_path).export()
EnergyBuildingsExportsFactory('idf', city, output_path).export()
self.assertEqual(1, len(city.buildings))
for building in city.buildings:
for internal_zone in building.internal_zones:

View File

@ -9,9 +9,8 @@ from unittest import TestCase
from numpy import inf
import exports.exports_factory
from imports.construction_factory import ConstructionFactory
from imports.geometry_factory import GeometryFactory
from imports.construction_factory import ConstructionFactory
class TestGeometryFactory(TestCase):
@ -26,15 +25,29 @@ class TestGeometryFactory(TestCase):
"""
self._city = None
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
self._output_path = (Path(__file__).parent / 'tests_outputs').resolve()
def _get_city(self, file, file_type, height_field=None, year_of_construction_field=None, function_field=None):
def _get_citygml(self, file):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory(file_type,
path=file_path,
height_field=height_field,
year_of_construction_field=year_of_construction_field,
function_field=function_field).city
self._city = GeometryFactory('citygml', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
def _get_geojson(self, file):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('gpandas', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
def _get_obj(self, file):
# todo: solve the incongruities between city and city_debug
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('obj', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
def _get_rhino(self, file):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('rhino', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
@ -47,6 +60,7 @@ class TestGeometryFactory(TestCase):
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none')
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none')
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
self.assertIsNotNone(building.centroid, 'building centroid is none')
self.assertIsNotNone(building.max_height, 'building max_height is none')
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
@ -65,6 +79,8 @@ class TestGeometryFactory(TestCase):
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
self.assertIsNone(building.terrains, 'building terrains is not none')
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
self.assertIsNotNone(building.function, 'building function is none')
self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none')
self.assertIsNone(building.storeys_above_ground, 'building storeys_above_ground is not none')
self.assertEqual(len(building.heating), 0, 'building heating is not none')
@ -101,9 +117,8 @@ class TestGeometryFactory(TestCase):
Test city objects in the city
:return: None
"""
file = 'FZK_Haus_LoD_2.gml'
city = self._get_city(file, 'citygml', year_of_construction_field='yearOfConstruction')
print(city)
file = 'one_building_in_kelowna.gml'
city = self._get_citygml(file)
self.assertTrue(len(city.buildings) == 1)
self._check_buildings(city)
for building in city.buildings:
@ -111,12 +126,13 @@ class TestGeometryFactory(TestCase):
building.year_of_construction = 2006
city = ConstructionFactory('nrel', city).enrich()
# rhino
def test_import_rhino(self):
"""
Test rhino import
"""
file = 'dompark.3dm'
city = self._get_city(file, 'rhino')
city = self._get_rhino(file)
self.assertIsNotNone(city, 'city is none')
self.assertTrue(len(city.buildings) == 36)
i = 0
@ -124,12 +140,14 @@ class TestGeometryFactory(TestCase):
self.assertIsNot(building.volume, inf, 'open volume')
i += 1
# obj
def test_import_obj(self):
"""
Test obj import
"""
file = 'kelowna.obj'
city = self._get_city(file, 'obj')
city = self._get_obj(file)
self.assertIsNotNone(city, 'city is none')
self.assertTrue(len(city.buildings) == 1)
self._check_buildings(city)
for building in city.buildings:
@ -140,36 +158,12 @@ class TestGeometryFactory(TestCase):
Test geopandas import
"""
file = 'sample.geojson'
city = self._get_city(file, 'gpandas')
city = self._get_geojson(file)
self.assertIsNotNone(city, 'city is none')
self.assertTrue(len(city.buildings) == 1)
self._check_buildings(city)
for building in city.buildings:
self._check_surfaces(building)
self.assertEqual(1912.0898135701814, building.volume)
self.assertEqual(146.19493345171213, building.floor_area)
def test_import_geojson(self):
"""
Test geojson import
"""
file = 'concordia.geojson'
city = self._get_city(file, 'geojson',
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
function_field='LIBELLE_UT')
for building in city.buildings:
print(building.name, building.volume)
exports.exports_factory.ExportsFactory('obj', city, self._output_path).export_debug()
self.assertEqual(166, len(city.buildings), 'wrong number of buildings')
self._check_buildings(city)
def test_subway(self):
"""
Test subway parsing
:return:
"""
file = 'subway.osm'
city = self._get_city(file, 'osm_subway')
self.assertIsNotNone(city, 'subway entrances is none')
self.assertEqual(len(city.city_objects), 20, 'Wrong number of subway entrances')

View File

@ -11,7 +11,7 @@ from unittest import TestCase
from imports.geometry_factory import GeometryFactory
from imports.usage_factory import UsageFactory
from imports.construction_factory import ConstructionFactory
from exports.exports_factory import ExportsFactory
from exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
from city_model_structure.greenery.vegetation import Vegetation
from city_model_structure.greenery.soil import Soil
from city_model_structure.greenery.plant import Plant
@ -66,7 +66,7 @@ class GreeneryInIdf(TestCase):
if surface.type == cte.ROOF:
surface.vegetation = vegetation
_idf_2 = ExportsFactory('idf', city, output_path).export_debug()
_idf_2 = EnergyBuildingsExportsFactory('idf', city, output_path).export_debug()
_idf_2.run()
with open((output_path / f'{city.name}_out.csv').resolve()) as f:
reader = csv.reader(f, delimiter=',')
@ -85,7 +85,7 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006
ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich()
_idf = ExportsFactory('idf', city, output_path).export()
_idf = EnergyBuildingsExportsFactory('idf', city, output_path).export()
_idf.run()
with open((output_path / f'{city.name}_out.csv').resolve()) as f:
reader = csv.reader(f, delimiter=',')

View File

@ -0,0 +1,149 @@
"""
TestInselExports test
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from pathlib import Path
from unittest import TestCase
import pandas as pd
import helpers.constants as cte
from helpers.monthly_values import MonthlyValues
from imports.geometry_factory import GeometryFactory
from imports.construction_factory import ConstructionFactory
from imports.usage_factory import UsageFactory
from exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
from imports.weather_factory import WeatherFactory
class TestExports(TestCase):
"""
TestExports class contains the unittest for export functionality
"""
def setUp(self) -> None:
"""
Test setup
:return: None
"""
self._city = None
self._complete_city = None
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
self._output_path = (Path(__file__).parent / 'tests_outputs').resolve()
def _get_citygml(self, file):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('citygml', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
@property
def _read_sra_file(self) -> []:
path = (self._example_path / "one_building_in_kelowna_sra_SW.out").resolve()
_results = pd.read_csv(path, sep='\s+', header=0)
id_building = ''
header_building = []
_radiation = []
for column in _results.columns.values:
if id_building != column.split(':')[1]:
id_building = column.split(':')[1]
if len(header_building) > 0:
_radiation.append(pd.concat([MonthlyValues().month_hour, _results[header_building]], axis=1))
header_building = [column]
else:
header_building.append(column)
_radiation.append(pd.concat([MonthlyValues().month_hour, _results[header_building]], axis=1))
return _radiation
def _set_irradiance_surfaces(self, city):
"""
saves in building surfaces the correspondent irradiance at different time-scales depending on the mode
if building is None, it saves all buildings' surfaces in file, if building is specified, it saves only that
specific building values
:parameter city: city
:return: none
"""
for radiation in self._read_sra_file:
city_object_name = radiation.columns.values.tolist()[1].split(':')[1]
building = city.city_object(city_object_name)
for column in radiation.columns.values:
if column == cte.MONTH:
continue
header_id = column
surface_id = header_id.split(':')[2]
surface = building.surface_by_id(surface_id)
new_value = pd.DataFrame(radiation[[header_id]].to_numpy(), columns=['sra'])
surface.global_irradiance[cte.HOUR] = new_value
month_new_value = MonthlyValues().get_mean_values(new_value)
surface.global_irradiance[cte.MONTH] = month_new_value
def test_insel_monthly_energy_balance_export(self):
"""
export to Insel MonthlyEnergyBalance
"""
city = self._get_citygml('one_building_in_kelowna.gml')
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
for building in city.buildings:
building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']])
self._set_irradiance_surfaces(city)
for building in city.buildings:
self.assertIsNotNone(building.external_temperature[cte.MONTH], f'building {building.name} '
f'external_temperature is none')
for surface in building.surfaces:
if surface.type != 'Ground':
self.assertIsNotNone(surface.global_irradiance[cte.MONTH], f'surface in building {building.name} '
f'global_irradiance is none')
for building in city.buildings:
building.year_of_construction = 2006
if building.function is None:
building.function = 'large office'
building.attic_heated = False
building.basement_heated = False
ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich()
# parameters written:
for building in city.buildings:
self.assertIsNotNone(building.volume, f'building {building.name} volume is none')
self.assertIsNotNone(building.average_storey_height, f'building {building.name} average_storey_height is none')
self.assertIsNotNone(building.storeys_above_ground, f'building {building.name} storeys_above_ground is none')
self.assertIsNotNone(building.attic_heated, f'building {building.name} attic_heated is none')
self.assertIsNotNone(building.basement_heated, f'building {building.name} basement_heated is none')
for internal_zone in building.internal_zones:
self.assertIsNotNone(internal_zone.area, f'internal zone {internal_zone.id} area is none')
for thermal_zone in internal_zone.thermal_zones:
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, f'thermal zone {thermal_zone.id} '
f'indirectly_heated_area_ratio is none')
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, f'thermal zone {thermal_zone.id} '
f'effective_thermal_capacity is none')
self.assertIsNotNone(thermal_zone.additional_thermal_bridge_u_value, f'thermal zone {thermal_zone.id} '
f'additional_thermal_bridge_u_value '
f'is none')
self.assertIsNotNone(thermal_zone.total_floor_area, f'thermal zone {thermal_zone.id} '
f'total_floor_area is none')
for thermal_boundary in thermal_zone.thermal_boundaries:
self.assertIsNotNone(thermal_boundary.type)
self.assertIsNotNone(thermal_boundary.opaque_area)
self.assertIsNotNone(thermal_boundary.window_ratio)
self.assertIsNotNone(thermal_boundary.u_value)
self.assertIsNotNone(thermal_boundary.thermal_openings)
if thermal_boundary.type is not cte.GROUND:
self.assertIsNotNone(thermal_boundary.parent_surface.short_wave_reflectance)
for usage_zone in internal_zone.usage_zones:
self.assertIsNotNone(usage_zone.percentage, f'usage zone {usage_zone.usage} percentage is none')
self.assertIsNotNone(usage_zone.internal_gains, f'usage zone {usage_zone.usage} internal_gains is none')
self.assertIsNotNone(usage_zone.thermal_control, f'usage zone {usage_zone.usage} thermal_control is none')
self.assertIsNotNone(usage_zone.hours_day, f'usage zone {usage_zone.usage} hours_day is none')
self.assertIsNotNone(usage_zone.days_year, f'usage zone {usage_zone.usage} days_year is none')
self.assertIsNotNone(usage_zone.mechanical_air_change, f'usage zone {usage_zone.usage} '
f'mechanical_air_change is none')
# export files
try:
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, self._output_path).export_debug()
except Exception:
self.fail("Insel MonthlyEnergyBalance ExportsFactory raised ExceptionType unexpectedly!")

File diff suppressed because it is too large Load Diff