コード例 #1
0
ファイル: design.py プロジェクト: AdelTaiebTamacha/ACDC
def nominal_mission(aircraft):
    """
    Compute nominal mission with range as input
    """

    disa = 0
    altp = aircraft.design_driver.ref_cruise_altp
    mach = aircraft.design_driver.cruise_mach
    nei = 0

    aircraft.nominal_mission.payload = aircraft.payload.nominal
    aircraft.nominal_mission.range = aircraft.design_driver.design_range
    aircraft.nominal_mission.tow = aircraft.weights.mtow

    (MTO, MCN, MCL, MCR, FID) = aircraft.propulsion.rating_code
    pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)
    lod_max, _ = craft_aero.lod_max(aircraft, pamb, tamb, mach)
    sfc = propu.sfc(aircraft, pamb, tamb, mach, MCR, nei)

    aircraft.high_speed.cruise_lod = lod_max
    aircraft.high_speed.cruise_sfc = sfc

    payload = aircraft.nominal_mission.payload
    range = aircraft.nominal_mission.range
    tow = aircraft.nominal_mission.tow

    block_fuel, block_time, total_fuel = perfo.mission(aircraft, range, tow,
                                                       altp, mach, disa)

    aircraft.nominal_mission.block_fuel = block_fuel
    aircraft.nominal_mission.block_time = block_time
    aircraft.nominal_mission.total_fuel = total_fuel

    return
コード例 #2
0
def acceleration(aircraft, nei, altp, disa, speed_mode, speed, mass, rating):
    """
    Aircraft acceleration on level flight
    """

    wing = aircraft.wing
    gam = earth.heat_ratio()

    [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

    acc = (fn - 0.5 * gam * pamb * mach**2 * wing.area * cx) / mass

    return acc
コード例 #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
コード例 #4
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
コード例 #5
0
def eval_aerodynamics_design(aircraft):
    """
    Defines high lift movable deflection settings
    HLDconf varies from 0 (clean) to 1 (full deflected)
    Typically : HLDconf = 1 ==> CzmaxLD
              : HLDconf = 0.1 to 0.5 ==> CzmaxTO
    """

    design_driver = aircraft.design_driver
    wing = aircraft.wing

    aerodynamics = aircraft.aerodynamics

    mach = design_driver.cruise_mach
    altp = design_driver.ref_cruise_altp
    disa = 0

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

    aerodynamics.cruise_lod_max, aerodynamics.cz_cruise_lod_max = craft_aero.lod_max(
        aircraft, pamb, tamb, mach)

    aerodynamics.hld_conf_clean = 0  # By definition (0=<hld_conf=<1)
    aerodynamics.cz_max_clean, Cz0 = craft_aero.high_lift(
        wing, aerodynamics.hld_conf_clean)

    aerodynamics.hld_conf_to = 0.3  # Take off (empirical setting)
    aerodynamics.cz_max_to, Cz0 = craft_aero.high_lift(
        wing, aerodynamics.hld_conf_to)

    aerodynamics.hld_conf_ld = 1  # By definition (0=<hld_conf=<1), 1 is full landing
    aerodynamics.cz_max_ld, Cz0 = craft_aero.high_lift(
        wing, aerodynamics.hld_conf_ld)

    return
コード例 #6
0
def forward_cg_stall(aircraft, altp, disa, nei, hld_conf, speed_mode, mass):
    """
    Computes max forward trimmable CG position at stall speed
    """

    wing = aircraft.wing
    htp = aircraft.horizontal_tail

    gam = earth.heat_ratio()

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

    [cz_max_wing, cz0] = craft_aero.high_lift(
        wing, hld_conf)  # Wing maximum lift coefficient without margin

    [cza_htp, xlc_htp, aoa_max_htp,
     ki_htp] = frame_aero.htp_aero_data(aircraft)

    cz_max_htp = cza_htp * aoa_max_htp

    c_z = cz_max_wing - cz_max_htp  # Max forward Cg assumed, HTP has down lift

    mach = flight.speed_from_lift(aircraft, pamb, c_z, mass)

    [cza_wo_htp, xlc_wo_htp,
     ki_wing] = frame_aero.wing_aero_data(aircraft, mach, hld_conf)

    if (nei > 0):
        dcx_oei = nei * propu.oei_drag(pamb, mach)
    else:
        dcx_oei = 0

    dw_angle = frame_aero.wing_downwash(
        aircraft, cz_max_wing)  # Downwash angle due to the wing
    cx_basic, lod_trash = craft_aero.drag(
        aircraft, pamb, tamb, mach,
        cz_max_wing)  # By definition of the drag_ function
    cxi_htp = (ki_htp * cz_max_htp**2) * (htp.area / wing.area
                                          )  # Induced drag generated by HTP
    cx_inter = cz_max_htp * dw_angle  # Interaction drag (due to downwash)
    cx_trimmed = cx_basic + cxi_htp + cx_inter + dcx_oei

    fn = 0.5 * gam * pamb * mach**2 * wing.area * cx_trimmed

    cm_prop = propu.thrust_pitch_moment(aircraft, fn, pamb, mach, dcx_oei)

    cg_max_fwd_stall = (cm_prop + xlc_wo_htp * cz_max_wing -
                        xlc_htp * cz_max_htp) / (cz_max_wing - cz_max_htp)

    aoa_wing = (cz_max_wing - cz0) / cza_wo_htp  # Wing angle of attack
    aoa = aoa_wing - wing.setting  # Reference angle of attack (fuselage axis versus air speed)
    ih = -aoa + dw_angle - aoa_max_htp  # HTP trim setting

    speed = flight.get_speed(pamb, speed_mode, mach)

    return cg_max_fwd_stall, speed, fn, aoa, ih, c_z, cx_trimmed
コード例 #7
0
 def fct_max_path(cz, aircraft, nei, altp, disa, speed_mode, mass, rating,
                  isformax):
     pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)
     mach = speed_from_lift(aircraft, pamb, cz, mass)
     speed = get_speed(pamb, speed_mode, mach)
     [slope, vz] = air_path(aircraft, nei, altp, disa, speed_mode, speed,
                            mass, rating)
     if (isformax == True):
         return slope
     elif (isformax == False):
         return slope, vz, speed
