|
| 1 | +import numpy as np |
| 2 | + |
| 3 | +def system_info (lines, type_idx_zero = False) : |
| 4 | + atom_names = [] |
| 5 | + atom_numbs = [] |
| 6 | + nelm = 0 |
| 7 | + natoms = int(lines[0].split()[0]) |
| 8 | + iteration = float(lines[0].split('Etot')[0].split('=')[1].split(',')[0]) |
| 9 | +# print(iteration) |
| 10 | + if iteration > 0 : |
| 11 | + nelm = 40 |
| 12 | + else: |
| 13 | + nelm = 100 |
| 14 | + atomic_number = [] |
| 15 | + for idx,ii in enumerate(lines): |
| 16 | + if 'Position' in ii: |
| 17 | + for kk in range(idx+1,idx+1+natoms) : |
| 18 | + min = kk |
| 19 | + for jj in range(kk+1,idx+1+natoms): |
| 20 | + if int(lines[jj].split()[0]) < int(lines[min].split()[0]): |
| 21 | + min = jj |
| 22 | + lines[min], lines[kk] = lines[kk],lines[min] |
| 23 | + for gg in range(idx+1,idx+1+natoms): |
| 24 | + tmpn = int(lines[gg].split()[0]) |
| 25 | + atomic_number.append(tmpn) |
| 26 | + for ii in np.unique(sorted(atomic_number)) : |
| 27 | + atom_numbs.append(atomic_number.count(ii)) |
| 28 | + atom_types = [] |
| 29 | + for idx,ii in enumerate(atom_numbs) : |
| 30 | + for jj in range(ii) : |
| 31 | + if type_idx_zero : |
| 32 | + atom_types.append(idx) |
| 33 | + else : |
| 34 | + atom_types.append(idx+1) |
| 35 | + ELEMENTS=['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca', \ |
| 36 | + 'Sc', 'Ti', 'V', 'Cr','Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y', 'Zr', \ |
| 37 | + 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd',\ |
| 38 | + 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', \ |
| 39 | + 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm', \ |
| 40 | + 'Md', 'No', 'Lr'] |
| 41 | + for ii in np.unique(sorted(atomic_number)): |
| 42 | + atom_names.append(ELEMENTS[ii-1]) |
| 43 | + return atom_names, atom_numbs, np.array(atom_types, dtype = int), nelm |
| 44 | + |
| 45 | + |
| 46 | +def get_movement_block(fp) : |
| 47 | + blk = [] |
| 48 | + for ii in fp : |
| 49 | + if not ii: |
| 50 | + return blk |
| 51 | + blk.append(ii.rstrip('\n')) |
| 52 | + if '------------' in ii: |
| 53 | + return blk |
| 54 | + return blk |
| 55 | + |
| 56 | +# we assume that the force is printed ... |
| 57 | +def get_frames (fname, begin = 0, step = 1) : |
| 58 | + fp = open(fname) |
| 59 | + blk = get_movement_block(fp) |
| 60 | + |
| 61 | + atom_names, atom_numbs, atom_types, nelm = system_info(blk, type_idx_zero = True) |
| 62 | + ntot = sum(atom_numbs) |
| 63 | + |
| 64 | + all_coords = [] |
| 65 | + all_cells = [] |
| 66 | + all_energies = [] |
| 67 | + all_atomic_energy = [] |
| 68 | + all_forces = [] |
| 69 | + all_virials = [] |
| 70 | + |
| 71 | + cc = 0 |
| 72 | + while len(blk) > 0 : |
| 73 | + if cc >= begin and (cc - begin) % step == 0 : |
| 74 | + coord, cell, energy, force, virial, is_converge = analyze_block(blk, ntot, nelm) |
| 75 | + if is_converge : |
| 76 | + if len(coord) == 0: |
| 77 | + break |
| 78 | + all_coords.append(coord) |
| 79 | + all_cells.append(cell) |
| 80 | + all_energies.append(energy) |
| 81 | + all_forces.append(force) |
| 82 | + if virial is not None : |
| 83 | + all_virials.append(virial) |
| 84 | + blk = get_movement_block(fp) |
| 85 | + cc += 1 |
| 86 | + |
| 87 | + if len(all_virials) == 0 : |
| 88 | + all_virials = None |
| 89 | + else : |
| 90 | + all_virials = np.array(all_virials) |
| 91 | + fp.close() |
| 92 | + return atom_names, atom_numbs, atom_types, np.array(all_cells), np.array(all_coords), \ |
| 93 | + np.array(all_energies), np.array(all_forces), all_virials |
| 94 | + |
| 95 | + |
| 96 | +def analyze_block(lines, ntot, nelm) : |
| 97 | + coord = [] |
| 98 | + cell = [] |
| 99 | + energy = None |
| 100 | +# atomic_energy = [] |
| 101 | + force = [] |
| 102 | + virial = None |
| 103 | + is_converge = True |
| 104 | + sc_index = 0 |
| 105 | + for idx,ii in enumerate(lines) : |
| 106 | + if 'Iteration' in ii: |
| 107 | + sc_index = int(ii.split('SCF =')[1]) |
| 108 | + if sc_index >= nelm: |
| 109 | + is_converge = False |
| 110 | + energy = float(ii.split('Etot,Ep,Ek (eV)')[1].split()[1]) |
| 111 | + elif '----------' in ii: |
| 112 | + assert((force is not None) and len(coord) > 0 and len(cell) > 0) |
| 113 | + # all_coords.append(coord) |
| 114 | + # all_cells.append(cell) |
| 115 | + # all_energies.append(energy) |
| 116 | + # all_forces.append(force) |
| 117 | + # if virial is not None : |
| 118 | + # all_virials.append(virial) |
| 119 | + return coord, cell, energy, force, virial, is_converge |
| 120 | +# elif 'NPT' in ii: |
| 121 | +# tmp_v = [] |
| 122 | + elif 'Lattice vector' in ii: |
| 123 | + if 'stress' in lines[idx+1]: |
| 124 | + tmp_v = [] |
| 125 | + for dd in range(3) : |
| 126 | + tmp_l = lines[idx+1+dd] |
| 127 | + cell.append([float(ss) |
| 128 | + for ss in tmp_l.split()[0:3]]) |
| 129 | + tmp_v.append([float(stress) for stress in tmp_l.split()[5:8]]) |
| 130 | + virial = np.zeros([3,3]) |
| 131 | + virial[0][0] = tmp_v[0][0] |
| 132 | + virial[0][1] = tmp_v[0][1] |
| 133 | + virial[0][2] = tmp_v[0][2] |
| 134 | + virial[1][0] = tmp_v[1][0] |
| 135 | + virial[1][1] = tmp_v[1][1] |
| 136 | + virial[1][2] = tmp_v[1][2] |
| 137 | + virial[2][0] = tmp_v[2][0] |
| 138 | + virial[2][1] = tmp_v[2][1] |
| 139 | + virial[2][2] = tmp_v[2][2] |
| 140 | + volume = np.linalg.det(np.array(cell)) |
| 141 | + virial = virial*160.2*10.0/volume |
| 142 | + else: |
| 143 | + for dd in range(3) : |
| 144 | + tmp_l = lines[idx+1+dd] |
| 145 | + cell.append([float(ss) |
| 146 | + for ss in tmp_l.split()[0:3]]) |
| 147 | + |
| 148 | +# else : |
| 149 | +# for dd in range(3) : |
| 150 | +# tmp_l = lines[idx+1+dd] |
| 151 | +# cell.append([float(ss) |
| 152 | +# for ss in tmp_l.split()[0:3]]) |
| 153 | +# virial = np.zeros([3,3]) |
| 154 | + elif 'Position' in ii: |
| 155 | + for kk in range(idx+1, idx+1+ntot): |
| 156 | + min = kk |
| 157 | + for jj in range(kk+1,idx+1+ntot): |
| 158 | + if int(lines[jj].split()[0]) < int(lines[min].split()[0]): |
| 159 | + min = jj |
| 160 | + lines[min], lines[kk] = lines[kk],lines[min] |
| 161 | + for gg in range(idx+1,idx+1+ntot): |
| 162 | + info = [float(jj) for jj in lines[gg].split()[1:4]] |
| 163 | + info = np.matmul(np.array(info),np.array(cell)) |
| 164 | + coord.append(info) |
| 165 | + elif 'Force' in ii: |
| 166 | + for kk in range(idx+1, idx+1+ntot): |
| 167 | + min = kk |
| 168 | + for jj in range(kk+1,idx+1+ntot): |
| 169 | + if int(lines[jj].split()[0]) < int(lines[min].split()[0]): |
| 170 | + min = jj |
| 171 | + lines[min], lines[kk] = lines[kk],lines[min] |
| 172 | + for gg in range(idx+1,idx+1+ntot): |
| 173 | + info = [float(ss) for ss in lines[gg].split()] |
| 174 | + force.append(info[1:4]) |
| 175 | +# elif 'Atomic-Energy' in ii: |
| 176 | +# for jj in range(idx+1, idx+1+ntot) : |
| 177 | +# tmp_l = lines[jj] |
| 178 | +# info = [float(ss) for ss in tmp_l.split()] |
| 179 | +# atomic_energy.append(info[1]) |
| 180 | + return coord, cell, energy, force, virial, is_converge |
0 commit comments