def estimate_2ndseg_lift_drag_ratio(config):
    """Estimates the 2nd segment climb lift to drag ratio (all engine operating)
    
    Assumptions:
    All engines operating

    Source:
    Fig. 27.34 of "Aerodynamic Design of Transport Airplane" - Obert

    Inputs:
    config.
      V2_VS_ratio              [Unitless]
      wings.
        areas.reference        [m^2]
	spans.projected        [m]
	aspect_ratio           [Unitless]
      maximum_lift_coefficient [Unitless]

    Outputs:
    lift_drag_ratio            [Unitless]

    Properties Used:
    N/A
    """
    # ==============================================
	# Unpack
    # ==============================================
    try:
        V2_VS_ratio    = config.V2_VS_ratio
    except:
        V2_VS_ratio    = 1.20 # typical condition

    # getting geometrical data (aspect ratio)
    n_wing = 0
    for wing in config.wings:
        if not isinstance(wing,Wings.Main_Wing): continue
        reference_area = wing.areas.reference
        wing_span      = wing.spans.projected
        try:
            aspect_ratio = wing.aspect_ratio
        except:
            aspect_ratio = wing_span ** 2 / reference_area
        n_wing += 1

    if n_wing > 1:
        print(' More than one Main_Wing in the config. Last one will be considered.')
    elif n_wing == 0:
        print('No Main_Wing defined! Using the 1st wing found')
        for wing in config.wings:
            if not isinstance(wing,Wings.Wing): continue
            reference_area = wing.areas.reference
            wing_span      = wing.spans.projected
            try:
                aspect_ratio = wing.aspect_ratio
            except:
                aspect_ratio = wing_span ** 2 / reference_area
            break


    # Determining vehicle maximum lift coefficient
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = config.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions = Data()
        conditions.freestream = Data()
        conditions.freestream.density           = 0.90477283
        conditions.freestream.dynamic_viscosity = 1.69220918e-05
        conditions.freestream.velocity          = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(config,conditions)
            config.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError("Maximum lift coefficient calculation error. Please, check inputs")

    # Compute CL in V2
    lift_coeff = maximum_lift_coefficient / (V2_VS_ratio ** 2)

    # Estimate L/D in 2nd segment condition, ALL ENGINES OPERATIVE!
    lift_drag_ratio = -6.464 * lift_coeff + 7.264 * aspect_ratio ** 0.5

    return lift_drag_ratio
def estimate_take_off_field_length(vehicle,analyses,airport,compute_2nd_seg_climb = 0):
    """ Computes the takeoff field length for a given vehicle configuration in a given airport.
    Also optionally computes the second segment climb gradient.

    Assumptions:
    For second segment climb gradient:
    One engine inoperative
    Only validated for two engine aircraft

    Source:
    http://adg.stanford.edu/aa241/AircraftDesign.html

    Inputs:
    analyses.base.atmosphere               [SUAVE data type]
    airport.
      altitude                             [m]
      delta_isa                            [K]
    vehicle.
      mass_properties.takeoff              [kg]
      reference_area                       [m^2]
      V2_VS_ratio (optional)               [Unitless]
      maximum_lift_coefficient (optional)  [Unitless]
      propulsors.*.number_of_engines       [Unitless]

    Outputs:
    takeoff_field_length                   [m]

    Properties Used:
    N/A
    """        

    # ==============================================
        # Unpack
    # ==============================================
    atmo            = analyses.base.atmosphere
    altitude        = airport.altitude * Units.ft
    delta_isa       = airport.delta_isa
    weight          = vehicle.mass_properties.takeoff
    reference_area  = vehicle.reference_area
    try:
        V2_VS_ratio = vehicle.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    atmo_values       = atmo.compute_values(altitude,delta_isa)
    conditions        = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
    
    p   = atmo_values.pressure
    T   = atmo_values.temperature
    rho = atmo_values.density
    a   = atmo_values.speed_of_sound
    mu  = atmo_values.dynamic_viscosity
    sea_level_gravity = atmo.planet.sea_level_gravity
    
    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions  = atmo.compute_values(10000. * Units.ft)
        conditions.freestream=Data()
        conditions.freestream.density   = conditions.density
        conditions.freestream.dynamic_viscosity = conditions.dynamic_viscosity
        conditions.freestream.velocity  = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(vehicle,conditions)
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, V2, 0.7*V2)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity / (rho * reference_area * maximum_lift_coefficient)) ** 0.5
    V2_speed    = V2_VS_ratio * stall_speed
    speed_for_thrust  = 0.70 * V2_speed

    # ==============================================
    # Determining vehicle number of engines
    # ==============================================
    engine_number = 0.
    for propulsor in vehicle.propulsors : # may have than one propulsor
        engine_number += propulsor.number_of_engines
    if engine_number == 0:
        raise ValueError, "No engine found in the vehicle"

    # ==============================================
    # Getting engine thrust
    # ==============================================    
    state = Data()
    state.conditions = Aerodynamics() 
    state.numerics   = Numerics()
    conditions = state.conditions    

    conditions.freestream.dynamic_pressure = np.array(np.atleast_1d(0.5 * rho * speed_for_thrust**2))
    conditions.freestream.gravity          = np.array([np.atleast_1d(sea_level_gravity)])
    conditions.freestream.velocity         = np.array(np.atleast_1d(speed_for_thrust))
    conditions.freestream.mach_number      = np.array(np.atleast_1d(speed_for_thrust/ a))
    conditions.freestream.speed_of_sound   = np.array(a)
    conditions.freestream.temperature      = np.array(np.atleast_1d(T))
    conditions.freestream.pressure         = np.array(np.atleast_1d(p))
    conditions.propulsion.throttle         = np.array(np.atleast_1d(1.))
    
    results = vehicle.propulsors.evaluate_thrust(state) # total thrust
    
    thrust = results.thrust_force_vector

    # ==============================================
    # Calculate takeoff distance
    # ==============================================

    # Defining takeoff distance equations coefficients
    try:
        takeoff_constants = vehicle.takeoff_constants # user defined
    except:  # default values
        takeoff_constants = np.zeros(3)
        if engine_number == 2:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] =   2.476
            takeoff_constants[2] =   0.00014
        elif engine_number == 3:
            takeoff_constants[0] = 667.9
            takeoff_constants[1] =   2.343
            takeoff_constants[2] =   0.000093
        elif engine_number == 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] =   2.282
            takeoff_constants[2] =   0.0000705
        elif engine_number >  4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] =   2.282
            takeoff_constants[2] =   0.0000705
            print 'The vehicle has more than 4 engines. Using 4 engine correlation. Result may not be correct.'
        else:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] =   2.476
            takeoff_constants[2] =   0.00014
            print 'Incorrect number of engines: {0:.1f}. Using twin engine correlation.'.format(engine_number)

    # Define takeoff index   (V2^2 / (T/W)
    takeoff_index = V2_speed**2. / (thrust[0][0] / weight)
    # Calculating takeoff field length
    takeoff_field_length = 0.
    for idx,constant in enumerate(takeoff_constants):
        takeoff_field_length += constant * takeoff_index**idx
    takeoff_field_length = takeoff_field_length * Units.ft
    
    # calculating second segment climb gradient, if required by user input
    if compute_2nd_seg_climb:
        # Getting engine thrust at V2 (update only speed related conditions)
        state.conditions.freestream.dynamic_pressure = np.array(np.atleast_1d(0.5 * rho * V2_speed**2))
        state.conditions.freestream.velocity         = np.array(np.atleast_1d(V2_speed))
        state.conditions.freestream.mach_number      = np.array(np.atleast_1d(V2_speed/ a))
        results = vehicle.propulsors['turbofan'].engine_out(state)
        thrust = results.thrust_force_vector[0][0]

        # Compute windmilling drag
        windmilling_drag_coefficient = windmilling_drag(vehicle,state)

        # Compute asymmetry drag   
        asymmetry_drag_coefficient = asymmetry_drag(state, vehicle, windmilling_drag_coefficient)
           
        # Compute l over d ratio for takeoff condition, NO engine failure
        l_over_d = estimate_2ndseg_lift_drag_ratio(vehicle) 
        
        # Compute L over D ratio for takeoff condition, WITH engine failure
        clv2 = maximum_lift_coefficient / (V2_VS_ratio) **2
        cdv2_all_engine = clv2 / l_over_d
        cdv2 = cdv2_all_engine + asymmetry_drag_coefficient + windmilling_drag_coefficient
        l_over_d_v2 = clv2 / cdv2
    
        # Compute 2nd segment climb gradient
        second_seg_climb_gradient = thrust / (weight*sea_level_gravity) - 1. / l_over_d_v2
        
        return takeoff_field_length, second_seg_climb_gradient
    
    else:
        # return only takeoff_field_length
        return takeoff_field_length
