module Pump

A variety of pump calculation methods that are the same regardless of pump type. These methods are available to PumpConstantSpeed, PumpVariableSpeed

Public Instance Methods

pump_apply_prm_pressure_rise_and_motor_efficiency(pump, target_w_per_gpm) click to toggle source

Set the pressure rise that corresponds to the target power per flow number, given the standard pump efficiency and the default EnergyPlus pump impeller efficiency of 0.78.

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@param target_w_per_gpm [Double] the target power per flow, in W/gpm @return [Boolean] returns true if successful, false if not @author jmarrec

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 14
def pump_apply_prm_pressure_rise_and_motor_efficiency(pump, target_w_per_gpm)
  # Eplus assumes an impeller efficiency of 0.78 to determine the total efficiency
  # http://bigladdersoftware.com/epx/docs/8-4/engineering-reference/component-sizing.html#pump-sizing
  # Rated_Power_Use = Rated_Volume_Flow_Rate * Rated_Pump_Head / Total_Efficiency
  # Rated_Power_Use / Rated_Volume_Flow_Rate =  Rated_Pump_Head / Total_Efficiency
  # Total_Efficiency = Motor_Efficiency * Impeler_Efficiency
  impeller_efficiency = 0.78

  # Get flow rate (whether autosized or hard-sized)
  flow_m3_per_s = 0
  flow_m3_per_s = if pump.to_PumpVariableSpeed.is_initialized || pump.to_PumpConstantSpeed.is_initialized
                    if pump.ratedFlowRate.is_initialized
                      pump.ratedFlowRate.get
                    elsif pump.autosizedRatedFlowRate.is_initialized
                      pump.autosizedRatedFlowRate.get
                    end
                  elsif pump.to_HeaderedPumpsVariableSpeed.is_initialized || pump.to_HeaderedPumpsConstantSpeed.is_initialized
                    if pump.totalRatedFlowRate.is_initialized
                      pump.totalRatedFlowRate.get / pump.numberofPumpsinBank
                    elsif pump.autosizedTotalRatedFlowRate.is_initialized
                      pump.autosizedTotalRatedFlowRate.get / pump.numberofPumpsinBank
                    end
                  end

  flow_gpm = OpenStudio.convert(flow_m3_per_s, 'm^3/s', 'gal/min').get

  # Calculate the target total pump motor power consumption
  target_motor_power_cons_w = target_w_per_gpm * flow_gpm
  target_motor_power_cons_hp = target_motor_power_cons_w / 745.7 # 745.7 W/HP

  # Find the motor efficiency using total power consumption
  # Note that this hp is ~5-10% high because it is being looked
  # up based on the motor consumption, which is always actually higher
  # than the brake horsepower.  This will bound the possible motor efficiency
  # values.  If a motor is just above a nominal size, and the next size
  # down has a lower efficiency value, later motor efficiency setting
  # methods can mess up the W/gpm.  All this nonsense avoids that.
  mot_eff_hi_end, nom_hp_hi_end = pump_standard_minimum_motor_efficiency_and_size(pump, target_motor_power_cons_hp)

  # Calculate the actual brake horsepower using this efficiency
  target_motor_bhp = target_motor_power_cons_hp * mot_eff_hi_end

  # Find the motor efficiency using actual bhp
  mot_eff_lo_end, nom_hp_lo_end = pump_standard_minimum_motor_efficiency_and_size(pump, target_motor_bhp)

  # If the efficiency drops you down into a lower band with
  # a lower efficiency value, use that for the motor efficiency.
  motor_efficiency = [mot_eff_lo_end, mot_eff_hi_end].min
  nominal_hp = [nom_hp_lo_end, nom_hp_hi_end].min

  # Calculate the brake horsepower that was assumed
  target_brake_power_hp = target_motor_power_cons_hp * motor_efficiency

  # Change the motor efficiency
  pump.setMotorEfficiency(motor_efficiency)

  total_efficiency = impeller_efficiency * motor_efficiency

  desired_power_per_m3_s = OpenStudio.convert(target_w_per_gpm, 'W*min/gal', 'W*s/m^3').get

  pressure_rise_pa = desired_power_per_m3_s * total_efficiency
  pressure_rise_ft_h2o = OpenStudio.convert(pressure_rise_pa, 'Pa', 'ftH_{2}O').get

  # Change pressure rise
  pump.setRatedPumpHead(pressure_rise_pa)

  # Report
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Pump', "For #{pump.name}: motor nameplate = #{nominal_hp}HP, motor eff = #{(motor_efficiency * 100).round(2)}%; #{target_w_per_gpm.round} W/gpm translates to a pressure rise of #{pressure_rise_ft_h2o.round(2)} ftH2O.")

  # Calculate the W/gpm for verification
  calculated_w = pump_pumppower(pump)

  calculated_w_per_gpm = calculated_w / flow_gpm

  OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Pump', "For #{pump.name}: calculated W/gpm = #{calculated_w_per_gpm.round(1)}.")

  return true
