class ASHRAE9012007

This class holds methods that apply ASHRAE 90.1-2007 to a given model. @ref [References::ASHRAE9012007]

Attributes

template[R]

Public Class Methods

new() click to toggle source
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.rb, line 8
def initialize
  @template = '90.1-2007'
  load_standards_database
end

Public Instance Methods

air_loop_hvac_demand_control_ventilation_limits(air_loop_hvac) click to toggle source

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_2007/ashrae_90_1_2007.AirLoopHVAC.rb, line 9
def air_loop_hvac_demand_control_ventilation_limits(air_loop_hvac)
  min_oa_without_economizer_cfm = 3000
  min_oa_with_economizer_cfm = 1200
  return [min_oa_without_economizer_cfm, min_oa_with_economizer_cfm]
end
air_loop_hvac_energy_recovery_ventilator_flow_limit(air_loop_hvac, climate_zone, pct_oa) click to toggle source

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_2007/ashrae_90_1_2007.AirLoopHVAC.rb, line 68
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
air_loop_hvac_motorized_oa_damper_limits(air_loop_hvac, climate_zone) click to toggle source

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_2007/ashrae_90_1_2007.AirLoopHVAC.rb, line 20
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
air_loop_hvac_single_zone_controls_num_stages(air_loop_hvac, climate_zone) click to toggle source

Determine the number of stages that should be used as controls for single zone DX systems. 90.1-2007 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_2007/ashrae_90_1_2007.AirLoopHVAC.rb, line 56
def air_loop_hvac_single_zone_controls_num_stages(air_loop_hvac, climate_zone)
  num_stages = 1
  return num_stages
end
air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(air_terminal_single_duct_vav_reheat, zone_oa_per_area) click to toggle source

@!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_2007/ashrae_90_1_2007.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
boiler_get_eff_fplr(boiler_hot_water) click to toggle source

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_2007/ashrae_90_1_2007.BoilerHotWater.rb, line 6
def boiler_get_eff_fplr(boiler_hot_water)
  return 'Boiler with No Minimum Turndown'
end
chiller_electric_eir_get_cap_f_t_curve_name(chiller_electric_eir, compressor_type, cooling_type, chiller_tonnage, compliance_path) click to toggle source

Get applicable performance curve for capacity as a function of temperature

@param chiller_electric_eir [OpenStudio::Model::ChillerElectricEIR] chiller object @param compressor_type [String] compressor type @param cooling_type [String] cooling type (‘AirCooled’ or ‘WaterCooled’) @param chiller_tonnage [Double] chiller capacity in ton @return [String] name of applicable cuvre, nil if not found @todo the current assingment is meant to replicate what was in the data, it probably needs to be reviewed

# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.ChillerElectricEIR.rb, line 10
def chiller_electric_eir_get_cap_f_t_curve_name(chiller_electric_eir, compressor_type, cooling_type, chiller_tonnage, compliance_path)
  case cooling_type
  when 'AirCooled'
    return 'AirCooled_Chiller_2010_PathA_CAPFT'
  when 'WaterCooled'
    case compressor_type
    when 'Centrifugal'
      if chiller_tonnage >= 150
        return 'WaterCooled_Centrifugal_Chiller_GT150_2004_CAPFT'
      else
        return 'WaterCooled_Centrifugal_Chiller_LT150_2004_CAPFT'
      end
    when 'Reciprocating', 'Rotary Screw', 'Scroll'
      if chiller_tonnage >= 150
        return 'WaterCooled_PositiveDisplacement_Chiller_GT150_2010_PathA_CAPFT' # 2010 reference might suggest that this is the wrong curve
      else
        return 'WaterCooled_PositiveDisplacement_Chiller_LT150_2010_PathA_CAPFT' # 2010 reference might suggest that this is the wrong curve
      end
    else
      return nil
    end
  else
    return nil
  end
end
chiller_electric_eir_get_eir_f_plr_curve_name(chiller_electric_eir, compressor_type, cooling_type, chiller_tonnage, compliance_path) click to toggle source

Get applicable performance curve for EIR as a function of part load ratio

@param chiller_electric_eir [OpenStudio::Model::ChillerElectricEIR] chiller object @param compressor_type [String] compressor type @param cooling_type [String] cooling type (‘AirCooled’ or ‘WaterCooled’) @param chiller_tonnage [Double] chiller capacity in ton @return [String] name of applicable cuvre, nil if not found @todo the current assingment is meant to replicate what was in the data, it probably needs to be reviewed

# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.ChillerElectricEIR.rb, line 78
def chiller_electric_eir_get_eir_f_plr_curve_name(chiller_electric_eir, compressor_type, cooling_type, chiller_tonnage, compliance_path)
  case cooling_type
  when 'AirCooled'
    return 'AirCooled_Chiller_AllCapacities_2004_2010_EIRFPLR'
  when 'WaterCooled'
    case compressor_type
    when 'Centrifugal'
      return 'ChlrWtrCentPathAAllEIRRatio_fQRatio'
    when 'Reciprocating', 'Rotary Screw', 'Scroll'
      return 'ChlrWtrPosDispPathAAllEIRRatio_fTchwsTcwsSI'
    else
      return nil
    end
  else
    return nil
  end
