git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@265 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2007-01-30 21:53:58 +00:00
parent 96c78b75c0
commit 4d65cd25f5
12 changed files with 2413 additions and 0 deletions

51
lib/meam/Makefile Executable file
View File

@ -0,0 +1,51 @@
# *
# *_________________________________________________________________________*
# * MEAM: MODEFIED EMBEDDED ATOM METHOD *
# * DESCRIPTION: SEE READ-ME *
# * FILE NAME: Makefile *
# * AUTHORS: Greg Wagner, Sandia National Laboratories *
# * CONTACT: gjwagne@sandia.gov *
# *_________________________________________________________________________*/
SHELL = /bin/sh
# ------ FILES ------
SRC = meam_data.F meam_setup_done.F meam_setup_global.F meam_setup_param.F meam_dens_init.F meam_dens_final.F meam_force.F
FILES = $(SRC) Makefile
# ------ DEFINITIONS ------
LIB = libmeam.a
OBJ = $(SRC:.F=.o)
# ------ SETTINGS ------
F90 = gfortran
F90FLAGS = -g -fno-second-underscore
#F90FLAGS = -O
ARCHIVE = ar
ARCHFLAG = -rc
LINK = g++
LINKFLAGS = -O
USRLIB =
SYSLIB =
# ------ MAKE PROCEDURE ------
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
# ------ COMPILE RULES ------
%.o:%.F
$(F90) $(F90FLAGS) -c $<
# ------ CLEAN ------
clean:
-rm *.o *.mod *~ $(LIB)
tar:
-tar -cvf ../MEAM.tar $(FILES)

48
lib/meam/Makefile.g95 Normal file
View File

@ -0,0 +1,48 @@
# *
# *_________________________________________________________________________*
# * MEAM: MODEFIED EMBEDDED ATOM METHOD *
# * DESCRIPTION: SEE READ-ME *
# * FILE NAME: Makefile *
# * AUTHORS: Greg Wagner, Sandia National Laboratories *
# * CONTACT: gjwagne@sandia.gov *
# *_________________________________________________________________________*/
SHELL = /bin/sh
# ------ FILES ------
SRC = meam_data.F meam_setup_done.F meam_setup_global.F meam_setup_param.F meam_dens_init.F meam_dens_final.F meam_force.F
FILES = $(SRC) Makefile
# ------ DEFINITIONS ------
LIB = libmeam.a
OBJ = $(SRC:.F=.o)
# ------ SETTINGS ------
F90 = g95
F90FLAGS = -O
ARCHIVE = ar
ARCHFLAG = -rc
USRLIB =
SYSLIB =
# ------ MAKE PROCEDURE ------
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
# ------ COMPILE RULES ------
%.o:%.F
$(F90) $(F90FLAGS) -c $<
# ------ CLEAN ------
clean:
-rm *.o *.mod *~ $(LIB)
tar:
-tar -cvf ../MEAM.tar $(FILES)

View File

@ -0,0 +1,51 @@
# *
# *_________________________________________________________________________*
# * MEAM: MODEFIED EMBEDDED ATOM METHOD *
# * DESCRIPTION: SEE READ-ME *
# * FILE NAME: Makefile *
# * AUTHORS: Greg Wagner, Sandia National Laboratories *
# * CONTACT: gjwagne@sandia.gov *
# *_________________________________________________________________________*/
SHELL = /bin/sh
# ------ FILES ------
SRC = meam_data.F meam_setup_done.F meam_setup_global.F meam_setup_param.F meam_dens_init.F meam_dens_final.F meam_force.F
FILES = $(SRC) Makefile
# ------ DEFINITIONS ------
LIB = libmeam.a
OBJ = $(SRC:.F=.o)
# ------ SETTINGS ------
F90 = gfortran
F90FLAGS = -g -fno-second-underscore
#F90FLAGS = -O
ARCHIVE = ar
ARCHFLAG = -rc
LINK = g++
LINKFLAGS = -O
USRLIB =
SYSLIB =
# ------ MAKE PROCEDURE ------
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
# ------ COMPILE RULES ------
%.o:%.F
$(F90) $(F90FLAGS) -c $<
# ------ CLEAN ------
clean:
-rm *.o *.mod *~ $(LIB)
tar:
-tar -cvf ../MEAM.tar $(FILES)

48
lib/meam/Makefile.ifort Normal file
View File

@ -0,0 +1,48 @@
# *
# *_________________________________________________________________________*
# * MEAM: MODEFIED EMBEDDED ATOM METHOD *
# * DESCRIPTION: SEE READ-ME *
# * FILE NAME: Makefile *
# * AUTHORS: Greg Wagner, Sandia National Laboratories *
# * CONTACT: gjwagne@sandia.gov *
# *_________________________________________________________________________*/
SHELL = /bin/sh
# ------ FILES ------
SRC = meam_data.F meam_setup_done.F meam_setup_global.F meam_setup_param.F meam_dens_init.F meam_dens_final.F meam_force.F
FILES = $(SRC) Makefile
# ------ DEFINITIONS ------
LIB = libmeam.a
OBJ = $(SRC:.F=.o)
# ------ SETTINGS ------
F90 = ifort
F90FLAGS = -O
ARCHIVE = ar
ARCHFLAG = -rc
USRLIB =
SYSLIB =
# ------ MAKE PROCEDURE ------
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
# ------ COMPILE RULES ------
%.o:%.F
$(F90) $(F90FLAGS) -c $<
# ------ CLEAN ------
clean:
-rm *.o *.mod *~ $(LIB)
tar:
-tar -cvf ../MEAM.tar $(FILES)

20
lib/meam/README Normal file
View File

@ -0,0 +1,20 @@
MEAM (modified embedded atom method) library
Greg Wagner, Sandia National Labs
gjwagne at sandia.gov
Jan 2007
--------------
This library is in implementation of the MEAM potential, specifically
designed to work with LAMMPS.
This library must be built with a F90 compiler, before LAMMPS is
built, so LAMMPS can link against it.
Build the library using one of the provided Makefiles or creating your
own, specific to your compiler and system. For example:
make -f Makefile.g95
If the build is successful, you should end up with a libmeam.a file.

76
lib/meam/meam_data.F Executable file
View File

@ -0,0 +1,76 @@
module meam_data
integer, parameter :: maxelt = 5
c cutforce = force cutoff
c cutforcesq = force cutoff squared
real*8 cutforce,cutforcesq
c Ec_meam = cohesive energy
c re_meam = nearest-neighbor distance
c Omega_meam = atomic volume
c B_meam = bulk modulus
c Z_meam = number of first neighbors for reference structure
c ielt_meam = atomic number of element
c A_meam = adjustable parameter
c alpha_meam = sqrt(9*Omega*B/Ec)
c rho0_meam = density scaling parameter
c delta_meam = heat of formation for alloys
c beta[0-3]_meam = electron density constants
c t[0-3]_meam = coefficients on densities in Gamma computation
c ibar_meam(i) = selection parameter for Gamma function for elt i,
c lattce_meam(i,j) = lattce configuration for elt i or alloy (i,j)
c neltypes = maximum number of element type defined
c eltind = index number of pair (similar to Voigt notation; ij = ji)
c phir = pair potential function array
c phirar[1-6] = spline coeffs
c attrac_meam = attraction parameter in Rose energy
c repuls_meam = repulsion parameter in Rose energy
c nn2_meam = 1 if second nearest neighbors are to be computed, else 0
c Cmin_meam, Cmax_meam = min and max values in screening cutoff
c rc_meam = cutoff distance for meam
c delr_meam = cutoff region for meam
c ebound_meam = factor giving maximum boundary of sceen fcn ellipse
c augt1 = flag for whether t1 coefficient should be augmented
c gsmooth_factor = factor determining length of G smoothing region
c vind[23]D = Voight notation index maps for 2 and 3D
c v2D,v3D = array of factors to apply for Voight notation
c nr,dr = pair function discretization parameters
c nrar,rdrar = spline coeff array parameters
real*8 Ec_meam(maxelt,maxelt),re_meam(maxelt,maxelt)
real*8 Omega_meam(maxelt),Z_meam(maxelt)
real*8 A_meam(maxelt),alpha_meam(maxelt,maxelt),rho0_meam(maxelt)
real*8 delta_meam(maxelt,maxelt)
real*8 beta0_meam(maxelt),beta1_meam(maxelt)
real*8 beta2_meam(maxelt),beta3_meam(maxelt)
real*8 t0_meam(maxelt),t1_meam(maxelt)
real*8 t2_meam(maxelt),t3_meam(maxelt)
integer ibar_meam(maxelt),ielt_meam(maxelt)
character*3 lattce_meam(maxelt,maxelt)
integer nn2_meam(maxelt,maxelt)
integer eltind(maxelt,maxelt)
integer neltypes
real*8, allocatable :: phir(:,:)
real*8, allocatable :: phirar(:,:),phirar1(:,:),phirar2(:,:),
$ phirar3(:,:),phirar4(:,:),phirar5(:,:),phirar6(:,:)
real*8 attrac_meam(maxelt,maxelt),repuls_meam(maxelt,maxelt)
real*8 Cmin_meam(maxelt,maxelt,maxelt)
real*8 Cmax_meam(maxelt,maxelt,maxelt)
real*8 rc_meam,delr_meam,ebound_meam(maxelt,maxelt)
integer augt1
real*8 gsmooth_factor
integer vind2D(3,3),vind3D(3,3,3)
integer v2D(6),v3D(10)
integer nr,nrar
real*8 dr,rdrar
end module

201
lib/meam/meam_dens_final.F Executable file
View File

