ep and units are fixed
This commit is contained in:
parent
ee7ff91410
commit
ad48b4432d
Binary file not shown.
|
@ -54,14 +54,6 @@ class Idf:
|
|||
_SIZING_PERIODS = 'SIZINGPERIOD:DESIGNDAY'
|
||||
_LOCATION = 'SITE:LOCATION'
|
||||
_SIMPLE = 'Simple'
|
||||
_EQUIPMENT_CONNECTIONS = 'ZONEHVAC:EQUIPMENTCONNECTIONS'
|
||||
_NODE_LIST = 'NODELIST'
|
||||
_BASEBOARD = 'ZONEHVAC:BASEBOARD:CONVECTIVE:ELECTRIC'
|
||||
_AIR_TERMINAL_NO_REHEAT = 'AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:NOREHEAT'
|
||||
_AIR_DISTRIBUTION = 'ZONEHVAC:AIRDISTRIBUTIONUNIT'
|
||||
_EQUIPMENT_LIST = 'ZONEHVAC:EQUIPMENTLIST'
|
||||
_SIZING_ZONE = 'SIZING:ZONE'
|
||||
_DESIGN_SPECIFICATION_OUTDOOR_AIR = 'DESIGNSPECIFICATION:OUTDOORAIR'
|
||||
|
||||
idf_surfaces = {
|
||||
cte.WALL: 'wall',
|
||||
|
@ -125,8 +117,7 @@ class Idf:
|
|||
if levels_of_detail.construction is None:
|
||||
raise AttributeError('Level of detail of construction not assigned')
|
||||
if levels_of_detail.construction < 2:
|
||||
raise AttributeError(
|
||||
f'Level of detail of construction = {levels_of_detail.construction}. Required minimum level 2')
|
||||
raise AttributeError(f'Level of detail of construction = {levels_of_detail.construction}. Required minimum level 2')
|
||||
if levels_of_detail.usage is None:
|
||||
raise AttributeError('Level of detail of usage not assigned')
|
||||
if levels_of_detail.usage < 2:
|
||||
|
@ -357,7 +348,7 @@ class Idf:
|
|||
def _add_window_construction_and_material(self, thermal_opening):
|
||||
for window_material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]:
|
||||
if window_material['UFactor'] == thermal_opening.overall_u_value and \
|
||||
window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value:
|
||||
window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value:
|
||||
return
|
||||
|
||||
order = str(len(self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]) + 1)
|
||||
|
@ -390,86 +381,22 @@ class Idf:
|
|||
)
|
||||
|
||||
def _add_heating_system(self, thermal_zone, zone_name):
|
||||
for air_system in self._idf.idfobjects[self._EQUIPMENT_CONNECTIONS]:
|
||||
for air_system in self._idf.idfobjects[self._IDEAL_LOAD_AIR_SYSTEM]:
|
||||
if air_system.Zone_Name == zone_name:
|
||||
return
|
||||
thermostat = self._add_thermostat(thermal_zone)
|
||||
self._idf.newidfobject(self._EQUIPMENT_CONNECTIONS,
|
||||
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
|
||||
Zone_Name=zone_name,
|
||||
Zone_Conditioning_Equipment_List_Name=f'{zone_name} Equipment List',
|
||||
Zone_Air_Inlet_Node_or_NodeList_Name=f'{zone_name} Inlet Node List',
|
||||
Zone_Air_Node_Name=f'Node 1',
|
||||
Zone_Return_Air_Node_or_NodeList_Name=f'{zone_name} Return Node List')
|
||||
|
||||
def _add_nodelist_system(self, thermal_zone, zone_name):
|
||||
self._idf.newidfobject(self._NODE_LIST,
|
||||
Name=f'{zone_name} Inlet Node List',
|
||||
Node_1_Name='Node 2')
|
||||
self._idf.newidfobject(self._NODE_LIST,
|
||||
Name=f'{zone_name} Return Node List',
|
||||
Node_1_Name='Node 3')
|
||||
|
||||
def _add_baseboard_system(self, thermal_zone, zone_name):
|
||||
for baseboard in self._idf.idfobjects[self._BASEBOARD]:
|
||||
if baseboard.Zone_Name == zone_name:
|
||||
return
|
||||
self._idf.newidfobject(self._BASEBOARD, Name=f'Elec Baseboard',Availability_Schedule_Name='HVAC AVAIL')
|
||||
|
||||
def _add_air_terminal_system(self, thermal_zone, zone_name):
|
||||
"""for air_terminal in self._idf.idfobjects[self._AIR_TERMINAL_NO_REHEAT]:
|
||||
if air_terminal.Zone_Name == zone_name:
|
||||
return"""
|
||||
self._idf.newidfobject(self._AIR_TERMINAL_NO_REHEAT, Name=f'Diffuser',
|
||||
Availability_Schedule_Name='HVAC AVAIL',
|
||||
Air_Inlet_Node_Name='Node 4',
|
||||
Air_Outlet_Node_Name='Node 2',
|
||||
Maximum_Air_Flow_Rate='AutoSize')
|
||||
|
||||
def _add_air_distribution_system(self, thermal_zone, zone_name):
|
||||
for air_distribution in self._idf.idfobjects[self._AIR_DISTRIBUTION]:
|
||||
if air_distribution.Zone_Name == zone_name:
|
||||
return
|
||||
self._idf.newidfobject(self._AIR_DISTRIBUTION,
|
||||
Name='ADU Diffuser',
|
||||
Air_Distribution_Unit_Outlet_Node_Name='Node 2',
|
||||
Air_Terminal_Object_Type='AirTerminal:SingleDuct:ConstantVolume:NoReheat',
|
||||
Air_Terminal_Name='Diffuser')
|
||||
|
||||
def _add_equipment_list_system(self, thermal_zone, zone_name):
|
||||
for air_distribution in self._idf.idfobjects[self._EQUIPMENT_LIST]:
|
||||
if air_distribution.Zone_Name == zone_name:
|
||||
return
|
||||
self._idf.newidfobject(self._EQUIPMENT_LIST,
|
||||
Name=f'{zone_name} Equipment List',
|
||||
Load_Distribution_Scheme='SequentialLoad',
|
||||
Zone_Equipment_1_Object_Type='ZoneHVAC:Baseboard:Convective:Electric',
|
||||
Zone_Equipment_1_Name='Elec Baseboard',
|
||||
Zone_Equipment_1_Cooling_Sequence='1',
|
||||
Zone_Equipment_1_Heating_or_NoLoad_Sequence='1',
|
||||
Zone_Equipment_2_Object_Type='ZoneHVAC:AirDistributionUnit',
|
||||
Zone_Equipment_2_Name='ADU Diffuser',
|
||||
Zone_Equipment_2_Cooling_Sequence='2',
|
||||
Zone_Equipment_2_Heating_or_NoLoad_Sequence='2'
|
||||
)
|
||||
|
||||
def _add_sizing_zone(self, thermal_zone, zone_name):
|
||||
koa=self._idf.newidfobject(self._SIZING_ZONE,
|
||||
Zone_or_ZoneList_Name=f'{zone_name}',
|
||||
Zone_Cooling_Design_Supply_Air_Humidity_Ratio='0.0085',
|
||||
Zone_Heating_Design_Supply_Air_Humidity_Ratio='0.008'
|
||||
)
|
||||
|
||||
def _add_outdoor_air_design_specification(self, thermal_zone, zone_name):
|
||||
self._idf.newidfobject(self._DESIGN_SPECIFICATION_OUTDOOR_AIR,
|
||||
Name='MidriseApartment Apartment Ventilation',
|
||||
Outdoor_Air_Method='Sum',
|
||||
Outdoor_Air_Flow_per_Person='0.0169901079552')
|
||||
System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
|
||||
Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
|
||||
Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
|
||||
Template_Thermostat_Name=thermostat.Name)
|
||||
|
||||
def _add_occupancy(self, thermal_zone, zone_name):
|
||||
number_of_people = thermal_zone.occupancy.occupancy_density * thermal_zone.total_floor_area
|
||||
fraction_radiant = 0
|
||||
total_sensible = (
|
||||
thermal_zone.occupancy.sensible_radiative_internal_gain + thermal_zone.occupancy.sensible_convective_internal_gain
|
||||
thermal_zone.occupancy.sensible_radiative_internal_gain + thermal_zone.occupancy.sensible_convective_internal_gain
|
||||
)
|
||||
if total_sensible != 0:
|
||||
fraction_radiant = thermal_zone.occupancy.sensible_radiative_internal_gain / total_sensible
|
||||
|
@ -626,6 +553,10 @@ class Idf:
|
|||
self._add_zone(thermal_zone, building.name)
|
||||
self._add_heating_system(thermal_zone, building.name)
|
||||
self._add_infiltration(thermal_zone, building.name)
|
||||
self._add_ventilation(thermal_zone, building.name)
|
||||
self._add_occupancy(thermal_zone, building.name)
|
||||
self._add_lighting(thermal_zone, building.name)
|
||||
self._add_appliances(thermal_zone, building.name)
|
||||
self._add_dhw(thermal_zone, building.name)
|
||||
if self._export_type == "Surfaces":
|
||||
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
|
||||
|
@ -679,6 +610,7 @@ class Idf:
|
|||
windows_list.append(window)
|
||||
for window in windows_list:
|
||||
self._idf.removeidfobject(window)
|
||||
|
||||
self._idf.saveas(str(self._output_file))
|
||||
return self._idf
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
! HVAC: None.
|
||||
!
|
||||
|
||||
Version,24.1;
|
||||
Version,23.2;
|
||||
|
||||
Timestep,4;
|
||||
|
||||
|
@ -122,30 +122,36 @@
|
|||
No, !- Do Zone Sizing Calculation
|
||||
No, !- Do System Sizing Calculation
|
||||
No, !- Do Plant Sizing Calculation
|
||||
Yes, !- Run Simulation for Sizing Periods
|
||||
No, !- Run Simulation for Weather File Run Periods
|
||||
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:VariableDictionary,Regular;
|
||||
Output:Table:SummaryReports, AnnualBuildingUtilityPerformanceSummary,
|
||||
DemandEndUseComponentsSummary,
|
||||
SensibleHeatGainSummary,
|
||||
InputVerificationandResultsSummary,
|
||||
AdaptiveComfortSummary,
|
||||
Standard62.1Summary,
|
||||
ClimaticDataSummary,
|
||||
EquipmentSummary,
|
||||
EnvelopeSummary,
|
||||
LightingSummary,
|
||||
HVACSizingSummary,
|
||||
SystemSummary,
|
||||
ComponentSizingSummary,
|
||||
OutdoorAirSummary,
|
||||
ObjectCountSummary,
|
||||
EndUseEnergyConsumptionOtherFuelsMonthly,
|
||||
PeakEnergyEndUseOtherFuelsMonthly;
|
||||
|
||||
Output:Variable,*,Site Outdoor Air Drybulb Temperature,Timestep;
|
||||
|
||||
Output:Variable,*,Site Outdoor Air Wetbulb Temperature,Timestep;
|
||||
OutputControl:Table:Style, CommaAndHTML,JtoKWH;
|
||||
|
||||
Output:Variable,*,Site Outdoor Air Dewpoint Temperature,Timestep;
|
||||
|
||||
Output:Variable,*,Site Solar Azimuth Angle,Timestep;
|
||||
|
||||
Output:Variable,*,Site Solar Altitude Angle,Timestep;
|
||||
|
||||
Output:Variable,*,Site Direct Solar Radiation Rate per Area,Timestep;
|
||||
|
||||
Output:Variable,*,Site Diffuse Solar Radiation Rate per Area,Timestep;
|
||||
|
||||
OutputControl:Table:Style,
|
||||
HTML; !- Column Separator
|
||||
|
||||
Output:Table:SummaryReports,
|
||||
AllSummary; !- Report 1 Name
|
||||
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
|
2
main.py
2
main.py
|
@ -29,7 +29,7 @@ city = GeometryFactory('geojson',
|
|||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
# Enrich city data
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('comnet', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
ExportsFactory('sra', city, output_path).export()
|
||||
sra_path = (output_path / f'{city.name}_sra.xml').resolve()
|
||||
|
|
|
@ -31,18 +31,18 @@ class EnergySystemAnalysisReport:
|
|||
building.name,
|
||||
str(building.year_of_construction),
|
||||
building.function,
|
||||
str(format(building.heating_demand[cte.YEAR][0] / 1e6, '.2f')),
|
||||
str(format(building.cooling_demand[cte.YEAR][0] / 1e6, '.2f')),
|
||||
str(format(building.heating_demand[cte.YEAR][0] / 3.6e9, '.2f')),
|
||||
str(format(building.cooling_demand[cte.YEAR][0] / 3.6e9, '.2f')),
|
||||
str(format(building.domestic_hot_water_heat_demand[cte.YEAR][0] / 1e6, '.2f')),
|
||||
str(format(
|
||||
(building.lighting_electrical_demand[cte.YEAR][0] + building.appliances_electrical_demand[cte.YEAR][0]) / 1e6,
|
||||
'.2f')),
|
||||
(building.lighting_electrical_demand[cte.YEAR][0] + building.appliances_electrical_demand[cte.YEAR][0])
|
||||
/ 1e6, '.2f')),
|
||||
]
|
||||
intensity_data = [
|
||||
building.name,
|
||||
str(format(total_floor_area, '.2f')),
|
||||
str(format(building.heating_demand[cte.YEAR][0] / (1e3 * total_floor_area), '.2f')),
|
||||
str(format(building.cooling_demand[cte.YEAR][0] / (1e3 * total_floor_area), '.2f')),
|
||||
str(format(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area), '.2f')),
|
||||
str(format(building.cooling_demand[cte.YEAR][0] / (3.6e6 * total_floor_area), '.2f')),
|
||||
str(format(
|
||||
(building.lighting_electrical_demand[cte.YEAR][0] + building.appliances_electrical_demand[cte.YEAR][0]) /
|
||||
(1e3 * total_floor_area), '.2f'))
|
||||
|
@ -109,8 +109,8 @@ class EnergySystemAnalysisReport:
|
|||
plt.close()
|
||||
|
||||
building_names = [building.name for building in self.city.buildings]
|
||||
yearly_heating_demand = [building.heating_demand[cte.YEAR][0] / 1e6 for building in self.city.buildings]
|
||||
yearly_cooling_demand = [building.cooling_demand[cte.YEAR][0] / 1e6 for building in self.city.buildings]
|
||||
yearly_heating_demand = [building.heating_demand[cte.YEAR][0] / 3.6e9 for building in self.city.buildings]
|
||||
yearly_cooling_demand = [building.cooling_demand[cte.YEAR][0] / 3.6e9 for building in self.city.buildings]
|
||||
yearly_dhw_demand = [building.domestic_hot_water_heat_demand[cte.YEAR][0] / 1e6 for building in
|
||||
self.city.buildings]
|
||||
yearly_electricity_demand = [(building.lighting_electrical_demand[cte.YEAR][0] +
|
||||
|
@ -139,14 +139,14 @@ class EnergySystemAnalysisReport:
|
|||
axs[0].bar(months, maximum_monthly_heating_load, color='red') # Plot on the first subplot
|
||||
axs[0].set_title('Maximum Monthly Heating Load')
|
||||
axs[0].set_xlabel('Month')
|
||||
axs[0].set_ylabel('Load (kW)')
|
||||
axs[0].set_ylabel('Load (kWh)')
|
||||
axs[0].tick_params(axis='x', rotation=45)
|
||||
|
||||
# Plot maximum monthly cooling load
|
||||
axs[1].bar(months, maximum_monthly_cooling_load, color='blue') # Plot on the second subplot
|
||||
axs[1].set_title('Maximum Monthly Cooling Load')
|
||||
axs[1].set_xlabel('Month')
|
||||
axs[1].set_ylabel('Load (kW)')
|
||||
axs[1].set_ylabel('Load (kWh)')
|
||||
axs[1].tick_params(axis='x', rotation=45)
|
||||
|
||||
plt.tight_layout() # Adjust layout to prevent overlapping
|
||||
|
@ -156,8 +156,8 @@ class EnergySystemAnalysisReport:
|
|||
def load_duration_curves(self):
|
||||
save_directory = self.output_path
|
||||
for building in self.city.buildings:
|
||||
heating_demand = [demand / 1000 for demand in building.heating_demand[cte.HOUR]]
|
||||
cooling_demand = [demand / 1000 for demand in building.cooling_demand[cte.HOUR]]
|
||||
heating_demand = [demand / 3.6e6 for demand in building.heating_demand[cte.HOUR]]
|
||||
cooling_demand = [demand / 3.6e6 for demand in building.cooling_demand[cte.HOUR]]
|
||||
heating_demand_sorted = sorted(heating_demand, reverse=True)
|
||||
cooling_demand_sorted = sorted(cooling_demand, reverse=True)
|
||||
|
||||
|
@ -169,7 +169,7 @@ class EnergySystemAnalysisReport:
|
|||
# Plot sorted heating demand
|
||||
axs[0].plot(heating_demand_sorted, color='red', linewidth=2, label='Heating Demand')
|
||||
axs[0].set_xlabel('Hour', fontsize=14)
|
||||
axs[0].set_ylabel('Heating Demand', fontsize=14)
|
||||
axs[0].set_ylabel('Heating Demand (kWh)', fontsize=14)
|
||||
axs[0].set_title('Heating Load Duration Curve', fontsize=16)
|
||||
axs[0].grid(True)
|
||||
axs[0].legend(loc='upper right', fontsize=12)
|
||||
|
@ -177,7 +177,7 @@ class EnergySystemAnalysisReport:
|
|||
# Plot sorted cooling demand
|
||||
axs[1].plot(cooling_demand_sorted, color='blue', linewidth=2, label='Cooling Demand')
|
||||
axs[1].set_xlabel('Hour', fontsize=14)
|
||||
axs[1].set_ylabel('Cooling Demand', fontsize=14)
|
||||
axs[1].set_ylabel('Cooling Demand (kWh)', fontsize=14)
|
||||
axs[1].set_title('Cooling Load Duration Curve', fontsize=16)
|
||||
axs[1].grid(True)
|
||||
axs[1].legend(loc='upper right', fontsize=12)
|
||||
|
@ -204,7 +204,7 @@ class EnergySystemAnalysisReport:
|
|||
cooling_system = "-"
|
||||
dhw = "-"
|
||||
electricity = "Grid"
|
||||
hvac_ec = format((building.heating_consumption[cte.YEAR][0] + building.cooling_consumption[cte.YEAR][0]) / 1e6,
|
||||
hvac_ec = format((building.heating_consumption[cte.YEAR][0] + building.cooling_consumption[cte.YEAR][0]) / 3.6e9,
|
||||
'.2f')
|
||||
dhw_ec = format(building.domestic_hot_water_consumption[cte.YEAR][0] / 1e6, '.2f')
|
||||
on_site_generation = "-"
|
||||
|
@ -258,11 +258,11 @@ class EnergySystemAnalysisReport:
|
|||
for generation_system in energy_system.generation_systems:
|
||||
consumption = 0
|
||||
if demand_type == cte.HEATING:
|
||||
consumption = building.heating_consumption[cte.YEAR][0] / 1e6
|
||||
consumption = building.heating_consumption[cte.YEAR][0] / 3.6e9
|
||||
elif demand_type == cte.DOMESTIC_HOT_WATER:
|
||||
consumption = building.domestic_hot_water_consumption[cte.YEAR][0] / 1e6
|
||||
elif demand_type == cte.COOLING:
|
||||
consumption = building.cooling_consumption[cte.YEAR][0] / 1e6
|
||||
consumption = building.cooling_consumption[cte.YEAR][0] / 3.6e9
|
||||
|
||||
if generation_system.fuel_type == cte.ELECTRICITY:
|
||||
fuel_breakdown[demand_type]["Electricity"] += consumption
|
||||
|
|
Loading…
Reference in New Issue
Block a user