第5章: 材料科学への応用

🎯 学習目標

📖 固溶体と金属間化合物

固溶体(Solid Solution)

2種以上の元素が結晶格子中でランダムに混合した単一相の固体

置換型固溶体: 溶質原子が溶媒原子の格子点を置換

  • Hume-Rothery則: 原子半径差<15%、結晶構造同一、電気陰性度類似
  • 例: Cu-Ni(全率固溶)、Fe-Cr(ステンレス鋼)

侵入型固溶体: 溶質原子が格子間隙に侵入

  • 溶質原子は小さい(C, N, H, B)
  • 例: Fe-C(鋼)、Ti-O

金属間化合物(Intermetallic Compound)

特定の化学量論比で形成される規則構造

  • 例: Fe₃C(セメンタイト)、Ni₃Al、TiAl
  • 特徴: 高強度・高脆性・高融点

💻 例題5.1: Fe-C系相図の解析

Python実装: Fe-C系相図の描画と読み方
import numpy as np import matplotlib.pyplot as plt def fe_c_phase_diagram(): """Fe-C系相図の簡略モデル""" # 組成(C wt%) # 液相線 x_liquidus = np.array([0, 0.5, 2.11, 4.3, 6.69]) T_liquidus = np.array([1538, 1500, 1148, 1148, 1130]) # γ相(オーステナイト)固相線 x_gamma_solidus = np.array([0, 0.5, 2.11]) T_gamma_solidus = np.array([1495, 1450, 1148]) # α相(フェライト)境界 x_alpha = np.array([0, 0.022, 0.022, 0, 0]) T_alpha = np.array([912, 727, 1495, 1538, 912]) # γ相境界 x_gamma_boundary = np.array([0.022, 0.77, 2.11, 2.11, 0.77, 0.022]) T_gamma_boundary = np.array([727, 727, 1148, 1495, 1495, 1495]) # セメンタイト境界 x_cementite = np.array([6.69, 6.69]) T_cementite = np.array([727, 1130]) # 共晶点・共析点 eutectic_point = (4.3, 1148) # L → γ + Fe₃C eutectoid_point = (0.77, 727) # γ → α + Fe₃C return { 'liquidus': (x_liquidus, T_liquidus), 'gamma_solidus': (x_gamma_solidus, T_gamma_solidus), 'alpha': (x_alpha, T_alpha), 'gamma_boundary': (x_gamma_boundary, T_gamma_boundary), 'cementite': (x_cementite, T_cementite), 'eutectic': eutectic_point, 'eutectoid': eutectoid_point } # 相図の描画 phase_data = fe_c_phase_diagram() fig, ax = plt.subplots(figsize=(12, 8)) # 液相線 x_liq, T_liq = phase_data['liquidus'] ax.plot(x_liq, T_liq, 'r-', linewidth=2.5, label='液相線') # γ相固相線 x_g_sol, T_g_sol = phase_data['gamma_solidus'] ax.plot(x_g_sol, T_g_sol, 'b-', linewidth=2.5) # α相境界 x_a, T_a = phase_data['alpha'] ax.plot(x_a, T_a, 'g-', linewidth=2.5, label='α相(フェライト)') # γ相境界 x_g, T_g = phase_data['gamma_boundary'] ax.plot(x_g, T_g, 'b-', linewidth=2.5, label='γ相(オーステナイト)') # セメンタイト境界 x_cem, T_cem = phase_data['cementite'] ax.plot([6.69], [1130], 'ko', markersize=8) ax.axvline(6.69, color='purple', linestyle='--', linewidth=1.5, label='Fe₃C(セメンタイト)') # 重要点 eutectic = phase_data['eutectic'] eutectoid = phase_data['eutectoid'] ax.plot(eutectic[0], eutectic[1], 'ro', markersize=12, label=f'共晶点(C {eutectic[0]:.1f}%, {eutectic[1]}°C)') ax.plot(eutectoid[0], eutectoid[1], 'mo', markersize=12, label=f'共析点(C {eutectoid[0]:.2f}%, {eutectoid[1]}°C)') # 領域ラベル ax.text(0.2, 1000, 'δ-Fe', fontsize=12, ha='center') ax.text(0.2, 1300, 'L(液相)', fontsize=13, ha='center', fontweight='bold') ax.text(0.5, 1000, 'γ\n(オーステナイト)', fontsize=12, ha='center') ax.text(0.01, 850, 'α\n(フェライト)', fontsize=12, ha='center') ax.text(0.4, 650, 'α + Fe₃C\n(パーライト)', fontsize=11, ha='center') ax.text(3.0, 1000, 'L + γ', fontsize=11, ha='center') ax.text(5.0, 1000, 'L + Fe₃C', fontsize=11, ha='center') # 重要な炭素濃度を示す垂直線 ax.axvline(0.022, color='gray', linestyle=':', alpha=0.5) ax.text(0.022, 500, '0.022%\n(α最大固溶)', fontsize=9, ha='center') ax.axvline(0.77, color='gray', linestyle=':', alpha=0.5) ax.text(0.77, 500, '0.77%\n(共析点)', fontsize=9, ha='center') ax.axvline(2.11, color='gray', linestyle=':', alpha=0.5) ax.text(2.11, 500, '2.11%\n(γ最大固溶)', fontsize=9, ha='center') ax.set_xlabel('炭素濃度 (wt%)', fontsize=13) ax.set_ylabel('温度 (°C)', fontsize=13) ax.set_title('Fe-C系相図(鉄-炭素系)', fontsize=15, fontweight='bold') ax.set_xlim([0, 7]) ax.set_ylim([400, 1600]) ax.legend(loc='upper right', fontsize=10) ax.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('materials_fe_c_phase_diagram.png', dpi=300, bbox_inches='tight') plt.show() # Fe-C系の分類 print("=== Fe-C系の分類 ===\n") print(f"{'種類':<15} {'炭素濃度 (wt%)':<20} {'主要組織':<30}") print("-" * 65) print(f"{'純鉄':<15} {'< 0.008':<20} {'α-Fe(フェライト)':<30}") print(f"{'鋼(Steel)':<15} {'0.008 - 2.11':<20} {'フェライト + セメンタイト':<30}") print(f"{' 亜共析鋼':<15} {'< 0.77':<20} {'フェライト主 + パーライト':<30}") print(f"{' 共析鋼':<15} {'= 0.77':<20} {'パーライト(層状組織)':<30}") print(f"{' 過共析鋼':<15} {'0.77 - 2.11':<20} {'セメンタイト + パーライト':<30}") print(f"{'鋳鉄(Cast Iron)':<15} {'2.11 - 6.69':<20} {'γ + グラファイト/Fe₃C':<30}") print() print("重要な相変態温度:") print(f" A₁: 727°C(共析温度、γ → α + Fe₃C)") print(f" A₃: 912°C(α → γ 変態開始)") print(f" 融点: 1538°C(純鉄)")

