Prandtl-Meyer Expansion
This module provides functions for analyzing Prandtl-Meyer expansion waves, which occur when supersonic flow turns around a convex corner or expands through a diverging channel.
Overview
Prandtl-Meyer expansion waves are isentropic compression waves that occur when supersonic flow encounters a convex corner or expansion. Unlike shock waves, expansion waves:
- Are isentropic (reversible process)
- Increase Mach number and velocity
- Decrease pressure, density, and temperature
- Maintain total temperature and pressure
- Can turn flow through large angles without losses
- Consist of infinitesimally weak waves (Mach waves)
Theory
Prandtl-Meyer expansion is governed by the Prandtl-Meyer function ν(M), which relates the Mach number to the maximum turning angle:
Prandtl-Meyer function: $\nu(M) = \sqrt{\frac{\gamma+1}{\gamma-1}} \arctan\sqrt{\frac{\gamma-1}{\gamma+1}(M^2-1)} - \arctan\sqrt{M^2-1}$
Turning angle relationship: $\theta_{12} = \nu(M_2) - \nu(M_1)$
Property ratios (from isentropic relations):
- Pressure: $\frac{p_2}{p_1} = \left(\frac{1 + \frac{\gamma-1}{2}M_1^2}{1 + \frac{\gamma-1}{2}M_2^2}\right)^{\frac{\gamma}{\gamma-1}}$
- Temperature: $\frac{T_2}{T_1} = \frac{1 + \frac{\gamma-1}{2}M_1^2}{1 + \frac{\gamma-1}{2}M_2^2}$
- Density: $\frac{\rho_2}{\rho_1} = \left(\frac{1 + \frac{\gamma-1}{2}M_1^2}{1 + \frac{\gamma-1}{2}M_2^2}\right)^{\frac{1}{\gamma-1}}$
Where:
- $M_1$, $M_2$ = upstream and downstream Mach numbers
- $\theta_{12}$ = turning angle from state 1 to state 2
- $\gamma$ = specific heat ratio
Functions
CompAir.prandtl_meyer
— Functionprandtl_meyer(M, gamma=1.4)
Prandtl Meyer 함수 nu 계산
인자
M::Float64
: 입구 마하수gamma::Float64=1.4
: 비열비
반환값
nu::Float64
: Prandtl-Meyer 함수 (단위: 도)
CompAir.expand_mach2
— Functionexpand_mach2(M1, theta, gamma=1.4)
마하수 M1인 유동이 theta 만큼 회전했을 때 마하수 계산
인자
M1::Float64
: 입구 마하수theta::Float64
: 유동 회전 각도 (단위: 도)gamma::Float64=1.4
: 비열비
반환값
mach::Float64
: 팽창파를 지난 후 마하수
CompAir.expand_p2
— Functionexpand_p2(M1, theta, gamma=1.4)
마하수 M1인 유동이 theta 만큼 회전했을 때 압력 계산
인자
M1::Float64
: 입구 마하수theta::Float64
: 유동 회전 각도 (단위: 도)gamma::Float64=1.4
: 비열비
반환값
p::Float64
: 팽창파를 지난 후 압력비 (p1/p2)
CompAir.theta_p
— Functiontheta_p(pratio, M1, gamma=1.4)
압력비를 만족하도록 발생하는 팽창파 각도 계산
인자
pratio::Float64
: 팽창파 전/후 압력비 (p1/p2)M1::Float64
: 입구 마하수gamma::Float64=1.4
: 비열비
반환값
theta::Float64
: 유동 회전 각도 (단위: 도)
Function Details
prandtl_meyer
prandtl_meyer(M, gamma=1.4)
Calculate the Prandtl-Meyer function ν(M) which represents the maximum turning angle from sonic conditions.
Arguments:
M::Real
: Mach number (must be ≥ 1)gamma::Real=1.4
: Specific heat ratio
Returns:
Float64
: Prandtl-Meyer angle ν in degrees
Formula: $\nu(M) = \sqrt{\frac{\gamma+1}{\gamma-1}} \arctan\sqrt{\frac{\gamma-1}{\gamma+1}(M^2-1)} - \arctan\sqrt{M^2-1}$
Example:
julia> prandtl_meyer(2.0)
26.379760813416906
julia> prandtl_meyer(3.0)
49.75681638417519
julia> prandtl_meyer(1.0)
0.0
expand_mach2
expand_mach2(M1, theta, gamma=1.4)
Calculate the downstream Mach number after a Prandtl-Meyer expansion through angle θ.
Arguments:
M1::Real
: Upstream Mach numbertheta::Real
: Turning angle in degreesgamma::Real=1.4
: Specific heat ratio
Returns:
Float64
: Downstream Mach number
Example:
julia> expand_mach2(2.0, 20.0)
2.3848314132746953
julia> expand_mach2(1.5, 10.0)
1.7985676229179285
expand_p2
expand_p2(M1, theta, gamma=1.4)
Calculate the pressure ratio (p₁/p₂) across a Prandtl-Meyer expansion.
Arguments:
M1::Real
: Upstream Mach numbertheta::Real
: Turning angle in degreesgamma::Real=1.4
: Specific heat ratio
Returns:
Float64
: Pressure ratio p₁/p₂
Example:
julia> expand_p2(2.0, 20.0)
1.687094471207049
julia> expand_p2(3.0, 15.0)
1.4720270270270274
theta_p
theta_p(pratio, M1, gamma=1.4)
Calculate the turning angle required to achieve a specified pressure ratio across an expansion.
Arguments:
pratio::Real
: Desired pressure ratio p₁/p₂M1::Real
: Upstream Mach numbergamma::Real=1.4
: Specific heat ratio
Returns:
Float64
: Required turning angle in degrees
Example:
julia> theta_p(1.5, 2.0)
14.396394107665233
julia> theta_p(2.0, 2.5)
22.69419642857143
Applications
Supersonic Nozzle Design
Design the diverging section of a supersonic nozzle:
# Design requirements
M_exit = 3.5 # Exit Mach number
M_throat = 1.0 # Throat conditions
theta_max = 15.0 # Maximum wall angle
println("Supersonic Nozzle Design:")
println("Exit Mach: $M_exit")
println("Maximum wall angle: $theta_max°")
# Calculate required turning angle
nu_exit = prandtl_meyer(M_exit)
nu_throat = prandtl_meyer(M_throat) # = 0 for M = 1
theta_required = nu_exit - nu_throat
println("Required turning angle: $(round(theta_required, digits=1))°")
# Check if design is feasible
if theta_required/2 <= theta_max
println("Design feasible - wall angle: $(round(theta_required/2, digits=1))°")
# Calculate area ratio
area_ratio = area_ratio_at(M_exit)
println("Area ratio A_exit/A*: $(round(area_ratio, digits=2))")
else
println("Design not feasible - requires curved walls or multiple sections")
# Calculate required sections
n_sections = ceil(theta_required / (2 * theta_max))
println("Minimum sections required: $n_sections")
end
Centered Expansion Fan
Analyze a centered expansion fan:
M1 = 1.5
theta_total = 30.0 # Total turning angle
n_waves = 6 # Number of Mach waves
println("Centered Expansion Fan Analysis:")
println("Initial Mach: $M1")
println("Total turning: $theta_total°")
println("Number of waves: $n_waves")
theta_step = theta_total / n_waves
println("\nWave\tθ (°)\tM\tμ (°)\tp/p₁")
println("----\t-----\t-----\t-----\t-----")
for i in 0:n_waves
theta_current = i * theta_step
if i == 0
M_current = M1
p_ratio = 1.0
else
M_current = expand_mach2(M1, theta_current)
p_ratio = 1.0 / expand_p2(M1, theta_current)
end
mu = asind(1/M_current) # Mach angle
println("$i\t$(round(theta_current, digits=1))\t$(round(M_current, digits=3))\t$(round(mu, digits=1))\t$(round(p_ratio, digits=3))")
end
Flow Over Expansion Corner
Analyze flow over a sharp expansion corner:
# Supersonic flow over a backward-facing step
M1 = 2.2
step_angle = 12.0 # degrees
println("Flow Over Expansion Corner:")
println("Upstream Mach: $M1")
println("Corner angle: $step_angle°")
# Expansion analysis
M2 = expand_mach2(M1, step_angle)
p_ratio = expand_p2(M1, step_angle)
# Calculate other properties
T_ratio = (1 + 0.2*M1^2) / (1 + 0.2*M2^2)
rho_ratio = (T_ratio)^(1/0.4)
println("\nDownstream conditions:")
println("Mach number: $(round(M2, digits=3))")
println("Pressure ratio p₁/p₂: $(round(p_ratio, digits=3))")
println("Temperature ratio T₁/T₂: $(round(T_ratio, digits=3))")
println("Density ratio ρ₁/ρ₂: $(round(rho_ratio, digits=3))")
# Wave angles
mu1 = asind(1/M1) # Upstream Mach angle
mu2 = asind(1/M2) # Downstream Mach angle
println("\nWave characteristics:")
println("Upstream Mach angle: $(round(mu1, digits=1))°")
println("Downstream Mach angle: $(round(mu2, digits=1))°")
Method of Characteristics Application
Simple application showing characteristic line method concepts:
# Prandtl-Meyer expansion around a corner
M1 = 2.0
theta_total = 30.0 # Total turning angle
n_steps = 6 # Number of characteristic steps
println("Method of Characteristics Example:")
println("Initial Mach: $M1")
println("Total turning: $theta_total°")
println("Steps: $n_steps")
theta_step = theta_total / n_steps
M_current = M1
println("\nStep\tθ(°)\tM\tν(°)\tμ(°)")
println("----\t----\t-----\t-----\t-----")
for i in 0:n_steps
theta_current = i * theta_step
if i == 0
nu_current = prandtl_meyer(M_current)
mu_current = asind(1/M_current) # Mach angle
println("$i\t$(round(theta_current, digits=1))\t$(round(M_current, digits=3))\t$(round(nu_current, digits=2))\t$(round(mu_current, digits=1))")
else
M_current = expand_mach2(M1, theta_current)
nu_current = prandtl_meyer(M_current)
mu_current = asind(1/M_current)
println("$i\t$(round(theta_current, digits=1))\t$(round(M_current, digits=3))\t$(round(nu_current, digits=2))\t$(round(mu_current, digits=1))")
end
end
# Compare with exact solution
M_exact = expand_mach2(M1, theta_total)
println("\nExact solution M_final: $(round(M_exact, digits=3))")
println("Final step M: $(round(M_current, digits=3))")
println("Error: $(round(abs(M_exact - M_current)/M_exact * 100, digits=2))%")
Different Gases
Analyze Prandtl-Meyer expansion for different gases:
M1 = 2.0
theta = 20.0
gases = [
("Air", 1.4),
("Helium", 1.67),
("Argon", 1.67),
("CO₂", 1.3)
]
println("Gas Effects on Prandtl-Meyer Expansion:")
println("M₁ = $M1, θ = $theta°")
println("Gas\tγ\tM₂\tp₁/p₂\tν₁ (°)\tν₂ (°)")
println("---\t----\t----\t-----\t------\t------")
for (gas, gamma) in gases
M2 = expand_mach2(M1, theta, gamma)
p_ratio = expand_p2(M1, theta, gamma)
nu1 = prandtl_meyer(M1, gamma)
nu2 = prandtl_meyer(M2, gamma)
println("$gas\t$gamma\t$(round(M2, digits=3))\t$(round(p_ratio, digits=2))\t$(round(nu1, digits=1))\t$(round(nu2, digits=1))")
end
Maximum Turning Angle
Find the maximum theoretical turning angle:
# For very high Mach numbers, ν approaches a maximum value
M_high = 100.0
nu_max = prandtl_meyer(M_high)
println("Maximum Prandtl-Meyer angle:")
println("ν(M→∞) ≈ $(round(nu_max, digits=1))°")
# Theoretical maximum for γ = 1.4
nu_theoretical = (sqrt((1.4+1)/(1.4-1)) - 1) * 90
println("Theoretical maximum: $(round(nu_theoretical, digits=1))°")
Validation Examples
Prandtl-Meyer Function Values
Calculate the Prandtl-Meyer function for different Mach numbers:
println("M\tν(M) (°)")
println("---\t-------")
for M in 1.0:0.2:4.0
if M > 1.0 # Function only valid for M > 1
nu = prandtl_meyer(M)
println("$(round(M, digits=1))\t$(round(nu, digits=1))")
else
println("$(round(M, digits=1))\t0.0")
end
end
Inverse Problem - Find Mach from Turning Angle
Given a turning angle, find the required initial Mach number:
M2_target = 3.0
theta_given = 25.0 # degrees
# Calculate required upstream Mach number
nu2 = prandtl_meyer(M2_target)
nu1 = nu2 - theta_given
# Find M1 by inverse of Prandtl-Meyer function (iterative)
M1_estimate = 1.5 # Initial guess
tolerance = 1e-6
for i in 1:100
nu_calc = prandtl_meyer(M1_estimate)
error = nu_calc - nu1
if abs(error) < tolerance
break
end
# Simple Newton-like iteration
M1_estimate -= error / 10.0
M1_estimate = max(M1_estimate, 1.001) # Keep supersonic
end
println("Inverse Prandtl-Meyer Problem:")
println("Target M₂: $M2_target")
println("Given turning angle: $theta_given°")
println("Required M₁: $(round(M1_estimate, digits=3))")
# Verify
M2_check = expand_mach2(M1_estimate, theta_given)
println("Verification M₂: $(round(M2_check, digits=3))")
Limitations and Considerations
- Isentropic assumption: Valid only for gradual expansions without shock waves
- Perfect gas: Constant specific heats and ideal gas behavior
- Steady flow: Time-invariant conditions
- Two-dimensional flow: Assumes planar or axisymmetric geometry
- Gradual expansion: Sharp corners may cause finite-strength waves
- Supersonic flow: Functions only valid for M > 1
For viscous effects, unsteady phenomena, or real gas behavior, additional analysis methods are required.
See Also
- Oblique Shock Waves: For compression processes
- Isentropic Relations: For property ratios
- Normal Shock Waves: For normal compression
- Nozzle Analysis: For nozzle design applications