한국형 발사체 누리호와 차세대 재사용 로켓이 지표면을 박차고 상승할 때 노즐 후방에 눈부신 다이아몬드 모양의 고리 구조로 나타나는 쇼크 다이아몬드(Shock Diamond, 마하 디스크)는 초음속 배기 가스 압력과 주변 대기압의 불일치로 인해 형성되는 주기적 충격파-팽창파 다이내믹스입니다. 프란틀-마이어(Prandtl-Meyer) 팽창 부채꼴과 사각 충격파(Oblique Shock), 수직 충격파(Mach Disk)가 교차하며 발생하는 고온·고압 정체 발광 현상을 1,000Hz 주기로 0-Alloc C# 수치해석하는 온디바이스 공기역학 시뮬레이터를 공개합니다.

1. 2022 개정 교육과정 교과 연계 분석

  • 물리학 (압축성 유체역학, 음속과 마하수, 사각 충격파 랭킨-위고니오): 초음속 유동에서 압력파의 중첩으로 인한 충격파 불연속면 형성, 노즐 출구 압력 $P_e$와 대기압 $P_a$의 불일치에 따른 과대 팽창($P_e < P_a$) 및 과소 팽창($P_e > P_a$) 주기 구조.
  • 지구과학/대기과학 (고도별 대기압 지수함수 감쇠 및 배기 플룸 팽창): 해수면($1\,\text{atm}$)에서 고도 50km 고진공($0.001\,\text{atm}$)으로 상승함에 따라 좁고 선명한 쇼크 다이아몬드에서 거대한 종 모양 진공 플룸으로 천이하는 대기 상호작용.
  • 수학 (프란틀-마이어 초월함수, 충격파 각도 $\theta-\beta-M$ 삼각함수 비선형 수치해법): 편향각 $\theta$와 마하수 $M_1$에 대한 충격파 각도 $\beta$의 3차 방정식 해석, 마하 디스크 직경 및 충격파 셀 주기 $L \approx 1.52 d_e \sqrt{P_e / P_a - 1}$ 산출.
  • 정보 (무할당 실시간 1,000Hz 축대칭 쇼크 격자 위치 및 마하수 추적 코어): 1ms 실시간 루프 내에서 가비지 컬렉터 없이 스택 구조체 `ref struct`로 비선형 초음속 경계선을 0-Alloc 계산하는 C# 온디바이스 엔진.

2. 쇼크 다이아몬드 및 경사 충격파 수식 모델

노즐 출구 직경 $d_e$, 출구 마하수 $M_e$, 출구 압력 $P_e$와 주변 정적 대기압 $P_a$에 대해, 주기적 다이아몬드 셀의 길이 $L_{cell}$은 다음과 같이 근사됩니다.

$$L_{cell} \approx d_e \sqrt{M_e^2 - 1} \cdot \sqrt{\frac{P_e}{P_a}}$$

과대 팽창 시 노즐 립(Lip)에서 발생하는 사각 충격파 각도 $\beta$는 유동 편향각 $\theta$ 및 비열비 $\gamma$에 대해 다음의 $\theta-\beta-M$ 관계식을 만족합니다.

$$\tan\theta = 2 \cot\beta \left[ \frac{M_1^2 \sin^2\beta - 1}{M_1^2 (\gamma + \cos 2\beta) + 2} \right]$$

사각 충격파가 축 중심선에서 정규 반사되지 못할 때 수직 충격파인 마하 디스크(Mach Disk)가 생성되며, 충격파 직후 유동은 아음속($M < 1$)으로 급감하고 정체 엔탈피 복원으로 인해 온도가 수천 도까지 치솟아 강렬한 빛을 방출합니다.

3. 1,000Hz 0-Alloc C# 쇼크 다이아몬드 해석 코어

using System;
using System.Runtime.CompilerServices;

