mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
/home/sm958/Work/pele/source/pele/wca.h
00001 #ifndef _PELE_WCA_H
00002 #define _PELE_WCA_H
00003 
00004 #include "simple_pairwise_potential.h"
00005 #include "simple_pairwise_ilist.h"
00006 #include "atomlist_potential.h"
00007 #include "distance.h"
00008 
00009 namespace pele {
00010 
00014 struct WCA_interaction {
00015     double const _C6, _C12;
00016     double const _6C6, _12C12, _42C6, _156C12;
00017     double const _coff2, _eps; //cutoff distance for WCA potential
00018 
00019     WCA_interaction(double sig, double eps) 
00020         : _C6(sig*sig*sig*sig*sig*sig),
00021           _C12(_C6*_C6), _6C6(6.*_C6),
00022           _12C12(12.*_C12), _42C6(42*_C6),
00023           _156C12(156*_C12),
00024           _coff2(pow(2.,1./3)*sig*sig), _eps(eps)
00025     {}
00026 
00027     /* calculate energy from distance squared */
00028     double energy(double r2, size_t atom_i, size_t atom_j) const 
00029     {
00030         double E;
00031         double ir2 = 1.0/r2;
00032         double ir6 = ir2*ir2*ir2;
00033         double ir12 = ir6*ir6;
00034         if (r2 < _coff2)
00035             E = 4.*_eps*(-_C6*ir6 + _C12*ir12) + _eps;
00036         else
00037             E = 0.;
00038 
00039         return E;
00040     }
00041 
00042     /* calculate energy and gradient from distance squared, gradient is in -(dv/drij)/|rij| */
00043     double energy_gradient(double r2, double *gij, size_t atom_i, size_t atom_j) const 
00044     {
00045         double E;
00046         double ir2 = 1.0/r2;
00047         double ir6 = ir2*ir2*ir2;
00048         double ir12 = ir6*ir6;
00049         if (r2 < _coff2) {
00050             E = 4.*_eps*(-_C6*ir6 + _C12*ir12) + _eps;
00051             *gij = 4.*_eps*(- _6C6 * ir6 + _12C12 * ir12) * ir2;
00052         } else {
00053             E = 0.;
00054             *gij = 0;
00055         }
00056 
00057         return E;
00058     }
00059 
00060     double inline energy_gradient_hessian(double r2, double *gij, double *hij, size_t atom_i, size_t atom_j) const 
00061     {
00062         double E;
00063         double ir2 = 1.0/r2;
00064         double ir6 = ir2*ir2*ir2;
00065         double ir12 = ir6*ir6;
00066 
00067         if (r2 < _coff2) {
00068             E = 4.*_eps*(-_C6*ir6 + _C12*ir12) + _eps;
00069             *gij = 4.*_eps*(- _6C6 * ir6 + _12C12 * ir12) * ir2;
00070             *hij = 4.*_eps*(- _42C6 * ir6 + _156C12 * ir12) * ir2;
00071         } else {
00072             E = 0.;
00073             *gij = 0;
00074             *hij=0;
00075         }
00076 
00077         return E;
00078     }
00079 };
00080 
00081 
00082 //
00083 // combine the components (interaction, looping method, distance function) into
00084 // defined classes
00085 //
00086 
00090 class WCA : public SimplePairwisePotential< WCA_interaction, cartesian_distance<3>> {
00091 public:
00092     WCA(double sig, double eps)
00093         : SimplePairwisePotential< WCA_interaction, cartesian_distance<3>>(
00094                 std::make_shared<WCA_interaction>(sig, eps),
00095                 std::make_shared<cartesian_distance<3>>()
00096                 )
00097     {}
00098 };
00099 
00100 class WCA2D : public SimplePairwisePotential< WCA_interaction, cartesian_distance<2> > {
00101 public:
00102     WCA2D(double sig, double eps)
00103         : SimplePairwisePotential< WCA_interaction, cartesian_distance<2>> (
00104                 std::make_shared<WCA_interaction>(sig, eps),
00105                 std::make_shared<cartesian_distance<2>>()
00106         ) 
00107     {}
00108 };
00109 
00113 class WCAPeriodic : public SimplePairwisePotential< WCA_interaction, periodic_distance<3> > {
00114 public:
00115     WCAPeriodic(double sig, double eps, Array<double> const boxvec)
00116         : SimplePairwisePotential< WCA_interaction, periodic_distance<3>> (
00117                 std::make_shared<WCA_interaction>(sig, eps),
00118                 std::make_shared<periodic_distance<3>>(boxvec)
00119                 )
00120     {}
00121 };
00122 
00126 class WCAPeriodic2D : public SimplePairwisePotential< WCA_interaction, periodic_distance<2> > {
00127 public:
00128     WCAPeriodic2D(double sig, double eps, Array<double> const boxvec)
00129         : SimplePairwisePotential< WCA_interaction, periodic_distance<2>> (
00130                 std::make_shared<WCA_interaction>(sig, eps),
00131                 std::make_shared<periodic_distance<2>>(boxvec)
00132                 )
00133     {}
00134 };
00135 
00139 class WCANeighborList : public SimplePairwiseNeighborList< WCA_interaction > {
00140 public:
00141     WCANeighborList(Array<size_t> & ilist, double sig, double eps)
00142         :  SimplePairwiseNeighborList< WCA_interaction > (
00143                 std::make_shared<WCA_interaction>(sig, eps), ilist)
00144     {}
00145 };
00146 
00147 class WCAAtomList : public AtomListPotential<WCA_interaction, cartesian_distance<3>> {
00148 public:
00149     WCAAtomList(double sig, double eps, Array<size_t> atoms1, Array<size_t> atoms2)
00150         : AtomListPotential<WCA_interaction, cartesian_distance<3> >(
00151             std::make_shared<WCA_interaction>(sig, eps),
00152             std::make_shared<cartesian_distance<3>>(), atoms1, atoms2)
00153     {}
00154     WCAAtomList(double sig, double eps, Array<size_t> atoms1)
00155         : AtomListPotential<WCA_interaction, cartesian_distance<3> >(
00156             std::make_shared<WCA_interaction>(sig, eps),
00157             std::make_shared<cartesian_distance<3>>(), atoms1)
00158     {}
00159 };
00160 
00161 }
00162 #endif
00163 
00164 
 All Classes Namespaces Functions Variables Typedefs