Coverage for gamdpy/interactions/potential_functions/SAAP.py: 11%
28 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-06-14 15:25 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2025-06-14 15:25 +0200
1import numba
2from math import exp
4def SAAP(dist, params):
5 """ The SAAP potential
6 is a pair potential for noble elements, its parameters
7 are derived from fitting on data obtained from ab initio methods (coupled cluster):
9 .. math::
11 u(x=r/\\sigma)/\\epsilon = (a_0\\exp(a_1 x)/x + a_2\\exp(a_3 x) + a_4) / (1+a_5 x^6)
13 The six :math:`a_i` parameters are given in units of eps and sigma.
15 Reference: https://doi.org/10.1063/1.5085420
17 Parameters
18 ----------
20 dist : float
21 Distance between particles
23 params : array-like
24 a₀, a₁, a₂, a₃, a₄, a₅, σ, ε
26 """
28 # Extract parameters compatibly with numba, in float32 precision
29 a0 = numba.float32(params[0])
30 a1 = numba.float32(params[1])
31 a2 = numba.float32(params[2])
32 a3 = numba.float32(params[3])
33 a4 = numba.float32(params[4])
34 a5 = numba.float32(params[5])
35 sigma = numba.float32(params[6])
36 eps = numba.float32(params[7])
38 # Definition of a reduced distance to make all consistent with the fact that
39 # the various a parameters are given in units of eps and sigma
40 r = dist / sigma
41 # Compute helper variables
42 one = numba.float32(1.0)
43 inv_r = one/r
45 exp_a1_r = exp(a1 * r)
46 a0_exp_r = a0 * exp_a1_r * inv_r # a0 exp(a1 r)/r
47 a2_exp = a2 * exp(a3 * r)
48 inverse_one_a5 = one / (one + a5 * r**6)
50 # Compute pair potential energy, pair force and pair curvature
52 # SAAP computation for r
53 u = eps * (a0_exp_r + a2_exp + a4) * inverse_one_a5
55 # Compute helper variables for s
56 s1 = -6*a5*r**5*(a0*exp(a1*r)/r + a2*exp(a3*r) + a4)/(a5*r**6 + one)**2
57 s2 = (a0*a1*exp(a1*r)/r - a0*exp(a1*r)/r**2 + a2*a3*exp(a3*r))/(a5*r**6 + one)
58 # First derivative of SAAP divided by r with a minus sign
59 s = - eps * (s1 + s2) / (r * sigma**2) # sigma² because of chain rule (CR) and 1/dist = 1/(r sigma)
61 # Compute helper variables for u''(r)
62 d2u_dr2_1 = numba.float32(72.0)*a5**2*r**10*(a0*exp(a1*r)/r
63 + a2*exp(a3*r)
64 + a4)/(a5*r**6 + one)**3
65 d2u_dr2_2 = -numba.float32(12.0)*a5*r**5*(a0*a1*exp(a1*r)/r
66 - a0*exp(a1*r)/r**2
67 + a2*a3*exp(a3*r))/(a5*r**6 + one)**2
68 d2u_dr2_3 = -numba.float32(30.0)*a5*r**4*(a0*exp(a1*r)/r
69 + a2*exp(a3*r)
70 + a4)/(a5*r**6 + one)**2
71 d2u_dr2_4 = (a0*a1**2*exp(a1*r)/r
72 - numba.float32(2.0)*a0*a1*exp(a1*r)/r**2
73 + numba.float32(2.0)*a0*exp(a1*r)/r**3
74 + a2*a3**2*exp(a3*r))/(a5*r**6 + one)
75 # Second derivative of SAAP
76 d2u_dr2 = eps * (d2u_dr2_1 + d2u_dr2_2 + d2u_dr2_3 + d2u_dr2_4) / sigma**2 # sigma² because of double CR
78 return u, s, d2u_dr2 # u(r), -u'(r)/r, u''(r)