vasp格式计算msd

1. MSD 包括所有起源和一半一半和单个起源

==去质心漂移对氢原子扩散重要==

重要的是TMSD,不管统计多少,TMSD总体是不变的,但是MSD需要除以一个数字,就是离子数目,来作为每个离子平均的TMSD,这时候,在系数项乘数时,需要乘前面的离子数目。所以叫做均方根位移,这里的均是对有效的假定的离子数目做平均

!November 12,2015, by Peihao Huang --<<Molecular dynamics simulation_elementary methods>>-Wiley
program main
implicit none
integer::i,j,Natoms,step,atom,Origin,n,Totalstep,Nkindsofatom,Nstep,Nreject,nna  !整型
real(kind=8)
::factor,a(3,3),t,timestep,DeltaX,DeltaY,DeltaZ,DeltaRx,DeltaRy,DeltaRz,DeltaR,Xcenter0
real(kind=8)   ::Ycenter0,Zcenter0,mh,mo,m3,m4,msum,dif,logdif,sigma
!实型
real(kind=8),allocatable ::X(:,:),Y(:,:),Z(:,:),MSD(:),x0(:),y0(:),z0(:),Xcenter(:),Ycenter(:),Zcenter(:)
!实型双精度可分配数组
integer,allocatable ::natom(:)
character(len=6),allocatable ::temp(:)
!长度为6的字符串数组
character(len=10) ::temp1
mo=39.10
mh=88.91
m3=28.09
m4=16.00
msum=30*mo+6*mh+24*m3+72*m4

!These parameters should be input by hand 
Totalstep=180000
Nstep=170000
Nreject=10000
timestep=0.002
Nkindsofatom=4
allocate(natom(Nkindsofatom),temp(Nkindsofatom))
!natom为四维整型数组,temp为四维字符型数组
!Read the original structure,only the fractional coordination is needed for the box is fixed
open(unit=30,file='POSCAR')
read(30,*)
read(30,*)
read(30,*)
read(30,*)
read(30,*) ! for earlier versions of VASP, you should delete on line of this
read(30,*)
read(30,*) natom
!将原子个数存在七维实型数组里
Natoms=0
do i=1,Nkindsofatom
  Natoms=Natoms+natom(i)
  write(*,*)natom(i)
end do
!计算总的原子个数
write(*,*)Natoms
allocate(x0(Natoms),y0(Natoms),z0(Natoms))
!分配一个natoms维的数组
!read(30,*)
read(30,*)
do atom=1,Natoms
  read(30,*)x0(atom),y0(atom),z0(atom)
end do
close(30)
!将所有的初始坐标存储
!Read the structural information of the trajactory
open(unit=10,file='XDATCAR')
read(10,*)temp1
read(10,*)factor
read(10,*)a(1,1),a(1,2),a(1,3)
read(10,*)a(2,1),a(2,2),a(2,3)
read(10,*)a(3,1),a(3,2),a(3,3)
do i=1,3
  do j=1,3
    a(i,j)=a(i,j)*factor
  end do
end do
!读入晶格常数
read(10,*)temp
read(10,*)
allocate(X(Totalstep,Natoms),Y(Totalstep,Natoms),Z(Totalstep,Natoms))
!分配二维数组
do step=1,Totalstep
  read(10,*)
  do atom=1,Natoms
    read(10,*)X(step,atom),Y(step,atom),Z(step,atom)
  end do
end do
close(10)
!将所有原子坐标读入
!Unfold the atoms in the box with PBC
do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

do step=2,Totalstep
  do atom=1,Natoms
    if(X(step,atom)-X(step-1,atom)<-0.5) then
      do n=step,Totalstep
        X(n,atom)=X(n,atom)+1.0
      end do
!从第二步开始计算,第二部比第一步多或少
    else if(X(step,atom)-X(step-1,atom)>0.5) then
      do n=step,Totalstep
        X(n,atom)=X(n,atom)-1.0
      end do
    end if
    if(Y(step,atom)-Y(step-1,atom)<-0.5) then
      do n=step,Totalstep
        Y(n,atom)=Y(n,atom)+1.0
      end do
    else if(Y(step,atom)-Y(step-1,atom)>0.5) then
      do n=step,Totalstep
        Y(n,atom)=Y(n,atom)-1.0
      end do
    end if
    if(Z(step,atom)-Z(step-1,atom)<-0.5) then
      do n=step,Totalstep
        Z(n,atom)=Z(n,atom)+1.0
      end do
    else if(Z(step,atom)-Z(step-1,atom)>0.5) then
      do n=step,Totalstep
        Z(n,atom)=Z(n,atom)-1.0
      end do
    end if
  end do
