Skip to content

Commit

Permalink
Support of all lammps dump coordinate style (#179)
Browse files Browse the repository at this point in the history
* Update dump.py

* Create test_lammps_dump_unfold.py

* Create conf_unfold.dump

* Update dump.py

* Create conf_s_su.dump

* Create test_lammps_dump_s_su.py

* Update dump.py

* Update conf_unfold.dump

* Update dump.py
  • Loading branch information
xfanak authored Aug 4, 2021
1 parent 980f297 commit 73ad164
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 36 deletions.
65 changes: 29 additions & 36 deletions dpdata/lammps/dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,45 +51,38 @@ def get_natoms_vec(lines) :
assert (sum(natoms_vec) == get_natoms(lines))
return natoms_vec

def get_posi(lines) :
def get_coordtype_and_scalefactor(keys):
# 4 types in total,with different scaling factor
key_pc=['x','y','z'] # plain cartesian, sf = 1
key_uc=['xu','yu','zu'] # unwraped cartesian, sf = 1
key_s=['xs','ys','zs'] # scaled by lattice parameter, sf = lattice parameter
key_su = ['xsu','ysu','zsu'] #scaled and unfolded,sf = lattice parameter
lmp_coor_type = [key_pc,key_uc,key_s,key_su]
sf = [0,0,1,1]
for k in range(4):
if all(i in keys for i in lmp_coor_type[k]):
return lmp_coor_type[k],sf[k]

def safe_get_posi(lines,cell,orig=np.zeros(3)) :
blk, head = _get_block(lines, 'ATOMS')
keys = head.split()
coord_tp_and_sf = get_coordtype_and_scalefactor(keys)
assert coord_tp_and_sf is not None, 'Dump file does not contain atomic coordinates!'
coordtype, sf = coord_tp_and_sf
id_idx = keys.index('id') - 2
xidx = keys.index('x') - 2
yidx = keys.index('y') - 2
zidx = keys.index('z') - 2
xidx = keys.index(coordtype[0])-2
yidx = keys.index(coordtype[1])-2
zidx = keys.index(coordtype[2])-2
sel = (xidx, yidx, zidx)
posis = []
for ii in blk :
words = ii.split()
posis.append([float(words[id_idx]), float(words[xidx]), float(words[yidx]), float(words[zidx])])
posis.sort()
posis = np.array(posis)
return posis[:,1:4]

def get_posi_frac(lines) :
blk, head = _get_block(lines, 'ATOMS')
keys = head.split()
id_idx = keys.index('id') - 2
xidx = keys.index('xs') - 2
yidx = keys.index('ys') - 2
zidx = keys.index('zs') - 2
sel = (xidx, yidx, zidx)
posis = []
for ii in blk :
words = ii.split()
posis.append([float(words[id_idx]), float(words[xidx]), float(words[yidx]), float(words[zidx])])
posis.sort()
posis = np.array(posis)
return posis[:,1:4]

def safe_get_posi(lines, cell, orig = np.zeros(3)):
try:
posis = get_posi(lines) - orig
except ValueError:
fposis = get_posi_frac(lines)
posis = fposis @ cell
return posis
posis = np.array(posis)[:,1:4]
if not sf:
posis = (posis-orig)@np.linalg.inv(cell)# Convert to scaled coordinates for unscaled coordinates
return (posis%1)@cell # Convert scaled coordinates back to Cartesien coordinates

def get_dumpbox(lines) :
blk, h = _get_block(lines, 'BOX BOUNDS')
Expand Down Expand Up @@ -211,16 +204,16 @@ def split_traj(dump_lines) :
# # print(get_natomtypes(lines))
# # print(get_natoms_vec(lines))
# posi = get_posi(lines)
# dbox, tilt = get_dumpbox(lines)
# orig, box = dumpbox2box(dbox, tilt)
# dbox1, tilt1 = box2dumpbox(orig, box)
# print(dbox - dbox1)
# print(tilt - tilt1)
# print(orig)
# print(box)
# np.savetxt('tmp.out', posi - orig, fmt='%.6f')
# print(system_data(lines))

lines = load_file('conf.5.dump', begin = 0, step = 2)
with open('tmp.out', 'w') as fp:
fp.write('\n'.join(lines))
lines = load_file('conf_unfold.dump', begin = 0, step = 1)
al = split_traj(lines)
s = system_data(lines,['O','H'])
#l = np.linalg.norm(s['cells'][1],axis=1)
#p = s['coords'][0] + l
#np.savetxt('p',p,fmt='%1.10f')
22 changes: 22 additions & 0 deletions tests/poscars/conf_s_su.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ITEM: TIMESTEP
0
ITEM: NUMBER OF ATOMS
2
ITEM: BOX BOUNDS xy xz yz pp pp pp
0.0 5.0739861 1.2621856
0.0 2.7916155 1.2874292
0.0 2.2254033 0.7485898
ITEM: ATOMS id type xs ys zs
1 1 0.0 0.0 0.0
2 2 0.2472745002 0.2527254533 0.2477701458
ITEM: TIMESTEP
1
ITEM: NUMBER OF ATOMS
2
ITEM: BOX BOUNDS xy xz yz pp pp pp
0.0 5.0739861 1.2621856
0.0 2.7916155 1.2874292
0.0 2.2254033 0.7485898
ITEM: ATOMS id type xsu ysu zsu
1 1 0.0 0.0 0.0
2 2 1.2472745002 1.2527254533 1.2477701458
22 changes: 22 additions & 0 deletions tests/poscars/conf_unfold.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ITEM: TIMESTEP
0
ITEM: NUMBER OF ATOMS
2
ITEM: BOX BOUNDS xy xz yz pp pp pp
0.0 5.0739861 1.2621856
0.0 2.7916155 1.2874292
0.0 2.2254033 0.7485898
ITEM: ATOMS id type xu yu zu
1 1 5.073986099999999944e+00 2.791615499999999805e+00 2.225403299999999973e+00
2 2 6.336171700000000406e+00 3.493418300000000087e+00 2.776791800099999818e+00
ITEM: TIMESTEP
0
ITEM: NUMBER OF ATOMS
2
ITEM: BOX BOUNDS xy xz yz pp pp pp
0.0 5.0739861 1.2621856
0.0 2.7916155 1.2874292
1.0 3.2254033 0.7485898
ITEM: ATOMS id type xu yu zu
1 1 5.073986099999999944e+00 2.791615499999999805e+00 3.225403299999999973e+00
2 2 6.336171700000000406e+00 3.493418300000000087e+00 3.776791800099999818e+00
26 changes: 26 additions & 0 deletions tests/poscars/test_lammps_dump_s_su.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
import numpy as np
import unittest
from context import dpdata
from poscars.poscar_ref_oh import TestPOSCARoh

class TestDump(unittest.TestCase, TestPOSCARoh):

def setUp(self):
self.system = dpdata.System(os.path.join('poscars', 'conf_s_su.dump'),
type_map = ['O', 'H'])

class TestDump2(unittest.TestCase, TestPOSCARoh):

def setUp(self):
self.tmp_system = dpdata.System(os.path.join('poscars', 'conf_s_su.dump'),
type_map = ['O', 'H'])
self.system = self.tmp_system.sub_system([1])

def test_nframes (self) :
self.assertEqual(self.tmp_system.get_nframes(), 2)


if __name__ == '__main__':
unittest.main()

26 changes: 26 additions & 0 deletions tests/test_lammps_dump_unfold.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
import numpy as np
import unittest
from context import dpdata
from poscars.poscar_ref_oh import TestPOSCARoh

class TestDump(unittest.TestCase, TestPOSCARoh):

def setUp(self):
self.system = dpdata.System(os.path.join('poscars', 'conf_unfold.dump'),
type_map = ['O', 'H'])

class TestDump2(unittest.TestCase, TestPOSCARoh):

def setUp(self):
self.tmp_system = dpdata.System(os.path.join('poscars', 'conf_unfold.dump'),
type_map = ['O', 'H'])
self.system = self.tmp_system.sub_system([1])

def test_nframes (self) :
self.assertEqual(self.tmp_system.get_nframes(), 2)


if __name__ == '__main__':
unittest.main()

0 comments on commit 73ad164

Please sign in to comment.