@ -0,0 +1,201 @@
c Extern "C" declaration has the form:
c
c void meam_dens_final_(int *, int *, int *, double *, int *, int *, int *,
c double *, double *, double *, double *, double *, double *,
c double *, double *, double *, double *, double *, double *,
c double *, double *, double *, double *, int *);
c
c Call from pair_meam.cpp has the form:
c
c meam_dens_final_(&nlocal,&nmax,&eflag,&eng_vdwl,ntype,type,fmap,
c &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],
c &arho3b[0][0],&t_ave[0][0],gamma,dgamma1,
c dgamma2,dgamma3,rho,rho0,rho1,rho2,rho3,frhop,&errorflag);
c
subroutine meam_dens_final(nlocal, nmax, eflag, eng_vdwl,
$ ntype, type, fmap,
$ Arho1, Arho2, Arho2b, Arho3, Arho3b, t_ave,
$ Gamma, dGamma1, dGamma2, dGamma3,
$ rho, rho0, rho1, rho2, rho3, fp, errorflag)
use meam_data
implicit none
integer nlocal, nmax, eflag, ntype, type, fmap
real*8 eng_vdwl, Arho1, Arho2
real*8 Arho2b, Arho3, Arho3b
real*8 t_ave
real*8 Gamma, dGamma1, dGamma2, dGamma3
real*8 rho, rho0, rho1, rho2, rho3
real*8 fp
integer errorflag
dimension type(nmax), fmap(ntype)
dimension Arho1(3,nmax), Arho2(6,nmax), Arho2b(nmax)
dimension Arho3(10,nmax), Arho3b(3,nmax), t_ave(3,nmax)
dimension Gamma(nmax), dGamma1(nmax), dGamma2(nmax)
dimension dGamma3(nmax), rho(nmax), rho0(nmax)
dimension rho1(nmax), rho2(nmax), rho3(nmax)
dimension fp(nmax)
integer i, elti
integer m
real*8 rhob, G, dG, Gbar, dGbar, gam, shp(3), shpi(3), Z
real*8 B, denom
c Complete the calculation of density
do i = 1,nlocal
elti = fmap(type(i))
rho1(i) = 0.d0
rho2(i) = -1.d0/3.d0*Arho2b(i)*Arho2b(i)
rho3(i) = 0.d0
do m = 1,3
rho1(i) = rho1(i) + Arho1(m,i)*Arho1(m,i)
rho3(i) = rho3(i) - 3.d0/5.d0*Arho3b(m,i)*Arho3b(m,i)
enddo
do m = 1,6
rho2(i) = rho2(i) + v2D(m)*Arho2(m,i)*Arho2(m,i)
enddo
do m = 1,10
rho3(i) = rho3(i) + v3D(m)*Arho3(m,i)*Arho3(m,i)
enddo
if( rho0(i) .gt. 0.0 ) then
t_ave(1,i) = t_ave(1,i)/rho0(i)
t_ave(2,i) = t_ave(2,i)/rho0(i)
t_ave(3,i) = t_ave(3,i)/rho0(i)
endif
Gamma(i) = t_ave(1,i)*rho1(i)
$ + t_ave(2,i)*rho2(i) + t_ave(3,i)*rho3(i)
if( rho0(i) .gt. 0.0 ) then
Gamma(i) = Gamma(i)/(rho0(i)*rho0(i))
end if
call G_gam(Gamma(i),ibar_meam(elti),gsmooth_factor,G,errorflag)
if (errorflag.ne.0) return
if (ibar_meam(elti).le.0) then
Gbar = 1.d0
else
call get_shpfcn(shp,lattce_meam(elti,elti))
gam = (t_ave(1,i)*shp(1)+t_ave(2,i)*shp(2)
$ +t_ave(3,i)*shp(3))/(Z_meam(elti)**2)
call G_gam(gam,ibar_meam(elti),gsmooth_factor,
$ Gbar,errorflag)
endif
rho(i) = rho0(i) * G
rhob = rho(i)/(rho0_meam(elti)*Z_meam(elti)*Gbar)
Z = Z_meam(elti)
call dG_gam(Gamma(i),ibar_meam(elti),gsmooth_factor,G,dG)
if (ibar_meam(elti).le.0) then
Gbar = 1.d0
dGbar = 0.d0
else
call get_shpfcn(shpi,lattce_meam(elti,elti))
gam = (t_ave(1,i)*shpi(1)+t_ave(2,i)*shpi(2)
$ +t_ave(3,i)*shpi(3))/(Z*Z)
call dG_gam(gam,ibar_meam(elti),gsmooth_factor,
$ Gbar,dGbar)
endif
denom = 1.d0/(rho0_meam(elti)*Z*Gbar)
dGamma1(i) = (G - 2*dG*Gamma(i))*denom
if( rho0(i) .ne. 0.d0 ) then
dGamma2(i) = (dG/rho0(i))*denom
else
dGamma2(i) = 0.d0
end if
dGamma3(i) = rho0(i)*G*dGbar/(Gbar*Z*Z)*denom
B = A_meam(elti)*Ec_meam(elti,elti)
if( rhob .ne. 0.d0 ) then
fp(i) = B*(log(rhob)+1.d0)
if (eflag.eq.1) eng_vdwl = eng_vdwl + B*rhob*log(rhob)
else
fp(i) = B
endif
enddo
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine G_gam(Gamma,ibar,gsmooth_factor,G,errorflag)
c Compute G(Gamma) based on selection flag ibar:
c 0 => G = sqrt(1+Gamma)
c 1 => G = exp(Gamma/2)
c 2 => not implemented
c 3 => G = 2/(1+exp(-Gamma))
c 4 => G = sqrt(1+Gamma)
implicit none
real*8 Gamma,G
real*8 gsmooth_factor, gsmooth_switchpoint
integer ibar, errorflag
if (ibar.eq.0.or.ibar.eq.4) then
gsmooth_switchpoint = -gsmooth_factor / (gsmooth_factor+1)
if (Gamma.lt.gsmooth_switchpoint) then
c e.g. gsmooth_factor is 99, then:
c gsmooth_switchpoint = -0.99
c G = 0.01*(-0.99/Gamma)**99
G = 1/(gsmooth_factor+1)
$ *(gsmooth_switchpoint/Gamma)**gsmooth_factor
G = sqrt(G)
else
G = sqrt(1.d0+Gamma)
endif
else if (ibar.eq.1) then
G = exp(Gamma/2.d0)
else if (ibar.eq.3) then
G = 2.d0/(1.d0+exp(-Gamma))
else
errorflag = 1
endif
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine dG_gam(Gamma,ibar,gsmooth_factor,G,dG)
c Compute G(Gamma) and dG(gamma) based on selection flag ibar:
c 0 => G = sqrt(1+Gamma)
c 1 => G = exp(Gamma/2)
c 2 => not implemented
c 3 => G = 2/(1+exp(-Gamma))
c 4 => G = sqrt(1+Gamma)
real*8 Gamma,G,dG
real*8 gsmooth_factor, gsmooth_switchpoint
integer ibar
if (ibar.eq.0.or.ibar.eq.4) then
gsmooth_switchpoint = -gsmooth_factor / (gsmooth_factor+1)
if (Gamma.lt.gsmooth_switchpoint) then
c e.g. gsmooth_factor is 99, then:
c gsmooth_switchpoint = -0.99
c G = 0.01*(-0.99/Gamma)**99
G = 1/(gsmooth_factor+1)
$ *(gsmooth_switchpoint/Gamma)**gsmooth_factor
G = sqrt(G)
dG = -gsmooth_factor*G/(2.0*Gamma)
else
G = sqrt(1.d0+Gamma)
dG = 1.d0/(2.d0*G)
endif
else if (ibar.eq.1) then
G = exp(Gamma/2.d0)
dG = G/2.d0
else if (ibar.eq.3) then
G = 2.d0/(1.d0+exp(-Gamma))
dG = G*(2.d0-G)/2
endif
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

521
lib/meam/meam_dens_init.F Executable file
View File

