第3章:ミラー指数と結晶面・方向

結晶構造を記述する普遍的な記法を学ぶ

📖 推定学習時間: 28分 🎯 難易度: 初級〜中級 💻 コード例: 8個

学習目標

この章を学ぶことで、以下の知識とスキルを習得できます:

1. ミラー指数とは何か

結晶学において、ミラー指数(Miller indices)は結晶内の面や方向を表す標準的な記法です。 1839年にイギリスの鉱物学者ウィリアム・ハロウズ・ミラー(William Hallowes Miller)によって提案されました。

1.1 なぜミラー指数が必要か

結晶中には無限の平面と方向が存在します。これらを一意に、かつ簡潔に表現する方法が必要です:

記法の約束

1.2 ミラー指数の定義

ミラー指数 (hkl) は以下の手順で求められます:

flowchart TD A[結晶面と3つの結晶軸の交点を求める] --> B[各軸での切片を格子定数で割る] B --> C[各値の逆数をとる] C --> D[最小公倍数を掛けて整数化] D --> E[ミラー指数 hkl を得る] style A fill:#e3f2fd style B fill:#e3f2fd style C fill:#fff3e0 style D fill:#fff3e0 style E fill:#e8f5e9

例:(111)面の求め方

  1. 切片:a軸、b軸、c軸すべてで切片が1格子定数
  2. 格子定数で割る:1/a, 1/b, 1/c = 1, 1, 1
  3. 逆数:1/1, 1/1, 1/1 = 1, 1, 1
  4. 整数化:すでに整数なのでそのまま
  5. 結果:ミラー指数は (111)

例:(200)面の求め方

  1. 切片:a軸で1/2、b軸とc軸で無限遠(平行)
  2. 格子定数で割る:1/2, ∞, ∞
  3. 逆数:2, 0, 0
  4. 結果:ミラー指数は (200)

これは(100)面の2倍の密度で並ぶ平面であることを意味します。

2. Pythonでミラー指数を計算する

2.1 切片からミラー指数を求める

コード例1:ミラー指数の計算

結晶軸との切片からミラー指数を自動計算するプログラム:

import numpy as np
from fractions import Fraction

def calculate_miller_indices(intercepts):
    """
    切片からミラー指数を計算する

    Parameters:
    -----------
    intercepts : tuple of float
        (a軸切片, b軸切片, c軸切片)
        無限大の場合は np.inf を使用

    Returns:
    --------
    tuple : ミラー指数 (h, k, l)
    """
    # 逆数を計算(無限大の逆数は0)
    reciprocals = []
    for intercept in intercepts:
        if np.isinf(intercept):
            reciprocals.append(0)
        else:
            reciprocals.append(1 / intercept)

    # 分数として扱い、最小公倍数を見つける
    fractions = [Fraction(r).limit_denominator(100) for r in reciprocals]

    # 分母の最小公倍数を計算
    denominators = [f.denominator for f in fractions]
    lcm = np.lcm.reduce(denominators)

    # 整数化
    h, k, l = [int(f * lcm) for f in fractions]

    # 最大公約数で簡約化
    gcd = np.gcd.reduce([abs(h), abs(k), abs(l)])
    if gcd > 0:
        h, k, l = h // gcd, k // gcd, l // gcd

    return (h, k, l)

# テスト例
print("=== ミラー指数の計算 ===\n")

# (111)面:すべての軸で切片が1
intercepts_111 = (1, 1, 1)
hkl = calculate_miller_indices(intercepts_111)
print(f"切片 {intercepts_111} → ミラー指数 {hkl}")

# (100)面:a軸のみで切片、他は平行
intercepts_100 = (1, np.inf, np.inf)
hkl = calculate_miller_indices(intercepts_100)
print(f"切片 {intercepts_100} → ミラー指数 {hkl}")

# (110)面:a軸とb軸で切片、c軸に平行
intercepts_110 = (1, 1, np.inf)
hkl = calculate_miller_indices(intercepts_110)
print(f"切片 {intercepts_110} → ミラー指数 {hkl}")

# (210)面:a軸で1/2、b軸で1の切片
intercepts_210 = (0.5, 1, np.inf)
hkl = calculate_miller_indices(intercepts_210)
print(f"切片 {intercepts_210} → ミラー指数 {hkl}")

