Ejemplo n.º 1
0
    def fct_power_bli(y, PwShaft, Tamb, Pamb, rho, Mach, Vair, Vsnd, r1, d1,
                      nozzle_area):

        Ttot = earth.total_temperature(
            Tamb, Mach)  # Stagnation temperature at inlet position
        (q0, q1, q2, Vinlet,
         dVbli) = craft_aero.air_flows(rho, Vair, r1, d1, y)
        Tstat = Ttot - 0.5 * Vinlet**2 / Cp  # Static temperature at inlet position
        Vsnd_inlet = earth.sound_speed(Tstat)  # Sound speed at inlet position
        MachInlet = Vinlet / Vsnd_inlet  # Mean Mach number at inlet position
        PwInput = nacelle.efficiency_fan * PwShaft
        Vjet = math.sqrt(2. * PwInput / q1 + Vinlet**2)
        TtotJet = Ttot + PwShaft / (
            q1 * Cp)  # Stagnation temperature increases due to introduced work
        Tstat = TtotJet - 0.5 * Vjet**2 / Cp  # Static temperature
        VsndJet = earth.sound_speed(Tstat)  # Sound speed at nozzle exhaust
        MachJet = Vjet / VsndJet  # Mach number at nozzle output
        PtotJet = earth.total_pressure(
            Pamb, MachJet)  # total pressure at nozzle exhaust (P = Pamb)
        CQoA1 = craft_aero.corrected_air_flow(
            PtotJet, TtotJet,
            MachJet)  # Corrected air flow per area at fan position
        q = CQoA1 * nozzle_area

        y = q1 - q

        return y
Ejemplo n.º 2
0
def eval_turboprop_engine_design(aircraft):
    """
    Turboprop architecture design
    """

    engine = aircraft.turboprop_engine

    engine.rating_factor = (0.800, 0.688, 0.624, 0.560, 0.100)

    disa = 0.
    altp = 0.
    mach = 0.25

    (pamb, tamb, tstd, dtodz) = earth.atmosphere(altp, disa)

    Vsnd = earth.sound_speed(tamb)
    Vair = Vsnd * mach

    engine.reference_power = engine.reference_thrust * (
        Vair / engine.propeller_efficiency)

    # assuming a fan disk load of 3000 N/m2
    engine.propeller_diameter = math.sqrt(
        (4. / math.pi) * (engine.reference_thrust / 3000))

    return
Ejemplo n.º 3
0
def air_path(aircraft, nei, altp, disa, speed_mode, speed, mass, rating):
    """
    Retrieves air path in various conditions
    """

    g = earth.gravity()

    [pamb, tamb, tstd, dtodz] = earth.atmosphere(altp, disa)

    mach = get_mach(pamb, speed_mode, speed)

    fn, data = propu.thrust(aircraft, pamb, tamb, mach, rating, nei)

    cz = lift_from_speed(aircraft, pamb, mach, mass)

    [cx, lod] = aero.drag(aircraft, pamb, tamb, mach, cz)

    if (nei > 0):
        dcx = propu.oei_drag(aircraft, pamb, mach)
        cx = cx + dcx * nei
        lod = cz / cx

    acc_factor = earth.climb_mode(speed_mode, dtodz, tstd, disa, mach)

    slope = (fn / (mass * g) - 1 / lod) / acc_factor

    vsnd = earth.sound_speed(tamb)

    v_z = mach * vsnd * slope

    return slope, v_z
Ejemplo n.º 4
0
def turbofan_thrust(aircraft, Pamb, Tamb, Mach, rating, nei):
    """
    Calculation of thrust for pure turbofan airplane
    Warning : ALL engine thrust returned
    """

    engine = aircraft.turbofan_engine
    nacelle = aircraft.turbofan_nacelle

    factor = engine.rating_factor  # [MTO,MCN,MCL,MCR,FID]

    kth =  0.475*Mach**2 + 0.091*(engine.bpr/10)**2 \
         - 0.283*Mach*engine.bpr/10 \
         - 0.633*Mach - 0.081*engine.bpr/10 + 1.192

    (rho, sig) = earth.air_density(Pamb, Tamb)

    fn0 = factor[rating] * kth * engine.reference_thrust * sig**0.75

    fn_core = fn0 * engine.core_thrust_ratio  # Core thrust

    fn_fan0 = fn0 * (1 - engine.core_thrust_ratio)  # Fan thrust

    Vsnd = earth.sound_speed(Tamb)
    Vair = Vsnd * Mach

    shaft_power0 = fn_fan0 * Vair / nacelle.efficiency_prop  # Available total shaft power for one engine

    fn = fn0 * (engine.n_engine - nei)  # All turbofan thrust

    data = (fn_core, fn_fan0, fn0, shaft_power0
            )  # Data for ONE turbofan engine

    return fn, data
