Normal Shock Waves
This module provides functions for analyzing normal shock waves, which are compression waves that occur perpendicular to the flow direction in supersonic flows.
Overview
Normal shock waves are sudden compression phenomena that occur when supersonic flow encounters an obstruction or adverse pressure gradient. They are characterized by:
- Instantaneous property changes across a thin wave front
- Entropy increase (irreversible process)
- Mach number reduction from supersonic to subsonic
- Pressure, density, and temperature increases
- Stagnation pressure loss
Theory
Normal shock waves are governed by the Rankine-Hugoniot relations, derived from conservation of mass, momentum, and energy:
Downstream Mach number: $M_2 = \sqrt{\frac{1 + \frac{\gamma-1}{2}M_1^2}{\gamma M_1^2 - \frac{\gamma-1}{2}}}$
Pressure ratio: $\frac{p_2}{p_1} = 1 + \frac{2\gamma}{\gamma+1}(M_1^2 - 1)$
Density ratio: $\frac{\rho_2}{\rho_1} = \frac{(\gamma+1)M_1^2}{2 + (\gamma-1)M_1^2}$
Temperature ratio: $\frac{T_2}{T_1} = \frac{p_2}{p_1} \cdot \frac{\rho_1}{\rho_2}$
Stagnation pressure ratio: $\frac{p_{02}}{p_{01}} = \left(\frac{2\gamma M_1^2 - (\gamma-1)}{\gamma+1}\right)^{\frac{1}{1-\gamma}} \left(\frac{(\gamma+1)M_1^2}{2 + (\gamma-1)M_1^2}\right)^{\frac{\gamma}{1-\gamma}}$
Where subscript 1 denotes upstream conditions and subscript 2 denotes downstream conditions.
Functions
CompAir.mach_after_normal_shock — Functionmach_after_normal_shock(M::Float64, gamma::Float64=1.4)Calculates the Mach number after a normal shock wave.
Arguments
M::Float64: Upstream Mach numbergamma::Float64=1.4: Specific heat ratio
Returns
mach::Float64: Downstream Mach number
CompAir.density_ratio_normal_shock — Functiondensity_ratio_normal_shock(M::Float64, gamma::Float64=1.4)Calculates the density ratio across a normal shock wave.
Arguments
M::Float64: Upstream Mach numbergamma::Float64=1.4: Specific heat ratio
Returns
rho2/rho1::Float64: Density ratio
CompAir.pressure_ratio_normal_shock — Functionpressure_ratio_normal_shock(M::Float64, gamma::Float64=1.4)Calculates the pressure ratio across a normal shock wave.
Arguments
M::Float64: Upstream Mach numbergamma::Float64=1.4: Specific heat ratio
Returns
p2/p1::Float64: Pressure ratio
CompAir.temperature_ratio_normal_shock — Functiontemperature_ratio_normal_shock(M::Float64, gamma::Float64=1.4)Calculates the temperature ratio across a normal shock wave.
Arguments
M::Float64: Upstream Mach numbergamma::Float64=1.4: Specific heat ratio
Returns
t2/t1::Float64: Temperature ratio
CompAir.total_pressure_after_normal_shock — Functiontotal_pressure_after_normal_shock(M::Float64, gamma::Float64=1.4)Calculates the total pressure after a normal shock wave.
Arguments
M::Float64: Upstream Mach numbergamma::Float64=1.4: Specific heat ratio
Returns
p02::Float64: Total pressure after the shock
CompAir.total_pressure_ratio_normal_shock — Functiontotal_pressure_ratio_normal_shock(M::Float64, gamma::Float64=1.4)Calculates the total pressure ratio across a normal shock wave.
Arguments
M::Float64: Upstream Mach numbergamma::Float64=1.4: Specific heat ratio
Returns
p02/p01::Float64: Total pressure ratio
CompAir.solve_normal — Functionsolve_normal(M::Float64, gamma::Float64=1.4)수직 충격파 후 물성치 변화
Arguments
M::Float64: 충격파 전 마하수gamma::Float64=1.4: 비열비
Returns
M2::Float64: 수직충격파 후 마하수rho2::Float64: 수직충격파 전/후 밀도비p2::Float64: 수직충격파 전/후 압력비p0ratio::Float64: 수직충격파 전/후 전압력비
Function Details
machafternormal_shock
mach_after_normal_shock(M, gamma=1.4)Calculate the downstream Mach number after a normal shock wave.
Arguments:
M::Real: Upstream Mach number (must be > 1)gamma::Real=1.4: Specific heat ratio
Returns:
Float64: Downstream Mach number (M₂)
Formula: $M_2 = \sqrt{\frac{1 + \frac{\gamma-1}{2}M_1^2}{\gamma M_1^2 - \frac{\gamma-1}{2}}}$
Example:
julia> mach_after_normal_shock(2.0)
0.5773502691896257
julia> mach_after_normal_shock(3.0)
0.4752229748622233densityrationormal_shock
density_ratio_normal_shock(M, gamma=1.4)Calculate the density ratio across a normal shock wave.
Arguments:
M::Real: Upstream Mach numbergamma::Real=1.4: Specific heat ratio
Returns:
Float64: Density ratio (ρ₂/ρ₁)
Formula: $\frac{\rho_2}{\rho_1} = \frac{(\gamma+1)M_1^2}{2 + (\gamma-1)M_1^2}$
Example:
julia> density_ratio_normal_shock(2.0)
2.6666666666666665
julia> density_ratio_normal_shock(5.0)
5.714285714285714pressurerationormal_shock
pressure_ratio_normal_shock(M, gamma=1.4)Calculate the pressure ratio across a normal shock wave.
Arguments:
M::Real: Upstream Mach numbergamma::Real=1.4: Specific heat ratio
Returns:
Float64: Pressure ratio (p₂/p₁)
Formula: $\frac{p_2}{p_1} = 1 + \frac{2\gamma}{\gamma+1}(M_1^2 - 1)$
Example:
julia> pressure_ratio_normal_shock(2.0)
4.5
julia> pressure_ratio_normal_shock(3.0)
10.333333333333334temperaturerationormal_shock
temperature_ratio_normal_shock(M, gamma=1.4)Calculate the temperature ratio across a normal shock wave.
Arguments:
M::Real: Upstream Mach numbergamma::Real=1.4: Specific heat ratio
Returns:
Float64: Temperature ratio (T₂/T₁)
Formula: $\frac{T_2}{T_1} = \frac{p_2}{p_1} \cdot \frac{\rho_1}{\rho_2}$
Example:
julia> temperature_ratio_normal_shock(2.0)
1.6874999999999998
julia> temperature_ratio_normal_shock(3.0)
1.8076923076923077totalpressureafternormalshock
total_pressure_after_normal_shock(M, gamma=1.4)Calculate the downstream stagnation pressure after a normal shock wave.
Arguments:
M::Real: Upstream Mach numbergamma::Real=1.4: Specific heat ratio
Returns:
Float64: Downstream stagnation pressure coefficient
Example:
julia> total_pressure_after_normal_shock(2.0)
8.526315789473685
julia> total_pressure_after_normal_shock(3.0)
12.061224489795916totalpressurerationormalshock
total_pressure_ratio_normal_shock(M, gamma=1.4)Calculate the stagnation pressure ratio across a normal shock wave.
Arguments:
M::Real: Upstream Mach numbergamma::Real=1.4: Specific heat ratio
Returns:
Float64: Stagnation pressure ratio (p₀₂/p₀₁)
Example:
julia> total_pressure_ratio_normal_shock(2.0)
0.7208738938053097
julia> total_pressure_ratio_normal_shock(3.0)
0.32834049679486917solve_normal
solve_normal(M, gamma=1.4)Complete normal shock analysis - calculate all property changes across the shock.
Arguments:
M::Real: Upstream Mach numbergamma::Real=1.4: Specific heat ratio
Returns:
M2::Float64: Downstream Mach numberrho2::Float64: Density ratio (ρ₂/ρ₁)p2::Float64: Pressure ratio (p₂/p₁)p0ratio::Float64: Stagnation pressure ratio (p₀₂/p₀₁)
Example:
julia> sol = solve_normal(2.5)
(M2 = 0.5130161854439888, rho2_ratio = 3.2, p2_ratio = 7.125, p0_ratio = 0.49949999999999994)
julia> println("M₂ = $(round(sol.M2, digits=3))")
M₂ = 0.513
julia> println("Pressure loss = $(round((1-sol.p0_ratio)*100, digits=1))%")
Pressure loss = 50.1%Applications
Supersonic Inlet Analysis
Analyze normal shock for inlet deceleration:
# Flight conditions
M_flight = 2.2
alt = 11000 # m
# Get atmospheric properties (simplified)
p_amb = 22600 # Pa at 11 km
T_amb = 216.7 # K at 11 km
# Shock analysis for inlet
sol = solve_normal(M_flight)
# Recovery factor
eta_inlet = sol.p0_ratio # Inlet total pressure recovery
println("Supersonic Inlet Analysis:")
println("Flight Mach: $M_flight")
println("Downstream Mach: $(round(sol.M2, digits=3))")
println("Inlet total pressure recovery: $(round(eta_inlet, digits=3))")
println("Pressure recovery: $(round(eta_inlet*100, digits=1))%")Shock Strength Analysis
Analyze how shock strength varies with upstream Mach number:
println("M₁\tM₂\tp₂/p₁\tρ₂/ρ₁\tT₂/T₁\tp₀₂/p₀₁\tLoss %")
println("---\t----\t-----\t-----\t-----\t------\t------")
for M1 in 1.1:0.2:4.0
sol = solve_normal(M1)
T_ratio = temperature_ratio_normal_shock(M1)
loss_percent = (1 - sol.p0_ratio) * 100
println("$(round(M1, digits=1))\t$(round(sol.M2, digits=2))\t$(round(sol.p2_ratio, digits=2))\t$(round(sol.rho2_ratio, digits=2))\t$(round(T_ratio, digits=2))\t$(round(sol.p0_ratio, digits=3))\t$(round(loss_percent, digits=1))")
endPitot Tube Behind Normal Shock
Calculate pitot pressure measurements behind a normal shock:
# Flight conditions
M1 = 2.0
p_static = 25000 # Pa (ambient static pressure)
# Normal shock analysis
sol = solve_normal(M1)
# Pressures
p2_static = p_static * sol.p2_ratio # Static pressure behind shock
p02_pitot = p2_static * total_to_static_pressure_ratio(sol.M2) # Pitot pressure behind shock
# Compare with direct pitot measurement (incorrect for supersonic)
p01_direct = p_static * total_to_static_pressure_ratio(M1) # What pitot would read in supersonic flow
println("Pitot Tube Analysis in Supersonic Flow:")
println("Freestream Mach: $M1")
println("Ambient static pressure: $(p_static/1000) kPa")
println("\nCorrect measurement (behind shock):")
println(" Static pressure behind shock: $(round(p2_static/1000, digits=1)) kPa")
println(" Pitot pressure: $(round(p02_pitot/1000, digits=1)) kPa")
println("\nIncorrect direct measurement:")
println(" Direct pitot reading: $(round(p01_direct/1000, digits=1)) kPa")
println(" Error factor: $(round(p01_direct/p02_pitot, digits=2))")Shock Tube Calculations
Calculate conditions in a shock tube:
# Initial conditions (driven section)
p4 = 101325 # Pa (atmospheric)
T4 = 300 # K
M_shock = 5.0 # Shock Mach number
# Calculate conditions behind shock (region 2)
sol = solve_normal(M_shock)
T_ratio = temperature_ratio_normal_shock(M_shock)
p2 = p4 * sol.p2_ratio
T2 = T4 * T_ratio
# Contact surface velocity (region 2 and 3 velocity)
a4 = sqrt(1.4 * 287 * T4) # Sound speed in region 4
u_contact = a4 * M_shock * (1 - 1/sol.rho2_ratio)
println("Shock Tube Analysis:")
println("Shock Mach number: $M_shock")
println("Initial pressure (region 4): $(p4/1000) kPa")
println("Initial temperature (region 4): $T4 K")
println("\nBehind shock (region 2):")
println(" Pressure: $(round(p2/1000, digits=1)) kPa")
println(" Temperature: $(round(T2, digits=1)) K")
println(" Density ratio: $(round(sol.rho2_ratio, digits=2))")
println("\nContact surface velocity: $(round(u_contact, digits=1)) m/s")Different Gases
Calculate shock properties for different gases:
M1 = 2.5
gases = [
("Air", 1.4),
("Helium", 1.67),
("Argon", 1.67),
("CO₂", 1.3)
]
println("Gas\tγ\tM₂\tp₂/p₁\tρ₂/ρ₁\tp₀₂/p₀₁")
println("---\t----\t----\t-----\t-----\t------")
for (gas, gamma) in gases
M2 = mach_after_normal_shock(M1, gamma)
p_ratio = pressure_ratio_normal_shock(M1, gamma)
rho_ratio = density_ratio_normal_shock(M1, gamma)
p0_ratio = total_pressure_ratio_normal_shock(M1, gamma)
println("$gas\t$gamma\t$(round(M2, digits=3))\t$(round(p_ratio, digits=2))\t$(round(rho_ratio, digits=2))\t$(round(p0_ratio, digits=3))")
endValidation Examples
Conservation Laws Check
Verify that the Rankine-Hugoniot relations satisfy conservation laws:
M1 = 3.0
gamma = 1.4
# Calculate all ratios
M2 = mach_after_normal_shock(M1, gamma)
p_ratio = pressure_ratio_normal_shock(M1, gamma)
rho_ratio = density_ratio_normal_shock(M1, gamma)
T_ratio = temperature_ratio_normal_shock(M1, gamma)
# Check ideal gas law: p₂/p₁ = (ρ₂/ρ₁)(T₂/T₁)
ideal_gas_check = p_ratio - (rho_ratio * T_ratio)
# Check momentum conservation
# Should satisfy: p₂ + ρ₂u₂² = p₁ + ρ₁u₁²
# Where u = Ma for convenience (normalized by sound speed)
println("Conservation Laws Verification:")
println("Ideal gas law check: $(round(ideal_gas_check, digits=10))")
println("(Should be ≈ 0)")Limitations and Considerations
- One-dimensional flow: Assumes uniform properties across the shock front
- Steady flow: Time-invariant shock position
- Perfect gas: Constant specific heats and ideal gas behavior
- No viscous effects: Inviscid flow assumption
- Thin shock: Shock thickness much smaller than characteristic length scales
For three-dimensional effects, unsteady phenomena, or real gas behavior, additional analysis methods are required.
See Also
- Oblique Shock Waves: For angled shock waves
- Isentropic Relations: For shock-free flow analysis
- Prandtl-Meyer Expansion: For expansion waves
- Nozzle Analysis: For internal flow applications