# (123)面:異なる切片
intercepts_123 = (1, 0.5, 0.333333)
hkl = calculate_miller_indices(intercepts_123)
print(f"切片 {intercepts_123} → ミラー指数 {hkl}")

実行結果

=== ミラー指数の計算 ===

切片 (1, 1, 1) → ミラー指数 (1, 1, 1)
切片 (1, inf, inf) → ミラー指数 (1, 0, 0)
切片 (1, 1, inf) → ミラー指数 (1, 1, 0)
切片 (0.5, 1, inf) → ミラー指数 (2, 1, 0)
切片 (1, 0.5, 0.333333) → ミラー指数 (1, 2, 3)

2.2 主要な低指数面の可視化

コード例2:立方晶の主要面を3D表示

代表的な結晶面を可視化して、ミラー指数の意味を理解します:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

def plot_lattice_plane(hkl, ax, color='cyan', alpha=0.6):
    """
    ミラー指数で指定された結晶面を描画

    Parameters:
    -----------
    hkl : tuple
        ミラー指数 (h, k, l)
    ax : Axes3D
        matplotlib の3D軸
    color : str
        面の色
    alpha : float
        透明度
    """
    h, k, l = hkl

    # 切片を計算(0の場合は大きな値に設定)
    intercepts = []
    for index in [h, k, l]:
        if index == 0:
            intercepts.append(10)  # 無限大の代わりに大きな値
        else:
            intercepts.append(1 / index)

    # 面を構成する頂点を計算
    vertices = []

    # ケースごとに頂点を設定
    if h != 0 and k != 0 and l != 0:
        # (111)タイプ:3つの切片を持つ
        vertices = [
            [intercepts[0], 0, 0],
            [0, intercepts[1], 0],
            [0, 0, intercepts[2]]
        ]
    elif h != 0 and k != 0 and l == 0:
        # (110)タイプ:2つの切片、c軸に平行
        vertices = [
            [intercepts[0], 0, 0],
            [intercepts[0], 0, 2],
            [0, intercepts[1], 2],
            [0, intercepts[1], 0]
        ]
    elif h != 0 and k == 0 and l == 0:
        # (100)タイプ:1つの切片、他の軸に平行
        vertices = [
            [intercepts[0], 0, 0],
            [intercepts[0], 2, 0],
            [intercepts[0], 2, 2],
            [intercepts[0], 0, 2]
        ]

    # 面を描画
    if len(vertices) > 0:
        poly = Poly3DCollection([vertices], alpha=alpha, facecolor=color, edgecolor='black', linewidth=2)
        ax.add_collection3d(poly)

def plot_crystal_axes():
    """立方晶の結晶軸と主要面を表示"""
    fig = plt.figure(figsize=(15, 5))

    planes = [
        ((1, 0, 0), 'cyan', '(100)面'),
        ((1, 1, 0), 'yellow', '(110)面'),
        ((1, 1, 1), 'magenta', '(111)面')
    ]

    for idx, (hkl, color, title) in enumerate(planes):
        ax = fig.add_subplot(1, 3, idx + 1, projection='3d')

        # 結晶軸を描画
        ax.quiver(0, 0, 0, 1.5, 0, 0, color='red', arrow_length_ratio=0.1, linewidth=2, label='a軸')
        ax.quiver(0, 0, 0, 0, 1.5, 0, color='green', arrow_length_ratio=0.1, linewidth=2, label='b軸')
        ax.quiver(0, 0, 0, 0, 0, 1.5, color='blue', arrow_length_ratio=0.1, linewidth=2, label='c軸')

        # 結晶面を描画
        plot_lattice_plane(hkl, ax, color=color, alpha=0.6)

        # 軸ラベル
        ax.set_xlabel('a', fontsize=12, fontweight='bold')
        ax.set_ylabel('b', fontsize=12, fontweight='bold')
        ax.set_zlabel('c', fontsize=12, fontweight='bold')

        ax.set_xlim([0, 1.5])
        ax.set_ylim([0, 1.5])
        ax.set_zlim([0, 1.5])

        ax.set_title(title, fontsize=14, fontweight='bold')
        ax.legend(loc='upper left', fontsize=8)

        # グリッドを追加
        ax.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.savefig('miller_indices_planes.png', dpi=150, bbox_inches='tight')
    plt.show()
    print("主要な結晶面の可視化を保存しました: miller_indices_planes.png")

# 実行
plot_crystal_axes()