@ -0,0 +1,521 @@
c Extern "C" declaration has the form:
c
c void meam_dens_init_(int *, int *, int *, double *, int *, int *, int *, double *,
c int *, int *, int *, int *,
c double *, double *, double *, double *, double *, double *,
c double *, double *, double *, double *, int *);
c
c
c Call from pair_meam.cpp has the form:
c
c meam_dens_init_(&i,&nmax,&eflag,&eng_vdwl,ntype,type,fmap,&x[0][0],
c &numneigh[i],firstneigh[i],&numneigh_full[i],firstneigh_full[i],
c &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
c rho0,&arho1[0][0],&arho2[0][0],arho2b,
c &arho3[0][0],&arho3b[0][0],&t_ave[0][0],&errorflag);
c
subroutine meam_dens_init(i, nmax, eflag, eng_vdwl,
$ ntype, type, fmap, x,
$ numneigh, firstneigh,
$ numneigh_full, firstneigh_full,
$ scrfcn, dscrfcn, fcpair, rho0, arho1, arho2, arho2b,
$ arho3, arho3b, t_ave, errorflag)
use meam_data
implicit none
integer i, nmax, eflag, ntype, type, fmap
real*8 eng_vdwl
real*8 x
integer numneigh, firstneigh, numneigh_full, firstneigh_full
real*8 scrfcn, dscrfcn, fcpair
real*8 rho0, arho1, arho2
real*8 arho2b, arho3, arho3b, t_ave
integer errorflag
integer j,jn
dimension x(3,nmax)
dimension type(nmax), fmap(ntype)
dimension firstneigh(numneigh), firstneigh_full(numneigh_full)
dimension scrfcn(numneigh), dscrfcn(numneigh), fcpair(numneigh)
dimension rho0(nmax), arho1(3,nmax), arho2(6,nmax)
dimension arho2b(nmax), arho3(10,nmax), arho3b(3,nmax)
dimension t_ave(3,nmax)
errorflag = 0
c Compute screening function and derivatives
call getscreen(i, nmax, scrfcn, dscrfcn, fcpair, x,
$ numneigh, firstneigh,
$ numneigh_full, firstneigh_full,
$ ntype, type, fmap)
c Calculate intermediate density terms to be communicated
call calc_rho1(i, nmax, ntype, type, fmap, x,
$ numneigh, firstneigh,
$ scrfcn, fcpair, rho0, arho1, arho2, arho2b,
$ arho3, arho3b, t_ave)
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine getscreen(i, nmax, scrfcn, dscrfcn, fcpair, x,
$ numneigh, firstneigh,
$ numneigh_full, firstneigh_full,
$ ntype, type, fmap)
use meam_data
implicit none
integer i, nmax
real*8 scrfcn, dscrfcn, fcpair, x
integer numneigh, firstneigh, numneigh_full, firstneigh_full
integer ntype, type, fmap
dimension scrfcn(numneigh), dscrfcn(numneigh)
dimension fcpair(numneigh), x(3,nmax)
dimension firstneigh(numneigh), firstneigh_full(numneigh_full)
dimension type(nmax), fmap(ntype)
integer jn,j,kn,k
integer elti,eltj,eltk
real*8 xitmp,yitmp,zitmp,delxij,delyij,delzij,rij2,rij
real*8 xjtmp,yjtmp,zjtmp,delxik,delyik,delzik,rik2,rik
real*8 xktmp,yktmp,zktmp,delxjk,delyjk,delzjk,rjk2,rjk
real*8 xik,xjk,sij,fcij,sfcij,dfcij,sikj,dfikj,cikj
real*8 Cmin,Cmax,delc,ebound,rbound,a,coef1,coef2
real*8 coef1a,coef1b,coef2a,coef2b
real*8 dcikj
real*8 dC1a,dC1b,dC2a,dC2b
real*8 rnorm,fc,dfc,drinv
drinv = 1.d0/delr_meam
elti = fmap(type(i))
xitmp = x(1,i)
yitmp = x(2,i)
zitmp = x(3,i)
do jn = 1,numneigh
j = firstneigh(jn)
c First compute screening function itself, sij
xjtmp = x(1,j)
yjtmp = x(2,j)
zjtmp = x(3,j)
delxij = xjtmp - xitmp
delyij = yjtmp - yitmp
delzij = zjtmp - zitmp
rij2 = delxij*delxij + delyij*delyij + delzij*delzij
rij = sqrt(rij2)
if (rij.gt.rc_meam) then
fcij = 0.0
dfcij = 0.d0
sij = 0.d0
else
rnorm = (rc_meam-rij)*drinv
call screen(i, j, nmax, x, rij2, sij,
$ numneigh_full, firstneigh_full, ntype, type, fmap)
call dfcut(rnorm,fc,dfc)
fcij = fc
dfcij = dfc*drinv
endif
c Now compute derivatives
dscrfcn(jn) = 0.d0
sfcij = sij*fcij
if (sfcij.eq.0.d0.or.sfcij.eq.1.d0) goto 100
eltj = fmap(type(j))
rbound = ebound_meam(elti,eltj) * rij2
do kn = 1,numneigh_full
k = firstneigh_full(kn)
if (k.eq.j) goto 10
eltk = fmap(type(k))
xktmp = x(1,k)
yktmp = x(2,k)
zktmp = x(3,k)
delxjk = xktmp - xjtmp
delyjk = yktmp - yjtmp
delzjk = zktmp - zjtmp
rjk2 = delxjk*delxjk + delyjk*delyjk + delzjk*delzjk
if (rjk2.gt.rbound) goto 10
delxik = xktmp - xitmp
delyik = yktmp - yitmp
delzik = zktmp - zitmp
rik2 = delxik*delxik + delyik*delyik + delzik*delzik
if (rik2.gt.rbound) goto 10
xik = rik2/rij2
xjk = rjk2/rij2
a = 1 - (xik-xjk)*(xik-xjk)
if (a.eq.0.d0) goto 10
cikj = (2.d0*(xik+xjk) + a - 2.d0)/a
Cmax = Cmax_meam(elti,eltj,eltk)
Cmin = Cmin_meam(elti,eltj,eltk)
if (cikj.ge.Cmax.or.cikj.lt.0.d0) then
goto 10
c Note that we never have 0<cikj<Cmin here, else sij=0 (rejected above)
else
delc = Cmax - Cmin
cikj = (cikj-Cmin)/delc
call dfcut(cikj,sikj,dfikj)
coef1 = dfikj/(delc*sikj)
call dCfunc(rij2,rik2,rjk2,dCikj)
dscrfcn(jn) = dscrfcn(jn) + coef1*dCikj
endif
10 continue
enddo
coef1 = sfcij
coef2 = sij*dfcij/rij
dscrfcn(jn) = dscrfcn(jn)*coef1 - coef2
100 continue
scrfcn(jn) = sij
fcpair(jn) = fcij
enddo
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine calc_rho1(i, nmax, ntype, type, fmap, x,
$ numneigh, firstneigh,
$ scrfcn, fcpair, rho0, arho1, arho2, arho2b,
$ arho3, arho3b, t_ave)
use meam_data
implicit none
integer i, nmax, ntype, type, fmap
real*8 x
integer numneigh, firstneigh
real*8 scrfcn, fcpair, rho0, arho1, arho2
real*8 arho2b, arho3, arho3b, t_ave
dimension type(nmax), fmap(ntype), x(3,nmax)
dimension firstneigh(numneigh)
dimension scrfcn(numneigh), fcpair(numneigh)
dimension rho0(nmax), arho1(3,nmax), arho2(6,nmax)
dimension arho2b(nmax), arho3(10,nmax), arho3b(3,nmax)
dimension t_ave(3,nmax)
integer jn,j,m,n,p,elti,eltj
integer nv2,nv3
real*8 xtmp,ytmp,ztmp,delij(3),rij2,rij,sij
real*8 ai,aj,rhoa0j,rhoa1j,rhoa2j,rhoa3j,A1j,A2j,A3j
real*8 G,Gbar,gam,shp(3)
real*8 ro0i,ro0j
real*8 rhoa0i,rhoa1i,rhoa2i,rhoa3i,A1i,A2i,A3i
elti = fmap(type(i))
xtmp = x(1,i)
ytmp = x(2,i)
ztmp = x(3,i)
do jn = 1,numneigh
if (scrfcn(jn).ne.0.d0) then
j = firstneigh(jn)
sij = scrfcn(jn)*fcpair(jn)
delij(1) = x(1,j) - xtmp
delij(2) = x(2,j) - ytmp
delij(3) = x(3,j) - ztmp
rij2 = delij(1)*delij(1) + delij(2)*delij(2)
$ + delij(3)*delij(3)
if (rij2.lt.cutforcesq) then
eltj = fmap(type(j))
rij = sqrt(rij2)
ai = rij/re_meam(elti,elti) - 1.d0
aj = rij/re_meam(eltj,eltj) - 1.d0
ro0i = rho0_meam(elti)
ro0j = rho0_meam(eltj)
rhoa0j = ro0j*exp(-beta0_meam(eltj)*aj)*sij
rhoa1j = ro0j*exp(-beta1_meam(eltj)*aj)*sij
rhoa2j = ro0j*exp(-beta2_meam(eltj)*aj)*sij
rhoa3j = ro0j*exp(-beta3_meam(eltj)*aj)*sij
rhoa0i = ro0i*exp(-beta0_meam(elti)*ai)*sij
rhoa1i = ro0i*exp(-beta1_meam(elti)*ai)*sij
rhoa2i = ro0i*exp(-beta2_meam(elti)*ai)*sij
rhoa3i = ro0i*exp(-beta3_meam(elti)*ai)*sij
rho0(i) = rho0(i) + rhoa0j
rho0(j) = rho0(j) + rhoa0i
t_ave(1,i) = t_ave(1,i) + t1_meam(eltj)*rhoa0j
t_ave(2,i) = t_ave(2,i) + t2_meam(eltj)*rhoa0j
t_ave(3,i) = t_ave(3,i) + t3_meam(eltj)*rhoa0j
t_ave(1,j) = t_ave(1,j) + t1_meam(elti)*rhoa0i
t_ave(2,j) = t_ave(2,j) + t2_meam(elti)*rhoa0i
t_ave(3,j) = t_ave(3,j) + t3_meam(elti)*rhoa0i
Arho2b(i) = Arho2b(i) + rhoa2j
Arho2b(j) = Arho2b(j) + rhoa2i
A1j = rhoa1j/rij
A2j = rhoa2j/rij2
A3j = rhoa3j/(rij2*rij)
A1i = rhoa1i/rij
A2i = rhoa2i/rij2
A3i = rhoa3i/(rij2*rij)
nv2 = 1
nv3 = 1
do m = 1,3
Arho1(m,i) = Arho1(m,i) + A1j*delij(m)
Arho1(m,j) = Arho1(m,j) - A1i*delij(m)
Arho3b(m,i) = Arho3b(m,i) + rhoa3j*delij(m)/rij
Arho3b(m,j) = Arho3b(m,j) - rhoa3i*delij(m)/rij
do n = m,3
Arho2(nv2,i) = Arho2(nv2,i) + A2j*delij(m)*delij(n)
Arho2(nv2,j) = Arho2(nv2,j) + A2i*delij(m)*delij(n)
nv2 = nv2+1
do p = n,3
Arho3(nv3,i) = Arho3(nv3,i)
$ + A3j*delij(m)*delij(n)*delij(p)
Arho3(nv3,j) = Arho3(nv3,j)
$ - A3i*delij(m)*delij(n)*delij(p)
nv3 = nv3+1
enddo
enddo
enddo
endif
endif
enddo
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine screen(i, j, nmax, x, rijsq, sij,
$ numneigh_full, firstneigh_full, ntype, type, fmap)
c Screening function
c Inputs: i = atom 1 id (integer)
c j = atom 2 id (integer)
c rijsq = squared distance between i and j
c Outputs: sij = screening function
use meam_data
implicit none
integer i,j,nmax,k,nk,m
real*8 x,rijsq,sij
integer numneigh_full, firstneigh_full
integer ntype, type, fmap
dimension x(3,nmax), firstneigh_full(numneigh_full)
dimension type(nmax), fmap(ntype)
integer elti,eltj,eltk
real*8 delxik,delyik,delzik
real*8 delxjk,delyjk,delzjk
real*8 riksq,rjksq,xik,xjk,cikj,a,delc,sikj,fcij,rij
real*8 Cmax,Cmin,rbound
sij = 1.d0
elti = fmap(type(i))
eltj = fmap(type(j))
c if rjksq > ebound*rijsq, atom k is definitely outside the ellipse
rbound = ebound_meam(elti,eltj)*rijsq
do nk = 1,numneigh_full
k = firstneigh_full(nk)
eltk = fmap(type(k))
if (k.eq.j) goto 10
delxjk = x(1,k) - x(1,j)
delyjk = x(2,k) - x(2,j)
delzjk = x(3,k) - x(3,j)
rjksq = delxjk*delxjk + delyjk*delyjk + delzjk*delzjk
if (rjksq.gt.rbound) goto 10
delxik = x(1,k) - x(1,i)
delyik = x(2,k) - x(2,i)
delzik = x(3,k) - x(3,i)
riksq = delxik*delxik + delyik*delyik + delzik*delzik
if (riksq.gt.rbound) goto 10
xik = riksq/rijsq
xjk = rjksq/rijsq
a = 1 - (xik-xjk)*(xik-xjk)
if (a.eq.0.d0) goto 10
cikj = (2.d0*(xik+xjk) + a - 2.d0)/a
Cmax = Cmax_meam(elti,eltj,eltk)
Cmin = Cmin_meam(elti,eltj,eltk)
if (cikj.ge.Cmax.or.cikj.lt.0.d0) then
goto 10
else if (cikj.le.Cmin) then
sij = 0.d0
goto 20
else
delc = Cmax - Cmin
cikj = (cikj-Cmin)/delc
call fcut(cikj,sikj)
endif
sij = sij * sikj
10 continue
enddo
20 continue
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine dsij(i,j,k,jn,nmax,numneigh,rij2,dsij1,dsij2,
$ ntype,type,fmap,x,scrfcn,fcpair)
c Inputs: i,j,k = id's of 3 atom triplet
c jn = id of i-j pair
c rij2 = squared distance between i and j
c Outputs: dsij1 = deriv. of sij w.r.t. rik
c dsij2 = deriv. of sij w.r.t. rjk
use meam_data
implicit none
integer i,j,k,jn,nmax,numneigh
integer elti,eltj,eltk
real*8 rij2,rik2,rjk2,dsij1,dsij2
integer ntype, type, fmap
real*8 x, scrfcn, fcpair
dimension type(nmax), fmap(ntype)
dimension x(3,nmax), scrfcn(numneigh), fcpair(numneigh)
real*8 dxik,dyik,dzik
real*8 dxjk,dyjk,dzjk
real*8 rbound,delc,sij,xik,xjk,cikj,sikj,dfc,a
real*8 Cmax,Cmin,dCikj1,dCikj2
sij = scrfcn(jn)*fcpair(jn)
elti = fmap(type(i))
eltj = fmap(type(j))
eltk = fmap(type(k))
Cmax = Cmax_meam(elti,eltj,eltk)
Cmin = Cmin_meam(elti,eltj,eltk)
dsij1 = 0.d0
dsij2 = 0.d0
if ((sij.ne.0.d0).and.(sij.ne.1.d0)) then
rbound = rij2*ebound_meam(elti,eltj)
delc = Cmax-Cmin
dxjk = x(1,k) - x(1,j)
dyjk = x(2,k) - x(2,j)
dzjk = x(3,k) - x(3,j)
rjk2 = dxjk*dxjk + dyjk*dyjk + dzjk*dzjk
if (rjk2.le.rbound) then
dxik = x(1,k) - x(1,i)
dyik = x(2,k) - x(2,i)
dzik = x(3,k) - x(3,i)
rik2 = dxik*dxik + dyik*dyik + dzik*dzik
if (rik2.le.rbound) then
xik = rik2/rij2
xjk = rjk2/rij2
a = 1 - (xik-xjk)*(xik-xjk)
if (a.ne.0.d0) then
cikj = (2.d0*(xik+xjk) + a - 2.d0)/a
if (cikj.ge.Cmin.and.cikj.le.Cmax) then
cikj = (cikj-Cmin)/delc
call dfcut(cikj,sikj,dfc)
call dCfunc2(rij2,rik2,rjk2,dCikj1,dCikj2)
a = sij/delc*dfc/sikj
dsij1 = a*dCikj1
dsij2 = a*dCikj2
endif
endif
endif
endif
endif
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine fcut(xi,fc)
c cutoff function
implicit none
real*8 xi,fc
real*8 a
if (xi.ge.1.d0) then
fc = 1.d0
else if (xi.le.0.d0) then
fc = 0.d0
else
a = 1.d0-xi
a = a*a
a = a*a
a = 1.d0-a
fc = a*a
c fc = xi
endif
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine dfcut(xi,fc,dfc)
c cutoff function and its derivative
implicit none
real*8 xi,fc,dfc,a,a3,a4
if (xi.ge.1.d0) then
fc = 1.d0
dfc = 0.d0
else if (xi.le.0.d0) then
fc = 0.d0
dfc = 0.d0
else
a = 1.d0-xi
a3 = a*a*a
a4 = a*a3
fc = (1.d0-a4)**2
dfc = 8*(1.d0-a4)*a3
c fc = xi
c dfc = 1.d0
endif
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine dCfunc(rij2,rik2,rjk2,dCikj)
c Inputs: rij,rij2,rik2,rjk2
c Outputs: dCikj = derivative of Cikj w.r.t. rij
implicit none
real*8 rij2,rik2,rjk2,dCikj
real*8 rij4,a,b,denom
rij4 = rij2*rij2
a = rik2-rjk2
b = rik2+rjk2
denom = rij4 - a*a
denom = denom*denom
dCikj = -4*(-2*rij2*a*a + rij4*b + a*a*b)/denom
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
subroutine dCfunc2(rij2,rik2,rjk2,dCikj1,dCikj2)
c Inputs: rij,rij2,rik2,rjk2
c Outputs: dCikj1 = derivative of Cikj w.r.t. rik
c dCikj2 = derivative of Cikj w.r.t. rjk
implicit none
real*8 rij2,rik2,rjk2,dCikj1,dCikj2
real*8 rij4,rik4,rjk4,a,b,denom
rij4 = rij2*rij2
rik4 = rik2*rik2
rjk4 = rjk2*rjk2
a = rik2-rjk2
b = rik2+rjk2
denom = rij4 - a*a
denom = denom*denom
dCikj1 = 4*rij2*(rij4 + rik4 + 2*rik2*rjk2 - 3*rjk4 - 2*rij2*a)/
$ denom
dCikj2 = 4*rij2*(rij4 - 3*rik4 + 2*rik2*rjk2 + rjk4 + 2*rij2*a)/
$ denom
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

