Exemple #1
0
def parasite_drag_aircraft(conditions, configuration, geometry):
    """ SUAVE.Methods.parasite_drag_aircraft(aircraft,segment,Cl,cdi_inv,cdp,fd_ws)
        computes the parasite_drag_aircraft associated with an aircraft 
        
        Inputs:

        
        Outputs:

        
        Assumptions:
            based on a set of fits
        
    """

    # unpack inputs
    wings = geometry.wings
    fuselages = geometry.fuselages
    propulsors = geometry.propulsors
    vehicle_reference_area = geometry.reference_area
    drag_breakdown = conditions.aerodynamics.drag_breakdown

    # the drag to be returned
    total_parasite_drag = 0.0

    # start conditions node
    drag_breakdown.parasite = Results()

    # from wings
    for wing in wings.values():
        parasite_drag = parasite_drag_wing(conditions, configuration, wing)
        conditions.aerodynamics.drag_breakdown.parasite[
            wing.
            tag].parasite_drag_coefficient = parasite_drag * wing.areas.reference / vehicle_reference_area
        total_parasite_drag += parasite_drag * wing.areas.reference / vehicle_reference_area

    # from fuselage
    for fuselage in fuselages.values():
        parasite_drag = parasite_drag_fuselage(conditions, configuration,
                                               fuselage)
        conditions.aerodynamics.drag_breakdown.parasite[
            fuselage.
            tag].parasite_drag_coefficient = parasite_drag * fuselage.areas.front_projected / vehicle_reference_area
        total_parasite_drag += parasite_drag * fuselage.areas.front_projected / vehicle_reference_area

    # from propulsors
    for propulsor in propulsors.values():
        parasite_drag = parasite_drag_propulsor(conditions, configuration,
                                                propulsor)
        ref_area = propulsor.nacelle_diameter**2 / 4 * np.pi
        conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.
            tag].parasite_drag_coefficient = parasite_drag * ref_area / vehicle_reference_area * propulsor.number_of_engines
        total_parasite_drag += parasite_drag * ref_area / vehicle_reference_area * propulsor.number_of_engines

    # dump to condtitions
    drag_breakdown.parasite.total = total_parasite_drag

    return total_parasite_drag
Exemple #2
0
def parasite_drag_propulsor(state, settings, geometry):
    """ SUAVE.Methods.parasite_drag_propulsor(conditions,configuration,propulsor)
        computes the parasite drag associated with a propulsor 
        
        Inputs:

        Outputs:

        Assumptions:

        
    """

    # unpack inputs
    conditions = state.conditions
    configuration = settings

    propulsor = geometry
    Sref = propulsor.nacelle_diameter**2. / 4. * np.pi
    Swet = propulsor.areas.wetted

    l_prop = propulsor.engine_length
    d_prop = propulsor.nacelle_diameter

    # conditions
    freestream = conditions.freestream
    Mc = freestream.mach_number
    Tc = freestream.temperature
    re = freestream.reynolds_number

    # reynolds number
    Re_prop = re * l_prop

    # skin friction coefficient
    cf_prop, k_comp, k_reyn = compressible_turbulent_flat_plate(
        Re_prop, Mc, Tc)

    ## form factor according to Raymer equation (pg 283 of Aircraft Design: A Conceptual Approach)
    k_prop = 1 + 0.35 / (float(l_prop) / float(d_prop))

    # find the final result
    propulsor_parasite_drag = k_prop * cf_prop * Swet / Sref

    # dump data to conditions
    propulsor_result = Results(
        wetted_area=Swet,
        reference_area=Sref,
        parasite_drag_coefficient=propulsor_parasite_drag,
        skin_friction_coefficient=cf_prop,
        compressibility_factor=k_comp,
        reynolds_factor=k_reyn,
        form_factor=k_prop,
    )
    conditions.aerodynamics.drag_breakdown.parasite[
        propulsor.tag] = propulsor_result

    return propulsor_parasite_drag
def fuselage_correction(state, settings, geometry):
    """ SUAVE.Methods.Aerodynamics.compute_aircraft_lift(conditions,configuration,geometry)
        computes the lift associated with an aircraft 
        
        Inputs:
            conditions - data dictionary with fields:
                mach_number - float or 1D array of freestream mach numbers
                angle_of_attack - floar or 1D array of angle of attacks
                
            configuration - data dictionary with fields:
                surrogate_models.lift_coefficient - a callable function or class 
                    with inputs of angle of attack and outputs of lift coefficent
                fuselage_lift_correction - the correction to fuselage contribution to lift
                    
            geometry - used for wing
            
        
        Outputs:
            CL - float or 1D array of lift coefficients of the total aircraft
        
        Updates:
            conditions.lift_breakdown - stores results here
            
        Assumptions:
            surrogate model returns total incompressible lift due to wings
            prandtl-glaurert compressibility correction on this
            fuselage contribution to lift correction as a factor
        
    """

    # unpack
    fus_correction = settings.fuselage_lift_correction
    Mc = state.conditions.freestream.mach_number
    AoA = state.conditions.aerodynamics.angle_of_attack

    wings_lift_comp = state.conditions.aerodynamics.lift_coefficient

    # total lift, accounting one fuselage
    aircraft_lift_total = wings_lift_comp * fus_correction

    # store results
    lift_results = Results(
        total=aircraft_lift_total,
        #incompressible_wings = wings_lift          ,
        compressible_wings=wings_lift_comp,
        #compressibility_correction_factor = compress_corr  ,
        #fuselage_correction_factor        = fus_correction ,
        #vortex                            = vortex_cl ,
    )

    #conditions.aerodynamics.lift_breakdown.update( lift_results )    #update

    state.conditions.aerodynamics.lift_coefficient = aircraft_lift_total

    return aircraft_lift_total