3. 面間隔 dhkl の計算

ミラー指数 (hkl) で指定される結晶面の面間隔 dhklは、 X線回折実験で観測されるブラッグピークの位置を決定する重要なパラメータです。

3.1 立方晶系での面間隔

立方晶(a = b = c、α = β = γ = 90°)では、面間隔は非常に簡潔な式で表されます:

$$ d_{hkl} = \frac{a}{\sqrt{h^2 + k^2 + l^2}} $$

ここで、aは格子定数、h, k, lはミラー指数です。

コード例3:立方晶の面間隔計算

import numpy as np
import matplotlib.pyplot as plt

def cubic_d_spacing(a, h, k, l):
    """
    立方晶系の面間隔を計算

    Parameters:
    -----------
    a : float
        格子定数 (Å)
    h, k, l : int
        ミラー指数

    Returns:
    --------
    float : 面間隔 d_hkl (Å)
    """
    return a / np.sqrt(h**2 + k**2 + l**2)

# シリコン(立方晶、a = 5.431 Å)での計算
a_Si = 5.431

print("=== シリコン(Si)の面間隔 ===")
print(f"格子定数 a = {a_Si} Å\n")

# 主要な面の面間隔を計算
planes = [
    (1, 0, 0), (1, 1, 0), (1, 1, 1),
    (2, 0, 0), (2, 2, 0), (3, 1, 1),
    (2, 2, 2), (4, 0, 0), (3, 3, 1)
]

results = []
for hkl in planes:
    h, k, l = hkl
    d = cubic_d_spacing(a_Si, h, k, l)
    results.append((hkl, d))
    print(f"({h}{k}{l})面: d = {d:.4f} Å")

# グラフで可視化
fig, ax = plt.subplots(figsize=(12, 6))

hkl_labels = [f"({h}{k}{l})" for (h, k, l), d in results]
d_values = [d for hkl, d in results]

bars = ax.bar(range(len(results)), d_values, color='skyblue', edgecolor='navy', linewidth=1.5)
ax.set_xticks(range(len(results)))
ax.set_xticklabels(hkl_labels, rotation=45, ha='right')
ax.set_ylabel('面間隔 d (Å)', fontsize=12, fontweight='bold')
ax.set_xlabel('ミラー指数', fontsize=12, fontweight='bold')
ax.set_title('シリコン(Si)の結晶面ごとの面間隔', fontsize=14, fontweight='bold')
ax.grid(axis='y', alpha=0.3)

# 値をバーの上に表示
for i, (bar, d) in enumerate(zip(bars, d_values)):
    ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.05,
            f'{d:.3f}', ha='center', va='bottom', fontsize=9)

plt.tight_layout()
plt.savefig('si_d_spacing.png', dpi=150, bbox_inches='tight')
plt.show()
print("\nグラフを保存しました: si_d_spacing.png")

3.2 正方晶系での面間隔

正方晶(a = b ≠ c、α = β = γ = 90°)では、c軸方向の格子定数が異なるため式が変わります:

$$ d_{hkl} = \frac{1}{\sqrt{\frac{h^2 + k^2}{a^2} + \frac{l^2}{c^2}}} $$

コード例4:正方晶の面間隔計算

def tetragonal_d_spacing(a, c, h, k, l):
    """
    正方晶系の面間隔を計算

    Parameters:
    -----------
    a : float
        a軸(= b軸)の格子定数 (Å)
    c : float
        c軸の格子定数 (Å)
    h, k, l : int
        ミラー指数

    Returns:
    --------
    float : 面間隔 d_hkl (Å)
    """
    return 1 / np.sqrt((h**2 + k**2) / a**2 + l**2 / c**2)

# TiO2 ルチル(正方晶、a = 4.594 Å, c = 2.958 Å)
a_TiO2 = 4.594
c_TiO2 = 2.958

print("=== TiO2(ルチル)の面間隔 ===")
print(f"格子定数 a = {a_TiO2} Å, c = {c_TiO2} Å")
print(f"c/a 比 = {c_TiO2/a_TiO2:.3f}\n")

planes_tetragonal = [
    (1, 0, 0), (0, 0, 1), (1, 1, 0),
    (1, 0, 1), (1, 1, 1), (2, 0, 0),
    (2, 1, 0), (2, 1, 1), (2, 2, 0)
]

