module Outpatient

Custom changes for the Outpatient prototype. These are changes that are inconsistent with other prototype building types.

Public Instance Methods

add_door_infiltration(climate_zone, model) click to toggle source

add door infiltration

@param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 208
def add_door_infiltration(climate_zone, model)
  # add extra infiltration for vestibule door
  case template
    when 'DOE Ref 1980-2004', 'DOE Ref Pre-1980'
      return true
    else
      vestibule_space = model.getSpaceByName('Floor 1 Vestibule').get
      infiltration_vestibule_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model)
      infiltration_vestibule_door.setName('Vestibule door Infiltration')
      infiltration_rate_vestibule_door = 0
      case template
        when '90.1-2004'
          infiltration_rate_vestibule_door = 1.186002811
          infiltration_vestibule_door.setSchedule(model_add_schedule(model, 'OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
        when '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
          case climate_zone
            when 'ASHRAE 169-2006-0A',
                 'ASHRAE 169-2006-1A',
                 'ASHRAE 169-2006-2A',
                 'ASHRAE 169-2006-2B',
                 'ASHRAE 169-2013-0A',
                 'ASHRAE 169-2013-1A',
                 'ASHRAE 169-2013-2A',
                 'ASHRAE 169-2013-2B'
              infiltration_rate_vestibule_door = 1.186002811
              infiltration_vestibule_door.setSchedule(model_add_schedule(model, 'OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
            else
              infiltration_rate_vestibule_door = 0.776824762
              infiltration_vestibule_door.setSchedule(model_add_schedule(model, 'OutPatientHealthCare INFIL_Door_Opening_SCH_0.131'))
          end
      end
      infiltration_vestibule_door.setDesignFlowRate(infiltration_rate_vestibule_door)
      infiltration_vestibule_door.setSpace(vestibule_space)
  end
  return true
end
add_extra_equip_elevator_pump_room(model) click to toggle source

add extra equipment for mechanical room

@param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 86
def add_extra_equip_elevator_pump_room(model)
  elevator_pump_room = model.getSpaceByName('Floor 1 Elevator Pump Room').get
  elec_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
  elec_equip_def.setName('Elevator Pump Room Electric Equipment Definition')
  elec_equip_def.setFractionLatent(0)
  elec_equip_def.setFractionRadiant(0.1)
  elec_equip_def.setFractionLost(0.9)
  elec_equip_def.setDesignLevel(48_165)
  elec_equip = OpenStudio::Model::ElectricEquipment.new(elec_equip_def)
  elec_equip.setName('Elevator Pump Room Elevator Equipment')
  elec_equip.setSpace(elevator_pump_room)
  case template
    when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
      elec_equip.setSchedule(model_add_schedule(model, 'OutPatientHealthCare BLDG_ELEVATORS'))

      # add elevator fan and lights for 90.1 prototypes
      elec_equip_def2 = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
      elec_equip_def2.setName('Elevator Pump Room Electric Equipment Definition2')
      elec_equip_def2.setFractionLatent(0)
      elec_equip_def2.setFractionRadiant(0.1)
      elec_equip_def2.setFractionLost(0.9)

      case template
      when '90.1-2004', '90.1-2007'
        elec_equip_def2.setDesignLevel(485.7)
      when '90.1-2010'
        elec_equip_def2.setDesignLevel(317.7)
      when '90.1-2013', '90.1-2016', '90.1-2019'
        elec_equip_def2.setDesignLevel(188)
      end

      elec_equip2 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def2)
      elec_equip2.setName('Elevator Lights Fan')
      elec_equip2.setSpace(elevator_pump_room)

      case template # light fan schedule for outpatient already exist in the schedule data sheet.
      when '90.1-2004', '90.1-2007'
        elec_equip2.setSchedule(model_add_schedule(model, 'OutPatientHealthCare ELEV_LIGHT_FAN_SCH_24_7'))
      when '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
        elec_equip2.setSchedule(model_add_schedule(model, 'OutPatientHealthCare ELEV_LIGHT_FAN_SCH_ADD_DF'))
      end

  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
    elec_equip.setSchedule(model_add_schedule(model, 'OutPatientHealthCare BLDG_ELEVATORS_Pre2004'))
  end
  return true
end
add_humidifier(hot_water_loop, model) click to toggle source

add humidifier to AHU1 (contains operating room1)

@param hot_water_loop [OpenStudio::Model::PlantLoop] hot water loop @param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 250
def add_humidifier(hot_water_loop, model)
  operatingroom1_space = model.getSpaceByName('Floor 1 Operating Room 1').get
  operatingroom1_zone = operatingroom1_space.thermalZone.get
  humidistat = OpenStudio::Model::ZoneControlHumidistat.new(model)
  humidistat.setHumidifyingRelativeHumiditySetpointSchedule(model_add_schedule(model, 'OutPatientHealthCare MinRelHumSetSch'))
  humidistat.setDehumidifyingRelativeHumiditySetpointSchedule(model_add_schedule(model, 'OutPatientHealthCare MaxRelHumSetSch'))
  operatingroom1_zone.setZoneControlHumidistat(humidistat)
  model.getAirLoopHVACs.sort.each do |air_loop|
    if air_loop.thermalZones.include? operatingroom1_zone
      humidifier = OpenStudio::Model::HumidifierSteamElectric.new(model)
      humidifier.setRatedCapacity(3.72E-5)
      humidifier.setRatedPower(100_000)
      humidifier.setName("#{air_loop.name.get} Electric Steam Humidifier")
      # get the water heating coil and add humidifier to the outlet of heating coil (right before fan)
      htg_coil = nil
      air_loop.supplyComponents.each do |equip|
        if equip.to_CoilHeatingWater.is_initialized
          htg_coil = equip.to_CoilHeatingWater.get
        end
      end
      heating_coil_outlet_node = htg_coil.airOutletModelObject.get.to_Node.get
      supply_outlet_node = air_loop.supplyOutletNode
      humidifier.addToNode(heating_coil_outlet_node)
      humidity_spm = OpenStudio::Model::SetpointManagerSingleZoneHumidityMinimum.new(model)
      case template
        when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
          create_coil_heating_electric(model,
                                       air_loop_node: supply_outlet_node,
                                       name: 'AHU1 extra Electric Htg Coil')
          create_coil_heating_water(model,
                                    hot_water_loop,
                                    air_loop_node: supply_outlet_node,
                                    name: 'AHU1 extra Water Htg Coil')
      end
      # humidity_spm.addToNode(supply_outlet_node)
      humidity_spm.addToNode(humidifier.outletModelObject.get.to_Node.get)
      humidity_spm.setControlZone(operatingroom1_zone)
    end
  end
  return true
end
adjust_clg_setpoint(climate_zone, model) click to toggle source

adjust cooling setpoint

@param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 139
def adjust_clg_setpoint(climate_zone, model)
  model.getSpaceTypes.sort.each do |space_type|
    space_type_name = space_type.name.get
    thermostat_name = "#{space_type_name} Thermostat"
    thermostat = model.getThermostatSetpointDualSetpointByName(thermostat_name).get
    case template
      when '90.1-2004', '90.1-2007', '90.1-2010'
        case climate_zone
          when 'ASHRAE 169-2006-0B',
               'ASHRAE 169-2006-1B',
               'ASHRAE 169-2006-2B',
               'ASHRAE 169-2006-3B',
               'ASHRAE 169-2013-0B',
               'ASHRAE 169-2013-1B',
               'ASHRAE 169-2013-2B',
               'ASHRAE 169-2013-3B'
            thermostat.setCoolingSetpointTemperatureSchedule(model_add_schedule(model, 'OutPatientHealthCare CLGSETP_SCH_YES_OPTIMUM'))
        end
    end
  end
  return true
end
adjust_infiltration(model) click to toggle source

adjust infiltration

@param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 166
def adjust_infiltration(model)
  case template
    when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
      model.getSpaces.sort.each do |space|
        space_type = space.spaceType.get
        # Skip interior spaces
        next if OpenstudioStandards::Geometry.space_get_exterior_wall_and_subsurface_area(space) <= 0
        # Skip spaces that have no infiltration objects to adjust
        next if space_type.spaceInfiltrationDesignFlowRates.size <= 0

        # get the infiltration information from the space type infiltration
        infiltration_space_type = space_type.spaceInfiltrationDesignFlowRates[0]
        infil_sch = infiltration_space_type.schedule.get
        infil_rate = nil
        infil_ach = nil
        if infiltration_space_type.flowperExteriorWallArea.is_initialized
          infil_rate = infiltration_space_type.flowperExteriorWallArea.get
        elsif infiltration_space_type.airChangesperHour.is_initialized
          infil_ach = infiltration_space_type.airChangesperHour.get
        end
        # Create an infiltration rate object for this space
        infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model)
        infiltration.setName("#{space.name} Infiltration")
        infiltration.setFlowperExteriorSurfaceArea(infil_rate) unless infil_rate.nil? || infil_rate.to_f.zero?
        infiltration.setAirChangesperHour(infil_ach) unless infil_ach.nil? || infil_ach.to_f.zero?
        infiltration.setSchedule(infil_sch)
        infiltration.setSpace(space)
      end
      model.getSpaceTypes.sort.each do |space_type|
        space_type.spaceInfiltrationDesignFlowRates.each(&:remove)
      end
    else
      return true
  end
  return true
end
air_loop_hvac_supply_air_temperature_reset_type(air_loop_hvac) click to toggle source

Type of SAT reset for this building type

@param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop @return [String] Returns type of SAT reset

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 593
def air_loop_hvac_supply_air_temperature_reset_type(air_loop_hvac)
  return 'oa'
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/common/buildings/Prototype.Outpatient.rb, line 519
def air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(air_terminal_single_duct_vav_reheat, zone_oa_per_area)
  # Minimum damper position
  # Based on AIA 2001 ventilation requirements
  # See Section 5.2.2.16 in Thornton et al. 2010
  # https://www.energycodes.gov/sites/default/files/documents/BECP_Energy_Cost_Savings_STD2010_May2011_v00.pdf
  if template == '90.1-2004' || template == '90.1-2007'
    min_damper_position = 0.3
    init_mdp = {
      'FLOOR 2 CONFERENCE TOILET' => 1.0,
      'FLOOR 2 EXAM 1' => 1.0,
      'FLOOR 2 EXAM 2' => 1.0,
      'FLOOR 2 EXAM 3' => 1.0,
      'FLOOR 2 EXAM 4' => 1.0,
      'FLOOR 2 EXAM 5' => 1.0,
      'FLOOR 2 EXAM 6' => 1.0,
      'FLOOR 2 EXAM 7' => 1.0,
      'FLOOR 2 EXAM 8' => 1.0,
      'FLOOR 2 EXAM 9' => 1.0,
      'FLOOR 2 RECEPTION TOILET' => 1.0,
      'FLOOR 2 WORK TOILET' => 1.0,
      'FLOOR 3 LOUNGE TOILET' => 1.0,
      'FLOOR 3 OFFICE TOILET' => 1.0,
      'FLOOR 3 PHYSICAL THERAPY 1' => 1.0,
      'FLOOR 3 PHYSICAL THERAPY 2' => 1.0,
      'FLOOR 3 PHYSICAL THERAPY TOILET' => 1.0,
      'FLOOR 3 STORAGE 1' => 1.0,
      'FLOOR 3 TREATMENT' => 1.0
    }
  elsif template == '90.1-2010' || template == '90.1-2013' || template == '90.1-2016' || template == '90.1-2019'
    min_damper_position = 0.2
    init_mdp = {
      'FLOOR 2 CONFERENCE TOILET' => 1.0,
      'FLOOR 2 EXAM 1' => 0.51,
      'FLOOR 2 EXAM 2' => 1.0,
      'FLOOR 2 EXAM 3' => 1.0,
      'FLOOR 2 EXAM 4' => 0.64,
      'FLOOR 2 EXAM 5' => 0.69,
      'FLOOR 2 EXAM 6' => 0.94,
      'FLOOR 2 EXAM 7' => 1.0,
      'FLOOR 2 EXAM 8' => 0.93,
      'FLOOR 2 EXAM 9' => 1.0,
      'FLOOR 2 RECEPTION TOILET' => 1.0,
      'FLOOR 2 WORK TOILET' => 1.0,
      'FLOOR 3 LOUNGE TOILET' => 1.0,
      'FLOOR 3 OFFICE TOILET' => 1.0,
      'FLOOR 3 PHYSICAL THERAPY 1' => 0.69,
      'FLOOR 3 PHYSICAL THERAPY 2' => 0.83,
      'FLOOR 3 PHYSICAL THERAPY TOILET' => 1.0,
      'FLOOR 3 STORAGE 1' => 1.0,
      'FLOOR 3 TREATMENT' => 0.81
    }
  end

  if init_mdp.nil?
    min_damper_position = 0.3
  else
    airlp = air_terminal_single_duct_vav_reheat.airLoopHVAC.get
    init_mdp.each do |zn_name, mdp|
      if air_terminal_single_duct_vav_reheat.name.to_s.upcase.strip.include? zn_name.to_s.strip
        min_damper_position = mdp
      end
    end
  end

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

  return true
end
apply_minimum_total_ach(building_type, model) click to toggle source

assign the minimum total air changes to the cooling minimum air flow in Sizing:Zone

@param building_type [String the building type @param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 449
def apply_minimum_total_ach(building_type, model)
  model.getSpaces.sort.each do |space|
    space_type_name = space.spaceType.get.standardsSpaceType.get
    search_criteria = {
      'template' => template,
      'building_type' => building_type,
      'space_type' => space_type_name
    }
    data = standards_lookup_table_first(table_name: 'space_types', search_criteria: search_criteria)

    if data.nil? ###
      OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "Could not find data for #{search_criteria}")
      next
    end

    # skip space type without minimum total air changes
    next if data['minimum_total_air_changes'].nil?

    # calculate the minimum total air flow
    minimum_total_ach = data['minimum_total_air_changes'].to_f
    space_volume = space.volume
    space_area = space.floorArea
    minimum_airflow_per_zone = minimum_total_ach * space_volume / 3600
    minimum_airflow_per_zone_floor_area = minimum_airflow_per_zone / space_area
    # add minimum total air flow limit to sizing:zone
    zone = space.thermalZone.get
    sizingzone = zone.sizingZone
    sizingzone.setCoolingDesignAirFlowMethod('DesignDayWithLimit')
    case template
      when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
        sizingzone.setCoolingMinimumAirFlow(minimum_airflow_per_zone)
      when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
        sizingzone.setCoolingMinimumAirFlowperZoneFloorArea(minimum_airflow_per_zone_floor_area)
    end
  end
  return true
end
model_adjust_vav_minimum_damper(model) click to toggle source

adjust room vav damper minimums

@param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 322
def model_adjust_vav_minimum_damper(model)
  # Minimum damper position for Outpatient prototype
  # Based on AIA 2001 ventilation requirements
  # See Section 5.2.2.16 in Thornton et al. 2010
  # https://www.energycodes.gov/sites/default/files/documents/BECP_Energy_Cost_Savings_STD2010_May2011_v00.pdf
  init_mdp = {
    'FLOOR 1 ANESTHESIA' => 1.0,
    'FLOOR 1 CLEAN' => 1.0,
    'FLOOR 1 CLEAN WORK' => 1.0,
    'FLOOR 1 LOBBY TOILET' => 1.0,
    'FLOOR 1 MRI TOILET' => 1.0,
    'FLOOR 1 NURSE TOILET' => 1.0,
    'FLOOR 1 OPERATING ROOM 1' => 1.0,
    'FLOOR 1 OPERATING ROOM 2' => 1.0,
    'FLOOR 1 OPERATING ROOM 3' => 1.0,
    'FLOOR 1 PACU' => 1.0,
    'FLOOR 1 PRE-OP ROOM 1' => 1.0,
    'FLOOR 1 PRE-OP ROOM 2' => 1.0,
    'FLOOR 1 PRE-OP TOILET' => 1.0,
    'FLOOR 1 PROCEDURE ROOM' => 1.0,
    'FLOOR 1 RECOVERY ROOM' => 1.0,
    'FLOOR 1 SOIL' => 1.0,
    'FLOOR 1 SOIL HOLD' => 1.0,
    'FLOOR 1 SOIL WORK' => 1.0,
    'FLOOR 1 STEP DOWN' => 1.0
  }

  model.getThermalZones.each do |zone|
    air_terminal = zone.airLoopHVACTerminal
    if air_terminal.is_initialized
      air_terminal = air_terminal.get
      if air_terminal.to_AirTerminalSingleDuctVAVReheat.is_initialized
        air_terminal = air_terminal.to_AirTerminalSingleDuctVAVReheat.get
        vav_name = air_terminal.name.get
        zone_oa_per_area = OpenstudioStandards::ThermalZone.thermal_zone_get_outdoor_airflow_rate_per_area(zone)
        case template
        # 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.
        when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
          air_terminal.setConstantMinimumAirFlowFraction(1.0) if vav_name.include?('Floor 1')
        # Minimum damper position for Outpatient prototype
        # Based on AIA 2001 ventilation requirements
        # See Section 5.2.2.16 in Thornton et al. 2010
        # https://www.energycodes.gov/sites/default/files/documents/BECP_Energy_Cost_Savings_STD2010_May2011_v00.pdf
        when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
          zone_name = zone.name.to_s.upcase.gsub(' ZN', '').strip
          if init_mdp.key? zone_name
            air_terminal.setConstantMinimumAirFlowFraction(init_mdp[zone_name])
          end
        end
      end
    end
  end
  return true
end
model_custom_geometry_tweaks(model, building_type, climate_zone, prototype_input) click to toggle source

geometry adjustments specific to the prototype model

@param model [OpenStudio::Model::Model] OpenStudio model object @param building_type [String the building type @param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @param prototype_input [Hash] hash of prototype inputs @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 505
def model_custom_geometry_tweaks(model, building_type, climate_zone, prototype_input)
  # Set original building North axis
  OpenstudioStandards::Geometry.model_set_building_north_axis(model, 0.0)
  return true
end
model_custom_hvac_tweaks(model, building_type, climate_zone, prototype_input) click to toggle source

hvac adjustments specific to the prototype model

@param model [OpenStudio::Model::Model] OpenStudio model object @param building_type [String the building type @param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @param prototype_input [Hash] hash of prototype inputs @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 11
def model_custom_hvac_tweaks(model, building_type, climate_zone, prototype_input)
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding HVAC')

  system_to_space_map = define_hvac_system_map(building_type, climate_zone)

  # add elevator for the elevator pump room (the fan&lights are already added via standard spreadsheet)
  add_extra_equip_elevator_pump_room(model)
  # adjust cooling setpoint at vintages 1B,2B,3B
  adjust_clg_setpoint(climate_zone, model)
  # Get the hot water loop
  hot_water_loop = nil
  model.getPlantLoops.sort.each do |loop|
    # If it has a boiler:hotwater, it is the correct loop
    unless loop.supplyComponents('OS:Boiler:HotWater'.to_IddObjectType).empty?
      hot_water_loop = loop
    end
  end
  # add humidifier to AHU1 (contains operating room 1)
  if hot_water_loop
    add_humidifier(hot_water_loop, model)
  else
    OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', 'Could not find hot water loop to attach humidifier to.')
  end

  # adjust minimum damper positions
  model_adjust_vav_minimum_damper(model)
  # adjust infiltration for vintages 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
  adjust_infiltration(model)
  # add door infiltration for vertibule
  add_door_infiltration(climate_zone, model)
  # reset boiler sizing factor to 0.3 (default 1)
  reset_boiler_sizing_factor(model)
  # assign the minimum total air changes to the cooling minimum air flow in Sizing:Zone
  apply_minimum_total_ach(building_type, model)

  # set coil sizing
  if template == '90.1-2004' || template == '90.1-2007'
    model.getCoilHeatingWaters.each do |coil|
      if coil.name.to_s == 'PVAV Outpatient F1 Main Htg Coil' || coil.name.to_s == 'PVAV Outpatient F2 F3 Main Htg Coil'
        coil.setRatedOutletAirTemperature(50.0)
      end
    end
  end

  # Some exceptions for the Outpatient
  # @todo Refactor: not sure if this is actually enabled in the original code
  #     if system_name.include? 'PVAV Outpatient F1'
  #       # Outpatient two AHU1 and AHU2 have different HVAC schedule
  #       hvac_op_sch = model_add_schedule(model, 'OutPatientHealthCare AHU1-Fan_Pre2004')
  #       # Outpatient has different temperature settings for sizing
  #       clg_sa_temp_f = 52 # for AHU1 in Outpatient, SAT is 52F
  #       sys_dsn_clg_sa_temp_f = if template == 'DOE Ref 1980-2004' || template == 'DOE Ref Pre-1980'
  #                                 52
  #                               else
  #                                 45
  #                               end
  #       zn_dsn_clg_sa_temp_f = 52 # zone cooling design SAT
  #       zn_dsn_htg_sa_temp_f = 104 # zone heating design SAT
  #     elsif system_name.include? 'PVAV Outpatient F2 F3'
  #       hvac_op_sch = model_add_schedule(model, 'OutPatientHealthCare AHU2-Fan_Pre2004')
  #       clg_sa_temp_f = 55 # for AHU2 in Outpatient, SAT is 55F
  #       sys_dsn_clg_sa_temp_f = 52
  #       zn_dsn_clg_sa_temp_f = 55 # zone cooling design SAT
  #       zn_dsn_htg_sa_temp_f = 104 # zone heating design SAT
  #     end

  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding HVAC')

  return true
end
model_custom_swh_tweaks(model, building_type, climate_zone, prototype_input) click to toggle source

swh adjustments specific to the prototype model

@param model [OpenStudio::Model::Model] OpenStudio model object @param building_type [String the building type @param climate_zone [String] ASHRAE climate zone, e.g. ‘ASHRAE 169-2013-4A’ @param prototype_input [Hash] hash of prototype inputs @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 494
def model_custom_swh_tweaks(model, building_type, climate_zone, prototype_input)
  return true
end
model_modify_oa_controller(model) click to toggle source

for 90.1-2010 Outpatient, AHU2 set minimum outdoor air flow rate as 0 AHU1 doesn’t have economizer

@param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 297
def model_modify_oa_controller(model)
  model.getAirLoopHVACs.sort.each do |air_loop|
    oa_system = air_loop.airLoopHVACOutdoorAirSystem.get
    controller_oa = oa_system.getControllerOutdoorAir
    controller_mv = controller_oa.controllerMechanicalVentilation
    # AHU1 OA doesn't have controller:mechanicalventilation
    if air_loop.name.to_s.include? 'Outpatient F1'
      controller_mv.setAvailabilitySchedule(model.alwaysOffDiscreteSchedule)
      # add minimum fraction of outdoor air schedule to AHU1
      controller_oa.setMinimumFractionofOutdoorAirSchedule(model_add_schedule(model, 'OutPatientHealthCare AHU-1_OAminOAFracSchedule'))
      # for AHU2, at vintages '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019' the minimum OA schedule is not the same as
      # airloop availability schedule, but separately assigned.
    elsif template == '90.1-2004' || template == '90.1-2007' || template == '90.1-2010' || template == '90.1-2013' || template == '90.1-2016' || template == '90.1-2019'
      controller_oa.setMinimumOutdoorAirSchedule(model_add_schedule(model, 'OutPatientHealthCare BLDG_OA_SCH'))
      # add minimum fraction of outdoor air schedule to AHU2
      controller_oa.setMinimumFractionofOutdoorAirSchedule(model_add_schedule(model, 'OutPatientHealthCare BLDG_OA_FRAC_SCH'))
    end
  end
  return true
end
model_reset_or_room_vav_minimum_damper(prototype_input, model) click to toggle source

For operating room 1&2 in 2010, 2013, 2016, and 2019 VAV minimum air flow is set by schedule This is NOT called in model_custom_hvac_tweaks, instead it is called by model_reset_or_room_vav_minimum_damper AFTER the sizing run, so that the system is sized at a constant airflow fraction of 1.0, not 0.3 as defaulted in the zone sizing object

@param prototype_input [Hash] hash of prototype inputs @param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 389
def model_reset_or_room_vav_minimum_damper(prototype_input, model)
  case template
  when '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
    model.getAirTerminalSingleDuctVAVReheats.sort.each do |air_terminal|
      air_terminal_name = air_terminal.name.get
      if air_terminal_name.include?('Floor 1 Operating Room 1') || air_terminal_name.include?('Floor 1 Operating Room 2')
        if model.version < OpenStudio::VersionString.new('3.0.1')
          air_terminal.setZoneMinimumAirFlowMethod('Scheduled')
        else
          air_terminal.setZoneMinimumAirFlowInputMethod('Scheduled')
        end
        air_terminal.setMinimumAirFlowFractionSchedule(model_add_schedule(model, 'OutPatientHealthCare OR_MinSA_Sched'))
      end
    end
  end
  return true
end
model_update_exhaust_fan_efficiency(model) click to toggle source

update exhuast fan efficiency

@param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 422
def model_update_exhaust_fan_efficiency(model)
  case template
    when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', '90.1-2016', '90.1-2019'
      model.getFanZoneExhausts.sort.each do |exhaust_fan|
        fan_name = exhaust_fan.name.to_s
        if (fan_name.include? 'X-Ray') || (fan_name.include? 'MRI Room')
          exhaust_fan.setFanEfficiency(0.16)
          exhaust_fan.setPressureRise(125)
        else
          exhaust_fan.setFanEfficiency(0.31)
          exhaust_fan.setPressureRise(249)
        end
      end
    when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
      model.getFanZoneExhausts.sort.each do |exhaust_fan|
        exhaust_fan.setFanEfficiency(0.338)
        exhaust_fan.setPressureRise(125)
      end
  end
  return true
end
reset_boiler_sizing_factor(model) click to toggle source

reset boiler sizing factor

@param model [OpenStudio::Model::Model] OpenStudio model object @return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb, line 411
def reset_boiler_sizing_factor(model)
  model.getBoilerHotWaters.sort.each do |boiler|
    boiler.setSizingFactor(0.3)
  end
  return true
end