end do
!考虑周期性
!在第一帧上全部加减
!Remove the drift of center of mass
Xcenter0=0
Ycenter0=0
Zcenter0=0
do atom=1,natom(1)
  Xcenter0=Xcenter0+x0(atom)*mo/msum
  Ycenter0=Ycenter0+y0(atom)*mo/msum
  zcenter0=Zcenter0+z0(atom)*mo/msum
end do
!在natom中提取第一个原子的数量,并且计算质心
do atom=natom(1)+1,natom(1)+natom(2)
  Xcenter0=Xcenter0+x0(atom)*mh/msum
  Ycenter0=Ycenter0+y0(atom)*mh/msum
  zcenter0=Zcenter0+z0(atom)*mh/msum
end do
!提取第二个原子质量并求质心
do atom=natom(1)+natom(2)+1,natom(1)+natom(2)+natom(3)
  Xcenter0=Xcenter0+x0(atom)*m3/msum
  Ycenter0=Ycenter0+y0(atom)*m3/msum
  zcenter0=Zcenter0+z0(atom)*m3/msum
end do
do atom=natom(1)+natom(2)+natom(3)+1,natom(1)+natom(2)+natom(3)+natom(4)
   Xcenter0=Xcenter0+x0(atom)*m4/msum
   Ycenter0=Ycenter0+y0(atom)*m4/msum
   zcenter0=Zcenter0+z0(atom)*m4/msum
 end do
 !计算质心
deallocate(x0,y0,z0)

allocate(Xcenter(Totalstep),Ycenter(Totalstep),Zcenter(Totalstep))
open(unit=400,file='Mc-drift.dat')
do step=1,Totalstep
  Xcenter(step)=0
  Ycenter(step)=0
  Zcenter(step)=0
  do atom=1,natom(1)
    Xcenter(step)=Xcenter(step)+X(step,atom)*mo/msum
    Ycenter(step)=Ycenter(step)+Y(step,atom)*mo/msum
    Zcenter(step)=Zcenter(step)+Z(step,atom)*mo/msum
  end do
  do atom=natom(1)+1,natom(1)+natom(2)
    Xcenter(step)=Xcenter(step)+X(step,atom)*mh/msum
    Ycenter(step)=Ycenter(step)+Y(step,atom)*mh/msum
    Zcenter(step)=Zcenter(step)+Z(step,atom)*mh/msum
  end do
  do atom=natom(1)+natom(2)+1,natom(1)+natom(2)+natom(3)
    Xcenter(step)=Xcenter(step)+X(step,atom)*m3/msum
    Ycenter(step)=Ycenter(step)+Y(step,atom)*m3/msum
    Zcenter(step)=Zcenter(step)+Z(step,atom)*m3/msum
  end do

  do atom=natom(1)+natom(2)+natom(3)+1,natom(1)+natom(2)+natom(3)+natom(4)
    Xcenter(step)=Xcenter(step)+X(step,atom)*m4/msum
    Ycenter(step)=Ycenter(step)+Y(step,atom)*m4/msum
    Zcenter(step)=Zcenter(step)+Z(step,atom)*m4/msum
  end do
  Xcenter(step)=Xcenter(step)-Xcenter0
  Ycenter(step)=Ycenter(step)-Ycenter0
  Zcenter(step)=zcenter(step)-Zcenter0
  t=step*timestep
  write(400,"(4(F9.6(2x)))")t,Xcenter(step),Ycenter(step),Zcenter(step)
  !计算质心运动
  do atom=1,Natoms
    X(step,atom)=X(step,atom)-Xcenter(step)
    Y(step,atom)=Y(step,atom)-Ycenter(step)
    Z(step,atom)=Z(step,atom)-Zcenter(step)
  end do
  !去除质心运动
end do
deallocate(Xcenter,Ycenter,Zcenter)

!Reject some steps before equilibrium
do step=1,Nstep
  do atom=1,Natoms
    X(step,atom)=X(step+Nreject,atom)
    Y(step,atom)=Y(step+Nreject,atom)
    Z(step,atom)=Z(step+Nreject,atom)
  end do
end do
!去除部分轨迹
!Multile time origins
allocate(MSD(Nstep-1))
open(unit=20,file='msd-zong-t.dat')
do step=1,Nstep-1
  MSD(step)=0.0
  do Origin=1,Nstep-step
    do atom=1,natom(1)
      DeltaX=X(Origin+step,atom)-X(Origin,atom)
      DeltaY=Y(Origin+step,atom)-Y(Origin,atom)
      DeltaZ=Z(Origin+step,atom)-Z(Origin,atom)
      DeltaRx=DeltaX*a(1,1)+DeltaY*a(2,1)+DeltaZ*a(3,1)
      DeltaRy=DeltaX*a(1,2)+DeltaY*a(2,2)+DeltaZ*a(3,2)
      DeltaRz=DeltaX*a(1,3)+DeltaY*a(2,3)+DeltaZ*a(3,3)
      DeltaR=DeltaRx**2+DeltaRy**2+DeltaRz**2
      MSD(step)=MSD(step)+DeltaR
    end do
  end do
  MSD(step)=MSD(step)/REAL(natom(1))/REAL(Nstep-step)
  t=step*timestep
  dif=MSD(step)/(t*6)*0.0001
  logdif=log10(dif)
  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!  sigma=sigma/(10**(-9))
  write(20,*)t,MSD(step)
