partial matsim implementation

This commit is contained in:
Guille Gutierrez 2024-04-03 12:34:09 +02:00
parent 039a0f30ba
commit c6f6498a23
6 changed files with 201 additions and 103689 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,157 +0,0 @@
! Minimal.idf
! Basic file description: This is a minimal configuration necessary to run.
! Highlights: Illustrates minimal items necessary to perform run.
! BUILDING, SURFACEGEOMETRY, LOCATION and DESIGNDAY (or RUNPERIOD) are the absolute minimal required input objects.
! TIME STEP IN HOUR is included so as to not get warning error.
! Including two design days, Run Control object and RunPeriod to facilitate use.
! Although not incredibly useful, this could be used as a weather/solar calculator.
! Simulation Location/Run: Denver is included. Any could be used.
! Building: None.
!
! Internal gains description: None.
!
! HVAC: None.
!
Version,9.5;
Timestep,4;
Building,
None, !- Name
0.0000000E+00, !- North Axis {deg}
Suburbs, !- Terrain
0.04, !- Loads Convergence Tolerance Value {W}
0.40, !- Temperature Convergence Tolerance Value {deltaC}
FullInteriorAndExterior, !- Solar Distribution
25, !- Maximum Number of Warmup Days
6; !- Minimum Number of Warmup Days
GlobalGeometryRules,
UpperLeftCorner, !- Starting Vertex Position
CounterClockWise, !- Vertex Entry Direction
World; !- Coordinate System
Site:Location,
DENVER_STAPLETON_CO_USA_WMO_724690, !- Name
39.77, !- Latitude {deg}
-104.87, !- Longitude {deg}
-7.00, !- Time Zone {hr}
1611.00; !- Elevation {m}
! DENVER_STAPLETON_CO_USA Annual Heating Design Conditions Wind Speed=2.3m/s Wind Dir=180
! Coldest Month=December
! DENVER_STAPLETON_CO_USA Annual Heating 99.6%, MaxDB=-20°C
SizingPeriod:DesignDay,
DENVER_STAPLETON Ann Htg 99.6% Condns DB, !- Name
12, !- Month
21, !- Day of Month
WinterDesignDay, !- Day Type
-20, !- Maximum Dry-Bulb Temperature {C}
0.0, !- Daily Dry-Bulb Temperature Range {deltaC}
, !- Dry-Bulb Temperature Range Modifier Type
, !- Dry-Bulb Temperature Range Modifier Day Schedule Name
Wetbulb, !- Humidity Condition Type
-20, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C}
, !- Humidity Condition Day Schedule Name
, !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir}
, !- Enthalpy at Maximum Dry-Bulb {J/kg}
, !- Daily Wet-Bulb Temperature Range {deltaC}
83411., !- Barometric Pressure {Pa}
2.3, !- Wind Speed {m/s}
180, !- Wind Direction {deg}
No, !- Rain Indicator
No, !- Snow Indicator
No, !- Daylight Saving Time Indicator
ASHRAEClearSky, !- Solar Model Indicator
, !- Beam Solar Day Schedule Name
, !- Diffuse Solar Day Schedule Name
, !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless}
, !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless}
0.00; !- Sky Clearness
! DENVER_STAPLETON Annual Cooling Design Conditions Wind Speed=4m/s Wind Dir=120
! Hottest Month=July
! DENVER_STAPLETON_CO_USA Annual Cooling (DB=>MWB) .4%, MaxDB=34.1°C MWB=15.8°C
SizingPeriod:DesignDay,
DENVER_STAPLETON Ann Clg .4% Condns DB=>MWB, !- Name
7, !- Month
21, !- Day of Month
SummerDesignDay, !- Day Type
34.1, !- Maximum Dry-Bulb Temperature {C}
15.2, !- Daily Dry-Bulb Temperature Range {deltaC}
, !- Dry-Bulb Temperature Range Modifier Type
, !- Dry-Bulb Temperature Range Modifier Day Schedule Name
Wetbulb, !- Humidity Condition Type
15.8, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C}
, !- Humidity Condition Day Schedule Name
, !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir}
, !- Enthalpy at Maximum Dry-Bulb {J/kg}
, !- Daily Wet-Bulb Temperature Range {deltaC}
83411., !- Barometric Pressure {Pa}
4, !- Wind Speed {m/s}
120, !- Wind Direction {deg}
No, !- Rain Indicator
No, !- Snow Indicator
No, !- Daylight Saving Time Indicator
ASHRAEClearSky, !- Solar Model Indicator
, !- Beam Solar Day Schedule Name
, !- Diffuse Solar Day Schedule Name
, !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless}
, !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless}
1.00; !- Sky Clearness
RunPeriod,
Run Period 1, !- Name
1, !- Begin Month
1, !- Begin Day of Month
, !- Begin Year
12, !- End Month
31, !- End Day of Month
, !- End Year
Tuesday, !- Day of Week for Start Day
Yes, !- Use Weather File Holidays and Special Days
Yes, !- Use Weather File Daylight Saving Period
No, !- Apply Weekend Holiday Rule
Yes, !- Use Weather File Rain Indicators
Yes; !- Use Weather File Snow Indicators
SimulationControl,
No, !- Do Zone Sizing Calculation
No, !- Do System Sizing Calculation
No, !- Do Plant Sizing Calculation
No, !- Run Simulation for Sizing Periods
Yes, !- Run Simulation for Weather File Run Periods
No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes
Output:Table:SummaryReports, AnnualBuildingUtilityPerformanceSummary,
DemandEndUseComponentsSummary,
SensibleHeatGainSummary,
InputVerificationandResultsSummary,
AdaptiveComfortSummary,
Standard62.1Summary,
ClimaticDataSummary,
EquipmentSummary,
EnvelopeSummary,
LightingSummary,
HVACSizingSummary,
SystemSummary,
ComponentSizingSummary,
OutdoorAirSummary,
ObjectCountSummary,
EndUseEnergyConsumptionOtherFuelsMonthly,
PeakEnergyEndUseOtherFuelsMonthly;
OutputControl:Table:Style, CommaAndHTML,JtoKWH;
Output:Meter,DISTRICTHEATING:Facility,hourly;
Output:Meter,DISTRICTCOOLING:Facility,hourly;
Output:Meter,InteriorEquipment:Electricity,hourly;
Output:Meter,InteriorLights:Electricity,hourly;
OutputControl:IlluminanceMap:Style,
Comma; !- Column separator