438
lib/meam/meam_force.F Executable file
View File

@ -0,0 +1,438 @@
c Extern "C" declaration has the form:
c
c void meam_force_(int *, int *, int *, double *, int *, int *, int *, double *,
c int *, int *, int *, int *, double *, double *,
c double *, double *, double *, double *, double *, double *,
c double *, double *, double *, double *, double *, double *,
c double *, double *, double *, double *, double *, int *);
c
c Call from pair_meam.cpp has the form:
c
c meam_force_(&i,&nmax,&eflag,&eng_vdwl,&ntype,type,fmap,&x[0][0],
c &numneigh[i],firstneigh[i],&numneigh_full[i],firstneigh_full[i],
c &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
c dgamma1,dgamma2,dgamma3,rho0,rho1,rho2,rho3,frhop,
c &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],&arho3b[0][0],
c &t_ave[0][0],&f[0][0],&strssa[0][0][0],&errorflag);
c
subroutine meam_force(i, nmax, eflag, eng_vdwl,
$ ntype, type, fmap, x,
$ numneigh, firstneigh, numneigh_full, firstneigh_full,
$ scrfcn, dscrfcn, fcpair,
$ dGamma1, dGamma2, dGamma3, rho0, rho1, rho2, rho3, fp,
$ Arho1, Arho2, Arho2b, Arho3, Arho3b, t_ave, f, strssa,
$ errorflag)
use meam_data
implicit none
integer eflag, nmax, ntype, type, fmap
real*8 eng_vdwl, x
integer numneigh, firstneigh, numneigh_full, firstneigh_full
real*8 scrfcn, dscrfcn, fcpair
real*8 dGamma1, dGamma2, dGamma3
real*8 rho0, rho1, rho2, rho3, fp
real*8 Arho1, Arho2, Arho2b
real*8 Arho3, Arho3b
real*8 t_ave, f, strssa
integer errorflag
dimension type(nmax), fmap(ntype)
dimension x(3,nmax)
dimension firstneigh(numneigh), firstneigh_full(numneigh_full)
dimension scrfcn(numneigh), dscrfcn(numneigh), fcpair(numneigh)
dimension dGamma1(nmax), dGamma2(nmax), dGamma3(nmax)
dimension rho0(nmax), rho1(nmax), rho2(nmax), rho3(nmax), fp(nmax)
dimension Arho1(3,nmax), Arho2(6,nmax), Arho2b(nmax)
dimension Arho3(10,nmax), Arho3b(3,nmax)
dimension t_ave(3,nmax), f(3,nmax), strssa(3,3,nmax)
integer i,j,jn,k,kn,kk,m,n,p,q,strscomp
integer nv2,nv3,elti,eltj,ind
real*8 xitmp,yitmp,zitmp,delij(3),delref(3),rij2,rij,rij3
real*8 delik(3),deljk(3)
real*8 Eu,astar,astarp
real*8 pp,phiforce,dUdrij,dUdsij,dUdrijm(3),force,forcem
real*8 B,r,recip,phi,phip,rhop,a
real*8 sij,fcij,dfcij,ds(3)
real*8 a0,a1,a1i,a1j,a2,a2i,a2j
real*8 a3i,a3j,a3i1,a3i2,a3j1,a3j2
real*8 G,dG,Gbar,dGbar,gam,shpi(3),shpj(3),Z,denom
real*8 ai,aj,ro0i,ro0j,invrei,invrej
real*8 b0,rhoa0j,drhoa0j,rhoa0i,drhoa0i
real*8 b1,rhoa1j,drhoa1j,rhoa1i,drhoa1i
real*8 b2,rhoa2j,drhoa2j,rhoa2i,drhoa2i
real*8 a3,a3a,b3,rhoa3j,drhoa3j,rhoa3i,drhoa3i
real*8 drho0dr1,drho0dr2,drho0ds1,drho0ds2
real*8 drho1dr1,drho1dr2,drho1ds1,drho1ds2
real*8 drho1drm1(3),drho1drm2(3)
real*8 drho2dr1,drho2dr2,drho2ds1,drho2ds2
real*8 drho2drm1(3),drho2drm2(3)
real*8 drho3dr1,drho3dr2,drho3ds1,drho3ds2
real*8 drho3drm1(3),drho3drm2(3)
real*8 dt1dr1,dt1dr2,dt1ds1,dt1ds2
real*8 dt2dr1,dt2dr2,dt2ds1,dt2ds2
real*8 dt3dr1,dt3dr2,dt3ds1,dt3ds2
real*8 drhodr1,drhodr2,drhods1,drhods2,drhodrm1(3),drhodrm2(3)
real*8 arg,arg1,arg2
real*8 arg1i1,arg1j1,arg1i2,arg1j2,arg2i2,arg2j2
real*8 arg1i3,arg1j3,arg2i3,arg2j3,arg3i3,arg3j3
real*8 dsij1,dsij2,force1,force2
real*8 t1i,t2i,t3i,t1j,t2j,t3j
errorflag = 0
strscomp = 0
c Compute forces atom i
elti = fmap(type(i))
xitmp = x(1,i)
yitmp = x(2,i)
zitmp = x(3,i)
c Treat each pair
do jn = 1,numneigh
if (scrfcn(jn).ne.0.d0) then
j = firstneigh(jn)
sij = scrfcn(jn)*fcpair(jn)
delij(1) = x(1,j) - xitmp
delij(2) = x(2,j) - yitmp
delij(3) = x(3,j) - zitmp
rij2 = delij(1)*delij(1) + delij(2)*delij(2)
$ + delij(3)*delij(3)
if (rij2.lt.cutforcesq) then
rij = sqrt(rij2)
r = rij
eltj = fmap(type(j))
c Compute phi and phip
ind = eltind(elti,eltj)
pp = rij*rdrar + 1.0D0
kk = pp
kk = min(kk,nrar-1)
pp = pp - kk
pp = min(pp,1.0D0)
phi = ((phirar3(kk,ind)*pp + phirar2(kk,ind))*pp
$ + phirar1(kk,ind))*pp + phirar(kk,ind)
phip = (phirar6(kk,ind)*pp + phirar5(kk,ind))*pp
$ + phirar4(kk,ind)
recip = 1.0d0/r
if (eflag.eq.1) eng_vdwl = eng_vdwl + phi*sij
c write(1,*) "force_meamf: phi: ",phi
c write(1,*) "force_meamf: phip: ",phip
c Compute pair densities and derivatives
invrei = 1.d0/re_meam(elti,elti)
ai = rij*invrei - 1.d0
ro0i = rho0_meam(elti)
rhoa0i = ro0i*exp(-beta0_meam(elti)*ai)
drhoa0i = -beta0_meam(elti)*invrei*rhoa0i
rhoa1i = ro0i*exp(-beta1_meam(elti)*ai)
drhoa1i = -beta1_meam(elti)*invrei*rhoa1i
rhoa2i = ro0i*exp(-beta2_meam(elti)*ai)
drhoa2i = -beta2_meam(elti)*invrei*rhoa2i
rhoa3i = ro0i*exp(-beta3_meam(elti)*ai)
drhoa3i = -beta3_meam(elti)*invrei*rhoa3i
if (elti.ne.eltj) then
invrej = 1.d0/re_meam(eltj,eltj)
aj = rij*invrej - 1.d0
ro0j = rho0_meam(eltj)
rhoa0j = ro0j*exp(-beta0_meam(eltj)*aj)
drhoa0j = -beta0_meam(eltj)*invrej*rhoa0j
rhoa1j = ro0j*exp(-beta1_meam(eltj)*aj)
drhoa1j = -beta1_meam(eltj)*invrej*rhoa1j
rhoa2j = ro0j*exp(-beta2_meam(eltj)*aj)
drhoa2j = -beta2_meam(eltj)*invrej*rhoa2j
rhoa3j = ro0j*exp(-beta3_meam(eltj)*aj)
drhoa3j = -beta3_meam(eltj)*invrej*rhoa3j
else
rhoa0j = rhoa0i
drhoa0j = drhoa0i
rhoa1j = rhoa1i
drhoa1j = drhoa1i
rhoa2j = rhoa2i
drhoa2j = drhoa2i
rhoa3j = rhoa3i
drhoa3j = drhoa3i
endif
nv2 = 1
nv3 = 1
arg1i1 = 0.d0
arg1j1 = 0.d0
arg1i2 = 0.d0
arg1j2 = 0.d0
arg1i3 = 0.d0
arg1j3 = 0.d0
arg3i3 = 0.d0
arg3j3 = 0.d0
do n = 1,3
do p = n,3
do q = p,3
arg = delij(n)*delij(p)*delij(q)*v3D(nv3)
arg1i3 = arg1i3 + Arho3(nv3,i)*arg
arg1j3 = arg1j3 - Arho3(nv3,j)*arg
nv3 = nv3+1
enddo
arg = delij(n)*delij(p)*v2D(nv2)
arg1i2 = arg1i2 + Arho2(nv2,i)*arg
arg1j2 = arg1j2 + Arho2(nv2,j)*arg
nv2 = nv2+1
enddo
arg1i1 = arg1i1 + Arho1(n,i)*delij(n)
arg1j1 = arg1j1 - Arho1(n,j)*delij(n)
arg3i3 = arg3i3 + Arho3b(n,i)*delij(n)
arg3j3 = arg3j3 - Arho3b(n,j)*delij(n)
enddo
c rho0 terms
drho0dr1 = drhoa0j * sij
drho0dr2 = drhoa0i * sij
c rho1 terms
a1 = 2*sij/rij
drho1dr1 = a1*(drhoa1j-rhoa1j/rij)*arg1i1
drho1dr2 = a1*(drhoa1i-rhoa1i/rij)*arg1j1
a1 = 2.d0*sij/rij
do m = 1,3
drho1drm1(m) = a1*rhoa1j*Arho1(m,i)
drho1drm2(m) = -a1*rhoa1i*Arho1(m,j)
enddo
c rho2 terms
a2 = 2*sij/rij2
drho2dr1 = a2*(drhoa2j - 2*rhoa2j/rij)*arg1i2
$ - 2.d0/3.d0*Arho2b(i)*drhoa2j*sij
drho2dr2 = a2*(drhoa2i - 2*rhoa2i/rij)*arg1j2
$ - 2.d0/3.d0*Arho2b(j)*drhoa2i*sij
a2 = 4*sij/rij2
do m = 1,3
drho2drm1(m) = 0.d0
drho2drm2(m) = 0.d0
do n = 1,3
drho2drm1(m) = drho2drm1(m)
$ + Arho2(vind2D(m,n),i)*delij(n)
drho2drm2(m) = drho2drm2(m)
$ - Arho2(vind2D(m,n),j)*delij(n)
enddo
drho2drm1(m) = a2*rhoa2j*drho2drm1(m)
drho2drm2(m) = -a2*rhoa2i*drho2drm2(m)
enddo
c rho3 terms
rij3 = rij*rij2
a3 = 2*sij/rij3
a3a = 6.d0/5.d0*sij/rij
drho3dr1 = a3*(drhoa3j - 3*rhoa3j/rij)*arg1i3
$ - a3a*(drhoa3j - rhoa3j/rij)*arg3i3
drho3dr2 = a3*(drhoa3i - 3*rhoa3i/rij)*arg1j3
$ - a3a*(drhoa3i - rhoa3i/rij)*arg3j3
a3 = 6*sij/rij3
a3a = 6*sij/(5*rij)
do m = 1,3
drho3drm1(m) = 0.d0
drho3drm2(m) = 0.d0
nv2 = 1
do n = 1,3
do p = n,3
arg = delij(n)*delij(p)*v2D(nv2)
drho3drm1(m) = drho3drm1(m)
$ + Arho3(vind3D(m,n,p),i)*arg
drho3drm2(m) = drho3drm2(m)
$ + Arho3(vind3D(m,n,p),j)*arg
nv2 = nv2 + 1
enddo
enddo
drho3drm1(m) = (a3*drho3drm1(m) - a3a*Arho3b(m,i))
$ *rhoa3j
drho3drm2(m) = (-a3*drho3drm2(m) + a3a*Arho3b(m,j))
$ *rhoa3i
enddo
c Compute derivatives of weighting functions t wrt rij
t1i = t_ave(1,i)
t2i = t_ave(2,i)
t3i = t_ave(3,i)
t1j = t_ave(1,j)
t2j = t_ave(2,j)
t3j = t_ave(3,j)
ai = 0.d0
if( rho0(i) .ne. 0.d0 ) then
ai = drhoa0j*sij/rho0(i)
end if
aj = 0.d0
if( rho0(j) .ne. 0.d0 ) then
aj = drhoa0i*sij/rho0(j)
end if
dt1dr1 = ai*(t1_meam(eltj)-t1i)
dt1dr2 = aj*(t1_meam(elti)-t1j)
dt2dr1 = ai*(t2_meam(eltj)-t2i)
dt2dr2 = aj*(t2_meam(elti)-t2j)
dt3dr1 = ai*(t3_meam(eltj)-t3i)
dt3dr2 = aj*(t3_meam(elti)-t3j)
c Compute derivatives of total density wrt rij, sij and rij(3)
call get_shpfcn(shpi,lattce_meam(elti,elti))
call get_shpfcn(shpj,lattce_meam(eltj,eltj))
drhodr1 = dGamma1(i)*drho0dr1
$ + dGamma2(i)*
$ (dt1dr1*rho1(i)+t1i*drho1dr1
$ + dt2dr1*rho2(i)+t2i*drho2dr1
$ + dt3dr1*rho3(i)+t3i*drho3dr1)
$ - dGamma3(i)*
$ (shpi(1)*dt1dr1+shpi(2)*dt2dr1+shpi(3)*dt3dr1)
drhodr2 = dGamma1(j)*drho0dr2
$ + dGamma2(j)*
$ (dt1dr2*rho1(j)+t1j*drho1dr2
$ + dt2dr2*rho2(j)+t2j*drho2dr2
$ + dt3dr2*rho3(j)+t3j*drho3dr2)
$ - dGamma3(j)*
$ (shpj(1)*dt1dr2+shpj(2)*dt2dr2+shpj(3)*dt3dr2)
do m = 1,3
drhodrm1(m) = 0.d0
drhodrm2(m) = 0.d0
drhodrm1(m) = dGamma2(i)*
$ (t1i*drho1drm1(m)
$ + t2i*drho2drm1(m)
$ + t3i*drho3drm1(m))
drhodrm2(m) = dGamma2(j)*
$ (t1j*drho1drm2(m)
$ + t2j*drho2drm2(m)
$ + t3j*drho3drm2(m))
enddo
c Compute derivatives wrt sij, but only if necessary
if (dscrfcn(jn).ne.0.d0) then
drho0ds1 = rhoa0j
drho0ds2 = rhoa0i
a1 = 2.d0/rij
drho1ds1 = a1*rhoa1j*arg1i1
drho1ds2 = a1*rhoa1i*arg1j1
a2 = 2.d0/rij2
drho2ds1 = a2*rhoa2j*arg1i2
$ - 2.d0/3.d0*Arho2b(i)*rhoa2j
drho2ds2 = a2*rhoa2i*arg1j2
$ - 2.d0/3.d0*Arho2b(j)*rhoa2i
a3 = 2.d0/rij3
a3a = 6.d0/(5.d0*rij)
drho3ds1 = a3*rhoa3j*arg1i3 - a3a*rhoa3j*arg3i3
drho3ds2 = a3*rhoa3i*arg1j3 - a3a*rhoa3i*arg3j3
ai = 0.d0
if( rho0(i) .ne. 0.d0 ) then
ai = rhoa0j/rho0(i)
end if
aj = 0.d0
if( rho0(j) .ne. 0.d0 ) then
aj = rhoa0i/rho0(j)
end if
dt1ds1 = ai*(t1_meam(eltj)-t1i)
dt1ds2 = aj*(t1_meam(elti)-t1j)
dt2ds1 = ai*(t2_meam(eltj)-t2i)
dt2ds2 = aj*(t2_meam(elti)-t2j)
dt3ds1 = ai*(t3_meam(eltj)-t3i)
dt3ds2 = aj*(t3_meam(elti)-t3j)
drhods1 = dGamma1(i)*drho0ds1
$ + dGamma2(i)*
$ (dt1ds1*rho1(i)+t1i*drho1ds1
$ + dt2ds1*rho2(i)+t2i*drho2ds1
$ + dt3ds1*rho3(i)+t3i*drho3ds1)
$ - dGamma3(i)*
$ (shpi(1)*dt1ds1+shpi(2)*dt2ds1+shpi(3)*dt3ds1)
drhods2 = dGamma1(j)*drho0ds2
$ + dGamma2(j)*
$ (dt1ds2*rho1(j)+t1j*drho1ds2
$ + dt2ds2*rho2(j)+t2j*drho2ds2
$ + dt3ds2*rho3(j)+t3j*drho3ds2)
$ - dGamma3(j)*
$ (shpj(1)*dt1ds2+shpj(2)*dt2ds2+shpj(3)*dt3ds2)
endif
c Compute derivatives of energy wrt rij, sij and rij(3)
dUdrij = phip*sij
$ + fp(i)*drhodr1 + fp(j)*drhodr2
dUdsij = 0.d0
if (dscrfcn(jn).ne.0.d0) then
dUdsij = phi
$ + fp(i)*drhods1 + fp(j)*drhods2
endif
do m = 1,3
dUdrijm(m) = fp(i)*drhodrm1(m) + fp(j)*drhodrm2(m)
enddo
c Add the part of the force due to dUdrij and dUdsij
force = dUdrij*recip + dUdsij*dscrfcn(jn)
do m = 1,3
forcem = delij(m)*force + dUdrijm(m)
f(m,i) = f(m,i) + forcem
f(m,j) = f(m,j) - forcem
if (strscomp>0) then
do n = 1,3
arg = delij(n)*forcem
strssa(n,m,i) = strssa(n,m,i) + arg
strssa(n,m,j) = strssa(n,m,j) + arg
enddo
endif
enddo
c write(1,*)"forcei1: ",f(1,i)," ",f(2,i)," ",f(3,i)
c write(1,*)"forcej1: ",f(1,j)," ",f(2,j)," ",f(3,j)
c Now compute forces on other atoms k due to change in sij
if (sij.eq.0.d0.or.sij.eq.1.d0) goto 100
do kn = 1,numneigh_full
k = firstneigh_full(kn)
if (k.ne.j) then
call dsij(i,j,k,jn,nmax,numneigh,rij2,dsij1,dsij2,
$ ntype,type,fmap,x,scrfcn,fcpair)
if (dsij1.ne.0.d0.or.dsij2.ne.0.d0) then
force1 = dUdsij*dsij1
force2 = dUdsij*dsij2
do m = 1,3
delik(m) = x(m,k) - x(m,i)
deljk(m) = x(m,k) - x(m,j)
enddo
do m = 1,3
f(m,i) = f(m,i) + force1*delik(m)
f(m,j) = f(m,j) + force2*deljk(m)
f(m,k) = f(m,k) - force1*delik(m)
$ - force2*deljk(m)
if (strscomp>0) then
do n = m,3
arg1 = force1*delik(m)*delik(n)
arg2 = force2*deljk(m)*deljk(n)
strssa(m,n,i) = strssa(m,n,i) + arg1
strssa(m,n,j) = strssa(m,n,j) + arg2
strssa(m,n,k) = strssa(m,n,k) +
$ arg1 + arg2
if (n.ne.m) then
strssa(n,m,i) = strssa(n,m,i) + arg1
strssa(n,m,j) = strssa(n,m,j) + arg2
strssa(n,m,k) = strssa(n,m,k)
$ + arg1 + arg2
endif
enddo
endif
enddo
endif
endif
c end of k loop
enddo
endif
100 continue
endif
c end of j loop
enddo
return
end

