コード例 #1
0
 def evaluate(self, *args, **kwarg):
     """This is used to execute the evaluate functions of the analyses
         stored in the container.
                                             
             Assumptions:
             None
                                             
             Source:
             N/A
                                             
             Inputs:
             None
                                             
             Outputs:
             Results of the Evaluate Functions
                                             
             Properties Used:
             N/A
         """
     results = Results()
     for tag, analysis in self.items():
         if hasattr(analysis, 'evaluate'):
             result = analysis.evaluate(*args, **kwarg)
         else:
             result = analysis(*args, **kwarg)
         results[tag] = result
     return results
コード例 #2
0
    def evaluate(self, state, settings, geometry):
        """Evaluates preset processes for each component.

        Assumptions:
        None

        Source:
        N/A

        Inputs:
        state     (passed to an evaluation function)
        setting   (passed to an evaluation function)
        geometry  (used to get keys and passed to an evaluation function)

        Outputs:
        None

        Properties Used:
        self.geometry_key <string>
        """
        geometry_items = geometry.deep_get(self.geometry_key)

        results = Results()

        for key, this_geometry in geometry_items.items():
            result = Process.evaluate(self, state, settings, this_geometry)
            results[key] = result

        return results
コード例 #3
0
def miscellaneous_drag_aircraft_ESDU(state, settings, geometry):
    """Computes the miscellaneous drag associated with an aircraft

    Assumptions:
    Basic fit

    Source:
    ESDU 94044, figure 1

    Inputs:
    state.conditions.freestream.mach_number    [Unitless] (actual values not used)
    geometry.reference_area                    [m^2]
    geometry.wings.areas.wetted                [m^2]
    geometry.fuselages.areas.wetted            [m^2]
    geometry.propulsor.areas.wetted            [m^2]
    geometry.propulsor.number_of_engines       [Unitless]

    Outputs:
    cd_excrescence (drag)                      [Unitless]

    Properties Used:
    N/A
    """

    # 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
コード例 #4
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
コード例 #5
0
def wave_drag_lift(conditions, configuration, wing):
    """Computes wave drag due to lift

    Assumptions:
    Simplified equations

    Source:
    http://adg.stanford.edu/aa241/drag/ssdragcalc.html

    Inputs:
    conditions.freestream.mach_number        [Unitless]
    conditions.aerodynamics.lift_coefficient [Unitless]
    wing.total_length                        [m]
    wing.areas.reference                     [m^2]

    Outputs:
    wave_drag_lift                           [Unitless]

    Properties Used:
    N/A
    """

    # 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
    if wing.vertical:
        CL = np.zeros_like(conditions.aerodynamics.lift_coefficient)
    else:
        # get wing specific CL
        CL = conditions.aerodynamics.lift_breakdown.inviscid_wings_lift[
            wing.tag]

    # 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
コード例 #6
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
コード例 #7
0
ファイル: Analysis.py プロジェクト: sirigatti/SUAVE
 def evaluate(self,*args,**kwarg):
     results = Results()
     for tag,analysis in self.items(): 
         if hasattr(analysis,'evaluate'):
             result = analysis.evaluate(*args,**kwarg)
         else:
             result = analysis(*args,**kwarg)
         results[tag] = result
     return results
コード例 #8
0
ファイル: Process_Geometry.py プロジェクト: sirigatti/SUAVE
    def evaluate(self, state, settings, geometry):

        geometry_items = geometry.deep_get(self.geometry_key)

        results = Results()

        for key, this_geometry in geometry_items.items():
            result = Process.evaluate(self, state, settings, this_geometry)
            results[key] = result

        return results