def miscellaneous_drag_aircraft_ESDU(state,settings,geometry):
#def miscellaneous_drag_aircraft_ESDU(conditions,configuration,geometry):
    """ SUAVE.Methods.miscellaneous_drag_aircraft_ESDU(conditions,configuration,geometry):
        computes the miscellaneous drag based in ESDU 94044, figure 1

        Inputs:
            conditions      - data dictionary for output dump
            configuration   - not in use
            geometry        - SUave type vehicle

        Outpus:
            cd_misc  - returns the miscellaneous drag associated with the vehicle

        Assumptions:
            if needed

    """

    # unpack inputs
    
    conditions = state.conditions
    configuration = settings
    
    Sref        = geometry.reference_area
    ones_1col   = conditions.freestream.mach_number *0.+1

    # Estimating total wetted area
    swet_tot        = 0.
    for wing in geometry.wings:
        swet_tot += wing.areas.wetted

    for fuselage in geometry.fuselages:
        swet_tot += fuselage.areas.wetted

    for propulsor in geometry.propulsors:
        swet_tot += propulsor.areas.wetted * propulsor.number_of_engines

    swet_tot *= 1.10
    
    # Estimating excrescence drag, based in ESDU 94044, figure 1
    D_q = 0.40* (0.0184 + 0.000469 * swet_tot - 1.13*10**-7 * swet_tot ** 2)
    cd_excrescence = D_q / Sref

    # ------------------------------------------------------------------
    #   The final result
    # ------------------------------------------------------------------
    # dump to results
    conditions.aerodynamics.drag_breakdown.miscellaneous = Results(
        total_wetted_area         = swet_tot,
        reference_area            = Sref ,
        total                     = cd_excrescence *ones_1col, )

    return cd_excrescence *ones_1col
Exemple #5
0
def wave_drag_lift(conditions, configuration, wing):
    """ SUAVE.Methods.wave_drag_lift(conditions,configuration,wing)
        computes the wave drag due to lift 
        Based on http://adg.stanford.edu/aa241/drag/ssdragcalc.html
        
        Inputs:
        - SUave wing
        - Sref - wing reference area
        - Mc - mach number
        - CL - coefficient of lift
        - total_length - length of the wing root

        Outputs:
        - CD due to wave drag from the wing

        Assumptions:
        - Supersonic mach numbers
        - Reference area of passed wing is desired for CD
        
    """

    # Unpack
    freestream = conditions.freestream
    total_length = wing.total_length
    Sref = wing.areas.reference

    # Conditions
    Mc = freestream.mach_number * 1.0

    # Length-wise aspect ratio
    ARL = total_length**2 / Sref

    # Lift coefficient
    CL = conditions.aerodynamics.lift_coefficient * 1.0

    # Computations
    x = np.pi * ARL / 4
    beta = np.array([[0.0]] * len(Mc))
    beta[Mc >= 1.05] = np.sqrt(Mc[Mc >= 1.05]**2 - 1)
    wave_drag_lift = np.array([[0.0]] * len(Mc))
    wave_drag_lift[Mc >= 1.05] = CL[Mc >= 1.05]**2 * x / 4 * (
        np.sqrt(1 + (beta[Mc >= 1.05] / x)**2) - 1)
    wave_drag_lift[0:len(Mc[Mc >= 1.05]), 0] = wave_drag_lift[Mc >= 1.05]

    # Dump data to conditions
    wave_lift_result = Results(
        reference_area=Sref,
        wave_drag_lift_coefficient=wave_drag_lift,
        length_AR=ARL,
    )

    return wave_drag_lift
Exemple #6
0
def induced_drag_aircraft(state,settings,geometry):
    """ SUAVE.Methods.induced_drag_aircraft(conditions,configuration,geometry)
        computes the induced drag associated with a wing 
        
        Inputs:
        
        Outputs:
        
        Assumptions:
            based on a set of fits
            
    """

    # unpack inputs
    conditions = state.conditions
    configuration = settings    
    
    aircraft_lift = conditions.aerodynamics.lift_coefficient
    e             = configuration.aircraft_span_efficiency_factor # TODO: get estimate from weissinger
    ar            = geometry.wings[0].aspect_ratio # TODO: get estimate from weissinger
    Mc            = conditions.freestream.mach_number
    #e             = geometry.wings[0].span_efficiency
    
    # start the result
    total_induced_drag = 0.0
    
    #print("In induced_drag_aircraft:")
    #print aircraft_lift
    #for ii in range(len(Mc)):
        #if Mc[ii] < 1.0:
            #total_induced_drag = aircraft_lift**2 / (np.pi*ar*e)
        #else:
            #total_induced_drag = aircraft_lift**2 / (np.pi*ar)
            ##total_induced_drag = aircraft_lift * 0.0
            
    total_induced_drag = np.array([[0.0]]*len(Mc))
    total_induced_drag[Mc < 1.0] = aircraft_lift[Mc < 1.0]**2 / (np.pi*ar*e)
    total_induced_drag[Mc >= 1.0] = aircraft_lift[Mc >= 1.0]**2 / (np.pi*ar*e)
        
    # store data
    try:
        conditions.aerodynamics.drag_breakdown.induced = Results(
            total             = total_induced_drag ,
            efficiency_factor = e                  ,
            aspect_ratio      = ar                 ,
        )
    except:
        print("Drag Polar Mode")     
    
    # done!
    return total_induced_drag
def induced_drag_aircraft(state, settings, geometry):
    """ SUAVE.Methods.induced_drag_aircraft(conditions,configuration,geometry)
        computes the induced drag associated with a wing 
        
        Inputs:
        
        Outputs:
        
        Assumptions:
            based on a set of fits
            
    """

    # unpack inputs
    conditions = state.conditions
    configuration = settings

    aircraft_lift = conditions.aerodynamics.lift_coefficient
    e = configuration.oswald_efficiency_factor
    K = configuration.viscous_lift_dependent_drag_factor
    wing_e = geometry.wings[0].span_efficiency
    ar = geometry.wings[0].aspect_ratio  # TODO: get estimate from weissinger
    CDp = state.conditions.aerodynamics.drag_breakdown.parasite.total

    if e == None:
        e = 1 / ((1 / wing_e) + np.pi * ar * K * CDp)

    # start the result
    total_induced_drag = 0.0

    #print("In induced_drag_aircraft:")
    #print aircraft_lift
    total_induced_drag = aircraft_lift**2 / (np.pi * ar * e)
    #raw_input()

    # store data
    conditions.aerodynamics.drag_breakdown.induced = Results(
        total=total_induced_drag,
        efficiency_factor=e,
        aspect_ratio=ar,
    )

    # done!

    return total_induced_drag
