Daijiro Taira

熱・反応工学ブラウザで動く

反応管 水の平衡圧ビューア

密閉した反応管(ガラスアンプルなど)に水を入れて加熱すると、中の圧力はどこまで上がるのか——を、温度・水の量・容器の大きさから見積もるツールです。実験の前に『どのくらいの圧力になるか』『液・気・超臨界のどの状態か』のあたりを付けられます。

反応管 水の平衡圧ビューア の操作の様子
温度を上げ下げすると、平衡圧・相状態バッジ・グラフ上の現在点がリアルタイムに動きます(実画面を自動操作して録画)。

使い方

  1. 画面の見方

    画面の見方

    左で条件を入力 → 中央に答え(平衡圧と相状態)→ 右に計算式 → 下に2つのグラフ、という並び。まずは全体をながめてみましょう。

  2. 条件を入れる

    条件を入れる

    温度 T・水の量 V_fill(室温で測った液量)・容器体積 V_vessel を、スライダーか数値で入れます。すぐ下に水の密度 ρ と充填率が自動で出ます。

  3. 圧力と相を読む

    圧力と相を読む

    中央の大きな数字が反応管内の水の平衡圧(MPa、下に bar / atm も)。バッジが相状態です。例:350℃・水1 mL・容器5 mL → 16.53 MPa・気液二相(V+L)。

  4. グラフで全体像をつかむ

    グラフで全体像をつかむ

    左=いまの密度のまま温度を上げたときの圧力カーブ(青)と、飽和蒸気圧曲線・臨界点。右=温度×充填量でどの相になるかを色分けしたマップ。白丸が今の条件です。

  5. やってみよう:温度を上げると

    やってみよう:温度を上げると

    温度を450℃に上げると 34.81 MPa・超臨界(SC) に。温度を上げると圧力が急上昇するのが一目で分かります。

  6. やってみよう:温度を下げると

    やってみよう:温度を下げると

    逆に120℃まで下げると 0.199 MPa(約2気圧)・気液二相。低温では圧力はごくわずかです。

  7. やってみよう:水を増やすと

    やってみよう:水を増やすと

    同じ350℃でも水を3 mLに増やすと 19.61 MPa・亜臨界水(L) へ。水の量(密度)が増えると圧力が上がり、相も変わります。

仕組みと使った技術

