0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ロケットのノズルはなぜ一度細くしてから広げるのか。ド・ラバルノズルをJavaScriptで設計

0
Posted at

「え、これってただの管が細くなってまた太くなってるだけですよね?」

そう思ったあなた、正解です。でもこの「ただのくびれ」が、ロケットを宇宙に飛ばし、戦闘機を音速の壁を越えさせ、産業用ジェットで素材を切断するほどの威力を秘めているんです。

収縮拡大ノズル、通称ド・ラバルノズル。スウェーデンの技術者カール・ド・ラバルが蒸気タービン用に発明したこの形状は、今やロケットエンジン・超音速風洞・スプレーガンに至るまで、ありとあらゆる流体機械で使われています。

「なぜ細くなってから広がる必要があるの?ただ細くすれば速くなるんじゃないの?」

その疑問、まさに本質をついています。今日はこの魔法の管を、数式とコードと実機の知見で完全に解剖します。

今回はこちらのツールを題材にします👇

▶ 今回のシミュレーター: 収縮拡大ノズル(ド・ラバルノズル)設計計算機 (ブラウザで動作・登録不要)


ざっくり本質──「亜音速と超音速では、流れのルールが真逆になる」

まず直感をつかみましょう。

亜音速の世界(M < 1)では、流路を狭めると流速は上がります。水道のホームの先を指でつまむと水が勢いよく出る──あれです。

ところが音速(M = 1)を超えると、ルールが逆転します。

超音速では、流路を広げないと加速できない。つまり、亜音速から超音速に移行するには、一度狭めて音速に到達させ、その後広げてさらに加速する──この「収縮→拡大」の形状が絶対条件になるんです。

「ド・ラバルノズルとは、流れの性質が切り替わる『音速の関所』を、形状で強制的に突破する装置である」

これが本質です。


数式で理解する──たった3つの式でノズルは設計できる

では、この現象を支配する数式を見ていきましょう。驚くべきことに、たった3つの式でノズル全体の流れが決まります。

① 温度とマッハ数の関係(エネルギー保存)

\frac{T}{T_0} = \left(1 + \frac{\gamma - 1}{2} M^2\right)^{-1}
  • $T_0$: よどみ点温度(入口で流速ゼロのときの温度)
  • $T$: ある断面での温度
  • $M$: その断面でのマッハ数
  • $\gamma$: 比熱比(空気なら1.4)

意味: 流れが加速するほど温度は下がる。超音速ノズルでは出口で猛烈に冷える(ロケットノズル出口は零下になることも)。

② 圧力とマッハ数の関係(等エントロピー関係)

\frac{p}{p_0} = \left(1 + \frac{\gamma - 1}{2} M^2\right)^{-\frac{\gamma}{\gamma - 1}}

意味: 加速するほど圧力は急激に下がる。これが推力の源。

③ これが核心──面積比とマッハ数の関係

\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)}}
  • $A^*$: スロート(最も細い部分)の断面積
  • $A$: 任意の断面での面積

この式がすべてです。 この式が、「出口マッハ数が決まればノズル形状(面積比)が決まる」 という関係を与えてくれます。

特徴的なのは:

  • M < 1 のとき:M が増えると A/A* は減少(収縮)
  • M = 1 のとき:A/A* = 1(最小断面)
  • M > 1 のとき:M が増えると A/A* は増加(拡大)

これが「収縮してから拡大する」ことの数学的証明です。


コードで実装する──JavaScriptで等エントロピー流れを再現

いよいよ核心です。上の式をコードに落とし込みます。

ここで重要なのは、「マッハ数から面積比」は直接計算できるが、「面積比からマッハ数」を求めるには逆計算が必要だということ。つまり、面積比を指定してマッハ数を得るには、数値的に方程式を解く必要があります。

以下が、実際にブラウザで動く設計計算機のコアロジックです:

/**
 * ド・ラバルノズル 等エントロピー流れ 計算モジュール
 * 
 * 仕様: 出口マッハ数 or 面積比のいずれかを指定すると、
 *       もう一方を自動計算し、軸方向の分布を返す
 */
