熱応力の理論と計算

構造物が温度変化を受けると膨張または収縮しますが、拘束条件がある場合にはその変形が妨げられ、内部に熱応力(thermal stress) が発生します。人工衛星が太陽に面する側と影の側で100度以上の温度差にさらされる場面など、熱応力は宇宙構造物の設計においても重要な課題です。

本記事では、熱膨張の基礎から熱応力の導出、異種材料の問題まで段階的に解説します。

本記事の内容

  • 熱膨張と線膨張係数
  • 自由膨張と拘束条件
  • 熱応力 $\sigma = -E\alpha\Delta T$ の導出
  • 異種材料の熱応力問題
  • Pythonでの解析と可視化

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

熱膨張とは

物体の温度が $\Delta T$ だけ変化すると、長さが変化します。温度変化による熱ひずみ(thermal strain) は:

$$ \boxed{\varepsilon_T = \alpha \Delta T} $$

ここで、$\alpha$ は線膨張係数(coefficient of linear thermal expansion) [1/K] です。

自由膨張のときの伸びは:

$$ \delta_T = \alpha \Delta T \cdot L $$

代表的な線膨張係数を示します:

材料 $\alpha$ [$\times 10^{-6}$ /K]
12
アルミニウム 23
17
インバー 1.2
コンクリート 10

拘束による熱応力

自由膨張(無拘束)

両端が自由な棒に温度変化 $\Delta T$ を与えると:

$$ \delta_T = \alpha \Delta T \cdot L $$

このとき応力は発生しません: $\sigma = 0$。

両端固定(完全拘束)

両端が剛体壁に固定された棒の場合、自由膨張は完全に拘束されます。

適合条件(全体の変位がゼロ):

$$ \delta_{\text{total}} = \delta_T + \delta_P = 0 $$

ここで $\delta_T = \alpha \Delta T \cdot L$ は自由膨張、$\delta_P = PL/AE$ は反力による弾性変形です。

$$ \alpha \Delta T \cdot L + \frac{PL}{AE} = 0 $$

$$ P = -AE\alpha\Delta T $$

よって熱応力は:

$$ \sigma = \frac{P}{A} = -E\alpha\Delta T $$

$$ \boxed{\sigma = -E\alpha\Delta T} $$

$\Delta T > 0$(温度上昇)のとき $\sigma < 0$(圧縮応力)、$\Delta T < 0$(温度低下)のとき $\sigma > 0$(引張応力)が生じます。

部分拘束

棒の一端が剛体壁に固定され、もう一端にばね(ばね定数 $k$)が接続されている場合:

適合条件:

$$ \delta_T = \delta_{\text{spring}} + \delta_{\text{bar}} $$

$$ \alpha \Delta T \cdot L = \frac{P}{k} + \frac{PL}{AE} $$

$$ P = \frac{\alpha \Delta T \cdot L}{\frac{1}{k} + \frac{L}{AE}} $$

ばね定数 $k \to \infty$ で完全拘束に帰着します。

異種材料の熱応力

バイメタル(二層材料)

長さ $L$ の2つの棒(材料1: $E_1, A_1, \alpha_1$、材料2: $E_2, A_2, \alpha_2$)が並列に接合された系を考えます。$\alpha_1 > \alpha_2$ と仮定します。

温度変化 $\Delta T$ により、材料1はより大きく膨張しようとしますが、接合されているため互いに拘束し合います。

力のつり合い(内力は等しく逆向き):

$$ P_1 + P_2 = 0 \implies P_1 = -P_2 = P \tag{1} $$

材料1は圧縮(膨張を妨げられる)、材料2は引張(引き伸ばされる)を受けます。

適合条件(両者の伸びが等しい):

$$ \delta_1 = \delta_2 \tag{2} $$

$$ \alpha_1 \Delta T \cdot L – \frac{PL}{A_1 E_1} = \alpha_2 \Delta T \cdot L + \frac{PL}{A_2 E_2} $$

整理すると:

$$ (\alpha_1 – \alpha_2)\Delta T = P\left(\frac{1}{A_1 E_1} + \frac{1}{A_2 E_2}\right) $$

$$ \boxed{P = \frac{(\alpha_1 – \alpha_2)\Delta T}{\frac{1}{A_1 E_1} + \frac{1}{A_2 E_2}}} $$

各材料の応力:

$$ \sigma_1 = -\frac{P}{A_1} \quad (\text{圧縮}), \quad \sigma_2 = \frac{P}{A_2} \quad (\text{引張}) $$

Pythonでの実装

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(16, 5))

# (1) 各材料の熱応力 vs 温度変化
materials = {
    'Steel':     {'E': 200e3, 'alpha': 12e-6, 'color': 'b'},
    'Aluminum':  {'E': 70e3,  'alpha': 23e-6, 'color': 'r'},
    'Copper':    {'E': 120e3, 'alpha': 17e-6, 'color': 'g'},
    'Invar':     {'E': 140e3, 'alpha': 1.2e-6, 'color': 'm'},
}

dT = np.linspace(0, 200, 100)  # 温度変化 [K]

for name, props in materials.items():
    sigma = props['E'] * props['alpha'] * dT  # [MPa](圧縮の大きさ)
    axes[0].plot(dT, sigma, color=props['color'], linewidth=2,
                label=f"{name} ($\\alpha$={props['alpha']*1e6:.1f})")

axes[0].set_xlabel('Temperature Change $\\Delta T$ [K]')
axes[0].set_ylabel('Thermal Stress $|\\sigma|$ [MPa]')
axes[0].set_title('Thermal Stress (Fully Constrained)')
axes[0].legend()
axes[0].grid(True, alpha=0.3)

# (2) 部分拘束: ばね定数による応力変化
E_bar = 200e3   # [MPa]
alpha_bar = 12e-6  # [1/K]
A_bar = 500e-6  # [m^2]
L_bar = 1.0     # [m]
dT_val = 100    # [K]

k_range = np.logspace(4, 10, 200)  # ばね定数 [N/m]
# 単位変換: E_barをPaに
E_pa = E_bar * 1e6

P_spring = alpha_bar * dT_val * L_bar / (1/k_range + L_bar / (A_bar * E_pa))
sigma_spring = P_spring / A_bar / 1e6  # [MPa]

# 完全拘束の応力
sigma_full = E_bar * alpha_bar * dT_val  # [MPa]

axes[1].semilogx(k_range, sigma_spring, 'b-', linewidth=2.5)
axes[1].axhline(sigma_full, color='r', linestyle='--', linewidth=1.5,
               label=f'Full constraint: {sigma_full:.1f} MPa')
axes[1].set_xlabel('Spring Constant $k$ [N/m]')
axes[1].set_ylabel('Stress [MPa]')
axes[1].set_title(f'Partial Constraint ($\\Delta T$ = {dT_val} K)')
axes[1].legend()
axes[1].grid(True, alpha=0.3)

# (3) 異種材料(バイメタル): Steel + Aluminum
E1, alpha1, A1 = 200e3, 12e-6, 500e-6   # 鋼 [MPa], [1/K], [m^2]
E2, alpha2, A2 = 70e3,  23e-6, 500e-6   # アルミ

dT_bi = np.linspace(0, 150, 100)

P_bi = (alpha2 - alpha1) * dT_bi / (1/(A1 * E1 * 1e6) + 1/(A2 * E2 * 1e6))
sigma1_bi = -P_bi / A1 / 1e6  # [MPa] 鋼(引張:アルミがより膨張するため)
sigma2_bi = P_bi / A2 / 1e6   # [MPa] アルミ(圧縮)

axes[2].plot(dT_bi, sigma1_bi, 'b-', linewidth=2.5, label='Steel (tensile)')
axes[2].plot(dT_bi, sigma2_bi, 'r-', linewidth=2.5, label='Aluminum (compressive)')
axes[2].axhline(0, color='k', linewidth=0.5)
axes[2].set_xlabel('Temperature Change $\\Delta T$ [K]')
axes[2].set_ylabel('Stress [MPa]')
axes[2].set_title('Bimetal: Steel + Aluminum')
axes[2].legend()
axes[2].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('thermal_stress.png', dpi=150, bbox_inches='tight')
plt.show()

まとめ

本記事では、熱応力の理論と計算方法を解説しました。

  • 熱ひずみ: $\varepsilon_T = \alpha\Delta T$(自由膨張では応力なし)
  • 完全拘束の熱応力: $\sigma = -E\alpha\Delta T$
  • 部分拘束では拘束の剛性に応じて応力が変化する
  • 異種材料の接合では線膨張係数の差が熱応力の原因となる
  • 温度変化は圧縮・引張の両方の応力を生じ得るため、設計時に注意が必要

次のステップとして、以下の記事も参考にしてください。