コード例 #8
0
ファイル: mission.py プロジェクト: AdelTaiebTamacha/ACDC
def ceilings(aircraft, toc, oei_ceil):

    design_driver = aircraft.design_driver
    propulsion = aircraft.propulsion
    weights = aircraft.weights

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

    disa = 15

    # propulsion ceilings
    #-----------------------------------------------------------------------------------------------------------
    nei = 0
    altp = toc
    speed_mode = 2  # WARNING : iso Mach climb mode
    speed = design_driver.cruise_mach

    mass = 0.97 * weights.mtow

    rating = MCL  # Max Climb

    slope, vz_clb = flight.air_path(aircraft, nei, altp, disa, speed_mode,
                                    speed, mass, rating)

    rating = MCR  # Max Cruise

    slope, vz_crz = flight.air_path(aircraft, nei, altp, disa, speed_mode,
                                    speed, mass, rating)

    # One engine inoperative ceiling
    #-----------------------------------------------------------------------------------------------------------
    nei = 1
    altp = oei_ceil
    speed_mode = 2  # WARNING : iso Mach climb mode

    pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)
    speed = earth.vcas_from_mach(pamb, design_driver.cruise_mach)

    mass = 0.95 * weights.mtow

    rating = MCN

    oei_slope, vz, oei_mach, cz = flight.max_path(aircraft, nei, altp, disa,
                                                  speed_mode, mass, rating)

    #-----------------------------------------------------------------------------------------------------------
    return vz_clb, vz_crz, oei_slope, oei_mach
