#if 0 forces-edip.c ------------- Version 1.1c Force and Energy Calculation with the Environment-Dependent Interatomic Potential written by Martin Z. Bazant, Department of Physics, Harvard University April - October 1997 (based on forces.c, June 1994) Current address (2000): Professor Martin Z. Bazant Department of Mathematics 2-363B Massachusetts Institute of Technology Cambridge, MA 02139-4307 E-mail: bazant@math.mit.edu optimized by Xianglong Yuan, yuanx@mit.edu, April 2002 COPYRIGHT NOTICE ---------------- forces-edip, copyright 1997 by Martin Z. Bazant and Harvard University. Permission is granted to use forces-edip.c for academic use only, at no cost. Unauthorized sale or commerical use of this software is prohibited by United States copyright law. Any publication describing research involving this software should contain the following citations, at once and in this order, to give proper credit to the theoretical work and fitting that produced EDIP and this subroutine: 1. M. Z. Bazant and E. Kaxiras, Phys. Rev. Lett. 77, 4370 (1996). 2. M. Z. Bazant, E. Kaxiras, J. F. Justo, Phys. Rev. B 56, 8542 (1997). 3. J. F. Justo, M. Z. Bazant, E. Kaxiras, V. V. Bulatov, and S. Yip, Phys. Rev. B 58, 2539 (1998). This software has been extensively tested for molecular dynamics simulations on Sun, SGI and IBM architectures, but no guarantees are made. WEBSITE ------- Updated versions of this software are available at the EDIP distribution site, http://pelion.eas.harvard.edu/software/EDIP/ Postscript files of related papers are available at the Kaxiras group web site in the Department of Physics at Harvard University, http://pelion.eas.harvard.edu, under 'Empirical Methods'. A description of the algorithm used in this subroutine can be found in the Ph.D. Thesis of M. Z. Bazant (1997), chapter 6, on the web at http://pelion.eas.harvard.edu/~bazant/thesis/ INTERFACE - PASSED VARIABLES ---------------------------- void compute_forces_EDIP(measure,version,local,pos,f,box) int measure; If this flag is nonzero, then the average energy and coordination are measured. int version; Not presently used. The next three arrays of structures contain the particle information. The division reflects different communication roles in SPMD parallelism. The following type declarations should appear elsewhere in the code, altough for the force routine, only export and import are really needed: typedef double SCALAR_t; typedef struct{ SCALAR_t x,y,z; } VECTOR_t; typedef VECTOR_t export_t; /* r */ typedef VECTOR_t import_t; /* f */ typedef struct{ /* derivatives of atomic positions */ VECTOR_t v; /* r' */ VECTOR_t a; /* r'' */ #if HIGH_ORDER > 0 VECTOR_t b; /* r''' */ #endif #if HIGH_ORDER > 1 VECTOR_t c; /* r'''' */ #endif /* other local atomic information - coordination and ID numbers */ double z; #if OLD int global_cell; #endif int global_id; int layer; } local_t; #define MAX_PART 4097 /* maximum number of particles (no dynamic mem.alloc.) */ local_t local[MAX_PART]; This structure is used for "extra" information, not needed for force computation. On output, it contains the average EDIP coordination of each atom. export_t pos[MAX_PART]; Contains position vectors of each particle. import_t f[MAX_PART]; On output, contains the total force on each particle. DOMAIN_t box; Dimensions of the periodic box. Note that the routine takes possible interactions from the neighbor list. So, one can "turn off" periodic boundary conditions in one or more directions by changing the neighbor list. No change would need to be made here. typedef struct{ double L_x,L_y,L_z; double L_x_div2,L_y_div2,L_z_div2; } DOMAIN_t; INTERFACE - GLOBAL VARIABLES ---------------------------- These are all defined below. In addition to the parameters for the potential, which are defined by init_EDIP(), one needs N_own, the total number of particles and the Verlet neighbor list. The array neighbors[] contains a list of particle numbers (indices in the pos[], local[], f[] arrays). The neighbors of atom i are given by the block of neighbors[] between p_nbrs[i] and p_nbrs[i+1]. Measurements of energy, virial,... are also returned as global variables. The atomic arrays and neighbor list are specific to our particular MD program. You will need to rewrite the outermost part of the loop over atoms (loop "i") to conform to your MD program. #endif #include #include /*---- These are only needed for the "mbmd" program. Can delete. -------*/ #include "parameters.h" #include "functions.h" extern PARAMETERS_t parameters; extern double cct,bct; /*--------*/ /* macro to inline minimum image distance checking */ #define MIN_IMAGE_DISTANCE(dx,L_x,L_x_div2) ((dx)+(((dx) > (L_x_div2)) ? -(L_x) : (((dx) < -(L_x_div2)) ? (L_x) : 0))) /* DEBUGGING FLAGS - systematically turn on various pieces of the potential. */ #define V2_on 1 #define V2Z_on 1 #define V3_on 1 #define V3g_on 1 #define V3h_on 1 #define V3Z_on 1 #define Zfast 1 /* Total number of particles */ extern int N_own; /* Verlet neighbor list with bonds double-counted */ extern int neighbors[MAX_NBRS],p_nbrs[MAX_PART]; /* EDIP Si PARAMETERS Justo et al., Phys. Rev. B 58, 2539 (1998). 5.6714030 2.0002804 1.2085196 3.1213820 0.5774108 1.4533108 1.1247945 3.1213820 2.5609104 78.7590539 0.6966326 312.1341346 1.4074424 0.0070975 3.1083847 connection between these parameters and Justo et al., Phys. Rev. B 58, 2539 (1998): A((B/r)**rh-palp*exp(-bet*Z*Z)) = A'((B'/r)**rh-exp(-bet*Z*Z)) so in the paper (') A' = A*palp B' = B * palp**(-1/rh) eta = detla/Qo */ static double A,B,rh,sig,a; static double lam,gam,b,c; static double mu,Qo,bet,alp; static double bg; /* cutoff for g(r) */ static double palp; /* justo prefactor for bond order - delete later */ static double delta,eta,zet; /* tau(Z) (Ismail & Kaxiras, 1993) */ static const double u1 = -0.165799; static const double u2 = 32.557; static const double u3 = 0.286198; static const double u4 = 0.66; /* measurements in force routine */ extern double virial,v2sum,E_potential,coord_total,V2,V3; /********************************************/ void init_EDIP(params) int params; /* Old parameter sets have been removed. This is unnecessary. */ { A = 5.6714030; B = 2.0002804; rh = 1.2085196; a = 3.1213820; sig = 0.5774108; lam = 1.4533108; gam = 1.1247945; b = 3.1213820; c = 2.5609104; delta = 78.7590539; mu = 0.6966326; Qo = 312.1341346; palp = 1.4074424; bet = 0.0070975; alp = 3.1083847; printf("\n EDIP-Si Parameters: \n"); printf("%lf %lf %lf %lf %lf \n",A,B,rh,a,sig); printf("%lf %lf %lf %lf %lf \n",lam,gam,b,c,delta); printf("%lf %lf %lf %lf %lf \n",mu,Qo,palp,bet,alp); bg=a; eta = delta/Qo; /* needed for mbmd program. can delete. */ parameters.pot_cutoff = a; bct=b; cct=c; } /********************************************/ void compute_forces_EDIP(measure,version,local,pos,f,box) int measure; int version; local_t local[MAX_PART]; export_t pos[MAX_PART]; import_t f[MAX_PART]; DOMAIN_t box; { /*------------------------- VARIABLE DECLARATIONS -------------------------*/ int i,j,k,l,n; double dx,dy,dz,r,rsqr,asqr; double rinv,rmainv,xinv,xinv3,den,Z,fZ; double dV2j,dV2ijx,dV2ijy,dV2ijz,pZ,dp; double temp0,temp1,temp2; double Qort,muhalf,u5; double rmbinv,winv,dwinv,tau,dtau,lcos,x,H,dHdx,dhdl; double dV3rij,dV3rijx,dV3rijy,dV3rijz; double dV3rik,dV3rikx,dV3riky,dV3rikz; double dV3l,dV3ljx,dV3ljy,dV3ljz,dV3lkx,dV3lky,dV3lkz; double dV2dZ,dxdZ,dV3dZ,dVdZ_sum; double dEdrl,dEdrlx,dEdrly,dEdrlz; double bmc,cmbinv; double fjx,fjy,fjz,fkx,fky,fkz; typedef struct{ double t0,t1,t2,t3; /* various V2 functions and derivatives */ double dx,dy,dz; /* unit separation vector */ double r; /* bond length (only needed for virial) */ } store2; store2 s2[MAX_NBRS_1]; /* two-body interaction quantities, r