💻 例題5.2: α-γ変態温度の計算

α-γ変態(フェライト-オーステナイト変態)

鉄の同素変態:

\[ \text{α-Fe (BCC)} \xrightarrow{912°C} \text{γ-Fe (FCC)} \]

相平衡条件: 化学ポテンシャルが等しい

\[ \mu^\alpha(T, P) = \mu^\gamma(T, P) \]

Gibbs自由エネルギー差:

\[ \Delta G^{\gamma \to \alpha} = \Delta H - T \Delta S \]

Python実装: α-γ変態の熱力学計算
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import fsolve # α-γ変態のパラメータ(純鉄) def gibbs_alpha_gamma(T): """α相とγ相のGibbs自由エネルギー差 Args: T: 温度 (K) Returns: ΔG^(γ→α): Gibbs自由エネルギー差 (J/mol) """ # 実験値に基づくモデル # ΔH ≈ -900 J/mol, ΔS ≈ -1.0 J/(mol·K) (簡略化) T_eq = 1185 # 912°C = 1185 K(α-γ変態点) DH = -900 # J/mol(変態エンタルピー) DS = DH / T_eq # J/(mol·K) DG = DH - T * DS return DG # 温度範囲 T_range = np.linspace(800, 1400, 100) # K DG_values = [gibbs_alpha_gamma(T) for T in T_range] # 変態点の計算 T_transformation = fsolve(gibbs_alpha_gamma, 1185)[0] # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # Gibbs自由エネルギー差 ax1 = axes[0] ax1.plot(T_range - 273.15, DG_values, 'b-', linewidth=2.5) ax1.axhline(0, color='r', linestyle='--', linewidth=2, label='ΔG = 0(平衡)') ax1.axvline(T_transformation - 273.15, color='g', linestyle='--', linewidth=2, label=f'変態点 {T_transformation - 273.15:.0f}°C') # 安定相の領域 ax1.fill_between(T_range - 273.15, -2000, 0, where=(T_range < T_transformation), color='lightblue', alpha=0.3, label='α相安定') ax1.fill_between(T_range - 273.15, 0, 2000, where=(T_range > T_transformation), color='lightcoral', alpha=0.3, label='γ相安定') ax1.set_xlabel('Temperature (°C)') ax1.set_ylabel('ΔG^(γ→α) (J/mol)') ax1.set_title('α-γ変態のGibbs自由エネルギー') ax1.legend() ax1.grid(True, alpha=0.3) # 炭素濃度による変態点の変化 # 簡略モデル: T_γ→α = 912°C - k·[C%] C_range = np.linspace(0, 1.5, 50) # C wt% k = 200 # °C/wt%(経験則) T_gamma_alpha = 912 - k * C_range ax2 = axes[1] ax2.plot(C_range, T_gamma_alpha, 'r-', linewidth=2.5, label='A₃線(α-γ変態開始)') ax2.axhline(727, color='purple', linestyle='--', linewidth=2, label='A₁線(共析温度)') # 重要な組成 ax2.axvline(0.77, color='gray', linestyle=':', alpha=0.5) ax2.text(0.77, 650, '共析組成\n0.77%', fontsize=10, ha='center') # 領域ラベル ax2.text(0.3, 850, 'γ相\n(オーステナイト)', fontsize=12, ha='center', bbox=dict(boxstyle='round', facecolor='lightcoral', alpha=0.5)) ax2.text(0.3, 750, 'α + γ', fontsize=11, ha='center') ax2.text(0.3, 650, 'α + Fe₃C\n(フェライト+セメンタイト)', fontsize=11, ha='center', bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.5)) ax2.set_xlabel('炭素濃度 (wt%)') ax2.set_ylabel('温度 (°C)') ax2.set_title('炭素濃度とα-γ変態温度') ax2.set_xlim([0, 1.5]) ax2.set_ylim([600, 950]) ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('materials_alpha_gamma_transformation.png', dpi=300, bbox_inches='tight') plt.show() # 計算結果 print("=== α-γ変態の熱力学 ===\n") print(f"変態点(計算): {T_transformation - 273.15:.2f}°C") print(f"実験値: 912°C") print() print("炭素濃度による変態点降下:") print(f"{'C濃度 (wt%)':<15} {'変態温度 (°C)':<20}") print("-" * 35) for C in [0, 0.2, 0.4, 0.6, 0.77]: T = 912 - k * C print(f"{C:<15.2f} {T:<20.0f}") print("\n物理的意義:") print(" - α相(BCC)は炭素固溶度が低い(0.022% at 727°C)") print(" - γ相(FCC)は炭素固溶度が高い(2.11% at 1148°C)") print(" - 炭素添加でγ相が安定化 → 変態温度低下")

