fix: importers are fixed for mixed use buildings #14
|
@ -1,4 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkUUID" value="97386509-ec9b-4dd7-929b-7585219c0447" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="hub" project-jdk-type="Python SDK" />
|
||||
</project>
|
|
@ -32,10 +32,21 @@ class NrcanPhysicsParameters:
|
|||
city = self._city
|
||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||
for building in city.buildings:
|
||||
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
|
||||
logging.error('Building %s has an unknown building function %s', building.name, building.function)
|
||||
main_function = None
|
||||
functions = building.function.split('_')
|
||||
if len(functions) > 1:
|
||||
maximum_percentage = 0
|
||||
for function in functions:
|
||||
percentage_and_function = function.split('-')
|
||||
if float(percentage_and_function[0]) > maximum_percentage:
|
||||
maximum_percentage = float(percentage_and_function[0])
|
||||
main_function = percentage_and_function[-1]
|
||||
else:
|
||||
main_function = functions[-1]
|
||||
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
|
||||
logging.error('Building %s has an unknown building function %s', building.name, main_function)
|
||||
continue
|
||||
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
|
||||
try:
|
||||
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
|
||||
|
||||
|
|
|
@ -127,6 +127,19 @@ class Geojson:
|
|||
function = None
|
||||
if self._function_field is not None:
|
||||
function = str(feature['properties'][self._function_field])
|
||||
if function == 'Mixed use' or function == 'mixed use':
|
||||
function_parts = []
|
||||
for key, value in feature['properties'].items():
|
||||
if key.startswith("mixed_type_") and not key.endswith("_percentage"):
|
||||
type_key = key
|
||||
percentage_key = f"{key}_percentage"
|
||||
if percentage_key in feature['properties']:
|
||||
if self._function_to_hub is not None and feature['properties'][type_key] in self._function_to_hub:
|
||||
usage_function = self._function_to_hub[feature['properties'][type_key]]
|
||||
function_parts.append(f"{feature['properties'][percentage_key]}-{usage_function}")
|
||||
else:
|
||||
function_parts.append(f"{feature['properties'][percentage_key]}-{feature['properties'][type_key]}")
|
||||
function = "_".join(function_parts)
|
||||
if self._function_to_hub is not None:
|
||||
# use the transformation dictionary to retrieve the proper function
|
||||
if function in self._function_to_hub:
|
||||
|
|
|
@ -35,29 +35,60 @@ class ComnetUsageParameters:
|
|||
city = self._city
|
||||
comnet_catalog = UsageCatalogFactory('comnet').catalog
|
||||
for building in city.buildings:
|
||||
usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
|
||||
try:
|
||||
archetype_usage = self._search_archetypes(comnet_catalog, usage_name)
|
||||
except KeyError:
|
||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
|
||||
continue
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
if internal_zone.area is None:
|
||||
raise TypeError('Internal zone area not defined, ACH cannot be calculated')
|
||||
if internal_zone.volume is None:
|
||||
raise TypeError('Internal zone volume not defined, ACH cannot be calculated')
|
||||
if internal_zone.area <= 0:
|
||||
raise TypeError('Internal zone area is zero, ACH cannot be calculated')
|
||||
volume_per_area = internal_zone.volume / internal_zone.area
|
||||
usage = Usage()
|
||||
usage.name = usage_name
|
||||
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
|
||||
usage.percentage = 1
|
||||
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
|
||||
|
||||
internal_zone.usages = [usage]
|
||||
usages = []
|
||||
comnet_archetype_usages = []
|
||||
building_functions = building.function.split('_')
|
||||
for function in building_functions:
|
||||
usages.append(function.split('-'))
|
||||
for usage in usages:
|
||||
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
|
||||
try:
|
||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
||||
comnet_archetype_usages.append(comnet_archetype_usage)
|
||||
except KeyError:
|
||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
|
||||
continue
|
||||
for (i, internal_zone) in enumerate(building.internal_zones):
|
||||
internal_zone_usages = []
|
||||
if len(building.internal_zones) > 1:
|
||||
volume_per_area = 0
|
||||
if internal_zone.area is None:
|
||||
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
|
||||
building.name, usages[i][-1])
|
||||
continue
|
||||
if internal_zone.volume is None:
|
||||
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
|
||||
building.name, usages[i][-1])
|
||||
continue
|
||||
if internal_zone.area <= 0:
|
||||
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
|
||||
building.name, usages[i][-1])
|
||||
continue
|
||||
volume_per_area += internal_zone.volume / internal_zone.area
|
||||
usage = Usage()
|
||||
usage.name = usages[i][-1]
|
||||
self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature)
|
||||
usage.percentage = 1
|
||||
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i])
|
||||
internal_zone_usages.append(usage)
|
||||
else:
|
||||
if building.storeys_above_ground is None:
|
||||
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s',
|
||||
building.name, usages)
|
||||
continue
|
||||
volume_per_area = building.volume / building.floor_area / building.storeys_above_ground
|
||||
for (j, mixed_usage) in enumerate(usages):
|
||||
usage = Usage()
|
||||
usage.name = mixed_usage[-1]
|
||||
if len(usages) > 1:
|
||||
usage.percentage = float(mixed_usage[0]) / 100
|
||||
else:
|
||||
usage.percentage = 1
|
||||
self._assign_values(usage, comnet_archetype_usages[j], volume_per_area, building.cold_water_temperature)
|
||||
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j])
|
||||
internal_zone_usages.append(usage)
|
||||
|
||||
internal_zone.usages = internal_zone_usages
|
||||
@staticmethod
|
||||
def _search_archetypes(comnet_catalog, usage_name):
|
||||
comnet_archetypes = comnet_catalog.entries('archetypes').usages
|
||||
|
|
|
@ -33,53 +33,72 @@ class NrcanUsageParameters:
|
|||
city = self._city
|
||||
nrcan_catalog = UsageCatalogFactory('nrcan').catalog
|
||||
comnet_catalog = UsageCatalogFactory('comnet').catalog
|
||||
|
||||
for building in city.buildings:
|
||||
usage_name = Dictionaries().hub_usage_to_nrcan_usage[building.function]
|
||||
try:
|
||||
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
|
||||
except KeyError:
|
||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
|
||||
continue
|
||||
usages = []
|
||||
nrcan_archetype_usages = []
|
||||
comnet_archetype_usages = []
|
||||
building_functions = building.function.split('_')
|
||||
for function in building_functions:
|
||||
usages.append(function.split('-'))
|
||||
for usage in usages:
|
||||
usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage[-1]]
|
||||
try:
|
||||
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
|
||||
nrcan_archetype_usages.append(archetype_usage)
|
||||
except KeyError:
|
||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
|
||||
continue
|
||||
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
|
||||
try:
|
||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
||||
comnet_archetype_usages.append(comnet_archetype_usage)
|
||||
except KeyError:
|
||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
|
||||
continue
|
||||
|
||||
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
|
||||
try:
|
||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
||||
except KeyError:
|
||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
|
||||
continue
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
for (i, internal_zone) in enumerate(building.internal_zones):
|
||||
internal_zone_usages = []
|
||||
if len(building.internal_zones) > 1:
|
||||
volume_per_area = 0
|
||||
if internal_zone.area is None:
|
||||
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
|
||||
building.name, usage_name)
|
||||
building.name, usages[i][-1])
|
||||
continue
|
||||
if internal_zone.volume is None:
|
||||
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
|
||||
building.name, usage_name)
|
||||
building.name, usages[i][-1])
|
||||
continue
|
||||
if internal_zone.area <= 0:
|
||||
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
|
||||
building.name, usage_name)
|
||||
building.name, usages[i][-1])
|
||||
continue
|
||||
volume_per_area += internal_zone.volume / internal_zone.area
|
||||
usage = Usage()
|
||||
usage.name = usages[i][-1]
|
||||
self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature)
|
||||
self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density)
|
||||
usage.percentage = 1
|
||||
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[i])
|
||||
internal_zone_usages.append(usage)
|
||||
else:
|
||||
if building.storeys_above_ground is None:
|
||||
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s',
|
||||
building.name, usage_name)
|
||||
building.name, usages)
|
||||
continue
|
||||
volume_per_area = building.volume / building.floor_area / building.storeys_above_ground
|
||||
for (j, mixed_usage) in enumerate(usages):
|
||||
usage = Usage()
|
||||
usage.name = mixed_usage[-1]
|
||||
if len(usages) > 1:
|
||||
usage.percentage = float(mixed_usage[0]) / 100
|
||||
else:
|
||||
usage.percentage = 1
|
||||
self._assign_values(usage, nrcan_archetype_usages[j], volume_per_area, building.cold_water_temperature)
|
||||
self._assign_comnet_extra_values(usage, comnet_archetype_usages[j], nrcan_archetype_usages[j].occupancy.occupancy_density)
|
||||
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j])
|
||||
internal_zone_usages.append(usage)
|
||||
|
||||
usage = Usage()
|
||||
usage.name = usage_name
|
||||
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
|
||||
self._assign_comnet_extra_values(usage, comnet_archetype_usage, archetype_usage.occupancy.occupancy_density)
|
||||
usage.percentage = 1
|
||||
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
|
||||
|
||||
internal_zone.usages = [usage]
|
||||
internal_zone.usages = internal_zone_usages
|
||||
|
||||
@staticmethod
|
||||
def _search_archetypes(catalog, usage_name):
|
||||
|
|
55
input_files/test_geojson.geojson
Normal file
55
input_files/test_geojson.geojson
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-73.58000127109773,
|
||||
45.49613461675315
|
||||
],
|
||||
[
|
||||
-73.57962787855432,
|
||||
45.496524875557746
|
||||
],
|
||||
[
|
||||
-73.57996357265695,
|
||||
45.49668114195629
|
||||
],
|
||||
[
|
||||
-73.57996427397713,
|
||||
45.496680342403664
|
||||
],
|
||||
[
|
||||
-73.58034707390021,
|
||||
45.49625804233725
|
||||
],
|
||||
[
|
||||
-73.58034697395713,
|
||||
45.496257942524835
|
||||
],
|
||||
[
|
||||
-73.58000127109773,
|
||||
45.49613461675315
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
"id": 179764,
|
||||
"properties": {
|
||||
"name": "01119274",
|
||||
"address": "rue Guy (MTL) 2157",
|
||||
"function": "Mixed use",
|
||||
"mixed_type_1": "commercial",
|
||||
"mixed_type_1_percentage": 50,
|
||||
"mixed_type_2": "6000",
|
||||
"mixed_type_2_percentage": 50,
|
||||
"height": 62,
|
||||
"year_of_construction": 1954
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
86
main.py
86
main.py
|
@ -0,0 +1,86 @@
|
|||
from pathlib import Path
|
||||
import subprocess
|
||||
from scripts.ep_run_enrich import energy_plus_workflow
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.weather_factory import WeatherFactory
|
||||
from hub.imports.results_factory import ResultFactory
|
||||
from scripts.energy_system_retrofit_report import EnergySystemRetrofitReport
|
||||
from scripts.geojson_creator import process_geojson
|
||||
from scripts import random_assignation
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from scripts.energy_system_sizing import SystemSizing
|
||||
from scripts.solar_angles import CitySolarAngles
|
||||
from scripts.pv_sizing_and_simulation import PVSizingSimulation
|
||||
from scripts.energy_system_retrofit_results import consumption_data, cost_data
|
||||
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
|
||||
from scripts.costs.cost import Cost
|
||||
from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS
|
||||
import hub.helpers.constants as cte
|
||||
from hub.exports.exports_factory import ExportsFactory
|
||||
from scripts.pv_feasibility import pv_feasibility
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
# Specify the GeoJSON file path
|
||||
data = {}
|
||||
input_files_path = (Path(__file__).parent / 'input_files')
|
||||
input_files_path.mkdir(parents=True, exist_ok=True)
|
||||
# geojson_file = process_geojson(x=-73.58001358793511, y=45.496445294438715, diff=0.0001)
|
||||
geojson_file_path = input_files_path / 'test_geojson.geojson'
|
||||
output_path = (Path(__file__).parent / 'out_files').resolve()
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
energy_plus_output_path = output_path / 'energy_plus_outputs'
|
||||
energy_plus_output_path.mkdir(parents=True, exist_ok=True)
|
||||
simulation_results_path = (Path(__file__).parent / 'out_files' / 'simulation_results').resolve()
|
||||
simulation_results_path.mkdir(parents=True, exist_ok=True)
|
||||
sra_output_path = output_path / 'sra_outputs'
|
||||
sra_output_path.mkdir(parents=True, exist_ok=True)
|
||||
cost_analysis_output_path = output_path / 'cost_analysis'
|
||||
cost_analysis_output_path.mkdir(parents=True, exist_ok=True)
|
||||
city = GeometryFactory(file_type='geojson',
|
||||
path=geojson_file_path,
|
||||
height_field='height',
|
||||
year_of_construction_field='year_of_construction',
|
||||
function_field='function',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
energy_plus_workflow(city, energy_plus_output_path)
|
||||
data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9
|
||||
city.buildings[0].function = cte.COMMERCIAL
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
energy_plus_workflow(city, energy_plus_output_path)
|
||||
data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9
|
||||
city.buildings[0].function = cte.MEDIUM_OFFICE
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
energy_plus_workflow(city, energy_plus_output_path)
|
||||
data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9
|
||||
categories = list(data.keys())
|
||||
values = list(data.values())
|
||||
# Plotting
|
||||
fig, ax = plt.subplots(figsize=(10, 6), dpi=96)
|
||||
fig.suptitle('Impact of different usages on yearly heating demand', fontsize=16, weight='bold', alpha=.8)
|
||||
ax.bar(categories, values, color=['#2196f3', '#ff5a5f', '#4caf50'], width=0.6, zorder=2)
|
||||
ax.grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
ax.grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
ax.set_xlabel('Building Type', fontsize=12, labelpad=10)
|
||||
ax.set_ylabel('Energy Consumption (MWh)', fontsize=14, labelpad=10)
|
||||
ax.yaxis.set_major_locator(plt.MaxNLocator(integer=True))
|
||||
ax.set_xticks(np.arange(len(categories)))
|
||||
ax.set_xticklabels(categories, rotation=45, ha='right')
|
||||
ax.bar_label(ax.containers[0], padding=3, color='black', fontsize=12, rotation=0)
|
||||
ax.spines[['top', 'left', 'bottom']].set_visible(False)
|
||||
ax.spines['right'].set_linewidth(1.1)
|
||||
# Set a white background
|
||||
fig.patch.set_facecolor('white')
|
||||
# Adjust the margins around the plot area
|
||||
plt.subplots_adjust(left=0.1, right=0.9, top=0.85, bottom=0.25)
|
||||
# Save the plot
|
||||
plt.savefig('plot_nrcan.png', bbox_inches='tight')
|
||||
plt.close()
|
||||
print('test')
|
BIN
plot_nrcan.png
Normal file
BIN
plot_nrcan.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Loading…
Reference in New Issue
Block a user