示例#3
0
def estimate_landing_field_length(vehicle, analyses, airport):
    """ Computes the landing field length for a given vehicle configuration in a given airport.

    Assumptions:
    See source
    Two wheel trucks (code needed for four wheel trucks also included)

    Source:
    Torenbeek, E., "Advanced Aircraft Design", 2013 (equation 9.25)

    Inputs:
    airport.
      atmosphere                           [SUAVE data type]
      altitude                             [m]
      delta_isa                            [K]
    vehicle.
      mass_properties.landing              [kg]
      reference_area                       [m^2]
      maximum_lift_coefficient (optional)  [Unitless]

    Outputs:
    landing_field_length                   [m]

    Properties Used:
    N/A
    """

    # ==============================================
    # Unpack
    # ==============================================
    atmo = airport.atmosphere
    altitude = airport.altitude * Units.ft
    delta_isa = airport.delta_isa
    weight = vehicle.mass_properties.landing
    reference_area = vehicle.reference_area
    try:
        Vref_VS_ratio = vehicle.Vref_VS_ratio
    except:
        Vref_VS_ratio = 1.23

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    atmo_values = atmo.compute_values(altitude, delta_isa)

    p = atmo_values.pressure
    T = atmo_values.temperature
    rho = atmo_values.density
    a = atmo_values.speed_of_sound
    mu = atmo_values.dynamic_viscosity
    sea_level_gravity = atmo.planet.sea_level_gravity

    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    # Condition to CLmax calculation: 90KTAS @ airport
    state = Data()
    state.conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics(
    )
    state.conditions.freestream = Data()
    state.conditions.freestream.density = rho
    state.conditions.freestream.velocity = 90. * Units.knots
    state.conditions.freestream.dynamic_viscosity = mu

    settings = analyses.aerodynamics.settings

    maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(
        state, settings, vehicle)

    # ==============================================
    # Computing speeds (Vs, Vref)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity /
                   (rho * reference_area * maximum_lift_coefficient))**0.5
    Vref = stall_speed * Vref_VS_ratio

    # ========================================================================================
    # Computing landing distance, according to Torenbeek equation
    #     Landing Field Length = k1 + k2 * Vref**2
    # ========================================================================================

    # Defining landing distance equation coefficients
    try:
        landing_constants = config.landing_constants  # user defined
    except:  # default values - According to Torenbeek book
        landing_constants = np.zeros(3)
        landing_constants[0] = 250.
        landing_constants[1] = 0.
        landing_constants[
            2] = 2.485 / sea_level_gravity  # Two-wheels truck : [ (1.56 / 0.40 + 1.07) / (2*sea_level_gravity) ]
        #landing_constants[2] =   2.9725 / sea_level_gravity  # Four-wheels truck: [ (1.56 / 0.32 + 1.07) / (2*sea_level_gravity) ]
    # Calculating landing field length
    landing_field_length = 0.
    for idx, constant in enumerate(landing_constants):
        landing_field_length += constant * Vref**idx

    # return
    return landing_field_length
def estimate_landing_field_length(vehicle,config,airport):
    """ SUAVE.Methods.Performance.estimate_landing_field_length(vehicle,config,airport):
        Computes the landing field length for a given vehicle condition in a given airport

        Inputs:
            vehicle	 - SUAVE type vehicle

            config   - data dictionary with fields:
                Mass_Properties.landing    - Landing weight to be evaluated
                S                          - Wing Area
                Vref_VS_ratio              - Ratio between Approach Speed and Stall speed
                                             [optional. Default value = 1.23]
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [optional. Calculated if not informed]

    airport   - SUAVE type airport data, with followig fields:
                atmosphere                  - Airport atmosphere (SUAVE type)
                altitude                    - Airport altitude
                delta_isa                   - ISA Temperature deviation


        Outputs:
            landing_field_length            - Landing field length


        Assumptions:
      		- Landing field length calculated according to Torenbeek, E., "Advanced
    Aircraft Design", 2013 (equation 9.25)
            - Considering average aav/g values of two-wheel truck (0.40)
    """

    # ==============================================
        # Unpack
    # ==============================================
    atmo            = airport.atmosphere
    altitude        = airport.altitude * Units.ft
    delta_isa       = airport.delta_isa
    weight          = config.mass_properties.landing
    reference_area  = config.reference_area
    try:
        Vref_VS_ratio = config.Vref_VS_ratio
    except:
        Vref_VS_ratio = 1.23

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    p0, T0, rho0, a0, mu0 = atmo.compute_values(0)
    p , T , rho , a , mu  = atmo.compute_values(altitude)
    T_delta_ISA = T + delta_isa
    sigma_disa = (p/p0) / (T_delta_ISA/T0)
    rho = rho0 * sigma_disa
    a_delta_ISA = atmo.fluid_properties.compute_speed_of_sound(T_delta_ISA)
    mu = 1.78938028e-05 * ((T0 + 120) / T0 ** 1.5) * ((T_delta_ISA ** 1.5) / (T_delta_ISA + 120))
    sea_level_gravity = atmo.planet.sea_level_gravity

    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = config.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        p_stall , T_stall , rho_stall , a_stall , mu_stall  = atmo.compute_values(10000. * Units.ft)
        conditions                      = Data()
        conditions.freestream           = Data()
        conditions.freestream.density   = rho_stall
        conditions.freestream.viscosity = mu_stall
        conditions.freestream.velocity  = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(config,conditions)
            config.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, Vref)
    # ==============================================
    stall_speed  = (2 * weight * sea_level_gravity / (rho * reference_area * maximum_lift_coefficient)) ** 0.5
    Vref         = stall_speed * Vref_VS_ratio

    # ========================================================================================
    # Computing landing distance, according to Torenbeek equation
    #     Landing Field Length = k1 + k2 * Vref**2
    # ========================================================================================

    # Defining landing distance equation coefficients
    try:
        landing_constants = config.landing_constants # user defined
    except:  # default values - According to Torenbeek book
        landing_constants = np.zeros(3)
        landing_constants[0] = 250.
        landing_constants[1] =   0.
        landing_constants[2] =   2.485  / sea_level_gravity  # Two-wheels truck : [ (1.56 / 0.40 + 1.07) / (2*sea_level_gravity) ]
##        landing_constants[2] =   2.9725 / sea_level_gravity  # Four-wheels truck: [ (1.56 / 0.32 + 1.07) / (2*sea_level_gravity) ]

    # Calculating landing field length
    landing_field_length = 0.
    for idx,constant in enumerate(landing_constants):
        landing_field_length += constant * Vref**idx

    # return
    return landing_field_length
示例#5
0
def estimate_landing_field_length(vehicle, analyses, airport):
    """ SUAVE.Methods.Performance.estimate_landing_field_length(vehicle,config,airport):
        Computes the landing field length for a given vehicle condition in a given airport

        Inputs:
            vehicle	 - SUAVE type vehicle

            config   - data dictionary with fields:
                Mass_Properties.landing    - Landing weight to be evaluated
                S                          - Wing Area
                Vref_VS_ratio              - Ratio between Approach Speed and Stall speed
                                             [optional. Default value = 1.23]
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [optional. Calculated if not informed]

    airport   - SUAVE type airport data, with followig fields:
                atmosphere                  - Airport atmosphere (SUAVE type)
                altitude                    - Airport altitude
                delta_isa                   - ISA Temperature deviation


        Outputs:
            landing_field_length            - Landing field length


        Assumptions:
      		- Landing field length calculated according to Torenbeek, E., "Advanced
    Aircraft Design", 2013 (equation 9.25)
            - Considering average aav/g values of two-wheel truck (0.40)
    """

    # ==============================================
    # Unpack
    # ==============================================
    atmo = airport.atmosphere
    altitude = airport.altitude * Units.ft
    delta_isa = airport.delta_isa
    weight = vehicle.mass_properties.landing
    reference_area = vehicle.reference_area
    try:
        Vref_VS_ratio = config.Vref_VS_ratio
    except:
        Vref_VS_ratio = 1.23

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    atmo_values = atmo.compute_values(altitude, delta_isa)
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()

    p = atmo_values.pressure
    T = atmo_values.temperature
    rho = atmo_values.density
    a = atmo_values.speed_of_sound
    mu = atmo_values.dynamic_viscosity
    sea_level_gravity = atmo.planet.sea_level_gravity

    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================

    try:  # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        conditions.freestream = Data()
        conditions.freestream.density = rho
        conditions.freestream.dynamic_viscosity = mu
        conditions.freestream.velocity = 90. * Units.knots

        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(
                vehicle, conditions)
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient

        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, Vref)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity /
                   (rho * reference_area * maximum_lift_coefficient))**0.5
    Vref = stall_speed * Vref_VS_ratio

    # ========================================================================================
    # Computing landing distance, according to Torenbeek equation
    #     Landing Field Length = k1 + k2 * Vref**2
    # ========================================================================================

    # Defining landing distance equation coefficients
    try:
        landing_constants = config.landing_constants  # user defined
    except:  # default values - According to Torenbeek book
        landing_constants = np.zeros(3)
        landing_constants[0] = 250.
        landing_constants[1] = 0.
        landing_constants[
            2] = 2.485 / sea_level_gravity  # Two-wheels truck : [ (1.56 / 0.40 + 1.07) / (2*sea_level_gravity) ]
##        landing_constants[2] =   2.9725 / sea_level_gravity  # Four-wheels truck: [ (1.56 / 0.32 + 1.07) / (2*sea_level_gravity) ]

# Calculating landing field length
    landing_field_length = 0.
    for idx, constant in enumerate(landing_constants):
        landing_field_length += constant * Vref**idx

    # return
    return landing_field_length