💻 例題5.3: マルテンサイト変態の熱力学

マルテンサイト変態

無拡散型変態: γ相(FCC)から急冷により形成される過飽和固溶体

特徴:

  • 拡散なし(原子の協調的剪断変形)
  • 準安定相(非平衡)
  • 高硬度・高脆性
  • 結晶構造: BCT(体心正方格子)

Ms点(Martensite start): マルテンサイト変態開始温度

\[ M_s = 539 - 423[\text{C}] - 30.4[\text{Mn}] - 12.1[\text{Cr}] - 17.7[\text{Ni}] \quad (°C) \]

Python実装: Ms点の計算と冷却曲線
import numpy as np import matplotlib.pyplot as plt def calculate_Ms(C, Mn=0, Cr=0, Ni=0): """マルテンサイト変態開始温度(Ms点)の計算 Andrews式による経験則 Args: C: 炭素濃度 (wt%) Mn: マンガン濃度 (wt%) Cr: クロム濃度 (wt%) Ni: ニッケル濃度 (wt%) Returns: Ms: マルテンサイト変態開始温度 (°C) """ Ms = 539 - 423*C - 30.4*Mn - 12.1*Cr - 17.7*Ni return Ms # 炭素濃度によるMs点の変化 C_range = np.linspace(0.1, 1.2, 50) Ms_values = [calculate_Ms(C) for C in C_range] # 合金元素の影響 Mn_range = [0, 1.0, 2.0] Ni_range = [0, 2.0, 4.0] fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # 炭素濃度の影響 ax1 = axes[0] ax1.plot(C_range, Ms_values, 'b-', linewidth=2.5, label='Plain carbon steel') # Mn添加の影響 for Mn in Mn_range[1:]: Ms_Mn = [calculate_Ms(C, Mn=Mn) for C in C_range] ax1.plot(C_range, Ms_Mn, '--', linewidth=2, label=f'+ {Mn:.1f}% Mn') ax1.axhline(0, color='red', linestyle=':', linewidth=1.5, label='室温') ax1.set_xlabel('炭素濃度 (wt%)') ax1.set_ylabel('Ms点 (°C)') ax1.set_title('マルテンサイト変態開始温度(Ms点)') ax1.legend() ax1.grid(True, alpha=0.3) ax1.set_ylim([-100, 550]) # 冷却曲線とマルテンサイト分率 ax2 = axes[1] # Koistinen-Marburger式: f_M = 1 - exp(-α(Ms - T)) def martensite_fraction(T, Ms, alpha=0.011): """マルテンサイト分率 Args: T: 温度 (°C) Ms: Ms点 (°C) alpha: 定数(通常 0.011) Returns: f_M: マルテンサイト分率 """ if T >= Ms: return 0 else: f_M = 1 - np.exp(-alpha * (Ms - T)) return f_M # 異なる炭素濃度でのマルテンサイト分率 T_range = np.linspace(-100, 800, 200) C_values = [0.3, 0.6, 0.9] colors = ['blue', 'green', 'red'] for C, color in zip(C_values, colors): Ms = calculate_Ms(C) f_M = [martensite_fraction(T, Ms) for T in T_range] ax2.plot(T_range, f_M, color=color, linewidth=2.5, label=f'C {C:.1f}% (Ms={Ms:.0f}°C)') ax2.axvline(25, color='purple', linestyle='--', linewidth=1.5, label='室温') ax2.set_xlabel('温度 (°C)') ax2.set_ylabel('マルテンサイト分率') ax2.set_title('マルテンサイト分率の温度依存性') ax2.legend() ax2.grid(True, alpha=0.3) ax2.set_xlim([-100, 800]) ax2.set_ylim([0, 1]) plt.tight_layout() plt.savefig('materials_martensite_transformation.png', dpi=300, bbox_inches='tight') plt.show() # 計算例 print("=== マルテンサイト変態のMs点 ===\n") steels = [ ("低炭素鋼", 0.2, 0, 0, 0), ("中炭素鋼", 0.6, 0, 0, 0), ("高炭素鋼", 1.0, 0, 0, 0), ("Mn鋼", 0.6, 2.0, 0, 0), ("Cr-Ni鋼", 0.6, 1.0, 12.0, 8.0), ] print(f"{'鋼種':<15} {'C%':<6} {'Mn%':<6} {'Cr%':<6} {'Ni%':<6} {'Ms点 (°C)':<12}") print("-" * 60) for name, C, Mn, Cr, Ni in steels: Ms = calculate_Ms(C, Mn, Cr, Ni) print(f"{name:<15} {C:<6.1f} {Mn:<6.1f} {Cr:<6.1f} {Ni:<6.1f} {Ms:<12.0f}") print("\n室温マルテンサイト分率(25°C):") for name, C, Mn, Cr, Ni in steels: Ms = calculate_Ms(C, Mn, Cr, Ni) f_M = martensite_fraction(25, Ms) print(f" {name}: {f_M*100:.1f}%") print("\n重要な知見:") print(" - 炭素↑ → Ms点↓(マルテンサイト形成しにくい)") print(" - 合金元素(Mn, Cr, Ni)もMs点を下げる") print(" - Ms < 室温の場合、残留オーステナイトが残る")

