Source code for gamdpy.interactions.potential_functions.universal_zbl_potential

from math import exp

import numba

[docs] def universal_zbl_potential(dist, params): r""" The Ziegler-Biersack-Littmark (ZBL) universal potential for high-energy pair collisions of atoms. The ZBL potential is a sum of four screened Coulomb interactions [Ziegler1985]_ : .. math:: u(r) = \varepsilon \sum^4_{k=1} \frac{\sigma}{r} c_k\exp(-b_k r/\sigma) where the c's are [0.18175, 0.50986, 0.28022, 0.02817] and the b's are [3.19980, 0.94229, 0.40290, 0.20162]. These are the same values as used in the LAMMPS implementation. Consider to atoms with atomic numbers :math:`Z_i` and :math:`Z_j`. Then the screening length is .. math:: \sigma = \frac{0.46850 \text{Å}}{Z_i^{0.23}+Z_j^{0.23}} and the energy parameter is .. math:: \varepsilon = \frac{Z_i Z_j e^2}{4 \pi \epsilon_0 \sigma} As an example, for copper (:math:`Z_i=Z_j=29`) the screening length is :math:`\sigma=0.1080` Å, the energy parameter is :math:`\varepsilon=1.122\times10^5` eV, :math:`\varepsilon/k_B=1.301\times10^9` K. Parameters ---------- dist : float Distance between particles params : array-like :math:`\sigma`, :math:`\varepsilon` References ---------- .. [Ziegler1985] JF Ziegler, JP Biersack, U Littmark "The Stopping and Range of Ions in Solids", Pergamon, 1985 """ # Use float32 for all calculations f32 = numba.float32 zero = f32(0.0) one = f32(1.0) two = f32(2.0) # Extract parameters sigma = f32(params[0]) epsilon = f32(params[1]) # Universal paramters cs = f32(0.18175), f32(0.50986), f32(0.28022), f32(0.02817) bs = f32(3.19980), f32(0.94229), f32(0.40290), f32(0.20162) # Compute pair potential energy, pair force and pair curvature u = zero # u = sum c·exp(-b*r)/r s = zero # s = -u'(r)/r d2u_dr2 = zero # d2u_dr2 = u''(r) dist_inv = one / dist dist_inv2 = dist_inv * dist_inv dist_inv3 = dist_inv2 * dist_inv sigma_inv = one / sigma for i in range(4): A = f32(epsilon * cs[i] * sigma) B = f32( bs[i] * sigma_inv ) u += A * exp( - B * dist ) * dist_inv s += (B*dist_inv2 + dist_inv3) * A * exp( - B * dist) d2u_dr2 += (B*B*dist_inv + two*B*dist_inv2 + two*dist_inv3) * A * exp( - B * dist) return u, s, d2u_dr2