# 比較:立方晶と仮定した場合(誤った計算)
print("正方晶として正しく計算した場合 vs 立方晶と誤って仮定した場合:\n")
for hkl in planes_tetragonal[:5]:
    h, k, l = hkl
    d_correct = tetragonal_d_spacing(a_TiO2, c_TiO2, h, k, l)
    d_wrong = cubic_d_spacing(a_TiO2, h, k, l)  # 誤った仮定
    error = abs(d_correct - d_wrong) / d_correct * 100

    print(f"({h}{k}{l})面:")
    print(f"  正しい d = {d_correct:.4f} Å")
    print(f"  誤った d = {d_wrong:.4f} Å (誤差: {error:.2f}%)\n")

重要な注意点

結晶系を誤って仮定すると、面間隔の計算が大きく間違います。 特にc軸が大きく異なる正方晶を立方晶と扱うと、(001)面などのc軸に関わる面で顕著な誤差が生じます。

3.3 六方晶系での面間隔

六方晶(a = b ≠ c、α = β = 90°、γ = 120°)は、しばしば4軸指数 (hkil)を使用します。 ここで、i = -(h+k) という関係があります。

$$ d_{hkl} = \frac{1}{\sqrt{\frac{4}{3}\frac{h^2 + hk + k^2}{a^2} + \frac{l^2}{c^2}}} $$

コード例5:六方晶の面間隔計算

def hexagonal_d_spacing(a, c, h, k, l):
    """
    六方晶系の面間隔を計算

    Parameters:
    -----------
    a : float
        a軸(= b軸)の格子定数 (Å)
    c : float
        c軸の格子定数 (Å)
    h, k, l : int
        ミラー指数(3軸表記)

    Returns:
    --------
    float : 面間隔 d_hkl (Å)
    """
    return 1 / np.sqrt((4/3) * (h**2 + h*k + k**2) / a**2 + l**2 / c**2)

def miller_to_miller_bravais(h, k, l):
    """
    3軸ミラー指数を4軸ミラー・ブラベー指数に変換

    Parameters:
    -----------
    h, k, l : int
        3軸ミラー指数

    Returns:
    --------
    tuple : 4軸指数 (h, k, i, l) ただし i = -(h+k)
    """
    i = -(h + k)
    return (h, k, i, l)

# α-Al2O3(コランダム、六方晶、a = 4.759 Å, c = 12.991 Å)
a_Al2O3 = 4.759
c_Al2O3 = 12.991

print("=== α-Al2O3(コランダム)の面間隔 ===")
print(f"格子定数 a = {a_Al2O3} Å, c = {c_Al2O3} Å")
print(f"c/a 比 = {c_Al2O3/a_Al2O3:.3f}\n")

planes_hexagonal = [
    (1, 0, 0), (0, 0, 1), (1, 1, 0),
    (1, 0, 1), (1, 1, 2), (2, 0, 0),
    (1, 0, 4), (2, 1, 0), (0, 0, 6)
]

print(f"{'3軸 (hkl)':<15} {'4軸 (hkil)':<20} {'d (Å)':<10}")
print("-" * 50)

for hkl in planes_hexagonal:
    h, k, l = hkl
    d = hexagonal_d_spacing(a_Al2O3, c_Al2O3, h, k, l)
    hkil = miller_to_miller_bravais(h, k, l)

    # 負の値を表示
    hkil_str = "("
    for idx in hkil:
        if idx < 0:
            hkil_str += f"{idx}"
        else:
            hkil_str += f"{idx}"
    hkil_str += ")"

    print(f"({h}{k}{l}){'':<12} {hkil_str:<20} {d:.4f}")

4軸指数の利点

六方晶では4軸指数 (hkil) を使うと、結晶の6回対称性が記法に反映されます。 例えば、{10\(\bar{1}\)0}は6つの等価な面を表し、これが4軸表記で明確になります。

4. 等価な面と方向(対称性)

結晶の対称性により、結晶学的に等価な面や方向が存在します。 これらをまとめて表記するために、波括弧 {hkl} や山括弧 <uvw> を使います。

4.1 立方晶の等価な面

立方晶では、以下のような等価関係があります:

表記 意味 例:{100}の等価な面
{100} 等価な面の集合 (100), (010), (001), (\(\bar{1}\)00), (0\(\bar{1}\)0), (00\(\bar{1}\))
{110} 等価な面の集合 (110), (101), (011), (\(\bar{1}\)10), (\(\bar{1}\)0\(\bar{1}\)), など12面
{111} 等価な面の集合 (111), (\(\bar{1}\)11), (1\(\bar{1}\)1), など8面