💻 例題5.4: TTT図(Time-Temperature-Transformation)の描画

TTT図とは

恒温変態図: 等温保持での変態開始・終了時間を示す

主要な変態:

  • パーライト変態: 拡散型、層状組織(α + Fe₃C)
  • ベイナイト変態: 中間的、針状組織
  • マルテンサイト変態: 無拡散型、急冷により形成

用途: 熱処理プロセス設計、組織予測

Python実装: TTT図の模擬データ生成
import numpy as np import matplotlib.pyplot as plt def generate_TTT_diagram(C_content=0.8): """TTT図の模擬データ生成 Args: C_content: 炭素濃度 (wt%) Returns: TTT diagram data """ # 温度範囲 T_range = np.linspace(200, 700, 100) # パーライト変態(C曲線) # 鼻点(最短変態時間): ~550°C, ~1秒 T_pearlite_nose = 550 t_pearlite_nose = 1.0 # 秒 def pearlite_curve(T, factor): """パーライト変態曲線(Johnson-Mehl-Avrami式に基づく)""" if T < 500 or T > 727: return 1e10 # 変態しない else: # C曲線の形状 t = t_pearlite_nose * factor * np.exp(abs(T - T_pearlite_nose) / 50) return t t_pearlite_start = [pearlite_curve(T, 1) for T in T_range] t_pearlite_finish = [pearlite_curve(T, 10) for T in T_range] # ベイナイト変態 T_bainite_nose = 350 t_bainite_nose = 10.0 def bainite_curve(T, factor): if T < 250 or T > 500: return 1e10 else: t = t_bainite_nose * factor * np.exp(abs(T - T_bainite_nose) / 30) return t t_bainite_start = [bainite_curve(T, 1) for T in T_range] t_bainite_finish = [bainite_curve(T, 10) for T in T_range] # マルテンサイト(瞬間的) Ms = calculate_Ms(C_content) Mf = Ms - 215 # Mf点(マルテンサイト変態終了) return { 'T_range': T_range, 'pearlite_start': t_pearlite_start, 'pearlite_finish': t_pearlite_finish, 'bainite_start': t_bainite_start, 'bainite_finish': t_bainite_finish, 'Ms': Ms, 'Mf': Mf } # TTT図の描画 C = 0.8 # 共析鋼 ttt_data = generate_TTT_diagram(C) fig, ax = plt.subplots(figsize=(12, 8)) T = ttt_data['T_range'] t_p_s = np.array(ttt_data['pearlite_start']) t_p_f = np.array(ttt_data['pearlite_finish']) t_b_s = np.array(ttt_data['bainite_start']) t_b_f = np.array(ttt_data['bainite_finish']) # 時間を有効範囲でマスク valid_p_s = t_p_s < 1e6 valid_p_f = t_p_f < 1e6 valid_b_s = t_b_s < 1e6 valid_b_f = t_b_f < 1e6 # パーライト ax.semilogx(t_p_s[valid_p_s], T[valid_p_s], 'b-', linewidth=2.5, label='パーライト変態開始') ax.semilogx(t_p_f[valid_p_f], T[valid_p_f], 'b--', linewidth=2.5, label='パーライト変態終了') ax.fill_betweenx(T[valid_p_s], t_p_s[valid_p_s], t_p_f[valid_p_f], where=valid_p_s & valid_p_f, color='lightblue', alpha=0.3) # ベイナイト ax.semilogx(t_b_s[valid_b_s], T[valid_b_s], 'g-', linewidth=2.5, label='ベイナイト変態開始') ax.semilogx(t_b_f[valid_b_f], T[valid_b_f], 'g--', linewidth=2.5, label='ベイナイト変態終了') ax.fill_betweenx(T[valid_b_s], t_b_s[valid_b_s], t_b_f[valid_b_f], where=valid_b_s & valid_b_f, color='lightgreen', alpha=0.3) # マルテンサイト Ms = ttt_data['Ms'] Mf = ttt_data['Mf'] ax.axhline(Ms, color='red', linestyle='-', linewidth=2.5, label=f'Ms = {Ms:.0f}°C') ax.axhline(Mf, color='red', linestyle='--', linewidth=2, label=f'Mf = {Mf:.0f}°C') ax.fill_between([1e-2, 1e6], Mf, Ms, color='lightcoral', alpha=0.3) # 冷却曲線の例 # 徐冷: パーライト形成 t_cool_slow = np.logspace(-1, 3, 50) T_cool_slow = 900 - 100 * np.log10(t_cool_slow + 1) ax.plot(t_cool_slow, T_cool_slow, 'purple', linewidth=2, linestyle=':', label='徐冷(炉冷)→ パーライト') # 急冷: マルテンサイト形成 t_cool_fast = np.logspace(-2, 0, 30) T_cool_fast = 900 - 800 * t_cool_fast ax.plot(t_cool_fast, T_cool_fast, 'orange', linewidth=2, linestyle=':', label='急冷(水冷)→ マルテンサイト') # ラベル ax.text(10, 600, 'パーライト', fontsize=14, fontweight='bold', bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.7)) ax.text(100, 350, 'ベイナイト', fontsize=14, fontweight='bold', bbox=dict(boxstyle='round', facecolor='lightgreen', alpha=0.7)) ax.text(0.5, Ms-50, 'マルテンサイト', fontsize=14, fontweight='bold', bbox=dict(boxstyle='round', facecolor='lightcoral', alpha=0.7)) ax.set_xlabel('時間 (秒)', fontsize=13) ax.set_ylabel('温度 (°C)', fontsize=13) ax.set_title(f'TTT図(Time-Temperature-Transformation)\nC {C}% 鋼', fontsize=15, fontweight='bold') ax.set_xlim([1e-2, 1e6]) ax.set_ylim([0, 800]) ax.legend(loc='upper right', fontsize=10) ax.grid(True, alpha=0.3, which='both') plt.tight_layout() plt.savefig('materials_TTT_diagram.png', dpi=300, bbox_inches='tight') plt.show() print("=== TTT図の読み方 ===\n") print("1. 縦軸: 温度(オーステナイト化温度から冷却)") print("2. 横軸: 時間(対数スケール)") print("3. C曲線: 変態開始・終了時間") print() print("組織の決定:") print(" - 徐冷(曲線を横切る)→ パーライト") print(" - 中速冷却 → ベイナイト") print(" - 急冷(曲線を避けてMs以下)→ マルテンサイト") print() print("実用例:") print(" - 焼入れ: 急冷してマルテンサイト(高硬度)") print(" - 焼なまし: 徐冷してパーライト(軟化)") print(" - 焼戻し: マルテンサイトを加熱して靭性改善")

