原子间距离-周期性边界条件-非立方晶胞

计算科学 Python 边界条件 分子动力学
2021-12-22 06:53:11

考虑到六边形立方晶胞(石墨)的周期性边界条件,我试图找到原子间距离。我试图在这里遵循这两个问题的答案,但无法获得正确的结果

三斜盒的周期性边界条件

三斜晶胞的最小图像约定

我的代码,在第一篇文章中实现答案是here

positions = initialConfig.get_positions()
nAtoms = positions.shape[0]
xMin = zMin = 0.0
xMax = LX
zMax = LZ
yCoord = positions[:,0:2]
u2 = UCell[1][0:2,]
modYPos = np.zeros((0,2))
for i in range(nAtoms):
    currAtom = yCoord[i,:]
    if currAtom[1]>LY:
        modPos = currAtom -LY*u2
    elif currAtom[1]<LY:
        modPos = currAtom +LY*u2
    else:
        modPos = currAtom
    modYPos = np.vstack((modYPos, modPos))
xCoord = modYPos[:,0].reshape(-1,1)
xCoord = xCoord - xMax*np.rint(xCoord/xMax)
zCoord = positions[:,2].reshape(-1,1)
zCoord = zCoord - zMax*np.rint(zCoord/zMax)
app5rMat = np.zeros((nAtoms,coordinates))
app5rMat[:,0] = xCoord[:,0]
app5rMat[:,1] = yCoord[:,1]
app5rMat[:,2] = zCoord[:,0]
app5RIJ = app5rMat.reshape(nAtoms,1,coordinates)-app5rMat.reshape(1,nAtoms,coordinates)
app5Dist = np.linalg.norm(app5RIJ, axis =2 )

第二篇文章的代码是

#S1 create A matrix 
UCell = initialConfig.get_cell()
cellParams = initialConfig.get_cell_lengths_and_angles()
a = cellParams[0]
b = cellParams[1]
c = cellParams[2]

alpha= math.radians(90)#math.pi/2#math.radians(cellParams[3])
beta= math.radians(90)#math.pi/3#math.radians(cellParams[4])
gamma= math.radians(60)#math.pi/2#math.radians(cellParams[5])

A = UCell.T

#S2 Invert A to bet B
B = np.linalg.inv(A)
np.matmul(B,A)

#S3 -- get fractional coordinates 

positions = initialConfig.get_positions()
nAtoms = positions.shape[0]
fracCood = np.zeros((0,3))
for i in range(nAtoms):
    currAtom = positions[i,:].reshape(-1,1)
    fracCood = np.vstack((fracCood, np.dot(B,currAtom).T))
fracCood.shape

#s4 -- translate into reference cell
onesArray = np.ones((nAtoms,coordinates))
g = fracCood - np.rint(2*fracCood - onesArray)#np.floor(fracCood)

#s4-- translate into real space 
realCood = np.zeros((0,3))
for i in range(nAtoms):
    currAtom = g[i,:].reshape(-1,1)
    realCood = np.vstack((realCood, np.dot(A,currAtom).T))
algoRij = g.reshape(nAtoms,1,coordinates)-g.reshape(1,nAtoms,coordinates)
secondPart = np.rint(2*algoRij.copy() - onesArray.reshape(nAtoms,1,coordinates))
algoRij = algoRij-secondPart
algoRijPer = algoRij #-np.rint(algoRij)
algoRijDis = np.linalg.norm(algoRijPer, axis =2 )
1个回答

我认为您可能使事情过于复杂,试图对具有 2D 六边形周期性的系统使用一般的三斜周期边界条件。很可能使用菱形单元格xy方向(在规则边界z如果需要,使其成为 3D 中的菱形棱柱)或实际上是矩形单元(即 3D 中的长方体)。这两者都在图中进行了说明。

用矩形和菱形盒子覆盖的六边形格子

对于这里所示的蓝色框,如果六边形的边是一个单位,那么Lx=12Ly=6310.392,但有很大的灵活性,具体取决于您希望包含多少个单元格(在每个方向上)。然后,用于周期性边界校正的 Python 代码与任何长方体框的代码相同,例如xij=xij-np.rint(xij/Lx)*Lx,对于yij和也是如此zij,其中(xij,yij,zij)是未校正的对向量。