1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
   | 
 
 
 
 
 
  import subprocess import numpy as np import sys
 
  def dist(a,b):     """ read coordinates of two points and return distance of two points"""     """vector module -->  |A - B|"""          distance = np.linalg.norm(a-b)     return distance     
  def angle(a,b,c):     """read coordinates of three points and return angle of <a_b_c"""     """cos_AB = A * B / (|A| * |B|)"""     cos_abc = np.dot(a-b, c-b) / (np.linalg.norm(a-b) * np.linalg.norm(c-b))     angle_abc = np.arccos(cos_abc) * 180 / np.pi     return angle_abc
       def diheral_angle(a,b,c,d):     """read coordinates of four points and return diheral angle of plane abc and bcd"""     NormVect_abc = np.cross(b-a,c-a)       NormVect_bcd = np.cross(b-c,d-c)     cosA = np.dot(NormVect_abc,NormVect_bcd) / (np.linalg.norm(NormVect_abc) * np.linalg.norm(NormVect_bcd))     angle_A = np.arccos(cosA) * 180 / np.pi     if angle_A > 90:         return 180 - angle_A     else:         return angle_A
 
  def file_process(CONTCAR):     """read data from CONTCAR file and return the distance between ATOM1 and Atom2"""               cmd1 = "sed -n 6p " + CONTCAR + " > atom_names"     cmd2 = "sed -n 7p " + CONTCAR + " > atom_nums"     cmd3 = "sed -n 3,5p " + CONTCAR + " > vect"     cmd4 = "sed 1,8d " + CONTCAR + " | grep -v E > atom_coors"     subprocess.call(cmd1,shell=True)     subprocess.call(cmd2,shell=True)     subprocess.call(cmd3,shell=True)     subprocess.call(cmd4,shell=True)               matrix_trans = np.loadtxt('vect')       atom_nums = np.loadtxt('atom_nums').astype(int)       coor = np.loadtxt('atom_coors')       with open('atom_names','r') as f:         atom_names = f.readline().split()           name = []         for i in range(len(atom_names)):             for j in range(atom_nums[i]):                 name.append(atom_names[i]+str(j+1))                        subprocess.run("rm atom_* vect",shell=True)       return matrix_trans,coor,name
 
  def distAB(CONTCAR,Atom1,Atom2):         matrix_trans,coor,name = file_process(CONTCAR)      a = np.dot(matrix_trans.T,coor[name.index(Atom1)])     b = np.dot(matrix_trans.T,coor[name.index(Atom2)])                           dist_value = dist(a,b)         return dist_value           def angleABC(CONTCAR,Atom1,Atom2,Atom3):     matrix_trans,coor,name = file_process(CONTCAR)     a = np.dot(matrix_trans.T,coor[name.index(Atom1)])     b = np.dot(matrix_trans.T,coor[name.index(Atom2)])     c = np.dot(matrix_trans.T,coor[name.index(Atom3)])                  angle_value = angle(a,b,c)         return angle_value     
  def diheralABCD(CONTCAR,Atom1,Atom2,Atom3,Atom4):     matrix_trans,coor,name = file_process(CONTCAR)               a = np.dot(matrix_trans.T,coor[name.index(Atom1)])     b = np.dot(matrix_trans.T,coor[name.index(Atom2)])     c = np.dot(matrix_trans.T,coor[name.index(Atom3)])     d = np.dot(matrix_trans.T,coor[name.index(Atom4)])     angle_value = diheral_angle(a,b,c,d)         return angle_value     
 
  ArgvNum = len(sys.argv) Atom = [] for i in range(ArgvNum):     Atom.append(sys.argv[i]) cmd5 = 'bash -c "find -type f -name CONTCAR"' files = subprocess.Popen(cmd5,stdout=subprocess.PIPE).stdout.read().decode(encoding="utf-8").split()
  value_list = [] file_name_list = [] for CONTCAR in files:     file_name_list.append(CONTCAR.lstrip('./').rstrip('CONTCAR').replace('/','__'))     if ArgvNum == 3:         value = distAB(CONTCAR,Atom[1],Atom[2])     elif ArgvNum == 4:         value = angleABC(CONTCAR,Atom[1],Atom[2],Atom[3])     elif ArgvNum == 5:         value = diheralABCD(CONTCAR,Atom[1],Atom[2],Atom[3],Atom[4])     else:         break     value_list.append(value)
  with open('output.dat', 'w') as file:     file.write("species"+" " * 13 + "values\n")     for i in range(len(files)):         file.write("{:<20}{:>.3f}\n".format(file_name_list[i],value_list[i]))
 
  |