💻 例題5.5: CCT図(Continuous Cooling Transformation)の計算

Python実装: CCT図と冷却速度
import numpy as np import matplotlib.pyplot as plt def generate_CCT_diagram(C_content=0.4): """CCT図の模擬データ(連続冷却変態図) Args: C_content: 炭素濃度 (wt%) """ # TTT図に比べて曲線が右にシフト T_range = np.linspace(200, 750, 100) # フェライト+パーライト変態 T_fp_nose = 600 t_fp_nose = 10.0 def fp_curve(T, factor): if T < 500 or T > 750: return 1e10 else: t = t_fp_nose * factor * np.exp(abs(T - T_fp_nose) / 60) return t t_fp_start = [fp_curve(T, 1) for T in T_range] t_fp_finish = [fp_curve(T, 50) for T in T_range] # ベイナイト T_b_nose = 400 t_b_nose = 100.0 def b_curve(T, factor): if T < 300 or T > 550: return 1e10 else: t = t_b_nose * factor * np.exp(abs(T - T_b_nose) / 40) return t t_b_start = [b_curve(T, 1) for T in T_range] t_b_finish = [b_curve(T, 50) for T in T_range] # マルテンサイト Ms = calculate_Ms(C_content) Mf = Ms - 215 return { 'T_range': T_range, 'fp_start': t_fp_start, 'fp_finish': t_fp_finish, 'b_start': t_b_start, 'b_finish': t_b_finish, 'Ms': Ms, 'Mf': Mf } # 冷却曲線の生成 def cooling_curve(cooling_rate, T_start=900, T_final=25): """冷却曲線 Args: cooling_rate: 冷却速度 (°C/s) T_start: 初期温度 (°C) T_final: 最終温度 (°C) Returns: t, T: 時間、温度 """ t_total = (T_start - T_final) / cooling_rate t = np.linspace(0, t_total, 200) T = T_start - cooling_rate * t T = np.maximum(T, T_final) return t, T # CCT図の描画 C = 0.4 # 中炭素鋼 cct_data = generate_CCT_diagram(C) fig, ax = plt.subplots(figsize=(12, 8)) T = cct_data['T_range'] t_fp_s = np.array(cct_data['fp_start']) t_fp_f = np.array(cct_data['fp_finish']) t_b_s = np.array(cct_data['b_start']) t_b_f = np.array(cct_data['b_finish']) # 有効範囲 valid_fp_s = t_fp_s < 1e6 valid_fp_f = t_fp_f < 1e6 valid_b_s = t_b_s < 1e6 valid_b_f = t_b_f < 1e6 # フェライト+パーライト ax.semilogx(t_fp_s[valid_fp_s], T[valid_fp_s], 'b-', linewidth=2.5, label='F+P開始') ax.semilogx(t_fp_f[valid_fp_f], T[valid_fp_f], 'b--', linewidth=2.5, label='F+P終了') ax.fill_betweenx(T, t_fp_s, t_fp_f, where=valid_fp_s & valid_fp_f, color='lightblue', alpha=0.3) # ベイナイト ax.semilogx(t_b_s[valid_b_s], T[valid_b_s], 'g-', linewidth=2.5, label='B開始') ax.semilogx(t_b_f[valid_b_f], T[valid_b_f], 'g--', linewidth=2.5, label='B終了') ax.fill_betweenx(T, t_b_s, t_b_f, where=valid_b_s & valid_b_f, color='lightgreen', alpha=0.3) # マルテンサイト Ms = cct_data['Ms'] Mf = cct_data['Mf'] ax.axhline(Ms, color='red', linestyle='-', linewidth=2.5, label=f'Ms = {Ms:.0f}°C') ax.axhline(Mf, color='red', linestyle='--', linewidth=2, label=f'Mf = {Mf:.0f}°C') # 様々な冷却速度 cooling_rates = [0.5, 5, 50, 500] # °C/s colors = ['purple', 'orange', 'brown', 'magenta'] microstructures = ['F+P', 'F+P+B', 'B+M', 'M'] for i, (cr, color, micro) in enumerate(zip(cooling_rates, colors, microstructures)): t_cool, T_cool = cooling_curve(cr) ax.plot(t_cool, T_cool, color=color, linewidth=2, linestyle=':', label=f'{cr} °C/s → {micro}') # 臨界冷却速度の表示 ax.axvline(1, color='gray', linestyle='--', alpha=0.5) ax.text(1, 100, '臨界冷却速度\n(この速度以上で\nマルテンサイト形成)', fontsize=10, ha='center', bbox=dict(boxstyle='round', facecolor='yellow', alpha=0.6)) ax.set_xlabel('時間 (秒)', fontsize=13) ax.set_ylabel('温度 (°C)', fontsize=13) ax.set_title(f'CCT図(Continuous Cooling Transformation)\nC {C}% 鋼', fontsize=15, fontweight='bold') ax.set_xlim([1e-1, 1e4]) ax.set_ylim([0, 900]) ax.legend(loc='upper right', fontsize=9) ax.grid(True, alpha=0.3, which='both') plt.tight_layout() plt.savefig('materials_CCT_diagram.png', dpi=300, bbox_inches='tight') plt.show() # 冷却速度と組織の関係 print("=== CCT図と冷却速度 ===\n") print(f"{'冷却速度 (°C/s)':<20} {'冷却時間 (900→25°C)':<25} {'組織':<30}") print("-" * 75) for cr in cooling_rates: t_total = (900 - 25) / cr # 組織判定(簡略) if cr < 1: micro = "フェライト + パーライト" elif cr < 10: micro = "フェライト + パーライト + ベイナイト" elif cr < 100: micro = "ベイナイト + マルテンサイト" else: micro = "マルテンサイト" print(f"{cr:<20.1f} {t_total:<25.1f} {micro:<30}") print("\n冷却方法と冷却速度:") print(" - 炉冷(Furnace cooling): ~0.1-1 °C/s") print(" - 空冷(Air cooling): ~1-10 °C/s") print(" - 油冷(Oil quenching): ~10-100 °C/s") print(" - 水冷(Water quenching): ~100-1000 °C/s") print() print("TTT図 vs CCT図:") print(" - TTT: 等温変態(実験室的)") print(" - CCT: 連続冷却変態(実用的)") print(" - CCT曲線はTTT曲線より右側(遅い時間)")

