def blade_angle( prop, bhp, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", ): """ Returns propeller blade angle. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) blade_angle = cp2blade_angle(prop, Cp, J, blade_tip_mach) return blade_angle
def blade_angle2bhp( prop, blade_angle, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", ): """ Returns returns engine power, given blade angle, rpm and flight conditions. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 # Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units = power_units, density_units = 'kg/m**3', dia_units = dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) Cp = blade_angle2cp(prop, blade_angle, J, blade_tip_mach) bhp = cp2bhp(Cp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) return bhp
def temp2speed_of_sound(temp, temp_units=default_temp_units, speed_units=default_speed_units): """ Return the speed of sound, given the air temperature. The temperature units may be deg C, F, K or R ('C', 'F', 'K' or 'R'). The speed units may be 'kt', 'mph', 'km/h', 'm/s' and 'ft/s'. If the units are not specified, the units in default_units.py are used. Examples: Determine speed of sound in knots at 15 deg (default temperature units): >>> temp2speed_of_sound(15) 661.47882487301808 Determine speed of sound in mph at 120 deg F: >>> temp2speed_of_sound(120, speed_units = 'mph', temp_units = 'F') 804.73500154991291 """ # function tested in tests/test_std_atm.py temp = U.temp_conv(temp, from_units=temp_units, to_units='K') speed_of_sound = M.sqrt((1.4 * Rd) * temp) speed_of_sound = U.speed_conv(speed_of_sound, from_units='m/s', to_units=speed_units) return speed_of_sound
def alt2temp(H, alt_units=default_alt_units, temp_units=default_temp_units): """Return the standard temperature for the specified altitude. Altitude units may be feet ('ft'), metres ('m'), statute miles, ('sm') or nautical miles ('nm'). Temperature units may be degrees C, F, K or R ('C', 'F', 'K' or 'R') If the units are not specified, the units in default_units.py are used. Examples: Calculate the standard temperature (in default temperature units) at 5,000 (default altitude units): >>> alt2temp(5000) 5.0939999999999941 Calculate the standard temperature in deg F at sea level: >>> alt2temp(0, temp_units = 'F') 59.0 Calculate the standard temperature in deg K at 11,000 m: >>> alt2temp(11000, alt_units = 'm', temp_units = 'K') 216.64999999999998 Calculate the standard temperature at 11 statute miles in deg R: >>> alt2temp(11, alt_units = 'sm', temp_units = 'R') 389.96999999999997 The input value may be an expression: >>> alt2temp(11 * 5280, temp_units = 'R') 389.96999999999997 """ # Validated to 84000 m # uses meters and degrees K for the internal calculations # function tested in tests/test_std_atm.py H = U.len_conv(H, from_units=alt_units, to_units='km') if H <= 11: temp = T0 + H * L0 elif H <= 20: temp = T11 elif H <= 32: temp = T20 + (H - 20) * L20 elif H <= 47: temp = T32 + (H - 32) * L32 elif H <= 51: temp = T47 elif H <= 71: temp = T51 + (H - 51) * L51 elif H <= 84.852: temp = T71 + (H - 71) * L71 else: raise ValueError, \ 'This function is only implemented for altitudes of 84.852 km and below.' return U.temp_conv(temp, to_units=temp_units, from_units='K')
def alt2temp(H, alt_units=default_alt_units, temp_units=default_temp_units): """Return the standard temperature for the specified altitude. Altitude units may be feet ('ft'), metres ('m'), statute miles, ('sm') or nautical miles ('nm'). Temperature units may be degrees C, F, K or R ('C', 'F', 'K' or 'R') If the units are not specified, the units in default_units.py are used. Examples: Calculate the standard temperature (in default temperature units) at 5,000 (default altitude units): >>> alt2temp(5000) 5.0939999999999941 Calculate the standard temperature in deg F at sea level: >>> alt2temp(0, temp_units = 'F') 59.0 Calculate the standard temperature in deg K at 11,000 m: >>> alt2temp(11000, alt_units = 'm', temp_units = 'K') 216.64999999999998 Calculate the standard temperature at 11 statute miles in deg R: >>> alt2temp(11, alt_units = 'sm', temp_units = 'R') 389.96999999999997 The input value may be an expression: >>> alt2temp(11 * 5280, temp_units = 'R') 389.96999999999997 """ # Validated to 84000 m # uses meters and degrees K for the internal calculations # function tested in tests/test_std_atm.py H = U.len_conv(H, from_units=alt_units, to_units='km') if H <= 11: temp = T0 + H * L0 elif H <= 20: temp = T11 elif H <= 32: temp = T20 + (H - 20) * L20 elif H <= 47: temp = T32 + (H - 32) * L32 elif H <= 51: temp = T47 elif H <= 71: temp = T51 + (H - 51) * L51 elif H <= 84.852: temp = T71 + (H - 71) * L71 else: print( 'This function is only implemented for altitudes of 84.852 km and below.' ) return U.temp_conv(temp, to_units=temp_units, from_units='K')
def temp2temp_ratio(temp, temp_units=default_temp_units): """ Return the temperature ratio """ theta = U.temp_conv(temp, from_units = temp_units, to_units='K') / T0 return theta
def temp2temp_ratio(temp, temp_units=default_temp_units): """ Return the temperature ratio """ theta = U.temp_conv(temp, from_units=temp_units, to_units='K') / T0 return theta
def prop_eff( prop, bhp, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", ): """ Returns propeller efficiency based on engine power provided to the propeller. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) if N.isnan(prop_eff): raise ValueError, "Out of range inputs" return prop_eff
def alt2kinematic_viscosity(H, T='std', alt_units=default_alt_units, temp_units=default_temp_units, kinematic_viscosity_units=default_kinematic_viscosity_units): """ Return kinematic viscosity, given altitude and an optional temperature input. """ density = alt2density(H, alt_units, density_units='kg/m**3') isa_temp = alt2temp(H, alt_units, 'K') if T != 'std': isa_temp = alt2temp(H, alt_units, 'K') T = U.temp_conv(T, temp_units, 'K') density *= isa_temp / T else: T = U.temp_conv(isa_temp, 'K', temp_units) u = temp2dynamic_viscosity(T, temp_units, 'Pa s') v = u / density v = U.kinematic_viscosity_conv(v, 'm**2/s', kinematic_viscosity_units) return v
def pwr(rpm, MP, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'): """ Returns horsepower for Lycoming O-360-A series engines, given: rpm - engine speed in revolutions per minute MP - manifold pressure (" HG) altitude - pressure altitude temp - ambient temperature (optional - std temperature is used if no temperature is input). alt_units - (optional) - units for altitude, ft, m, or km (default is ft) temp_units - (optional) - units for temperature, C, F, K or R (default is deg C) The function replicates Lycoming curve ??????? and is valid at mixture for maximum power. Examples: Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and -10 deg C: >>> pwr(2620, 28, 0, -10) 183.91485642478889 Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F: >>> pwr(2500, 25, 5000, 0, temp_units = 'F') 164.10572738791328 Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C >>> pwr(2200, 20, 2000, -5, alt_units = 'm') 111.72954664842844 Determine power at 2200 rpm, 20" MP, 2000 metres and standard temperature: >>> pwr(2200, 20, 2000, alt_units = 'm') 110.29915330621547 """ # convert units altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units = temp_units) temp = U.temp_conv(temp, from_units = temp_units, to_units = 'K') # get standard temperature temp_std = SA.alt2temp(altitude, temp_units = 'K') # get power at standard temperature pwr_std = _pwr_std_temp(rpm, MP, altitude) # correct power for non-standard temperature pwr = pwr_std * M.sqrt(temp_std / temp) return pwr
def pwr(rpm, MP, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'): """ Returns horsepower for Lycoming IO-360-A series engines, given: rpm - engine speed in revolutions per minute MP - manifold pressure (" HG) altitude - pressure altitude temp - ambient temperature (optional - std temperature is used if no temperature is input). alt_units - (optional) - units for altitude, ft, m, or km (default is ft) temp_units - (optional) - units for temperature, C, F, K or R (default is deg C) The function replicates Lycoming curve 12700-A, and is valid at mixture for maximum power. Examples: Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and -10 deg C: >>> pwr(2620, 28, 0, -10) 197.71751932574702 Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F: >>> pwr(2500, 25, 5000, 0, temp_units = 'F') 171.87810350172663 Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C >>> pwr(2200, 20, 2000, -5, alt_units = 'm') 108.60284092217333 Determine power at 2200 rpm, 20" MP, 2000 metres and standard temperature: >>> pwr(2200, 20, 2000, alt_units = 'm') 107.2124765533882 """ # convert units altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units = temp_units) temp = U.temp_conv(temp, from_units = temp_units, to_units = 'K') # get standard temperature temp_std = SA.alt2temp(altitude, temp_units = 'K') # get power at standard temperature pwr_std = _pwr_std_temp(rpm, MP, altitude) # correct power for non-standard temperature pwr = pwr_std * M.sqrt(temp_std / temp) return pwr
def pwr(rpm, MP, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns horsepower for Lycoming O-360-A series engines, given: rpm - engine speed in revolutions per minute MP - manifold pressure (" HG) altitude - pressure altitude temp - ambient temperature (optional - std temperature is used if no temperature is input). alt_units - (optional) - units for altitude, ft, m, or km (default is ft) temp_units - (optional) - units for temperature, C, F, K or R (default is deg C) The function replicates Lycoming curve ??????? and is valid at mixture for maximum power. Examples: Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and -10 deg C: >>> pwr(2620, 28, 0, -10) 183.91485642478889 Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F: >>> pwr(2500, 25, 5000, 0, temp_units = 'F') 164.10572738791328 Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C >>> pwr(2200, 20, 2000, -5, alt_units = 'm') 111.72954664842844 Determine power at 2200 rpm, 20" MP, 2000 metres and standard temperature: >>> pwr(2200, 20, 2000, alt_units = 'm') 110.29915330621547 """ # convert units altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='K') # get standard temperature temp_std = SA.alt2temp(altitude, temp_units='K') # get power at standard temperature pwr_std = _pwr_std_temp(rpm, MP, altitude) # correct power for non-standard temperature pwr = pwr_std * np.sqrt(temp_std / temp) return pwr
def pwr(rpm, MP, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns horsepower for Lycoming IO-360-A series engines, given: rpm - engine speed in revolutions per minute MP - manifold pressure (" HG) altitude - pressure altitude temp - ambient temperature (optional - std temperature is used if no temperature is input). alt_units - (optional) - units for altitude, ft, m, or km (default is ft) temp_units - (optional) - units for temperature, C, F, K or R (default is deg C) The function replicates Lycoming curve 12700-A, and is valid at mixture for maximum power. Examples: Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and -10 deg C: >>> pwr(2620, 28, 0, -10) 197.71751932574702 Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F: >>> pwr(2500, 25, 5000, 0, temp_units = 'F') 171.87810350172663 Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C >>> pwr(2200, 20, 2000, -5, alt_units = 'm') 108.60284092217333 Determine power at 2200 rpm, 20" MP, 2000 metres and standard temperature: >>> pwr(2200, 20, 2000, alt_units = 'm') 107.2124765533882 """ # convert units altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='K') # get standard temperature temp_std = SA.alt2temp(altitude, temp_units='K') # get power at standard temperature pwr_std = _pwr_std_temp(rpm, MP, altitude) # correct power for non-standard temperature pwr = pwr_std * M.sqrt(temp_std / temp) return pwr
def temp2dynamic_viscosity(T, temp_units=default_temp_units, dynamic_viscosity_units=default_dynamic_viscosity_units): """ Return dynamic viscosity given the air temperature. Formula from US Standard Atmosphere, 1976 section 1.3.11 on page 19. """ T = U.temp_conv(T, temp_units, 'K') u = 1.458e-6 * T**1.5 / (T + 110.4) u = U.dynamic_viscosity_conv(u, 'Pa s', dynamic_viscosity_units) return u
def prop_eff(prop, bhp, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in'): """ Returns propeller efficiency based on engine power provided to the propeller. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) if N.isnan(prop_eff): raise ValueError('Out of range inputs') return prop_eff
def temp2dynamic_viscosity( T, temp_units=default_temp_units, dynamic_viscosity_units=default_dynamic_viscosity_units): """ Return dynamic viscosity given the air temperature. Formula from US Standard Atmosphere, 1976 section 1.3.11 on page 19. """ T = U.temp_conv(T, temp_units, 'K') u = 1.458e-6 * T**1.5 / (T + 110.4) u = U.dynamic_viscosity_conv(u, 'Pa s', dynamic_viscosity_units) return u
def alt2kinematic_viscosity( H, T='std', alt_units=default_alt_units, temp_units=default_temp_units, kinematic_viscosity_units=default_kinematic_viscosity_units): """ Return kinematic viscosity, given altitude and an optional temperature input. """ density = alt2density(H, alt_units, density_units='kg/m**3') isa_temp = alt2temp(H, alt_units, 'K') if T != 'std': isa_temp = alt2temp(H, alt_units, 'K') T = U.temp_conv(T, temp_units, 'K') density *= isa_temp / T else: T = U.temp_conv(isa_temp, 'K', temp_units) u = temp2dynamic_viscosity(T, temp_units, 'Pa s') v = u / density v = U.kinematic_viscosity_conv(v, 'm**2/s', kinematic_viscosity_units) return v
def blade_angle2bhp(prop, blade_angle, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in'): """ Returns returns engine power, given blade angle, rpm and flight conditions. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 # Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units = power_units, density_units = 'kg/m**3', dia_units = dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) Cp = blade_angle2cp(prop, blade_angle, J, blade_tip_mach) bhp = cp2bhp(Cp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) return bhp
def pp(rpm, MP, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'): """ Returns percent power for Lycoming IO-360-A series engines, given: rpm - engine speed in revolutions per minute MP - manifold pressure (" HG) altitude - pressure altitude temp - ambient temperature (optional - std temperature is used if no temperature is input). alt_units - (optional) - units for altitude, ft, m, or km (default is ft) temp_units - (optional) - units for temperature, C, F, K or R (default is deg C) The function replicates Lycoming curve 12700-A, and is valid at mixture for maximum power. Note: the output is rounded off to two decimal places. Examples: Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and -10 deg C: >>> pp(2620, 28, 0, -10) '98.86%' Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F: >>> pp(2500, 25, 5000, 0, temp_units = 'F') '85.94%' Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C >>> pp(2200, 20, 2000, -5, alt_units = 'm') '54.30%' Determine power at 2200 rpm, 20" MP, 2000 metres and standard temperature: >>> pp(2200, 20, 2000, alt_units = 'm') '53.61%' """ altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units = temp_units) temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C') pp = pwr(rpm, MP, altitude, temp) / 2 # return pp return '%.2f' % (pp) + '%'
def pp(rpm, MP, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns percent power for Lycoming IO-360-A series engines, given: rpm - engine speed in revolutions per minute MP - manifold pressure (" HG) altitude - pressure altitude temp - ambient temperature (optional - std temperature is used if no temperature is input). alt_units - (optional) - units for altitude, ft, m, or km (default is ft) temp_units - (optional) - units for temperature, C, F, K or R (default is deg C) The function replicates Lycoming curve 12700-A, and is valid at mixture for maximum power. Note: the output is rounded off to two decimal places. Examples: Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and -10 deg C: >>> pp(2620, 28, 0, -10) '98.86%' Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F: >>> pp(2500, 25, 5000, 0, temp_units = 'F') '85.94%' Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C >>> pp(2200, 20, 2000, -5, alt_units = 'm') '54.30%' Determine power at 2200 rpm, 20" MP, 2000 metres and standard temperature: >>> pp(2200, 20, 2000, alt_units = 'm') '53.61%' """ altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='C') pp = pwr(rpm, MP, altitude, temp) / 2 # return pp return '%.2f' % (pp) + '%'
def power_alt(ff, n, Hp, OAT, k=.00283, k2=.007, ff_units='USG/h', temp_units = 'F'): """ Alternate, simplified method to determine power. Assume that the fuel flow for peak EGT varies linearly with density ratio and rpm. Then use the main power method to calculate power for cases where there is not a good indication of fuel flow at peak EGT. Only applicable to Lycoming IO-360A series engines. Based on a very limited set of flight test data, so the accuracy of the fuel flow at peak EGT has not been established under all conditions. """ oat = U.temp_conv(OAT, from_units='F', to_units='R') dr = SA.alt_temp2density_ratio(Hp, OAT, temp_units='F') ff_peak_EGT = k * dr * n + k2 * oat p = power(ff, ff_peak_EGT, n) return p
def blade_angle(prop, bhp, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in'): """ Returns propeller blade angle. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) blade_angle = cp2blade_angle(prop, Cp, J, blade_tip_mach) return blade_angle
def pp2mp(percent_power, rpm, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns manifold pressure in inches of mercury for a given percent power, rpm, altitude and temperature (temperature input is optional - standard temperature is used if no temperature is input). Note: the output is rounded off to two decimal places. Examples: Determine manifold pressure required for 62.5% power at 2550 rpm at 8000 ft and 10 deg C: >>> pp2mp(62.5, 2550, 8000, 10) '19.45' Determine manifold pressure required for 75% power at 2500 rpm at 7500 ft at 10 deg F: >>> pp2mp(75, 2500, 7500, 10, temp_units = 'F') '22.25' Determine manifold pressure required for 55% power at 2400 rpm at 9,500 ft at standard temperature: >>> pp2mp(55, 2400, 9500) '18.18' """ if percent_power <= 0: raise ValueError('Power input must be positive.') # convert units altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='C') pwr_seek = percent_power * 2 mp = pwr2mp(pwr_seek, rpm, altitude, temp) return mp
def pp2rpm(percent_power, mp, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns manifold pressure in inches of mercury for a given percent power, rpm, altitude and temperature (temperature input is optional - standard temperature is used if no temperature is input). Examples: Determine rpm required for 125 hp at 20 inches HG manifold pressure at 8000 ft and 10 deg C: >>> pp2rpm(62.5, 20, 8000, 10) 2246 Determine rpm required for 75% power at 22 inches HG manifold pressure at 6500 ft and 10 deg F: >>> pp2rpm(75, 22, 6500, 10, temp_units = 'F') 2345 Determine rpm required for 55% power at at 18 inches HG manifold pressure at 9,500 ft at standard temperature: >>> pp2rpm(55, 18, 9500) 2423 """ if percent_power <= 0: raise ValueError('Power input must be positive.') # convert units altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='C') pwr_seek = percent_power * 1.8 # print('Temp:', temp) print('Power seeked:', pwr_seek) rpm = pwr2rpm(pwr_seek, mp, altitude, temp) return rpm
def density_alt2temp( density_alt_seek, press_alt, alt_units=default_alt_units, temp_units=default_temp_units, ): """ Return temperature to achieve a desired density altitude. If the units are not specified, the units in default_units.py are used. """ low = -100 # initial lower guess high = 100 # initial upper guess # confirm initial low and high are OK: da_low = density_alt(press_alt, low, alt_units=alt_units) if da_low > density_alt_seek: print('Initial low guess too high.') da_high = density_alt(press_alt, high, alt_units=alt_units) if da_high < density_alt_seek: print('Initial high guess too low.') guess = (low + high) / 2. da_guess = density_alt(press_alt, guess, alt_units=alt_units) # keep iterating until da is within 1 ft of desired value while M.fabs(da_guess - density_alt_seek) > 1: if da_guess > density_alt_seek: high = guess else: low = guess guess = (low + high) / 2. da_guess = density_alt(press_alt, guess, alt_units=alt_units) guess = U.temp_conv(guess, from_units='C', to_units=temp_units) return guess
def density_alt2temp( density_alt_seek, press_alt, alt_units=default_alt_units, temp_units=default_temp_units, ): """ Return temperature to achieve a desired density altitude. If the units are not specified, the units in default_units.py are used. """ low = -100. # initial lower guess high = 100. # initial upper guess # confirm initial low and high are OK: da_low = density_alt(press_alt, low, alt_units=alt_units) if da_low > density_alt_seek: raise ValueError('Initial low guess too high.') da_high = density_alt(press_alt, high, alt_units=alt_units) if da_high < density_alt_seek: raise ValueError('Initial high guess too low.') guess = (low + high) / 2. da_guess = density_alt(press_alt, guess, alt_units=alt_units) # keep iterating until da is within 1 ft of desired value while M.fabs(da_guess - density_alt_seek) > 1: if da_guess > density_alt_seek: high = guess else: low = guess guess = (low + high) / 2. da_guess = density_alt(press_alt, guess, alt_units=alt_units) guess = U.temp_conv(guess, from_units='C', to_units=temp_units) return guess
def pp2mp(percent_power, rpm, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'): """ Returns manifold pressure in inches of mercury for a given percent power, rpm, altitude and temperature (temperature input is optional - standard temperature is used if no temperature is input). Note: the output is rounded off to two decimal places. Examples: Determine manifold pressure required for 62.5% power at 2550 rpm at 8000 ft and 10 deg C: >>> pp2mp(62.5, 2550, 8000, 10) '19.45' Determine manifold pressure required for 75% power at 2500 rpm at 7500 ft at 10 deg F: >>> pp2mp(75, 2500, 7500, 10, temp_units = 'F') '22.25' Determine manifold pressure required for 55% power at 2400 rpm at 9,500 ft at standard temperature: >>> pp2mp(55, 2400, 9500) '18.18' """ if percent_power <= 0: raise ValueError, 'Power input must be positive.' # convert units altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units = temp_units) temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C') pwr_seek = percent_power * 2 mp = pwr2mp(pwr_seek, rpm, altitude, temp) return mp
def pp2rpm(percent_power, mp, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'): """ Returns manifold pressure in inches of mercury for a given percent power, rpm, altitude and temperature (temperature input is optional - standard temperature is used if no temperature is input). Examples: Determine rpm required for 125 hp at 20 inches HG manifold pressure at 8000 ft and 10 deg C: >>> pp2rpm(62.5, 20, 8000, 10) 2246 Determine rpm required for 75% power at 22 inches HG manifold pressure at 6500 ft and 10 deg F: >>> pp2rpm(75, 22, 6500, 10, temp_units = 'F') 2345 Determine rpm required for 55% power at at 18 inches HG manifold pressure at 9,500 ft at standard temperature: >>> pp2rpm(55, 18, 9500) 2423 """ if percent_power <= 0: raise ValueError, 'Power input must be positive.' # convert units altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units = temp_units) temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C') pwr_seek = percent_power * 1.8 # print 'Temp:', temp print 'Power seeked:', pwr_seek rpm = pwr2rpm(pwr_seek, mp, altitude, temp) return rpm
def power_alt(ff, n, Hp, OAT, k=.00283, k2=.007, ff_units='USG/h', temp_units='F'): """ Alternate, simplified method to determine power. Assume that the fuel flow for peak EGT varies linearly with density ratio and rpm. Then use the main power method to calculate power for cases where there is not a good indication of fuel flow at peak EGT. Only applicable to Lycoming IO-360A series engines. Based on a very limited set of flight test data, so the accuracy of the fuel flow at peak EGT has not been established under all conditions. """ oat = U.temp_conv(OAT, from_units='F', to_units='R') dr = SA.alt_temp2density_ratio(Hp, OAT, temp_units='F') ff_peak_EGT = k * dr * n + k2 * oat p = power(ff, ff_peak_EGT, n) return p
def test_08(self): Value = U.temp_conv(180, from_units='R', to_units='K') Truth = 100 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_07(self): Value = U.temp_conv(100, from_units='K', to_units='R') Truth = 180 self.failUnless(RE(Value, Truth) <= 1e-5)
def sat_press( T='FALSE', DP='FALSE', RH=0.0, temp_units=default_temp_units, press_units=default_press_units, ): """ Return the saturated vapour pressure of water. Either the dew point, or the temperature and the relative humidity must be specified. If both the dew point and relative humidity are specified, the relative humidity value is ignored. If the temperature and dew point are both specified, the dew point cannot be greater than the temperature: If the units are not specified, the units in default_units.py are used. >>> sat_press(T=10, DP=11) Traceback (most recent call last): File '<stdin>', line 1, in <module> File 'std_atm.py', line 795, in sat_press raise ValueError, 'The dew point cannot be greater than the temperature.' ValueError: The dew point cannot be greater than the temperature. Dew point is 11 deg (default temperature units). Find the water vapour pressure in default pressure units: >>> sat_press(DP=11) 0.38741015927568667 Dew point is 65 deg F. Find the water vapour pressure in default pressure units: >>> sat_press(DP=65, temp_units = 'F') 0.62207710701956165 Dew point is 212 deg F (the boiling point of water at sea level). Find the water vapour pressure in lb per sq. inch: >>> sat_press(DP=212, temp_units = 'F', press_units = 'psi') 14.696764873564959 Temperature is 30 deg C. Find the water vapour pressure in default pressure units: for 50% relative humidity: >>> sat_press(T=30, RH = 0.5) 0.62647666996057927 """ if DP != 'FALSE': # use dew point method if T != 'FALSE': if DP > T: print('The dew point cannot be greater than the temperature.') DP = U.temp_conv(DP, from_units=temp_units, to_units='C') # calculate vapour pressure Pv = _sat_press(DP) * 100 else: if RH == 'FALSE': print( 'Either DP (dew point) or RH (relative humidity) must be specified.' ) # relative humidity is specified # confirm relative humidity is in range if RH < 0 or RH > 1: print('The relative humidity must be in the range of 0 to 1.') if T == 'FALSE': print( 'If the relative humidity is specified, the temperature must also be specified.' ) T = U.temp_conv(T, from_units=temp_units, to_units='C') Pv = _sat_press(T) * 100 Pv *= RH Pv = U.press_conv(Pv, from_units='pa', to_units=press_units) return Pv
def test_13(self): Value = U.temp_conv(373.15, from_units='K', to_units='F') Truth = 212 self.failUnless(RE(Value, Truth) <= 1e-8)
def density_alt_table( density_alt_seek, alt_range=2000, alt_inc=100, alt_units=default_alt_units, temp_units=default_temp_units, multi_units=False, file='', format='text', ): """ Return a text or html table of required temperature vs pressure altitude. If the units are not specified, the units in default_units.py are used. """ line_buffer = [] if format == 'text': line_buffer.append( 'Pressure altitudes and temperatures for a density ') line_buffer.append('altitude of ' + str(density_alt_seek) + ' ' + alt_units) line_buffer.append('(assuming dry air)\n') if multi_units: line_buffer.append(' Pressure Temp Temp') line_buffer.append(' Altitude') line_buffer.append(' (' + alt_units + ') (deg C) (deg F)') else: line_buffer.append(' Pressure Temp') line_buffer.append(' Altitude') line_buffer.append(' (' + alt_units + ') (deg ' + temp_units + ')') elif format == 'html': print('creating html') else: print('Invalid format. Must be either "text" or "html"') if multi_units: for alt in range(max(density_alt_seek - alt_range / 2., 0), density_alt_seek + alt_range / 2. + alt_inc, alt_inc): temp_c = density_alt2temp(density_alt_seek, alt, alt_units=alt_units) temp_f = U.temp_conv(temp_c, from_units='C', to_units='F') alt_str = L.format('%.*f', (0, alt), grouping=True) temp_c_str = '%.1f' % temp_c temp_f_str = '%.1f' % temp_f line_buffer.append( alt_str.rjust(6) + temp_c_str.rjust(11) + temp_f_str.rjust(10)) else: for alt in range(max(density_alt_seek - alt_range / 2., 0), density_alt_seek + alt_range / 2. + alt_inc, alt_inc): alt_str = L.format('%.*f', (0, alt), grouping=True) temp_str = '%.1f' % density_alt2temp(density_alt_seek, alt, temp_units=temp_units, alt_units=alt_units) line_buffer.append(alt_str.rjust(6) + temp_str.rjust(11)) if file != '': OUT = open(file, 'w') for line in line_buffer: OUT.write(line + '\n') print('file selected') else: return '\n'.join(line_buffer)
def test_08(self): Value = U.temp_conv(180, from_units='R', to_units='K') Truth = 100 self.failUnless(RE(Value, Truth) <= 1e-8)
def test_11(self): Value = U.temp_conv(671.67, from_units='R', to_units='C') Truth = 100 self.failUnless(RE(Value, Truth) <= 1e-8)
def test_02(self): Value = U.temp_conv(100, from_units='C', to_units='F') Truth = 212 self.failUnless(RE(Value, Truth) <= 1e-5)
def sat_press( T='FALSE', DP='FALSE', RH=0.0, temp_units=default_temp_units, press_units=default_press_units, ): """ Return the saturated vapour pressure of water. Either the dew point, or the temperature and the relative humidity must be specified. If both the dew point and relative humidity are specified, the relative humidity value is ignored. If the temperature and dew point are both specified, the dew point cannot be greater than the temperature: If the units are not specified, the units in default_units.py are used. >>> sat_press(T=10, DP=11) Traceback (most recent call last): File '<stdin>', line 1, in <module> File 'std_atm.py', line 795, in sat_press raise ValueError, 'The dew point cannot be greater than the temperature.' ValueError: The dew point cannot be greater than the temperature. Dew point is 11 deg (default temperature units). Find the water vapour pressure in default pressure units: >>> sat_press(DP=11) 0.38741015927568667 Dew point is 65 deg F. Find the water vapour pressure in default pressure units: >>> sat_press(DP=65, temp_units = 'F') 0.62207710701956165 Dew point is 212 deg F (the boiling point of water at sea level). Find the water vapour pressure in lb per sq. inch: >>> sat_press(DP=212, temp_units = 'F', press_units = 'psi') 14.696764873564959 Temperature is 30 deg C. Find the water vapour pressure in default pressure units: for 50% relative humidity: >>> sat_press(T=30, RH = 0.5) 0.62647666996057927 """ if DP != 'FALSE': # use dew point method if T != 'FALSE': if DP > T: raise ValueError('The dew point cannot be greater than the temperature.') DP = U.temp_conv(DP, from_units=temp_units, to_units='C') # calculate vapour pressure Pv = _sat_press(DP) * 100. else: if RH == 'FALSE': raise ValueError('Either DP (dew point) or RH (relative humidity) must be specified.') # relative humidity is specified # confirm relative humidity is in range if RH < 0 or RH > 1: raise ValueError('The relative humidity must be in the range of 0 to 1.') if T == 'FALSE': raise ValueError('If the relative humidity is specified, the temperature must also be specified.') T = U.temp_conv(T, from_units=temp_units, to_units='C') Pv = _sat_press(T) * 100. Pv *= RH Pv = U.press_conv(Pv, from_units='pa', to_units=press_units) return Pv
def test_13(self): Value = U.temp_conv(373.15, from_units='K', to_units='F') Truth = 212 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_14(self): Value = U.temp_conv(-148, from_units='F', to_units='K') Truth = 173.15 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_12(self): Value = U.temp_conv(-100, from_units='C', to_units='R') Truth = 311.67 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_11(self): Value = U.temp_conv(671.67, from_units='R', to_units='C') Truth = 100 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_09(self): Value = U.temp_conv(32, from_units='F', to_units='R') Truth = 491.67 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_04(self): Value = U.temp_conv(212, from_units='F', to_units='C') Truth = 100 self.failUnless(RE(Value, Truth) <= 1e-8)
def density_alt( H, T, alt_setting=P0 / 100., DP='FALSE', RH=0.0, alt_units=default_alt_units, temp_units=default_temp_units, ): """ Return density altitude, given the pressure altitude and the temperature with altitudes in units of feet ('ft'), metres ('m'), statute miles, ('sm') or nautical miles ('nm'), and temperature in units of deg C, F, K or R ('C', 'F', 'K' or 'R'). Mandatory parametres: H = altitude T = temperature Optional parametres: alt_setting = altimeter setting (defaults to 29.9213 if not provided DP = dew point RH = relative humidity alt_units = units for the altitude. 'ft', 'm', or 'km'. temp_units = units for the temperature and dew point. 'C', 'F', 'K' or 'R'. The altimeter setting units are assumed to be inches of HG, unless the value is greater than 35. In this case the units are assumed to be mb. If the dew point or relative humidity are not specified, the air is assumed to be completely dry. If both the dew point and relative humidity are specified, the relative humidity value is ignored. If the units are not specified, the units in default_units.py are used. The method is from: http://wahiduddin.net/calc/density_altitude.htm Examples: Calculate the density altitude in default altitude units for a pressure altitude of 7000 default altitude units and a temperature of 15 deg (default temperature units). The altimeter setting is not specified, so it defaults to standard pressure of 29.9213 in HG or 1013.25 mb: >>> density_alt(7000, 15) 8595.3122796056014 Calculate the density altitude in default altitude units for a pressure altitude of 7000 default altitude units and a temperature of 85 deg F. The altimeter setting is not specified, so it defaults to standard pressure of 29.9213 in HG or 1013.25 mb. The dew point and relative humidity are not specified, so the air is assumed to be dry: >>> density_alt(7000, 85, temp_units = 'F') 10159.073046375761 Calculate the density altitude in default altitude units for a pressure altitude of 7000 default altitude units, an altimeter setting of 29.80 and a temperature of 85 deg F and a dew point of 55 deg F: >>> density_alt(7000, 85, 29.80, 55, temp_units = 'F') 10522.777736545509 Calculate the density altitude in metres for a pressure altitude of 2000 m, an altimeter setting of 1010 mb, a temperature of 15 deg (default temperature units) and a relative humidity of 50%: >>> density_alt(2000, 15, 1010, alt_units = 'm', RH = 0.5) 2529.8235607713582 The dew point may be specified in one of two ways: as the fourth argument on the command line, or via the keyword argument DP. >>> density_alt(2000, 15, 1010, alt_units = 'm', DP = 5) 2530.7533211614682 The relative humidity must be in the range of 0 to 1: >>> density_alt(2000, 15, 1010, alt_units = 'm', RH = 1.1) Traceback (most recent call last): File \"<stdin>\", line 1, in <module> File \"std_atm.py\", line 852, in density_alt Pv = sat_press(T, DP, RH, temp_units, press_units='pa') File \"std_atm.py\", line 962, in sat_press 'The relative humidity must be in the range of 0 to 1.' ValueError: The relative humidity must be in the range of 0 to 1. """ Rv = 461.495 # gas constant for water vapour # saturated vapour pressure if DP == 'FALSE' and RH == 0: Pv = 0 else: Pv = sat_press(T, DP, RH, temp_units, press_units='pa') # dry air pressure Pd = dry_press(H, Pv, alt_setting=alt_setting, alt_units=alt_units, press_units='pa') T = U.temp_conv(T, from_units=temp_units, to_units='K') D = Pd / (Rd * T) + Pv / (Rv * T) DR = D / Rho0 return density_ratio2alt(DR, alt_units)
def test_05(self): Value = U.temp_conv(473.15, from_units='K', to_units='C') Truth = 200. self.failUnless(RE(Value, Truth) <= 1e-8)
def density_alt_table( density_alt_seek, alt_range=2000, alt_inc=100., alt_units=default_alt_units, temp_units=default_temp_units, multi_units=False, file='', format='text', ): """ Return a text or html table of required temperature vs pressure altitude. If the units are not specified, the units in default_units.py are used. """ line_buffer = [] if format == 'text': line_buffer.append('Pressure altitudes and temperatures for a density ' ) line_buffer.append('altitude of ' + str(density_alt_seek) + ' ' + alt_units) line_buffer.append('(assuming dry air)\n') if multi_units: line_buffer.append(' Pressure Temp Temp') line_buffer.append(' Altitude') line_buffer.append(' (' + alt_units + ') (deg C) (deg F)') else: line_buffer.append(' Pressure Temp') line_buffer.append(' Altitude') line_buffer.append(' (' + alt_units + ') (deg ' + temp_units + ')') elif format == 'html': print('creating html') else: raise ValueError('Invalid format. Must be either "text" or "html"') if multi_units: for alt in range(max(density_alt_seek - alt_range / 2., 0), density_alt_seek + alt_range / 2. + alt_inc, alt_inc): temp_c = density_alt2temp(density_alt_seek, alt, alt_units=alt_units) temp_f = U.temp_conv(temp_c, from_units='C', to_units='F') alt_str = L.format('%.*f', (0, alt), grouping=True) temp_c_str = '%.1f' % temp_c temp_f_str = '%.1f' % temp_f line_buffer.append(alt_str.rjust(6) + temp_c_str.rjust(11) + temp_f_str.rjust(10)) else: for alt in range(max(density_alt_seek - alt_range / 2., 0), density_alt_seek + alt_range / 2. + alt_inc, alt_inc): alt_str = L.format('%.*f', (0, alt), grouping=True) temp_str = '%.1f' % density_alt2temp(density_alt_seek, alt, temp_units=temp_units, alt_units=alt_units) line_buffer.append(alt_str.rjust(6) + temp_str.rjust(11)) if file != '': OUT = open(file, 'w') for line in line_buffer: OUT.write(line + '\n') print('file selected') else: return '\n'.join(line_buffer)
def test_09(self): Value = U.temp_conv(32, from_units='F', to_units='R') Truth = 491.67 self.failUnless(RE(Value, Truth) <= 1e-8)
def test_14(self): Value = U.temp_conv(-148, from_units='F', to_units='K') Truth = 173.15 self.assertTrue(RE(Value, Truth) <= 1e-8)
def test_12(self): Value = U.temp_conv(-100, from_units='C', to_units='R') Truth = 311.67 self.failUnless(RE(Value, Truth) <= 1e-8)
def pwr2mp(pwr_seek, rpm, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns manifold pressure in inches of mercury for a given power, rpm, altitude and temperature (temperature input is optional - standard temperature is used if no temperature is input). Note: the output is rounded off to two decimal places. Examples: Determine manifold pressure required for 125 hp at 2550 rpm at 8000 ft and 10 deg C: >>> pwr2mp(125, 2550, 8000, 10) '19.45' Determine manifold pressure required for 75% power at 2500 rpm at 7500 ft at 10 deg F: >>> pwr2mp(.75 * 200, 2500, 7500, 10, temp_units = 'F') '22.25' Determine manifold pressure required for 55% power at 2400 rpm at 9,500 ft at standard temperature: >>> pwr2mp(.55 * 200, 2400, 9500) '18.18' """ if pwr_seek <= 0: raise ValueError('Power input must be positive.') low = 0 # initial lower guess high = 35 # initial upper guess # convert units altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='C') # confirm initial low and high are OK: pwr_low = pwr(rpm, low, altitude, temp) if pwr_low > pwr_seek: raise ValueError('Initial low guess too high.') pwr_high = pwr(rpm, high, altitude, temp) if pwr_high < pwr_seek: raise ValueError('Initial high guess too low.') guess = (low + high) / 2. pwr_guess = pwr(rpm, guess, altitude, temp) # keep iterating until power is within 0.1% of desired value while M.fabs(pwr_guess - pwr_seek) / pwr_seek > 1e-3: if pwr_guess > pwr_seek: high = guess else: low = guess guess = (low + high) / 2. pwr_guess = pwr(rpm, guess, altitude, temp) # result = int(guess) + round(guess % 1, 2)) # return guess # return result return '%.2f' % (guess)
def test_14(self): Value = U.temp_conv(-148, from_units='F', to_units='K') Truth = 173.15 self.failUnless(RE(Value, Truth) <= 1e-8)
def pwr2rpm(pwr_seek, mp, altitude, temp='std', alt_units='ft', temp_units='C'): """ Returns rpm for a given power, manifold pressure in inches of mercury, altitude and temperature (temperature input is optional - standard temperature is used if no temperature is input). Note: the output is rounded off to the nearest rpm. Examples: Determine rpm required for 125 hp at 20 inches HG manifold pressure at 8000 ft and 10 deg C: >>> pwr2rpm(125, 20, 8000, 10) 2477 Determine rpm required for 75% power at 22 inches HG manifold pressure at 6500 ft and 10 deg F: >>> pwr2rpm(.75 * 200, 22, 6500, 10, temp_units = 'F') 2547 Determine rpm required for 55% power at at 18 inches HG manifold pressure at 9,500 ft at standard temperature: >>> pwr2rpm(.55 * 200, 18, 9500) 2423 """ if pwr_seek <= 0: raise ValueError('Power input must be positive.') low = 1000 # initial lower guess high = 3500 # initial upper guess # convert units altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft') if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units) temp = U.temp_conv(temp, from_units=temp_units, to_units='C') # confirm initial low and high are OK: pwr_low = pwr(low, mp, altitude, temp) # print "pwr_low=", pwr_low if pwr_low > pwr_seek: raise ValueError('Initial low guess too high.') pwr_high = pwr(high, mp, altitude, temp) # print "pwr_high=", pwr_high if pwr_high < pwr_seek: # print "pwr_high=", pwr_high print("Function called was IO.pwr(%f, %f, %f, %f)" % (high, mp, altitude, temp)) raise ValueError('Initial high guess too low.') guess = (low + high) / 2. pwr_guess = pwr(guess, mp, altitude, temp) # keep iterating until power is within 0.1% of desired value while M.fabs(pwr_guess - pwr_seek) / pwr_seek > 1e-4: if pwr_guess > pwr_seek: high = guess else: low = guess guess = (low + high) / 2. pwr_guess = pwr(guess, mp, altitude, temp) return int(round(guess, 0))
def test_10(self): Value = U.temp_conv(671.67, from_units='R', to_units='F') Truth = 212 self.failUnless(RE(Value, Truth) <= 1e-5)
def prop_data( prop, bhp, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", thrust_units="lb", ): """ Returns advance ratio, power coefficient, thrust coefficient, blade tip mach number, propeller efficiency and thrust. Validated against Excel spreadsheet provided by Les Doud (Hartzell). """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) try: Ct = cp2ct(prop, Cp, J, blade_tip_mach) except: Ct = cp2ct_alt( prop, Cp, bhp, rpm, tas, altitude, temp=temp, power_units=power_units, alt_units=alt_units, temp_units=temp_units, speed_units=speed_units, ) if prop_eff > 0.1: thrust = eff2thrust( prop_eff, bhp, tas, power_units=power_units, speed_units=speed_units, thrust_units=thrust_units ) else: thrust = ct2thrust( Ct, density, rpm, prop.dia, thrust_units=thrust_units, density_units="kg/m**3", dia_units=dia_units ) # data_block = 'J = ' + str(J) + '\nCp = ' + str(Cp) + '\n Tip mach = ' + str(blade_tip_mach) + '\n Ct = ' + str(Ct) + '\n Thrust = ' + str(thrust) + ' ' + thrust_units + '\n Prop efficiency = ' + str(prop_eff) print " prop = ", prop.prop print " J = %.3f" % J print " Cp = %.5f" % Cp print " Tip Mach = %.3f" % blade_tip_mach print " Ct = %.3f" % Ct print " Thrust = %.2f" % thrust, thrust_units print "Prop efficiency = %.4f" % prop_eff print " Thrust HP = %.2f" % bhp * prop_eff return
def density_alt( H, T, alt_setting=P0, DP='FALSE', RH=0.0, alt_units=default_alt_units, temp_units=default_temp_units, ): """ Return density altitude, given the pressure altitude and the temperature with altitudes in units of feet ('ft'), metres ('m'), statute miles, ('sm') or nautical miles ('nm'), and temperature in units of deg C, F, K or R ('C', 'F', 'K' or 'R'). Mandatory parametres: H = altitude T = temperature Optional parametres: alt_setting = altimeter setting (defaults to 29.9213 if not provided DP = dew point RH = relative humidity alt_units = units for the altitude. 'ft', 'm', or 'km'. temp_units = units for the temperature and dew point. 'C', 'F', 'K' or 'R'. The altimeter setting units are assumed to be inches of HG, unless the value is greater than 35. In this case the units are assumed to be mb. If the dew point or relative humidity are not specified, the air is assumed to be completely dry. If both the dew point and relative humidity are specified, the relative humidity value is ignored. If the units are not specified, the units in default_units.py are used. The method is from: http://wahiduddin.net/calc/density_altitude.htm Examples: Calculate the density altitude in default altitude units for a pressure altitude of 7000 default altitude units and a temperature of 15 deg (default temperature units). The altimeter setting is not specified, so it defaults to standard pressure of 29.9213 in HG or 1013.25 mb: >>> density_alt(7000, 15) 8595.3465863232504 Calculate the density altitude in default altitude units for a pressure altitude of 7000 default altitude units and a temperature of 85 deg F. The altimeter setting is not specified, so it defaults to standard pressure of 29.9213 in HG or 1013.25 mb. The dew point and relative humidity are not specified, so the air is assumed to be dry: >>> density_alt(7000, 85, temp_units = 'F') 10159.10696106757 Calculate the density altitude in default altitude units for a pressure altitude of 7000 default altitude units, an altimeter setting of 29.80 and a temperature of 85 deg F and a dew point of 55 deg F: >>> density_alt(7000, 85, 29.80, 55, temp_units = 'F') 10522.776013011618 Calculate the density altitude in metres for a pressure altitude of 2000 m, an altimeter setting of 1010 mb, a temperature of 15 deg (default temperature units) and a relative humidity of 50%: >>> density_alt(2000, 15, 1010, alt_units = 'm', RH = 0.5) 2529.8230634449737 The dew point may be specified in one of two ways: as the fourth argument on the command line, or via the keyword argument DP. >>> density_alt(2000, 15, 1010, alt_units = 'm', DP = 5) 2530.7528237990618 The relative humidity must be in the range of 0 to 1: >>> density_alt(2000, 15, 1010, alt_units = 'm', RH = 1.1) Traceback (most recent call last): File '<stdin>', line 1, in ? File 'std_atm.py', line 533, in density_alt raise ValueError, 'The relative humidity must be in the range of 0 to 1.' ValueError: The relative humidity must be in the range of 0 to 1. """ Rv = 461.495 # gas constant for water vapour # saturated vapour pressure if DP == 'FALSE' and RH == 0: Pv = 0 else: Pv = sat_press(T, DP, RH, temp_units, press_units='pa') # dry air pressure Pd = dry_press(H, Pv, alt_setting=alt_setting, alt_units=alt_units, press_units='pa') T = U.temp_conv(T, from_units=temp_units, to_units='K') D = Pd / (Rd * T) + Pv / (Rv * T) DR = D / Rho0 return density_ratio2alt(DR, alt_units)
def test_02(self): Value = U.temp_conv(100, from_units='C', to_units='F') Truth = 212 self.failUnless(RE(Value, Truth) <= 1e-8)
def test_05(self): Value = U.temp_conv(473.15, from_units='K', to_units='C') Truth = 200. self.failUnless(RE(Value, Truth) <= 1e-5)
def test_04(self): Value = U.temp_conv(212, from_units='F', to_units='C') Truth = 100 self.failUnless(RE(Value, Truth) <= 1e-5)