end
pump_apply_standard_minimum_motor_efficiency(pump) click to toggle source

Applies the minimum motor efficiency for this pump based on the motor’s brake horsepower.

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@return [Boolean] returns true if successful, false if not

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 98
def pump_apply_standard_minimum_motor_efficiency(pump)
  # Get the horsepower
  bhp = pump_brake_horsepower(pump)

  # Find the motor efficiency
  motor_eff, nominal_hp = pump_standard_minimum_motor_efficiency_and_size(pump, bhp)

  # Change the motor efficiency
  pump.setMotorEfficiency(motor_eff)

  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Pump', "For #{pump.name}: brake hp = #{bhp.round(2)}HP, motor nameplate = #{nominal_hp.round(2)}HP, motor eff = #{(motor_eff * 100).round(2)}%.")

  return true
end
pump_brake_horsepower(pump) click to toggle source

Determines the brake horsepower of the pump based on flow rate, pressure rise, and impeller efficiency.

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@return [Double] brake horsepower

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 223
def pump_brake_horsepower(pump)
  # Get flow rate (whether autosized or hard-sized)
  # Get flow rate (whether autosized or hard-sized)
  flow_m3_per_s = 0
  flow_m3_per_s = if pump.to_PumpVariableSpeed.is_initialized || pump.to_PumpConstantSpeed.is_initialized
                    if pump.ratedFlowRate.is_initialized
                      pump.ratedFlowRate.get
                    elsif pump.autosizedRatedFlowRate.is_initialized
                      pump.autosizedRatedFlowRate.get
                    end
                  elsif pump.to_HeaderedPumpsVariableSpeed.is_initialized || pump.to_HeaderedPumpsConstantSpeed.is_initialized
                    if pump.totalRatedFlowRate.is_initialized
                      pump.totalRatedFlowRate.get
                    elsif pump.autosizedTotalRatedFlowRate.is_initialized
                      pump.autosizedTotalRatedFlowRate.get
                    end
                  end

  # E+ default impeller efficiency
  # http://bigladdersoftware.com/epx/docs/8-4/engineering-reference/component-sizing.html#pump-sizing
  impeller_eff = 0.78

  # Get the pressure rise (Pa)
  pressure_rise_pa = pump.ratedPumpHead

  # Calculate the pump power (W)
  pump_power_w = pressure_rise_pa * flow_m3_per_s / impeller_eff

  # Convert to HP
  pump_power_hp = pump_power_w / 745.7 # 745.7 W/HP

  return pump_power_hp
end
pump_motor_horsepower(pump) click to toggle source

Determines the horsepower of the pump motor, including motor efficiency and pump impeller efficiency.

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@return [Double] motor horsepower

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 262
def pump_motor_horsepower(pump)
  # Get the pump power
  pump_power_w = pump_pumppower(pump)

  # Convert to HP
  pump_hp = pump_power_w / 745.7 # 745.7 W/HP

  return pump_hp
end
pump_pumppower(pump) click to toggle source

Determines the pump power (W) based on flow rate, pressure rise, and total pump efficiency(impeller eff * motor eff). Uses the E+ default assumption of 0.78 impeller efficiency.

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@return [Double] pump power in watts

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 177
def pump_pumppower(pump)
  # Get flow rate (whether autosized or hard-sized)
  flow_m3_per_s = 0
  flow_m3_per_s = if pump.to_PumpVariableSpeed.is_initialized || pump.to_PumpConstantSpeed.is_initialized
                    if pump.ratedFlowRate.is_initialized
                      pump.ratedFlowRate.get
                    elsif pump.autosizedRatedFlowRate.is_initialized
                      pump.autosizedRatedFlowRate.get
                    else
                      pump.ratedFlowRate.get
                    end
                  elsif pump.to_HeaderedPumpsVariableSpeed.is_initialized || pump.to_HeaderedPumpsConstantSpeed.is_initialized
                    if pump.totalRatedFlowRate.is_initialized
                      pump.totalRatedFlowRate.get
                    elsif pump.autosizedTotalRatedFlowRate.is_initialized
                      pump.autosizedTotalRatedFlowRate.get
                    end
                  end

  # E+ default impeller efficiency
  # http://bigladdersoftware.com/epx/docs/8-4/engineering-reference/component-sizing.html#pump-sizing
  impeller_eff = 0.78

  # Get the motor efficiency
  motor_eff = pump.motorEfficiency

  # Calculate the total efficiency
  # which includes both motor and
  # impeller efficiency.
  pump_total_eff = impeller_eff * motor_eff

  # Get the pressure rise (Pa)
  pressure_rise_pa = pump.ratedPumpHead

  # Calculate the pump power (W)
  pump_power_w = pressure_rise_pa * flow_m3_per_s / pump_total_eff

  return pump_power_w