💻 例題5.6: 合金の混合エンタルピー計算

Python実装: 二元系の混合エンタルピー
import numpy as np import matplotlib.pyplot as plt def mixing_enthalpy(x_B, H_AB, omega=0): """二元合金A-Bの混合エンタルピー 正則溶体モデル: ΔH_mix = Ω x_A x_B Args: x_B: B原子分率 H_AB: 相互作用パラメータ(A-B結合エネルギー) omega: 相互作用パラメータ Ω = z(ε_AB - (ε_AA + ε_BB)/2) Returns: ΔH_mix: 混合エンタルピー (J/mol) """ x_A = 1 - x_B if omega == 0: omega = H_AB DH_mix = omega * x_A * x_B return DH_mix def mixing_entropy(x_B, R=8.314): """理想溶体の配置エントロピー Args: x_B: B原子分率 R: 気体定数 (J/(mol·K)) Returns: ΔS_mix: 混合エントロピー (J/(mol·K)) """ x_A = 1 - x_B if x_A == 0 or x_B == 0: return 0 else: DS_mix = -R * (x_A * np.log(x_A) + x_B * np.log(x_B)) return DS_mix def mixing_gibbs(x_B, T, omega, R=8.314): """混合Gibbs自由エネルギー ΔG_mix = ΔH_mix - T ΔS_mix Args: x_B: B原子分率 T: 温度 (K) omega: 相互作用パラメータ (J/mol) R: 気体定数 Returns: ΔG_mix: 混合Gibbs自由エネルギー (J/mol) """ DH = mixing_enthalpy(x_B, 0, omega) DS = mixing_entropy(x_B, R) DG = DH - T * DS return DG # 組成範囲 x_B_range = np.linspace(0.001, 0.999, 200) # 相互作用パラメータ(異なる系) omega_values = { '理想溶体(Ω=0)': 0, '弱い吸引(Ω=-5kJ/mol)': -5000, '強い反発(Ω=+20kJ/mol)': 20000, } fig, axes = plt.subplots(2, 2, figsize=(14, 10)) # 混合エンタルピー ax1 = axes[0, 0] for name, omega in omega_values.items(): DH_values = [mixing_enthalpy(x, 0, omega) for x in x_B_range] ax1.plot(x_B_range, np.array(DH_values) / 1000, linewidth=2.5, label=name) ax1.set_xlabel('組成 x_B') ax1.set_ylabel('ΔH_mix (kJ/mol)') ax1.set_title('混合エンタルピー') ax1.legend() ax1.grid(True, alpha=0.3) ax1.axhline(0, color='black', linestyle='--', linewidth=1) # 混合エントロピー ax2 = axes[0, 1] DS_values = [mixing_entropy(x) for x in x_B_range] ax2.plot(x_B_range, DS_values, 'g-', linewidth=2.5) ax2.set_xlabel('組成 x_B') ax2.set_ylabel('ΔS_mix (J/(mol·K))') ax2.set_title('混合エントロピー(理想溶体)') ax2.grid(True, alpha=0.3) # 混合Gibbs自由エネルギー(温度依存) ax3 = axes[1, 0] T_values = [300, 600, 1000, 1500] omega_example = 20000 # 反発系 for T in T_values: DG_values = [mixing_gibbs(x, T, omega_example) for x in x_B_range] ax3.plot(x_B_range, np.array(DG_values) / 1000, linewidth=2.5, label=f'T = {T} K') ax3.set_xlabel('組成 x_B') ax3.set_ylabel('ΔG_mix (kJ/mol)') ax3.set_title(f'混合Gibbs自由エネルギー(Ω = {omega_example/1000:.0f} kJ/mol)') ax3.legend() ax3.grid(True, alpha=0.3) ax3.axhline(0, color='black', linestyle='--', linewidth=1) # 相分離の判定(∂²ΔG/∂x² < 0 でスピノーダル) ax4 = axes[1, 1] T = 600 omega_spinodal = 20000 DG_values = [mixing_gibbs(x, T, omega_spinodal) for x in x_B_range] ax4.plot(x_B_range, np.array(DG_values) / 1000, 'b-', linewidth=2.5, label='ΔG_mix') # 接線(共通接線法で相分離組成を求める - 簡略化) # ここでは視覚的に表示 ax4.axhline(0, color='gray', linestyle='--', linewidth=1, alpha=0.5) ax4.text(0.5, 3, f'T = {T} K\n高温で相分離傾向', fontsize=11, ha='center', bbox=dict(boxstyle='round', facecolor='yellow', alpha=0.6)) ax4.set_xlabel('組成 x_B') ax4.set_ylabel('ΔG_mix (kJ/mol)') ax4.set_title('相分離と共通接線') ax4.legend() ax4.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('materials_mixing_enthalpy.png', dpi=300, bbox_inches='tight') plt.show() # 解析 print("=== 混合エンタルピーと相安定性 ===\n") print("相互作用パラメータ Ω の意味:") print(" Ω < 0: A-B結合が A-A, B-B より強い → 吸引、固溶傾向") print(" Ω = 0: 理想溶体(完全にランダム)") print(" Ω > 0: A-B結合が弱い → 反発、相分離傾向") print() print("ΔG_mix = ΔH_mix - T ΔS_mix の競合:") print(" - 低温: ΔH_mixが支配 → Ω>0なら相分離") print(" - 高温: -TΔS_mixが支配 → エントロピー項で混合") print() # 臨界温度の計算(簡略化) omega_critical = 20000 R = 8.314 T_critical = omega_critical / (2 * R) # 正則溶体の臨界温度 print(f"臨界温度(正則溶体モデル):") print(f" T_c = Ω / (2R) = {omega_critical/1000:.0f} / (2 × 8.314)") print(f" T_c ≈ {T_critical:.0f} K = {T_critical - 273:.0f} °C") print(f" T > T_c: 全率固溶") print(f" T < T_c: 相分離(ミスシビリティギャップ)")