class DeLavalNozzle {
  /**
   * @param {number} gamma - 比熱比 (例: 1.4)
   * @param {number} exitMach - 出口マッハ数 (指定時)
   * @param {number} areaRatio - 面積比 A/A* (指定時、exitMach未指定の場合に使用)
   */
  constructor(gamma = 1.4, exitMach = null, areaRatio = null) {
    this.gamma = gamma;
    
    // 出口マッハ数 or 面積比のいずれかから計算
    if (exitMach !== null) {
      this.exitMach = exitMach;
      this.exitAreaRatio = this.machToAreaRatio(exitMach);
    } else if (areaRatio !== null) {
      this.exitAreaRatio = areaRatio;
      this.exitMach = this.areaRatioToMach(areaRatio);
    } else {
      throw new Error('出口マッハ数または面積比のいずれかを指定してください');
    }
  }

  /**
   * マッハ数 → 面積比 (A/A*)
   * 式: A/A* = (1/M) * [(2/(γ+1)) * (1 + (γ-1)/2 * M^2)]^((γ+1)/(2(γ-1)))
   */
  machToAreaRatio(M) {
    const g = this.gamma;
    const term = (2 / (g + 1)) * (1 + (g - 1) / 2 * M * M);
    const exponent = (g + 1) / (2 * (g - 1));
    return (1 / M) * Math.pow(term, exponent);
  }

  /**
   * 面積比 → マッハ数 (ニュートン法)
   * 亜音速解と超音速解の両方を探索する
   */
  areaRatioToMach(targetAreaRatio) {
    const g = this.gamma;
    
    // 亜音速解 (M ∈ [0.001, 0.999])
    let subsonic = this._solveMach(targetAreaRatio, 0.001, 0.999);
    
    // 超音速解 (M ∈ [1.001, 50])
    let supersonic = this._solveMach(targetAreaRatio, 1.001, 50);
    
    // 収束した方を返す (両方収束した場合は両方保持)
    return {
      subsonic: subsonic,
      supersonic: supersonic
    };
  }

  /**
   * ニュートン法でマッハ数を探索
   */
  _solveMach(target, M_min, M_max) {
    const maxIter = 100;
    const tol = 1e-10;
    let M = (M_min + M_max) / 2; // 初期値

    for (let i = 0; i < maxIter; i++) {
      const f = this.machToAreaRatio(M) - target;
      // 数値微分
      const h = 1e-6;
      const df = (this.machToAreaRatio(M + h) - this.machToAreaRatio(M - h)) / (2 * h);
      
      if (Math.abs(f) < tol) break;
      if (Math.abs(df) < 1e-15) break; // 微分がゼロに近い場合は打ち切り
      
      M = M - f / df;
      
      // 範囲外に出たら二分法にフォールバック
      if (M < M_min || M > M_max) {
        M = (M_min + M_max) / 2;
        // 単純な二分法
        for (let j = 0; j < 50; j++) {
          const f_mid = this.machToAreaRatio(M) - target;
          if (f_mid > 0) {
            if (M < M_max) M_min = M;
            else M_max = M;
          } else {
            if (M > M_min) M_max = M;
            else M_min = M;
          }
          M = (M_min + M_max) / 2;
          if (Math.abs(this.machToAreaRatio(M) - target) < tol) break;
        }
        break;
      }
    }
    return M;
  }