コード例6:等価な面の生成

from itertools import permutations, product

def generate_equivalent_planes(h, k, l, crystal_system='cubic'):
    """
    対称性を考慮して等価な面をすべて生成

    Parameters:
    -----------
    h, k, l : int
        基準となるミラー指数
    crystal_system : str
        結晶系 ('cubic', 'tetragonal', 'hexagonal')

    Returns:
    --------
    set : 等価な面の集合
    """
    planes = set()

    if crystal_system == 'cubic':
        # 立方晶:符号と置換の全組み合わせ
        for perm in permutations([abs(h), abs(k), abs(l)]):
            for signs in product([1, -1], repeat=3):
                plane = tuple(s * p for s, p in zip(signs, perm))
                if plane != (0, 0, 0):  # (000)は除外
                    planes.add(plane)

    elif crystal_system == 'tetragonal':
        # 正方晶:a, b軸は等価、c軸は独立
        # h, k の置換と符号変更のみ
        for h_sign, k_sign, l_sign in product([1, -1], repeat=3):
            planes.add((h_sign * h, k_sign * k, l_sign * l))
            planes.add((k_sign * k, h_sign * h, l_sign * l))  # h, k の置換

    elif crystal_system == 'hexagonal':
        # 六方晶:より複雑な対称性(簡略版)
        # 6回回転対称性を考慮
        for l_sign in [1, -1]:
            planes.add((h, k, l_sign * l))
            planes.add((k, -(h+k), l_sign * l))
            planes.add((-(h+k), h, l_sign * l))

    return sorted(planes)

# 立方晶での等価な面
print("=== 立方晶の等価な面 ===\n")

for base_plane in [(1, 0, 0), (1, 1, 0), (1, 1, 1)]:
    h, k, l = base_plane
    equiv = generate_equivalent_planes(h, k, l, 'cubic')
    print(f"{{{h}{k}{l}}} の等価な面 ({len(equiv)} 個):")

    # 見やすく整形して表示
    for i in range(0, len(equiv), 6):
        planes_str = ', '.join([f"({p[0]:2}{p[1]:2}{p[2]:2})" for p in equiv[i:i+6]])
        print(f"  {planes_str}")
    print()

# 正方晶での等価な面
print("=== 正方晶の等価な面 ===\n")
base_plane = (1, 1, 0)
equiv_tetra = generate_equivalent_planes(*base_plane, 'tetragonal')
print(f"{{{base_plane[0]}{base_plane[1]}{base_plane[2]}}} の等価な面(正方晶)({len(equiv_tetra)} 個):")
for plane in equiv_tetra:
    print(f"  ({plane[0]:2}{plane[1]:2}{plane[2]:2})")

4.2 結晶方向 [uvw] の表記

結晶方向は[uvw]で表され、原点から座標 (u·a, v·b, w·c) へのベクトルを意味します。

面と方向の関係

立方晶では、(hkl)面に垂直な方向は[hkl]になります。 ただし、これは立方晶特有の性質で、他の結晶系では一般に成り立ちません。

コード例7:結晶方向ベクトルの可視化

def plot_crystal_directions():
    """立方晶の主要な結晶方向を可視化"""
    fig = plt.figure(figsize=(15, 5))

    directions = [
        ([1, 0, 0], 'red', '[100]'),
        ([1, 1, 0], 'green', '[110]'),
        ([1, 1, 1], 'blue', '[111]')
    ]

    for idx, (uvw, color, title) in enumerate(directions):
        ax = fig.add_subplot(1, 3, idx + 1, projection='3d')

        # 立方体の枠を描画
        r = [0, 1]
        for s, e in combinations(np.array(list(product(r, r, r))), 2):
            if np.sum(np.abs(s - e)) == 1:
                ax.plot3D(*zip(s, e), color='gray', alpha=0.3, linewidth=1)

        # 方向ベクトルを描画
        ax.quiver(0, 0, 0, uvw[0], uvw[1], uvw[2],
                 color=color, arrow_length_ratio=0.15, linewidth=3,
                 label=f'{title} 方向')

        # 軸ラベル
        ax.set_xlabel('a', fontsize=12, fontweight='bold')
        ax.set_ylabel('b', fontsize=12, fontweight='bold')
        ax.set_zlabel('c', fontsize=12, fontweight='bold')

        ax.set_xlim([0, 1.5])
        ax.set_ylim([0, 1.5])
        ax.set_zlim([0, 1.5])

        ax.set_title(title + ' 結晶方向', fontsize=14, fontweight='bold')
        ax.legend(loc='upper left')
        ax.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.savefig('crystal_directions.png', dpi=150, bbox_inches='tight')
    plt.show()
    print("結晶方向の可視化を保存しました: crystal_directions.png")

