最近忙里偷闲的在学习VASP,在看到POSCAR这个输入文件时,对两种不同的原子坐标表示方式有点搞不清楚,在这里就顺便写笔记,对这两种不同的坐标之间的联系进行整理.同时也对这个输入文件里面的参数做一些自己的理解.
POSCAR输入参数
直角坐标
Cubic BN # 这里就是给你要计算的体系起个名字
3.57 # 这是一个缩放系数,会对所有的格矢和原子坐标进行缩放
0.0 0.5 0.5 # 这三行就是组成格子的三条边的矢量坐标信息,缩放系数就在这里起作用
0.5 0.0 0.5 # 利用缩放系数可以得到,格子第二条边的矢量为(0.5*3.57,0,0.5*3.57)
0.5 0.5 0.0 # 这三个矢量就是用来确定元胞的基矢
1 1 # 计算的系统中每个原子的数量,譬如FeSe就表示体系统有一个Fe原子,一个Se原子
Selective dynamics # 这个选项用来设置在离子弛豫过程中原子的位置是否要保持不动(这个一个可选参数,默认下也可以不设置)
Cartesian # 接下来的三行是关于分子动力学的设置,我不懂
0.00 0.00 0.00 T T F
0.25 0.25 0.25 F F F
Cartesian # 这里就是来设置坐标是直角坐标,通常都只是识别第一个字母,但是为了明确一般就写成Cartesian这个易懂的单词
0.01 0.01 0.01 # 第一个原子在元胞中的位置
0.00 0.00 0.00 # 第二个原子在元胞中的位置
# 在设置原子的坐标位置的时候,一定要和前面原子的数目一致.
在这里要说明,在设置元胞基矢$a_1,a_2,a_3$的时候,三个分量代表的是基矢在直角坐标系上的分量,比如$a_1=(1,1,1)$就说明这个矢量在直角坐标系上三个基矢上的分量都是1.
而在设置原子位置的时候,这个三个分量则是原子位置在元胞基矢上的分量,也就是$\vec{R}=x_1\vec{a_1}+x_2\vec{a_2}+x_3\vec{a_3}$,在上面元胞中原子位置设置时候的三个值就对应着这里的$x_1,x_2,x_3$.在换算真实坐标的时候,需要将缩放系数代入$\vec{R}=s(x_1,x_2,x_3)$.
分数坐标
在上面介绍的直角坐标中,所有的坐标都是真实的空间位置,比如按照上面的计算公式,你得到一个原子的位置,那么它一定就是真实空间中以直角坐标系为基,原子在这个坐标系中的位置.而分数坐标则不同,这里用分数坐标表示的是原子位置,那么转换一下视角,以元胞为整体,看原子相对于元胞的相对位置,那么得到的就是分数坐标.
再进一步说,就是看以元胞基矢作为坐标轴,看原子位置投影在每个元胞基矢上的分量,很自然的这个分量范围是$[0,1]$,因为你的原子肯定是要在元胞内的,要不然就属于另外一个元胞,利用周期性还是会在元胞内.
Direct
0.00 0.00 0.00 # 这里说明第一个原子在三个元胞基矢上的投影都是0,也就是说是以这个原子为中心的,它是坐标原点
0.25 0.25 0.25 # 第二个原子在每个元胞基矢上的分量都是0.25
换算关系
首先,假设元胞基矢为 \(\left[\begin{array}{c} \vec{a_1}&\\ \vec{a_2}&\\ \vec{a_3}& \end{array}\right]=\left[\begin{array}{ccc} x_1& y_1&z_1\\ x_2&y_2&z_2\\ x_3&y_3&z_3\\ \end{array}\right]\)
如果一个点的分数坐标为$\vec{p}=(p_1,p_2,p_3)$,这个坐标的意思就是点$\vec{p}$在第一个基矢上的投影大小是$p_1$,在第二个基矢上的投影分量为$p_2$,在第三个基矢上的投影分量大小是$p_3$,那么要计算这个点的直角坐标的过程如下
\[\vec{p}=p_1\cdot\vec{a_1}+p_2\cdot\vec{a_2}+p_3\cdot\vec{a_3}\]则点$\vec{p}$的直接坐标分量分别为
\[p_x = p_1 \cdot x_1 + p_2 \cdot x_2 + p_3\cdot x_3\\ p_y = p_1 \cdot y_1 + p_2 \cdot y_2 + p_3\cdot y_3\\ p_z = p_1 \cdot z_1 + p_2 \cdot z_2 + p_3\cdot z_3\]小程序
下面是一个简答的小程序用来实现两种坐标之间的转换,程序不是我写的,是从GitHub上面copy的,来自这里.
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 9 16:07:58 2019
@author: Yaqiong Su
"""
import numpy as np
import pandas as pd
import linecache as lc
f1 = open('POSCAR','rb')
f2 = open('head','wb')
f3 = open('direct','wb')
f4 = open('lattice','wb')
i = 0
while True:
line = f1.readline()
i+=1
if i < 7:
f2.write(line)
if i == 7:
f2.write('Cartesian \n')
if i > 8:
f3.write(line)
if i > 300:
break
f1.close()
f2.close()
f3.close()
with open('head','rb') as f22:
i = 0
while True:
line = f22.readline()
i+=1
if i> 2 and i < 6:
f4.write(line)
if i > 300:
break
f4.close()
#with open('matrix','rb') as f33:
# for data in f33.readlines():
# data = data.strip('\n')
# nums = data.split()
# nums = [float(x) for x in nums]
# direct = np.array(nums)
# print direct
direct = np.loadtxt('direct')
print "direct coordinate"
print direct
lattice = np.loadtxt('lattice')
print "lattice"
print lattice
cartesian = np.dot(direct,lattice)
print"cartesian coordinate"
print cartesian
np.savetxt('cartesian',cartesian)
f5 = open('Cartesian_POSCAR','ab')
with open('head','rb') as f:
for lines in f.readlines():
f5.write(lines)
with open('cartesian','rb') as f0:
for lines in f0.readlines():
f5.write(lines)
f5.close()
print "Cartesian_POSCAR"
with open('Cartesian_POSCAR','rb') as f:
for lines in f.readlines():
print lines
公众号
相关内容均会在公众号进行同步,若对该Blog感兴趣,欢迎关注微信公众号。