  /**
   * ノズル軸方向の分布を計算
   * @param {number} numPoints - 分割数
   * @param {number} shockPos - 衝撃波位置 (0〜1、衝撃波なしの場合はnull)
   * @returns {Array} 各断面の {x, areaRatio, mach, pressureRatio, tempRatio}
   */
  computeDistribution(numPoints = 100, shockPos = null) {
    const distribution = [];
    
    // 軸方向位置 x (0:入口〜1:出口) と面積比の関係を仮定 (放物線+直線)
    // 実際の設計では形状関数を与えるが、ここでは標準的な分布を使用
    for (let i = 0; i <= numPoints; i++) {
      const x = i / numPoints;
      
      // 面積比分布: 入口で大きい → スロートで1 → 出口でexitAreaRatio
      // 放物線状の分布を仮定 (典型的なノズル形状)
      let areaRatio;
      if (x < 0.3) {
        // 収縮部: 入口面積比を仮定 (例: 5)
        const t = x / 0.3;
        areaRatio = 5 + (1 - 5) * t * t; // 放物線で減少
      } else if (x < 0.5) {
        // スロート付近: 1に漸近
        const t = (x - 0.3) / 0.2;
        areaRatio = 1 + (5 - 1) * (1 - t) * (1 - t); // 放物線で1に
      } else {
        // 拡大部: 1から出口面積比まで放物線
        const t = (x - 0.5) / 0.5;
        areaRatio = 1 + (this.exitAreaRatio - 1) * t * t;
      }
      
      // 衝撃波処理
      let mach, pressureRatio, tempRatio;
      if (shockPos !== null && x >= shockPos && i > 0) {
        // 衝撃波通過後は別途計算 (ここでは簡略化のため前の値を使用)
        // 実際のツールでは垂直衝撃波関係式を使用
        const prev = distribution[distribution.length - 1];
        mach = prev.mach; // 衝撃波後の値は別計算
        pressureRatio = prev.pressureRatio;
        tempRatio = prev.tempRatio;
      } else {
        // 等エントロピー計算
        const machResult = this.areaRatioToMach(areaRatio);
        // 亜音速/超音速の選択: スロートまでは亜音速、以降は超音速
        const M = (x < 0.5) ? machResult.subsonic : machResult.supersonic;
        
        mach = M;
        pressureRatio = Math.pow(1 + (this.gamma - 1) / 2 * M * M, -this.gamma / (this.gamma - 1));
        tempRatio = 1 / (1 + (this.gamma - 1) / 2 * M * M);
      }
      
      distribution.push({
        x: x,
        areaRatio: areaRatio,
        mach: mach,
        pressureRatio: pressureRatio,
        tempRatio: tempRatio
      });
    }
    
    return distribution;
  }
}

// 使用例: 出口マッハ数2.0、比熱比1.4(空気)
const nozzle = new DeLavalNozzle(1.4, 2.0);
console.log(`出口マッハ数: ${nozzle.exitMach}`);
console.log(`必要な面積比 A/A*: ${nozzle.exitAreaRatio.toFixed(4)}`);

// 分布を計算
const dist = nozzle.computeDistribution(50);
console.log('=== ノズル内分布 ===');
console.log('x\tA/A*\tM\tp/p0\tT/T0');
dist.forEach((d, i) => {
  if (i % 10 === 0) { // 10点ごとに表示
    console.log(
      `${d.x.toFixed(2)}\t${d.areaRatio.toFixed(3)}\t` +
      `${d.mach.toFixed(3)}\t${d.pressureRatio.toFixed(3)}\t${d.tempRatio.toFixed(3)}`
    );
  }
});

このコードのポイント:

  1. machToAreaRatio: マッハ数から面積比を直接計算(解析解)
  2. areaRatioToMach: 面積比からマッハ数をニュートン法で逆算。亜音速解と超音速解の両方を探索
  3. computeDistribution: ノズル形状に沿って各断面のマッハ数・圧力比・温度比を計算

数値例で確かめる──出口マッハ数2.0のノズルを設計してみる

実際に計算してみましょう。空気(γ = 1.4) で、出口マッハ数 M_exit = 2.0 のノズルを設計します。

面積比の計算

\frac{A}{A^*} = \frac{1}{2.0} \left[ \frac{2}{1.4 + 1} \left(1 + \frac{1.4 - 1}{2} \times 2.0^2\right) \right]^{\frac{1.4 + 1}{2(1.4 - 1)}}

ステップバイステップ:

  1. $\frac{2}{\gamma + 1} = \frac{2}{2.4} = 0.8333$
  2. $\frac{\gamma - 1}{2} M^2 = \frac{0.4}{2} \times 4 = 0.8$
  3. $1 + 0.8 = 1.8$
  4. $0.8333 \times 1.8 = 1.5$
  5. 指数: $\frac{\gamma + 1}{2(\gamma - 1)} = \frac{2.4}{2 \times 0.4} = \frac{2.4}{0.8} = 3$
  6. $1.5^3 = 3.375$
  7. $\frac{1}{2.0} \times 3.375 = 1.6875$

答え: 出口面積比 A/A = 1.688*

つまり、スロート(最も細い部分)の面積を1とすると、出口は約1.69倍の断面積が必要ということです。

圧力・温度の確認

出口での圧力比:

\frac{p}{p_0} = \left(1 + \frac{1.4 - 1}{2} \times 2.0^2\right)^{-\frac{1.4}{1.4 - 1}} = (1.8)^{-3.5} = 0.1278

出口での温度比:

\frac{T}{T_0} = \left(1 + \frac{1.4 - 1}{2} \times 2.0^2\right)^{-1} = (1.8)^{-1} = 0.5556