Ejemplo n.º 5
0
def specific_air_range(aircraft, altp, mass, mach, disa):

    propulsion = aircraft.propulsion

    (MTO, MCN, MCL, MCR, FID) = propulsion.rating_code

    g = earth.gravity()

    pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)

    vsnd = earth.sound_speed(tamb)

    Cz = flight.lift_from_speed(aircraft, pamb, mach, mass)

    [Cx, LoD] = craft_aero.drag(aircraft, pamb, tamb, mach, Cz)

    nei = 0.

    sfc = propu.sfc(aircraft, pamb, tamb, mach, MCR, nei)

    sar = (vsnd * mach * LoD) / (mass * g * sfc)

    return sar
Ejemplo n.º 6
0
run.mass_mission_adaptation(aircraft)
#run.mass_estimation(aircraft)

# Calculate all airplane performances
#------------------------------------------------------------------------------------------------------
run.performance_analysis(aircraft)

# Print relevant output
#------------------------------------------------------------------------------------------------------
altp = unit.m_ft(35000)
disa = 0
pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)
(MTO, MCN, MCL, MCR, FID) = aircraft.propulsion.rating_code
nei = 0
Fn, Data = propu.thrust(aircraft, pamb, tamb, cruise_mach, MTO, nei)
vsnd = earth.sound_speed(tamb)
tas = vsnd * cruise_mach
print("")
print("True air speed in cruise", "%.1f" % tas, " m/s")
print("Totalthrust in cruise", "%.0f" % Fn, " N")

print("")
print("Engine thrust = ",
      "%.1f" % (aircraft.propulsion.reference_thrust_effective / 10), " daN")
print("Wing area = ", "%.1f" % aircraft.wing.area, " m2")
print("MTOW = ", "%.0f" % aircraft.weights.mtow, " kg")
print("OWE = ", "%.0f" % aircraft.weights.owe, " kg")

print("")
print("Turbofan nacelle width = ", "%.1f" % aircraft.turbofan_nacelle.width,
      " m")
Ejemplo n.º 7
0
def hybrid_body_thrust(aircraft, Pamb, Tamb, Mach, rating, nei):

    propulsion = aircraft.propulsion
    engine = aircraft.turbofan_engine
    nacelle = aircraft.turbofan_nacelle

    battery = aircraft.battery
    power_elec = aircraft.power_elec_chain
    e_engine = aircraft.electric_engine
    e_nacelle = aircraft.electric_nacelle

    power_ratio = numpy.array([
        e_engine.mto_e_power_ratio, e_engine.mcn_e_power_ratio,
        e_engine.mcl_e_power_ratio, e_engine.mcr_e_power_ratio,
        e_engine.fid_e_power_ratio
    ])

    # Battery power feed is used in temporary phases only
    battery_power_feed = numpy.array([1,0,1,0,0])*battery.power_feed \
                                                 *e_nacelle.controler_efficiency \
                                                 *e_nacelle.motor_efficiency

    fn, data = propu.turbofan_thrust(aircraft, Pamb, Tamb, Mach, rating, nei)
    (fn_core, fn_fan0, fn0, shaft_power0) = data

    Vsnd = earth.sound_speed(Tamb)

    Vair = Vsnd * Mach

    shaft_power1 = (1 - power_ratio[rating]
                    ) * shaft_power0  # Shaft power dedicated to the fan

    if (propulsion.bli_effect > 0):
        (fn_fan1, q1,
         dVbli) = propu.fan_thrust_with_bli(nacelle, Pamb, Tamb, Mach, Vair,
                                            shaft_power1)
    else:
        (fn_fan1, q0) = propu.fan_thrust(nacelle, Pamb, Tamb, Mach, Vair,
                                         shaft_power1)

    shaft_power2 = power_ratio[rating] * shaft_power0 * (
        engine.n_engine - nei)  # Shaft power dedicated to electric generator

    # Effective eFan shaft power
    pw_shaft2 =   power_elec.overall_efficiency*shaft_power2 \
                + e_nacelle.motor_efficiency*e_nacelle.controler_efficiency*battery_power_feed[rating]

    if (pw_shaft2 > 0.):

        if (propulsion.bli_effect > 0):
            (fn_fan2, q1,
             dVbli) = propu.fan_thrust_with_bli(e_nacelle, Pamb, Tamb, Mach,
                                                Vair, pw_shaft2)
            dVbli_o_V = dVbli / Vair
        else:
            (fn_fan2, q0) = propu.fan_thrust(e_nacelle, Pamb, Tamb, Mach, Vair,
                                             pw_shaft2)
            dVbli_o_V = 0.

        sec = (pw_shaft2 / e_nacelle.motor_efficiency) / fn_fan2

    else:

        dVbli_o_V = 0.
        fn_fan2 = 0.
        sec = 0

    fn = (fn_core + fn_fan1) * (engine.n_engine - nei) + fn_fan2

    data = (fn_core, fn_fan1, fn_fan2, dVbli_o_V, shaft_power2, fn0,
            shaft_power0)

    return (fn, sec, data)
