engineeringkit.aerodynamics#

Dynamic pressure and force coefficients; Kutta-Joukowski circulation lift; thin-airfoil theory (with Glauert’s zero-lift integral by scipy.integrate.quad) and NACA four-digit sections; Prandtl’s lifting line, induced drag, the Oswald drag polar and the Breguet range equation; Reynolds similarity and Blasius/Prandtl flat-plate friction; sound speed, the Mach cone, isentropic stagnation states, Prandtl-Glauert, normal shocks and the area-Mach relation; and the International Standard Atmosphere. All models are hand-written closed forms, because the formula is the subject.

engineeringkit.aerodynamics: from dynamic pressure to finite wings and compressible flow.

Force coefficients and dynamic pressure; Kutta-Joukowski circulation lift; thin-airfoil theory and NACA four-digit sections; Prandtl’s lifting line, induced drag, the parabolic drag polar and Breguet range; Reynolds-number similarity and Blasius/Prandtl flat-plate boundary layers; perfect-gas sound speed, isentropic stagnation states, the Mach cone, Prandtl-Glauert, Rankine-Hugoniot normal shocks and the de Laval area-Mach relation; and the International Standard Atmosphere. Every model is a hand-written closed-form relation (the formula is the pedagogical subject); SciPy is used only for the thin-airfoil quadrature.

class engineeringkit.aerodynamics.Airfoil(name, x, camber, thickness, upper, lower)[source]#

Bases: object

Coordinates of an airfoil section on a unit chord.

All coordinates are fractions of the chord c; multiply by c [m] for physical dimensions.

Parameters:
  • name (str)

  • x (ndarray)

  • camber (ndarray)

  • thickness (ndarray)

  • upper (ndarray)

  • lower (ndarray)

camber: ndarray#

Mean-camber-line ordinate at each station.

Type:

ndarray

lower: ndarray#

Lower-surface points, shape (n, 2).

Type:

ndarray

name: str#

Section designation, e.g. "NACA 2412".

Type:

str

plot(ax=None)[source]#

Draw the section outline and camber line; return (fig, ax).

summary()[source]#

Maximum thickness and camber (fractions of chord) and their locations.

Return type:

dict

thickness: ndarray#

Half-thickness at each station.

Type:

ndarray

upper: ndarray#

Upper-surface points, shape (n, 2).

Type:

ndarray

x: ndarray#

Chordwise stations of the mean camber line, from 0 to 1.

Type:

ndarray

class engineeringkit.aerodynamics.AtmosphereState(altitude, temperature, pressure, density, speed_of_sound)[source]#

Bases: object

Thermodynamic state of the standard atmosphere at a geometric altitude.

Parameters:
  • altitude (ndarray)

  • temperature (ndarray)

  • pressure (ndarray)

  • density (ndarray)

  • speed_of_sound (ndarray)

altitude: ndarray#

Altitude above mean sea level [m].

Type:

ndarray

density: ndarray#

Density [kg/m^3].

Type:

ndarray

plot(ax=None)[source]#

Plot temperature, pressure and density against altitude; return (fig, axes).

pressure: ndarray#

Static pressure [Pa].

Type:

ndarray

speed_of_sound: ndarray#

Speed of sound [m/s].

Type:

ndarray

summary()[source]#

Sea-level-relative density and pressure at the highest altitude.

Return type:

dict

temperature: ndarray#

Static temperature [K].

Type:

ndarray

engineeringkit.aerodynamics.area_mach_ratio(M, gamma=1.4)[source]#

Isentropic area ratio \(A/A^*\) of a quasi-one-dimensional nozzle.

\[\frac{A}{A^*} = \frac{1}{M}\left[\frac{2}{\gamma+1}\left(1 + \frac{\gamma-1}{2}M^2\right)\right]^{\frac{\gamma+1}{2(\gamma-1)}}\]
Parameters:
  • M (float or array_like) – Mach number [-], positive.

  • gamma (float, optional) – Ratio of specific heats [-], greater than one.

Returns:

