Skip to content

Commit a1cb245

Browse files
authored
Merge pull request #134 from deepmodeling/devel
merge recent development on devel to master
2 parents f150dd1 + 3443aec commit a1cb245

24 files changed

+4679
-1934
lines changed

.github/workflows/test.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Python package
2+
3+
on:
4+
- push
5+
- pull_request
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
python-version: [3.6, 3.7, 3.8]
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
- name: Set up Python ${{ matrix.python-version }}
17+
uses: actions/setup-python@v2
18+
with:
19+
python-version: ${{ matrix.python-version }}
20+
- name: Install dependencies
21+
run: pip install . coverage codecov
22+
- name: Test
23+
run: cd tests && coverage run --source=../dpdata -m unittest && cd .. && coverage combine tests/.coverage && coverage report
24+
- run: codecov

.travis.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,13 @@ perturbed_system = dpdata.System('./POSCAR').perturb(pert_num=3,
197197
atom_pert_style='normal')
198198
print(perturbed_system.data)
199199
```
200+
201+
## replace
202+
By the following example, Random 8 Hf atoms in the system will be replaced by Zr atoms with the atom postion unchanged.
203+
```python
204+
s=dpdata.System('tests/poscars/POSCAR.P42nmc',fmt='vasp/poscar')
205+
s.replace('Hf', 'Zr', 8)
206+
s.to_vasp_poscar('POSCAR.P42nmc.replace')
207+
```
208+
209+

dpdata/cp2k/output.py

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,12 @@ def handle_single_xyz_frame(self, lines):
190190
element_index +=1
191191
element_dict[line_list[0]]=[element_index,1]
192192
atom_types_list.append(element_dict[line_list[0]][0])
193-
coords_list.append([float(line_list[1])*AU_TO_ANG,
194-
float(line_list[2])*AU_TO_ANG,
195-
float(line_list[3])*AU_TO_ANG])
193+
# coords_list.append([float(line_list[1])*AU_TO_ANG,
194+
# float(line_list[2])*AU_TO_ANG,
195+
# float(line_list[3])*AU_TO_ANG])
196+
coords_list.append([float(line_list[1]),
197+
float(line_list[2]),
198+
float(line_list[3])])
196199
atom_names=list(element_dict.keys())
197200
atom_numbs=[]
198201
for ii in atom_names:
@@ -210,17 +213,22 @@ def handle_single_xyz_frame(self, lines):
210213
def get_frames (fname) :
211214
coord_flag = False
212215
force_flag = False
216+
stress_flag = False
213217
eV = 2.72113838565563E+01 # hatree to eV
214-
angstrom = 5.29177208590000E-01 # Bohrto Angstrom
218+
angstrom = 5.29177208590000E-01 # Bohr to Angstrom
219+
GPa = 160.21766208 # 1 eV/(Angstrom^3) = 160.21 GPa
215220
fp = open(fname)
216221
atom_symbol_list = []
217222
cell = []
218223
coord = []
219224
force = []
225+
stress = []
226+
cell_count = 0
220227
coord_count = 0
221228
for idx, ii in enumerate(fp) :
222-
if 'CELL| Vector' in ii :
229+
if ('CELL| Vector' in ii) and (cell_count < 3) :
223230
cell.append(ii.split()[4:7])
231+
cell_count += 1
224232
if 'Atom Kind Element' in ii :
225233
coord_flag = True
226234
coord_idx = idx
@@ -244,6 +252,18 @@ def get_frames (fname) :
244252
force_flag = False
245253
else :
246254
force.append(ii.split()[3:6])
255+
# add reading stress tensor
256+
if 'STRESS TENSOR [GPa' in ii :
257+
stress_flag = True
258+
stress_idx = idx
259+
if stress_flag :
260+
if (idx > stress_idx + 2):
261+
if (ii == '\n') :
262+
stress_flag = False
263+
else :
264+
stress.append(ii.split()[1:4])
265+
266+
247267
fp.close()
248268
assert(coord), "cannot find coords"
249269
assert(energy), "cannot find energies"
@@ -260,10 +280,27 @@ def get_frames (fname) :
260280
force = np.array(force)
261281
force = force.astype(np.float)
262282
force = force[np.newaxis, :, :]
283+
284+
# virial is not necessary
285+
if stress:
286+
stress = np.array(stress)
287+
stress = stress.astype(np.float)
288+
stress = stress[np.newaxis, :, :]
289+
# stress to virial conversion, default unit in cp2k is GPa
290+
# note the stress is virial = stress * volume
291+
virial = stress * np.linalg.det(cell[0])/GPa
292+
else:
293+
virial = None
294+
295+
# force unit conversion, default unit in cp2k is hartree/bohr
263296
force = force * eV / angstrom
297+
# energy unit conversion, default unit in cp2k is hartree
264298
energy = float(energy) * eV
265299
energy = np.array(energy)
266300
energy = energy[np.newaxis]
301+
302+
303+
267304
tmp_names, symbol_idx = np.unique(atom_symbol_list, return_index=True)
268305
atom_types = []
269306
atom_numbs = []
@@ -278,7 +315,7 @@ def get_frames (fname) :
278315

279316
atom_types = np.array(atom_types)
280317

281-
return list(atom_names), atom_numbs, atom_types, cell, coord, energy, force
318+
return list(atom_names), atom_numbs, atom_types, cell, coord, energy, force, virial
282319

283320

284321

dpdata/md/rdf.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ def rdf(sys,
2121
Maximal range of rdf calculation
2222
nbins: int
2323
Number of bins for rdf calculation
24+
25+
Returns
26+
-------
27+
xx: np.array
28+
The lattice of r
29+
rdf: np.array
30+
The value of rdf at r
31+
coord: np.array
32+
The coordination number up to r
2433
"""
2534
return compute_rdf(sys['cells'], sys['coords'], sys['atom_types'],
2635
sel_type = sel_type,
@@ -36,12 +45,16 @@ def compute_rdf(box,
3645
nframes = box.shape[0]
3746
xx = None
3847
all_rdf = []
48+
all_cod = []
3949
for ii in range(nframes):
40-
xx, rdf = _compute_rdf_1frame(box[ii], posis[ii], atype, sel_type, max_r, nbins)
50+
xx, rdf, cod = _compute_rdf_1frame(box[ii], posis[ii], atype, sel_type, max_r, nbins)
4151
all_rdf.append(rdf)
52+
all_cod.append(cod)
4253
all_rdf = np.array(all_rdf).reshape([nframes, -1])
54+
all_cod = np.array(all_cod).reshape([nframes, -1])
4355
all_rdf = np.average(all_rdf, axis = 0)
44-
return xx, all_rdf
56+
all_cod = np.average(all_cod, axis = 0)
57+
return xx, all_rdf, all_cod
4558

4659
def _compute_rdf_1frame(box,
4760
posis,
@@ -65,6 +78,7 @@ def _compute_rdf_1frame(box,
6578
nlist = ase.neighborlist.NeighborList(max_r, self_interaction=False, bothways=True, primitive=ase.neighborlist.NewPrimitiveNeighborList)
6679
nlist.update(atoms)
6780
stat = np.zeros(nbins)
81+
stat_acc = np.zeros(nbins)
6882
hh = max_r / float(nbins)
6983
for ii in range(natoms) :
7084
# atom "0"
@@ -90,13 +104,17 @@ def _compute_rdf_1frame(box,
90104
for ii in sel_type[1]:
91105
c1 += np.sum(atype == ii)
92106
rho1 = c1 / np.linalg.det(box)
107+
# compute coordination number
108+
for ii in range(1, nbins):
109+
stat_acc[ii] = stat_acc[ii-1] + stat[ii-1]
110+
stat_acc = stat_acc / c0
93111
# compute rdf
94112
for ii in range(nbins):
95113
vol = 4./3. * np.pi * ( ((ii+1)*hh) ** 3 - ((ii)*hh) ** 3 )
96114
rho = stat[ii] / vol
97115
stat[ii] = rho / rho1 / c0
98116
xx = np.arange(0, max_r-1e-12, hh)
99-
return xx, stat
117+
return xx, stat, stat_acc
100118

101119
if __name__ == '__main__':
102120
import dpdata

dpdata/md/water.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22
from .pbc import posi_diff
3+
from .pbc import posi_shift
34

45
def compute_bonds (box,
56
posis,
@@ -179,3 +180,26 @@ def find_ions (atype,
179180
else :
180181
raise RuntimeError("unknow case: numb of O bonded to H > 1")
181182
return no, noh, noh2, noh3, nh
183+
184+
185+
186+
def pbc_coords(cells,
187+
coords,
188+
atom_types,
189+
oh_sel = [0, 1],
190+
max_roh = 1.3):
191+
bonds = compute_bonds(cells, coords, atom_types, oh_sel = oh_sel, max_roh = max_roh, uniq_hbond = True)
192+
193+
new_coords = np.copy(coords)
194+
natoms = len(atom_types)
195+
o_type = oh_sel[0]
196+
h_type = oh_sel[1]
197+
for ii in range(natoms):
198+
if atom_types[ii] == o_type:
199+
assert(len(bonds[ii]) == 2), 'O has more than 2 bonded Hs, stop'
200+
for jj in bonds[ii]:
201+
assert(atom_types[jj] == h_type), 'The atom bonded to O is not H, stop'
202+
shift = posi_shift(cells, coords[jj], coords[ii])
203+
new_coords[jj] = coords[jj] + np.matmul(shift, cells)
204+
return new_coords
205+

dpdata/qe/scf.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ def get_coords (lines) :
6464
return list(atom_names), atom_numbs, atom_types, coord
6565

6666
def get_energy (lines) :
67+
energy = None
6768
for ii in lines :
6869
if '! total energy' in ii :
69-
return ry2ev * float(ii.split('=')[1].split()[0])
70-
return None
70+
energy = ry2ev * float(ii.split('=')[1].split()[0])
71+
return energy
7172

7273
def get_force (lines) :
7374
blk = get_block(lines, 'Forces acting on atoms', skip = 1)

0 commit comments

Comments
 (0)