コード例 #9
0
ファイル: mission.py プロジェクト: AdelTaiebTamacha/ACDC
def approach_speed(aircraft, altp, disa, mass, hld_conf):
    """
    Minimum approach speed (VLS)
    """

    wing = aircraft.wing

    g = earth.gravity()

    czmax, trash = craft_aero.high_lift(wing, hld_conf)

    stall_margin = regul.kvs1g_min_landing()

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

    [rho, sig] = earth.air_density(pamb, tamb)

    vapp = numpy.sqrt(
        (mass * g) / (0.5 * rho * wing.area * (czmax / stall_margin**2)))

    return vapp
コード例 #10
0
ファイル: mission.py プロジェクト: AdelTaiebTamacha/ACDC
def take_off(aircraft, kvs1g, altp, disa, mass, hld_conf):
    """
    Take off field length and climb path at 35 ft depending on stall margin (kVs1g)
    """

    wing = aircraft.wing
    propulsion = aircraft.propulsion

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

    czmax, cz_0 = craft_aero.high_lift(wing, hld_conf)

    rating = MTO

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

    [rho, sig] = earth.air_density(pamb, tamb)

    cz_to = czmax / kvs1g**2

    mach = flight.speed_from_lift(aircraft, pamb, cz_to, mass)

    nei = 0  # For Magic Line factor computation

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

    ml_factor = mass**2 / (cz_to * fn * wing.area * sig**0.8
                           )  # Magic Line factor

    tofl = 14.23 * ml_factor + 97.58

    nei = 1  # For 2nd segment computation
    speed_mode = 1
    speed = flight.get_speed(pamb, speed_mode, mach)

    seg2path, vz = flight.air_path(aircraft, nei, altp, disa, speed_mode,
                                   speed, mass, rating)

    return seg2path, tofl
コード例 #11
0
ファイル: mission.py プロジェクト: AdelTaiebTamacha/ACDC
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
コード例 #12
0
ファイル: demo2.py プロジェクト: AdelTaiebTamacha/ACDC
run.aircraft_pre_design(aircraft)

# Estimate all mass and CGs
#------------------------------------------------------------------------------------------------------
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")
コード例 #13
0
def eval_propulsion_design(aircraft):
    """
    Propulsion architecture design
    """

    propulsion = aircraft.propulsion

    propulsion.rating_code = (0, 1, 2, 3, 4)

    if (propulsion.architecture == 1):

        engine = aircraft.turbofan_engine

        eval_turbofan_engine_design(aircraft)
        eval_turbofan_nacelle_design(aircraft)

    elif (propulsion.architecture == 2):

        engine = aircraft.turbofan_engine

        eval_turbofan_engine_design(aircraft)
        eval_hybrid_engine_design(aircraft)
        eval_hybrid_nacelle_design(aircraft)

    elif (propulsion.architecture == 3):

        engine = aircraft.turbofan_engine

        eval_hybrid_turbofan_engine_design(aircraft)
        eval_hybrid_engine_design(aircraft)
        eval_hybrid_body_nacelle_design(aircraft)

    elif (propulsion.architecture == 4):

        engine = aircraft.turboprop_engine

        eval_turboprop_engine_design(aircraft)
        eval_turboprop_nacelle_design(aircraft)

    else:
        raise Exception("propulsion.architecture index is out of range")

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

    disa = 15.
    altp = 0.
    mach = 0.25
    nei = 0.

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

    (Fn, Data) = propu.thrust(aircraft, pamb, tamb, mach, MTO, nei)

    propulsion.reference_thrust_effective = (Fn / engine.n_engine) / 0.80
    propulsion.mto_thrust_ref = Fn / engine.n_engine

    disa = aircraft.low_speed.disa_oei
    altp = aircraft.low_speed.req_oei_altp
    mach = 0.5 * aircraft.design_driver.cruise_mach
    nei = 1.

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

    (Fn, Data) = propu.thrust(aircraft, pamb, tamb, mach, MCN, nei)

    propulsion.mcn_thrust_ref = Fn / (engine.n_engine - nei)

    disa = 0.
    altp = aircraft.design_driver.ref_cruise_altp
    mach = aircraft.design_driver.cruise_mach
    nei = 0.

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

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

    if (propulsion.architecture == 1):

        sec = 0.

    elif (propulsion.architecture == 2):

        fn, sec, data = propu.hybrid_thrust(aircraft, pamb, tamb, mach, MCR,
                                            nei)

    elif (propulsion.architecture == 3):

        fn, sec, data = propu.hybrid_thrust(aircraft, pamb, tamb, mach, MCR,
                                            nei)

    elif (propulsion.architecture == 4):

        sec = 0.

    else:
        raise Exception("propulsion.architecture index is out of range")

    propulsion.sec_cruise_ref = sec

    (Fn, Data) = propu.thrust(aircraft, pamb, tamb, mach, FID, nei)

    propulsion.fid_thrust_ref = Fn / engine.n_engine

    disa = 0.
    altp = aircraft.design_driver.top_of_climb_altp
    mach = aircraft.design_driver.cruise_mach
    nei = 0.

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

    (Fn, Data) = propu.thrust(aircraft, pamb, tamb, mach, MCL, nei)

    propulsion.mcl_thrust_ref = Fn / engine.n_engine

    (Fn, Data) = propu.thrust(aircraft, pamb, tamb, mach, MCR, nei)

    propulsion.mcr_thrust_ref = Fn / engine.n_engine

    return