from itertools import combinations, product

# 実行
plot_crystal_directions()

5. 実材料での応用

ミラー指数は材料科学のあらゆる分野で使われます。 ここでは、実際の材料を例に面間隔の計算と応用を学びます。

5.1 X線回折パターンの解釈

X線回折(XRD)では、ブラッグの法則により特定の角度でピークが観測されます:

$$ n\lambda = 2d_{hkl}\sin\theta $$

ここで、λはX線の波長、θはブラッグ角、nは反射の次数(通常1)です。 面間隔 dhkl を知ることで、観測されたピークがどの結晶面からの反射かを特定できます。

コード例8:実材料でのXRDピーク予測

def bragg_angle(d_hkl, wavelength, n=1):
    """
    ブラッグの法則から回折角を計算

    Parameters:
    -----------
    d_hkl : float
        面間隔 (Å)
    wavelength : float
        X線波長 (Å)
    n : int
        反射の次数(通常1)

    Returns:
    --------
    float : ブラッグ角 θ (度)、Noneの場合は回折不可
    """
    sin_theta = n * wavelength / (2 * d_hkl)
    if abs(sin_theta) > 1:
        return None  # 回折条件を満たさない
    return np.degrees(np.arcsin(sin_theta))

def predict_xrd_pattern(material_name, a, c=None, crystal_system='cubic',
                       wavelength=1.5406, max_hkl=3):
    """
    材料のXRD回折パターンを予測

    Parameters:
    -----------
    material_name : str
        材料名
    a : float
        格子定数 a (Å)
    c : float, optional
        格子定数 c (Å)(正方晶・六方晶の場合)
    crystal_system : str
        結晶系
    wavelength : float
        X線波長 (Å)、Cu Kα線がデフォルト
    max_hkl : int
        計算する最大のミラー指数
    """
    print(f"\n=== {material_name} のXRD回折パターン予測 ===")
    print(f"結晶系: {crystal_system}")
    print(f"格子定数: a = {a:.4f} Å" + (f", c = {c:.4f} Å" if c else ""))
    print(f"X線波長: {wavelength:.4f} Å (Cu Kα)\n")

    print(f"{'(hkl)':<10} {'d (Å)':<12} {'2θ (度)':<12} {'強度目安':<10}")
    print("-" * 55)

    results = []

    # ミラー指数の組み合わせを生成
    for h in range(max_hkl + 1):
        for k in range(h, max_hkl + 1):
            for l in range(k, max_hkl + 1):
                if h == 0 and k == 0 and l == 0:
                    continue

                # 面間隔を計算
                if crystal_system == 'cubic':
                    d = cubic_d_spacing(a, h, k, l)
                elif crystal_system == 'tetragonal':
                    d = tetragonal_d_spacing(a, c, h, k, l)
                elif crystal_system == 'hexagonal':
                    d = hexagonal_d_spacing(a, c, h, k, l)

                # ブラッグ角を計算
                theta = bragg_angle(d, wavelength)

                if theta is not None and theta < 90:
                    # 多重度(等価な面の数)を考慮した相対強度の簡易推定
                    multiplicity = len(generate_equivalent_planes(h, k, l, crystal_system))
                    intensity = multiplicity / (h**2 + k**2 + l**2)  # 簡易的な構造因子

                    results.append(((h, k, l), d, 2 * theta, intensity))

    # 2θ の小さい順にソート
    results.sort(key=lambda x: x[2])

    # 上位10ピークを表示
    for i, ((h, k, l), d, two_theta, intensity) in enumerate(results[:10]):
        # 強度を視覚化
        intensity_bar = '█' * int(intensity * 10)
        print(f"({h}{k}{l}){'':<8} {d:8.4f}    {two_theta:8.2f}    {intensity_bar}")

# 実行:代表的な材料のXRDパターン予測

