Skip to content

Commit

Permalink
Merge pull request #1558 from NREL/deer_ventilation_rates
Browse files Browse the repository at this point in the history
Deer ventilation rates
  • Loading branch information
mdahlhausen authored Aug 9, 2023
2 parents 714437e + dc94c41 commit 94243bb
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 128 deletions.
20 changes: 20 additions & 0 deletions lib/openstudio-standards.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,26 @@ module OpenstudioStandards
require_relative "#{stds}/deer/deer.AirLoopHVAC"
require_relative "#{stds}/deer/deer.Space"
require_relative "#{stds}/deer/deer.PlanarSurface"
# DEER 2003
require_relative "#{stds}/deer/deer_2003/deer_2003.ThermalZone"
# DEER 2007
require_relative "#{stds}/deer/deer_2007/deer_2007.ThermalZone"
# DEER 2011
require_relative "#{stds}/deer/deer_2011/deer_2011.ThermalZone"
# DEER 2014
require_relative "#{stds}/deer/deer_2014/deer_2014.Space"
require_relative "#{stds}/deer/deer_2014/deer_2014.ThermalZone"
# DEER 2015
require_relative "#{stds}/deer/deer_2015/deer_2015.Space"
require_relative "#{stds}/deer/deer_2015/deer_2015.ThermalZone"
# DEER 2017
require_relative "#{stds}/deer/deer_2017/deer_2017.Space"
require_relative "#{stds}/deer/deer_2017/deer_2017.ThermalZone"
# DEER 2020
require_relative "#{stds}/deer/deer_2020/deer_2020.AirLoopHVAC"
require_relative "#{stds}/deer/deer_2020/deer_2020.FanVariableVolume"
require_relative "#{stds}/deer/deer_2020/deer_2020.Space"
require_relative "#{stds}/deer/deer_2020/deer_2020.ThermalZone"
# CBES Common
require_relative "#{stds}/cbes/cbes.AirLoopHVAC"
require_relative "#{stds}/cbes/cbes.Model"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,7 @@ def thermal_zone_demand_control_ventilation_required?(thermal_zone, climate_zone

# Not required if both limits nil
if min_area_m2.nil? && min_area_m2_per_occ.nil?
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ThermalZone', "For #{thermal_zone.name}: DCV is not required due to lack of minimum area requirements.")
return dcv_required
end

Expand Down
23 changes: 22 additions & 1 deletion lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@ def air_loop_hvac_unoccupied_fan_shutoff_required?(air_loop_hvac)
return shutoff_required
end

# Determines the OA flow rates above which an economizer is required.
# Two separate rates, one for systems with an economizer and another
# for systems without.
# The small numbers here are to reflect that there is not a minimum
# airflow requirement in Title 24.
# @return [Array<Double>] [min_oa_without_economizer_cfm, min_oa_with_economizer_cfm]
def air_loop_hvac_demand_control_ventilation_limits(air_loop_hvac)
min_oa_without_economizer_cfm = 0.01
min_oa_with_economizer_cfm = 0.01
return [min_oa_without_economizer_cfm, min_oa_with_economizer_cfm]
end

# Determine if the standard has an exception for demand control ventilation
# when an energy recovery device is present.
# Unlike ASHRAE 90.1, Title 24 does not have an ERV exception to DCV.
# This method is a copy of what is in Standards.AirLoopHVAC.rb and ensures
# ERVs will not prevent DCV from being applied to DEER models.
def air_loop_hvac_dcv_required_when_erv(air_loop_hvac)
dcv_required_when_erv_present = true
return dcv_required_when_erv_present
end

# Determine whether or not this system is required to have an economizer.
# Logic inferred from MASControl3 INP files and parameters database.
#
Expand Down Expand Up @@ -126,7 +148,6 @@ def air_loop_hvac_economizer_type_allowable?(air_loop_hvac, climate_zone)

# Determine the limits for the type of economizer present on the AirLoopHVAC, if any.
# Enthalpy limit is from MASControl3.
#
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
# @return [Array<Double>] [drybulb_limit_f, enthalpy_limit_btu_per_lb, dewpoint_limit_f]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2003 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = min_area_ft2
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2007 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = min_area_ft2
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2011 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = 150
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = OpenStudio.convert(min_area_ft2, 'ft^2', 'm^2').get
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2014 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = 150
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = OpenStudio.convert(min_area_ft2, 'ft^2', 'm^2').get
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2015 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = 150
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = OpenStudio.convert(min_area_ft2, 'ft^2', 'm^2').get
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2017 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = 150
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = OpenStudio.convert(min_area_ft2, 'ft^2', 'm^2').get
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,14 @@ def air_loop_hvac_demand_control_ventilation_limits(air_loop_hvac)
min_oa_with_economizer_cfm = 0
return [min_oa_without_economizer_cfm, min_oa_with_economizer_cfm]
end
end

# Determine if the standard has an exception for demand control ventilation
# when an energy recovery device is present.
# Unlike ASHRAE 90.1, Title 24 does not have an ERV exception to DCV.
# This method is a copy of what is in Standards.AirLoopHVAC.rb and ensures
# ERVs will not prevent DCV from being applied to DEER models.
def air_loop_hvac_dcv_required_when_erv(air_loop_hvac)
dcv_required_when_erv_present = true
return dcv_required_when_erv_present
end
end
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
class DEER2020 < DEER
# @!group ThermalZone
# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = nil # No minimum area
min_ft2_per_occ = 40
# Convert to SI
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_ft2, min_m2_per_occ]
end
# @!group ThermalZone

# Determine the area and occupancy level limits for
# demand control ventilation.
#
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
# @return [Array<Double>] the minimum area, in m^2
# and the minimum occupancy density in m^2/person. Returns nil
# if there is no requirement.
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
min_area_ft2 = 150
min_ft2_per_occ = 40

# Convert to SI
min_area_m2 = OpenStudio.convert(min_area_ft2, 'ft^2', 'm^2').get
min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get

return [min_area_m2, min_m2_per_occ]
end
end

0 comments on commit 94243bb

Please sign in to comment.