コード例 #14
0
def eval_pre_design_wing(aircraft):
    """
    Wing predesign
    """

    design_driver = aircraft.design_driver
    fuselage = aircraft.fuselage
    vtp = aircraft.vertical_tail
    nacelle = aircraft.turbofan_nacelle
    weights = aircraft.weights

    wing = aircraft.wing

    wing.t_o_c_t = 0.10
    wing.t_o_c_k = wing.t_o_c_t + 0.01
    wing.t_o_c_r = wing.t_o_c_k + 0.03

    wing.sweep = 1.6 * max(0,
                           (design_driver.cruise_mach - 0.5))  # Empirical law

    wing.dihedral = unit.rad_deg(5)

    if (wing.morphing == 1):  # Aspect ratio is driving parameter
        wing.span = numpy.sqrt(wing.aspect_ratio * wing.area)
    elif (wing.morphing == 2):  # Span is driving parameter
        wing.aspect_ratio = wing.span**2 / wing.area
    else:
        print("geometry_predesign_, wing_morphing index is unkown")

    # Correlation between span loading and tapper ratio
    wing.taper_ratio = 0.3 - 0.025 * (1e-3 * weights.mtow / wing.span)

    # Factor 1.64 accounts for the part of HTP ref area hidden in the fuselage
    wing.net_wetted_area = 1.64 * wing.area

    wing.y_kink = nacelle.y_ext
    wing.y_root = 0.5 * fuselage.width
    wing.y_tip = 0.5 * wing.span

    if (15 < unit.deg_rad(wing.sweep)):  # With kink
        Phi100intTE = max(0, 2 * (wing.sweep - unit.rad_deg(32)))
        tan_phi100 = numpy.tan(Phi100intTE)
        A = ((1 - 0.25 * wing.taper_ratio) * wing.y_kink +
             0.25 * wing.taper_ratio * wing.y_root - wing.y_tip) / (
                 0.75 * wing.y_kink + 0.25 * wing.y_root - wing.y_tip)
        B = (numpy.tan(wing.sweep) - tan_phi100) * (
            (wing.y_tip - wing.y_kink) *
            (wing.y_kink - wing.y_root)) / (0.25 * wing.y_root +
                                            0.75 * wing.y_kink - wing.y_tip)
        wing.c_root = (wing.area - B * (wing.y_tip - wing.y_root)) / (
            wing.y_root + wing.y_kink + A *
            (wing.y_tip - wing.y_root) + wing.taper_ratio *
            (wing.y_tip - wing.y_kink))
        wing.c_kink = A * wing.c_root + B
        wing.c_tip = wing.taper_ratio * wing.c_root

    else:  # Without kink
        wing.c_root = 2 * wing.area / (
            2 * wing.y_root * (1 - wing.taper_ratio) +
            (1 + wing.taper_ratio) * numpy.sqrt(wing.aspect_ratio * wing.area))
        wing.c_tip = wing.taper_ratio * wing.c_root
        wing.c_kink = ((wing.y_tip - wing.y_kink) * wing.c_root +
                       (wing.y_kink - wing.y_root) * wing.c_tip) / (
                           wing.y_tip - wing.y_root)

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

    wing.mac = 2.*(3*wing.y_root*wing.c_root**2 \
            +(wing.y_kink-wing.y_root)*(wing.c_root**2+wing.c_kink**2+wing.c_root*wing.c_kink) \
            +(wing.y_tip-wing.y_kink)*(wing.c_kink**2+wing.c_tip**2+wing.c_kink*wing.c_tip) \
            )/(3*wing.area)

    wing.y_mac = ( 3*wing.c_root*wing.y_root**2 \
              +(wing.y_kink-wing.y_root)*(wing.c_kink*(wing.y_root+wing.y_kink*2.)+wing.c_root*(wing.y_kink+wing.y_root*2.)) \
              +(wing.y_tip-wing.y_kink)*(wing.c_tip*(wing.y_kink+wing.y_tip*2.)+wing.c_kink*(wing.y_tip+wing.y_kink*2.)) \
              )/(3*wing.area)

    x_mac_local = ( (wing.y_kink-wing.y_root)*tan_phi0*((wing.y_kink-wing.y_root)*(wing.c_kink*2.+wing.c_root) \
                   +(wing.y_tip-wing.y_kink)*(wing.c_kink*2.+wing.c_tip))+(wing.y_tip-wing.y_root)*tan_phi0*(wing.y_tip-wing.y_kink)*(wing.c_tip*2.+wing.c_kink) \
                  )/(3*wing.area)

    wing.x_root = vtp.x_mac + 0.25 * vtp.mac - vtp.lever_arm - 0.25 * wing.mac - x_mac_local

    wing.x_kink = wing.x_root + (wing.y_kink - wing.y_root) * tan_phi0
    wing.x_tip = wing.x_root + (wing.y_tip - wing.y_root) * tan_phi0

    wing.x_mac = wing.x_root+( (wing.x_kink-wing.x_root)*((wing.y_kink-wing.y_root)*(wing.c_kink*2.+wing.c_root) \
                        +(wing.y_tip-wing.y_kink)*(wing.c_kink*2.+wing.c_tip))+(wing.x_tip-wing.x_root)*(wing.y_tip-wing.y_kink)*(wing.c_tip*2.+wing.c_kink) \
                       )/(wing.area*3.)
    if (wing.attachment == 1):
        wing.z_root = 0
    else:
        wing.z_root = fuselage.height - 0.5 * wing.t_o_c_r * wing.c_root

    wing.z_kink = wing.z_root + (wing.y_kink - wing.y_root) * numpy.tan(
        wing.dihedral)
    wing.z_tip = wing.z_root + (wing.y_tip - wing.y_root) * numpy.tan(
        wing.dihedral)

    # Wing setting
    #-----------------------------------------------------------------------------------------------------------
    g = earth.gravity()
    gam = earth.heat_ratio()

    disa = 0
    rca = design_driver.ref_cruise_altp
    mach = design_driver.cruise_mach
    mass = 0.95 * weights.mtow

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

    cza_wo_htp = frame_aero.cza_wo_htp(mach, fuselage.width, wing.aspect_ratio,
                                       wing.span, wing.sweep)

    # AoA = 2.5° at cruise start
    wing.setting = (0.97 * mass * g) / (0.5 * gam * pamb * mach**2 * wing.area
                                        * cza_wo_htp) - unit.rad_deg(2.5)

    return
