mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
/home/sm958/Work/pele/source/pele/lj.h
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
 All Classes Namespaces Functions Variables Typedefs