Exemple #8
0
def fuselage_correction(state,settings,geometry):
    
    # unpack
    fus_correction  = settings.fuselage_lift_correction
    Mc              = state.conditions.freestream.mach_number
    AoA             = state.conditions.aerodynamics.angle_of_attack
    
    wings_lift_comp = state.conditions.aerodynamics.lift_coefficient

   
    # total lift, accounting one fuselage
    aircraft_lift_total = wings_lift_comp * fus_correction
    
    # store results
    lift_results = Results(
        total                = aircraft_lift_total ,
        compressible_wings   = wings_lift_comp     ,
    )
    
    state.conditions.aerodynamics.lift_coefficient= aircraft_lift_total

    return aircraft_lift_total
def parasite_drag_propulsor(state,settings,geometry):
#def parasite_drag_propulsor(conditions,configuration,propulsor):
    """ SUAVE.Methods.parasite_drag_propulsor(conditions,configuration,propulsor)
        computes the parasite drag associated with a propulsor 
        
        Inputs:

        Outputs:

        Assumptions:

        
    """



    # unpack inputs
    
    conditions = state.conditions
    configuration = settings
    propulsor = geometry
    
    # unpack inputs
    try:
        form_factor = configuration.propulsor_parasite_drag_form_factor
    except(AttributeError):
        form_factor = 2.3
        
    freestream = conditions.freestream
    
    Sref        = propulsor.nacelle_diameter**2 / 4 * np.pi
    Swet        = propulsor.nacelle_diameter * np.pi * propulsor.engine_length
    
    l_prop  = propulsor.engine_length
    d_prop  = propulsor.nacelle_diameter
    
    # conditions
    Mc  = freestream.mach_number
    roc = freestream.density
    muc = freestream.dynamic_viscosity
    Tc  = freestream.temperature    
    pc  = freestream.pressure

    # reynolds number
    V = Mc * compute_speed_of_sound(Tc, pc) 
    Re_prop = roc * V * l_prop/muc
    
    # skin friction coefficient
    cf_prop, k_comp, k_reyn = compressible_turbulent_flat_plate(Re_prop,Mc,Tc)
    
    # form factor for cylindrical bodies
    try: # Check if propulsor has an intake
        A_max = propulsor.nacelle_diameter
        A_exit = propulsor.A7
        A_inflow = propulsor.Ao
        d_d = 1/((propulsor.engine_length + propulsor.D) / np.sqrt(4/np.pi*(A_max - (A_exit+A_inflow)/2)))
    except:
        d_d = float(d_prop)/float(l_prop)
    D = np.array([[0.0]] * len(Mc))
    a = np.array([[0.0]] * len(Mc))
    du_max_u = np.array([[0.0]] * len(Mc))
    k_prop = np.array([[0.0]] * len(Mc))
    
    D[Mc < 0.95] = np.sqrt(1 - (1-Mc[Mc < 0.95]**2) * d_d**2)
    a[Mc < 0.95] = 2 * (1-Mc[Mc < 0.95]**2) * (d_d**2) *(np.arctanh(D[Mc < 0.95])-D[Mc < 0.95]) / (D[Mc < 0.95]**3)
    du_max_u[Mc < 0.95] = a[Mc < 0.95] / ( (2-a[Mc < 0.95]) * (1-Mc[Mc < 0.95]**2)**0.5 )
    
    D[Mc >= 0.95] = np.sqrt(1 - d_d**2)
    a[Mc >= 0.95] = 2  * (d_d**2) *(np.arctanh(D[Mc >= 0.95])-D[Mc >= 0.95]) / (D[Mc >= 0.95]**3)
    du_max_u[Mc >= 0.95] = a[Mc >= 0.95] / ( (2-a[Mc >= 0.95]) )
    
    k_prop = (1 + form_factor*du_max_u)**2
    
    # --------------------------------------------------------
    # find the final result    
    propulsor_parasite_drag = k_prop * cf_prop * Swet / Sref  
    # --------------------------------------------------------
    
    # dump data to conditions
    propulsor_result = Results(
        wetted_area               = Swet    , 
        reference_area            = Sref    , 
        parasite_drag_coefficient = propulsor_parasite_drag ,
        skin_friction_coefficient = cf_prop ,
        compressibility_factor    = k_comp  ,
        reynolds_factor           = k_reyn  , 
        form_factor               = k_prop  ,
    )
    state.conditions.aerodynamics.drag_breakdown.parasite[propulsor.tag] = propulsor_result    
    
    return propulsor_parasite_drag