Area relative to the sonic throat [-]; one at \(M = 1\). Each ratio above one corresponds to one subsonic and one supersonic Mach number; this function does not invert.

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(area_mach_ratio(2.0)), 4)
1.6875
engineeringkit.aerodynamics.aspect_ratio(span, area)[source]#

Wing aspect ratio \(AR = b^2 / S\).

Parameters:
  • span (float or array_like) – Wing span [m], positive.

  • area (float or array_like) – Planform area [m^2], positive.

Returns:

Aspect ratio [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(aspect_ratio(10.0, 20.0))
5.0
engineeringkit.aerodynamics.best_glide_cl(Cd0, AR, e=1.0)[source]#

Lift coefficient of maximum \(L/D\) for a parabolic polar, \(\sqrt{\pi e AR C_{D0}}\).

At this point induced drag equals parasite drag, so \((L/D)_{\max} = \tfrac12\sqrt{\pi e AR / C_{D0}}\).

Parameters:
  • Cd0 (float or array_like) – Zero-lift drag coefficient [-], positive.

  • AR (float or array_like) – Aspect ratio [-], positive.

  • e (float or array_like, optional) – Oswald efficiency factor [-] in (0, 1].

Returns:

Lift coefficient for best glide [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(best_glide_cl(0.02, 8.0, 0.8)), 4)
0.6341
engineeringkit.aerodynamics.boundary_layer_laminar(x, Re_x)[source]#

Laminar boundary-layer thickness \(\delta \approx 5x/\sqrt{Re_x}\).

Parameters:
  • x (float or array_like) – Distance from the leading edge [m], nonnegative.

  • Re_x (float or array_like) – Local Reynolds number \(\rho V x/\mu\) [-], positive.

Returns:

99%-velocity thickness [m] (Blasius gives 4.91; 5 is the textbook rounding).

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(boundary_layer_laminar(1.0, 1e6)), 6)
0.005
engineeringkit.aerodynamics.breguet_range(V, tsfc, lift_to_drag, W_initial, W_final, g=9.80665)[source]#

Jet-aircraft cruise range \(R = \dfrac{V}{g\,c_T}\dfrac{L}{D}\ln\dfrac{W_i}{W_f}\) (Breguet).

Integrates \(dR = V\,dt\) while fuel burns at \(\dot m = c_T T\) and thrust equals drag, \(T = W/(L/D)\), at constant speed and lift-to-drag ratio.

Parameters:
  • V (float or array_like) – Cruise true airspeed [m/s], positive.

  • tsfc (float or array_like) – Thrust-specific fuel consumption [kg/(N s)], positive (e.g. 1.6e-5 for a modern turbofan).

  • lift_to_drag (float or array_like) – Cruise lift-to-drag ratio [-], positive.

  • W_initial (float or array_like) – Weight at the start and end of cruise [N], with W_initial >= W_final > 0.

  • W_final (float or array_like) – Weight at the start and end of cruise [N], with W_initial >= W_final > 0.

  • g (float, optional) – Gravitational acceleration [m/s^2].

Returns:

Still-air range [m].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

J. D. Anderson, Aircraft Performance and Design (McGraw-Hill, 1999), sec. 5.13, for the derivation of the range equation attributed to Louis Breguet.

Examples

>>> round(float(breguet_range(230.0, 1.6e-5, 18.0, 7.0e5, 5.0e5)) / 1e3)
8878
engineeringkit.aerodynamics.drag(q, S, Cd)[source]#

Drag force \(D = q S C_D\).

Parameters:
  • q (float or array_like) – Dynamic pressure [Pa], nonnegative.

  • S (float or array_like) – Reference area [m^2], positive.

  • Cd (float or array_like) – Drag coefficient [-], nonnegative.

Returns:

Drag [N], parallel to the free stream.

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(drag(1500.0, 2.0, 0.02))
60.0
engineeringkit.aerodynamics.drag_coefficient(D, rho, V, S)[source]#

Drag coefficient \(C_D = D / (q S)\) from a measured drag force.

Parameters:
  • D (float or array_like) – Drag [N], nonnegative.

  • rho (float or array_like) – Density [kg/m^3], positive.

  • V (float or array_like) – Speed [m/s], positive.

  • S (float or array_like) – Reference area [m^2], positive.

Returns:

