Class: ASHRAE9012007

Inherits:
ASHRAE901 show all
Defined in:
lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.rb,
lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Model.rb,
lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Space.rb,
lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb,
lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.ThermalZone.rb,
lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb,
lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanOnOff.rb,
lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanConstantVolume.rb,
lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb,
lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirTerminalSingleDuctVAVReheat.rb

Overview

This class holds methods that apply ASHRAE 90.1-2007 to a given model.

Technical References:

Constant Summary collapse

@@template =

rubocop:disable Style/ClassVars

'90.1-2007'

Instance Attribute Summary collapse

Model collapse

Space collapse

AirLoopHVAC collapse

ThermalZone collapse

FanVariableVolume collapse

FanOnOff collapse

FanConstantVolume collapse

AirTerminalSingleDuctVAVReheat collapse

Instance Method Summary collapse

Constructor Details

#initializeASHRAE9012007

Returns a new instance of ASHRAE9012007.


9
10
11
12
13
# File 'lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.rb', line 9

def initialize
  super()
  @template = @@template
  load_standards_database
end

Instance Attribute Details

#templateObject (readonly)

Returns the value of attribute template


7
8
9
# File 'lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.rb', line 7

def template
  @template
end

Instance Method Details

#air_loop_hvac_demand_control_ventilation_limits(air_loop_hvac) ⇒ Array<Double>

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. are zero for both types.

Returns:

  • (Array<Double>)
    min_oa_without_economizer_cfm, min_oa_with_economizer_cfm

9
10
11
12
13
# 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) ⇒ Double

Determine the airflow limits that govern whether or not an ERV is required. Based on climate zone and % OA. if nil, ERV is never required.

Returns:

  • (Double)

    the flow rate above which an ERV is required.


50
51
52
53
54
55
56
57
58
59
# File 'lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb', line 50

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) ⇒ Array<Double>

Determine the air flow and number of story limits for whether motorized OA damper is required.

Returns:

  • (Array<Double>)
    minimum_oa_flow_cfm, maximum_stories

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb', line 18

def air_loop_hvac_motorized_oa_damper_limits(air_loop_hvac, climate_zone)
  case climate_zone
  when 'ASHRAE 169-2006-1A',
      'ASHRAE 169-2006-1B',
      'ASHRAE 169-2006-2A',
      'ASHRAE 169-2006-2B',
      'ASHRAE 169-2006-3A',
      'ASHRAE 169-2006-3B',
      'ASHRAE 169-2006-3C',
    minimum_oa_flow_cfm = 300
    maximum_stories = 999 # Any number of stories
  else
    minimum_oa_flow_cfm = 300
    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) ⇒ Integer

Determine the number of stages that should be used as controls for single zone DX systems. 90.1-2007 requires 1 stage.

Returns:

  • (Integer)

    the number of stages: 0, 1, 2


41
42
43
44
# File 'lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb', line 41

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, building_type, zone_oa_per_area) ⇒ Bool

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

Parameters:

  • zone_oa_per_area (Double)

    the zone outdoor air per area, m^3/s

Returns:

  • (Bool)

    returns true if successful, false if not


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirTerminalSingleDuctVAVReheat.rb', line 11

def air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(air_terminal_single_duct_vav_reheat, building_type, zone_oa_per_area)
  vav_name = air_terminal_single_duct_vav_reheat.name.get
  min_damper_position = 0.3

  # High OA zones
  # Determine whether or not to use the high minimum guess.
  # Cutoff was determined by correlating apparent minimum guesses
  # to OA rates in prototypes since not well documented in papers.
  if zone_oa_per_area > 0.001 # 0.001 m^3/s*m^2 = .196 cfm/ft2

    min_damper_position = if building_type == 'Outpatient' || building_type == 'Hospital'
                            1.0
                          else
                            0.7
                          end
  end

  # Set the minimum flow fraction
  air_terminal_single_duct_vav_reheat.setConstantMinimumAirFlowFraction(min_damper_position)

  return true
end

#fan_constant_volume_airloop_fan_pressure_rise(fan_constant_volume) ⇒ Double

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

Returns:

  • (Double)

    the pressure rise (in H2O). Defaults


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanConstantVolume.rb', line 8

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) ⇒ Double

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

Returns:

  • (Double)

    the pressure rise (in H2O). Defaults


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 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) ⇒ Double

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

Returns:

  • (Double)

    the pressure rise (in H2O). Defaults


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb', line 8

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) ⇒ Double

TODO:

AddRef

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

Parameters:

  • fan_variable_volume (OpenStudio::Model::FanVariableVolume)

    the fan

Returns:

  • (Double)

    the limit, in horsepower. Return nil for no limit by default.


10
11
12
13
# 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

#model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type, area_ft2, num_stories, custom) ⇒ String

Determines which system number is used for the baseline system. 5_or_6, 7_or_8, 9_or_10

Returns:

  • (String)

    the system number: 1_or_2, 3_or_4,


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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

#space_infiltration_rate_75_pa(space) ⇒ Double

Determine the base infiltration rate at 75 PA.

defaults to no infiltration.

Returns:

  • (Double)

    the baseline infiltration rate, in cfm/ft^2


8
9
10
11
# File 'lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Space.rb', line 8

def space_infiltration_rate_75_pa(space)
  basic_infil_rate_cfm_per_ft2 = 1.8
  return basic_infil_rate_cfm_per_ft2
end

#thermal_zone_demand_control_ventilation_limits(thermal_zone) ⇒ Array<Double>

Determine the area and occupancy level limits for demand control ventilation.

and the minimum occupancy density in m^2/person. Returns nil if there is no requirement.

Parameters:

  • thermal_zone (OpenStudio::Model::ThermalZone)

    the thermal zone

Returns:

  • (Array<Double>)

    the minimum area, in m^2


11
12
13
14
15
16
17
18
19
20
21
22
# 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