/* forces-edip.c ------------- Version 1.0c 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 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 HISTORY ------- 2022-04-18: Updated for easy to debug and port to Rust (ybyygu@gmail.com) */ #include #include #include /* 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 */ static int N_own = 5; static int MAX_NBRS = 30; static int MAX_PART = 4097; static int MAX_NBRS_1 = 4096; 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 */ /* Verlet neighbor list with bonds double-counted */ static int neighbors[100]; static int p_nbrs[100]; /* 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 */ static double virial, v2sum, E_potential, coord_total, V2, V3; /********************************************/ void init_EDIP() { 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; } /********************************************/ void compute_forces_EDIP(measure, version, pos, f) int measure; int version; export_t pos[MAX_PART]; import_t f[MAX_PART]; { /*------------------------- 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; 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