def estimate_2ndseg_lift_drag_ratio(config):
    """Estimates the 2nd segment climb lift to drag ratio (all engine operating)
    
    Assumptions:
    All engines operating

    Source:
    Fig. 27.34 of "Aerodynamic Design of Transport Airplane" - Obert

    Inputs:
    config.
      V2_VS_ratio              [Unitless]
      wings.
        areas.reference        [m^2]
	spans.projected        [m]
	aspect_ratio           [Unitless]
      maximum_lift_coefficient [Unitless]

    Outputs:
    lift_drag_ratio            [Unitless]

    Properties Used:
    N/A
    """
    # ==============================================
	# Unpack
    # ==============================================
    try:
        V2_VS_ratio    = config.V2_VS_ratio
    except:
        V2_VS_ratio    = 1.20 # typical condition

    # getting geometrical data (aspect ratio)
    n_wing = 0
    for wing in config.wings:
        if not isinstance(wing,Wings.Main_Wing): continue
        reference_area = wing.areas.reference
        wing_span      = wing.spans.projected
        try:
            aspect_ratio = wing.aspect_ratio
        except:
            aspect_ratio = wing_span ** 2 / reference_area
        n_wing += 1

    if n_wing > 1:
        print ' More than one Main_Wing in the config. Last one will be considered.'
    elif n_wing == 0:
        print  'No Main_Wing defined! Using the 1st wing found'
        for wing in config.wings:
            if not isinstance(wing,Wings.Wing): continue
            reference_area = wing.areas.reference
            wing_span      = wing.spans.projected
            try:
                aspect_ratio = wing.aspect_ratio
            except:
                aspect_ratio = wing_span ** 2 / reference_area
            break


    # Determining vehicle maximum lift coefficient
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = config.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions = Data()
        conditions.freestream = Data()
        conditions.freestream.density           = 0.90477283
        conditions.freestream.dynamic_viscosity = 1.69220918e-05
        conditions.freestream.velocity          = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(config,conditions)
            config.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # Compute CL in V2
    lift_coeff = maximum_lift_coefficient / (V2_VS_ratio ** 2)

    # Estimate L/D in 2nd segment condition, ALL ENGINES OPERATIVE!
    lift_drag_ratio = -6.464 * lift_coeff + 7.264 * aspect_ratio ** 0.5

    return lift_drag_ratio
示例#7
0
def estimate_take_off_field_length(vehicle,
                                   analyses,
                                   airport,
                                   compute_2nd_seg_climb=0):
    """ Computes the takeoff field length for a given vehicle configuration in a given airport.
    Also optionally computes the second segment climb gradient.

    Assumptions:
    For second segment climb gradient:
    One engine inoperative
    Only validated for two engine aircraft

    Source:
    http://adg.stanford.edu/aa241/AircraftDesign.html

    Inputs:
    analyses.base.atmosphere               [SUAVE data type]
    airport.
      altitude                             [m]
      delta_isa                            [K]
    vehicle.
      mass_properties.takeoff              [kg]
      reference_area                       [m^2]
      V2_VS_ratio (optional)               [Unitless]
      maximum_lift_coefficient (optional)  [Unitless]
      propulsors.*.number_of_engines       [Unitless]

    Outputs:
    takeoff_field_length                   [m]

    Properties Used:
    N/A
    """

    # ==============================================
    # Unpack
    # ==============================================
    atmo = analyses.base.atmosphere
    altitude = airport.altitude * Units.ft
    delta_isa = airport.delta_isa
    weight = vehicle.mass_properties.takeoff
    reference_area = vehicle.reference_area
    try:
        V2_VS_ratio = vehicle.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    atmo_values = atmo.compute_values(altitude, delta_isa)
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()

    p = atmo_values.pressure
    T = atmo_values.temperature
    rho = atmo_values.density
    a = atmo_values.speed_of_sound
    mu = atmo_values.dynamic_viscosity
    sea_level_gravity = atmo.planet.sea_level_gravity

    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    try:  # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions = atmo.compute_values(10000. * Units.ft)
        conditions.freestream = Data()
        conditions.freestream.density = conditions.density
        conditions.freestream.dynamic_viscosity = conditions.dynamic_viscosity
        conditions.freestream.velocity = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(
                vehicle, conditions)
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, V2, 0.7*V2)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity /
                   (rho * reference_area * maximum_lift_coefficient))**0.5
    V2_speed = V2_VS_ratio * stall_speed
    speed_for_thrust = 0.70 * V2_speed

    # ==============================================
    # Determining vehicle number of engines
    # ==============================================
    engine_number = 0.
    for propulsor in vehicle.propulsors:  # may have than one propulsor
        engine_number += propulsor.number_of_engines
    if engine_number == 0:
        raise ValueError, "No engine found in the vehicle"

    # ==============================================
    # Getting engine thrust
    # ==============================================
    state = Data()
    state.conditions = Aerodynamics()
    state.numerics = Numerics()
    conditions = state.conditions

    conditions.freestream.dynamic_pressure = np.array(
        np.atleast_1d(0.5 * rho * speed_for_thrust**2))
    conditions.freestream.gravity = np.array(
        [np.atleast_1d(sea_level_gravity)])
    conditions.freestream.velocity = np.array(np.atleast_1d(speed_for_thrust))
    conditions.freestream.mach_number = np.array(
        np.atleast_1d(speed_for_thrust / a))
    conditions.freestream.temperature = np.array(np.atleast_1d(T))
    conditions.freestream.pressure = np.array(np.atleast_1d(p))
    conditions.propulsion.throttle = np.array(np.atleast_1d(1.))

    results = vehicle.propulsors.evaluate_thrust(state)  # total thrust

    thrust = results.thrust_force_vector

    # ==============================================
    # Calculate takeoff distance
    # ==============================================

    # Defining takeoff distance equations coefficients
    try:
        takeoff_constants = vehicle.takeoff_constants  # user defined
    except:  # default values
        takeoff_constants = np.zeros(3)
        if engine_number == 2:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] = 2.476
            takeoff_constants[2] = 0.00014
        elif engine_number == 3:
            takeoff_constants[0] = 667.9
            takeoff_constants[1] = 2.343
            takeoff_constants[2] = 0.000093
        elif engine_number == 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] = 2.282
            takeoff_constants[2] = 0.0000705
        elif engine_number > 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] = 2.282
            takeoff_constants[2] = 0.0000705
            print 'The vehicle has more than 4 engines. Using 4 engine correlation. Result may not be correct.'
        else:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] = 2.476
            takeoff_constants[2] = 0.00014
            print 'Incorrect number of engines: {0:.1f}. Using twin engine correlation.'.format(
                engine_number)

    # Define takeoff index   (V2^2 / (T/W)
    takeoff_index = V2_speed**2. / (thrust[0][0] / weight)
    # Calculating takeoff field length
    takeoff_field_length = 0.
    for idx, constant in enumerate(takeoff_constants):
        takeoff_field_length += constant * takeoff_index**idx
    takeoff_field_length = takeoff_field_length * Units.ft

    # calculating second segment climb gradient, if required by user input
    if compute_2nd_seg_climb:
        # Getting engine thrust at V2 (update only speed related conditions)
        state.conditions.freestream.dynamic_pressure = np.array(
            np.atleast_1d(0.5 * rho * V2_speed**2))
        state.conditions.freestream.velocity = np.array(
            np.atleast_1d(V2_speed))
        state.conditions.freestream.mach_number = np.array(
            np.atleast_1d(V2_speed / a))
        results = vehicle.propulsors['turbofan'].engine_out(state)
        thrust = results.thrust_force_vector[0][0]

        # Compute windmilling drag
        windmilling_drag_coefficient = windmilling_drag(vehicle, state)

        # Compute asymmetry drag
        asymmetry_drag_coefficient = asymmetry_drag(
            state, vehicle, windmilling_drag_coefficient)

        # Compute l over d ratio for takeoff condition, NO engine failure
        l_over_d = estimate_2ndseg_lift_drag_ratio(vehicle)

        # Compute L over D ratio for takeoff condition, WITH engine failure
        clv2 = maximum_lift_coefficient / (V2_VS_ratio)**2
        cdv2_all_engine = clv2 / l_over_d
        cdv2 = cdv2_all_engine + asymmetry_drag_coefficient + windmilling_drag_coefficient
        l_over_d_v2 = clv2 / cdv2

        # Compute 2nd segment climb gradient
        second_seg_climb_gradient = thrust / (
            weight * sea_level_gravity) - 1. / l_over_d_v2

        return takeoff_field_length, second_seg_climb_gradient

    else:
        # return only takeoff_field_length
        return takeoff_field_length