Exemple #10
0
def parasite_drag_wing(state, settings, geometry):
    """ SUAVE.Methods.parasite_drag_wing(conditions,configuration,wing)
        computes the parastite drag associated with a wing 
        
        Inputs:
            conditions
            -freestream mach number
            -freestream density
            -freestream dynamic_viscosity
            -freestream temperature
            -freestream pressuve
            
            configuration
            -wing parasite drag form factor
            
            wing
            -S reference
            -mean aerodynamic chord
            -thickness to chord ratio
            -sweep
            -aspect ratio
            -span
            -S exposed
            -S affected
            -transition x
            
        Outputs:
            wing parasite drag coefficient with refernce area as the
            reference area of the input wing

        
        Assumptions:
        
    """

    # unpack inputs
    C = settings.wing_parasite_drag_form_factor
    freestream = state.conditions.freestream

    wing = geometry
    Sref = wing.areas.reference

    # wing
    mac_w = wing.chords.mean_aerodynamic
    t_c_w = wing.thickness_to_chord
    sweep_w = wing.sweep
    arw_w = wing.aspect_ratio
    span_w = wing.spans.projected
    S_exposed_w = wing.areas.exposed  # TODO: calculate by fuselage diameter (in Fidelity_Zero.initialize())
    S_affected_w = wing.areas.affected
    xtu = wing.transition_x_upper
    xtl = wing.transition_x_lower

    # compute wetted area # TODO: calcualte as preprocessing
    Swet = 1. * (1.0 + 0.2 * t_c_w) * S_exposed_w

    # conditions
    Mc = freestream.mach_number
    Tc = freestream.temperature
    re = freestream.reynolds_number

    # reynolds number
    Re_w = re * mac_w

    # skin friction  coefficient, upper
    cf_w_u, k_comp_u, k_reyn_u = compressible_mixed_flat_plate(
        Re_w, Mc, Tc, xtu)

    # skin friction  coefficient, lower
    cf_w_l, k_comp_l, k_reyn_l = compressible_mixed_flat_plate(
        Re_w, Mc, Tc, xtl)

    # correction for airfoils
    k_w = np.array([[0.0]] * len(Mc))

    k_w[Mc < 0.95] = 1. + ( 2.* C * (t_c_w * (np.cos(sweep_w))**2.) ) / ( np.sqrt(1.- Mc[Mc < 0.95]**2. * ( np.cos(sweep_w))**2.) )  \
                     + ( C**2. * (np.cos(sweep_w))**2. * t_c_w**2. * (1. + 5.*(np.cos(sweep_w)**2.)) ) \
                        / (2.*(1.-(Mc[Mc < 0.95]*np.cos(sweep_w))**2.))

    k_w[Mc >= 0.95] = 1.

    # find the final result
    wing_parasite_drag = k_w * cf_w_u * Swet / Sref / 2. + k_w * cf_w_l * Swet / Sref / 2.

    # dump data to conditions
    wing_result = Results(
        wetted_area=Swet,
        reference_area=Sref,
        parasite_drag_coefficient=wing_parasite_drag,
        skin_friction_coefficient=(cf_w_u + cf_w_l) / 2.,
        compressibility_factor=k_comp_u,
        reynolds_factor=k_reyn_l,
        form_factor=k_w,
    )
    state.conditions.aerodynamics.drag_breakdown.parasite[
        wing.tag] = wing_result

    return wing_parasite_drag
def parasite_drag_fuselage(state, settings, geometry):
    """ SUAVE.Methods.parasite_drag_fuselage(conditions,configuration,fuselage)
        computes the parasite drag associated with a fuselage 
        
        Inputs:

        Outputs:

        Assumptions:

        
    """

    # unpack inputs
    configuration = settings
    form_factor = configuration.fuselage_parasite_drag_form_factor
    fuselage = geometry

    freestream = state.conditions.freestream

    Sref = fuselage.areas.front_projected
    Swet = fuselage.areas.wetted

    #l_fus  = fuselage.lengths.cabin
    l_fus = fuselage.lengths.total
    d_fus = fuselage.width
    l_nose = fuselage.lengths.nose
    l_tail = fuselage.lengths.tail

    # conditions
    Mc = freestream.mach_number
    roc = freestream.density
    muc = freestream.dynamic_viscosity
    Tc = freestream.temperature
    pc = freestream.pressure

    # reynolds number
    V = Mc * compute_speed_of_sound(Tc, pc)
    Re_fus = roc * V * l_fus / muc

    # skin friction coefficient
    cf_fus, k_comp, k_reyn = compressible_turbulent_flat_plate(Re_fus, Mc, Tc)

    # form factor for cylindrical bodies
    d_d = float(d_fus) / float(l_fus)
    D = np.array([[0.0]] * len(Mc))
    a = np.array([[0.0]] * len(Mc))
    du_max_u = np.array([[0.0]] * len(Mc))
    k_fus = np.array([[0.0]] * len(Mc))

    D[Mc < 0.95] = np.sqrt(1 - (1 - Mc[Mc < 0.95]**2) * d_d**2)
    a[Mc < 0.95] = 2 * (1 - Mc[Mc < 0.95]**2) * (d_d**2) * (
        np.arctanh(D[Mc < 0.95]) - D[Mc < 0.95]) / (D[Mc < 0.95]**3)
    du_max_u[Mc < 0.95] = a[Mc < 0.95] / ((2 - a[Mc < 0.95]) *
                                          (1 - Mc[Mc < 0.95]**2)**0.5)

    D[Mc >= 0.95] = np.sqrt(1 - d_d**2)
    a[Mc >= 0.95] = 2 * (d_d**2) * (np.arctanh(D[Mc >= 0.95]) -
                                    D[Mc >= 0.95]) / (D[Mc >= 0.95]**3)
    du_max_u[Mc >= 0.95] = a[Mc >= 0.95] / ((2 - a[Mc >= 0.95]))

    k_fus = (1 + form_factor * du_max_u)**2

    #for i in range(len(Mc)):
    #if Mc[i] < 0.95:
    #D[i] = np.sqrt(1 - (1-Mc[i]**2) * d_d**2)
    #a[i]        = 2 * (1-Mc[i]**2) * (d_d**2) *(np.arctanh(D[i])-D[i]) / (D[i]**3)
    #du_max_u[i] = a[i] / ( (2-a[i]) * (1-Mc[i]**2)**0.5 )
    #else:
    #D[i] = np.sqrt(1 - d_d**2)
    #a[i]        = 2  * (d_d**2) *(np.arctanh(D[i])-D[i]) / (D[i]**3)
    #du_max_u[i] = a[i] / ( (2-a[i]) )
    #k_fus[i]    = (1 + cf_fus[i]*du_max_u[i])**2

    # --------------------------------------------------------
    # find the final result

    fuselage_parasite_drag = k_fus * cf_fus * Swet / Sref
    # --------------------------------------------------------

    # dump data to conditions
    fuselage_result = Results(
        wetted_area=Swet,
        reference_area=Sref,
        parasite_drag_coefficient=fuselage_parasite_drag,
        skin_friction_coefficient=cf_fus,
        compressibility_factor=k_comp,
        reynolds_factor=k_reyn,
        form_factor=k_fus,
    )
    try:
        state.conditions.aerodynamics.drag_breakdown.parasite[
            fuselage.tag] = fuselage_result
    except:
        print("Drag Polar Mode fuse parasite")

    return fuselage_parasite_drag