end
pump_rated_w_per_gpm(pump) click to toggle source

Determines the rated watts per GPM of the pump

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@return [Double] rated power consumption per flow in watts per gpm, W*min/gal

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 277
def pump_rated_w_per_gpm(pump)
  # Get design power (whether autosized or hard-sized)
  rated_power_w = 0
  if pump.ratedPowerConsumption.is_initialized
    rated_power_w = pump.ratedPowerConsumption.get
  elsif pump.autosizedRatedPowerConsumption.is_initialized
    rated_power_w = pump.autosizedRatedPowerConsumption.get
  else
    OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find rated pump power consumption, cannot determine w per gpm correctly.")
    return 0.0
  end

  rated_m3_per_s = 0
  if pump.to_PumpVariableSpeed.is_initialized || pump.to_PumpConstantSpeed.is_initialized
    if pump.ratedFlowRate.is_initialized
      rated_m3_per_s = pump.ratedFlowRate.get
    elsif pump.autosizedRatedFlowRate.is_initialized
      rated_m3_per_s = pump.autosizedRatedFlowRate.get
    else
      OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find rated pump Flow Rate, cannot determine w per gpm correctly.")
      return 0.0
    end
  elsif pump.to_HeaderedPumpsVariableSpeed.is_initialized || pump.to_HeaderedPumpsConstantSpeed.is_initialized
    if pump.totalRatedFlowRate.is_initialized
      rated_m3_per_s = pump.totalRatedFlowRate.get
    elsif pump.autosizedTotalRatedFlowRate.is_initialized
      rated_m3_per_s = pump.autosizedTotalRatedFlowRate.get
    else
      OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find rated pump Flow Rate, cannot determine w per gpm correctly.")
      return 0.0
    end
  end

  rated_w_per_m3s = rated_power_w / rated_m3_per_s

  rated_w_per_gpm = OpenStudio.convert(rated_w_per_m3s, 'W*s/m^3', 'W*min/gal').get

  return rated_w_per_gpm
end
pump_standard_minimum_motor_efficiency_and_size(pump, motor_bhp) click to toggle source

Determines the minimum pump motor efficiency and nominal size for a given motor bhp. This should be the total brake horsepower with any desired safety factor already included. This method picks the next nominal motor catgory larger than the required brake horsepower, and the efficiency is based on that size. For example, if the bhp = 6.3, the nominal size will be 7.5HP and the efficiency for 90.1-2010 will be 91.7% from Table 10.8B. This method assumes 4-pole, 1800rpm totally-enclosed fan-cooled motors.

@param pump [OpenStudio::Model::StraightComponent] pump object, allowable types:

PumpConstantSpeed, PumpVariableSpeed

@param motor_bhp [Double] motor brake horsepower (hp) @return [Array<Double>] minimum motor efficiency (0.0 to 1.0), nominal horsepower

# File lib/openstudio-standards/standards/Standards.Pump.rb, line 126
def pump_standard_minimum_motor_efficiency_and_size(pump, motor_bhp)
  motor_eff = 0.85
  nominal_hp = motor_bhp

  # Don't attempt to look up motor efficiency
  # for zero-hp pumps (required for circulation-pump-free
  # service water heating systems).
  return [1.0, 0] if motor_bhp == 0.0

  # Lookup the minimum motor efficiency
  motors = standards_data['motors']

  # Assuming all pump motors are 4-pole ODP
  search_criteria = {
    'template' => template,
    'number_of_poles' => 4.0,
    'type' => 'Enclosed'
  }

  motor_properties = model_find_object(motors, search_criteria, motor_bhp)
  if motor_properties.nil?
    OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find motor properties using search criteria: #{search_criteria}, motor_bhp = #{motor_bhp} hp.")
    return [motor_eff, nominal_hp]
  end

  motor_eff = motor_properties['nominal_full_load_efficiency']
  nominal_hp = motor_properties['maximum_capacity'].to_f.round(1)
  # Round to nearest whole HP for niceness
  if nominal_hp >= 2
    nominal_hp = nominal_hp.round
  end

  # Get the efficiency based on the nominal horsepower
  # Add 0.01 hp to avoid search errors.
  motor_properties = model_find_object(motors, search_criteria, nominal_hp + 0.01)
  if motor_properties.nil?
    OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Fan', "For #{pump.name}, could not find nominal motor properties using search criteria: #{search_criteria}, motor_hp = #{nominal_hp} hp.")
    return [motor_eff, nominal_hp]
  end
  motor_eff = motor_properties['nominal_full_load_efficiency']

  return [motor_eff, nominal_hp]
end