1、本文搬运自ETasci-2013-SurfacePreparationHowTo,简单总结一下,方便大家
2、首先讲一下思路:我们要找到新的单胞,然后我们做晶格基矢转换再加一个真空层就行了,其实很简单。下面讲解步骤。
首先你需要两个东西,一个是晶格结构,需要时VESTA能够打开的格式,这里以Material Project上下载下来的*.cif文件为例。然后把文件拖入到VESTA中。
然后就是找新的单胞,首先我们要找到单胞对应的6个平面,当然在这之前要先扩展成超胞看起来比较方便。(这一步的所有步骤都没有改变元胞信息只是为了我们看着方便,包括下面的删除原子之类的。)点左边的Boundary,然后把x,y,z改成3 3 3
然后我们的模型就变成超胞了。
点左上角的
Edit
,然后点Lattice Planes
,就出来编辑平面的窗口然后点
New
,就可以新建平面,新建完了以后会显示在左边,这里添加6个平面,得到新的单胞,如下图所示。删除多余的原子,用最左侧边栏上的第二个鼠标指针选中然后按键盘上的Del键即可删除
然后我们就得到了新的单胞,这里丢失了一些原子。
这里因为晶格间距和例子中的不一样,所以截出来的单胞并不是很理想,所以拿上面那个PDF中的来说吧,实际操作中根据自己的需要来截,这一步是最关键的。
这个就是PDF中的例子给出的单胞,顶点上有4个原子,像上边一样用左边栏第二个箭头选中4个原子下面的窗口会给出4个原子现在的坐标,分别减去新的原点O‘的坐标,就得到了新的晶格基矢与原来的基矢的关系
终于得到了晶格变换矩阵
注意:到这里为止我们都没有实际上改变原来的晶格结构文件。下面我们就要改了
点Edit
>>Edit data
>>Unit cell
然后点Transform在Rotation matrixP中填上刚才得到的变换矩阵就得到了新的单胞,下面就是添加真空层了,只需要File>>Export data选VASP的格式然后选笛卡尔坐标,再把c方向加大就行了。PP
VESTA建立截止面/移除部分isosurface
添加平面不仅可以帮助简立新的单胞,还可以帮助截取isosurface的一部分。
我在画电荷密度的时候,有时候会遇到想去掉自己不想要的isosurface部分的想法但是直接像删除原子那样的方式是删不掉的,说明书里有一个如何截图像的方法,名字叫做建立边界平面。
同时按ctrl
、shift
、B
就可以打开建立截止面的界面,然后输入自己想要的截止面就可以了!
VESTA变换元胞后保持矢量与之前一致
按照上面描述的方法变换元胞之后,原来设置的矢量有可能会改变方向,因为元胞的基矢被改变了,但是我发现只要在变换的时候选择第二个选项就可以保持矢量不变,但是需要重新设置矢量和原子的对应顺序。
VESTA 批量添加矢量
VESTA里面添加矢量比较麻烦,手动一个一个点,能不能通过脚本来实现呢?答案是可以的,因为VESTA的输入文件prefix.vesta
实际上是一个文本文档,所有的信息都以文本的方式存在里面,那么只需要按照VESTA的格式把矢量写进去就可以了,上网一搜有人写过了,于是就直接拿过来了。脚本来自GitHub - hzr-piggy/plot_vec_VESTA,他参考了另一个人的写法GitHub - lucydot/vesta_vectors。非常感谢他们!
输入文件就是两个,一个是需要修改的VESTA输入文件,还有一个就是记录矢量的文本文档,大致格式是这样的
-0.05
-0.05
-0.05
0.1
0.1
0.1
就是把矢量分成每行一个数就可以了。这里只加了两个矢量,需要加更多只需要也参照这个格式加下去就可以了。
def plot_vec(vesta_file, vec_file,
cutoff = 0.1,
radius=0.5, color=[255,0,0], penetrate = True, add_atom_radius = False,
scale_factor = 1,
delim = None, vec_type = "Cart", lat = None,
output_suffix = "_vec"):
# vesta_file: A *.vesta file
# vec_file: A file containing vectors having dimensions of 3N*1 (or 1*3N)
# with delimiter=delim i.e.
# x1
# y1
# z1
# x2
# y2
# z2
# .
# .
# .
# cutoff (Double): Angstrom below which vector will not show
# radius (Double): Set radius of vector
# color (Double 0-255): Set color of vector
# penetrate (Bool): Set whether vector penetrate atom
# add_atom_radius (Bool):Set whether to add atom radius to vector modulus
# scale_factor (Double): Scale vector in the figure
# delim: Delimiter in the vec_file
# vec_type: Type of vectors, can be "Cart" (Cartesian), "Lat" (Lattice vector notation [u v w], in reduced coord)
# or "Modulus" (Modulus along crystallographic axis). Default is 'Cart'
# lat: 3-by-3 lattice parameter in Angstrom required if vec_type == 'Cart'
import numpy as np
import re
import os
# Read input files
vesta_data = open(vesta_file,'r').read()
temp = np.loadtxt(vec_file,delimiter=delim)
N_dim = temp.shape[0]
temp = temp.reshape((N_dim//3,3))
# Convert to Modulus along crystallographic axis
if vec_type == 'Lat':
struct_match=re.findall(r'CELLP\n\s+(\d+\.\d+\s+\d+\.\d+\s+\d+\.\d+\s+)',vesta_data)[0]
cell = np.array([float(x) for x in struct_match.split()]) # cell lengths in angstrong
temp *= cell
elif vec_type == 'Cart':
assert lat is not None, '3-by-3 lattice parameter in Angstrom required if vec_type == Cart'
temp = temp@np.linalg.inv(lat)*np.linalg.norm(lat,axis=1)
# print(lat)
vectors = np.around(temp*scale_factor,decimals=3) # Round the disp to 3 decimals
# Find unique vectors
print(vectors)
vectors_unique = np.unique(vectors,axis=0)
# Vector penetrate atom or add atomic radius?
flag = int(penetrate)+int(add_atom_radius)*2
VECTR_str=r"\1"
VECTT_str=r"\1"
i = 1
for v in vectors:
if np.linalg.norm(v) > cutoff: # only create vector with modules > cutoff
VECTR_str += " {0} {1} {2} {3} 0\n".format(i,v[0],v[1],v[2]) # create vectors
atom_list = np.where((vectors == v).all(axis=1))[0]
for atom in atom_list:
print(atom)
VECTR_str += " {0} 0 0 0 0\n".format(atom+1) # create atom labels start from 1
VECTR_str += "0 0 0 0 0\n"
VECTT_str += " {0} {1} {2} {3} {4} {5}\n".format(i,radius, color[0], color[1], color[2], flag)
i += 1
output_data = re.sub(r"(VECTR\n)",VECTR_str,vesta_data)
output_data = re.sub(r"(VECTT\n)",VECTT_str,output_data)
# print(output_data)
name, ext = os.path.splitext(vesta_file)
file_out = open(name+output_suffix+ext,'w+')
file_out.write(output_data)
file_out.close()
mode = 12
plot_vec('NbAs.vesta', 'NbAs_vector'+str(mode)+'.dat',
cutoff = 0.1,
radius=0.4, color=[255,0,0], penetrate = False, add_atom_radius = False,
scale_factor =-1,
delim = None, vec_type = "Cart", lat = [[6.374959638, 0.003597502 , -0.000000000],
[ 4.478346762 , 4.537022058 , -0.000000000],
[-5.426653274 ,-2.270309811 , 2.457085633]],
output_suffix = "_vec"+str(mode))
VESTA保存带电荷密度图
VESTA为了保持vesta文件格式的简介一致性,将电荷密度这一类数据在保存的时候就删掉了,想要保存这一类数据需要将其再保存为一个XX.ggrid文件,然后打开的时候 Edit > volumetric-data 导入进去就可以了。
VESTA 调节isosurface 透明度,
VESTA中如果想要调节isosurface的透明度,是在properties里面然后打开isosurface选项里就可以调,关键在于理解两个透明度的意思是什么,
这一点从这个图上可以看出来,其中O1和O2分别代变两个方向的透明度,分别对应opacity1和opacity2,然后前面那个render from front to back 影响也很大。