View File

View File

View File

@ -0,0 +1,162 @@
import gzip
import math
import shutil
import geopandas as gpd
from lxml import etree
from shapely import Polygon
class Matsim:
_x = 0
_y = 1
_z = 2
def __init__(self, city, output_file_path):
self._city = city
self._output_file_path = output_file_path
self._crs = city.c
self._facilities = {
'name': self._city.name + ' Facilities',
'facility': []
}
self._export()
def _export(self):
self._export_facilities()
self._export_network()
self._export_population()
self._export_config()
def _export_facilities(self):
"""
Exports the city's facilities data to XML and shapefile formats.
"""
facilities_xml = etree.Element('facilities', name=self._facilities['name'])
for building in self._city.buildings:
try:
facility = {
'id': building.name,
'x': str(building.centroid[0]),
'y': str(building.centroid[1]),
'activity': []
}
if len(building.thermal_zones_from_internal_zones) > 1:
raise NotImplementedError('multi-zone buildings aren\'t yet supported')
building_schedules = []
capacity = 0
for thermal_zone in building.thermal_zones_from_internal_zones:
capacity = thermal_zone.occupancy.occupancy_density * building.floor_area * building.storeys_above_ground
for schedule in thermal_zone.occupancy.occupancy_schedules:
building_schedules.append(schedule)
activity_info = {
'type': building.function,
'capacity': math.ceil(capacity),
'opentime': Matsim._convert_schedules(building_schedules)
}
facility_xml = etree.SubElement(facilities_xml, 'facility', {
'id': f'{facility["id"]}',
'x': f'{facility["x"]}',
'y': f'{facility["y"]}',
})
activity_xml = etree.SubElement(facility_xml, 'activity', {
'type': f'{activity_info["type"]}'
})
etree.SubElement(activity_xml, 'capacity', {
'value': f'{activity_info["capacity"]}'
})
etree.SubElement(activity_xml, 'opentime', {
'day': f'{activity_info["opentime"][0]["day"]}',
'start_time': f'{activity_info["opentime"][0]["start_time"]}',
'end_time': f'{activity_info["opentime"][0]["end_time"]}'
})
facility['activity'].append(activity_info)
self._facilities['facility'].append(facility)
except Exception as ex:
print('error: ', ex)
# todo: this may be changed to
viewport = Polygon([
(self._city.lower_corner[self._x], self._city.upper_corner[self._y]),
(self._city.upper_corner[self._x], self._city.upper_corner[self._y]),
(self._city.upper_corner[self._x], self._city.lower_corner[self._y]),
(self._city.lower_corner[self._x], self._city.lower_corner[self._y])])
gdf = gpd.GeoDataFrame(
geometry=[viewport],
crs=self._city.srs_name
)
gdf.to_file(f'{self._output_file_path}/buildings_shapefile.shp')
# Write xml content to file
xml_content = etree.tostring(facilities_xml, pretty_print=True, encoding='UTF-8').decode('utf-8')
output_file = f'{self._output_file_path}/{self._city.name}_facilities.xml'
xml_dtd = '<!DOCTYPE facilities SYSTEM "http://www.matsim.org/files/dtd/facilities_v1.dtd">\n'
Matsim._save_xml(output_file, xml_content, xml_dtd)
@staticmethod
def _convert_schedules(building_schedules):
"""
Converts building schedules into a format suitable for facilities.xml.
:param building_schedules: A list of building schedule objects to be converted.
:return: A list of dictionaries, each representing the converted schedule for a building.
"""
converted_schedules = []
opening_hour = 0
closing_hour = 0
schedule = building_schedules[0]
for i, value in enumerate(schedule.values):
if value > 0:
opening_hour = i
break
for i, value in reversed(list(enumerate(schedule.values))):
if value > 0:
closing_hour = i
break
for day in schedule.day_types:
if day[0:3] != 'hol':
converted_schedules.append({
'day': day[0:3],
'start_time': f"{opening_hour:02}:00:00",
'end_time': f"{closing_hour:02}:00:00"
})
return converted_schedules
@staticmethod
def _save_xml(output_file, xml_content, xml_dtd=None):
"""
Saves XML content to a file, optionally adding a DOCTYPE declaration and compressing the file.
:param output_file: The path where the XML file will be saved.
:param xml_content: The XML content to be written to the file.
:param xml_dtd: An optional DOCTYPE declaration to be included at the beginning of the file.
"""
if xml_dtd is None:
xml_dtd = ''
with open(output_file, 'w') as file:
file.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
file.write(xml_dtd)
file.write(xml_content)
with open(output_file, 'rb') as f_in:
with gzip.open(output_file + '.gz', 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)

View File

@ -0,0 +1,39 @@
"""
Traffic factory export a city traffic information into several formats
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from pathlib import Path
from hub.exports.traffic.matsim import Matsim
from hub.helpers.utils import validate_import_export_type
class TrafficFactory:
"""
Exports factory class
"""
def __init__(self, handler, city, path):
self._city = city
self._handler = '_' + handler.lower()
validate_import_export_type(TrafficFactory, handler)
if isinstance(path, str):
path = Path(path)
self._path = path
@property
def _matsim(self):
"""
Export the city traffic information to Matsim
:return: None
"""
return Matsim(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._handler, lambda: None)