示例#8
0
def estimate_2ndseg_lift_drag_ratio(config):
    """ SUAVE.Methods.Aerodynamics.Drag.Correlations.estimate_2ndseg_lift_drag_ratio(config):
        Estimates the 2nd segment Lift to drag ration (all engine operating)
        Inputs:
            config   - data dictionary with fields:
                reference_area             - Airplane reference area
                V2_VS_ratio                - Ratio between V2 and Stall speed
                                             [optional. Default value = 1.20]
                Main_Wing.aspect_ratio     - Main_Wing aspect ratio
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [Calculated if not informed]

        Outputs:
            takeoff_field_length            - Takeoff field length

        Assumptions:
            All engines Operating. Must be corrected for second segment climb configuration
            reference: Fig. 27.34 of "Aerodynamic Design of Transport Airplane" - Obert

"""
    # ==============================================
    # Unpack
    # ==============================================
    try:
        V2_VS_ratio = config.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20  # typical condition

    # getting geometrical data (aspect ratio)
    n_wing = 0
    for wing in config.wings:
        if not isinstance(wing, Wings.Main_Wing): continue
        reference_area = wing.areas.reference
        wing_span = wing.spans.projected
        try:
            aspect_ratio = wing.aspect_ratio
        except:
            aspect_ratio = wing_span**2 / reference_area
        n_wing += 1

    if n_wing > 1:
        print ' More than one Main_Wing in the config. Last one will be considered.'
    elif n_wing == 0:
        print 'No Main_Wing defined! Using the 1st wing found'
        for wing in config.wings:
            if not isinstance(wing, Wings.Wing): continue
            reference_area = wing.areas.reference
            wing_span = wing.spans.projected
            try:
                aspect_ratio = wing.aspect_ratio
            except:
                aspect_ratio = wing_span**2 / reference_area
            break

    # Determining vehicle maximum lift coefficient
    try:  # aircraft maximum lift informed by user
        maximum_lift_coefficient = config.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions = Data()
        conditions.freestream = Data()
        conditions.freestream.density = 0.90477283
        conditions.freestream.dynamic_viscosity = 1.69220918e-05
        conditions.freestream.velocity = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(
                config, conditions)
            config.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # Compute CL in V2
    lift_coeff = maximum_lift_coefficient / (V2_VS_ratio**2)

    # Estimate L/D in 2nd segment condition, ALL ENGINES OPERATIVE!
    lift_drag_ratio = -6.464 * lift_coeff + 7.264 * aspect_ratio**0.5

    return lift_drag_ratio
示例#9
0
def estimate_take_off_field_length(vehicle,analyses,airport,compute_2nd_seg_climb = 0):
    """ SUAVE.Methods.Performance.estimate_take_off_field_length(vehicle,analyses,airport,compute_2nd_seg_climb = 0):
        Computes the takeoff field length for a given vehicle condition in a given airport, and
        allow user to compute 2nd segment climb gradient

        Inputs:
            vehicle	 - SUAVE type vehicle, with following fields:
                mass_properties.takeoff    - Takeoff weight to be evaluated
                vehicle.reference_area     - Airplane reference area
                V2_VS_ratio                - Ratio between V2 and Stall speed
                                             [optional. Default value = 1.20]
                takeoff_constants          - Coefficients for takeoff field length equation
                                             [optional. Default values: AA241 method]
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [Calculated if not informed]

            analyses  - SUAVE analyses type data structure, with the following fields:
                analyses.base.atmosphere   - Atmosphere to be used for calculation
                 
                
            airport   - SUAVE type airport data, with followig fields:
                atmosphere                  - Airport atmosphere (SUAVE type)
                altitude                    - Airport altitude
                delta_isa                   - ISA Temperature deviation

            compute_2nd_seg_climb   - Flag to define if second segment climb gradient
                                      should be calculated
                                      
        Outputs:
            takeoff_field_length            - Takeoff field length
            second_seg_climb_gradient       - Second Segment Climb gradient [ optional]

        Assumptions:
            Correlation based.
            Second segment climb gradient:
                - Considers ONE engine inoperative, for any number of engines.
                - Valid for twin engine airplane - NOT VALIDATED/VERIFICATED WITH 3 OR MORE ENGINES.
    """

    # ==============================================
        # Unpack
    # ==============================================
    atmo            = analyses.base.atmosphere
    altitude        = airport.altitude * Units.ft
    delta_isa       = airport.delta_isa
    weight          = vehicle.mass_properties.takeoff
    reference_area  = vehicle.reference_area
    try:
        V2_VS_ratio = vehicle.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    atmo_values       = atmo.compute_values(altitude,delta_isa)
    conditions        = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
    
    p   = atmo_values.pressure
    T   = atmo_values.temperature
    rho = atmo_values.density
    a   = atmo_values.speed_of_sound
    mu  = atmo_values.dynamic_viscosity
    sea_level_gravity = atmo.planet.sea_level_gravity
    
    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions  = atmo.compute_values(10000. * Units.ft)
        conditions.freestream=Data()
        conditions.freestream.density   = conditions.density
        conditions.freestream.dynamic_viscosity = conditions.dynamic_viscosity
        conditions.freestream.velocity  = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(vehicle,conditions)
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, V2, 0.7*V2)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity / (rho * reference_area * maximum_lift_coefficient)) ** 0.5
    V2_speed    = V2_VS_ratio * stall_speed
    speed_for_thrust  = 0.70 * V2_speed

    # ==============================================
    # Determining vehicle number of engines
    # ==============================================
    engine_number = 0.
    for propulsor in vehicle.propulsors : # may have than one propulsor
        engine_number += propulsor.number_of_engines
    if engine_number == 0:
        raise ValueError, "No engine found in the vehicle"

    # ==============================================
    # Getting engine thrust
    # ==============================================    
    state = Data()
    state.conditions = Aerodynamics() 
    state.numerics   = Numerics()
    conditions = state.conditions    

    conditions.freestream.dynamic_pressure = np.array(np.atleast_1d(0.5 * rho * speed_for_thrust**2))
    conditions.freestream.gravity          = np.array([np.atleast_1d(sea_level_gravity)])
    conditions.freestream.velocity         = np.array(np.atleast_1d(speed_for_thrust))
    conditions.freestream.mach_number      = np.array(np.atleast_1d(speed_for_thrust/ a))
    conditions.freestream.temperature      = np.array(np.atleast_1d(T))
    conditions.freestream.pressure         = np.array(np.atleast_1d(p))
    conditions.propulsion.throttle         = np.array(np.atleast_1d(1.))
    
    results = vehicle.propulsors.evaluate_thrust(state) # total thrust
    
    thrust = results.thrust_force_vector

    # ==============================================
    # Calculate takeoff distance
    # ==============================================

    # Defining takeoff distance equations coefficients
    try:
        takeoff_constants = vehicle.takeoff_constants # user defined
    except:  # default values
        takeoff_constants = np.zeros(3)
        if engine_number == 2:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] =   2.476
            takeoff_constants[2] =   0.00014
        elif engine_number == 3:
            takeoff_constants[0] = 667.9
            takeoff_constants[1] =   2.343
            takeoff_constants[2] =   0.000093
        elif engine_number == 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] =   2.282
            takeoff_constants[2] =   0.0000705
        elif engine_number >  4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] =   2.282
            takeoff_constants[2] =   0.0000705
            print 'The vehicle has more than 4 engines. Using 4 engine correlation. Result may not be correct.'
        else:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] =   2.476
            takeoff_constants[2] =   0.00014
            print 'Incorrect number of engines: {0:.1f}. Using twin engine correlation.'.format(engine_number)

    # Define takeoff index   (V2^2 / (T/W)
    takeoff_index = V2_speed**2. / (thrust[0][0] / weight)
    # Calculating takeoff field length
    takeoff_field_length = 0.
    for idx,constant in enumerate(takeoff_constants):
        takeoff_field_length += constant * takeoff_index**idx
    takeoff_field_length = takeoff_field_length * Units.ft
    
    # calculating second segment climb gradient, if required by user input
    if compute_2nd_seg_climb:
        # Getting engine thrust at V2 (update only speed related conditions)
        state.conditions.freestream.dynamic_pressure = np.array(np.atleast_1d(0.5 * rho * V2_speed**2))
        state.conditions.freestream.velocity         = np.array(np.atleast_1d(V2_speed))
        state.conditions.freestream.mach_number      = np.array(np.atleast_1d(V2_speed/ a))
        results = vehicle.propulsors[0].engine_out(state)
        thrust = results.thrust_force_vector[0][0]

        # Compute windmilling drag
        windmilling_drag_coefficient = windmilling_drag(vehicle,state)

        # Compute asymmetry drag   
        asymmetry_drag_coefficient = asymmetry_drag(state, vehicle, windmilling_drag_coefficient)
           
        # Compute l over d ratio for takeoff condition, NO engine failure
        l_over_d = estimate_2ndseg_lift_drag_ratio(vehicle) 
        
        # Compute L over D ratio for takeoff condition, WITH engine failure
        clv2 = maximum_lift_coefficient / (V2_VS_ratio) **2
        cdv2_all_engine = clv2 / l_over_d
        cdv2 = cdv2_all_engine + asymmetry_drag_coefficient + windmilling_drag_coefficient
        l_over_d_v2 = clv2 / cdv2
    
        # Compute 2nd segment climb gradient
        second_seg_climb_gradient = thrust / (weight*sea_level_gravity) - 1. / l_over_d_v2
        
        return takeoff_field_length, second_seg_climb_gradient
    
    else:
        # return only takeoff_field_length
        return takeoff_field_length
