Commit ad75a390 authored by Peter Eastman's avatar Peter Eastman
Browse files

Split StandardMMForceField into separate classes for each force term.

parent 8078c417
/* -------------------------------------------------------------------------- *
* 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) 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. *
* -------------------------------------------------------------------------- */
#include "internal/OpenMMContextImpl.h"
#include "internal/RBTorsionForceImpl.h"
#include "kernels.h"
using namespace OpenMM;
using std::pair;
using std::vector;
using std::set;
RBTorsionForceImpl::RBTorsionForceImpl(RBTorsionForce& owner) : owner(owner) {
}
RBTorsionForceImpl::~RBTorsionForceImpl() {
}
void RBTorsionForceImpl::initialize(OpenMMContextImpl& context) {
kernel = context.getPlatform().createKernel(CalcRBTorsionForceKernel::Name(), context);
dynamic_cast<CalcRBTorsionForceKernel&>(kernel.getImpl()).initialize(context.getSystem(), owner);
}
void RBTorsionForceImpl::calcForces(OpenMMContextImpl& context, Stream& forces) {
dynamic_cast<CalcRBTorsionForceKernel&>(kernel.getImpl()).executeForces(context);
}
double RBTorsionForceImpl::calcEnergy(OpenMMContextImpl& context) {
return dynamic_cast<CalcRBTorsionForceKernel&>(kernel.getImpl()).executeEnergy(context);
}
std::vector<std::string> RBTorsionForceImpl::getKernelNames() {
std::vector<std::string> names;
names.push_back(CalcRBTorsionForceKernel::Name());
return names;
}
......@@ -43,7 +43,7 @@
namespace OpenMM {
/**
* This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class BrookBonded : public BrookCommon {
......
......@@ -39,7 +39,7 @@
namespace OpenMM {
/**
* This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class BrookCalcGBSAOBCForceFieldKernel : public CalcGBSAOBCForceFieldKernel {
......@@ -83,7 +83,7 @@ class BrookCalcGBSAOBCForceFieldKernel : public CalcGBSAOBCForceFieldKernel {
*
* @param positions atom positions
*
* @return potential energy due to the StandardMMForceField
* @return potential energy due to the NonbondedForce
* Currently always return 0.0 since energies not calculated on gpu
*
*/
......
......@@ -35,28 +35,28 @@
#include <sstream>
#include "BrookStreamImpl.h"
#include "BrookCalcStandardMMForceFieldKernel.h"
#include "BrookCalcNonbondedForceKernel.h"
#include "gpu/kforce.h"
#include "gpu/kinvmap_gather.h"
#include "StandardMMForceField.h"
#include "NonbondedForce.h"
using namespace OpenMM;
using namespace std;
/**
* BrookCalcStandardMMForceFieldKernel constructor
* BrookCalcNonbondedForceKernel constructor
*
* @param name kernel name
* @param platform platform
*
*/
BrookCalcStandardMMForceFieldKernel::BrookCalcStandardMMForceFieldKernel( std::string name, const Platform& platform ) :
CalcStandardMMForceFieldKernel( name, platform ){
BrookCalcNonbondedForceKernel::BrookCalcNonbondedForceKernel( std::string name, const Platform& platform ) :
CalcNonbondedForceKernel( name, platform ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::BrookCalcStandardMMForceFieldKernel";
// static const std::string methodName = "BrookCalcNonbondedForceKernel::BrookCalcNonbondedForceKernel";
// ---------------------------------------------------------------------------------------
......@@ -80,15 +80,15 @@ BrookCalcStandardMMForceFieldKernel::BrookCalcStandardMMForceFieldKernel( std::s
}
/**
* BrookCalcStandardMMForceFieldKernel destructor
* BrookCalcNonbondedForceKernel destructor
*
*/
BrookCalcStandardMMForceFieldKernel::~BrookCalcStandardMMForceFieldKernel( ){
BrookCalcNonbondedForceKernel::~BrookCalcNonbondedForceKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::BrookCalcStandardMMForceFieldKernel";
// static const std::string methodName = "BrookCalcNonbondedForceKernel::BrookCalcNonbondedForceKernel";
// ---------------------------------------------------------------------------------------
......@@ -113,7 +113,7 @@ BrookCalcStandardMMForceFieldKernel::~BrookCalcStandardMMForceFieldKernel( ){
*
*/
FILE* BrookCalcStandardMMForceFieldKernel::getLog( void ) const {
FILE* BrookCalcNonbondedForceKernel::getLog( void ) const {
return _log;
}
......@@ -126,7 +126,7 @@ FILE* BrookCalcStandardMMForceFieldKernel::getLog( void ) const {
*
*/
int BrookCalcStandardMMForceFieldKernel::setLog( FILE* log ){
int BrookCalcNonbondedForceKernel::setLog( FILE* log ){
_log = log;
return BrookCommon::DefaultReturnValue;
}
......@@ -155,7 +155,7 @@ int BrookCalcStandardMMForceFieldKernel::setLog( FILE* log ){
* @param periodicBoxSize the size of the periodic box (if nonbondedMethod involves a periodic boundary conditions)
*/
void BrookCalcStandardMMForceFieldKernel::initialize(
void BrookCalcNonbondedForceKernel::initialize(
const vector<vector<int> >& bondIndices, const vector<vector<double> >& bondParameters,
const vector<vector<int> >& angleIndices, const vector<vector<double> >& angleParameters,
const vector<vector<int> >& periodicTorsionIndices, const vector<vector<double> >& periodicTorsionParameters,
......@@ -166,7 +166,7 @@ void BrookCalcStandardMMForceFieldKernel::initialize(
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::initialize";
static const std::string methodName = "BrookCalcNonbondedForceKernel::initialize";
// ---------------------------------------------------------------------------------------
......@@ -224,8 +224,8 @@ void BrookCalcStandardMMForceFieldKernel::initialize(
// used for calculating energy
/*
_referenceCalcStandardMMForceFieldKernel = new ReferenceCalcStandardMMForceFieldKernel( getName(), getPlatform() );
_referenceCalcStandardMMForceFieldKernel->initialize( bondIndices, bondParameters,
_referenceCalcNonbondedForceKernel = new ReferenceCalcNonbondedForceKernel( getName(), getPlatform() );
_referenceCalcNonbondedForceKernel->initialize( bondIndices, bondParameters,
angleIndices, angleParameters,
periodicTorsionIndices, periodicTorsionParameters,
rbTorsionIndices, rbTorsionParameters,
......@@ -233,7 +233,7 @@ void BrookCalcStandardMMForceFieldKernel::initialize(
exclusions, nonbondedParameters,
nonbondedMethod, nonbondedCutoff, periodicBoxSize );
*/
_refForceField = new StandardMMForceField( _numberOfAtoms, bondIndices.size(), angleIndices.size(),
_refForceField = new NonbondedForce( _numberOfAtoms, bondIndices.size(), angleIndices.size(),
periodicTorsionIndices.size(), rbTorsionIndices.size() );
// bonds
......@@ -318,11 +318,11 @@ printf( "RbTor: [%d %d %d %d] [%.5e %.5e %.5e %.5e %.5e %.5e]\n", rbTorsionInd[0
* have been calculated so far. The kernel should add its own forces to the values already in the stream.
*/
void BrookCalcStandardMMForceFieldKernel::executeForces( const Stream& positions, Stream& forces ){
void BrookCalcNonbondedForceKernel::executeForces( const Stream& positions, Stream& forces ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::executeForces";
static const std::string methodName = "BrookCalcNonbondedForceKernel::executeForces";
static const int I_Stream = 0;
static const int J_Stream = 1;
......@@ -677,16 +677,16 @@ nonbondedForceStreams[3]->fillWithValue( &zerof );
*
* @param positions atom positions
*
* @return potential energy due to the StandardMMForceField
* @return potential energy due to the NonbondedForce
* Currently always return 0.0 since energies not calculated on gpu
*
*/
double BrookCalcStandardMMForceFieldKernel::executeEnergy( const Stream& atomPositions ){
double BrookCalcNonbondedForceKernel::executeEnergy( const Stream& atomPositions ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::executeEnergy";
//static const std::string methodName = "BrookCalcNonbondedForceKernel::executeEnergy";
// ---------------------------------------------------------------------------------------
......@@ -706,7 +706,7 @@ double BrookCalcStandardMMForceFieldKernel::executeEnergy( const Stream& atomPos
State state = context->getState( State::Energy );
double energy = state.getPotentialEnergy();
// (void) fprintf( stdout, "BrookCalcStandardMMForceFieldKernel::executeEnergy E=%.5e\n", energy ); fflush( stdout );
// (void) fprintf( stdout, "BrookCalcNonbondedForceKernel::executeEnergy E=%.5e\n", energy ); fflush( stdout );
return energy;
......@@ -721,11 +721,11 @@ double BrookCalcStandardMMForceFieldKernel::executeEnergy( const Stream& atomPos
*
*/
OpenMMContext* BrookCalcStandardMMForceFieldKernel::getReferenceOpenMMContext( int numberOfAtoms ){
OpenMMContext* BrookCalcNonbondedForceKernel::getReferenceOpenMMContext( int numberOfAtoms ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::getReferenceOpenMMContext";
//static const std::string methodName = "BrookCalcNonbondedForceKernel::getReferenceOpenMMContext";
// ---------------------------------------------------------------------------------------
......@@ -749,16 +749,16 @@ OpenMMContext* BrookCalcStandardMMForceFieldKernel::getReferenceOpenMMContext( i
*
* @param positions atom positions
*
* @return potential energy due to the StandardMMForceField
* @return potential energy due to the NonbondedForce
* Currently always return 0.0 since energies not calculated on gpu
*
*/
double BrookCalcStandardMMForceFieldKernel::executeEnergyOld( const Stream& atomPositions ){
double BrookCalcNonbondedForceKernel::executeEnergyOld( const Stream& atomPositions ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcStandardMMForceFieldKernel::executeEnergy";
//static const std::string methodName = "BrookCalcNonbondedForceKernel::executeEnergy";
// ---------------------------------------------------------------------------------------
......@@ -786,7 +786,7 @@ double BrookCalcStandardMMForceFieldKernel::executeEnergyOld( const Stream& atom
//delete forceField;
// (void) fprintf( stdout, "BrookCalcStandardMMForceFieldKernel::executeEnergy E=%.5e\n", energy ); fflush( stdout );
// (void) fprintf( stdout, "BrookCalcNonbondedForceKernel::executeEnergy E=%.5e\n", energy ); fflush( stdout );
return energy;
......
......@@ -36,7 +36,7 @@
#include "../../reference/src/SimTKUtilities/SimTKOpenMMRealType.h"
#include "BrookBonded.h"
#include "BrookNonBonded.h"
#include "StandardMMForceField.h"
#include "NonbondedForce.h"
#include "OpenMMContext.h"
#include "System.h"
#include "ReferencePlatform.h"
......@@ -45,15 +45,15 @@
namespace OpenMM {
/**
* This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class BrookCalcStandardMMForceFieldKernel : public CalcStandardMMForceFieldKernel {
class BrookCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
public:
BrookCalcStandardMMForceFieldKernel( std::string name, const Platform& platform );
BrookCalcNonbondedForceKernel( std::string name, const Platform& platform );
~BrookCalcStandardMMForceFieldKernel();
~BrookCalcNonbondedForceKernel();
/**
* Initialize the kernel, setting up the values of all the force field parameters.
......@@ -103,7 +103,7 @@ class BrookCalcStandardMMForceFieldKernel : public CalcStandardMMForceFieldKerne
*
* @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
*
* @return the potential energy due to the StandardMMForceField
* @return the potential energy due to the NonbondedForce
*
* Currently always return 0.0 since energies not calculated on gpu
*/
......@@ -171,7 +171,7 @@ class BrookCalcStandardMMForceFieldKernel : public CalcStandardMMForceFieldKerne
// used to calculate energy
StandardMMForceField* _refForceField;
NonbondedForce* _refForceField;
System* _refSystem;
OpenMMContext* _refOpenMMContext;
ReferencePlatform* _referencePlatform;
......
......@@ -42,7 +42,7 @@
namespace OpenMM {
/**
* This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class BrookCommon {
......
......@@ -30,7 +30,7 @@
* -------------------------------------------------------------------------- */
#include "BrookKernelFactory.h"
#include "BrookCalcStandardMMForceFieldKernel.h"
#include "BrookCalcNonbondedForceKernel.h"
#include "BrookIntegrateLangevinStepKernel.h"
#include "BrookIntegrateVerletStepKernel.h"
#include "BrookIntegrateBrownianStepKernel.h"
......@@ -50,9 +50,9 @@ KernelImpl* BrookKernelFactory::createKernelImpl( std::string name, const Platfo
// StandardMM
if( name == CalcStandardMMForceFieldKernel::Name() ){
if( name == CalcNonbondedForceKernel::Name() ){
return new BrookCalcStandardMMForceFieldKernel( name, platform );
return new BrookCalcNonbondedForceKernel( name, platform );
// GBSA OBC
......
......@@ -43,7 +43,7 @@
namespace OpenMM {
/**
* This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class BrookNonBonded : public BrookCommon {
......
......@@ -153,7 +153,7 @@ void BrookPlatform::_initializeKernelFactory( void ){
BrookKernelFactory* factory = new BrookKernelFactory();
registerKernelFactory( CalcStandardMMForceFieldKernel::Name(), factory);
registerKernelFactory( CalcNonbondedForceKernel::Name(), factory);
registerKernelFactory( CalcGBSAOBCForceFieldKernel::Name(), factory);
registerKernelFactory( IntegrateVerletStepKernel::Name(), factory);
registerKernelFactory( IntegrateLangevinStepKernel::Name(), factory);
......
......@@ -47,7 +47,7 @@
#include "OpenMMContext.h"
#include "CMMotionRemover.h"
#include "StandardMMForceField.h"
#include "NonbondedForce.h"
#include "GBSAOBCForceField.h"
#include "System.h"
#include "LangevinIntegrator.h"
......@@ -1070,7 +1070,7 @@ void testBrookBonds( void ){
// int numAtoms, int numBonds, int numAngles, int numPeriodicTorsions, int numRBTorsions
StandardMMForceField* forceField = new StandardMMForceField( 3, 2, 0, 0, 0 );
NonbondedForce* forceField = new NonbondedForce( 3, 2, 0, 0, 0 );
// ( index, atom1, atom2, length, k )
forceField->setBondParameters(0, 0, 1, 1.5, 0.8);
......@@ -1133,7 +1133,7 @@ void testBrookAngles( void ){
// int numAtoms, int numBonds, int numAngles, int numPeriodicTorsions, int numRBTorsions
StandardMMForceField* forceField = new StandardMMForceField( numberOfAtoms, 0, 2, 0, 0 );
NonbondedForce* forceField = new NonbondedForce( numberOfAtoms, 0, 2, 0, 0 );
// int index, int atom1, int atom2, int atom3, double angle, double k
forceField->setAngleParameters(0, 0, 1, 2, PI_M/3, 1.1);
......@@ -1202,7 +1202,7 @@ void testBrookPeriodicTorsions( void ){
// int numAtoms, int numBonds, int numAngles, int numPeriodicTorsions, int numRBTorsions
StandardMMForceField* forceField = new StandardMMForceField( numberOfAtoms, 0, 0, 1, 0 );
NonbondedForce* forceField = new NonbondedForce( numberOfAtoms, 0, 0, 1, 0 );
// int index, int atom1, int atom2, int atom3, double angle, double k
forceField->setPeriodicTorsionParameters(0, 0, 1, 2, 3, 2, PI_M/3, 1.1);
......@@ -1274,7 +1274,7 @@ void testBrookRBTorsions( void ){
// int numAtoms, int numBonds, int numAngles, int numPeriodicTorsions, int numRBTorsions
StandardMMForceField* forceField = new StandardMMForceField( numberOfAtoms, 0, 0, 0, 1 );
NonbondedForce* forceField = new NonbondedForce( numberOfAtoms, 0, 0, 0, 1 );
for( int ii = 0; ii < numberOfAtoms; ii++ ){
forceField->setAtomParameters( ii, 0.0, 1, 0);
......@@ -1356,7 +1356,7 @@ void testBrookCoulomb( void ){
// int index, double charge, double radius, double depth
StandardMMForceField* forceField = new StandardMMForceField( numberOfAtoms, 0, 0, 0, 0 );
NonbondedForce* forceField = new NonbondedForce( numberOfAtoms, 0, 0, 0, 0 );
forceField->setAtomParameters(0, 0.5, 1, 0);
forceField->setAtomParameters(1, -1.5, 1, 0);
system.addForce(forceField);
......@@ -1418,7 +1418,7 @@ void testBrookLJ( void ){
// int index, double charge, double radius, double depth
StandardMMForceField* forceField = new StandardMMForceField( numberOfAtoms, 0, 0, 0, 0 );
NonbondedForce* forceField = new NonbondedForce( numberOfAtoms, 0, 0, 0, 0 );
forceField->setAtomParameters(0, 0, 1.2, 1);
forceField->setAtomParameters(1, 0, 1.4, 2);
system.addForce(forceField);
......@@ -1481,7 +1481,7 @@ void testBrookExclusionsAnd14( void ){
// int index, double charge, double radius, double depth
StandardMMForceField* forceField = new StandardMMForceField( numberOfAtoms, numberOfAtoms-1, 0, 0, 0 );
NonbondedForce* forceField = new NonbondedForce( numberOfAtoms, numberOfAtoms-1, 0, 0, 0 );
for( int ii = 1; ii < numberOfAtoms; ii++ ){
forceField->setBondParameters(ii-1, ii-1, ii, 1, 0);
}
......@@ -2086,7 +2086,7 @@ static OpenMMContext* testLangevinSingleBondSetup( int brookContext, LangevinInt
LangevinIntegrator* integrator = new LangevinIntegrator(0, 0.1, 0.01);
*outIntegrator = integrator;
StandardMMForceField* forceField = new StandardMMForceField(2, 1, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(2, 1, 0, 0, 0);
forceField->setBondParameters(0, 0, 1, 1.5, 1);
system->addForce(forceField);
OpenMMContext* context = new OpenMMContext( *system, *integrator, *platform );
......@@ -2179,7 +2179,7 @@ void testLangevinTemperature() {
const double temp = 100.0;
System system(numberOfAtoms, 0);
LangevinIntegrator integrator(temp, 2.0, 0.001);
StandardMMForceField* forceField = new StandardMMForceField(numberOfAtoms, 0, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(numberOfAtoms, 0, 0, 0, 0);
for (int i = 0; i < numberOfAtoms; ++i){
system.setAtomMass(i, 2.0);
forceField->setAtomParameters(i, (i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
......@@ -2258,7 +2258,7 @@ void testLangevinConstraints() {
//ReferencePlatform platform;
System system(numAtoms, numAtoms-1);
LangevinIntegrator integrator(temp, 2.0, 0.001);
StandardMMForceField* forceField = new StandardMMForceField(numAtoms, 0, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(numAtoms, 0, 0, 0, 0);
for (int i = 0; i < numAtoms; ++i) {
system.setAtomMass(i, mass);
forceField->setAtomParameters(i, (i%2 == 0 ? 0.2 : -0.2), 0.5, 5.0);
......@@ -2321,7 +2321,7 @@ void testVerletSingleBond( void ){
VerletIntegrator integrator(0.01);
StandardMMForceField* forceField = new StandardMMForceField(2, 1, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(2, 1, 0, 0, 0);
forceField->setBondParameters(0, 0, 1, 1.5, 1);
system.addForce(forceField);
......@@ -2416,7 +2416,7 @@ void testVerletConstraints() {
ReferencePlatform platform;
System system(numAtoms, numAtoms/2);
VerletIntegrator integrator(0.0005);
StandardMMForceField* forceField = new StandardMMForceField(numAtoms, 0, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(numAtoms, 0, 0, 0, 0);
for (int i = 0; i < numAtoms; ++i) {
system.setAtomMass(i, 1.0);
forceField->setAtomParameters(i, (i%2 == 0 ? 0.2 : -0.2), 0.5, 5.0);
......
......@@ -38,6 +38,8 @@
class _gpuContext;
namespace OpenMM {
class KernelImpl;
/**
* This Platform subclass uses CUDA implementations of the OpenMM kernels to run on NVidia GPUs.
......@@ -63,11 +65,13 @@ private:
class CudaPlatform::PlatformData {
public:
PlatformData(_gpuContext* gpu) : gpu(gpu), removeCM(false), useOBC(false) {
PlatformData(_gpuContext* gpu) : gpu(gpu), removeCM(false), useOBC(false), hasBonds(false), hasAngles(false),
hasPeriodicTorsions(false), hasRB(false), hasNonbonded(false), primaryKernel(NULL) {
}
_gpuContext* gpu;
bool removeCM;
bool useOBC;
KernelImpl* primaryKernel;
bool removeCM, useOBC;
bool hasBonds, hasAngles, hasPeriodicTorsions, hasRB, hasNonbonded;
int cmMotionFrequency;
};
......
......@@ -37,8 +37,16 @@ using namespace OpenMM;
KernelImpl* CudaKernelFactory::createKernelImpl(std::string name, const Platform& platform, OpenMMContextImpl& context) const {
CudaPlatform::PlatformData& data = *static_cast<CudaPlatform::PlatformData*>(context.getPlatformData());
if (name == CalcStandardMMForceFieldKernel::Name())
return new CudaCalcStandardMMForceFieldKernel(name, platform, data, context.getSystem());
if (name == CalcHarmonicBondForceKernel::Name())
return new CudaCalcHarmonicBondForceKernel(name, platform, data, context.getSystem());
if (name == CalcHarmonicAngleForceKernel::Name())
return new CudaCalcHarmonicAngleForceKernel(name, platform, data, context.getSystem());
if (name == CalcPeriodicTorsionForceKernel::Name())
return new CudaCalcPeriodicTorsionForceKernel(name, platform, data, context.getSystem());
if (name == CalcRBTorsionForceKernel::Name())
return new CudaCalcRBTorsionForceKernel(name, platform, data, context.getSystem());
if (name == CalcNonbondedForceKernel::Name())
return new CudaCalcNonbondedForceKernel(name, platform, data, context.getSystem());
if (name == CalcGBSAOBCForceFieldKernel::Name())
return new CudaCalcGBSAOBCForceFieldKernel(name, platform, data);
// if (name == IntegrateVerletStepKernel::Name())
......
......@@ -45,96 +45,193 @@ extern "C" int gpuSetConstants( gpuContext gpu );
using namespace OpenMM;
using namespace std;
CudaCalcStandardMMForceFieldKernel::~CudaCalcStandardMMForceFieldKernel() {
static void calcForces(OpenMMContextImpl& context, CudaPlatform::PlatformData& data) {
_gpuContext* gpu = data.gpu;
if (data.useOBC) {
kCalculateCDLJObcGbsaForces1(gpu);
kReduceObcGbsaBornForces(gpu);
kCalculateObcGbsaForces2(gpu);
}
else {
kClearForces(gpu);
kCalculateCDLJForces(gpu);
}
kCalculateLocalForces(gpu);
kReduceBornSumAndForces(gpu);
}
void CudaCalcStandardMMForceFieldKernel::initialize(const System& system, const StandardMMForceField& force, const std::vector<std::set<int> >& exclusions) {
numAtoms = force.getNumAtoms();
static double calcEnergy(OpenMMContextImpl& context, System& system) {
// We don't currently have GPU kernels to calculate energy, so instead we have the reference
// platform do it. This is VERY slow.
LangevinIntegrator integrator(0.0, 1.0, 0.0);
ReferencePlatform platform;
OpenMMContext refContext(system, integrator, platform);
const Stream& positions = context.getPositions();
double* posData = new double[positions.getSize()*3];
positions.saveToArray(posData);
vector<Vec3> pos(positions.getSize());
for (int i = 0; i < pos.size(); i++)
pos[i] = Vec3(posData[3*i], posData[3*i+1], posData[3*i+2]);
delete[] posData;
refContext.setPositions(pos);
return refContext.getState(State::Energy).getPotentialEnergy();
}
CudaCalcHarmonicBondForceKernel::~CudaCalcHarmonicBondForceKernel() {
}
void CudaCalcHarmonicBondForceKernel::initialize(const System& system, const HarmonicBondForce& force) {
if (data.primaryKernel == NULL)
data.primaryKernel = this;
data.hasBonds = true;
numBonds = force.getNumBonds();
vector<int> atom1(numBonds);
vector<int> atom2(numBonds);
vector<float> length(numBonds);
vector<float> k(numBonds);
for (int i = 0; i < numBonds; i++) {
double lengthValue, kValue;
force.getBondParameters(i, atom1[i], atom2[i], lengthValue, kValue);
length[i] = (float) lengthValue;
k[i] = (float) kValue;
}
gpuSetBondParameters(data.gpu, atom1, atom2, length, k);
}
void CudaCalcHarmonicBondForceKernel::executeForces(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
calcForces(context, data);
}
double CudaCalcHarmonicBondForceKernel::executeEnergy(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
return calcEnergy(context, system);
return 0.0;
}
CudaCalcHarmonicAngleForceKernel::~CudaCalcHarmonicAngleForceKernel() {
}
void CudaCalcHarmonicAngleForceKernel::initialize(const System& system, const HarmonicAngleForce& force) {
if (data.primaryKernel == NULL)
data.primaryKernel = this;
data.hasAngles = true;
numAngles = force.getNumAngles();
numPeriodicTorsions = force.getNumPeriodicTorsions();
numRBTorsions = force.getNumRBTorsions();
num14 = force.getNumNonbonded14();
const float RadiansToDegrees = 180.0/3.14159265;
_gpuContext* gpu = data.gpu;
// Initialize bonds.
{
vector<int> atom1(numBonds);
vector<int> atom2(numBonds);
vector<float> length(numBonds);
vector<float> k(numBonds);
for (int i = 0; i < numBonds; i++) {
double lengthValue, kValue;
force.getBondParameters(i, atom1[i], atom2[i], lengthValue, kValue);
length[i] = (float) lengthValue;
k[i] = (float) kValue;
}
gpuSetBondParameters(gpu, atom1, atom2, length, k);
}
// Initialize angles.
{
vector<int> atom1(numAngles);
vector<int> atom2(numAngles);
vector<int> atom3(numAngles);
vector<float> angle(numAngles);
vector<float> k(numAngles);
for (int i = 0; i < numAngles; i++) {
double angleValue, kValue;
force.getAngleParameters(i, atom1[i], atom2[i], atom3[i], angleValue, kValue);
angle[i] = (float) (angleValue*RadiansToDegrees);
k[i] = (float) kValue;
}
gpuSetBondAngleParameters(gpu, atom1, atom2, atom3, angle, k);
vector<int> atom1(numAngles);
vector<int> atom2(numAngles);
vector<int> atom3(numAngles);
vector<float> angle(numAngles);
vector<float> k(numAngles);
for (int i = 0; i < numAngles; i++) {
double angleValue, kValue;
force.getAngleParameters(i, atom1[i], atom2[i], atom3[i], angleValue, kValue);
angle[i] = (float) (angleValue*RadiansToDegrees);
k[i] = (float) kValue;
}
gpuSetBondAngleParameters(data.gpu, atom1, atom2, atom3, angle, k);
}
// Initialize periodic torsions.
{
vector<int> atom1(numPeriodicTorsions);
vector<int> atom2(numPeriodicTorsions);
vector<int> atom3(numPeriodicTorsions);
vector<int> atom4(numPeriodicTorsions);
vector<float> k(numPeriodicTorsions);
vector<float> phase(numPeriodicTorsions);
vector<int> periodicity(numPeriodicTorsions);
for (int i = 0; i < numPeriodicTorsions; i++) {
double kValue, phaseValue;
force.getPeriodicTorsionParameters(i, atom1[i], atom2[i], atom3[i], atom4[i], periodicity[i], phaseValue, kValue);
k[i] = (float) kValue;
phase[i] = (float) (phaseValue*RadiansToDegrees);
}
gpuSetDihedralParameters(gpu, atom1, atom2, atom3, atom4, k, phase, periodicity);
void CudaCalcHarmonicAngleForceKernel::executeForces(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
calcForces(context, data);
}
double CudaCalcHarmonicAngleForceKernel::executeEnergy(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
return calcEnergy(context, system);
return 0.0;
}
CudaCalcPeriodicTorsionForceKernel::~CudaCalcPeriodicTorsionForceKernel() {
}
void CudaCalcPeriodicTorsionForceKernel::initialize(const System& system, const PeriodicTorsionForce& force) {
if (data.primaryKernel == NULL)
data.primaryKernel = this;
data.hasPeriodicTorsions = true;
numTorsions = force.getNumTorsions();
const float RadiansToDegrees = 180.0/3.14159265;
vector<int> atom1(numTorsions);
vector<int> atom2(numTorsions);
vector<int> atom3(numTorsions);
vector<int> atom4(numTorsions);
vector<float> k(numTorsions);
vector<float> phase(numTorsions);
vector<int> periodicity(numTorsions);
for (int i = 0; i < numTorsions; i++) {
double kValue, phaseValue;
force.getTorsionParameters(i, atom1[i], atom2[i], atom3[i], atom4[i], periodicity[i], phaseValue, kValue);
k[i] = (float) kValue;
phase[i] = (float) (phaseValue*RadiansToDegrees);
}
// Initialize Ryckaert-Bellemans torsions.
{
vector<int> atom1(numRBTorsions);
vector<int> atom2(numRBTorsions);
vector<int> atom3(numRBTorsions);
vector<int> atom4(numRBTorsions);
vector<float> c0(numRBTorsions);
vector<float> c1(numRBTorsions);
vector<float> c2(numRBTorsions);
vector<float> c3(numRBTorsions);
vector<float> c4(numRBTorsions);
vector<float> c5(numRBTorsions);
for (int i = 0; i < numRBTorsions; i++) {
double c[6];
force.getRBTorsionParameters(i, atom1[i], atom2[i], atom3[i], atom4[i], c[0], c[1], c[2], c[3], c[4], c[5]);
c0[i] = (float) c[0];
c1[i] = (float) c[1];
c2[i] = (float) c[2];
c3[i] = (float) c[3];
c4[i] = (float) c[4];
c5[i] = (float) c[5];
}
gpuSetRbDihedralParameters(gpu, atom1, atom2, atom3, atom4, c0, c1, c2, c3, c4, c5);
gpuSetDihedralParameters(data.gpu, atom1, atom2, atom3, atom4, k, phase, periodicity);
}
void CudaCalcPeriodicTorsionForceKernel::executeForces(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
calcForces(context, data);
}
double CudaCalcPeriodicTorsionForceKernel::executeEnergy(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
return calcEnergy(context, system);
return 0.0;
}
CudaCalcRBTorsionForceKernel::~CudaCalcRBTorsionForceKernel() {
}
void CudaCalcRBTorsionForceKernel::initialize(const System& system, const RBTorsionForce& force) {
if (data.primaryKernel == NULL)
data.primaryKernel = this;
data.hasRB = true;
numTorsions = force.getNumTorsions();
vector<int> atom1(numTorsions);
vector<int> atom2(numTorsions);
vector<int> atom3(numTorsions);
vector<int> atom4(numTorsions);
vector<float> c0(numTorsions);
vector<float> c1(numTorsions);
vector<float> c2(numTorsions);
vector<float> c3(numTorsions);
vector<float> c4(numTorsions);
vector<float> c5(numTorsions);
for (int i = 0; i < numTorsions; i++) {
double c[6];
force.getTorsionParameters(i, atom1[i], atom2[i], atom3[i], atom4[i], c[0], c[1], c[2], c[3], c[4], c[5]);
c0[i] = (float) c[0];
c1[i] = (float) c[1];
c2[i] = (float) c[2];
c3[i] = (float) c[3];
c4[i] = (float) c[4];
c5[i] = (float) c[5];
}
gpuSetRbDihedralParameters(data.gpu, atom1, atom2, atom3, atom4, c0, c1, c2, c3, c4, c5);
}
void CudaCalcRBTorsionForceKernel::executeForces(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
calcForces(context, data);
}
double CudaCalcRBTorsionForceKernel::executeEnergy(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
return calcEnergy(context, system);
return 0.0;
}
CudaCalcNonbondedForceKernel::~CudaCalcNonbondedForceKernel() {
}
void CudaCalcNonbondedForceKernel::initialize(const System& system, const NonbondedForce& force, const std::vector<std::set<int> >& exclusions) {
if (data.primaryKernel == NULL)
data.primaryKernel = this;
data.hasNonbonded = true;
numAtoms = force.getNumAtoms();
num14 = force.getNumNonbonded14();
_gpuContext* gpu = data.gpu;
// Initialize nonbonded interactions.
......@@ -180,37 +277,15 @@ void CudaCalcStandardMMForceFieldKernel::initialize(const System& system, const
}
}
void CudaCalcStandardMMForceFieldKernel::executeForces(OpenMMContextImpl& context) {
_gpuContext* gpu = data.gpu;
if (data.useOBC) {
kCalculateCDLJObcGbsaForces1(gpu);
kReduceObcGbsaBornForces(gpu);
kCalculateObcGbsaForces2(gpu);
}
else {
kClearForces(gpu);
kCalculateCDLJForces(gpu);
}
kCalculateLocalForces(gpu);
kReduceBornSumAndForces(gpu);
void CudaCalcNonbondedForceKernel::executeForces(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
calcForces(context, data);
}
double CudaCalcStandardMMForceFieldKernel::executeEnergy(OpenMMContextImpl& context) {
// We don't currently have GPU kernels to calculate energy, so instead we have the reference
// platform do it. This is VERY slow.
LangevinIntegrator integrator(0.0, 1.0, 0.0);
ReferencePlatform platform;
OpenMMContext refContext(system, integrator, platform);
const Stream& positions = context.getPositions();
double* posData = new double[positions.getSize()*3];
positions.saveToArray(posData);
vector<Vec3> pos(positions.getSize());
for (int i = 0; i < pos.size(); i++)
pos[i] = Vec3(posData[3*i], posData[3*i+1], posData[3*i+2]);
delete[] posData;
refContext.setPositions(pos);
return refContext.getState(State::Energy).getPotentialEnergy();
double CudaCalcNonbondedForceKernel::executeEnergy(OpenMMContextImpl& context) {
if (data.primaryKernel == this)
return calcEnergy(context, system);
return 0.0;
}
CudaCalcGBSAOBCForceFieldKernel::~CudaCalcGBSAOBCForceFieldKernel() {
......@@ -281,6 +356,25 @@ void CudaIntegrateLangevinStepKernel::initialize(const System& system, const Lan
invMass2[i] = 1.0f/mass[atom2Index];
}
gpuSetShakeParameters(gpu, atom1, atom2, distance, invMass1, invMass2);
// Initialize any terms that haven't already been handled by a Force.
if (!data.hasBonds)
gpuSetBondParameters(gpu, vector<int>(), vector<int>(), vector<float>(), vector<float>());
if (!data.hasAngles)
gpuSetBondAngleParameters(gpu, vector<int>(), vector<int>(), vector<int>(), vector<float>(), vector<float>());
if (!data.hasPeriodicTorsions)
gpuSetDihedralParameters(gpu, vector<int>(), vector<int>(), vector<int>(), vector<int>(), vector<float>(), vector<float>(), vector<int>());
if (!data.hasRB)
gpuSetRbDihedralParameters(gpu, vector<int>(), vector<int>(), vector<int>(), vector<int>(), vector<float>(), vector<float>(),
vector<float>(), vector<float>(), vector<float>(), vector<float>());
if (!data.hasNonbonded) {
gpuSetCoulombParameters(gpu, 138.935485f, vector<int>(), vector<float>(), vector<float>(), vector<float>(), vector<char>(), vector<vector<int> >());
gpuSetLJ14Parameters(gpu, 138.935485f, 1.0f, vector<int>(), vector<int>(), vector<float>(), vector<float>(), vector<float>(), vector<float>());
}
// Finish initialization.
gpuBuildThreadBlockWorkList(gpu);
gpuBuildExclusionList(gpu);
gpuBuildOutputBuffers(gpu);
......
......@@ -45,24 +45,161 @@ class CudaVerletDynamics;
namespace OpenMM {
/**
* This kernel is invoked by HarmonicBondForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcHarmonicBondForceKernel : public CalcHarmonicBondForceKernel {
public:
CudaCalcHarmonicBondForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcHarmonicBondForceKernel(name, platform), data(data), system(system) {
}
~CudaCalcHarmonicBondForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the HarmonicBondForce this kernel will be used for
*/
void initialize(const System& system, const HarmonicBondForce& force);
/**
* Execute the kernel to calculate the forces.
*
* @param context the context in which to execute this kernel
*/
void executeForces(OpenMMContextImpl& context);
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
* @return the potential energy due to the HarmonicBondForce
*/
double executeEnergy(OpenMMContextImpl& context);
private:
int numBonds;
CudaPlatform::PlatformData& data;
System& system;
};
/**
* This kernel is invoked by HarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcHarmonicAngleForceKernel : public CalcHarmonicAngleForceKernel {
public:
CudaCalcHarmonicAngleForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcHarmonicAngleForceKernel(name, platform), data(data), system(system) {
}
~CudaCalcHarmonicAngleForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the HarmonicAngleForce this kernel will be used for
*/
void initialize(const System& system, const HarmonicAngleForce& force);
/**
* Execute the kernel to calculate the forces.
*
* @param context the context in which to execute this kernel
*/
void executeForces(OpenMMContextImpl& context);
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
* @return the potential energy due to the HarmonicAngleForce
*/
double executeEnergy(OpenMMContextImpl& context);
private:
int numAngles;
CudaPlatform::PlatformData& data;
System& system;
};
/**
* This kernel is invoked by PeriodicTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcPeriodicTorsionForceKernel : public CalcPeriodicTorsionForceKernel {
public:
CudaCalcPeriodicTorsionForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcPeriodicTorsionForceKernel(name, platform), data(data), system(system) {
}
~CudaCalcPeriodicTorsionForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the PeriodicTorsionForce this kernel will be used for
*/
void initialize(const System& system, const PeriodicTorsionForce& force);
/**
* Execute the kernel to calculate the forces.
*
* @param context the context in which to execute this kernel
*/
void executeForces(OpenMMContextImpl& context);
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
* @return the potential energy due to the PeriodicTorsionForce
*/
double executeEnergy(OpenMMContextImpl& context);
private:
int numTorsions;
CudaPlatform::PlatformData& data;
System& system;
};
/**
* This kernel is invoked by RBTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcRBTorsionForceKernel : public CalcRBTorsionForceKernel {
public:
CudaCalcRBTorsionForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcRBTorsionForceKernel(name, platform), data(data), system(system) {
}
~CudaCalcRBTorsionForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the RBTorsionForce this kernel will be used for
*/
void initialize(const System& system, const RBTorsionForce& force);
/**
* Execute the kernel to calculate the forces.
*
* @param context the context in which to execute this kernel
*/
void executeForces(OpenMMContextImpl& context);
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
* @return the potential energy due to the RBTorsionForce
*/
double executeEnergy(OpenMMContextImpl& context);
private:
int numTorsions;
CudaPlatform::PlatformData& data;
System& system;
};
/**
* This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class CudaCalcStandardMMForceFieldKernel : public CalcStandardMMForceFieldKernel {
class CudaCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
public:
CudaCalcStandardMMForceFieldKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcStandardMMForceFieldKernel(name, platform), data(data), system(system) {
CudaCalcNonbondedForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcNonbondedForceKernel(name, platform), data(data), system(system) {
}
~CudaCalcStandardMMForceFieldKernel();
~CudaCalcNonbondedForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the StandardMMForceField this kernel will be used for
* @param force the NonbondedForce this kernel will be used for
* @param exclusions the i'th element lists the indices of all atoms with which the i'th atom should not interact through
* nonbonded forces. Bonded 1-4 pairs are also included in this list, since they should be omitted from
* the standard nonbonded calculation.
*/
void initialize(const System& system, const StandardMMForceField& force, const std::vector<std::set<int> >& exclusions);
void initialize(const System& system, const NonbondedForce& force, const std::vector<std::set<int> >& exclusions);
/**
* Execute the kernel to calculate the forces.
*
......@@ -73,12 +210,12 @@ public:
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
* @return the potential energy due to the StandardMMForceField
* @return the potential energy due to the NonbondedForce
*/
double executeEnergy(OpenMMContextImpl& context);
private:
CudaPlatform::PlatformData& data;
int numAtoms, numBonds, numAngles, numPeriodicTorsions, numRBTorsions, num14;
int numAtoms, num14;
System& system;
};
......
......@@ -40,7 +40,11 @@ using namespace OpenMM;
CudaPlatform::CudaPlatform() {
CudaKernelFactory* factory = new CudaKernelFactory();
registerKernelFactory(CalcStandardMMForceFieldKernel::Name(), factory);
registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory);
registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory);
registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory);
registerKernelFactory(CalcRBTorsionForceKernel::Name(), factory);
registerKernelFactory(CalcNonbondedForceKernel::Name(), factory);
registerKernelFactory(CalcGBSAOBCForceFieldKernel::Name(), factory);
// registerKernelFactory(IntegrateVerletStepKernel::Name(), factory);
registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory);
......
......@@ -37,7 +37,8 @@
#include "CMMotionRemover.h"
#include "OpenMMContext.h"
#include "CudaPlatform.h"
#include "StandardMMForceField.h"
#include "HarmonicBondForce.h"
#include "NonbondedForce.h"
#include "System.h"
#include "LangevinIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
......@@ -63,13 +64,15 @@ void testMotionRemoval() {
CudaPlatform platform;
System system(numAtoms, 0);
LangevinIntegrator integrator(0.0, 1e-5, 0.01);
StandardMMForceField* forceField = new StandardMMForceField(numAtoms, 1, 0, 0, 0, 0);
HarmonicBondForce* bonds = new HarmonicBondForce(1);
bonds->setBondParameters(0, 2, 3, 2.0, 0.5);
system.addForce(bonds);
NonbondedForce* nonbonded = new NonbondedForce(numAtoms, 0);
for (int i = 0; i < numAtoms; ++i) {
system.setAtomMass(i, i+1);
forceField->setAtomParameters(i, (i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
nonbonded->setAtomParameters(i, (i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
}
forceField->setBondParameters(0, 2, 3, 2.0, 0.5);
system.addForce(forceField);
system.addForce(nonbonded);
CMMotionRemover* remover = new CMMotionRemover();
system.addForce(remover);
OpenMMContext context(system, integrator, platform);
......
......@@ -41,7 +41,7 @@
#include "LangevinIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
#include "../src/sfmt/SFMT.h"
#include "StandardMMForceField.h"
#include "NonbondedForce.h"
#include <iostream>
#include <vector>
......@@ -56,7 +56,7 @@ void testSingleAtom() {
system.setAtomMass(0, 2.0);
LangevinIntegrator integrator(0, 0.1, 0.01);
GBSAOBCForceField* forceField = new GBSAOBCForceField(1);
StandardMMForceField* standard = new StandardMMForceField(1, 0, 0, 0, 0, 0);
NonbondedForce* standard = new NonbondedForce(1, 0);
forceField->setAtomParameters(0, 0.5, 0.15, 1);
standard->setAtomParameters(0, 0.5, 1, 0);
system.addForce(forceField);
......@@ -80,7 +80,7 @@ void testForce() {
System system(numAtoms, 0);
LangevinIntegrator integrator(0, 0.1, 0.01);
GBSAOBCForceField* forceField = new GBSAOBCForceField(numAtoms);
StandardMMForceField* standard = new StandardMMForceField(numAtoms, 0, 0, 0, 0, 0);
NonbondedForce* standard = new NonbondedForce(numAtoms, 0);
for (int i = 0; i < numAtoms; ++i) {
double charge = i%2 == 0 ? -1 : 1;
forceField->setAtomParameters(i, charge, 0.15, 1);
......
/* -------------------------------------------------------------------------- *
* 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) 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 HarmonicAngleForce.
*/
#include "../../../tests/AssertionUtilities.h"
#include "OpenMMContext.h"
#include "CudaPlatform.h"
#include "HarmonicAngleForce.h"
#include "System.h"
#include "LangevinIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
using namespace std;
const double TOL = 1e-5;
void testAngles() {
CudaPlatform platform;
System system(4, 0);
LangevinIntegrator integrator(0.0, 0.1, 0.01);
HarmonicAngleForce* forceField = new HarmonicAngleForce(2);
forceField->setAngleParameters(0, 0, 1, 2, PI_M/3, 1.1);
forceField->setAngleParameters(1, 1, 2, 3, PI_M/2, 1.2);
system.addForce(forceField);
OpenMMContext context(system, integrator, platform);
vector<Vec3> positions(4);
positions[0] = Vec3(0, 1, 0);
positions[1] = Vec3(0, 0, 0);
positions[2] = Vec3(1, 0, 0);
positions[3] = Vec3(2, 1, 0);
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
const vector<Vec3>& forces = state.getForces();
double torque1 = 1.1*PI_M/6;
double torque2 = 1.2*PI_M/4;
ASSERT_EQUAL_VEC(Vec3(torque1, 0, 0), forces[0], TOL);
ASSERT_EQUAL_VEC(Vec3(-0.5*torque2, 0.5*torque2, 0), forces[3], TOL); // reduced by sqrt(2) due to the bond length, another sqrt(2) due to the angle
ASSERT_EQUAL_VEC(Vec3(forces[0][0]+forces[1][0]+forces[2][0]+forces[3][0], forces[0][1]+forces[1][1]+forces[2][1]+forces[3][1], forces[0][2]+forces[1][2]+forces[2][2]+forces[3][2]), Vec3(0, 0, 0), TOL);
ASSERT_EQUAL_TOL(0.5*1.1*(PI_M/6)*(PI_M/6) + 0.5*1.2*(PI_M/4)*(PI_M/4), state.getPotentialEnergy(), TOL);
}
int main() {
try {
testAngles();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
/* -------------------------------------------------------------------------- *
* 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) 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 HarmonicBondForce.
*/
#include "../../../tests/AssertionUtilities.h"
#include "OpenMMContext.h"
#include "CudaPlatform.h"
#include "HarmonicBondForce.h"
#include "System.h"
#include "LangevinIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
using namespace std;
const double TOL = 1e-5;
void testBonds() {
CudaPlatform platform;
System system(3, 0);
LangevinIntegrator integrator(0.0, 0.1, 0.01);
HarmonicBondForce* forceField = new HarmonicBondForce(2);
forceField->setBondParameters(0, 0, 1, 1.5, 0.8);
forceField->setBondParameters(1, 1, 2, 1.2, 0.7);
system.addForce(forceField);
OpenMMContext context(system, integrator, platform);
vector<Vec3> positions(3);
positions[0] = Vec3(0, 2, 0);
positions[1] = Vec3(0, 0, 0);
positions[2] = Vec3(1, 0, 0);
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
const vector<Vec3>& forces = state.getForces();
ASSERT_EQUAL_VEC(Vec3(0, -0.8*0.5, 0), forces[0], TOL);
ASSERT_EQUAL_VEC(Vec3(0.7*0.2, 0, 0), forces[2], TOL);
ASSERT_EQUAL_VEC(Vec3(-forces[0][0]-forces[2][0], -forces[0][1]-forces[2][1], -forces[0][2]-forces[2][2]), forces[1], TOL);
ASSERT_EQUAL_TOL(0.5*0.8*0.5*0.5 + 0.5*0.7*0.2*0.2, state.getPotentialEnergy(), TOL);
}
int main() {
try {
testBonds();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
......@@ -36,7 +36,8 @@
#include "../../../tests/AssertionUtilities.h"
#include "OpenMMContext.h"
#include "CudaPlatform.h"
#include "StandardMMForceField.h"
#include "HarmonicBondForce.h"
#include "NonbondedForce.h"
#include "System.h"
#include "LangevinIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
......@@ -55,7 +56,7 @@ void testSingleBond() {
system.setAtomMass(0, 2.0);
system.setAtomMass(1, 2.0);
LangevinIntegrator integrator(0, 0.1, 0.01);
StandardMMForceField* forceField = new StandardMMForceField(2, 1, 0, 0, 0, 0);
HarmonicBondForce* forceField = new HarmonicBondForce(1);
forceField->setBondParameters(0, 0, 1, 1.5, 1);
system.addForce(forceField);
OpenMMContext context(system, integrator, platform);
......@@ -99,7 +100,7 @@ void testTemperature() {
CudaPlatform platform;
System system(numAtoms, 0);
LangevinIntegrator integrator(temp, 2.0, 0.01);
StandardMMForceField* forceField = new StandardMMForceField(numAtoms, 0, 0, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(numAtoms, 0);
for (int i = 0; i < numAtoms; ++i) {
system.setAtomMass(i, 2.0);
forceField->setAtomParameters(i, (i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
......@@ -135,7 +136,7 @@ void testConstraints() {
CudaPlatform platform;
System system(numAtoms, numConstraints);
LangevinIntegrator integrator(temp, 2.0, 0.01);
StandardMMForceField* forceField = new StandardMMForceField(numAtoms, 0, 0, 0, 0, 0);
NonbondedForce* forceField = new NonbondedForce(numAtoms, 0);
for (int i = 0; i < numAtoms; ++i) {
system.setAtomMass(i, 10.0);
forceField->setAtomParameters(i, (i%2 == 0 ? 0.2 : -0.2), 0.5, 5.0);
......
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