Exemple #12
0
def windmilling_drag(geometry,state):
    """ SUAVE.Methods.Aerodynamics.Fidelity_Zero.Drag.windmilling_drag(geometry,state):
        Computes the windmilling drag of turbofan engines

        Inputs:
            geometry   - data dictionary with data of vehicle and engine
            state      - to output drag breakdown

        Outputs:
            windmilling_drag

        Assumptions:
"""
    # ==============================================
	# Unpack
    # ==============================================
    vehicle = geometry

    # Defining reference area
    if vehicle.reference_area:
            reference_area = vehicle.reference_area
    else:
        n_wing = 0
        for wing in vehicle.wings:
            if not isinstance(wing,Wings.Main_Wing): continue
            n_wing = n_wing + 1
            reference_area = wing.sref
        if n_wing > 1:
            print ' More than one Main_Wing in the vehicle. Last one will be considered.'
        elif n_wing == 0:
            print  'No Main_Wing defined! Using the 1st wing found'
            for wing in vehicle.wings:
                if not isinstance(wing,Wings.Wing): continue
                reference_area = wing.sref
                break

    # getting geometric data from engine (estimating when not available)
    for idx,propulsor in enumerate(vehicle.propulsors):
        try:
            swet_nac = propulsor.areas.wetted
        except:
            try:
                D_nac = propulsor.nacelle_diameter
                if propulsor.engine_length <> 0.:
                    l_nac = propulsor.engine_length
                else:
                    try:
                        MMO = vehicle.max_mach_operational
                    except:
                        MMO = 0.84
                    D_nac_in = D_nac / Units.inches
                    l_nac = (2.36 * D_nac_in - 0.01*(D_nac_in*MMO)**2) * Units.inches
            except AttributeError:
                print 'Error calculating windmilling drag. Engine dimensions missing.'
            swet_nac = 5.62 * D_nac * l_nac

    # Compute
    windmilling_drag_coefficient = 0.007274 * swet_nac / reference_area

    # dump data to state
    windmilling_result = Results(
        wetted_area                  = swet_nac    ,
        windmilling_drag_coefficient = windmilling_drag_coefficient ,
    )
    state.conditions.aerodynamics.drag_breakdown.windmilling_drag = windmilling_result

    return windmilling_drag_coefficient
Exemple #13
0
def compute_aircraft_lift(conditions, configuration, geometry):
    """ SUAVE.Methods.Aerodynamics.compute_aircraft_lift(conditions,configuration,geometry)
        computes the lift associated with an aircraft 
        
        Inputs:
            conditions - data dictionary with fields:
                mach_number - float or 1D array of freestream mach numbers
                angle_of_attack - floar or 1D array of angle of attacks
                
            configuration - data dictionary with fields:
                surrogate_models.lift_coefficient - a callable function or class 
                    with inputs of angle of attack and outputs of lift coefficent
                fuselage_lift_correction - the correction to fuselage contribution to lift
                    
            geometry - used for wing
            
        
        Outputs:
            CL - float or 1D array of lift coefficients of the total aircraft
        
        Updates:
            conditions.lift_breakdown - stores results here
            
        Assumptions:
            surrogate model returns total incompressible lift due to wings
            prandtl-glaurert compressibility correction on this
            fuselage contribution to lift correction as a factor
        
    """

    # unpack
    fus_correction = configuration.fuselage_lift_correction
    Mc = conditions.freestream.mach_number
    AoA = conditions.aerodynamics.angle_of_attack

    # pack for interpolate
    X_interp = AoA

    wings_lift = np.array([[0.0]] * len(Mc))
    wings_lift_comp = np.array([[0.0]] * len(Mc))
    compress_corr = np.array([[0.0]] * len(Mc))
    aircraft_lift_total = np.array([[0.0]] * len(Mc))
    vortex_cl = np.array([[0.0]] * len(Mc))
    #print aircraft_lift_total
    wing = geometry.wings[0]

    # Subsonic setup
    wings_lift = conditions.aerodynamics.lift_breakdown.inviscid_wings_lift
    compress_corr[Mc < 0.95] = 1. / (np.sqrt(1. - Mc[Mc < 0.95]**2.))
    compress_corr[Mc >= 0.95] = 1. / (
        np.sqrt(1. - 0.95**2)
    )  # Values for Mc > 1.05 are update after this assignment
    # wings_lift[Mc <= 1.05] = wings_lift_model(X_interp[Mc <= 1.05])
    if wing.vortex_lift is True:
        vortex_cl[Mc < 1.0] = vortex_lift(X_interp[Mc < 1.0], configuration,
                                          wing)  # This was initialized at 0.0
    wings_lift[Mc <= 1.05] = wings_lift[Mc <= 1.05] + vortex_cl[Mc <= 1.05]

    # Supersonic setup
    # wings_lift_model = configuration.surrogate_models_sup.lift_coefficient
    compress_corr[Mc > 1.05] = 1. / (np.sqrt(Mc[Mc > 1.05]**2. - 1.))
    # wings_lift[Mc > 1.05] = wings_lift_model(X_interp[Mc > 1.05])

    wings_lift_comp = wings_lift * compress_corr

    aircraft_lift_total = wings_lift_comp * fus_correction
    # store results
    lift_results = Results(
        total=aircraft_lift_total,
        incompressible_wings=wings_lift,
        compressible_wings=wings_lift_comp,
        compressibility_correction_factor=compress_corr,
        fuselage_correction_factor=fus_correction,
        vortex=vortex_cl,
    )
    conditions.aerodynamics.lift_breakdown.update(lift_results)  #update

    conditions.aerodynamics.lift_coefficient = aircraft_lift_total

    return aircraft_lift_total
