adjasted workflow to new concept of the libs
This commit is contained in:
parent
a17e575948
commit
248438f4ab
|
@ -24,7 +24,7 @@ class MonthlyEnergyBalance:
|
||||||
|
|
||||||
file += 'p 4' + '\n'
|
file += 'p 4' + '\n'
|
||||||
# BUILDING PARAMETERS
|
# BUILDING PARAMETERS
|
||||||
file += str(0.85*building.heated_volume) + ' % BP(1) Heated Volume (vBrutto)\n'
|
file += str(0.85*building.volume) + ' % BP(1) Heated Volume (vBrutto)\n'
|
||||||
file += str(building.average_storey_height) + ' % BP(2) Average storey height / m\n'
|
file += str(building.average_storey_height) + ' % BP(2) Average storey height / m\n'
|
||||||
file += str(building.storeys_above_ground) + ' % BP(3) Number of storeys above ground\n'
|
file += str(building.storeys_above_ground) + ' % BP(3) Number of storeys above ground\n'
|
||||||
file += str(building.attic_heated) + ' % BP(4) Attic heating type (0=no room, 1=unheated, 2=heated)\n'
|
file += str(building.attic_heated) + ' % BP(4) Attic heating type (0=no room, 1=unheated, 2=heated)\n'
|
||||||
|
@ -43,12 +43,13 @@ class MonthlyEnergyBalance:
|
||||||
i = 0
|
i = 0
|
||||||
for usage_zone in building.usage_zones:
|
for usage_zone in building.usage_zones:
|
||||||
percentage_usage = 1
|
percentage_usage = 1
|
||||||
file += str(float(building.foot_print.area) * percentage_usage) + ' % BP(11) #1 Area of zone ' + \
|
file += str(float(building.floor_area) * percentage_usage) + ' % BP(11) #1 Area of zone ' + \
|
||||||
str(i + 1) + ' (sqm)' + '\n'
|
str(i + 1) + ' (sqm)' + '\n'
|
||||||
total_internal_gains = 0
|
total_internal_gains = 0
|
||||||
for ig in usage_zone.internal_gains:
|
for ig in usage_zone.internal_gains:
|
||||||
total_internal_gains += float(ig.average_internal_gain) * \
|
# total_internal_gains += float(ig.average_internal_gain) * \
|
||||||
(float(ig.convective_fraction) + float(ig.radiative_fraction))
|
# (float(ig.convective_fraction) + float(ig.radiative_fraction))
|
||||||
|
total_internal_gains += 10.45 * (float(ig.convective_fraction) + float(ig.radiative_fraction))
|
||||||
file += str(total_internal_gains) + ' % BP(12) #2 Internal gains of zone ' + str(i + 1) + '\n'
|
file += str(total_internal_gains) + ' % BP(12) #2 Internal gains of zone ' + str(i + 1) + '\n'
|
||||||
file += str(usage_zone.heating_setpoint) + ' % BP(13) #3 Heating setpoint temperature zone ' + \
|
file += str(usage_zone.heating_setpoint) + ' % BP(13) #3 Heating setpoint temperature zone ' + \
|
||||||
str(i + 1) + ' (tSetHeat)' + '\n'
|
str(i + 1) + ' (tSetHeat)' + '\n'
|
||||||
|
@ -59,7 +60,12 @@ class MonthlyEnergyBalance:
|
||||||
file += str(usage_zone.hours_day) + ' % BP(16) #6 Usage hours per day zone ' + str(i + 1) + '\n'
|
file += str(usage_zone.hours_day) + ' % BP(16) #6 Usage hours per day zone ' + str(i + 1) + '\n'
|
||||||
file += str(usage_zone.days_year) + ' % BP(17) #7 Usage days per year zone ' + str(i + 1) + '\n'
|
file += str(usage_zone.days_year) + ' % BP(17) #7 Usage days per year zone ' + str(i + 1) + '\n'
|
||||||
if usage_zone.mechanical_air_change is None:
|
if usage_zone.mechanical_air_change is None:
|
||||||
|
if thermal_zone.infiltration_rate_system_off is None:
|
||||||
raise Exception('Ventilation air rate is not initialized')
|
raise Exception('Ventilation air rate is not initialized')
|
||||||
|
else:
|
||||||
|
file += str(thermal_zone.infiltration_rate_system_off) + ' % BP(18) #8 Minimum air change rate zone ' + \
|
||||||
|
str(i + 1) + ' (h^-1)' + '\n'
|
||||||
|
else:
|
||||||
file += str(usage_zone.mechanical_air_change) + ' % BP(18) #8 Minimum air change rate zone ' + \
|
file += str(usage_zone.mechanical_air_change) + ' % BP(18) #8 Minimum air change rate zone ' + \
|
||||||
str(i + 1) + ' (h^-1)' + '\n'
|
str(i + 1) + ' (h^-1)' + '\n'
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -79,11 +85,17 @@ class MonthlyEnergyBalance:
|
||||||
# todo: this method has to be reviewed for more than one thermal opening per thermal boundary
|
# todo: this method has to be reviewed for more than one thermal opening per thermal boundary
|
||||||
for thermal_boundary in building.thermal_zones[0].bounded:
|
for thermal_boundary in building.thermal_zones[0].bounded:
|
||||||
type_code = lc.construction_types_to_code(thermal_boundary.type)
|
type_code = lc.construction_types_to_code(thermal_boundary.type)
|
||||||
string = type_code + ' ' + str(thermal_boundary.area_above_ground) + ' ' + \
|
if thermal_boundary.surface.holes_polygons is None:
|
||||||
|
window_area = float(thermal_boundary.surface.perimeter_polygon.area) * float(thermal_boundary.window_ratio)
|
||||||
|
else:
|
||||||
|
window_area = 0
|
||||||
|
for hole_polygon in thermal_boundary.surface.holes_polygons:
|
||||||
|
window_area += hole_polygon.area
|
||||||
|
string = type_code + ' ' + str(0.85*thermal_boundary.area_above_ground) + ' ' + \
|
||||||
str(thermal_boundary.area_below_ground) + ' ' + str(thermal_boundary.u_value) + ' ' + \
|
str(thermal_boundary.area_below_ground) + ' ' + str(thermal_boundary.u_value) + ' ' + \
|
||||||
str(thermal_boundary.window_area) + ' '
|
str(0.85*window_area) + ' '
|
||||||
|
|
||||||
if thermal_boundary.window_area <= 0.001:
|
if window_area <= 0.001:
|
||||||
string = string + '0 0 0 '
|
string = string + '0 0 0 '
|
||||||
else:
|
else:
|
||||||
string = string + str(thermal_boundary.thermal_openings[0].frame_ratio) + ' ' + \
|
string = string + str(thermal_boundary.thermal_openings[0].frame_ratio) + ' ' + \
|
||||||
|
@ -153,6 +165,10 @@ class MonthlyEnergyBalance:
|
||||||
csv_reader = csv.reader(csv_file)
|
csv_reader = csv.reader(csv_file)
|
||||||
for line in csv_reader:
|
for line in csv_reader:
|
||||||
demand = str(line).replace("['", '').replace("']", '').split()
|
demand = str(line).replace("['", '').replace("']", '').split()
|
||||||
|
for i in range(0, 2):
|
||||||
|
if demand[i] != 'NaN':
|
||||||
|
aux = float(demand[i])*1000 # kWh to Wh
|
||||||
|
demand[i] = str(aux)
|
||||||
heating.append(demand[0])
|
heating.append(demand[0])
|
||||||
cooling.append(demand[1])
|
cooling.append(demand[1])
|
||||||
monthly_heating = pd.DataFrame(heating, columns=['INSEL'])
|
monthly_heating = pd.DataFrame(heating, columns=['INSEL'])
|
||||||
|
|
65
main.py
65
main.py
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Monthly energy balance main
|
Monthly energy balance main
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
Copyright © 2020 Project Author Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
@ -19,6 +19,7 @@ from imports.geometry_factory import GeometryFactory
|
||||||
from imports.weather_factory import WeatherFactory
|
from imports.weather_factory import WeatherFactory
|
||||||
from city_model_structure.city import City
|
from city_model_structure.city import City
|
||||||
import datetime
|
import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
parser = ArgumentParser(description='Monthly energy balance workflow v0.1.')
|
parser = ArgumentParser(description='Monthly energy balance workflow v0.1.')
|
||||||
required = parser.add_argument_group('required arguments')
|
required = parser.add_argument_group('required arguments')
|
||||||
|
@ -33,8 +34,8 @@ parser.add_argument('--weather_step_in_pickle', '-ws', help='Weather parameters
|
||||||
parser.add_argument('--use_cached_sra_file', '-u', help='Use sra files from cache, instead of freshly calculated sra '
|
parser.add_argument('--use_cached_sra_file', '-u', help='Use sra files from cache, instead of freshly calculated sra '
|
||||||
'files', default=False)
|
'files', default=False)
|
||||||
required.add_argument('--project_folder', '-f', help='Project folder', required=True)
|
required.add_argument('--project_folder', '-f', help='Project folder', required=True)
|
||||||
required.add_argument('--cli_weather_file', '-c', help='weather cli file', required=True)
|
required.add_argument('--weather_file_name', '-w', help='Weather file', required=True)
|
||||||
required.add_argument('--city_name', '-n', help='city name for dat file', required=True)
|
required.add_argument('--climate_reference_city', '-c', help='Closest city with climate weather', required=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -54,14 +55,11 @@ else:
|
||||||
city = GeometryFactory(args.geometry_type, file).city
|
city = GeometryFactory(args.geometry_type, file).city
|
||||||
city.save(pickle_file)
|
city.save(pickle_file)
|
||||||
|
|
||||||
|
print('begin_populating_time', datetime.datetime.now())
|
||||||
# Step 2: Populate city adding thermal- and usage-related parameters
|
# Step 2: Populate city adding thermal- and usage-related parameters
|
||||||
populated_step_in_pickle = ast.literal_eval(args.populated_step_in_pickle)
|
populated_step_in_pickle = ast.literal_eval(args.populated_step_in_pickle)
|
||||||
if populated_step_in_pickle:
|
if populated_step_in_pickle:
|
||||||
populated_city = city
|
populated_city = city
|
||||||
for building in populated_city.buildings:
|
|
||||||
for usage_zone in building.usage_zones:
|
|
||||||
usage_zone.heating_setpoint = 20
|
|
||||||
usage_zone.heating_setback = 17
|
|
||||||
else:
|
else:
|
||||||
populated_city = Populate(city).populated_city
|
populated_city = Populate(city).populated_city
|
||||||
pickle_file = Path(str(pickle_file).replace('.pickle', '_populated.pickle'))
|
pickle_file = Path(str(pickle_file).replace('.pickle', '_populated.pickle'))
|
||||||
|
@ -70,12 +68,14 @@ if populated_city.buildings is None:
|
||||||
print('No building to be calculated')
|
print('No building to be calculated')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
print('populating_time', datetime.datetime.now())
|
print('begin_weather_time', datetime.datetime.now())
|
||||||
# Step 3: Populate city adding climate-related parameters
|
# Step 3: Populate city adding climate-related parameters
|
||||||
weather_step_in_pickle = ast.literal_eval(args.weather_step_in_pickle)
|
weather_step_in_pickle = ast.literal_eval(args.weather_step_in_pickle)
|
||||||
if not weather_step_in_pickle:
|
if not weather_step_in_pickle:
|
||||||
city_name = args.city_name
|
city.climate_reference_city = args.climate_reference_city
|
||||||
WeatherFactory('dat', populated_city, city_name)
|
path = (Path(args.project_folder) / 'tmp').resolve()
|
||||||
|
city.climate_file = (path / f'{args.climate_reference_city}.cli').resolve()
|
||||||
|
WeatherFactory('epw', populated_city, file_name=args.weather_file_name).enrich()
|
||||||
for building in populated_city.buildings:
|
for building in populated_city.buildings:
|
||||||
if 'hour' not in building.external_temperature:
|
if 'hour' not in building.external_temperature:
|
||||||
print('No external temperature found')
|
print('No external temperature found')
|
||||||
|
@ -83,13 +83,10 @@ if not weather_step_in_pickle:
|
||||||
|
|
||||||
if 'month' not in building.external_temperature:
|
if 'month' not in building.external_temperature:
|
||||||
building.external_temperature['month'] = mv.MonthlyValues().\
|
building.external_temperature['month'] = mv.MonthlyValues().\
|
||||||
get_mean_values(building.external_temperature['hour'][['inseldb']])
|
get_mean_values(building.external_temperature['hour'][['epw']])
|
||||||
|
|
||||||
max_buildings_handled_by_sra = 500
|
max_buildings_handled_by_sra = 500
|
||||||
sra_file_name = 'SRA'
|
sra = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), city, args.weather_file_name)
|
||||||
sra = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), sra_file_name,
|
|
||||||
Path(args.cli_weather_file).resolve(),
|
|
||||||
city.city_objects, lower_corner=city.lower_corner)
|
|
||||||
if ast.literal_eval(args.use_cached_sra_file):
|
if ast.literal_eval(args.use_cached_sra_file):
|
||||||
sra.results()
|
sra.results()
|
||||||
sra.set_irradiance_surfaces(populated_city)
|
sra.set_irradiance_surfaces(populated_city)
|
||||||
|
@ -99,11 +96,7 @@ if not weather_step_in_pickle:
|
||||||
radius = 100
|
radius = 100
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
new_city = city.region(building.location, radius)
|
new_city = city.region(building.location, radius)
|
||||||
sra_file_name = 'SRA'
|
sra_new = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), city, args.weather_file_name)
|
||||||
|
|
||||||
sra_new = SimplifiedRadiosityAlgorithm(Path(args.project_folder).resolve(), sra_file_name,
|
|
||||||
Path(args.cli_weather_file).resolve(),
|
|
||||||
new_city.city_objects, lower_corner=new_city.lower_corner)
|
|
||||||
sra_new.call_sra(keep_files=True)
|
sra_new.call_sra(keep_files=True)
|
||||||
sra_new.set_irradiance_surfaces(city, building_name=building.name)
|
sra_new.set_irradiance_surfaces(city, building_name=building.name)
|
||||||
else:
|
else:
|
||||||
|
@ -115,28 +108,17 @@ if not weather_step_in_pickle:
|
||||||
print('begin_insel_time', datetime.datetime.now())
|
print('begin_insel_time', datetime.datetime.now())
|
||||||
# Step 4: Demand calculation (one model per building)
|
# Step 4: Demand calculation (one model per building)
|
||||||
print_results = None
|
print_results = None
|
||||||
# todo: city.name needs location and so, internet connection
|
file = 'city name: ' + city.name + '\n'
|
||||||
# file = 'city name: ' + city.name + '\n'
|
|
||||||
file = 'city name: Kelowna\n'
|
|
||||||
i = 0
|
i = 0
|
||||||
|
init = time.process_time_ns()
|
||||||
for building in populated_city.buildings:
|
for building in populated_city.buildings:
|
||||||
if building.name != 'BLD122177':
|
if building.name != 'BLD122177':
|
||||||
print(building.name)
|
|
||||||
# todo: default values to be defined at each specific workflow!
|
# todo: default values to be defined at each specific workflow!
|
||||||
building.heated = True
|
building.heated = True
|
||||||
building.cooled = False
|
building.cooled = False
|
||||||
building.attic_heated = 2
|
building.attic_heated = 1
|
||||||
building.basement_heated = 1
|
building.basement_heated = 1
|
||||||
for thermal_boundary in building.thermal_zones[0].bounded:
|
# building.usage_zones[0].internal_gains[0].average_internal_gain = '10.45'
|
||||||
thermal_boundary.hi = 10
|
|
||||||
thermal_boundary.he = 25
|
|
||||||
for thermal_opening in thermal_boundary.thermal_openings:
|
|
||||||
thermal_opening.hi = 10
|
|
||||||
thermal_opening.he = 25
|
|
||||||
building.thermal_zones[0].indirectly_heated_area_ratio = 0.25
|
|
||||||
building.thermal_zones[0].additional_thermal_bridge_u_value = 0.05
|
|
||||||
building.usage_zones[0].mechanical_air_change = 0.35
|
|
||||||
building.thermal_zones[0].infiltration_rate_system_on = 0
|
|
||||||
full_path_out = Path(args.project_folder + '/outputs/' + building.name + '_insel.out').resolve()
|
full_path_out = Path(args.project_folder + '/outputs/' + building.name + '_insel.out').resolve()
|
||||||
full_path_out.parent.mkdir(parents=True, exist_ok=True)
|
full_path_out.parent.mkdir(parents=True, exist_ok=True)
|
||||||
insel_file_name = building.name + '.insel'
|
insel_file_name = building.name + '.insel'
|
||||||
|
@ -145,6 +127,13 @@ for building in populated_city.buildings:
|
||||||
insel = Insel(Path(args.project_folder).resolve(), insel_file_name, content, mode=2, keep_files=keep_files).run()
|
insel = Insel(Path(args.project_folder).resolve(), insel_file_name, content, mode=2, keep_files=keep_files).run()
|
||||||
building.heating['month'], building.cooling['month'] = templates.demand(full_path_out)
|
building.heating['month'], building.cooling['month'] = templates.demand(full_path_out)
|
||||||
new_building = building.heating['month'].rename(columns={'INSEL': building.name})
|
new_building = building.heating['month'].rename(columns={'INSEL': building.name})
|
||||||
|
demand_year = 0
|
||||||
|
for value in building.heating['month']['INSEL']:
|
||||||
|
if value == 'NaN':
|
||||||
|
value = '0'
|
||||||
|
demand_year += float(value)
|
||||||
|
yearly_heating = pd.DataFrame([demand_year], columns=['INSEL'])
|
||||||
|
building.heating['year'] = yearly_heating
|
||||||
if print_results is None:
|
if print_results is None:
|
||||||
print_results = new_building
|
print_results = new_building
|
||||||
else:
|
else:
|
||||||
|
@ -155,7 +144,7 @@ for building in populated_city.buildings:
|
||||||
file += 'function: ' + building.function + '\n'
|
file += 'function: ' + building.function + '\n'
|
||||||
file += 'floor area: ' + str(building.thermal_zones[0].floor_area) + '\n'
|
file += 'floor area: ' + str(building.thermal_zones[0].floor_area) + '\n'
|
||||||
file += 'storeys: ' + str(building.storeys_above_ground) + '\n'
|
file += 'storeys: ' + str(building.storeys_above_ground) + '\n'
|
||||||
file += 'heated_volume: ' + str(building.heated_volume) + '\n'
|
file += 'heated_volume: ' + str(building.volume) + '\n'
|
||||||
file += 'volume: ' + str(building.volume) + '\n'
|
file += 'volume: ' + str(building.volume) + '\n'
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -164,11 +153,13 @@ for building in populated_city.buildings:
|
||||||
continue
|
continue
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
full_path_results = Path(args.project_folder + '/outputs/heating_demand.csv').resolve()
|
full_path_results = Path(args.project_folder + '/outputs/heating_demand.csv').resolve()
|
||||||
print_results.to_csv(full_path_results)
|
print_results.to_csv(full_path_results)
|
||||||
full_path_metadata = Path(args.project_folder + '/outputs/metadata.csv').resolve()
|
full_path_metadata = Path(args.project_folder + '/outputs/metadata.csv').resolve()
|
||||||
with open(full_path_metadata, 'w') as metadata_file:
|
with open(full_path_metadata, 'w') as metadata_file:
|
||||||
metadata_file.write(file)
|
metadata_file.write(file)
|
||||||
|
|
||||||
|
pickle_file = Path(str(pickle_file).replace('.pickle', '_demand.pickle'))
|
||||||
|
populated_city.save(pickle_file)
|
||||||
|
|
||||||
print('end_time', datetime.datetime.now())
|
print('end_time', datetime.datetime.now())
|
||||||
|
|
10
populate.py
10
populate.py
|
@ -32,7 +32,9 @@ class Populate:
|
||||||
self._errors = []
|
self._errors = []
|
||||||
# Step 2.1: Thermal parameters
|
# Step 2.1: Thermal parameters
|
||||||
tmp_city = City(self._city.lower_corner, self._city.upper_corner, self._city.srs_name)
|
tmp_city = City(self._city.lower_corner, self._city.upper_corner, self._city.srs_name)
|
||||||
PhysicsFactory(self.handler, self._city)
|
# todo: just for Rabeehs case!!
|
||||||
|
#PhysicsFactory(self.handler, self._city)
|
||||||
|
PhysicsFactory('ca', self._city).enrich()
|
||||||
print('original:', len(self._city.buildings))
|
print('original:', len(self._city.buildings))
|
||||||
for building in self._city.buildings:
|
for building in self._city.buildings:
|
||||||
# infiltration_rate_system_off is a mandatory parameter.
|
# infiltration_rate_system_off is a mandatory parameter.
|
||||||
|
@ -45,7 +47,10 @@ class Populate:
|
||||||
|
|
||||||
# Step 2.2: Usage parameters
|
# Step 2.2: Usage parameters
|
||||||
print('physics:', len(tmp_city.buildings))
|
print('physics:', len(tmp_city.buildings))
|
||||||
UsageFactory(self.handler, tmp_city)
|
|
||||||
|
# todo: just for Rabeehs case!!
|
||||||
|
#UsageFactory(self.handler, tmp_city)
|
||||||
|
UsageFactory('ca', tmp_city).enrich()
|
||||||
self._populated_city = City(self._city.lower_corner, self._city.upper_corner, self._city.srs_name)
|
self._populated_city = City(self._city.lower_corner, self._city.upper_corner, self._city.srs_name)
|
||||||
for building in tmp_city.buildings:
|
for building in tmp_city.buildings:
|
||||||
# heating_setpoint is a mandatory parameter.
|
# heating_setpoint is a mandatory parameter.
|
||||||
|
@ -54,4 +59,5 @@ class Populate:
|
||||||
self._populated_city.add_city_object(building)
|
self._populated_city.add_city_object(building)
|
||||||
if self._populated_city.buildings is None:
|
if self._populated_city.buildings is None:
|
||||||
self._errors.append('no archetype found per usage')
|
self._errors.append('no archetype found per usage')
|
||||||
|
print('usage:', len(tmp_city.buildings))
|
||||||
return self._populated_city
|
return self._populated_city
|
||||||
|
|
|
@ -10,82 +10,56 @@ from pathlib import Path
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from helpers import monthly_values as mv
|
from helpers import monthly_values as mv
|
||||||
import subprocess
|
import subprocess
|
||||||
import xmltodict
|
|
||||||
from collections import OrderedDict
|
|
||||||
from subprocess import SubprocessError, TimeoutExpired, CalledProcessError
|
from subprocess import SubprocessError, TimeoutExpired, CalledProcessError
|
||||||
|
|
||||||
|
from exports.exports_factory import ExportsFactory
|
||||||
|
from imports.weather_factory import WeatherFactory
|
||||||
|
|
||||||
|
|
||||||
class SimplifiedRadiosityAlgorithm:
|
class SimplifiedRadiosityAlgorithm:
|
||||||
# todo: define executable as configurable parameter
|
# todo: define executable as configurable parameter
|
||||||
# _executable = 'citysim_sra' # for linux
|
# _executable = 'citysim_sra' # for linux
|
||||||
_executable = 'shortwave_integer' # for windows
|
_executable = 'shortwave_integer' # for windows
|
||||||
|
|
||||||
def __init__(self, sra_working_path, sra_file_name, full_path_cli, city_objects=None,
|
def __init__(self, sra_working_path, city, weather_file_name):
|
||||||
begin_month=1, begin_day=1, end_month=12, end_day=31, lower_corner=None):
|
self._city = city
|
||||||
self._full_path_cli = full_path_cli
|
|
||||||
self._sra_file_name = sra_file_name
|
|
||||||
self._begin_month = begin_month
|
|
||||||
self._begin_day = begin_day
|
|
||||||
self._end_month = end_month
|
|
||||||
self._end_day = end_day
|
|
||||||
if lower_corner is None:
|
|
||||||
lower_corner = [0, 0, 0]
|
|
||||||
self._lower_corner = lower_corner
|
|
||||||
self._sra_working_path = sra_working_path
|
self._sra_working_path = sra_working_path
|
||||||
tmp_path = (sra_working_path / 'tmp').resolve()
|
self._weather_file_name = weather_file_name
|
||||||
Path(tmp_path).mkdir(parents=True, exist_ok=True)
|
self._tmp_path = (sra_working_path / 'tmp').resolve()
|
||||||
|
Path(self._tmp_path).mkdir(parents=True, exist_ok=True)
|
||||||
# Ensure tmp file is empty
|
# Ensure tmp file is empty
|
||||||
for child in tmp_path.glob('*'):
|
for child in self._tmp_path.glob('*'):
|
||||||
if child.is_file():
|
if child.is_file():
|
||||||
child.unlink()
|
child.unlink()
|
||||||
cache_path = (sra_working_path / 'cache').resolve()
|
self._cache_path = (sra_working_path / 'cache').resolve()
|
||||||
Path(cache_path).mkdir(parents=True, exist_ok=True)
|
Path(self._cache_path).mkdir(parents=True, exist_ok=True)
|
||||||
self._full_path_in_sra = (tmp_path / (sra_file_name + '.xml')).resolve()
|
self._sra_out_file_name = self._city.name + '_sra_SW.out'
|
||||||
self._sra_out_file_name = sra_file_name + '_SW.out'
|
|
||||||
self._full_path_out_sra = (cache_path / self._sra_out_file_name).resolve()
|
|
||||||
|
|
||||||
print(self._full_path_in_sra, self._sra_out_file_name, self._full_path_out_sra)
|
|
||||||
|
|
||||||
self._out_values = None
|
self._out_values = None
|
||||||
self._radiation = []
|
self._radiation = []
|
||||||
self._content = OrderedDict()
|
|
||||||
climate = OrderedDict()
|
|
||||||
climate['@location'] = self._full_path_cli
|
|
||||||
climate['@city'] = self.city
|
|
||||||
simulation = OrderedDict()
|
|
||||||
simulation['@beginMonth'] = begin_month
|
|
||||||
simulation['@beginDay'] = begin_day
|
|
||||||
simulation['@endMonth'] = end_month
|
|
||||||
simulation['@endDay'] = end_day
|
|
||||||
city_sim = OrderedDict()
|
|
||||||
city_sim['@name'] = sra_file_name + '.xml'
|
|
||||||
city_sim['Simulation'] = simulation
|
|
||||||
city_sim['Climate'] = climate
|
|
||||||
self._content['CitySim'] = city_sim
|
|
||||||
if city_objects is not None:
|
|
||||||
self.add_city_objects(city_objects)
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def call_sra(self, keep_files=False):
|
def call_sra(self, keep_files=False):
|
||||||
|
self._create_cli_file()
|
||||||
|
ExportsFactory('sra', self._city, self._tmp_path).export()
|
||||||
try:
|
try:
|
||||||
completed = subprocess.run([self._executable, str(self._full_path_in_sra)])
|
completed = subprocess.run([self._executable, str(Path(self._tmp_path / f'{self._city.name}_sra.xml').resolve())])
|
||||||
except (SubprocessError, TimeoutExpired, CalledProcessError) as error:
|
except (SubprocessError, TimeoutExpired, CalledProcessError) as error:
|
||||||
raise Exception(error)
|
raise Exception(error)
|
||||||
file = (Path(self._sra_working_path) / 'tmp' / self._sra_out_file_name).resolve()
|
file = (self._tmp_path / self._sra_out_file_name).resolve()
|
||||||
new_path = (Path(self._sra_working_path) / 'cache' / self._sra_out_file_name).resolve()
|
new_path = (self._cache_path / self._sra_out_file_name).resolve()
|
||||||
try:
|
try:
|
||||||
shutil.move(str(file), str(new_path))
|
shutil.move(str(file), str(new_path))
|
||||||
except Exception:
|
except Exception:
|
||||||
raise Exception('No SRA output file found')
|
raise Exception('No SRA output file found')
|
||||||
self._out_values = self.results()
|
self._out_values = self.results()
|
||||||
if not keep_files:
|
if not keep_files:
|
||||||
os.remove(self._full_path_in_sra)
|
os.remove(Path(self._tmp_path / f'{self._city.name}_sra.xml').resolve())
|
||||||
return completed
|
return completed
|
||||||
|
|
||||||
def results(self):
|
def results(self):
|
||||||
if self._out_values is None:
|
if self._out_values is None:
|
||||||
try:
|
try:
|
||||||
self._out_values = pd.read_csv(self._full_path_out_sra, sep='\s+', header=0)
|
path = (self._cache_path / self._sra_out_file_name).resolve()
|
||||||
|
self._out_values = pd.read_csv(path, sep='\s+', header=0)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise Exception('No SRA output file found')
|
raise Exception('No SRA output file found')
|
||||||
return self._out_values
|
return self._out_values
|
||||||
|
@ -126,84 +100,52 @@ class SimplifiedRadiosityAlgorithm:
|
||||||
if city_object_name != building_name:
|
if city_object_name != building_name:
|
||||||
continue
|
continue
|
||||||
city_object = city.city_object(city_object_name)
|
city_object = city.city_object(city_object_name)
|
||||||
|
print(city_object.name)
|
||||||
for column in radiation.columns.values:
|
for column in radiation.columns.values:
|
||||||
if column == 'month':
|
if column == 'month':
|
||||||
continue
|
continue
|
||||||
header_name = column
|
header_name = column
|
||||||
surface_name = header_name.split(':')[2]
|
surface_name = header_name.split(':')[2]
|
||||||
surface = city_object.surface(surface_name)
|
surface = city_object.surface(surface_name)
|
||||||
|
print('surface', surface)
|
||||||
new_value = pd.DataFrame(radiation[[header_name]].to_numpy(), columns=['sra'])
|
new_value = pd.DataFrame(radiation[[header_name]].to_numpy(), columns=['sra'])
|
||||||
if mode == 0 or mode == 2:
|
if mode == 0 or mode == 2:
|
||||||
month_new_value = mv.MonthlyValues().get_mean_values(new_value)
|
month_new_value = mv.MonthlyValues().get_mean_values(new_value)
|
||||||
|
print(surface.global_irradiance)
|
||||||
|
print(month_new_value)
|
||||||
if 'month' not in surface.global_irradiance:
|
if 'month' not in surface.global_irradiance:
|
||||||
surface.global_irradiance['month'] = month_new_value
|
surface.global_irradiance['month'] = month_new_value
|
||||||
|
print('1', month_new_value)
|
||||||
else:
|
else:
|
||||||
pd.concat([surface.global_irradiance['month'], month_new_value], axis=1)
|
pd.concat([surface.global_irradiance['month'], month_new_value], axis=1)
|
||||||
|
print('rest', month_new_value)
|
||||||
if mode == 1 or mode == 2:
|
if mode == 1 or mode == 2:
|
||||||
if 'hour' not in surface.global_irradiance:
|
if 'hour' not in surface.global_irradiance:
|
||||||
surface.global_irradiance['hour'] = new_value
|
surface.global_irradiance['hour'] = new_value
|
||||||
else:
|
else:
|
||||||
pd.concat([surface.global_irradiance['hour'], new_value], axis=1)
|
pd.concat([surface.global_irradiance['hour'], new_value], axis=1)
|
||||||
|
|
||||||
@property
|
def _create_cli_file(self):
|
||||||
def content(self):
|
file = self._city.climate_file
|
||||||
return xmltodict.unparse(self._content, pretty=True, short_empty_elements=True)
|
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||||
|
WeatherFactory('epw', self._city, file_name=self._weather_file_name).enrich()
|
||||||
def save(self):
|
content = self._city.name + '\n'
|
||||||
with open(self._full_path_in_sra, "w") as sra_file:
|
content += str(self._city.latitude) + ',' + str(self._city.longitude) + ',0.0,' + str(self._city.time_zone) + '\n'
|
||||||
sra_file.write(self.content)
|
content += '\ndm m h G_Dh G_Bn\n'
|
||||||
return
|
total_days = 0
|
||||||
|
for month in range(1, 13):
|
||||||
def _correct_points(self, points):
|
if month > 1:
|
||||||
# correct the x, y, z values into the reference frame set by lower_corner parameter
|
total_days += days_in_month[month - 2]
|
||||||
# [0, 0, 0] by default means no correction.
|
for day in range(1, days_in_month[month-1]+1):
|
||||||
x = points[0] - self._lower_corner[0]
|
for hour in range(1, 25):
|
||||||
y = points[1] - self._lower_corner[1]
|
if month == 1:
|
||||||
z = points[2] - self._lower_corner[2]
|
i = 24 * (day-1) + hour - 1
|
||||||
correct_points = [x, y, z]
|
|
||||||
return correct_points
|
|
||||||
|
|
||||||
def add_city_objects(self, city_objects):
|
|
||||||
buildings = []
|
|
||||||
for i in range(len(city_objects)):
|
|
||||||
city_object = city_objects[i]
|
|
||||||
building = OrderedDict()
|
|
||||||
building['@Name'] = city_object.name
|
|
||||||
building['@id'] = i
|
|
||||||
building['@key'] = city_object.name
|
|
||||||
building['@Simulate'] = 'True'
|
|
||||||
walls, roofs, floors = [], [], []
|
|
||||||
for s in city_object.surfaces:
|
|
||||||
surface = OrderedDict()
|
|
||||||
surface['@id'] = s.name
|
|
||||||
surface['@ShortWaveReflectance'] = s.swr
|
|
||||||
for j in range(len(s.points - 1)):
|
|
||||||
points = self._correct_points(s.points[j])
|
|
||||||
vertex = OrderedDict()
|
|
||||||
vertex['@x'] = points[0]
|
|
||||||
vertex['@y'] = points[1]
|
|
||||||
vertex['@z'] = points[2]
|
|
||||||
surface['V' + str(j)] = vertex
|
|
||||||
if s.type == 'Wall':
|
|
||||||
walls.append(surface)
|
|
||||||
elif s.type == 'Roof':
|
|
||||||
roofs.append(surface)
|
|
||||||
else:
|
else:
|
||||||
floors.append(surface)
|
i = (total_days+day-1)*24 + hour - 1
|
||||||
|
representative_building = self._city.buildings[0]
|
||||||
building['Wall'] = walls
|
content += str(day) + ' ' + str(month) + ' ' + str(hour) + ' ' \
|
||||||
building['Roof'] = roofs
|
+ str(representative_building.global_horizontal['hour'].epw[i]) + ' ' \
|
||||||
building['Floor'] = floors
|
+ str(representative_building.beam['hour'].epw[i]) + '\n'
|
||||||
buildings.append(building)
|
with open(file, "w") as file:
|
||||||
|
file.write(content)
|
||||||
district = OrderedDict()
|
|
||||||
district['FarFieldObstructions'] = None
|
|
||||||
district['Building'] = buildings
|
|
||||||
self._content['CitySim']['District'] = district
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@property
|
|
||||||
def city(self):
|
|
||||||
with open(self._full_path_cli, 'r') as file:
|
|
||||||
return file.readline().replace('\n', '')
|
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ from subprocess import SubprocessError, TimeoutExpired, CalledProcessError
|
||||||
|
|
||||||
from insel.insel import Insel
|
from insel.insel import Insel
|
||||||
from insel.templates.monthly_energy_balance import MonthlyEnergyBalance as templates
|
from insel.templates.monthly_energy_balance import MonthlyEnergyBalance as templates
|
||||||
from factories.geometry_factory import GeometryFactory
|
from imports.geometry_factory import GeometryFactory
|
||||||
from populate import Populate
|
from populate import Populate
|
||||||
from factories.weather_factory import WeatherFactory
|
from imports.weather_factory import WeatherFactory
|
||||||
from helpers import monthly_values as mv
|
from helpers import monthly_values as mv
|
||||||
from simplified_radiosity_algorithm.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm as sralgorithm
|
from simplified_radiosity_algorithm.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm as sralgorithm
|
||||||
from city_model_structure.city import City
|
from city_model_structure.city import City
|
||||||
|
@ -32,7 +32,7 @@ class TestMebWorkflow(TestCase):
|
||||||
self._example_path = (Path(__file__).parent.parent / 'tests_data').resolve()
|
self._example_path = (Path(__file__).parent.parent / 'tests_data').resolve()
|
||||||
self._geometry_type = 'citygml'
|
self._geometry_type = 'citygml'
|
||||||
self._use_cached_sra_file = False
|
self._use_cached_sra_file = False
|
||||||
self._input_geometry_file = (self._example_path / 'gis' / '2050 bp_2buildings.gml').resolve()
|
self._input_geometry_file = (self._example_path / 'gis' / '2050_bp_2buildings.gml').resolve()
|
||||||
self._project_folder = Path(__file__).parent.parent
|
self._project_folder = Path(__file__).parent.parent
|
||||||
self._cli_weather_file = (self._example_path / 'weather' / 'inseldb_new_york_city.cli').resolve()
|
self._cli_weather_file = (self._example_path / 'weather' / 'inseldb_new_york_city.cli').resolve()
|
||||||
self._city_gml = None
|
self._city_gml = None
|
||||||
|
@ -67,10 +67,10 @@ class TestMebWorkflow(TestCase):
|
||||||
if self._city_with_weather is None:
|
if self._city_with_weather is None:
|
||||||
self._city_with_weather = self._get_citygml(use_pickle=use_pickle)
|
self._city_with_weather = self._get_citygml(use_pickle=use_pickle)
|
||||||
weather_path = (self._example_path / 'weather').resolve()
|
weather_path = (self._example_path / 'weather').resolve()
|
||||||
WeatherFactory('dat', self._city_with_weather, city_name=self._city_name, base_path=weather_path)
|
WeatherFactory('epw', self._city_with_weather, base_path=weather_path)
|
||||||
for building in self._city_with_weather.buildings:
|
for building in self._city_with_weather.buildings:
|
||||||
building.external_temperature['month'] = mv.MonthlyValues(). \
|
building.external_temperature['month'] = mv.MonthlyValues(). \
|
||||||
get_mean_values(building.external_temperature['hour'][['inseldb']])
|
get_mean_values(building.external_temperature['hour'][['epw']])
|
||||||
|
|
||||||
sra_file_name = 'SRA'
|
sra_file_name = 'SRA'
|
||||||
sra = sralgorithm(Path(self._project_folder).resolve(), sra_file_name, Path(self._cli_weather_file).resolve(),
|
sra = sralgorithm(Path(self._project_folder).resolve(), sra_file_name, Path(self._cli_weather_file).resolve(),
|
||||||
|
@ -85,9 +85,9 @@ class TestMebWorkflow(TestCase):
|
||||||
def _get_cli_single_building(self, building_name, radius, use_pickle):
|
def _get_cli_single_building(self, building_name, radius, use_pickle):
|
||||||
self._city_with_cli = self._get_citygml(use_pickle=use_pickle)
|
self._city_with_cli = self._get_citygml(use_pickle=use_pickle)
|
||||||
building = self._city_with_cli.city_object(building_name)
|
building = self._city_with_cli.city_object(building_name)
|
||||||
new_city = self._city_with_cli.region(building.location, radius)
|
new_city = self._city_with_cli.region(building.centroid, radius)
|
||||||
sra_file_name = 'SRA'
|
sra_file_name = 'SRA'
|
||||||
print('location', building.location)
|
print('location', building.centroid)
|
||||||
print('lower corner', new_city.lower_corner)
|
print('lower corner', new_city.lower_corner)
|
||||||
full_path_cli = (self._example_path / 'weather' / 'inseldb_Summerland.cli').resolve()
|
full_path_cli = (self._example_path / 'weather' / 'inseldb_Summerland.cli').resolve()
|
||||||
sra = sralgorithm(Path(self._project_folder).resolve(), sra_file_name, full_path_cli, new_city.city_objects,
|
sra = sralgorithm(Path(self._project_folder).resolve(), sra_file_name, full_path_cli, new_city.city_objects,
|
||||||
|
@ -96,16 +96,6 @@ class TestMebWorkflow(TestCase):
|
||||||
sra.set_irradiance_surfaces(self._city_with_cli, building_name=building_name)
|
sra.set_irradiance_surfaces(self._city_with_cli, building_name=building_name)
|
||||||
return self._city_with_cli
|
return self._city_with_cli
|
||||||
|
|
||||||
def _get_city_with_dat(self, use_pickle):
|
|
||||||
if self._city_with_dat is None:
|
|
||||||
self._city_with_dat = self._get_citygml(use_pickle=use_pickle)
|
|
||||||
weather_path = (self._example_path / 'weather').resolve()
|
|
||||||
WeatherFactory('dat', self._city_with_dat, city_name=self._city_name, base_path=weather_path)
|
|
||||||
for building in self._city_with_dat.buildings:
|
|
||||||
building.external_temperature['month'] = mv.MonthlyValues(). \
|
|
||||||
get_mean_values(building.external_temperature['hour'][['inseldb']])
|
|
||||||
return self._city_with_dat
|
|
||||||
|
|
||||||
def test_populate_city(self):
|
def test_populate_city(self):
|
||||||
"""
|
"""
|
||||||
Test populate class
|
Test populate class
|
||||||
|
|
|
@ -420,7 +420,7 @@
|
||||||
</Solid>
|
</Solid>
|
||||||
</lod1Solid>
|
</lod1Solid>
|
||||||
<yearOfConstruction>1965</yearOfConstruction>
|
<yearOfConstruction>1965</yearOfConstruction>
|
||||||
<function>I1</function>
|
<function>residential</function>
|
||||||
</Building>
|
</Building>
|
||||||
</cityObjectMember>
|
</cityObjectMember>
|
||||||
<cityObjectMember>
|
<cityObjectMember>
|
||||||
|
@ -620,7 +620,7 @@
|
||||||
</Solid>
|
</Solid>
|
||||||
</lod1Solid>
|
</lod1Solid>
|
||||||
<yearOfConstruction>2045</yearOfConstruction>
|
<yearOfConstruction>2045</yearOfConstruction>
|
||||||
<function>I1</function>
|
<function>residential</function>
|
||||||
</Building>
|
</Building>
|
||||||
</cityObjectMember>
|
</cityObjectMember>
|
||||||
</CityModel>
|
</CityModel>
|
Loading…
Reference in New Issue
Block a user