全体の流れ

  1. ユーザーが温度 T(25–500℃)・水充填量 V_fill(室温の液量)・容器体積 V_vessel(既定5 mL)をスライダまたは数値入力で指定する。
  2. 密閉管は等容系であるため、状態は (T, 全体密度 ρ = 水質量 / V_vessel) の2変数だけで決まる(ρは室温密度997 kg/m³で充填量を質量に換算して算出)。
  3. ビルド前に precompute.py が CoolProp(IAPWS-95)を呼び出し、(T, ρ) の単相2Dグリッドと、T軸に沿った飽和蒸気圧・飽和液密度・飽和蒸気密度の1D飽和テーブルを data_grid.json へ書き出す。臨界点近傍の折れを滑らかにするため、臨界点ノット(Tcrit±0.5/0.2/0.05℃)を飽和テーブルに追加している。
  4. core.js が相判定を行う。T ≥ Tcrit は単相(超臨界 or 気体様)、T < Tcrit では ρV_sat ≤ ρ ≤ ρL_sat なら二相(V+L)で P = Psat(T)、ρ > ρL_sat なら加圧熱水(L)、ρ < ρV_sat なら蒸気(V)として単相EOSグリッドを補間する。
  5. 単相の圧力補間は、動く相境界(飽和液密度ρL_sat)をアンカーに「Δρ = ρ − ρsat(T)」で温度方向を補間する「境界相対密度補間」を採用し、二相/単相境界のキンクを跨がないようにしている。
  6. build.py が template.html・Plotly.js(vendor)・data_grid.json・core.js・app.js を単一HTMLに結合して配布物を生成する。ブラウザは外部通信なし・インストール不要でブラウザ内だけで動作し、左ペインに圧力値と相バッジ、右ペインに「式と計算」透明化パネル、下部に P–T 等容線グラフと相状態ヒートマップを表示する。
  7. URLパラメータ(?T=400&fill=2.0&vessel=5)で初期条件を指定でき、条件の共有が可能。公開版(https://reactor-water.daijirotaira.com)は Cloudflare Workers で静的配信しており、noindexで検索除外されている。

使った技術

CoolProp (IAPWS-95 / HEOS)
Python側でビルド前に純水の (T, ρ) 2Dグリッドおよび飽和テーブルを事前計算するための物性ライブラリ
Python / precompute.py
非一様ρグリッドと臨界点ノット付き飽和テーブルを生成し data_grid.json に書き出すビルドスクリプト
JavaScript / core.js
DOM・Plotly非依存の物性補間・相分岐ロジック。qa_compare.py と同一仕様でPython参照とbit一致検証済み
JavaScript / app.js
UI層(スライダ・数値入力→core.js呼び出し→Plotly描画・計算透明化パネル更新)
Plotly.js (cartesianバンドル)
P–T等容線グラフと相状態ヒートマップの描画。vendorとして単一HTMLに埋め込み、外部通信なしの動作を実現
Python / build.py
template.html・vendor Plotly・data・core・appを結合して単一HTMLを生成するビルドスクリプト
Node.js / verify_core.js
core.jsの補間結果をPython参照(gen_truth.py生成の真値JSON)と突合してJS移植の正しさを定量検証
Cloudflare Workers
reactor-water-pressureフォルダのindex.htmlと仕様書spec.htmlを静的配信(README/コードは非公開)

実装の工夫

  • 物性グリッドはビルド前にPython(CoolProp)で計算し data_grid.json に埋め込む「事前計算アーキテクチャ」を採用。ブラウザはJSで補間するだけなので無依存・外部通信なし・file://直開きが可能。
  • ρグリッドは非一様設計。飽和液密度が通る圧縮液域(600–1000 kg/m³)はP–ρが急峻なため1刻みで細密化し、希薄蒸気側は5刻みに粗くしてファイルサイズを抑えている。
  • 相分岐補間(境界相対密度補間):動く飽和境界をアンカーに「Δρ = ρ − ρsat(T)」でT方向補間することで、二相/単相境界キンクをまたいだ非物理的な補間を回避。
  • 飽和テーブルに臨界点ノット(Tcrit±0.5/0.2/0.05℃と臨界点そのもの)を追加し、373℃で飽和テーブルが打ち切られることによる臨界近傍の二相判定抜けを解消。
  • JS core(core.js)はDOM非依存モジュールとして実装し、Python側で生成した真値点群JSONをNodeで読み込んでJS出力と突合(max|ΔP|=1.4e-14 MPa)することで移植の正しさをbit一致で保証。
  • レイアウトは font-size:clamp(min, vh, max) とflexでチャートが残り高さを埋める構成にし、ResizeObserverでPlotly.Plots.resizeを呼ぶことで、1280×800〜1920×1200で1画面無スクロールを実現。

用語

平衡圧
密閉容器の中で、液体とその蒸気がつり合った(平衡になった)ときに示す圧力。
等容系(定容)
容器の体積が変わらない系。密閉した反応管はこれにあたり、状態は温度と全体密度だけで決まる。
全体密度 ρ
入れた水の質量 ÷ 容器体積。等容系では圧力と相を決める鍵になる量。
充填率
容器体積に対する、室温で測った水の体積の割合(例: 5 mL の容器に 1 mL なら 20%)。
飽和蒸気圧
ある温度で液体と蒸気が共存できる圧力。気液二相のときの圧力はこれで決まる。
気液二相(V+L)
液体と蒸気が同時に存在している状態。容器内に液面がある状態。
臨界点
これより高温・高圧では気体と液体の区別が無くなる点。水は約374℃・22.1 MPa。
超臨界(SC)
臨界点を超えた状態。気体と液体の中間のような性質をもつ。
亜臨界水(加圧熱水, L)
臨界点に達しない範囲で加圧された、高温の液体の水。