733
lib/meam/meam_setup_done.F Executable file
View File

@ -0,0 +1,733 @@
c Declaration in pair_meam.h:
c
c void meam_setup_done(double *)
c
c Call from pair_meam.cpp:
c
c meam_setup_done(&cutmax)
c
subroutine meam_setup_done(cutmax)
use meam_data
implicit none
real*8 cutmax
integer nv2, nv3, m, n, p
c Force cutoff
cutforce = rc_meam
cutforcesq = cutforce*cutforce
c Pass cutoff back to calling program
cutmax = cutforce
c Augment t1 term
t1_meam(:) = t1_meam(:) + augt1 * 3.d0/5.d0 * t3_meam(:)
c Compute off-diagonal alloy parameters
call alloyparams
c indices and factors for Voight notation
nv2 = 1
nv3 = 1
do m = 1,3
do n = m,3
vind2D(m,n) = nv2
vind2D(n,m) = nv2
nv2 = nv2+1
do p = n,3
vind3D(m,n,p) = nv3
vind3D(m,p,n) = nv3
vind3D(n,m,p) = nv3
vind3D(n,p,m) = nv3
vind3D(p,m,n) = nv3
vind3D(p,n,m) = nv3
nv3 = nv3+1
enddo
enddo
enddo
v2D(1) = 1
v2D(2) = 2
v2D(3) = 2
v2D(4) = 1
v2D(5) = 2
v2D(6) = 1
v3D(1) = 1
v3D(2) = 3
v3D(3) = 3
v3D(4) = 3
v3D(5) = 6
v3D(6) = 3
v3D(7) = 1
v3D(8) = 3
v3D(9) = 3
v3D(10) = 1
nv2 = 1
do m = 1,neltypes
do n = m,neltypes
eltind(m,n) = nv2
eltind(n,m) = nv2
nv2 = nv2+1
enddo
enddo
c Compute pair potentials and setup arrays for interpolation
nr = 1000
dr = 1.1*rc_meam/nr
call compute_pair_meam
return
end
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c Fill off-diagonal alloy parameters
subroutine alloyparams
use meam_data
implicit none
integer i,j,k
real*8 eb
c Loop over pairs
do i = 1,neltypes
do j = 1,neltypes
c Treat off-diagonal pairs
c If i>j, set all equal to i<j case (which has aready been set,
c here or in the input file)
if (i.gt.j) then
re_meam(i,j) = re_meam(j,i)
Ec_meam(i,j) = Ec_meam(j,i)
alpha_meam(i,j) = alpha_meam(j,i)
lattce_meam(i,j) = lattce_meam(j,i)
c If i<j and term is unset, use default values (e.g. mean of i-i and j-j)
else if (j.gt.i) then
if (Ec_meam(i,j).eq.0.d0) then
Ec_meam(i,j) = (Ec_meam(i,i)+Ec_meam(j,j))/2.d0
$ - delta_meam(i,j)
endif
if (alpha_meam(i,j).eq.0.d0) then
alpha_meam(i,j) = (alpha_meam(i,i)+alpha_meam(j,j))/2.d0
endif
if (re_meam(i,j).eq.0.d0) then
re_meam(i,j) = (re_meam(i,i)+re_meam(j,j))/2.d0
endif
endif
enddo
enddo
c Cmin(i,k,j) is symmetric in i-j, but not k. For all triplets
c where i>j, set equal to the i<j element. Likewise for Cmax.
do i = 2,neltypes
do j = 1,i-1
do k = 1,neltypes
Cmin_meam(i,j,k) = Cmin_meam(j,i,k)
Cmax_meam(i,j,k) = Cmax_meam(j,i,k)
enddo
enddo
enddo
c ebound gives the squared distance such that, for rik2 or rjk2>ebound,
c atom k definitely lies outside the screening function ellipse (so
c there is no need to calculate its effects). Here, compute it for all
c triplets (i,j,k) so that ebound(i,j) is the maximized over k
do i = 1,neltypes
do j = 1,neltypes
do k = 1,neltypes
eb = (Cmax_meam(i,j,k)*Cmax_meam(i,j,k))
$ /(4.d0*(Cmax_meam(i,j,k)-1.d0))
ebound_meam(i,j) = max(ebound_meam(i,j),eb)
enddo
enddo
enddo
return
end
c-----------------------------------------------------------------------
c compute MEAM pair potential for each pair of element types
c
subroutine compute_pair_meam
use meam_data
implicit none
real*8 r, temp
integer j,a,b,nv2
real*8 astar,frac,phizbl
integer n,nmax,Z1,Z2
real*8 arat,scrn
real*8 phitmp
real*8, external :: phi_meam
real*8, external :: zbl
c allocate memory for array that defines the potential
allocate(phir(nr,(neltypes*(neltypes+1))/2))
c allocate coeff memory
allocate(phirar(nr,(neltypes*(neltypes+1))/2))
allocate(phirar1(nr,(neltypes*(neltypes+1))/2))
allocate(phirar2(nr,(neltypes*(neltypes+1))/2))
allocate(phirar3(nr,(neltypes*(neltypes+1))/2))
allocate(phirar4(nr,(neltypes*(neltypes+1))/2))
allocate(phirar5(nr,(neltypes*(neltypes+1))/2))
allocate(phirar6(nr,(neltypes*(neltypes+1))/2))
c loop over pairs of element types
nv2 = 0
do a = 1,neltypes
do b = a,neltypes
nv2 = nv2 + 1
c loop over r values and compute
do j = 1,nr
r = (j-1)*dr
phir(j,nv2) = phi_meam(r,a,b)
c if using second-nearest neighbor, solve recursive problem
c (see Lee and Baskes, PRB 62(13):8564 eqn.(21))
if (nn2_meam(a,b).eq.1) then
if (a.ne.b) then
write(6,*) 'Second-neighbor currently only valid '
write(6,*) 'if element types are the same.'
c call error(' ')
endif
call get_Zij(Z1,lattce_meam(a,b))
call get_Zij2(Z2,arat,scrn,lattce_meam(a,b),
$ Cmin_meam(a,a,b),Cmax_meam(a,a,b))
nmax = 10
do n = 1,nmax
phir(j,nv2) = phir(j,nv2) +
$ (-Z2*scrn/Z1)**n * phi_meam(r*arat**n,a,b)
enddo
endif
c if astar <= -3
c potential is zbl potential
c else if -3 < astar < -1
c potential is linear combination with zbl potential
c endif
astar = alpha_meam(a,b) * (r/re_meam(a,b) - 1.d0)
if (astar.le.-3.d0) then
phir(j,nv2) = zbl(r,ielt_meam(a),ielt_meam(b))
else if (astar.gt.-3.d0.and.astar.lt.-1.d0) then
call fcut(1-(astar+1.d0)/(-3.d0+1.d0),frac)
phizbl = zbl(r,ielt_meam(a),ielt_meam(b))
phir(j,nv2) = frac*phir(j,nv2) + (1-frac)*phizbl
endif
enddo
c call interpolation
call interpolate_meam(nv2)
enddo
enddo
return
end
c----------------------------------------------------------------------c
c Compute MEAM pair potential for distance r, element types a and b
c
real*8 recursive function phi_meam(r,a,b)result(phi_m)
use meam_data
implicit none
integer a,b
real*8 r
real*8 a1,a2,a12
real*8 t11av,t21av,t31av,t12av,t22av,t32av
real*8 G1,G2,s1(3),s2(3),s12(3),rho0_1,rho0_2
real*8 Gam1,Gam2,Z1,Z2
real*8 rhobar1,rhobar2,F1,F2
real*8 rhoa01,rhoa11,rhoa21,rhoa31
real*8 rhoa02,rhoa12,rhoa22,rhoa32
real*8 rho01,rho11,rho21,rho31
real*8 rho02,rho12,rho22,rho32
real*8 scalfac,phiaa,phibb
real*8 Eu
integer Z12
character*3 latta,lattb
real*8, external :: erose
c Equation numbers below refer to:
c I. Huang et.al., Modelling simul. Mater. Sci. Eng. 3:615
c get number of neighbors in the reference structure
c Nref(i,j) = # of i's neighbors of type j
call get_Zij(Z12,lattce_meam(a,b))
call get_densref(r,a,b,rho01,rho11,rho21,rho31,
$ rho02,rho12,rho22,rho32)
c calculate average weighting factors for the reference structure
if (lattce_meam(a,b).eq.'c11') then
scalfac = 1.0/(rho01+rho02)
t11av = scalfac*(t1_meam(a)*rho01 + t1_meam(b)*rho02)
t12av = t11av
t21av = scalfac*(t2_meam(a)*rho01 + t2_meam(b)*rho02)
t22av = t21av
t31av = scalfac*(t3_meam(a)*rho01 + t3_meam(b)*rho02)
t32av = t31av
else
c average weighting factors for the reference structure, eqn. I.8
call get_tavref(t11av,t21av,t31av,t12av,t22av,t32av,
$ t1_meam(a),t2_meam(a),t3_meam(a),
$ t1_meam(b),t2_meam(b),t3_meam(b),lattce_meam(a,b))
endif
c for c11b structure, calculate background electron densities
if (lattce_meam(a,b).eq.'c11') then
latta = lattce_meam(a,a)
if (latta.eq.'dia') then
rhobar1 = ((Z12/2)*(rho02+rho01))**2 +
$ t11av*(rho12-rho11)**2 +
$ t21av/6.0*(rho22+rho21)**2 +
$ 121.0/40.*t31av*(rho32-rho31)**2
rhobar1 = sqrt(rhobar1)
rhobar2 = (Z12*rho01)**2 + 2.0/3.0*t21av*rho21**2
rhobar2 = sqrt(rhobar2)
else
rhobar2 = ((Z12/2)*(rho01+rho02))**2 +
$ t12av*(rho11-rho12)**2 +
$ t22av/6.0*(rho21+rho22)**2 +
$ 121.0/40.*t32av*(rho31-rho32)**2
rhobar2 = sqrt(rhobar2)
rhobar1 = (Z12*rho02)**2 + 2.0/3.0*t22av*rho22**2
rhobar1 = sqrt(rhobar1)
endif
else
c for other structures, use formalism developed in Huang's paper
c
c composition-dependent scaling, equation I.7
c -- note: The shape factors for the individual elements are used, since
c this function should cancel the F(rho) terms when the atoms are
c in the reference structure.
Z1 = Z_meam(a)
Z2 = Z_meam(b)
if (ibar_meam(a).le.0) then
G1 = 1.d0
else
call get_shpfcn(s1,lattce_meam(a,a))
Gam1 = (s1(1)*t11av+s1(2)*t21av+s1(3)*t31av)/(Z1*Z1)
call G_gam(Gam1,ibar_meam(a),gsmooth_factor,G1)
endif
if (ibar_meam(b).le.0) then
G2 = 1.d0
else
call get_shpfcn(s2,lattce_meam(b,b))
Gam2 = (s2(1)*t12av+s2(2)*t22av+s2(3)*t32av)/(Z2*Z2)
call G_gam(Gam2,ibar_meam(b),gsmooth_factor,G2)
endif
rho0_1 = rho0_meam(a)*Z1*G1
rho0_2 = rho0_meam(b)*Z2*G2
c get number of neighbors in the reference structure
c Nref(i,j) = # of i's neighbors of type j
c call get_Zij(Z12,lattce_meam(a,b))
c
c call get_densref(r,a,b,rho01,rho11,rho21,rho31,
c $ rho02,rho12,rho22,rho32)
c compute total background density, eqn I.6
Gam1 = (t11av*rho11+t21av*rho21+t31av*rho31)
Gam1 = Gam1/(rho01*rho01)
Gam2 = (t12av*rho12+t22av*rho22+t32av*rho32)
Gam2 = Gam2/(rho02*rho02)
call G_gam(Gam1,ibar_meam(a),gsmooth_factor,G1)
call G_gam(Gam2,ibar_meam(b),gsmooth_factor,G2)
rhobar1 = rho01/rho0_1*G1
rhobar2 = rho02/rho0_2*G2
endif
c compute embedding functions, eqn I.5
if (rhobar1.eq.0.d0) then
F1 = 0.d0
else
F1 = A_meam(a)*Ec_meam(a,a)*rhobar1*log(rhobar1)
endif
if (rhobar2.eq.0.d0) then
F2 = 0.d0
else
F2 = A_meam(b)*Ec_meam(b,b)*rhobar2*log(rhobar2)
endif
c compute Rose function, I.16
Eu = erose(r,re_meam(a,b),alpha_meam(a,b),
$ Ec_meam(a,b),repuls_meam(a,b),attrac_meam(a,b))
c calculate the pair energy
if (lattce_meam(a,b).eq.'c11') then
latta = lattce_meam(a,a)
if (latta.eq.'dia') then
phiaa = phi_meam(r,a,a)
phi_m = (3*Eu - F2 - 2*F1 - 5*phiaa)/Z12
else
phibb = phi_meam(r,b,b)
phi_m = (3*Eu - F1 - 2*F2 - 5*phibb)/Z12
endif
c phi_m = 0.d0
else
c
c potential is computed from Rose function and embedding energy
phi_m = (2*Eu - F1 - F2)/Z12
c
endif
c if r = 0, just return 0
if (r.eq.0.d0) then
phi_m = 0.d0
endif
return
end
c----------------------------------------------------------------------c
c Shape factors for various configurations
subroutine get_shpfcn(s,latt)
implicit none
real*8 s(3)
character*3 latt
if (latt.eq.'fcc'.or.latt.eq.'bcc'.or.latt.eq.'b1') then
s(1) = 0.d0
s(2) = 0.d0
s(3) = 0.d0
else if (latt.eq.'hcp') then
s(1) = 0.d0
s(2) = 0.d0
s(3) = 1.d0/3.d0
else if (latt.eq.'dia') then
s(1) = 0.d0
s(2) = 0.d0
s(3) = 32.d0/9.d0
else if (latt.eq.'dim') then
s(1) = 1.d0
s(2) = 2.d0/3.d0
c s(3) = 1.d0
s(3) = 0.4d0
else
s(1) = 0.0
c call error('Lattice not defined in get_shpfcn.')
endif
return
end
c------------------------------------------------------------------------------c
c Average weighting factors for the reference structure
subroutine get_tavref(t11av,t21av,t31av,t12av,t22av,t32av,
$ t11,t21,t31,t12,t22,t32,latt)
implicit none
real*8 t11av,t21av,t31av,t12av,t22av,t32av
real*8 t11,t21,t31,t12,t22,t32
character*3 latt
if (latt.eq.'fcc'.or.latt.eq.'bcc'.or.latt.eq.'dia'
$ .or.latt.eq.'hcp'.or.latt.eq.'b1'
$ .or.latt.eq.'dim') then
c all neighbors are of the opposite type
t11av = t12
t21av = t22
t31av = t32
t12av = t11
t22av = t21
t32av = t31
else
c call error('Lattice not defined in get_tavref.')
endif
return
end
c------------------------------------------------------------------------------c
c Number of neighbors for the reference structure
subroutine get_Zij(Zij,latt)
implicit none
integer Zij
character*3 latt
if (latt.eq.'fcc') then
Zij = 12
else if (latt.eq.'bcc') then
Zij = 8
else if (latt.eq.'hcp') then
Zij = 12
else if (latt.eq.'b1') then
Zij = 6
else if (latt.eq.'dia') then
Zij = 4
else if (latt.eq.'dim') then
Zij = 1
else if (latt.eq.'c11') then
Zij = 10
else
c call error('Lattice not defined in get_Zij.')
endif
return
end
c------------------------------------------------------------------------------c
c Zij2 = number of second neighbors, a = distance ratio R1/R2, and S = second
c neighbor screening function for lattice type "latt"
subroutine get_Zij2(Zij2,a,S,latt,cmin,cmax)
implicit none
integer Zij2
real*8 a,S,cmin,cmax
character*3 latt
real*8 rratio,C,x,sijk
integer numscr
if (latt.eq.'bcc') then
Zij2 = 6
a = 2.d0/sqrt(3.d0)
numscr = 4
else if (latt.eq.'fcc') then
Zij2 = 6
a = sqrt(2.d0)
numscr = 4
else if (latt.eq.'dia') then
Zij2 = 0
a = sqrt(8.d0/3.d0)
numscr = 4
if (cmin.lt.0.500001) then
c call error('can not do 2NN MEAM for dia')
endif
else if (latt.eq.'hcp') then
Zij2 = 6
a = sqrt(2.d0)
numscr = 4
else if (latt.eq.'b1') then
Zij2 = 6
a = sqrt(2.d0)
numscr = 4
else
c call error('Lattice not defined in get_Zij2.')
endif
c Compute screening for each first neighbor
C = 4.d0/(a*a) - 1.d0
x = (C-cmin)/(cmax-cmin)
call fcut(x,sijk)
c There are numscr first neighbors screening the second neighbors
S = sijk**numscr
return
end
c------------------------------------------------------------------------------c
c Calculate density functions, assuming reference configuration
subroutine get_densref(r,a,b,rho01,rho11,rho21,rho31,
$ rho02,rho12,rho22,rho32)
use meam_data
implicit none
real*8 r,rho01,rho11,rho21,rho31,rho02,rho12,rho22,rho32
real*8 a1,a2
real*8 rhoa01,rhoa11,rhoa21,rhoa31,rhoa02,rhoa12,rhoa22,rhoa32
real*8 C,Cmin,Cmax,fc,s(3)
character*3 lat
integer a,b
integer Zij1nn,Zij2nn
real*8 rhoa01nn,rhoa02nn
real*8 arat,scrn
a1 = r/re_meam(a,a) - 1.d0
a2 = r/re_meam(b,b) - 1.d0
rhoa01 = rho0_meam(a)*exp(-beta0_meam(a)*a1)
rhoa11 = rho0_meam(a)*exp(-beta1_meam(a)*a1)
rhoa21 = rho0_meam(a)*exp(-beta2_meam(a)*a1)
rhoa31 = rho0_meam(a)*exp(-beta3_meam(a)*a1)
rhoa02 = rho0_meam(b)*exp(-beta0_meam(b)*a2)
rhoa12 = rho0_meam(b)*exp(-beta1_meam(b)*a2)
rhoa22 = rho0_meam(b)*exp(-beta2_meam(b)*a2)
rhoa32 = rho0_meam(b)*exp(-beta3_meam(b)*a2)
lat = lattce_meam(a,b)
rho11 = 0.d0
rho21 = 0.d0
rho31 = 0.d0
rho12 = 0.d0
rho22 = 0.d0
rho32 = 0.d0
call get_Zij(Zij1nn,lat)
if (lat.eq.'fcc') then
rho01 = 12.d0*rhoa02
rho02 = 12.d0*rhoa01
else if (lat.eq.'bcc') then
rho01 = 8.d0*rhoa02
rho02 = 8.d0*rhoa01
else if (lat.eq.'b1') then
c Warning: this assumes that atoms of element 1 are not completely
c screened from each other, but that atoms of element 2 are. So
c Cmin_meam(1,1,2) can be less than 1.0, but Cmin_meam(2,2,1) cannot.
c This should be made more general in the future.
c Cmin = Cmin_meam(1,1,2)
c Cmax = Cmax_meam(1,1,2)
c C = (1.0-Cmin)/(Cmax-Cmin)
c call fcut(C,fc)
c a1 = sqrt(2.0)*r/re_meam(1,1) - 1.d0
c rho01 = 6*rhoa02 + 12*fc*fc*rho0_meam(1)*exp(-beta0_meam(1)*a1)
c rho02 = 6*rhoa01
rho01 = 6*rhoa02
rho02 = 6*rhoa01
else if (lat.eq.'dia') then
rho01 = 4*rhoa02
rho02 = 4*rhoa01
rho31 = 32.d0/9.d0*rhoa32*rhoa32
rho32 = 32.d0/9.d0*rhoa31*rhoa31
else if (lat.eq.'hcp') then
rho01 = 12*rhoa02
rho02 = 12*rhoa01
rho31 = 1.d0/3.d0*rhoa32*rhoa32
rho32 = 1.d0/3.d0*rhoa31*rhoa31
else if (lat.eq.'dim') then
call get_shpfcn(s,'dim')
rho01 = rhoa02
rho02 = rhoa01
rho11 = s(1)*rhoa12*rhoa12
rho12 = s(1)*rhoa11*rhoa11
rho21 = s(2)*rhoa22*rhoa22
rho22 = s(2)*rhoa21*rhoa21
rho31 = s(3)*rhoa32*rhoa32
rho32 = s(3)*rhoa31*rhoa31
else if (lat.eq.'c11') then
rho01 = rhoa01
rho02 = rhoa02
rho11 = rhoa11
rho12 = rhoa12
rho21 = rhoa21
rho22 = rhoa22
rho31 = rhoa31
rho32 = rhoa32
else
c call error('Lattice not defined in get_densref.')
endif
if (nn2_meam(a,b).eq.1) then
c Assume that second neighbor is of same type, first neighbor
c may be of different type
if (lat.ne.'bcc') then
c call error('Second-neighbor not defined for this lattice')
endif
call get_Zij2(Zij2nn,arat,scrn,lat,
$ Cmin_meam(a,a,b),Cmax_meam(a,a,b))
a1 = arat*r/re_meam(a,a) - 1.d0
a2 = arat*r/re_meam(b,b) - 1.d0
rhoa01nn = rho0_meam(a)*exp(-beta0_meam(a)*a1)
rhoa02nn = rho0_meam(b)*exp(-beta0_meam(b)*a2)
rho01 = rho01 + Zij2nn*scrn*rhoa02nn
rho02 = rho02 + Zij2nn*scrn*rhoa01nn
endif
return
end
c---------------------------------------------------------------------
c Compute ZBL potential
c
real*8 function zbl(r,z1,z2)
implicit none
integer i,z1,z2
real*8 r,c,d,a,azero,cc,x
dimension c(4),d(4)
data c /0.028171,0.28022,0.50986,0.18175/
data d /0.20162,0.40290,0.94229,3.1998/
data azero /0.4685/
data cc /14.3997/
c azero = (9pi^2/128)^1/3 (0.529) Angstroms
a = azero/(z1**0.23+z2**0.23)
zbl = 0.0
x = r/a
do i=1,4
zbl = zbl + c(i)*exp(-d(i)*x)
enddo
if (r.gt.0.d0) zbl = zbl*z1*z2/r*cc
return
end
c---------------------------------------------------------------------
c Compute Rose energy function, I.16
c
real*8 function erose(r,re,alpha,Ec,repuls,attrac)
implicit none
real*8 r,re,alpha,Ec,repuls,attrac,astar,a3
erose = 0.d0
if (r.gt.0.d0) then
astar = alpha * (r/re - 1.d0)
a3 = 0.d0
if (astar.ge.0) then
a3 = attrac
else if (astar.lt.0) then
a3 = repuls
endif
c erose = -Ec * (1 + astar + a3*(astar**3)/(r/re)) * exp(-astar)
erose = -Ec*(1+astar+(-attrac+repuls/r)*(astar**3))*exp(-astar)
endif
return
end
c -----------------------------------------------------------------------
subroutine interpolate_meam(ind)
use meam_data
implicit none
integer j,ind
real*8 drar
c map to coefficient space
nrar = nr
drar = dr
rdrar = 1.0D0/drar
c phir interp
do j = 1,nrar
phirar(j,ind) = phir(j,ind)
enddo
phirar1(1,ind) = phirar(2,ind)-phirar(1,ind)
phirar1(2,ind) = 0.5D0*(phirar(3,ind)-phirar(1,ind))
phirar1(nrar-1,ind) = 0.5D0*(phirar(nrar,ind)
$ -phirar(nrar-2,ind))
phirar1(nrar,ind) = 0.0D0
do j = 3,nrar-2
phirar1(j,ind) = ((phirar(j-2,ind)-phirar(j+2,ind)) +
$ 8.0D0*(phirar(j+1,ind)-phirar(j-1,ind)))/12.
enddo
do j = 1,nrar-1
phirar2(j,ind) = 3.0D0*(phirar(j+1,ind)-phirar(j,ind)) -
$ 2.0D0*phirar1(j,ind) - phirar1(j+1,ind)
phirar3(j,ind) = phirar1(j,ind) + phirar1(j+1,ind) -
$ 2.0D0*(phirar(j+1,ind)-phirar(j,ind))
enddo
phirar2(nrar,ind) = 0.0D0
phirar3(nrar,ind) = 0.0D0
do j = 1,nrar
phirar4(j,ind) = phirar1(j,ind)/drar
phirar5(j,ind) = 2.0D0*phirar2(j,ind)/drar
phirar6(j,ind) = 3.0D0*phirar3(j,ind)/drar
enddo
end