コード例 #9
0
def miscellaneous_drag_aircraft_ESDU(state,settings,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
コード例 #10
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
コード例 #11
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
コード例 #12
0
def induced_drag_aircraft(state,settings,geometry):
    """Determines induced drag for the full aircraft

    Assumptions:
    Based on fits

    Source:
    adg.stanford.edu (Stanford AA241 A/B Course Notes)

    Inputs:
    state.conditions.aerodynamics.lift_coefficient               [Unitless]
    state.conditions.aerodynamics.drag_breakdown.parasite.total  [Unitless]
    configuration.oswald_efficiency_factor                       [Unitless]
    configuration.viscous_lift_dependent_drag_factor             [Unitless]
    geometry.wings['main_wing'].span_efficiency                  [Unitless]
    geometry.wings['main_wing'].aspect_ratio                     [Unitless]

    Outputs:
    total_induced_drag                                           [Unitless]

    Properties Used:
    N/A
    """

    # 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['main_wing'].span_efficiency
    ar            = geometry.wings['main_wing'].aspect_ratio 
    CDp           = state.conditions.aerodynamics.drag_breakdown.parasite.total
    
    if e == None:
        e = 1/((1/wing_e)+np.pi*ar*K*CDp)    
    
    total_induced_drag = aircraft_lift**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")     
    
    return total_induced_drag
コード例 #13
0
 def evaluate(self, condtitions):
     """Evaluate the Geometry analysis.
         
             Assumptions:
             None
         
             Source:
             N/A
         
             Inputs:
             None
         
             Outputs:
             Results of the Geometry Analysis
         
             Properties Used:
             N/A                
         """
     return Results()
コード例 #14
0
 def evaluate(self, conditions):
     """Evaluate the Structures analysis.
         
             Assumptions:
             None
         
             Source:
             N/A
         
             Inputs:
             None
         
             Outputs:
             Results of the Structures Analysis
         
             Properties Used:
             N/A                
         """
     return Results()
コード例 #15
0
 def evaluate(self, *args, **kwarg):
     """This is used to execute the analysis' specific algorithms.
             
             Assumptions:
             None
             
             Source:
             N/A
             
             Inputs:
             None
             
             Outputs:
             None
             
             Properties Used:
             N/A
         """
     raise NotImplementedError
     return Results()
コード例 #16
0
ファイル: induced_drag_aircraft.py プロジェクト: rreis/SUAVE
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['main_wing'].span_efficiency
    ar = geometry.wings['main_wing'].aspect_ratio
    CDp = state.conditions.aerodynamics.drag_breakdown.parasite.total

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

    total_induced_drag = aircraft_lift**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")

    return total_induced_drag
コード例 #17
0
ファイル: Stability.py プロジェクト: ocornes/SUAVE
    def evaluate(self, conditions):
        """Evaluate the stability analysis.
    
        Assumptions:
        None

        Source:
        N/A

        Inputs:
        None

        Outputs:
        results

        Properties Used:
        N/A
        """
        results = Results()

        return results
コード例 #18
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
コード例 #19
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.total
    d_fus = fuselage.effective_diameter

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

    # reynolds number
    Re_fus = re * (l_fus)

    # 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
コード例 #20
0
def windmilling_drag(geometry,state):
    """Computes windmilling drag for turbofan engines

    Assumptions:
    None

    Source:
    http://www.dept.aoe.vt.edu/~mason/Mason_f/AskinThesis2002_13.pdf
    
    Inputs:
    geometry.
      max_mach_operational        [Unitless]
      reference_area              [m^2]
      wings.sref                  [m^2]
      propulsors. 
        areas.wetted              [m^2]
        nacelle_diameter          [m^2]
        engine_length             [m^2]

    Outputs:
    windmilling_drag_coefficient  [Unitless]

    Properties Used:
    N/A
    """    
    # ==============================================
	# 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
コード例 #21
0
def miscellaneous_drag_aircraft(state, settings, geometry):
    """Computes the miscellaneous drag associated with an aircraft

    Assumptions:
    Basic fit

    Source:
    adg.stanford.edu (Stanford AA241 A/B Course Notes)

    Inputs:
    configuration.trim_drag_correction_factor  [Unitless]
    geometry.propulsors.nacelle_diameter       [m]
    geometry.reference_area                    [m^2]
    geometry.wings['main_wing'].aspect_ratio   [Unitless]
    state.conditions.freestream.mach_number    [Unitless] (actual values are not used)

    Outputs:
    total_miscellaneous_drag                   [Unitless]

    Properties Used:
    N/A
    """

    # 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.000

    # ------------------------------------------------------------------
    #   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
コード例 #22
0
def parasite_drag_propulsor(state, settings, geometry):
    """Computes the parasite drag due to the propulsor

    Assumptions:
    Basic fit

    Source:
    adg.stanford.edu (Stanford AA241 A/B Course Notes)

    Inputs:
    state.conditions.freestream.
      mach_number                                [Unitless]
      temperature                                [K]
      reynolds_number                            [Unitless]
    geometry.      
      nacelle_diameter                           [m^2]
      areas.wetted                               [m^2]
      engine_length                              [m]

    Outputs:
    propulsor_parasite_drag                      [Unitless]

    Properties Used:
    N/A
    """

    # 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
コード例 #23
0
def pre_stall_coefficients(state,settings,geometry):
    """Uses the AERODAS method to determine prestall parameters for lift and drag for a single wing

    Assumptions:
    None

    Source:
    NASA TR: "Models of Lift and Drag Coefficients of Stalled and Unstalled Airfoils in
      Wind Turbines and Wind Tunnels" by D. A. Spera

    Inputs:
    state.conditions.aerodynamics.angle_of_attack
    settings.section_zero_lift_angle_of_attack
    geometry.
      section.
        angle_attack_max_prestall_lift
        zero_lift_drag_coefficient
      pre_stall_maximum_drag_coefficient_angle
      pre_stall_maximum_lift_coefficient
      pre_stall_lift_curve_slope 
      pre_stall_maximum_lift_drag_coefficient

    Outputs:
    CL1 (coefficient of lift)                       [Unitless]
    CD1 (coefficient of drag)                       [Unitless]
    (packed in state.conditions.aerodynamics.pre_stall_coefficients[geometry.tag])

    Properties Used:
    N/A
    """  
    
    # unpack inputs
    wing   = geometry
    alpha  = state.conditions.aerodynamics.angle_of_attack * 1.0
    A0     = settings.section_zero_lift_angle_of_attack
    ACL1   = wing.section.angle_attack_max_prestall_lift 
    ACD1   = wing.pre_stall_maximum_drag_coefficient_angle
    CL1max = wing.pre_stall_maximum_lift_coefficient
    CD0    = wing.section.zero_lift_drag_coefficient
    S1     = wing.pre_stall_lift_curve_slope  
    CD1max = wing.pre_stall_maximum_lift_drag_coefficient
    
    if wing.vertical == True:
        alpha = 0. * np.ones_like(alpha)
        
        
    # Equation 6c
    RCL1          = S1*(ACL1-A0)-CL1max
    RCL1[RCL1<=0] = 1.e-16
    
    # Equation 6d
    N1            = 1 + CL1max/RCL1
    
    # Equation 6a or 6b depending on the alpha
    CL1            = 0.0 * np.ones_like(state.conditions.freestream.altitude)
    CL1[alpha>A0]  = S1*(alpha[alpha>A0]-A0)-RCL1[alpha>A0]*((alpha[alpha>A0]-A0)/(ACL1[alpha>A0]-A0))**N1[alpha>A0]
    CL1[alpha==A0] = 0.0
    CL1[alpha<A0]  = S1*(alpha[alpha<A0]-A0)+RCL1[alpha<A0]*((A0-alpha[alpha<A0])/(ACL1[alpha<A0]-A0))**N1[alpha<A0]
    
    # M what is m?
    M              = 2.0 # Does this need changing

    # Equation 7a
    con      = np.logical_and((2*A0-ACD1)<=alpha,alpha<=ACD1)
    CD1      = np.ones_like(state.conditions.freestream.altitude)
    CD1[con] = CD0[con] + (CD1max[con]-CD0[con])*((alpha[con] -A0)/(ACD1[con]-A0))**M    
    
    # Equation 7b
    CD1[np.logical_not(con)] = 0.
    
    # Pack outputs
    wing_result = Results(
        lift_coefficient = CL1,
        drag_coefficient = CD1
        )

    state.conditions.aerodynamics.pre_stall_coefficients[wing.tag] =  wing_result
    

    return CL1, CD1
コード例 #24
0
    def evaluate(self, conditions):

        results = Results()

        return results
コード例 #25
0
def parasite_drag_propulsor(state, settings, geometry):
    """Computes the parasite drag due to the propulsor

    Assumptions:
    Basic fit

    Source:
    Raymer equation (pg 283 of Aircraft Design: A Conceptual Approach) (subsonic)
    http://adg.stanford.edu/aa241/drag/BODYFORMFACTOR.HTML (supersonic)

    Inputs:
    state.conditions.freestream.
      mach_number                                [Unitless]
      temperature                                [K]
      reynolds_number                            [Unitless]
    geometry.      
      nacelle_diameter                           [m^2]
      areas.wetted                               [m^2]
      engine_length                              [m]
    state.conditions.aerodynamics.drag_breakdown.
      compressible.main_wing.divergence_mach     [Unitless]

    Outputs:
    propulsor_parasite_drag                      [Unitless]

    Properties Used:
    N/A
    """

    # unpack inputs

    conditions = state.conditions
    configuration = settings
    propulsor = geometry

    freestream = conditions.freestream

    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)

    k_prop = np.array([[0.0]] * len(Mc))
    # assume that the drag divergence mach number of the propulsor matches the main wing
    Mdiv = state.conditions.aerodynamics.drag_breakdown.compressible.main_wing.divergence_mach

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

    # for supersonic flow (http://adg.stanford.edu/aa241/drag/BODYFORMFACTOR.HTML)
    k_prop_sup = 1.

    sb_mask = (Mc <= Mdiv)
    tn_mask = ((Mc > Mdiv) & (Mc < 1.05))
    sp_mask = (Mc >= 1.05)

    k_prop[sb_mask] = k_prop_sub
    # basic interpolation for transonic
    k_prop[tn_mask] = (k_prop_sup - k_prop_sub) * (
        Mc[tn_mask] - Mdiv[tn_mask]) / (1.05 - Mdiv[tn_mask]) + k_prop_sub
    k_prop[sp_mask] = k_prop_sup

    # --------------------------------------------------------
    # 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
