interatomic_distance.py ダウンロード/コピー
interatomic_distance.py をダウンロード
interatomic_distance.py
interatomic_distance.py
1import sys
2import os
3from numpy import sin, cos, tan, arcsin, arccos, arctan, exp, log, sqrt
4import numpy as np
5from numpy import linalg as la
6from mpl_toolkits.mplot3d import Axes3D
7import matplotlib.pyplot as plt
8
9from tkcrystalbase import *
10
11
12"""
13概要: 原子間距離を計算するためのスクリプト。
14詳細説明:
15 結晶構造の格子パラメータとサイト情報に基づいて、指定された距離範囲内の原子間距離を計算し、表示します。
16 TKCrystalBaseモジュールに依存しており、結晶学的な計算(格子ベクトル、計量テンソルなど)はそのモジュールが提供する関数を使用します。
17 計算された原子間距離は、サイトの組み合わせと周期境界条件を考慮した単位胞の並進ベクトルと共にソートして出力されます。
18関連リンク: :doc:`interatomic_distance_usage`
19"""
20
21
22# Lattice parameters (angstrom and degree)
23#lattice_parameters = [ 5.62, 5.62, 5.62, 60.0, 60.0, 60.0]
24lattice_parameters = [ 5.62, 5.62, 5.62, 90.0, 90.0, 90.0]
25
26# Site information (atom name, site label, atomic number, atomic mass, charge, radius, color, position)
27sites = [
28 ['Na', 'Na1', 11, 22.98997, +1.0, 0.7, 'red', np.array([0.0, 0.0, 0.0])]
29 ,['Na', 'Na2', 11, 22.98997, +1.0, 0.7, 'red', np.array([0.0, 0.5, 0.5])]
30 ,['Na', 'Na3', 11, 22.98997, +1.0, 0.7, 'red', np.array([0.5, 0.0, 0.5])]
31 ,['Na', 'Na4', 11, 22.98997, +1.0, 0.7, 'red', np.array([0.5, 0.5, 0.0])]
32 ,['Cl', 'Cl1', 17, 35.4527, -1.0, 1.4, 'blue', np.array([0.5, 0.0, 0.0])]
33 ,['Cl', 'Cl2', 17, 35.4527, -1.0, 1.4, 'blue', np.array([0.5, 0.5, 0.5])]
34 ,['Cl', 'Cl3', 17, 35.4527, -1.0, 1.4, 'blue', np.array([0.0, 0.0, 0.5])]
35 ,['Cl', 'Cl4', 17, 35.4527, -1.0, 1.4, 'blue', np.array([0.0, 0.5, 0.0])]
36 ]
37
38# Distance range
39rmin = 0.1 # angstrom. used to judge identical site
40rmax = 4.5 # angstrom.
41
42
43def main():
44 """
45 概要: プログラムの主要な処理を実行し、原子間距離を計算して出力する。
46 詳細説明:
47 この関数は以下のステップを実行します。
48 1. 与えられた格子パラメータから格子ベクトル、計量テンソル、単位胞体積、およびそれらの逆格子版を計算し、標準出力に表示します。
49 2. 原子間距離の計算範囲 `rmax` に基づいて、考慮すべき単位胞の最大並進数 (`nxmax`, `nymax`, `nzmax`) を決定します。
50 3. `sites` リストに定義された全ての原子サイトのペアについて、計算された単位胞の並進範囲内で原子間距離を計算します。
51 4. 計算された距離が `rmin` と `rmax` の間にある場合、その距離と関連するサイト情報、並進ベクトルを `rlist` に追加します。
52 5. `rlist` を距離でソートした後、結果を整形して標準出力に表示します。
53 """
54 print("")
55 print("Lattice parameters:", lattice_parameters)
56 aij = cal_lattice_vectors(lattice_parameters)
57 print("Lattice vectors:")
58 print(" ax: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(aij[0][0], aij[0][1], aij[0][2]))
59 print(" ay: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(aij[1][0], aij[1][1], aij[1][2]))
60 print(" az: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(aij[2][0], aij[2][1], aij[2][2]))
61 inf = cal_metrics(lattice_parameters)
62 gij = inf['gij']
63 print("Metric tensor:")
64 print(" gij: ({:10.4g}, {:10.4g}, {:10.4g}) A".format(*gij[0]))
65 print(" ({:10.4g}, {:10.4g}, {:10.4g}) A".format(*gij[1]))
66 print(" ({:10.4g}, {:10.4g}, {:10.4g}) A".format(*gij[2]))
67 print("")
68 volume = cal_volume(aij)
69 print("Volume: {:12.4g} A^3".format(volume))
70
71 print("")
72 print("Unit cell volume: {:12.4g} A^3".format(volume))
73 Raij = cal_reciprocal_lattice_vectors(aij)
74 Rlatt = cal_reciprocal_lattice_parameters(Raij)
75 Rinf = cal_metrics(Rlatt)
76 Rgij = Rinf['gij']
77 print("Reciprocal lattice parameters:", Rlatt)
78 print("Reciprocal lattice vectors:")
79 print(" Rax: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Raij[0]))
80 print(" Ray: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Raij[1]))
81 print(" Raz: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Raij[2]))
82 print("Reciprocal lattice metric tensor:")
83 print(" Rgij: ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Rgij[0]))
84 print(" ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Rgij[1]))
85 print(" ({:10.4g}, {:10.4g}, {:10.4g}) A^-1".format(*Rgij[2]))
86 Rvolume = cal_volume(Raij)
87 print("Reciprocal unit cell volume: {:12.4g} A^-3".format(Rvolume))
88
89# Calculate the range of unit cells
90 nxmax = int(rmax / lattice_parameters[0]) + 1
91 nymax = int(rmax / lattice_parameters[1]) + 1
92 nzmax = int(rmax / lattice_parameters[2]) + 1
93 print("")
94 print("nmax:", nxmax, nymax, nzmax)
95
96# Calculate interatomic distances and store them in rlist list variable
97 rlist = []
98 for isite0 in range(len(sites)):
99 site0 = sites[isite0]
100 name0, label0, z0, M0, q0, r0, color0, pos0 = site0
101 for isite1 in range(len(sites)):
102 site1 = sites[isite1]
103 name1, label1, z1, M1, q1, r1, color1, pos1 = site1
104 for iz in range(-nzmax, nzmax+1):
105 for iy in range(-nymax, nymax+1):
106 for ix in range(-nxmax, nxmax+1):
107 dis = distance(pos0, pos1 + np.array([ix, iy, iz]), gij)
108 if dis < rmin or rmax < dis:
109 continue
110
111 rlist.append([dis, site0, site1, ix, iy, iz])
112
113# print(" {:4} ({:8.4g}, {:8.4g}, {:8.4g}) - {:4} ({:8.4g}, {:8.4g}, {:8.4g}) + ({:2d}, {:2d}, {:2d}): dis = {:10.4g} A"
114# .format(label0, pos0[0], pos0[1], pos0[2], label1, pos1[0], pos1[1], pos1[2], ix, iy, iz, dis))
115
116# Sort rlist by distance (x[0] priority)
117 rlist.sort(key = lambda x: (x[0], x[1], x[3], x[4], x[5], x[2]))
118
119 print("")
120 print("Interatomic distances:")
121 for rinf in rlist:
122 dis, site0, site1, ix, iy, iz = rinf
123 name0, label0, z0, M0, q0, r0, color0, pos0 = site0
124 name1, label1, z1, M1, q1, r1, color1, pos1 = site1
125 print(" {:4} ({:8.4g}, {:8.4g}, {:8.4g}) - {:4} ({:8.4g}, {:8.4g}, {:8.4g}) + ({:2d}, {:2d}, {:2d}): dis = {:10.4g} A"
126 .format(label0, pos0[0], pos0[1], pos0[2], label1, pos1[0], pos1[1], pos1[2], ix, iy, iz, dis))
127
128 print("")
129 exit()
130
131
132if __name__ == '__main__':
133 main()