pele
Python energy landscape explorer
/home/js850/projects/pele/source/pele/hs_wca.h
00001 #ifndef _PELE_HS_WCA_H
00002 #define _PELE_HS_WCA_H
00003 
00004 #include <algorithm>
00005 #include <memory>
00006 
00007 #include "atomlist_potential.h"
00008 #include "cell_list_potential.h"
00009 #include "distance.h"
00010 #include "frozen_atoms.h"
00011 #include "meta_pow.h"
00012 #include "simple_pairwise_ilist.h"
00013 #include "simple_pairwise_potential.h"
00014 
00015 namespace pele {
00016 
00038 struct sf_HS_WCA_interaction {
00039     const double m_eps;
00040     const double m_alpha;
00041     const Array<double> m_radii;
00042     const double m_delta;
00043     const double m_prfac;
00044     sf_HS_WCA_interaction(const double eps, const double alpha, const Array<double> radii, const double delta=1e-10)
00045         : m_eps(eps),
00046           m_alpha(alpha),
00047           m_radii(radii.copy()),
00048           m_delta(delta),
00049           m_prfac(std::pow((2 * m_alpha + m_alpha * m_alpha), 3) / std::sqrt(2))
00050     {}
00051     double energy(const double r2, const size_t atomi, const size_t atomj) const
00052     {
00053         const double r_H = m_radii[atomi] + m_radii[atomj];
00054         const double r_S = (1 + m_alpha) * r_H;
00055         const double r_S2 = pos_int_pow<2>(r_S);
00056         if (r2 > r_S2) {
00057             // Energy: separation larger than soft shell.
00058             return 0;
00059         }
00060         // r2 <= r_S2: we have to compute the remaining quantities.
00061         const double r_X = r_H + m_delta;
00062         const double r_X2 = pos_int_pow<2>(r_X);
00063         const double r_H2 = pos_int_pow<2>(r_H);
00064         if (r2 > r_X2) {
00065             // Energy: separation in fHS-WCA regime.
00066             const double dr = r2 - r_H2;
00067             const double ir2 = 1.0 / (dr * dr);
00068             const double ir6 = ir2 * ir2 * ir2;
00069             const double ir12 = ir6 * ir6;
00070             const double C3 = m_prfac * r_H2 * r_H2 * r_H2;
00071             const double C6 = C3 * C3;
00072             const double C12 = C6 * C6;
00073             return std::max<double>(0, 4. * m_eps * (-C6 * ir6 + C12 * ir12) + m_eps);
00074         }
00075         // r2 <= r_X2
00076         // Energy: separation in linear regime.
00077         const double dr = r_X2 - r_H2;
00078         const double ir2 = 1.0 / (dr * dr);
00079         const double ir6 = ir2 * ir2 * ir2;
00080         const double ir12 = ir6 * ir6;
00081         const double C3 = m_prfac * r_H2 * r_H2 * r_H2;
00082         const double C6 = C3 * C3;
00083         const double C12 = C6 * C6;
00084         const double EX = std::max<double>(0, 4. * m_eps * (-C6 * ir6 + C12 * ir12) + m_eps);
00085         const double GX = (m_eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr) * (-r_X);
00086         return EX + GX * (std::sqrt(r2) - r_X);
00087     }
00088     double energy_gradient(const double r2, double *const gij, const size_t atomi, const size_t atomj) const
00089     {
00090         const double r_H = m_radii[atomi] + m_radii[atomj];
00091         const double r_S = (1 + m_alpha) * r_H;
00092         const double r_S2 = pos_int_pow<2>(r_S);
00093         if (r2 > r_S2) {
00094             // Energy, gradient: separation larger than soft shell.
00095             *gij = 0;
00096             return 0;
00097         }
00098         // r2 <= r_S2: we have to compute the remaining quantities.
00099         const double r_X = r_H + m_delta;
00100         const double r_X2 = pos_int_pow<2>(r_X);
00101         const double r_H2 = pos_int_pow<2>(r_H);
00102         if (r2 > r_X2) {
00103             // Energy, gradient: separation in fHS-WCA regime.
00104             const double dr = r2 - r_H2;
00105             const double ir2 = 1.0 / (dr * dr);
00106             const double ir6 = ir2 * ir2 * ir2;
00107             const double ir12 = ir6 * ir6;
00108             const double C3 = m_prfac * r_H2 * r_H2 * r_H2;
00109             const double C6 = C3 * C3;
00110             const double C12 = C6 * C6;
00111             *gij = m_eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr; 
00112             return std::max<double>(0, 4. * m_eps * (-C6 * ir6 + C12 * ir12) + m_eps);
00113         }
00114         // r2 <= r_X2
00115         // Energy, gradient: separation in linear regime.
00116         const double dr = r_X2 - r_H2;
00117         const double ir2 = 1.0 / (dr * dr);
00118         const double ir6 = ir2 * ir2 * ir2;
00119         const double ir12 = ir6 * ir6;
00120         const double C3 = m_prfac * r_H2 * r_H2 * r_H2;
00121         const double C6 = C3 * C3;
00122         const double C12 = C6 * C6;
00123         const double EX = std::max<double>(0, 4. * m_eps * (-C6 * ir6 + C12 * ir12) + m_eps);
00124         const double GX = (m_eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr) * (-r_X);
00125         *gij = GX / (-r_X);
00126         return EX + GX * (std::sqrt(r2) - r_X);
00127     }
00128     double energy_gradient_hessian(const double r2, double *const gij, double *const hij, const size_t atomi, const size_t atomj) const
00129     {
00130         const double r_H = m_radii[atomi] + m_radii[atomj];
00131         const double r_S = (1 + m_alpha) * r_H;
00132         const double r_S2 = pos_int_pow<2>(r_S);
00133         if (r2 > r_S2) {
00134             // Energy, gradient, hessian: separation larger than soft shell.
00135             *gij = 0;
00136             *hij = 0;
00137             return 0;
00138         }
00139         // r2 <= r_S2: we have to compute the remaining quantities.
00140         const double r_X = r_H + m_delta;
00141         const double r_X2 = pos_int_pow<2>(r_X);
00142         const double r_H2 = pos_int_pow<2>(r_H);
00143         if (r2 > r_X2) {
00144             // Energy, gradient, hessian: separation in fHS-WCA regime.
00145             const double dr = r2 - r_H2;
00146             const double ir2 = 1.0 / (dr * dr);
00147             const double ir6 = ir2 * ir2 * ir2;
00148             const double ir12 = ir6 * ir6;
00149             const double C3 = m_prfac * r_H2 * r_H2 * r_H2;
00150             const double C6 = C3 * C3;
00151             const double C12 = C6 * C6;
00152             *gij = m_eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr; 
00153             *hij = -*gij + m_eps * ( -672. * C6 * ir6 + 2496. * C12 * ir12)  * r2 * ir2;
00154             return std::max<double>(0, 4. * m_eps * (-C6 * ir6 + C12 * ir12) + m_eps);
00155         }
00156         // r2 <= r_X2
00157         // Energy, gradient, hessian: separation in linear regime.
00158         const double dr = r_X2 - r_H2;
00159         const double ir2 = 1.0 / (dr * dr);
00160         const double ir6 = ir2 * ir2 * ir2;
00161         const double ir12 = ir6 * ir6;
00162         const double C3 = m_prfac * r_H2 * r_H2 * r_H2;
00163         const double C6 = C3 * C3;
00164         const double C12 = C6 * C6;
00165         const double EX = std::max<double>(0, 4. * m_eps * (-C6 * ir6 + C12 * ir12) + m_eps);
00166         const double GX = (m_eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr) * (-r_X);
00167         *gij = GX / (-r_X);
00168         *hij = 0;
00169         return EX + GX * (std::sqrt(r2) - r_X);
00170     }
00174     void evaluate_pair_potential(const double rmin, const double rmax, const size_t nr_points, const size_t atomi, const size_t atomj, std::vector<double>& x, std::vector<double>& y) const
00175     {
00176         x = std::vector<double>(nr_points, 0);
00177         y = std::vector<double>(nr_points, 0);
00178         const double rdelta = (rmax - rmin) / (nr_points - 1);
00179         for (size_t i = 0; i < nr_points; ++i) {
00180             x.at(i) = rmin + i * rdelta;
00181             y.at(i) = energy(x.at(i) * x.at(i), atomi, atomj);
00182         }
00183     }
00184 };
00185 
00191 struct HS_WCA_interaction {
00192     const double _eps;
00193     const double _sca;
00194     const double _infty;
00195     const double _prfac;
00196     const Array<double> _radii;
00197 
00198     HS_WCA_interaction(const double eps, const double sca, const Array<double> radii) 
00199         : _eps(eps),
00200           _sca(sca),
00201           _infty(std::pow(10.0, 50)),
00202           _prfac(std::pow((2 * _sca + _sca * _sca), 3) / std::sqrt(2)),
00203           _radii(radii.copy())
00204     {}
00205     
00206     /* calculate energy from distance squared, r0 is the hard core distance, r is the distance between the centres */
00207     double inline energy(const double r2, const size_t atomi, const size_t atomj) const 
00208     {
00209         const double r0 = _radii[atomi] + _radii[atomj]; //sum of the hard core radii
00210         const double r02 = r0 * r0;
00211         if (r2 <= r02) {
00212             return _infty;
00213         }
00214         const double coff = r0 * (1.0 + _sca); //distance at which the soft cores are at contact
00215         if (r2 > coff * coff) {
00216             return 0;
00217         }
00218         const double dr = r2 - r02; // note that dr is the difference of the squares
00219         const double ir2 = 1.0 / (dr * dr);
00220         const double ir6 = ir2 * ir2 * ir2;
00221         const double ir12 = ir6 * ir6;
00222         const double C3 = _prfac * r02 * r02 * r02;
00223         const double C6 = C3 * C3;
00224         const double C12 = C6 * C6;
00225         return compute_energy(C6, C12, ir6, ir12);
00226     }
00227 
00228     /* calculate energy and gradient from distance squared, gradient is in g/|rij|, r0 is the hard core distance, r is the distance between the centres */
00229     double inline energy_gradient(const double r2, double *const gij, const size_t atomi, const size_t atomj) const 
00230     {
00231         const double r0 = _radii[atomi] + _radii[atomj]; //sum of the hard core radii
00232         const double r02 = r0 * r0;
00233         if (r2 <= r02) {
00234             *gij = _infty;
00235             return _infty;
00236         }
00237         const double coff = r0 * (1.0 + _sca); //distance at which the soft cores are at contact
00238         if (r2 > coff * coff) {
00239             *gij = 0.;
00240             return 0.;
00241         }
00242         const double dr = r2 - r02; // note that dr is the difference of the squares
00243         const double ir2 = 1.0 / (dr * dr);
00244         const double ir6 = ir2 * ir2 * ir2;
00245         const double ir12 = ir6 * ir6;
00246         const double C3 = _prfac * r02 * r02 * r02;
00247         const double C6 = C3 * C3;
00248         const double C12 = C6 * C6;
00249         *gij = _eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr; //this is -g/r, 1/dr because powers must be 7 and 13
00250         return compute_energy(C6, C12, ir6, ir12);
00251     }
00252 
00253     double inline energy_gradient_hessian(const double r2, double *const gij, double *const hij, const size_t atomi, const size_t atomj) const
00254     {
00255         const double r0 = _radii[atomi] + _radii[atomj]; //sum of the hard core radii
00256         const double r02 = r0 * r0;
00257         if (r2 <= r02) {
00258             *gij = _infty;
00259             *hij = _infty;
00260             return _infty;
00261         }
00262         const double coff = r0 * (1.0 + _sca); //distance at which the soft cores are at contact
00263         if (r2 > coff * coff) {
00264             *gij = 0.;
00265             *hij = 0.;
00266             return 0.;
00267         }
00268         const double dr = r2 - r02; // note that dr is the difference of the squares
00269         const double ir2 = 1.0 / (dr * dr);
00270         const double ir6 = ir2 * ir2 * ir2;
00271         const double ir12 = ir6 * ir6;
00272         const double C3 = _prfac * r02 * r02 * r02;
00273         const double C6 = C3 * C3;
00274         const double C12 = C6 * C6;
00275         *gij = _eps * (- 48. * C6 * ir6 + 96. * C12 * ir12) / dr; //this is -g/r, 1/dr because powers must be 7 and 13
00276         *hij = -*gij + _eps * ( -672. * C6 * ir6 + 2496. * C12 * ir12)  * r2 * ir2;
00277         return compute_energy(C6, C12, ir6, ir12);
00278     }
00279     
00286     double compute_energy(const double C6, const double C12, const double ir6, const double ir12) const
00287     {
00288         return std::min<double>(_infty, std::max<double>(0, 4. * _eps * (-C6 * ir6 + C12 * ir12) + _eps));
00289     }
00290     
00294     void evaluate_pair_potential(const double rmin, const double rmax, const size_t nr_points, const size_t atomi, const size_t atomj, std::vector<double>& x, std::vector<double>& y) const
00295     {
00296         x = std::vector<double>(nr_points, 0);
00297         y = std::vector<double>(nr_points, 0);
00298         const double rdelta = (rmax - rmin) / (nr_points - 1);
00299         for (size_t i = 0; i < nr_points; ++i) {
00300             x.at(i) = rmin + i * rdelta;
00301             y.at(i) = energy(x.at(i) * x.at(i), atomi, atomj);
00302         }
00303     }
00304 };
00305 
00306 //
00307 // combine the components (interaction, looping method, distance function) into
00308 // defined classes
00309 //
00310 
00314 template<size_t ndim>
00315 class HS_WCA : public SimplePairwisePotential< sf_HS_WCA_interaction, cartesian_distance<ndim> > {
00316 public:
00317     HS_WCA(double eps, double sca, Array<double> radii)
00318         : SimplePairwisePotential< sf_HS_WCA_interaction, cartesian_distance<ndim> >(
00319                 std::make_shared<sf_HS_WCA_interaction>(eps, sca, radii),
00320                 std::make_shared<cartesian_distance<ndim> >()
00321             )
00322     {
00323         static_assert(ndim > 0, "illegal box dimension");
00324         if (eps < 0) {
00325             throw std::runtime_error("HS_WCA: illegal input: eps");
00326         }
00327         if (sca < 0) {
00328             throw std::runtime_error("HS_WCA: illegal input: sca");
00329         }
00330         if (radii.size() == 0) {
00331             throw std::runtime_error("HS_WCA: illegal input: radii");
00332         }
00333     }
00334 };
00335 
00339 template<size_t ndim>
00340 class HS_WCAPeriodic : public SimplePairwisePotential< sf_HS_WCA_interaction, periodic_distance<ndim> > {
00341 public:
00342     HS_WCAPeriodic(double eps, double sca, Array<double> radii, Array<double> const boxvec)
00343         : SimplePairwisePotential< sf_HS_WCA_interaction, periodic_distance<ndim> > (
00344                 std::make_shared<sf_HS_WCA_interaction>(eps, sca, radii),
00345                 std::make_shared<periodic_distance<ndim> >(boxvec)
00346                 )
00347     {
00348         static_assert(ndim > 0, "illegal box dimension");
00349         if (eps < 0) {
00350             throw std::runtime_error("HS_WCA: illegal input: eps");
00351         }
00352         if (sca < 0) {
00353             throw std::runtime_error("HS_WCA: illegal input: sca");
00354         }
00355         if (radii.size() == 0) {
00356             throw std::runtime_error("HS_WCA: illegal input: radii");
00357         }
00358         if (boxvec.size() != ndim) {
00359             throw std::runtime_error("HS_WCA: illegal input: boxvec");
00360         }
00361     }
00362 };
00363 
00364 template<size_t ndim>
00365 class HS_WCACellLists : public CellListPotential< sf_HS_WCA_interaction, cartesian_distance<ndim> > {
00366 public:
00367     HS_WCACellLists(double eps, double sca, Array<double> radii, Array<double> const boxvec,
00368             const double rcut, const double ncellx_scale = 1.0)
00369     : CellListPotential< sf_HS_WCA_interaction, cartesian_distance<ndim> >(
00370             std::make_shared<sf_HS_WCA_interaction>(eps, sca, radii),
00371             std::make_shared<cartesian_distance<ndim> >(),
00372             boxvec, rcut, ncellx_scale)
00373     {
00374         static_assert(ndim > 0, "illegal box dimension");
00375         if (eps < 0) {
00376             throw std::runtime_error("HS_WCA: illegal input: eps");
00377         }
00378         if (sca < 0) {
00379             throw std::runtime_error("HS_WCA: illegal input: sca");
00380         }
00381         if (radii.size() == 0) {
00382             throw std::runtime_error("HS_WCA: illegal input: radii");
00383         }
00384         if (boxvec.size() != ndim) {
00385             throw std::runtime_error("HS_WCA: illegal input: boxvec");
00386         }
00387         if (rcut < 2 * (1 + sca) * *std::max_element(radii.data(), radii.data() + radii.size())) {
00388             throw std::runtime_error("HS_WCA: illegal input: rcut");
00389         }
00390     }
00391     size_t get_nr_unique_pairs() const { return CellListPotential< sf_HS_WCA_interaction, cartesian_distance<ndim> >::m_celliter->get_nr_unique_pairs(); }
00392 };
00393 
00394 template<size_t ndim>
00395 class HS_WCAPeriodicCellLists : public CellListPotential< sf_HS_WCA_interaction, periodic_distance<ndim> > {
00396 public:
00397     HS_WCAPeriodicCellLists(double eps, double sca, Array<double> radii, Array<double> const boxvec,
00398             const double rcut, const double ncellx_scale = 1.0)
00399     : CellListPotential< sf_HS_WCA_interaction, periodic_distance<ndim> >(
00400             std::make_shared<sf_HS_WCA_interaction>(eps, sca, radii),
00401             std::make_shared<periodic_distance<ndim> >(boxvec),
00402             boxvec, rcut, ncellx_scale)
00403     {
00404         static_assert(ndim > 0, "illegal box dimension");
00405         if (eps < 0) {
00406             throw std::runtime_error("HS_WCA: illegal input: eps");
00407         }
00408         if (sca < 0) {
00409             throw std::runtime_error("HS_WCA: illegal input: sca");
00410         }
00411         if (radii.size() == 0) {
00412             throw std::runtime_error("HS_WCA: illegal input: radii");
00413         }
00414         if (boxvec.size() != ndim) {
00415             throw std::runtime_error("HS_WCA: illegal input: boxvec");
00416         }
00417         if (rcut < 2 * (1 + sca) * *std::max_element(radii.data(), radii.data() + radii.size())) {
00418             throw std::runtime_error("HS_WCA: illegal input: rcut");
00419         }
00420     }
00421     size_t get_nr_unique_pairs() const { return CellListPotential< sf_HS_WCA_interaction, periodic_distance<ndim> >::m_celliter->get_nr_unique_pairs(); }
00422 };
00423 
00427 template<size_t ndim>
00428 class HS_WCAFrozen : public FrozenPotentialWrapper<HS_WCA<ndim> > {
00429 public:
00430     HS_WCAFrozen(double eps, double sca, Array<double> radii, Array<double>& reference_coords, Array<size_t>& frozen_dof)
00431         : FrozenPotentialWrapper< HS_WCA<ndim> > ( std::make_shared<HS_WCA<ndim> >(eps, sca,
00432                     radii), reference_coords.copy(), frozen_dof.copy())
00433     {
00434         static_assert(ndim > 0, "illegal box dimension");
00435         if (eps < 0) {
00436             throw std::runtime_error("HS_WCA: illegal input: eps");
00437         }
00438         if (sca < 0) {
00439             throw std::runtime_error("HS_WCA: illegal input: sca");
00440         }
00441         if (radii.size() == 0) {
00442             throw std::runtime_error("HS_WCA: illegal input: radii");
00443         }
00444         if (reference_coords.size() != ndim * radii.size()) {
00445             throw std::runtime_error("HS_WCA: illegal input: coords vs. radii");
00446         }
00447     }
00448 };
00449 
00453 template<size_t ndim>
00454 class HS_WCAPeriodicFrozen : public FrozenPotentialWrapper<HS_WCAPeriodic<ndim> > {
00455 public:
00456     HS_WCAPeriodicFrozen(double eps, double sca, Array<double> radii, 
00457             Array<double> const boxvec, Array<double>& reference_coords,
00458             Array<size_t>& frozen_dof)
00459         : FrozenPotentialWrapper< HS_WCAPeriodic<ndim> > (
00460                 std::make_shared<HS_WCAPeriodic<ndim> >(eps, sca, radii, boxvec),
00461                 reference_coords.copy(), frozen_dof.copy())
00462     {
00463         static_assert(ndim > 0, "illegal box dimension");
00464         if (eps < 0) {
00465             throw std::runtime_error("HS_WCA: illegal input: eps");
00466         }
00467         if (sca < 0) {
00468             throw std::runtime_error("HS_WCA: illegal input: sca");
00469         }
00470         if (radii.size() == 0) {
00471             throw std::runtime_error("HS_WCA: illegal input: radii");
00472         }
00473         if (boxvec.size() != ndim) {
00474             throw std::runtime_error("HS_WCA: illegal input: boxvec");
00475         }
00476         if (reference_coords.size() != ndim * radii.size()) {
00477             throw std::runtime_error("HS_WCA: illegal input: coords vs. radii");
00478         }
00479     }
00480 };
00481 
00482 template<size_t ndim>
00483 class HS_WCACellListsFrozen : public FrozenPotentialWrapper<HS_WCACellLists<ndim> > {
00484 public:
00485     HS_WCACellListsFrozen(double eps, double sca, Array<double> radii,
00486             Array<double> const boxvec, Array<double>& reference_coords,
00487             Array<size_t>& frozen_dof, const double rcut, const double ncellx_scale = 1.0)
00488         : FrozenPotentialWrapper< HS_WCACellLists<ndim> > (
00489                 std::make_shared<HS_WCACellLists<ndim> >(eps, sca, radii, boxvec, rcut, ncellx_scale),
00490                 reference_coords.copy(), frozen_dof.copy())
00491     {
00492         static_assert(ndim > 0, "illegal box dimension");
00493         if (eps < 0) {
00494             throw std::runtime_error("HS_WCA: illegal input: eps");
00495         }
00496         if (sca < 0) {
00497             throw std::runtime_error("HS_WCA: illegal input: sca");
00498         }
00499         if (radii.size() == 0) {
00500             throw std::runtime_error("HS_WCA: illegal input: radii");
00501         }
00502         if (boxvec.size() != ndim) {
00503             throw std::runtime_error("HS_WCA: illegal input: boxvec");
00504         }
00505         if (reference_coords.size() != ndim * radii.size()) {
00506             throw std::runtime_error("HS_WCA: illegal input: coords vs. radii");
00507         }
00508         if (rcut < 2 * (1 + sca) * *std::max_element(radii.data(), radii.data() + radii.size())) {
00509             throw std::runtime_error("HS_WCA: illegal input: rcut");
00510         }
00511     }
00512 };
00513 
00514 template<size_t ndim>
00515 class HS_WCAPeriodicCellListsFrozen : public FrozenPotentialWrapper<HS_WCAPeriodicCellLists<ndim> > {
00516 public:
00517     HS_WCAPeriodicCellListsFrozen(double eps, double sca, Array<double> radii,
00518             Array<double> const boxvec, Array<double>& reference_coords,
00519             Array<size_t>& frozen_dof, const double rcut, const double ncellx_scale = 1.0)
00520         : FrozenPotentialWrapper< HS_WCAPeriodicCellLists<ndim> > (
00521                 std::make_shared<HS_WCAPeriodicCellLists<ndim> >(eps, sca, radii, boxvec, rcut, ncellx_scale),
00522                 reference_coords.copy(), frozen_dof.copy())
00523     {
00524         static_assert(ndim > 0, "illegal box dimension");
00525         if (eps < 0) {
00526             throw std::runtime_error("HS_WCA: illegal input: eps");
00527         }
00528         if (sca < 0) {
00529             throw std::runtime_error("HS_WCA: illegal input: sca");
00530         }
00531         if (radii.size() == 0) {
00532             throw std::runtime_error("HS_WCA: illegal input: radii");
00533         }
00534         if (boxvec.size() != ndim) {
00535             throw std::runtime_error("HS_WCA: illegal input: boxvec");
00536         }
00537         if (reference_coords.size() != ndim * radii.size()) {
00538             throw std::runtime_error("HS_WCA: illegal input: coords vs. radii");
00539         }
00540         if (rcut < 2 * (1 + sca) * *std::max_element(radii.data(), radii.data() + radii.size())) {
00541             throw std::runtime_error("HS_WCA: illegal input: rcut");
00542         }
00543     }
00544 };
00545 
00549 class HS_WCANeighborList : public SimplePairwiseNeighborList< sf_HS_WCA_interaction > {
00550 public:
00551     HS_WCANeighborList(Array<size_t> & ilist, double eps, double sca, Array<double> radii)
00552         :  SimplePairwiseNeighborList< sf_HS_WCA_interaction > (
00553                 std::make_shared<sf_HS_WCA_interaction>(eps, sca, radii), ilist)
00554     {
00555         if (eps < 0) {
00556             throw std::runtime_error("HS_WCA: illegal input: eps");
00557         }
00558         if (sca < 0) {
00559             throw std::runtime_error("HS_WCA: illegal input: sca");
00560         }
00561         if (radii.size() == 0) {
00562             throw std::runtime_error("HS_WCA: illegal input: radii");
00563         }
00564     }
00565 };
00566 
00567 } //namespace pele
00568 #endif //#ifndef _PELE_HS_WCA_H
 All Classes Namespaces Functions Variables Typedefs