🌐 JP | 🇬🇧 EN | Last sync: 2025-11-16
🎯 学習目標
- 熱力学の第0〜第3法則の意味と応用を理解する
- 内部エネルギー (U) の定義と熱力学第一法則を学ぶ
- エンタルピー (H) の物理的意味と等圧過程での役割を理解する
- Helmholtz自由エネルギー (F) と等温過程での仕事を学ぶ
- Gibbs自由エネルギー (G) と化学平衡・相平衡への応用を理解する
- 4つの熱力学ポテンシャルの使い分けを習得する
- Pythonで熱力学関数を計算し、可視化する
📖 熱力学の基本法則
熱力学の4つの法則
熱力学は4つの基本法則に基づいて構築されています。これらは実験事実から導かれた普遍的な原理です。
第0法則(熱平衡の法則)
「物体AとBが熱平衡、BとCが熱平衡ならば、AとCも熱平衡にある」
意味 : 温度の概念を定義可能にする。温度計の原理。
第1法則(エネルギー保存則)
\[ dU = \delta Q - \delta W \]
内部エネルギー変化 \(dU\) = 系に与えられた熱 \(\delta Q\) − 系が外部にした仕事 \(\delta W\)
意味 : エネルギーは保存される。第一種永久機関は不可能。
第2法則(エントロピー増大則)
\[ dS \geq \frac{\delta Q}{T} \]
孤立系のエントロピーは決して減少しない(等号は可逆過程)。
意味 : 不可逆性の起源。熱は自発的に高温から低温へ流れる。第二種永久機関は不可能。
第3法則(Nernstの定理)
\[ \lim_{T \to 0} S(T) = 0 \]
絶対零度でエントロピーは0(完全結晶の場合)。
意味 : 絶対零度到達は有限回の操作では不可能。
準静的過程と可逆過程
準静的過程(Quasi-static process) : 系が常にほぼ平衡状態にあるよう、無限にゆっくり進む過程。
可逆過程(Reversible process) : 準静的かつ、逆向きの過程を辿れば系と外界が元の状態に戻る過程。散逸がない。
不可逆過程(Irreversible process) : 実際の現実的な過程。摩擦、熱伝導、拡散などで散逸が起きる。
💻 コード例1.1: 理想気体の断熱過程と等温過程
Python実装: PV図での可逆過程の可視化
import numpy as np import matplotlib.pyplot as plt # 物理定数 R = 8.314 # J/(mol·K) n = 1.0 # mol gamma = 1.4 # 比熱比(空気) # 初期状態 P1 = 1e5 # Pa (1 atm) V1 = 0.0224 # m³ (標準状態) T1 = 273.15 # K # 体積範囲 V_range = np.linspace(0.01, 0.05, 200) # 等温過程 (PV = nRT = const) def isothermal_process(V, n, R, T): """等温過程: PV = nRT""" return n * R * T / V # 断熱過程 (PV^γ = const) def adiabatic_process(V, P1, V1, gamma): """断熱過程: PV^γ = const""" return P1 * (V1 / V)gamma # 等圧過程 def isobaric_process(V, P): """等圧過程: P = const""" return P * np.ones_like(V) # 計算 P_isothermal = isothermal_process(V_range, n, R, T1) P_adiabatic = adiabatic_process(V_range, P1, V1, gamma) P_isobaric = isobaric_process(V_range, P1) # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # PV図 ax1 = axes[0] ax1.plot(V_range * 1000, P_isothermal / 1e5, ‘b-’, linewidth=2, label=f’等温 (T = {T1:.1f} K)’) ax1.plot(V_range * 1000, P_adiabatic / 1e5, ‘r-’, linewidth=2, label=f’断熱 (γ = {gamma})’) ax1.plot(V_range * 1000, P_isobaric / 1e5, ‘g—’, linewidth=2, label=f’等圧 (P = {P1/1e5:.1f} bar)’) ax1.scatter([V1 * 1000], [P1 / 1e5], color=‘black’, s=100, zorder=5, label=‘初期状態’) ax1.set_xlabel(‘Volume (L)’) ax1.set_ylabel(‘Pressure (bar)’) ax1.set_title(‘PV線図(可逆過程の比較)’) ax1.legend() ax1.grid(True, alpha=0.3) # 仕事の計算(体積がV1→V2へ変化) V2 = 0.04 # m³ W_isothermal = n * R * T1 * np.log(V2 / V1) W_adiabatic = (P1 * V1gamma) * (V2**(1-gamma) - V1**(1-gamma)) / (1 - gamma) W_isobaric = P1 * (V2 - V1) # 仕事の比較 ax2 = axes[1] processes = [‘等温’, ‘断熱’, ‘等圧’] works = [W_isothermal, W_adiabatic, W_isobaric] colors = [‘blue’, ‘red’, ‘green’] ax2.bar(processes, works, color=colors, alpha=0.7, edgecolor=‘black’) ax2.set_ylabel(‘Work done by gas (J)’) ax2.set_title(f’体積膨張の仕事(V: {V11000:.1f}L → {V21000:.1f}L)’) ax2.grid(True, axis=‘y’, alpha=0.3) for i, (process, work) in enumerate(zip(processes, works)): ax2.text(i, work + 50, f’{work:.1f} J’, ha=‘center’, fontweight=‘bold’) plt.tight_layout() plt.savefig(‘thermo_reversible_processes.png’, dpi=300, bbox_inches=‘tight’) plt.show() print(”=== 可逆過程における仕事 ===”) print(f”初期状態: V = {V11000:.1f} L, P = {P1/1e5:.2f} bar, T = {T1:.1f} K”) print(f”最終状態: V = {V21000:.1f} L\n”) print(f”等温過程: W = nRT ln(V2/V1) = {W_isothermal:.2f} J”) print(f”断熱過程: W = (P1V1^γ)(V2^(1-γ) - V1^(1-γ))/(1-γ) = {W_adiabatic:.2f} J”) print(f”等圧過程: W = P(V2-V1) = {W_isobaric:.2f} J”) print(“\n→ 等温過程が最も大きな仕事を取り出せる(熱を吸収するため)”)
📊 熱力学ポテンシャル
4つの熱力学ポテンシャル
系の状態を記述する4つの基本的な状態関数:
| ポテンシャル | 定義 | 自然変数 | 主な応用 |
|---|---|---|---|
| 内部エネルギー (U) | \(U = U(S, V, N)\) | \(S, V, N\) | 孤立系、断熱過程 |
| エンタルピー (H) | \(H = U + PV\) | \(S, P, N\) | 等圧過程、化学反応熱 |
| Helmholtz自由エネルギー (F) | \(F = U - TS\) | \(T, V, N\) | 等温等積過程、統計力学 |
| Gibbs自由エネルギー (G) | \(G = H - TS = U + PV - TS\) | \(T, P, N\) | 等温等圧過程、化学・相平衡 |
微分形式
\[ \begin{aligned} dU &= TdS - PdV + \mu dN \\ dH &= TdS + VdP + \mu dN \\ dF &= -SdT - PdV + \mu dN \\ dG &= -SdT + VdP + \mu dN \end{aligned} \]
ここで \(\mu\) は化学ポテンシャル。
ポテンシャルの選択基準
- 内部エネルギー U : エントロピー \(S\) と体積 \(V\) が制御しやすい系(断熱壁の容器)
- エンタルピー H : 圧力 \(P\) が一定の系(大気圧下の化学反応)
- Helmholtz自由エネルギー F : 温度 \(T\) が一定の系(熱浴と接触)、統計力学との接続
- Gibbs自由エネルギー G : 温度 \(T\) と圧力 \(P\) が一定(最も一般的な実験条件)
💻 コード例1.2: 理想気体の熱力学ポテンシャル
Python実装: 4つのポテンシャルの計算と比較
import numpy as np import matplotlib.pyplot as plt # 物理定数 R = 8.314 # J/(mol·K) n = 1.0 # mol # 理想気体の熱力学ポテンシャル def ideal_gas_potentials(T, V, P, n, R): """理想気体の4つの熱力学ポテンシャル Args: T: 温度 (K) V: 体積 (m³) P: 圧力 (Pa) n: 物質量 (mol) R: 気体定数 (J/(mol·K)) Returns: U, H, F, G: 各ポテンシャル (J) """ # 内部エネルギー(単原子理想気体, Cv = (3/2)R) U = (3/2) * n * R * T # エンタルピー H = U + PV H = U + P * V # Helmholtz自由エネルギー F = U - TS # S = nCv ln(T) + nR ln(V) + const (Sackur-Tetrode式の簡易版) # ここでは定性的に S ∝ ln(VT^(3/2)) S = n * R * ((3/2) * np.log(T) + np.log(V) + 10) # constは適当 F = U - T * S # Gibbs自由エネルギー G = H - TS G = H - T * S return U, H, F, G, S # 温度範囲(体積固定) V_fixed = 0.0224 # m³ P_fixed = 1e5 # Pa T_range = np.linspace(100, 500, 100) potentials_vs_T = { ‘U’: [], ‘H’: [], ‘F’: [], ‘G’: [], ‘S’: [] } for T in T_range: U, H, F, G, S = ideal_gas_potentials(T, V_fixed, P_fixed, n, R) potentials_vs_T[‘U’].append(U) potentials_vs_T[‘H’].append(H) potentials_vs_T[‘F’].append(F) potentials_vs_T[‘G’].append(G) potentials_vs_T[‘S’].append(S) # 可視化 fig, axes = plt.subplots(2, 2, figsize=(14, 10)) # 内部エネルギー ax1 = axes[0, 0] ax1.plot(T_range, potentials_vs_T[‘U’], ‘b-’, linewidth=2) ax1.set_xlabel(‘Temperature (K)’) ax1.set_ylabel(‘U (J)’) ax1.set_title(‘内部エネルギー U(T)’) ax1.grid(True, alpha=0.3) # エンタルピー ax2 = axes[0, 1] ax2.plot(T_range, potentials_vs_T[‘H’], ‘r-’, linewidth=2) ax2.set_xlabel(‘Temperature (K)’) ax2.set_ylabel(‘H (J)’) ax2.set_title(‘エンタルピー H(T)’) ax2.grid(True, alpha=0.3) # Helmholtz自由エネルギー ax3 = axes[1, 0] ax3.plot(T_range, potentials_vs_T[‘F’], ‘g-’, linewidth=2) ax3.set_xlabel(‘Temperature (K)’) ax3.set_ylabel(‘F (J)’) ax3.set_title(‘Helmholtz自由エネルギー F(T)’) ax3.grid(True, alpha=0.3) # Gibbs自由エネルギー ax4 = axes[1, 1] ax4.plot(T_range, potentials_vs_T[‘G’], ‘purple’, linewidth=2) ax4.set_xlabel(‘Temperature (K)’) ax4.set_ylabel(‘G (J)’) ax4.set_title(‘Gibbs自由エネルギー G(T)’) ax4.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(‘thermo_potentials.png’, dpi=300, bbox_inches=‘tight’) plt.show() # 特定温度での値 T_ref = 300 # K U, H, F, G, S = ideal_gas_potentials(T_ref, V_fixed, P_fixed, n, R) print(f”=== 理想気体の熱力学ポテンシャル(T = {T_ref} K)===”) print(f”体積 V = {V_fixed * 1000:.2f} L”) print(f”圧力 P = {P_fixed / 1e5:.2f} bar\n”) print(f”内部エネルギー U = {U:.2f} J”) print(f”エンタルピー H = U + PV = {H:.2f} J”) print(f”Helmholtz自由エネルギー F = U - TS = {F:.2f} J”) print(f”Gibbs自由エネルギー G = H - TS = {G:.2f} J”) print(f”エントロピー S = {S:.2f} J/K”) print(f”\n関係式の確認:”) print(f”H - U = PV = {H - U:.2f} J (理論値: {P_fixed * V_fixed:.2f} J)”) print(f”U - F = TS = {U - F:.2f} J (理論値: {T_ref * S:.2f} J)”) print(f”H - G = TS = {H - G:.2f} J (理論値: {T_ref * S:.2f} J)”)
💻 コード例1.3: 等温等圧過程でのGibbs自由エネルギー
Gibbs自由エネルギーと自発性
等温等圧条件(\(T, P\) 一定)では、Gibbs自由エネルギー \(G\) が重要:
\[ dG = -SdT + VdP \]
\(T, P\) 一定なら \(dG = 0\) → 平衡状態
自発性の判定基準 :
- \(\Delta G < 0\): 自発的に進行(発エルゴン反応)
- \(\Delta G = 0\): 平衡状態
- \(\Delta G > 0\): 自発的に進まない(吸エルゴン反応)
Python実装: 化学反応のGibbs自由エネルギー変化
import numpy as np import matplotlib.pyplot as plt # 仮想的な化学反応: A ⇌ B # ΔG = ΔH - TΔS # 反応エンタルピーとエントロピー(仮想値) delta_H = -50000 # J/mol (発熱反応) delta_S = -100 # J/(mol·K) (エントロピー減少、秩序化) def gibbs_free_energy_change(delta_H, delta_S, T): """反応のGibbs自由エネルギー変化 Args: delta_H: エンタルピー変化 (J/mol) delta_S: エントロピー変化 (J/(mol·K)) T: 温度 (K) Returns: delta_G: Gibbs自由エネルギー変化 (J/mol) """ return delta_H - T * delta_S # 温度範囲 T_range = np.linspace(200, 800, 100) delta_G_range = [gibbs_free_energy_change(delta_H, delta_S, T) for T in T_range] # 平衡温度(ΔG = 0) T_eq = delta_H / delta_S delta_G_eq = gibbs_free_energy_change(delta_H, delta_S, T_eq) # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # ΔG vs T ax1 = axes[0] ax1.plot(T_range, delta_G_range, ‘b-’, linewidth=2, label=‘ΔG(T)’) ax1.axhline(0, color=‘black’, linestyle=’—’, linewidth=1.5, label=‘ΔG = 0 (平衡)’) ax1.axvline(T_eq, color=‘red’, linestyle=’—’, linewidth=1.5, label=f’平衡温度 ({T_eq:.1f} K)’) ax1.fill_between(T_range, delta_G_range, 0, where=(np.array(delta_G_range) < 0), alpha=0.3, color=‘green’, label=‘自発進行領域 (ΔG < 0)’) ax1.fill_between(T_range, delta_G_range, 0, where=(np.array(delta_G_range) > 0), alpha=0.3, color=‘red’, label=‘非自発領域 (ΔG > 0)’) ax1.set_xlabel(‘Temperature (K)’) ax1.set_ylabel(‘ΔG (J/mol)’) ax1.set_title(‘Gibbs自由エネルギー変化の温度依存性’) ax1.legend() ax1.grid(True, alpha=0.3) # エンタルピー項とエントロピー項の寄与 ax2 = axes[1] enthalpy_term = delta_H * np.ones_like(T_range) entropy_term = -T_range * delta_S ax2.plot(T_range, enthalpy_term, ‘r-’, linewidth=2, label=‘ΔH(エンタルピー項)’) ax2.plot(T_range, entropy_term, ‘b-’, linewidth=2, label=’-TΔS(エントロピー項)’) ax2.plot(T_range, delta_G_range, ‘purple’, linewidth=2.5, label=‘ΔG = ΔH - TΔS’) ax2.axhline(0, color=‘black’, linestyle=’—’, linewidth=1) ax2.set_xlabel(‘Temperature (K)’) ax2.set_ylabel(‘Energy (J/mol)’) ax2.set_title(‘エンタルピー項とエントロピー項の寄与’) ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(‘thermo_gibbs_reaction.png’, dpi=300, bbox_inches=‘tight’) plt.show() print(”=== 化学反応のGibbs自由エネルギー解析 ===”) print(f”反応: A ⇌ B”) print(f”ΔH = {delta_H / 1000:.1f} kJ/mol(発熱反応)”) print(f”ΔS = {delta_S:.1f} J/(mol·K)(エントロピー減少)\n”) print(f”平衡温度: T_eq = ΔH/ΔS = {T_eq:.1f} K\n”) # 特定温度での判定 T_test = [300, T_eq, 700] for T in T_test: dG = gibbs_free_energy_change(delta_H, delta_S, T) if dG < 0: spontaneity = “自発的に進行(A → B)” elif dG > 0: spontaneity = “自発的に進まない(B → A が有利)” else: spontaneity = “平衡状態” print(f”T = {T:.1f} K: ΔG = {dG / 1000:.2f} kJ/mol → {spontaneity}”) print(“\n解釈:”) print(”- 低温: ΔH項が支配的 → 発熱反応が有利(ΔG < 0)”) print(”- 高温: -TΔS項が支配的 → エントロピー増大が重要(ΔG > 0, 逆反応有利)”) print(f”- T = {T_eq:.1f} K: 両項が釣り合う → 平衡”)
💻 コード例1.4: Legendre変換とポテンシャルの関係
Legendre変換
熱力学ポテンシャル間の変換はLegendre変換 で与えられます。
関数 \(f(x)\) のLegendre変換 \(g(p)\) は:
\[ g(p) = px - f(x), \quad p = \frac{df}{dx} \]
熱力学ポテンシャルへの適用
- \(H = U + PV\) (\(V\) → \(P\) への変換、\(P = -\partial U/\partial V\))
- \(F = U - TS\) (\(S\) → \(T\) への変換、\(T = \partial U/\partial S\))
- \(G = U - TS + PV = F + PV = H - TS\) (両方の変換)
Python実装: Legendre変換の数値例
import numpy as np import matplotlib.pyplot as plt import sympy as sp # SymPyでのLegendre変換の例 x = sp.Symbol(‘x’, real=True, positive=True) # 元の関数 f(x) = x² f = x2 # df/dx df_dx = sp.diff(f, x) print(”=== Legendre変換の解析例 ===”) print(f”元の関数: f(x) = {f}”) print(f”df/dx = {df_dx}”) # p = df/dx として、x を p で表す p = sp.Symbol(‘p’, real=True, positive=True) x_of_p = sp.solve(df_dx - p, x)[0] # x(p) を求める print(f”p = df/dx より、x(p) = {x_of_p}”) # Legendre変換 g(p) = px - f(x) g = (p * x_of_p - f.subs(x, x_of_p)).simplify() print(f”Legendre変換: g(p) = px - f(x) = {g}”) print() # 数値プロット x_vals = np.linspace(0.1, 3, 100) f_vals = x_vals2 p_vals = 2 * x_vals # p = df/dx = 2x g_vals = p_vals**2 / 4 # g(p) = p²/4 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # 元の関数 f(x) ax1 = axes[0] ax1.plot(x_vals, f_vals, ‘b-’, linewidth=2, label=‘f(x) = x²’) ax1.set_xlabel(‘x’) ax1.set_ylabel(‘f(x)’) ax1.set_title(‘元の関数 f(x)’) ax1.legend() ax1.grid(True, alpha=0.3) # Legendre変換 g(p) ax2 = axes[1] ax2.plot(p_vals, g_vals, ‘r-’, linewidth=2, label=‘g(p) = p²/4’) ax2.set_xlabel(‘p = df/dx’) ax2.set_ylabel(‘g(p)’) ax2.set_title(‘Legendre変換 g(p)’) ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(‘thermo_legendre_transform.png’, dpi=300, bbox_inches=‘tight’) plt.show() # 熱力学への応用例 print(”=== 熱力学ポテンシャルへの応用 ===”) print(“内部エネルギー U(S,V):”) print(” dU = TdS - PdV”) print(” → T = (∂U/∂S)_V, P = -(∂U/∂V)_S”) print() print(“Legendre変換:”) print(” S → T: F = U - TS (Helmholtz自由エネルギー)”) print(” V → P: H = U + PV (エンタルピー)”) print(” 両方: G = U - TS + PV (Gibbs自由エネルギー)”) print() print(“この変換により、実験で制御しやすい変数(T, P)を”) print(“自然変数とするポテンシャルを構築できる。”)
💻 コード例1.5: 熱力学第3法則とNernstの定理
熱力学第3法則(Nernstの定理)
絶対零度 (\(T \to 0\)) でのエントロピー:
\[ \lim_{T \to 0} S(T) = 0 \]
意味 :
- 完全結晶では、絶対零度でエントロピーがゼロ
- 絶対零度では系が唯一の基底状態に凍結(\(\Omega = 1\))
- 絶対零度到達は有限回の操作では不可能
帰結 : 低温での比熱 \(C_V \propto T^3\) (Debye理論)
Python実装: 低温でのエントロピーと比熱
import numpy as np import matplotlib.pyplot as plt # Debye理論によるエントロピーと比熱 def debye_entropy(T, theta_D, R): """Debye理論によるエントロピー(簡易版) Args: T: 温度 (K) theta_D: Debye温度 (K) R: 気体定数 (J/(mol·K)) Returns: S: エントロピー (J/(mol·K)) """ x = theta_D / T if T < 0.01: # 数値計算の安定性 return 0 # 低温極限: S ∝ (T/θ_D)³ if x > 10: return (12/5) * np.pi**4 * R * (T / theta_D)3 # 高温極限: S → 3R ln(T/θ_D) + const else: return 3 * R * (np.log(T / theta_D) + 4/3) def debye_heat_capacity(T, theta_D, R): """Debye理論による定積比熱 Args: T: 温度 (K) theta_D: Debye温度 (K) R: 気体定数 (J/(mol·K)) Returns: C_V: 定積比熱 (J/(mol·K)) """ x = theta_D / T # 低温極限: C_V ∝ T³ if x > 10: return (12/5) * np.pi4 * R * (T / theta_D)**3 # 高温極限: C_V → 3R (Dulong-Petit) else: return 3 * R # 物理定数 R = 8.314 # J/(mol·K) theta_D_Cu = 343 # Cuのebye温度 (K) # 温度範囲 T_range = np.logspace(-1, 3, 200) # 0.1 K to 1000 K S_vals = [debye_entropy(T, theta_D_Cu, R) for T in T_range] C_vals = [debye_heat_capacity(T, theta_D_Cu, R) for T in T_range] # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # エントロピー ax1 = axes[0] ax1.loglog(T_range, S_vals, ‘b-’, linewidth=2) ax1.axvline(theta_D_Cu, color=‘red’, linestyle=’—’, linewidth=1.5, label=f’Debye温度 ({theta_D_Cu} K)’) ax1.set_xlabel(‘Temperature (K)’) ax1.set_ylabel(‘Entropy (J/(mol·K))’) ax1.set_title(‘エントロピーの温度依存性(Cu)’) ax1.legend() ax1.grid(True, alpha=0.3, which=‘both’) # 比熱 ax2 = axes[1] ax2.loglog(T_range, C_vals, ‘r-’, linewidth=2, label=‘Debye理論’) ax2.axhline(3 * R, color=‘green’, linestyle=’—’, linewidth=1.5, label=‘Dulong-Petit則 (3R)’) ax2.axvline(theta_D_Cu, color=‘black’, linestyle=’—’, linewidth=1.5, label=f’Debye温度’) ax2.set_xlabel(‘Temperature (K)’) ax2.set_ylabel(‘Heat capacity C_V (J/(mol·K))’) ax2.set_title(‘定積比熱の温度依存性(Cu)’) ax2.legend() ax2.grid(True, alpha=0.3, which=‘both’) plt.tight_layout() plt.savefig(‘thermo_third_law.png’, dpi=300, bbox_inches=‘tight’) plt.show() print(”=== 熱力学第3法則の検証(Cu)===”) print(f”Debye温度: θ_D = {theta_D_Cu} K\n”) # 低温でのエントロピー T_low = [0.1, 1, 10, 100] print(“低温でのエントロピー:”) for T in T_low: S = debye_entropy(T, theta_D_Cu, R) print(f” T = {T:6.1f} K: S = {S:.6f} J/(mol·K)”) print(f”\n→ T → 0 で S → 0 (第3法則)”) print(f”\n低温での振る舞い:”) print(f” S ∝ T³ (T << θ_D)”) print(f” C_V ∝ T³ (T << θ_D)”) print(f”\n高温での振る舞い:”) print(f” C_V → 3R = {3*R:.2f} J/(mol·K) (Dulong-Petit則)”)
💻 コード例1.6: van der Waals気体の状態方程式と内部エネルギー
van der Waals状態方程式
実在気体を記述する近似:
\[ \left(P + \frac{an^2}{V^2}\right)(V - nb) = nRT \]
- \(a\): 分子間引力の補正項
- \(b\): 分子体積の補正項
内部エネルギー:
\[ U = nC_VT - \frac{an^2}{V} \]
理想気体と異なり、\(U\) は体積にも依存。
Python実装: van der Waals気体の解析
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import fsolve # van der Waals定数(N₂) a_N2 = 0.1408 # Pa·m⁶/mol² b_N2 = 3.913e-5 # m³/mol R = 8.314 # J/(mol·K) C_V = 2.5 * R # J/(mol·K)(二原子分子) def van_der_waals_pressure(V, n, T, a, b, R): """van der Waals圧力""" return n * R * T / (V - n * b) - a * n2 / V2 def van_der_waals_internal_energy(V, n, T, a, C_V): """van der Waals内部エネルギー""" return n * C_V * T - a * n2 / V # 固定パラメータ n = 1.0 # mol T = 300 # K # 体積範囲 V_range = np.linspace(0.001, 0.1, 200) # van der Waals圧力と内部エネルギー P_vdw = [van_der_waals_pressure(V, n, T, a_N2, b_N2, R) for V in V_range] U_vdw = [van_der_waals_internal_energy(V, n, T, a_N2, C_V) for V in V_range] # 理想気体との比較 P_ideal = [n * R * T / V for V in V_range] U_ideal = n * C_V * T * np.ones_like(V_range) # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # 圧力比較 ax1 = axes[0] ax1.plot(V_range * 1000, np.array(P_vdw) / 1e5, ‘b-’, linewidth=2, label=‘van der Waals’) ax1.plot(V_range * 1000, np.array(P_ideal) / 1e5, ‘r—’, linewidth=2, label=‘理想気体’) ax1.set_xlabel(‘Volume (L)’) ax1.set_ylabel(‘Pressure (bar)’) ax1.set_title(f’PV等温線(T = {T} K, N₂)’) ax1.set_xlim([0, 100]) ax1.set_ylim([0, 50]) ax1.legend() ax1.grid(True, alpha=0.3) # 内部エネルギー比較 ax2 = axes[1] ax2.plot(V_range * 1000, U_vdw, ‘b-’, linewidth=2, label=‘van der Waals’) ax2.plot(V_range * 1000, U_ideal, ‘r—’, linewidth=2, label=‘理想気体’) ax2.set_xlabel(‘Volume (L)’) ax2.set_ylabel(‘Internal energy U (J)’) ax2.set_title(f’内部エネルギー(T = {T} K, N₂)’) ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(‘thermo_van_der_waals.png’, dpi=300, bbox_inches=‘tight’) plt.show() # 数値比較 V_test = 0.0224 # m³ (標準状態) P_vdw_val = van_der_waals_pressure(V_test, n, T, a_N2, b_N2, R) P_ideal_val = n * R * T / V_test U_vdw_val = van_der_waals_internal_energy(V_test, n, T, a_N2, C_V) U_ideal_val = n * C_V * T print(”=== van der Waals気体 vs 理想気体(N₂, T = 300 K)===”) print(f”体積 V = {V_test * 1000:.2f} L\n”) print(“圧力:”) print(f” van der Waals: P = {P_vdw_val / 1e5:.4f} bar”) print(f” 理想気体: P = {P_ideal_val / 1e5:.4f} bar”) print(f” 差: {(P_vdw_val - P_ideal_val) / 1e5:.4f} bar\n”) print(“内部エネルギー:”) print(f” van der Waals: U = {U_vdw_val:.2f} J”) print(f” 理想気体: U = {U_ideal_val:.2f} J”) print(f” 差: {U_vdw_val - U_ideal_val:.2f} J”) print(f”\n補正項:”) print(f” 引力補正: -an²/V = {-a_N2 * n2 / V_test:.2f} J”) print(f” 体積補正: nb = {n * b_N2 * 1000:.4f} L”)
💻 コード例1.7: 材料科学応用 - 状態方程式と熱膨張
Python実装: 固体の熱膨張とGrüneisen関係式
import numpy as np import matplotlib.pyplot as plt # Grüneisen関係式: α = γC_V / (VK_T) # α: 熱膨張率, γ: Grüneisenパラメータ, K_T: 等温圧縮率 def thermal_expansion_coefficient(T, gamma, C_V, V, K_T): """熱膨張率 α = γC_V/(VK_T)""" return gamma * C_V(T) / (V * K_T) def debye_heat_capacity_solid(T, theta_D, R): """固体のDebye比熱""" x = theta_D / T if x > 10: # 低温 return (12/5) * np.pi**4 * R * (T / theta_D)**3 else: # 高温(Dulong-Petit) return 3 * R # Cuの物性値 theta_D_Cu = 343 # K gamma_Cu = 2.0 # Grüneisenパラメータ V_Cu = 7.11e-6 # m³/mol K_T_Cu = 1.4e11 # Pa R = 8.314 # J/(mol·K) # 温度範囲 T_range = np.linspace(10, 1000, 200) # 熱膨張率 alpha_vals = [] C_V_vals = [] for T in T_range: C_V = debye_heat_capacity_solid(T, theta_D_Cu, R) alpha = thermal_expansion_coefficient(T, gamma_Cu, lambda t: C_V, V_Cu, K_T_Cu) alpha_vals.append(alpha) C_V_vals.append(C_V) # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # 熱膨張率 ax1 = axes[0] ax1.plot(T_range, np.array(alpha_vals) * 1e6, ‘b-’, linewidth=2) ax1.axvline(theta_D_Cu, color=‘red’, linestyle=’—’, linewidth=1.5, label=f’Debye温度 ({theta_D_Cu} K)’) ax1.set_xlabel(‘Temperature (K)’) ax1.set_ylabel(‘Thermal expansion coefficient α (10⁻⁶ K⁻¹)’) ax1.set_title(‘熱膨張率の温度依存性(Cu)’) ax1.legend() ax1.grid(True, alpha=0.3) # 比熱との相関 ax2 = axes[1] ax2.scatter(C_V_vals, np.array(alpha_vals) * 1e6, c=T_range, cmap=‘viridis’, s=20) cbar = plt.colorbar(ax2.scatter(C_V_vals, np.array(alpha_vals) * 1e6, c=T_range, cmap=‘viridis’, s=20), ax=ax2) cbar.set_label(‘Temperature (K)’) ax2.set_xlabel(‘Heat capacity C_V (J/(mol·K))’) ax2.set_ylabel(‘Thermal expansion coefficient α (10⁻⁶ K⁻¹)’) ax2.set_title(‘熱膨張率と比熱の関係(Grüneisen関係式)’) ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(‘thermo_thermal_expansion.png’, dpi=300, bbox_inches=‘tight’) plt.show() print(”=== 固体の熱膨張(Cu)===”) print(f”Debye温度: θ_D = {theta_D_Cu} K”) print(f”Grüneisenパラメータ: γ = {gamma_Cu}”) print(f”等温圧縮率: K_T = {K_T_Cu:.2e} Pa\n”) # 特定温度での値 T_test = [100, 300, 500, 1000] print(“温度依存性:”) for T in T_test: C_V = debye_heat_capacity_solid(T, theta_D_Cu, R) alpha = thermal_expansion_coefficient(T, gamma_Cu, lambda t: C_V, V_Cu, K_T_Cu) print(f”T = {T:4d} K: C_V = {C_V:.2f} J/(mol·K), α = {alpha*1e6:.2f} × 10⁻⁶ K⁻¹”) print(“\nGrüneisen関係式: α = γC_V/(VK_T)”) print(”→ 熱膨張率は比熱に比例(低温で両方ともゼロに近づく)”) print(”→ 材料設計における熱応力評価に重要”)
📚 まとめ
- 熱力学の4つの法則 は、温度の定義、エネルギー保存、エントロピー増大、絶対零度の性質を規定
- 内部エネルギー U は基本的な状態関数で、第一法則 \(dU = \delta Q - \delta W\) に従う
- エンタルピー H は等圧過程で有用で、化学反応熱の計算に使われる
- Helmholtz自由エネルギー F は等温過程での有用仕事を与え、統計力学と直結
- Gibbs自由エネルギー G は等温等圧条件で最重要で、化学平衡・相平衡の判定基準
- ポテンシャル間の関係はLegendre変換 で結ばれる
- 熱力学第3法則 により、低温でエントロピーと比熱がゼロに近づく(\(T^3\) 依存)
- van der Waals気体や熱膨張など、材料科学への応用が豊富
💡 演習問題
- Carnot効率 : 高温熱源 \(T_H = 600\) K、低温熱源 \(T_C = 300\) Kの Carnotサイクルの効率 \(\eta = 1 - T_C/T_H\) を計算し、第二法則との関係を説明せよ。
- ポテンシャルの微分関係 : \(G = H - TS\) から \(dG = -SdT + VdP\) を導出せよ(\(N\) 一定)。
- 化学平衡定数 : 反応 \(\Delta G^\circ = -RT \ln K_{eq}\) を用いて、\(T = 298\) K で \(\Delta G^\circ = -10\) kJ/mol の反応の平衡定数を計算せよ。
- van der Waals臨界点 : 臨界条件 \((\partial P/\partial V)_T = 0\) かつ \((\partial^2 P/\partial V^2)_T = 0\) から、臨界温度 \(T_c = 8a/(27Rb)\) を導出せよ。
- Debye温度の推定 : 固体の低温比熱データ \(C_V \propto T^3\) から、Debye温度を推定する方法を実装せよ。
← シリーズTOP 第2章: Maxwell関係式と熱力学的関係 →
免責事項
- 本コンテンツは教育・研究・情報提供のみを目的としており、専門的な助言(法律・会計・技術的保証など)を提供するものではありません。
- 本コンテンツおよび付随するCode examplesは「現状有姿(AS IS)」で提供され、明示または黙示を問わず、商品性、特定目的適合性、権利非侵害、正確性・完全性、動作・安全性等いかなる保証もしません。
- 外部リンク、第三者が提供するデータ・ツール・ライブラリ等の内容・可用性・安全性について、作成者および東北大学は一切の責任を負いません。
- 本コンテンツの利用・実行・解釈により直接的・間接的・付随的・特別・結果的・懲罰的損害が生じた場合でも、適用法で許容される最大限の範囲で、作成者および東北大学は責任を負いません。
- 本コンテンツの内容は、予告なく変更・更新・提供停止されることがあります。
- 本コンテンツの著作権・ライセンスは明記された条件(例: CC BY 4.0)に従います。当該ライセンスは通常、無保証条項を含みます。