end
chiller_electric_eir_get_eir_f_t_curve_name(chiller_electric_eir, compressor_type, cooling_type, chiller_tonnage, compliance_path) click to toggle source

Get applicable performance curve for EIR as a function of temperature

@param chiller_electric_eir [OpenStudio::Model::ChillerElectricEIR] chiller object @param compressor_type [String] compressor type @param cooling_type [String] cooling type (‘AirCooled’ or ‘WaterCooled’) @param chiller_tonnage [Double] chiller capacity in ton @return [String] name of applicable cuvre, nil if not found @todo the current assingment is meant to replicate what was in the data, it probably needs to be reviewed

# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.ChillerElectricEIR.rb, line 44
def chiller_electric_eir_get_eir_f_t_curve_name(chiller_electric_eir, compressor_type, cooling_type, chiller_tonnage, compliance_path)
  case cooling_type
  when 'AirCooled'
    return 'AirCooled_Chiller_2010_PathA_EIRFT'
  when 'WaterCooled'
    case compressor_type
    when 'Centrifugal'
      if chiller_tonnage >= 150
        return 'WaterCooled_Centrifugal_Chiller_GT150_2004_EIRFT'
      else
        return 'WaterCooled_Centrifugal_Chiller_LT150_2004_EIRFT'
      end
    when 'Reciprocating', 'Rotary Screw', 'Scroll'
      if chiller_tonnage >= 150
        return 'WaterCooled_PositiveDisplacement_Chiller_GT150_2010_PathA_EIRFT' # 2010 reference might suggest that this is the wrong curve
      else
        return 'WaterCooled_PositiveDisplacement_Chiller_LT150_2010_PathA_EIRFT' # 2010 reference might suggest that this is the wrong curve
      end
    else
      return nil
    end
  else
    return nil
  end
end
fan_constant_volume_airloop_fan_pressure_rise(fan_constant_volume) click to toggle source

Determine the prototype fan pressure rise for a constant volume fan on an AirLoopHVAC based on system airflow. Defaults to the logic from ASHRAE 90.1-2004 prototypes.

@param fan_constant_volume [OpenStudio::Model::FanConstantVolume] constant volume fan object @return [Double] pressure rise in inches H20

# File lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanConstantVolume.rb, line 9
def fan_constant_volume_airloop_fan_pressure_rise(fan_constant_volume)
  # Get the max flow rate from the fan.
  maximum_flow_rate_m3_per_s = nil
  if fan_constant_volume.maximumFlowRate.is_initialized
    maximum_flow_rate_m3_per_s = fan_constant_volume.maximumFlowRate.get
  elsif fan_constant_volume.autosizedMaximumFlowRate.is_initialized
    maximum_flow_rate_m3_per_s = fan_constant_volume.autosizedMaximumFlowRate.get
  else
    OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.FanConstantVolume', "For #{fan_constant_volume.name} max flow rate is not available, cannot apply prototype assumptions.")
    return false
  end

  # Convert max flow rate to cfm
  maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s, 'm^3/s', 'cfm').get

  # Determine the pressure rise
  pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
                           2.5
                         else # Over 7,437 cfm
                           4.09
                         end

  return pressure_rise_in_h2o
end
fan_on_off_airloop_or_unitary_fan_pressure_rise(fan_on_off) click to toggle source

Determine the prototype fan pressure rise for an on off fan on an AirLoopHVAC or inside a unitary system based on system airflow. Defaults to the logic from ASHRAE 90.1-2004 prototypes.

@param fan_on_off [OpenStudio::Model::FanOnOff] on off fan object @return [Double] pressure rise in inches H20

# File lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanOnOff.rb, line 9
def fan_on_off_airloop_or_unitary_fan_pressure_rise(fan_on_off)
  # Get the max flow rate from the fan.
  maximum_flow_rate_m3_per_s = nil
  if fan_on_off.maximumFlowRate.is_initialized
    maximum_flow_rate_m3_per_s = fan_on_off.maximumFlowRate.get
  elsif fan_on_off.autosizedMaximumFlowRate.is_initialized
    maximum_flow_rate_m3_per_s = fan_on_off.autosizedMaximumFlowRate.get
  else
    OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.FanOnOff', "For #{fan_on_off.name} max flow rate is not available, cannot apply prototype assumptions.")
    return false
  end

  # Convert max flow rate to cfm
  maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s, 'm^3/s', 'cfm').get

  # Determine the pressure rise
  pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
                           2.5
                         else # Over 7,437 cfm
                           4.09
                         end

  return pressure_rise_in_h2o
end
fan_variable_volume_airloop_fan_pressure_rise(fan_variable_volume) click to toggle source

