/** compute potential and its derivative at squared distance 'rr' for particles of type 'a' and 'b' */ std::tuple<float_type, float_type> operator()(float_type rr, unsigned a, unsigned b) const { float_type sigma2 = sigma2_(a, b); float_type rri = sigma2 / rr; float_type r6i = rri * rri * rri; float_type eps_r6i = epsilon_(a, b) * r6i; float_type fval = 48 * rri * eps_r6i * (r6i - 0.5) / sigma2; float_type en_pot = 4 * eps_r6i * (r6i - 1) - en_cut_(a, b); return std::make_tuple(fval, en_pot); }
/** compute potential and its derivatives at squared distance 'rr' for particles of type 'a' and 'b' * * @param rr squared distance between particles * @returns tuple of unit "force" @f$ -U'(r)/r @f$, potential @f$ U(r) @f$ * * @f{eqnarray*}{ * - U'(r) / r &=& 4 r^{-2} \epsilon (\sigma/r)^{n} \left[ m (\sigma/r)^{m-n} - n \right] \\ * U(r) &=& 4 \epsilon (\sigma/r)^{n} \left[ (\sigma/r)^{m-n} - 1 \right] * @f} */ std::tuple<float_type, float_type> operator()(float_type rr, unsigned a, unsigned b) const { float_type sigma2 = sigma2_(a, b); unsigned m_2 = index_m_2_(a, b); unsigned n_2 = index_n_2_(a, b); float_type rri = sigma2 / rr; float_type rni = pow(rri, n_2); float_type rmni = (m_2 - n_2 == n_2) ? rni : pow(rri, m_2 - n_2); float_type eps_rni = epsilon_(a, b) * rni; float_type fval = 8 * rri * eps_rni * (m_2 * rmni - n_2) / sigma2; float_type en_pot = 4 * eps_rni * (rmni - 1); return std::make_tuple(fval, en_pot); }
std::tuple<float_type, float_type> impl_(float_type rr, unsigned a, unsigned b) const { // choose arbitrary index_ if template parameter index = 0 unsigned int n = const_index > 0 ? const_index : index_(a, b); float_type rri = sigma2_(a, b) / rr; // avoid computation of square root for even powers float_type rni = (const_index > 0) ? fixed_pow<const_index / 2>(rri) : halmd::pow(rri, n / 2); if (n % 2) { rni *= std::sqrt(rri); } float_type eps_rni = epsilon_(a, b) * rni; float_type fval = n * eps_rni / rr; float_type en_pot = eps_rni - en_cut_(a, b); return std::make_tuple(fval, en_pot); }