def estimate_take_off_field_length(vehicle,analyses,airport):
    """ SUAVE.Methods.Performance.estimate_take_off_field_length(vehicle,airport):
        Computes the takeoff field length for a given vehicle condition in a given airport

        Inputs:
            vehicle	 - SUAVE type vehicle

            includes these fields:
                Mass_Properties.takeoff       - Takeoff weight to be evaluated
                S                          - Wing Area
                V2_VS_ratio                - Ratio between V2 and Stall speed
                                             [optional. Default value = 1.20]
                takeoff_constants          - Coefficients for takeoff field length equation
                                             [optional. Default values: AA241 method]
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [optional. Calculated if not informed]

    airport   - SUAVE type airport data, with followig fields:
                atmosphere                  - Airport atmosphere (SUAVE type)
                altitude                    - Airport altitude
                delta_isa                   - ISA Temperature deviation


        Outputs:
            takeoff_field_length            - Takeoff field length


        Assumptions:
            Correlation based.

    """

    # ==============================================
        # Unpack
    # ==============================================
    atmo            = airport.atmosphere
    altitude        = airport.altitude * Units.ft
    delta_isa       = airport.delta_isa
    weight          = vehicle.mass_properties.takeoff
    reference_area  = vehicle.reference_area
    try:
        V2_VS_ratio = vehicle.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    conditions0       = atmo.compute_values(0.)
    atmo_values       = atmo.compute_values(altitude)
    conditions        =SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
    
    p   = atmo_values.pressure
    T   = atmo_values.temperature
    rho = atmo_values.density
    a   = atmo_values.speed_of_sound
    mu  =atmo_values.dynamic_viscosity

    p0   = conditions0.pressure
    T0   = conditions0.temperature
    rho0 = conditions0.density
    a0   = conditions0.speed_of_sound
    mu0  = conditions0.dynamic_viscosity

    T_delta_ISA       = T + delta_isa
    sigma_disa        = (p/p0) / (T_delta_ISA/T0)
    rho               = rho0 * sigma_disa
    a_delta_ISA       = atmo.fluid_properties.compute_speed_of_sound(T_delta_ISA)
    mu                = 1.78938028e-05 * ((T0 + 120) / T0 ** 1.5) * ((T_delta_ISA ** 1.5) / (T_delta_ISA + 120))
    sea_level_gravity = atmo.planet.sea_level_gravity
    
    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions  = atmo.compute_values(10000. * Units.ft)
        conditions.freestream=Data()
        conditions.freestream.density   = conditions.density
        conditions.freestream.dynamic_viscosity = conditions.dynamic_viscosity
        conditions.freestream.velocity  = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(vehicle,conditions)
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, V2, 0.7*V2)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity / (rho * reference_area * maximum_lift_coefficient)) ** 0.5
    V2_speed    = V2_VS_ratio * stall_speed
    speed_for_thrust  = 0.70 * V2_speed

    # ==============================================
    # Determining vehicle number of engines
    # ==============================================
    engine_number = 0.
    for propulsor in vehicle.propulsors : # may have than one propulsor
        engine_number += propulsor.number_of_engines
    if engine_number == 0:
        raise ValueError, "No engine found in the vehicle"

    # ==============================================
    # Getting engine thrust
    # ==============================================
    
    state = Data()
    state.conditions = conditions
    state.numerics   = Data()
    conditions.freestream = Data()
    conditions.propulsion = Data()

    conditions.freestream.dynamic_pressure = np.array(np.atleast_1d(0.5 * rho * speed_for_thrust**2))
    conditions.freestream.gravity          = np.array([np.atleast_1d(sea_level_gravity)])
    conditions.freestream.velocity         = np.array(np.atleast_1d(speed_for_thrust))
    conditions.freestream.mach_number      = np.array(np.atleast_1d(speed_for_thrust/ a_delta_ISA))
    conditions.freestream.temperature      = np.array(np.atleast_1d(T_delta_ISA))
    conditions.freestream.pressure         = np.array(np.atleast_1d(p))
    conditions.propulsion.throttle         = np.array(np.atleast_1d(1.))
    results = vehicle.propulsors.evaluate_thrust(state) # total thrust
    
    thrust = results.thrust_force_vector

    # ==============================================
    # Calculate takeoff distance
    # ==============================================

    # Defining takeoff distance equations coefficients
    try:
        takeoff_constants = vehicle.takeoff_constants # user defined
    except:  # default values
        takeoff_constants = np.zeros(3)
        if engine_number == 2:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] =   2.476
            takeoff_constants[2] =   0.00014
        elif engine_number == 3:
            takeoff_constants[0] = 667.9
            takeoff_constants[1] =   2.343
            takeoff_constants[2] =   0.000093
        elif engine_number == 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] =   2.282
            takeoff_constants[2] =   0.0000705
        elif engine_number >  4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] =   2.282
            takeoff_constants[2] =   0.0000705
            print 'The vehicle has more than 4 engines. Using 4 engine correlation. Result may not be correct.'
        else:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] =   2.476
            takeoff_constants[2] =   0.00014
            print 'Incorrect number of engines: {0:.1f}. Using twin engine correlation.'.format(engine_number)

    # Define takeoff index   (V2^2 / (T/W)
    takeoff_index = V2_speed**2. / (thrust[0][0] / weight)
    # Calculating takeoff field length
    takeoff_field_length = 0.
    for idx,constant in enumerate(takeoff_constants):
        takeoff_field_length += constant * takeoff_index**idx
        p
    takeoff_field_length = takeoff_field_length * Units.ft
    # return
    return takeoff_field_length
def estimate_2ndseg_lift_drag_ratio(config):
    """ SUAVE.Methods.Aerodynamics.Drag.Correlations.estimate_2ndseg_lift_drag_ratio(config):
        Estimates the 2nd segment Lift to drag ration (all engine operating)
        Inputs:
            config   - data dictionary with fields:
                reference_area             - Airplane reference area
                V2_VS_ratio                - Ratio between V2 and Stall speed
                                             [optional. Default value = 1.20]
                Main_Wing.aspect_ratio     - Main_Wing aspect ratio
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [Calculated if not informed]

        Outputs:
            takeoff_field_length            - Takeoff field length

        Assumptions:
            All engines Operating. Must be corrected for second segment climb configuration
            reference: Fig. 27.34 of "Aerodynamic Design of Transport Airplane" - Obert

"""
    # ==============================================
	# Unpack
    # ==============================================
    try:
        V2_VS_ratio    = config.V2_VS_ratio
    except:
        V2_VS_ratio    = 1.20 # typical condition

    # getting geometrical data (aspect ratio)
    n_wing = 0
    for wing in config.wings:
        if not isinstance(wing,Wings.Main_Wing): continue
        reference_area = wing.areas.reference
        wing_span      = wing.spans.projected
        try:
            aspect_ratio = wing.aspect_ratio
        except:
            aspect_ratio = wing_span ** 2 / reference_area
        n_wing += 1

    if n_wing > 1:
        print ' More than one Main_Wing in the config. Last one will be considered.'
    elif n_wing == 0:
        print  'No Main_Wing defined! Using the 1st wing found'
        for wing in config.wings:
            if not isinstance(wing,Wings.Wing): continue
            reference_area = wing.areas.reference
            wing_span      = wing.spans.projected
            try:
                aspect_ratio = wing.aspect_ratio
            except:
                aspect_ratio = wing_span ** 2 / reference_area
            break


    # Determining vehicle maximum lift coefficient
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = config.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions = Data()
        conditions.freestream = Data()
        conditions.freestream.density           = 0.90477283
        conditions.freestream.dynamic_viscosity = 1.69220918e-05
        conditions.freestream.velocity          = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(config,conditions)
            config.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # Compute CL in V2
    lift_coeff = maximum_lift_coefficient / (V2_VS_ratio ** 2)

    # Estimate L/D in 2nd segment condition, ALL ENGINES OPERATIVE!
    lift_drag_ratio = -6.464 * lift_coeff + 7.264 * aspect_ratio ** 0.5

    return lift_drag_ratio
