"libraries/vscode:/vscode.git/clone" did not exist on "e3b252043f1a45bad2253e6c755a48efacf38649"
Commit d58cc041 authored by Lee-Ping Wang's avatar Lee-Ping Wang
Browse files

Merge branch 'master' of github.com:SimTk/openmm

Conflicts:
	wrappers/python/simtk/openmm/app/modeller.py
parents d7b3a3c2 ce8d6a2d
extern "C" __global__ void applyPositionDeltas(real4* __restrict__ posq, real4* __restrict__ posqCorrection, mixed4* __restrict__ posDelta) { extern "C" __global__ void applyPositionDeltas(int numAtoms, real4* __restrict__ posq, real4* __restrict__ posqCorrection, mixed4* __restrict__ posDelta) {
for (unsigned int index = blockIdx.x*blockDim.x+threadIdx.x; index < NUM_ATOMS; index += blockDim.x*gridDim.x) { for (unsigned int index = blockIdx.x*blockDim.x+threadIdx.x; index < numAtoms; index += blockDim.x*gridDim.x) {
#ifdef USE_MIXED_PRECISION #ifdef USE_MIXED_PRECISION
real4 pos1 = posq[index]; real4 pos1 = posq[index];
real4 pos2 = posqCorrection[index]; real4 pos2 = posqCorrection[index];
......
...@@ -4,7 +4,7 @@ enum {VelScale, ForceScale, NoiseScale, MaxParams}; ...@@ -4,7 +4,7 @@ enum {VelScale, ForceScale, NoiseScale, MaxParams};
* Perform the first step of Langevin integration. * Perform the first step of Langevin integration.
*/ */
extern "C" __global__ void integrateLangevinPart1(mixed4* __restrict__ velm, const long long* __restrict__ force, mixed4* __restrict__ posDelta, extern "C" __global__ void integrateLangevinPart1(int numAtoms, int paddedNumAtoms, mixed4* __restrict__ velm, const long long* __restrict__ force, mixed4* __restrict__ posDelta,
const mixed* __restrict__ paramBuffer, const mixed2* __restrict__ dt, const float4* __restrict__ random, unsigned int randomIndex) { const mixed* __restrict__ paramBuffer, const mixed2* __restrict__ dt, const float4* __restrict__ random, unsigned int randomIndex) {
mixed vscale = paramBuffer[VelScale]; mixed vscale = paramBuffer[VelScale];
mixed fscale = paramBuffer[ForceScale]/(mixed) 0x100000000; mixed fscale = paramBuffer[ForceScale]/(mixed) 0x100000000;
...@@ -12,13 +12,13 @@ extern "C" __global__ void integrateLangevinPart1(mixed4* __restrict__ velm, con ...@@ -12,13 +12,13 @@ extern "C" __global__ void integrateLangevinPart1(mixed4* __restrict__ velm, con
mixed stepSize = dt[0].y; mixed stepSize = dt[0].y;
int index = blockIdx.x*blockDim.x+threadIdx.x; int index = blockIdx.x*blockDim.x+threadIdx.x;
randomIndex += index; randomIndex += index;
while (index < NUM_ATOMS) { while (index < numAtoms) {
mixed4 velocity = velm[index]; mixed4 velocity = velm[index];
if (velocity.w != 0) { if (velocity.w != 0) {
mixed sqrtInvMass = SQRT(velocity.w); mixed sqrtInvMass = SQRT(velocity.w);
velocity.x = vscale*velocity.x + fscale*velocity.w*force[index] + noisescale*sqrtInvMass*random[randomIndex].x; velocity.x = vscale*velocity.x + fscale*velocity.w*force[index] + noisescale*sqrtInvMass*random[randomIndex].x;
velocity.y = vscale*velocity.y + fscale*velocity.w*force[index+PADDED_NUM_ATOMS] + noisescale*sqrtInvMass*random[randomIndex].y; velocity.y = vscale*velocity.y + fscale*velocity.w*force[index+paddedNumAtoms] + noisescale*sqrtInvMass*random[randomIndex].y;
velocity.z = vscale*velocity.z + fscale*velocity.w*force[index+PADDED_NUM_ATOMS*2] + noisescale*sqrtInvMass*random[randomIndex].z; velocity.z = vscale*velocity.z + fscale*velocity.w*force[index+paddedNumAtoms*2] + noisescale*sqrtInvMass*random[randomIndex].z;
velm[index] = velocity; velm[index] = velocity;
posDelta[index] = make_mixed4(stepSize*velocity.x, stepSize*velocity.y, stepSize*velocity.z, 0); posDelta[index] = make_mixed4(stepSize*velocity.x, stepSize*velocity.y, stepSize*velocity.z, 0);
} }
...@@ -31,7 +31,7 @@ extern "C" __global__ void integrateLangevinPart1(mixed4* __restrict__ velm, con ...@@ -31,7 +31,7 @@ extern "C" __global__ void integrateLangevinPart1(mixed4* __restrict__ velm, con
* Perform the second step of Langevin integration. * Perform the second step of Langevin integration.
*/ */
extern "C" __global__ void integrateLangevinPart2(real4* __restrict__ posq, real4* __restrict__ posqCorrection, const mixed4* __restrict__ posDelta, mixed4* __restrict__ velm, const mixed2* __restrict__ dt) { extern "C" __global__ void integrateLangevinPart2(int numAtoms, real4* __restrict__ posq, real4* __restrict__ posqCorrection, const mixed4* __restrict__ posDelta, mixed4* __restrict__ velm, const mixed2* __restrict__ dt) {
#if __CUDA_ARCH__ >= 130 #if __CUDA_ARCH__ >= 130
double invStepSize = 1.0/dt[0].y; double invStepSize = 1.0/dt[0].y;
#else #else
...@@ -39,7 +39,7 @@ extern "C" __global__ void integrateLangevinPart2(real4* __restrict__ posq, real ...@@ -39,7 +39,7 @@ extern "C" __global__ void integrateLangevinPart2(real4* __restrict__ posq, real
float correction = (1.0f-invStepSize*dt[0].y)/dt[0].y; float correction = (1.0f-invStepSize*dt[0].y)/dt[0].y;
#endif #endif
int index = blockIdx.x*blockDim.x+threadIdx.x; int index = blockIdx.x*blockDim.x+threadIdx.x;
while (index < NUM_ATOMS) { while (index < numAtoms) {
mixed4 vel = velm[index]; mixed4 vel = velm[index];
if (vel.w != 0) { if (vel.w != 0) {
#ifdef USE_MIXED_PRECISION #ifdef USE_MIXED_PRECISION
...@@ -78,7 +78,7 @@ extern "C" __global__ void integrateLangevinPart2(real4* __restrict__ posq, real ...@@ -78,7 +78,7 @@ extern "C" __global__ void integrateLangevinPart2(real4* __restrict__ posq, real
* Select the step size to use for the next step. * Select the step size to use for the next step.
*/ */
extern "C" __global__ void selectLangevinStepSize(mixed maxStepSize, mixed errorTol, mixed tau, mixed kT, mixed2* __restrict__ dt, extern "C" __global__ void selectLangevinStepSize(int numAtoms, int paddedNumAtoms, mixed maxStepSize, mixed errorTol, mixed tau, mixed kT, mixed2* __restrict__ dt,
const mixed4* __restrict__ velm, const long long* __restrict__ force, mixed* __restrict__ paramBuffer) { const mixed4* __restrict__ velm, const long long* __restrict__ force, mixed* __restrict__ paramBuffer) {
// Calculate the error. // Calculate the error.
...@@ -87,8 +87,8 @@ extern "C" __global__ void selectLangevinStepSize(mixed maxStepSize, mixed error ...@@ -87,8 +87,8 @@ extern "C" __global__ void selectLangevinStepSize(mixed maxStepSize, mixed error
mixed err = 0; mixed err = 0;
unsigned int index = threadIdx.x; unsigned int index = threadIdx.x;
const mixed scale = RECIP((mixed) 0x100000000); const mixed scale = RECIP((mixed) 0x100000000);
while (index < NUM_ATOMS) { while (index < numAtoms) {
mixed3 f = make_mixed3(scale*force[index], scale*force[index+PADDED_NUM_ATOMS], scale*force[index+PADDED_NUM_ATOMS*2]); mixed3 f = make_mixed3(scale*force[index], scale*force[index+paddedNumAtoms], scale*force[index+paddedNumAtoms*2]);
mixed invMass = velm[index].w; mixed invMass = velm[index].w;
err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass; err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass;
index += blockDim.x*gridDim.x; index += blockDim.x*gridDim.x;
...@@ -106,7 +106,7 @@ extern "C" __global__ void selectLangevinStepSize(mixed maxStepSize, mixed error ...@@ -106,7 +106,7 @@ extern "C" __global__ void selectLangevinStepSize(mixed maxStepSize, mixed error
if (blockIdx.x*blockDim.x+threadIdx.x == 0) { if (blockIdx.x*blockDim.x+threadIdx.x == 0) {
// Select the new step size. // Select the new step size.
mixed totalError = SQRT(error[0]/(NUM_ATOMS*3)); mixed totalError = SQRT(error[0]/(numAtoms*3));
mixed newStepSize = SQRT(errorTol/totalError); mixed newStepSize = SQRT(errorTol/totalError);
mixed oldStepSize = dt[0].y; mixed oldStepSize = dt[0].y;
if (oldStepSize > 0.0f) if (oldStepSize > 0.0f)
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
* Perform the first step of Verlet integration. * Perform the first step of Verlet integration.
*/ */
extern "C" __global__ void integrateVerletPart1(const mixed2* __restrict__ dt, const real4* __restrict__ posq, extern "C" __global__ void integrateVerletPart1(int numAtoms, int paddedNumAtoms, const mixed2* __restrict__ dt, const real4* __restrict__ posq,
const real4* __restrict__ posqCorrection, mixed4* __restrict__ velm, const long long* __restrict__ force, mixed4* __restrict__ posDelta) { const real4* __restrict__ posqCorrection, mixed4* __restrict__ velm, const long long* __restrict__ force, mixed4* __restrict__ posDelta) {
const mixed2 stepSize = dt[0]; const mixed2 stepSize = dt[0];
const mixed dtPos = stepSize.y; const mixed dtPos = stepSize.y;
const mixed dtVel = 0.5f*(stepSize.x+stepSize.y); const mixed dtVel = 0.5f*(stepSize.x+stepSize.y);
const mixed scale = dtVel/(mixed) 0x100000000; const mixed scale = dtVel/(mixed) 0x100000000;
for (int index = blockIdx.x*blockDim.x+threadIdx.x; index < NUM_ATOMS; index += blockDim.x*gridDim.x) { for (int index = blockIdx.x*blockDim.x+threadIdx.x; index < numAtoms; index += blockDim.x*gridDim.x) {
mixed4 velocity = velm[index]; mixed4 velocity = velm[index];
if (velocity.w != 0.0) { if (velocity.w != 0.0) {
#ifdef USE_MIXED_PRECISION #ifdef USE_MIXED_PRECISION
...@@ -19,8 +19,8 @@ extern "C" __global__ void integrateVerletPart1(const mixed2* __restrict__ dt, c ...@@ -19,8 +19,8 @@ extern "C" __global__ void integrateVerletPart1(const mixed2* __restrict__ dt, c
real4 pos = posq[index]; real4 pos = posq[index];
#endif #endif
velocity.x += scale*force[index]*velocity.w; velocity.x += scale*force[index]*velocity.w;
velocity.y += scale*force[index+PADDED_NUM_ATOMS]*velocity.w; velocity.y += scale*force[index+paddedNumAtoms]*velocity.w;
velocity.z += scale*force[index+PADDED_NUM_ATOMS*2]*velocity.w; velocity.z += scale*force[index+paddedNumAtoms*2]*velocity.w;
pos.x = velocity.x*dtPos; pos.x = velocity.x*dtPos;
pos.y = velocity.y*dtPos; pos.y = velocity.y*dtPos;
pos.z = velocity.z*dtPos; pos.z = velocity.z*dtPos;
...@@ -34,7 +34,7 @@ extern "C" __global__ void integrateVerletPart1(const mixed2* __restrict__ dt, c ...@@ -34,7 +34,7 @@ extern "C" __global__ void integrateVerletPart1(const mixed2* __restrict__ dt, c
* Perform the second step of Verlet integration. * Perform the second step of Verlet integration.
*/ */
extern "C" __global__ void integrateVerletPart2(mixed2* __restrict__ dt, real4* __restrict__ posq, extern "C" __global__ void integrateVerletPart2(int numAtoms, mixed2* __restrict__ dt, real4* __restrict__ posq,
real4* __restrict__ posqCorrection, mixed4* __restrict__ velm, const mixed4* __restrict__ posDelta) { real4* __restrict__ posqCorrection, mixed4* __restrict__ velm, const mixed4* __restrict__ posDelta) {
mixed2 stepSize = dt[0]; mixed2 stepSize = dt[0];
#if __CUDA_ARCH__ >= 130 #if __CUDA_ARCH__ >= 130
...@@ -46,7 +46,7 @@ extern "C" __global__ void integrateVerletPart2(mixed2* __restrict__ dt, real4* ...@@ -46,7 +46,7 @@ extern "C" __global__ void integrateVerletPart2(mixed2* __restrict__ dt, real4*
int index = blockIdx.x*blockDim.x+threadIdx.x; int index = blockIdx.x*blockDim.x+threadIdx.x;
if (index == 0) if (index == 0)
dt[0].x = stepSize.y; dt[0].x = stepSize.y;
for (; index < NUM_ATOMS; index += blockDim.x*gridDim.x) { for (; index < numAtoms; index += blockDim.x*gridDim.x) {
mixed4 velocity = velm[index]; mixed4 velocity = velm[index];
if (velocity.w != 0.0) { if (velocity.w != 0.0) {
#ifdef USE_MIXED_PRECISION #ifdef USE_MIXED_PRECISION
...@@ -80,14 +80,14 @@ extern "C" __global__ void integrateVerletPart2(mixed2* __restrict__ dt, real4* ...@@ -80,14 +80,14 @@ extern "C" __global__ void integrateVerletPart2(mixed2* __restrict__ dt, real4*
* Select the step size to use for the next step. * Select the step size to use for the next step.
*/ */
extern "C" __global__ void selectVerletStepSize(mixed maxStepSize, mixed errorTol, mixed2* __restrict__ dt, const mixed4* __restrict__ velm, const long long* __restrict__ force) { extern "C" __global__ void selectVerletStepSize(int numAtoms, int paddedNumAtoms, mixed maxStepSize, mixed errorTol, mixed2* __restrict__ dt, const mixed4* __restrict__ velm, const long long* __restrict__ force) {
// Calculate the error. // Calculate the error.
extern __shared__ mixed error[]; extern __shared__ mixed error[];
mixed err = 0.0f; mixed err = 0.0f;
const mixed scale = RECIP((mixed) 0x100000000); const mixed scale = RECIP((mixed) 0x100000000);
for (int index = threadIdx.x; index < NUM_ATOMS; index += blockDim.x*gridDim.x) { for (int index = threadIdx.x; index < numAtoms; index += blockDim.x*gridDim.x) {
mixed3 f = make_mixed3(scale*force[index], scale*force[index+PADDED_NUM_ATOMS], scale*force[index+PADDED_NUM_ATOMS*2]); mixed3 f = make_mixed3(scale*force[index], scale*force[index+paddedNumAtoms], scale*force[index+paddedNumAtoms*2]);
mixed invMass = velm[index].w; mixed invMass = velm[index].w;
err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass; err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass;
} }
...@@ -102,7 +102,7 @@ extern "C" __global__ void selectVerletStepSize(mixed maxStepSize, mixed errorTo ...@@ -102,7 +102,7 @@ extern "C" __global__ void selectVerletStepSize(mixed maxStepSize, mixed errorTo
__syncthreads(); __syncthreads();
} }
if (threadIdx.x == 0) { if (threadIdx.x == 0) {
mixed totalError = SQRT(error[0]/(NUM_ATOMS*3)); mixed totalError = SQRT(error[0]/(numAtoms*3));
mixed newStepSize = SQRT(errorTol/totalError); mixed newStepSize = SQRT(errorTol/totalError);
mixed oldStepSize = dt[0].y; mixed oldStepSize = dt[0].y;
if (oldStepSize > 0.0f) if (oldStepSize > 0.0f)
......
...@@ -53,44 +53,6 @@ using namespace std; ...@@ -53,44 +53,6 @@ using namespace std;
CudaPlatform platform; CudaPlatform platform;
void testChangingBoxSize() {
System system;
system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 5, 0), Vec3(0, 0, 6));
system.addParticle(1.0);
NonbondedForce* nb = new NonbondedForce();
nb->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
nb->setCutoffDistance(2.0);
nb->addParticle(1, 0.5, 0.5);
system.addForce(nb);
LangevinIntegrator integrator(300.0, 1.0, 0.01);
Context context(system, integrator, platform);
vector<Vec3> positions;
positions.push_back(Vec3());
context.setPositions(positions);
Vec3 x, y, z;
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ASSERT_EQUAL_VEC(Vec3(4, 0, 0), x, 0);
ASSERT_EQUAL_VEC(Vec3(0, 5, 0), y, 0);
ASSERT_EQUAL_VEC(Vec3(0, 0, 6), z, 0);
context.setPeriodicBoxVectors(Vec3(7, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 9));
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ASSERT_EQUAL_VEC(Vec3(7, 0, 0), x, 0);
ASSERT_EQUAL_VEC(Vec3(0, 8, 0), y, 0);
ASSERT_EQUAL_VEC(Vec3(0, 0, 9), z, 0);
// Shrinking the box too small should produce an exception.
context.setPeriodicBoxVectors(Vec3(7, 0, 0), Vec3(0, 3.9, 0), Vec3(0, 0, 9));
bool ok = true;
try {
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ok = false;
}
catch (exception& ex) {
}
ASSERT(ok);
}
void testIdealGas() { void testIdealGas() {
const int numParticles = 64; const int numParticles = 64;
const int frequency = 10; const int frequency = 10;
...@@ -112,7 +74,7 @@ void testIdealGas() { ...@@ -112,7 +74,7 @@ void testIdealGas() {
system.addParticle(1.0); system.addParticle(1.0);
positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt));
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], frequency); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], true, true, true, frequency);
system.addForce(barostat); system.addForce(barostat);
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -170,7 +132,7 @@ void testIdealGasAxis(int axis) { ...@@ -170,7 +132,7 @@ void testIdealGasAxis(int axis) {
system.addParticle(1.0); system.addParticle(1.0);
positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt));
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], frequency, scaleX, scaleY, scaleZ); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], scaleX, scaleY, scaleZ, frequency);
system.addForce(barostat); system.addForce(barostat);
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -226,7 +188,7 @@ void testRandomSeed() { ...@@ -226,7 +188,7 @@ void testRandomSeed() {
forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0); forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
} }
system.addForce(forceField); system.addForce(forceField);
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, 1); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, true, true, true, 1);
system.addForce(barostat); system.addForce(barostat);
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
...@@ -332,7 +294,7 @@ void testEinsteinCrystal() { ...@@ -332,7 +294,7 @@ void testEinsteinCrystal() {
system.addForce(force); system.addForce(force);
system.addForce(nb); system.addForce(nb);
// Create the barostat. // Create the barostat.
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pres3[p], pres3[p], pres3[p]), temp, frequency, (a==0||a==3), (a==1||a==3), (a==2||a==3)); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pres3[p], pres3[p], pres3[p]), temp, (a==0||a==3), (a==1||a==3), (a==2||a==3), frequency);
system.addForce(barostat); system.addForce(barostat);
barostat->setTemperature(temp); barostat->setTemperature(temp);
LangevinIntegrator integrator(temp, 0.1, 0.01); LangevinIntegrator integrator(temp, 0.1, 0.01);
...@@ -422,7 +384,6 @@ int main(int argc, char* argv[]) { ...@@ -422,7 +384,6 @@ int main(int argc, char* argv[]) {
try { try {
if (argc > 1) if (argc > 1)
platform.setPropertyDefaultValue("CudaPrecision", string(argv[1])); platform.setPropertyDefaultValue("CudaPrecision", string(argv[1]));
testChangingBoxSize();
testIdealGas(); testIdealGas();
testIdealGasAxis(0); testIdealGasAxis(0);
testIdealGasAxis(1); testIdealGasAxis(1);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2009-2011 Stanford University and the Authors. * * Portions copyright (c) 2009-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -589,7 +589,6 @@ private: ...@@ -589,7 +589,6 @@ private:
struct MoleculeGroup; struct MoleculeGroup;
class VirtualSiteInfo; class VirtualSiteInfo;
void findMoleculeGroups(); void findMoleculeGroups();
static void tagAtomsInMolecule(int atom, int molecule, std::vector<int>& atomMolecule, std::vector<std::vector<int> >& atomBonds);
/** /**
* Ensure that all molecules marked as "identical" really are identical. This should be * Ensure that all molecules marked as "identical" really are identical. This should be
* called whenever force field parameters change. If necessary, it will rebuild the list * called whenever force field parameters change. If necessary, it will rebuild the list
......
...@@ -19,6 +19,6 @@ ELSE (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug) ...@@ -19,6 +19,6 @@ ELSE (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(MAIN_OPENMM_LIB ${OPENMM_LIBRARY_NAME}) SET(MAIN_OPENMM_LIB ${OPENMM_LIBRARY_NAME})
ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug) ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_OPENCL_BUILDING_SHARED_LIBRARY") SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-msse2 -DOPENMM_OPENCL_BUILDING_SHARED_LIBRARY")
INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${SHARED_TARGET}) INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${SHARED_TARGET})
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2009-2012 Stanford University and the Authors. * * Portions copyright (c) 2009-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "openmm/Platform.h" #include "openmm/Platform.h"
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/VirtualSite.h" #include "openmm/VirtualSite.h"
#include "openmm/internal/ContextImpl.h"
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
...@@ -618,15 +619,6 @@ void OpenCLContext::reduceBuffer(OpenCLArray& array, int numBuffers) { ...@@ -618,15 +619,6 @@ void OpenCLContext::reduceBuffer(OpenCLArray& array, int numBuffers) {
executeKernel(reduceReal4Kernel, bufferSize, 128); executeKernel(reduceReal4Kernel, bufferSize, 128);
} }
void OpenCLContext::tagAtomsInMolecule(int atom, int molecule, vector<int>& atomMolecule, vector<vector<int> >& atomBonds) {
// Recursively tag atoms as belonging to a particular molecule.
atomMolecule[atom] = molecule;
for (int i = 0; i < (int) atomBonds[atom].size(); i++)
if (atomMolecule[atomBonds[atom][i]] == -1)
tagAtomsInMolecule(atomBonds[atom][i], molecule, atomMolecule, atomBonds);
}
/** /**
* This class ensures that atom reordering doesn't break virtual sites. * This class ensures that atom reordering doesn't break virtual sites.
*/ */
...@@ -722,16 +714,14 @@ void OpenCLContext::findMoleculeGroups() { ...@@ -722,16 +714,14 @@ void OpenCLContext::findMoleculeGroups() {
} }
} }
// Now tag atoms by which molecule they belong to. // Now identify atoms by which molecule they belong to.
vector<int> atomMolecule(numAtoms, -1); vector<vector<int> > atomIndices = ContextImpl::findMolecules(numAtoms, atomBonds);
int numMolecules = 0; int numMolecules = atomIndices.size();
for (int i = 0; i < numAtoms; i++) vector<int> atomMolecule(numAtoms);
if (atomMolecule[i] == -1) for (int i = 0; i < (int) atomIndices.size(); i++)
tagAtomsInMolecule(i, numMolecules++, atomMolecule, atomBonds); for (int j = 0; j < (int) atomIndices[i].size(); j++)
vector<vector<int> > atomIndices(numMolecules); atomMolecule[atomIndices[i][j]] = i;
for (int i = 0; i < numAtoms; i++)
atomIndices[atomMolecule[i]].push_back(i);
// Construct a description of each molecule. // Construct a description of each molecule.
......
This diff is collapsed.
...@@ -39,13 +39,13 @@ FOREACH(TEST_PROG ${TEST_PROGS}) ...@@ -39,13 +39,13 @@ FOREACH(TEST_PROG ${TEST_PROGS})
SET(NONBOND_TEST "TestOpenCLNonbondedForce2") SET(NONBOND_TEST "TestOpenCLNonbondedForce2")
ADD_EXECUTABLE(${NONBOND_TEST} ${TEST_PROG}) ADD_EXECUTABLE(${NONBOND_TEST} ${TEST_PROG})
SET_TARGET_PROPERTIES(${NONBOND_TEST} PROPERTIES COMPILE_FLAGS ${NONBOND_DEFINE_STRING} ) SET_TARGET_PROPERTIES(${NONBOND_TEST} PROPERTIES COMPILE_FLAGS "-msse2 ${NONBOND_DEFINE_STRING}" )
ADD_TEST(${NONBOND_TEST} ${EXECUTABLE_OUTPUT_PATH}/${NONBOND_TEST}) ADD_TEST(${NONBOND_TEST} ${EXECUTABLE_OUTPUT_PATH}/${NONBOND_TEST})
# OBC # OBC
SET(DEFINE_STRING "${DEFINE_STRING} -DIMPLICIT_SOLVENT=1") SET(DEFINE_STRING "${DEFINE_STRING} -DIMPLICIT_SOLVENT=1")
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES COMPILE_FLAGS ${DEFINE_STRING} ) SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES COMPILE_FLAGS "-msse2 ${DEFINE_STRING}" )
IF( INCLUDE_SERIALIZATION ) IF( INCLUDE_SERIALIZATION )
TARGET_LINK_LIBRARIES(${NONBOND_TEST} ${SHARED_TARGET} ${SHARED_OPENMM_SERIALIZATION} ) TARGET_LINK_LIBRARIES(${NONBOND_TEST} ${SHARED_TARGET} ${SHARED_OPENMM_SERIALIZATION} )
...@@ -54,6 +54,8 @@ FOREACH(TEST_PROG ${TEST_PROGS}) ...@@ -54,6 +54,8 @@ FOREACH(TEST_PROG ${TEST_PROGS})
TARGET_LINK_LIBRARIES(${NONBOND_TEST} ${SHARED_TARGET}) TARGET_LINK_LIBRARIES(${NONBOND_TEST} ${SHARED_TARGET})
ENDIF( INCLUDE_SERIALIZATION ) ENDIF( INCLUDE_SERIALIZATION )
ELSE( ${TEST_ROOT} STREQUAL "TestOpenCLGBSAOBCForce2" )
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES COMPILE_FLAGS -msse2)
ENDIF( ${TEST_ROOT} STREQUAL "TestOpenCLGBSAOBCForce2" ) ENDIF( ${TEST_ROOT} STREQUAL "TestOpenCLGBSAOBCForce2" )
ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single) ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single)
IF (OPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS) IF (OPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS)
......
...@@ -53,44 +53,6 @@ using namespace std; ...@@ -53,44 +53,6 @@ using namespace std;
OpenCLPlatform platform; OpenCLPlatform platform;
void testChangingBoxSize() {
System system;
system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 5, 0), Vec3(0, 0, 6));
system.addParticle(1.0);
NonbondedForce* nb = new NonbondedForce();
nb->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
nb->setCutoffDistance(2.0);
nb->addParticle(1, 0.5, 0.5);
system.addForce(nb);
LangevinIntegrator integrator(300.0, 1.0, 0.01);
Context context(system, integrator, platform);
vector<Vec3> positions;
positions.push_back(Vec3());
context.setPositions(positions);
Vec3 x, y, z;
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ASSERT_EQUAL_VEC(Vec3(4, 0, 0), x, 0);
ASSERT_EQUAL_VEC(Vec3(0, 5, 0), y, 0);
ASSERT_EQUAL_VEC(Vec3(0, 0, 6), z, 0);
context.setPeriodicBoxVectors(Vec3(7, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 9));
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ASSERT_EQUAL_VEC(Vec3(7, 0, 0), x, 0);
ASSERT_EQUAL_VEC(Vec3(0, 8, 0), y, 0);
ASSERT_EQUAL_VEC(Vec3(0, 0, 9), z, 0);
// Shrinking the box too small should produce an exception.
context.setPeriodicBoxVectors(Vec3(7, 0, 0), Vec3(0, 3.9, 0), Vec3(0, 0, 9));
bool ok = true;
try {
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ok = false;
}
catch (exception& ex) {
}
ASSERT(ok);
}
void testIdealGas() { void testIdealGas() {
const int numParticles = 64; const int numParticles = 64;
const int frequency = 10; const int frequency = 10;
...@@ -112,7 +74,7 @@ void testIdealGas() { ...@@ -112,7 +74,7 @@ void testIdealGas() {
system.addParticle(1.0); system.addParticle(1.0);
positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt));
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], frequency); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], true, true, true, frequency);
system.addForce(barostat); system.addForce(barostat);
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -170,7 +132,7 @@ void testIdealGasAxis(int axis) { ...@@ -170,7 +132,7 @@ void testIdealGasAxis(int axis) {
system.addParticle(1.0); system.addParticle(1.0);
positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt));
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], frequency, scaleX, scaleY, scaleZ); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], scaleX, scaleY, scaleZ, frequency);
system.addForce(barostat); system.addForce(barostat);
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -226,7 +188,7 @@ void testRandomSeed() { ...@@ -226,7 +188,7 @@ void testRandomSeed() {
forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0); forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
} }
system.addForce(forceField); system.addForce(forceField);
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, 1); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, true, true, true, 1);
system.addForce(barostat); system.addForce(barostat);
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
...@@ -332,7 +294,7 @@ void testEinsteinCrystal() { ...@@ -332,7 +294,7 @@ void testEinsteinCrystal() {
system.addForce(force); system.addForce(force);
system.addForce(nb); system.addForce(nb);
// Create the barostat. // Create the barostat.
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pres3[p], pres3[p], pres3[p]), temp, frequency, (a==0||a==3), (a==1||a==3), (a==2||a==3)); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pres3[p], pres3[p], pres3[p]), temp, (a==0||a==3), (a==1||a==3), (a==2||a==3), frequency);
system.addForce(barostat); system.addForce(barostat);
barostat->setTemperature(temp); barostat->setTemperature(temp);
LangevinIntegrator integrator(temp, 0.1, 0.01); LangevinIntegrator integrator(temp, 0.1, 0.01);
...@@ -422,7 +384,6 @@ int main(int argc, char* argv[]) { ...@@ -422,7 +384,6 @@ int main(int argc, char* argv[]) {
try { try {
if (argc > 1) if (argc > 1)
platform.setPropertyDefaultValue("OpenCLPrecision", string(argv[1])); platform.setPropertyDefaultValue("OpenCLPrecision", string(argv[1]));
testChangingBoxSize();
testIdealGas(); testIdealGas();
testIdealGasAxis(0); testIdealGasAxis(0);
testIdealGasAxis(1); testIdealGasAxis(1);
......
...@@ -51,45 +51,6 @@ ...@@ -51,45 +51,6 @@
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
void testChangingBoxSize() {
ReferencePlatform platform;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 5, 0), Vec3(0, 0, 6));
system.addParticle(1.0);
NonbondedForce* nb = new NonbondedForce();
nb->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
nb->setCutoffDistance(2.0);
nb->addParticle(1, 0.5, 0.5);
system.addForce(nb);
LangevinIntegrator integrator(300.0, 1.0, 0.01);
Context context(system, integrator, platform);
vector<Vec3> positions;
positions.push_back(Vec3());
context.setPositions(positions);
Vec3 x, y, z;
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ASSERT_EQUAL_VEC(Vec3(4, 0, 0), x, 0);
ASSERT_EQUAL_VEC(Vec3(0, 5, 0), y, 0);
ASSERT_EQUAL_VEC(Vec3(0, 0, 6), z, 0);
context.setPeriodicBoxVectors(Vec3(7, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 9));
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ASSERT_EQUAL_VEC(Vec3(7, 0, 0), x, 0);
ASSERT_EQUAL_VEC(Vec3(0, 8, 0), y, 0);
ASSERT_EQUAL_VEC(Vec3(0, 0, 9), z, 0);
// Shrinking the box too small should produce an exception.
context.setPeriodicBoxVectors(Vec3(7, 0, 0), Vec3(0, 3.9, 0), Vec3(0, 0, 9));
bool ok = true;
try {
context.getState(State::Forces).getPeriodicBoxVectors(x, y, z);
ok = false;
}
catch (exception& ex) {
}
ASSERT(ok);
}
void testIdealGas() { void testIdealGas() {
const int numParticles = 64; const int numParticles = 64;
const int frequency = 10; const int frequency = 10;
...@@ -112,7 +73,7 @@ void testIdealGas() { ...@@ -112,7 +73,7 @@ void testIdealGas() {
system.addParticle(1.0); system.addParticle(1.0);
positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt));
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], frequency); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], true, true, true, frequency);
system.addForce(barostat); system.addForce(barostat);
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -171,7 +132,7 @@ void testIdealGasAxis(int axis) { ...@@ -171,7 +132,7 @@ void testIdealGasAxis(int axis) {
system.addParticle(1.0); system.addParticle(1.0);
positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt));
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], frequency, scaleX, scaleY, scaleZ); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], scaleX, scaleY, scaleZ, frequency);
system.addForce(barostat); system.addForce(barostat);
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -228,7 +189,7 @@ void testRandomSeed() { ...@@ -228,7 +189,7 @@ void testRandomSeed() {
forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0); forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0);
} }
system.addForce(forceField); system.addForce(forceField);
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, 1); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, true, true, true, 1);
system.addForce(barostat); system.addForce(barostat);
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
...@@ -335,7 +296,7 @@ void testEinsteinCrystal() { ...@@ -335,7 +296,7 @@ void testEinsteinCrystal() {
system.addForce(force); system.addForce(force);
system.addForce(nb); system.addForce(nb);
// Create the barostat. // Create the barostat.
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pres3[p], pres3[p], pres3[p]), temp, frequency, (a==0||a==3), (a==1||a==3), (a==2||a==3)); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pres3[p], pres3[p], pres3[p]), temp, (a==0||a==3), (a==1||a==3), (a==2||a==3), frequency);
system.addForce(barostat); system.addForce(barostat);
barostat->setTemperature(temp); barostat->setTemperature(temp);
LangevinIntegrator integrator(temp, 0.1, 0.01); LangevinIntegrator integrator(temp, 0.1, 0.01);
......
...@@ -113,7 +113,7 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug) ...@@ -113,7 +113,7 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}OpenCL_d optimized ${OPENMM_LIBRARY_NAME}OpenCL) TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}OpenCL_d optimized ${OPENMM_LIBRARY_NAME}OpenCL)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_DRUDE_TARGET} optimized ${SHARED_DRUDE_TARGET}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_DRUDE_TARGET} optimized ${SHARED_DRUDE_TARGET})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY") SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-msse2 -DOPENMM_BUILDING_SHARED_LIBRARY")
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
# Ensure that links to the main OpenCL library will be resolved. # Ensure that links to the main OpenCL library will be resolved.
......
...@@ -112,7 +112,7 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug) ...@@ -112,7 +112,7 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}OpenCL_d optimized ${OPENMM_LIBRARY_NAME}OpenCL) TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}OpenCL_d optimized ${OPENMM_LIBRARY_NAME}OpenCL)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_RPMD_TARGET} optimized ${SHARED_RPMD_TARGET}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_RPMD_TARGET} optimized ${SHARED_RPMD_TARGET})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY") SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-msse2 -DOPENMM_BUILDING_SHARED_LIBRARY")
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
# Ensure that links to the main OpenCL library will be resolved. # Ensure that links to the main OpenCL library will be resolved.
......
/* -------------------------------------------------------------------------- *
* 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) 2013 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 "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
using namespace std;
void testFindMolecules() {
const int numMolecules = 5;
const int moleculeSize[] = {1, 10, 100, 1000, 10000};
vector<int> particleMolecule;
System system;
HarmonicBondForce* bonds = new HarmonicBondForce();
system.addForce(bonds);
for (int i = 0; i < numMolecules; i++)
for (int j = 0; j < moleculeSize[i]; j++) {
int index = system.addParticle(1.0);
particleMolecule.push_back(i);
if (j > 0)
bonds->addBond(index, index-1, 1.0, 1.0);
}
VerletIntegrator integrator(1.0);
Context context(system, integrator, Platform::getPlatformByName("Reference"));
ContextImpl* contextImpl = *reinterpret_cast<ContextImpl**>(&context);
const vector<vector<int> >& molecules = contextImpl->getMolecules();
ASSERT_EQUAL(numMolecules, molecules.size());
for (int i = 0; i < numMolecules; i++) {
ASSERT_EQUAL(moleculeSize[i], molecules[i].size());
for (int j = 0; j < moleculeSize[i]; j++)
ASSERT_EQUAL(particleMolecule[molecules[i][j]], i);
}
}
int main() {
try {
testFindMolecules();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
...@@ -21,8 +21,25 @@ set(STAGING_OUTPUT_FILES "") # Will contain all required package files ...@@ -21,8 +21,25 @@ set(STAGING_OUTPUT_FILES "") # Will contain all required package files
file(GLOB STAGING_INPUT_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" file(GLOB STAGING_INPUT_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.in" "${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.in"
"${CMAKE_CURRENT_SOURCE_DIR}/README.txt" "${CMAKE_CURRENT_SOURCE_DIR}/README.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/*.py" "${CMAKE_CURRENT_SOURCE_DIR}/filterPythonFiles.py"
) )
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py ${OPENMM_PYTHON_STAGING_DIR}/setup.py)
###########################################################
### Check the git revision of the source, and write it ###
### to a python file in the in the staging directory ###
###########################################################
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE rev_hash_str
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(NOT rev_hash_str)
set(rev_hash_str "Unknown")
endif()
file(WRITE "${OPENMM_PYTHON_STAGING_DIR}/simtk/openmm/version.py" "git_revision = '${rev_hash_str}'\n")
# file(GLOB_RECURSE temp RELATIVE "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/src/*.i") # file(GLOB_RECURSE temp RELATIVE "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/src/*.i")
# foreach(f ${temp}) # foreach(f ${temp})
......
...@@ -6,15 +6,18 @@ setup.py: Used for building python wrappers for Simbios' OpenMM library. ...@@ -6,15 +6,18 @@ setup.py: Used for building python wrappers for Simbios' OpenMM library.
__author__ = "Randall J. Radmer" __author__ = "Randall J. Radmer"
__version__ = "1.0" __version__ = "1.0"
import ast
import os, sys, platform, glob, shutil import re
import struct import os
import sys
import platform
from distutils.core import setup from distutils.core import setup
MAJOR_VERSION_NUM='5' MAJOR_VERSION_NUM='@OPENMM_MAJOR_VERSION@'
MINOR_VERSION_NUM='1' MINOR_VERSION_NUM='@OPENMM_MINOR_VERSION@'
BUILD_INFO='0' BUILD_INFO='@OPENMM_BUILD_VERSION@'
IS_RELEASED = False
def reportError(message): def reportError(message):
sys.stdout.write("ERROR: ") sys.stdout.write("ERROR: ")
...@@ -64,6 +67,57 @@ def uninstall(verbose=True): ...@@ -64,6 +67,57 @@ def uninstall(verbose=True):
sys.path=save_path sys.path=save_path
def writeVersionPy(filename="simtk/openmm/version.py", major_version_num=MAJOR_VERSION_NUM,
minor_version_num=MINOR_VERSION_NUM, build_info=BUILD_INFO):
"""Write a version.py file into the python source directory before installation.
If a version.py file already exists, we assume that it contains only the git_revision
information, since from within this python session in the python staging directory, we're
not in the version controlled directory hierarchy.
When cmake is copying files into the PYTHON_STAGING_DIRECTORY, it will write the
git revision to version.py. We read that, and then overwrite it.
"""
cnt = """
# THIS FILE IS GENERATED FROM OPENMM SETUP.PY
short_version = '%(version)s'
version = '%(version)s'
full_version = '%(full_version)s'
git_revision = '%(git_revision)s'
release = %(isrelease)s
if not release:
version = full_version
"""
if os.path.exists(filename):
# git_revision is written to the file by cmake
with open(filename) as f:
text = f.read()
match = re.search(r"git_revision\s+=\s+(.*)", text, re.MULTILINE)
try:
git_revision = ast.literal_eval(match.group(1))
except:
# except anything, including no re match or
# literal_eval failing
git_revision = 'Unknown'
else:
git_revision = 'Unknown'
version = full_version = '%s.%s.%s' % (major_version_num, minor_version_num, build_info)
if not IS_RELEASED:
full_version += '.dev-' + git_revision[:7]
a = open(filename, 'w')
try:
a.write(cnt % {'version': version,
'full_version' : full_version,
'git_revision' : git_revision,
'isrelease': str(IS_RELEASED)})
finally:
a.close()
def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
minor_version_num=MINOR_VERSION_NUM, minor_version_num=MINOR_VERSION_NUM,
build_info=BUILD_INFO): build_info=BUILD_INFO):
...@@ -184,6 +238,7 @@ def main(): ...@@ -184,6 +238,7 @@ def main():
uninstall() uninstall()
except: except:
pass pass
writeVersionPy()
setupKeywords=buildKeywordDictionary() setupKeywords=buildKeywordDictionary()
setup(**setupKeywords) setup(**setupKeywords)
......
<ForceField>
<AtomTypes>
<Type name="swm4ndp-O" class="OW" element="O" mass="15.59943"/>
<Type name="swm4ndp-H" class="HW" element="H" mass="1.007947"/>
<Type name="swm4ndp-M" class="MW" mass="0"/>
<Type name="swm4ndp-OD" class="OWD" mass="0.4"/>
</AtomTypes>
<Residues>
<Residue name="HOH">
<Atom name="O" type="swm4ndp-O"/>
<Atom name="H1" type="swm4ndp-H"/>
<Atom name="H2" type="swm4ndp-H"/>
<Atom name="M" type="swm4ndp-M"/>
<Atom name="OD" type="swm4ndp-OD"/>
<VirtualSite type="average3" index="3" atom1="0" atom2="1" atom3="2" weight1="0.786646558" weight2="0.106676721" weight3="0.106676721"/>
<Bond from="0" to="1"/>
<Bond from="0" to="2"/>
</Residue>
</Residues>
<HarmonicBondForce>
<Bond class1="OW" class2="HW" length="0.09572" k="462750.4"/>
</HarmonicBondForce>
<HarmonicAngleForce>
<Angle class1="HW" class2="OW" class3="HW" angle="1.82421813418" k="836.8"/>
</HarmonicAngleForce>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5">
<Atom type="swm4ndp-O" charge="1.71636" sigma="0.318395" epsilon="0.882573"/>
<Atom type="swm4ndp-H" charge="0.55733" sigma="1" epsilon="0"/>
<Atom type="swm4ndp-M" charge="-1.11466" sigma="1" epsilon="0"/>
<Atom type="swm4ndp-OD" charge="-1.71636" sigma="1" epsilon="0"/>
</NonbondedForce>
<DrudeForce>
<Particle type1="swm4ndp-OD" type2="swm4ndp-O" charge="-1.71636" polarizability="7.040850e-6" thole="1.3"/>
</DrudeForce>
</ForceField>
...@@ -323,7 +323,7 @@ class ForceField(object): ...@@ -323,7 +323,7 @@ class ForceField(object):
template = t template = t
break break
if matches is None: if matches is None:
raise ValueError('No template found for residue %d (%s). This might mean your input topology is missing some atoms or bonds, or possibly that you are using the wrong force field.' % (res.index+1, res.name)) raise ValueError('No template found for residue %d (%s). %s' % (res.index+1, res.name, _findMatchErrors(self, res)))
for atom, match in zip(res.atoms(), matches): for atom, match in zip(res.atoms(), matches):
data.atomType[atom] = template.atoms[match].type data.atomType[atom] = template.atoms[match].type
for site in template.virtualSites: for site in template.virtualSites:
...@@ -461,19 +461,24 @@ class ForceField(object): ...@@ -461,19 +461,24 @@ class ForceField(object):
return sys return sys
def _createResidueSignature(elements): def _countResidueAtoms(elements):
"""Create a signature for a residue based on the elements of the atoms it contains.""" """Count the number of atoms of each element in a residue."""
counts = {} counts = {}
for element in elements: for element in elements:
if element is None: if element in counts:
pass # This residue contains "atoms" (probably virtual sites) that should match any element
elif element in counts:
counts[element] += 1 counts[element] += 1
else: else:
counts[element] = 1 counts[element] = 1
return counts
def _createResidueSignature(elements):
"""Create a signature for a residue based on the elements of the atoms it contains."""
counts = _countResidueAtoms(elements)
sig = [] sig = []
for c in counts: for c in counts:
sig.append((c, counts[c])) if c is not None:
sig.append((c, counts[c]))
sig.sort(key=lambda x: -x[0].mass) sig.sort(key=lambda x: -x[0].mass)
# Convert it to a string. # Convert it to a string.
...@@ -539,6 +544,67 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch ...@@ -539,6 +544,67 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
return False return False
def _findMatchErrors(forcefield, res):
"""Try to guess why a residue failed to match any template and return an error message."""
residueCounts = _countResidueAtoms([atom.element for atom in res.atoms()])
numResidueAtoms = sum(residueCounts.itervalues())
numResidueHeavyAtoms = sum(residueCounts[element] for element in residueCounts if element not in (None, elem.hydrogen))
# Loop over templates and see how closely each one might match.
bestMatchName = None
numBestMatchAtoms = 3*numResidueAtoms
numBestMatchHeavyAtoms = 2*numResidueHeavyAtoms
for templateName in forcefield._templates:
template = forcefield._templates[templateName]
templateCounts = _countResidueAtoms([atom.element for atom in template.atoms])
# Does the residue have any atoms that clearly aren't in the template?
if any(element not in templateCounts or templateCounts[element] < residueCounts[element] for element in residueCounts):
continue
# If there are too many missing atoms, discard this template.
numTemplateAtoms = sum(templateCounts.itervalues())
numTemplateHeavyAtoms = sum(templateCounts[element] for element in templateCounts if element not in (None, elem.hydrogen))
if numTemplateAtoms > numBestMatchAtoms:
continue
if numTemplateHeavyAtoms > numBestMatchHeavyAtoms:
continue
# If this template has the same number of missing atoms as our previous best one, look at the name
# to decide which one to use.
if numTemplateAtoms == numBestMatchAtoms:
if bestMatchName == res.name or res.name not in templateName:
continue
# Accept this as our new best match.
bestMatchName = templateName
numBestMatchAtoms = numTemplateAtoms
numBestMatchHeavyAtoms = numTemplateHeavyAtoms
numBestMatchExtraParticles = len([atom for atom in template.atoms if atom.element is None])
# Return an appropriate error message.
if numBestMatchAtoms == numResidueAtoms:
chainLength = len(list(res.chain.residues()))
if chainLength > 1 and (res.index == 0 or res.index == chainLength-1):
return 'The set of atoms matches %s, but the bonds are different. Perhaps the chain is missing a terminal group?' % bestMatchName
return 'The set of atoms matches %s, but the bonds are different.' % bestMatchName
if bestMatchName is not None:
if numBestMatchHeavyAtoms == numResidueHeavyAtoms:
numResidueExtraParticles = len([atom for atom in res.atoms() if atom.element is None])
if numResidueExtraParticles == 0 and numBestMatchExtraParticles == 0:
return 'The set of atoms is similar to %s, but it is missing %d hydrogen atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
if numBestMatchExtraParticles-numResidueExtraParticles == numBestMatchAtoms-numResidueAtoms:
return 'The set of atoms is similar to %s, but it is missing %d extra particles. You can add them with Modeller.addExtraParticles().' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
return 'The set of atoms is similar to %s, but it is missing %d atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
return 'This might mean your input topology is missing some atoms or bonds, or possibly that you are using the wrong force field.'
# The following classes are generators that know how to create Force subclasses and add them to a System that is being # The following classes are generators that know how to create Force subclasses and add them to a System that is being
# created. Each generator class must define two methods: 1) a static method that takes an etree Element and a ForceField, # created. Each generator class must define two methods: 1) a static method that takes an etree Element and a ForceField,
# and returns the corresponding generator object; 2) a createForce() method that constructs the Force object and adds it # and returns the corresponding generator object; 2) a createForce() method that constructs the Force object and adds it
......
...@@ -462,6 +462,24 @@ class GromacsTopFile(object): ...@@ -462,6 +462,24 @@ class GromacsTopFile(object):
topologyAtoms = list(self.topology.atoms()) topologyAtoms = list(self.topology.atoms())
exceptions = [] exceptions = []
fudgeQQ = float(self._defaults[4]) fudgeQQ = float(self._defaults[4])
# Build a lookup table to let us process dihedrals more quickly.
dihedralTypeTable = {}
for key in self._dihedralTypes:
if key[1] != 'X' and key[2] != 'X':
if (key[1], key[2]) not in dihedralTypeTable:
dihedralTypeTable[(key[1], key[2])] = []
dihedralTypeTable[(key[1], key[2])].append(key)
if (key[2], key[1]) not in dihedralTypeTable:
dihedralTypeTable[(key[2], key[1])] = []
dihedralTypeTable[(key[2], key[1])].append(key)
wildcardDihedralTypes = []
for key in self._dihedralTypes:
if key[1] == 'X' or key[2] == 'X':
wildcardDihedralTypes.append(key)
for types in dihedralTypeTable.itervalues():
types.append(key)
# Loop over molecules and create the specified number of each type. # Loop over molecules and create the specified number of each type.
...@@ -584,7 +602,11 @@ class GromacsTopFile(object): ...@@ -584,7 +602,11 @@ class GromacsTopFile(object):
else: else:
# Look for a matching dihedral type. # Look for a matching dihedral type.
paramsList = None paramsList = None
for key in self._dihedralTypes: if (types[1], types[2]) in dihedralTypeTable:
dihedralTypes = dihedralTypeTable[(types[1], types[2])]
else:
dihedralTypes = wildcardDihedralTypes
for key in dihedralTypes:
if all(a == b or a == 'X' for a, b in zip(key, types)) or all(a == b or a == 'X' for a, b in zip(key, reversedTypes)): if all(a == b or a == 'X' for a, b in zip(key, types)) or all(a == b or a == 'X' for a, b in zip(key, reversedTypes)):
paramsList = self._dihedralTypes[key] paramsList = self._dihedralTypes[key]
if 'X' not in key: if 'X' not in key:
......
...@@ -176,6 +176,8 @@ class Modeller(object): ...@@ -176,6 +176,8 @@ class Modeller(object):
Parameters: Parameters:
- model (string='tip3p') the water model to convert to. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'. - model (string='tip3p') the water model to convert to. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'.
@deprecated Use addExtraParticles() instead. It performs the same function but in a more general way.
""" """
if model in ('tip3p', 'spce'): if model in ('tip3p', 'spce'):
sites = 3 sites = 3
...@@ -517,7 +519,7 @@ class Modeller(object): ...@@ -517,7 +519,7 @@ class Modeller(object):
terminal = hydrogen.attrib['terminal'] terminal = hydrogen.attrib['terminal']
data.hydrogens.append(Modeller._Hydrogen(hydrogen.attrib['name'], hydrogen.attrib['parent'], maxph, atomVariants, terminal)) data.hydrogens.append(Modeller._Hydrogen(hydrogen.attrib['name'], hydrogen.attrib['parent'], maxph, atomVariants, terminal))
def addHydrogens(self, forcefield, pH=7.0, variants=None): def addHydrogens(self, forcefield, pH=7.0, variants=None, platform=None):
"""Add missing hydrogens to the model. """Add missing hydrogens to the model.
Some residues can exist in multiple forms depending on the pH and properties of the local environment. These Some residues can exist in multiple forms depending on the pH and properties of the local environment. These
...@@ -564,6 +566,8 @@ class Modeller(object): ...@@ -564,6 +566,8 @@ class Modeller(object):
- variants (list=None) an optional list of variants to use. If this is specified, its length must equal the number - variants (list=None) an optional list of variants to use. If this is specified, its length must equal the number
of residues in the model. variants[i] is the name of the variant to use for residue i (indexed starting at 0). of residues in the model. variants[i] is the name of the variant to use for residue i (indexed starting at 0).
If an element is None, the standard rules will be followed to select a variant for that residue. If an element is None, the standard rules will be followed to select a variant for that residue.
- platform (Platform=None) the Platform to use when computing the hydrogen atom positions. If this is None,
the default Platform will be used.
Returns: a list of what variant was actually selected for each residue, in the same format as the variants parameter Returns: a list of what variant was actually selected for each residue, in the same format as the variants parameter
""" """
# Check the list of variants. # Check the list of variants.
...@@ -757,9 +761,10 @@ class Modeller(object): ...@@ -757,9 +761,10 @@ class Modeller(object):
if atoms[i].element != elem.hydrogen: if atoms[i].element != elem.hydrogen:
# This is a heavy atom, so make it immobile. # This is a heavy atom, so make it immobile.
system.setParticleMass(i, 0) system.setParticleMass(i, 0)
from simtk.openmm import Platform if platform is None:
plt = Platform.getPlatformByName('Reference') context = Context(system, VerletIntegrator(0.0))
context = Context(system, VerletIntegrator(0.0), plt) else:
context = Context(system, VerletIntegrator(0.0), platform)
context.setPositions(newPositions) context.setPositions(newPositions)
LocalEnergyMinimizer.minimize(context) LocalEnergyMinimizer.minimize(context)
self.topology = newTopology self.topology = newTopology
......
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