end do
close(20)


!一半一半

open(unit=50,file='msd-zong-2-t.dat')
do step=1,Nstep/2
  MSD(step)=0.0
  do Origin=1,Nstep/2
    do atom=1,natom(1)
      DeltaX=X(Origin+step,atom)-X(Origin,atom)
      DeltaY=Y(Origin+step,atom)-Y(Origin,atom)
      DeltaZ=Z(Origin+step,atom)-Z(Origin,atom)
      DeltaRx=DeltaX*a(1,1)+DeltaY*a(2,1)+DeltaZ*a(3,1)
      DeltaRy=DeltaX*a(1,2)+DeltaY*a(2,2)+DeltaZ*a(3,2)
      DeltaRz=DeltaX*a(1,3)+DeltaY*a(2,3)+DeltaZ*a(3,3)
      DeltaR=DeltaRx**2+DeltaRy**2+DeltaRz**2
      MSD(step)=MSD(step)+DeltaR
    end do
  end do
  MSD(step)=MSD(step)*2/REAL(natom(1))/REAL(Nstep)
  t=step*timestep
  dif=MSD(step)/(t*6)*0.0001
  logdif=log10(dif)
  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!  sigma=sigma/(10**(-9))
  write(50,*)t,MSD(step)
end do
close(50)



!只和第一帧比较
open(unit=60,file='msd-zong-t.dat')
do step=0,Nstep-1
  MSD(step)=0.0
  do atom=1,natom(1)
    DeltaX=X(1+step,atom)-X(1,atom)
    DeltaY=Y(1+step,atom)-Y(1,atom)
    DeltaZ=Z(1+step,atom)-Z(1,atom)
    DeltaRx=DeltaX*a(1,1)+DeltaY*a(2,1)+DeltaZ*a(3,1)
    DeltaRy=DeltaX*a(1,2)+DeltaY*a(2,2)+DeltaZ*a(3,2)
    DeltaRz=DeltaX*a(1,3)+DeltaY*a(2,3)+DeltaZ*a(3,3)
    DeltaR=DeltaRx**2+DeltaRy**2+DeltaRz**2
    MSD(step)=MSD(step)+DeltaR
  end do
  MSD(step)=MSD(step)/REAL(natom(1))
  t=step*timestep
  dif=MSD(step)/(t*6)*0.0001
  logdif=log10(dif)
  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!  sigma=sigma/(10**(-9))
  write(60,*)t,MSD(step)
end do
close(60)





deallocate(MSD)
deallocate(X,Y,Z)
write(*,*)"success!"
end program

image-20231019205733452

同一段轨迹的不同算法会得出不同的结果(真实VS统计结果)

平均算法会低估前面时间的msd

