Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,13 @@ perturbed_system = dpdata.System('./POSCAR').perturb(pert_num=3,
atom_pert_style='normal')
print(perturbed_system.data)
```

## replace
By the following example, Random 8 Hf atoms in the system will be replaced by Zr atoms with the atom postion unchanged.
```python
s=dpdata.System('tests/poscars/POSCAR.P42nmc',fmt='vasp/poscar')
s.replace('Hf', 'Zr', 8)
s.to_vasp_poscar('POSCAR.P42nmc.replace')
```


34 changes: 34 additions & 0 deletions dpdata/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,40 @@ def replicate(self, ncopy):
tmp.data['coords'] = np.reshape(np.transpose(tmp.data['coords'], [3,4,0,1,2,5]), (nframes, -1 , 3))
return tmp

def replace(self, initial_atom_type, end_atom_type, replace_num):
if type(self) is not dpdata.System:
raise RuntimeError('Must use method replace() of the instance of class dpdata.System')
if type(replace_num) is not int:
raise ValueError("replace_num must be a integer. Now is {replace_num}".format(replace_num=replace_num))
if replace_num <= 0:
raise ValueError("replace_num must be larger than 0.Now is {replace_num}".format(replace_num=replace_num))

try:
initial_atom_index = self.data['atom_names'].index(initial_atom_type)
except ValueError as e:
raise ValueError("atom_type {initial_atom_type} not in {atom_names}"
.format(initial_atom_type=initial_atom_type, atom_names=self.data['atom_names']))
max_replace_num = self.data['atom_numbs'][initial_atom_index]

if replace_num > max_replace_num:
raise RuntimeError("not enough {initial_atom_type} atom, only {max_replace_num} available, less than {replace_num}.Please check."
.format(initial_atom_type=initial_atom_type,max_replace_num=max_replace_num, replace_num=replace_num))

may_replace_indices = [i for i, x in enumerate(self.data['atom_types']) if x == initial_atom_index]
to_replace_indices = np.random.choice(may_replace_indices, size=replace_num, replace=False)

if end_atom_type not in self.data['atom_names']:
self.data['atom_names'].append(end_atom_type)
self.data['atom_numbs'].append(0)

end_atom_index = self.data['atom_names'].index(end_atom_type)
for ii in to_replace_indices:
self.data['atom_types'][ii] = end_atom_index
self.data['atom_numbs'][initial_atom_index] -= replace_num
self.data['atom_numbs'][end_atom_index] += replace_num
self.sort_atom_types()


def perturb(self,
pert_num,
cell_pert_fraction,
Expand Down
104 changes: 104 additions & 0 deletions tests/poscars/POSCAR.P42nmc
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
Hf32 O64
1.0
10.001280 0.000000 0.000000
0.000000 10.001280 0.000000
0.000000 0.000000 10.163840
Hf O
32 64
direct
0.000000 0.000000 0.000000 Hf
0.000000 0.000000 0.500000 Hf
0.000000 0.500000 1.000000 Hf
0.000000 0.500000 0.500000 Hf
0.500000 0.000000 1.000000 Hf
0.500000 0.000000 0.500000 Hf
0.500000 0.500000 1.000000 Hf
0.500000 0.500000 0.500000 Hf
0.250000 0.000000 0.250000 Hf
0.250000 0.000000 0.750000 Hf
0.250000 0.500000 0.250000 Hf
0.250000 0.500000 0.750000 Hf
0.750000 0.000000 0.250000 Hf
0.750000 0.000000 0.750000 Hf
0.750000 0.500000 0.250000 Hf
0.750000 0.500000 0.750000 Hf
0.000000 0.250000 0.250000 Hf
0.000000 0.250000 0.750000 Hf
1.000000 0.750000 0.250000 Hf
1.000000 0.750000 0.750000 Hf
0.500000 0.250000 0.250000 Hf
0.500000 0.250000 0.750000 Hf
0.500000 0.750000 0.250000 Hf
0.500000 0.750000 0.750000 Hf
0.250000 0.250000 1.000000 Hf
0.250000 0.250000 0.500000 Hf
0.250000 0.750000 1.000000 Hf
0.250000 0.750000 0.500000 Hf
0.750000 0.250000 1.000000 Hf
0.750000 0.250000 0.500000 Hf
0.750000 0.750000 0.000000 Hf
0.750000 0.750000 0.500000 Hf
0.375000 0.375000 0.146120 O
0.375000 0.375000 0.646120 O
0.375000 0.875000 0.146120 O
0.375000 0.875000 0.646120 O
0.875000 0.375000 0.146120 O
0.875000 0.375000 0.646120 O
0.875000 0.875000 0.146120 O
0.875000 0.875000 0.646120 O
0.375000 0.375000 0.396120 O
0.375000 0.375000 0.896120 O
0.375000 0.875000 0.396120 O
0.375000 0.875000 0.896120 O
0.875000 0.375000 0.396120 O
0.875000 0.375000 0.896120 O
0.875000 0.875000 0.396120 O
0.875000 0.875000 0.896120 O
0.375000 0.125000 0.103880 O
0.375000 0.125000 0.603880 O
0.375000 0.625000 0.103880 O
0.375000 0.625000 0.603880 O
0.875000 0.125000 0.103880 O
0.875000 0.125000 0.603880 O
0.875000 0.625000 0.103880 O
0.875000 0.625000 0.603880 O
0.375000 0.125000 0.353880 O
0.375000 0.125000 0.853880 O
0.375000 0.625000 0.353880 O
0.375000 0.625000 0.853880 O
0.875000 0.125000 0.353880 O
0.875000 0.125000 0.853880 O
0.875000 0.625000 0.353880 O
0.875000 0.625000 0.853880 O
0.125000 0.375000 0.103880 O
0.125000 0.375000 0.603880 O
0.125000 0.875000 0.103880 O
0.125000 0.875000 0.603880 O
0.625000 0.375000 0.103880 O
0.625000 0.375000 0.603880 O
0.625000 0.875000 0.103880 O
0.625000 0.875000 0.603880 O
0.125000 0.375000 0.353880 O
0.125000 0.375000 0.853880 O
0.125000 0.875000 0.353880 O
0.125000 0.875000 0.853880 O
0.625000 0.375000 0.353880 O
0.625000 0.375000 0.853880 O
0.625000 0.875000 0.353880 O
0.625000 0.875000 0.853880 O
0.125000 0.125000 0.146120 O
0.125000 0.125000 0.646120 O
0.125000 0.625000 0.146120 O
0.125000 0.625000 0.646120 O
0.625000 0.125000 0.146120 O
0.625000 0.125000 0.646120 O
0.625000 0.625000 0.146120 O
0.625000 0.625000 0.646120 O
0.125000 0.125000 0.396120 O
0.125000 0.125000 0.896120 O
0.125000 0.625000 0.396120 O
0.125000 0.625000 0.896120 O
0.625000 0.125000 0.396120 O
0.625000 0.125000 0.896120 O
0.625000 0.625000 0.396120 O
0.625000 0.625000 0.896120 O
104 changes: 104 additions & 0 deletions tests/poscars/POSCAR.P42nmc.replace
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
Hf24 O64 Zr8
1.0
1.0001280000000000e+01 0.0000000000000000e+00 0.0000000000000000e+00
0.0000000000000000e+00 1.0001280000000000e+01 0.0000000000000000e+00
0.0000000000000000e+00 0.0000000000000000e+00 1.0163840000000000e+01
Hf O Zr
24 64 8
Cartesian
0.0000000000 0.0000000000 0.0000000000
7.5009600000 7.5009600000 5.0819200000
7.5009600000 7.5009600000 0.0000000000
7.5009600000 2.5003200000 10.1638400000
2.5003200000 7.5009600000 5.0819200000
2.5003200000 7.5009600000 10.1638400000
2.5003200000 2.5003200000 5.0819200000
2.5003200000 2.5003200000 10.1638400000
5.0006400000 2.5003200000 7.6228800000
10.0012800000 7.5009600000 2.5409600000
0.0000000000 2.5003200000 7.6228800000
0.0000000000 2.5003200000 2.5409600000
7.5009600000 5.0006400000 7.6228800000
7.5009600000 5.0006400000 2.5409600000
10.0012800000 7.5009600000 7.6228800000
7.5009600000 0.0000000000 2.5409600000
0.0000000000 0.0000000000 5.0819200000
0.0000000000 5.0006400000 5.0819200000
7.5009600000 0.0000000000 7.6228800000
5.0006400000 0.0000000000 5.0819200000
2.5003200000 0.0000000000 2.5409600000
5.0006400000 0.0000000000 10.1638400000
2.5003200000 0.0000000000 7.6228800000
2.5003200000 5.0006400000 7.6228800000
1.2501600000 8.7511200000 1.0558196992
1.2501600000 8.7511200000 3.5967796992
1.2501600000 3.7504800000 8.6786996992
1.2501600000 3.7504800000 3.5967796992
6.2508000000 8.7511200000 6.1377396992
6.2508000000 8.7511200000 1.0558196992
6.2508000000 3.7504800000 6.1377396992
8.7511200000 1.2501600000 8.6786996992
6.2508000000 3.7504800000 1.0558196992
1.2501600000 3.7504800000 1.0558196992
1.2501600000 8.7511200000 8.6786996992
8.7511200000 6.2508000000 3.5967796992
8.7511200000 6.2508000000 8.6786996992
1.2501600000 8.7511200000 6.1377396992
1.2501600000 3.7504800000 6.1377396992
6.2508000000 3.7504800000 3.5967796992
6.2508000000 6.2508000000 1.4851403008
6.2508000000 8.7511200000 3.5967796992
6.2508000000 1.2501600000 9.1080203008
6.2508000000 1.2501600000 4.0261003008
1.2501600000 6.2508000000 9.1080203008
1.2501600000 6.2508000000 4.0261003008
1.2501600000 1.2501600000 9.1080203008
1.2501600000 1.2501600000 4.0261003008
6.2508000000 6.2508000000 6.5670603008
8.7511200000 1.2501600000 3.5967796992
6.2508000000 1.2501600000 6.5670603008
6.2508000000 1.2501600000 1.4851403008
1.2501600000 6.2508000000 6.5670603008
1.2501600000 6.2508000000 1.4851403008
1.2501600000 1.2501600000 6.5670603008
1.2501600000 1.2501600000 1.4851403008
6.2508000000 8.7511200000 8.6786996992
6.2508000000 3.7504800000 8.6786996992
3.7504800000 6.2508000000 8.6786996992
8.7511200000 8.7511200000 9.1080203008
3.7504800000 1.2501600000 8.6786996992
3.7504800000 3.7504800000 1.4851403008
3.7504800000 3.7504800000 6.5670603008
3.7504800000 8.7511200000 1.4851403008
3.7504800000 8.7511200000 6.5670603008
8.7511200000 3.7504800000 1.4851403008
8.7511200000 3.7504800000 6.5670603008
8.7511200000 8.7511200000 1.4851403008
8.7511200000 8.7511200000 6.5670603008
3.7504800000 6.2508000000 3.5967796992
3.7504800000 3.7504800000 9.1080203008
3.7504800000 8.7511200000 4.0261003008
3.7504800000 8.7511200000 9.1080203008
3.7504800000 3.7504800000 4.0261003008
8.7511200000 3.7504800000 9.1080203008
3.7504800000 1.2501600000 3.5967796992
8.7511200000 3.7504800000 4.0261003008
8.7511200000 6.2508000000 1.0558196992
8.7511200000 1.2501600000 6.1377396992
8.7511200000 1.2501600000 1.0558196992
8.7511200000 6.2508000000 6.1377396992
3.7504800000 6.2508000000 1.0558196992
3.7504800000 1.2501600000 6.1377396992
3.7504800000 1.2501600000 1.0558196992
6.2508000000 6.2508000000 4.0261003008
8.7511200000 8.7511200000 4.0261003008
3.7504800000 6.2508000000 6.1377396992
6.2508000000 6.2508000000 9.1080203008
7.5009600000 2.5003200000 5.0819200000
5.0006400000 7.5009600000 7.6228800000
5.0006400000 7.5009600000 2.5409600000
5.0006400000 2.5003200000 2.5409600000
2.5003200000 5.0006400000 2.5409600000
5.0006400000 5.0006400000 5.0819200000
5.0006400000 5.0006400000 10.1638400000
0.0000000000 5.0006400000 10.1638400000
40 changes: 40 additions & 0 deletions tests/test_replace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os
import numpy as np
import unittest
from context import dpdata
from comp_sys import CompSys, IsPBC

from unittest.mock import Mock
from unittest.mock import patch, MagicMock


class ConstGenerator(object):
def __init__(self):
self.choice_generator = self.get_choice_generator()
def choice(self, a, size=None, replace=True, p=None):
return next(self.choice_generator)

@staticmethod
def get_choice_generator():
yield np.asarray([20, 6, 7, 22, 29, 2, 23, 10])

class TestReplace(unittest.TestCase, CompSys, IsPBC):
@patch('numpy.random')
def setUp(self, random_mock):
random_mock.choice = ConstGenerator().choice
self.system_1 = dpdata.System('poscars/POSCAR.P42nmc',fmt='vasp/poscar')
self.system_1.replace('Hf', 'Zr', 8)
# print(self.system_1.data)
self.system_2 = dpdata.System('poscars/POSCAR.P42nmc.replace',fmt='vasp/poscar')
# print(self.system_2.data)
self.places = 6

# class TestReplicate123_not_change_origin(unittest.TestCase, CompSys, IsPBC):
# def setUp (self) :
# self.system_1 = dpdata.System('poscars/POSCAR.SiC',fmt='vasp/poscar')
# self.system_1.replicate((1,2,3,))
# self.system_2 = dpdata.System('poscars/POSCAR.SiC',fmt='vasp/poscar')
# self.places = 6

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