openstudio-standards 0.2.17.rc1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +5 -0
- data/lib/openstudio-standards/btap/btap_result.rb +138 -138
- data/lib/openstudio-standards/btap/economics.rb +58 -53
- data/lib/openstudio-standards/btap/envelope.rb +1 -1
- data/lib/openstudio-standards/btap/fileio.rb +12 -12
- data/lib/openstudio-standards/btap/measures.rb +63 -59
- data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +5 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +8 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +9 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +53 -23
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +15 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +18 -18
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +5 -5
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +3 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +43 -40
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.entryways.json +19 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.parking.json +13 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +5 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +5 -1
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +8 -4
- data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +8 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +7 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +4 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +5 -0
- metadata +4 -2
@@ -19,21 +19,18 @@ class Standard
|
|
19
19
|
# @note Per 90.1, the Performance Rating Method "does NOT offer an alternative compliance path for minimum standard compliance."
|
20
20
|
# This means you can't use this method for code compliance to get a permit.
|
21
21
|
# @param user_model [OpenStudio::model::Model] User specified OpenStudio model
|
22
|
-
# @param building_type [String] the building type
|
23
22
|
# @param climate_zone [String] the climate zone
|
24
23
|
# @param hvac_building_type [String] the building type for baseline HVAC system determination (90.1-2016 and onward)
|
25
24
|
# @param wwr_building_type [String] the building type for baseline WWR determination (90.1-2016 and onward)
|
26
25
|
# @param swh_building_type [String] the building type for baseline SWH determination (90.1-2016 and onward)
|
27
|
-
# @param
|
28
|
-
# If nothing is specified, no custom logic will be applied; the process will follow the template logic explicitly.
|
29
|
-
# @param sizing_run_dir [String] the directory where the sizing runs will be performed
|
26
|
+
# @param output_dir [String] the directory where the PRM generations will be performed
|
30
27
|
# @param run_all_orients [Boolean] indicate weather a baseline model should be created for all 4 orientations: same as user model, +90 deg, +180 deg, +270 deg
|
31
28
|
# @param debug [Boolean] If true, will report out more detailed debugging output
|
32
29
|
# @return [Bool] returns true if successful, false if not
|
33
30
|
|
34
31
|
# Method used for 90.1-2016 and onward
|
35
|
-
def model_create_prm_stable_baseline_building(model,
|
36
|
-
model_create_prm_any_baseline_building(model,
|
32
|
+
def model_create_prm_stable_baseline_building(model, climate_zone, hvac_building_type, wwr_building_type, swh_building_type, output_dir = Dir.pwd, unmet_load_hours_check = true, debug = false)
|
33
|
+
model_create_prm_any_baseline_building(model, '', climate_zone, hvac_building_type, wwr_building_type, swh_building_type, true, false, output_dir, true, unmet_load_hours_check, debug)
|
37
34
|
end
|
38
35
|
|
39
36
|
# Creates a Performance Rating Method (aka Appendix G aka LEED) baseline building model
|
@@ -77,6 +74,9 @@ class Standard
|
|
77
74
|
OpenStudio.logFree(OpenStudio::Error, 'prm.log', "Proposed model unmet load hours exceed 300. Baseline model(s) won't be created.")
|
78
75
|
raise "Proposed model unmet load hours exceed 300. Baseline model(s) won't be created."
|
79
76
|
end
|
77
|
+
else
|
78
|
+
OpenStudio.logFree(OpenStudio::Error, 'prm.log', "Simulation failed. Check the model to make sure no severe errors.")
|
79
|
+
raise "Simulation on proposed model failed. Baseline generation is stopped."
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -1885,9 +1885,9 @@ class Standard
|
|
1885
1885
|
# separate the primary zones from the secondary zones.
|
1886
1886
|
# Add the baseline system type to the primary zones
|
1887
1887
|
# and add the suplemental system type to the secondary zones.
|
1888
|
-
story_zone_lists.each do |
|
1888
|
+
story_zone_lists.each do |story_group|
|
1889
1889
|
# Differentiate primary and secondary zones
|
1890
|
-
pri_sec_zone_lists = model_differentiate_primary_secondary_thermal_zones(model, story_group
|
1890
|
+
pri_sec_zone_lists = model_differentiate_primary_secondary_thermal_zones(model, story_group)
|
1891
1891
|
# Record the primary zone system types
|
1892
1892
|
pri_sec_zone_lists['primary'].each do |zone|
|
1893
1893
|
zone_to_sys_type[zone] = pri_system_type
|
@@ -6926,7 +6926,7 @@ class Standard
|
|
6926
6926
|
# include data source from:
|
6927
6927
|
# 1. user data csv files
|
6928
6928
|
# 2. data from measure and OpenStudio interface
|
6929
|
-
# @param [
|
6929
|
+
# @param [OpenStudio:model:Model] model
|
6930
6930
|
# @param [String] climate_zone
|
6931
6931
|
# @param [String] default_hvac_building_type
|
6932
6932
|
# @param [String] default_wwr_building_type
|
@@ -6940,7 +6940,7 @@ class Standard
|
|
6940
6940
|
# Template method for adding a setpoint manager for a coil control logic to a heating coil.
|
6941
6941
|
# ASHRAE 90.1-2019 Appendix G.
|
6942
6942
|
#
|
6943
|
-
# @param model [OpenStudio::Model::Model]
|
6943
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6944
6944
|
# @param thermalZones Array([OpenStudio::Model::ThermalZone]) thermal zone array
|
6945
6945
|
# @param coil Heating Coils
|
6946
6946
|
# @return [Boolean] true
|
@@ -6951,7 +6951,7 @@ class Standard
|
|
6951
6951
|
# Template method for adding zone additional property "zone DCV implemented in user model"
|
6952
6952
|
#
|
6953
6953
|
# @author Xuechen (Jerry) Lei, PNNL
|
6954
|
-
# @param model [OpenStudio::Model::Model]
|
6954
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6955
6955
|
def model_mark_zone_dcv_existence(model)
|
6956
6956
|
return true
|
6957
6957
|
end
|
@@ -6960,7 +6960,7 @@ class Standard
|
|
6960
6960
|
# The default shall be true
|
6961
6961
|
#
|
6962
6962
|
# @param [Boolean] run_all_orients: user inputs to indicate whether it is required to run all orientations
|
6963
|
-
# @param [OpenStudio::Model::Model]
|
6963
|
+
# @param [OpenStudio::Model::Model] OpenStudio model
|
6964
6964
|
def run_all_orientations(run_all_orients, user_model)
|
6965
6965
|
return run_all_orients
|
6966
6966
|
end
|
@@ -6968,7 +6968,7 @@ class Standard
|
|
6968
6968
|
# Template method for reading user data and adding to zone additional properties
|
6969
6969
|
#
|
6970
6970
|
# @author Xuechen (Jerry) Lei, PNNL
|
6971
|
-
# @param model [OpenStudio::Model::Model]
|
6971
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6972
6972
|
def model_add_dcv_user_exception_properties(model)
|
6973
6973
|
return true
|
6974
6974
|
end
|
@@ -6976,7 +6976,7 @@ class Standard
|
|
6976
6976
|
# Template method for raising user model DCV warning and errors
|
6977
6977
|
#
|
6978
6978
|
# @author Xuechen (Jerry) Lei, PNNL
|
6979
|
-
# @param model [OpenStudio::Model::Model]
|
6979
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6980
6980
|
def model_raise_user_model_dcv_errors(model)
|
6981
6981
|
return true
|
6982
6982
|
end
|
@@ -6984,7 +6984,7 @@ class Standard
|
|
6984
6984
|
# Template method for adding zone additional property "airloop dcv required by 901" and "zone dcv required by 901"
|
6985
6985
|
#
|
6986
6986
|
# @author Xuechen (Jerry) Lei, PNNL
|
6987
|
-
# @param model [OpenStudio::Model::Model]
|
6987
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6988
6988
|
def model_add_dcv_requirement_properties(model)
|
6989
6989
|
return true
|
6990
6990
|
end
|
@@ -6993,7 +6993,7 @@ class Standard
|
|
6993
6993
|
# Zone additional property 'apxg no need to have DCV' added
|
6994
6994
|
#
|
6995
6995
|
# @author Xuechen (Jerry) Lei, PNNL
|
6996
|
-
# @param model [OpenStudio::Model::Model]
|
6996
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6997
6997
|
def model_add_apxg_dcv_properties(model)
|
6998
6998
|
return true
|
6999
6999
|
end
|
@@ -7001,14 +7001,14 @@ class Standard
|
|
7001
7001
|
# Template method for setting DCV in baseline HVAC system if required
|
7002
7002
|
#
|
7003
7003
|
# @author Xuechen (Jerry) Lei, PNNL
|
7004
|
-
# @param model [OpenStudio::Model::Model]
|
7004
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
7005
7005
|
def model_set_baseline_demand_control_ventilation(model, climate_zone)
|
7006
7006
|
return true
|
7007
7007
|
end
|
7008
7008
|
|
7009
7009
|
# Identify the return air type associated with each thermal zone
|
7010
7010
|
#
|
7011
|
-
# @param model [OpenStudio::Model::Model]
|
7011
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
7012
7012
|
def model_identify_return_air_type(model)
|
7013
7013
|
# air-loop based system
|
7014
7014
|
model.getThermalZones.each do |zone|
|
@@ -7,7 +7,7 @@ class Standard
|
|
7
7
|
# create a construction that meets those properties and assign it to this surface.
|
8
8
|
# 90.1-2007, 90.1-2010, 90.1-2013
|
9
9
|
#
|
10
|
-
# @param planar_surface [
|
10
|
+
# @param planar_surface [OpenStudio::Model:PlanarSurface] surface object
|
11
11
|
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
12
12
|
# @param previous_construction_map [Hash] a hash where the keys are an array of inputs
|
13
13
|
# [template, climate_zone, intended_surface_type, standards_construction_type, occ_type]
|
@@ -980,7 +980,7 @@ class Standard
|
|
980
980
|
end
|
981
981
|
elsif equip.to_ZoneHVACLowTemperatureRadiantElectric.is_initialized
|
982
982
|
equip = equip.to_ZoneHVACLowTemperatureRadiantElectric.get
|
983
|
-
htg_sch = equip.heatingSetpointTemperatureSchedule
|
983
|
+
htg_sch = equip.heatingSetpointTemperatureSchedule
|
984
984
|
elsif equip.to_ZoneHVACLowTempRadiantConstFlow.is_initialized
|
985
985
|
equip = equip.to_ZoneHVACLowTempRadiantConstFlow.get
|
986
986
|
htg_coil = equip.heatingCoil
|
@@ -169,15 +169,15 @@ class Standard
|
|
169
169
|
end
|
170
170
|
|
171
171
|
# Convert to SI
|
172
|
-
|
173
|
-
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, skin-loss UA = #{
|
172
|
+
ua_w_per_k = OpenStudio.convert(ua_btu_per_hr_per_f, 'Btu/hr*R', 'W/K').get
|
173
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, skin-loss UA = #{ua_w_per_k} W/K.")
|
174
174
|
|
175
175
|
# Set the water heater properties
|
176
176
|
# Efficiency
|
177
177
|
water_heater_mixed.setHeaterThermalEfficiency(water_heater_eff)
|
178
178
|
# Skin loss
|
179
|
-
water_heater_mixed.setOffCycleLossCoefficienttoAmbientTemperature(
|
180
|
-
water_heater_mixed.setOnCycleLossCoefficienttoAmbientTemperature(
|
179
|
+
water_heater_mixed.setOffCycleLossCoefficienttoAmbientTemperature(ua_w_per_k)
|
180
|
+
water_heater_mixed.setOnCycleLossCoefficienttoAmbientTemperature(ua_w_per_k)
|
181
181
|
# @todo Parasitic loss (pilot light)
|
182
182
|
# PNNL document says pilot lights were removed, but IDFs
|
183
183
|
# still have the on/off cycle parasitic fuel consumptions filled in
|
@@ -190,7 +190,7 @@ class Standard
|
|
190
190
|
|
191
191
|
# Append the name with standards information
|
192
192
|
water_heater_mixed.setName("#{water_heater_mixed.name} #{water_heater_eff.round(3)} Therm Eff")
|
193
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.WaterHeaterMixed', "For #{template}: #{water_heater_mixed.name}; thermal efficiency = #{water_heater_eff.round(3)}, skin-loss UA = #{ua_btu_per_hr_per_f.round}Btu/hr")
|
193
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.WaterHeaterMixed', "For #{template}: #{water_heater_mixed.name}; thermal efficiency = #{water_heater_eff.round(3)}, skin-loss UA = #{ua_btu_per_hr_per_f.round}Btu/hr-R")
|
194
194
|
|
195
195
|
return true
|
196
196
|
end
|
@@ -144,6 +144,7 @@ class Standard
|
|
144
144
|
# Zone HVAC operating schedule if providing ventilation
|
145
145
|
# Zone HVAC components return an OptionalSchedule object for supplyAirFanOperatingModeSchedule
|
146
146
|
# except for ZoneHVACTerminalUnitVariableRefrigerantFlow which returns a Schedule
|
147
|
+
# and starting at 3.5.0, PTAC / PTHP also return a Schedule, optional before that
|
147
148
|
existing_sch = nil
|
148
149
|
if zone_hvac_component.to_ZoneHVACFourPipeFanCoil.is_initialized
|
149
150
|
zone_hvac_component = zone_hvac_component.to_ZoneHVACFourPipeFanCoil.get
|
@@ -161,7 +162,7 @@ class Standard
|
|
161
162
|
ventilation = true if oa_rate > 0.0
|
162
163
|
end
|
163
164
|
ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized
|
164
|
-
fan_op_sch = zone_hvac_component.supplyAirFanOperatingModeSchedule
|
165
|
+
fan_op_sch = OpenStudio::Model::OptionalSchedule.new(zone_hvac_component.supplyAirFanOperatingModeSchedule)
|
165
166
|
existing_sch = fan_op_sch.get if fan_op_sch.is_initialized
|
166
167
|
elsif zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
|
167
168
|
zone_hvac_component = zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.get
|
@@ -170,7 +171,7 @@ class Standard
|
|
170
171
|
ventilation = true if oa_rate > 0.0
|
171
172
|
end
|
172
173
|
ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized
|
173
|
-
fan_op_sch = zone_hvac_component.supplyAirFanOperatingModeSchedule
|
174
|
+
fan_op_sch = OpenStudio::Model::OptionalSchedule.new(zone_hvac_component.supplyAirFanOperatingModeSchedule)
|
174
175
|
existing_sch = fan_op_sch.get if fan_op_sch.is_initialized
|
175
176
|
elsif zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.is_initialized
|
176
177
|
zone_hvac_component = zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.get
|
data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb
CHANGED
@@ -640,46 +640,49 @@ class ASHRAE9012019 < ASHRAE901
|
|
640
640
|
# Controller:MechanicalVentilation object
|
641
641
|
# to the design v_ot using the maximum OA
|
642
642
|
# fraction schedule
|
643
|
-
|
644
|
-
#
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
643
|
+
# In newer EnergyPlus versions, this is handled by Standard62.1VentilationRateProcedureWithLimit
|
644
|
+
# in the Controller:MechanicalVentilation object
|
645
|
+
if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.3.0')
|
646
|
+
# Add EMS sensors
|
647
|
+
# OA mass flow calculated by the Controller:MechanicalVentilation
|
648
|
+
air_loop_hvac_name_ems = "EMS_#{air_loop_hvac.name.to_s.gsub(' ', '_')}"
|
649
|
+
oa_vrp_mass_flow = OpenStudio::Model::EnergyManagementSystemSensor.new(air_loop_hvac.model, 'Air System Outdoor Air Mechanical Ventilation Requested Mass Flow Rate')
|
650
|
+
oa_vrp_mass_flow.setKeyName(air_loop_hvac.name.to_s)
|
651
|
+
oa_vrp_mass_flow.setName("#{air_loop_hvac_name_ems}_OA_VRP")
|
652
|
+
# Actual sensed OA mass flow
|
653
|
+
oa_mass_flow = OpenStudio::Model::EnergyManagementSystemSensor.new(air_loop_hvac.model, 'Air System Outdoor Air Mass Flow Rate')
|
654
|
+
oa_mass_flow.setKeyName(air_loop_hvac.name.to_s)
|
655
|
+
oa_mass_flow.setName("#{air_loop_hvac_name_ems}_OA")
|
656
|
+
# Actual sensed volumetric OA flow
|
657
|
+
oa_vol_flow = OpenStudio::Model::EnergyManagementSystemSensor.new(air_loop_hvac.model, 'System Node Standard Density Volume Flow Rate')
|
658
|
+
oa_vol_flow.setKeyName("#{air_loop_hvac.name} Mixed Air Node")
|
659
|
+
oa_vol_flow.setName("#{air_loop_hvac_name_ems}_SUPPLY_FLOW")
|
660
|
+
|
661
|
+
# Add EMS actuator
|
662
|
+
max_oa_fraction = OpenStudio::Model::EnergyManagementSystemActuator.new(max_oa_frac_sch, max_oa_frac_sch_type, 'Schedule Value')
|
663
|
+
max_oa_fraction.setName("#{air_loop_hvac_name_ems}_MAX_OA_FRAC")
|
664
|
+
|
665
|
+
# Add EMS program
|
666
|
+
max_oa_ems_prog = OpenStudio::Model::EnergyManagementSystemProgram.new(air_loop_hvac.model)
|
667
|
+
max_oa_ems_prog.setName("#{air_loop_hvac.name}_MAX_OA_FRAC")
|
668
|
+
max_oa_ems_prog_body = <<-EMS
|
669
|
+
IF #{air_loop_hvac_name_ems}_OA > #{air_loop_hvac_name_ems}_OA_VRP,
|
670
|
+
SET #{air_loop_hvac_name_ems}_MAX_OA_FRAC = NULL,
|
671
|
+
ELSE,
|
672
|
+
IF #{air_loop_hvac_name_ems}_SUPPLY_FLOW > 0,
|
673
|
+
SET #{air_loop_hvac_name_ems}_MAX_OA_FRAC = #{v_ot} / #{air_loop_hvac_name_ems}_SUPPLY_FLOW,
|
674
|
+
ELSE,
|
675
|
+
SET #{air_loop_hvac_name_ems}_MAX_OA_FRAC = NULL,
|
676
|
+
ENDIF,
|
677
|
+
ENDIF
|
678
|
+
EMS
|
679
|
+
max_oa_ems_prog.setBody(max_oa_ems_prog_body)
|
680
|
+
|
681
|
+
max_oa_ems_prog_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(air_loop_hvac.model)
|
682
|
+
max_oa_ems_prog_manager.setName("SET_#{air_loop_hvac.name.to_s.gsub(' ', '_')}_MAX_OA_FRAC")
|
683
|
+
max_oa_ems_prog_manager.setCallingPoint('InsideHVACSystemIterationLoop')
|
684
|
+
max_oa_ems_prog_manager.addProgram(max_oa_ems_prog)
|
685
|
+
end
|
683
686
|
|
684
687
|
# Hard-size the sizing:system
|
685
688
|
# object with the calculated min OA flow rate
|
@@ -44,7 +44,8 @@ class ASHRAE9012019 < ASHRAE901
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# Set fan operating schedule during assumed occupant standby mode time to 0 so the fan can cycle
|
47
|
-
|
47
|
+
# ZoneHVACFourPipeFanCoil has it optional, PTAC/PTHP starting a 3.5.0 is required
|
48
|
+
new_sch = model_set_schedule_value(OpenStudio::Model::OptionalSchedule.new(zone_hvac_component.supplyAirFanOperatingModeSchedule).get, '12' => 0)
|
48
49
|
zone_hvac_component.setSupplyAirFanOperatingModeSchedule(new_sch) unless new_sch == true
|
49
50
|
|
50
51
|
return true
|
@@ -2,25 +2,25 @@
|
|
2
2
|
"entryways": [
|
3
3
|
{
|
4
4
|
"building_type": "College",
|
5
|
-
"rollup_doors_per_10,000":
|
6
|
-
"entrance_doors_per_10,000":
|
7
|
-
"others_doors_per_10,000":
|
5
|
+
"rollup_doors_per_10,000": 0.0,
|
6
|
+
"entrance_doors_per_10,000": 2.0,
|
7
|
+
"others_doors_per_10,000": 2.45,
|
8
8
|
"entrance_canopies": null,
|
9
9
|
"emergency_canopies": null,
|
10
10
|
"canopy_size": null,
|
11
11
|
"floor_area_per_drive_through_window": null,
|
12
|
-
"notes":
|
12
|
+
"notes": "match SecondarySchool"
|
13
13
|
},
|
14
14
|
{
|
15
15
|
"building_type": "Courthouse",
|
16
|
-
"rollup_doors_per_10,000":
|
17
|
-
"entrance_doors_per_10,000":
|
18
|
-
"others_doors_per_10,000":
|
16
|
+
"rollup_doors_per_10,000": 0.0,
|
17
|
+
"entrance_doors_per_10,000": 1.0,
|
18
|
+
"others_doors_per_10,000": 3.0,
|
19
19
|
"entrance_canopies": null,
|
20
20
|
"emergency_canopies": null,
|
21
21
|
"canopy_size": null,
|
22
22
|
"floor_area_per_drive_through_window": null,
|
23
|
-
"notes":
|
23
|
+
"notes": "match MediumOffice"
|
24
24
|
},
|
25
25
|
{
|
26
26
|
"building_type": "FullServiceRestaurant",
|
@@ -55,6 +55,17 @@
|
|
55
55
|
"floor_area_per_drive_through_window": null,
|
56
56
|
"notes": "No source for canopy size, Table 5.41. Exterior Lighting Savings Summary for Addendum 90.1-07i doesn't indicate canopy lighting. Section 5.4.2 Exterior Lights in U.S. Department of Energy Commercial Reference Building Models of the National Building Stock shows their use."
|
57
57
|
},
|
58
|
+
{
|
59
|
+
"building_type": "Laboratory",
|
60
|
+
"rollup_doors_per_10,000": 0.0,
|
61
|
+
"entrance_doors_per_10,000": 2.0,
|
62
|
+
"others_doors_per_10,000": 2.45,
|
63
|
+
"entrance_canopies": null,
|
64
|
+
"emergency_canopies": null,
|
65
|
+
"canopy_size": null,
|
66
|
+
"floor_area_per_drive_through_window": null,
|
67
|
+
"notes": "match SecondarySchool"
|
68
|
+
},
|
58
69
|
{
|
59
70
|
"building_type": "LargeDataCenterHighITE",
|
60
71
|
"rollup_doors_per_10,000": null,
|
@@ -2,21 +2,21 @@
|
|
2
2
|
"parking": [
|
3
3
|
{
|
4
4
|
"building_type": "College",
|
5
|
-
"building_area_per_spot":
|
5
|
+
"building_area_per_spot": 250.0,
|
6
6
|
"units_per_spot": null,
|
7
7
|
"students_per_spot": null,
|
8
8
|
"beds_per_spot": null,
|
9
9
|
"parking_area_per_spot": 405.0,
|
10
|
-
"notes": "
|
10
|
+
"notes": "match MediumOffice"
|
11
11
|
},
|
12
12
|
{
|
13
13
|
"building_type": "Courthouse",
|
14
|
-
"building_area_per_spot":
|
14
|
+
"building_area_per_spot": 250.0,
|
15
15
|
"units_per_spot": null,
|
16
16
|
"students_per_spot": null,
|
17
17
|
"beds_per_spot": null,
|
18
18
|
"parking_area_per_spot": 405.0,
|
19
|
-
"notes": "
|
19
|
+
"notes": "match MediumOffice"
|
20
20
|
},
|
21
21
|
{
|
22
22
|
"building_type": "FullServiceRestaurant",
|
@@ -45,6 +45,15 @@
|
|
45
45
|
"parking_area_per_spot": 405.0,
|
46
46
|
"notes": "Based on Table 4.17 Illuminated Parking Area from Achieving the 30% Goal: Energy and Cost Savings Analysis of ASHRAE Standard 90.1-2010"
|
47
47
|
},
|
48
|
+
{
|
49
|
+
"building_type": "Laboratory",
|
50
|
+
"building_area_per_spot": 250.0,
|
51
|
+
"units_per_spot": null,
|
52
|
+
"students_per_spot": null,
|
53
|
+
"beds_per_spot": null,
|
54
|
+
"parking_area_per_spot": 405.0,
|
55
|
+
"notes": "match MediumOffice"
|
56
|
+
},
|
48
57
|
{
|
49
58
|
"building_type": "LargeDataCenterHighITE",
|
50
59
|
"building_area_per_spot": 0.0,
|
@@ -47,4 +47,15 @@ class DOERef1980to2004 < ASHRAE901
|
|
47
47
|
damper_action = 'Single Maximum'
|
48
48
|
return damper_action
|
49
49
|
end
|
50
|
+
|
51
|
+
# Determine minimum ventilation efficiency for zones.
|
52
|
+
# For DOE Ref 1980-2004, assume that VAV system designers did not
|
53
|
+
# care about decreasing system OA flow rates and therefore did not
|
54
|
+
# adjust minimum damper positions to achieve any specific
|
55
|
+
# ventilation efficiency.
|
56
|
+
def air_loop_hvac_minimum_zone_ventilation_efficiency(air_loop_hvac)
|
57
|
+
min_ventilation_efficiency = 0
|
58
|
+
|
59
|
+
return min_ventilation_efficiency
|
60
|
+
end
|
50
61
|
end
|
data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb
CHANGED
@@ -47,4 +47,15 @@ class DOERefPre1980 < ASHRAE901
|
|
47
47
|
damper_action = 'Single Maximum'
|
48
48
|
return damper_action
|
49
49
|
end
|
50
|
+
|
51
|
+
# Determine minimum ventilation efficiency for zones.
|
52
|
+
# For DOE Ref Pre-1980, assume that VAV system designers did not
|
53
|
+
# care about decreasing system OA flow rates and therefore did not
|
54
|
+
# adjust minimum damper positions to achieve any specific
|
55
|
+
# ventilation efficiency.
|
56
|
+
def air_loop_hvac_minimum_zone_ventilation_efficiency(air_loop_hvac)
|
57
|
+
min_ventilation_efficiency = 0
|
58
|
+
|
59
|
+
return min_ventilation_efficiency
|
60
|
+
end
|
50
61
|
end
|
@@ -272,7 +272,7 @@ class ASHRAE901PRM < Standard
|
|
272
272
|
return_fan_power_fraction /= total_fan_avg_fan_w
|
273
273
|
relief_fan_power_fraction /= total_fan_avg_fan_w
|
274
274
|
else
|
275
|
-
|
275
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.ashrae_90_1_prm.AirLoopHVAC', "Total zone design airflow for #{air_loop_hvac.name} is 0.")
|
276
276
|
end
|
277
277
|
elsif system_type == 'PTAC' ||
|
278
278
|
system_type == 'PTHP' ||
|
@@ -1176,7 +1176,7 @@ class ASHRAE901PRM < Standard
|
|
1176
1176
|
# Template method for adding a setpoint manager for a coil control logic to a heating coil.
|
1177
1177
|
# ASHRAE 90.1-2019 Appendix G.
|
1178
1178
|
#
|
1179
|
-
# @param model [OpenStudio::Model::Model]
|
1179
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1180
1180
|
# @param thermalZones Array([OpenStudio::Model::ThermalZone]) thermal zone array
|
1181
1181
|
# @param coil Heating Coils
|
1182
1182
|
# @return [Boolean] true
|
@@ -1228,7 +1228,7 @@ class ASHRAE901PRM < Standard
|
|
1228
1228
|
# - 'false' otherwise
|
1229
1229
|
#
|
1230
1230
|
# @author Xuechen (Jerry) Lei, PNNL
|
1231
|
-
# @param model [OpenStudio::Model::Model]
|
1231
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1232
1232
|
def model_mark_zone_dcv_existence(model)
|
1233
1233
|
model.getAirLoopHVACs.each do |air_loop_hvac|
|
1234
1234
|
next unless air_loop_hvac.airLoopHVACOutdoorAirSystem.is_initialized
|
@@ -1274,7 +1274,7 @@ class ASHRAE901PRM < Standard
|
|
1274
1274
|
# "one user specified DCV exception"
|
1275
1275
|
#
|
1276
1276
|
# @author Xuechen (Jerry) Lei, PNNL
|
1277
|
-
# @param model [OpenStudio::Model::Model]
|
1277
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1278
1278
|
def model_add_dcv_user_exception_properties(model)
|
1279
1279
|
model.getAirLoopHVACs.each do |air_loop_hvac|
|
1280
1280
|
dcv_airloop_user_exception = false
|
@@ -1336,7 +1336,7 @@ class ASHRAE901PRM < Standard
|
|
1336
1336
|
# - 'flase' otherwise
|
1337
1337
|
#
|
1338
1338
|
# @author Xuechen (Jerry) Lei, PNNL
|
1339
|
-
# @param model [OpenStudio::Model::Model]
|
1339
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1340
1340
|
def model_add_dcv_requirement_properties(model)
|
1341
1341
|
model.getAirLoopHVACs.each do |air_loop_hvac|
|
1342
1342
|
if user_model_air_loop_hvac_demand_control_ventilation_required?(air_loop_hvac)
|
@@ -1370,7 +1370,7 @@ class ASHRAE901PRM < Standard
|
|
1370
1370
|
# generation
|
1371
1371
|
#
|
1372
1372
|
# @author Xuechen (Jerry) Lei, PNNL
|
1373
|
-
# @param model [OpenStudio::Model::Model]
|
1373
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1374
1374
|
def model_raise_user_model_dcv_errors(model)
|
1375
1375
|
# TODO: JXL add log msgs to PRM logger
|
1376
1376
|
model.getThermalZones.each do |thermal_zone|
|
@@ -1396,7 +1396,7 @@ class ASHRAE901PRM < Standard
|
|
1396
1396
|
# property 'apxg no need to have DCV' added
|
1397
1397
|
#
|
1398
1398
|
# @author Xuechen (Jerry) Lei, PNNL
|
1399
|
-
# @param model [OpenStudio::Model::Model]
|
1399
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1400
1400
|
def model_add_apxg_dcv_properties(model)
|
1401
1401
|
model.getAirLoopHVACs.each do |air_loop_hvac|
|
1402
1402
|
if air_loop_hvac.airLoopHVACOutdoorAirSystem.is_initialized
|
@@ -1434,7 +1434,7 @@ class ASHRAE901PRM < Standard
|
|
1434
1434
|
# Set DCV in baseline HVAC system if required
|
1435
1435
|
#
|
1436
1436
|
# @author Xuechen (Jerry) Lei, PNNL
|
1437
|
-
# @param model [OpenStudio::Model::Model]
|
1437
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
1438
1438
|
def model_set_baseline_demand_control_ventilation(model, climate_zone)
|
1439
1439
|
model.getAirLoopHVACs.each do |air_loop_hvac|
|
1440
1440
|
if baseline_air_loop_hvac_demand_control_ventilation_required?(air_loop_hvac)
|
@@ -1452,7 +1452,7 @@ class ASHRAE901PRM < Standard
|
|
1452
1452
|
# include data source from:
|
1453
1453
|
# 1. user data csv files
|
1454
1454
|
# 2. data from measure and OpenStudio interface
|
1455
|
-
# @param [
|
1455
|
+
# @param [OpenStudio:model:Model] model
|
1456
1456
|
# @param [String] climate_zone
|
1457
1457
|
# @param [String] default_hvac_building_type
|
1458
1458
|
# @param [String] default_wwr_building_type
|
@@ -1948,7 +1948,7 @@ class ASHRAE901PRM < Standard
|
|
1948
1948
|
# The default shall be true
|
1949
1949
|
#
|
1950
1950
|
# @param [Boolean] run_all_orients: user inputs to indicate whether it is required to run all orientations
|
1951
|
-
# @param [OpenStudio::Model::Model]
|
1951
|
+
# @param [OpenStudio::Model::Model] OpenStudio model
|
1952
1952
|
def run_all_orientations(run_all_orients, user_model)
|
1953
1953
|
# Step 0, assign the default value
|
1954
1954
|
run_orients_flag = run_all_orients
|
@@ -7,7 +7,7 @@ class ASHRAE901PRM < Standard
|
|
7
7
|
# create a construction that meets those properties and assign it to this surface.
|
8
8
|
# 90.1-PRM-2019
|
9
9
|
#
|
10
|
-
# @param planar_surface [
|
10
|
+
# @param planar_surface [OpenStudio::Model:PlanarSurface] surface object
|
11
11
|
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
12
12
|
# @param previous_construction_map [Hash] a hash where the keys are an array of inputs
|
13
13
|
# [template, climate_zone, intended_surface_type, standards_construction_type, occ_type]
|
@@ -112,7 +112,11 @@ class ASHRAE901PRM < Standard
|
|
112
112
|
sizing_run_ran = model_run_sizing_run(model, "#{sizing_run_dir}/SR_cooling_plant") if !sizing_run_ran
|
113
113
|
|
114
114
|
if sizing_run_ran
|
115
|
-
|
115
|
+
if model.version <= OpenStudio::VersionString.new('3.2.1')
|
116
|
+
sizing_run_capacity = model.getAutosizedValueFromEquipmentSummary(chiller, 'Central Plant', 'Nominal Capacity', 'W').get
|
117
|
+
else
|
118
|
+
sizing_run_capacity = model.getAutosizedValueFromEquipmentSummary(chiller, 'Central Plant', 'Rated Capacity', 'W').get
|
119
|
+
end
|
116
120
|
chiller.setReferenceCapacity(sizing_run_capacity)
|
117
121
|
total_cooling_capacity_w += sizing_run_capacity
|
118
122
|
else
|
@@ -235,7 +235,11 @@ class BTAPPRE1980
|
|
235
235
|
air_loop_sizing.setCentralHeatingDesignSupplyAirTemperature(system_data[:CentralHeatingDesignSupplyAirTemperature])
|
236
236
|
air_loop_sizing.setAllOutdoorAirinCooling(system_data[:AllOutdoorAirinCooling])
|
237
237
|
air_loop_sizing.setAllOutdoorAirinHeating(system_data[:AllOutdoorAirinHeating])
|
238
|
-
|
238
|
+
if model.version < OpenStudio::VersionString.new('2.7.0')
|
239
|
+
air_loop_sizing.setMinimumSystemAirFlowRatio(system_data[:MinimumSystemAirFlowRatio])
|
240
|
+
else
|
241
|
+
air_loop_sizing.setCentralHeatingMaximumSystemAirFlowRatio(system_data[:MinimumSystemAirFlowRatio])
|
242
|
+
end
|
239
243
|
|
240
244
|
supply_fan = OpenStudio::Model::FanVariableVolume.new(model, always_on)
|
241
245
|
supply_fan.setName('Sys6 Supply Fan')
|
@@ -442,7 +442,7 @@ class ECMS
|
|
442
442
|
end
|
443
443
|
return storey_zones_map
|
444
444
|
end
|
445
|
-
|
445
|
+
|
446
446
|
#==============================================================================================================================
|
447
447
|
# Update the map between systems and zones
|
448
448
|
def update_system_zones_map(model,system_zones_map,system_zones_map_option,system_key)
|
@@ -482,7 +482,7 @@ class ECMS
|
|
482
482
|
system_zones_map = update_system_zones_map(model,system_zones_map,ecm_system_zones_map_option,'sys_1')
|
483
483
|
else
|
484
484
|
updated_system_zones_map = {}
|
485
|
-
system_zones_map.each {|sname,zones| updated_system_zones_map["sys_1#{sname[5..-1]}"] = zones} # doas unit is an NECB sys_1
|
485
|
+
system_zones_map.each {|sname,zones| updated_system_zones_map["sys_1#{sname[5..-1]}"] = zones} # doas unit is an NECB sys_1
|
486
486
|
system_zones_map = updated_system_zones_map
|
487
487
|
end
|
488
488
|
# Add outdoor VRF unit
|
@@ -612,7 +612,11 @@ class ECMS
|
|
612
612
|
airloop.sizingSystem.setSystemOutdoorAirMethod('ZoneSum')
|
613
613
|
airloop.sizingSystem.setCentralCoolingDesignSupplyAirHumidityRatio(0.0085)
|
614
614
|
airloop.sizingSystem.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080)
|
615
|
-
|
615
|
+
if model.version < OpenStudio::VersionString.new('2.7.0')
|
616
|
+
airloop.sizingSystem.setMinimumSystemAirFlowRatio(1.0)
|
617
|
+
else
|
618
|
+
airloop.sizingSystem.setCentralHeatingMaximumSystemAirFlowRatio(1.0)
|
619
|
+
end
|
616
620
|
case sys_vent_type.downcase
|
617
621
|
when 'doas'
|
618
622
|
airloop.sizingSystem.setAllOutdoorAirinCooling(true)
|
@@ -1126,7 +1130,7 @@ class ECMS
|
|
1126
1130
|
# There is an error in EnergyPlus in the estimated capacity of the coil "CoilCoolingDXVariableSpeed".
|
1127
1131
|
# Here the capacity reported by OS is adjusted to estimate an appropriate capacity for the cooling coil.
|
1128
1132
|
# The autosized capacity is corrected for the actual fan flow rate and fan power.
|
1129
|
-
if supply_fan.autosizedMaximumFlowRate.is_initialized
|
1133
|
+
if supply_fan.autosizedMaximumFlowRate.is_initialized
|
1130
1134
|
fan_max_afr = supply_fan.autosizedMaximumFlowRate.to_f
|
1131
1135
|
elsif supply_fan.maximumFlowRate.is_initialized
|
1132
1136
|
fan_max_afr = supply_fan.maximumFlowRate.to_f
|
@@ -121,8 +121,11 @@ class ECMS
|
|
121
121
|
|
122
122
|
##### Add a "ZoneVentilation:DesignFlowRate" object for NV to set OA per person.
|
123
123
|
zn_vent_design_flow_rate_1 = OpenStudio::Model::ZoneVentilationDesignFlowRate.new(model)
|
124
|
-
zn_vent_design_flow_rate_1.setDesignFlowRateCalculationMethod('Flow/Person')
|
125
124
|
zn_vent_design_flow_rate_1.setFlowRateperPerson(oa_per_person_normalized_by_number_of_windows)
|
125
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
126
|
+
# Design Flow Rate Calculation Method is automatically set in 3.5.0+
|
127
|
+
zn_vent_design_flow_rate_1.setDesignFlowRateCalculationMethod('Flow/Person')
|
128
|
+
end
|
126
129
|
zn_vent_design_flow_rate_1.setVentilationType('Natural')
|
127
130
|
zn_vent_design_flow_rate_1.setMinimumIndoorTemperatureSchedule(min_Tin_schedule)
|
128
131
|
zn_vent_design_flow_rate_1.setMaximumIndoorTemperatureSchedule(max_Tin_schedule)
|
@@ -133,8 +136,11 @@ class ECMS
|
|
133
136
|
|
134
137
|
##### Add another "ZoneVentilation:DesignFlowRate" object for NV to set OA per floor area.
|
135
138
|
zn_vent_design_flow_rate_2 = OpenStudio::Model::ZoneVentilationDesignFlowRate.new(model)
|
136
|
-
zn_vent_design_flow_rate_2.setDesignFlowRateCalculationMethod('Flow/Area')
|
137
139
|
zn_vent_design_flow_rate_2.setFlowRateperZoneFloorArea(oa_per_floor_area_normalized_by_number_of_windows)
|
140
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
141
|
+
# Design Flow Rate Calculation Method is automatically set in 3.5.0+
|
142
|
+
zn_vent_design_flow_rate_2.setDesignFlowRateCalculationMethod('Flow/Area')
|
143
|
+
end
|
138
144
|
zn_vent_design_flow_rate_2.setVentilationType('Natural')
|
139
145
|
zn_vent_design_flow_rate_2.setMinimumIndoorTemperatureSchedule(min_Tin_schedule)
|
140
146
|
zn_vent_design_flow_rate_2.setMaximumIndoorTemperatureSchedule(max_Tin_schedule)
|