# 1. シリコン(Si、立方晶)
predict_xrd_pattern('Silicon (Si)', a=5.4310, crystal_system='cubic', max_hkl=3)

# 2. 金(Au、立方晶)
predict_xrd_pattern('Gold (Au)', a=4.0782, crystal_system='cubic', max_hkl=2)

# 3. TiO2 ルチル(正方晶)
predict_xrd_pattern('TiO2 (Rutile)', a=4.594, c=2.958,
                   crystal_system='tetragonal', max_hkl=2)

# 4. α-Al2O3(六方晶)
predict_xrd_pattern('α-Al2O3 (Corundum)', a=4.759, c=12.991,
                   crystal_system='hexagonal', max_hkl=2)

XRD解析への応用

このプログラムは、実験で得られたXRDパターンと理論計算を比較するための基礎ツールです。 実際の解析では、原子の配置による構造因子や温度因子も考慮する必要がありますが、 ミラー指数と面間隔の理解は全ての基礎となります。

5.2 材料の異方性と結晶面

材料の物性は結晶面により大きく異なります。例えば:

6. 演習問題

演習1:ミラー指数の決定

立方晶の結晶で、以下の切片を持つ結晶面のミラー指数を求めなさい:

  1. a軸で2、b軸で1、c軸で無限遠(平行)
  2. a軸で1、b軸で1、c軸で2
  3. a軸で-1、b軸で1、c軸で1
解答を見る
  1. 切片 (2, 1, ∞) → 逆数 (1/2, 1, 0) → 整数化 (1, 2, 0) → (120)
  2. 切片 (1, 1, 2) → 逆数 (1, 1, 1/2) → 整数化 (2, 2, 1) → (221)
  3. 切片 (-1, 1, 1) → 逆数 (-1, 1, 1) → (\(\bar{1}\)11)

演習2:面間隔の計算

銅(Cu)は面心立方構造(fcc)で、格子定数 a = 3.615 Å です。 以下の面の面間隔を計算しなさい:

  1. (111)面
  2. (200)面
  3. (220)面

また、Cu Kα線(λ = 1.5406 Å)を用いたXRD測定で、これらの面からの回折ピークは 何度(2θ)に現れるか計算しなさい。

解答を見る

面間隔:

  1. d111 = 3.615 / √3 = 2.087 Å
  2. d200 = 3.615 / √4 = 1.808 Å
  3. d220 = 3.615 / √8 = 1.278 Å

ブラッグ角:(λ = 2d sinθ より)

  1. 111 = 2 × arcsin(1.5406/(2×2.087)) ≈ 43.3°
  2. 200 = 2 × arcsin(1.5406/(2×1.808)) ≈ 50.4°
  3. 220 = 2 × arcsin(1.5406/(2×1.278)) ≈ 74.1°

演習3:等価な面の理解

立方晶において、{110} に含まれる等価な面をすべて列挙しなさい。 また、これらの面が何個あるか答えなさい。

解答を見る

答え:12個

等価な面:

  • (110), (101), (011)
  • (\(\bar{1}\)10), (\(\bar{1}\)0\(\bar{1}\)), (0\(\bar{1}\)\(\bar{1}\))
  • (1\(\bar{1}\)0), (10\(\bar{1}\)), (01\(\bar{1}\))
  • (\(\bar{1}\)\(\bar{1}\)0), (\(\bar{1}\)0\(\bar{1}\)), (0\(\bar{1}\)1)

これらは立方晶の対称性(24個の対称操作)により等価となり、 同じ物理的性質を持ちます。

演習4:プログラミング課題

正方晶の材料(例:ZrO2、a = 3.64 Å、c = 5.27 Å)について、 以下を実行するPythonプログラムを作成しなさい:

  1. (100)から(333)までのすべての面の面間隔を計算する
  2. 面間隔が2.0 Å以上の面のみを抽出する
  3. 結果を面間隔の降順でソートして表示する
ヒント

コード例4のtetragonal_d_spacing関数を使用し、 3重ループでh, k, lを1から3まで変化させて計算します。 結果はリストに保存し、sorted()関数でソートできます。

まとめ

この章では、結晶学における最も重要な記法であるミラー指数について学びました:

重要ポイント

次章では、X線回折の原理とブラッグの法則を詳しく学び、 ミラー指数と面間隔の知識を実際の構造解析に応用します。