/* * ManyBodyPotential_Tersoff.hpp * * Created on: Sep 26, 2012 * Author: heber */ #ifndef MANYBODYPOTENTIAL_TERSOFF_HPP_ #define MANYBODYPOTENTIAL_TERSOFF_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include "CodePatterns/Assert.hpp" #include "Potentials/EmpiricalPotential.hpp" #include "FunctionApproximation/FunctionModel.hpp" /** This class is the implementation of the Tersoff potential function. * * \note The arguments_t argument list is here in the following order: * -# first \f$ r_{ij}$ \f$, * -# then all \f$ r_{ik}$ \f$ that are within the cutoff, i.e. \f$ r_{ik}$ < R + D\f$ * */ class ManyBodyPotential_Tersoff : virtual public EmpiricalPotential, virtual public FunctionModel { //!> grant unit test access to internal parts friend class ManyBodyPotential_TersoffTest; // some repeated typedefs to avoid ambiguities typedef FunctionModel::arguments_t arguments_t; typedef FunctionModel::result_t result_t; typedef FunctionModel::results_t results_t; typedef EmpiricalPotential::derivative_components_t derivative_components_t; typedef FunctionModel::parameters_t parameters_t; public: /** Constructor for class ManyBodyPotential_Tersoff. * * @param _triplefunction function that returns a list of triples (i.e. the * two remaining distances) to a given pair of points (contained as * indices within the argument) */ ManyBodyPotential_Tersoff( boost::function< std::vector(const argument_t &, const double)> &_triplefunction ); /** Constructor for class ManyBodyPotential_Tersoff. * * @param _R offset for cutoff * @param _S halfwidth for cutoff relative to \a _R * @param A * @param B * @param lambda * @param mu * @param lambda3 * @param alpha * @param beta * @param chi * @param omega * @param n * @param c * @param d * @param h * @param _triplefunction function that returns a list of triples (i.e. the * two remaining distances) to a given pair of points (contained as * indices within the argument) */ ManyBodyPotential_Tersoff( const double &_R, const double &_S, const double &_A, const double &_B, const double &_lambda, const double &_mu, const double &_lambda3, const double &_alpha, const double &_beta, const double &_chi, const double &_omega, const double &_n, const double &_c, const double &_d, const double &_h, boost::function< std::vector(const argument_t &, const double)> &_triplefunction); /** Destructor of class ManyBodyPotential_Tersoff. * */ virtual ~ManyBodyPotential_Tersoff() {} /** Evaluates the Tersoff potential for the given arguments. * * @param arguments single distance * @return value of the potential function */ results_t operator()(const arguments_t &arguments) const; /** Evaluates the derivative of the Tersoff potential with respect to the * input variables. * * @param arguments single distance * @return vector with components of the derivative */ derivative_components_t derivative(const arguments_t &arguments) const; /** Evaluates the derivative of the function with the given \a arguments * with respect to a specific parameter indicated by \a index. * * \param arguments set of arguments as input variables to the function * \param index derivative of which parameter * \return result vector containing the derivative with respect to the given * input */ results_t parameter_derivative(const arguments_t &arguments, const size_t index) const; private: /** Prohibit private default constructor. * * We essentially need the triplefunction, hence without this function cannot * be. */ ManyBodyPotential_Tersoff(); private: /** This function represents the cutoff \f$ f_C \f$. * * @param distance variable of the function * @return a value in [0,1]. */ result_t function_cutoff( const double &distance ) const; /** This function has the exponential feature from the Morse potential. * * @param prefactor prefactor parameter to exp function * @param lambda scale parameter of exp function's argument * @param distance variable of the function * @return */ result_t function_smoother( const double &prefactor, const double &lambda, const double &distance ) const; /** This function represents \f$ (1 + \alpha^n \eta^n)^{-1/2n} \f$. * * @param alpha prefactor to eta function * @param r_ij distance argument * @param eta result value of eta or zeta * @return \f$ (1 + \alpha^n \eta^n)^{-1/2n} \f$ */ result_t function_prefactor( const double &alpha, const double &eta ) const; result_t function_eta( const argument_t &r_ij ) const; result_t function_zeta( const argument_t &r_ij ) const; result_t function_angle( const double &r_ij, const double &r_ik, const double &r_jk ) const; private: enum parameter_enum_t { R=0, S=1, A=2, B=3, lambda=4, mu=5, beta=6, n=7, c=8, d=9, h=10, // lambda3=11, // alpha=12, // chi=13, // omega=14, MAXPARAMS }; //!> parameter vector with parameters as in enum parameter_enum_t parameters_t params; // some internal parameters which are fixed const double lambda3; const double alpha; const double chi; const double omega; public: /** Setter for parameters as required by FunctionModel interface. * * \param _params given set of parameters */ void setParameters(const parameters_t &_params) { ASSERT( _params.size() == getParameterDimension(), "ManyBodyPotential_Tersoff::setParameters() - we need exactly " +toString(getParameterDimension())+" parameters."); params = _params; } /** Getter for parameters as required by FunctionModel interface. * * \return set of parameters */ parameters_t getParameters() const { return params; } /** Getter for the number of parameters of this model function. * * \return number of parameters */ size_t getParameterDimension() const { return MAXPARAMS; } private: //!> bound function that obtains the triples for the internal coordinationb summation. const boost::function< std::vector< arguments_t >(const argument_t &, const double)> &triplefunction; }; #endif /* MANYBODYPOTENTIAL_TERSOFF_HPP_ */