105
lib/meam/meam_setup_global.F Executable file
View File

@ -0,0 +1,105 @@
c
c declaration in pair_meam.h:
c
c void meam_setup_global(int *, int *, double *, int *, double *, double *,
c double *, double *, double *, double *, double *,
c double *, double *, double *, double *, double *,
c double *, double *, int *);
c
c call in pair_meam.cpp:
c
c meam_setup_global(&nelements,lat,z,ielement,atwt,alpha,b0,b1,b2,b3,
c alat,esub,asub,t0,t1,t2,t3,rozero,ibar);
c
c
subroutine meam_setup_global(nelt, lat, z, ielement, atwt, alpha,
$ b0, b1, b2, b3, alat, esub, asub,
$ t0, t1, t2, t3, rozero, ibar)
use meam_data
implicit none
integer nelt, lat, ielement, ibar
real*8 z, atwt, alpha, b0, b1, b2, b3
real*8 alat, esub, asub, t0, t1, t2, t3
real*8 rozero
dimension lat(nelt), ielement(nelt), ibar(nelt)
dimension z(nelt), atwt(nelt), alpha(nelt)
dimension b0(nelt), b1(nelt), b2(nelt), b3(nelt)
dimension alat(nelt), esub(nelt), asub(nelt)
dimension t0(nelt), t1(nelt), t2(nelt), t3(nelt), rozero(nelt)
integer i
real*8 tmplat(maxelt)
neltypes = nelt
do i = 1,nelt
if (lat(i).eq.0) then
lattce_meam(i,i) = 'fcc'
else if (lat(i).eq.1) then
lattce_meam(i,i) = 'bcc'
else if (lat(i).eq.2) then
lattce_meam(i,i) = 'hcp'
else if (lat(i).eq.3) then
lattce_meam(i,i) = 'dim'
else if (lat(i).eq.4) then
lattce_meam(i,i) = 'dia'
else
c unknown
endif
Z_meam(i) = z(i)
ielt_meam(i) = ielement(i)
alpha_meam(i,i) = alpha(i)
beta0_meam(i) = b0(i)
beta1_meam(i) = b1(i)
beta2_meam(i) = b2(i)
beta3_meam(i) = b3(i)
tmplat(i) = alat(i)
Ec_meam(i,i) = esub(i)
A_meam(i) = asub(i)
t0_meam(i) = t0(i)
t1_meam(i) = t1(i)
t2_meam(i) = t2(i)
t3_meam(i) = t3(i)
rho0_meam(i) = rozero(i)
ibar_meam(i) = ibar(i)
if (lattce_meam(i,i).eq.'fcc') then
re_meam(i,i) = tmplat(i)/sqrt(2.d0)
elseif (lattce_meam(i,i).eq.'bcc') then
re_meam(i,i) = tmplat(i)*sqrt(3.d0)/2.d0
elseif (lattce_meam(i,i).eq.'hcp') then
re_meam(i,i) = tmplat(i)
elseif (lattce_meam(i,i).eq.'dim') then
re_meam(i,i) = tmplat(i)
elseif (lattce_meam(i,i).eq.'dia') then
re_meam(i,i) = tmplat(i)*sqrt(3.d0)/4.d0
else
c error
endif
enddo
c Set some defaults
rc_meam = 4.0
delr_meam = 0.1
attrac_meam(:,:) = 0.0
repuls_meam(:,:) = 0.0
Cmax_meam(:,:,:) = 2.8
Cmin_meam(:,:,:) = 2.0
ebound_meam(:,:) = (2.8d0**2)/(4.d0*(2.8d0-1.d0))
delta_meam(:,:) = 0.0
nn2_meam(:,:) = 0
gsmooth_factor = 99.0
augt1 = 1
return
end

