#!/usr/bin/python3
import numpy as np
def _to_system_data_lower(lines, cartesian=True):
"""Treat as cartesian poscar."""
system = {}
system["atom_names"] = [str(ii) for ii in lines[5].split()]
system["atom_numbs"] = [int(ii) for ii in lines[6].split()]
scale = float(lines[1])
cell = []
for ii in range(2, 5):
boxv = [float(jj) for jj in lines[ii].split()]
boxv = np.array(boxv) * scale
cell.append(boxv)
system["cells"] = [np.array(cell)]
natoms = sum(system["atom_numbs"])
coord = []
for ii in range(8, 8 + natoms):
tmpv = [float(jj) for jj in lines[ii].split()[:3]]
if cartesian:
tmpv = np.array(tmpv) * scale
else:
tmpv = np.matmul(np.array(tmpv), system["cells"][0])
coord.append(tmpv)
system["coords"] = [np.array(coord)]
system["orig"] = np.zeros(3)
atom_types = []
for idx, ii in enumerate(system["atom_numbs"]):
for jj in range(ii):
atom_types.append(idx)
system["atom_types"] = np.array(atom_types, dtype=int)
system["cells"] = np.array(system["cells"])
system["coords"] = np.array(system["coords"])
return system
[docs]
def to_system_data(lines):
# remove the line that has 'selective dynamics'
if lines[7][0] == "S" or lines[7][0] == "s":
lines.pop(7)
is_cartesian = lines[7][0] in ["C", "c", "K", "k"]
if not is_cartesian:
if lines[7][0] not in ["d", "D"]:
raise RuntimeError(
"seem not to be a valid POSCAR of vasp 5.x, may be a POSCAR of vasp 4.x?"
)
return _to_system_data_lower(lines, is_cartesian)
[docs]
def from_system_data(system, f_idx=0, skip_zeros=True):
ret = ""
for ii, name in zip(system["atom_numbs"], system["atom_names"]):
if ii == 0:
continue
ret += "%s%d " % (name, ii)
ret += "\n"
ret += "1.0\n"
for ii in system["cells"][f_idx]:
for jj in ii:
ret += f"{jj:.16e} "
ret += "\n"
for idx, ii in enumerate(system["atom_names"]):
if system["atom_numbs"][idx] == 0:
continue
ret += f"{ii} "
ret += "\n"
for ii in system["atom_numbs"]:
if ii == 0:
continue
ret += "%d " % ii
ret += "\n"
# should use Cartesian for VESTA software
ret += "Cartesian\n"
atype = system["atom_types"]
posis = system["coords"][f_idx]
# atype_idx = [[idx,tt] for idx,tt in enumerate(atype)]
# sort_idx = np.argsort(atype, kind = 'mergesort')
sort_idx = np.lexsort((np.arange(len(atype)), atype))
atype = atype[sort_idx]
posis = posis[sort_idx]
posi_list = []
for ii in posis:
posi_list.append(f"{ii[0]:15.10f} {ii[1]:15.10f} {ii[2]:15.10f}")
posi_list.append("")
ret += "\n".join(posi_list)
return ret