def pwr2ff(pwr, rpm, mixture='pwr', ff_units='gph'): """ Returns fuel flow. Defaults to mixture for best power ("pwr"), but may also be used with mixture for best economy ("econ"). Fuel flow units default to USG/hr, but pounds per hour ("lb/hr") and litres per hour ("l/hr") may also be selected. """ if mixture == 'pwr': if rpm >= 2600: rpm1 = 2600 rpm2 = 2700 elif rpm >= 2400: rpm1 = 2400 rpm2 = 2600 elif rpm >= 2200: rpm1 = 2200 rpm2 = 2400 else: rpm1 = 2000 rpm2 = 2200 ff1 = _pwr_ff_best_power(rpm1, pwr) ff2 = _pwr_ff_best_power(rpm2, pwr) elif mixture == 'econ': if rpm >= 2600: rpm1 = 2600 rpm2 = 2700 elif rpm >= 2400: rpm1 = 2400 rpm2 = 2600 elif rpm >= 2200: rpm1 = 2200 rpm2 = 2400 elif rpm >= 2000: rpm1 = 2000 rpm2 = 2200 else: rpm1 = 1800 rpm2 = 2000 ff1 = _pwr_ff_econ(rpm1, pwr) ff2 = _pwr_ff_econ(rpm2, pwr) else: raise ValueError('mixture must be one of "econ" or "pwr"') # else: # raise ValueError('Invalid value for mixture.') ff = ff1 + (ff2 - ff1) * (rpm - rpm1) / (rpm2 - rpm1) if ff_units == 'lb/hr': pass elif ff_units == 'gph': ff = unit_conversion.avgas_conv(ff, to_units='USG') elif ff_units == 'l/hr': ff = unit_conversion.avgas_conv(ff, to_units='l') else: raise ValueError('Invalid fuel flow units') return ff
def test_02(self): # 200 lb of nominal fuel at -40 deg C to USG # truth value from Canada Flight Supplement Value = U.avgas_conv(200., from_units='lb', to_units='USG', temp=-40) Truth = 200. / 6.41 self.assertLessEqual(RE(Value, Truth), 5e-4)
def test_01(self): # 10 USG of nominal fuel at nominal temperature to lbs # truth value from Canada Flight Supplement Value = U.avgas_conv(10, from_units='USG', to_units='lb') Truth = 60.1 self.assertLessEqual(RE(Value, Truth), 5e-4)
def test_03(self): # 200 lb of 100LL grade fuel at 15 deg C to Imperial Gallons # truth value from Air BP Handbook of Products - 715 kg/m**3 Value = U.avgas_conv(200., from_units='lb', to_units='ImpGal', grade='100LL') Truth = (((200. / 2.204622622) / 715) * 1000) / 4.54609 self.assertLessEqual(RE(Value, Truth), 5e-4)
def test_05(self): # 200 l of 80 grade fuel at -40 deg C to kg # truth value from Air BP Handbook of Products - 690 kg/m**3 at 15 deg C Value = U.avgas_conv(200., from_units='l', to_units='kg', grade='80', temp=-40) Truth = (200. / 1000) * 690 # correct for temperature, using ratio given in Canada Flight Supplement Truth *= 6.41 / 6.01 self.assertLessEqual(RE(Value, Truth), 5e-4)
def test_04(self): # 200 kg of 100 grade fuel at 30 deg C to l # truth value from Air BP Handbook of Products - 695 kg/m**3 at 15 deg C Value = U.avgas_conv(200., from_units='kg', to_units='l', grade='100', temp=30) Truth = (200. / 695) * 1000 # correct for temperature, using ratio given in Canada Flight Supplement Truth *= 6.01 / 5.9 self.assertLessEqual(RE(Value, Truth), 5e-4)
def power_lop(ff, n, ff_units='USG/h'): """ Alternate, very simplified and approximate method to determine power, for lean of peak operations. Optimized for operations at 50 deg F lean of peak on Lycoming IO-360A series engines. This was a trial, and initial testing suggests this function is not adequately accurate. """ ff_units = ff_units[:-2] ff = unit_conversion.avgas_conv(ff, from_units=ff_units, to_units='USG') a, b, c, d, e, f, g, h, i = [ 4.61824610e+00, -7.90382136e-01, -4.09623195e-03, 7.58928066e-04, -3.51093492e-05, -1.87325980e-07, 8.64253036e-09, 3.65001722e-02, 1.02174312e-06 ] sfc = a + b * ff + c * n + d * ff * n + e * ff**2 * n + \ f * ff * n**2 + g * ff**2 * n**2 + h * ff**2 + i * n**2 pwr = ff * 6.01 / sfc return pwr
def power(ff, ff_at_pk_EGT, rpm, CR=8.7, displacement=360, ff_units='USG/h', fric_power_factor=1): """ Returns engine power, based on fuel flow data. Based on an internal Lycoming document, apparently for use during flight test programs. ff = fuel flow ff_at_pk_EGT = fuel flow at peak EGT rpm = engine speed CR = compression ratio. Allowable values are 6.75, 7, 7.2, 7.3, 8, 8.5, 8.7 or 9 (10 to be implemented later). displacement = engine displacement in cubic inches. Allowable values are 235, 320, 360, 480, 480S, 540, 540S, 541 or 720. The suffix S denotes GSO or IGSO engines. # type = type of fuel delivery system. Allowable values are # 'port_injection', 'carb', and 'single_point' (i.e fuel # injected at a single point, prior to the intake tubes). # This input is not yet implemented, as it is only needed # for an alternate method, for high power conditions where # it is not safe to lean to peak EGT. ff_units = fuel flow units. Allowable values are 'USG/h', 'ImpGal/h', 'l/h', 'lb/h', and 'kg/h' """ ff_units = ff_units[:-2] ff = unit_conversionavgas_conv(ff, from_units=ff_units, to_units='lb') ff_at_pk_EGT = unit_conversion.avgas_conv(ff_at_pk_EGT, from_units=ff_units, to_units='lb') ff_best_mixture = ff_at_pk_EGT / .849 SFC_best_mixture = iSFC(CR) best_mixture_pwr = ff_best_mixture / SFC_best_mixture ihp = best_mixture_pwr * pwr_ratio_vs_ff_ratio(ff / ff_best_mixture) try: imep = piston.BMEP(best_mixture_pwr, rpm, displacement, power_units='hp', vol_units='in**3') disp_numeric = displacement except TypeError: disp_numeric = int(displacement[:3]) imep = piston.BMEP(best_mixture_pwr, rpm, disp_numeric, power_units='hp', vol_units='in**3') if imep < 140: imep_best_pwr = imep for n in range(10): SFC_best_mixture = iSFC(CR, imep_best_pwr) best_mixture_pwr = ff_best_mixture / SFC_best_mixture imep_best_pwr = piston.BMEP(best_mixture_pwr, rpm, disp_numeric, power_units='hp', vol_units='in**3') # print('iSFC = %.4f' % SFC_best_mixture) ihp = best_mixture_pwr * pwr_ratio_vs_ff_ratio(ff / ff_best_mixture) bhp = ihp - friction_hp(displacement, rpm) * fric_power_factor return bhp