121
lib/meam/meam_setup_param.F Executable file
View File

@ -0,0 +1,121 @@
c
c Declaration in pair_meam.h:
c
c void meam_setup_param(int *, double *, int *, int *, int *);
c
c Call in pair_meam.cpp
c
c meam_setup_param(&which,&value,&nindex,index,&errorflag);
c
c
c
c The "which" argument corresponds to the index of the "keyword" array
c in pair_meam.cpp:
c
c 0 = Ec_meam
c 1 = alpha_meam
c 2 = rho0_meam
c 3 = delta_meam
c 4 = lattce_meam
c 5 = attrac_meam
c 6 = repuls_meam
c 7 = nn2_meam
c 8 = Cmin_meam
c 9 = Cmax_meam
c 10 = rc_meam
c 11 = delr_meam
c 12 = augt1
c 13 = gsmooth_factor
c 14 = re_meam
subroutine meam_setup_param(which, value, nindex,
$ index, errorflag)
use meam_data
implicit none
integer which, nindex, index(3), errorflag
real*8 value
errorflag = 0
c 0 = Ec_meam
if (which.eq.0) then
Ec_meam(index(1),index(2)) = value
c 1 = alpha_meam
else if (which.eq.1) then
alpha_meam(index(1),index(2)) = value
c 2 = rho0_meam
else if (which.eq.2) then
rho0_meam(index(1)) = value
c 3 = delta_meam
else if (which.eq.3) then
delta_meam(index(1),index(2)) = value
c 4 = lattce_meam
else if (which.eq.4) then
if (value.eq.0) then
lattce_meam(index(1),index(2)) = "fcc"
else if (value.eq.1) then
lattce_meam(index(1),index(2)) = "bcc"
else if (value.eq.2) then
lattce_meam(index(1),index(2)) = "hcp"
else if (value.eq.3) then
lattce_meam(index(1),index(2)) = "dim"
else if (value.eq.4) then
lattce_meam(index(1),index(2)) = "dia"
else if (value.eq.5) then
lattce_meam(index(1),index(2)) = 'b1'
else if (value.eq.6) then
lattce_meam(index(1),index(2)) = 'c11'
endif
c 5 = attrac_meam
else if (which.eq.5) then
attrac_meam(index(1),index(2)) = value
c 6 = repuls_meam
else if (which.eq.6) then
repuls_meam(index(1),index(2)) = value
c 7 = nn2_meam
else if (which.eq.7) then
nn2_meam(index(1),index(2)) = value
c 8 = Cmin_meam
else if (which.eq.8) then
Cmin_meam(index(1),index(2),index(3)) = value
c 9 = Cmax_meam
else if (which.eq.9) then
Cmax_meam(index(1),index(2),index(3)) = value
c 10 = rc_meam
else if (which.eq.10) then
rc_meam = value
c 11 = delr_meam
else if (which.eq.11) then
delr_meam = value
c 12 = augt1
else if (which.eq.12) then
augt1 = value
c 13 = gsmooth
else if (which.eq.13) then
gsmooth_factor = value
c 14 = re_meam
else if (which.eq.14) then
re_meam(index(1),index(2)) = value
else
errorflag = 1
endif
return
end