def estimate_take_off_field_length(vehicle, analyses, airport):
    """ SUAVE.Methods.Performance.estimate_take_off_field_length(vehicle,airport):
        Computes the takeoff field length for a given vehicle condition in a given airport

        Inputs:
            vehicle	 - SUAVE type vehicle

            includes these fields:
                Mass_Properties.takeoff       - Takeoff weight to be evaluated
                S                          - Wing Area
                V2_VS_ratio                - Ratio between V2 and Stall speed
                                             [optional. Default value = 1.20]
                takeoff_constants          - Coefficients for takeoff field length equation
                                             [optional. Default values: AA241 method]
                maximum_lift_coefficient   - Maximum lift coefficient for the config
                                             [optional. Calculated if not informed]

    airport   - SUAVE type airport data, with followig fields:
                atmosphere                  - Airport atmosphere (SUAVE type)
                altitude                    - Airport altitude
                delta_isa                   - ISA Temperature deviation


        Outputs:
            takeoff_field_length            - Takeoff field length


        Assumptions:
            Correlation based.

    """

    # ==============================================
    # Unpack
    # ==============================================
    atmo = airport.atmosphere
    altitude = airport.altitude * Units.ft
    delta_isa = airport.delta_isa
    weight = vehicle.mass_properties.takeoff
    reference_area = vehicle.reference_area
    try:
        V2_VS_ratio = vehicle.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20

    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    conditions0 = atmo.compute_values(0.)
    atmo_values = atmo.compute_values(altitude)
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()

    p = atmo_values.pressure
    T = atmo_values.temperature
    rho = atmo_values.density
    a = atmo_values.speed_of_sound
    mu = atmo_values.dynamic_viscosity

    p0 = conditions0.pressure
    T0 = conditions0.temperature
    rho0 = conditions0.density
    a0 = conditions0.speed_of_sound
    mu0 = conditions0.dynamic_viscosity

    T_delta_ISA = T + delta_isa
    sigma_disa = (p / p0) / (T_delta_ISA / T0)
    rho = rho0 * sigma_disa
    a_delta_ISA = atmo.fluid_properties.compute_speed_of_sound(T_delta_ISA)
    mu = 1.78938028e-05 * ((T0 + 120) / T0**1.5) * ((T_delta_ISA**1.5) /
                                                    (T_delta_ISA + 120))
    sea_level_gravity = atmo.planet.sea_level_gravity

    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    try:  # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        # Condition to CLmax calculation: 90KTAS @ 10000ft, ISA
        conditions = atmo.compute_values(10000. * Units.ft)
        conditions.freestream = Data()
        conditions.freestream.density = conditions.density
        conditions.freestream.dynamic_viscosity = conditions.dynamic_viscosity
        conditions.freestream.velocity = 90. * Units.knots
        try:
            maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(
                vehicle, conditions)
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient
        except:
            raise ValueError, "Maximum lift coefficient calculation error. Please, check inputs"

    # ==============================================
    # Computing speeds (Vs, V2, 0.7*V2)
    # ==============================================
    stall_speed = (2 * weight * sea_level_gravity /
                   (rho * reference_area * maximum_lift_coefficient))**0.5
    V2_speed = V2_VS_ratio * stall_speed
    speed_for_thrust = 0.70 * V2_speed

    # ==============================================
    # Determining vehicle number of engines
    # ==============================================
    engine_number = 0.
    for propulsor in vehicle.propulsors:  # may have than one propulsor
        engine_number += propulsor.number_of_engines
    if engine_number == 0:
        raise ValueError, "No engine found in the vehicle"

    # ==============================================
    # Getting engine thrust
    # ==============================================

    state = Data()
    state.conditions = conditions
    state.numerics = Data()
    conditions.freestream = Data()
    conditions.propulsion = Data()

    conditions.freestream.dynamic_pressure = np.array(
        np.atleast_1d(0.5 * rho * speed_for_thrust**2))
    conditions.freestream.gravity = np.array(
        [np.atleast_1d(sea_level_gravity)])
    conditions.freestream.velocity = np.array(np.atleast_1d(speed_for_thrust))
    conditions.freestream.mach_number = np.array(
        np.atleast_1d(speed_for_thrust / a_delta_ISA))
    conditions.freestream.temperature = np.array(np.atleast_1d(T_delta_ISA))
    conditions.freestream.pressure = np.array(np.atleast_1d(p))
    conditions.propulsion.throttle = np.array(np.atleast_1d(1.))
    results = vehicle.propulsors.evaluate_thrust(state)  # total thrust

    thrust = results.thrust_force_vector

    # ==============================================
    # Calculate takeoff distance
    # ==============================================

    # Defining takeoff distance equations coefficients
    try:
        takeoff_constants = vehicle.takeoff_constants  # user defined
    except:  # default values
        takeoff_constants = np.zeros(3)
        if engine_number == 2:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] = 2.476
            takeoff_constants[2] = 0.00014
        elif engine_number == 3:
            takeoff_constants[0] = 667.9
            takeoff_constants[1] = 2.343
            takeoff_constants[2] = 0.000093
        elif engine_number == 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] = 2.282
            takeoff_constants[2] = 0.0000705
        elif engine_number > 4:
            takeoff_constants[0] = 486.7
            takeoff_constants[1] = 2.282
            takeoff_constants[2] = 0.0000705
            print 'The vehicle has more than 4 engines. Using 4 engine correlation. Result may not be correct.'
        else:
            takeoff_constants[0] = 857.4
            takeoff_constants[1] = 2.476
            takeoff_constants[2] = 0.00014
            print 'Incorrect number of engines: {0:.1f}. Using twin engine correlation.'.format(
                engine_number)

    # Define takeoff index   (V2^2 / (T/W)
    takeoff_index = V2_speed**2. / (thrust[0][0] / weight)
    # Calculating takeoff field length
    takeoff_field_length = 0.
    for idx, constant in enumerate(takeoff_constants):
        takeoff_field_length += constant * takeoff_index**idx
        p
    takeoff_field_length = takeoff_field_length * Units.ft
    # return
    return takeoff_field_length
