Skip to content

Commit 62aebb9

Browse files
author
Han Wang
committed
use nlist built by ase
1 parent 6b0c957 commit 62aebb9

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

dpdata/md/water.py

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,76 @@
11
import numpy as np
22
from .pbc import posi_diff
33

4-
def compute_bonds(box,
5-
posis,
6-
atype,
7-
oh_sel = [0,1],
8-
max_roh = 1.3,
9-
uniq_hbond = True):
4+
def compute_bonds (box,
5+
posis,
6+
atype,
7+
oh_sel = [0,1],
8+
max_roh = 1.3,
9+
uniq_hbond = True):
10+
try :
11+
import ase
12+
import ase.neighborlist
13+
# nlist implemented by ase
14+
return compute_bonds_ase(box, posis, atype, oh_sel, max_roh, uniq_hbond)
15+
except ImportError:
16+
# nlist naivly implemented , scales as O(N^2)
17+
return compute_bonds_naive(box, posis, atype, oh_sel, max_roh, uniq_hbond)
18+
19+
20+
def compute_bonds_ase(box,
21+
posis,
22+
atype,
23+
oh_sel = [0,1],
24+
max_roh = 1.3,
25+
uniq_hbond = True):
26+
natoms = len(posis)
27+
from ase import Atoms
28+
import ase.neighborlist
29+
atoms = Atoms(positions=posis, cell=box, pbc=[1,1,1])
30+
nlist = ase.neighborlist.NeighborList(max_roh, self_interaction=False, bothways=True, primitive=ase.neighborlist.NewPrimitiveNeighborList)
31+
nlist.update(atoms)
32+
bonds = []
33+
o_type = oh_sel[0]
34+
h_type = oh_sel[1]
35+
for ii in range(natoms) :
36+
bonds.append([])
37+
for ii in range(natoms) :
38+
if atype[ii] == o_type :
39+
nn, ss = nlist.get_neighbors(ii)
40+
for jj in nn:
41+
if atype[jj] == h_type :
42+
dr = posi_diff(box, posis[ii], posis[jj])
43+
if np.linalg.norm(dr) < max_roh :
44+
bonds[ii].append(jj)
45+
bonds[jj].append(ii)
46+
if uniq_hbond :
47+
for jj in range(natoms) :
48+
if atype[jj] == h_type :
49+
if len(bonds[jj]) > 1 :
50+
orig_bonds = bonds[jj]
51+
min_bd = 1e10
52+
min_idx = -1
53+
for ii in bonds[jj] :
54+
dr = posi_diff(box, posis[ii], posis[jj])
55+
drr = np.linalg.norm(dr)
56+
# print(ii,jj, posis[ii], posis[jj], drr)
57+
if drr < min_bd :
58+
min_idx = ii
59+
min_bd = drr
60+
bonds[jj] = [min_idx]
61+
orig_bonds.remove(min_idx)
62+
# print(min_idx, orig_bonds, bonds[jj])
63+
for ii in orig_bonds :
64+
bonds[ii].remove(jj)
65+
return bonds
66+
67+
68+
def compute_bonds_naive(box,
69+
posis,
70+
atype,
71+
oh_sel = [0,1],
72+
max_roh = 1.3,
73+
uniq_hbond = True):
1074
natoms = len(posis)
1175
bonds = []
1276
o_type = oh_sel[0]

tests/test_water_ions.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
import numpy as np
33
import unittest
44
from context import dpdata
5+
try:
6+
import ase
7+
import ase.neighborlist
8+
exist_ase=True
9+
except:
10+
exist_ase=False
511

612
class TestIons(unittest.TestCase):
713

@@ -13,7 +19,6 @@ def setUp(self):
1319
self.system.data['coords'][0],
1420
self.system.data['atom_types'])
1521

16-
1722
def test_ions_count(self) :
1823
no, noh, noh2, noh3, nh \
1924
= dpdata.md.water.find_ions(self.system.data['atom_types'], self.bonds)
@@ -25,6 +30,26 @@ def test_ions_count(self) :
2530
self.assertEqual(noh[0], 0)
2631
self.assertEqual(noh3[0], 51)
2732

33+
34+
@unittest.skipIf(not exist_ase, "skip TestAseComputeBond")
35+
class TestAseComputeBond(unittest.TestCase):
36+
def setUp(self):
37+
self.system = dpdata.System()
38+
self.system.from_lammps_lmp(os.path.join('poscars', 'conf.waterion.lmp'),
39+
type_map = ['O', 'H'])
40+
self.bonds = dpdata.md.water.compute_bonds_naive(self.system.data['cells'][0],
41+
self.system.data['coords'][0],
42+
self.system.data['atom_types'])
43+
self.bonds_ase = dpdata.md.water.compute_bonds_ase(self.system.data['cells'][0],
44+
self.system.data['coords'][0],
45+
self.system.data['atom_types'])
46+
47+
def test_bond_identity(self):
48+
self.assertTrue(len(self.bonds), len(self.bonds_ase))
49+
for ii in range(len(self.bonds)):
50+
self.assertTrue(set(self.bonds[ii]) == set(self.bonds_ase[ii]))
51+
52+
2853

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

0 commit comments

Comments
 (0)