mcpele
1.0.0
The Monte Carlo Python Energy Landscape Explorer
|
00001 #ifndef _PELE_MORSE_H_ 00002 #define _PELE_MORSE_H_ 00003 00004 #include "simple_pairwise_potential.h" 00005 #include "simple_pairwise_ilist.h" 00006 #include "atomlist_potential.h" 00007 #include "distance.h" 00008 #include "frozen_atoms.h" 00009 #include <cmath> 00010 #include <memory> 00011 00012 namespace pele 00013 { 00014 00019 struct morse_interaction { 00020 double const _A; 00021 double const _rho; 00022 double const _r0; 00023 morse_interaction(double rho, double r0, double A) 00024 : _A(A), _rho(rho), _r0(r0) 00025 {} 00026 00027 /* calculate energy from distance squared */ 00028 double inline energy(double r2, size_t atom_i, size_t atom_j) const 00029 { 00030 double r = std::sqrt(r2); 00031 double c = std::exp(-_rho * (r - _r0)); 00032 return _A * c * (c - 2.); 00033 } 00034 00035 /* calculate energy and gradient from distance squared, gradient is in g/|rij| */ 00036 double inline energy_gradient(double r2, double *gij, size_t atom_i, size_t atom_j) const 00037 { 00038 double r = std::sqrt(r2); 00039 double c = std::exp(-_rho * (r - _r0)); 00040 *gij = 2.0 * _A * c * _rho * (c - 1.0) / r; 00041 return _A * c * (c - 2.0); 00042 } 00043 00044 double inline energy_gradient_hessian(double r2, double *gij, double *hij, size_t atom_i, size_t atom_j) const 00045 { 00046 double r = std::sqrt(r2); 00047 double c = std::exp(-_rho * (r - _r0)); 00048 //double A_rho_2_c = 00049 *gij = 2.0 * _A * c * _rho * (c - 1.0) / r; 00050 *hij = 2.0 * _A * c * _rho * _rho * (2.0 * c - 1.0); 00051 return _A * c * (c - 2.0); 00052 } 00053 }; 00054 00058 class Morse: public SimplePairwisePotential<morse_interaction> 00059 { 00060 public: 00061 Morse(double rho, double r0, double A) 00062 : SimplePairwisePotential<morse_interaction>( 00063 std::make_shared<morse_interaction>(rho, r0, A) ) 00064 {} 00065 }; 00066 00067 } 00068 #endif