pele
Python energy landscape explorer
|
00001 /******************************+ 00002 * This is an example on how to define a new c potential. The class 00003 * internally calls the lennard jones fortran function but manages all 00004 * the parameters. 00005 * 00006 * The python bindings for this potential are in lj.pyx 00007 * 00008 * For an alternative pure cython implementation for this interface 00009 * see _lj_cython.pyx 00010 * 00011 */ 00012 00013 #ifndef PYGMIN_LJ_H 00014 #define PYGMIN_LJ_H 00015 00016 #include "simple_pairwise_potential.h" 00017 #include "simple_pairwise_ilist.h" 00018 #include "atomlist_potential.h" 00019 #include "distance.h" 00020 #include "frozen_atoms.h" 00021 #include <memory> 00022 00023 namespace pele { 00024 00028 struct lj_interaction { 00029 double const _C6, _C12; 00030 double const _6C6, _12C12; 00031 double const _42C6, _156C12; 00032 lj_interaction(double C6, double C12) 00033 : _C6(C6), _C12(C12), 00034 _6C6(6.*_C6), _12C12(12.*_C12), 00035 _42C6(42.*_C6), _156C12(156.*_C12) 00036 {} 00037 00038 /* calculate energy from distance squared */ 00039 double inline energy(double r2, size_t atom_i, size_t atom_j) const 00040 { 00041 double ir2 = 1.0/r2; 00042 double ir6 = ir2*ir2*ir2; 00043 double ir12 = ir6*ir6; 00044 00045 return -_C6*ir6 + _C12*ir12; 00046 } 00047 00048 /* calculate energy and gradient from distance squared, gradient is in g/|rij| */ 00049 double inline energy_gradient(double r2, double *gij, size_t atom_i, size_t atom_j) const 00050 { 00051 double ir2 = 1.0/r2; 00052 double ir6 = ir2*ir2*ir2; 00053 double ir12 = ir6*ir6; 00054 00055 *gij = (_12C12 * ir12 - _6C6 * ir6) * ir2; 00056 return -_C6*ir6 + _C12*ir12; 00057 } 00058 00059 double inline energy_gradient_hessian(double r2, double *gij, double *hij, 00060 size_t atom_i, size_t atom_j) const 00061 { 00062 double ir2 = 1.0/r2; 00063 double ir6 = ir2*ir2*ir2; 00064 double ir12 = ir6*ir6; 00065 *gij = (_12C12 * ir12 - _6C6 * ir6) * ir2; 00066 *hij = (_156C12 * ir12 - _42C6 * ir6) * ir2; 00067 return -_C6*ir6 + _C12*ir12; 00068 } 00069 }; 00070 00071 00072 // 00073 // combine the components (interaction, looping method, distance function) into 00074 // defined classes 00075 // 00076 00080 class LJ : public SimplePairwisePotential< lj_interaction > { 00081 public: 00082 LJ(double C6, double C12) 00083 : SimplePairwisePotential< lj_interaction > ( 00084 std::make_shared<lj_interaction>(C6, C12) ) 00085 {} 00086 }; 00087 00091 class LJPeriodic : public SimplePairwisePotential< lj_interaction, periodic_distance<3> > { 00092 public: 00093 LJPeriodic(double C6, double C12, Array<double> const boxvec) 00094 : SimplePairwisePotential< lj_interaction, periodic_distance<3>> ( 00095 std::make_shared<lj_interaction>(C6, C12), 00096 std::make_shared<periodic_distance<3>>(boxvec) 00097 ) 00098 {} 00099 }; 00100 00104 class LJFrozen : public FrozenPotentialWrapper<LJ> { 00105 public: 00106 LJFrozen(double C6, double C12, Array<double> const & reference_coords, Array<size_t> const & frozen_dof) 00107 : FrozenPotentialWrapper< LJ > (std::make_shared<LJ>(C6, C12), 00108 reference_coords, frozen_dof ) 00109 {} 00110 }; 00111 00115 class LJNeighborList : public SimplePairwiseNeighborList< lj_interaction > { 00116 public: 00117 LJNeighborList(Array<size_t> & ilist, double C6, double C12) 00118 : SimplePairwiseNeighborList<lj_interaction>( 00119 std::make_shared<lj_interaction>(C6, C12), ilist) 00120 {} 00121 }; 00122 } 00123 #endif