π¬
Solver Purpose & Physical Scope
Size converging-diverging de Laval nozzles, identifying normal shock location inside diverging section, choked mass flow rate, exit Mach, and rocket thrust.
π Discipline: Cfd
β‘ Precision: IEEE-754 64-bit Real(`real(8)`)
π₯ Total Downloads: 356 times
π Source File:
supersonic_converging_diverging_nozzle.f90
π calcul/CFD /
supersonic_converging_diverging_nozzle.f90
program supersonic_converging_diverging_nozzle
implicit none
integer :: iostat_val, iter
double precision :: Dt_throat_mm, Ae_At_ratio, L_div_mm, P0_bar, T0_K, Pb_bar, gamma_ratio
double precision :: At_m2, Ae_m2, R_gas, mdot_choked_kgs, Me_design, Pe_design_bar
double precision :: M_sub_exit, P_crit1_bar, P_crit2_bar, Me_actual, Pe_actual_bar
double precision :: x_shock_pct, Ms_pre, M_low, M_high, M_mid, ar_mid
double precision :: Ve_actual_ms, thrust_N, CF_thrust
character(len=40) :: nozzle_regime
double precision, parameter :: PI = 3.141592653589793d0
! Read inputs
read(*,*,iostat=iostat_val) Dt_throat_mm ! Throat Diameter [mm] (e.g. 50.0)
read(*,*,iostat=iostat_val) Ae_At_ratio ! Exit Area Ratio Ae/At (e.g. 2.50)
read(*,*,iostat=iostat_val) L_div_mm ! Diverging Length [mm] (e.g. 180.0)
read(*,*,iostat=iostat_val) P0_bar ! Stagnation Pressure [bar] (e.g. 10.0)
read(*,*,iostat=iostat_val) T0_K ! Stagnation Temp [K] (e.g. 500.0)
read(*,*,iostat=iostat_val) Pb_bar ! Back Pressure [bar] (e.g. 1.013)
read(*,*,iostat=iostat_val) gamma_ratio ! Specific Heat Ratio (e.g. 1.40)
if (iostat_val /= 0) then
write(*,*) 'ERROR: Invalid input data for de Laval nozzle calculation.'
stop
end if
if (Dt_throat_mm <= 0.0d0 .or. Ae_At_ratio <= 1.0d0 .or. P0_bar <= 0.0d0 .or. Pb_bar <= 0.0d0) then
write(*,*) 'ERROR: All geometric and pressure parameters must be positive, Ae/At > 1.'
stop
end if
R_gas = 287.05d0
At_m2 = (PI / 4.0d0) * ((Dt_throat_mm * 1.0d-3)**2)
Ae_m2 = At_m2 * Ae_At_ratio
! Choked Mass Flow Rate [kg/s]
mdot_choked_kgs = (P0_bar * 1.0d5 * At_m2 / sqrt(T0_K)) * sqrt(gamma_ratio / R_gas) * &
((2.0d0 / (gamma_ratio + 1.0d0))**((gamma_ratio + 1.0d0) / (2.0d0 * (gamma_ratio - 1.0d0))))
! Solve for Design Supersonic Exit Mach Me_design via Bisection
M_low = 1.001d0
M_high = 8.0d0
do iter = 1, 80
M_mid = 0.5d0 * (M_low + M_high)
ar_mid = (1.0d0 / M_mid) * (((2.0d0 + (gamma_ratio - 1.0d0) * (M_mid**2)) / &
(gamma_ratio + 1.0d0))**((gamma_ratio + 1.0d0) / (2.0d0 * (gamma_ratio - 1.0d0))))
if (ar_mid < Ae_At_ratio) then
M_low = M_mid
else
M_high = M_mid
end if
end do
Me_design = M_mid
Pe_design_bar = P0_bar * (1.0d0 + 0.5d0 * (gamma_ratio - 1.0d0) * (Me_design**2))**(-gamma_ratio / (gamma_ratio - 1.0d0))
! Solve for Subsonic Exit Mach M_sub_exit
M_low = 0.001d0
M_high = 0.999d0
do iter = 1, 80
M_mid = 0.5d0 * (M_low + M_high)
ar_mid = (1.0d0 / M_mid) * (((2.0d0 + (gamma_ratio - 1.0d0) * (M_mid**2)) / &
(gamma_ratio + 1.0d0))**((gamma_ratio + 1.0d0) / (2.0d0 * (gamma_ratio - 1.0d0))))
if (ar_mid > Ae_At_ratio) then
M_low = M_mid
else
M_high = M_mid
end if
end do
M_sub_exit = M_mid
P_crit1_bar = P0_bar * (1.0d0 + 0.5d0 * (gamma_ratio - 1.0d0) * (M_sub_exit**2))**(-gamma_ratio / (gamma_ratio - 1.0d0))
! Normal Shock at Exit Plane Pressure P_crit2
P_crit2_bar = Pe_design_bar * (2.0d0 * gamma_ratio * (Me_design**2) - (gamma_ratio - 1.0d0)) / (gamma_ratio + 1.0d0)
! Regime Classification & Shock Position Determination
if (Pb_bar >= P_crit1_bar) then
nozzle_regime = 'Subsonic Venturi Flow (Unchoked Throat)'
x_shock_pct = 0.0d0
Me_actual = M_sub_exit
Pe_actual_bar = Pb_bar
else if (Pb_bar > P_crit2_bar) then
nozzle_regime = 'Normal Shock in Diverging Section'
! Shock position interpolated between throat (0%) and exit (100%)
x_shock_pct = ((P_crit1_bar - Pb_bar) / (P_crit1_bar - P_crit2_bar)) * 100.0d0
Me_actual = 0.65d0
Pe_actual_bar = Pb_bar
else if (abs(Pb_bar - P_crit2_bar) < 0.02d0 * P_crit2_bar) then
nozzle_regime = 'Normal Shock at Exit Plane'
x_shock_pct = 100.0d0
Me_actual = sqrt((1.0d0 + 0.5d0*(gamma_ratio-1.0d0)*(Me_design**2)) / (gamma_ratio*(Me_design**2) - 0.5d0*(gamma_ratio-1.0d0)))
Pe_actual_bar = Pb_bar
else if (Pb_bar > Pe_design_bar) then
nozzle_regime = 'Over-Expanded (Oblique Exit Shocks)'
x_shock_pct = 100.0d0
Me_actual = Me_design
Pe_actual_bar = Pe_design_bar
else if (abs(Pb_bar - Pe_design_bar) < 0.02d0 * Pe_design_bar) then
nozzle_regime = 'Perfectly Expanded (Design Condition)'
x_shock_pct = 100.0d0
Me_actual = Me_design
Pe_actual_bar = Pe_design_bar
else
nozzle_regime = 'Under-Expanded (Exit Expansion Fan)'
x_shock_pct = 100.0d0
Me_actual = Me_design
Pe_actual_bar = Pe_design_bar
end if
! Exit velocity & Thrust
Ve_actual_ms = Me_actual * sqrt(gamma_ratio * R_gas * (T0_K / (1.0d0 + 0.5d0 * (gamma_ratio - 1.0d0) * (Me_actual**2))))
thrust_N = mdot_choked_kgs * Ve_actual_ms + (Pe_actual_bar - Pb_bar) * 1.0d5 * Ae_m2
CF_thrust = thrust_N / (P0_bar * 1.0d5 * At_m2)
! Output Results
write(*,'(A)') '============================================================'
write(*,'(A)') ' THERMOFLUIDCALC β SUPERSONIC DE LAVAL NOZZLE ENGINE'
write(*,'(A)') '============================================================'
write(*,'(A,F10.2,A,F10.2)') 'Throat Diam / Area Ratio = ', Dt_throat_mm, ' mm / ', Ae_At_ratio
write(*,'(A,F10.2,A,F10.3,A)')'Stagnation P0 / Back Pb = ', P0_bar, ' bar / ', Pb_bar, ' bar'
write(*,'(A)') '------------------------------------------------------------'
write(*,'(A,A)') 'Flow Regime = ', trim(nozzle_regime)
write(*,'(A,F10.3)') 'Design Supersonic Mach Me = ', Me_design
write(*,'(A,F10.3,A)') 'Design Exit Pressure Pe = ', Pe_design_bar, ' bar'
if (x_shock_pct > 0.0d0 .and. x_shock_pct < 100.0d0) then
write(*,'(A,F10.1,A,F10.1,A)') 'Normal Shock Location = ', x_shock_pct, ' % (x = ', x_shock_pct*L_div_mm/100.0d0, ' mm)'
end if
write(*,'(A,F10.3,A)') 'Mass Flow Rate (Choked) = ', mdot_choked_kgs, ' kg/s'
write(*,'(A,F10.1,A,F10.3)') 'Thrust Force / Coeff CF = ', thrust_N, ' N / ', CF_thrust
write(*,'(A)') '============================================================'
end program supersonic_converging_diverging_nozzle
π» How to Compile & Run Locally
1. Compilation (GNU Fortran / Intel oneAPI):
gfortran -O3 supersonic_converging_diverging_nozzle.f90 -o supersonic_converging_diverging_nozzle
2. Execution with input.txt redirection:
supersonic_converging_diverging_nozzle < input.txt
π Sample input.txt File Structure
Sample Data:
60.0 3.20 220.0 30.0 1800.0 1.013 1.25
Parameter Description:
Throat Diameter [mm]\nExit Area Ratio Ae/At\nDiverging Length [mm]\nChamber Pressure [bar]\nChamber Temp [K]\nBack Pressure [bar]\nSpecific Heat Ratio gamma