Determine the prototype fan pressure rise for a variable volume fan on an AirLoopHVAC based on system airflow. Defaults to the logic from ASHRAE 90.1-2004 prototypes.

@param fan_variable_volume [OpenStudio::Model::FanVariableVolume] variable volume fan object @return [Double] pressure rise in inches H20

# File lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb, line 9
def fan_variable_volume_airloop_fan_pressure_rise(fan_variable_volume)
  # Get the max flow rate from the fan.
  maximum_flow_rate_m3_per_s = nil
  if fan_variable_volume.maximumFlowRate.is_initialized
    maximum_flow_rate_m3_per_s = fan_variable_volume.maximumFlowRate.get
  elsif fan_variable_volume.autosizedMaximumFlowRate.is_initialized
    maximum_flow_rate_m3_per_s = fan_variable_volume.autosizedMaximumFlowRate.get
  else
    OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.FanVariableVolume', "For #{fan_variable_volume.name} max flow rate is not available, cannot apply prototype assumptions.")
    return false
  end

  # Convert max flow rate to cfm
  maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s, 'm^3/s', 'cfm').get

  # Determine the pressure rise
  pressure_rise_in_h2o = if maximum_flow_rate_cfm < 4648
                           4.0
                         else # Over 7,437 cfm
                           5.58
                         end

  return pressure_rise_in_h2o
end
fan_variable_volume_part_load_fan_power_limitation_hp_limit(fan_variable_volume) click to toggle source

The threhold horsepower below which part load control is not required. 10 nameplate HP threshold is equivalent to motors with input powers of 7.54 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_2007/ashrae_90_1_2007.FanVariableVolume.rb, line 10
def fan_variable_volume_part_load_fan_power_limitation_hp_limit(fan_variable_volume)
  hp_limit = 7.54
  return hp_limit
end
load_standards_database(data_directories = []) click to toggle source

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

Calls superclass method ASHRAE901#load_standards_database
# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.rb, line 17
def load_standards_database(data_directories = [])
  super([__dir__] + data_directories)
end
model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type, area_ft2, num_stories, custom) click to toggle source

Determines which system number is used for the baseline system. @return [String] the system number: 1_or_2, 3_or_4, 5_or_6, 7_or_8, 9_or_10

# File lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Model.rb, line 8
def model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type, area_ft2, num_stories, custom)
  sys_num = nil

  # @todo refactor: figure out this weird template switching case
  # For a custom scenario, use the lookup method from
  # a different standard instead of the specified standard.
  # if custom == "90.1-2007 with addenda dn"
  # OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', 'Custom; per Addenda dn of 90.1-2007, System 10 and 11 (same as system 9 and 10 in 90.1-2010) will be used for heated only space.')
  # template = '90.1-2010'
  # sys_num = model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type, area_ft2, num_stories, custom)
  # return sys_num
  # end

  # Set the area limit
  limit_ft2 = 25_000

  # Warn about heated only
  if area_type == 'heatedonly'
    OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Per Table G3.1.10.d, '(In the proposed building) Where no cooling system exists or no cooling system has been specified, the cooling system shall be identical to the system modeled in the baseline building design.' This requires that you go back and add a cooling system to the proposed model.  This code cannot do that for you; you must do it manually.")
  end

  case area_type
  when 'residential'
    sys_num = '1_or_2'
  when 'nonresidential', 'heatedonly'
    # nonresidential and 3 floors or less and <25,000 ft2
    if num_stories <= 3 && area_ft2 < limit_ft2
      sys_num = '3_or_4'
    # nonresidential and 4 or 5 floors or 5 floors or less and 25,000 ft2 to 150,000 ft2
    elsif ((num_stories == 4 || num_stories == 5) && area_ft2 < limit_ft2) || (num_stories <= 5 && (area_ft2 >= limit_ft2 && area_ft2 <= 150_000))
      sys_num = '5_or_6'
    # nonresidential and more than 5 floors or >150,000 ft2
    elsif num_stories >= 5 || area_ft2 > 150_000
      sys_num = '7_or_8'
    end
  end

  return sys_num
end
pump_variable_speed_get_control_type(pump, plant_loop_type, pump_nominal_hp) click to toggle source

Determine type of pump part load control type @note code_sections [90.1-2007_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_2007/ashrae_90_1_2007.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
space_infiltration_rate_75_pa(space = nil) click to toggle source

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_2007/ashrae_90_1_2007.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
thermal_zone_demand_control_ventilation_limits(thermal_zone) click to toggle source

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_2007/ashrae_90_1_2007.ThermalZone.rb, line 11
def thermal_zone_demand_control_ventilation_limits(thermal_zone)
  min_area_ft2 = 500
  min_occ_per_1000_ft2 = 40

  # Convert to SI
  min_area_m2 = OpenStudio.convert(min_area_ft2, 'ft^2', 'm^2').get
  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_m2, min_m2_per_occ]
end