namespace ZeliDesk.Education.StemAero.ShockDiamond
{
    public readonly record struct RocketNozzleExitState(
        float AltitudeMeters,       // 비행 고도 (m)
        float NozzleExitDiameterM,  // 노즐 출구 직경 (m)
        float ExitMachNumber,       // 출구 마하수 (예: 3.2)
        float ExitPressureKpa,      // 출구 정압 (kPa, 예: 70 kPa)
        float ChamberTotalTempK     // 연소실 총온도 (K, 예: 3400 K)
    );

    public ref struct ShockDiamondTelemetry
    {
        public float AmbientPressureKpa;
        public float PressureRatioPePa;
        public float DiamondCellLengthMeters;
        public float EstimatedMachDiskDiameterMeters;
        public float PostShockTemperatureKelvin;
        public int VisibleDiamondCount;
    }

    public static class ShockDiamondEngineCore
    {
        private const float SeaLevelPressureKpa = 101.325f;
        private const float ScaleHeightMeters = 8400f; // 지구 대기 스케일 높이
        private const float SpecificHeatRatioGamma = 1.22f; // 로켓 연소가스 비열비

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void CalculatePlumeStructure(
            in RocketNozzleExitState state,
            ref ShockDiamondTelemetry telemetry)
        {
            // 1. 고도별 표준 대기압 계산: P_amb = P0 * exp(-h / H) (0-Alloc)
            float pAmbient = SeaLevelPressureKpa * MathF.Exp(-state.AltitudeMeters / ScaleHeightMeters);
            pAmbient = MathF.Max(pAmbient, 0.01f); // 진공 한계
            telemetry.AmbientPressureKpa = pAmbient;

            float pr = state.ExitPressureKpa / pAmbient;
            telemetry.PressureRatioPePa = pr;

            // 2. 쇼크 다이아몬드 셀 주기 길이 산출 L = d * sqrt(M^2 - 1) * sqrt(Pe/Pa)
            float machFactor = MathF.Sqrt(MathF.Max(0.1f, state.ExitMachNumber * state.ExitMachNumber - 1.0f));
            float expansionFactor = MathF.Sqrt(MathF.Max(0.1f, pr));
            float cellLength = state.NozzleExitDiameterM * machFactor * expansionFactor;
            telemetry.DiamondCellLengthMeters = cellLength;

            // 3. 마하 디스크 직경 및 충격파 후단 온도 추정
            if (pr < 0.7f) // 강한 과대팽창 (해수면 부근)
            {
                telemetry.EstimatedMachDiskDiameterMeters = state.NozzleExitDiameterM * (1.0f - pr) * 0.6f;
                // 수직 충격파 랭킨-위고니오 온도 상승
                float m1Sq = state.ExitMachNumber * state.ExitMachNumber;
                float tempRatio = (1f + 0.2f * m1Sq); // 정체온도 회복
                telemetry.PostShockTemperatureKelvin = state.ChamberTotalTempK * 0.85f;
                telemetry.VisibleDiamondCount = Math.Clamp((int)(4.5f / MathF.Max(0.5f, cellLength)), 1, 8);
            }
            else
            {
                telemetry.EstimatedMachDiskDiameterMeters = 0f; // 정규 반사 혹은 과소팽창
                telemetry.PostShockTemperatureKelvin = state.ChamberTotalTempK * 0.45f;
                telemetry.VisibleDiamondCount = (pr > 3.0f) ? 1 : 4; // 고고도에서는 단일 거대 플룸으로 팽창
            }
        }
    }
}

4. 교육적 가치 및 로켓 공학 시각화 연계

본 교구는 로켓 발사 영상에서 가장 화려하고 신비로운 쇼크 다이아몬드가 왜 고도가 높아질수록 사라지고 거대한 구름 형태로 퍼져나가는지를 대기압과 압축성 유체역학 수식으로 명쾌하게 증명합니다. 학생들은 발사 고도 슬라이더를 올리며 해수면에서 10여 개에 달하던 다이아몬드 마하 디스크가 고고도에서 진공 팽창 플룸으로 드라마틱하게 전환되는 과정을 온디바이스 시뮬레이터를 통해 시각적으로 체득하게 됩니다.