2. NPT的MSD计算(因为每一步的晶格常数都会变,所以不能用上面的

program main
implicit none
integer::i,j,Natoms,step,atom,Origin,n,Totalstep,Nkindsofatom,Nstep,Nreject,nna
!整型
real(kind=8)  ::factor,a(3,3),t,timestep,DeltaX,DeltaY,DeltaZ,DeltaRx,DeltaRy,DeltaRz,DeltaR,Xcenter0
real(kind=8)   ::Ycenter0,Zcenter0,mh,mo,m3,m4,msum,dif,logdif,sigma
!实型
real(kind=8),allocatable  ::X(:,:),Y(:,:),Z(:,:),MSD(:),x0(:),y0(:),z0(:),Xcenter(:),Ycenter(:),Zcenter(:),MM(:,:)
real(kind=8),allocatable  ::NN(:,:),QQ(:,:)
!实型双精度可分配数组
integer,allocatable ::natom(:)
character(len=6),allocatable ::temp(:)
!长度为6的字符串数组
character(len=10) ::temp1
mo=40.08
mh=1.008
m3=28.09
m4=16.00
msum=256*mo+1472*mh

!These parameters should be input by hand 
Totalstep=451
Nstep=400
Nreject=0
timestep=0.002
Nkindsofatom=2
allocate(natom(Nkindsofatom),temp(Nkindsofatom))
!natom为四维整型数组,temp为四维字符型数组
!Read the original structure,only the fractional coordination is needed
!for the box is fixed
open(unit=30,file='POSCAR')
read(30,*)
read(30,*)
read(30,*)a(1,1),a(1,2),a(1,3)
read(30,*)a(2,1),a(2,2),a(2,3)
read(30,*)a(3,1),a(3,2),a(3,3)! for earlier versions of VASP, you should delete on line ofthis
read(30,*)
read(30,*) natom
!将原子个数存在七维实型数组里
Natoms=0
do i=1,Nkindsofatom
  Natoms=Natoms+natom(i)
  write(*,*)natom(i)
end do
!计算总的原子个数
write(*,*)Natoms
allocate(x0(Natoms),y0(Natoms),z0(Natoms))
!分配一个natoms维的数组
!read(30,*)
read(30,*)
do atom=1,Natoms
  read(30,*)x0(atom),y0(atom),z0(atom)
end do
close(30)
!将所有的初始坐标存储
!Read the structural information of the trajactory
open(unit=10,file='XDATCAR')
allocate(X(Totalstep,Natoms),Y(Totalstep,Natoms),Z(Totalstep,Natoms))
allocate(MM(Totalstep,3),NN(Totalstep,3),QQ(Totalstep,3))
do step=1,Totalstep
  read(10,*)
  read(10,*)
  read(10,*) MM(step,1),MM(step,2),MM(step,3)
  read(10,*) NN(step,1),NN(step,2),NN(step,3)
  read(10,*) QQ(step,1),QQ(step,2),QQ(step,3)
  read(10,*)
  read(10,*)
  read(10,*)
  do atom=1,Natoms
    read(10,*)X(step,atom),Y(step,atom),Z(step,atom)
  end do
end do
close(10)
!将所有原子坐标读入
!Unfold the atoms in the box with PBC
do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

do step=2,Totalstep
  do atom=1,Natoms
    if(X(step,atom)-X(step-1,atom)<-0.5) then
      do n=step,Totalstep
        X(n,atom)=X(n,atom)+1.0
      end do
!从第二步开始计算,第二部比第一步多或少
    else if(X(step,atom)-X(step-1,atom)>0.5) then
      do n=step,Totalstep
        X(n,atom)=X(n,atom)-1.0
      end do
    end if
    if(Y(step,atom)-Y(step-1,atom)<-0.5) then
      do n=step,Totalstep
        Y(n,atom)=Y(n,atom)+1.0
      end do
    else if(Y(step,atom)-Y(step-1,atom)>0.5) then
      do n=step,Totalstep
        Y(n,atom)=Y(n,atom)-1.0
      end do
    end if
    if(Z(step,atom)-Z(step-1,atom)<-0.5) then
      do n=step,Totalstep
        Z(n,atom)=Z(n,atom)+1.0
      end do
    else if(Z(step,atom)-Z(step-1,atom)>0.5) then
      do n=step,Totalstep
        Z(n,atom)=Z(n,atom)-1.0
      end do
    end if
  end do
end do
open(unit=100,file='XDATCAR-3')
  do step=1,Nstep
   write(100,*) step,"sucess"
  do atom =1,Natoms
 write(100,"(F11.8,F15.8,F15.8)") X(step,atom),Y(step,atom),Z(step,atom)
  end do
  end do
close(100)


do step=1,Totalstep
   do atom=1,Natoms
     X(step,atom)=MM(step,1)*X(step,atom)+NN(step,1)*Y(step,atom)+QQ(step,1)*Z(step,atom)
     Y(step,atom)=MM(step,2)*X(step,atom)+NN(step,2)*Y(step,atom)+QQ(step,2)*Z(step,atom)
     Z(step,atom)=MM(step,3)*X(step,atom)+NN(step,3)*Y(step,atom)+QQ(step,3)*Z(step,atom)
   end do
end do

do atom=1,Natoms
  x0(atom)=a(1,1)*x0(atom)
  y0(atom)=a(2,2)*y0(atom)
  z0(atom)=a(3,3)*z0(atom)
end do



open(unit=100,file='XDATCAR-2')
  do step=1,Nstep
   write(100,*) step ,"success"
  do atom =1,Natoms
 write(100,"(F11.8,F15.8,F15.8)") X(step,atom),Y(step,atom),Z(step,atom)
  end do
  end do
close(100)

!考虑周期性
!在第一帧上全部加减
!Remove the drift of center of mass
Xcenter0=0
Ycenter0=0
Zcenter0=0
do atom=1,natom(1)
  Xcenter0=Xcenter0+x0(atom)*mo/msum
  Ycenter0=Ycenter0+y0(atom)*mo/msum
  zcenter0=Zcenter0+z0(atom)*mo/msum
end do
!在natom中提取第一个原子的数量,并且计算质心
do atom=natom(1)+1,natom(2)
  Xcenter0=Xcenter0+x0(atom)*mh/msum
  Ycenter0=Ycenter0+y0(atom)*mh/msum
  zcenter0=Zcenter0+z0(atom)*mh/msum
end do
!提取第二个原子质量并求质心
 !计算质心
deallocate(x0,y0,z0)

allocate(Xcenter(Totalstep),Ycenter(Totalstep),Zcenter(Totalstep))
open(unit=400,file='Mc-drift.dat')
do step=1,Totalstep
  Xcenter(step)=0
  Ycenter(step)=0
  Zcenter(step)=0
  do atom=1,natom(1)
    Xcenter(step)=Xcenter(step)+X(step,atom)*mo/msum
    Ycenter(step)=Ycenter(step)+Y(step,atom)*mo/msum
    Zcenter(step)=Zcenter(step)+Z(step,atom)*mo/msum
  end do
  do atom=natom(1)+1,natom(1)+natom(2)
    Xcenter(step)=Xcenter(step)+X(step,atom)*mh/msum
    Ycenter(step)=Ycenter(step)+Y(step,atom)*mh/msum
    Zcenter(step)=Zcenter(step)+Z(step,atom)*mh/msum
  end do

  Xcenter(step)=Xcenter(step)-Xcenter0
  Ycenter(step)=Ycenter(step)-Ycenter0
  Zcenter(step)=zcenter(step)-Zcenter0
  t=step*timestep
  write(400,"(4(F9.6(2x)))")t,Xcenter(step),Ycenter(step),Zcenter(step)
  !计算质心运动
  do atom=1,Natoms
    X(step,atom)=X(step,atom)-Xcenter(step)
    Y(step,atom)=Y(step,atom)-Ycenter(step)
    Z(step,atom)=Z(step,atom)-Zcenter(step)
  end do
  !去除质心运动
end do
deallocate(Xcenter,Ycenter,Zcenter)

!Reject some steps before equilibrium
do step=1,Nstep
  do atom=1,Natoms
    X(step,atom)=X(step+Nreject,atom)
    Y(step,atom)=Y(step+Nreject,atom)
    Z(step,atom)=Z(step+Nreject,atom)
  end do
end do
!去除部分轨迹
!Multile time origins
allocate(MSD(Nstep-1))
open(unit=20,file='msd-zong-t-2.dat')
do step=1,Nstep-1
  MSD(step)=0.0
  do Origin=1,Nstep-step
    do atom=natom(1)+1,natom(1)+natom(2)
      DeltaX=X(Origin+step,atom)-X(Origin,atom)
      DeltaY=Y(Origin+step,atom)-Y(Origin,atom)
      DeltaZ=Z(Origin+step,atom)-Z(Origin,atom)
      DeltaR=DeltaX**2+DeltaY**2+DeltaZ**2
      MSD(step)=MSD(step)+DeltaR
    end do
  end do
  MSD(step)=MSD(step)/REAL(natom(2))/REAL(Nstep-step)
  t=step*timestep
  dif=MSD(step)/(t*6)*0.0001
  logdif=log10(dif)
  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!  sigma=sigma/(10**(-9))
  write(20,*)t,MSD(step)
end do
close(20)
!
!
!!一半一半
!
!open(unit=50,file='msd-zong-2-t.dat')
!do step=1,Nstep/2
!  MSD(step)=0.0
!  do Origin=1,Nstep/2
!    do atom=1,natom(1)
!      DeltaX=X(Origin+step,atom)-X(Origin,atom)
!      DeltaY=Y(Origin+step,atom)-Y(Origin,atom)
!      DeltaZ=Z(Origin+step,atom)-Z(Origin,atom)
!      DeltaRx=DeltaX*a(1,1)+DeltaY*a(2,1)+DeltaZ*a(3,1)
!      DeltaRy=DeltaX*a(1,2)+DeltaY*a(2,2)+DeltaZ*a(3,2)
!      DeltaRz=DeltaX*a(1,3)+DeltaY*a(2,3)+DeltaZ*a(3,3)
!      DeltaR=DeltaRx**2+DeltaRy**2+DeltaRz**2
!      MSD(step)=MSD(step)+DeltaR
!    end do
!  end do
!  MSD(step)=MSD(step)*2/REAL(natom(1))/REAL(Nstep)
!  t=step*timestep
!  dif=MSD(step)/(t*6)*0.0001
!  logdif=log10(dif)
!  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!!  sigma=sigma/(10**(-9))
!  write(50,*)t,MSD(step)
!end do
!close(50)



!只和第一帧比较
open(unit=60,file='msd-zong-t.dat')
do step=0,Nstep-1
  MSD(step)=0.0
  do atom=natom(1),natom(1)+natom(2)
    DeltaX=X(1+step,atom)-X(1,atom)
    DeltaY=Y(1+step,atom)-Y(1,atom)
    DeltaZ=Z(1+step,atom)-Z(1,atom)
    DeltaR=DeltaX**2+DeltaY**2+DeltaZ**2
    MSD(step)=MSD(step)+DeltaR
  end do
  MSD(step)=MSD(step)/REAL(natom(2))
  t=step*timestep
  dif=MSD(step)/(t*6)*0.0001
  logdif=log10(dif)
  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!  sigma=sigma/(10**(-9))
  write(60,*)t,MSD(step)
end do
close(60)





deallocate(MSD)
deallocate(X,Y,Z)
write(*,*)"success!"
end program

3. pymatgen计算MSD

import os
from pymatgen.core.trajectory import Trajectory
from pymatgen.io.vasp.outputs import Xdatcar
from pymatgen.core import Structure
from pymatgen.analysis.diffusion_analyzer import DiffusionAnalyzer
import numpy as np
import pickle
from pymatgen.analysis.diffusion_analyzer import get_conversion_factor
traj=Trajectory.from_file('XDATCAR')
diff=DiffusionAnalyzer.from_structures(traj,'H',600,1,1,smoothed='constant',avg_nsteps=1)
#转换系数
conv_factor = get_conversion_factor(diff.structure, diff.specie, diff.temperature)
with open('conv_factor.dat','w') as f:
    f.write('conv_factor\t%f' %(conv_factor))
#get summary
summary = diff.get_summary_dict()
import json
json.dump(summary,open('summary.json','w'))
#msd数据
diff.export_msdt('msddata.dat')
#mscd数据
#mscd = diff.mscd
#with open('mscd.dat','w') as f:
#    for row in mscd :
#       f.write(' '.join([str(row)]))
#       f.write('\n')

4. 续算的分子动力学XDATCAR处理

!November 12,2015, by Peihao Huang --<<Molecular dynamics simulation_elementary methods>>-Wiley
program main
implicit none
integer::i,j,Natoms,step,atom,Origin,n,Totalstep,Nkindsofatom,Nstep,Nreject  !整型
real(kind=8)             ::factor,a(3,3),t,timestep,DeltaX,DeltaY,DeltaZ,DeltaRx,DeltaRy,DeltaRz,DeltaR,Xcenter0
real(kind=8)             ::Ycenter0,Zcenter0,mh,mo,m3,m4,msum,dif,logdif,sigma
!实型
real(kind=8),allocatable ::X(:,:),Y(:,:),Z(:,:),MSD(:),x0(:),y0(:),z0(:),Xcenter(:),Ycenter(:),Zcenter(:)
!实型双精度可分配数组
integer,allocatable ::natom(:)
character(len=6),allocatable ::temp(:)
!长度为6的字符串数组
character(len=7) ::temp1
mo=6.94
mh=69.72
m3=78.96
m4=16
msum=8*mo+8*mh+16*m3+48*m4

!These parameters should be input by hand 
Totalstep=187554
Nstep=187554
Nreject=0
timestep=0.002
Nkindsofatom=4

allocate(natom(Nkindsofatom),temp(Nkindsofatom))
!natom为四维整型数组,temp为四维字符型数组
!Read the original structure,only the fractional coordination is needed for the box is fixed
open(unit=30,file='POSCAR')
read(30,*)
read(30,*)
read(30,*)
read(30,*)
read(30,*) ! for earlier versions of VASP, you should delete on line of this
read(30,*)
read(30,*) natom
!将原子个数存在四维实型数组里
Natoms=0
do i=1,Nkindsofatom
  Natoms=Natoms+natom(i)
end do
!计算总的原子个数
write(*,*)Natoms
allocate(x0(Natoms),y0(Natoms),z0(Natoms))
!分配一个natoms维的数组
!read(30,*)
read(30,*)
do atom=1,Natoms
  read(30,*)x0(atom),y0(atom),z0(atom)
end do
close(30)
!将所有的初始坐标存储
!Read the structural information of the trajactory
open(unit=10,file='XDATCAR')
read(10,*)temp1
read(10,*)factor
read(10,*)a(1,1),a(1,2),a(1,3)
read(10,*)a(2,1),a(2,2),a(2,3)
read(10,*)a(3,1),a(3,2),a(3,3)
do i=1,3
  do j=1,3
    a(i,j)=a(i,j)*factor
  end do
end do
!读入晶格常数
read(10,*)temp
read(10,*)temp
allocate(X(Totalstep,Natoms),Y(Totalstep,Natoms),Z(Totalstep,Natoms))
!分配二维数组
do step=1,Totalstep
  read(10,*)
  do atom=1,Natoms
    read(10,*)X(step,atom),Y(step,atom),Z(step,atom)
  end do
end do
close(10)
!将所有原子坐标读入
!Unfold the atoms in the box with PBC
do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

open(unit=100,file='XDATCAR-1')
  do step=1,Nstep
   write(100,*) step
  do atom =1,Natoms
 write(100,"(F11.8,F15.8,F15.8)") X(step,atom),Y(step,atom),Z(step,atom)
  end do
  end do
close(100)


do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

open(unit=100,file='XDATCAR-2')
  do step=1,Nstep
   write(100,*) step
  do atom =1,Natoms
 write(100,"(F11.8,F15.8,F15.8)") X(step,atom),Y(step,atom),Z(step,atom)
  end do
  end do
close(100)

do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

open(unit=100,file='XDATCAR-3')
  do step=1,Nstep
   write(100,*) step
  do atom =1,Natoms
 write(100,"(F11.8,F15.8,F15.8)") X(step,atom),Y(step,atom),Z(step,atom)
  end do
  end do
close(100)

do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

open(unit=100,file='XDATCAR-4')
  do step=1,Nstep
   write(100,*) step
  do atom =1,Natoms
 write(100,"(F11.8,F15.8,F15.8)") X(step,atom),Y(step,atom),Z(step,atom)
  end do
  end do
close(100)

deallocate(X,Y,Z)
write(*,*)"success!"
end program

5. 计算单个原子的总MSD判断跳跃次数

楼下 /work/home/liz/workspace/1-system-MD/1-Na5YSi4O12/9a-smass=2potim=1/600/4-msd-for-every-atom/msd-atom.f90

!November 12,2015, by Peihao Huang --<<Molecular dynamics simulation_elementary methods>>-Wiley
program main
implicit none
integer::i,j,Natoms,step,atom,Origin,n,Totalstep,Nkindsofatom,Nstep,Nreject,nna  !整型
real(kind=8)::factor,a(3,3),t,timestep,DeltaX,DeltaY,DeltaZ,DeltaRx,DeltaRy,DeltaRz,DeltaR,Xcenter0
real(kind=8) ::Ycenter0,Zcenter0,mh,mo,m3,m4,msum,dif,logdif,sigma
!实型
real(kind=8),allocatable::X(:,:),Y(:,:),Z(:,:),MSD(:),x0(:),y0(:),z0(:),Xcenter(:),Ycenter(:),Zcenter(:)
!实型双精度可分配数组
integer,allocatable ::natom(:)
character(len=6),allocatable ::temp(:)
!长度为6的字符串数组
character(len=10) ::temp1
character(len=20) :: filename

!These parameters should be input by hand 
Totalstep=270000
Nstep=270000
Nreject=0
timestep=0.002
Nkindsofatom=4

allocate(natom(Nkindsofatom),temp(Nkindsofatom))
!natom为四维整型数组,temp为四维字符型数组
!Read the original structure,only the fractional coordination is needed for the box is fixed
open(unit=30,file='POSCAR')
read(30,*)
read(30,*)
read(30,*)
read(30,*)
read(30,*) ! for earlier versions of VASP, you should delete on line of this
read(30,*)
read(30,*) natom
!将原子个数存在七维实型数组里
Natoms=0
do i=1,Nkindsofatom
  Natoms=Natoms+natom(i)
end do
!计算总的原子个数
write(*,*)Natoms
allocate(x0(Natoms),y0(Natoms),z0(Natoms))
!分配一个natoms维的数组
!read(30,*)
read(30,*)
do atom=1,Natoms
  read(30,*)x0(atom),y0(atom),z0(atom)
end do
close(30)
!将所有的初始坐标存储
!Read the structural information of the trajactory
open(unit=10,file='XDATCAR')
read(10,*)temp1
read(10,*)factor
read(10,*)a(1,1),a(1,2),a(1,3)
read(10,*)a(2,1),a(2,2),a(2,3)
read(10,*)a(3,1),a(3,2),a(3,3)
do i=1,3
  do j=1,3
    a(i,j)=a(i,j)*factor
  end do
end do
!读入晶格常数
read(10,*)temp
read(10,*)
allocate(X(Totalstep,Natoms),Y(Totalstep,Natoms),Z(Totalstep,Natoms))
!分配二维数组
do step=1,Totalstep
  read(10,*)
  do atom=1,Natoms
    read(10,*)X(step,atom),Y(step,atom),Z(step,atom)
  end do
end do
close(10)
!将所有原子坐标读入
!Unfold the atoms in the box with PBC
do atom=1,Natoms
  if(X(1,atom)-x0(atom)<-0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)+1.0
    end do
  else if(X(1,atom)-x0(atom)>0.5) then
    do step=1,Totalstep
      X(step,atom)=X(step,atom)-1.0
    end do
  end if
  if(Y(1,atom)-y0(atom)<-0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)+1.0
    end do
  else if(Y(1,atom)-y0(atom)>0.5) then
    do step=1,Totalstep
      Y(step,atom)=Y(step,atom)-1.0
    end do
  end if
  if(Z(1,atom)-z0(atom)<-0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)+1.0
    end do
  else if(Z(1,atom)-z0(atom)>0.5) then
    do step=1,Totalstep
      Z(step,atom)=Z(step,atom)-1.0
    end do
  end if
end do

do step=2,Totalstep
  do atom=1,Natoms
    if(X(step,atom)-X(step-1,atom)<-0.5) then
      do n=step,Totalstep
        X(n,atom)=X(n,atom)+1.0
      end do
!从第二步开始计算,第二部比第一步多或少
    else if(X(step,atom)-X(step-1,atom)>0.5) then
      do n=step,Totalstep
        X(n,atom)=X(n,atom)-1.0
      end do
    end if
    if(Y(step,atom)-Y(step-1,atom)<-0.5) then
      do n=step,Totalstep
        Y(n,atom)=Y(n,atom)+1.0
      end do
    else if(Y(step,atom)-Y(step-1,atom)>0.5) then
      do n=step,Totalstep
        Y(n,atom)=Y(n,atom)-1.0
      end do
    end if
    if(Z(step,atom)-Z(step-1,atom)<-0.5) then
      do n=step,Totalstep
        Z(n,atom)=Z(n,atom)+1.0
      end do
    else if(Z(step,atom)-Z(step-1,atom)>0.5) then
      do n=step,Totalstep
        Z(n,atom)=Z(n,atom)-1.0
      end do
    end if
  end do
end do
!考虑周期性
!在第一帧上全部加减
!Remove the drift of center of mass

!Reject some steps before equilibrium
do step=1,Nstep
  do atom=1,Natoms
    X(step,atom)=X(step+Nreject,atom)
    Y(step,atom)=Y(step+Nreject,atom)
    Z(step,atom)=Z(step+Nreject,atom)
  end do
end do
!去除部分轨迹
!Multile time origins
allocate(MSD(Nstep-1))
!open(unit=20,file='msd-zong-t.dat')
!do step=1,Nstep-1
!  MSD(step)=0.0
!  atom=1
!  DeltaX=X(step,atom)-X(1,atom)
!  DeltaY=Y(step,atom)-Y(1,atom)
!  DeltaZ=Z(step,atom)-Z(1,atom)
!  DeltaRx=DeltaX*a(1,1)+DeltaY*a(2,1)+DeltaZ*a(3,1)
!  DeltaRy=DeltaX*a(2,2)+DeltaY*a(2,2)+DeltaZ*a(3,2)
!  DeltaRz=DeltaX*a(1,3)+DeltaY*a(2,3)+DeltaZ*a(3,3)
!  DeltaR=DeltaRx**2+DeltaRy**2+DeltaRz**2
!  MSD(step)=MSD(step)+DeltaR
!    
!  t=step*timestep
!  dif=MSD(step)/(t*6)*0.0001
!  logdif=log10(dif)
!  sigma=30*1.6*1.6*dif/1.38/400/1796.86
!!  sigma=sigma/(10**(-9))
!  write(20,*)t,MSD(step)
!end do
!close(20)
do atom=1, 30
  write(filename, "(A,I0,A)") "msd-", atom, ".dat"
  open(unit=20, file=trim(filename))
  do step=1, Nstep-1
    MSD(step) = 0.0
    DeltaX = X(step,atom) - X(1,atom)
    DeltaY = Y(step,atom) - Y(1,atom)
    DeltaZ = Z(step,atom) - Z(1,atom)
    DeltaRx = DeltaX * a(1,1) + DeltaY * a(2,1) + DeltaZ * a(3,1)
    DeltaRy = DeltaX * a(1,2) + DeltaY * a(2,2) + DeltaZ * a(3,2)
    DeltaRz = DeltaX * a(1,3) + DeltaY * a(2,3) + DeltaZ * a(3,3)
    DeltaR = DeltaRx**2 + DeltaRy**2 + DeltaRz**2
    MSD(step) = MSD(step) + DeltaR

    t = step * timestep
    dif = MSD(step) / (t * 6) * 0.0001
    logdif = log10(dif)
    sigma = 30 * 1.6 * 1.6 * dif / 1.38 / 400 / 1796.86
    !  sigma = sigma / (10**(-9))
    write(20, *) t, MSD(step)
  end do
  close(20)
end do

deallocate(MSD)
deallocate(X,Y,Z)
write(*,*)"success!"
end program

转载请注明来源 有问题可通过github提交issue