Ejemplo n.º 8
0
def eval_bli_nacelle_design(this_nacelle, Pamb, Tamb, Mach, shaft_power,
                            hub_width, body_length, body_width):
    """
    BLI nacelle design
    """

    gam = earth.heat_ratio()
    r = earth.gaz_constant()
    Cp = earth.heat_constant(gam, r)

    (rho, sig) = earth.air_density(Pamb, Tamb)
    Vsnd = earth.sound_speed(Tamb)
    Re = craft_aero.reynolds_number(Pamb, Tamb, Mach)
    Vair = Vsnd * Mach

    # Precalculation of the relation between d0 and d1
    #-----------------------------------------------------------------------------------------------------------

    body_bnd_layer = eval_boundary_layer(body_width, hub_width)

    # Electrical nacelle geometry : e-nacelle diameter is size by cruise conditions
    #-----------------------------------------------------------------------------------------------------------
    r0 = 0.5 * body_width  # Radius of the fuselage, supposed constant
    d0 = craft_aero.boundary_layer(
        Re, body_length
    )  # theoritical thickness of the boundary layer without taking account of fuselage tapering
    r1 = 0.5 * hub_width  # Radius of the hub of the efan nacelle
    d1 = lin_interp_1d(d0, body_bnd_layer[:, 0],
                       body_bnd_layer[:,
                                      1])  # Thickness of the BL around the hub

    deltaV = 2. * Vair * (
        this_nacelle.efficiency_fan / this_nacelle.efficiency_prop - 1.
    )  # speed variation produced by the fan

    PwInput = this_nacelle.efficiency_fan * shaft_power  # kinetic energy produced by the fan

    #===========================================================================================================
    def fct_power_1(y, PwInput, deltaV, rho, Vair, r1, d1):
        (q0, q1, q2, v1, dVbli) = craft_aero.air_flows(rho, Vair, r1, d1, y)
        Vinlet = Vair - dVbli
        Vjet = Vinlet + deltaV
        Pw = 0.5 * q1 * (Vjet**2 - Vinlet**2)
        y = PwInput - Pw
        return y

    #-----------------------------------------------------------------------------------------------------------

    fct_arg = (PwInput, deltaV, rho, Vair, r1, d1)

    # Computation of y1 : thickness of the vein swallowed by the inlet
    output_dict = fsolve(fct_power_1, x0=d1, args=fct_arg, full_output=True)

    y1 = output_dict[0][0]

    (q0, q1, q2, v1, dVbli) = craft_aero.air_flows(rho, Vair, r1, d1, y1)

    MachInlet = v1 / Vsnd  # Mean Mach number at inlet position

    Ptot = earth.total_pressure(
        Pamb, MachInlet)  # Stagnation pressure at inlet position

    Ttot = earth.total_temperature(
        Tamb, MachInlet)  # Stagnation temperature at inlet position

    MachFan = 0.5  # required Mach number at fan position

    CQoA1 = craft_aero.corrected_air_flow(
        Ptot, Ttot, MachFan)  # Corrected air flow per area at fan position

    eFanArea = q1 / CQoA1  # Fan area around the hub

    fan_width = math.sqrt(hub_width**2 +
                          4 * eFanArea / math.pi)  # Fan diameter

    Vjet = v1 + deltaV  # Jet velocity

    TtotJet = Ttot + shaft_power / (
        q1 * Cp)  # Stagnation pressure increases due to introduced work

    Tstat = TtotJet - 0.5 * Vjet**2 / Cp  # static temperature

    VsndJet = math.sqrt(gam * r * Tstat)  # Sound velocity at nozzle exhaust

    MachJet = Vjet / VsndJet  # Mach number at nozzle output

    PtotJet = earth.total_pressure(
        Pamb, MachJet)  # total pressure at nozzle exhaust (P = Pamb)

    CQoA2 = craft_aero.corrected_air_flow(
        PtotJet, TtotJet,
        MachJet)  # Corrected air flow per area at nozzle output

    nozzle_area = q1 / CQoA2  # Fan area around the hub

    nozzle_width = math.sqrt(4 * nozzle_area / math.pi)  # Nozzle diameter

    this_nacelle.hub_width = hub_width

    this_nacelle.fan_width = fan_width

    this_nacelle.nozzle_width = nozzle_width

    this_nacelle.nozzle_area = nozzle_area

    this_nacelle.width = 1.19 * fan_width  # Surrounding structure

    this_nacelle.length = 1.68 * this_nacelle.width

    this_nacelle.net_wetted_area = math.pi * this_nacelle.width * this_nacelle.length  # Nacelle wetted area

    this_nacelle.bnd_layer = body_bnd_layer

    this_nacelle.body_length = body_length

    return
