class ASHRAE901PRM < Standard # @!group ZoneHVACComponent # Sets the fan power of zone level HVAC equipment # (Fan coils, Unit Heaters, PTACs, PTHPs, VRF Terminals, WSHPs, ERVs) # based on the W/cfm specified in the standard. # # @return [Boolean] returns true if successful, false if not def zone_hvac_component_apply_prm_baseline_fan_power(zone_hvac_component) OpenStudio.logFree(OpenStudio::Debug, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', "Setting fan power for #{zone_hvac_component.name}.") # Convert this to the actual class type zone_hvac = if zone_hvac_component.to_ZoneHVACFourPipeFanCoil.is_initialized zone_hvac_component.to_ZoneHVACFourPipeFanCoil.get elsif zone_hvac_component.to_ZoneHVACUnitHeater.is_initialized zone_hvac_component.to_ZoneHVACUnitHeater.get elsif zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.get elsif zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.is_initialized zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.get elsif zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.is_initialized zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.get elsif zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.is_initialized zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.get elsif zone_hvac_component.to_ZoneHVACEnergyRecoveryVentilator.is_initialized zone_hvac_component.to_ZoneHVACEnergyRecoveryVentilator.get end # Do nothing for other types of zone HVAC equipment return false if zone_hvac.nil? # Do nothing if zone hav component isn't assigned to thermal zone return false unless zone_hvac.thermalZone.is_initialized # Get baseline system type system_type = zone_hvac.thermalZone.get.additionalProperties.getFeatureAsString('baseline_system_type').get # Get non-mechanically cooled flag if zone_hvac.thermalZone.get.additionalProperties.hasFeature('non_mechanically_cooled') nmc_flag = zone_hvac.thermalZone.get.additionalProperties.hasFeature('non_mechanically_cooled') else nmc_flag = false end # Get the fan fan = if zone_hvac.supplyAirFan.to_FanConstantVolume.is_initialized zone_hvac.supplyAirFan.to_FanConstantVolume.get elsif zone_hvac.supplyAirFan.to_FanVariableVolume.is_initialized zone_hvac.supplyAirFan.to_FanVariableVolume.get elsif zone_hvac.supplyAirFan.to_FanOnOff.is_initialized zone_hvac.supplyAirFan.to_FanOnOff.get elsif zone_hvac.supplyAirFan.to_FanSystemModel.is_initialized zone_hvac.supplyAirFan.to_FanSystemModel.get end if system_type == 'SZ_CV' # System 12, 13 # Get design supply air flow rate (whether autosized or hard-sized) dsn_air_flow_m3_per_s = 0 dsn_air_flow_cfm = 0 if fan.maximumFlowRate.is_initialized dsn_air_flow_m3_per_s = fan.maximumFlowRate.get elsif fan.isMaximumFlowRateAutosized dsn_air_flow_m3_per_s = fan.autosizedMaximumFlowRate.get end dsn_air_flow_cfm = OpenStudio.convert(dsn_air_flow_m3_per_s, 'm^3/s', 'cfm').get # Determine allowable fan BHP and power allowable_fan_bhp = 0.00094 * dsn_air_flow_cfm + thermal_zone_get_fan_power_limitations(zone_hvac.thermalZone.get, false) fan_apply_standard_minimum_motor_efficiency(fan, allowable_fan_bhp) allowable_power_w = allowable_fan_bhp * 746 / fan.motorEfficiency # Modify fan pressure rise to match target fan power fan_adjust_pressure_rise_to_meet_fan_power(fan, allowable_power_w) else # System 1, 2 # Determine the W/cfm fan_efficacy_w_per_cfm = 0.0 case system_type when 'PTAC', 'PTHP' fan_efficacy_w_per_cfm = 0.3 # System 9, 10 when 'Gas_Furnace', 'Electric_Furnace' # Zone heater cannot provide cooling if nmc_flag & !zone_hvac_component.to_ZoneHVACUnitHeater.is_initialized fan_efficacy_w_per_cfm = 0.054 else fan_efficacy_w_per_cfm = 0.3 end else OpenStudio.logFree(OpenStudio::Error, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', 'Zone HVAC system fan power lookup missing.') end # Convert efficacy to metric fan_efficacy_w_per_m3_per_s = OpenStudio.convert(fan_efficacy_w_per_cfm, 'm^3/s', 'cfm').get # Get the maximum flow rate through the fan max_air_flow_rate = nil if fan.maximumFlowRate.is_initialized max_air_flow_rate = fan.maximumFlowRate.get elsif fan.autosizedMaximumFlowRate.is_initialized max_air_flow_rate = fan.autosizedMaximumFlowRate.get end max_air_flow_rate_cfm = OpenStudio.convert(max_air_flow_rate, 'm^3/s', 'ft^3/min').get # Set the impeller efficiency fan_change_impeller_efficiency(fan, fan_baseline_impeller_efficiency(fan)) # Get fan BHP fan_bhp = fan_brake_horsepower(fan) # Set the motor efficiency, preserving the impeller efficiency. # For zone HVAC fans, a bhp lookup of 0.5bhp is always used because # they are assumed to represent a series of small fans in reality. fan_apply_standard_minimum_motor_efficiency(fan, fan_bhp) # Calculate a new pressure rise to hit the target W/cfm fan_tot_eff = fan.fanEfficiency fan_rise_new_pa = fan_efficacy_w_per_m3_per_s * fan_tot_eff fan.setPressureRise(fan_rise_new_pa) # Calculate the newly set efficacy fan_power_new_w = fan_rise_new_pa * max_air_flow_rate / fan_tot_eff fan_efficacy_new_w_per_cfm = fan_power_new_w / max_air_flow_rate_cfm OpenStudio.logFree(OpenStudio::Info, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', "For #{zone_hvac_component.name}: fan efficacy set to #{fan_efficacy_new_w_per_cfm.round(2)} W/cfm.") end return true end # Default occupancy fraction threshold for determining if the spaces served by the zone hvac are occupied # # @return [Double] unoccupied threshold def zone_hvac_unoccupied_threshold # Use 10% based on PRM-RM return 0.10 end end