diff --git a/dpdata/lammps/dump.py b/dpdata/lammps/dump.py index 74fdb6530..7136d3e63 100644 --- a/dpdata/lammps/dump.py +++ b/dpdata/lammps/dump.py @@ -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') @@ -211,8 +204,6 @@ 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) @@ -220,7 +211,9 @@ def split_traj(dump_lines) : # 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') diff --git a/tests/poscars/conf_s_su.dump b/tests/poscars/conf_s_su.dump new file mode 100644 index 000000000..8cc97b775 --- /dev/null +++ b/tests/poscars/conf_s_su.dump @@ -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 diff --git a/tests/poscars/conf_unfold.dump b/tests/poscars/conf_unfold.dump new file mode 100644 index 000000000..3d46a9f44 --- /dev/null +++ b/tests/poscars/conf_unfold.dump @@ -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 diff --git a/tests/poscars/test_lammps_dump_s_su.py b/tests/poscars/test_lammps_dump_s_su.py new file mode 100644 index 000000000..2370cffc4 --- /dev/null +++ b/tests/poscars/test_lammps_dump_s_su.py @@ -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() + diff --git a/tests/test_lammps_dump_unfold.py b/tests/test_lammps_dump_unfold.py new file mode 100644 index 000000000..4ffd5f730 --- /dev/null +++ b/tests/test_lammps_dump_unfold.py @@ -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() +