示例#13
0
def V_n_diagram(vehicle, analyses, weight, altitude, delta_ISA):
    """ Computes a V-n diagram for a given aircraft and given regulations for ISA conditions

    Source:
    S. Gudmundsson "General Aviation Aircraft Design: Applied Methods and Procedures", Butterworth-Heinemann; 1 edition
    CFR FAR Part 23: https://www.ecfr.gov/cgi-bin/text-idx?SID=0e6a13c7c1de7f501d0eb0a4d71418bd&mc=true&tpl=/ecfrbrowse/Title14/14cfr23_main_02.tpl
    CFR FAR Part 25: https://www.ecfr.gov/cgi-bin/text-idx?tpl=/ecfrbrowse/Title14/14cfr25_main_02.tpl

    Inputs:
    analyses.base.atmosphere               [SUAVE data type]
    vehicle.
      reference_area                       [m^2]
      maximum_lift_coefficient             [Unitless]
      minimum_lift_coefficient             [Unitless]
      chords.mean_aerodynamic              [m]
      envelope.FARpart_number              [Unitless]
        limit_loads.positive               [Unitless]
        limit_loads.negative               [Unitless]
        cruise_mach                        [Unitless]
    weight                                 [kg]
    altitude                               [m]
    delta_ISA                              [deg C]

    Outputs:
    V_n_data

    Properties Used:
    N/A

    Description:
    The script creates an aircraft V-n diagram based on the input parameters specified by the user.
    Depending on the certification flag, an appropriate diagram, output and log files are created.
    """

    #------------------------
    # Create a log - file
    #------------------------
    flog = open("V_n_diagram_" + vehicle.tag + ".log", "w")

    print('Running the V-n diagram calculation...')
    flog.write('Running the V-n diagram calculation...\n')
    flog.write('Aircraft: ' + vehicle.tag + '\n')
    flog.write('Category: ' + vehicle.envelope.category + '\n')
    flog.write('FAR certification: Part ' +
               str(vehicle.envelope.FAR_part_number) + '\n\n')

    # ----------------------------------------------
    # Unpack
    # ----------------------------------------------
    flog.write('Unpacking the input and calculating required inputs...\n')
    FAR_part_number = vehicle.envelope.FAR_part_number
    atmo = analyses.atmosphere
    Mc = vehicle.envelope.cruise_mach

    for wing in vehicle.wings:
        reference_area = vehicle.reference_area
        Cmac = wing.chords.mean_aerodynamic

    for envelope in vehicle:
        pos_limit_load = vehicle.envelope.limit_loads.positive
        neg_limit_load = vehicle.envelope.limit_loads.negative

    category_tag = vehicle.envelope.category

    # ----------------------------------------------
    # Computing atmospheric conditions
    # ----------------------------------------------
    atmo_values = atmo.compute_values(altitude, delta_ISA)
    SL_atmo_values = atmo.compute_values(0, delta_ISA)
    conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()

    rho = atmo_values.density
    sea_level_rho = SL_atmo_values.density
    sea_level_gravity = atmo.planet.sea_level_gravity
    Vc = Mc * (1.4 * 287 * atmo_values.temperature)**0.5

    # ------------------------------
    # Computing lift-curve slope
    # ------------------------------
    CLa = datcom(vehicle.wings.main_wing, np.array([Mc]))
    CLa = CLa[0]

    # -----------------------------------------------------------
    # Determining vehicle minimum and maximum lift coefficients
    # -----------------------------------------------------------
    try:  # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Condition to CLmax calculation: 0.333 * Vc @ specified altitude, ISA
        conditions.freestream = Data()
        conditions.freestream.density = atmo_values.density
        conditions.freestream.dynamic_viscosity = atmo_values.dynamic_viscosity
        conditions.freestream.velocity = 0.333 * Vc
        try:
            max_lift_coefficient, induced_drag_high_lift \
                                             = compute_max_lift_coeff(vehicle,conditions)
            maximum_lift_coefficient = max_lift_coefficient[0][0]
            vehicle.maximum_lift_coefficient = maximum_lift_coefficient

        except:
            raise ValueError(
                "Maximum lift coefficient calculation error. Please, check inputs"
            )

    try:  # aircraft minimum lift informed by user
        minimum_lift_coefficient = vehicle.minimum_lift_coefficient
    except:
        raise ValueError(
            "The value not found. Specify minimum lift coefficient")

    # -----------------------------------------------------------------------------
    # Convert all terms to English (Used for FAR) and remove elements from arrays
    # -----------------------------------------------------------------------------
    altitude = altitude / Units.ft
    rho = rho[0, 0] / Units['slug/ft**3']
    sea_level_rho = sea_level_rho[0, 0] / Units['slug/ft**3']
    density_ratio = (rho / sea_level_rho)**0.5
    sea_level_gravity = sea_level_gravity / Units['ft/s**2']
    weight = weight / Units['slug'] * sea_level_gravity
    reference_area = reference_area / Units['ft**2']
    Cmac = Cmac / Units.ft
    wing_loading = weight / reference_area
    Vc = Vc / Units['ft/s']

    load_factors_pos = np.zeros(shape=(5))
    load_factors_neg = np.zeros(shape=(5))
    load_factors_pos[1] = 1
    load_factors_neg[1] = -1
    airspeeds_pos = np.zeros(shape=(5))
    airspeeds_neg = np.zeros(shape=(5))

    # --------------------------------------------------
    # Establish limit maneuver load factors n+ and n-
    # --------------------------------------------------
    flog.write('Establish limit maneuver load factors n+ and n-...\n')
    # CFR Part 25
    # Positive and negative limits
    if FAR_part_number == 25:
        # Positive limit
        flog.write('    Estimating n+...\n')
        load_factors_pos[2] = 2.1 + 24000 / (weight + 10000)
        if load_factors_pos[2] < 2.5:
            flog.write(
                '        Defined positive limit load factor < 2.5. Setting 2.5...\n'
            )
            load_factors_pos[2] = 2.5
        elif load_factors_pos[2] < pos_limit_load:
            load_factors_pos[2] = pos_limit_load
        elif load_factors_pos[2] > 3.8:
            flog.write(
                '        Defined positive limit load factor > 3.8. Setting 3.8...\n'
            )
            load_factors_pos[2] = 3.8

        # Negative limit
        flog.write('    Estimating n-...\n')
        load_factors_neg[2] = neg_limit_load
        if load_factors_neg[2] > -1:
            flog.write(
                '        Negative limit load factor magnitude is too small. Setting to -1...\n'
            )
            load_factors_neg[2] = -1

    elif FAR_part_number == 23:
        if category_tag == 'normal' or category_tag == 'commuter':
            # Positive limit
            flog.write('    Estimating n+...\n')
            load_factors_pos[2] = 2.1 + 24000 / (weight + 10000)
            if load_factors_pos[2] < 2.5:
                flog.write(
                    '        Defined positive limit load factor < 2.5. Setting 2.5...\n'
                )
                load_factors_pos[2] = 2.5
            elif load_factors_pos[2] < pos_limit_load:
                load_factors_pos[2] = pos_limit_load
            elif load_factors_pos[2] > 3.8:
                flog.write(
                    '        Defined positive limit load factor > 3.8. Setting 3.8...\n'
                )
                load_factors_pos[2] = 3.8

            # Negative limit
            flog.write('    Estimating n-...\n')
            load_factors_neg[2] = -0.4 * load_factors_pos[2]

        elif category_tag == 'utility':
            # Positive limit
            flog.write('    Estimating n+...\n')
            load_factors_pos[2] = pos_limit_load
            if load_factors_pos[2] < 4.4:
                flog.write(
                    '        Defined positive limit load factor < 4.4. Setting 4.4...\n'
                )
                load_factors_pos[2] = 4.4

            # Negative limit
            flog.write('    Estimating n-...\n')
            load_factors_neg[2] = -0.4 * load_factors_pos[2]

        elif category_tag == 'acrobatic':
            # Positive limit
            load_factors_pos[2] = pos_limit_load
            if load_factors_pos[2] < 6.0:
                flog.write(
                    '        Defined positive limit load factor < 6.0. Setting 6.0...\n'
                )
                load_factors_pos[2] = 6.0

            # Negative limit
            load_factors_neg[2] = -0.5 * load_factors_pos[2]

        else:
            raise ValueError(
                "Check the category_tag input. The parameter was not found")

    else:
        raise ValueError(
            "Check the FARflag input. The parameter was not found")

    # Check input of the limit load
    if abs(neg_limit_load) > abs(load_factors_neg[2]):
        load_factors_neg[2] = neg_limit_load

    #----------------------------------------
    # Generate a V-n diagram data structure
    #----------------------------------------
    V_n_data = Data()
    V_n_data.limit_loads = Data()
    V_n_data.limit_loads.dive = Data()
    V_n_data.load_factors = Data()
    V_n_data.gust_load_factors = Data()
    V_n_data.Vb_load_factor = Data()
    V_n_data.airspeeds = Data()
    V_n_data.Vs1 = Data()
    V_n_data.Va = Data()
    V_n_data.Vb = Data()
    V_n_data.load_factors.positive = load_factors_pos
    V_n_data.load_factors.negative = load_factors_neg
    V_n_data.airspeeds.positive = airspeeds_pos
    V_n_data.airspeeds.negative = airspeeds_neg
    V_n_data.Vc = Vc
    V_n_data.weight = weight
    V_n_data.wing_loading = wing_loading
    V_n_data.altitude = altitude
    V_n_data.density = rho
    V_n_data.density_ratio = density_ratio
    V_n_data.reference_area = reference_area
    V_n_data.maximum_lift_coefficient = maximum_lift_coefficient
    V_n_data.minimum_lift_coefficient = minimum_lift_coefficient
    V_n_data.limit_loads.positive = load_factors_pos[2]
    V_n_data.limit_loads.negative = load_factors_neg[2]

    # --------------------------------------------------
    # Computing critical speeds (Va, Vc, Vb, Vd, Vs1)
    # --------------------------------------------------
    flog.write('Computing critical speeds (Va, Vc, Vb, Vd, Vs1)...\n')

    # Calculate Stall and Maneuver speeds
    flog.write('    Computing Vs1 and Va...\n')
    stall_maneuver_speeds(V_n_data)

    # convert speeds to KEAS for future calculations
    convert_keas(V_n_data)

    # unpack modified airspeeds
    airspeeds_pos = V_n_data.airspeeds.positive
    airspeeds_neg = V_n_data.airspeeds.negative
    Vc = V_n_data.Vc
    Va_pos = V_n_data.Va.positive
    Va_neg = V_n_data.Va.negative
    Va_pos = V_n_data.Va.positive
    Va_neg = V_n_data.Va.negative

    flog.write('    Checking Vc wrt Va...\n')
    if Va_neg > Vc and Va_neg > Va_pos:
        flog.write('        Negative Va > Vc. Setting Vc = 1.15 * Va...\n')
        Vc = 1.15 * Va_neg
    elif Va_pos > Vc and Va_neg < Va_pos:
        flog.write('        Positive Va > Vc. Setting Vc = 1.15 * Va...\n')
        Vc = 1.15 * Va_pos

    # Gust speeds between Vb and Vc (EAS) and minimum Vc
    miu = 2 * wing_loading / (rho * Cmac * CLa * sea_level_gravity)
    Kg = 0.88 * miu / (5.3 + miu)

    if FAR_part_number == 25:
        if altitude < 15000:
            Uref_cruise = (-0.0008 * altitude + 56)
            Uref_rough = Uref_cruise
            Uref_dive = 0.5 * Uref_cruise
        else:
            Uref_cruise = (-0.0005142 * altitude + 51.7133)
            Uref_rough = Uref_cruise
            Uref_dive = 0.5 * Uref_cruise

        # Minimum Cruise speed Vc_min
        coefs = [
            1, -Uref_cruise * (2.64 + (Kg * CLa * airspeeds_pos[1]**2) /
                               (498 * wing_loading)),
            1.72424 * Uref_cruise**2 - airspeeds_pos[1]**2
        ]
        Vc1 = max(np.roots(coefs))

    elif FAR_part_number == 23:
        if altitude < 20000:
            Uref_cruise = 50
            Uref_dive = 25
        else:
            Uref_cruise = (-0.0008333 * altitude + 66.67)
            Uref_dive = (-0.0004167 * altitude + 33.334)

        if category_tag == 'commuter':
            if altitude < 20000:
                Uref_rough = 66
            else:
                Uref_rough = -0.000933 * altitude + 84.667
        else:
            Uref_rough = Uref_cruise

        # Minimum Cruise speed Vc_min
        if category_tag == 'acrobatic':
            Vc1 = 36 * wing_loading**0.5
            if wing_loading >= 20:
                Vc1 = (-0.0925 * wing_loading + 37.85) * wing_loading**0.5
        else:
            Vc1 = 33 * wing_loading**0.5
            if wing_loading >= 20:
                Vc1 = (-0.055 * wing_loading + 34.1) * wing_loading**0.5

    # checking input Cruise speed
    flog.write('    Checking Vc wrt Vcmin... \n')
    if Vc1 > Vc:
        flog.write(
            '        Specified cruise speed is less than the minimum required. Setting th minimum required value...\n'
        )
        Vc = Vc1

    # Dive speed
    flog.write('    Computing Vd...\n')
    if FAR_part_number == 25:
        airspeeds_pos[4] = 1.25 * Vc
    elif FAR_part_number == 23:
        if category_tag == 'acrobatic':
            airspeeds_pos[4] = 1.55 * Vc1
            if wing_loading > 20:
                airspeeds_pos[4] = (-0.0025 * wing_loading + 1.6) * Vc1
        elif category_tag == 'utility':
            airspeeds_pos[4] = 1.5 * Vc1
            if wing_loading > 20:
                airspeeds_pos[4] = (-0.001875 * wing_loading + 1.5375) * Vc1
        else:
            airspeeds_pos[4] = 1.4 * Vc1
            if wing_loading > 20:
                airspeeds_pos[4] = (-0.000625 * wing_loading + 1.4125) * Vc1

        if airspeeds_pos[4] < 1.15 * Vc:
            flog.write(
                '        Based on min Vc, Vd is too close Vc. Setting Vd = 1.15 Vc...\n'
            )
            airspeeds_pos[4] = 1.15 * Vc

    Vd = airspeeds_pos[4]
    airspeeds_pos[3] = airspeeds_pos[4]
    airspeeds_neg[3] = Vc
    airspeeds_neg[4] = airspeeds_pos[4]

    # complete initial load factors
    load_factors_pos[4] = 0
    load_factors_neg[4] = 0
    if category_tag == 'acrobatic' or category_tag == 'utility':
        load_factors_neg[4] = -1

    load_factors_pos[3] = load_factors_pos[2]
    load_factors_neg[3] = load_factors_neg[2]

    # add parameters to the data structure
    V_n_data.load_factors.positive = load_factors_pos
    V_n_data.load_factors.negative = load_factors_neg
    V_n_data.airspeeds.positive = airspeeds_pos
    V_n_data.airspeeds.negative = airspeeds_neg
    V_n_data.Vd = Vd
    V_n_data.Vc = Vc

    #------------------------
    # Create Stall lines
    #------------------------
    flog.write('Creating stall lines...\n')
    Num_of_points = 20  # number of points for the stall line
    upper_bound = 2
    lower_bound = 1
    stall_line(V_n_data, upper_bound, lower_bound, Num_of_points, 1)
    stall_line(V_n_data, upper_bound, lower_bound, Num_of_points, 2)

    # ----------------------------------------------
    # Determine Gust loads
    # ----------------------------------------------
    flog.write('Calculating gust loads...\n')
    V_n_data.gust_data = Data()
    V_n_data.gust_data.airspeeds = Data()

    V_n_data.gust_data.airspeeds.rough_gust = Uref_rough
    V_n_data.gust_data.airspeeds.cruise_gust = Uref_cruise
    V_n_data.gust_data.airspeeds.dive_gust = Uref_dive

    gust_loads(category_tag, V_n_data, Kg, CLa, Num_of_points, FAR_part_number,
               1)
    gust_loads(category_tag, V_n_data, Kg, CLa, Num_of_points, FAR_part_number,
               2)

    #----------------------------------------------------------------
    # Finalize the load factors for acrobatic and utility aircraft
    #----------------------------------------------------------------
    if category_tag == 'acrobatic' or category_tag == 'utility':
        V_n_data.airspeeds.negative = np.append(V_n_data.airspeeds.negative,
                                                Vd)
        V_n_data.load_factors.negative = np.append(
            V_n_data.load_factors.negative, 0)

    # ----------------------------------------------
    # Post-processing the V-n diagram
    # ----------------------------------------------
    flog.write('Post-Processing...\n')
    V_n_data.limit_loads.positive = max(V_n_data.load_factors.positive)
    V_n_data.limit_loads.negative = min(V_n_data.load_factors.negative)

    post_processing(category_tag, Uref_rough, Uref_cruise, Uref_dive, V_n_data,
                    vehicle)

    print('Calculation complete...')
    flog.write('Calculation complete\n')
    flog.close()

    return V_n_data
