Commit 5209c1cd authored by Mark Friedrichs's avatar Mark Friedrichs
Browse files

Lee-Ping's vdw dispersion correction

added tests to TestCudaAmoebaVdwForce for dispersion correction using box of 216 water molecules
AmoebaVdwForce and AmoebaMultipoleForce now throw execptions if cutoff > 0.5*(box size)
parent 887d4e18
#ifndef OPENMM_AMOEBA_VDW_FORCE_H_ #ifndef OPENMM_AMOEBA_VDW_FORCE_H_
#define OPENMM_AMOEBA_VDW_FORCE_H_ #define OPENMM_AMOEBA_VDW_FORCE_H_
/* -------------------------------------------------------------------------- * /* -------------------------------------------------------------------------- *
* OpenMMAmoeba * * OpenMMAmoeba *
* -------------------------------------------------------------------------- * * -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from * * This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of * * Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. * * Portions copyright (c) 2008-2009 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
* Permission is hereby granted, free of charge, to any person obtaining a * * Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * * copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation * * to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the * * and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: * * Software is furnished to do so, subject to the following conditions: *
* * * *
* The above copyright notice and this permission notice shall be included in * * The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. * * all copies or substantial portions of the Software. *
* * * *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/Force.h" #include "openmm/Force.h"
#include "openmm/internal/windowsExport.h" #include "openmm/internal/windowsExport.h"
#include <vector> #include <vector>
namespace OpenMM { namespace OpenMM {
/** /**
* This class implements an interaction between pairs of particles that varies harmonically with the distance * This class implements an interaction between pairs of particles that varies harmonically with the distance
* between them. To use it, create a VdwForce object then call addAngle() once for each angle. After * between them. To use it, create a VdwForce object then call addAngle() once for each angle. After
* a angle has been added, you can modify its force field parameters by calling setAngleParameters(). * a angle has been added, you can modify its force field parameters by calling setAngleParameters().
*/ */
class OPENMM_EXPORT AmoebaVdwForce : public Force { class OPENMM_EXPORT AmoebaVdwForce : public Force {
public: public:
/** /**
* Create a Amoeba VdwForce. * Create a Amoeba VdwForce.
*/ */
AmoebaVdwForce(); AmoebaVdwForce();
/** /**
* Get the number of particles * Get the number of particles
*/ */
int getNumParticles() const { int getNumParticles() const {
return parameters.size(); return parameters.size();
} }
/** /**
* Set the force field parameters for a vdw particle. * Set the force field parameters for a vdw particle.
* *
* @param particleIndex the particle index * @param particleIndex the particle index
* @param ivIndex the iv index * @param ivIndex the iv index
* @param classIndex the class index into the sig-eps table * @param classIndex the class index into the sig-eps table
* @param sigma vdw sigma * @param sigma vdw sigma
* @param epsilon vdw epsilon * @param epsilon vdw epsilon
* @param reductionFactor the reduction factor * @param reductionFactor the reduction factor
*/ */
void setParticleParameters(int particleIndex, int ivIndex, int classIndex, void setParticleParameters(int particleIndex, int ivIndex, int classIndex,
double sigma, double epsilon, double reductionFactor ); double sigma, double epsilon, double reductionFactor );
/** /**
* Get the force field parameters for a vdw particle. * Get the force field parameters for a vdw particle.
* *
* @param particleIndex the particle index * @param particleIndex the particle index
* @param ivIndex the iv index * @param ivIndex the iv index
* @param classIndex the class index into the sig-eps table * @param classIndex the class index into the sig-eps table
* @param sigma vdw sigma * @param sigma vdw sigma
* @param epsilon vdw epsilon * @param epsilon vdw epsilon
* @param reductionFactor the reduction factor * @param reductionFactor the reduction factor
*/ */
void getParticleParameters(int particleIndex, int& ivIndex, int& classIndex, void getParticleParameters(int particleIndex, int& ivIndex, int& classIndex,
double& sigma, double& epsilon, double& reductionFactor ) const; double& sigma, double& epsilon, double& reductionFactor ) const;
/** /**
* Set the force field parameters for a vdw particle. * Set the force field parameters for a vdw particle.
* *
* @param particleIndex the particle index * @param particleIndex the particle index
* @param ivIndex the iv index * @param ivIndex the iv index
* @param classIndex the class index into the sig-eps table * @param classIndex the class index into the sig-eps table
* @param sigma vdw sigma * @param sigma vdw sigma
* @param epsilon vdw epsilon * @param epsilon vdw epsilon
* @param reductionFactor the reduction factor * @param reductionFactor the reduction factor
* @return index of added particle * @return index of added particle
*/ */
int addParticle(int ivIndex, int classIndex, int addParticle(int ivIndex, int classIndex,
double sigma, double epsilon, double reductionFactor ); double sigma, double epsilon, double reductionFactor );
/** /**
* Set sigma combining rule * Set sigma combining rule
* *
* @param sigmaCombiningRule sigma combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'CUBIC-MEAN' * @param sigmaCombiningRule sigma combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'CUBIC-MEAN'
*/ */
void setSigmaCombiningRule( const std::string& sigmaCombiningRule ); void setSigmaCombiningRule( const std::string& sigmaCombiningRule );
/** /**
* Get sigma combining rule * Get sigma combining rule
* *
* @return sigmaCombiningRule sigma combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'CUBIC-MEAN' * @return sigmaCombiningRule sigma combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'CUBIC-MEAN'
*/ */
const std::string& getSigmaCombiningRule( void ) const; const std::string& getSigmaCombiningRule( void ) const;
/** /**
* Set epsilon combining rule * Set epsilon combining rule
* *
* @param epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG' * @param epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG'
*/ */
void setEpsilonCombiningRule( const std::string& epsilonCombiningRule ); void setEpsilonCombiningRule( const std::string& epsilonCombiningRule );
/** /**
* Get epsilon combining rule * Get epsilon combining rule
* *
* @return epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG' * @return epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG'
*/ */
const std::string& getEpsilonCombiningRule( void ) const; const std::string& getEpsilonCombiningRule( void ) const;
/** /**
* Set exclusions for specified particle * LPW: Get whether to add a contribution to the energy that approximately represents the effect of VdW
* * interactions beyond the cutoff distance. The energy depends on the volume of the periodic box, and is only
* @param particleIndex particle index * applicable when periodic boundary conditions are used. When running simulations at constant pressure, adding
* @param exclusions output vector of exclusions * this contribution can improve the quality of results.
*/ */
void setParticleExclusions( int particleIndex, const std::vector< int >& exclusions ); bool getUseDispersionCorrection() const {
return useDispersionCorrection;
/** }
* Get exclusions for specified particle
* /**
* @param particleIndex particle index * Set whether to add a contribution to the energy that approximately represents the effect of VdW
* @param exclusions output vector of exclusions * interactions beyond the cutoff distance. The energy depends on the volume of the periodic box, and is only
*/ * applicable when periodic boundary conditions are used. When running simulations at constant pressure, adding
void getParticleExclusions( int particleIndex, std::vector< int >& exclusions ) const; * this contribution can improve the quality of results.
*/
/** void setUseDispersionCorrection(bool useCorrection) {
* Set cutoff useDispersionCorrection = useCorrection;
* }
* @param cutoff cutoff
*/ /**
void setCutoff( double cutoff ); * Set exclusions for specified particle
*
/** * @param particleIndex particle index
* Get cutoff * @param exclusions output vector of exclusions
* */
* @return cutoff void setParticleExclusions( int particleIndex, const std::vector< int >& exclusions );
*/
double getCutoff( void ) const; /**
* Get exclusions for specified particle
/** *
* Set flag for using neighbor list for vdw ixn * @param particleIndex particle index
* * @param exclusions output vector of exclusions
* @param neighboristFlag neighbor list flag */
*/ void getParticleExclusions( int particleIndex, std::vector< int >& exclusions ) const;
void setUseNeighborList( int neighborListFlag );
/**
/** * Set cutoff
* Get neighbor list flag for vdw ixn *
* * @param cutoff cutoff
* @return neighbor list flag */
*/ void setCutoff( double cutoff );
int getUseNeighborList( void ) const;
/**
/** * Get cutoff
* Set flag for employing periodic boundary conditions *
* * @return cutoff
* @param pbcFlag if nonozero, use periodic boundary conditions */
*/ double getCutoff( void ) const;
void setPBC( int pbcFlag );
/**
/** * Set flag for using neighbor list for vdw ixn
* Get periodic boundary conditions flag *
* * @param neighboristFlag neighbor list flag
* @return periodic boundary conditions flag (nonzero -> use PBC) */
*/ void setUseNeighborList( int neighborListFlag );
int getPBC( void ) const;
/**
protected: * Get neighbor list flag for vdw ixn
ForceImpl* createImpl(); *
private: * @return neighbor list flag
*/
class VdwInfo; int getUseNeighborList( void ) const;
int usePBC;
int useNeighborList; /**
double cutoff; * Set flag for employing periodic boundary conditions
*
std::string sigmaCombiningRule; * @param pbcFlag if nonozero, use periodic boundary conditions
std::string epsilonCombiningRule; */
void setPBC( int pbcFlag );
std::vector< std::vector<int> > exclusions;
/**
// Retarded visual studio compiler complains about being unable to * Get periodic boundary conditions flag
// export private stl class members. *
// This stanza explains that it should temporarily shut up. * @return periodic boundary conditions flag (nonzero -> use PBC)
#if defined(_MSC_VER) */
#pragma warning(push) int getPBC( void ) const;
#pragma warning(disable:4251)
#endif protected:
std::vector<VdwInfo> parameters; ForceImpl* createImpl();
#if defined(_MSC_VER) private:
#pragma warning(pop)
#endif class VdwInfo;
int usePBC;
std::vector< std::vector< std::vector<double> > > sigEpsTable; int useNeighborList;
}; double cutoff;
bool useDispersionCorrection;
class AmoebaVdwForce::VdwInfo {
public: std::string sigmaCombiningRule;
int ivIndex, classIndex; std::string epsilonCombiningRule;
double reductionFactor, sigma, epsilon, cutoff;
VdwInfo() { std::vector< std::vector<int> > exclusions;
ivIndex = classIndex = -1;
reductionFactor = 0.0; // Retarded visual studio compiler complains about being unable to
sigma = 1.0; // export private stl class members.
epsilon = 0.0; // This stanza explains that it should temporarily shut up.
} #if defined(_MSC_VER)
VdwInfo(int ivIndex, int classIndex, double sigma, double epsilon, double reductionFactor ) : #pragma warning(push)
ivIndex(ivIndex), classIndex(classIndex), sigma(sigma), epsilon(epsilon), reductionFactor(reductionFactor) { #pragma warning(disable:4251)
} #endif
}; std::vector<VdwInfo> parameters;
#if defined(_MSC_VER)
} // namespace OpenMM #pragma warning(pop)
#endif
#endif /*OPENMM_AMOEBA_VDW_FORCE_H_*/
std::vector< std::vector< std::vector<double> > > sigEpsTable;
};
class AmoebaVdwForce::VdwInfo {
public:
int ivIndex, classIndex;
double reductionFactor, sigma, epsilon, cutoff;
VdwInfo() {
ivIndex = classIndex = -1;
reductionFactor = 0.0;
sigma = 1.0;
epsilon = 0.0;
}
VdwInfo(int ivIndex, int classIndex, double sigma, double epsilon, double reductionFactor ) :
ivIndex(ivIndex), classIndex(classIndex), sigma(sigma), epsilon(epsilon), reductionFactor(reductionFactor) {
}
};
} // namespace OpenMM
#endif /*OPENMM_AMOEBA_VDW_FORCE_H_*/
#ifndef OPENMM_AMOEBA_VDW_FORCE_IMPL_H_ #ifndef OPENMM_AMOEBA_VDW_FORCE_IMPL_H_
#define OPENMM_AMOEBA_VDW_FORCE_IMPL_H_ #define OPENMM_AMOEBA_VDW_FORCE_IMPL_H_
/* -------------------------------------------------------------------------- * /* -------------------------------------------------------------------------- *
* OpenMMAmoeba * * OpenMMAmoeba *
* -------------------------------------------------------------------------- * * -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from * * This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of * * Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
* Permission is hereby granted, free of charge, to any person obtaining a * * Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * * copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation * * to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the * * and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: * * Software is furnished to do so, subject to the following conditions: *
* * * *
* The above copyright notice and this permission notice shall be included in * * The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. * * all copies or substantial portions of the Software. *
* * * *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/internal/ForceImpl.h" #include "openmm/internal/ForceImpl.h"
#include "openmm/AmoebaVdwForce.h" #include "openmm/AmoebaVdwForce.h"
#include "openmm/Kernel.h" #include "openmm/Kernel.h"
#include <utility> #include <utility>
#include <set> #include <set>
#include <string> #include <string>
namespace OpenMM { namespace OpenMM {
/** class System;
* This is the internal implementation of AmoebaVdwForce.
*/ /**
* This is the internal implementation of AmoebaVdwForce.
class AmoebaVdwForceImpl : public ForceImpl { */
public:
AmoebaVdwForceImpl(AmoebaVdwForce& owner); class AmoebaVdwForceImpl : public ForceImpl {
~AmoebaVdwForceImpl(); public:
void initialize(ContextImpl& context); AmoebaVdwForceImpl(AmoebaVdwForce& owner);
AmoebaVdwForce& getOwner() { ~AmoebaVdwForceImpl();
return owner; void initialize(ContextImpl& context);
} AmoebaVdwForce& getOwner() {
void updateContextState(ContextImpl& context) { return owner;
// This force field doesn't update the state directly. }
} void updateContextState(ContextImpl& context) {
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups); // This force field doesn't update the state directly.
std::map<std::string, double> getDefaultParameters() { }
return std::map<std::string, double>(); // This force field doesn't define any parameters. double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups);
} std::map<std::string, double> getDefaultParameters() {
std::vector<std::string> getKernelNames(); return std::map<std::string, double>(); // This force field doesn't define any parameters.
private: }
AmoebaVdwForce& owner; std::vector<std::string> getKernelNames();
Kernel kernel; /**
}; * Compute the coefficient which, when divided by the periodic box volume, gives the
* long range dispersion correction to the energy.
} // namespace OpenMM */
static double calcDispersionCorrection(const System& system, const AmoebaVdwForce& force);
#endif /*OPENMM_AMOEBA_VDW_FORCE_IMPL_H_*/ private:
AmoebaVdwForce& owner;
Kernel kernel;
};
} // namespace OpenMM
#endif /*OPENMM_AMOEBA_VDW_FORCE_IMPL_H_*/
...@@ -53,6 +53,16 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { ...@@ -53,6 +53,16 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) {
if (owner.getNumMultipoles() != system.getNumParticles()) if (owner.getNumMultipoles() != system.getNumParticles())
throw OpenMMException("AmoebaMultipoleForce must have exactly as many particles as the System it belongs to."); throw OpenMMException("AmoebaMultipoleForce must have exactly as many particles as the System it belongs to.");
// check cutoff < 0.5*boxSize
if (owner.getNonbondedMethod() == AmoebaMultipoleForce::PME) {
Vec3 boxVectors[3];
system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
double cutoff = owner.getCutoffDistance();
if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2])
throw OpenMMException("AmoebaMultipoleForce: The cutoff distance cannot be greater than half the periodic box size.");
}
double quadrupoleValidationTolerance = 1.0e-05; double quadrupoleValidationTolerance = 1.0e-05;
for( int ii = 0; ii < system.getNumParticles(); ii++ ){ for( int ii = 0; ii < system.getNumParticles(); ii++ ){
......
/* -------------------------------------------------------------------------- * /* -------------------------------------------------------------------------- *
* OpenMMAmoeba * * OpenMMAmoeba *
* -------------------------------------------------------------------------- * * -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from * * This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of * * Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. * * Portions copyright (c) 2008-2009 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
* Permission is hereby granted, free of charge, to any person obtaining a * * Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * * copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation * * to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the * * and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: * * Software is furnished to do so, subject to the following conditions: *
* * * *
* The above copyright notice and this permission notice shall be included in * * The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. * * all copies or substantial portions of the Software. *
* * * *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/Force.h" #include "openmm/Force.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/AmoebaVdwForce.h" #include "openmm/AmoebaVdwForce.h"
#include "openmm/internal/AmoebaVdwForceImpl.h" #include "openmm/internal/AmoebaVdwForceImpl.h"
using namespace OpenMM; using namespace OpenMM;
using std::string; using std::string;
using std::vector; using std::vector;
AmoebaVdwForce::AmoebaVdwForce() : sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), usePBC(0), cutoff(1.0e+10), useNeighborList(0) { AmoebaVdwForce::AmoebaVdwForce() : sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), usePBC(0), cutoff(1.0e+10), useNeighborList(0), useDispersionCorrection(true) {
} }
int AmoebaVdwForce::addParticle(int ivIndex, int classIndex, double sigma, double epsilon, double reductionFactor ) { int AmoebaVdwForce::addParticle(int ivIndex, int classIndex, double sigma, double epsilon, double reductionFactor ) {
parameters.push_back(VdwInfo(ivIndex, classIndex, sigma, epsilon, reductionFactor)); parameters.push_back(VdwInfo(ivIndex, classIndex, sigma, epsilon, reductionFactor));
return parameters.size()-1; return parameters.size()-1;
} }
void AmoebaVdwForce::getParticleParameters(int particleIndex, int& ivIndex, int& classIndex, void AmoebaVdwForce::getParticleParameters(int particleIndex, int& ivIndex, int& classIndex,
double& sigma, double& epsilon, double& reductionFactor ) const { double& sigma, double& epsilon, double& reductionFactor ) const {
ivIndex = parameters[particleIndex].ivIndex; ivIndex = parameters[particleIndex].ivIndex;
classIndex = parameters[particleIndex].classIndex; classIndex = parameters[particleIndex].classIndex;
sigma = parameters[particleIndex].sigma; sigma = parameters[particleIndex].sigma;
epsilon = parameters[particleIndex].epsilon; epsilon = parameters[particleIndex].epsilon;
reductionFactor = parameters[particleIndex].reductionFactor; reductionFactor = parameters[particleIndex].reductionFactor;
} }
void AmoebaVdwForce::setParticleParameters(int particleIndex, int ivIndex, int classIndex, void AmoebaVdwForce::setParticleParameters(int particleIndex, int ivIndex, int classIndex,
double sigma, double epsilon, double reductionFactor ) { double sigma, double epsilon, double reductionFactor ) {
parameters[particleIndex].ivIndex = ivIndex; parameters[particleIndex].ivIndex = ivIndex;
parameters[particleIndex].classIndex = classIndex; parameters[particleIndex].classIndex = classIndex;
parameters[particleIndex].sigma = sigma; parameters[particleIndex].sigma = sigma;
parameters[particleIndex].epsilon = epsilon; parameters[particleIndex].epsilon = epsilon;
parameters[particleIndex].reductionFactor = reductionFactor; parameters[particleIndex].reductionFactor = reductionFactor;
} }
void AmoebaVdwForce::setSigmaCombiningRule( const std::string& inputSigmaCombiningRule ) { void AmoebaVdwForce::setSigmaCombiningRule( const std::string& inputSigmaCombiningRule ) {
sigmaCombiningRule = inputSigmaCombiningRule; sigmaCombiningRule = inputSigmaCombiningRule;
} }
const std::string& AmoebaVdwForce::getSigmaCombiningRule( void ) const { const std::string& AmoebaVdwForce::getSigmaCombiningRule( void ) const {
return sigmaCombiningRule; return sigmaCombiningRule;
} }
void AmoebaVdwForce::setEpsilonCombiningRule( const std::string& inputEpsilonCombiningRule ) { void AmoebaVdwForce::setEpsilonCombiningRule( const std::string& inputEpsilonCombiningRule ) {
epsilonCombiningRule = inputEpsilonCombiningRule; epsilonCombiningRule = inputEpsilonCombiningRule;
} }
const std::string& AmoebaVdwForce::getEpsilonCombiningRule( void ) const { const std::string& AmoebaVdwForce::getEpsilonCombiningRule( void ) const {
return epsilonCombiningRule; return epsilonCombiningRule;
} }
void AmoebaVdwForce::setParticleExclusions( int particleIndex, const std::vector< int >& inputExclusions ) { void AmoebaVdwForce::setParticleExclusions( int particleIndex, const std::vector< int >& inputExclusions ) {
if( exclusions.size() < parameters.size() ){ if( exclusions.size() < parameters.size() ){
exclusions.resize( parameters.size() ); exclusions.resize( parameters.size() );
} }
if( static_cast<int>(exclusions.size()) < particleIndex ){ if( static_cast<int>(exclusions.size()) < particleIndex ){
exclusions.resize( particleIndex + 10 ); exclusions.resize( particleIndex + 10 );
} }
for( unsigned int ii = 0; ii < inputExclusions.size(); ii++ ){ for( unsigned int ii = 0; ii < inputExclusions.size(); ii++ ){
exclusions[particleIndex].push_back( inputExclusions[ii] ); exclusions[particleIndex].push_back( inputExclusions[ii] );
} }
} }
void AmoebaVdwForce::getParticleExclusions( int particleIndex, std::vector< int >& outputExclusions ) const { void AmoebaVdwForce::getParticleExclusions( int particleIndex, std::vector< int >& outputExclusions ) const {
if( particleIndex < static_cast<int>(exclusions.size()) ){ if( particleIndex < static_cast<int>(exclusions.size()) ){
outputExclusions.resize( exclusions[particleIndex].size() ); outputExclusions.resize( exclusions[particleIndex].size() );
for( unsigned int ii = 0; ii < exclusions[particleIndex].size(); ii++ ){ for( unsigned int ii = 0; ii < exclusions[particleIndex].size(); ii++ ){
outputExclusions[ii] = exclusions[particleIndex][ii]; outputExclusions[ii] = exclusions[particleIndex][ii];
} }
} }
} }
void AmoebaVdwForce::setCutoff( double inputCutoff ){ void AmoebaVdwForce::setCutoff( double inputCutoff ){
cutoff = inputCutoff; cutoff = inputCutoff;
} }
double AmoebaVdwForce::getCutoff( void ) const { double AmoebaVdwForce::getCutoff( void ) const {
return cutoff; return cutoff;
} }
void AmoebaVdwForce::setUseNeighborList( int useNeighborListFlag ){ void AmoebaVdwForce::setUseNeighborList( int useNeighborListFlag ){
useNeighborList = useNeighborListFlag; useNeighborList = useNeighborListFlag;
} }
int AmoebaVdwForce::getUseNeighborList( void ) const { int AmoebaVdwForce::getUseNeighborList( void ) const {
return useNeighborList; return useNeighborList;
} }
void AmoebaVdwForce::setPBC( int pbcFlag ){ void AmoebaVdwForce::setPBC( int pbcFlag ){
usePBC = pbcFlag; usePBC = pbcFlag;
} }
int AmoebaVdwForce::getPBC( void ) const { int AmoebaVdwForce::getPBC( void ) const {
return usePBC; return usePBC;
} }
ForceImpl* AmoebaVdwForce::createImpl() { ForceImpl* AmoebaVdwForce::createImpl() {
return new AmoebaVdwForceImpl(*this); return new AmoebaVdwForceImpl(*this);
} }
/* -------------------------------------------------------------------------- * /* -------------------------------------------------------------------------- *
* OpenMMAmoeba * * OpenMMAmoeba *
* -------------------------------------------------------------------------- * * -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from * * This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of * * Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
* Permission is hereby granted, free of charge, to any person obtaining a * * Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * * copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation * * to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the * * and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: * * Software is furnished to do so, subject to the following conditions: *
* * * *
* The above copyright notice and this permission notice shall be included in * * The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. * * all copies or substantial portions of the Software. *
* * * *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/AmoebaVdwForceImpl.h" #include "openmm/internal/AmoebaVdwForceImpl.h"
#include "openmm/amoebaKernels.h" #include "openmm/amoebaKernels.h"
#include <map>
using namespace OpenMM; #include <stdio.h>
using std::pair; using namespace OpenMM;
using std::vector; using namespace std;
using std::set;
using std::pair;
AmoebaVdwForceImpl::AmoebaVdwForceImpl(AmoebaVdwForce& owner) : owner(owner) { using std::vector;
} using std::set;
AmoebaVdwForceImpl::~AmoebaVdwForceImpl() { AmoebaVdwForceImpl::AmoebaVdwForceImpl(AmoebaVdwForce& owner) : owner(owner) {
} }
void AmoebaVdwForceImpl::initialize(ContextImpl& context) { AmoebaVdwForceImpl::~AmoebaVdwForceImpl() {
System& system = context.getSystem(); }
if (owner.getNumParticles() != system.getNumParticles()) void AmoebaVdwForceImpl::initialize(ContextImpl& context) {
throw OpenMMException("AmoebaVdwForce must have exactly as many particles as the System it belongs to."); System& system = context.getSystem();
kernel = context.getPlatform().createKernel(CalcAmoebaVdwForceKernel::Name(), context); if (owner.getNumParticles() != system.getNumParticles())
kernel.getAs<CalcAmoebaVdwForceKernel>().initialize(context.getSystem(), owner); throw OpenMMException("AmoebaVdwForce must have exactly as many particles as the System it belongs to.");
}
// check that cutoff < 0.5*boxSize
double AmoebaVdwForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
if ((groups&(1<<owner.getForceGroup())) != 0) if (owner.getPBC()) {
return kernel.getAs<CalcAmoebaVdwForceKernel>().execute(context, includeForces, includeEnergy); Vec3 boxVectors[3];
return 0.0; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
} double cutoff = owner.getCutoff();
if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2])
std::vector<std::string> AmoebaVdwForceImpl::getKernelNames() { throw OpenMMException("AmoebaVdwForce: The cutoff distance cannot be greater than half the periodic box size.");
std::vector<std::string> names; }
names.push_back(CalcAmoebaVdwForceKernel::Name());
return names; kernel = context.getPlatform().createKernel(CalcAmoebaVdwForceKernel::Name(), context);
} kernel.getAs<CalcAmoebaVdwForceKernel>().initialize(context.getSystem(), owner);
}
double AmoebaVdwForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
if ((groups&(1<<owner.getForceGroup())) != 0)
return kernel.getAs<CalcAmoebaVdwForceKernel>().execute(context, includeForces, includeEnergy);
return 0.0;
}
double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const AmoebaVdwForce& force) {
// Amoeba VdW dispersion correction implemented by LPW
// There is no dispersion correction if PBC is off or the cutoff is set to the default value of ten billion (AmoebaVdwForce.cpp)
if (force.getPBC() == 0 || force.getUseNeighborList() == 0)
return 0.0;
// Identify all particle classes (defined by sigma and epsilon and reduction), and count the number of
// particles in each class.
map<pair<double, double>, int> classCounts;
for (int i = 0; i < force.getNumParticles(); i++) {
double sigma, epsilon, reduction;
// The variables reduction, ivindex, classindex are not used.
int ivindex, classindex;
// Get the sigma and epsilon parameters, ignoring everything else.
force.getParticleParameters(i, ivindex, classindex, sigma, epsilon, reduction);
pair<double, double> key = make_pair(sigma, epsilon);
map<pair<double, double>, int>::iterator entry = classCounts.find(key);
if (entry == classCounts.end())
classCounts[key] = 1;
else
entry->second++;
}
// Compute the VdW tapering coefficients. Mostly copied from amoebaCudaGpu.cpp.
double cutoff = force.getCutoff();
double vdwTaper = 0.90; // vdwTaper is a scaling factor, it is not a distance.
double c0 = 0.0;
double c1 = 0.0;
double c2 = 0.0;
double c3 = 0.0;
double c4 = 0.0;
double c5 = 0.0;
double vdwCut = cutoff;
double vdwTaperCut = vdwTaper*cutoff;
double vdwCut2 = vdwCut*vdwCut;
double vdwCut3 = vdwCut2*vdwCut;
double vdwCut4 = vdwCut2*vdwCut2;
double vdwCut5 = vdwCut2*vdwCut3;
double vdwCut6 = vdwCut3*vdwCut3;
double vdwCut7 = vdwCut3*vdwCut4;
double vdwTaperCut2 = vdwTaperCut*vdwTaperCut;
double vdwTaperCut3 = vdwTaperCut2*vdwTaperCut;
double vdwTaperCut4 = vdwTaperCut2*vdwTaperCut2;
double vdwTaperCut5 = vdwTaperCut2*vdwTaperCut3;
double vdwTaperCut6 = vdwTaperCut3*vdwTaperCut3;
double vdwTaperCut7 = vdwTaperCut3*vdwTaperCut4;
// get 5th degree multiplicative switching function coefficients;
double denom = 1.0 / (vdwCut - vdwTaperCut);
double denom2 = denom*denom;
denom = denom * denom2*denom2;
c0 = vdwCut * vdwCut2 * (vdwCut2 - 5.0 * vdwCut * vdwTaperCut + 10.0 * vdwTaperCut2) * denom;
c1 = -30.0 * vdwCut2 * vdwTaperCut2*denom;
c2 = 30.0 * (vdwCut2 * vdwTaperCut + vdwCut * vdwTaperCut2) * denom;
c3 = -10.0 * (vdwCut2 + 4.0 * vdwCut * vdwTaperCut + vdwTaperCut2) * denom;
c4 = 15.0 * (vdwCut + vdwTaperCut) * denom;
c5 = -6.0 * denom;
// Loop over all pairs of classes to compute the coefficient.
// Copied over from TINKER - numerical integration.
double range = 20.0;
double cut = vdwTaperCut; // This is where tapering BEGINS
double off = vdwCut; // This is where tapering ENDS
int nstep = 200;
int ndelta = int(double(nstep) * (range - cut));
double rdelta = (range - cut) / double(ndelta);
double offset = cut - 0.5 * rdelta;
double dhal = 0.07; // This magic number also appears in kCalculateAmoebaCudaVdw14_7.cu
double ghal = 0.12; // This magic number also appears in kCalculateAmoebaCudaVdw14_7.cu
double elrc = 0.0; // This number is incremented and passed out at the end
double e = 0.0;
double sigma, epsilon; // The pairwise sigma and epsilon parameters.
int i = 0, k = 0; // Loop counters.
// Double loop over different atom types.
std::string sigmaCombiningRule = force.getSigmaCombiningRule();
std::string epsilonCombiningRule = force.getEpsilonCombiningRule();
for (map<pair<double, double>, int>::const_iterator class1 = classCounts.begin(); class1 != classCounts.end(); ++class1) {
k = 0;
for (map<pair<double, double>, int>::const_iterator class2 = classCounts.begin(); class2 != classCounts.end(); ++class2) {
// AMOEBA combining rules, copied over from the CUDA code.
double iSigma = class1->first.first;
double jSigma = class2->first.first;
double iEpsilon = class1->first.second;
double jEpsilon = class2->first.second;
// ARITHMETIC = 1
// GEOMETRIC = 2
// CUBIC-MEAN = 3
if (sigmaCombiningRule == "ARITHMETIC") {
sigma = iSigma + jSigma;
} else if (sigmaCombiningRule == "GEOMETRIC") {
sigma = 2.0f * std::sqrt(iSigma * jSigma);
} else {
double iSigma2 = iSigma*iSigma;
double jSigma2 = jSigma*jSigma;
sigma = 2.0f * (iSigma2 * iSigma + jSigma2 * jSigma) / (iSigma2 + jSigma2);
}
// ARITHMETIC = 1
// GEOMETRIC = 2
// HARMONIC = 3
// HHG = 4
if (epsilonCombiningRule == "ARITHMETIC") {
epsilon = 0.5f * (iEpsilon + jEpsilon);
} else if (epsilonCombiningRule == "GEOMETRIC") {
epsilon = std::sqrt(iEpsilon * jEpsilon);
} else if (epsilonCombiningRule == "HARMONIC") {
epsilon = 2.0f * (iEpsilon * jEpsilon) / (iEpsilon + jEpsilon);
} else {
double epsilonS = std::sqrt(iEpsilon) + std::sqrt(jEpsilon);
epsilon = 4.0f * (iEpsilon * jEpsilon) / (epsilonS * epsilonS);
}
int count = class1->second * class2->second;
// Below is an exact copy of stuff from the previous block.
double rv = sigma;
double termik = 2.0 * M_PI * count; // termik is equivalent to 2 * pi * count.
double rv2 = rv * rv;
double rv6 = rv2 * rv2 * rv2;
double rv7 = rv6 * rv;
double etot = 0.0;
double r2 = 0.0;
for (int j = 1; j <= ndelta; j++) {
double r = offset + double(j) * rdelta;
r2 = r*r;
double r3 = r2 * r;
double r6 = r3 * r3;
double r7 = r6 * r;
// The following is for buffered 14-7 only.
/*
double rho = r/rv;
double term1 = pow(((dhal + 1.0) / (dhal + rho)),7);
double term2 = ((ghal + 1.0) / (ghal + pow(rho,7))) - 2.0;
e = epsilon * term1 * term2;
*/
double rho = r7 + ghal*rv7;
double tau = (dhal + 1.0) / (r + dhal * rv);
double tau7 = pow(tau, 7);
e = epsilon * rv7 * tau7 * ((ghal + 1.0) * rv7 / rho - 2.0);
double taper = 0.0;
if (r < off) {
double r4 = r2 * r2;
double r5 = r2 * r3;
taper = c5 * r5 + c4 * r4 + c3 * r3 + c2 * r2 + c1 * r + c0;
e = e * (1.0 - taper);
}
etot = etot + e * rdelta * r2;
}
elrc = elrc + termik * etot;
k++;
}
i++;
}
return elrc;
}
std::vector<std::string> AmoebaVdwForceImpl::getKernelNames() {
std::vector<std::string> names;
names.push_back(CalcAmoebaVdwForceKernel::Name());
return names;
}
#ifndef AMOEBA_CUDA_DATA_H_ #ifndef AMOEBA_CUDA_DATA_H_
#define AMOEBA_CUDA_DATA_H_ #define AMOEBA_CUDA_DATA_H_
/* -------------------------------------------------------------------------- * /* -------------------------------------------------------------------------- *
* OpenMMAmoeba * * OpenMMAmoeba *
* -------------------------------------------------------------------------- * * -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from * * This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of * * Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published * * it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or * * by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. * * GNU Lesser General Public License for more details. *
* * * *
* You should have received a copy of the GNU Lesser General Public License * * You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "CudaPlatform.h" #include "CudaPlatform.h"
#include "kernels/amoebaGpuTypes.h" #include "kernels/amoebaGpuTypes.h"
#include "kernels/cudaKernels.h" #include "kernels/cudaKernels.h"
#include "openmm/KernelImpl.h" #include "openmm/KernelImpl.h"
namespace OpenMM { namespace OpenMM {
/** /**
* This kernel is invoked by AmoebaHarmonicBondForce to calculate the forces acting on the system and the energy of the system. * This kernel is invoked by AmoebaHarmonicBondForce to calculate the forces acting on the system and the energy of the system.
*/ */
class AmoebaCudaData { class AmoebaCudaData {
public: public:
AmoebaCudaData( CudaPlatform::PlatformData& data ); AmoebaCudaData( CudaPlatform::PlatformData& data );
~AmoebaCudaData(); ~AmoebaCudaData();
/** /**
* Increment kernel count * Increment kernel count
* *
*/ */
void incrementKernelCount( void ); void incrementKernelCount( void );
/** /**
* Decrement kernel count * Decrement kernel count
* *
*/ */
void decrementKernelCount( void ); void decrementKernelCount( void );
/** /**
* Set value of hasAmoebaBonds * Set value of hasAmoebaBonds
* *
* @param value of hasAmoebaBonds * @param value of hasAmoebaBonds
*/ */
void setHasAmoebaBonds( bool inputHasAmoebaBonds ); void setHasAmoebaBonds( bool inputHasAmoebaBonds );
/** /**
* Set value of hasAmoebaMultipole * Set value of hasAmoebaMultipole
* *
* @param value of hasAmoebaMultipole * @param value of hasAmoebaMultipole
*/ */
void setHasAmoebaMultipole( bool inputHasAmoebaMultipole ); void setHasAmoebaMultipole( bool inputHasAmoebaMultipole );
/** /**
* Get value of hasAmoebaMultipole * Get value of hasAmoebaMultipole
* *
* @return value of hasAmoebaMultipole * @return value of hasAmoebaMultipole
*/ */
bool getHasAmoebaMultipole( void ) const; bool getHasAmoebaMultipole( void ) const;
/** /**
* Get use Grycuk flag * Get use Grycuk flag
* *
* @return value of useGrycuk * @return value of useGrycuk
*/ */
int getUseGrycuk( void ) const; int getUseGrycuk( void ) const;
/** /**
* Set value of hasAmoebaGeneralizedKirkwood * Set value of hasAmoebaGeneralizedKirkwood
* *
* @param value of hasAmoebaGeneralizedKirkwood * @param value of hasAmoebaGeneralizedKirkwood
*/ */
void setHasAmoebaGeneralizedKirkwood( bool inputHasAmoebaGeneralizedKirkwood ); void setHasAmoebaGeneralizedKirkwood( bool inputHasAmoebaGeneralizedKirkwood );
/** /**
* Get value of hasAmoebaGeneralizedKirkwood * Get value of hasAmoebaGeneralizedKirkwood
* *
* @return value of hasAmoebaGeneralizedKirkwood * @return value of hasAmoebaGeneralizedKirkwood
*/ */
bool getHasAmoebaGeneralizedKirkwood( void ) const; bool getHasAmoebaGeneralizedKirkwood( void ) const;
/** /**
* Return amoebaGpuContext context * Return amoebaGpuContext context
* *
* @return amoebaGpuContext * @return amoebaGpuContext
*/ */
amoebaGpuContext OPENMMCUDA_EXPORT getAmoebaGpu( void ) const; amoebaGpuContext OPENMMCUDA_EXPORT getAmoebaGpu( void ) const;
/** /**
* Set accessor for LocalForcesKernel * Set accessor for LocalForcesKernel
* *
* @param inputLocalForceKernel * @param inputLocalForceKernel
*/ */
void setAmoebaLocalForcesKernel( KernelImpl* inputLocalForceKernel ); void setAmoebaLocalForcesKernel( KernelImpl* inputLocalForceKernel );
/** /**
* Get accessor for LocalForcesKernel * Get accessor for LocalForcesKernel
* *
* @return localForceKernel * @return localForceKernel
*/ */
KernelImpl* getAmoebaLocalForcesKernel( void ) const; KernelImpl* getAmoebaLocalForcesKernel( void ) const;
/** /**
* Set log file reference * Set log file reference
* *
* @param log file reference; if not set, then no logging * @param log file reference; if not set, then no logging
*/ */
void setLog( FILE* inputLog ); void setLog( FILE* inputLog );
/** /**
* Get log file reference * Get log file reference
* *
* @return log file reference * @return log file reference
*/ */
FILE* getLog( void ) const; FILE* getLog( void ) const;
/** /**
* if gpuInitialized is false, write data to board * if gpuInitialized is false, write data to board
* *
* @param log file reference; if not set, then no logging * @param log file reference; if not set, then no logging
*/ */
void initializeGpu( void ); void initializeGpu( void );
/** /**
* Set contextImpl * Set contextImpl
* *
* @param contextImpl reference * @param contextImpl reference
*/ */
void setContextImpl( void* contextImpl ); void setContextImpl( void* contextImpl );
/** /**
* Get multipole force count * Get multipole force count
* *
* @return multipole force count * @return multipole force count
*/ */
int getMultipoleForceCount( void ) const; int getMultipoleForceCount( void ) const;
/** /**
* Get multipole force count * Get multipole force count
* *
* @return multipole force count * @return multipole force count
*/ */
void incrementMultipoleForceCount( void ); void incrementMultipoleForceCount( void );
/** /**
* Get multipole cutoff * Get multipole cutoff
* *
* @return multipole cutoff * @return multipole cutoff
*/ */
int getApplyMultipoleCutoff( ) const; int getApplyMultipoleCutoff( ) const;
/** /**
* Set multipole cutoff * Set multipole cutoff
* *
* @return multipole cutoff * @return multipole cutoff
*/ */
void setApplyMultipoleCutoff( int applyMultipoleCutoff ); void setApplyMultipoleCutoff( int applyMultipoleCutoff );
/** /**
* Get vdw cutoff * Get vdw cutoff
* *
* @return vdw cutoff * @return vdw cutoff
*/ */
int getUseVdwNeighborList( ) const; int getUseVdwNeighborList( ) const;
/** /**
* Set vdw cutoff * Set vdw cutoff
* *
* @return vdw cutoff * @return vdw cutoff
*/ */
void setUseVdwNeighborList( int useVdwNeighborList ); void setUseVdwNeighborList( int useVdwNeighborList );
/** /**
* Set flag indicating whether gpu is initialized * Set flag indicating whether gpu is initialized
* *
* @param flag indicating gpu is initialized * @param flag indicating gpu is initialized
*/ */
void setGpuInitialized( bool gpuInitialized ); void setGpuInitialized( bool gpuInitialized );
CudaPlatform::PlatformData& cudaPlatformData; CudaPlatform::PlatformData& cudaPlatformData;
private: double dispersionCoefficient;
amoebaGpuContext amoebaGpu; private:
bool hasAmoebaBonds, hasAmoebaGeneralizedKirkwood, hasAmoebaMultipole;
int multipoleForceCount; amoebaGpuContext amoebaGpu;
int applyMultipoleCutoff; bool hasAmoebaBonds, hasAmoebaGeneralizedKirkwood, hasAmoebaMultipole;
int useVdwNeighborList; int multipoleForceCount;
int useGrycuk; int applyMultipoleCutoff;
KernelImpl* localForceKernel; int useVdwNeighborList;
unsigned int kernelCount; int useGrycuk;
void* contextImpl; KernelImpl* localForceKernel;
FILE* log; unsigned int kernelCount;
bool gpuInitialized; void* contextImpl;
double boxDimensions[3]; FILE* log;
}; bool gpuInitialized;
double boxDimensions[3];
};
} // namespace OpenMM
#endif /*AMOEBA_CUDA_DATA_H_*/ } // namespace OpenMM
#endif /*AMOEBA_CUDA_DATA_H_*/
...@@ -618,6 +618,10 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextI ...@@ -618,6 +618,10 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextI
ReferenceCalcAmoebaVdwForceKernel::ReferenceCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, System& system) : ReferenceCalcAmoebaVdwForceKernel::ReferenceCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, System& system) :
CalcAmoebaVdwForceKernel(name, platform), system(system) { CalcAmoebaVdwForceKernel(name, platform), system(system) {
useNeighborList = 0;
usePBC = 0;
cutoff = 1.0e+10;
} }
ReferenceCalcAmoebaVdwForceKernel::~ReferenceCalcAmoebaVdwForceKernel() { ReferenceCalcAmoebaVdwForceKernel::~ReferenceCalcAmoebaVdwForceKernel() {
...@@ -656,14 +660,27 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A ...@@ -656,14 +660,27 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A
} }
sigmaCombiningRule = force.getSigmaCombiningRule(); sigmaCombiningRule = force.getSigmaCombiningRule();
epsilonCombiningRule = force.getEpsilonCombiningRule(); epsilonCombiningRule = force.getEpsilonCombiningRule();
useNeighborList = force.getUseNeighborList();
usePBC = force.getPBC();
cutoff = force.getCutoff();
} }
double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceVdwForce vdwForce( sigmaCombiningRule, epsilonCombiningRule, AmoebaReferenceVdwForce::NoCutoff ); AmoebaReferenceVdwForce vdwForce( sigmaCombiningRule, epsilonCombiningRule );
RealOpenMM energy = vdwForce.calculateForceAndEnergy( numParticles, posData, indexIVs, indexClasses, sigmas, epsilons, reductions, allExclusions, forceData); if( useNeighborList ){
vdwForce.setCutoff( cutoff );
if( usePBC ){
vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffPeriodic);
} else {
vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffNonPeriodic);
}
} else {
vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::NoCutoff );
}
RealOpenMM energy = vdwForce.calculateForceAndEnergy( numParticles, posData, indexIVs, indexClasses, sigmas, epsilons, reductions, allExclusions, forceData);
return static_cast<double>(energy); return static_cast<double>(energy);
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/amoebaKernels.h" #include "openmm/amoebaKernels.h"
#include "SimTKReference/ReferenceNeighborList.h"
#include "SimTKUtilities/SimTKOpenMMRealType.h" #include "SimTKUtilities/SimTKOpenMMRealType.h"
namespace OpenMM { namespace OpenMM {
...@@ -430,33 +431,6 @@ private: ...@@ -430,33 +431,6 @@ private:
System& system; System& system;
}; };
// /**
// * This kernel is invoked by AmoebaMultipoleForce to calculate the forces acting on the system and the energy of the system.
// */
// class ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel : public CalcAmoebaGeneralizedKirkwoodForceKernel {
// public:
// ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, System& system);
// ~ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel();
// /**
// * Initialize the kernel.
// *
// * @param system the System this kernel will be applied to
// * @param force the AmoebaMultipoleForce this kernel will be used for
// */
// void initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force);
// /**
// * Execute the kernel to calculate the forces and/or energy.
// *
// * @param context the context in which to execute this kernel
// * @param includeForces true if forces should be calculated
// * @param includeEnergy true if the energy should be calculated
// * @return the potential energy due to the force
// */
// double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
// private:
// System& system;
// };
/** /**
* This kernel is invoked to calculate the vdw forces acting on the system and the energy of the system. * This kernel is invoked to calculate the vdw forces acting on the system and the energy of the system.
*/ */
...@@ -482,6 +456,9 @@ public: ...@@ -482,6 +456,9 @@ public:
double execute(ContextImpl& context, bool includeForces, bool includeEnergy); double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
private: private:
int numParticles; int numParticles;
int useNeighborList;
int usePBC;
double cutoff;
std::vector<int> indexIVs; std::vector<int> indexIVs;
std::vector<int> indexClasses; std::vector<int> indexClasses;
std::vector< std::vector<int> > allExclusions; std::vector< std::vector<int> > allExclusions;
...@@ -491,6 +468,7 @@ private: ...@@ -491,6 +468,7 @@ private:
std::string sigmaCombiningRule; std::string sigmaCombiningRule;
std::string epsilonCombiningRule; std::string epsilonCombiningRule;
System& system; System& system;
NeighborList* neighborList;
}; };
/** /**
......
...@@ -32,12 +32,12 @@ using OpenMM::RealVec; ...@@ -32,12 +32,12 @@ using OpenMM::RealVec;
AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( ) : _nonbondedMethod(NoCutoff) { AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( ) : _nonbondedMethod(NoCutoff) {
_cutoff = 1.0e+10;
setSigmaCombiningRule( "ARITHMETIC" ); setSigmaCombiningRule( "ARITHMETIC" );
setEpsilonCombiningRule( "GEOMETRIC" ); setEpsilonCombiningRule( "GEOMETRIC" );
} }
AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, NonbondedMethod nonbondedMethod ) : AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule ) : _nonbondedMethod(NoCutoff) {
_nonbondedMethod(nonbondedMethod) {
setSigmaCombiningRule( sigmaCombiningRule ); setSigmaCombiningRule( sigmaCombiningRule );
setEpsilonCombiningRule( epsilonCombiningRule ); setEpsilonCombiningRule( epsilonCombiningRule );
...@@ -51,6 +51,14 @@ void AmoebaReferenceVdwForce::setNonbondedMethod( AmoebaReferenceVdwForce::Nonbo ...@@ -51,6 +51,14 @@ void AmoebaReferenceVdwForce::setNonbondedMethod( AmoebaReferenceVdwForce::Nonbo
_nonbondedMethod = nonbondedMethod; _nonbondedMethod = nonbondedMethod;
} }
void AmoebaReferenceVdwForce::setCutoff( double cutoff ){
_cutoff = cutoff;
}
double AmoebaReferenceVdwForce::getCutoff( void ) const {
return _cutoff;
}
void AmoebaReferenceVdwForce::setSigmaCombiningRule( const std::string& sigmaCombiningRule ){ void AmoebaReferenceVdwForce::setSigmaCombiningRule( const std::string& sigmaCombiningRule ){
_sigmaCombiningRule = sigmaCombiningRule; _sigmaCombiningRule = sigmaCombiningRule;
...@@ -116,7 +124,7 @@ RealOpenMM AmoebaReferenceVdwForce::arithmeticEpsilonCombiningRule( RealOpenMM e ...@@ -116,7 +124,7 @@ RealOpenMM AmoebaReferenceVdwForce::arithmeticEpsilonCombiningRule( RealOpenMM e
} }
RealOpenMM AmoebaReferenceVdwForce::geometricEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const { RealOpenMM AmoebaReferenceVdwForce::geometricEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const {
return 2.0*SQRT(epsilonI*epsilonJ); return SQRT(epsilonI*epsilonJ);
} }
RealOpenMM AmoebaReferenceVdwForce::harmonicEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const { RealOpenMM AmoebaReferenceVdwForce::harmonicEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const {
...@@ -199,7 +207,7 @@ RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combindedSigma, ...@@ -199,7 +207,7 @@ RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combindedSigma,
} }
RealOpenMM AmoebaReferenceVdwForce::calculateNoCutoffForceAndEnergy( int numParticles, RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergyNoCutoff( int numParticles,
const vector<RealVec>& particlePositions, const vector<RealVec>& particlePositions,
const std::vector<int>& indexIVs, const std::vector<int>& indexIVs,
const std::vector<int>& indexClasses, const std::vector<int>& indexClasses,
...@@ -211,7 +219,88 @@ RealOpenMM AmoebaReferenceVdwForce::calculateNoCutoffForceAndEnergy( int numPart ...@@ -211,7 +219,88 @@ RealOpenMM AmoebaReferenceVdwForce::calculateNoCutoffForceAndEnergy( int numPart
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceVdwForce::calculateNoCutoffForceAndEnergy"; static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
static const RealOpenMM two = 2.0;
// ---------------------------------------------------------------------------------------
// set reduced coordinates
std::vector<Vec3> reducedPositions;
reducedPositions.resize(numParticles);
for( unsigned int ii = 0; ii < static_cast<unsigned int>(numParticles); ii++ ){
if( reductions[ii] != zero ){
int reductionIndex = indexIVs[ii];
reducedPositions[ii] = Vec3( reductions[ii]*( particlePositions[ii][0] - particlePositions[reductionIndex][0] ) + particlePositions[reductionIndex][0],
reductions[ii]*( particlePositions[ii][1] - particlePositions[reductionIndex][1] ) + particlePositions[reductionIndex][1],
reductions[ii]*( particlePositions[ii][2] - particlePositions[reductionIndex][2] ) + particlePositions[reductionIndex][2] );
} else {
reducedPositions[ii] = Vec3( particlePositions[ii][0], particlePositions[ii][1], particlePositions[ii][2] );
}
}
// loop over all ixns
// (1) initialize exclusion vector
RealOpenMM energy = zero;
std::vector<unsigned int> exclusions(numParticles, 0);
for( unsigned int ii = 0; ii < static_cast<unsigned int>(numParticles); ii++ ){
RealOpenMM sigmaI = sigmas[ii];
RealOpenMM epsilonI = epsilons[ii];
for( unsigned int jj = 0; jj < allExclusions[ii].size(); jj++ ){
exclusions[allExclusions[ii][jj]] = 1;
}
for( unsigned int jj = ii+1; jj < static_cast<unsigned int>(numParticles); jj++ ){
if( exclusions[jj] == 0 ){
RealOpenMM combindedSigma = (this->*_combineSigmas)(sigmaI, sigmas[jj] );
RealOpenMM combindedEpsilon = (this->*_combineEpsilons)(epsilonI, epsilons[jj] );
Vec3 force;
energy += calculatePairIxn( combindedSigma, combindedEpsilon,
reducedPositions[ii], reducedPositions[jj],
force );
if( indexIVs[ii] == ii ){
forces[ii][0] -= force[0];
forces[ii][1] -= force[1];
forces[ii][2] -= force[2];
} else {
addReducedForce( ii, indexIVs[ii], reductions[ii], -one, force, forces );
}
if( indexIVs[jj] == jj ){
forces[jj][0] += force[0];
forces[jj][1] += force[1];
forces[jj][2] += force[2];
} else {
addReducedForce( jj, indexIVs[jj], reductions[jj], one, force, forces );
}
}
}
for( unsigned int jj = 0; jj < allExclusions[ii].size(); jj++ ){
exclusions[allExclusions[ii][jj]] = 0;
}
}
return energy;
}
RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergyApplyCutoff( int numParticles,
const vector<RealVec>& particlePositions,
const std::vector<int>& indexIVs,
const std::vector<int>& indexClasses,
const std::vector<RealOpenMM>& sigmas,
const std::vector<RealOpenMM>& epsilons,
const std::vector<RealOpenMM>& reductions,
const std::vector< std::vector<int> >& allExclusions,
vector<RealVec>& forces ) const {
// ---------------------------------------------------------------------------------------
static const RealOpenMM zero = 0.0; static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0; static const RealOpenMM one = 1.0;
...@@ -295,11 +384,24 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, ...@@ -295,11 +384,24 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles,
vector<RealVec>& forces ) const { vector<RealVec>& forces ) const {
if( getNonbondedMethod() == NoCutoff || 1 ){ if( getNonbondedMethod() == NoCutoff ){
return calculateNoCutoffForceAndEnergy( numParticles, particlePositions, return calculateForceAndEnergyNoCutoff( numParticles, particlePositions,
indexIVs, indexClasses, sigmas, epsilons, indexIVs, indexClasses, sigmas, epsilons,
reductions, allExclusions, forces ); reductions, allExclusions, forces );
} else {
return calculateForceAndEnergyApplyCutoff( numParticles, particlePositions,
indexIVs, indexClasses, sigmas, epsilons,
reductions, allExclusions, forces );
} }
} }
/*
double cutoff = force.getCutoff();
double taperCutoff = cutoff*0.9;
replacements["CUTOFF_DISTANCE"] = cu.doubleToString(force.getCutoff());
replacements["TAPER_CUTOFF"] = cu.doubleToString(taperCutoff);
replacements["TAPER_C3"] = cu.doubleToString(10/pow(taperCutoff-cutoff, 3.0));
replacements["TAPER_C4"] = cu.doubleToString(15/pow(taperCutoff-cutoff, 4.0));
replacements["TAPER_C5"] = cu.doubleToString(6/pow(taperCutoff-cutoff, 5.0));
*/
...@@ -79,8 +79,7 @@ public: ...@@ -79,8 +79,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceVdwForce( const std::string& sigmaCombiningRule, AmoebaReferenceVdwForce( const std::string& sigmaCombiningRule,
const std::string& epsilonCombiningRule, const std::string& epsilonCombiningRule );
NonbondedMethod nonbondedMethod );
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -110,6 +109,26 @@ public: ...@@ -110,6 +109,26 @@ public:
void setNonbondedMethod( NonbondedMethod nonbondedMethod ); void setNonbondedMethod( NonbondedMethod nonbondedMethod );
/**---------------------------------------------------------------------------------------
Get cutoff
@return cutoff
--------------------------------------------------------------------------------------- */
double getCutoff( void ) const;
/**---------------------------------------------------------------------------------------
Set cutof
@param cutoff
--------------------------------------------------------------------------------------- */
void setCutoff( double cutoff );
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Set sigma combining rule Set sigma combining rule
...@@ -181,6 +200,7 @@ private: ...@@ -181,6 +200,7 @@ private:
std::string _sigmaCombiningRule; std::string _sigmaCombiningRule;
std::string _epsilonCombiningRule; std::string _epsilonCombiningRule;
NonbondedMethod _nonbondedMethod; NonbondedMethod _nonbondedMethod;
double _cutoff;
CombiningFunction _combineSigmas; CombiningFunction _combineSigmas;
RealOpenMM arithmeticSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const; RealOpenMM arithmeticSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const;
...@@ -246,7 +266,7 @@ private: ...@@ -246,7 +266,7 @@ private:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM calculateNoCutoffForceAndEnergy( int numParticles, const std::vector<OpenMM::RealVec>& particlePositions, RealOpenMM calculateForceAndEnergyNoCutoff( int numParticles, const std::vector<OpenMM::RealVec>& particlePositions,
const std::vector<int>& indexIVs, const std::vector<int>& indexIVs,
const std::vector<int>& indexClasses, const std::vector<int>& indexClasses,
const std::vector<RealOpenMM>& sigmas, const std::vector<RealOpenMM>& epsilons, const std::vector<RealOpenMM>& sigmas, const std::vector<RealOpenMM>& epsilons,
...@@ -254,6 +274,32 @@ private: ...@@ -254,6 +274,32 @@ private:
const std::vector< std::vector<int> >& vdwExclusions, const std::vector< std::vector<int> >& vdwExclusions,
std::vector<OpenMM::RealVec>& forces ) const; std::vector<OpenMM::RealVec>& forces ) const;
/**---------------------------------------------------------------------------------------
Calculate Vdw ixns w/ cutoff
@param numParticles number of particles
@param particlePositions Cartesian coordinates of particles
@param indexIVs position index for associated reducing particle
@param indexClasses class index for combining sigmas/epsilons (not currently used)
@param sigmas particle sigmas
@param epsilons particle epsilons
@param reductions particle reduction factors
@param vdwExclusions particle exclusions
@param forces add forces to this vector
@return energy
--------------------------------------------------------------------------------------- */
RealOpenMM calculateForceAndEnergyApplyCutoff( int numParticles, const std::vector<OpenMM::RealVec>& particlePositions,
const std::vector<int>& indexIVs,
const std::vector<int>& indexClasses,
const std::vector<RealOpenMM>& sigmas, const std::vector<RealOpenMM>& epsilons,
const std::vector<RealOpenMM>& reductions,
const std::vector< std::vector<int> >& vdwExclusions,
std::vector<OpenMM::RealVec>& forces ) const;
}; };
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
......
...@@ -2793,6 +2793,11 @@ class AmoebaVdwGenerator: ...@@ -2793,6 +2793,11 @@ class AmoebaVdwGenerator:
else: else:
force.setCutoff(nonbondedCutoff) force.setCutoff(nonbondedCutoff)
# dispersion correction
if ('useDispersionCorrection' in args):
force.setUseDispersionCorrection(int(args['useDispersionCorrection']))
if (nonbondedMethod == PME): if (nonbondedMethod == PME):
force.setPBC(1) force.setPBC(1)
force.setUseNeighborList(1) force.setUseNeighborList(1)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment