Chapter 1: 金属結合と結晶構造
金属の自由電子モデル、FCC/BCC/HCP結晶構造、ブラベー格子、ミラー指数
1.1 金属結合の電子論
金属の特性を理解するには、金属結合の本質を知ることが重要です。金属結合は、イオン化した金属原子(陽イオン)が、自由に動き回る電子(自由電子)によって結びついている状態です。この自由電子モデルによって、金属の電気伝導性、熱伝導性、光沢などの特性を説明できます。
1.1.1 Drudeモデル
Drudeモデルは、金属中の自由電子を古典的な気体分子として扱うモデルです。このモデルでは、電子は金属イオンの間を自由に動き回り、イオンや他の電子と衝突することで散乱されます。
電気伝導度の式:
$$\sigma = \frac{ne^2\tau}{m}$$ここで、$n$は電子密度、$e$は電子の電荷、$\tau$は緩和時間、$m$は電子の質量です。
この式から、電気伝導度は電子密度と緩和時間に比例することがわかります。金属の電気抵抗は温度上昇とともに増加しますが、これは格子振動(フォノン)による電子の散乱が増えるためです。
1.1.2 フェルミ-ディラック分布
量子力学的には、電子はフェルミ粒子であり、パウリの排他原理に従います。温度$T$におけるエネルギー$E$の状態の占有確率は、フェルミ-ディラック分布関数で表されます:
ここで、$E_F$はフェルミエネルギー、$k_B$はボルツマン定数です。
絶対零度($T = 0$ K)では、フェルミエネルギー以下のすべての状態が占有され、それより上の状態は空になります。室温でも、金属のフェルミエネルギー(数eV)は熱エネルギー$k_BT$(約0.025 eV)よりはるかに大きいため、フェルミ-ディラック分布はステップ関数に近い形をしています。
1.1.3 状態密度
金属中の電子の状態密度$D(E)$は、単位エネルギー当たりの状態数を表します。自由電子モデルでは、3次元の状態密度は次のように表されます:
ここで、$V$は体積、$h$はプランク定数、$m$は電子の質量です。
コード例1: Drudeモデルによる電気伝導度計算
import numpy as np
import matplotlib.pyplot as plt
# 物理定数
e = 1.602e-19 # 電子の電荷 (C)
m_e = 9.109e-31 # 電子の質量 (kg)
def calculate_conductivity(n, tau):
"""
Drudeモデルで電気伝導度を計算
Parameters:
-----------
n : float
電子密度 (m^-3)
tau : float
緩和時間 (s)
Returns:
--------
sigma : float
電気伝導度 (S/m)
"""
sigma = (n * e**2 * tau) / m_e
return sigma
# 代表的な金属の電子密度 (m^-3)
metals = {
'Cu': 8.45e28, # 銅
'Ag': 5.85e28, # 銀
'Al': 18.1e28, # アルミニウム
'Fe': 17.0e28, # 鉄
'Au': 5.90e28 # 金
}
# 緩和時間(典型的な値)
tau = 2.5e-14 # s
# 各金属の電気伝導度を計算
print("金属の電気伝導度 (Drudeモデル):")
print("-" * 50)
for metal, n in metals.items():
sigma = calculate_conductivity(n, tau)
resistivity = 1 / sigma
print(f"{metal:4s}: σ = {sigma:.2e} S/m, ρ = {resistivity*1e8:.2f} μΩ·cm")
# 温度依存性のシミュレーション(銅)
temperatures = np.linspace(100, 500, 100) # K
# 緩和時間は温度に反比例すると仮定
tau_T = tau * 300 / temperatures # 300Kで規格化
conductivity_T = np.array([calculate_conductivity(metals['Cu'], t) for t in tau_T])
resistivity_T = 1 / conductivity_T
# グラフ描画
plt.figure(figsize=(10, 6))
plt.plot(temperatures, resistivity_T * 1e8, 'b-', linewidth=2)
plt.xlabel('温度 (K)', fontsize=12)
plt.ylabel('電気抵抗率 (μΩ·cm)', fontsize=12)
plt.title('銅の電気抵抗率の温度依存性 (Drudeモデル)', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('cu_resistivity_vs_temperature.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n✓ グラフを 'cu_resistivity_vs_temperature.png' として保存しました")
コード例2: フェルミエネルギーと状態密度の計算
import numpy as np
import matplotlib.pyplot as plt
from scipy import constants
# 物理定数
h = constants.h # プランク定数
hbar = constants.hbar # ディラック定数
m_e = constants.m_e # 電子の質量
k_B = constants.k # ボルツマン定数
e = constants.e # 電子の電荷
def fermi_energy(n):
"""
フェルミエネルギーを計算
Parameters:
-----------
n : float
電子密度 (m^-3)
Returns:
--------
E_F : float
フェルミエネルギー (J)
"""
E_F = (hbar**2 / (2 * m_e)) * (3 * np.pi**2 * n)**(2/3)
return E_F
def fermi_dirac(E, E_F, T):
"""
フェルミ-ディラック分布関数
Parameters:
-----------
E : array-like
エネルギー (J)
E_F : float
フェルミエネルギー (J)
T : float
温度 (K)
Returns:
--------
f : array-like
占有確率
"""
if T == 0:
return np.where(E <= E_F, 1.0, 0.0)
else:
return 1 / (1 + np.exp((E - E_F) / (k_B * T)))
def density_of_states(E):
"""
自由電子の状態密度(3次元)
Parameters:
-----------
E : array-like
エネルギー (J)
Returns:
--------
D : array-like
状態密度 (J^-1 m^-3)
"""
# 単位体積あたり
D = (1 / (2 * np.pi**2)) * (2 * m_e / hbar**2)**(3/2) * np.sqrt(E)
return D
# 銅のパラメータ
n_Cu = 8.45e28 # 電子密度 (m^-3)
E_F_Cu = fermi_energy(n_Cu)
E_F_eV = E_F_Cu / e # eV単位
print(f"銅のフェルミエネルギー: {E_F_eV:.2f} eV")
print(f"フェルミ速度: {np.sqrt(2 * E_F_Cu / m_e) / 1e6:.2f} × 10^6 m/s")
# フェルミ-ディラック分布のプロット
E_range = np.linspace(0, 2 * E_F_Cu, 1000)
E_range_eV = E_range / e
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 左図: フェルミ-ディラック分布
temperatures = [0, 300, 1000, 3000]
for T in temperatures:
f = fermi_dirac(E_range, E_F_Cu, T)
label = f'{T} K' if T > 0 else '0 K'
axes[0].plot(E_range_eV, f, linewidth=2, label=label)
axes[0].axvline(E_F_eV, color='red', linestyle='--', linewidth=1.5, label=f'$E_F$ = {E_F_eV:.2f} eV')
axes[0].set_xlabel('エネルギー (eV)', fontsize=12)
axes[0].set_ylabel('占有確率 f(E)', fontsize=12)
axes[0].set_title('フェルミ-ディラック分布', fontsize=14, fontweight='bold')
axes[0].legend(fontsize=10)
axes[0].grid(True, alpha=0.3)
axes[0].set_xlim(0, 2 * E_F_eV)
axes[0].set_ylim(-0.05, 1.05)
# 右図: 状態密度
D = density_of_states(E_range[E_range > 0])
E_positive_eV = E_range_eV[E_range > 0]
axes[1].plot(E_positive_eV, D / 1e47, 'b-', linewidth=2)
axes[1].axvline(E_F_eV, color='red', linestyle='--', linewidth=1.5, label=f'$E_F$ = {E_F_eV:.2f} eV')
axes[1].set_xlabel('エネルギー (eV)', fontsize=12)
axes[1].set_ylabel('状態密度 (10^47 states/(J·m³))', fontsize=12)
axes[1].set_title('自由電子の状態密度', fontsize=14, fontweight='bold')
axes[1].legend(fontsize=10)
axes[1].grid(True, alpha=0.3)
axes[1].set_xlim(0, 2 * E_F_eV)
plt.tight_layout()
plt.savefig('fermi_dirac_and_dos.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n✓ グラフを 'fermi_dirac_and_dos.png' として保存しました")
1.2 結晶構造の基礎
金属の多くは結晶構造を持ち、原子が規則正しく配列しています。金属の機械的性質、電気的性質、熱的性質は、この結晶構造に大きく依存します。代表的な金属結晶構造として、面心立方格子(FCC)、体心立方格子(BCC)、六方最密充填構造(HCP)があります。
1.2.1 面心立方格子(FCC: Face-Centered Cubic)
FCC構造は、立方体の各頂点と各面の中心に原子が配置された構造です。代表的なFCC金属には、銅(Cu)、アルミニウム(Al)、金(Au)、銀(Ag)、ニッケル(Ni)などがあります。
- 格子定数: 立方体の一辺の長さ $a$
- 原子数: 単位格子あたり 4 個(頂点 $8 \times 1/8 = 1$、面心 $6 \times 1/2 = 3$)
- 配位数: 12(最近接原子数)
- 原子半径: $r = \frac{a}{2\sqrt{2}}$
- 充填率: $\frac{\pi}{3\sqrt{2}} \approx 0.74$ (74%)
1.2.2 体心立方格子(BCC: Body-Centered Cubic)
BCC構造は、立方体の各頂点と中心に原子が配置された構造です。代表的なBCC金属には、鉄(Fe、常温)、クロム(Cr)、タングステン(W)、モリブデン(Mo)などがあります。
- 格子定数: 立方体の一辺の長さ $a$
- 原子数: 単位格子あたり 2 個(頂点 $8 \times 1/8 = 1$、体心 $1$)
- 配位数: 8
- 原子半径: $r = \frac{\sqrt{3}a}{4}$
- 充填率: $\frac{\sqrt{3}\pi}{8} \approx 0.68$ (68%)
1.2.3 六方最密充填構造(HCP: Hexagonal Close-Packed)
HCP構造は、六方晶系の最密充填構造です。代表的なHCP金属には、マグネシウム(Mg)、チタン(Ti)、亜鉛(Zn)、コバルト(Co)などがあります。
- 格子定数: 底面の辺の長さ $a$、高さ $c$
- 原子数: 単位格子あたり 6 個
- 配位数: 12
- 理想的な軸比: $c/a = \sqrt{8/3} \approx 1.633$
- 充填率: $\frac{\pi}{3\sqrt{2}} \approx 0.74$ (74%、FCCと同じ)
コード例3: 結晶構造の3D可視化(FCC/BCC/HCP)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def create_fcc_structure(a=1.0):
"""
FCC構造の原子座標を生成
Parameters:
-----------
a : float
格子定数
Returns:
--------
positions : ndarray
原子座標 (N, 3)
"""
positions = []
# 頂点の原子(単位格子内の原子のみ)
corners = [
[0, 0, 0], [a, 0, 0], [0, a, 0], [0, 0, a],
[a, a, 0], [a, 0, a], [0, a, a], [a, a, a]
]
# 面心の原子
face_centers = [
[a/2, a/2, 0], [a/2, 0, a/2], [0, a/2, a/2],
[a/2, a/2, a], [a/2, a, a/2], [a, a/2, a/2]
]
positions.extend(corners)
positions.extend(face_centers)
return np.array(positions)
def create_bcc_structure(a=1.0):
"""
BCC構造の原子座標を生成
Parameters:
-----------
a : float
格子定数
Returns:
--------
positions : ndarray
原子座標 (N, 3)
"""
positions = []
# 頂点の原子
corners = [
[0, 0, 0], [a, 0, 0], [0, a, 0], [0, 0, a],
[a, a, 0], [a, 0, a], [0, a, a], [a, a, a]
]
# 体心の原子
body_center = [[a/2, a/2, a/2]]
positions.extend(corners)
positions.extend(body_center)
return np.array(positions)
def create_hcp_structure(a=1.0, c_over_a=1.633):
"""
HCP構造の原子座標を生成(簡易版)
Parameters:
-----------
a : float
格子定数(底面)
c_over_a : float
軸比 c/a
Returns:
--------
positions : ndarray
原子座標 (N, 3)
"""
c = a * c_over_a
positions = []
# 底面の原子(A層)
positions.append([0, 0, 0])
positions.append([a, 0, 0])
positions.append([a/2, a*np.sqrt(3)/2, 0])
# 中間層の原子(B層)
positions.append([a/2, a*np.sqrt(3)/6, c/2])
# 上面の原子(A層)
positions.append([0, 0, c])
positions.append([a, 0, c])
positions.append([a/2, a*np.sqrt(3)/2, c])
return np.array(positions)
def plot_crystal_structure(positions, title, ax, color='blue', atom_size=300):
"""
結晶構造を3Dプロット
"""
ax.scatter(positions[:, 0], positions[:, 1], positions[:, 2],
c=color, s=atom_size, alpha=0.7, edgecolors='black', linewidth=1.5)
ax.set_xlabel('X', fontsize=10, fontweight='bold')
ax.set_ylabel('Y', fontsize=10, fontweight='bold')
ax.set_zlabel('Z', fontsize=10, fontweight='bold')
ax.set_title(title, fontsize=12, fontweight='bold', pad=10)
# 軸の範囲を設定
max_coord = np.max(positions)
ax.set_xlim([-0.2, max_coord + 0.2])
ax.set_ylim([-0.2, max_coord + 0.2])
ax.set_zlim([-0.2, max_coord + 0.2])
ax.set_box_aspect([1, 1, 1])
# 3つの結晶構造を生成
a = 1.0
fcc_pos = create_fcc_structure(a)
bcc_pos = create_bcc_structure(a)
hcp_pos = create_hcp_structure(a)
# プロット
fig = plt.figure(figsize=(16, 5))
ax1 = fig.add_subplot(131, projection='3d')
plot_crystal_structure(fcc_pos, 'FCC構造\n(Cu, Al, Au, Ag)', ax1, color='#FF6B6B')
ax2 = fig.add_subplot(132, projection='3d')
plot_crystal_structure(bcc_pos, 'BCC構造\n(Fe, Cr, W, Mo)', ax2, color='#4ECDC4')
ax3 = fig.add_subplot(133, projection='3d')
plot_crystal_structure(hcp_pos, 'HCP構造\n(Mg, Ti, Zn, Co)', ax3, color='#95E1D3')
plt.tight_layout()
plt.savefig('crystal_structures_3d.png', dpi=300, bbox_inches='tight')
plt.show()
# 充填率と配位数の計算
print("結晶構造の比較:")
print("=" * 60)
print(f"{'構造':<8} {'充填率':<15} {'配位数':<10} {'代表的な金属'}")
print("-" * 60)
print(f"{'FCC':<8} {np.pi/(3*np.sqrt(2)):.4f} (74%) {12:<10} Cu, Al, Au, Ag, Ni")
print(f"{'BCC':<8} {np.sqrt(3)*np.pi/8:.4f} (68%) {8:<10} Fe, Cr, W, Mo")
print(f"{'HCP':<8} {np.pi/(3*np.sqrt(2)):.4f} (74%) {12:<10} Mg, Ti, Zn, Co")
print("=" * 60)
print("\n✓ グラフを 'crystal_structures_3d.png' として保存しました")
コード例4: 充填率と配位数の詳細計算
import numpy as np
import matplotlib.pyplot as plt
def calculate_fcc_properties(a):
"""FCC構造の物性を計算"""
# 原子半径
r = a / (2 * np.sqrt(2))
# 原子数(単位格子あたり)
n_atoms = 4
# 単位格子の体積
V_cell = a**3
# 原子の体積
V_atom = (4/3) * np.pi * r**3
# 充填率
packing_fraction = (n_atoms * V_atom) / V_cell
# 配位数
coordination_number = 12
# 最近接原子間距離
nearest_neighbor = 2 * r
return {
'structure': 'FCC',
'lattice_constant': a,
'atomic_radius': r,
'atoms_per_cell': n_atoms,
'packing_fraction': packing_fraction,
'coordination_number': coordination_number,
'nearest_neighbor': nearest_neighbor
}
def calculate_bcc_properties(a):
"""BCC構造の物性を計算"""
# 原子半径
r = (np.sqrt(3) * a) / 4
# 原子数
n_atoms = 2
# 単位格子の体積
V_cell = a**3
# 原子の体積
V_atom = (4/3) * np.pi * r**3
# 充填率
packing_fraction = (n_atoms * V_atom) / V_cell
# 配位数
coordination_number = 8
# 最近接原子間距離
nearest_neighbor = 2 * r
return {
'structure': 'BCC',
'lattice_constant': a,
'atomic_radius': r,
'atoms_per_cell': n_atoms,
'packing_fraction': packing_fraction,
'coordination_number': coordination_number,
'nearest_neighbor': nearest_neighbor
}
def calculate_hcp_properties(a, c_over_a=1.633):
"""HCP構造の物性を計算"""
c = a * c_over_a
# 原子半径(最近接原子間距離の半分)
r = a / 2
# 原子数
n_atoms = 6
# 単位格子の体積(六角柱)
V_cell = (3 * np.sqrt(3) / 2) * a**2 * c
# 原子の体積
V_atom = (4/3) * np.pi * r**3
# 充填率
packing_fraction = (n_atoms * V_atom) / V_cell
# 配位数
coordination_number = 12
# 最近接原子間距離
nearest_neighbor = 2 * r
return {
'structure': 'HCP',
'lattice_constant_a': a,
'lattice_constant_c': c,
'c_over_a': c_over_a,
'atomic_radius': r,
'atoms_per_cell': n_atoms,
'packing_fraction': packing_fraction,
'coordination_number': coordination_number,
'nearest_neighbor': nearest_neighbor
}
# 格子定数(任意の単位)
a = 1.0
# 各構造の物性を計算
fcc_props = calculate_fcc_properties(a)
bcc_props = calculate_bcc_properties(a)
hcp_props = calculate_hcp_properties(a)
# 結果を表示
print("\n結晶構造の詳細物性比較")
print("=" * 80)
for props in [fcc_props, bcc_props, hcp_props]:
print(f"\n【{props['structure']}構造】")
print("-" * 80)
if props['structure'] == 'HCP':
print(f" 格子定数 a: {props['lattice_constant_a']:.4f}")
print(f" 格子定数 c: {props['lattice_constant_c']:.4f}")
print(f" 軸比 c/a: {props['c_over_a']:.4f}")
else:
print(f" 格子定数: {props['lattice_constant']:.4f}")
print(f" 原子半径: {props['atomic_radius']:.4f}")
print(f" 単位格子あたり原子数: {props['atoms_per_cell']}")
print(f" 充填率: {props['packing_fraction']:.4f} ({props['packing_fraction']*100:.1f}%)")
print(f" 配位数: {props['coordination_number']}")
print(f" 最近接原子間距離: {props['nearest_neighbor']:.4f}")
# 視覚化
structures = ['FCC', 'BCC', 'HCP']
packing_fractions = [fcc_props['packing_fraction'],
bcc_props['packing_fraction'],
hcp_props['packing_fraction']]
coordination_numbers = [fcc_props['coordination_number'],
bcc_props['coordination_number'],
hcp_props['coordination_number']]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
# 充填率の比較
colors = ['#FF6B6B', '#4ECDC4', '#95E1D3']
bars1 = ax1.bar(structures, [pf * 100 for pf in packing_fractions], color=colors, alpha=0.8, edgecolor='black', linewidth=2)
ax1.set_ylabel('充填率 (%)', fontsize=12, fontweight='bold')
ax1.set_title('結晶構造の充填率比較', fontsize=14, fontweight='bold')
ax1.set_ylim(0, 80)
ax1.grid(axis='y', alpha=0.3)
# バーに数値を表示
for bar in bars1:
height = bar.get_height()
ax1.text(bar.get_x() + bar.get_width()/2., height + 1,
f'{height:.1f}%', ha='center', va='bottom', fontsize=11, fontweight='bold')
# 配位数の比較
bars2 = ax2.bar(structures, coordination_numbers, color=colors, alpha=0.8, edgecolor='black', linewidth=2)
ax2.set_ylabel('配位数', fontsize=12, fontweight='bold')
ax2.set_title('結晶構造の配位数比較', fontsize=14, fontweight='bold')
ax2.set_ylim(0, 14)
ax2.grid(axis='y', alpha=0.3)
# バーに数値を表示
for bar in bars2:
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width()/2., height + 0.3,
f'{int(height)}', ha='center', va='bottom', fontsize=11, fontweight='bold')
plt.tight_layout()
plt.savefig('crystal_properties_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n" + "=" * 80)
print("✓ グラフを 'crystal_properties_comparison.png' として保存しました")
1.3 ミラー指数
結晶中の面や方位を表記するために、ミラー指数が用いられます。ミラー指数は、結晶構造の対称性を理解し、X線回折データを解析する上で不可欠です。
1.3.1 結晶面の表記 (hkl)
結晶面は、3つの整数 $(h, k, l)$ で表されます。これらは、その面が結晶軸 $a, b, c$ を切る点の逆数の比を最小の整数で表したものです。
ミラー指数の求め方:
- 面が各結晶軸を切る点の座標を求める(例:$x=2, y=3, z=6$)
- その逆数を取る(例:$1/2, 1/3, 1/6$)
- 最小公倍数を掛けて整数にする(例:$\times 6$ で $3, 2, 1$)
- $(hkl) = (321)$ と表記
代表的な面:
- $(100)$: $a$ 軸に垂直な面
- $(110)$: $a$ 軸と $b$ 軸の両方に斜めの面
- $(111)$: 3つの軸すべてに等しく傾いた面(FCC の最密充填面)
1.3.2 結晶方位の表記 [uvw]
結晶方位(方向)は、角括弧 $[uvw]$ で表されます。これは、原点から $(u, v, w)$ の点へ向かうベクトルの方向を示します。
1.3.3 面間隔の計算
立方晶系において、$(hkl)$ 面の面間隔 $d_{hkl}$ は次の式で計算されます:
ここで、$a$ は格子定数です。
コード例5: ミラー指数と面間隔の計算
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
def calculate_d_spacing(a, h, k, l, crystal_system='cubic'):
"""
面間隔を計算
Parameters:
-----------
a : float
格子定数
h, k, l : int
ミラー指数
crystal_system : str
結晶系('cubic', 'tetragonal', 'hexagonal'など)
Returns:
--------
d : float
面間隔
"""
if crystal_system == 'cubic':
d = a / np.sqrt(h**2 + k**2 + l**2)
else:
raise NotImplementedError(f"{crystal_system}系は未実装です")
return d
def plot_plane(h, k, l, a=1.0, ax=None):
"""
(hkl)面を可視化
Parameters:
-----------
h, k, l : int
ミラー指数
a : float
格子定数
ax : matplotlib axis
プロット用の軸
"""
if ax is None:
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
# 面が軸を切る点を計算
# h, k, l がゼロの場合は無限遠(実際には大きな値)
intercepts = []
for index in [h, k, l]:
if index != 0:
intercepts.append(a / index)
else:
intercepts.append(10 * a) # 大きな値
# 面を描画(三角形として近似)
points = [
[intercepts[0], 0, 0],
[0, intercepts[1], 0],
[0, 0, intercepts[2]]
]
# 面の多角形
poly = [[points[0], points[1], points[2]]]
ax.add_collection3d(Poly3DCollection(poly, alpha=0.5, facecolor='cyan', edgecolor='blue', linewidth=2))
# 座標軸を描画
ax.plot([0, a], [0, 0], [0, 0], 'r-', linewidth=2, label='a軸')
ax.plot([0, 0], [0, a], [0, 0], 'g-', linewidth=2, label='b軸')
ax.plot([0, 0], [0, 0], [0, a], 'b-', linewidth=2, label='c軸')
# 切片にマーカー
if h != 0:
ax.scatter([intercepts[0]], [0], [0], c='red', s=100, marker='o')
if k != 0:
ax.scatter([0], [intercepts[1]], [0], c='green', s=100, marker='o')
if l != 0:
ax.scatter([0], [0], [intercepts[2]], c='blue', s=100, marker='o')
ax.set_xlabel('X (a軸)', fontsize=11, fontweight='bold')
ax.set_ylabel('Y (b軸)', fontsize=11, fontweight='bold')
ax.set_zlabel('Z (c軸)', fontsize=11, fontweight='bold')
ax.set_title(f'({h}{k}{l}) 面', fontsize=13, fontweight='bold')
max_val = max(intercepts) * 0.6
ax.set_xlim([0, max_val])
ax.set_ylim([0, max_val])
ax.set_zlim([0, max_val])
ax.legend(fontsize=9)
return ax
# 代表的な面の可視化
fig = plt.figure(figsize=(16, 5))
planes = [(1, 0, 0), (1, 1, 0), (1, 1, 1)]
a = 1.0
for i, (h, k, l) in enumerate(planes):
ax = fig.add_subplot(1, 3, i+1, projection='3d')
plot_plane(h, k, l, a, ax)
# 面間隔を計算して表示
d = calculate_d_spacing(a, h, k, l)
ax.text2D(0.05, 0.95, f'd = {d:.3f}a', transform=ax.transAxes, fontsize=11,
verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8))
plt.tight_layout()
plt.savefig('miller_indices_planes.png', dpi=300, bbox_inches='tight')
plt.show()
# 主要な面の面間隔を計算
print("\n立方晶系における主要な面の面間隔")
print("=" * 60)
print(f"{'面':<10} {'面間隔 (単位: a)':<20} {'相対強度'}")
print("-" * 60)
important_planes = [
(1, 0, 0), (1, 1, 0), (1, 1, 1),
(2, 0, 0), (2, 1, 0), (2, 1, 1),
(2, 2, 0), (3, 1, 0), (2, 2, 2)
]
for h, k, l in important_planes:
d = calculate_d_spacing(a, h, k, l)
# 構造因子による相対強度(簡易版、FCC を仮定)
if (h % 2 == 0 and k % 2 == 0 and l % 2 == 0) or \
(h % 2 == 1 and k % 2 == 1 and l % 2 == 1):
intensity = "強"
else:
intensity = "消滅 (FCC)"
print(f"({h}{k}{l}){'':<7} {d:.4f} a{'':<15} {intensity}")
print("=" * 60)
print("\n注:FCC構造では、すべて偶数またはすべて奇数の(hkl)面のみが回折を示します")
print("✓ グラフを 'miller_indices_planes.png' として保存しました")
1.4 Python実践:ASE/pymatgenによる結晶構造の生成と解析
実際の材料科学研究では、pymatgen や ASE(Atomic Simulation Environment)といったPythonライブラリを用いて結晶構造を生成・操作します。これらのツールは、密度汎関数理論(DFT)計算との連携や、Materials Project データベースへのアクセスも可能です。
コード例6: ASEによる結晶構造生成と可視化
"""
ASE (Atomic Simulation Environment) を使用した結晶構造の生成と解析
注: ASEのインストールが必要です: pip install ase
"""
try:
from ase import Atoms
from ase.build import bulk
from ase.visualize import view
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
# 各種金属の結晶構造を生成
structures = {}
# 銅(FCC)
cu = bulk('Cu', 'fcc', a=3.615) # a = 3.615 Å
structures['Cu (FCC)'] = cu
# 鉄(BCC)
fe = bulk('Fe', 'bcc', a=2.866) # a = 2.866 Å
structures['Fe (BCC)'] = fe
# マグネシウム(HCP)
mg = bulk('Mg', 'hcp', a=3.209, c=5.211) # a = 3.209 Å, c = 5.211 Å
structures['Mg (HCP)'] = mg
# アルミニウム(FCC)
al = bulk('Al', 'fcc', a=4.046) # a = 4.046 Å
structures['Al (FCC)'] = al
# 各構造の情報を表示
print("ASEによる金属結晶構造の生成")
print("=" * 80)
for name, atoms in structures.items():
print(f"\n【{name}】")
print("-" * 80)
print(f" 化学式: {atoms.get_chemical_formula()}")
print(f" 原子数: {len(atoms)}")
print(f" 格子定数 (Å): a = {atoms.cell.cellpar()[0]:.3f}, "
f"b = {atoms.cell.cellpar()[1]:.3f}, c = {atoms.cell.cellpar()[2]:.3f}")
print(f" セル角度 (deg): α = {atoms.cell.cellpar()[3]:.1f}, "
f"β = {atoms.cell.cellpar()[4]:.1f}, γ = {atoms.cell.cellpar()[5]:.1f}")
print(f" 体積 (Ų): {atoms.get_volume():.3f}")
print(f" 密度 (g/cm³): 計算値 = {atoms.get_masses().sum() / atoms.get_volume() * 1.66054:.3f}")
# スーパーセルの作成(Cu の 2x2x2)
cu_supercell = cu.repeat((2, 2, 2))
print(f"\n\n【Cu スーパーセル (2×2×2)】")
print("-" * 80)
print(f" 原子数: {len(cu_supercell)}")
print(f" 体積 (Ų): {cu_supercell.get_volume():.3f}")
# 3D可視化用の関数
def plot_ase_structure(atoms, title, ax):
"""ASE Atomsオブジェクトを3Dプロット"""
positions = atoms.get_positions()
ax.scatter(positions[:, 0], positions[:, 1], positions[:, 2],
c='#FF6B6B', s=300, alpha=0.7, edgecolors='black', linewidth=1.5)
# セルの境界を描画
cell = atoms.cell
# セルの頂点
origin = np.array([0, 0, 0])
vertices = [
origin,
cell[0],
cell[1],
cell[2],
cell[0] + cell[1],
cell[0] + cell[2],
cell[1] + cell[2],
cell[0] + cell[1] + cell[2]
]
# セルのエッジ
edges = [
(0, 1), (0, 2), (0, 3),
(1, 4), (1, 5), (2, 4),
(2, 6), (3, 5), (3, 6),
(4, 7), (5, 7), (6, 7)
]
for i, j in edges:
edge = np.array([vertices[i], vertices[j]])
ax.plot3D(edge[:, 0], edge[:, 1], edge[:, 2], 'k-', linewidth=1, alpha=0.6)
ax.set_xlabel('X (Å)', fontsize=10, fontweight='bold')
ax.set_ylabel('Y (Å)', fontsize=10, fontweight='bold')
ax.set_zlabel('Z (Å)', fontsize=10, fontweight='bold')
ax.set_title(title, fontsize=12, fontweight='bold', pad=10)
ax.set_box_aspect([1, 1, 1])
# プロット
fig = plt.figure(figsize=(16, 5))
plot_structures = [(cu, 'Cu (FCC)'), (fe, 'Fe (BCC)'), (mg, 'Mg (HCP)')]
for i, (atoms, name) in enumerate(plot_structures):
ax = fig.add_subplot(1, 3, i+1, projection='3d')
plot_ase_structure(atoms, name, ax)
plt.tight_layout()
plt.savefig('ase_crystal_structures.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n" + "=" * 80)
print("✓ グラフを 'ase_crystal_structures.png' として保存しました")
print("\n※ ASEでは atoms.edit() または from ase.visualize import view; view(atoms) で")
print(" インタラクティブな3D可視化が可能です(GUI環境が必要)")
except ImportError:
print("エラー: ASEがインストールされていません")
print("インストール方法: pip install ase")
print("\n代替として、以下のように手動で結晶構造を定義できます:")
print("""
import numpy as np
# FCC構造の手動定義
a = 3.615 # 銅の格子定数 (Å)
fcc_positions = np.array([
[0.0, 0.0, 0.0],
[0.5*a, 0.5*a, 0.0],
[0.5*a, 0.0, 0.5*a],
[0.0, 0.5*a, 0.5*a]
])
print("FCC原子座標 (Å):")
print(fcc_positions)
""")
コード例7: pymatgenによる結晶構造の高度な解析
"""
pymatgen を使用した結晶構造の高度な解析
注: pymatgenのインストールが必要です: pip install pymatgen
"""
try:
from pymatgen.core import Structure, Lattice
from pymatgen.analysis.structure_analyzer import SpacegroupAnalyzer
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer as SGA
import numpy as np
# 銅(FCC)の構造を生成
lattice_cu = Lattice.cubic(3.615) # a = 3.615 Å
species_cu = ['Cu'] * 4
coords_cu = [
[0.0, 0.0, 0.0],
[0.5, 0.5, 0.0],
[0.5, 0.0, 0.5],
[0.0, 0.5, 0.5]
]
cu_structure = Structure(lattice_cu, species_cu, coords_cu)
# 鉄(BCC)の構造を生成
lattice_fe = Lattice.cubic(2.866) # a = 2.866 Å
species_fe = ['Fe'] * 2
coords_fe = [
[0.0, 0.0, 0.0],
[0.5, 0.5, 0.5]
]
fe_structure = Structure(lattice_fe, species_fe, coords_fe)
# マグネシウム(HCP)の構造を生成
a_mg = 3.209
c_mg = 5.211
lattice_mg = Lattice.hexagonal(a_mg, c_mg)
species_mg = ['Mg'] * 2
coords_mg = [
[1/3, 2/3, 1/4],
[2/3, 1/3, 3/4]
]
mg_structure = Structure(lattice_mg, species_mg, coords_mg)
structures = {
'Cu (FCC)': cu_structure,
'Fe (BCC)': fe_structure,
'Mg (HCP)': mg_structure
}
print("pymatgenによる結晶構造の詳細解析")
print("=" * 80)
for name, structure in structures.items():
print(f"\n【{name}】")
print("-" * 80)
# 基本情報
print(f" 化学式: {structure.composition.reduced_formula}")
print(f" 空間群: ", end="")
try:
sga = SpacegroupAnalyzer(structure)
spacegroup = sga.get_space_group_symbol()
spacegroup_number = sga.get_space_group_number()
print(f"{spacegroup} (No. {spacegroup_number})")
# 対称操作の数
print(f" 対称操作の数: {len(sga.get_symmetry_operations())}")
# 点群
print(f" 点群: {sga.get_point_group_symbol()}")
except Exception as e:
print(f"解析エラー: {e}")
# 格子情報
abc = structure.lattice.abc
angles = structure.lattice.angles
print(f" 格子定数 (Å): a = {abc[0]:.3f}, b = {abc[1]:.3f}, c = {abc[2]:.3f}")
print(f" 格子角度 (deg): α = {angles[0]:.1f}, β = {angles[1]:.1f}, γ = {angles[2]:.1f}")
print(f" 体積 (Ų): {structure.volume:.3f}")
print(f" 密度 (g/cm³): {structure.density:.3f}")
# 最近接原子間距離
print(f"\n 最近接原子間距離:")
all_nn_distances = []
for i, site in enumerate(structure):
neighbors = structure.get_neighbors(site, 4.0) # 4 Å以内
if neighbors:
nn_dist = min([neighbor[1] for neighbor in neighbors])
all_nn_distances.append(nn_dist)
if all_nn_distances:
avg_nn = np.mean(all_nn_distances)
print(f" 平均: {avg_nn:.3f} Å")
print(f" 範囲: {min(all_nn_distances):.3f} - {max(all_nn_distances):.3f} Å")
# 構造の比較
print("\n\n【構造比較】")
print("=" * 80)
print(f"{'構造':<15} {'空間群':<15} {'密度 (g/cm³)':<15} {'最近接距離 (Å)'}")
print("-" * 80)
for name, structure in structures.items():
try:
sga = SpacegroupAnalyzer(structure)
sg = sga.get_space_group_symbol()
except:
sg = "N/A"
neighbors = structure.get_neighbors(structure[0], 4.0)
if neighbors:
nn_dist = min([neighbor[1] for neighbor in neighbors])
else:
nn_dist = 0.0
print(f"{name:<15} {sg:<15} {structure.density:<15.3f} {nn_dist:.3f}")
print("=" * 80)
print("\n✓ pymatgenによる解析が完了しました")
# CIF形式で保存
print("\n構造をCIF形式で保存:")
for name, structure in structures.items():
filename = name.replace(' ', '_').replace('(', '').replace(')', '') + '.cif'
structure.to(filename=filename, fmt='cif')
print(f" ✓ {filename}")
except ImportError:
print("エラー: pymatgenがインストールされていません")
print("インストール方法: pip install pymatgen")
print("\npymatgenは材料科学研究で広く使われているライブラリで、以下の機能があります:")
print(" - 結晶構造の生成・操作・解析")
print(" - 空間群・点群の自動判定")
print(" - Materials Projectデータベースへのアクセス")
print(" - 密度汎関数理論(DFT)計算との連携")
print(" - 相図・状態図の計算")
演習問題
演習 1.1
Easy問題:銅(Cu)の電子密度は $n = 8.45 \times 10^{28}$ m⁻³、緩和時間は $\tau = 2.5 \times 10^{-14}$ s です。Drudeモデルを用いて銅の電気伝導度 $\sigma$ と電気抵抗率 $\rho$ を計算してください。
解答を表示
import numpy as np
# 物理定数
e = 1.602e-19 # 電子の電荷 (C)
m_e = 9.109e-31 # 電子の質量 (kg)
# 銅のパラメータ
n = 8.45e28 # 電子密度 (m^-3)
tau = 2.5e-14 # 緩和時間 (s)
# 電気伝導度の計算
sigma = (n * e**2 * tau) / m_e
# 電気抵抗率の計算
rho = 1 / sigma
print("=" * 60)
print("銅の電気伝導度と電気抵抗率(Drudeモデル)")
print("=" * 60)
print(f"\n与えられた値:")
print(f" 電子密度 n: {n:.2e} m^-3")
print(f" 緩和時間 τ: {tau:.2e} s")
print(f"\n計算結果:")
print(f" 電気伝導度 σ: {sigma:.3e} S/m")
print(f" 電気抵抗率 ρ: {rho:.3e} Ω·m")
print(f" {rho * 1e8:.2f} μΩ·cm")
print(f"\n参考: 実測値は約 1.68 μΩ·cm(室温)")
print("=" * 60)
# 説明
print("\n【計算の説明】")
print("-" * 60)
print("Drudeモデルの電気伝導度の式:")
print(" σ = (n × e² × τ) / m")
print("\nここで、")
print(" n : 電子密度")
print(" e : 電子の電荷 (1.602 × 10⁻¹⁹ C)")
print(" τ : 緩和時間(電子が散乱されるまでの平均時間)")
print(" m : 電子の質量 (9.109 × 10⁻³¹ kg)")
print("\n電気抵抗率は電気伝導度の逆数:")
print(" ρ = 1 / σ")
print("-" * 60)
# 検証
print("\n【結果の検証】")
print("-" * 60)
theoretical = rho * 1e8
experimental = 1.68
error = abs(theoretical - experimental) / experimental * 100
print(f"理論値(Drudeモデル): {theoretical:.2f} μΩ·cm")
print(f"実測値(室温): {experimental:.2f} μΩ·cm")
print(f"誤差: {error:.1f}%")
print("\nDrudeモデルは古典的な近似ですが、")
print("オーダーは合っており、金属の電気伝導性を")
print("定性的に説明できることがわかります。")
print("=" * 60)
演習 1.2
Easy問題:FCC構造において、格子定数 $a = 4.05$ Åのとき、以下を計算してください:
- 原子半径 $r$
- 充填率
- 単位格子あたりの原子数
解答を表示
import numpy as np
# 格子定数
a = 4.05 # Å
print("=" * 70)
print("FCC構造の計算問題")
print("=" * 70)
print(f"\n与えられた値:")
print(f" 格子定数 a = {a} Å")
# (1) 原子半径の計算
# FCC では、面対角線上に原子が接触している
# 面対角線の長さ = 4r = a√2
r = a / (2 * np.sqrt(2))
print(f"\n(1) 原子半径の計算:")
print(f" FCC構造では、面対角線上に原子が接触しています。")
print(f" 面対角線の長さ = 4r = a√2")
print(f" したがって、r = a / (2√2)")
print(f" ")
print(f" 計算: r = {a} / (2√2)")
print(f" = {a} / {2 * np.sqrt(2):.4f}")
print(f" = {r:.4f} Å")
# (2) 充填率の計算
# 単位格子あたりの原子数
n_atoms = 4
# 単位格子の体積
V_cell = a**3
# 原子の体積(球として)
V_atom = (4/3) * np.pi * r**3
# 充填率
packing_fraction = (n_atoms * V_atom) / V_cell
print(f"\n(2) 充填率の計算:")
print(f" 単位格子あたりの原子数: n = {n_atoms}")
print(f" 単位格子の体積: V_cell = a³ = {a}³ = {V_cell:.3f} ų")
print(f" 原子1個の体積: V_atom = (4/3)πr³ = {V_atom:.3f} ų")
print(f" ")
print(f" 充填率 = (n × V_atom) / V_cell")
print(f" = ({n_atoms} × {V_atom:.3f}) / {V_cell:.3f}")
print(f" = {packing_fraction:.4f}")
print(f" = {packing_fraction * 100:.2f}%")
# 理論値との比較
theoretical_packing = np.pi / (3 * np.sqrt(2))
print(f" ")
print(f" 理論値: π / (3√2) = {theoretical_packing:.4f} = {theoretical_packing * 100:.2f}%")
# (3) 単位格子あたりの原子数
print(f"\n(3) 単位格子あたりの原子数:")
print(f" 頂点の原子: 8個の頂点 × 1/8 = 1個")
print(f" 面心の原子: 6個の面 × 1/2 = 3個")
print(f" 合計: 1 + 3 = {n_atoms}個")
# まとめ
print("\n" + "=" * 70)
print("【解答まとめ】")
print("=" * 70)
print(f"(1) 原子半径 r: {r:.4f} Å = {r * 100:.2f} pm")
print(f"(2) 充填率: {packing_fraction:.4f} = {packing_fraction * 100:.2f}%")
print(f"(3) 単位格子あたりの原子数: {n_atoms}個")
print("=" * 70)
# 補足情報
print("\n【補足】")
print("-" * 70)
print("FCC構造の特徴:")
print(" - 最密充填構造の一つ(充填率 74%)")
print(" - 配位数: 12")
print(" - すべり系が多く、延性が高い")
print(" - 代表的な金属: Cu, Al, Au, Ag, Ni, Pb")
print("-" * 70)
演習 1.3
Medium問題:立方晶系の結晶において、格子定数 $a = 3.5$ Å のとき、以下の面の面間隔を計算してください:$(100)$, $(110)$, $(111)$, $(200)$, $(220)$
解答を表示
import numpy as np
import matplotlib.pyplot as plt
def calculate_d_spacing(a, h, k, l):
"""
立方晶系の面間隔を計算
Parameters:
-----------
a : float
格子定数 (Å)
h, k, l : int
ミラー指数
Returns:
--------
d : float
面間隔 (Å)
"""
d = a / np.sqrt(h**2 + k**2 + l**2)
return d
# 格子定数
a = 3.5 # Å
# 計算する面
planes = [
(1, 0, 0),
(1, 1, 0),
(1, 1, 1),
(2, 0, 0),
(2, 2, 0)
]
print("=" * 80)
print("立方晶系における面間隔の計算")
print("=" * 80)
print(f"\n与えられた値:")
print(f" 格子定数 a = {a} Å")
print(f"\n立方晶系の面間隔の公式:")
print(f" d_hkl = a / √(h² + k² + l²)")
print(f"\n計算結果:")
print("=" * 80)
print(f"{'(hkl)':<8} {'h²+k²+l²':<12} {'√(h²+k²+l²)':<18} {'d_hkl (Å)':<15}")
print("-" * 80)
d_values = []
plane_labels = []
for h, k, l in planes:
sum_squares = h**2 + k**2 + l**2
sqrt_sum = np.sqrt(sum_squares)
d = calculate_d_spacing(a, h, k, l)
d_values.append(d)
plane_labels.append(f"({h}{k}{l})")
print(f"({h}{k}{l}){'':<5} {sum_squares:<12} {sqrt_sum:<18.4f} {d:.4f}")
print("=" * 80)
# 面間隔の可視化
fig, ax = plt.subplots(figsize=(12, 7))
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8']
bars = ax.bar(plane_labels, d_values, color=colors, alpha=0.8, edgecolor='black', linewidth=2)
ax.set_ylabel('面間隔 d (Å)', fontsize=13, fontweight='bold')
ax.set_xlabel('ミラー指数 (hkl)', fontsize=13, fontweight='bold')
ax.set_title(f'立方晶系の面間隔(a = {a} Å)', fontsize=15, fontweight='bold', pad=15)
ax.grid(axis='y', alpha=0.3, linestyle='--')
# バーに数値を表示
for bar, d in zip(bars, d_values):
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height + 0.05,
f'{d:.3f} Å', ha='center', va='bottom', fontsize=11, fontweight='bold')
plt.tight_layout()
plt.savefig('d_spacing_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n✓ グラフを 'd_spacing_comparison.png' として保存しました")
# X線回折への応用
print("\n【X線回折への応用】")
print("=" * 80)
print("Braggの法則: 2d sinθ = nλ")
print(f"\nCu Kα線(λ = 1.5418 Å)を使った場合の回折角 2θ:")
print("-" * 80)
lambda_cu = 1.5418 # Å
for (h, k, l), d in zip(planes, d_values):
if d > lambda_cu / 2: # Bragg条件を満たす場合のみ
sin_theta = lambda_cu / (2 * d)
theta = np.arcsin(sin_theta) * 180 / np.pi
two_theta = 2 * theta
print(f"({h}{k}{l}): d = {d:.4f} Å → 2θ = {two_theta:.2f}°")
else:
print(f"({h}{k}{l}): d = {d:.4f} Å → 回折なし(λ/2 より小さい)")
print("=" * 80)
# 面間隔の順序
print("\n【面間隔の順序】")
print("-" * 80)
sorted_indices = np.argsort(d_values)[::-1] # 降順
print("面間隔の大きい順:")
for i, idx in enumerate(sorted_indices):
h, k, l = planes[idx]
print(f" {i+1}. ({h}{k}{l}): {d_values[idx]:.4f} Å")
print("-" * 80)
演習 1.4
Medium問題:銅(Cu)のフェルミエネルギーは 7.05 eV です。以下を計算してください:
- 絶対零度(0 K)と室温(300 K)におけるフェルミ-ディラック分布を計算し、グラフで比較してください
- フェルミ速度(フェルミエネルギーに対応する電子の速度)を計算してください
解答を表示
import numpy as np
import matplotlib.pyplot as plt
from scipy import constants
# 物理定数
k_B = constants.k # ボルツマン定数 (J/K)
e = constants.e # 電子の電荷 (C)
m_e = constants.m_e # 電子の質量 (kg)
# 銅のフェルミエネルギー
E_F_eV = 7.05 # eV
E_F = E_F_eV * e # J に変換
print("=" * 80)
print("銅のフェルミ-ディラック分布とフェルミ速度の計算")
print("=" * 80)
print(f"\n与えられた値:")
print(f" フェルミエネルギー E_F = {E_F_eV} eV = {E_F:.3e} J")
# (1) フェルミ-ディラック分布の計算
def fermi_dirac(E, E_F, T):
"""
フェルミ-ディラック分布関数
Parameters:
-----------
E : array-like
エネルギー (J)
E_F : float
フェルミエネルギー (J)
T : float
温度 (K)
Returns:
--------
f : array-like
占有確率
"""
if T == 0:
return np.where(E <= E_F, 1.0, 0.0)
else:
# オーバーフロー対策
x = (E - E_F) / (k_B * T)
x = np.clip(x, -100, 100)
return 1 / (1 + np.exp(x))
# エネルギー範囲(eV単位で設定)
E_range_eV = np.linspace(0, 15, 1000)
E_range = E_range_eV * e # J に変換
# 0 K と 300 K での分布
f_0K = fermi_dirac(E_range, E_F, 0)
f_300K = fermi_dirac(E_range, E_F, 300)
# プロット
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# 左図: 分布関数の比較
ax1.plot(E_range_eV, f_0K, 'b-', linewidth=2.5, label='T = 0 K')
ax1.plot(E_range_eV, f_300K, 'r-', linewidth=2.5, label='T = 300 K')
ax1.axvline(E_F_eV, color='green', linestyle='--', linewidth=2, label=f'$E_F$ = {E_F_eV} eV')
ax1.fill_between(E_range_eV, 0, f_300K, alpha=0.2, color='red')
ax1.set_xlabel('エネルギー (eV)', fontsize=12, fontweight='bold')
ax1.set_ylabel('占有確率 f(E)', fontsize=12, fontweight='bold')
ax1.set_title('フェルミ-ディラック分布の温度依存性', fontsize=13, fontweight='bold')
ax1.legend(fontsize=11)
ax1.grid(True, alpha=0.3)
ax1.set_xlim(0, 15)
ax1.set_ylim(-0.05, 1.05)
# 右図: フェルミエネルギー付近の拡大図
E_zoom_eV = np.linspace(E_F_eV - 1, E_F_eV + 1, 500)
E_zoom = E_zoom_eV * e
f_zoom_0K = fermi_dirac(E_zoom, E_F, 0)
f_zoom_300K = fermi_dirac(E_zoom, E_F, 300)
ax2.plot(E_zoom_eV, f_zoom_0K, 'b-', linewidth=2.5, label='T = 0 K')
ax2.plot(E_zoom_eV, f_zoom_300K, 'r-', linewidth=2.5, label='T = 300 K')
ax2.axvline(E_F_eV, color='green', linestyle='--', linewidth=2, label=f'$E_F$ = {E_F_eV} eV')
ax2.axhline(0.5, color='gray', linestyle=':', linewidth=1.5, alpha=0.7)
ax2.set_xlabel('エネルギー (eV)', fontsize=12, fontweight='bold')
ax2.set_ylabel('占有確率 f(E)', fontsize=12, fontweight='bold')
ax2.set_title('フェルミエネルギー付近の拡大図', fontsize=13, fontweight='bold')
ax2.legend(fontsize=11)
ax2.grid(True, alpha=0.3)
ax2.set_xlim(E_F_eV - 1, E_F_eV + 1)
ax2.set_ylim(-0.05, 1.05)
plt.tight_layout()
plt.savefig('fermi_dirac_temperature_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n(1) フェルミ-ディラック分布:")
print("-" * 80)
print(f" 0 K: E < E_F ではすべての状態が占有 (f = 1)")
print(f" E > E_F ではすべての状態が空 (f = 0)")
print(f" ステップ関数として振る舞う")
print(f" ")
print(f" 300 K: E = E_F で f = 0.5")
print(f" 熱エネルギー k_B T = {k_B * 300 / e * 1000:.2f} meV 程度の幅で")
print(f" 分布が「ぼける」")
print(f" しかし、E_F = {E_F_eV} eV >> k_B T なので、")
print(f" ステップ関数に近い形を保つ")
# (2) フェルミ速度の計算
# E_F = (1/2) m v_F^2 より v_F = √(2 E_F / m)
v_F = np.sqrt(2 * E_F / m_e)
print(f"\n(2) フェルミ速度の計算:")
print("-" * 80)
print(f" フェルミエネルギーと電子の運動エネルギーの関係:")
print(f" E_F = (1/2) m v_F²")
print(f" ")
print(f" したがって、フェルミ速度は:")
print(f" v_F = √(2 E_F / m)")
print(f" ")
print(f" 計算:")
print(f" v_F = √(2 × {E_F:.3e} J / {m_e:.3e} kg)")
print(f" = {v_F:.3e} m/s")
print(f" = {v_F / 1e6:.3f} × 10⁶ m/s")
print(f" ")
print(f" 光速 c = {constants.c:.3e} m/s との比:")
print(f" v_F / c = {v_F / constants.c:.4f} = {v_F / constants.c * 100:.2f}%")
print("-" * 80)
print("\n" + "=" * 80)
print("【解答まとめ】")
print("=" * 80)
print(f"(1) フェルミ-ディラック分布:")
print(f" - 0 K ではステップ関数")
print(f" - 300 K では E_F 付近で k_B T 程度の幅でぼける")
print(f" - グラフを 'fermi_dirac_temperature_comparison.png' に保存")
print(f"")
print(f"(2) フェルミ速度:")
print(f" v_F = {v_F / 1e6:.3f} × 10⁶ m/s (光速の約 {v_F / constants.c * 100:.1f}%)")
print("=" * 80)
print("\n【物理的意義】")
print("-" * 80)
print("フェルミ速度は、絶対零度においてフェルミエネルギーを持つ")
print("電子の速度です。この速度は非常に大きく(約 10⁶ m/s)、")
print("金属中の電子が高速で運動していることを示しています。")
print("これが金属の高い電気伝導性と熱伝導性の原因です。")
print("-" * 80)
演習 1.5
Hard問題:FCC構造の金属において、$(111)$ 面と $(100)$ 面のすべり系(すべり面とすべり方向の組み合わせ)を特定し、それぞれの面での原子配列密度を比較してください。どちらの面がすべりやすいか、理由とともに説明してください。
解答を表示
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
print("=" * 80)
print("FCC金属のすべり系解析:(111)面 vs (100)面")
print("=" * 80)
# FCC構造のすべり系
print("\n【FCC構造のすべり系】")
print("-" * 80)
print("FCC金属(Cu, Al, Au, Ag, Niなど)の主要なすべり系:")
print(" すべり面: {111} 面(最密充填面)")
print(" すべり方向: <110> 方向(最密充填方向)")
print(" ")
print("(111)面のすべり系: 4つの{111}面 × 3つの<110>方向 = 12個")
print("(100)面のすべり系: 通常はすべらないが、高温では活性化")
# (111)面と(100)面の原子配列密度の計算
print("\n【原子配列密度の比較】")
print("-" * 80)
# 格子定数
a = 1.0 # 任意単位
# (111)面の原子配列密度
# (111)面は正三角形の格子
# 三角形の面積 = (√3/2) × (a/√2)² = (√3/4) × a²
area_111_triangle = (np.sqrt(3) / 4) * a**2
# (111)面の単位三角形には1個の原子が含まれる
# (頂点の3個 × 1/3 = 1個)
atoms_per_triangle_111 = 1
# 原子配列密度 = 原子数 / 面積
density_111 = atoms_per_triangle_111 / area_111_triangle
print(f"\n(111)面の解析:")
print(f" 格子構造: 正三角形格子(最密充填)")
print(f" 単位三角形の面積: (√3/4) × a² = {area_111_triangle:.4f} a²")
print(f" 単位三角形あたりの原子数: {atoms_per_triangle_111}")
print(f" 原子配列密度: {density_111:.4f} / a²")
print(f" = {density_111:.4f} × (1/a²)")
# (100)面の原子配列密度
# (100)面は正方格子
# 正方形の面積 = (a/√2)² = a²/2
area_100_square = a**2 / 2
# (100)面の単位正方形には1個の原子が含まれる
# (頂点の4個 × 1/4 = 1個)
atoms_per_square_100 = 1
# 原子配列密度
density_100 = atoms_per_square_100 / area_100_square
print(f"\n(100)面の解析:")
print(f" 格子構造: 正方格子")
print(f" 単位正方形の面積: a²/2 = {area_100_square:.4f} a²")
print(f" 単位正方形あたりの原子数: {atoms_per_square_100}")
print(f" 原子配列密度: {density_100:.4f} / a²")
print(f" = {density_100:.4f} × (1/a²)")
# 比較
ratio = density_111 / density_100
print(f"\n原子配列密度の比:")
print(f" (111)面 / (100)面 = {ratio:.4f}")
print(f" (111)面は(100)面の {ratio:.2f}倍 密に原子が配列")
# すべりやすさの評価
print("\n" + "=" * 80)
print("【すべりやすさの評価】")
print("=" * 80)
print("\n(111)面が主要なすべり面である理由:")
print("-" * 80)
print(f"1. 最密充填面である")
print(f" → 原子配列密度が最も高い ({density_111:.4f} / a²)")
print(f" → 原子間結合が強く、面全体として安定")
print(f"")
print(f"2. 面間隔が最も大きい")
print(f" → d_111 = a / √3 = {a / np.sqrt(3):.4f} a")
print(f" → d_100 = a / √1 = {a / np.sqrt(1):.4f} a")
print(f" → 面間隔が大きいほど、すべりに必要なせん断応力が小さい")
print(f"")
print(f"3. すべり方向 <110> が最密充填方向")
print(f" → 原子間距離が最短 (a/√2 = {a / np.sqrt(2):.4f} a)")
print(f" → すべりの際の原子の移動距離が最小")
print(f"")
print(f"4. すべり系の数が多い")
print(f" → {111} 面: 4面 × 3方向 = 12個のすべり系")
print(f" → 多様な応力方向に対応可能 → 延性が高い")
print("\n(100)面がすべりにくい理由:")
print("-" * 80)
print(f"1. 原子配列密度が低い ({density_100:.4f} / a²)")
print(f" → (111)面の {1/ratio:.2f}倍")
print(f" → 面全体としての結合が弱い")
print(f"")
print(f"2. 面間隔が小さい")
print(f" → d_100 = {a / np.sqrt(1):.4f} a ((111)面の {np.sqrt(3):.2f}倍密)")
print(f" → すべりに必要なせん断応力が大きい")
print(f"")
print(f"3. 常温では活性化しない")
print(f" → 高温(>0.5T_m)で初めて活性化")
# 臨界分解せん断応力(CRSS)の概念
print("\n" + "=" * 80)
print("【臨界分解せん断応力(CRSS)】")
print("=" * 80)
print("\nSchmidの法則:")
print(" τ_R = σ cos φ cos λ")
print(" ")
print(" ここで、")
print(" τ_R : 分解せん断応力")
print(" σ : 引張応力")
print(" φ : 応力軸とすべり面法線のなす角")
print(" λ : 応力軸とすべり方向のなす角")
print(" ")
print("すべりが開始する条件:")
print(" τ_R ≥ τ_CRSS")
print(" ")
print("FCC金属の典型的なCRSS値(室温):")
print(" Cu: 約 0.5 - 1.0 MPa")
print(" Al: 約 0.2 - 0.5 MPa")
print(" Au: 約 0.3 - 0.8 MPa")
# 可視化:すべり系の模式図
fig = plt.figure(figsize=(14, 6))
# 左図: (111)面のすべり系
ax1 = fig.add_subplot(121, projection='3d')
ax1.set_title('(111)面のすべり系\n(最密充填面、12個のすべり系)',
fontsize=12, fontweight='bold', pad=15)
# (111)面を描画(簡略化)
plane_vertices_111 = np.array([
[0, 0, 1],
[1, 0, 0],
[0, 1, 0]
])
# 面を描画
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
poly_111 = Poly3DCollection([plane_vertices_111], alpha=0.5,
facecolor='cyan', edgecolor='blue', linewidth=2)
ax1.add_collection3d(poly_111)
# すべり方向のベクトルを描画
slip_directions_111 = [
([0, 0, 1], [1, 0, 0]),
([1, 0, 0], [0, 1, 0]),
([0, 1, 0], [0, 0, 1])
]
for start, end in slip_directions_111:
start = np.array(start)
end = np.array(end)
ax1.quiver(start[0], start[1], start[2],
end[0] - start[0], end[1] - start[1], end[2] - start[2],
color='red', arrow_length_ratio=0.2, linewidth=2)
ax1.set_xlabel('X', fontsize=10, fontweight='bold')
ax1.set_ylabel('Y', fontsize=10, fontweight='bold')
ax1.set_zlabel('Z', fontsize=10, fontweight='bold')
ax1.set_xlim([0, 1])
ax1.set_ylim([0, 1])
ax1.set_zlim([0, 1])
# 右図: (100)面のすべり系
ax2 = fig.add_subplot(122, projection='3d')
ax2.set_title('(100)面のすべり系\n(非最密充填面、常温では不活性)',
fontsize=12, fontweight='bold', pad=15)
# (100)面を描画
plane_vertices_100 = np.array([
[1, 0, 0],
[1, 1, 0],
[1, 1, 1],
[1, 0, 1]
])
poly_100 = Poly3DCollection([plane_vertices_100], alpha=0.5,
facecolor='lightcoral', edgecolor='red', linewidth=2)
ax2.add_collection3d(poly_100)
ax2.set_xlabel('X', fontsize=10, fontweight='bold')
ax2.set_ylabel('Y', fontsize=10, fontweight='bold')
ax2.set_zlabel('Z', fontsize=10, fontweight='bold')
ax2.set_xlim([0, 1])
ax2.set_ylim([0, 1])
ax2.set_zlim([0, 1])
plt.tight_layout()
plt.savefig('fcc_slip_systems_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print("\n" + "=" * 80)
print("【結論】")
print("=" * 80)
print("(111)面が(100)面よりすべりやすい理由:")
print(" 1. 最密充填面であり、原子配列密度が高い")
print(f" → (111): {density_111:.4f} / a²")
print(f" → (100): {density_100:.4f} / a² ({ratio:.2f}倍の差)")
print(" 2. 面間隔が大きく、すべりに必要なせん断応力が小さい")
print(" 3. すべり系が12個と多く、多様な応力に対応可能")
print(" 4. FCC金属の高い延性の主要因")
print("=" * 80)
print("\n✓ グラフを 'fcc_slip_systems_comparison.png' として保存しました")
学習目標の確認
レベル1: 基本理解(知識の習得)
- 金属結合の自由電子モデルとDrudeモデルを説明できる
- FCC、BCC、HCP結晶構造の違いを説明できる
- 充填率と配位数の意味を理解している
- フェルミ-ディラック分布の概念を理解している
- ミラー指数の表記方法を理解している
レベル2: 実践スキル(計算と応用)
- Drudeモデルで電気伝導度を計算できる
- FCC、BCC、HCP構造の充填率を計算できる
- ミラー指数から面間隔を計算できる
- フェルミエネルギーとフェルミ速度を計算できる
- Pythonで結晶構造を可視化できる
- ASEやpymatgenを使って結晶構造を生成・操作できる
レベル3: 応用力(問題解決と最適化)
- 結晶構造から材料の機械的性質を予測できる
- すべり系を解析し、材料の延性を評価できる
- 実験データ(XRD、電気抵抗率など)を結晶構造と関連付けて解釈できる
- pymatgenやASEを使って材料設計シミュレーションを実行できる
- Materials Projectなどのデータベースを活用して材料探索ができる
参考文献
- Kittel, C. (2018). Introduction to Solid State Physics, 9th ed. Wiley, pp. 145-189, 223-267.
- Ashcroft, N.W., Mermin, N.D. (1976). Solid State Physics. Brooks Cole, pp. 1-48, 123-167.
- Callister, W.D., Jr., Rethwisch, D.G. (2020). Materials Science and Engineering: An Introduction, 10th ed. Wiley, pp. 45-89, 112-145.
- Porter, D.A., Easterling, K.E., Sherif, M.Y. (2009). Phase Transformations in Metals and Alloys, 3rd ed. CRC Press, pp. 1-35.
- Cottrell, A.H. (1953). Dislocations and Plastic Flow in Crystals. Oxford University Press, pp. 8-34.
- Hosford, W.F. (2010). Mechanical Behavior of Materials, 2nd ed. Cambridge University Press, pp. 67-102.
- pymatgen documentation: Structure module. https://pymatgen.org/pymatgen.core.structure.html
- ASE (Atomic Simulation Environment) documentation: Atoms and lattice objects. https://wiki.fysik.dtu.dk/ase/