Commit 7a36f461 authored by Mark Friedrichs's avatar Mark Friedrichs
Browse files

dded GB/VI to Cuda platform

Free energy plugin added
Plugin will not run w/ Obc or GB/VI forces unless line 2004 of gpu.cpp (gpu->sim.totalNonbondOutputBuffers  = 2*gpu->sim.nonbondOutputBuffers;) is commented in -- working on removing this constraint
Also unit tests for GB/VI currently fail 
parent 43ebedfb
...@@ -215,6 +215,8 @@ IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug) ...@@ -215,6 +215,8 @@ IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(STATIC_TARGET ${STATIC_TARGET}_d) SET(STATIC_TARGET ${STATIC_TARGET}_d)
ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug) ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
# used by plugin
SET(OPENMM_DIR ${CMAKE_CURRENT_SOURCE_DIR})
# These are all the places to search for header files which are # These are all the places to search for header files which are
# to be part of the API. # to be part of the API.
...@@ -303,6 +305,16 @@ IF(OPENMM_BUILD_OPENCL_LIB) ...@@ -303,6 +305,16 @@ IF(OPENMM_BUILD_OPENCL_LIB)
ADD_SUBDIRECTORY(platforms/opencl) ADD_SUBDIRECTORY(platforms/opencl)
ENDIF(OPENMM_BUILD_OPENCL_LIB) ENDIF(OPENMM_BUILD_OPENCL_LIB)
# FreeEnergy plugin
SET(OPENMM_BUILD_FREE_ENERGY_PLUGIN OFF CACHE BOOL "Build FreeEnergy plugin for Nvidia GPUs")
SET(OPENMM_BUILD_FREE_ENERGY_PATH)
IF(OPENMM_BUILD_FREE_ENERGY_PLUGIN)
SET(OPENMM_BUILD_FREE_ENERGY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/plugins/freeEnergy)
#MESSAGE("\nIn0 OpenMM: OPENMM_BUILD_FREE_ENERGY_PATH=" ${OPENMM_BUILD_FREE_ENERGY_PATH} )
ADD_SUBDIRECTORY(plugins/freeEnergy)
ENDIF(OPENMM_BUILD_FREE_ENERGY_PLUGIN)
INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${SHARED_TARGET}) INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${SHARED_TARGET})
INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${STATIC_TARGET}) INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${STATIC_TARGET})
FILE(GLOB CORE_HEADERS include/*.h */include/*.h) FILE(GLOB CORE_HEADERS include/*.h */include/*.h)
......
...@@ -378,7 +378,7 @@ public: ...@@ -378,7 +378,7 @@ public:
class CalcGBSAOBCForceKernel : public KernelImpl { class CalcGBSAOBCForceKernel : public KernelImpl {
public: public:
static std::string Name() { static std::string Name() {
return "CalcGBSAOBCForces"; return "CalcGBSAOBCForce";
} }
CalcGBSAOBCForceKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) { CalcGBSAOBCForceKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) {
} }
...@@ -410,7 +410,7 @@ public: ...@@ -410,7 +410,7 @@ public:
class CalcGBVIForceKernel : public KernelImpl { class CalcGBVIForceKernel : public KernelImpl {
public: public:
static std::string Name() { static std::string Name() {
return "CalcGBVIForces"; return "CalcGBVIForce";
} }
CalcGBVIForceKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) { CalcGBVIForceKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) {
} }
......
...@@ -107,6 +107,41 @@ public: ...@@ -107,6 +107,41 @@ public:
* @param gamma the gamma parameter * @param gamma the gamma parameter
*/ */
void setParticleParameters(int index, double charge, double radius, double gamma); void setParticleParameters(int index, double charge, double radius, double gamma);
/**
* Add a bond
*
* @param particle1 the index of the first particle
* @param particle2 the index of the second particle
* @param distance the distance between the two particles, measured in nm
* @return the index of the bond that was added
*/
int addBond(int particle1, int particle2, double distance);
/**
* Get the parameters defining a bond
*
* @param index the index of the bond for which to get parameters
* @param particle1 the index of the first particle involved in the bond
* @param particle2 the index of the second particle involved in the bond
* @param distance the distance between the two particles, measured in nm
*/
void getBondParameters(int index, int& particle1, int& particle2, double& distance) const;
/**
* Set 1-2 bonds
*
* @param index index of the bond for which to set parameters
* @param particle1 index of first atom in bond
* @param particle2 index of second atom in bond
* @param bondLength bond length
*/
void setBondParameters( int index, int particle1, int particle2, double bondLength);
/**
* Get number of bonds
*
* @return number of bonds
*/
int getNumBonds( void ) const;
/** /**
* Get the dielectric constant for the solvent. * Get the dielectric constant for the solvent.
*/ */
...@@ -155,7 +190,23 @@ private: ...@@ -155,7 +190,23 @@ private:
class ParticleInfo; class ParticleInfo;
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
double cutoffDistance, solventDielectric, soluteDielectric; double cutoffDistance, solventDielectric, soluteDielectric;
class BondInfo;
// Retarded visual studio compiler complains about being unable to
// export private stl class members.
// This stanza explains that it should temporarily shut up.
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4251)
#endif
std::vector<ParticleInfo> particles; std::vector<ParticleInfo> particles;
std::vector<BondInfo> bonds;
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
}; };
class GBVIForce::ParticleInfo { class GBVIForce::ParticleInfo {
...@@ -169,6 +220,20 @@ public: ...@@ -169,6 +220,20 @@ public:
} }
}; };
class GBVIForce::BondInfo {
public:
int particle1, particle2;
double bondLength;
BondInfo() {
bondLength = 0.0;
particle1 = -1;
particle2 = -1;
}
BondInfo(int atomIndex1, int atomIndex2, double bondLength) :
particle1(atomIndex1), particle2(atomIndex2), bondLength(bondLength) {
}
};
} // namespace OpenMM } // namespace OpenMM
#endif /*OPENMM_GBVIFORCEFIELD_H_*/ #endif /*OPENMM_GBVIFORCEFIELD_H_*/
...@@ -56,6 +56,9 @@ public: ...@@ -56,6 +56,9 @@ public:
void findScaledRadii( int numberOfParticles, const std::vector<std::vector<int> >& bondIndices, void findScaledRadii( int numberOfParticles, const std::vector<std::vector<int> >& bondIndices,
const std::vector<double> & bondLengths, std::vector<double> & scaledRadii) const; const std::vector<double> & bondLengths, std::vector<double> & scaledRadii) const;
// if bond info not set, then use bond forces/constraints
int getBondsFromForces(ContextImpl& context);
void updateContextState(ContextImpl& context) { void updateContextState(ContextImpl& context) {
// This force field doesn't update the state directly. // This force field doesn't update the state directly.
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/GBVIForce.h" #include "openmm/GBVIForce.h"
#include "openmm/internal/GBVIForceImpl.h" #include "openmm/internal/GBVIForceImpl.h"
#include <sstream>
using namespace OpenMM; using namespace OpenMM;
...@@ -72,6 +73,27 @@ void GBVIForce::setCutoffDistance(double distance) { ...@@ -72,6 +73,27 @@ void GBVIForce::setCutoffDistance(double distance) {
cutoffDistance = distance; cutoffDistance = distance;
} }
int GBVIForce::addBond(int particle1, int particle2, double bondLength) {
bonds.push_back(BondInfo(particle1, particle2, bondLength));
return bonds.size()-1;
}
void GBVIForce::setBondParameters( int index, int particle1, int particle2, double bondLength) {
bonds[index].particle1 = particle1;
bonds[index].particle2 = particle2;
bonds[index].bondLength = bondLength;
}
int GBVIForce::getNumBonds( void ) const {
return (int) bonds.size();
}
void GBVIForce::getBondParameters(int index, int& bondIndex1, int& bondIndex2, double& bondLength) const {
bondIndex1 = bonds[index].particle1;
bondIndex2 = bonds[index].particle2;
bondLength = bonds[index].bondLength;
}
ForceImpl* GBVIForce::createImpl() { ForceImpl* GBVIForce::createImpl() {
return new GBVIForceImpl(*this); return new GBVIForceImpl(*this);
} }
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <vector> #include <vector>
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
#include <sstream>
using namespace OpenMM; using namespace OpenMM;
using std::vector; using std::vector;
...@@ -48,51 +49,93 @@ void GBVIForceImpl::initialize(ContextImpl& context) { ...@@ -48,51 +49,93 @@ void GBVIForceImpl::initialize(ContextImpl& context) {
if (owner.getNumParticles() != context.getSystem().getNumParticles()) if (owner.getNumParticles() != context.getSystem().getNumParticles())
throw OpenMMException("GBVIForce must have exactly as many particles as the System it belongs to."); throw OpenMMException("GBVIForce must have exactly as many particles as the System it belongs to.");
// load 1-2 atom pairs along w/ bond distance using HarmonicBondForce & constraints
System& system = context.getSystem(); System& system = context.getSystem();
int numberOfParticles = owner.getNumParticles(); int numberOfParticles = owner.getNumParticles();
int numberOfBonds = owner.getNumBonds();
// load 1-2 atom pairs along w/ bond distance using HarmonicBondForce & constraints
// numberOfBonds < 1, indicating they were not set by the user
if( numberOfBonds < 1 ){
(void) fprintf( stderr, "Warning: no covalent bonds set for GB/VI force!\n" );
// getBondsFromForces( context );
// numberOfBonds = owner.getNumBonds();
}
std::vector< std::vector<int> > bondIndices;
bondIndices.resize( numberOfBonds );
std::vector<double> bondLengths;
bondLengths.resize( numberOfBonds );
for (int i = 0; i < numberOfBonds; i++) {
int particle1, particle2;
double bondLength;
owner.getBondParameters(i, particle1, particle2, bondLength);
if (particle1 < 0 || particle1 >= owner.getNumParticles()) {
std::stringstream msg;
msg << "GBVISoftcoreForce: Illegal particle index: ";
msg << particle1;
throw OpenMMException(msg.str());
}
if (particle2 < 0 || particle2 >= owner.getNumParticles()) {
std::stringstream msg;
msg << "GBVISoftcoreForce: Illegal particle index: ";
msg << particle2;
throw OpenMMException(msg.str());
}
if (bondLength < 0 ) {
std::stringstream msg;
msg << "GBVISoftcoreForce: negative bondlength: ";
msg << bondLength;
throw OpenMMException(msg.str());
}
bondIndices[i].push_back( particle1 );
bondIndices[i].push_back( particle2 );
bondLengths[i] = bondLength;
}
vector<double> scaledRadii;
scaledRadii.resize(numberOfParticles);
findScaledRadii( numberOfParticles, bondIndices, bondLengths, scaledRadii);
dynamic_cast<CalcGBVIForceKernel&>(kernel.getImpl()).initialize(context.getSystem(), owner, scaledRadii);
}
vector<vector<int> > bondIndices; int GBVIForceImpl::getBondsFromForces(ContextImpl& context) {
vector<double> bondLengths;
// load 1-2 atom pairs along w/ bond distance using HarmonicBondForce & constraints
System& system = context.getSystem();
for (int i = 0; i < system.getNumForces(); i++) { for (int i = 0; i < system.getNumForces(); i++) {
if (dynamic_cast<HarmonicBondForce*>(&system.getForce(i)) != NULL) { if (dynamic_cast<HarmonicBondForce*>(&system.getForce(i)) != NULL) {
const HarmonicBondForce& force = dynamic_cast<const HarmonicBondForce&>(system.getForce(i)); const HarmonicBondForce& force = dynamic_cast<const HarmonicBondForce&>(system.getForce(i));
bondIndices.resize(force.getNumBonds());
for (int j = 0; j < force.getNumBonds(); ++j) { for (int j = 0; j < force.getNumBonds(); ++j) {
int particle1, particle2; int particle1, particle2;
double length, k; double length, k;
force.getBondParameters(j, particle1, particle2, length, k); force.getBondParameters(j, particle1, particle2, length, k);
bondIndices[j].push_back(particle1); owner.addBond( particle1, particle2, length );
bondIndices[j].push_back(particle2);
bondLengths.push_back(length);
} }
break; break;
} }
} }
// Also treat constrained distances as bonds. // Also treat constrained distances as bonds if mass of one particle is < (2 + epsilon) (~2=deuterium)
int numBonds = bondIndices.size();
bondIndices.resize(numBonds+system.getNumConstraints());
for (int j = 0; j < system.getNumConstraints(); j++) { for (int j = 0; j < system.getNumConstraints(); j++) {
int particle1, particle2; int particle1, particle2;
double distance; double distance;
system.getConstraintParameters(j, particle1, particle2, distance); system.getConstraintParameters(j, particle1, particle2, distance);
bondIndices[j+numBonds].push_back(particle1); double mass1 = system.getParticleMass( particle1 );
bondIndices[j+numBonds].push_back(particle2); double mass2 = system.getParticleMass( particle2 );
bondLengths.push_back(distance); if( mass1 < 2.1 || mass2 < 2.1 ){
owner.addBond( particle1, particle2, distance );
}
} }
vector<double> scaledRadii;
scaledRadii.resize(numberOfParticles);
findScaledRadii( numberOfParticles, bondIndices, bondLengths, scaledRadii);
dynamic_cast<CalcGBVIForceKernel&>(kernel.getImpl()).initialize(context.getSystem(), owner, scaledRadii);
} }
#define GBVIDebug 1 #define GBVIDebug 0
void GBVIForceImpl::findScaledRadii( int numberOfParticles, const std::vector<std::vector<int> >& bondIndices, void GBVIForceImpl::findScaledRadii( int numberOfParticles, const std::vector<std::vector<int> >& bondIndices,
const std::vector<double> & bondLengths, std::vector<double> & scaledRadii) const { const std::vector<double> & bondLengths, std::vector<double> & scaledRadii) const {
......
...@@ -51,6 +51,8 @@ KernelImpl* CudaKernelFactory::createKernelImpl(std::string name, const Platform ...@@ -51,6 +51,8 @@ KernelImpl* CudaKernelFactory::createKernelImpl(std::string name, const Platform
return new CudaCalcCustomNonbondedForceKernel(name, platform, data, context.getSystem()); return new CudaCalcCustomNonbondedForceKernel(name, platform, data, context.getSystem());
if (name == CalcGBSAOBCForceKernel::Name()) if (name == CalcGBSAOBCForceKernel::Name())
return new CudaCalcGBSAOBCForceKernel(name, platform, data); return new CudaCalcGBSAOBCForceKernel(name, platform, data);
if (name == CalcGBVIForceKernel::Name())
return new CudaCalcGBVIForceKernel(name, platform, data);
if (name == IntegrateVerletStepKernel::Name()) if (name == IntegrateVerletStepKernel::Name())
return new CudaIntegrateVerletStepKernel(name, platform, data); return new CudaIntegrateVerletStepKernel(name, platform, data);
if (name == IntegrateLangevinStepKernel::Name()) if (name == IntegrateLangevinStepKernel::Name())
......
...@@ -51,11 +51,16 @@ void CudaCalcForcesAndEnergyKernel::beginForceComputation(ContextImpl& context) ...@@ -51,11 +51,16 @@ void CudaCalcForcesAndEnergyKernel::beginForceComputation(ContextImpl& context)
void CudaCalcForcesAndEnergyKernel::finishForceComputation(ContextImpl& context) { void CudaCalcForcesAndEnergyKernel::finishForceComputation(ContextImpl& context) {
_gpuContext* gpu = data.gpu; _gpuContext* gpu = data.gpu;
if (gpu->bIncludeGBSA) {
if (gpu->bIncludeGBSA || gpu->bIncludeGBVI) {
gpu->bRecalculateBornRadii = true; gpu->bRecalculateBornRadii = true;
kCalculateCDLJObcGbsaForces1(gpu); kCalculateCDLJObcGbsaForces1(gpu);
kReduceObcGbsaBornForces(gpu); kReduceObcGbsaBornForces(gpu);
if (gpu->bIncludeGBSA ) {
kCalculateObcGbsaForces2(gpu); kCalculateObcGbsaForces2(gpu);
} else {
kCalculateGBVIForces2(gpu);
}
} }
else if (data.hasNonbonded) else if (data.hasNonbonded)
kCalculateCDLJForces(gpu); kCalculateCDLJForces(gpu);
...@@ -75,19 +80,21 @@ void CudaCalcForcesAndEnergyKernel::beginEnergyComputation(ContextImpl& context) ...@@ -75,19 +80,21 @@ void CudaCalcForcesAndEnergyKernel::beginEnergyComputation(ContextImpl& context)
double CudaCalcForcesAndEnergyKernel::finishEnergyComputation(ContextImpl& context) { double CudaCalcForcesAndEnergyKernel::finishEnergyComputation(ContextImpl& context) {
_gpuContext* gpu = data.gpu; _gpuContext* gpu = data.gpu;
if (gpu->bIncludeGBSA) { if (gpu->bIncludeGBSA || gpu->bIncludeGBVI) {
gpu->bRecalculateBornRadii = true; gpu->bRecalculateBornRadii = true;
kCalculateCDLJObcGbsaForces1(gpu); kCalculateCDLJObcGbsaForces1(gpu);
kReduceObcGbsaBornForces(gpu); kReduceObcGbsaBornForces(gpu);
if (gpu->bIncludeGBSA ) {
kCalculateObcGbsaForces2(gpu); kCalculateObcGbsaForces2(gpu);
} else {
kCalculateGBVIForces2(gpu);
}
} }
else if (data.hasNonbonded) else if (data.hasNonbonded)
kCalculateCDLJForces(gpu); kCalculateCDLJForces(gpu);
if (data.hasCustomNonbonded) if (data.hasCustomNonbonded)
kCalculateCustomNonbondedForces(gpu, data.hasNonbonded); kCalculateCustomNonbondedForces(gpu, data.hasNonbonded);
kCalculateLocalForces(gpu); kCalculateLocalForces(gpu);
if (gpu->bIncludeGBSA)
kReduceBornSumAndForces(gpu);
return kReduceEnergy(gpu)+data.ewaldSelfEnergy; return kReduceEnergy(gpu)+data.ewaldSelfEnergy;
} }
...@@ -533,6 +540,38 @@ void CudaCalcGBSAOBCForceKernel::initialize(const System& system, const GBSAOBCF ...@@ -533,6 +540,38 @@ void CudaCalcGBSAOBCForceKernel::initialize(const System& system, const GBSAOBCF
void CudaCalcGBSAOBCForceKernel::executeForces(ContextImpl& context) { void CudaCalcGBSAOBCForceKernel::executeForces(ContextImpl& context) {
} }
CudaCalcGBVIForceKernel::~CudaCalcGBVIForceKernel() {
}
void CudaCalcGBVIForceKernel::initialize(const System& system, const GBVIForce& force, const std::vector<double> & inputScaledRadii) {
int numParticles = system.getNumParticles();
_gpuContext* gpu = data.gpu;
vector<int> particle(numParticles);
vector<float> radius(numParticles);
vector<float> scaledRadii(numParticles);
vector<float> gammas(numParticles);
for (int i = 0; i < numParticles; i++) {
double charge, particleRadius, gamma, bornRadiusScaleFactor;
force.getParticleParameters(i, charge, particleRadius, gamma );
particle[i] = i;
radius[i] = (float) particleRadius;
gammas[i] = (float) gamma;
scaledRadii[i] = (float) inputScaledRadii[i];
}
gpuSetGBVIParameters(gpu, (float) force.getSoluteDielectric(), (float) force.getSolventDielectric(), particle,
radius, gammas, scaledRadii );
}
void CudaCalcGBVIForceKernel::executeForces(ContextImpl& context) {
}
double CudaCalcGBVIForceKernel::executeEnergy(ContextImpl& context) {
return 0.0;
}
static void initializeIntegration(const System& system, CudaPlatform::PlatformData& data, const Integrator& integrator) { static void initializeIntegration(const System& system, CudaPlatform::PlatformData& data, const Integrator& integrator) {
// Initialize any terms that haven't already been handled by a Force. // Initialize any terms that haven't already been handled by a Force.
...@@ -643,7 +682,6 @@ void CudaIntegrateLangevinStepKernel::execute(ContextImpl& context, const Langev ...@@ -643,7 +682,6 @@ void CudaIntegrateLangevinStepKernel::execute(ContextImpl& context, const Langev
double stepSize = integrator.getStepSize(); double stepSize = integrator.getStepSize();
if (temperature != prevTemp || friction != prevFriction || stepSize != prevStepSize) { if (temperature != prevTemp || friction != prevFriction || stepSize != prevStepSize) {
// Initialize the GPU parameters. // Initialize the GPU parameters.
double tau = (friction == 0.0 ? 0.0 : 1.0/friction); double tau = (friction == 0.0 ? 0.0 : 1.0/friction);
gpuSetLangevinIntegrationParameters(gpu, (float) tau, (float) stepSize, (float) temperature, 0.0f); gpuSetLangevinIntegrationParameters(gpu, (float) tau, (float) stepSize, (float) temperature, 0.0f);
gpuSetConstants(gpu); gpuSetConstants(gpu);
......
...@@ -389,6 +389,39 @@ private: ...@@ -389,6 +389,39 @@ private:
CudaPlatform::PlatformData& data; CudaPlatform::PlatformData& data;
}; };
/**
* This kernel is invoked by GBVIForce to calculate the forces acting on the system.
*/
class CudaCalcGBVIForceKernel : public CalcGBVIForceKernel {
public:
CudaCalcGBVIForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : CalcGBVIForceKernel(name, platform), data(data) {
}
~CudaCalcGBVIForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the GBVIForce this kernel will be used for
* @param scaledRadii the scaled radii (Eq. 5 of Labute paper)
*/
void initialize(const System& system, const GBVIForce& force, const std::vector<double> & scaledRadii);
/**
* Execute the kernel to calculate the forces.
*
* @param context the context in which to execute this kernel
*/
void executeForces(ContextImpl& 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 GBVIForce
*/
double executeEnergy(ContextImpl& context);
private:
CudaPlatform::PlatformData& data;
};
/** /**
* This kernel is invoked by VerletIntegrator to take one time step. * This kernel is invoked by VerletIntegrator to take one time step.
*/ */
......
...@@ -30,16 +30,22 @@ ...@@ -30,16 +30,22 @@
extern void kClearForces(gpuContext gpu); extern void kClearForces(gpuContext gpu);
extern void kClearEnergy(gpuContext gpu); extern void kClearEnergy(gpuContext gpu);
extern void kClearBornForces(gpuContext gpu); extern void kClearBornForces(gpuContext gpu);
extern void kClearObcGbsaBornSum(gpuContext gpu);
extern void kCalculateObcGbsaBornSum(gpuContext gpu); extern void kCalculateObcGbsaBornSum(gpuContext gpu);
extern void kReduceObcGbsaBornSum(gpuContext gpu); extern void kReduceObcGbsaBornSum(gpuContext gpu);
extern void kCalculateGBVIBornSum(gpuContext gpu);
extern void kReduceGBVIBornSum(gpuContext gpu);
extern void kClearGBVIBornSum( gpuContext gpu );
extern void kGenerateRandoms(gpuContext gpu); extern void kGenerateRandoms(gpuContext gpu);
// Main loop // Main loop
extern void kCalculateCDLJObcGbsaForces1(gpuContext gpu); extern void kCalculateCDLJObcGbsaForces1(gpuContext gpu);
extern void kCalculateCDLJGBVIForces1(gpuContext gpu);
extern void kCalculateCDLJForces(gpuContext gpu); extern void kCalculateCDLJForces(gpuContext gpu);
extern void kCalculateCustomNonbondedForces(gpuContext gpu, bool neighborListValid); extern void kCalculateCustomNonbondedForces(gpuContext gpu, bool neighborListValid);
extern void kReduceObcGbsaBornForces(gpuContext gpu); extern void kReduceObcGbsaBornForces(gpuContext gpu);
extern void kCalculateObcGbsaForces2(gpuContext gpu); extern void kCalculateObcGbsaForces2(gpuContext gpu);
extern void kCalculateGBVIForces2(gpuContext gpu);
extern void kCalculateLocalForces(gpuContext gpu); extern void kCalculateLocalForces(gpuContext gpu);
extern void kCalculateAndersenThermostat(gpuContext gpu); extern void kCalculateAndersenThermostat(gpuContext gpu);
extern void kReduceBornSumAndForces(gpuContext gpu); extern void kReduceBornSumAndForces(gpuContext gpu);
...@@ -73,8 +79,12 @@ extern void SetCalculateLocalForcesSim(gpuContext gpu); ...@@ -73,8 +79,12 @@ extern void SetCalculateLocalForcesSim(gpuContext gpu);
extern void GetCalculateLocalForcesSim(gpuContext gpu); extern void GetCalculateLocalForcesSim(gpuContext gpu);
extern void SetCalculateObcGbsaBornSumSim(gpuContext gpu); extern void SetCalculateObcGbsaBornSumSim(gpuContext gpu);
extern void GetCalculateObcGbsaBornSumSim(gpuContext gpu); extern void GetCalculateObcGbsaBornSumSim(gpuContext gpu);
extern void SetCalculateGBVIBornSumSim(gpuContext gpu);
extern void GetCalculateGBVIBornSumSim(gpuContext gpu);
extern void SetCalculateObcGbsaForces2Sim(gpuContext gpu); extern void SetCalculateObcGbsaForces2Sim(gpuContext gpu);
extern void GetCalculateObcGbsaForces2Sim(gpuContext gpu); extern void GetCalculateObcGbsaForces2Sim(gpuContext gpu);
extern void SetCalculateGBVIForces2Sim(gpuContext gpu);
extern void GetCalculateGBVIForces2Sim(gpuContext gpu);
extern void SetCalculateAndersenThermostatSim(gpuContext gpu); extern void SetCalculateAndersenThermostatSim(gpuContext gpu);
extern void GetCalculateAndersenThermostatSim(gpuContext gpu); extern void GetCalculateAndersenThermostatSim(gpuContext gpu);
extern void SetCalculatePMESim(gpuContext gpu); extern void SetCalculatePMESim(gpuContext gpu);
......
...@@ -524,7 +524,8 @@ void gpuSetLJ14Parameters(gpuContext gpu, float epsfac, float fudge, const vecto ...@@ -524,7 +524,8 @@ void gpuSetLJ14Parameters(gpuContext gpu, float epsfac, float fudge, const vecto
psLJ14Parameter->Upload(); psLJ14Parameter->Upload();
} }
static void setExclusions(gpuContext gpu, const vector<vector<int> >& exclusions) { extern "C"
void setExclusions(gpuContext gpu, const vector<vector<int> >& exclusions) {
if (gpu->exclusions.size() > 0) { if (gpu->exclusions.size() > 0) {
bool ok = (exclusions.size() == gpu->exclusions.size()); bool ok = (exclusions.size() == gpu->exclusions.size());
for (int i = 0; i < exclusions.size() && ok; i++) { for (int i = 0; i < exclusions.size() && ok; i++) {
...@@ -569,7 +570,8 @@ void gpuSetCoulombParameters(gpuContext gpu, float epsfac, const vector<int>& at ...@@ -569,7 +570,8 @@ void gpuSetCoulombParameters(gpuContext gpu, float epsfac, const vector<int>& at
} }
// Dummy out extra atom data // Dummy out extra atom data
for (unsigned int i = coulombs; i < gpu->sim.paddedNumberOfAtoms; i++)
for (unsigned int i = gpu->natoms; i < gpu->sim.paddedNumberOfAtoms; i++)
{ {
(*gpu->psPosq4)[i].x = 100000.0f + i * 10.0f; (*gpu->psPosq4)[i].x = 100000.0f + i * 10.0f;
(*gpu->psPosq4)[i].y = 100000.0f + i * 10.0f; (*gpu->psPosq4)[i].y = 100000.0f + i * 10.0f;
...@@ -578,7 +580,6 @@ void gpuSetCoulombParameters(gpuContext gpu, float epsfac, const vector<int>& at ...@@ -578,7 +580,6 @@ void gpuSetCoulombParameters(gpuContext gpu, float epsfac, const vector<int>& at
(*gpu->psSigEps2)[i].x = 0.0f; (*gpu->psSigEps2)[i].x = 0.0f;
(*gpu->psSigEps2)[i].y = 0.0f; (*gpu->psSigEps2)[i].y = 0.0f;
} }
gpu->psPosq4->Upload(); gpu->psPosq4->Upload();
gpu->psSigEps2->Upload(); gpu->psSigEps2->Upload();
} }
...@@ -916,6 +917,53 @@ void gpuSetObcParameters(gpuContext gpu, float innerDielectric, float solventDie ...@@ -916,6 +917,53 @@ void gpuSetObcParameters(gpuContext gpu, float innerDielectric, float solventDie
gpu->sim.preFactor = 2.0f*electricConstant*((1.0f/innerDielectric)-(1.0f/solventDielectric))*gpu->sim.forceConversionFactor; gpu->sim.preFactor = 2.0f*electricConstant*((1.0f/innerDielectric)-(1.0f/solventDielectric))*gpu->sim.forceConversionFactor;
} }
extern "C"
void gpuSetGBVIParameters(gpuContext gpu, float innerDielectric, float solventDielectric, const vector<int>& atom, const vector<float>& radius,
const vector<float>& gamma, const vector<float>& scaledRadii )
{
unsigned int atoms = atom.size();
gpu->bIncludeGBVI = true;
double tau = ((1.0f/innerDielectric)-(1.0f/solventDielectric));
for (unsigned int i = 0; i < atoms; i++)
{
(*gpu->psGBVIData)[i].x = radius[i];
(*gpu->psGBVIData)[i].y = scaledRadii[i];
(*gpu->psGBVIData)[i].z = tau*gamma[i];
(*gpu->psGBVIData)[i].w = 1.0f;
(*gpu->psObcData)[i].x = radius[i];
(*gpu->psObcData)[i].y = 0.9f*radius[i];
#undef DUMP_PARAMETERS
#define DUMP_PARAMETERS 0
#if (DUMP_PARAMETERS == 1)
(void) fprintf( stderr,"GBVI param: %5u R=%14.7e scaledR=%14.7e gamma*tau=%14.7e bornRadiusScaleFactor=%14.7e\n",
i, (*gpu->psGBVIData)[i].x, (*gpu->psGBVIData)[i].y,
(*gpu->psGBVIData)[i].z, (*gpu->psGBVIData)[i].w );
#endif
}
//(void) fprintf( stderr, "gpuSetGBVIParameters: setting Obc parameters!!!! should be removed.\n" );
// Dummy out extra atom data
for (unsigned int i = atoms; i < gpu->sim.paddedNumberOfAtoms; i++)
{
(*gpu->psBornRadii)[i] = 0.2f;
(*gpu->psGBVIData)[i].x = 0.01f;
(*gpu->psGBVIData)[i].y = 0.01f;
(*gpu->psGBVIData)[i].z = 0.01f;
(*gpu->psGBVIData)[i].w = 1.00f;
}
gpu->psBornRadii->Upload();
gpu->psGBVIData->Upload();
gpu->psObcData->Upload();
gpu->sim.preFactor = 2.0f*electricConstant*((1.0f/innerDielectric)-(1.0f/solventDielectric))*gpu->sim.forceConversionFactor;
#if (DUMP_PARAMETERS == 1)
(void) fprintf( stderr, "gpuSetGBVIParameters: preFactor=%14.6e elecCnstnt=%.4f frcCnvrsnFctr=%.4f tau=%.4f.\n",
gpu->sim.preFactor, 2.0f*electricConstant, gpu->sim.forceConversionFactor, ((1.0f/innerDielectric)-(1.0f/solventDielectric)) );
#endif
}
static void markShakeClusterInvalid(ShakeCluster& cluster, map<int, ShakeCluster>& allClusters, vector<bool>& invalidForShake) static void markShakeClusterInvalid(ShakeCluster& cluster, map<int, ShakeCluster>& allClusters, vector<bool>& invalidForShake)
{ {
cluster.valid = false; cluster.valid = false;
...@@ -1435,6 +1483,8 @@ int gpuAllocateInitialBuffers(gpuContext gpu) ...@@ -1435,6 +1483,8 @@ int gpuAllocateInitialBuffers(gpuContext gpu)
gpu->sim.pAttr = gpu->psSigEps2->_pDevStream[0]; gpu->sim.pAttr = gpu->psSigEps2->_pDevStream[0];
gpu->psObcData = new CUDAStream<float2>(gpu->sim.paddedNumberOfAtoms, 1, "ObcData"); gpu->psObcData = new CUDAStream<float2>(gpu->sim.paddedNumberOfAtoms, 1, "ObcData");
gpu->sim.pObcData = gpu->psObcData->_pDevStream[0]; gpu->sim.pObcData = gpu->psObcData->_pDevStream[0];
gpu->psGBVIData = new CUDAStream<float4>(gpu->sim.paddedNumberOfAtoms, 1, "GBVIData");
gpu->sim.pGBVIData = gpu->psGBVIData->_pDevStream[0];
gpu->psStepSize = new CUDAStream<float2>(1, 1, "StepSize"); gpu->psStepSize = new CUDAStream<float2>(1, 1, "StepSize");
gpu->sim.pStepSize = gpu->psStepSize->_pDevStream[0]; gpu->sim.pStepSize = gpu->psStepSize->_pDevStream[0];
(*gpu->psStepSize)[0] = make_float2(0.0f, 0.0f); (*gpu->psStepSize)[0] = make_float2(0.0f, 0.0f);
...@@ -1671,6 +1721,7 @@ void* gpuInit(int numAtoms, unsigned int device, bool useBlockingSync) ...@@ -1671,6 +1721,7 @@ void* gpuInit(int numAtoms, unsigned int device, bool useBlockingSync)
gpu->bRemoveCM = false; gpu->bRemoveCM = false;
gpu->bRecalculateBornRadii = true; gpu->bRecalculateBornRadii = true;
gpu->bIncludeGBSA = false; gpu->bIncludeGBSA = false;
gpu->bIncludeGBVI = false;
gpuInitializeRandoms(gpu); gpuInitializeRandoms(gpu);
// To be determined later // To be determined later
...@@ -1883,6 +1934,7 @@ void gpuShutDown(gpuContext gpu) ...@@ -1883,6 +1934,7 @@ void gpuShutDown(gpuContext gpu)
if (gpu->psTabulatedErfc != NULL) if (gpu->psTabulatedErfc != NULL)
delete gpu->psTabulatedErfc; delete gpu->psTabulatedErfc;
delete gpu->psObcData; delete gpu->psObcData;
delete gpu->psGBVIData;
delete gpu->psObcChain; delete gpu->psObcChain;
delete gpu->psBornForce; delete gpu->psBornForce;
delete gpu->psBornRadii; delete gpu->psBornRadii;
...@@ -1957,10 +2009,10 @@ int gpuBuildOutputBuffers(gpuContext gpu) ...@@ -1957,10 +2009,10 @@ int gpuBuildOutputBuffers(gpuContext gpu)
gpu->bOutputBufferPerWarp = false; gpu->bOutputBufferPerWarp = false;
gpu->sim.nonbondOutputBuffers = gpu->sim.paddedNumberOfAtoms / GRID; gpu->sim.nonbondOutputBuffers = gpu->sim.paddedNumberOfAtoms / GRID;
} }
gpu->sim.totalNonbondOutputBuffers = (gpu->bIncludeGBSA ? 2 * gpu->sim.nonbondOutputBuffers : gpu->sim.nonbondOutputBuffers); gpu->sim.totalNonbondOutputBuffers = ( (gpu->bIncludeGBSA || gpu->bIncludeGBVI) ? 2 * gpu->sim.nonbondOutputBuffers : gpu->sim.nonbondOutputBuffers);
//gpu->sim.totalNonbondOutputBuffers = 2*gpu->sim.nonbondOutputBuffers;
gpu->sim.outputBuffers = gpu->sim.totalNonbondOutputBuffers; gpu->sim.outputBuffers = gpu->sim.totalNonbondOutputBuffers;
unsigned int outputBuffers = gpu->sim.totalNonbondOutputBuffers; unsigned int outputBuffers = gpu->sim.totalNonbondOutputBuffers;
for (unsigned int i = 0; i < gpu->sim.paddedNumberOfAtoms; i++) for (unsigned int i = 0; i < gpu->sim.paddedNumberOfAtoms; i++)
{ {
...@@ -2234,7 +2286,9 @@ int gpuSetConstants(gpuContext gpu) ...@@ -2234,7 +2286,9 @@ int gpuSetConstants(gpuContext gpu)
SetCalculateCustomNonbondedForcesSim(gpu); SetCalculateCustomNonbondedForcesSim(gpu);
SetCalculateLocalForcesSim(gpu); SetCalculateLocalForcesSim(gpu);
SetCalculateObcGbsaBornSumSim(gpu); SetCalculateObcGbsaBornSumSim(gpu);
SetCalculateGBVIBornSumSim(gpu);
SetCalculateObcGbsaForces2Sim(gpu); SetCalculateObcGbsaForces2Sim(gpu);
SetCalculateGBVIForces2Sim(gpu);
SetCalculateAndersenThermostatSim(gpu); SetCalculateAndersenThermostatSim(gpu);
SetCalculatePMESim(gpu); SetCalculatePMESim(gpu);
SetForcesSim(gpu); SetForcesSim(gpu);
......
...@@ -62,7 +62,6 @@ enum SM_VERSION ...@@ -62,7 +62,6 @@ enum SM_VERSION
* to gromacs functions*/ * to gromacs functions*/
struct _gpuContext { struct _gpuContext {
//Cache this here so that it doesn't //Cache this here so that it doesn't
//have to be repeatedly passed around //have to be repeatedly passed around
int natoms; int natoms;
...@@ -87,6 +86,7 @@ struct _gpuContext { ...@@ -87,6 +86,7 @@ struct _gpuContext {
bool bRecalculateBornRadii; bool bRecalculateBornRadii;
bool bOutputBufferPerWarp; bool bOutputBufferPerWarp;
bool bIncludeGBSA; bool bIncludeGBSA;
bool bIncludeGBVI;
bool tabulatedFunctionsChanged; bool tabulatedFunctionsChanged;
unsigned long seed; unsigned long seed;
SM_VERSION sm_version; SM_VERSION sm_version;
...@@ -114,6 +114,7 @@ struct _gpuContext { ...@@ -114,6 +114,7 @@ struct _gpuContext {
CUDAStream<int>* psPmeAtomRange; // The range of sorted atoms at each grid point CUDAStream<int>* psPmeAtomRange; // The range of sorted atoms at each grid point
CUDAStream<float2>* psPmeAtomGridIndex; // The grid point each atom is at CUDAStream<float2>* psPmeAtomGridIndex; // The grid point each atom is at
CUDAStream<float2>* psObcData; CUDAStream<float2>* psObcData;
CUDAStream<float4>* psGBVIData;
CUDAStream<float>* psObcChain; CUDAStream<float>* psObcChain;
CUDAStream<float>* psBornForce; CUDAStream<float>* psBornForce;
CUDAStream<float>* psBornRadii; CUDAStream<float>* psBornRadii;
...@@ -223,6 +224,10 @@ void gpuSetPeriodicBoxSize(gpuContext gpu, float xsize, float ysize, float zsize ...@@ -223,6 +224,10 @@ void gpuSetPeriodicBoxSize(gpuContext gpu, float xsize, float ysize, float zsize
extern "C" extern "C"
void gpuSetObcParameters(gpuContext gpu, float innerDielectric, float solventDielectric, const std::vector<float>& radius, const std::vector<float>& scale, const std::vector<float>& charge); void gpuSetObcParameters(gpuContext gpu, float innerDielectric, float solventDielectric, const std::vector<float>& radius, const std::vector<float>& scale, const std::vector<float>& charge);
extern "C"
void gpuSetGBVIParameters(gpuContext gpu, float innerDielectric, float solventDielectric, const std::vector<int>& atom, const std::vector<float>& radius,
const std::vector<float>& gammas, const std::vector<float>& scaledRadii);
extern "C" extern "C"
void gpuSetConstraintParameters(gpuContext gpu, const std::vector<int>& atom1, const std::vector<int>& atom2, const std::vector<float>& distance, void gpuSetConstraintParameters(gpuContext gpu, const std::vector<int>& atom1, const std::vector<int>& atom2, const std::vector<float>& distance,
const std::vector<float>& invMass1, const std::vector<float>& invMass2, float constraintTolerance); const std::vector<float>& invMass1, const std::vector<float>& invMass2, float constraintTolerance);
...@@ -275,4 +280,7 @@ int gpuSetConstants(gpuContext gpu); ...@@ -275,4 +280,7 @@ int gpuSetConstants(gpuContext gpu);
extern "C" extern "C"
void gpuReorderAtoms(gpuContext gpu); void gpuReorderAtoms(gpuContext gpu);
extern "C"
void setExclusions(gpuContext gpu, const std::vector<std::vector<int> >& exclusions);
#endif //__GPUTYPES_H__ #endif //__GPUTYPES_H__
...@@ -55,6 +55,7 @@ void SetCalculateCDLJObcGbsaForces1Sim(gpuContext gpu) ...@@ -55,6 +55,7 @@ void SetCalculateCDLJObcGbsaForces1Sim(gpuContext gpu)
cudaError_t status; cudaError_t status;
status = cudaMemcpyToSymbol(cSim, &gpu->sim, sizeof(cudaGmxSimulation)); status = cudaMemcpyToSymbol(cSim, &gpu->sim, sizeof(cudaGmxSimulation));
RTERROR(status, "cudaMemcpyToSymbol: SetSim copy to cSim failed"); RTERROR(status, "cudaMemcpyToSymbol: SetSim copy to cSim failed");
} }
void GetCalculateCDLJObcGbsaForces1Sim(gpuContext gpu) void GetCalculateCDLJObcGbsaForces1Sim(gpuContext gpu)
...@@ -142,15 +143,22 @@ void kCalculateCDLJObcGbsaForces1(gpuContext gpu) ...@@ -142,15 +143,22 @@ void kCalculateCDLJObcGbsaForces1(gpuContext gpu)
case NO_CUTOFF: case NO_CUTOFF:
if (gpu->bRecalculateBornRadii) if (gpu->bRecalculateBornRadii)
{ {
if( gpu->bIncludeGBVI ){
kCalculateGBVIBornSum(gpu);
kReduceGBVIBornSum(gpu);
} else {
kCalculateObcGbsaBornSum(gpu); kCalculateObcGbsaBornSum(gpu);
kReduceObcGbsaBornSum(gpu); kReduceObcGbsaBornSum(gpu);
} }
}
if (gpu->bOutputBufferPerWarp) if (gpu->bOutputBufferPerWarp)
kCalculateCDLJObcGbsaN2ByWarpForces1_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.nonbond_threads_per_block, kCalculateCDLJObcGbsaN2ByWarpForces1_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.nonbond_threads_per_block,
sizeof(Atom)*gpu->sim.nonbond_threads_per_block>>>(gpu->sim.pWorkUnit); sizeof(Atom)*gpu->sim.nonbond_threads_per_block>>>(gpu->sim.pWorkUnit);
else else
kCalculateCDLJObcGbsaN2Forces1_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.nonbond_threads_per_block, kCalculateCDLJObcGbsaN2Forces1_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.nonbond_threads_per_block,
sizeof(Atom)*gpu->sim.nonbond_threads_per_block>>>(gpu->sim.pWorkUnit); sizeof(Atom)*gpu->sim.nonbond_threads_per_block>>>(gpu->sim.pWorkUnit);
LAUNCHERROR("kCalculateCDLJObcGbsaN2Forces1"); LAUNCHERROR("kCalculateCDLJObcGbsaN2Forces1");
break; break;
case CUTOFF: case CUTOFF:
......
...@@ -45,7 +45,6 @@ struct Atom { ...@@ -45,7 +45,6 @@ struct Atom {
float r; float r;
float sr; float sr;
float sum; float sum;
float junk;
}; };
static __constant__ cudaGmxSimulation cSim; static __constant__ cudaGmxSimulation cSim;
...@@ -150,14 +149,21 @@ void kReduceObcGbsaBornSum(gpuContext gpu) ...@@ -150,14 +149,21 @@ void kReduceObcGbsaBornSum(gpuContext gpu)
LAUNCHERROR("kReduceObcGbsaBornSum"); LAUNCHERROR("kReduceObcGbsaBornSum");
} }
void kClearObcGbsaBornSum(gpuContext gpu)
{
// printf("kClearObcGbsaBornSum\n");
kClearObcGbsaBornSum_kernel<<<gpu->sim.blocks, 384>>>();
}
void kCalculateObcGbsaBornSum(gpuContext gpu) void kCalculateObcGbsaBornSum(gpuContext gpu)
{ {
// printf("kCalculateObcgbsaBornSum\n"); // printf("kCalculateObcgbsaBornSum\n");
kClearObcGbsaBornSum_kernel<<<gpu->sim.blocks, 384>>>(); kClearObcGbsaBornSum(gpu);
LAUNCHERROR("kClearBornSum"); LAUNCHERROR("kClearBornSum");
switch (gpu->sim.nonbondedMethod) switch (gpu->sim.nonbondedMethod)
{ {
case NO_CUTOFF: case NO_CUTOFF:
if (gpu->bOutputBufferPerWarp) if (gpu->bOutputBufferPerWarp)
kCalculateObcGbsaN2ByWarpBornSum_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.nonbond_threads_per_block, kCalculateObcGbsaN2ByWarpBornSum_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.nonbond_threads_per_block,
sizeof(Atom)*gpu->sim.nonbond_threads_per_block>>>(gpu->sim.pWorkUnit); sizeof(Atom)*gpu->sim.nonbond_threads_per_block>>>(gpu->sim.pWorkUnit);
......
...@@ -43,14 +43,14 @@ void SetForcesSim(gpuContext gpu) ...@@ -43,14 +43,14 @@ void SetForcesSim(gpuContext gpu)
{ {
cudaError_t status; cudaError_t status;
status = cudaMemcpyToSymbol(cSim, &gpu->sim, sizeof(cudaGmxSimulation)); status = cudaMemcpyToSymbol(cSim, &gpu->sim, sizeof(cudaGmxSimulation));
RTERROR(status, "cudaMemcpyToSymbol: SetSim copy to cSim failed"); RTERROR(status, "cudaMemcpyToSymbol: SetForcesSim copy to cSim failed");
} }
void GetForcesSim(gpuContext gpu) void GetForcesSim(gpuContext gpu)
{ {
cudaError_t status; cudaError_t status;
status = cudaMemcpyFromSymbol(&gpu->sim, cSim, sizeof(cudaGmxSimulation)); status = cudaMemcpyFromSymbol(&gpu->sim, cSim, sizeof(cudaGmxSimulation));
RTERROR(status, "cudaMemcpyFromSymbol: SetSim copy from cSim failed"); RTERROR(status, "cudaMemcpyFromSymbol: GetForcesSim copy from cSim failed");
} }
__global__ void kClearForces_kernel() __global__ void kClearForces_kernel()
...@@ -259,11 +259,13 @@ void kReduceForces(gpuContext gpu) ...@@ -259,11 +259,13 @@ void kReduceForces(gpuContext gpu)
double kReduceEnergy(gpuContext gpu) double kReduceEnergy(gpuContext gpu)
{ {
// printf("kReduceEnergy\n"); //printf("kReduceEnergy\n");
gpu->psEnergy->Download(); gpu->psEnergy->Download();
double sum = 0.0f; double sum = 0.0;
for (int i = 0; i < gpu->sim.energyOutputBuffers; i++) for (int i = 0; i < gpu->sim.energyOutputBuffers; i++){
sum += (*gpu->psEnergy)[i]; sum += (*gpu->psEnergy)[i];
}
return sum; return sum;
} }
...@@ -308,29 +310,87 @@ __global__ void kReduceObcGbsaBornForces_kernel() ...@@ -308,29 +310,87 @@ __global__ void kReduceObcGbsaBornForces_kernel()
} }
float r = (obcData.x + cSim.dielectricOffset + cSim.probeRadius); float r = (obcData.x + cSim.dielectricOffset + cSim.probeRadius);
float ratio6 = pow((obcData.x + cSim.dielectricOffset) / bornRadius, 6.0f); float ratio6 = pow((obcData.x + cSim.dielectricOffset) / bornRadius, 6.0f);
//float saTerm = cSim.surfaceAreaFactor * r * r * ratio6;
float saTerm = cSim.surfaceAreaFactor * r * r * ratio6; float saTerm = cSim.surfaceAreaFactor * r * r * ratio6;
totalForce += saTerm / bornRadius; // 1.102 == Temp mysterious fudge factor, FIX FIX FIX
/* E */
energy += saTerm;
totalForce += saTerm / bornRadius;
totalForce *= bornRadius * bornRadius * obcChain; totalForce *= bornRadius * bornRadius * obcChain;
energy += saTerm;
pFt = cSim.pBornForce + pos; pFt = cSim.pBornForce + pos;
*pFt = totalForce; *pFt = totalForce;
pos += gridDim.x * blockDim.x; pos += gridDim.x * blockDim.x;
} }
/* E */
// correct for surface area factor of -6 // correct for surface area factor of -6
cSim.pEnergy[blockIdx.x * blockDim.x + threadIdx.x] += energy / -6.0f; cSim.pEnergy[blockIdx.x * blockDim.x + threadIdx.x] += energy / -6.0f;
} }
__global__ void kReduceGBVIBornForces_kernel()
{
unsigned int pos = (blockIdx.x * blockDim.x + threadIdx.x);
float energy = 0.0f;
while (pos < cSim.atoms)
{
float bornRadius = cSim.pBornRadii[pos];
float4 gbviData = cSim.pGBVIData[pos];
float totalForce = 0.0f;
float* pFt = cSim.pBornForce + pos;
int i = cSim.nonbondOutputBuffers;
while (i >= 4)
{
float f1 = *pFt;
pFt += cSim.stride;
float f2 = *pFt;
pFt += cSim.stride;
float f3 = *pFt;
pFt += cSim.stride;
float f4 = *pFt;
pFt += cSim.stride;
totalForce += f1 + f2 + f3 + f4;
i -= 4;
}
if (i >= 2)
{
float f1 = *pFt;
pFt += cSim.stride;
float f2 = *pFt;
pFt += cSim.stride;
totalForce += f1 + f2;
i -= 2;
}
if (i > 0)
{
totalForce += *pFt;
}
float ratio = (gbviData.x/bornRadius);
float ratio3 = ratio*ratio*ratio;
energy -= gbviData.z*ratio3;
totalForce += (3.0f*gbviData.z*ratio3)/bornRadius; // 'cavity' term
float br2 = bornRadius*bornRadius;
totalForce *= (1.0f/3.0f)*br2*br2;
pFt = cSim.pBornForce + pos;
*pFt = totalForce;
pos += gridDim.x * blockDim.x;
}
cSim.pEnergy[blockIdx.x * blockDim.x + threadIdx.x] += energy;
}
void kReduceObcGbsaBornForces(gpuContext gpu) void kReduceObcGbsaBornForces(gpuContext gpu)
{ {
//printf("kReduceObcGbsaBornForces\n"); //printf("kReduceObcGbsaBornForces\n");
if( gpu->bIncludeGBSA ){
kReduceObcGbsaBornForces_kernel<<<gpu->sim.blocks, gpu->sim.bf_reduce_threads_per_block>>>(); kReduceObcGbsaBornForces_kernel<<<gpu->sim.blocks, gpu->sim.bf_reduce_threads_per_block>>>();
LAUNCHERROR("kReduceObcGbsaBornForces"); LAUNCHERROR("kReduceObcGbsaBornForces");
} else if( gpu->bIncludeGBVI ){
kReduceGBVIBornForces_kernel<<<gpu->sim.blocks, gpu->sim.bf_reduce_threads_per_block>>>();
LAUNCHERROR("kReduceGBVIBornForces");
}
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -155,7 +155,7 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct( RealOpenMM* vector1, RealOpenM ...@@ -155,7 +155,7 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct( RealOpenMM* vector1, RealOpenM
// for angles near pi, double is required due to the 'steepness' of acos() // for angles near pi, double is required due to the 'steepness' of acos()
// in this regime. // in this regime.
#define USE_DOUBLE_FOR_NORMED_DOT_PRODUCT //#define USE_DOUBLE_FOR_NORMED_DOT_PRODUCT
#if defined USE_DOUBLE_FOR_NORMED_DOT_PRODUCT #if defined USE_DOUBLE_FOR_NORMED_DOT_PRODUCT
double v1D[3]; double v1D[3];
......
...@@ -109,7 +109,7 @@ int ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, ...@@ -109,7 +109,7 @@ int ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices,
// debug flag // debug flag
static const int debug = 0; static int debug = 0;
static const int LastAtomIndex = 4; static const int LastAtomIndex = 4;
...@@ -244,9 +244,12 @@ int ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, ...@@ -244,9 +244,12 @@ int ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices,
} }
message << std::endl; message << std::endl;
message << " k=" << parameters[0]; message << std::endl << numberOfParameters << " Parameters: [";
message << " a=" << parameters[1]; for( int ii = 0; ii < numberOfParameters; ii++ ){
message << " m=" << parameters[2]; message << parameters[ii] << " ";
}
message << " ]" << std::endl;
message << " ang=" << dihederalAngle; message << " ang=" << dihederalAngle;
message << " dotD=" << cosPhi; message << " dotD=" << cosPhi;
message << " sign=" << signOfAngle; message << " sign=" << signOfAngle;
......
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
#include "UtilitiesSimTk.h" //#include "SimTKOpenMMUtilities.h"
#include "SimTKOpenMMUtilities.h"
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -116,11 +117,11 @@ TwoDimArraySimTk<T>::TwoDimArraySimTk( int rowSize, int columnSize ){ ...@@ -116,11 +117,11 @@ TwoDimArraySimTk<T>::TwoDimArraySimTk( int rowSize, int columnSize ){
_columnSize = columnSize; _columnSize = columnSize;
#ifdef useXMalloc #ifdef useXMalloc
_2Darray = (T**) UtilitiesSimTk::Xmalloc( "TwoDimArraySimTk", __FILE__, __LINE__, rowSize*sizeof( T* ) ); _2Darray = (T**) SimTKOpenMMUtilities::Xmalloc( "TwoDimArraySimTk", __FILE__, __LINE__, rowSize*sizeof( T* ) );
_2DMemoryBlock = (T*) UtilitiesSimTk::Xmalloc( "block", __FILE__, __LINE__, columnSize*rowSize*sizeof( T ) ); _2DMemoryBlock = (T*) SimTKOpenMMUtilities::Xmalloc( "block", __FILE__, __LINE__, columnSize*rowSize*sizeof( T ) );
#else #else
_2Darray = (T**) UtilitiesSimTk::Xmalloc( "TwoDimArraySimTk", __FILE__, __LINE__, rowSize*sizeof( T* ) ); _2Darray = (T**) SimTKOpenMMUtilities::Xmalloc( "TwoDimArraySimTk", __FILE__, __LINE__, rowSize*sizeof( T* ) );
_2DMemoryBlock = (T*) UtilitiesSimTk::Xmalloc( "block", __FILE__, __LINE__, columnSize*rowSize*sizeof( T ) ); _2DMemoryBlock = (T*) SimTKOpenMMUtilities::Xmalloc( "block", __FILE__, __LINE__, columnSize*rowSize*sizeof( T ) );
#endif #endif
T* blockPtr = _2DMemoryBlock; T* blockPtr = _2DMemoryBlock;
...@@ -157,10 +158,10 @@ template <typename T> TwoDimArraySimTk<T>::~TwoDimArraySimTk( ){ ...@@ -157,10 +158,10 @@ template <typename T> TwoDimArraySimTk<T>::~TwoDimArraySimTk( ){
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
if( _2DMemoryBlock ){ if( _2DMemoryBlock ){
UtilitiesSimTk::Xfree( "2DMemoryBlock", __FILE__, __LINE__, _2DMemoryBlock ); SimTKOpenMMUtilities::Xfree( "2DMemoryBlock", __FILE__, __LINE__, _2DMemoryBlock );
} }
if( _2Darray ){ if( _2Darray ){
UtilitiesSimTk::Xfree( "2Darray", __FILE__, __LINE__, _2Darray ); SimTKOpenMMUtilities::Xfree( "2Darray", __FILE__, __LINE__, _2Darray );
} }
} }
......
...@@ -170,7 +170,7 @@ int CpuGBVI::computeBornRadii( RealOpenMM** atomCoordinates, RealOpenMM* bornRad ...@@ -170,7 +170,7 @@ int CpuGBVI::computeBornRadii( RealOpenMM** atomCoordinates, RealOpenMM* bornRad
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
#if GBVIDebug #if( GBVIDebug == 1 )
FILE* logFile = stderr; FILE* logFile = stderr;
(void) fprintf( logFile, "\n%s\n", methodName ); (void) fprintf( logFile, "\n%s\n", methodName );
#endif #endif
...@@ -201,18 +201,24 @@ int CpuGBVI::computeBornRadii( RealOpenMM** atomCoordinates, RealOpenMM* bornRad ...@@ -201,18 +201,24 @@ int CpuGBVI::computeBornRadii( RealOpenMM** atomCoordinates, RealOpenMM* bornRad
sum += CpuGBVI::getVolume( r, radiusI, scaledRadii[atomJ] ); sum += CpuGBVI::getVolume( r, radiusI, scaledRadii[atomJ] );
#if GBVIDebug #if( GBVIDebug == 1 )
(void) fprintf( logFile, "%d r=%.5f add for atom J=%d scR=%.4e %.6e sum=%14.6e\n", if( atomI == 1568 || atomJ == 1568 ){
atomI, r, atomJ, scaledRadii[atomJ], getVolume( r, radiusI, scaledRadii[atomJ] ), sum ); (void) fprintf( logFile, "%d addJ=%d scR=%14.6e %14.6e sum=%14.6e rI=%14.6e r=%14.6e S-R=%14.6e\n",
atomI, atomJ, scaledRadii[atomJ], getVolume( r, radiusI, scaledRadii[atomJ] ), sum,
radiusI, r, (scaledRadii[atomJ]-radiusI) );
}
#endif #endif
} }
} }
#if( GBVIDebug == 1 )
(void) fprintf( logFile, "%d Born radius sum=%14.6e %14.6e %14.6e ", atomI, sum, POW( radiusI, minusThree ), (POW( radiusI, minusThree ) - sum) );
#endif
sum = POW( radiusI, minusThree ) - sum; sum = POW( radiusI, minusThree ) - sum;
bornRadii[atomI] = POW( sum, minusOneThird ); bornRadii[atomI] = POW( sum, minusOneThird );
#if GBVIDebug #if( GBVIDebug == 1 )
(void) fprintf( logFile, "%d Born radius %14.6e\n", atomI, bornRadii[atomI] ); (void) fprintf( logFile, "br=%14.6e\n", atomI, bornRadii[atomI] );
#endif #endif
} }
...@@ -442,7 +448,7 @@ RealOpenMM CpuGBVI::computeBornEnergy( const RealOpenMM* bornRadii, RealOpenMM** ...@@ -442,7 +448,7 @@ RealOpenMM CpuGBVI::computeBornEnergy( const RealOpenMM* bornRadii, RealOpenMM**
bornRadii = getBornRadii(); bornRadii = getBornRadii();
} }
#if GBVIDebug #if( GBVIDebug == 1 )
FILE* logFile = stderr; FILE* logFile = stderr;
(void) fprintf( logFile, "\n%s\n", methodName ); (void) fprintf( logFile, "\n%s\n", methodName );
(void) fflush( logFile ); (void) fflush( logFile );
...@@ -451,22 +457,24 @@ RealOpenMM CpuGBVI::computeBornEnergy( const RealOpenMM* bornRadii, RealOpenMM** ...@@ -451,22 +457,24 @@ RealOpenMM CpuGBVI::computeBornEnergy( const RealOpenMM* bornRadii, RealOpenMM**
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Eq.2 of Labute paper [JCC 29 p. 1693-1698 2008] // Eq.2 of Labute paper [JCC 29 p. 1693-1698 2008]
// to minimze roundoff error sum cavityEnergy separately since in general much
// smaller than other contributions
RealOpenMM energy = zero; RealOpenMM energy = zero;
RealOpenMM cavityEnergy = zero;
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
RealOpenMM partialChargeI = preFactor*partialCharges[atomI]; RealOpenMM partialChargeI = partialCharges[atomI];
RealOpenMM partialChargeI2 = two*partialChargeI;
// self-energy term // self-energy term
energy += partialChargeI*partialCharges[atomI]/bornRadii[atomI]; RealOpenMM atomIEnergy = half*partialChargeI/bornRadii[atomI];
// cavity term // cavity term
RealOpenMM ratio = (atomicRadii[atomI]/bornRadii[atomI]); RealOpenMM ratio = (atomicRadii[atomI]/bornRadii[atomI]);
energy -= gammaParameters[atomI]*ratio*ratio*ratio; cavityEnergy += gammaParameters[atomI]*ratio*ratio*ratio;
/* /*
RealOpenMM e1 = partialChargeI*partialCharges[atomI]/bornRadii[atomI]; RealOpenMM e1 = partialChargeI*partialCharges[atomI]/bornRadii[atomI];
...@@ -485,15 +493,19 @@ RealOpenMM e2 = gammaParameters[atomI]*ratio*ratio*ratio; ...@@ -485,15 +493,19 @@ RealOpenMM e2 = gammaParameters[atomI]*ratio*ratio*ratio;
RealOpenMM r2 = deltaR[ReferenceForce::R2Index]; RealOpenMM r2 = deltaR[ReferenceForce::R2Index];
RealOpenMM t = fourth*r2/(bornRadii[atomI]*bornRadii[atomJ]); RealOpenMM t = fourth*r2/(bornRadii[atomI]*bornRadii[atomJ]);
energy += partialChargeI2*partialCharges[atomJ]*Sgb( t )/deltaR[ReferenceForce::RIndex]; atomIEnergy += partialCharges[atomJ]*Sgb( t )/deltaR[ReferenceForce::RIndex];
/* /*
RealOpenMM e3 = -partialChargeI2*partialCharges[atomJ]*Sgb( t )/deltaR[ReferenceForce::RIndex]; RealOpenMM e3 = -partialChargeI2*partialCharges[atomJ]*Sgb( t )/deltaR[ReferenceForce::RIndex];
(void) fprintf( stderr, "E %d %d e3=%.4e r2=%4e t=%.3e sgb=%.4e e=%.5e\n", atomI, atomJ, e3, r2, t, Sgb( t ), energy ); (void) fprintf( stderr, "E %d %d e3=%.4e r2=%4e t=%.3e sgb=%.4e e=%.5e\n", atomI, atomJ, e3, r2, t, Sgb( t ), energy );
*/ */
} }
energy += two*partialChargeI*atomIEnergy;
} }
energy *= CAL_TO_JOULE*preFactor;
energy -= cavityEnergy;
#if GBVIDebug #if( GBVIDebug == 1 )
(void) fprintf( logFile, "ElectricConstant=%.4e Tau=%.4e e=%.5e eOut=%.5e\n", preFactor, gbviParameters->getTau(), energy, gbviParameters->getTau()*energy ); (void) fprintf( logFile, "ElectricConstant=%.4e Tau=%.4e e=%.5e eOut=%.5e\n", preFactor, gbviParameters->getTau(), energy, gbviParameters->getTau()*energy );
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
(void) fprintf( logFile, "bR %d bR=%16.8e\n", atomI, bornRadii[atomI] ); (void) fprintf( logFile, "bR %d bR=%16.8e\n", atomI, bornRadii[atomI] );
...@@ -501,11 +513,15 @@ RealOpenMM e3 = -partialChargeI2*partialCharges[atomJ]*Sgb( t )/deltaR[Reference ...@@ -501,11 +513,15 @@ RealOpenMM e3 = -partialChargeI2*partialCharges[atomJ]*Sgb( t )/deltaR[Reference
(void) fflush( logFile ); (void) fflush( logFile );
#endif #endif
RealOpenMM conversion = (RealOpenMM)(CAL_TO_JOULE*gbviParameters->getTau()); RealOpenMM conversion = (RealOpenMM)(gbviParameters->getTau());
return (conversion*energy); return (conversion*energy);
} }
#undef GBVIDebug
#define GBVIDebug 0
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get GB/VI forces Get GB/VI forces
...@@ -539,7 +555,7 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo ...@@ -539,7 +555,7 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
#if GBVIDebug #if( GBVIDebug == 1 )
FILE* logFile = stderr; FILE* logFile = stderr;
(void) fprintf( logFile, "\n%s\n", methodName ); (void) fprintf( logFile, "\n%s\n", methodName );
(void) fflush( logFile ); (void) fflush( logFile );
...@@ -584,11 +600,6 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo ...@@ -584,11 +600,6 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
// partial of cavity term wrt Born radius
RealOpenMM ratio = (atomicRadii[atomI]/bornRadii[atomI]);
bornForces[atomI] += (three*gammaParameters[atomI]*ratio*ratio*ratio)/bornRadii[atomI];
// partial of polar term wrt Born radius // partial of polar term wrt Born radius
// and (dGpol/dr)(dr/dx) // and (dGpol/dr)(dr/dx)
...@@ -641,16 +652,50 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo ...@@ -641,16 +652,50 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo
// 3 FLOP // 3 FLOP
#if 0
if( atomI == 0 ){
(void) fprintf( logFile, "bFCalc: %6d %6d %14.6e %14.6e %14.6e %14.6e\n", atomI, atomJ, dGpol_dalpha2_ij, bornRadii[atomJ], bornForces[atomI], bornRadii[atomI] );
}
#endif
bornForces[atomI] += dGpol_dalpha2_ij*bornRadii[atomJ]; bornForces[atomI] += dGpol_dalpha2_ij*bornRadii[atomJ];
} }
} }
#if GBVIDebug #if( GBVIDebug == 1 )
{
double stupidFactor = three/CAL_TO_JOULE;
RealOpenMM conversion = (RealOpenMM)(CAL_TO_JOULE*gbviParameters->getTau());
int maxPrint = 10;
const RealOpenMM* scaledRadii = gbviParameters->getScaledRadii();
(void) fprintf( logFile, "Conversion=%14.6e %14.6e*%14.6e (tau)\n", conversion, CAL_TO_JOULE, gbviParameters->getTau() );
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
(void) fprintf( logFile, "F1 %d bF=%14.6e [%14.6e %14.6e %14.6e]\n", atomI, bornForces[atomI], forces[atomI][0], forces[atomI][1], forces[atomI][2] ); RealOpenMM R = atomicRadii[atomI];
// partial of cavity term wrt Born radius
RealOpenMM ratio = (atomicRadii[atomI]/bornRadii[atomI]);
bornForces[atomI] += (stupidFactor*gammaParameters[atomI]*ratio*ratio*ratio)/bornRadii[atomI];
RealOpenMM b2 = bornRadii[atomI]*bornRadii[atomI];
double xx = bornForces[atomI]*oneThird*b2*b2;
// xx*conversion should agree w/ values pulled out of kReduceGBVIBornForces_kernel in kForces.cu
(void) fprintf( logFile, "F1 %6d r/sclR[%14.6e %14.6e] bR=%14.6e bF=%14.6e %14.6e f[%14.6e %14.6e %14.6e](cnvrtd)"
" x[%14.6e %14.6e %14.6e]\n",
atomI, atomicRadii[atomI], scaledRadii[atomI], bornRadii[atomI], bornForces[atomI], xx*conversion,
// forces[atomI][0], forces[atomI][1], forces[atomI][2],
conversion*forces[atomI][0], conversion*forces[atomI][1], conversion*forces[atomI][2],
atomCoordinates[atomI][0], atomCoordinates[atomI][1], atomCoordinates[atomI][2] );
if( atomI == maxPrint ){
atomI = numberOfAtoms - maxPrint;
if( atomI < maxPrint )atomI = maxPrint;
}
} }
(void) fflush( logFile ); (void) fflush( logFile );
}
#endif #endif
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -660,11 +705,28 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo ...@@ -660,11 +705,28 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo
// dGpol/dBornRadius) = bornForces[] // dGpol/dBornRadius) = bornForces[]
// dBornRadius/dr = (1/3)*(bR**4)*(dV/dr) // dBornRadius/dr = (1/3)*(bR**4)*(dV/dr)
#if 0
(void) fprintf( logFile, "Clearing forces before loop2 periodic=%d cutoff=%d cutoffR=%14.7e\n",
_gbviParameters->getPeriodic(), _gbviParameters->getUseCutoff(), _gbviParameters->getCutoffDistance() );
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
forces[atomI][0] = zero;
forces[atomI][1] = zero;
forces[atomI][2] = zero;
}
(void) fflush( logFile );
#endif
const RealOpenMM* scaledRadii = gbviParameters->getScaledRadii(); const RealOpenMM* scaledRadii = gbviParameters->getScaledRadii();
double stupidFactor = three/CAL_TO_JOULE;
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
RealOpenMM R = atomicRadii[atomI]; RealOpenMM R = atomicRadii[atomI];
// partial of cavity term wrt Born radius
RealOpenMM ratio = (atomicRadii[atomI]/bornRadii[atomI]);
bornForces[atomI] += (stupidFactor*gammaParameters[atomI]*ratio*ratio*ratio)/bornRadii[atomI];
RealOpenMM b2 = bornRadii[atomI]*bornRadii[atomI]; RealOpenMM b2 = bornRadii[atomI]*bornRadii[atomI];
bornForces[atomI] *= oneThird*b2*b2; bornForces[atomI] *= oneThird*b2*b2;
...@@ -698,22 +760,18 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo ...@@ -698,22 +760,18 @@ int CpuGBVI::computeBornForces( const RealOpenMM* bornRadii, RealOpenMM** atomCo
// find dRb/dr, where Rb is the Born radius // find dRb/dr, where Rb is the Born radius
if( FABS( diff ) < r ){
de = CpuGBVI::dL_dr( r, r+S, S ) + CpuGBVI::dL_dx( r, r+S, S ); de = CpuGBVI::dL_dr( r, r+S, S ) + CpuGBVI::dL_dx( r, r+S, S );
if( FABS( diff ) < r ){
if( R > (r - S) ){ if( R > (r - S) ){
//(void) fprintf( stderr, "F2 %d %d block 0\n", atomI, atomJ );
de -= CpuGBVI::dL_dr( r, R, S ); de -= CpuGBVI::dL_dr( r, R, S );
} else { } else {
//(void) fprintf( stderr, "F2 %d %d block 1\n", atomI, atomJ );
de -= ( CpuGBVI::dL_dr( r, (r-S), S ) + CpuGBVI::dL_dx( r, (r-S), S ) ); de -= ( CpuGBVI::dL_dr( r, (r-S), S ) + CpuGBVI::dL_dx( r, (r-S), S ) );
} }
} else if( r < (S - R) ){ } else if( r < (S - R) ){
//(void) fprintf( stderr, "F3 %d %d block 2\n", atomI, atomJ ); de -= ( CpuGBVI::dL_dr( r, r-S, S ) + CpuGBVI::dL_dx( r, r-S, S ) );
de = CpuGBVI::dL_dr( r, r+S, S ) + CpuGBVI::dL_dx( r, r+S, S ) -
( CpuGBVI::dL_dr( r, r-S, S ) + CpuGBVI::dL_dx( r, r-S, S ) );
} }
if( 0 ){ #if 0
RealOpenMM delta = (RealOpenMM) 1.0e-02; RealOpenMM delta = (RealOpenMM) 1.0e-02;
(void) fprintf( stderr, "\n" ); (void) fprintf( stderr, "\n" );
for( int kk = 0; kk < 5; kk++ ){ for( int kk = 0; kk < 5; kk++ ){
...@@ -733,9 +791,7 @@ if( 0 ){ ...@@ -733,9 +791,7 @@ if( 0 ){
(void) fprintf( stderr, "df %d %d [%14.6e %14.6e] V[%14.6e %14.6e] %.2e\n", atomI, atomJ, ded, df, V2, V1, deltaD ); (void) fprintf( stderr, "df %d %d [%14.6e %14.6e] V[%14.6e %14.6e] %.2e\n", atomI, atomJ, ded, df, V2, V1, deltaD );
deltaD *= 0.1; deltaD *= 0.1;
} }
} #endif
// de = (dG/dRb)(dRb/dr) // de = (dG/dRb)(dRb/dr)
...@@ -759,7 +815,7 @@ if( 0 ){ ...@@ -759,7 +815,7 @@ if( 0 ){
} }
#if GBVIDebug #if( GBVIDebug == 1 )
(void) fprintf( logFile, "Atom BornRadii BornForce Forces\n" ); (void) fprintf( logFile, "Atom BornRadii BornForce Forces\n" );
double forceSum[3] = { 0.0, 0.0, 0.0 }; double forceSum[3] = { 0.0, 0.0, 0.0 };
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
...@@ -772,17 +828,33 @@ if( 0 ){ ...@@ -772,17 +828,33 @@ if( 0 ){
(void) fflush( logFile ); (void) fflush( logFile );
#endif #endif
#undef GBVIDebug
// convert from cal to Joule & apply prefactor tau = (1/diel_solute - 1/diel_solvent) // convert from cal to Joule & apply prefactor tau = (1/diel_solute - 1/diel_solvent)
RealOpenMM conversion = (RealOpenMM)(CAL_TO_JOULE*gbviParameters->getTau()); RealOpenMM conversion = (RealOpenMM)(CAL_TO_JOULE*gbviParameters->getTau());
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
inputForces[atomI][0] = conversion*forces[atomI][0]; inputForces[atomI][0] += conversion*forces[atomI][0];
inputForces[atomI][1] = conversion*forces[atomI][1]; inputForces[atomI][1] += conversion*forces[atomI][1];
inputForces[atomI][2] = conversion*forces[atomI][2]; inputForces[atomI][2] += conversion*forces[atomI][2];
} }
#if( GBVIDebug == 1 )
{
(void) fprintf( logFile, "\nPost conversion\n" );
(void) fprintf( logFile, "Atom BornRadii BornForce Forces\n" );
int maxPrint = 10;
for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){
(void) fprintf( logFile, "%4d %14.6e %14.6e [%14.6e %14.6e %14.6e]\n", atomI, bornRadii[atomI], conversion*bornForces[atomI],
inputForces[atomI][0], inputForces[atomI][1], inputForces[atomI][2] );
if( atomI == maxPrint ){
atomI = numberOfAtoms - maxPrint;
if( atomI < maxPrint )atomI = numberOfAtoms;
}
}
(void) fflush( logFile );
}
#endif
#undef GBVIDebug
delete[] forces; delete[] forces;
delete[] block; delete[] block;
......
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