コード例 #15
0
ファイル: mission.py プロジェクト: AdelTaiebTamacha/ACDC
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
コード例 #16
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
コード例 #17
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
コード例 #18
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
コード例 #19
0
ファイル: design.py プロジェクト: AdelTaiebTamacha/ACDC
def performance_analysis(aircraft):
    """
    Compute operational performances
    """

    # Nominal mission (here : range is an output)
    #------------------------------------------------------------------------------------------------------
    disa = 0.
    altp = aircraft.design_driver.ref_cruise_altp
    mach = aircraft.design_driver.cruise_mach
    nei = 0.

    (MTO, MCN, MCL, MCR, FID) = aircraft.propulsion.rating_code
    pamb, tamb, tstd, dtodz = earth.atmosphere(altp, disa)
    lod_max, _ = craft_aero.lod_max(aircraft, pamb, tamb, mach)
    sfc = propu.sfc(aircraft, pamb, tamb, mach, MCR, nei)

    aircraft.high_speed.cruise_lod = lod_max
    aircraft.high_speed.cruise_sfc = sfc

    aircraft.nominal_mission.payload = aircraft.payload.nominal
    aircraft.nominal_mission.range = aircraft.design_driver.design_range
    aircraft.nominal_mission.tow = aircraft.weights.mtow

    payload = aircraft.nominal_mission.payload
    tow = aircraft.nominal_mission.tow

    range, block_fuel, block_time, total_fuel = sub_proc.mission_range(
        aircraft, tow, payload, altp, mach, disa)

    aircraft.nominal_mission.range = range

    aircraft.nominal_mission.block_fuel = block_fuel
    aircraft.nominal_mission.block_time = block_time
    aircraft.nominal_mission.total_fuel = total_fuel

    # Ceilings
    #------------------------------------------------------------------------------------------------------
    toc = aircraft.design_driver.top_of_climb_altp
    oei_ceil_req = aircraft.low_speed.req_oei_altp

    vz_clb, vz_crz, oei_path, oei_mach = perfo.ceilings(
        aircraft, toc, oei_ceil_req)

    aircraft.high_speed.eff_vz_climb = vz_clb
    aircraft.high_speed.eff_vz_cruise = vz_crz
    aircraft.low_speed.eff_oei_path = oei_path

    # Time to climb to requested altitude
    #------------------------------------------------------------------------------------------------------
    toc = aircraft.high_speed.req_toc_altp
    disa = 0
    mass = aircraft.weights.mtow
    vcas1 = aircraft.high_speed.cas1_ttc
    vcas2 = aircraft.high_speed.cas2_ttc
    mach = aircraft.design_driver.cruise_mach

    ttc = perfo.time_to_climb(aircraft, toc, disa, mass, vcas1, vcas2, mach)

    aircraft.high_speed.eff_ttc = ttc

    # Take off field length
    #------------------------------------------------------------------------------------------------------
    altp = aircraft.low_speed.altp_tofl
    disa = aircraft.low_speed.disa_tofl
    mass = aircraft.weights.mtow
    hld_conf_to = aircraft.aerodynamics.hld_conf_to

    tofl, seg2_path, eff_kvs1g, limitation = perfo.take_off_field_length(
        aircraft, altp, disa, mass, hld_conf_to)

    aircraft.low_speed.eff_tofl = tofl
    aircraft.low_speed.eff_kvs1g = eff_kvs1g
    aircraft.low_speed.seg2_path = seg2_path
    aircraft.low_speed.limitation = limitation

    # Approach speed
    #------------------------------------------------------------------------------------------------------
    altp = aircraft.low_speed.altp_app_speed
    disa = aircraft.low_speed.disa_app_speed
    mass = aircraft.weights.mlw
    hld_conf_ld = aircraft.aerodynamics.hld_conf_to

    app_speed = perfo.approach_speed(aircraft, altp, disa, mass, hld_conf_ld)

    aircraft.low_speed.eff_app_speed = app_speed

    # Environment
    #------------------------------------------------------------------------------------------------------
    CO2_metric, rgf = environ.fuel_efficiency_metric(aircraft)

    aircraft.environmental_impact.rgf = rgf
    aircraft.environmental_impact.CO2_metric = CO2_metric

    # Cost mission
    #-----------------------------------------------------------------------------------------------------------------------------------------------
    altp = aircraft.design_driver.ref_cruise_altp
    mach = aircraft.design_driver.cruise_mach

    disa = aircraft.cost_mission.disa
    range = aircraft.cost_mission.range

    payload = aircraft.payload.nominal

    aircraft.cost_mission.payload = payload

    tow, block_fuel, block_time, total_fuel = sub_proc.mission_tow(
        aircraft, payload, range, altp, mach, disa)

    aircraft.cost_mission.block_fuel = block_fuel
    aircraft.cost_mission.block_time = block_time
    aircraft.cost_mission.total_fuel = total_fuel

    aircraft.cost_mission.block_CO2 = block_fuel * aircraft.environmental_impact.CO2_index

    # Economics
    #------------------------------------------------------------------------------------------------------
    direct_op_cost, cash_op_cost, block_fuel, engine_price, airplane_price = costing.operating_costs(
        aircraft, block_fuel, block_time)

    aircraft.economics.engine_price = engine_price
    aircraft.economics.airplane_price = airplane_price

    aircraft.economics.direct_operating_cost = direct_op_cost
    aircraft.economics.cash_operating_cost = cash_op_cost

    return
