class ASHRAE9012004
This class holds methods that apply ASHRAE 90.1-2004 to a given model. @ref [References::ASHRAE9012004]
Attributes
Public Class Methods
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.rb, line 8 def initialize @template = '90.1-2004' load_standards_database end
Public Instance Methods
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.
@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @return [Array<Double>] [min_oa_without_economizer_cfm, min_oa_with_economizer_cfm]
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 100 def air_loop_hvac_demand_control_ventilation_limits(air_loop_hvac) min_oa_without_economizer_cfm = 3000 min_oa_with_economizer_cfm = 0 return [min_oa_without_economizer_cfm, min_oa_with_economizer_cfm] end
Determines supply air temperature (SAT) temperature. For 90.1-2007, 10 delta-F ®
@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @return [Double] the SAT reset amount in degrees Rankine
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 167 def air_loop_hvac_enable_supply_air_temperature_reset_delta(air_loop_hvac) sat_reset_r = 10.0 return sat_reset_r end
Determine the airflow limits that govern whether or not an ERV is required. Based on climate zone and % OA.
@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @param pct_oa [Double] percentage of outdoor air @return [Double] the flow rate above which an ERV is required. if nil, ERV is never required.
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 179 def air_loop_hvac_energy_recovery_ventilator_flow_limit(air_loop_hvac, climate_zone, pct_oa) erv_cfm = if pct_oa < 0.7 nil else # @todo Add exceptions (eg: e. cooling systems in climate zones 3C, 4C, 5B, 5C, 6B, 7 and 8 | d. Heating systems in climate zones 1 to 3) 5000 end return erv_cfm end
Determine the air flow and number of story limits for whether motorized OA damper is required.
@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>] [minimum_oa_flow_cfm, maximum_stories]. If both nil, never required
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 121 def air_loop_hvac_motorized_oa_damper_limits(air_loop_hvac, climate_zone) case climate_zone when 'ASHRAE 169-2006-0A', 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-0B', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-3A', 'ASHRAE 169-2006-3B', 'ASHRAE 169-2006-3C', 'ASHRAE 169-2013-0A', 'ASHRAE 169-2013-1A', 'ASHRAE 169-2013-0B', 'ASHRAE 169-2013-1B', 'ASHRAE 169-2013-2A', 'ASHRAE 169-2013-2B', 'ASHRAE 169-2013-3A', 'ASHRAE 169-2013-3B', 'ASHRAE 169-2013-3C' minimum_oa_flow_cfm = 0 maximum_stories = 999 # Any number of stories else minimum_oa_flow_cfm = 0 maximum_stories = 3 end return [minimum_oa_flow_cfm, maximum_stories] end
Determine if an economizer is required per the PRM.
@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @return [Boolean] returns true if required, false if not
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 9 def air_loop_hvac_prm_baseline_economizer_required?(air_loop_hvac, climate_zone) economizer_required = false # A big number of ft2 as the minimum requirement infinity_ft2 = 999_999_999_999 min_int_area_served_ft2 = infinity_ft2 min_ext_area_served_ft2 = infinity_ft2 # Determine the minimum capacity that requires an economizer case climate_zone when 'ASHRAE 169-2006-0A', 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-0B', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-3A', 'ASHRAE 169-2006-4A', 'ASHRAE 169-2013-0A', 'ASHRAE 169-2013-1A', 'ASHRAE 169-2013-0B', 'ASHRAE 169-2013-1B', 'ASHRAE 169-2013-2A', 'ASHRAE 169-2013-3A', 'ASHRAE 169-2013-4A' min_int_area_served_ft2 = infinity_ft2 # No requirement min_ext_area_served_ft2 = infinity_ft2 # No requirement when 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-5A', 'ASHRAE 169-2006-6A', 'ASHRAE 169-2006-7A', 'ASHRAE 169-2006-7B', 'ASHRAE 169-2006-8A', 'ASHRAE 169-2006-8B', 'ASHRAE 169-2013-2B', 'ASHRAE 169-2013-5A', 'ASHRAE 169-2013-6A', 'ASHRAE 169-2013-7A', 'ASHRAE 169-2013-7B', 'ASHRAE 169-2013-8A', 'ASHRAE 169-2013-8B' min_int_area_served_ft2 = 15_000 min_ext_area_served_ft2 = infinity_ft2 # No requirement when 'ASHRAE 169-2006-3B', 'ASHRAE 169-2006-3C', 'ASHRAE 169-2006-4B', 'ASHRAE 169-2006-4C', 'ASHRAE 169-2006-5B', 'ASHRAE 169-2006-5C', 'ASHRAE 169-2006-6B', 'ASHRAE 169-2013-3B', 'ASHRAE 169-2013-3C', 'ASHRAE 169-2013-4B', 'ASHRAE 169-2013-4C', 'ASHRAE 169-2013-5B', 'ASHRAE 169-2013-5C', 'ASHRAE 169-2013-6B' min_int_area_served_ft2 = 10_000 min_ext_area_served_ft2 = 25_000 end # Check whether the system requires an economizer by comparing # the system capacity to the minimum capacity. min_int_area_served_m2 = OpenStudio.convert(min_int_area_served_ft2, 'ft^2', 'm^2').get min_ext_area_served_m2 = OpenStudio.convert(min_ext_area_served_ft2, 'ft^2', 'm^2').get # Get the interior and exterior area served int_area_served_m2 = air_loop_hvac_floor_area_served_interior_zones(air_loop_hvac) ext_area_served_m2 = air_loop_hvac_floor_area_served_exterior_zones(air_loop_hvac) # Check the floor area exception if int_area_served_m2 < min_int_area_served_m2 && ext_area_served_m2 < min_ext_area_served_m2 if min_int_area_served_ft2 == infinity_ft2 && min_ext_area_served_ft2 == infinity_ft2 OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Economizer not required for climate zone #{climate_zone}.") else OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Economizer not required for because the interior area served of #{int_area_served_m2} ft2 is less than the minimum of #{min_int_area_served_m2} and the perimeter area served of #{ext_area_served_m2} ft2 is less than the minimum of #{min_ext_area_served_m2} for climate zone #{climate_zone}.") end return economizer_required end # If here, economizer required economizer_required = true OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Economizer required for the performance rating method baseline.") return economizer_required end
Determine the number of stages that should be used as controls for single zone DX systems. 90.1-2004 requires 1 stage.
@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @return [Integer] the number of stages: 0, 1, 2
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 157 def air_loop_hvac_single_zone_controls_num_stages(air_loop_hvac, climate_zone) num_stages = 1 return num_stages end
Determine whether the VAV damper control is single maximum or dual maximum control. Single Maximum for 90.1-2004.
@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @return [String] the damper control type: Single Maximum, Dual Maximum
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb, line 111 def air_loop_hvac_vav_damper_action(air_loop_hvac) damper_action = 'Single Maximum' return damper_action end
@!group AirTerminalSingleDuctVAVReheat Set the initial minimum damper position based on OA rate of the space and the template. Zones with low OA per area get lower initial guesses. Final position will be adjusted upward as necessary by Standards.AirLoopHVAC.apply_minimum_vav_damper_positions
@param air_terminal_single_duct_vav_reheat [OpenStudio::Model::AirTerminalSingleDuctVAVReheat] the air terminal object @param zone_oa_per_area [Double] the zone outdoor air per area in m^3/s*m^2 @return [Boolean] returns true if successful, false if not
# File lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirTerminalSingleDuctVAVReheat.rb, line 10 def air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(air_terminal_single_duct_vav_reheat, zone_oa_per_area) min_damper_position = 0.3 # Set the minimum flow fraction air_terminal_single_duct_vav_reheat.setConstantMinimumAirFlowFraction(min_damper_position) return true end
Determine what part load efficiency degredation curve should be used for a boiler
@param boiler_hot_water [OpenStudio::Model::BoilerHotWater] hot water boiler object @return [String] returns name of the boiler curve to be used, or nil if not applicable
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.BoilerHotWater.rb, line 6 def boiler_get_eff_fplr(boiler_hot_water) return 'Boiler with No Minimum Turndown' end
The threhold horsepower below which part load control is not required. 15 nameplate HP threshold is equivalent to motors with input powers of 9.9 HP per TSD
@param fan_variable_volume [OpenStudio::Model::FanVariableVolume] variable volume fan object @return [Double] the limit, in horsepower. Return nil for no limit by default. @todo AddRef
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.FanVariableVolume.rb, line 10 def fan_variable_volume_part_load_fan_power_limitation_hp_limit(fan_variable_volume) hp_limit = 9.9 return hp_limit end
Loads the openstudio standards dataset for this standard.
@param data_directories [Array<String>] array of file paths that contain standards data @return [Hash] a hash of standards data
ASHRAE901#load_standards_database
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.rb, line 17 def load_standards_database(data_directories = []) super([__dir__] + data_directories) end
@!group Model
Determine the surface range of a baseline model. The method calculates the window to wall ratio (assuming all spaces are conditioned) and select the range based on the calculated window to wall ratio @param model [OpenStudio::Model::Model] OpenStudio model object @param wwr_parameter [Hash] parameters to choose min and max percent of surfaces,
could be different set in different standard
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb, line 10 def model_get_percent_of_surface_range(model, wwr_parameter) wwr_range = { 'minimum_percent_of_surface' => nil, 'maximum_percent_of_surface' => nil } intended_surface_type = wwr_parameter['intended_surface_type'] # Do not process surfaces other than exterior windows and glass door for 2004 standard if intended_surface_type == 'ExteriorWindow' || intended_surface_type == 'GlassDoor' wwr = OpenstudioStandards::Geometry.model_get_exterior_window_to_wall_ratio(model) if wwr <= 0.1 wwr_range['minimum_percent_of_surface'] = 1.0 wwr_range['maximum_percent_of_surface'] = 10.0 elsif wwr <= 0.2 wwr_range['minimum_percent_of_surface'] = 10.001 wwr_range['maximum_percent_of_surface'] = 20 elsif wwr <= 0.3 wwr_range['minimum_percent_of_surface'] = 20.001 wwr_range['maximum_percent_of_surface'] = 30 elsif wwr <= 0.4 wwr_range['minimum_percent_of_surface'] = 30.001 wwr_range['maximum_percent_of_surface'] = 40 else wwr_range['minimum_percent_of_surface'] = 40.001 wwr_range['maximum_percent_of_surface'] = 100.0 end end return wwr_range end
Set the primary and secondary pumping control types for the chilled water loop, as specified in Appendix G.
@param plant_loop [OpenStudio::Model::PlantLoop] chilled water loop @return [Boolean] returns true if successful, false if not
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb, line 8 def plant_loop_apply_prm_baseline_chilled_water_pumping_type(plant_loop) # Determine the pumping type. minimum_area_ft2 = 120_000 # Determine the area served area_served_m2 = plant_loop_total_floor_area_served(plant_loop) area_served_ft2 = OpenStudio.convert(area_served_m2, 'm^2', 'ft^2').get # Determine the primary pump type pri_control_type = 'Constant Flow' # Determine the secondary pump type sec_control_type = 'Riding Curve' if area_served_ft2 > minimum_area_ft2 sec_control_type = 'VSD No Reset' end # Report out the pumping type unless pri_control_type.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{plant_loop.name}, primary pump type is #{pri_control_type}.") end unless sec_control_type.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{plant_loop.name}, secondary pump type is #{sec_control_type}.") end # Modify all the primary pumps plant_loop.supplyComponents.each do |sc| if sc.to_PumpVariableSpeed.is_initialized pump = sc.to_PumpVariableSpeed.get pump_variable_speed_set_control_type(pump, pri_control_type) elsif sc.to_HeaderedPumpsVariableSpeed.is_initialized pump = sc.to_HeaderedPumpsVariableSpeed.get headered_pump_variable_speed_set_control_type(pump, control_type) end end # Modify all the secondary pumps plant_loop.demandComponents.each do |sc| if sc.to_PumpVariableSpeed.is_initialized pump = sc.to_PumpVariableSpeed.get pump_variable_speed_set_control_type(pump, sec_control_type) elsif sc.to_HeaderedPumpsVariableSpeed.is_initialized pump = sc.to_HeaderedPumpsVariableSpeed.get headered_pump_variable_speed_set_control_type(pump, control_type) end end return true end
Determine type of pump part load control type @note code_sections [90.1-2004_6.5.4.1]
@param pump [OpenStudio::Model::PumpVariableSpeed] OpenStudio pump object @param plant_loop_type [String] Type of plant loop @param pump_nominal_hp [Float] Pump
nominal horsepower @return [String] Pump
part load control type
# File lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb, line 11 def pump_variable_speed_get_control_type(pump, plant_loop_type, pump_nominal_hp) threshold = 50 # hp # Sizing factor to take into account that pumps # are typically sized to handle a ~10% pressure # increase and ~10% flow increase. design_sizing_factor = 1.25 # Get pump head in Pa pump_head_pa = pump.ratedPumpHead return 'VSD No Reset' if pump_nominal_hp * design_sizing_factor > threshold && pump_head_pa > 300_000 # 100 ft. of head # else return 'Riding Curve' end
Baseline infiltration rate
@return [Double] the baseline infiltration rate, in cfm/ft^2 exterior above grade wall area at 75 Pa
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Space.rb, line 7 def space_infiltration_rate_75_pa(space = nil) basic_infil_rate_cfm_per_ft2 = 1.8 return basic_infil_rate_cfm_per_ft2 end
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.
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.ThermalZone.rb, line 11 def thermal_zone_demand_control_ventilation_limits(thermal_zone) min_area_ft2 = nil # No minimum area min_occ_per_1000_ft2 = 100 # Convert to SI min_occ_per_ft2 = min_occ_per_1000_ft2 / 1000.0 min_ft2_per_occ = 1.0 / min_occ_per_ft2 min_m2_per_occ = OpenStudio.convert(min_ft2_per_occ, 'ft^2', 'm^2').get return [min_area_ft2, min_m2_per_occ] end