💻 例題5.7: 高エントロピー合金(HEA)の配置エントロピー

Python実装: 多元系の配置エントロピー
import numpy as np import matplotlib.pyplot as plt from itertools import combinations def configurational_entropy_multicomponent(composition, R=8.314): """多元系の配置エントロピー ΔS_conf = -R Σ x_i ln(x_i) Args: composition: 各元素の原子分率(リスト) R: 気体定数 (J/(mol·K)) Returns: ΔS_conf: 配置エントロピー (J/(mol·K)) """ x = np.array(composition) x = x[x > 0] # ゼロを除く if np.sum(x) != 1.0: x = x / np.sum(x) # 規格化 DS_conf = -R * np.sum(x * np.log(x)) return DS_conf # 代表的な高エントロピー合金(HEA) HEAs = { 'CoCrFeMnNi(Cantor合金)': [0.2, 0.2, 0.2, 0.2, 0.2], # 等原子比5元系 'AlCoCrFeNi': [0.2, 0.2, 0.2, 0.2, 0.2], 'CoCrFeNi': [0.25, 0.25, 0.25, 0.25], # 4元系 'TiZrHfNbTa': [0.2, 0.2, 0.2, 0.2, 0.2], # 難融性HEA } # 伝統的合金(比較用) traditional_alloys = { 'ステンレス鋼(SUS304)': [0.70, 0.18, 0.08, 0.04], # Fe, Cr, Ni, Mn(簡略) 'Al合金(7075)': [0.90, 0.05, 0.03, 0.02], # Al, Zn, Mg, Cu(簡略) '真鍮(黄銅)': [0.70, 0.30], # Cu, Zn } print("=== 高エントロピー合金(HEA)の配置エントロピー ===\n") print(f"{'合金':<30} {'元素数':<10} {'ΔS_conf (J/(mol·K))':<25}") print("-" * 65) # HEAの計算 for name, comp in HEAs.items(): n_elements = len(comp) DS = configurational_entropy_multicomponent(comp) print(f"{name:<30} {n_elements:<10} {DS:<25.4f}") print("\n伝統的合金(比較):") for name, comp in traditional_alloys.items(): n_elements = len(comp) DS = configurational_entropy_multicomponent(comp) print(f"{name:<30} {n_elements:<10} {DS:<25.4f}") # 理論的最大値 R = 8.314 print("\n理論的最大値:") for n in [2, 3, 4, 5, 6]: DS_max = R * np.log(n) print(f" {n}元系(等原子比): ΔS_conf = R ln({n}) = {DS_max:.4f} J/(mol·K)") # 可視化 fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # 元素数と最大エントロピー ax1 = axes[0] n_range = np.arange(2, 11) DS_max_range = R * np.log(n_range) ax1.plot(n_range, DS_max_range, 'bo-', markersize=8, linewidth=2.5, label='理論最大値(等原子比)') # HEAと伝統的合金をプロット all_alloys = {**HEAs, **traditional_alloys} for name, comp in all_alloys.items(): n = len(comp) DS = configurational_entropy_multicomponent(comp) marker = 's' if name in HEAs else '^' color = 'red' if name in HEAs else 'green' ax1.plot(n, DS, marker, markersize=10, color=color) ax1.plot([], [], 'rs', markersize=10, label='HEA') ax1.plot([], [], 'g^', markersize=10, label='伝統的合金') ax1.set_xlabel('元素数') ax1.set_ylabel('ΔS_conf (J/(mol·K))') ax1.set_title('配置エントロピーと元素数') ax1.legend() ax1.grid(True, alpha=0.3) ax1.set_xticks(n_range) # 組成の影響(5元系で1元素の濃度を変化) ax2 = axes[1] x_vary = np.linspace(0.05, 0.85, 50) DS_vary = [] for x1 in x_vary: # 残り4元素を等分 x_rest = (1 - x1) / 4 comp = [x1, x_rest, x_rest, x_rest, x_rest] DS = configurational_entropy_multicomponent(comp) DS_vary.append(DS) ax2.plot(x_vary, DS_vary, 'b-', linewidth=2.5) ax2.axvline(0.2, color='red', linestyle='--', linewidth=2, label='等原子比(x=0.2)') ax2.axhline(R * np.log(5), color='red', linestyle='--', linewidth=1.5, alpha=0.5) ax2.set_xlabel('第1元素の原子分率 x₁') ax2.set_ylabel('ΔS_conf (J/(mol·K))') ax2.set_title('配置エントロピーの組成依存性(5元系)') ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('materials_HEA_entropy.png', dpi=300, bbox_inches='tight') plt.show() # HEAの定義 print("\n=== 高エントロピー合金(HEA)の定義 ===") print("ΔS_conf ≥ 1.5R を満たす多元系合金") print(f" 1.5R = 1.5 × 8.314 = {1.5*R:.4f} J/(mol·K)") print() print("HEAの特徴:") print(" 1. 高い配置エントロピー → 固溶体安定化") print(" 2. 多元系(通常5元素以上)") print(" 3. 格子歪み効果 → 高強度") print(" 4. カクテル効果(相乗効果)") print() print("応用例:") print(" - CoCrFeMnNi: 極低温での優れた靭性") print(" - TiZrHfNbTa: 超高温耐性(難融性HEA)") print(" - AlCoCrFeNi: 高温強度と耐酸化性")

📚 まとめ

💡 演習問題

  1. [Easy] Fe-C系で炭素濃度0.4%の鋼を800°Cから徐冷すると、どの組織が得られるか。相図を用いて説明せよ。
  2. [Easy] Andrews式を用いて、C 0.8%, Mn 1.0% の鋼のMs点を計算せよ。
  3. [Medium] Koistinen-Marburger式 \(f_M = 1 - \exp(-0.011(M_s - T))\) を用いて、Ms=350°Cの鋼を25°Cまで冷却したときのマルテンサイト分率を求めよ。
  4. [Medium] 正則溶体モデルで相互作用パラメータΩ=20 kJ/molの二元系の臨界温度を計算せよ。ただし \(T_c = \Omega / (2R)\) とする。
  5. [Hard] 5元系等原子比合金(各20%)と、主成分80%+4元素各5%の合金の配置エントロピーを計算し、どちらが高エントロピー合金の定義(ΔS ≥ 1.5R)を満たすか判定せよ。