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()