Exemple #14
0
def parasite_drag_pylon(state, settings, geometry):
    """ SUAVE.Methods.parasite_drag_pylon(conditions,configuration,geometry):
        Simplified estimation, considering pylon drag a fraction of the nacelle drag

        Inputs:
            conditions      - data dictionary for output dump
            configuration   - not in use
            geometry        - SUave type vehicle

        Outpus:
            cd_misc  - returns the miscellaneous drag associated with the vehicle

        Assumptions:
            simplified estimation, considering pylon drag a fraction of the nacelle drag

    """
    # unpack

    conditions = state.conditions
    configuration = settings

    pylon_factor = 0.20  # 20% of propulsor drag
    n_propulsors = len(
        geometry.propulsors
    )  # number of propulsive system in vehicle (NOT # of ENGINES)
    pylon_parasite_drag = 0.00
    pylon_wetted_area = 0.00
    pylon_cf = 0.00
    pylon_compr_fact = 0.00
    pylon_rey_fact = 0.00
    pylon_FF = 0.00

    # Estimating pylon drag
    for propulsor in geometry.propulsors:
        ref_area = propulsor.nacelle_diameter**2 / 4 * np.pi
        pylon_parasite_drag += pylon_factor * conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.tag].parasite_drag_coefficient * (
                ref_area / geometry.reference_area *
                propulsor.number_of_engines)
        pylon_wetted_area += pylon_factor * conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.tag].wetted_area * propulsor.number_of_engines
        pylon_cf += conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.tag].skin_friction_coefficient
        pylon_compr_fact += conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.tag].compressibility_factor
        pylon_rey_fact += conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.tag].reynolds_factor
        pylon_FF += conditions.aerodynamics.drag_breakdown.parasite[
            propulsor.tag].form_factor

    pylon_cf /= n_propulsors
    pylon_compr_fact /= n_propulsors
    pylon_rey_fact /= n_propulsors
    pylon_FF /= n_propulsors

    # dump data to conditions
    pylon_result = Results(
        wetted_area=pylon_wetted_area,
        reference_area=geometry.reference_area,
        parasite_drag_coefficient=pylon_parasite_drag,
        skin_friction_coefficient=pylon_cf,
        compressibility_factor=pylon_compr_fact,
        reynolds_factor=pylon_rey_fact,
        form_factor=pylon_FF,
    )
    conditions.aerodynamics.drag_breakdown.parasite['pylon'] = pylon_result

    return pylon_parasite_drag
def compressibility_drag_wing(conditions, configuration, geometry):
    """ SUAVE.Methods.compressibility_drag_wing(conditions,configuration,geometry)
        computes the induced drag associated with a wing 
        
        Inputs:
        
        Outputs:
        
        Assumptions:
            based on a set of fits
            
    """

    # unpack
    wings = geometry.Wings
    fuselages = geometry.Fuselages
    wing_lifts = conditions.aerodynamics.lift_breakdown.compressible_wings  # currently the total aircraft lift
    mach = conditions.freestream.mach_number
    drag_breakdown = conditions.aerodynamics.drag_breakdown

    # start result
    total_compressibility_drag = 0.0
    drag_breakdown.compressible = Results()

    # go go go
    for i_wing, wing, in enumerate(wings.values()):

        # unpack wing
        t_c_w = wing.t_c
        sweep_w = wing.sweep
        Mc = copy.copy(mach)

        for ii in range(len(Mc)):
            if Mc[ii] > 0.95 and Mc[ii] < 1.05:
                Mc[ii] = 0.95

            if Mc[ii] <= 0.95:

                if i_wing == 0:
                    cl_w = wing_lifts
                else:
                    cl_w = 0

                # get effective Cl and sweep
                tc = t_c_w / (np.cos(sweep_w))
                cl = cl_w / (np.cos(sweep_w))**2

                # compressibility drag based on regressed fits from AA241
                mcc_cos_ws = 0.922321524499352       \
                           - 1.153885166170620*tc    \
                           - 0.304541067183461*cl    \
                           + 0.332881324404729*tc**2 \
                           + 0.467317361111105*tc*cl \
                           + 0.087490431201549*cl**2

                # crest-critical mach number, corrected for wing sweep
                mcc = mcc_cos_ws / np.cos(sweep_w)

                # divergence mach number
                MDiv = mcc * (1.02 + 0.08 * (1 - np.cos(sweep_w)))

                # divergence ratio
                mo_mc = mach / mcc

                # compressibility correlation, Shevell
                dcdc_cos3g = 0.0019 * mo_mc**14.641

                # compressibility drag
                cd_c = dcdc_cos3g * (np.cos(sweep_w))**3

            else:
                cd_lift_wave = wave_drag_lift(conditions, configuration, wing)
                cd_volume_wave = wave_drag_volume(conditions, configuration,
                                                  wing)
                cd_c = cd_lift_wave + cd_volume_wave
                tc = 0
                sweep_w = 0
                mcc = 0
                MDiv = 0

            # increment
            #total_compressibility_drag += cd_c  ## todo when there is a lift break down by wing

            # dump data to conditions
            wing_results = Results(
                compressibility_drag=cd_c,
                thickness_to_chord=tc,
                wing_sweep=sweep_w,
                crest_critical=mcc,
                divergence_mach=MDiv,
            )
            #drag_breakdown.compressible[wing.tag] = wing_results

    #: for each wing

    # dump total comp drag
    total_compressibility_drag = drag_breakdown.compressible[
        1 + 0].compressibility_drag
    drag_breakdown.compressible.total = total_compressibility_drag

    return total_compressibility_drag, wing_results
