def _sw_angle_interaction(dR12, dR13, gamma=1.2, sigma=2.0951, cutoff=1.8 * 2.0951): """The angular interaction for the Stillinger-Weber potential. This function is defined only for interaction with a pair of neighbors. We then vmap this function three times below to make it work on the whole system of atoms. Args: dR12: A d-dimensional vector that specifies the displacement of the first neighbor. This potential is usually used in three dimensions. dR13: A d-dimensional vector that specifies the displacement of the second neighbor. gamma: A scalar used to fit the angle interaction. sigma: A scalar that sets the distance scale between neighbors. cutoff: The cutoff beyond which the interactions are not considered. The default value should not be changed for the default SW potential. Returns: Angular interaction energy for one pair of neighbors. """ a = cutoff / sigma dr12 = space.distance(dR12) dr13 = space.distance(dR13) dr12 = np.where(dr12 < cutoff, dr12, 0) dr13 = np.where(dr13 < cutoff, dr13, 0) term1 = np.exp(gamma / (dr12 / sigma - a) + gamma / (dr13 / sigma - a)) cos_angle = quantity.angle_between_two_vectors(dR12, dR13) term2 = (cos_angle + 1. / 3)**2 within_cutoff = (dr12 > 0) & (dr13 > 0) & (np.linalg.norm(dR12 - dR13) > 1e-5) return np.where(within_cutoff, term1 * term2, 0)
def single_pair_angular_symmetry_function(dR12, dR13, eta, lam, zeta, cutoff_distance): """Computes the angular symmetry function due to one pair of neighbors.""" dR23 = dR12 - dR13 dr12_2 = space.square_distance(dR12) dr13_2 = space.square_distance(dR13) dr23_2 = space.square_distance(dR23) dr12 = space.distance(dR12) dr13 = space.distance(dR13) dr23 = space.distance(dR23) triplet_squared_distances = dr12_2 + dr13_2 + dr23_2 triplet_cutoff = reduce( lambda x, y: x * _behler_parrinello_cutoff_fn(y, cutoff_distance), [dr12, dr13, dr23], 1.0) result = 2.0 ** (1.0 - zeta) * ( 1.0 + lam * quantity.angle_between_two_vectors(dR12, dR13)) ** zeta * \ np.exp(-eta * triplet_squared_distances) * triplet_cutoff return result