Program Listing for File inversepower_stillinger.hpp#
↰ Return to documentation for file (source/pele/inversepower_stillinger.hpp)
#ifndef _PELE_INVERSEPOWER_STILLIGNER_H
#define _PELE_INVERSEPOWER_STILLIGNER_H
#include "base_interaction.hpp"
#include "pele/simple_pairwise_potential.hpp"
namespace pele {
struct InversePowerStillinger_interaction : BaseInteraction {
// Inverse power law potential, see JCP 83, 4767 (1984),
// http://dx.doi.org/10.1063/1.449840
const double m_pow;
InversePowerStillinger_interaction(const size_t pow) : m_pow(pow) {}
double energy(double r2, const double dij) const {
const double E = power_inp2((dij * dij) / r2, m_pow);
return E;
}
// calculate energy and gradient from distance squared, gradient is in
// -(dv/drij)/|rij|
double energy_gradient(double r2, double *gij, const double dij) const {
const double E = power_inp2((dij * dij) / r2, m_pow);
*gij = m_pow * E / r2;
return E;
}
double energy_gradient_hessian(double r2, double *gij, double *hij,
const double dij) const {
const double E = power_inp2((dij * dij) / r2, m_pow);
*gij = m_pow * E / r2;
*hij = *gij * (m_pow + 1);
return E;
}
// Compute inp ** n.
// See Skiena, p. 48.
template <class T>
T power(const T inp, const size_t n) const {
if (n == 0) {
return 1;
}
const T x = power(inp, n / 2);
if (n % 2) {
return inp * x * x;
} else {
return x * x;
}
}
// Compute inp ** n, given inp ** 2.
template <class T>
T power_inp2(const T inp2, const size_t n) const {
const T x = power(inp2, n / 2);
if (n % 2) {
return std::sqrt(inp2) * x;
} else {
return x;
}
}
};
template <size_t ndim>
class InversePowerStillinger
: public SimplePairwisePotential<InversePowerStillinger_interaction,
cartesian_distance<ndim>> {
public:
InversePowerStillinger(const size_t pow, const pele::Array<double> radii)
: SimplePairwisePotential<InversePowerStillinger_interaction,
cartesian_distance<ndim>>(
std::make_shared<InversePowerStillinger_interaction>(pow), radii,
std::make_shared<cartesian_distance<ndim>>()) {}
};
template <size_t ndim>
class InversePowerStillingerPeriodic
: public SimplePairwisePotential<InversePowerStillinger_interaction,
periodic_distance<ndim>> {
public:
InversePowerStillingerPeriodic(const size_t pow,
const pele::Array<double> radii,
const pele::Array<double> boxvec)
: SimplePairwisePotential<InversePowerStillinger_interaction,
periodic_distance<ndim>>(
std::make_shared<InversePowerStillinger_interaction>(pow), radii,
std::make_shared<periodic_distance<ndim>>(boxvec)) {}
};
} // namespace pele
#endif // #ifndef _PELE_INVERSEPOWER_STILLIGNER_H