pele
Python energy landscape explorer
|
00001 #ifndef _PELE_LJ_CUT_H 00002 #define _PELE_LJ_CUT_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 "cell_list_potential.h" 00010 00011 namespace pele { 00012 00018 struct lj_interaction_cut_smooth { 00019 double const _C6, _C12; 00020 double const _6C6, _12C12; 00021 double const _42C6, _156C12; 00022 double const _rcut2; 00023 double const _A0; 00024 double const _A2; 00025 double const _2A2; 00026 lj_interaction_cut_smooth(double C6, double C12, double rcut) 00027 : 00028 _C6(C6), _C12(C12), 00029 _6C6(6.*_C6), _12C12(12.*_C12), 00030 _42C6(42.*_C6), _156C12(156.*_C12), 00031 _rcut2(rcut*rcut), 00032 //A0 = 4.0*(sig**6/rcut**6) - 7.0*(sig**12/rcut**12) 00033 _A0( 4.*_C6 / (_rcut2*_rcut2*_rcut2) - 7.*_C12/(_rcut2*_rcut2*_rcut2*_rcut2*_rcut2*_rcut2)), 00034 //A2 = (-3.0*(sig6/rcut**8) + 6.0*(sig12/rcut**14)) 00035 _A2( -3.*_C6 / (_rcut2*_rcut2*_rcut2*_rcut2) + 6.*_C12/(_rcut2*_rcut2*_rcut2*_rcut2*_rcut2*_rcut2*_rcut2)), 00036 _2A2(2.*_A2) 00037 {} 00038 00039 /* calculate energy from distance squared */ 00040 double inline energy(double r2, size_t atom_i, size_t atom_j) const 00041 { 00042 if (r2 >= _rcut2) { 00043 return 0.; 00044 } 00045 double ir2 = 1.0/r2; 00046 double ir6 = ir2*ir2*ir2; 00047 double ir12 = ir6*ir6; 00048 00049 return -_C6*ir6 + _C12*ir12 + _A0 + _A2*r2; 00050 } 00051 00052 /* calculate energy and gradient from distance squared, gradient is in g/|rij| */ 00053 double inline energy_gradient(double r2, double *gij, size_t atom_i, size_t atom_j) const 00054 { 00055 if (r2 >= _rcut2) { 00056 *gij = 0.; 00057 return 0.; 00058 } 00059 double ir2 = 1.0/r2; 00060 double ir6 = ir2*ir2*ir2; 00061 double ir12 = ir6*ir6; 00062 00063 *gij = (_12C12 * ir12 - _6C6 * ir6) * ir2 - _2A2; 00064 return -_C6*ir6 + _C12*ir12 + _A0 + _A2*r2; 00065 } 00066 00067 double inline energy_gradient_hessian(double r2, double *gij, double *hij, size_t atom_i, size_t atom_j) const 00068 { 00069 if (r2 >= _rcut2) { 00070 *gij = 0.; 00071 *hij = 0.; 00072 return 0.; 00073 } 00074 double ir2 = 1.0/r2; 00075 double ir6 = ir2*ir2*ir2; 00076 double ir12 = ir6*ir6; 00077 00078 *gij = (_12C12 * ir12 - _6C6 * ir6) * ir2 - _2A2; 00079 *hij = (_156C12 * ir12 - _42C6 * ir6) * ir2 + _2A2; 00080 return -_C6*ir6 + _C12*ir12 + _A0 + _A2*r2; 00081 } 00082 }; 00083 00087 class LJCut : public SimplePairwisePotential< lj_interaction_cut_smooth > { 00088 public: 00089 LJCut(double C6, double C12, double rcut) 00090 : SimplePairwisePotential< lj_interaction_cut_smooth > ( 00091 std::make_shared<lj_interaction_cut_smooth>(C6, C12, rcut) ) 00092 {} 00093 }; 00094 00098 class LJCutPeriodic : public SimplePairwisePotential< lj_interaction_cut_smooth, periodic_distance<3>> { 00099 public: 00100 LJCutPeriodic(double C6, double C12, double rcut, Array<double> const boxvec) 00101 : SimplePairwisePotential< lj_interaction_cut_smooth, periodic_distance<3>> ( 00102 std::make_shared<lj_interaction_cut_smooth>(C6, C12, rcut), 00103 std::make_shared<periodic_distance<3>>(boxvec) 00104 ) 00105 {} 00106 }; 00107 00112 class LJCutAtomList : public AtomListPotential<lj_interaction_cut_smooth, cartesian_distance<3>> { 00113 public: 00114 LJCutAtomList(double C6, double C12, double rcut, Array<size_t> atoms1, Array<size_t> atoms2) 00115 : AtomListPotential<lj_interaction_cut_smooth, cartesian_distance<3>>( 00116 std::make_shared<lj_interaction_cut_smooth>(C6, C12, rcut), 00117 std::make_shared<cartesian_distance<3>>(), atoms1, atoms2) 00118 {} 00119 00120 LJCutAtomList(double C6, double C12, double rcut, Array<size_t> atoms1) 00121 : AtomListPotential<lj_interaction_cut_smooth, cartesian_distance<3>>( 00122 std::make_shared<lj_interaction_cut_smooth>(C6, C12, rcut), 00123 std::make_shared<cartesian_distance<3>>(), atoms1) 00124 {} 00125 }; 00126 00131 class LJCutPeriodicAtomList : public AtomListPotential<lj_interaction_cut_smooth, periodic_distance<3>> { 00132 public: 00133 LJCutPeriodicAtomList(double C6, double C12, double rcut, pele::Array<double> boxvec, 00134 Array<size_t> atoms1, Array<size_t> atoms2) 00135 : AtomListPotential<lj_interaction_cut_smooth, periodic_distance<3> >( 00136 std::make_shared<lj_interaction_cut_smooth>(C6, C12, rcut), 00137 std::make_shared<periodic_distance<3>>(boxvec), atoms1, 00138 atoms2) 00139 {} 00140 00141 LJCutPeriodicAtomList(double C6, double C12, double rcut, pele::Array<double> boxvec, 00142 Array<size_t> atoms1) 00143 : AtomListPotential<lj_interaction_cut_smooth, periodic_distance<3>>( 00144 std::make_shared<lj_interaction_cut_smooth>(C6, C12, rcut), 00145 std::make_shared<periodic_distance<3>>(boxvec), atoms1) 00146 {} 00147 }; 00148 00150 // * Pairwise Lennard-Jones potential with smooth cutoff with loops done 00151 // * using cell lists 00152 // */ 00153 template<size_t ndim> 00154 class LJCutPeriodicCellLists : public CellListPotential<lj_interaction_cut_smooth, periodic_distance<ndim> > { 00155 public: 00156 LJCutPeriodicCellLists(double c6, double c12, double rcut, Array<double> const boxvec, double ncellx_scale) 00157 : CellListPotential<lj_interaction_cut_smooth, periodic_distance<ndim> >( 00158 std::make_shared<lj_interaction_cut_smooth>(c6, c12, rcut), 00159 std::make_shared<periodic_distance<ndim> >(boxvec), 00160 boxvec, rcut, ncellx_scale) 00161 {} 00162 }; 00163 00164 } 00165 00166 #endif