Commit 1db349e5 authored by Peter Eastman's avatar Peter Eastman
Browse files

Major cleanup of the AMOEBA API

parent a919f305
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* 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: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* 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 *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/Force.h"
#include "openmm/OpenMMException.h"
#include "openmm/AmoebaTorsionForce.h"
#include "openmm/internal/AmoebaTorsionForceImpl.h"
using namespace OpenMM;
AmoebaTorsionForce::AmoebaTorsionForce() {
}
int AmoebaTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4,
const std::vector<double>& torsion1, const std::vector<double>& torsion2, const std::vector<double>& torsion3 ) {
torsions.push_back(TorsionInfo(particle1, particle2, particle3, particle4, torsion1, torsion2, torsion3));
return torsions.size()-1;
}
void AmoebaTorsionForce::getTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4,
std::vector<double>& torsion1, std::vector<double>& torsion2, std::vector<double>& torsion3 ) const {
particle1 = torsions[index].particle1;
particle2 = torsions[index].particle2;
particle3 = torsions[index].particle3;
particle4 = torsions[index].particle4;
torsion1.resize( AmoebaTorsionForce::ParametersPerTorsion );
torsion2.resize( AmoebaTorsionForce::ParametersPerTorsion );
torsion3.resize( AmoebaTorsionForce::ParametersPerTorsion );
for( unsigned int ii = 0; ii < AmoebaTorsionForce::ParametersPerTorsion; ii++ ){
torsion1[ii] = torsions[index].torsionParameters[0][ii];
torsion2[ii] = torsions[index].torsionParameters[1][ii];
torsion3[ii] = torsions[index].torsionParameters[2][ii];
}
}
void AmoebaTorsionForce::setTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4,
const std::vector<double>& torsion1, const std::vector<double>& torsion2, const std::vector<double>& torsion3 ) {
torsions[index].particle1 = particle1;
torsions[index].particle2 = particle2;
torsions[index].particle3 = particle3;
torsions[index].particle4 = particle4;
torsions[index].copyTorsionParameter( 0, torsion1 );
torsions[index].copyTorsionParameter( 1, torsion2 );
torsions[index].copyTorsionParameter( 2, torsion3 );
}
ForceImpl* AmoebaTorsionForce::createImpl() {
return new AmoebaTorsionForceImpl(*this);
}
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* 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: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* 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 *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/AmoebaTorsionForceImpl.h"
#include "openmm/amoebaKernels.h"
using namespace OpenMM;
using std::pair;
using std::vector;
using std::set;
AmoebaTorsionForceImpl::AmoebaTorsionForceImpl(AmoebaTorsionForce& owner) : owner(owner) {
}
AmoebaTorsionForceImpl::~AmoebaTorsionForceImpl() {
}
void AmoebaTorsionForceImpl::initialize(ContextImpl& context) {
kernel = context.getPlatform().createKernel(CalcAmoebaTorsionForceKernel::Name(), context);
kernel.getAs<CalcAmoebaTorsionForceKernel>().initialize(context.getSystem(), owner);
}
double AmoebaTorsionForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
if ((groups&(1<<owner.getForceGroup())) != 0)
return kernel.getAs<CalcAmoebaTorsionForceKernel>().execute(context, includeForces, includeEnergy);
return 0.0;
}
std::vector<std::string> AmoebaTorsionForceImpl::getKernelNames() {
std::vector<std::string> names;
names.push_back(CalcAmoebaTorsionForceKernel::Name());
return names;
}
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* 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: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* 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 *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/Force.h"
#include "openmm/OpenMMException.h"
#include "openmm/AmoebaUreyBradleyForce.h"
#include "openmm/internal/AmoebaUreyBradleyForceImpl.h"
using namespace OpenMM;
AmoebaUreyBradleyForce::AmoebaUreyBradleyForce() {
_globalCubicK = _globalQuarticK = 0.0;
}
int AmoebaUreyBradleyForce::addUreyBradley(int particle1, int particle2, double length, double quadraticK) {
bonds.push_back(UreyBradleyInfo(particle1, particle2, length, quadraticK ));
return bonds.size()-1;
}
void AmoebaUreyBradleyForce::getUreyBradleyParameters(int index, int& particle1, int& particle2, double& length, double& quadraticK ) const {
particle1 = bonds[index].particle1;
particle2 = bonds[index].particle2;
length = bonds[index].length;
quadraticK = bonds[index].quadraticK;
}
void AmoebaUreyBradleyForce::setUreyBradleyParameters(int index, int particle1, int particle2, double length, double quadraticK ) {
bonds[index].particle1 = particle1;
bonds[index].particle2 = particle2;
bonds[index].length = length;
bonds[index].quadraticK = quadraticK;
}
void AmoebaUreyBradleyForce::setAmoebaGlobalUreyBradleyCubic(double cubicK ) {
_globalCubicK = cubicK;
}
void AmoebaUreyBradleyForce::setAmoebaGlobalUreyBradleyQuartic(double quarticK ) {
_globalQuarticK = quarticK;
}
double AmoebaUreyBradleyForce::getAmoebaGlobalUreyBradleyCubic( void ) const {
return _globalCubicK;
}
double AmoebaUreyBradleyForce::getAmoebaGlobalUreyBradleyQuartic( void ) const {
return _globalQuarticK;
}
ForceImpl* AmoebaUreyBradleyForce::createImpl() {
return new AmoebaUreyBradleyForceImpl(*this);
}
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* 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: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* 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 *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/AmoebaUreyBradleyForceImpl.h"
#include "openmm/amoebaKernels.h"
#include "openmm/Platform.h"
using namespace OpenMM;
using std::pair;
using std::vector;
using std::set;
AmoebaUreyBradleyForceImpl::AmoebaUreyBradleyForceImpl(AmoebaUreyBradleyForce& owner) : owner(owner) {
}
AmoebaUreyBradleyForceImpl::~AmoebaUreyBradleyForceImpl() {
}
void AmoebaUreyBradleyForceImpl::initialize(ContextImpl& context) {
kernel = context.getPlatform().createKernel(CalcAmoebaUreyBradleyForceKernel::Name(), context);
kernel.getAs<CalcAmoebaUreyBradleyForceKernel>().initialize(context.getSystem(), owner);
}
double AmoebaUreyBradleyForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
if ((groups&(1<<owner.getForceGroup())) != 0)
return kernel.getAs<CalcAmoebaUreyBradleyForceKernel>().execute(context, includeForces, includeEnergy);
return 0.0;
}
std::vector<std::string> AmoebaUreyBradleyForceImpl::getKernelNames() {
std::vector<std::string> names;
names.push_back(CalcAmoebaUreyBradleyForceKernel::Name());
return names;
}
......@@ -38,27 +38,25 @@ using namespace OpenMM;
using std::string;
using std::vector;
AmoebaVdwForce::AmoebaVdwForce() : sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), usePBC(0), cutoff(1.0e+10), useNeighborList(0), useDispersionCorrection(true) {
AmoebaVdwForce::AmoebaVdwForce() : nonbondedMethod(NoCutoff), sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), cutoff(1.0e+10), useDispersionCorrection(true) {
}
int AmoebaVdwForce::addParticle(int ivIndex, int classIndex, double sigma, double epsilon, double reductionFactor ) {
parameters.push_back(VdwInfo(ivIndex, classIndex, sigma, epsilon, reductionFactor));
int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor ) {
parameters.push_back(VdwInfo(parentIndex, sigma, epsilon, reductionFactor));
return parameters.size()-1;
}
void AmoebaVdwForce::getParticleParameters(int particleIndex, int& ivIndex, int& classIndex,
void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex,
double& sigma, double& epsilon, double& reductionFactor ) const {
ivIndex = parameters[particleIndex].ivIndex;
classIndex = parameters[particleIndex].classIndex;
parentIndex = parameters[particleIndex].parentIndex;
sigma = parameters[particleIndex].sigma;
epsilon = parameters[particleIndex].epsilon;
reductionFactor = parameters[particleIndex].reductionFactor;
}
void AmoebaVdwForce::setParticleParameters(int particleIndex, int ivIndex, int classIndex,
void AmoebaVdwForce::setParticleParameters(int particleIndex, int parentIndex,
double sigma, double epsilon, double reductionFactor ) {
parameters[particleIndex].ivIndex = ivIndex;
parameters[particleIndex].classIndex = classIndex;
parameters[particleIndex].parentIndex = parentIndex;
parameters[particleIndex].sigma = sigma;
parameters[particleIndex].epsilon = epsilon;
parameters[particleIndex].reductionFactor = reductionFactor;
......@@ -112,20 +110,12 @@ double AmoebaVdwForce::getCutoff( void ) const {
return cutoff;
}
void AmoebaVdwForce::setUseNeighborList( int useNeighborListFlag ){
useNeighborList = useNeighborListFlag;
AmoebaVdwForce::NonbondedMethod AmoebaVdwForce::getNonbondedMethod() const {
return nonbondedMethod;
}
int AmoebaVdwForce::getUseNeighborList( void ) const {
return useNeighborList;
}
void AmoebaVdwForce::setPBC( int pbcFlag ){
usePBC = pbcFlag;
}
int AmoebaVdwForce::getPBC( void ) const {
return usePBC;
void AmoebaVdwForce::setNonbondedMethod(NonbondedMethod method) {
nonbondedMethod = method;
}
ForceImpl* AmoebaVdwForce::createImpl() {
......
......@@ -29,9 +29,9 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#ifdef WIN32
#define _USE_MATH_DEFINES // Needed to get M_PI
#endif
#ifdef WIN32
#define _USE_MATH_DEFINES // Needed to get M_PI
#endif
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/AmoebaVdwForceImpl.h"
#include "openmm/amoebaKernels.h"
......@@ -59,7 +59,7 @@ void AmoebaVdwForceImpl::initialize(ContextImpl& context) {
// check that cutoff < 0.5*boxSize
if (owner.getPBC()) {
if (owner.getNonbondedMethod() == AmoebaVdwForce::CutoffPeriodic) {
Vec3 boxVectors[3];
system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
double cutoff = owner.getCutoff();
......@@ -81,7 +81,7 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
// 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)
if (force.getNonbondedMethod() == AmoebaVdwForce::NoCutoff)
return 0.0;
// Identify all particle classes (defined by sigma and epsilon and reduction), and count the number of
......@@ -90,10 +90,10 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
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;
// The variables reduction, ivindex are not used.
int ivindex;
// Get the sigma and epsilon parameters, ignoring everything else.
force.getParticleParameters(i, ivindex, classindex, sigma, epsilon, reduction);
force.getParticleParameters(i, ivindex, 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())
......
......@@ -44,10 +44,8 @@ extern "C" OPENMMCUDA_EXPORT void registerKernelFactories() {
AmoebaCudaKernelFactory* factory = new AmoebaCudaKernelFactory();
platform.registerKernelFactory(CalcAmoebaHarmonicBondForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaUreyBradleyForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaHarmonicAngleForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaHarmonicInPlaneAngleForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaTorsionForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaPiTorsionForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaStretchBendForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaOutOfPlaneBendForceKernel::Name(), factory);
......@@ -124,9 +122,6 @@ KernelImpl* AmoebaCudaKernelFactory::createKernelImpl(std::string name, const Pl
if (name == CalcAmoebaHarmonicInPlaneAngleForceKernel::Name())
return new CudaCalcAmoebaHarmonicInPlaneAngleForceKernel(name, platform, *amoebaCudaData, context.getSystem());
if (name == CalcAmoebaTorsionForceKernel::Name())
return new CudaCalcAmoebaTorsionForceKernel(name, platform, *amoebaCudaData, context.getSystem());
if (name == CalcAmoebaPiTorsionForceKernel::Name())
return new CudaCalcAmoebaPiTorsionForceKernel(name, platform, *amoebaCudaData, context.getSystem());
......@@ -151,8 +146,5 @@ KernelImpl* AmoebaCudaKernelFactory::createKernelImpl(std::string name, const Pl
if (name == CalcAmoebaWcaDispersionForceKernel::Name())
return new CudaCalcAmoebaWcaDispersionForceKernel(name, platform, *amoebaCudaData, context.getSystem());
if (name == CalcAmoebaUreyBradleyForceKernel::Name())
return new CudaCalcAmoebaUreyBradleyForceKernel(name, platform, *amoebaCudaData, context.getSystem());
throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str());
}
......@@ -136,79 +136,6 @@ double CudaCalcAmoebaHarmonicBondForceKernel::execute(ContextImpl& context, bool
return 0.0;
}
/* -------------------------------------------------------------------------- *
* AmoebaUreyBradley *
* -------------------------------------------------------------------------- */
class CudaCalcAmoebaUreyBradleyForceKernel::ForceInfo : public CudaForceInfo {
public:
ForceInfo(const AmoebaUreyBradleyForce& force) : force(force) {
}
int getNumParticleGroups() {
return force.getNumInteractions();
}
void getParticlesInGroup(int index, std::vector<int>& particles) {
int particle1, particle2;
double length, k;
force.getUreyBradleyParameters(index, particle1, particle2, length, k);
particles.resize(2);
particles[0] = particle1;
particles[1] = particle2;
}
bool areGroupsIdentical(int group1, int group2) {
int particle1, particle2;
double length1, length2, k1, k2;
force.getUreyBradleyParameters(group1, particle1, particle2, length1, k1);
force.getUreyBradleyParameters(group2, particle1, particle2, length2, k2);
return (length1 == length2 && k1 == k2);
}
private:
const AmoebaUreyBradleyForce& force;
};
CudaCalcAmoebaUreyBradleyForceKernel::CudaCalcAmoebaUreyBradleyForceKernel(std::string name, const Platform& platform, AmoebaCudaData& data, System& system) :
CalcAmoebaUreyBradleyForceKernel(name, platform), data(data), system(system) {
data.incrementKernelCount();
}
CudaCalcAmoebaUreyBradleyForceKernel::~CudaCalcAmoebaUreyBradleyForceKernel() {
data.decrementKernelCount();
}
void CudaCalcAmoebaUreyBradleyForceKernel::initialize(const System& system, const AmoebaUreyBradleyForce& force) {
data.setAmoebaLocalForcesKernel( this );
numInteractions = force.getNumInteractions();
std::vector<int> particle1(numInteractions);
std::vector<int> particle2(numInteractions);
std::vector<float> length(numInteractions);
std::vector<float> quadratic(numInteractions);
for (int i = 0; i < numInteractions; i++) {
int particle1Index, particle2Index;
double lengthValue, kValue;
force.getUreyBradleyParameters(i, particle1Index, particle2Index, lengthValue, kValue );
particle1[i] = particle1Index;
particle2[i] = particle2Index;
length[i] = static_cast<float>( lengthValue );
quadratic[i] = static_cast<float>( kValue );
}
gpuSetAmoebaUreyBradleyParameters( data.getAmoebaGpu(), particle1, particle2, length, quadratic,
static_cast<float>(force.getAmoebaGlobalUreyBradleyCubic()),
static_cast<float>(force.getAmoebaGlobalUreyBradleyQuartic()) );
data.getAmoebaGpu()->gpuContext->forces.push_back(new ForceInfo(force));
}
double CudaCalcAmoebaUreyBradleyForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
if( data.getAmoebaLocalForcesKernel() == this ){
computeAmoebaLocalForces( data );
}
return 0.0;
}
/* -------------------------------------------------------------------------- *
* AmoebaHarmonicAngle *
* -------------------------------------------------------------------------- */
......@@ -357,101 +284,6 @@ double CudaCalcAmoebaHarmonicInPlaneAngleForceKernel::execute(ContextImpl& conte
return 0.0;
}
/* -------------------------------------------------------------------------- *
* AmoebaHarmonicTorsion *
* -------------------------------------------------------------------------- */
class CudaCalcAmoebaTorsionForceKernel::ForceInfo : public CudaForceInfo {
public:
ForceInfo(const AmoebaTorsionForce& force) : force(force) {
}
int getNumParticleGroups() {
return force.getNumTorsions();
}
void getParticlesInGroup(int index, std::vector<int>& particles) {
int particle1, particle2, particle3, particle4;
vector<double> torsion1, torsion2, torsion3;
force.getTorsionParameters(index, particle1, particle2, particle3, particle4, torsion1, torsion2, torsion3);
particles.resize(4);
particles[0] = particle1;
particles[1] = particle2;
particles[2] = particle3;
particles[3] = particle4;
}
bool areGroupsIdentical(int group1, int group2) {
int particle1, particle2, particle3, particle4;
vector<double> torsion11, torsion21, torsion31;
vector<double> torsion12, torsion22, torsion32;
force.getTorsionParameters(group1, particle1, particle2, particle3, particle4, torsion11, torsion21, torsion31);
force.getTorsionParameters(group2, particle1, particle2, particle3, particle4, torsion12, torsion22, torsion32);
for (int i = 0; i < (int) torsion11.size(); ++i)
if (torsion11[i] != torsion12[i])
return false;
for (int i = 0; i < (int) torsion21.size(); ++i)
if (torsion21[i] != torsion22[i])
return false;
for (int i = 0; i < (int) torsion31.size(); ++i)
if (torsion31[i] != torsion32[i])
return false;
return true;
}
private:
const AmoebaTorsionForce& force;
};
CudaCalcAmoebaTorsionForceKernel::CudaCalcAmoebaTorsionForceKernel(std::string name, const Platform& platform, AmoebaCudaData& data, System& system) :
CalcAmoebaTorsionForceKernel(name, platform), data(data), system(system) {
data.incrementKernelCount();
}
CudaCalcAmoebaTorsionForceKernel::~CudaCalcAmoebaTorsionForceKernel() {
data.decrementKernelCount();
}
void CudaCalcAmoebaTorsionForceKernel::initialize(const System& system, const AmoebaTorsionForce& force) {
data.setAmoebaLocalForcesKernel( this );
numTorsions = force.getNumTorsions();
std::vector<int> particle1(numTorsions);
std::vector<int> particle2(numTorsions);
std::vector<int> particle3(numTorsions);
std::vector<int> particle4(numTorsions);
std::vector< std::vector<float> > torsionParameters1(numTorsions);
std::vector< std::vector<float> > torsionParameters2(numTorsions);
std::vector< std::vector<float> > torsionParameters3(numTorsions);
for (int i = 0; i < numTorsions; i++) {
std::vector<double> torsionParameter1;
std::vector<double> torsionParameter2;
std::vector<double> torsionParameter3;
std::vector<float> torsionParameters1F(3);
std::vector<float> torsionParameters2F(3);
std::vector<float> torsionParameters3F(3);
force.getTorsionParameters(i, particle1[i], particle2[i], particle3[i], particle4[i], torsionParameter1, torsionParameter2, torsionParameter3 );
for ( unsigned int jj = 0; jj < torsionParameter1.size(); jj++) {
torsionParameters1F[jj] = static_cast<float>(torsionParameter1[jj]);
torsionParameters2F[jj] = static_cast<float>(torsionParameter2[jj]);
torsionParameters3F[jj] = static_cast<float>(torsionParameter3[jj]);
}
torsionParameters1[i] = torsionParameters1F;
torsionParameters2[i] = torsionParameters2F;
torsionParameters3[i] = torsionParameters3F;
}
gpuSetAmoebaTorsionParameters(data.getAmoebaGpu(), particle1, particle2, particle3, particle4, torsionParameters1, torsionParameters2, torsionParameters3 );
data.getAmoebaGpu()->gpuContext->forces.push_back(new ForceInfo(force));
}
double CudaCalcAmoebaTorsionForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
if( data.getAmoebaLocalForcesKernel() == this ){
computeAmoebaLocalForces( data );
}
return 0.0;
}
/* -------------------------------------------------------------------------- *
* AmoebaHarmonicPiTorsion *
* -------------------------------------------------------------------------- */
......@@ -1086,8 +918,7 @@ void CudaCalcAmoebaMultipoleForceKernel::getElectrostaticPotential(ContextImpl&
return;
}
void CudaCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, const Vec3& origin,
std::vector< double >& outputMultipoleMonents) {
void CudaCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMonents) {
computeAmoebaSystemMultipoleMoments( data, outputMultipoleMonents);
return;
}
......@@ -1183,10 +1014,9 @@ public:
}
bool areParticlesIdentical(int particle1, int particle2) {
int iv1, iv2;
int classIndex1, classIndex2;
double sigma1, sigma2, epsilon1, epsilon2, reduction1, reduction2;
force.getParticleParameters(particle1, iv1, classIndex1, sigma1, epsilon1, reduction1);
force.getParticleParameters(particle2, iv2, classIndex2, sigma2, epsilon2, reduction2);
force.getParticleParameters(particle1, iv1, sigma1, epsilon1, reduction1);
force.getParticleParameters(particle2, iv2, sigma2, epsilon2, reduction2);
return (sigma1 == sigma2 && epsilon1 == epsilon2 && reduction1 == reduction2);
}
private:
......@@ -1216,11 +1046,10 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
for( int ii = 0; ii < numParticles; ii++ ){
int indexIV;
int classIndex;
double sigma, epsilon, reduction;
std::vector<int> exclusions;
force.getParticleParameters( ii, indexIV, classIndex, sigma, epsilon, reduction );
force.getParticleParameters( ii, indexIV, sigma, epsilon, reduction );
force.getParticleExclusions( ii, exclusions );
for( unsigned int jj = 0; jj < exclusions.size(); jj++ ){
allExclusions[ii].push_back( exclusions[jj] );
......@@ -1232,15 +1061,16 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
reductions[ii] = static_cast<float>( reduction );
}
bool useCutoff = (force.getNonbondedMethod() == AmoebaVdwForce::CutoffPeriodic);
gpuSetAmoebaVdwParameters( data.getAmoebaGpu(), indexIVs, sigmas, epsilons, reductions,
force.getSigmaCombiningRule(), force.getEpsilonCombiningRule(),
allExclusions, force.getPBC(), static_cast<float>(force.getCutoff()) );
allExclusions, useCutoff, static_cast<float>(force.getCutoff()) );
data.getAmoebaGpu()->gpuContext->forces.push_back(new ForceInfo(force));
if( data.getLog() ){
(void) fprintf( data.getLog(), "CudaCalcAmoebaVdwForceKernel PBC=%d getUseNeighborList=%d\n",
force.getPBC(), force.getUseNeighborList() );
(void) fprintf( data.getLog(), "CudaCalcAmoebaVdwForceKernel useCutoff=%d\n",
useCutoff );
}
data.setUseVdwNeighborList( force.getUseNeighborList() );
data.setUseVdwNeighborList(force.getNonbondedMethod() != AmoebaVdwForce::NoCutoff);
if (force.getUseDispersionCorrection())
data.dispersionCoefficient = AmoebaVdwForceImpl::calcDispersionCorrection(system, force);
else
......
......@@ -68,39 +68,6 @@ private:
System& system;
};
/**
* This kernel is invoked by AmoebaUreyBradleyForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaUreyBradleyForceKernel : public CalcAmoebaUreyBradleyForceKernel {
public:
CudaCalcAmoebaUreyBradleyForceKernel(std::string name,
const Platform& platform,
AmoebaCudaData& data,
System& system);
~CudaCalcAmoebaUreyBradleyForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaUreyBradleyForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaUreyBradleyForce& 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:
class ForceInfo;
int numInteractions;
AmoebaCudaData& data;
System& system;
};
/**
* This kernel is invoked by AmoebaHarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
*/
......@@ -161,36 +128,6 @@ private:
System& system;
};
/**
* This kernel is invoked by AmoebaTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaTorsionForceKernel : public CalcAmoebaTorsionForceKernel {
public:
CudaCalcAmoebaTorsionForceKernel(std::string name, const Platform& platform, AmoebaCudaData& data, System& system);
~CudaCalcAmoebaTorsionForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaTorsionForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaTorsionForce& 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:
class ForceInfo;
int numTorsions;
AmoebaCudaData& data;
System& system;
};
/**
* This kernel is invoked by AmoebaPiTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
......@@ -348,7 +285,6 @@ public:
/**
* Get the system multipole moments
*
* @param origin origin
* @param context context
* @param outputMultipoleMonents (charge,
dipole_x, dipole_y, dipole_z,
......@@ -357,7 +293,7 @@ public:
quadrupole_zx, quadrupole_zy, quadrupole_zz )
*/
void getSystemMultipoleMoments( ContextImpl& context, const Vec3& origin, std::vector< double >& outputMultipoleMonents );
void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMonents );
private:
......
......@@ -189,11 +189,11 @@ void kClearFields_1( amoebaGpuContext amoebaGpu )
{
gpuContext gpu = amoebaGpu->gpuContext;
kClearFields_kernel<<<gpu->sim.nonbond_blocks, 384>>>( gpu->sim.paddedNumberOfAtoms*gpu->sim.outputBuffers,
kClearFields_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.threads_per_block>>>( gpu->sim.paddedNumberOfAtoms*gpu->sim.outputBuffers,
amoebaGpu->psWorkArray_1_1->_pDevData );
LAUNCHERROR("kClearFields_1_1");
kClearFields_kernel<<<gpu->sim.nonbond_blocks, 384>>>( gpu->sim.paddedNumberOfAtoms*gpu->sim.outputBuffers,
kClearFields_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.threads_per_block>>>( gpu->sim.paddedNumberOfAtoms*gpu->sim.outputBuffers,
amoebaGpu->psWorkArray_1_2->_pDevData );
LAUNCHERROR("kClearFields_1_2");
}
......
......@@ -2834,7 +2834,7 @@ static int readAmoebaVdwParameters( FILE* filePtr, int version, MapStringInt& fo
methodName.c_str(), arraySize, (useOpenMMUnits ? "OpenMM" : "Amoeba"),
vdwForce->getSigmaCombiningRule().c_str(), vdwForce->getEpsilonCombiningRule().c_str() );
(void) fprintf( log, "use periodic boundary conditions=%d cutoff=%15.7e\n", vdwForce->getPBC(), vdwForce->getCutoff() );
(void) fprintf( log, "use periodic boundary conditions=%d cutoff=%15.7e\n", vdwForce->getNonbondedMethod(), vdwForce->getCutoff() );
for( int ii = 0; ii < vdwForce->getNumParticles(); ii++ ){
int indexIV, indexClass;
......
......@@ -55,7 +55,7 @@ const double TOL = 1e-4;
 
// setup for 2 ammonia molecules
 
static void setupAndGetForcesEnergyMultipoleAmmonia( AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
static void setupAndGetForcesEnergyMultipoleAmmonia( AmoebaMultipoleForce::PolarizationType polarizationType,
int includeCavityTerm, std::vector<Vec3>& forces, double& energy, FILE* log ){
 
// beginning of Multipole setup
......@@ -316,7 +316,7 @@ static void setupAndGetForcesEnergyMultipoleAmmonia( AmoebaMultipoleForce::Amoeb
 
// setup for villin
 
static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::PolarizationType polarizationType,
int includeCavityTerm, std::vector<Vec3>& forces, double& energy, FILE* log ){
 
// beginning of Multipole setup
......
......@@ -55,8 +55,8 @@ const double TOL = 1e-4;
// setup for 2 ammonia molecules
static void setupAndGetForcesEnergyMultipoleAmmonia( AmoebaMultipoleForce::AmoebaNonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
static void setupAndGetForcesEnergyMultipoleAmmonia( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::PolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::vector<Vec3>& forces, double& energy, FILE* log ){
// beginning of Multipole setup
......@@ -498,8 +498,8 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) {
// setup for box of 4 water molecules -- used to test PME
static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::AmoebaNonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::PolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::vector<Vec3>& forces,
double& energy, FILE* log ){
......@@ -938,8 +938,8 @@ static void testQuadrupoleValidation( FILE* log ){
// this method does too much; I tried passing the context ptr back to
// the tests methods, but the tests would seg fault w/ a bad_alloc error
static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::AmoebaNonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::PolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::string testName,
std::vector<Vec3>& forces, double& energy, FILE* log ){
......@@ -1204,8 +1204,8 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization( FILE* log ) {
// setup for box of 216 water molecules -- used to test PME
static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::AmoebaNonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::PolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::string& testName,
std::vector<Vec3>& forces, double& energy,
std::vector< double >& outputMultipoleMoments,
......@@ -1993,8 +1993,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::Am
context.setPositions(positions);
if( testName == "testSystemMultipoleMoments" ){
Vec3 origin( 0.0, 0.0, 0.0 );
amoebaMultipoleForce->getSystemMultipoleMoments( origin, context, outputMultipoleMoments );
amoebaMultipoleForce->getSystemMultipoleMoments(context, outputMultipoleMoments );
} else if( testName == "testMultipoleGridPotential" ){
amoebaMultipoleForce->getElectrostaticPotential( inputGrid, context, outputGridPotential );
} else {
......
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* 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: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* 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 *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
/**
* This tests the Cuda implementation of CudaAmoebaTorsionForce.
*/
#include "openmm/internal/AssertionUtilities.h"
#include "AmoebaTinkerParameterFile.h"
#include "openmm/Context.h"
#include "OpenMMAmoeba.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
const double TOL = 1e-3;
#define PI_M 3.141592653589
#define RADIAN 57.29577951308
/* ---------------------------------------------------------------------------------------
Compute cross product of two 3-vectors and place in 3rd vector
vectorZ = vectorX x vectorY
@param vectorX x-vector
@param vectorY y-vector
@param vectorZ z-vector
@return vector is vectorZ
--------------------------------------------------------------------------------------- */
static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){
vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1];
vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2];
vectorZ[2] = vectorX[0]*vectorY[1] - vectorX[1]*vectorY[0];
return;
}
static double dotVector3( double* vectorX, double* vectorY ){
return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2];
}
static void computeAmoebaTorsionForce(int bondIndex, std::vector<Vec3>& positions, AmoebaTorsionForce& amoebaTorsionForce,
std::vector<Vec3>& forces, double* energy, FILE* log ) {
int particle1, particle2, particle3, particle4;
std::vector<double> torsion1;
std::vector<double> torsion2;
std::vector<double> torsion3;
torsion1.resize(3);
torsion2.resize(3);
torsion3.resize(3);
amoebaTorsionForce.getTorsionParameters(bondIndex, particle1, particle2, particle3, particle4, torsion1, torsion2, torsion3);
std::vector< std::vector<double> > torsions;
torsions.push_back( torsion1 );
torsions.push_back( torsion2 );
torsions.push_back( torsion3 );
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaTorsionForce: bond %d [%d %d %d %d]\n",
bondIndex, particle1, particle2, particle3, particle4 );
for( unsigned int ii = 0; ii < 3; ii++ ){
(void) fprintf( log, " [%10.3e %10.3e %10.3e]\n", torsions[ii][0], torsions[ii][1], torsions[ii][2] );
}
(void) fflush( log );
}
#endif
enum { BA, CB, DC, CA, DB, LastDeltaIndex };
double deltaR[LastDeltaIndex][3];
for( int ii = 0; ii < 3; ii++ ){
deltaR[BA][ii] = positions[particle2][ii] - positions[particle1][ii];
deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii];
deltaR[DC][ii] = positions[particle4][ii] - positions[particle3][ii];
deltaR[CA][ii] = positions[particle3][ii] - positions[particle1][ii];
deltaR[DB][ii] = positions[particle4][ii] - positions[particle2][ii];
}
enum { Xt, Xu, Xtu, LastXtIndex };
double crossProducts[LastXtIndex][3];
crossProductVector3( deltaR[BA], deltaR[CB], crossProducts[Xt] );
crossProductVector3( deltaR[CB], deltaR[DC], crossProducts[Xu] );
crossProductVector3( crossProducts[Xt], crossProducts[Xu], crossProducts[Xtu] );
double rT2 = dotVector3( crossProducts[Xt], crossProducts[Xt] );
double rU2 = dotVector3( crossProducts[Xu], crossProducts[Xu] );
double rTrU = sqrt( rT2*rU2 );
if( rTrU <= 0.0 ){
return;
}
double rCB = dotVector3( deltaR[CB], deltaR[CB] );
rCB = sqrt( rCB );
// ---------------------------------------------------------------------------------------
// cos(w), cos(2w), cos(3w), ...
// sin(w), sin(2w), sin(3w), ...
double cosine[6], sine[6];
cosine[0] = dotVector3( crossProducts[Xt], crossProducts[Xu] );
cosine[0] /= rTrU;
sine[0] = dotVector3( deltaR[CB], crossProducts[Xtu] );
sine[0] /= (rCB*rTrU);
for( int ii = 1; ii < 3; ii++ ){
cosine[ii] = cosine[0]*cosine[ii-1] - sine[0]* sine[ii-1];
sine[ii] = cosine[0]* sine[ii-1] + sine[0]*cosine[ii-1];
}
// ---------------------------------------------------------------------------------------
// dEdPhi prefactor
double dEdPhi = 0.0;
for( int ii = 0; ii < 3; ii++ ){
dEdPhi += torsions[ii][0]*((double) (ii+1))*( cosine[ii]*sin( torsions[ii][1] ) - sine[ii]*cos( torsions[ii][1] ) );
}
// ---------------------------------------------------------------------------------------
// dEdtu[0] = dEdT
// dEdtu[1] = dEdU
// tempVector[0] == dEdA: dEdT x CB
// tempVector[1] == dEdB: (CA x dEdT) + (dEdU x DC)
// tempVector[2] == dEdC: (dEdT x BA) + (DB x dEdU)
// tempVector[3] == dEdD: (dEdU x CB)
double dEdtu[2][3];
double tempVector[6][3];
// dEdT & dEdU
crossProductVector3( crossProducts[Xt], deltaR[CB], tempVector[0] );
crossProductVector3( crossProducts[Xu], deltaR[CB], tempVector[1] );
double norm[2] = { dEdPhi/(rT2*rCB ), -dEdPhi/(rU2*rCB ) };
for( int jj = 0; jj < 2; jj++ ){
for( int ii = 0; ii < 3; ii++ ){
dEdtu[jj][ii] = norm[jj]*tempVector[jj][ii];
}
}
// dEdA
crossProductVector3( dEdtu[0], deltaR[CB], tempVector[0] );
// dEdB
crossProductVector3( deltaR[CA], dEdtu[0], tempVector[4] );
crossProductVector3( dEdtu[1], deltaR[DC], tempVector[1] );
// dEdC
crossProductVector3( dEdtu[0], deltaR[BA], tempVector[5] );
crossProductVector3( deltaR[DB], dEdtu[1], tempVector[2] );
for( int jj = 0; jj < 3; jj++ ){
tempVector[1][jj] += tempVector[4][jj];
tempVector[2][jj] += tempVector[5][jj];
}
// dEdD
crossProductVector3( dEdtu[1], deltaR[CB], tempVector[3] );
// ---------------------------------------------------------------------------------------
// accumulate forces and energy
forces[particle1][0] -= tempVector[0][0];
forces[particle1][1] -= tempVector[0][1];
forces[particle1][2] -= tempVector[0][2];
forces[particle2][0] -= tempVector[1][0];
forces[particle2][1] -= tempVector[1][1];
forces[particle2][2] -= tempVector[1][2];
forces[particle3][0] -= tempVector[2][0];
forces[particle3][1] -= tempVector[2][1];
forces[particle3][2] -= tempVector[2][2];
forces[particle4][0] -= tempVector[3][0];
forces[particle4][1] -= tempVector[3][1];
forces[particle4][2] -= tempVector[3][2];
double energyTerm = 0.0;
for( int ii = 0; ii < 3; ii++ ){
energyTerm += torsions[ii][0]*( 1.0 + cosine[ii]*cos( torsions[ii][1] ) + sine[ii]*sin( torsions[ii][1] ) );
}
*energy += energyTerm;
}
static void computeAmoebaTorsionForces( Context& context, AmoebaTorsionForce& amoebaTorsionForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) {
// get positions and zero forces
State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() );
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
}
// calculates forces/energy
*expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaTorsionForce.getNumTorsions(); ii++ ){
computeAmoebaTorsionForce(ii, positions, amoebaTorsionForce, expectedForces, expectedEnergy, log );
}
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaTorsionForces: expected energy=%14.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
}
#endif
return;
}
void compareWithExpectedForceAndEnergy( Context& context, AmoebaTorsionForce& amoebaTorsionForce,
double tolerance, const std::string& idString, FILE* log) {
std::vector<Vec3> expectedForces;
double expectedEnergy;
computeAmoebaTorsionForces( context, amoebaTorsionForce, expectedForces, &expectedEnergy, log );
State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces();
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() );
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
}
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance );
}
void testOneTorsion( FILE* log ) {
System system;
int numberOfParticles = 4;
for( int ii = 0; ii < numberOfParticles; ii++ ){
system.addParticle(1.0);
}
LangevinIntegrator integrator(0.0, 0.1, 0.01);
AmoebaTorsionForce* amoebaTorsionForce = new AmoebaTorsionForce();
std::vector<double> torsion1;
torsion1.push_back( 0.619500000E+00 );
torsion1.push_back( 0.000000000E+00 );
std::vector<double> torsion2;
torsion2.push_back( -0.202500000E+00 );
torsion2.push_back( 0.180000000E+03 );
std::vector<double> torsion3;
torsion3.push_back( 0.175000000E-01 );
torsion3.push_back( 0.000000000E+00 );
amoebaTorsionForce->addTorsion(0, 1, 2, 3, torsion1, torsion2, torsion3 );
system.addForce(amoebaTorsionForce);
Context context(system, integrator, Platform::getPlatformByName( "Cuda"));
std::vector<Vec3> positions(numberOfParticles);
positions[0] = Vec3( 0.278860000E+01, 0.264630000E+01, 0.426300000E+00 );
positions[1] = Vec3( 0.273400000E+01, 0.244300000E+01, 0.261400000E+00 );
positions[2] = Vec3( 0.262660000E+01, 0.254130000E+01, 0.284200000E+00 );
positions[3] = Vec3( 0.269130000E+01, 0.266390000E+01, 0.353100000E+00 );
context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaTorsionForce, TOL, "testOneTorsion", log );
}
int main( int numberOfArguments, char* argv[] ) {
try {
std::cout << "TestCudaAmoebaTorsionForce running test..." << std::endl;
registerAmoebaCudaKernelFactories();
FILE* log = NULL;
testOneTorsion( log );
} catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
std::cout << "FAIL - ERROR. Test failed." << std::endl;
return 1;
}
std::cout << "Done" << std::endl;
return 0;
}
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* 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: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* 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 *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
/**
* This tests the Cuda implementation of UreyBradleyForce.
*/
#include "openmm/internal/AssertionUtilities.h"
#include "AmoebaTinkerParameterFile.h"
#include "openmm/Context.h"
#include "OpenMMAmoeba.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
const double TOL = 1e-5;
static void computeAmoebaUreyBradleyForce(int bondIndex, std::vector<Vec3>& positions, AmoebaUreyBradleyForce& amoebaUreyBradleyForce,
std::vector<Vec3>& forces, double* energy ) {
int particle1, particle2;
double bondLength;
double quadraticK;
double cubicK = amoebaUreyBradleyForce.getAmoebaGlobalUreyBradleyCubic();
double quarticK = amoebaUreyBradleyForce.getAmoebaGlobalUreyBradleyQuartic();
amoebaUreyBradleyForce.getUreyBradleyParameters(bondIndex, particle1, particle2, bondLength, quadraticK );
double deltaR[3];
double r2 = 0.0;
for( int ii = 0; ii < 3; ii++ ){
deltaR[ii] = positions[particle2][ii] - positions[particle1][ii];
r2 += deltaR[ii]*deltaR[ii];
}
double r = sqrt( r2 );
double bondDelta = (r - bondLength);
double bondDelta2 = bondDelta*bondDelta;
double dEdR = 1.0 + 1.5*cubicK*bondDelta + 2.0*quarticK*bondDelta2;
dEdR *= (r > 0.0) ? (2.0*quadraticK*bondDelta)/r : 0.0;
forces[particle1][0] += dEdR*deltaR[0];
forces[particle1][1] += dEdR*deltaR[1];
forces[particle1][2] += dEdR*deltaR[2];
forces[particle2][0] -= dEdR*deltaR[0];
forces[particle2][1] -= dEdR*deltaR[1];
forces[particle2][2] -= dEdR*deltaR[2];
*energy += (1.0f + cubicK*bondDelta + quarticK*bondDelta2)*quadraticK*bondDelta2;
}
static void computeAmoebaUreyBradleyForces( Context& context, AmoebaUreyBradleyForce& amoebaUreyBradleyForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) {
// get positions and zero forces
State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() );
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
}
// calculates forces/energy
*expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaUreyBradleyForce.getNumInteractions(); ii++ ){
computeAmoebaUreyBradleyForce(ii, positions, amoebaUreyBradleyForce, expectedForces, expectedEnergy );
}
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaUreyBradleyForces: expected energy=%15.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%15.7e %15.7e %15.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
}
#endif
return;
}
void compareWithExpectedForceAndEnergy( Context& context, AmoebaUreyBradleyForce& amoebaUreyBradleyForce, double tolerance, const std::string& idString, FILE* log) {
std::vector<Vec3> expectedForces;
double expectedEnergy;
computeAmoebaUreyBradleyForces( context, amoebaUreyBradleyForce, expectedForces, &expectedEnergy, NULL );
State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces();
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaUreyBradleyForces: expected energy=%15.7e %15.7e\n", expectedEnergy, state.getPotentialEnergy() );
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
(void) fprintf( log, "%6u [%15.7e %15.7e %15.7e] [%15.7e %15.7e %15.7e]\n", ii,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
}
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance );
}
void testOneBond( FILE* log ) {
System system;
system.addParticle(1.0);
system.addParticle(1.0);
LangevinIntegrator integrator(0.0, 0.1, 0.01);
AmoebaUreyBradleyForce* amoebaUreyBradleyForce = new AmoebaUreyBradleyForce();
double bondLength = 1.5;
double quadraticK = 1.0;
double cubicK = 2.0;
double quarticicK = 3.0;
amoebaUreyBradleyForce->setAmoebaGlobalUreyBradleyCubic( cubicK );
amoebaUreyBradleyForce->setAmoebaGlobalUreyBradleyQuartic( quarticicK );
amoebaUreyBradleyForce->addUreyBradley(0, 1, bondLength, quadraticK);
system.addForce(amoebaUreyBradleyForce);
Context context(system, integrator, Platform::getPlatformByName( "Cuda"));
std::vector<Vec3> positions(2);
positions[0] = Vec3(0, 1, 0);
positions[1] = Vec3(0, 0, 0);
context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaUreyBradleyForce, TOL, "testOneBond", log );
}
void testTwoBond( FILE* log ) {
System system;
system.addParticle(1.0);
system.addParticle(1.0);
system.addParticle(1.0);
LangevinIntegrator integrator(0.0, 0.1, 0.01);
AmoebaUreyBradleyForce* amoebaUreyBradleyForce = new AmoebaUreyBradleyForce();
double bondLength = 1.5;
double quadraticK = 1.0;
double cubicK = 2.0;
double quarticicK = 3.0;
amoebaUreyBradleyForce->setAmoebaGlobalUreyBradleyCubic( cubicK );
amoebaUreyBradleyForce->setAmoebaGlobalUreyBradleyQuartic( quarticicK );
amoebaUreyBradleyForce->addUreyBradley(0, 1, bondLength, quadraticK);
amoebaUreyBradleyForce->addUreyBradley(1, 2, bondLength, quadraticK);
system.addForce(amoebaUreyBradleyForce);
Context context(system, integrator, Platform::getPlatformByName( "Cuda"));
std::vector<Vec3> positions(3);
positions[0] = Vec3(0, 1, 0);
positions[1] = Vec3(0, 0, 0);
positions[2] = Vec3(1, 0, 1);
context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaUreyBradleyForce, TOL, "testTwoBond", log );
}
int main( int numberOfArguments, char* argv[] ) {
try {
std::cout << "TestCudaAmoebaUreyBradleyForce running test..." << std::endl;
registerAmoebaCudaKernelFactories();
FILE* log = NULL;
//testOneBond( log );
testTwoBond( log );
} catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
std::cout << "FAIL - ERROR. Test failed." << std::endl;
return 1;
}
std::cout << "Done" << std::endl;
return 0;
}
......@@ -63,7 +63,6 @@ void testVdw( FILE* log ) {
std::string epsilonCombiningRule = std::string("HHG");
amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule );
int classIndex = 0;
for( int ii = 0; ii < numberOfParticles; ii++ ){
int indexIV;
double mass, sigma, epsilon, reduction;
......@@ -94,7 +93,7 @@ void testVdw( FILE* log ) {
exclusions.push_back ( 5 );
}
system.addParticle(mass);
amoebaVdwForce->addParticle( indexIV, classIndex, sigma, epsilon, reduction );
amoebaVdwForce->addParticle( indexIV, sigma, epsilon, reduction );
amoebaVdwForce->setParticleExclusions( ii, exclusions );
}
LangevinIntegrator integrator(0.0, 0.1, 0.01);
......@@ -136,12 +135,11 @@ void testVdw( FILE* log ) {
}
for( int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++ ){
int indexIV;
int classIndex;
double sigma, epsilon, reduction;
amoebaVdwForce->getParticleParameters( ii, indexIV, classIndex, sigma, epsilon, reduction );
amoebaVdwForce->getParticleParameters( ii, indexIV, sigma, epsilon, reduction );
sigma *= AngstromToNm;
epsilon *= CalToJoule;
amoebaVdwForce->setParticleParameters( ii, indexIV, classIndex, sigma, epsilon, reduction );
amoebaVdwForce->setParticleParameters( ii, indexIV, sigma, epsilon, reduction );
}
platformName = "Cuda";
Context context(system, integrator, Platform::getPlatformByName( platformName ) );
......@@ -186,46 +184,44 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c
int numberOfParticles = 8;
amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule );
amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule );
amoebaVdwForce->setUseNeighborList( 1 );
amoebaVdwForce->setCutoff( cutoff );
if( boxDimension > 0.0 ){
Vec3 a( boxDimension, 0.0, 0.0 );
Vec3 b( 0.0, boxDimension, 0.0 );
Vec3 c( 0.0, 0.0, boxDimension );
system.setDefaultPeriodicBoxVectors( a, b, c );
amoebaVdwForce->setPBC( 1 );
amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic);
amoebaVdwForce->setUseDispersionCorrection( 1 );
} else {
amoebaVdwForce->setPBC( 0 );
amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff);
amoebaVdwForce->setUseDispersionCorrection( 0 );
}
// addParticle: ivIndex, radius, epsilon, reductionFactor
int classIndex = 0;
system.addParticle( 1.4007000e+01 );
amoebaVdwForce->addParticle( 0, classIndex, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 );
amoebaVdwForce->addParticle( 0, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( 0, classIndex, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( 0, classIndex, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( 0, classIndex, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
system.addParticle( 1.4007000e+01 );
amoebaVdwForce->addParticle( 4, classIndex, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 );
amoebaVdwForce->addParticle( 4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( 4, classIndex, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( 4, classIndex, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( 4, classIndex, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 );
// ParticleExclusions
......@@ -463,7 +459,7 @@ void testVdwTaper( FILE* log ) {
std::string testName = "testVdwTaper";
int numberOfParticles = 8;
double boxDimension = -1.0;
double boxDimension = 50.0;
double cutoff = 0.25;
std::vector<Vec3> forces;
......@@ -532,33 +528,32 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con
int numberOfParticles = 648;
amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule );
amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule );
amoebaVdwForce->setUseNeighborList( 1 );
amoebaVdwForce->setCutoff( cutoff );
if( boxDimension > 0.0 ){
Vec3 a( boxDimension, 0.0, 0.0 );
Vec3 b( 0.0, boxDimension, 0.0 );
Vec3 c( 0.0, 0.0, boxDimension );
system.setDefaultPeriodicBoxVectors( a, b, c );
amoebaVdwForce->setPBC( 1 );
amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic);
amoebaVdwForce->setUseDispersionCorrection( includeVdwDispersionCorrection );
} else {
amoebaVdwForce->setPBC( 0 );
amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff);
amoebaVdwForce->setUseDispersionCorrection( 0 );
}
// addParticle: ivIndex, classIndex, radius, epsilon, reductionFactor
// addParticle: ivIndex, radius, epsilon, reductionFactor
int classIndex = 0;
for( unsigned int ii = 0; ii < numberOfParticles; ii += 3 ){
system.addParticle( 1.5995000e+01 );
amoebaVdwForce->addParticle( ii, 0, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00 );
amoebaVdwForce->addParticle( ii, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( ii, 0, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( ii, 0, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 );
amoebaVdwForce->addParticle( ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 );
}
// exclusions
......
......@@ -122,79 +122,6 @@ void CudaCalcAmoebaHarmonicBondForceKernel::initialize(const System& system, con
double CudaCalcAmoebaHarmonicBondForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
return 0.0;
}
//
///* -------------------------------------------------------------------------- *
// * AmoebaUreyBradley *
// * -------------------------------------------------------------------------- */
//
//class CudaCalcAmoebaUreyBradleyForceKernel::ForceInfo : public CudaForceInfo {
//public:
// ForceInfo(const AmoebaUreyBradleyForce& force) : force(force) {
// }
// int getNumParticleGroups() {
// return force.getNumInteractions();
// }
// void getParticlesInGroup(int index, std::vector<int>& particles) {
// int particle1, particle2;
// double length, k;
// force.getUreyBradleyParameters(index, particle1, particle2, length, k);
// particles.resize(2);
// particles[0] = particle1;
// particles[1] = particle2;
// }
// bool areGroupsIdentical(int group1, int group2) {
// int particle1, particle2;
// double length1, length2, k1, k2;
// force.getUreyBradleyParameters(group1, particle1, particle2, length1, k1);
// force.getUreyBradleyParameters(group2, particle1, particle2, length2, k2);
// return (length1 == length2 && k1 == k2);
// }
//private:
// const AmoebaUreyBradleyForce& force;
//};
//
//CudaCalcAmoebaUreyBradleyForceKernel::CudaCalcAmoebaUreyBradleyForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system) :
// CalcAmoebaUreyBradleyForceKernel(name, platform), cu(cu), system(system) {
// data.incrementKernelCount();
//}
//
//CudaCalcAmoebaUreyBradleyForceKernel::~CudaCalcAmoebaUreyBradleyForceKernel() {
// data.decrementKernelCount();
//}
//
//void CudaCalcAmoebaUreyBradleyForceKernel::initialize(const System& system, const AmoebaUreyBradleyForce& force) {
//
// data.setAmoebaLocalForcesKernel( this );
//
// numInteractions = force.getNumInteractions();
// std::vector<int> particle1(numInteractions);
// std::vector<int> particle2(numInteractions);
// std::vector<float> length(numInteractions);
// std::vector<float> quadratic(numInteractions);
//
// for (int i = 0; i < numInteractions; i++) {
//
// int particle1Index, particle2Index;
// double lengthValue, kValue;
// force.getUreyBradleyParameters(i, particle1Index, particle2Index, lengthValue, kValue );
//
// particle1[i] = particle1Index;
// particle2[i] = particle2Index;
// length[i] = static_cast<float>( lengthValue );
// quadratic[i] = static_cast<float>( kValue );
// }
// gpuSetAmoebaUreyBradleyParameters( data.getAmoebaGpu(), particle1, particle2, length, quadratic,
// static_cast<float>(force.getAmoebaGlobalUreyBradleyCubic()),
// static_cast<float>(force.getAmoebaGlobalUreyBradleyQuartic()) );
// data.getAmoebaGpu()->gpuContext->forces.push_back(new ForceInfo(force));
//}
//
//double CudaCalcAmoebaUreyBradleyForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
// if( data.getAmoebaLocalForcesKernel() == this ){
// computeAmoebaLocalForces( data );
// }
// return 0.0;
//}
/* -------------------------------------------------------------------------- *
* AmoebaHarmonicAngle *
......@@ -344,101 +271,6 @@ double CudaCalcAmoebaHarmonicInPlaneAngleForceKernel::execute(ContextImpl& conte
return 0.0;
}
///* -------------------------------------------------------------------------- *
// * AmoebaTorsion *
// * -------------------------------------------------------------------------- */
//
//class CudaCalcAmoebaTorsionForceKernel::ForceInfo : public CudaForceInfo {
//public:
// ForceInfo(const AmoebaTorsionForce& force) : force(force) {
// }
// int getNumParticleGroups() {
// return force.getNumTorsions();
// }
// void getParticlesInGroup(int index, std::vector<int>& particles) {
// int particle1, particle2, particle3, particle4;
// vector<double> torsion1, torsion2, torsion3;
// force.getTorsionParameters(index, particle1, particle2, particle3, particle4, torsion1, torsion2, torsion3);
// particles.resize(4);
// particles[0] = particle1;
// particles[1] = particle2;
// particles[2] = particle3;
// particles[3] = particle4;
// }
// bool areGroupsIdentical(int group1, int group2) {
// int particle1, particle2, particle3, particle4;
// vector<double> torsion11, torsion21, torsion31;
// vector<double> torsion12, torsion22, torsion32;
// force.getTorsionParameters(group1, particle1, particle2, particle3, particle4, torsion11, torsion21, torsion31);
// force.getTorsionParameters(group2, particle1, particle2, particle3, particle4, torsion12, torsion22, torsion32);
// for (int i = 0; i < (int) torsion11.size(); ++i)
// if (torsion11[i] != torsion12[i])
// return false;
// for (int i = 0; i < (int) torsion21.size(); ++i)
// if (torsion21[i] != torsion22[i])
// return false;
// for (int i = 0; i < (int) torsion31.size(); ++i)
// if (torsion31[i] != torsion32[i])
// return false;
// return true;
// }
//private:
// const AmoebaTorsionForce& force;
//};
//
//CudaCalcAmoebaTorsionForceKernel::CudaCalcAmoebaTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system) :
// CalcAmoebaTorsionForceKernel(name, platform), cu(cu), system(system) {
// data.incrementKernelCount();
//}
//
//CudaCalcAmoebaTorsionForceKernel::~CudaCalcAmoebaTorsionForceKernel() {
// data.decrementKernelCount();
//}
//
//void CudaCalcAmoebaTorsionForceKernel::initialize(const System& system, const AmoebaTorsionForce& force) {
//
// data.setAmoebaLocalForcesKernel( this );
// numTorsions = force.getNumTorsions();
// std::vector<int> particle1(numTorsions);
// std::vector<int> particle2(numTorsions);
// std::vector<int> particle3(numTorsions);
// std::vector<int> particle4(numTorsions);
//
// std::vector< std::vector<float> > torsionParameters1(numTorsions);
// std::vector< std::vector<float> > torsionParameters2(numTorsions);
// std::vector< std::vector<float> > torsionParameters3(numTorsions);
//
// for (int i = 0; i < numTorsions; i++) {
//
// std::vector<double> torsionParameter1;
// std::vector<double> torsionParameter2;
// std::vector<double> torsionParameter3;
//
// std::vector<float> torsionParameters1F(3);
// std::vector<float> torsionParameters2F(3);
// std::vector<float> torsionParameters3F(3);
//
// force.getTorsionParameters(i, particle1[i], particle2[i], particle3[i], particle4[i], torsionParameter1, torsionParameter2, torsionParameter3 );
// for ( unsigned int jj = 0; jj < torsionParameter1.size(); jj++) {
// torsionParameters1F[jj] = static_cast<float>(torsionParameter1[jj]);
// torsionParameters2F[jj] = static_cast<float>(torsionParameter2[jj]);
// torsionParameters3F[jj] = static_cast<float>(torsionParameter3[jj]);
// }
// torsionParameters1[i] = torsionParameters1F;
// torsionParameters2[i] = torsionParameters2F;
// torsionParameters3[i] = torsionParameters3F;
// }
// gpuSetAmoebaTorsionParameters(data.getAmoebaGpu(), particle1, particle2, particle3, particle4, torsionParameters1, torsionParameters2, torsionParameters3 );
// data.getAmoebaGpu()->gpuContext->forces.push_back(new ForceInfo(force));
//}
//
//double CudaCalcAmoebaTorsionForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
// if( data.getAmoebaLocalForcesKernel() == this ){
// computeAmoebaLocalForces( data );
// }
// return 0.0;
//}
/* -------------------------------------------------------------------------- *
* AmoebaPiTorsion *
* -------------------------------------------------------------------------- */
......@@ -1579,7 +1411,7 @@ void CudaCalcAmoebaMultipoleForceKernel::getElectrostaticPotential(ContextImpl&
}
template <class T, class T4>
void CudaCalcAmoebaMultipoleForceKernel::computeSystemMultipoleMoments(ContextImpl& context, const Vec3& origin, vector<double>& outputMultipoleMoments) {
void CudaCalcAmoebaMultipoleForceKernel::computeSystemMultipoleMoments(ContextImpl& context, vector<double>& outputMultipoleMoments) {
// Compute the local coordinates relative to the center of mass.
int numAtoms = cu.getNumAtoms();
vector<T4> posq, velm;
......@@ -1689,12 +1521,12 @@ void CudaCalcAmoebaMultipoleForceKernel::computeSystemMultipoleMoments(ContextIm
outputMultipoleMoments[12] = zzqdp*debye;
}
void CudaCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, const Vec3& origin, vector<double>& outputMultipoleMoments) {
void CudaCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, vector<double>& outputMultipoleMoments) {
context.calcForcesAndEnergy(false, false, -1);
if (cu.getUseDoublePrecision())
computeSystemMultipoleMoments<double, double4>(context, origin, outputMultipoleMoments);
computeSystemMultipoleMoments<double, double4>(context, outputMultipoleMoments);
else
computeSystemMultipoleMoments<float, float4>(context, origin, outputMultipoleMoments);
computeSystemMultipoleMoments<float, float4>(context, outputMultipoleMoments);
}
/* -------------------------------------------------------------------------- *
......@@ -1905,11 +1737,11 @@ public:
ForceInfo(const AmoebaVdwForce& force) : force(force) {
}
bool areParticlesIdentical(int particle1, int particle2) {
int iv1, iv2, class1, class2;
int iv1, iv2;
double sigma1, sigma2, epsilon1, epsilon2, reduction1, reduction2;
force.getParticleParameters(particle1, iv1, class1, sigma1, epsilon1, reduction1);
force.getParticleParameters(particle2, iv2, class2, sigma2, epsilon2, reduction2);
return (class1 == class2 && sigma1 == sigma2 && epsilon1 == epsilon2 && reduction1 == reduction2);
force.getParticleParameters(particle1, iv1, sigma1, epsilon1, reduction1);
force.getParticleParameters(particle2, iv2, sigma2, epsilon2, reduction2);
return (sigma1 == sigma2 && epsilon1 == epsilon2 && reduction1 == reduction2);
}
private:
const AmoebaVdwForce& force;
......@@ -1951,9 +1783,9 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
vector<float> bondReductionFactorsVec(cu.getPaddedNumAtoms(), 0);
vector<vector<int> > exclusions(cu.getNumAtoms());
for (int i = 0; i < force.getNumParticles(); i++) {
int ivIndex, classIndex;
int ivIndex;
double sigma, epsilon, reductionFactor;
force.getParticleParameters(i, ivIndex, classIndex, sigma, epsilon, reductionFactor);
force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor);
sigmaEpsilonVec[i] = make_float2((float) sigma, (float) epsilon);
bondReductionAtomsVec[i] = ivIndex;
bondReductionFactorsVec[i] = (float) reductionFactor;
......@@ -2005,7 +1837,8 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
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));
nonbonded->addInteraction(force.getUseNeighborList(), force.getPBC(), true, force.getCutoff(), exclusions,
bool useCutoff = (force.getNonbondedMethod() != AmoebaVdwForce::NoCutoff);
nonbonded->addInteraction(useCutoff, useCutoff, true, force.getCutoff(), exclusions,
cu.replaceStrings(CudaAmoebaKernelSources::amoebaVdwForce2, replacements), force.getForceGroup());
// Create the other kernels.
......@@ -2101,7 +1934,7 @@ void CudaCalcAmoebaWcaDispersionForceKernel::initialize(const System& system, co
// just so that CudaNonbondedUtilities will keep track of the tiles.
vector<vector<int> > exclusions;
cu.getNonbondedUtilities().addInteraction(false, false, false, 0, exclusions, "", force.getForceGroup());
cu.getNonbondedUtilities().addInteraction(false, false, false, cu.getNonbondedUtilities().getCutoffDistance(), exclusions, "", force.getForceGroup());
cu.addForce(new ForceInfo(force));
}
......
......@@ -73,39 +73,6 @@ private:
CudaArray* params;
};
/**
* This kernel is invoked by AmoebaUreyBradleyForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaUreyBradleyForceKernel : public CalcAmoebaUreyBradleyForceKernel {
public:
CudaCalcAmoebaUreyBradleyForceKernel(std::string name,
const Platform& platform,
CudaContext& cu,
System& system);
~CudaCalcAmoebaUreyBradleyForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaUreyBradleyForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaUreyBradleyForce& 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:
class ForceInfo;
int numInteractions;
CudaContext& cu;
System& system;
};
/**
* This kernel is invoked by AmoebaHarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
*/
......@@ -168,36 +135,6 @@ private:
CudaArray* params;
};
/**
* This kernel is invoked by AmoebaTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaTorsionForceKernel : public CalcAmoebaTorsionForceKernel {
public:
CudaCalcAmoebaTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system);
~CudaCalcAmoebaTorsionForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaTorsionForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaTorsionForce& 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:
class ForceInfo;
int numTorsions;
CudaContext& cu;
System& system;
};
/**
* This kernel is invoked by AmoebaPiTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
......@@ -361,7 +298,6 @@ public:
/**
* Get the system multipole moments
*
* @param origin origin
* @param context context
* @param outputMultipoleMoments (charge,
* dipole_x, dipole_y, dipole_z,
......@@ -369,7 +305,7 @@ public:
* quadrupole_yx, quadrupole_yy, quadrupole_yz,
* quadrupole_zx, quadrupole_zy, quadrupole_zz )
*/
void getSystemMultipoleMoments(ContextImpl& context, const Vec3& origin, std::vector<double>& outputMultipoleMoments);
void getSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments);
private:
......@@ -385,7 +321,7 @@ private:
const char* getSortKey() const {return "value.y";}
};
void initializeScaleFactors();
template <class T, class T4> void computeSystemMultipoleMoments(ContextImpl& context, const Vec3& origin, std::vector<double>& outputMultipoleMoments);
template <class T, class T4> void computeSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments);
int numMultipoles, maxInducedIterations;
double inducedEpsilon;
bool hasInitializedScaleFactors, hasInitializedFFT;
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman, Mark Friedrichs *
* Contributors: *
* *
* 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 *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* 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/>. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/CMMotionRemover.h"
#include "openmm/System.h"
#include "openmm/Context.h"
#include "openmm/LangevinIntegrator.h"
#include "openmm/VariableLangevinIntegrator.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/VariableVerletIntegrator.h"
#include "openmm/BrownianIntegrator.h"
#include "openmm/AmoebaHarmonicBondForce.h"
#include "openmm/AmoebaHarmonicAngleForce.h"
#include "openmm/AmoebaHarmonicInPlaneAngleForce.h"
#include "openmm/AmoebaTorsionForce.h"
#include "openmm/AmoebaPiTorsionForce.h"
#include "openmm/AmoebaStretchBendForce.h"
#include "openmm/AmoebaOutOfPlaneBendForce.h"
#include "openmm/AmoebaTorsionTorsionForce.h"
#include "openmm/AmoebaMultipoleForce.h"
#include "openmm/AmoebaGeneralizedKirkwoodForce.h"
#include "openmm/AmoebaVdwForce.h"
#include "openmm/AmoebaWcaDispersionForce.h"
#include "openmm/AmoebaUreyBradleyForce.h"
#include "openmm/internal/windowsExport.h"
#include "openmm/internal/AmoebaWcaDispersionForceImpl.h"
#include <ctime>
#include <vector>
#include <algorithm>
#include <map>
#include <cfloat>
#include <cstring>
#include <cstdlib>
#include <typeinfo>
#include <time.h>
extern "C" void registerAmoebaCudaKernelFactories();
// force enums
#define MAX_PRINT 5
static std::string AMOEBA_HARMONIC_BOND_FORCE = "AmoebaHarmonicBond";
static std::string AMOEBA_HARMONIC_ANGLE_FORCE = "AmoebaHarmonicAngle";
static std::string AMOEBA_HARMONIC_IN_PLANE_ANGLE_FORCE = "AmoebaHarmonicInPlaneAngle";
static std::string AMOEBA_TORSION_FORCE = "AmoebaTorsion";
static std::string AMOEBA_PI_TORSION_FORCE = "AmoebaPiTorsion";
static std::string AMOEBA_STRETCH_BEND_FORCE = "AmoebaStretchBend";
static std::string AMOEBA_OUT_OF_PLANE_BEND_FORCE = "AmoebaOutOfPlaneBend";
static std::string AMOEBA_TORSION_TORSION_FORCE = "AmoebaTorsionTorsion";
static std::string AMOEBA_MULTIPOLE_FORCE = "AmoebaMultipole";
static std::string AMOEBA_GK_FORCE = "AmoebaGk";
static std::string AMOEBA_GK_CAVITY_FORCE = "AmoebaGkAndCavity";
static std::string AMOEBA_VDW_FORCE = "AmoebaVdw";
static std::string AMOEBA_WCA_DISPERSION_FORCE = "AmoebaWcaDispersion";
static std::string AMOEBA_UREY_BRADLEY_FORCE = "AmoebaUreyBradley";
static std::string ALL_FORCES = "AllForces";
static std::string AMOEBA_MULTIPOLE_ROTATION_MATRICES = "AmoebaMultipoleRotationMatrices";
static std::string AMOEBA_MULTIPOLE_ROTATED = "AmoebaMultipolesRotated";
static std::string AMOEBA_FIXED_E = "AmoebaFixedE";
static std::string AMOEBA_FIXED_E_GK = "AmoebaFixedE_GK";
static std::string AMOEBA_INDUCDED_DIPOLES = "AmoebaInducedDipoles";
static std::string AMOEBA_INDUCDED_DIPOLES_GK = "AmoebaInducedDipoles_GK";
static std::string INCLUDE_OBC_CAVITY_TERM = "includeObcCavityTerm";
static std::string MUTUAL_INDUCED_MAX_ITERATIONS = "mutualInducedMaxIterations";
static std::string MUTUAL_INDUCED_TARGET_EPSILON = "mutualInducedTargetEpsilon";
static std::string APPLY_N2 = "applyN2";
static std::string ZERO_HARMONIC_BOND_IXN = "zeroHarmonicBondIxn";
#define AmoebaHarmonicBondIndex 0
#define AmoebaHarmonicAngleIndex 1
#define AmoebaHarmonicInPlaneAngleIndex 2
#define AmoebaTorsionIndex 3
#define AmoebaPiTorsionIndex 4
#define AmoebaStretchBendIndex 5
#define AmoebaOutOfPlaneBendIndex 6
#define AmoebaTorsionTorsionIndex 7
#define AmoebaMultipoleIndex 8
#define AmoebaVdwIndex 9
#define AmoebaWcaDispersionIndex 10
#define AmoebaObcIndex 11
#define SumIndex 12
#define UreyBradleyIndex 13
#define AmoebaLastIndex 14
#define AngstromToNm 0.1
#define CalToJoule 4.184
const double DegreesToRadians = 3.14159265/180.0;
const double RadiansToDegrees = 180/3.14159265;
using namespace OpenMM;
using namespace std;
// the following are used in parsing parameter file
typedef std::vector<std::string> StringVector;
typedef StringVector::iterator StringVectorI;
typedef StringVector::const_iterator StringVectorCI;
typedef std::vector<StringVector> StringVectorVector;
typedef std::vector<std::vector<double> > VectorOfVectors;
typedef VectorOfVectors::iterator VectorOfVectorsI;
typedef VectorOfVectors::const_iterator VectorOfVectorsCI;
typedef std::map< std::string, VectorOfVectors > MapStringVectorOfVectors;
typedef MapStringVectorOfVectors::iterator MapStringVectorOfVectorsI;
typedef MapStringVectorOfVectors::const_iterator MapStringVectorOfVectorsCI;
typedef std::map< std::string, std::string > MapStringString;
typedef MapStringString::iterator MapStringStringI;
typedef MapStringString::const_iterator MapStringStringCI;
typedef std::map< std::string, int > MapStringInt;
typedef MapStringInt::iterator MapStringIntI;
typedef MapStringInt::const_iterator MapStringIntCI;
typedef std::map< std::string, std::vector<Vec3> > MapStringVec3;
typedef MapStringVec3::iterator MapStringVec3I;
typedef MapStringVec3::const_iterator MapStringVec3CI;
typedef std::map< std::string, double > MapStringDouble;
typedef MapStringDouble::iterator MapStringDoubleI;
typedef MapStringDouble::const_iterator MapStringDoubleCI;
typedef std::map< std::string, Force*> MapStringForce;
typedef MapStringForce::iterator MapStringForceI;
typedef MapStringForce::const_iterator MapStringForceCI;
// default return value from methods
static const int DefaultReturnValue = 0;
static const int LengthUnit = 0;
static const int EnergyUnit = 1;
static const int ForceUnit = 2;
static const int LastUnits = ForceUnit + 1;
static const int NoUnitsConversion = 0;
static const int KcalA_To_kJNm = 1;
/**---------------------------------------------------------------------------------------
* Initialize units
*
* @param unitType has w/ force name as key and int as value
* @param units array
*
*
--------------------------------------------------------------------------------------- */
void setUnits( int unitType, double* units );
/**---------------------------------------------------------------------------------------
Read parameter file
@param inputParameterFile input parameter file name
@param system system to which forces based on parameters are to be added
@param coordinates Vec3 array containing coordinates on output
@param velocities Vec3 array containing velocities on output
@param inputLog log file pointer -- may be NULL
@return number of lines read
--------------------------------------------------------------------------------------- */
Integrator* readAmoebaParameterFile( const std::string& inputParameterFile, MapStringInt& forceMap, System& system,
std::vector<Vec3>& coordinates,
std::vector<Vec3>& velocities,
MapStringVec3& forces, MapStringDouble& potentialEnergy,
MapStringVectorOfVectors& supplementary, FILE* inputLog );
/**---------------------------------------------------------------------------------------
* Get integrator
*
* @param integratorName integratorName (VerletIntegrator, BrownianIntegrator, LangevinIntegrator, ...)
* @param timeStep time step
* @param friction (ps) friction
* @param temperature temperature
* @param shakeTolerance Shake tolerance
* @param errorTolerance Error tolerance
* @param randomNumberSeed seed
*
* @return DefaultReturnValue or ErrorReturnValue
*
--------------------------------------------------------------------------------------- */
Integrator* getIntegrator( std::string& integratorName, double timeStep,
double friction, double temperature,
double shakeTolerance, double errorTolerance,
int randomNumberSeed, FILE* log );
/**---------------------------------------------------------------------------------------
* Initialize forceMap
*
* @param forceMap has w/ force name as key and int as value
* @param initialValue initial value
*
*
--------------------------------------------------------------------------------------- */
void initializeForceMap( MapStringInt& forceMap, int initialValue );
void testUsingAmoebaTinkerParameterFile( const std::string& amoebaTinkerParameterFileName, MapStringInt& forceMap,
double tolerance, FILE* summaryFile, FILE* log );
int OPENMM_EXPORT runTestsUsingAmoebaTinkerParameterFile( MapStringString& argumentMap );
void OPENMM_EXPORT appendInputArgumentsToArgumentMap( int numberOfArguments, char* argv[], MapStringString& argumentMap );
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