Skip to content

Commit 30cbb6a

Browse files
authored
Merge pull request #67 from felix5572/devel
replicate and disturb and its document,unittest
2 parents a1c791c + 0e4d5c3 commit 30cbb6a

File tree

9 files changed

+432
-0
lines changed

9 files changed

+432
-0
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,20 @@ Frame selection can be implemented by
152152
dpdata.LabeledSystem('OUTCAR').sub_system([0,-1]).to_deepmd_raw('dpmd_raw')
153153
```
154154
by which only the first and last frames are dumped to `dpmd_raw`.
155+
156+
## replicate
157+
dpdata will create a super cell of the current atom configuration.
158+
```python
159+
dpdata.System('./POSCAR').replicate((1,2,3,) )
160+
```
161+
tuple(1,2,3) means don't copy atom configuration in x direction, make 2 copys in y direction, make 3 copys in z direction.
162+
163+
## perturb
164+
By the following example, each frame of the original system (`dpdata.System('./POSCAR')`) is perturbed to generate three new frames. For each frame, the cell is perturbed by 5% and the atom positions are perturbed by 0.6 Angstrom. `atom_pert_style` indicates that the perturbation to the atom positions is subject to normal distribution. Other available options to `atom_pert_style` are`uniform` (uniform in a ball), and `const` (uniform on a sphere).
165+
```python
166+
perturbed_system = dpdata.System('./POSCAR').perturb(pert_num=3,
167+
cell_pert_fraction=0.05,
168+
atom_pert_distance=0.6,
169+
atom_pert_style='normal')
170+
print(perturbed_system.data)
171+
```

dpdata/system.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,142 @@ def add_atom_names(self, atom_names):
579579
self.data['atom_names'].extend(atom_names)
580580
self.data['atom_numbs'].extend([0 for _ in atom_names])
581581

582+
def replicate(self, ncopy):
583+
"""
584+
Replicate the each frame in the system in 3 dimensions.
585+
Each frame in the system will become a supercell.
586+
587+
Parameters
588+
----------
589+
ncopy :
590+
list: [4,2,3]
591+
or tuple: (4,2,3,)
592+
make `ncopy[0]` copys in x dimensions,
593+
make `ncopy[1]` copys in y dimensions,
594+
make `ncopy[2]` copys in z dimensions.
595+
596+
Returns
597+
-------
598+
tmp : System
599+
The system after replication.
600+
"""
601+
if len(ncopy) !=3:
602+
raise RuntimeError('ncopy must be a list or tuple with 3 int')
603+
for ii in ncopy:
604+
if type(ii) is not int:
605+
raise RuntimeError('ncopy must be a list or tuple must with 3 int')
606+
607+
tmp = System()
608+
nframes = self.get_nframes()
609+
data = self.data
610+
tmp.data['atom_names'] = list(np.copy(data['atom_names']))
611+
tmp.data['atom_numbs'] = list(np.array(np.copy(data['atom_numbs'])) * np.prod(ncopy))
612+
tmp.data['atom_types'] = np.sort(np.tile(np.copy(data['atom_types']),np.prod(ncopy)))
613+
tmp.data['cells'] = np.copy(data['cells'])
614+
for ii in range(3):
615+
tmp.data['cells'][:,ii,:] *= ncopy[ii]
616+
tmp.data['coords'] = np.tile(np.copy(data['coords']),tuple(ncopy)+(1,1,1))
617+
618+
for xx in range(ncopy[0]):
619+
for yy in range(ncopy[1]):
620+
for zz in range(ncopy[2]):
621+
tmp.data['coords'][xx,yy,zz,:,:,:] += xx * np.reshape(data['cells'][:,0,:], [-1,1,3])\
622+
+ yy * np.reshape(data['cells'][:,1,:], [-1,1,3])\
623+
+ zz * np.reshape(data['cells'][:,2,:], [-1,1,3])
624+
tmp.data['coords'] = np.reshape(np.transpose(tmp.data['coords'], [3,4,0,1,2,5]), (nframes, -1 , 3))
625+
return tmp
626+
627+
def perturb(self,
628+
pert_num,
629+
cell_pert_fraction,
630+
atom_pert_distance,
631+
atom_pert_style='normal'):
632+
"""
633+
Perturb each frame in the system randomly.
634+
The cell will be deformed randomly, and atoms will be displaced by a random distance in random direction.
635+
636+
Parameters
637+
----------
638+
pert_num : int
639+
Each frame in the system will make `pert_num` copies,
640+
and all the copies will be perturbed.
641+
That means the system to be returned will contain `pert_num` * frame_num of the input system.
642+
cell_pert_fraction : float
643+
A fraction determines how much (relatively) will cell deform.
644+
The cell of each frame is deformed by a symmetric matrix perturbed from identity.
645+
The perturbation to the diagonal part is subject to a uniform distribution in [-cell_pert_fraction, cell_pert_fraction),
646+
and the perturbation to the off-diagonal part is subject to a uniform distribution in [-0.5*cell_pert_fraction, 0.5*cell_pert_fraction).
647+
atom_pert_distance: float
648+
unit: Angstrom. A distance determines how far atoms will move.
649+
Atoms will move about `atom_pert_distance` in random direction.
650+
The distribution of the distance atoms move is determined by atom_pert_style
651+
atom_pert_style : str
652+
Determines the distribution of the distance atoms move is subject to.
653+
Avaliable options are
654+
- `'normal'`: the `distance` will be object to `chi-square distribution with 3 degrees of freedom` after normalization.
655+
The mean value of the distance is `atom_pert_fraction*side_length`
656+
- `'uniform'`: will generate uniformly random points in a 3D-balls with radius as `atom_pert_distance`.
657+
These points are treated as vector used by atoms to move.
658+
Obviously, the max length of the distance atoms move is `atom_pert_distance`.
659+
- `'const'`: The distance atoms move will be a constant `atom_pert_distance`.
660+
661+
Returns
662+
-------
663+
perturbed_system : System
664+
The perturbed_system. It contains `pert_num` * frame_num of the input system frames.
665+
"""
666+
perturbed_system = System()
667+
nframes = self.get_nframes()
668+
for ii in range(nframes):
669+
for jj in range(pert_num):
670+
tmp_system = self[ii].copy()
671+
cell_perturb_matrix = get_cell_perturb_matrix(cell_pert_fraction)
672+
tmp_system.data['cells'][0] = np.matmul(tmp_system.data['cells'][0],cell_perturb_matrix)
673+
tmp_system.data['coords'][0] = np.matmul(tmp_system.data['coords'][0],cell_perturb_matrix)
674+
for kk in range(len(tmp_system.data['coords'][0])):
675+
atom_perturb_vector = get_atom_perturb_vector(atom_pert_distance, atom_pert_style)
676+
tmp_system.data['coords'][0][kk] += atom_perturb_vector
677+
tmp_system.rot_lower_triangular()
678+
perturbed_system.append(tmp_system)
679+
return perturbed_system
680+
681+
def get_cell_perturb_matrix(cell_pert_fraction):
682+
if cell_pert_fraction<0:
683+
raise RuntimeError('cell_pert_fraction can not be negative')
684+
e0 = np.random.rand(6)
685+
e = e0 * 2 *cell_pert_fraction - cell_pert_fraction
686+
cell_pert_matrix = np.array(
687+
[[1+e[0], 0.5 * e[5], 0.5 * e[4]],
688+
[0.5 * e[5], 1+e[1], 0.5 * e[3]],
689+
[0.5 * e[4], 0.5 * e[3], 1+e[2]]]
690+
)
691+
return cell_pert_matrix
692+
693+
def get_atom_perturb_vector(atom_pert_distance, atom_pert_style='normal'):
694+
random_vector = None
695+
if atom_pert_distance < 0:
696+
raise RuntimeError('atom_pert_distance can not be negative')
697+
698+
if atom_pert_style == 'normal':
699+
e = np.random.randn(3)
700+
random_vector=(atom_pert_distance/np.sqrt(3))*e
701+
elif atom_pert_style == 'uniform':
702+
e = np.random.randn(3)
703+
while np.linalg.norm(e) < 0.1:
704+
e = np.random.randn(3)
705+
random_unit_vector = e/np.linalg.norm(e)
706+
v0 = np.random.rand(1)
707+
v = np.power(v0,1/3)
708+
random_vector = atom_pert_distance*v*random_unit_vector
709+
elif atom_pert_style == 'const' :
710+
e = np.random.randn(3)
711+
while np.linalg.norm(e) < 0.1:
712+
e = np.random.randn(3)
713+
random_unit_vector = e/np.linalg.norm(e)
714+
random_vector = atom_pert_distance*random_unit_vector
715+
else:
716+
raise RuntimeError('unsupported options atom_pert_style={}'.format(atom_pert_style))
717+
return random_vector
582718

583719
class LabeledSystem (System):
584720
'''

tests/poscars/POSCAR.SiC

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
C4 Si4
2+
1.0
3+
4.1454462863815970e+00 0.0000000000000000e+00 0.0000000000000000e+00
4+
1.3000000000000000e-01 3.9594462863815970e+00 0.0000000000000000e+00
5+
2.5000000000000000e-01 3.7000000000000000e-01 4.0400062863815970e+00
6+
C Si
7+
4 4
8+
cartesian
9+
-0.0666948568 0.0604660432 2.1539831432
10+
1.9907431432 -0.0864349568 0.0663397432
11+
0.0885598432 2.0783031432 0.0622547432
12+
2.0324731432 2.0217031432 2.0253831432
13+
-0.0448649568 0.1153571432 0.0540263432
14+
1.9664731432 1.9313831432 -0.1405848568
15+
2.0807731432 0.0065058032 1.9956031432
16+
0.0632185432 1.9999431432 2.0438931432

tests/poscars/POSCAR.SiC.const

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
C4 Si4
2+
1.0
3+
3.9448633066729739e+00 -3.6344794672422329e-18 1.1581293029516294e-17
4+
1.6817409381958889e-01 4.0320777239133783e+00 -8.7954588948930866e-19
5+
1.4551929935812052e-01 3.9989012843738053e-01 3.9977352939318109e+00
6+
C Si
7+
4 4
8+
Cartesian
9+
0.0946327782 -0.2781320996 1.6927633385
10+
2.1395921916 -0.5505295607 0.3561009428
11+
-0.2623111485 2.0403483142 0.5289485573
12+
2.0291102621 2.0166734366 1.4189102698
13+
-0.4274609464 0.4275845699 -0.2870878166
14+
1.8398859643 1.9175800522 -0.7344827910
15+
1.5794721062 0.2698516856 1.5600233361
16+
0.2272461445 2.4170250626 2.4545090907

tests/poscars/POSCAR.SiC.normal

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
C4 Si4
2+
1.0
3+
4.0354487481064565e+00 1.1027270790560616e-17 2.5642993008475204e-17
4+
2.0693526054669642e-01 4.1066892997402196e+00 -8.6715682899078028e-18
5+
4.2891472979598610e-01 5.5796885749827474e-01 4.1100061517204542e+00
6+
C Si
7+
4 4
8+
Cartesian
9+
0.2840021179 -0.6003817253 2.7192043932
10+
1.7870636884 0.4043686026 -0.3468222936
11+
-0.4647946470 2.0243215781 -0.0624256251
12+
2.1747504767 2.0704389063 2.4228997681
13+
-0.3817468326 0.0611851697 0.1116535817
14+
2.1483270977 2.3528212071 -0.3719335435
15+
2.4540854549 0.7297685673 1.8434611305
16+
0.1075358778 2.0300985762 2.0687710181

tests/poscars/POSCAR.SiC.replicate123

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
C24 Si24
2+
1.000000
3+
4.14544629 0.00000000 0.00000000
4+
0.26000000 7.91889257 0.00000000
5+
0.75000000 1.11000000 12.12001886
6+
C Si
7+
24 24
8+
Cartesian
9+
-0.06669486 0.06046604 2.15398314
10+
0.18330514 0.43046604 6.19398943
11+
0.43330514 0.80046604 10.23399572
12+
0.06330514 4.01991233 2.15398314
13+
0.31330514 4.38991233 6.19398943
14+
0.56330514 4.75991233 10.23399572
15+
1.99074314 -0.08643496 0.06633974
16+
2.24074314 0.28356504 4.10634603
17+
2.49074314 0.65356504 8.14635232
18+
2.12074314 3.87301133 0.06633974
19+
2.37074314 4.24301133 4.10634603
20+
2.62074314 4.61301133 8.14635232
21+
0.08855984 2.07830314 0.06225474
22+
0.33855984 2.44830314 4.10226103
23+
0.58855984 2.81830314 8.14226732
24+
0.21855984 6.03774943 0.06225474
25+
0.46855984 6.40774943 4.10226103
26+
0.71855984 6.77774943 8.14226732
27+
2.03247314 2.02170314 2.02538314
28+
2.28247314 2.39170314 6.06538943
29+
2.53247314 2.76170314 10.10539572
30+
2.16247314 5.98114943 2.02538314
31+
2.41247314 6.35114943 6.06538943
32+
2.66247314 6.72114943 10.10539572
33+
-0.04486496 0.11535714 0.05402634
34+
0.20513504 0.48535714 4.09403263
35+
0.45513504 0.85535714 8.13403892
36+
0.08513504 4.07480343 0.05402634
37+
0.33513504 4.44480343 4.09403263
38+
0.58513504 4.81480343 8.13403892
39+
1.96647314 1.93138314 -0.14058486
40+
2.21647314 2.30138314 3.89942143
41+
2.46647314 2.67138314 7.93942772
42+
2.09647314 5.89082943 -0.14058486
43+
2.34647314 6.26082943 3.89942143
44+
2.59647314 6.63082943 7.93942772
45+
2.08077314 0.00650580 1.99560314
46+
2.33077314 0.37650580 6.03560943
47+
2.58077314 0.74650580 10.07561572
48+
2.21077314 3.96595209 1.99560314
49+
2.46077314 4.33595209 6.03560943
50+
2.71077314 4.70595209 10.07561572
51+
0.06321854 1.99994314 2.04389314
52+
0.31321854 2.36994314 6.08389943
53+
0.56321854 2.73994314 10.12390572
54+
0.19321854 5.95938943 2.04389314
55+
0.44321854 6.32938943 6.08389943
56+
0.69321854 6.69938943 10.12390572

tests/poscars/POSCAR.SiC.uniform

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
C4 Si4
2+
1.0
3+
4.0817852422279959e+00 -8.0334347485565818e-20 1.4195449766884313e-17
4+
1.2315711101650186e-01 3.7860044730134366e+00 -1.7522489439993958e-18
5+
4.0639226354941010e-01 3.2444019947671882e-01 4.2124083393682454e+00
6+
C Si
7+
4 4
8+
Cartesian
9+
-0.1022885809 0.5553879154 2.3401729917
10+
1.4574918226 -0.0391762715 0.0190932943
11+
-0.0904993945 1.7684440711 -0.1710987880
12+
2.0638159391 2.1681985074 2.4580083474
13+
-0.3261354126 0.1759255681 0.2236316249
14+
2.0738703301 2.3024191125 -0.5031567813
15+
2.3488610334 0.3825072268 1.7330866249
16+
-0.0534780340 1.5938442575 1.8486892947

0 commit comments

Comments
 (0)