def compressibility_drag_wing(state, settings, geometry):
    #def compressibility_drag_wing(conditions,configuration,geometry):
    """ SUAVE.Methods.compressibility_drag_wing(conditions,configuration,geometry)
        computes the induced drag associated with a wing 
        
        Inputs:
        
        Outputs:
        
        Assumptions:
            based on a set of fits
            
    """

    # unpack
    conditions = state.conditions
    configuration = settings

    wing = geometry
    if isinstance(wing, Wings.Main_Wing):
        wing_lifts = conditions.aerodynamics.lift_breakdown.compressible_wings  # currently the total aircraft lift
    elif wing.vertical:
        wing_lifts = 0
    else:
        wing_lifts = 0.15 * conditions.aerodynamics.lift_breakdown.compressible_wings

    mach = conditions.freestream.mach_number
    drag_breakdown = conditions.aerodynamics.drag_breakdown

    # start result
    total_compressibility_drag = 0.0
    #drag_breakdown.compressible = Results()

    # unpack wing
    t_c_w = wing.thickness_to_chord
    sweep_w = wing.sweep

    # Currently uses vortex lattice model on all wings
    if wing.tag == 'main_wing':
        cl_w = wing_lifts
    else:
        cl_w = 0

    # get effective Cl and sweep
    tc = t_c_w / (np.cos(sweep_w))
    cl = cl_w / (np.cos(sweep_w))**2

    # compressibility drag based on regressed fits from AA241
    mcc_cos_ws = 0.922321524499352       \
               - 1.153885166170620*tc    \
               - 0.304541067183461*cl    \
               + 0.332881324404729*tc**2 \
               + 0.467317361111105*tc*cl \
               + 0.087490431201549*cl**2

    # crest-critical mach number, corrected for wing sweep
    mcc = mcc_cos_ws / np.cos(sweep_w)

    # divergence mach number
    MDiv = mcc * (1.02 + 0.08 * (1 - np.cos(sweep_w)))

    # divergence ratio
    mo_mc = mach / mcc

    # compressibility correlation, Shevell
    dcdc_cos3g = 0.0019 * mo_mc**14.641

    # compressibility drag
    cd_c = dcdc_cos3g * (np.cos(sweep_w))**3

    # increment
    #total_compressibility_drag += cd_c

    # dump data to conditions
    wing_results = Results(
        compressibility_drag=cd_c,
        thickness_to_chord=tc,
        wing_sweep=sweep_w,
        crest_critical=mcc,
        divergence_mach=MDiv,
    )
    drag_breakdown.compressible[wing.tag] = wing_results

    # dump total comp drag
    #drag_breakdown.compressible.total = total_compressibility_drag
    #conditions.aerodynamics.drag_breakdown.compressible[wing.tag] = wing_results
    #conditions.aerodynamics.drag_breakdown.compressible.total = total_compressibility_drag

    return total_compressibility_drag
Exemple #17
0
def parasite_drag_fuselage(state, settings, geometry):
    """ SUAVE.Methods.parasite_drag_fuselage(conditions,configuration,fuselage)
        computes the parasite drag associated with a fuselage 
        
        Inputs:

        Outputs:

        Assumptions:

        
    """

    # unpack inputs
    conditions = state.conditions
    configuration = settings
    fuselage = geometry

    form_factor = configuration.fuselage_parasite_drag_form_factor
    freestream = conditions.freestream
    Sref = fuselage.areas.front_projected
    Swet = fuselage.areas.wetted

    l_fus = fuselage.lengths.cabin
    d_fus = fuselage.effective_diameter
    l_nose = fuselage.lengths.nose
    l_tail = fuselage.lengths.tail

    # conditions
    Mc = freestream.mach_number
    Tc = freestream.temperature
    re = freestream.reynolds_number

    # reynolds number
    Re_fus = re * (l_fus + l_nose + l_tail)

    # skin friction coefficient
    cf_fus, k_comp, k_reyn = compressible_turbulent_flat_plate(Re_fus, Mc, Tc)

    # form factor for cylindrical bodies
    d_d = float(d_fus) / float(l_fus)
    D = np.sqrt(1 - (1 - Mc**2) * d_d**2)
    a = 2 * (1 - Mc**2) * (d_d**2) * (np.arctanh(D) - D) / (D**3)
    du_max_u = a / ((2 - a) * (1 - Mc**2)**0.5)
    k_fus = (1 + form_factor * du_max_u)**2

    # find the final result
    fuselage_parasite_drag = k_fus * cf_fus * Swet / Sref

    # dump data to conditions
    fuselage_result = Results(
        wetted_area=Swet,
        reference_area=Sref,
        parasite_drag_coefficient=fuselage_parasite_drag,
        skin_friction_coefficient=cf_fus,
        compressibility_factor=k_comp,
        reynolds_factor=k_reyn,
        form_factor=k_fus,
    )
    state.conditions.aerodynamics.drag_breakdown.parasite[
        fuselage.tag] = fuselage_result

    return fuselage_parasite_drag
def miscellaneous_drag_aircraft(state, settings, geometry):
    """ SUAVE.Methods.miscellaneous_drag_aircraft(Wing,segment)
        computes the miscellaneous drag associated with an aircraft
        
        Inputs:
            aircraft- An aircraft object is passed in
            segment - the segment object contains information regarding the mission segment
            Cl - wing Cl
        Outpus:
            cd_misc  - returns the miscellaneous drag assoicated with the wing
            
            >> try to minimize outputs
            >> pack up outputs into Data() if needed
        
        Assumptions:
            if needed
        
    """

    # unpack inputs
    configuration = settings

    trim_correction_factor = configuration.trim_drag_correction_factor
    propulsors = geometry.propulsors
    vehicle_reference_area = geometry.reference_area
    ones_1col = state.conditions.freestream.mach_number * 0. + 1

    conditions = state.conditions

    # ------------------------------------------------------------------
    #   Control surface gap drag
    # ------------------------------------------------------------------
    #f_gaps_w=0.0002*(numpy.cos(sweep_w))**2*S_affected_w
    #f_gaps_h=0.0002*(numpy.cos(sweep_h))**2*S_affected_h
    #f_gaps_v=0.0002*(numpy.cos(sweep_v))**2*S_affected_v

    #f_gapst = f_gaps_w + f_gaps_h + f_gaps_v

    # TODO: do this correctly
    total_gap_drag = 0.0001

    # ------------------------------------------------------------------
    #   Nacelle base drag
    # ------------------------------------------------------------------
    total_nacelle_base_drag = 0.0
    nacelle_base_drag_results = Results()

    for propulsor in propulsors.values():

        # calculate
        nacelle_base_drag = 0.5 / 12. * np.pi * propulsor.nacelle_diameter * 0.2 / vehicle_reference_area

        # dump
        nacelle_base_drag_results[
            propulsor.tag] = nacelle_base_drag * ones_1col

        # increment
        total_nacelle_base_drag += nacelle_base_drag

    # ------------------------------------------------------------------
    #   Fuselage upsweep drag
    # ------------------------------------------------------------------
    fuselage_upsweep_drag = 0.006 / vehicle_reference_area

    # ------------------------------------------------------------------
    #   Fuselage base drag
    # ------------------------------------------------------------------
    fuselage_base_drag = 0.0

    # ------------------------------------------------------------------
    #   The final result
    # ------------------------------------------------------------------

    total_miscellaneous_drag = total_gap_drag          \
                             + total_nacelle_base_drag \
                             + fuselage_upsweep_drag   \
                             + fuselage_base_drag

    # dump to results
    conditions.aerodynamics.drag_breakdown.miscellaneous = Results(
        fuselage_upsweep=fuselage_upsweep_drag * ones_1col,
        nacelle_base=nacelle_base_drag_results,
        fuselage_base=fuselage_base_drag * ones_1col,
        control_gaps=total_gap_drag * ones_1col,
        total=total_miscellaneous_drag * ones_1col,
    )

    return total_miscellaneous_drag * ones_1col