Ejemplo n.º 9
0
def eval_hybrid_engine_design(aircraft):
    """
    Thermal propulsive architecture design
    """

    design_driver = aircraft.design_driver
    fuselage = aircraft.fuselage

    propulsion = aircraft.propulsion
    engine = aircraft.turbofan_engine
    nacelle = aircraft.turbofan_nacelle

    battery = aircraft.battery
    power_elec = aircraft.power_elec_chain
    e_engine = aircraft.electric_engine
    e_nacelle = aircraft.electric_nacelle

    low_speed = aircraft.low_speed

    (MTO, MCN, MCL, MCR, FID) = propulsion.rating_code

    # Propulsion architecture design
    #-----------------------------------------------------------------------------------------------------------

    # Initialisation
    crm = design_driver.cruise_mach
    toc = design_driver.top_of_climb_altp
    rca = design_driver.ref_cruise_altp
    roa = low_speed.req_oei_altp

    #                      MTO   MCN    MCL  MCR  FIR
    fd_disa = numpy.array([15., 0., 0., 0., 0.])
    fd_altp = numpy.array([0., roa, toc, rca, rca])
    fd_mach = numpy.array([0.25, crm / 2, crm, crm, crm])
    fd_nei = numpy.array([0., 1., 0., 0., 0.])

    e_engine.flight_data = {
        "disa": fd_disa,
        "altp": fd_altp,
        "mach": fd_mach,
        "nei": fd_nei
    }

    e_fan_power = numpy.array([
        power_elec.mto, power_elec.mcn, power_elec.mcl, power_elec.mcr,
        power_elec.fid
    ])

    # Battery power feed is used in temporary phases only
    battery_power_feed = numpy.array([1,0,1,0,0])*battery.power_feed \
                                                 *e_nacelle.controler_efficiency \
                                                 *e_nacelle.motor_efficiency

    e_power_ratio = numpy.zeros(5)
    e_shaft_power = numpy.zeros(5)

    for rating in propulsion.rating_code:

        (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(fd_altp[rating],
                                                     fd_disa[rating])
        (fn, data) = propu.turbofan_thrust(aircraft, Pamb, Tamb,
                                           fd_mach[rating], rating,
                                           fd_nei[rating])
        (fn_core, fn_fan0, fn0, shaft_power0) = data

        if e_fan_power[rating] > 1:  # required eFan shaft power is given

            # Fraction of the turbofan shaft power dedicated to electric generation
            e_power_ratio[rating] =  ( (e_fan_power[rating] - battery_power_feed[rating] \
                                        )/ power_elec.overall_efficiency \
                                      )/((shaft_power0)*(engine.n_engine-fd_nei[rating]))

            # e-fan shaft power
            e_shaft_power[rating] = e_fan_power[rating]

        else:  # required turbofan shaft power ration is given

            # Shaft power dedicated to electric generator
            shaft_power2 = e_power_ratio[rating] * shaft_power0 * (
                engine.n_engine - fd_nei[rating])

            # Fraction of the shaft power dedicated to the electric generation
            e_power_ratio[rating] = e_fan_power[rating]

            e_shaft_power[rating] =   shaft_power2*power_elec.overall_efficiency \
                                    + battery_power_feed[rating]

    e_engine.mto_e_power_ratio = e_power_ratio[MTO]
    e_engine.mcn_e_power_ratio = e_power_ratio[MCN]
    e_engine.mcl_e_power_ratio = e_power_ratio[MCL]
    e_engine.mcr_e_power_ratio = e_power_ratio[MCR]
    e_engine.fid_e_power_ratio = e_power_ratio[FID]

    e_engine.mto_e_shaft_power = e_shaft_power[MTO]
    e_engine.mcn_e_shaft_power = e_shaft_power[MCN]
    e_engine.mcl_e_shaft_power = e_shaft_power[MCL]
    e_engine.mcr_e_shaft_power = e_shaft_power[MCR]
    e_engine.fid_e_shaft_power = e_shaft_power[FID]

    # Engine performance update
    #-----------------------------------------------------------------------------------------------------------
    (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(fd_altp[MTO], fd_disa[MTO])
    (fn, data) = propu.turbofan_thrust(aircraft, Pamb, Tamb, fd_mach[MTO], MTO,
                                       fd_nei[MTO])
    (fn_core, fn_fan0, fn0, shaft_power0) = data

    shaft_power1 = (1 - e_power_ratio[MTO]
                    ) * shaft_power0  # Shaft power dedicated to the fan

    Vsnd = earth.sound_speed(Tamb)
    Vair = Vsnd * fd_mach[MTO]

    fn_fan1 = nacelle.efficiency_prop * shaft_power1 / Vair  # Effective fan thrust

    engine.kfn_off_take = (
        fn_core +
        fn_fan1) / fn0  # Thrust reduction due to power off take for the e-fan

    return
Ejemplo n.º 10
0
def eval_hybrid_nacelle_design(aircraft):
    """
    Hybrid propulsive architecture design
    """

    design_driver = aircraft.design_driver
    fuselage = aircraft.fuselage
    wing = aircraft.wing

    propulsion = aircraft.propulsion

    engine = aircraft.turbofan_engine
    nacelle = aircraft.turbofan_nacelle

    e_engine = aircraft.electric_engine
    e_nacelle = aircraft.electric_nacelle

    (MTO, MCN, MCL, MCR, FID) = propulsion.rating_code

    # Turbofan nacelles geometry adjustment
    #-----------------------------------------------------------------------------------------------------------
    nacWidth0 = 0.49 * engine.bpr**0.67 + 4.8e-6 * engine.reference_thrust  # Reference dimensions of the nacelle without power off take

    nacLength0 = 0.86 * nacWidth0 + engine.bpr**0.37

    kSize = math.sqrt(
        engine.kfn_off_take)  # Diameter decrease due to max thrust decrease

    kSize_eff = (kSize + engine.core_width_ratio * (1 - kSize)
                 )  # Diameter decrease considering core is unchanged

    nacelle.width = nacWidth0 * kSize_eff  # Real nacelle diameter assuming core section remains unchanged

    nacelle.length = nacLength0 * kSize_eff  # Nacelle length is reduced according to the same factor

    knac = math.pi * nacelle.width * nacelle.length

    nacelle.net_wetted_area = knac * (1.48 - 0.0076 * knac) * engine.n_engine

    tan_phi0 = 0.25 * (wing.c_kink - wing.c_tip) / (
        wing.y_tip - wing.y_kink) + numpy.tan(wing.sweep)

    if (nacelle.attachment == 1):

        nacelle.y_ext = 0.7 * fuselage.width + 1.4 * nacelle.width  # statistical regression

        nacelle.x_ext = wing.x_root + (
            nacelle.y_ext - wing.y_root) * tan_phi0 - 0.7 * nacelle.length

        nacelle.z_ext = - 0.5 * fuselage.height \
                    + (nacelle.y_ext - 0.5 * fuselage.width) * math.tan(wing.dihedral) \
                    - 0.5*nacelle.width

    elif (nacelle.attachment == 2):

        nacelle.y_ext = 0.5 * fuselage.width + 0.6 * nacelle.width  # statistical regression

        nacelle.x_ext = wing.x_root + (
            nacelle.y_ext - wing.y_root) * tan_phi0 - 0.7 * nacelle.length

        nacelle.z_ext = 0.5 * fuselage.height

    # Electric nacelle is design for cruise conditions
    #-----------------------------------------------------------------------------------------------------------

    dISA = 0.
    Altp = design_driver.ref_cruise_altp
    Mach = design_driver.cruise_mach

    (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(Altp, dISA)

    shaft_power = e_engine.mcr_e_shaft_power
    hub_width = 0.5  # Diameter of the e fan hub

    body_length = fuselage.length
    body_width = fuselage.width

    eval_bli_nacelle_design(e_nacelle, Pamb, Tamb, Mach, shaft_power,
                            hub_width, body_length, body_width)

    e_nacelle.x_ext = fuselage.length + 0.2 * e_nacelle.width
    e_nacelle.y_ext = 0
    e_nacelle.z_ext = 0.91 * fuselage.height - 0.51 * fuselage.height

    # Engine performance update
    #-----------------------------------------------------------------------------------------------------------
    fd = e_engine.flight_data

    e_fan_thrust = numpy.zeros(5)

    for rating in propulsion.rating_code:

        altp = fd.get("altp")[rating]
        disa = fd.get("disa")[rating]
        mach = fd.get("mach")[rating]
        nei = fd.get("nei")[rating]

        (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(altp, disa)
        (fn, sec, data) = propu.hybrid_thrust(aircraft, Pamb, Tamb, mach,
                                              rating, nei)
        (fn_core, fn_fan1, fn_fan2, dVbli_o_V, shaft_power2, fn0,
         shaft_power0) = data

        e_fan_thrust[rating] = fn_fan2

    e_engine.mto_e_fan_thrust = e_fan_thrust[MTO]
    e_engine.mcn_e_fan_thrust = e_fan_thrust[MCN]
    e_engine.mcl_e_fan_thrust = e_fan_thrust[MCL]
    e_engine.mcr_e_fan_thrust = e_fan_thrust[MCR]
    e_engine.fid_e_fan_thrust = e_fan_thrust[FID]

    Vair = Mach * earth.sound_speed(Tamb)

    (eFanFnBli, q1, dVbli) = propu.fan_thrust_with_bli(e_nacelle, Pamb, Tamb,
                                                       Mach, Vair, shaft_power)

    (eFanFn, q0) = propu.fan_thrust(e_nacelle, Pamb, Tamb, Mach, Vair,
                                    shaft_power)

    propulsion.bli_e_thrust_factor = eFanFnBli / eFanFn  # Thrust increase due to BLI at iso shaft power

    propulsion.bli_thrust_factor = 1  # Thrust increase due to BLI at iso shaft power

    return
Ejemplo n.º 11
0
def fan_thrust(nacelle, Pamb, Tamb, Mach, Vair, PwShaft):
    """
    Compute the thrust of a fan of given geometry swallowing
    the boundary layer (BL) of a body of given geometry
    The amount of swallowed BL depends on the given shaft power
    and flying conditions
    """

    bnd_layer = nacelle.bnd_layer

    Re = craft_aero.reynolds_number(Pamb, Tamb, Mach)
    (rho, sig) = earth.air_density(Pamb, Tamb)
    Vsnd = earth.sound_speed(Tamb)

    d0 = craft_aero.boundary_layer(
        Re, nacelle.body_length
    )  #Theoritical thickness of the boundary layer without taking account of fuselage tapering
    d1 = lin_interp_1d(d0, bnd_layer[:, 0],
                       bnd_layer[:, 1])  # Using the precomputed relation
    r1 = 0.5 * nacelle.hub_width  # Radius of the hub of the eFan nacelle

    PwInput = nacelle.efficiency_fan * PwShaft

    #===========================================================================================================
    def fct_power(q, PwInput, Vair, Vsnd, eNozzleArea):

        Vinlet = Vair
        MachInlet = Vinlet / Vsnd  # Mean Mach number at inlet position
        Ptot = earth.total_pressure(
            Pamb, MachInlet)  #total pressure at inlet position
        Ttot = earth.total_temperature(
            Tamb, MachInlet)  # Total temperature at inlet position
        Vjet = math.sqrt(2. * PwInput / q + Vinlet**2)
        MachJet = Vjet / Vsnd
        CQoA1 = craft_aero.corrected_air_flow(
            Ptot, Ttot, MachJet)  # Corrected air flow per area at fan position
        q0 = CQoA1 * eNozzleArea

        y = q - q0

        return y

    #-----------------------------------------------------------------------------------------------------------

    eNozzleArea = nacelle.nozzle_area

    fct_arg = (PwInput, Vair, Vsnd, eNozzleArea)

    (q0init, q1, q2, V1, dV) = craft_aero.air_flows(rho, Vair, r1, d1, 1.00)

    # Computation of y1 : thikness of the vein swallowed by the inlet
    output_dict = fsolve(fct_power, x0=q0init, args=fct_arg, full_output=True)

    q0 = output_dict[0][0]

    Vinlet = Vair
    Vjet = math.sqrt(2. * PwInput / q0 + Vinlet**2)

    eFn = q0 * (Vjet - Vinlet)

    return (eFn, q0)
Ejemplo n.º 12
0
def fan_thrust_with_bli(nacelle, Pamb, Tamb, Mach, Vair, PwShaft):
    """
    Compute the thrust of a fan of a given geometry swallowing
    the boundary layer (BL) of a body of a given geometry
    The amount of swallowed BL depends on the given shaft power and flying
    conditions.
    """

    bnd_layer = nacelle.bnd_layer

    gam = earth.heat_ratio()
    r = earth.gaz_constant()
    Cp = earth.heat_constant(gam, r)

    Re = craft_aero.reynolds_number(Pamb, Tamb, Mach)
    (rho, sig) = earth.air_density(Pamb, Tamb)
    Vsnd = earth.sound_speed(Tamb)

    d0 = craft_aero.boundary_layer(
        Re, nacelle.body_length
    )  # theorical thickness of the boundary layer without taking account of fuselage tapering
    r1 = 0.5 * nacelle.hub_width  # Radius of the hub of the eFan nacelle
    d1 = lin_interp_1d(d0, bnd_layer[:, 0],
                       bnd_layer[:, 1])  # Using the precomputed relation

    #===========================================================================================================
    def fct_power_bli(y, PwShaft, Tamb, Pamb, rho, Mach, Vair, Vsnd, r1, d1,
                      nozzle_area):

        Ttot = earth.total_temperature(
            Tamb, Mach)  # Stagnation temperature at inlet position
        (q0, q1, q2, Vinlet,
         dVbli) = craft_aero.air_flows(rho, Vair, r1, d1, y)
        Tstat = Ttot - 0.5 * Vinlet**2 / Cp  # Static temperature at inlet position
        Vsnd_inlet = earth.sound_speed(Tstat)  # Sound speed at inlet position
        MachInlet = Vinlet / Vsnd_inlet  # Mean Mach number at inlet position
        PwInput = nacelle.efficiency_fan * PwShaft
        Vjet = math.sqrt(2. * PwInput / q1 + Vinlet**2)
        TtotJet = Ttot + PwShaft / (
            q1 * Cp)  # Stagnation temperature increases due to introduced work
        Tstat = TtotJet - 0.5 * Vjet**2 / Cp  # Static temperature
        VsndJet = earth.sound_speed(Tstat)  # Sound speed at nozzle exhaust
        MachJet = Vjet / VsndJet  # Mach number at nozzle output
        PtotJet = earth.total_pressure(
            Pamb, MachJet)  # total pressure at nozzle exhaust (P = Pamb)
        CQoA1 = craft_aero.corrected_air_flow(
            PtotJet, TtotJet,
            MachJet)  # Corrected air flow per area at fan position
        q = CQoA1 * nozzle_area

        y = q1 - q

        return y

    #-----------------------------------------------------------------------------------------------------------

    nozzle_area = nacelle.nozzle_area

    fct_arg = (PwShaft, Tamb, Pamb, rho, Mach, Vair, Vsnd, r1, d1, nozzle_area)

    # Computation of y1 : thikness of the vein swallowed by the inlet
    output_dict = fsolve(fct_power_bli,
                         x0=0.50,
                         args=fct_arg,
                         full_output=True)

    y = output_dict[0][0]

    Ttot = earth.total_temperature(
        Tamb, Mach)  # Stagnation temperature at inlet position
    (q0, q1, q2, Vinlet, dVbli) = craft_aero.air_flows(rho, Vair, r1, d1, y)
    Tstat = Ttot - 0.5 * Vinlet**2 / Cp  # Static temperature at inlet position
    Vsnd_inlet = earth.sound_speed(Tstat)  # Sound speed at inlet position
    MachInlet = Vinlet / Vsnd_inlet  # Mean Mach number at inlet position
    PwInput = nacelle.efficiency_fan * PwShaft
    Vjet = math.sqrt(2. * PwInput / q1 + Vinlet**2)

    eFn = q1 * (Vjet - Vinlet)

    return (eFn, q1, dVbli)
Ejemplo n.º 13
0
def eval_hybrid_body_nacelle_design(aircraft):
    """
    Hybrid propulsive architecture design
    """

    design_driver = aircraft.design_driver
    fuselage = aircraft.fuselage
    wing = aircraft.wing

    propulsion = aircraft.propulsion

    engine = aircraft.turbofan_engine
    nacelle = aircraft.turbofan_nacelle
    body = aircraft.body_nacelle

    e_engine = aircraft.electric_engine
    e_nacelle = aircraft.electric_nacelle

    (MTO, MCN, MCL, MCR, FID) = propulsion.rating_code

    #-----------------------------------------------------------------------------------------------------------
    tan_phi0 = 0.25 * (wing.c_kink - wing.c_tip) / (
        wing.y_tip - wing.y_kink) + numpy.tan(wing.sweep)

    body.y_ext = 0.8 * fuselage.width + 1.5 * nacelle.width  # statistical regression

    body.x_ext = wing.x_root + (nacelle.y_ext -
                                wing.y_root) * tan_phi0 - 0.5 * body.length

    body.z_ext = - 0.5 * fuselage.height \
                    + (nacelle.y_ext - 0.5 * fuselage.width) * math.tan(wing.dihedral) \
                    - 0.5*nacelle.width

    body.net_wetted_area = 2.7 * body.length * body.width * engine.n_engine  # All bodies wetted area

    # Turbofan nacelles geometry is designed according to cruise conditions
    #-----------------------------------------------------------------------------------------------------------
    dISA = 0.
    Altp = design_driver.ref_cruise_altp
    Mach = design_driver.cruise_mach
    nei = 0

    (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(Altp, dISA)

    fn, data = propu.turbofan_thrust(aircraft, Pamb, Tamb, Mach, MCR, nei)
    (fn_core, fn_fan0, fn0, shaft_power0) = data

    shaft_power1 = (1 - e_engine.mcr_e_power_ratio
                    ) * shaft_power0  # Shaft power dedicated to the fan

    body_hub_width = body.hub_width  # Diameter of the fan hub

    body_length = body.length
    body_width = body.width

    eval_bli_nacelle_design(nacelle, Pamb, Tamb, Mach, shaft_power1,
                            body_hub_width, body_length, body_width)

    nacelle.y_ext = body.y_ext
    nacelle.x_ext = body.x_ext + body.length
    nacelle.z_ext = body.z_ext

    # Electric nacelle is design for cruise conditions
    #-----------------------------------------------------------------------------------------------------------
    dISA = 0.
    Altp = design_driver.ref_cruise_altp
    Mach = design_driver.cruise_mach

    (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(Altp, dISA)

    shaft_power = e_engine.mcr_e_shaft_power

    efan_hub_width = 0.5  # Diameter of the e fan hub
    body_length = fuselage.length
    body_width = fuselage.width

    eval_bli_nacelle_design(e_nacelle, Pamb, Tamb, Mach, shaft_power,
                            efan_hub_width, body_length, body_width)

    e_nacelle.x_ext = fuselage.length + 0.2 * e_nacelle.width
    e_nacelle.y_ext = 0
    e_nacelle.z_ext = 0.91 * fuselage.height - 0.51 * fuselage.height

    # Engine performance update
    #-----------------------------------------------------------------------------------------------------------
    fd = e_engine.flight_data

    e_fan_thrust = numpy.zeros(5)

    for rating in propulsion.rating_code:

        altp = fd.get("altp")[rating]
        disa = fd.get("disa")[rating]
        mach = fd.get("mach")[rating]
        nei = fd.get("nei")[rating]

        (Pamb, Tamb, Tstd, dTodZ) = earth.atmosphere(altp, disa)
        (fn, sec, data) = propu.hybrid_thrust(aircraft, Pamb, Tamb, mach,
                                              rating, nei)
        (fn_core, fn_fan1, fn_fan2, dVbli_o_V, shaft_power2, fn0,
         shaft_power0) = data

        e_fan_thrust[rating] = fn_fan2

    e_engine.mto_e_fan_thrust = e_fan_thrust[MTO]
    e_engine.mcn_e_fan_thrust = e_fan_thrust[MCN]
    e_engine.mcl_e_fan_thrust = e_fan_thrust[MCL]
    e_engine.mcr_e_fan_thrust = e_fan_thrust[MCR]
    e_engine.fid_e_fan_thrust = e_fan_thrust[FID]

    Vair = Mach * earth.sound_speed(Tamb)

    (eFanFnBli, q1, dVbli) = propu.fan_thrust_with_bli(e_nacelle, Pamb, Tamb,
                                                       Mach, Vair, shaft_power)
    (eFanFn, q0) = propu.fan_thrust(e_nacelle, Pamb, Tamb, Mach, Vair,
                                    shaft_power)
    propulsion.bli_e_thrust_factor = eFanFnBli / eFanFn  # Thrust increase due to BLI at iso shaft power

    (FanFnBli, q1, dVbli) = propu.fan_thrust_with_bli(nacelle, Pamb, Tamb,
                                                      Mach, Vair, shaft_power)
    (FanFn, q0) = propu.fan_thrust(nacelle, Pamb, Tamb, Mach, Vair,
                                   shaft_power)
    propulsion.bli_thrust_factor = FanFnBli / FanFn  # Thrust increase due to BLI at iso shaft power

    return
Ejemplo n.º 14
0
def mission(aircraft, dist_range, tow, altp, mach, disa):
    """
    Mission computation using breguet equation, fixed L/D and fixed sfc
    """

    engine = aircraft.turbofan_engine
    propulsion = aircraft.propulsion
    battery = aircraft.battery

    (MTO, MCN, MCL, MCR, FID) = propulsion.rating_code

    g = earth.gravity()

    pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)
    vsnd = earth.sound_speed(tamb)
    tas = vsnd * mach

    lod_max, cz_lod_max = craft_aero.lod_max(aircraft, pamb, tamb, mach)

    lod_cruise = 0.95 * lod_max

    nei = 0.

    sfc = propu.sfc(aircraft, pamb, tamb, mach, MCR, nei)

    if (propulsion.architecture == 2):
        fn, sec, data = propu.hybrid_thrust(aircraft, pamb, tamb, mach, MCR,
                                            nei)
    if (propulsion.architecture == 3):
        fn, sec, data = propu.hybrid_thrust(aircraft, pamb, tamb, mach, MCR,
                                            nei)

    # Departure ground phases
    #-----------------------------------------------------------------------------------------------------------
    fuel_taxi_out = (34 + 2.3e-4 * engine.reference_thrust) * engine.n_engine
    time_taxi_out = 540

    fuel_take_off = 1e-4 * (2.8 + 2.3 / engine.bpr) * tow
    time_take_off = 220 * tow / (engine.reference_thrust * engine.n_engine)

    # Mission leg
    #-----------------------------------------------------------------------------------------------------------
    if (propulsion.architecture == 1):
        fuel_mission = tow * (1 - numpy.exp(-(sfc * g * dist_range) /
                                            (tas * lod_cruise)))
    elif (propulsion.architecture == 2):
        fuel_mission = tow*(1-numpy.exp(-(sfc*g*dist_range)/(tas*lod_cruise))) \
                        - (sfc/sec)*battery.energy_cruise
    elif (propulsion.architecture == 3):
        fuel_mission = tow*(1-numpy.exp(-(sfc*g*dist_range)/(tas*lod_cruise))) \
                        - (sfc/sec)*battery.energy_cruise
    elif (propulsion.architecture == 4):
        fuel_mission = tow * (1 - numpy.exp(-(sfc * g * dist_range) /
                                            (tas * lod_cruise)))
    else:
        raise Exception("propulsion.architecture index is out of range")

    time_mission = 1.09 * (dist_range / tas)

    l_w = tow - fuel_mission

    # Arrival ground phases
    #-----------------------------------------------------------------------------------------------------------
    fuel_landing = 1e-4 * (0.5 + 2.3 / engine.bpr) * l_w
    time_landing = 180

    fuel_taxi_in = (26 + 1.8e-4 * engine.reference_thrust) * engine.n_engine
    time_taxi_in = 420

    # Block fuel and time
    #-----------------------------------------------------------------------------------------------------------
    block_fuel = fuel_taxi_out + fuel_take_off + fuel_mission + fuel_landing + fuel_taxi_in
    time_block = time_taxi_out + time_take_off + time_mission + time_landing + time_taxi_in

    # Diversion and holding reserve fuel
    #-----------------------------------------------------------------------------------------------------------
    fuel_diversion = l_w * (1 -
                            numpy.exp(-(sfc * g * regul.diversion_range()) /
                                      (tas * lod_cruise)))

    fuel_holding = sfc * (l_w * g / lod_max) * regul.holding_time()

    # Total
    #-----------------------------------------------------------------------------------------------------------
    fuel_total = fuel_mission * (
        1 + regul.reserve_fuel_ratio()) + fuel_diversion + fuel_holding

    #-----------------------------------------------------------------------------------------------------------
    return block_fuel, time_block, fuel_total