crystal_XRD.py ダウンロード/コピー

crystal_XRD.py をダウンロード

crystal_XRD.py
crystal_XRD.py
  1"""
  2X線回折のブラッグ角計算スクリプト。
  3
  4概要:
  5    結晶格子パラメータとサイト情報に基づいて、X線回折ピークの2θ角、格子面間隔d、ミラー指数(hkl)を計算し、表示します。
  6
  7詳細説明:
  8    このスクリプトは、指定された格子パラメータと原子サイト情報を用いて、結晶構造のX線回折パターンをシミュレートします。
  9    直接格子および逆格子の各種パラメータ(格子ベクトル、メートルテンソル、単位胞体積)を計算し、
 10    その後、ブラッグの法則に基づいて各ミラー指数(hkl)に対する2θ回折角と格子面間隔(d)を算出します。
 11    計算された回折データは、2θ角でソートされて表示されます。
 12    `tkcrystalbase.py` モジュールに依存しており、結晶学的な計算のための基本関数を提供します。
 13
 14関連リンク:
 15    :doc:`crystal_XRD_usage`
 16"""
 17import sys
 18import os
 19from numpy import sin, cos, tan, arcsin, arccos, arctan, exp, log, sqrt
 20import numpy as np
 21from numpy import linalg as la
 22from mpl_toolkits.mplot3d import Axes3D
 23import matplotlib.pyplot as plt
 24
 25from tkcrystalbase import *
 26
 27
 28# Lattice parameters (angstrom and degree)
 29#lattice_parameters = [ 5.62, 5.62, 5.62, 60.0, 60.0, 60.0]
 30lattice_parameters = [ 5.62, 5.62, 5.62, 90.0, 90.0, 90.0]
 31
 32# Site information (atom name, site label, atomic number, atomic mass, charge, radius, color, position)
 33sites = [
 34         ['Na', 'Na1', 11, 22.98997, +1.0, 0.7, 'red',  np.array([0.0, 0.0, 0.0])]
 35        ,['Na', 'Na2', 11, 22.98997, +1.0, 0.7, 'red',  np.array([0.0, 0.5, 0.5])]
 36        ,['Na', 'Na3', 11, 22.98997, +1.0, 0.7, 'red',  np.array([0.5, 0.0, 0.5])]
 37        ,['Na', 'Na4', 11, 22.98997, +1.0, 0.7, 'red',  np.array([0.5, 0.5, 0.0])]
 38        ,['Cl', 'Cl1', 17, 35.4527,  -1.0, 1.4, 'blue', np.array([0.5, 0.0, 0.0])]
 39        ,['Cl', 'Cl2', 17, 35.4527,  -1.0, 1.4, 'blue', np.array([0.5, 0.5, 0.5])]
 40        ,['Cl', 'Cl3', 17, 35.4527,  -1.0, 1.4, 'blue', np.array([0.0, 0.0, 0.5])]
 41        ,['Cl', 'Cl4', 17, 35.4527,  -1.0, 1.4, 'blue', np.array([0.0, 0.5, 0.0])]
 42        ]
 43
 44# X-ray wavelength
 45wl = 1.5405         # angstrom
 46
 47# G min to remove the origin of reciprocal space
 48Gmin = 1.0e-5
 49
 50# 2Theta max
 51Q2max = 150.0       # degree in 2Theta
 52
 53
 54def main():
 55    """
 56    メイン処理を実行し、結晶の基本情報とX線回折結果を表示します。
 57
 58    概要:
 59        結晶の格子情報、逆格子情報、そしてX線回折ピークの2θ角とd値を計算し、コンソールに出力します。
 60
 61    詳細説明:
 62        この関数は以下のステップを実行します。
 63        1. 直接格子の格子ベクトル、メートルテンソル、単位胞体積を計算し表示します。
 64        2. 逆格子の格子パラメータ、格子ベクトル、メートルテンソル、単位胞体積を計算し表示します。
 65        3. 指定されたX線波長と2θ最大値に基づいて、dminとhklの最大範囲を決定します。
 66        4. その範囲内の全ての(h, k, l)ミラー指数に対し、逆格子空間での距離G、格子面間隔d、
 67           そしてブラッグの法則に従って2θ回折角を計算します。
 68        5. 計算された(2θ, d, h, k, l)のリストを2θ角でソートし、コンソールに出力します。
 69
 70    Returns:
 71        None
 72    """
 73    print("")
 74    print("Lattice parameters:", lattice_parameters)
 75    aij = cal_lattice_vectors(lattice_parameters)
 76    print("Lattice vectors:")
 77    print("  ax: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(aij[0][0], aij[0][1], aij[0][2]))
 78    print("  ay: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(aij[1][0], aij[1][1], aij[1][2]))
 79    print("  az: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(aij[2][0], aij[2][1], aij[2][2]))
 80    inf = cal_metrics(lattice_parameters)
 81    gij = inf['gij']
 82    print("Metric tensor:")
 83    print("  gij: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(*gij[0]))
 84    print("       ({:10.4g}, {:10.4g}, {:10.4g}) A".format(*gij[1]))
 85    print("       ({:10.4g}, {:10.4g}, {:10.4g}) A".format(*gij[2]))
 86    volume = cal_volume(aij)
 87    print("Volume: {:12.4g} A^3".format(volume))
 88
 89    print("")
 90    print("Unit cell volume: {:12.4g} A^3".format(volume))
 91    Raij  = cal_reciprocal_lattice_vectors(aij)
 92    Rlatt = cal_reciprocal_lattice_parameters(Raij)
 93    Rinf  = cal_metrics(Rlatt)
 94    Rgij  = Rinf['gij']
 95    print("Reciprocal lattice parameters:", Rlatt)
 96    print("Reciprocal lattice vectors:")
 97    print("  Rax: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Raij[0]))
 98    print("  Ray: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Raij[1]))
 99    print("  Raz: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Raij[2]))
100    print("Reciprocal lattice metric tensor:")
101    print("  Rgij: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Rgij[0]))
102    print("        ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Rgij[1]))
103    print("        ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Rgij[2]))
104    Rvolume = cal_volume(Raij)
105    print("Reciprocal unit cell volume: {:12.4g} A^-3".format(Rvolume))
106
107    dmin = wl / 2.0 / sin(0.5 * Q2max * torad)
108    hmax = int(lattice_parameters[0] / dmin)
109    kmax = int(lattice_parameters[1] / dmin)
110    lmax = int(lattice_parameters[2] / dmin)
111
112    print("")
113    print("hkl range:", hmax, kmax, lmax)
114
115# Calculate diffraction angles and store them in qlist list variable
116    org = np.array([0.0, 0.0, 0.0])
117    qlist = []
118    for l in range(-lmax, lmax+1):
119      for k in range(-kmax, kmax+1):
120        for h in range(-hmax, hmax+1):
121# Calculate distance in reciprocal space between (0, 0, 0) and (h, k, l)
122            G = distance(org, np.array([h, k, l]), Rgij)
123            if G < Gmin:
124                continue
125
126# Calculate lattice space from G
127            d = 1.0 / G
128
129            sinQ = wl / 2.0 / d
130            if sinQ >= 1.0:
131                continue
132            
133# Calculate diffraction angle 2Theta
134            Q2 = 2.0 * todeg * arcsin(sinQ)
135            if Q2 > Q2max:
136                continue
137
138            qlist.append([Q2, d, h, k, l])
139#            print("  2Q={:12.4g}  d={:12.6g}  ({:3d} {:3d} {:3d})".format(Q2, d, h, k, l))
140
141# Sort rlist by 2Theta (x[0] priority)
142    qlist.sort(key = lambda x: (x[0], x[2], x[3], x[4]))
143
144    print("")
145    print("Diffraction angle, d, h, k, l:")
146    for qinf in qlist:
147        Q2, d, h, k, l = qinf
148        print("  2Q={:12.4g}  d={:12.6g}  ({:3d} {:3d} {:3d})".format(Q2, d, h, k, l))
149
150    print("")
151    exit()
152
153
154if __name__ == '__main__':
155    main()