Exemple #19
0
def compressibility_drag_total(state,settings,geometry):
    """ SUAVE.Methods.compressibility_drag_total_supersonic(conditions,configuration,geometry)
        computes the compressibility drag on a full aircraft

        Inputs:
            wings
    fuselages
    propulsors
    freestream conditions

        Outputs:
    compressibility drag coefficient

        Assumptions:
            drag is only calculated for the wings, main fuselage, and propulsors
    main fuselage must have tag 'fuselage'
    no lift on wings other than main wing

    """

    # Unpack
    conditions    = state.conditions
    configuration = settings
    
    wings       = geometry.wings
    fuselages   = geometry.fuselages
    propulsor   = geometry.propulsors[0]

    Mc             = conditions.freestream.mach_number
    drag_breakdown = conditions.aerodynamics.drag_breakdown

    # Initialize result
    drag_breakdown.compressible = Results()

    # Iterate through wings
    for i_wing, wing, in enumerate(wings.values()):

        # initialize array to correct length
        cd_c = np.array([[0.0]] * len(Mc))
        mcc = np.array([[0.0]] * len(Mc))
        MDiv = np.array([[0.0]] * len(Mc))     

        # Use main wing reference area for drag coefficients
        if i_wing == 0:
            Sref_main = wing.areas.reference

        # Get main fuselage data - note that name of fuselage is important here
        # This should be changed to be general 
        main_fuselage = fuselages['fuselage']

        # Get number of engines data
        num_engines = propulsor.number_of_engines

        # Get the lift coefficient of the wing.
        # Note that this is not the total CL
        cl = conditions.aerodynamics.lift_breakdown.compressible_wings

        # Calculate compressibility drag at Mach 0.99 and 1.05 for interpolation between
        (drag99,a,b) = drag_div(np.array([[0.99]] * len(Mc)),wing,i_wing,cl,Sref_main)
        (drag105,a,b) = wave_drag(conditions, 
                                  configuration, 
                                  main_fuselage, 
                                  propulsor, 
                                  wing, 
                                  num_engines,i_wing,Sref_main,True)

        # For subsonic mach numbers, use drag divergence correlations to find the drag
        (cd_c[Mc <= 0.99],mcc[Mc <= 0.99], MDiv[Mc <= 0.99]) = drag_div(Mc[Mc <= 0.99],wing,i_wing,cl[Mc <= 0.99],Sref_main)

        # For mach numbers close to 1, use an interpolation to avoid intensive calculations
        cd_c[Mc > 0.99] = drag99[Mc > 0.99] + (drag105[Mc > 0.99]-drag99[Mc > 0.99])*(Mc[Mc > 0.99]-0.99)/(1.05-0.99)

        # Use wave drag equations at supersonic values. The cutoff for this function is 1.05
        # Only the supsonic results are returned with nonzero values
        (cd_c_sup,mcc_sup,MDiv_sup) = wave_drag(conditions, 
                                                configuration, 
                                                main_fuselage, 
                                                propulsor, 
                                                wing, 
                                                num_engines,i_wing,Sref_main,False)

        # Incorporate supersonic results into total compressibility drag coefficient
        (cd_c[Mc >= 1.05],mcc[Mc >= 1.05], MDiv[Mc >= 1.05]) = (cd_c_sup[Mc >= 1.05],mcc_sup[Mc >= 1.05],MDiv_sup[Mc >= 1.05])

        # Dump data to conditions
        wing_results = Results(
            compressibility_drag      = cd_c    ,
            crest_critical            = mcc     ,
            divergence_mach           = MDiv    ,
        )
        drag_breakdown.compressible[wing.tag] = wing_results        
    
    # Initialize arrays
    mach       = conditions.freestream.mach_number
    prop_drag = np.array([[0.0]] * len(mach))
    fuse_drag = np.array([[0.0]] * len(mach))

    # Fuselage wave drag
    if len(main_fuselage) > 0:
        fuse_drag[mach >= 1.05] = wave_drag_body_of_rev(main_fuselage.lengths.total,main_fuselage.effective_diameter/2.0,Sref_main)
    else:
        raise ValueError('Main fuselage does not have a total length')

    # Propulsor wave drag	
    prop_drag[mach >= 1.05] = wave_drag_body_of_rev(propulsor.engine_length,propulsor.nacelle_diameter/2.0,Sref_main)*propulsor.number_of_engines

    # Pack values
    #cd_c[mach >= 1.05] = cd_c[mach >= 1.05] + fuse_drag[mach >= 1.05]
    #cd_c[mach >= 1.05] = cd_c[mach >= 1.05] + prop_drag[mach >= 1.05]   
    drag_breakdown.compressible[main_fuselage.tag] = fuse_drag
    drag_breakdown.compressible[propulsor.tag] = prop_drag

    # Dump total comp drag
    total_compressibility_drag = 0.0

    for jj in range(0,i_wing+1):
        total_compressibility_drag = drag_breakdown.compressible[jj].compressibility_drag + total_compressibility_drag
    total_compressibility_drag = total_compressibility_drag + fuse_drag
    total_compressibility_drag = total_compressibility_drag + prop_drag
    drag_breakdown.compressible.total = total_compressibility_drag

    return total_compressibility_drag