示例#14
0
def estimate_2ndseg_lift_drag_ratio(state, settings, geometry):
    """Estimates the 2nd segment climb lift to drag ratio (all engine operating)
    
    Assumptions:
    All engines operating

    Source:
    Fig. 27.34 of "Aerodynamic Design of Transport Airplane" - Obert

    Inputs:
    config.
      V2_VS_ratio              [Unitless]
      wings.
        areas.reference        [m^2]
	spans.projected        [m]
	aspect_ratio           [Unitless]
      maximum_lift_coefficient [Unitless]

    Outputs:
    lift_drag_ratio            [Unitless]

    Properties Used:
    N/A
    """
    # ==============================================
    # Unpack
    # ==============================================
    try:
        V2_VS_ratio = geometry.V2_VS_ratio
    except:
        V2_VS_ratio = 1.20  # typical condition

    # getting geometrical data (aspect ratio)
    n_wing = 0
    for wing in geometry.wings:
        if not isinstance(wing, Wings.Main_Wing): continue
        reference_area = wing.areas.reference
        wing_span = wing.spans.projected
        try:
            aspect_ratio = wing.aspect_ratio
        except:
            aspect_ratio = wing_span**2 / reference_area
        n_wing += 1

    if n_wing > 1:
        print(
            ' More than one Main_Wing in the config. Last one will be considered.'
        )
    elif n_wing == 0:
        print('No Main_Wing defined! Using the 1st wing found')
        for wing in geometry.wings:
            if not isinstance(wing, Wings.Wing): continue
            reference_area = wing.areas.reference
            wing_span = wing.spans.projected
            try:
                aspect_ratio = wing.aspect_ratio
            except:
                aspect_ratio = wing_span**2 / reference_area
            break

    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    maximum_lift_coefficient, induced_drag_high_lift = compute_max_lift_coeff(
        state, settings, geometry)

    # Compute CL in V2
    lift_coeff = maximum_lift_coefficient / (V2_VS_ratio**2)

    # Estimate L/D in 2nd segment condition, ALL ENGINES OPERATIVE!
    lift_drag_ratio = -6.464 * lift_coeff + 7.264 * aspect_ratio**0.5

    return lift_drag_ratio
def estimate_landing_field_length(vehicle,analyses,airport):
    """ Computes the landing field length for a given vehicle configuration in a given airport.

    Assumptions:
    See source
    Two wheel trucks (code needed for four wheel trucks also included)

    Source:
    Torenbeek, E., "Advanced Aircraft Design", 2013 (equation 9.25)

    Inputs:
    airport.
      atmosphere                           [SUAVE data type]
      altitude                             [m]
      delta_isa                            [K]
    vehicle.
      mass_properties.landing              [kg]
      reference_area                       [m^2]
      maximum_lift_coefficient (optional)  [Unitless]

    Outputs:
    landing_field_length                   [m]

    Properties Used:
    N/A
    """       
   
    # ==============================================
    # Unpack
    # ==============================================
    atmo            = airport.atmosphere
    altitude        = airport.altitude * Units.ft
    delta_isa       = airport.delta_isa
    weight          = vehicle.mass_properties.landing
    reference_area  = vehicle.reference_area
    try:
        Vref_VS_ratio = config.Vref_VS_ratio
    except:
        Vref_VS_ratio = 1.23
        
    # ==============================================
    # Computing atmospheric conditions
    # ==============================================
    atmo_values     = atmo.compute_values(altitude,delta_isa)
    conditions      = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics()
    
    p   = atmo_values.pressure
    T   = atmo_values.temperature
    rho = atmo_values.density
    a   = atmo_values.speed_of_sound
    mu  = atmo_values.dynamic_viscosity
    sea_level_gravity = atmo.planet.sea_level_gravity
   
    # ==============================================
    # Determining vehicle maximum lift coefficient
    # ==============================================
    
    try:   # aircraft maximum lift informed by user
        maximum_lift_coefficient = vehicle.maximum_lift_coefficient
    except:
        # Using semi-empirical method for maximum lift coefficient calculation
        from SUAVE.Methods.Aerodynamics.Fidelity_Zero.Lift import compute_max_lift_coeff

        
        conditions.freestream = Data()
        conditions.freestream.density           = rho
        conditions.freestream.dynamic_viscosity = mu
        conditions.freestream.velocity          = 90. * Units.knots
        
        try:
            maximum_lift_coefficient, induced_drag_high_lift =   compute_max_lift_coeff(vehicle,conditions)
            vehicle.maximum_lift_coefficient                 =   maximum_lift_coefficient
            
        except:
            raise ValueError("Maximum lift coefficient calculation error. Please, check inputs")
        
    # ==============================================
    # Computing speeds (Vs, Vref)
    # ==============================================
    stall_speed  = (2 * weight * sea_level_gravity / (rho * reference_area * maximum_lift_coefficient)) ** 0.5
    Vref         = stall_speed * Vref_VS_ratio
    
    # ========================================================================================
    # Computing landing distance, according to Torenbeek equation
    #     Landing Field Length = k1 + k2 * Vref**2
    # ========================================================================================

    # Defining landing distance equation coefficients
    try:
        landing_constants = config.landing_constants # user defined
    except:  # default values - According to Torenbeek book
        landing_constants = np.zeros(3)
        landing_constants[0] = 250.
        landing_constants[1] =   0.
        landing_constants[2] =  2.485  / sea_level_gravity  # Two-wheels truck : [ (1.56 / 0.40 + 1.07) / (2*sea_level_gravity) ]
##        landing_constants[2] =   2.9725 / sea_level_gravity  # Four-wheels truck: [ (1.56 / 0.32 + 1.07) / (2*sea_level_gravity) ]

    # Calculating landing field length
    landing_field_length = 0.
    for idx,constant in enumerate(landing_constants):
        landing_field_length += constant * Vref**idx
    
    # return
    return landing_field_length