意味: 入口の圧力が1気圧(101.3 kPa)なら、出口では約0.128気圧(13.0 kPa)。温度は入口が300K(27℃)なら出口は約167K(-106℃)──超音速に加速する過程で、気体は猛烈に冷えることがわかります。


シミュレーターで遊ぶ──3つの実験

実際にツールを開いて試してみましょう。

実験1: 出口マッハ数を変えてみる

操作: 出口マッハ数のスライダーを 1.5 → 2.0 → 3.0 と動かす

出口M 面積比 A/A* 出口圧力比 p/p0 特徴
1.5 1.176 0.272 拡大部が短く、弱い超音速
2.0 1.688 0.128 典型的なロケット1段目
3.0 4.235 0.027 宇宙空間用、大きく広がる

気づき: M=3.0では面積比が4倍以上になる。「少しマッハ数を上げたい」が、実はノズルを大幅に大きくする必要があるという現実が見えてきます。

実験2: 比熱比を変えてみる

操作: 出口M=2.0に固定し、比熱比γを 1.4(空気)→ 1.2(ロケット燃焼ガス) に変更

  • γ=1.4: 面積比 1.688
  • γ=1.2: 面積比 1.939

なぜ?: γが小さいほど、同じマッハ数でもより大きな膨張が必要。ロケットの燃焼ガス(γ≈1.2)は空気より「膨らみやすい」ため、ノズルをより大きく設計する必要があるんです。

実験3: 衝撃波を発生させる

操作: 出口M=2.0、γ=1.4で、「衝撃波位置」スライダーを0.6(スロートから60%の位置)に設定

何が起きるか:

  • 衝撃波の手前(上流): M=1.8、p/p0=0.16(超音速、低圧)
  • 衝撃波の直後(下流): M=0.6、p/p0=0.72(亜音速、高圧)

衝撃波を境に、マッハ数が不連続に1.8→0.6へ急減、圧力は4.5倍に跳ね上がる。

これが「垂直衝撃波」です。超音速流が何らかの理由で亜音速に戻るとき、衝撃波面という極薄い領域で圧力・温度・密度が不連続に変化します。この現象は推力損失の直接原因になるため、設計では絶対に避けたい。


現場でハマるポイント──「教科書通り」が通用しない3つの現実

1. 入口条件の仮定が崩れる

問題: このシミュレーターは「入口で流速ゼロ(M≈0)」を仮定。でも実機の燃焼室には入口流速がある。

対策: 入口マッハ数が0.1を超えると、単純な面積比の式では誤差が大きくなる。入口条件を考慮した補正式が必要。

2. 比熱比の設定ミスが致命傷

事例: 空気(γ=1.4)でロケットノズルを設計してしまう

結果: 出口M=5.0を狙うと、γ=1.4では面積比≈25、γ=1.25では面積比≈65。2.6倍も形状が変わる。

教訓: 「なんとなく1.4」は絶対ダメ。燃焼ガスの組成分析か、信頼できる物性値を使うこと。

3. 一次元近似の限界

現実: この計算は「流れは管の断面で一様」と仮定。でも実際のノズルでは:

  • 壁面摩擦による境界層の発達
  • 二次元・三次元の流れの歪み
  • 熱損失

特に小型ノズルでは、境界層が流路面積の10〜20%を占めることも。設計値から「安全率」を見込むのが現場の常識です。


まとめ──「魔法の管」の正体

  1. ド・ラバルノズルは、亜音速→超音速の「ルールの切り替わり」を形状で強制する装置。収縮部で音速に到達させ、拡大部でさらに加速する。

  2. たった1つの式(面積比-マッハ数関係式)で設計が決まるが、実装では数値解法(ニュートン法)が必要。コードに落とせば、誰でも再現可能。

  3. 実機では「理想と現実のギャップ」に常に注意。比熱比の正確な値、入口条件、境界層の影響──これらを無視すると、設計通りの性能は出ない。

「ただのくびれた管」に見えたあの形状が、実は流体力学の叡智の結晶だった──そう思えてきませんか?

▶ 収縮拡大ノズル(ド・ラバルノズル)設計計算機 — ブラウザで即動作、登録不要。スライダーを動かすだけで、あなたもノズル設計者になれます。

NovaSolverでは1,600以上の工学シミュレーターを無料公開中 👉 一覧はこちら

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?