# !/usr/bin/python3
import numpy as np
ev2ev = 1
ang2ang = 1
#############################read output#####################################
[docs]
def get_single_line_tail(fin, keyword, num=1):
file = open(fin)
part_res = []
for value in file:
if keyword in value:
temp = len(value.split()) - num
part_res.append(float(value.split()[temp]))
file.close()
return part_res
## atomnum: number of atoms, row numbers
## begin_column: begin column num
## read_column_num: read column num
## column_num: the column number in nxet reading line
[docs]
def obtain_nframe(fname):
fp = open(fname)
flag = False
idx = 0
temp = 0
for ii in fp:
if "siesta: Stress tensor (static) (eV/Ang**3):" in ii:
flag = True
continue
if flag:
if "siesta: Pressure (static):" not in ii:
if len(ii.split()) == 3:
temp += 1
if temp == 3:
idx += 1
# print(idx)
flag = False
temp = 0
fp.close()
return idx
[docs]
def get_atom_types(fout, atomnums):
covert_type = extract_keyword(
fout, "outcoor: Atomic coordinates (Ang):", atomnums, 3, 4, 0, 6
)[0]
atomtype = []
# print(covert_type)
for i in range(0, len(covert_type)):
atomtype.append(int(covert_type[i]) - 1)
return atomtype
[docs]
def get_atom_name(fout):
file = open(fout)
ret = []
for value in file:
if "Species number:" in value:
for j in range(len(value.split())):
if value.split()[j] == "Label:":
ret.append(value.split()[j + 1])
break
file.close()
return ret
[docs]
def get_atom_numbs(atomtypes):
atom_numbs = []
for i in set(atomtypes):
atom_numbs.append(atomtypes.count(i))
return atom_numbs
[docs]
def get_virial(fout, cell):
viri = extract_keyword(
fout, "siesta: Stress tensor (static) (eV/Ang**3):", 3, 0, 3, 1, 3
)
vols = []
length = obtain_nframe(fout)
for ii in range(length):
vols.append(np.linalg.det(cell[ii].reshape([3, 3])))
for jj in range(len(viri[ii])):
## siesta: 1eV/A^3= 1.60217*10^11 Pa , ---> qe: kBar=10^8Pa
# ii *= vols[idx] * 1e3 / 1.602176621e6 * (1.602176621e3)
viri[ii][jj] *= vols[ii]
return viri
[docs]
def covert_dimension(arr, num):
arr = np.array(arr)
frames = len(arr)
ret = np.zeros((frames, num, 3))
for i in range(frames):
ret[i] = arr[i].reshape(num, 3)
return ret
[docs]
def get_aiMD_frame(fname):
NumberOfSpecies = int(
get_single_line_tail(fname, "redata: Number of Atomic Species")[0]
)
atom_names = get_atom_name(fname)
tot_natoms = int(get_single_line_tail(fname, "Number of atoms", 3)[0])
atom_types = get_atom_types(fname, tot_natoms)
atom_numbs = get_atom_numbs(atom_types)
assert max(atom_types) + 1 == NumberOfSpecies
cell = extract_keyword(fname, "outcell: Unit cell vectors (Ang):", 3, 0, 3, 1, 3)
coord = extract_keyword(
fname, "outcoor: Atomic coordinates (Ang):", tot_natoms, 0, 3, 1, 6
)
energy = get_single_line_tail(fname, "siesta: E_KS(eV) =")
force = extract_keyword(
fname, "siesta: Atomic forces (eV/Ang):", tot_natoms, 1, 4, 1, 4
)
virial = get_virial(fname, cell)
cells = covert_dimension(np.array(cell), 3)
coords = covert_dimension(np.array(coord), tot_natoms)
forces = covert_dimension(np.array(force), tot_natoms)
virials = covert_dimension(np.array(virial), 3)
return (
atom_names,
atom_numbs,
np.array(atom_types),
cells,
coords,
np.array(energy),
forces,
virials,
)