Source code for RCAIDE.Library.Methods.Aerodynamics.Common.Drag.compressibility_drag

# RCAIDE/Library/Methods/Aerodynamics/Common/Drag/compressibility_drag.py
# 
# Created:  Jul 2024, RCAIDE Team 

# ----------------------------------------------------------------------------------------------------------------------
#  IMPORT
# ----------------------------------------------------------------------------------------------------------------------
import RCAIDE
from RCAIDE.Library.Methods.Utilities         import Cubic_Spline_Blender  
from RCAIDE.Library.Components.Wings          import Main_Wing 

# package imports
import numpy as np
from scipy.interpolate import RegularGridInterpolator
# ---------------------------------------------------------------------------------------------------------------------- 
#  Compressibility Drag Total
# ----------------------------------------------------------------------------------------------------------------------  
[docs] def compressibility_drag(state,settings,geometry): """ Computes compressibility drag coefficient for full aircraft including volume drag effects. Parameters ---------- state : Data Flight conditions and aerodynamic state containing: - conditions.freestream.mach_number : float Freestream Mach number [unitless] - conditions.aerodynamics.coefficients.lift.total : float Total lift coefficient [unitless] settings : dict Aerodynamic analysis settings containing: - supersonic.begin_drag_rise_mach_number : float Mach number at which drag rise begins [unitless] - supersonic.end_drag_rise_mach_number : float Mach number at which drag rise ends [unitless] geometry : Data Aircraft geometry containing: - reference_area : float Reference area for drag coefficient calculation [m²] - wings : list List of wing objects containing: - sweeps.leading_edge : float Leading edge sweep angle [radians] - thickness_to_chord : float Thickness-to-chord ratio [unitless] Returns ------- None Results are stored in state.conditions.aerodynamics.coefficients.drag.compressible.total Notes ----- This function calculates the compressibility drag coefficient using empirical correlations based on wing geometry and flight conditions. The calculation accounts for the critical Mach number and the drag rise characteristics of swept wings. **Major Assumptions** * Compressibility effects are primarily due to wing geometry * Critical Mach number correlation is valid for typical transport aircraft * Cubic spline blending smooths transition between subsonic and supersonic regimes **Theory** The critical Mach number is calculated using a regression fit from AA241: :math:`M_{cc} \\cos(\\Lambda) = 0.922 - 1.154(t/c) - 0.305 C_L + 0.333(t/c)^2 + 0.467(t/c)C_L + 0.087 C_L^2` where: - :math:`M_{cc}` is the critical Mach number - :math:`\\Lambda` is the leading edge sweep angle [radians] - :math:`t/c` is the thickness-to-chord ratio corrected for sweep - :math:`C_L` is the lift coefficient corrected for sweep The corrected thickness-to-chord ratio is: :math:`(t/c)_{eff} = \\frac{t/c}{\\cos(\\Lambda)}` The corrected lift coefficient is: :math:`C_{L,eff} = \\frac{C_L}{\\cos^2(\\Lambda)}` The divergence ratio is: :math:`M/M_{cc} = \\frac{M}{M_{cc}}` The compressibility drag coefficient follows Shevell's correlation: :math:`\\Delta C_{D,comp} = 0.0019 \\left(\\frac{M}{M_{cc}}\\right)^{14.641} \\cos^3(\\Lambda)` **Definitions** 'Compressibility Drag' Additional drag caused by compressibility effects as the aircraft approaches and exceeds the critical Mach number. 'Critical Mach Number' The freestream Mach number at which the local flow over some part of the aircraft first reaches sonic velocity. 'Drag Rise' Rapid increase in drag coefficient as the aircraft approaches and exceeds the critical Mach number. References ---------- [1] Stanford AA241 Lecture Notes [2] Shevell, R. S. (1989). "Fundamentals of Flight." Prentice Hall. See Also -------- RCAIDE.Library.Components.Wings.Main_Wing RCAIDE.Library.Components.Wings.Blended_Wing_Body RCAIDE.Library.Methods.Utilities.Cubic_Spline_Blender """ # Unpack conditions = state.conditions Mach = conditions.freestream.mach_number sup_low_mach_cutoff = settings.supersonic.begin_drag_rise_mach_number sup_high_mach_cutoff = settings.supersonic.end_drag_rise_mach_number sub_low_mach_cutoff = settings.subsonic.begin_transonic_rise_mach_number sub_high_mach_cutoff = settings.subsonic.end_transonic_rise_rise_mach_number # functions smoothing sup_spline = Cubic_Spline_Blender(sup_low_mach_cutoff,sup_high_mach_cutoff) sup_h00 = lambda M:sup_spline.compute(M) sub_spline = Cubic_Spline_Blender(sub_low_mach_cutoff, sub_high_mach_cutoff) sub_h00 = lambda M:sub_spline.compute(M) subsonic_CDc = subsonic_compressibility_drag(state,settings,geometry) transonic_CDw_lift = transonic_lift_wave_drag(conditions, settings, geometry) supersonic_CDw_volume = supersonic_volume_wave_drag(conditions, settings, geometry) supersonic_CDw_lift = supersonic_lift_wave_drag(conditions, settings, geometry) # Apply smoothing functions sub_CDc = subsonic_CDc *(sub_h00(Mach)) trans_CDw_lift = transonic_CDw_lift * (1-sub_h00(Mach)) sup_CDw_lift = supersonic_CDw_lift * (1-sup_h00(Mach)) sup_CDw_volume = supersonic_CDw_volume * (1-sup_h00(Mach)) # compute totals total_CDc = sup_CDw_lift + trans_CDw_lift + sup_CDw_volume + sub_CDc total_CDw = sup_CDw_lift + sup_CDw_volume + trans_CDw_lift total_CDw_lift = sup_CDw_lift + trans_CDw_lift # store results conditions.aerodynamics.coefficients.drag.compressible.total[:,0] = total_CDc[:,0] conditions.aerodynamics.coefficients.drag.compressible.wave.total[:,0] = total_CDw[:,0] conditions.aerodynamics.coefficients.drag.compressible.wave.volume[:,0] = sup_CDw_volume[:,0] conditions.aerodynamics.coefficients.drag.compressible.wave.lift[:,0] = total_CDw_lift[:,0] return
[docs] def subsonic_compressibility_drag(state,settings,geometry): """ Computes compressibility drag coefficient for full aircraft including volume drag effects. Parameters ---------- state : Data Flight conditions and aerodynamic state containing: - conditions.freestream.mach_number : float Freestream Mach number [unitless] - conditions.aerodynamics.coefficients.lift.total : float Total lift coefficient [unitless] settings : dict Aerodynamic analysis settings containing: - supersonic.begin_drag_rise_mach_number : float Mach number at which drag rise begins [unitless] - supersonic.end_drag_rise_mach_number : float Mach number at which drag rise ends [unitless] geometry : Data Aircraft geometry containing: - reference_area : float Reference area for drag coefficient calculation [m²] - wings : list List of wing objects containing: - sweeps.leading_edge : float Leading edge sweep angle [radians] - thickness_to_chord : float Thickness-to-chord ratio [unitless] Returns ------- None Results are stored in state.conditions.aerodynamics.coefficients.drag.compressible.total Notes ----- This function calculates the compressibility drag coefficient using empirical correlations based on wing geometry and flight conditions. The calculation accounts for the critical Mach number and the drag rise characteristics of swept wings. **Major Assumptions** * Compressibility effects are primarily due to wing geometry * Critical Mach number correlation is valid for typical transport aircraft * Cubic spline blending smooths transition between subsonic and supersonic regimes **Theory** The critical Mach number is calculated using a regression fit from AA241: :math:`M_{cc} \\cos(\\Lambda) = 0.922 - 1.154(t/c) - 0.305 C_L + 0.333(t/c)^2 + 0.467(t/c)C_L + 0.087 C_L^2` where: - :math:`M_{cc}` is the critical Mach number - :math:`\\Lambda` is the leading edge sweep angle [radians] - :math:`t/c` is the thickness-to-chord ratio corrected for sweep - :math:`C_L` is the lift coefficient corrected for sweep The corrected thickness-to-chord ratio is: :math:`(t/c)_{eff} = \\frac{t/c}{\\cos(\\Lambda)}` The corrected lift coefficient is: :math:`C_{L,eff} = \\frac{C_L}{\\cos^2(\\Lambda)}` The divergence ratio is: :math:`M/M_{cc} = \\frac{M}{M_{cc}}` The compressibility drag coefficient follows Shevell's correlation: :math:`\\Delta C_{D,comp} = 0.0019 \\left(\\frac{M}{M_{cc}}\\right)^{14.641} \\cos^3(\\Lambda)` **Definitions** 'Compressibility Drag' Additional drag caused by compressibility effects as the aircraft approaches and exceeds the critical Mach number. 'Critical Mach Number' The freestream Mach number at which the local flow over some part of the aircraft first reaches sonic velocity. 'Drag Rise' Rapid increase in drag coefficient as the aircraft approaches and exceeds the critical Mach number. References ---------- [1] Stanford AA241 Lecture Notes [2] Shevell, R. S. (1989). "Fundamentals of Flight." Prentice Hall. See Also -------- RCAIDE.Library.Components.Wings.Main_Wing RCAIDE.Library.Components.Wings.Blended_Wing_Body RCAIDE.Library.Methods.Utilities.Cubic_Spline_Blender """ # Unpack conditions = state.conditions Mach = conditions.freestream.mach_number cd_compressibility = np.zeros_like(Mach) cl = conditions.aerodynamics.coefficients.lift.total for wing in geometry.wings: if isinstance(wing,RCAIDE.Library.Components.Wings.Main_Wing) or isinstance(wing,RCAIDE.Library.Components.Wings.Blended_Wing_Body): sweep_w = wing.sweeps.leading_edge # Get effective CLift_wings and sweep tc = wing.thickness_to_chord / np.cos(sweep_w) cl = conditions.aerodynamics.coefficients.lift.total/ (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*tc + 0.467317361111105*tc*cl + 0.087490431201549*cl*cl # Crest-critical Mach number, corrected for wing sweep Mcc = mcc_cos_ws/ np.cos(sweep_w) # Divergence ratio mo_Mach = Mach/Mcc # Compressibility correlation, Shevell dcdc_cos3g = 0.0019*mo_Mach**14.641 # Compressibility drag cd_compressibility = dcdc_cos3g * (np.cos(sweep_w)**3) cd_comp = cd_compressibility return cd_comp
# ---------------------------------------------------------------------------------------------------------------------- # transonic_wave_drag # ----------------------------------------------------------------------------------------------------------------------
[docs] def transonic_lift_wave_drag(conditions, settings, geometry): """ Computes transonic lift wave drag coefficient using empirical correlations. Parameters ---------- conditions : Data Flight conditions containing: - freestream.mach_number : float Freestream Mach number [unitless] - aerodynamics.coefficients.lift.total : float Total lift coefficient [unitless] - aerodynamics.coefficients.lift.spanwise : float, optional Spanwise lift distribution [unitless] settings : dict Analysis settings containing: - use_surrogate : bool Flag to use surrogate model - vortex_distribution : Data, optional Vortex distribution data containing: - chord_lengths : array Chord lengths at spanwise stations [m] - leading_edge_sweeps : array Leading edge sweep angles [radians] - chord_widths : array Chord widths at spanwise stations [m] geometry : Data Aircraft geometry containing: - reference_area : float Reference area [m²] Returns ------- CD_wave_transonic : float Transonic lift wave drag coefficient [unitless] Notes ----- This function calculates the transonic lift wave drag using either a surrogate model or detailed spanwise analysis based on shock wave formation from Lock (1986). A generic airfoil (RAE 5225) is assumed for the Cp data. **Major Assumptions** * Surrogate model is valid for Mach 0.7-0.95 range * Shock wave formation depends on local pressure coefficient * Normalized curvature factor is constant (0.23) * Spanwise analysis accounts for sweep effects **Theory** For surrogate model: :math:`C_{D,wave} = f(C_L) \\cdot (12.5M - 8.75)` For detailed analysis: :math:`C_{D,wave} = \\sum_{i=1}^{n} C_{D,wave,i} \\cdot \\frac{S_i}{S_{ref}}` where each segment's wave drag is: :math:`C_{D,wave,i} = \\frac{\\cos^4(\\Lambda)}{\\kappa} \\cdot 0.243 \\cdot \\left(\\frac{1+0.2M\\cos(\\Lambda)}{M\\cos(\\Lambda)}\\right)^3 \\cdot (M_1^* - 1)^4 \\cdot \\frac{2-M_1^*}{M_1^*(1+0.2M_1^{*2})} \\cdot 0.5` The local Mach number before shock is: :math:`M_1^* = \\sqrt{\\frac{5+M^2\\cos^2(\\Lambda)}{(1+0.7M^2C_p)^{2/7}} - 5}` **Definitions** 'Transonic Wave Drag' Wave drag occurring in the transonic regime (M ≈ 0.7-0.95). 'Shock Wave' Discontinuity in flow properties caused by compressibility effects. 'Pressure Coefficient' Dimensionless pressure difference normalized by dynamic pressure. References ---------- [1] Lock, R. C. (1986). "The Prediction of the Drag of Aerofoils and Wings at High Subsonic Speeds." Aeronautical Journal. [2] Harris, C. D. (1990). "NASA Supercritical Airfoils." NASA TP 2969. """ Mach = conditions.freestream.mach_number S_ref = geometry.reference_area CD_wave_transonic = np.zeros_like(Mach) CL_y = conditions.aerodynamics.coefficients.lift.spanwise *geometry.wings.main_wing.areas.projected/S_ref chords = settings.vortex_distribution.chord_lengths delta = settings.vortex_distribution.leading_edge_sweeps dy = settings.vortex_distribution.chord_widths CD_wave_transonic = np.zeros_like(Mach) c_kappa = 0.23 # normalized curvature of the airfoil. This can eventually be calcualted using airfoil shape data. # ------------------------------------------------------------------ # Cp Data (as function of CL) from "The Prediciton of the Drag of Aerofoils and Wings at High Subsonic Speeds" by R.C. Lock, 1986, Aeronautical journal and NASA TP 2969, NASA Supercritical Airfoils by Charles D. Harris # ------------------------------------------------------------------ Cp_shock = 0.9825 *(CL_y**2) - 2.5132 *(CL_y) + 0.0279 # Cp vlaue right before the shock wave # ------------------------------------------------------------------ # Wave Drag Calculation # ------------------------------------------------------------------ # Calculate the local mach number right before the shock wave M1_0_star = np.sqrt((5+Mach**2*np.cos(delta[0])**2)/(1+0.7*Mach**2*Cp_shock)**(2/7) - 5) # Calculate the wave drag coefficient constant = (np.cos(delta[0])**4)/c_kappa * 0.243*((1+0.2*Mach*np.cos(delta[0]))/(Mach*np.cos(delta[0])))**3 # note, delta is assumed to remain constant across all conditions. CD_wave_segment = constant*(M1_0_star - 1)**4*(2-M1_0_star)/(M1_0_star*(1+0.2*M1_0_star**2)) * 0.5 # Set the wave drag coefficient to 0 if there is no shock wave CD_wave_segment[Cp_shock > -0.6] = 0.0 # If the Cp > -0.6 then there is likely no shock wave S_segment = chords[0]*dy[0] CD_wave_transonic = np.sum(CD_wave_segment*S_segment/S_ref, axis=1, keepdims=True) CD_wave_transonic[Mach>1] = 0.0 return CD_wave_transonic
# ---------------------------------------------------------------------------------------------------------------------- # supersonic_lift_wave_drag # ----------------------------------------------------------------------------------------------------------------------
[docs] def supersonic_lift_wave_drag(conditions,configuration,geometry): """ Computes supersonic lift wave drag coefficient using JAXA methodology. Parameters ---------- conditions : Data Flight conditions containing: - freestream.mach_number : float Freestream Mach number [unitless] - aerodynamics.coefficients.lift.total : float Total lift coefficient [unitless] configuration : dict Aircraft configuration settings geometry : Data Aircraft geometry containing: - wings : list List of wing objects containing: - chords.root : float Root chord length [m] - spans.projected : float Projected span [m] - aspect_ratio : float Aspect ratio [unitless] Returns ------- cd_lift_wave : float Supersonic lift wave drag coefficient [unitless] Notes ----- This function calculates the supersonic lift wave drag using the JAXA methodology based on wing geometry and lift coefficient. **Major Assumptions** * JAXA methodology is valid for supersonic speeds * Only main wing contributes to lift wave drag * Wing geometry parameters are sufficient for calculation * Empirical correlation is valid for typical supersonic aircraft **Theory** The supersonic lift wave drag coefficient is: :math:`C_{D,wave,lift} = C_L^2 \\cdot \\frac{\\beta^2}{\\pi} \\cdot p \\cdot \\frac{s}{l} \\cdot K_w` where: - :math:`\\beta = \\sqrt{M^2-1}` is the Prandtl-Glauert factor - :math:`p = \\frac{2}{AR} \\cdot \\frac{s}{l}` is the wing parameter - :math:`x = \\beta \\cdot \\frac{s}{l}` is the normalized span parameter - :math:`K_w` is the wave drag factor calculated from empirical correlation **Definitions** 'Supersonic Wave Drag' Wave drag occurring at supersonic speeds (M > 1.0). 'JAXA Methodology' Empirical method for calculating supersonic wave drag developed by JAXA. 'Prandtl-Glauert Factor' Compressibility correction factor for supersonic flow. References ---------- [1] Yoshida, K. "Supersonic drag reduction technology in the scaled supersonic experimental airplane project by JAXA." """ # Initalize cd arrays Mach = conditions.freestream.mach_number cd_lift_wave = np.zeros_like(Mach) for wing in geometry.wings: if isinstance(wing, Main_Wing): # Lift coefficient CL = conditions.aerodynamics.coefficients.lift.total l = wing.chords.root # JAXA method s = wing.spans.projected / 2 AR = wing.aspect_ratio p = 2/AR*s/l beta = np.sqrt(Mach**2-1) x = beta*s/l ret = np.zeros_like(x) ret[x > 0.178] = 0.4935 - 0.2382*x[x > 0.178] + 1.6306*x[x > 0.178]**2 - 0.86*x[x > 0.178]**3 + 0.2232*x[x > 0.178]**4 - 0.0365*x[x > 0.178]**5 - 0.5 Kw = (1+1/p)*ret/(2*beta**2*(s/l)**2) cd_lift_wave = CL**2 * (beta**2/np.pi*p*(s/l)*Kw) cd_lift_wave[cd_lift_wave<0] = 0. cd_lift_wave[np.isnan(cd_lift_wave)] = 0. return cd_lift_wave
[docs] def supersonic_volume_wave_drag(conditions, settings, vehicle): """ Computes supersonic volume wave drag coefficient based on aircraft geometry. Parameters ---------- conditions : Data Flight conditions (not used in calculation) settings : dict Analysis settings (not used in calculation) vehicle : Data Aircraft geometry containing: - reference_area : float Reference area for drag coefficient [m²] - length : float Total aircraft length [m] - maximum_cross_sectional_area : float Maximum cross-sectional area [m²] - fuselages : list List of fuselage objects containing: - width : float Width of the fuselage [m] Returns ------- CD_wave_vol : float Supersonic volume wave drag coefficient [unitless] Notes ----- This function calculates the supersonic volume wave drag based on aircraft geometry using empirical correlations from Wright Laboratory procedures. **Major Assumptions** * Volume wave drag is independent of Mach number * Aircraft volume can be approximated by cylindrical geometry * Maximum fuselage width represents the characteristic dimension * Empirical correlation is valid for typical supersonic aircraft **Theory** The volume wave drag coefficient is: :math:`C_{D,wave,volume} = C_{D,wave,volume,frontal} \\cdot \\frac{A_{max}}{S_{ref}}` where the frontal area wave drag is: :math:`C_{D,wave,volume,frontal} = 24 \\cdot \\frac{V}{L^3}` The aircraft volume is approximated as: :math:`V = \\frac{3}{16} \\pi^2 R_{max}^2 L` where: - :math:`R_{max}` is the maximum fuselage radius - :math:`L` is the total aircraft length - :math:`A_{max}` is the maximum cross-sectional area - :math:`S_{ref}` is the reference area **Definitions** 'Volume Wave Drag' Wave drag caused by aircraft volume in supersonic flow. 'Frontal Area Wave Drag' Volume wave drag normalized by frontal area. 'Characteristic Length' Representative length scale for volume wave drag calculation. References ---------- [1] Sieron, T. R., et al. (1993). "Procedures and design data for the formulation of aircraft configurations." WRIGHT LAB WRIGHT-PATTERSON AFB OH. """ S_ref = vehicle.reference_area L = vehicle.length Amax = vehicle.maximum_cross_sectional_area # compute volume drag referenced to frontal area Rmax = 0 for fuselage in vehicle.fuselages: Rmax = np.maximum(Rmax, fuselage.width) volume = (3 / 16) * (np.pi ** 2) * (Rmax ** 2) * L CD_wave_vol_frontal = 24 *volume /(L **3) CD_wave_vol = CD_wave_vol_frontal * ( Amax / S_ref) * np.ones_like(conditions.freestream.mach_number) return CD_wave_vol