Commit 61d5cc0f authored by Peter's avatar Peter
Browse files

Merge branch 'master' into applecl

parents e2999354 afae4bc8
...@@ -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) 2013-2014 Stanford University and the Authors. * * Portions copyright (c) 2013-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -109,24 +109,12 @@ public: ...@@ -109,24 +109,12 @@ public:
fvec4 operator|(const fvec4& other) const { fvec4 operator|(const fvec4& other) const {
return (fvec4) (((__m128i)val)|((__m128i)other.val)); return (fvec4) (((__m128i)val)|((__m128i)other.val));
} }
fvec4 operator==(const fvec4& other) const { ivec4 operator==(const fvec4& other) const;
return (val==other.val); ivec4 operator!=(const fvec4& other) const;
} ivec4 operator>(const fvec4& other) const;
fvec4 operator!=(const fvec4& other) const { ivec4 operator<(const fvec4& other) const;
return (val!=other.val); ivec4 operator>=(const fvec4& other) const;
} ivec4 operator<=(const fvec4& other) const;
fvec4 operator>(const fvec4& other) const {
return (val>other.val);
}
fvec4 operator<(const fvec4& other) const {
return (val<other.val);
}
fvec4 operator>=(const fvec4& other) const {
return (val>=other.val);
}
fvec4 operator<=(const fvec4& other) const {
return (val<=other.val);
}
operator ivec4() const; operator ivec4() const;
}; };
...@@ -207,42 +195,42 @@ public: ...@@ -207,42 +195,42 @@ public:
// Conversion operators. // Conversion operators.
inline fvec4::operator ivec4() const { inline ivec4 fvec4::operator==(const fvec4& other) const {
return __builtin_convertvector(val, __m128i); return (__m128i) (val==other.val);
} }
inline ivec4::operator fvec4() const { inline ivec4 fvec4::operator!=(const fvec4& other) const {
return __builtin_convertvector(val, __m128); return (__m128i) (val!=other.val);
} }
// Functions that operate on fvec4s. inline ivec4 fvec4::operator>(const fvec4& other) const {
return (__m128i) (val>other.val);
static inline fvec4 floor(const fvec4& v) {
return fvec4(std::floor(v[0]), std::floor(v[1]), std::floor(v[2]), std::floor(v[3]));
} }
static inline fvec4 ceil(const fvec4& v) { inline ivec4 fvec4::operator<(const fvec4& other) const {
return fvec4(std::ceil(v[0]), std::ceil(v[1]), std::ceil(v[2]), std::ceil(v[3])); return (__m128i) (val<other.val);
} }
static inline fvec4 round(const fvec4& v) { inline ivec4 fvec4::operator>=(const fvec4& other) const {
return fvec4(std::round(v[0]), std::round(v[1]), std::round(v[2]), std::round(v[3])); return (__m128i) (val>=other.val);
} }
static inline fvec4 min(const fvec4& v1, const fvec4& v2) { inline ivec4 fvec4::operator<=(const fvec4& other) const {
return fvec4(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]), std::min(v1[2], v2[2]), std::min(v1[3], v2[3])); return (__m128i) (val<=other.val);
} }
static inline fvec4 max(const fvec4& v1, const fvec4& v2) { inline fvec4::operator ivec4() const {
return fvec4(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]), std::max(v1[2], v2[2]), std::max(v1[3], v2[3])); return __builtin_convertvector(val, __m128i);
} }
static inline fvec4 abs(const fvec4& v) { inline ivec4::operator fvec4() const {
return fvec4(std::abs(v[0]), std::abs(v[1]), std::abs(v[2]), std::abs(v[3])); return __builtin_convertvector(val, __m128);
} }
static inline fvec4 sqrt(const fvec4& v) { // Functions that operate on fvec4s.
return fvec4(std::sqrt(v[0]), std::sqrt(v[1]), std::sqrt(v[2]), std::sqrt(v[3]));
static inline fvec4 abs(const fvec4& v) {
return v&(__m128) ivec4(0x7FFFFFFF);
} }
static inline float dot3(const fvec4& v1, const fvec4& v2) { static inline float dot3(const fvec4& v1, const fvec4& v2) {
...@@ -252,7 +240,8 @@ static inline float dot3(const fvec4& v1, const fvec4& v2) { ...@@ -252,7 +240,8 @@ static inline float dot3(const fvec4& v1, const fvec4& v2) {
static inline float dot4(const fvec4& v1, const fvec4& v2) { static inline float dot4(const fvec4& v1, const fvec4& v2) {
fvec4 r = v1*v2; fvec4 r = v1*v2;
return r[0]+r[1]+r[2]+r[3]; fvec4 temp = __builtin_shufflevector(r.val, r.val, 0, 1, -1, -1)+__builtin_shufflevector(r.val, r.val, 2, 3, -1, -1);
return temp[0]+temp[1];
} }
static inline fvec4 cross(const fvec4& v1, const fvec4& v2) { static inline fvec4 cross(const fvec4& v1, const fvec4& v2) {
...@@ -287,7 +276,8 @@ static inline ivec4 abs(const ivec4& v) { ...@@ -287,7 +276,8 @@ static inline ivec4 abs(const ivec4& v) {
} }
static inline bool any(const __m128i& v) { static inline bool any(const __m128i& v) {
return (v[0] || v[1] || v[2] || v[3]); ivec4 temp = __builtin_shufflevector(v, v, 0, 1, -1, -1) | __builtin_shufflevector(v, v, 2, 3, -1, -1);
return (temp[0] || temp[1]);
} }
// Mathematical operators involving a scalar and a vector. // Mathematical operators involving a scalar and a vector.
...@@ -311,7 +301,53 @@ static inline fvec4 operator/(float v1, const fvec4& v2) { ...@@ -311,7 +301,53 @@ static inline fvec4 operator/(float v1, const fvec4& v2) {
// Operations for blending fvec4s based on an ivec4. // Operations for blending fvec4s based on an ivec4.
static inline fvec4 blend(const fvec4& v1, const fvec4& v2, const __m128i& mask) { static inline fvec4 blend(const fvec4& v1, const fvec4& v2, const __m128i& mask) {
return fvec4(mask[0] ? v2[0] : v1[0], mask[1] ? v2[1] : v1[1], mask[2] ? v2[2] : v1[2], mask[3] ? v2[3] : v1[3]); return (__m128) ((mask&(__m128i)v2) + ((ivec4(0xFFFFFFFF)-ivec4(mask))&(__m128i)v1));
}
// These are at the end since they involve other functions defined above.
static inline fvec4 min(const fvec4& v1, const fvec4& v2) {
return blend(v1, v2, v1 > v2);
}
static inline fvec4 max(const fvec4& v1, const fvec4& v2) {
return blend(v1, v2, v1 < v2);
}
static inline fvec4 round(const fvec4& v) {
fvec4 shift(0x1.0p23f);
fvec4 absResult = (abs(v)+shift)-shift;
return (__m128) ((ivec4(0x80000000)&(__m128i)v) + (ivec4(0x7FFFFFFF)&(__m128i)absResult));
}
static inline fvec4 floor(const fvec4& v) {
fvec4 truncated = __builtin_convertvector(__builtin_convertvector(v.val, __m128i), __m128);
return truncated + blend(0.0f, -1.0f, truncated>v);
}
static inline fvec4 ceil(const fvec4& v) {
fvec4 truncated = __builtin_convertvector(__builtin_convertvector(v.val, __m128i), __m128);
return truncated + blend(0.0f, 1.0f, truncated<v);
}
static inline fvec4 rsqrt(const fvec4& v) {
// Initial estimate of rsqrt().
ivec4 i = (__m128i) v;
i = ivec4(0x5f375a86)-ivec4(i.val>>ivec4(1).val);
fvec4 y = (__m128) i;
// Perform three iterations of Newton refinement.
fvec4 x2 = 0.5f*v;
y *= 1.5f-x2*y*y;
y *= 1.5f-x2*y*y;
y *= 1.5f-x2*y*y;
return y;
}
static inline fvec4 sqrt(const fvec4& v) {
return rsqrt(v)*v;
} }
#endif /*OPENMM_VECTORIZE_PNACL_H_*/ #endif /*OPENMM_VECTORIZE_PNACL_H_*/
......
...@@ -241,6 +241,18 @@ static inline fvec4 sqrt(const fvec4& v) { ...@@ -241,6 +241,18 @@ static inline fvec4 sqrt(const fvec4& v) {
return fvec4(_mm_sqrt_ps(v.val)); return fvec4(_mm_sqrt_ps(v.val));
} }
static inline fvec4 rsqrt(const fvec4& v) {
// Initial estimate of rsqrt().
fvec4 y(_mm_rsqrt_ps(v.val));
// Perform an iteration of Newton refinement.
fvec4 x2 = v*0.5f;
y *= fvec4(1.5f)-x2*y*y;
return y;
}
static inline float dot3(const fvec4& v1, const fvec4& v2) { static inline float dot3(const fvec4& v1, const fvec4& v2) {
return _mm_cvtss_f32(_mm_dp_ps(v1, v2, 0x71)); return _mm_cvtss_f32(_mm_dp_ps(v1, v2, 0x71));
} }
......
...@@ -37,7 +37,7 @@ using namespace OpenMM; ...@@ -37,7 +37,7 @@ using namespace OpenMM;
AndersenThermostat::AndersenThermostat(double defaultTemperature, double defaultCollisionFrequency) : AndersenThermostat::AndersenThermostat(double defaultTemperature, double defaultCollisionFrequency) :
defaultTemp(defaultTemperature), defaultFreq(defaultCollisionFrequency) { defaultTemp(defaultTemperature), defaultFreq(defaultCollisionFrequency) {
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
ForceImpl* AndersenThermostat::createImpl() const { ForceImpl* AndersenThermostat::createImpl() const {
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/kernels.h" #include "openmm/kernels.h"
#include <string> #include <string>
...@@ -46,7 +45,7 @@ BrownianIntegrator::BrownianIntegrator(double temperature, double frictionCoeff, ...@@ -46,7 +45,7 @@ BrownianIntegrator::BrownianIntegrator(double temperature, double frictionCoeff,
setFriction(frictionCoeff); setFriction(frictionCoeff);
setStepSize(stepSize); setStepSize(stepSize);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
void BrownianIntegrator::initialize(ContextImpl& contextRef) { void BrownianIntegrator::initialize(ContextImpl& contextRef) {
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -96,3 +96,6 @@ ForceImpl* CMAPTorsionForce::createImpl() const { ...@@ -96,3 +96,6 @@ ForceImpl* CMAPTorsionForce::createImpl() const {
return new CMAPTorsionForceImpl(*this); return new CMAPTorsionForceImpl(*this);
} }
void CMAPTorsionForce::updateParametersInContext(Context& context) {
dynamic_cast<CMAPTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
}
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -154,4 +154,8 @@ void CMAPTorsionForceImpl::calcMapDerivatives(int size, const vector<double>& en ...@@ -154,4 +154,8 @@ void CMAPTorsionForceImpl::calcMapDerivatives(int size, const vector<double>& en
} }
} }
} }
} }
\ No newline at end of file
void CMAPTorsionForceImpl::updateParametersInContext(ContextImpl& context) {
kernel.getAs<CalcCMAPTorsionForceKernel>().copyParametersToContext(context, owner);
}
...@@ -143,42 +143,15 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const { ...@@ -143,42 +143,15 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const {
} }
void Context::setState(const State& state) { void Context::setState(const State& state) {
// Determine what information the state contains.
bool hasPositions = false, hasVelocities = false, hasParameters = false;
try {
state.getPositions();
hasPositions = true;
}
catch (OpenMMException& ex) {
// The State does not include positions.
}
try {
state.getVelocities();
hasVelocities = true;
}
catch (OpenMMException& ex) {
// The State does not include velocities.
}
try {
state.getParameters();
hasParameters = true;
}
catch (OpenMMException& ex) {
// The State does not include parameters.
}
// Copy it over.
setTime(state.getTime()); setTime(state.getTime());
Vec3 a, b, c; Vec3 a, b, c;
state.getPeriodicBoxVectors(a, b, c); state.getPeriodicBoxVectors(a, b, c);
setPeriodicBoxVectors(a, b, c); setPeriodicBoxVectors(a, b, c);
if (hasPositions) if ((state.getDataTypes()&State::Positions) != 0)
setPositions(state.getPositions()); setPositions(state.getPositions());
if (hasVelocities) if ((state.getDataTypes()&State::Velocities) != 0)
setVelocities(state.getVelocities()); setVelocities(state.getVelocities());
if (hasParameters) if ((state.getDataTypes()&State::Parameters) != 0)
for (map<string, double>::const_iterator iter = state.getParameters().begin(); iter != state.getParameters().end(); ++iter) for (map<string, double>::const_iterator iter = state.getParameters().begin(); iter != state.getParameters().end(); ++iter)
setParameter(iter->first, iter->second); setParameter(iter->first, iter->second);
} }
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "openmm/VirtualSite.h" #include "openmm/VirtualSite.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include <algorithm> #include <algorithm>
#include <cmath>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <utility> #include <utility>
...@@ -235,10 +236,10 @@ void ContextImpl::getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) { ...@@ -235,10 +236,10 @@ void ContextImpl::getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) {
void ContextImpl::setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) { void ContextImpl::setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) {
if (a[1] != 0.0 || a[2] != 0.0) if (a[1] != 0.0 || a[2] != 0.0)
throw OpenMMException("First periodic box vector must be parallel to x."); throw OpenMMException("First periodic box vector must be parallel to x.");
if (b[0] != 0.0 || b[2] != 0.0) if (b[2] != 0.0)
throw OpenMMException("Second periodic box vector must be parallel to y."); throw OpenMMException("Second periodic box vector must be in the x-y plane.");
if (c[0] != 0.0 || c[1] != 0.0) if (a[0] <= 0.0 || b[1] <= 0.0 || c[2] <= 0.0 || a[0] < 2*fabs(b[0]) || a[0] < 2*fabs(c[0]) || b[1] < 2*fabs(c[1]))
throw OpenMMException("Third periodic box vector must be parallel to z."); throw OpenMMException("Periodic box vectors must be in reduced form.");
updateStateDataKernel.getAs<UpdateStateDataKernel>().setPeriodicBoxVectors(*this, a, b, c); updateStateDataKernel.getAs<UpdateStateDataKernel>().setPeriodicBoxVectors(*this, a, b, c);
} }
...@@ -259,12 +260,16 @@ double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy, ...@@ -259,12 +260,16 @@ double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy,
throw OpenMMException("Particle positions have not been set"); throw OpenMMException("Particle positions have not been set");
lastForceGroups = groups; lastForceGroups = groups;
CalcForcesAndEnergyKernel& kernel = initializeForcesKernel.getAs<CalcForcesAndEnergyKernel>(); CalcForcesAndEnergyKernel& kernel = initializeForcesKernel.getAs<CalcForcesAndEnergyKernel>();
double energy = 0.0; while (true) {
kernel.beginComputation(*this, includeForces, includeEnergy, groups); double energy = 0.0;
for (int i = 0; i < (int) forceImpls.size(); ++i) kernel.beginComputation(*this, includeForces, includeEnergy, groups);
energy += forceImpls[i]->calcForcesAndEnergy(*this, includeForces, includeEnergy, groups); for (int i = 0; i < (int) forceImpls.size(); ++i)
energy += kernel.finishComputation(*this, includeForces, includeEnergy, groups); energy += forceImpls[i]->calcForcesAndEnergy(*this, includeForces, includeEnergy, groups);
return energy; bool valid = true;
energy += kernel.finishComputation(*this, includeForces, includeEnergy, groups, valid);
if (valid)
return energy;
}
} }
int ContextImpl::getLastForceGroups() const { int ContextImpl::getLastForceGroups() const {
......
...@@ -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) 2011-2012 Stanford University and the Authors. * * Portions copyright (c) 2011-2014 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,24 +34,35 @@ ...@@ -34,24 +34,35 @@
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/kernels.h" #include "openmm/kernels.h"
#include <set>
#include <string> #include <string>
using namespace OpenMM; using namespace OpenMM;
using std::string; using namespace std;
using std::vector;
CustomIntegrator::CustomIntegrator(double stepSize) : globalsAreCurrent(true), forcesAreValid(false) { CustomIntegrator::CustomIntegrator(double stepSize) : globalsAreCurrent(true), forcesAreValid(false) {
setStepSize(stepSize); setStepSize(stepSize);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
kineticEnergy = "m*v*v/2"; kineticEnergy = "m*v*v/2";
} }
void CustomIntegrator::initialize(ContextImpl& contextRef) { void CustomIntegrator::initialize(ContextImpl& contextRef) {
if (owner != NULL && &contextRef.getOwner() != owner) if (owner != NULL && &contextRef.getOwner() != owner)
throw OpenMMException("This Integrator is already bound to a context"); throw OpenMMException("This Integrator is already bound to a context");
vector<std::string> variableList;
set<std::string> variableSet;
variableList.insert(variableList.end(), globalNames.begin(), globalNames.end());
variableList.insert(variableList.end(), perDofNames.begin(), perDofNames.end());
for (int i = 0; i < (int) variableList.size(); i++) {
string& name = variableList[i];
if (variableSet.find(name) != variableSet.end())
throw OpenMMException("The Integrator defines two variables with the same name: "+name);
variableSet.insert(name);
if (contextRef.getParameters().find(name) != contextRef.getParameters().end())
throw OpenMMException("The Integrator defines a variable with the same name as a Context parameter: "+name);
}
context = &contextRef; context = &contextRef;
owner = &contextRef.getOwner(); owner = &contextRef.getOwner();
kernel = context->getPlatform().createKernel(IntegrateCustomStepKernel::Name(), contextRef); kernel = context->getPlatform().createKernel(IntegrateCustomStepKernel::Name(), contextRef);
...@@ -124,6 +135,15 @@ double CustomIntegrator::getGlobalVariable(int index) const { ...@@ -124,6 +135,15 @@ double CustomIntegrator::getGlobalVariable(int index) const {
return globalValues[index]; return globalValues[index];
} }
double CustomIntegrator::getGlobalVariableByName(const string& name) const {
for (int i = 0; i < (int) globalNames.size(); i++) {
if (name == globalNames[i]) {
return getGlobalVariable(i);
}
}
throw OpenMMException("Illegal global variable name: "+name);
}
void CustomIntegrator::setGlobalVariable(int index, double value) { void CustomIntegrator::setGlobalVariable(int index, double value) {
ASSERT_VALID_INDEX(index, globalValues); ASSERT_VALID_INDEX(index, globalValues);
if (owner != NULL && !globalsAreCurrent) { if (owner != NULL && !globalsAreCurrent) {
...@@ -152,6 +172,16 @@ void CustomIntegrator::getPerDofVariable(int index, vector<Vec3>& values) const ...@@ -152,6 +172,16 @@ void CustomIntegrator::getPerDofVariable(int index, vector<Vec3>& values) const
kernel.getAs<const IntegrateCustomStepKernel>().getPerDofVariable(*context, index, values); kernel.getAs<const IntegrateCustomStepKernel>().getPerDofVariable(*context, index, values);
} }
void CustomIntegrator::getPerDofVariableByName(const string& name, vector<Vec3>& values) const {
for (int i = 0; i < (int) perDofNames.size(); i++) {
if (name == perDofNames[i]) {
getPerDofVariable(i, values);
return;
}
}
throw OpenMMException("Illegal per-DOF variable name: "+name);
}
void CustomIntegrator::setPerDofVariable(int index, const vector<Vec3>& values) { void CustomIntegrator::setPerDofVariable(int index, const vector<Vec3>& values) {
ASSERT_VALID_INDEX(index, perDofValues); ASSERT_VALID_INDEX(index, perDofValues);
if (owner != NULL && values.size() != context->getSystem().getNumParticles()) if (owner != NULL && values.size() != context->getSystem().getNumParticles())
......
...@@ -49,6 +49,10 @@ void Force::setForceGroup(int group) { ...@@ -49,6 +49,10 @@ void Force::setForceGroup(int group) {
forceGroup = group; forceGroup = group;
} }
bool Force::usesPeriodicBoundaryConditions() const {
throw OpenMMException("usesPeriodicBoundaryConditions is not implemented");
}
ForceImpl& Force::getImplInContext(Context& context) { ForceImpl& Force::getImplInContext(Context& context) {
const vector<ForceImpl*>& impls = context.getImpl().getForceImpls(); const vector<ForceImpl*>& impls = context.getImpl().getForceImpls();
for (int i = 0; i < (int) impls.size(); i++) for (int i = 0; i < (int) impls.size(); i++)
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
using namespace OpenMM; using namespace OpenMM;
GBSAOBCForce::GBSAOBCForce() : nonbondedMethod(NoCutoff), cutoffDistance(1.0), solventDielectric(78.3), soluteDielectric(1.0) { GBSAOBCForce::GBSAOBCForce() : nonbondedMethod(NoCutoff), cutoffDistance(1.0), solventDielectric(78.3), soluteDielectric(1.0), surfaceAreaEnergy(2.25936) {
} }
int GBSAOBCForce::addParticle(double charge, double radius, double scalingFactor) { int GBSAOBCForce::addParticle(double charge, double radius, double scalingFactor) {
......
...@@ -77,7 +77,7 @@ void GBVIForce::setCutoffDistance(double distance) { ...@@ -77,7 +77,7 @@ void GBVIForce::setCutoffDistance(double distance) {
cutoffDistance = distance; cutoffDistance = distance;
} }
GBVIForce::BornRadiusScalingMethod GBVIForce::getBornRadiusScalingMethod( void ) const { GBVIForce::BornRadiusScalingMethod GBVIForce::getBornRadiusScalingMethod() const {
return scalingMethod; return scalingMethod;
} }
...@@ -85,7 +85,7 @@ void GBVIForce::setBornRadiusScalingMethod(BornRadiusScalingMethod method) { ...@@ -85,7 +85,7 @@ void GBVIForce::setBornRadiusScalingMethod(BornRadiusScalingMethod method) {
scalingMethod = method; scalingMethod = method;
} }
double GBVIForce::getQuinticLowerLimitFactor( void ) const { double GBVIForce::getQuinticLowerLimitFactor() const {
return quinticLowerLimitFactor; return quinticLowerLimitFactor;
} }
...@@ -93,7 +93,7 @@ void GBVIForce::setQuinticLowerLimitFactor(double inputQuinticLowerLimitFactor ) ...@@ -93,7 +93,7 @@ void GBVIForce::setQuinticLowerLimitFactor(double inputQuinticLowerLimitFactor )
quinticLowerLimitFactor = inputQuinticLowerLimitFactor; quinticLowerLimitFactor = inputQuinticLowerLimitFactor;
} }
double GBVIForce::getQuinticUpperBornRadiusLimit( void ) const { double GBVIForce::getQuinticUpperBornRadiusLimit() const {
return quinticUpperBornRadiusLimit; return quinticUpperBornRadiusLimit;
} }
...@@ -113,7 +113,7 @@ void GBVIForce::setBondParameters( int index, int particle1, int particle2, doub ...@@ -113,7 +113,7 @@ void GBVIForce::setBondParameters( int index, int particle1, int particle2, doub
bonds[index].bondLength = bondLength; bonds[index].bondLength = bondLength;
} }
int GBVIForce::getNumBonds( void ) const { int GBVIForce::getNumBonds() const {
return (int) bonds.size(); return (int) bonds.size();
} }
......
...@@ -145,8 +145,6 @@ int GBVIForceImpl::getBondsFromForces(ContextImpl& context) { ...@@ -145,8 +145,6 @@ int GBVIForceImpl::getBondsFromForces(ContextImpl& context) {
} }
*/ */
#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 {
...@@ -219,26 +217,6 @@ void GBVIForceImpl::findScaledRadii( int numberOfParticles, const std::vector<st ...@@ -219,26 +217,6 @@ void GBVIForceImpl::findScaledRadii( int numberOfParticles, const std::vector<st
if( errors ){ if( errors ){
throw OpenMMException("GBVIForceImpl::findScaledRadii errors -- aborting"); throw OpenMMException("GBVIForceImpl::findScaledRadii errors -- aborting");
} }
#if GBVIDebug
(void) fprintf( stderr, " R q gamma scaled radii no. bnds\n" );
double totalQ = 0.0;
for( int i = 0; i < (int) scaledRadii.size(); i++ ){
double charge;
double gamma;
double radiusI;
owner.getParticleParameters(i, charge, radiusI, gamma);
totalQ += charge;
(void) fprintf( stderr, "%4d %14.5e %14.5e %14.5e %14.5e %d\n", i, radiusI, charge, gamma, scaledRadii[i], (int) bonded12[i].size() );
}
(void) fprintf( stderr, "Total charge=%e\n", totalQ );
(void) fflush( stderr );
#endif
#undef GBVIDebug
} }
double GBVIForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { double GBVIForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/kernels.h" #include "openmm/kernels.h"
#include <string> #include <string>
...@@ -46,7 +45,7 @@ LangevinIntegrator::LangevinIntegrator(double temperature, double frictionCoeff, ...@@ -46,7 +45,7 @@ LangevinIntegrator::LangevinIntegrator(double temperature, double frictionCoeff,
setFriction(frictionCoeff); setFriction(frictionCoeff);
setStepSize(stepSize); setStepSize(stepSize);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
void LangevinIntegrator::initialize(ContextImpl& contextRef) { void LangevinIntegrator::initialize(ContextImpl& contextRef) {
......
...@@ -31,13 +31,12 @@ ...@@ -31,13 +31,12 @@
#include "openmm/MonteCarloAnisotropicBarostat.h" #include "openmm/MonteCarloAnisotropicBarostat.h"
#include "openmm/internal/MonteCarloAnisotropicBarostatImpl.h" #include "openmm/internal/MonteCarloAnisotropicBarostatImpl.h"
#include "openmm/internal/OSRngSeed.h"
using namespace OpenMM; using namespace OpenMM;
MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double temperature, bool scaleX, bool scaleY, bool scaleZ, int frequency) : MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double temperature, bool scaleX, bool scaleY, bool scaleZ, int frequency) :
defaultPressure(defaultPressure), temperature(temperature), scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), frequency(frequency) { defaultPressure(defaultPressure), temperature(temperature), scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), frequency(frequency) {
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
ForceImpl* MonteCarloAnisotropicBarostat::createImpl() const { ForceImpl* MonteCarloAnisotropicBarostat::createImpl() const {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "openmm/internal/MonteCarloAnisotropicBarostatImpl.h" #include "openmm/internal/MonteCarloAnisotropicBarostatImpl.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/kernels.h" #include "openmm/kernels.h"
#include <cmath> #include <cmath>
...@@ -60,7 +61,10 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) { ...@@ -60,7 +61,10 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) {
numAttempted[i] = 0; numAttempted[i] = 0;
numAccepted[i] = 0; numAccepted[i] = 0;
} }
init_gen_rand(owner.getRandomNumberSeed(), random); int randSeed = owner.getRandomNumberSeed();
// A random seed of 0 means use a unique one
if (randSeed == 0) randSeed = osrngseed();
init_gen_rand(randSeed, random);
} }
void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) { void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) {
...@@ -108,7 +112,9 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) ...@@ -108,7 +112,9 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
Vec3 lengthScale(1.0, 1.0, 1.0); Vec3 lengthScale(1.0, 1.0, 1.0);
lengthScale[axis] = newVolume/volume; lengthScale[axis] = newVolume/volume;
kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]); kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]);
context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale[0], box[1]*lengthScale[1], box[2]*lengthScale[2]); context.getOwner().setPeriodicBoxVectors(Vec3(box[0][0]*lengthScale[0], box[0][1]*lengthScale[1], box[0][2]*lengthScale[2]),
Vec3(box[1][0]*lengthScale[0], box[1][1]*lengthScale[1], box[1][2]*lengthScale[2]),
Vec3(box[2][0]*lengthScale[0], box[2][1]*lengthScale[1], box[2][2]*lengthScale[2]));
// Compute the energy of the modified system. // Compute the energy of the modified system.
......
...@@ -31,13 +31,12 @@ ...@@ -31,13 +31,12 @@
#include "openmm/MonteCarloBarostat.h" #include "openmm/MonteCarloBarostat.h"
#include "openmm/internal/MonteCarloBarostatImpl.h" #include "openmm/internal/MonteCarloBarostatImpl.h"
#include "openmm/internal/OSRngSeed.h"
using namespace OpenMM; using namespace OpenMM;
MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double temperature, int frequency) : MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double temperature, int frequency) :
defaultPressure(defaultPressure), temperature(temperature), frequency(frequency) { defaultPressure(defaultPressure), temperature(temperature), frequency(frequency) {
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
ForceImpl* MonteCarloBarostat::createImpl() const { ForceImpl* MonteCarloBarostat::createImpl() const {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "openmm/internal/MonteCarloBarostatImpl.h" #include "openmm/internal/MonteCarloBarostatImpl.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/kernels.h" #include "openmm/kernels.h"
#include <cmath> #include <cmath>
...@@ -58,7 +59,10 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) { ...@@ -58,7 +59,10 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) {
volumeScale = 0.01*volume; volumeScale = 0.01*volume;
numAttempted = 0; numAttempted = 0;
numAccepted = 0; numAccepted = 0;
init_gen_rand(owner.getRandomNumberSeed(), random); int randSeed = owner.getRandomNumberSeed();
// A random seed of 0 means use a unique one
if (randSeed == 0) randSeed = osrngseed();
init_gen_rand(randSeed, random);
} }
void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) { void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) {
......
/* -------------------------------------------------------------------------- *
* 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) 2010-2014 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/MonteCarloMembraneBarostat.h"
#include "openmm/internal/MonteCarloMembraneBarostatImpl.h"
using namespace OpenMM;
MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double temperature, XYMode xymode, ZMode zmode, int frequency) :
defaultPressure(defaultPressure), defaultSurfaceTension(defaultSurfaceTension), temperature(temperature),
xymode(xymode), zmode(zmode), frequency(frequency) {
setRandomNumberSeed(0);
}
ForceImpl* MonteCarloMembraneBarostat::createImpl() const {
return new MonteCarloMembraneBarostatImpl(*this);
}
/* -------------------------------------------------------------------------- *
* 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) 2010-2014 Stanford University and the Authors. *
* Authors: Peter Eastman, Lee-Ping Wang *
* 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/MonteCarloMembraneBarostatImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/Context.h"
#include "openmm/kernels.h"
#include <cmath>
#include <vector>
#include <algorithm>
using namespace OpenMM;
using namespace OpenMM_SFMT;
using std::vector;
const float BOLTZMANN = 1.380658e-23f; // (J/K)
const float AVOGADRO = 6.0221367e23f;
const float RGAS = BOLTZMANN*AVOGADRO; // (J/(mol K))
const float BOLTZ = RGAS/1000; // (kJ/(mol K))
MonteCarloMembraneBarostatImpl::MonteCarloMembraneBarostatImpl(const MonteCarloMembraneBarostat& owner) : owner(owner), step(0) {
}
void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) {
kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context);
kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner);
Vec3 box[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2];
for (int i=0; i<3; i++) {
volumeScale[i] = 0.01*volume;
numAttempted[i] = 0;
numAccepted[i] = 0;
}
int randSeed = owner.getRandomNumberSeed();
// A random seed of 0 means use a unique one
if (randSeed == 0) randSeed = osrngseed();
init_gen_rand(randSeed, random);
}
void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) {
if (++step < owner.getFrequency() || owner.getFrequency() == 0)
return;
step = 0;
// Compute the current potential energy.
double initialEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy();
double pressure = context.getParameter(MonteCarloMembraneBarostat::Pressure())*(AVOGADRO*1e-25);
double tension = context.getParameter(MonteCarloMembraneBarostat::SurfaceTension())*(AVOGADRO*1e-25);
// Choose which axis to modify at random.
int axis;
while (true) {
double rnd = genrand_real2(random)*3.0;
if (rnd < 1.0) {
axis = 0;
break;
} else if (rnd < 2.0) {
axis = (owner.getXYMode() == MonteCarloMembraneBarostat::XYIsotropic ? 0 : 1);
break;
} else if (owner.getZMode() == MonteCarloMembraneBarostat::ZFree) {
axis = 2;
break;
}
}
// Modify the periodic box size.
Vec3 box[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2];
double deltaVolume = volumeScale[axis]*2*(genrand_real2(random)-0.5);
double newVolume = volume+deltaVolume;
Vec3 lengthScale(1.0, 1.0, 1.0);
if ((axis == 0 || axis == 1) && owner.getXYMode() == MonteCarloMembraneBarostat::XYIsotropic)
lengthScale[0] = lengthScale[1] = sqrt(newVolume/volume);
else
lengthScale[axis] = newVolume/volume;
if (owner.getZMode() == MonteCarloMembraneBarostat::ConstantVolume) {
lengthScale[2] = 1.0/(lengthScale[0]*lengthScale[1]);
newVolume = volume;
deltaVolume = 0;
}
double deltaArea = box[0][0]*lengthScale[0]*box[1][1]*lengthScale[1] - box[0][0]*box[1][1];
kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]);
context.getOwner().setPeriodicBoxVectors(Vec3(box[0][0]*lengthScale[0], box[0][1]*lengthScale[1], box[0][2]*lengthScale[2]),
Vec3(box[1][0]*lengthScale[0], box[1][1]*lengthScale[1], box[1][2]*lengthScale[2]),
Vec3(box[2][0]*lengthScale[0], box[2][1]*lengthScale[1], box[2][2]*lengthScale[2]));
// Compute the energy of the modified system.
double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy();
double kT = BOLTZ*owner.getTemperature();
double w = finalEnergy-initialEnergy + pressure*deltaVolume - tension*deltaArea - context.getMolecules().size()*kT*std::log(newVolume/volume);
if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) {
// Reject the step.
kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context);
context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]);
volume = newVolume;
}
else
numAccepted[axis]++;
numAttempted[axis]++;
if (numAttempted[axis] >= 10) {
if (numAccepted[axis] < 0.25*numAttempted[axis]) {
volumeScale[axis] /= 1.1;
numAttempted[axis] = 0;
numAccepted[axis] = 0;
}
else if (numAccepted[axis] > 0.75*numAttempted[axis]) {
volumeScale[axis] = std::min(volumeScale[axis]*1.1, volume*0.3);
numAttempted[axis] = 0;
numAccepted[axis] = 0;
}
}
}
std::map<std::string, double> MonteCarloMembraneBarostatImpl::getDefaultParameters() {
std::map<std::string, double> parameters;
parameters[MonteCarloMembraneBarostat::Pressure()] = getOwner().getDefaultPressure();
parameters[MonteCarloMembraneBarostat::SurfaceTension()] = getOwner().getDefaultSurfaceTension();
return parameters;
}
std::vector<std::string> MonteCarloMembraneBarostatImpl::getKernelNames() {
std::vector<std::string> names;
names.push_back(ApplyMonteCarloBarostatKernel::Name());
return names;
}
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