问题描述
VASP计算表面时,需要将下面几层进行固定,用于模拟体相,如下面例子中我们把z方向坐标在0-0.5之间的原子全部固定
处理脚本
from pymatgen import Structure,Element
import numpy as np
def atom_selection(struct,in_str=None):
r'''
select atoms by three different schemes:
1. by atomic index
2. by element symbol
3. by fractional coordinates range
'''
tip="""
select atoms by following ways:
1. atomic index in POSCAR
i.e. : 1 2 4-8 10 12-30
i.e. : 1 2 4 8 10
2. atomic label
i.e. : Si O
3. atomic position
i.e. : 0 0.5 | 0.2 0.4 | 0.3 0.7
this means atoms with 0<x<0.5,
0.2<y<0.4 and 0.3<z<0.7 will be seleted
or just specific the z coordinates,
i.e. : ||0.3 0.7
"""
print(tip)
def parse_index(in_str):
atom_index=[]
tmp_str=in_str.split()
#tmp_str=in_str.split()[1:]
for i in tmp_str:
if '-' not in i:
atom_index.append(int(i))
else:
atom_index.extend(range(int(i.split('-')[0]),int(i.split('-')[1])+1))
return [i-1 for i in atom_index]
def parse_label(in_str):
atom_label= [Element(elem) for elem in in_str.split()]
#atom_label= [Element(elem) for elem in in_str.split()[1:]]
atom_index=[]
for i, site in enumerate(struct.sites):
if site.specie in atom_label:
atom_index.append(i)
return atom_index
def parse_range(in_str):
def check_frac(coord,lim):
con=[False]*3
for i in range(3):
con[i]=coord[i]>=lim[i][0] and coord[i]<=lim[i][1]
if np.all(con):
return True
else:
return False
coord_range={}
tmp_str=in_str.split();tmp1_str=' '.join(tmp_str);tmp2_str=tmp1_str.split("|")
#tmp_str=in_str.split()[1:];tmp1_str=' '.join(tmp_str);tmp2_str=tmp1_str.split("|")
icount=0
for i in tmp2_str:
if i=='':
coord_range[icount]=''
else:
coord_range[icount]=[float(x) for x in i.split()]
icount+=1
for key in coord_range.keys():
if coord_range[key]=='':
coord_range[key]=[0,1]
atom_index=[]
for i, site in enumerate(struct.sites):
if check_frac(site.frac_coords,coord_range):
atom_index.append(i)
return atom_index
if "|" in in_str.strip():
atom_index_list=parse_range(in_str)
else:
for str in in_str.strip():
if str.isalpha():
atom_index_list=parse_label(in_str)
return atom_index_list,in_str
atom_index_list=parse_index(in_str)
#if in_str.strip().startswith('a'):
# atom_index_list=parse_index(in_str)
#elif in_str.strip().startswith('b'):
# atom_index_list=parse_label(in_str)
#elif in_str.strip().startswith('c'):
# atom_index_list=parse_range(in_str)
return atom_index_list,in_str
def constrain(struct,in_str=None):
natom=struct.num_sites
atom_index,in_str=atom_selection(struct,in_str)
selective_dynamics=[[True for col in range(3)] for row in range(natom)]
for i in range(natom):
if i in atom_index:
selective_dynamics[i]=[False,False,False]
tmp_struct=Structure(struct.lattice,struct.species,struct.frac_coords,site_properties={'selective_dynamics':selective_dynamics})
return tmp_struct
if __name__=='__main__':
from pymatgen.io.vasp import Poscar
st=Structure.from_file('L1-Te2.vasp')
in_str='||0.0 0.5'
cst=constrain(st,in_str=in_str)
poscar=Poscar(cst)
print(st)
print(poscar)
poscar.comment=poscar.comment+' |--> '+in_str
poscar.write_file('Fixed.vasp')
运行脚本 python run.py
,确保当前文件夹里面有L1-Te2.vasp文件
L1-Te2.vasp文件内容为:
Li6 V9 Te4 O24
1.0
6.042800 0.000000 0.000000
-3.021400 5.233218 0.000000
0.000000 0.000000 30.535545
Li V Te O
6 9 4 24
direct
0.333333 0.666667 0.265354 Li
0.333333 0.666667 0.395473 Li
0.000000 0.000000 0.434944 Li
0.000000 0.000000 0.565063 Li
0.666667 0.333333 0.604534 Li
0.666667 0.333333 0.734653 Li
0.833330 0.666667 0.330406 V
0.333333 0.166670 0.330406 V
0.833330 0.166670 0.330406 V
0.166670 0.333333 0.669585 V
-0.000000 0.500000 0.500001 V
0.500000 0.500000 0.500001 V
0.666667 0.833330 0.669585 V
0.166670 0.833330 0.669585 V
0.500000 0.000000 0.500001 V
0.000000 0.000000 0.245619 Te
0.666667 0.333333 0.415209 Te
0.333333 0.666667 0.584798 Te
0.000000 0.000000 0.754388 Te
0.666667 0.333333 0.296140 O
0.153020 0.306040 0.290630 O
0.693960 0.846980 0.290630 O
0.153020 0.846980 0.290630 O
0.333333 0.666667 0.465730 O
0.513650 0.486350 0.370182 O
0.972710 0.486350 0.370182 O
0.513650 0.027290 0.370182 O
0.819690 0.639370 0.460220 O
0.360630 0.180310 0.460220 O
0.819690 0.180310 0.460220 O
0.000000 0.000000 0.364687 O
0.000000 0.000000 0.635320 O
0.180310 0.819690 0.539772 O
0.639370 0.819690 0.539772 O
0.180310 0.360630 0.539772 O
0.486350 0.972710 0.629825 O
0.027290 0.513650 0.629825 O
0.486350 0.513650 0.629825 O
0.666667 0.333333 0.534277 O
0.846980 0.153020 0.709361 O
0.306040 0.153020 0.709361 O
0.846980 0.693960 0.709361 O
0.333333 0.666667 0.703867 O
即可得到如下内容:
select atoms by following ways:
1. atomic index in POSCAR
i.e. : 1 2 4-8 10 12-30
i.e. : 1 2 4 8 10
2. atomic label
i.e. : Si O
3. atomic position
i.e. : 0 0.5 | 0.2 0.4 | 0.3 0.7
this means atoms with 0<x<0.5,
0.2<y<0.4 and 0.3<z<0.7 will be seleted
or just specific the z coordinates,
i.e. : ||0.3 0.7
Full Formula (Li6 V9 Te4 O24)
Reduced Formula: Li6V9(TeO6)4
abc : 6.042800 6.042800 30.535545
angles: 90.000000 90.000000 120.000001
Sites (43)
# SP a b c
--- ---- --------- -------- --------
0 Li 0.333333 0.666667 0.265354
1 Li 0.333333 0.666667 0.395473
2 Li 0 0 0.434944
3 Li 0 0 0.565063
4 Li 0.666667 0.333333 0.604534
5 Li 0.666667 0.333333 0.734653
6 V 0.83333 0.666667 0.330406
7 V 0.333333 0.16667 0.330406
8 V 0.83333 0.16667 0.330406
9 V 0.16667 0.333333 0.669585
10 V -0 0.5 0.500001
11 V 0.5 0.5 0.500001
12 V 0.666667 0.83333 0.669585
13 V 0.16667 0.83333 0.669585
14 V 0.5 0 0.500001
15 Te 0 0 0.245619
16 Te 0.666667 0.333333 0.415209
17 Te 0.333333 0.666667 0.584798
18 Te 0 0 0.754388
19 O 0.666667 0.333333 0.29614
20 O 0.15302 0.30604 0.29063
21 O 0.69396 0.84698 0.29063
22 O 0.15302 0.84698 0.29063
23 O 0.333333 0.666667 0.46573
24 O 0.51365 0.48635 0.370182
25 O 0.97271 0.48635 0.370182
26 O 0.51365 0.02729 0.370182
27 O 0.81969 0.63937 0.46022
28 O 0.36063 0.18031 0.46022
29 O 0.81969 0.18031 0.46022
30 O 0 0 0.364687
31 O 0 0 0.63532
32 O 0.18031 0.81969 0.539772
33 O 0.63937 0.81969 0.539772
34 O 0.18031 0.36063 0.539772
35 O 0.48635 0.97271 0.629825
36 O 0.02729 0.51365 0.629825
37 O 0.48635 0.51365 0.629825
38 O 0.666667 0.333333 0.534277
39 O 0.84698 0.15302 0.709361
40 O 0.30604 0.15302 0.709361
41 O 0.84698 0.69396 0.709361
42 O 0.333333 0.666667 0.703867
------------------------------------------
Li6 V9 Te4 O24
1.0
6.042800 0.000000 0.000000
-3.021400 5.233218 0.000000
0.000000 0.000000 30.535545
Li V Te O
6 9 4 24
Selective dynamics
direct
0.333333 0.666667 0.265354 F F F Li
0.333333 0.666667 0.395473 F F F Li
0.000000 0.000000 0.434944 F F F Li
0.000000 0.000000 0.565063 T T T Li
0.666667 0.333333 0.604534 T T T Li
0.666667 0.333333 0.734653 T T T Li
0.833330 0.666667 0.330406 F F F V
0.333333 0.166670 0.330406 F F F V
0.833330 0.166670 0.330406 F F F V
0.166670 0.333333 0.669585 T T T V
-0.000000 0.500000 0.500001 T T T V
0.500000 0.500000 0.500001 T T T V
0.666667 0.833330 0.669585 T T T V
0.166670 0.833330 0.669585 T T T V
0.500000 0.000000 0.500001 T T T V
0.000000 0.000000 0.245619 F F F Te
0.666667 0.333333 0.415209 F F F Te
0.333333 0.666667 0.584798 T T T Te
0.000000 0.000000 0.754388 T T T Te
0.666667 0.333333 0.296140 F F F O
0.153020 0.306040 0.290630 F F F O
0.693960 0.846980 0.290630 F F F O
0.153020 0.846980 0.290630 F F F O
0.333333 0.666667 0.465730 F F F O
0.513650 0.486350 0.370182 F F F O
0.972710 0.486350 0.370182 F F F O
0.513650 0.027290 0.370182 F F F O
0.819690 0.639370 0.460220 F F F O
0.360630 0.180310 0.460220 F F F O
0.819690 0.180310 0.460220 F F F O
0.000000 0.000000 0.364687 F F F O
0.000000 0.000000 0.635320 T T T O
0.180310 0.819690 0.539772 T T T O
0.639370 0.819690 0.539772 T T T O
0.180310 0.360630 0.539772 T T T O
0.486350 0.972710 0.629825 T T T O
0.027290 0.513650 0.629825 T T T O
0.486350 0.513650 0.629825 T T T O
0.666667 0.333333 0.534277 T T T O
0.846980 0.153020 0.709361 T T T O
0.306040 0.153020 0.709361 T T T O
0.846980 0.693960 0.709361 T T T O
0.333333 0.666667 0.703867 T T T O
当然该脚本还支持其他模式的原子固定,具体可以参考tip