Drag coefficient [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(drag_coefficient(60.0, 1.2, 50.0, 2.0))
0.02
engineeringkit.aerodynamics.drag_polar(Cl, Cd0, AR, e=1.0)[source]#

Parabolic drag polar \(C_D = C_{D0} + C_L^2/(\pi e AR)\).

Parameters:
  • Cl (float or array_like) – Lift coefficient [-].

  • Cd0 (float or array_like) – Zero-lift (parasite) drag coefficient [-], nonnegative.

  • AR (float or array_like) – Aspect ratio [-], positive.

  • e (float or array_like, optional) – Oswald efficiency factor [-] in (0, 1].

Returns:

Total drag coefficient [-].

Return type:

float or ndarray

Notes

Compressibility and Reynolds-number variation of \(C_{D0}\) are not modelled. Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(drag_polar(0.5, 0.02, 8.0, 0.8)), 6)
0.032434
engineeringkit.aerodynamics.dynamic_pressure(rho, V)[source]#

Dynamic pressure \(q = \tfrac12 \rho V^2\).

Bernoulli’s kinetic-energy term per unit volume: the pressure rise available when a stream is brought to rest without losses.

Parameters:
  • rho (float or array_like) – Fluid density [kg/m^3], positive.

  • V (float or array_like) – Flow speed [m/s], nonnegative.

Returns:

Dynamic pressure [Pa].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(dynamic_pressure(1.2, 50.0))
1500.0
engineeringkit.aerodynamics.finite_wing_cl(alpha_rad, AR, e=1.0, alpha_l0=0.0)[source]#

Wing lift coefficient \(C_L = a(\alpha - \alpha_{L=0})\) with the lifting-line slope.

Parameters:
  • alpha_rad (float or array_like) – Angle of attack [rad].

  • AR (float or array_like) – Aspect ratio [-], positive.

  • e (float, optional) – Span efficiency factor [-] in (0, 1].

  • alpha_l0 (float, optional) – Zero-lift angle [rad].

Returns:

Wing lift coefficient [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(finite_wing_cl(0.1, 8.0)), 5)
0.50265
engineeringkit.aerodynamics.finite_wing_lift_slope(AR, e=1.0, a0=6.283185307179586)[source]#

Lifting-line lift-curve slope \(a = a_0 / (1 + a_0/(\pi e AR))\).

Parameters:
  • AR (float or array_like) – Aspect ratio [-], positive.

  • e (float or array_like, optional) – Span efficiency factor [-] in (0, 1].

  • a0 (float, optional) – Two-dimensional section lift slope [1/rad]; \(2\pi\) from thin-airfoil theory.

Returns:

Wing lift-curve slope [1/rad]; tends to a0 as AR grows.

Return type:

float or ndarray

Notes

Valid for unswept, moderate-to-high aspect-ratio wings in attached incompressible flow. Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(finite_wing_lift_slope(8.0)), 4)
5.0265
engineeringkit.aerodynamics.glide_ratio(Cl, Cd)[source]#

Lift-to-drag ratio \(L/D = C_L/C_D\), the still-air glide distance per unit height lost.

Parameters:
  • Cl (float or array_like) – Lift coefficient [-].

  • Cd (float or array_like) – Drag coefficient [-], positive.

Returns:

Glide ratio [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(glide_ratio(0.8, 0.05))
16.0
engineeringkit.aerodynamics.induced_drag_coefficient(Cl, AR, e=1.0)[source]#

Induced (vortex) drag coefficient \(C_{D,i} = C_L^2/(\pi e AR)\).

Parameters:
  • Cl (float or array_like) – Wing lift coefficient [-].

  • AR (float or array_like) – Aspect ratio [-], positive.

  • e (float or array_like, optional) – Span efficiency factor [-] in (0, 1]; one for an elliptic load.

Returns:

Induced drag coefficient [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; see Aerodynamics: incompressible limits and compressible conservation.

References

  1. Prandtl, “Tragflügeltheorie,” Nachr. Ges. Wiss. Göttingen (1918).

Examples

>>> round(float(induced_drag_coefficient(0.5, 8.0)), 6)
0.009947
engineeringkit.aerodynamics.isa_atmosphere(altitude)[source]#

Standard-atmosphere temperature, pressure, density and sound speed.

\[T = T_0 - L h,\quad p = p_0 (T/T_0)^{g_0/(R L)} \quad (h \le 11\,\mathrm{km}), \qquad p = p_{11}\, e^{-g_0 (h - 11\,\mathrm{km})/(R T_{11})} \quad (11 < h \le 20\,\mathrm{km})\]
Parameters:

altitude (float or array_like) – Geopotential altitude [m] in [0, 20000].

Return type:

AtmosphereState

Notes

Sea-level values are 288.15 K, 101325 Pa and 1.225 kg/m^3 with a lapse rate of 6.5 K/km. Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

ISO 2533:1975, Standard Atmosphere; ICAO Doc 7488 (1952).

Examples

>>> state = isa_atmosphere(11000.0)
>>> round(float(state.temperature), 2), round(float(state.pressure))
(216.65, 22632)
engineeringkit.aerodynamics.isentropic_factor(M, gamma=1.4)[source]#

Stagnation-to-static temperature ratio \(1 + \tfrac{\gamma-1}{2}M^2\).

Every isentropic relation (stagnation temperature and pressure, the area-Mach relation) is a power of this one factor.

Parameters:
  • M (float or array_like) – Mach number [-], nonnegative.

  • gamma (float, optional) – Ratio of specific heats [-], greater than one.

Returns:

\(T_0/T\) [-].

Return type:

float or ndarray

Examples

>>> float(isentropic_factor(1.0))
1.2
engineeringkit.aerodynamics.kutta_joukowski_lift(rho, V, circulation)[source]#

Lift per unit span \(L' = \rho V \Gamma\) (Kutta-Joukowski theorem).

Any two-dimensional body in a steady inviscid stream carries a lift per unit span proportional to the circulation \(\Gamma\) around it, and no drag (d’Alembert).

Parameters:
  • rho (float or array_like) – Density [kg/m^3], positive.

  • V (float or array_like) – Free-stream speed [m/s], nonnegative.

  • circulation (float or array_like) – Circulation \(\Gamma\) [m^2/s]; positive for clockwise flow about a body in a stream moving in the +x direction.

Returns:

Lift per unit span [N/m].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

References

    1. Kutta, Illustrierte Aeronautische Mitteilungen 6 (1902);

  1. Joukowski, Bull. Inst. Aérodyn. Koutchino 1 (1906).

Examples

>>> float(kutta_joukowski_lift(1.2, 50.0, 10.0))
600.0
engineeringkit.aerodynamics.lift(q, S, Cl)[source]#

Lift force \(L = q S C_L\).

Parameters:
  • q (float or array_like) – Dynamic pressure [Pa], nonnegative.

  • S (float or array_like) – Reference (wing planform) area [m^2], positive.

  • Cl (float or array_like) – Lift coefficient [-]; signed.

Returns:

Lift [N], perpendicular to the free stream.

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(lift(1500.0, 2.0, 0.5))
1500.0
engineeringkit.aerodynamics.lift_coefficient(L, rho, V, S)[source]#

Lift coefficient \(C_L = L / (q S)\) from a measured lift force.

Parameters:
  • L (float or array_like) – Lift [N]; signed.

  • rho (float or array_like) – Density [kg/m^3], positive.

  • V (float or array_like) – Speed [m/s], positive.

  • S (float or array_like) – Reference area [m^2], positive.

Returns:

Lift coefficient [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(lift_coefficient(1500.0, 1.2, 50.0, 2.0))
0.5
engineeringkit.aerodynamics.mach_angle(M)[source]#

Half-angle of the Mach cone, \(\mu = \arcsin(1/M)\).

Parameters:

M (float or array_like) – Mach number [-], at least one.

Returns:

Mach angle [rad]; \(\pi/2\) at \(M = 1\).

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

E. Mach and P. Salcher, “Photographische Fixirung der durch Projectile in der Luft eingeleiteten Vorgänge,” Sitzungsber. Akad. Wiss. Wien 95 (1887).

Examples

>>> round(float(np.degrees(mach_angle(2.0))), 6)
30.0
engineeringkit.aerodynamics.mach_number(V, a)[source]#

Mach number \(M = V/a\).

Parameters:
  • V (float or array_like) – Flow speed [m/s], nonnegative.

  • a (float or array_like) – Speed of sound [m/s], positive.

Returns:

Mach number [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> float(mach_number(170.0, 340.0))
0.5
engineeringkit.aerodynamics.naca4_airfoil(designation, n=101, closed_trailing_edge=False)[source]#

Coordinates of a NACA four-digit section on a unit chord.

The half-thickness is

\[y_t = 5t\,(0.2969\sqrt{x} - 0.1260x - 0.3516x^2 + 0.2843x^3 - 0.1015x^4),\]

and the surfaces are offset from the camber line along its normal. Stations are cosine-spaced to resolve the leading edge.

Parameters:
  • designation (str) – Four digits, e.g. "0012" or "2412".

  • n (int) – Number of chordwise stations, at least 3.

  • closed_trailing_edge (bool) – Use -0.1036 instead of -0.1015 for the quartic coefficient so the trailing edge has zero thickness.

Return type:

Airfoil

Notes

Coordinates are fractions of chord; see Aerodynamics: incompressible limits and compressible conservation.

References

E. N. Jacobs, K. E. Ward and R. M. Pinkerton, “The characteristics of 78 related airfoil sections from tests in the variable-density wind tunnel,” NACA Report 460 (1933).

Examples

>>> foil = naca4_airfoil("2412")
>>> round(foil.summary()["max_thickness"], 3)
0.12
engineeringkit.aerodynamics.naca4_zero_lift_angle(m, p)[source]#

Thin-airfoil zero-lift angle of a NACA four-digit camber line.

Glauert’s integral

\[\alpha_{L=0} = -\frac{1}{\pi}\int_0^\pi \frac{dz}{dx}(\theta)\,(\cos\theta - 1)\,d\theta, \qquad x = \tfrac12(1-\cos\theta),\]

is evaluated numerically for the two-parabola camber line with maximum camber m at chordwise position p.

Parameters:
  • m (float) – Maximum camber as a fraction of chord, in [0, 0.095] (first digit / 100).

  • p (float) – Position of maximum camber as a fraction of chord, in (0, 1) (second digit / 10).

Returns:

Zero-lift angle of attack [rad]; zero for m = 0.

Return type:

float

Notes

Inputs are raw SI numbers with no dimensional metadata; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(np.degrees(naca4_zero_lift_angle(0.02, 0.4))), 2)
-2.08
engineeringkit.aerodynamics.normal_shock_mach2(M1, gamma=1.4)[source]#

Downstream Mach number of a normal shock.

\[M_2^2 = \frac{1 + \tfrac{\gamma-1}{2}M_1^2}{\gamma M_1^2 - \tfrac{\gamma-1}{2}}\]
Parameters:
  • M1 (float or array_like) – Upstream Mach number [-], at least one.

  • gamma (float, optional) – Ratio of specific heats [-], greater than one.

Returns:

Downstream Mach number [-], at most one.

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

W. J. M. Rankine, Phil. Trans. R. Soc. 160 (1870) 277-288; H. Hugoniot, J. École Polytech. 57 (1887) 3-97; 58 (1889) 1-125.

Examples

>>> round(float(normal_shock_mach2(2.0)), 6)
0.57735
engineeringkit.aerodynamics.normal_shock_pressure_ratio(M1, gamma=1.4)[source]#

Static pressure ratio across a normal shock, \(p_2/p_1 = 1 + \tfrac{2\gamma}{\gamma+1}(M_1^2 - 1)\).

Parameters:
  • M1 (float or array_like) – Upstream Mach number [-], at least one.

  • gamma (float, optional) – Ratio of specific heats [-], greater than one.

Returns:

Pressure ratio [-], at least one.

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(normal_shock_pressure_ratio(2.0)), 6)
4.5
engineeringkit.aerodynamics.oswald_efficiency_estimate(AR)[source]#

Empirical Oswald factor for straight wings, \(e = 1.78(1 - 0.045 AR^{0.68}) - 0.64\).

Parameters:

AR (float or array_like) – Aspect ratio [-] in [2, 10], the range of the underlying data.

Returns:

Oswald efficiency factor [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

D. P. Raymer, Aircraft Design: A Conceptual Approach, 6th ed. (AIAA, 2018), eq. 12.48.

Examples

>>> round(float(oswald_efficiency_estimate(8.0)), 4)
0.8106
engineeringkit.aerodynamics.prandtl_glauert_cp(cp0, M)[source]#

Prandtl-Glauert compressibility correction \(C_p = C_{p,0}/\sqrt{1 - M_\infty^2}\).

Parameters:
  • cp0 (float or array_like) – Incompressible pressure coefficient [-].

  • M (float or array_like) – Free-stream Mach number [-] in [0, 1).

Returns:

Compressible pressure coefficient [-].

Return type:

float or ndarray

Notes

Linearized subsonic theory; it diverges as \(M \to 1\) and is unreliable above roughly \(M = 0.7\). Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

H. Glauert, “The effect of compressibility on the lift of an aerofoil,” Proc. R. Soc. Lond. A 118 (1928) 113-119.

Examples

>>> round(float(prandtl_glauert_cp(-1.0, 0.6)), 6)
-1.25
engineeringkit.aerodynamics.reynolds_number(rho, V, L, mu)[source]#

Reynolds number \(Re = \rho V L / \mu\).

Parameters:
  • rho (float or array_like) – Density [kg/m^3], positive.

  • V (float or array_like) – Speed [m/s], nonnegative.

  • L (float or array_like) – Reference length (chord, plate distance) [m], positive.

  • mu (float or array_like) – Dynamic viscosity [Pa s], positive.

Returns:

Reynolds number [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(reynolds_number(1.0, 10.0, 1.0, 1e-5)))
1000000
engineeringkit.aerodynamics.skin_friction_laminar(Re)[source]#

Blasius average skin-friction coefficient of a laminar flat plate, \(C_f = 1.328/\sqrt{Re_L}\).

Parameters:

Re (float or array_like) – Plate-length Reynolds number [-], positive; laminar flow (typically \(Re_L < 5\times10^5\)) is assumed, not checked.

Returns:

Average skin-friction coefficient (both sides not included) [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

H. Blasius, “Grenzschichten in Flüssigkeiten mit kleiner Reibung,” Z. Math. Phys. 56 (1908) 1-37.

Examples

>>> round(float(skin_friction_laminar(1e6)), 6)
0.001328
engineeringkit.aerodynamics.skin_friction_turbulent(Re)[source]#

Prandtl’s one-fifth-power turbulent flat-plate skin friction, \(C_f = 0.074/Re_L^{1/5}\).

Parameters:

Re (float or array_like) – Plate-length Reynolds number [-], positive; fully turbulent flow from the leading edge, roughly \(5\times10^5 < Re_L < 10^7\).

Returns:

Average skin-friction coefficient [-].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

H. Schlichting and K. Gersten, Boundary-Layer Theory, 9th ed. (Springer, 2017), ch. 18.

Examples

>>> round(float(skin_friction_turbulent(1e5)), 6)
0.0074
engineeringkit.aerodynamics.speed_of_sound(gamma, R, T)[source]#

Speed of sound in a perfect gas, \(a = \sqrt{\gamma R T}\) (Laplace).

Parameters:
  • gamma (float or array_like) – Ratio of specific heats [-], greater than one.

  • R (float or array_like) – Specific gas constant [J/(kg K)], positive (287.05 for air).

  • T (float or array_like) – Absolute temperature [K], positive.

Returns:

Speed of sound [m/s].

Return type:

float or ndarray

Notes

Newton’s isothermal estimate is \(\sqrt{RT}\); Laplace’s adiabatic correction multiplies it by \(\sqrt{\gamma}\). Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(speed_of_sound(1.4, 287.05, 288.15)), 2)
340.29
engineeringkit.aerodynamics.stagnation_pressure(p, M, gamma=1.4)[source]#

Isentropic stagnation pressure \(p_0 = p(1 + \tfrac{\gamma-1}{2}M^2)^{\gamma/(\gamma-1)}\).

Parameters:
  • p (float or array_like) – Static pressure [Pa], positive.

  • M (float or array_like) – Mach number [-], nonnegative.

  • gamma (float, optional) – Ratio of specific heats [-], greater than one.

Returns:

Stagnation (total) pressure [Pa].

Return type:

float or ndarray

Notes

Not conserved across a shock wave. Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

References

A. J. C. B. de Saint-Venant and L. Wantzel, “Mémoire et expériences sur l’écoulement de l’air,” J. École Polytech. 16 (1839) 85-122.

Examples

>>> round(float(stagnation_pressure(100.0, 2.0)), 3)
782.445
engineeringkit.aerodynamics.stagnation_temperature(T, M, gamma=1.4)[source]#

Isentropic stagnation temperature \(T_0 = T(1 + \tfrac{\gamma-1}{2}M^2)\).

Parameters:
  • T (float or array_like) – Static temperature [K], positive.

  • M (float or array_like) – Mach number [-], nonnegative.

  • gamma (float, optional) – Ratio of specific heats [-], greater than one.

Returns:

Stagnation (total) temperature [K].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers; see Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(stagnation_temperature(300.0, 2.0)), 6)
540.0
engineeringkit.aerodynamics.stall_speed(weight, rho, S, Clmax)[source]#

Minimum level-flight speed \(V_s = \sqrt{2W / (\rho S C_{L,\max})}\).

Setting lift equal to weight at the largest attainable lift coefficient gives the slowest speed at which the wing can still support the aircraft.

Parameters:
  • weight (float or array_like) – Aircraft weight [N], positive.

  • rho (float or array_like) – Air density [kg/m^3], positive.

  • S (float or array_like) – Wing area [m^2], positive.

  • Clmax (float or array_like) – Maximum lift coefficient [-], positive.

Returns:

Stall speed [m/s].

Return type:

float or ndarray

Notes

Inputs are raw SI numbers with no dimensional metadata; assumptions and validity limits are in Aerodynamics: incompressible limits and compressible conservation.

Examples

>>> round(float(stall_speed(12000.0, 1.2, 20.0, 1.5)), 4)
25.8199
engineeringkit.aerodynamics.thin_airfoil_cl(alpha_rad, alpha_l0=0.0)[source]#

Thin-airfoil section lift coefficient \(c_l = 2\pi(\alpha - \alpha_{L=0})\).

Parameters:
  • alpha_rad (float or array_like) – Angle of attack [rad].

  • alpha_l0 (float, optional) – Zero-lift angle of attack [rad]; zero for a symmetric section and negative for positive camber (see naca4_zero_lift_angle()).

Returns:

Section lift coefficient [-].

Return type:

float or ndarray

Notes

Small angles and attached, inviscid, incompressible flow are assumed; stall is not predicted. Inputs are raw SI numbers with no dimensional metadata; see Aerodynamics: incompressible limits and compressible conservation.

References

H. Glauert, The Elements of Aerofoil and Airscrew Theory (Cambridge University Press, 1926), ch. 7.

Examples

>>> round(float(thin_airfoil_cl(0.1)), 6)
0.628319

Visualizers#

Matplotlib visualizers for engineeringkit.aerodynamics.

engineeringkit.aerodynamics.visualizers.plot_airfoil(airfoil, ax=None)[source]#

Draw an airfoil outline and its mean camber line on equal axes.

Parameters:
Return type:

matplotlib.axes.Axes

engineeringkit.aerodynamics.visualizers.plot_atmosphere(state, axes=None)[source]#

Plot temperature, pressure and density against altitude side by side.

Parameters:
Return type:

ndarray of matplotlib.axes.Axes

engineeringkit.aerodynamics.visualizers.plot_drag_polar(cl, cd, ax=None, label=None)[source]#

Plot lift coefficient against drag coefficient and mark the best-glide tangent.

Parameters:
  • cl (array_like) – Matching lift and drag coefficients [-].

  • cd (array_like) – Matching lift and drag coefficients [-].

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on; a new figure is created if omitted.

  • label (str, optional) – Legend label for the polar.

Return type:

matplotlib.axes.Axes