コード例 #20
0
def vertical_tail_sizing(aircraft):
    """
    Computes necessary VTP area variation to meet engine failure case constraint
    Influence of CG position is ignored
    """

    design_driver = aircraft.design_driver
    propulsion = aircraft.propulsion
    wing = aircraft.wing
    vtp = aircraft.vertical_tail
    aerodynamics = aircraft.aerodynamics
    payload = aircraft.payload
    c_of_g = aircraft.center_of_gravity

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

    cyb_vtp, xlc_vtp, aoa_max_vtp, ki_vtp = frame_aero.vtp_aero_data(aircraft)

    payload = 0.5 * payload.nominal  # Light payload
    range = design_driver.design_range / 15  # Short mission
    altp = design_driver.ref_cruise_altp
    mach = design_driver.cruise_mach
    disa = 30  # Hot condition

    tow, block_fuel, block_time, total_fuel = sub_proc.mission_tow(
        aircraft, payload, range, altp, mach, disa)

    altp = 0
    disa = 15

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

    stall_margin = regul.kvs1g_min_take_off()

    czmax_to = aerodynamics.cz_max_to

    mach_s1g = flight.speed_from_lift(aircraft, pamb, czmax_to, tow)

    mach_35ft = stall_margin * mach_s1g  # V2 speed

    mach_mca = mach_35ft / 1.1  #Approximation of required VMCA

    altp = 0
    disa = 15

    nei = 1

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

    fn, data = propu.thrust(aircraft, pamb, tamb, mach_mca, MTO, nei)

    dcx_oei = propu.oei_drag(aircraft, pamb, tamb)

    cn_prop = propu.thrust_yaw_moment(aircraft, fn, pamb, mach_mca, dcx_oei)

    x_cg = c_of_g.max_bwd_req_cg

    cyb_vtp_req = (cn_prop * wing.mac) / ((xlc_vtp - x_cg) * aoa_max_vtp)

    k_vtp_area = cyb_vtp_req / cyb_vtp

    d_vtp_area = (k_vtp_area - 1) * vtp.area

    return d_vtp_area