コード例 #26
0
def parasite_drag_pylon(state,settings,geometry):
    """Computes the parasite drag due to pylons as a proportion of the propulsor drag

    Assumptions:
    Basic fit

    Source:
    adg.stanford.edu (Stanford AA241 A/B Course Notes)

    Inputs:
    conditions.aerodynamics.drag_breakdown.parasite[propulsor.tag].
      form_factor                                                   [Unitless]
      compressibility_factor                                        [Unitless]
      skin_friction_coefficient                                     [Unitless]
      wetted_area                                                   [m^2]
      parasite_drag_coefficient                                     [Unitless]
      reynolds_number                                               [Unitless]
    geometry.reference_area                                         [m^2]
    geometry.propulsors. 
      nacelle_diameter                                              [m]
      number_of_engines                                             [Unitless]

    Outputs:
    propulsor_parasite_drag                                         [Unitless]

    Properties Used:
    N/A
    """
    # 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
コード例 #27
0
def compressibility_drag_wing(state, settings, 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 wing.tag == '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

    # unpack wing
    t_c_w = wing.thickness_to_chord
    sweep_w = wing.sweeps.quarter_chord

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

    cos_sweep = np.cos(sweep_w)

    # get effective Cl and sweep
    tc = t_c_w / (cos_sweep)
    cl = cl_w / (cos_sweep * cos_sweep)

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

    # crest-critical mach number, corrected for wing sweep
    mcc = mcc_cos_ws / cos_sweep

    # divergence mach number
    MDiv = mcc * (1.02 + 0.08 * (1 - cos_sweep))

    # divergence ratio
    mo_mc = mach / mcc

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

    # compressibility drag
    cd_c = dcdc_cos3g * cos_sweep * cos_sweep * cos_sweep

    # 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

    return total_compressibility_drag
コード例 #28
0
def parasite_drag_fuselage(state, settings, geometry):
    """Computes the parasite drag due to the fuselage

    Assumptions:
    Basic fit

    Source:
    adg.stanford.edu (Stanford AA241 A/B Course Notes)

    Inputs:
    state.conditions.freestream.
      mach_number                                [Unitless]
      temperature                                [K]
      reynolds_number                            [Unitless]
    settings.fuselage_parasite_drag_form_factor  [Unitless]
    geometry.fuselage.       
      areas.front_projected                      [m^2]
      areas.wetted                               [m^2]
      lengths.total                              [m]
      effective_diameter                         [m]

    Outputs:
    fuselage_parasite_drag                       [Unitless]

    Properties Used:
    N/A
    """

    # 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.total
    d_fus = fuselage.effective_diameter

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

    # reynolds number
    Re_fus = re * (l_fus)

    # 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

    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
コード例 #29
0
ファイル: Loads.py プロジェクト: sirigatti/SUAVE
 def evaluate(self, condtitions):
     return Results()
コード例 #30
0
def compressibility_drag_total(state, settings, geometry):
    """Computes compressibility drag for full aircraft including volume drag through OpenVSP

    Assumptions:
    None

    Source:
    adg.stanford.edu (Stanford AA241 A/B Course Notes)

    Inputs:
    settings.number_slices
    settings.number_rotations
    state.conditions.aerodynamics.
      lift_breakdown.compressible_wings      [-]
    state.conditions.freestream.mach_number  [-]
    geometry.wings.*.tag                       

    Outputs:
    drag_breakdown.compressible[wing.tag].
      divergence_mach                        [-]
    drag_breakdown.compressible.total        [-]                    
    drag_breakdown.compressible.total_volume [-]
    drag_breakdown.compressible.total_lift   [-]
    cd_c                                     [-] Total compressibility drag

    Properties Used:
    N/A
    """

    # Unpack
    conditions = state.conditions
    configuration = settings
    number_slices = settings.number_slices
    number_rotations = settings.number_rotations

    wings = geometry.wings
    fuselages = geometry.fuselages
    propulsor_name = geometry.propulsors.keys()[
        0]  #obtain the key for the propulsor for assignment purposes
    propulsor = geometry.propulsors[propulsor_name]

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

    # Initialize result
    drag_breakdown.compressible = Results()

    # Use main wing reference area for drag coefficients
    Sref_main = geometry.reference_area

    drag99_total = np.zeros(np.shape(Mc))
    drag105_total = np.zeros(np.shape(Mc))

    # Iterate through wings
    for k in wings.keys():

        wing = wings[k]

        # 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))

        # 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
        # dummy variables are unused function outputs
        (drag99, dummy1, dummy2) = drag_div(np.array([[0.99]] * len(Mc)), wing,
                                            k, cl, Sref_main)
        cdc_l = lift_wave_drag(conditions, configuration, wing, k, Sref_main,
                               True)

        drag99_total = drag99_total + drag99
        drag105_total = drag105_total + cdc_l

    try:
        old_array = np.load('volume_drag_data_' + geometry.tag + '.npy')
        file_exists = True
    except:
        file_exists = False
        old_array = np.array([[-1, -1]])

    if np.any(old_array[:, 0] == 1.05):
        cd_c_v = np.array([[float(old_array[old_array[:, 0] == 1.05, 1])]])
    else:
        cd_c_v = wave_drag_volume(conditions, geometry, True)

    if file_exists:
        pass
    else:
        new_save_row = np.array([[1.05, cd_c_v]])
        np.save('volume_drag_data_' + geometry.tag + '.npy', new_save_row)

    drag105 = drag105_total + cd_c_v * np.ones(np.shape(Mc))
    drag99 = drag99_total
    cd_c_l = np.array([[0.0]] * len(Mc))

    # For subsonic mach numbers, use drag divergence correlations to find the drag
    for k in wings.keys():
        wing = wings[k]
        (a, b, c) = drag_div(Mc[Mc <= 0.99], wing, k, cl[Mc <= 0.99],
                             Sref_main)
        cd_c[Mc <= 0.99] = cd_c[Mc <= 0.99] + a
        mcc[Mc <= 0.99] = b
        MDiv[Mc <= 0.99] = c
        drag_breakdown.compressible[wing.tag] = Data()
        drag_breakdown.compressible[wing.tag].divergence_mach = MDiv
        cd_c_l = lift_wave_drag(conditions, configuration, wing, k, Sref_main,
                                False) + cd_c_l

    # 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_v = wave_drag_volume(conditions,
                              geometry,
                              False,
                              num_slices=number_slices,
                              num_rots=number_rotations)

    cd_c[Mc >= 1.05] = cd_c_l[Mc >= 1.05] + cd_c_v[Mc >= 1.05]

    # Save drag breakdown

    drag_breakdown.compressible.total = cd_c
    drag_breakdown.compressible.total_volume = cd_c_v
    drag_breakdown.compressible.total_lift = cd_c_l

    return cd_c