Commit 2e9c418a authored by peastman's avatar peastman
Browse files

Merge branch 'master' into gayberne

parents 8f532e31 a4d327f5
...@@ -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) 2015 Stanford University and the Authors. * * Portions copyright (c) 2015-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -48,7 +48,7 @@ using std::string; ...@@ -48,7 +48,7 @@ using std::string;
using std::stringstream; using std::stringstream;
using std::vector; using std::vector;
CustomCentroidBondForce::CustomCentroidBondForce(int numGroups, const string& energy) : groupsPerBond(numGroups), energyExpression(energy) { CustomCentroidBondForce::CustomCentroidBondForce(int numGroups, const string& energy) : groupsPerBond(numGroups), energyExpression(energy), usePeriodic(false) {
} }
CustomCentroidBondForce::~CustomCentroidBondForce() { CustomCentroidBondForce::~CustomCentroidBondForce() {
...@@ -173,3 +173,11 @@ ForceImpl* CustomCentroidBondForce::createImpl() const { ...@@ -173,3 +173,11 @@ ForceImpl* CustomCentroidBondForce::createImpl() const {
void CustomCentroidBondForce::updateParametersInContext(Context& context) { void CustomCentroidBondForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomCentroidBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomCentroidBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void CustomCentroidBondForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool CustomCentroidBondForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -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) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -48,7 +48,7 @@ using std::string; ...@@ -48,7 +48,7 @@ using std::string;
using std::stringstream; using std::stringstream;
using std::vector; using std::vector;
CustomCompoundBondForce::CustomCompoundBondForce(int numParticles, const string& energy) : particlesPerBond(numParticles), energyExpression(energy) { CustomCompoundBondForce::CustomCompoundBondForce(int numParticles, const string& energy) : particlesPerBond(numParticles), energyExpression(energy), usePeriodic(false) {
} }
...@@ -176,3 +176,11 @@ ForceImpl* CustomCompoundBondForce::createImpl() const { ...@@ -176,3 +176,11 @@ ForceImpl* CustomCompoundBondForce::createImpl() const {
void CustomCompoundBondForce::updateParametersInContext(Context& context) { void CustomCompoundBondForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomCompoundBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomCompoundBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void CustomCompoundBondForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool CustomCompoundBondForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -248,21 +248,21 @@ int CustomIntegrator::addUpdateContextState() { ...@@ -248,21 +248,21 @@ int CustomIntegrator::addUpdateContextState() {
int CustomIntegrator::beginIfBlock(const string& expression) { int CustomIntegrator::beginIfBlock(const string& expression) {
if (owner != NULL) if (owner != NULL)
throw OpenMMException("The integrator cannot be modified after it is bound to a context"); throw OpenMMException("The integrator cannot be modified after it is bound to a context");
computations.push_back(ComputationInfo(BeginIfBlock, "", expression)); computations.push_back(ComputationInfo(IfBlockStart, "", expression));
return computations.size()-1; return computations.size()-1;
} }
int CustomIntegrator::beginWhileBlock(const string& expression) { int CustomIntegrator::beginWhileBlock(const string& expression) {
if (owner != NULL) if (owner != NULL)
throw OpenMMException("The integrator cannot be modified after it is bound to a context"); throw OpenMMException("The integrator cannot be modified after it is bound to a context");
computations.push_back(ComputationInfo(BeginWhileBlock, "", expression)); computations.push_back(ComputationInfo(WhileBlockStart, "", expression));
return computations.size()-1; return computations.size()-1;
} }
int CustomIntegrator::endBlock() { int CustomIntegrator::endBlock() {
if (owner != NULL) if (owner != NULL)
throw OpenMMException("The integrator cannot be modified after it is bound to a context"); throw OpenMMException("The integrator cannot be modified after it is bound to a context");
computations.push_back(ComputationInfo(EndBlock, "", "")); computations.push_back(ComputationInfo(BlockEnd, "", ""));
return computations.size()-1; return computations.size()-1;
} }
......
...@@ -87,7 +87,7 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context, ...@@ -87,7 +87,7 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
for (int step = 0; step < numSteps; step++) { for (int step = 0; step < numSteps; step++) {
string expression; string expression;
integrator.getComputationStep(step, stepType[step], stepVariable[step], expression); integrator.getComputationStep(step, stepType[step], stepVariable[step], expression);
if (stepType[step] == CustomIntegrator::BeginIfBlock || stepType[step] == CustomIntegrator::BeginWhileBlock) { if (stepType[step] == CustomIntegrator::IfBlockStart || stepType[step] == CustomIntegrator::WhileBlockStart) {
// This step involves a condition. // This step involves a condition.
string lhs, rhs; string lhs, rhs;
...@@ -158,9 +158,9 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context, ...@@ -158,9 +158,9 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
vector<int> blockStart; vector<int> blockStart;
blockEnd.resize(numSteps, -1); blockEnd.resize(numSteps, -1);
for (int step = 0; step < numSteps; step++) { for (int step = 0; step < numSteps; step++) {
if (stepType[step] == CustomIntegrator::BeginIfBlock || stepType[step] == CustomIntegrator::BeginWhileBlock) if (stepType[step] == CustomIntegrator::IfBlockStart || stepType[step] == CustomIntegrator::WhileBlockStart)
blockStart.push_back(step); blockStart.push_back(step);
else if (stepType[step] == CustomIntegrator::EndBlock) { else if (stepType[step] == CustomIntegrator::BlockEnd) {
if (blockStart.size() == 0) { if (blockStart.size() == 0) {
stringstream error("CustomIntegrator: Unexpected end of block at computation "); stringstream error("CustomIntegrator: Unexpected end of block at computation ");
error << step; error << step;
...@@ -207,7 +207,7 @@ void CustomIntegratorUtilities::enumeratePaths(int firstStep, vector<int> steps, ...@@ -207,7 +207,7 @@ void CustomIntegratorUtilities::enumeratePaths(int firstStep, vector<int> steps,
jumps[step] = -1; jumps[step] = -1;
step = nextStep; step = nextStep;
} }
else if (stepType[step] == CustomIntegrator::BeginIfBlock) { else if (stepType[step] == CustomIntegrator::IfBlockStart) {
// Consider skipping the block. // Consider skipping the block.
enumeratePaths(blockEnd[step]+1, steps, jumps, blockEnd, stepType, needsForces, needsEnergy, invalidatesForces, forceGroup, computeBoth); enumeratePaths(blockEnd[step]+1, steps, jumps, blockEnd, stepType, needsForces, needsEnergy, invalidatesForces, forceGroup, computeBoth);
...@@ -216,7 +216,7 @@ void CustomIntegratorUtilities::enumeratePaths(int firstStep, vector<int> steps, ...@@ -216,7 +216,7 @@ void CustomIntegratorUtilities::enumeratePaths(int firstStep, vector<int> steps,
step++; step++;
} }
else if (stepType[step] == CustomIntegrator::BeginWhileBlock && jumps[step] != -2) { else if (stepType[step] == CustomIntegrator::WhileBlockStart && jumps[step] != -2) {
// Consider skipping the block. // Consider skipping the block.
enumeratePaths(blockEnd[step]+1, steps, jumps, blockEnd, stepType, needsForces, needsEnergy, invalidatesForces, forceGroup, computeBoth); enumeratePaths(blockEnd[step]+1, steps, jumps, blockEnd, stepType, needsForces, needsEnergy, invalidatesForces, forceGroup, computeBoth);
......
...@@ -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-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -44,7 +44,7 @@ using std::string; ...@@ -44,7 +44,7 @@ using std::string;
using std::stringstream; using std::stringstream;
using std::vector; using std::vector;
CustomTorsionForce::CustomTorsionForce(const string& energy) : energyExpression(energy) { CustomTorsionForce::CustomTorsionForce(const string& energy) : energyExpression(energy), usePeriodic(false) {
} }
const string& CustomTorsionForce::getEnergyFunction() const { const string& CustomTorsionForce::getEnergyFunction() const {
...@@ -125,3 +125,11 @@ ForceImpl* CustomTorsionForce::createImpl() const { ...@@ -125,3 +125,11 @@ ForceImpl* CustomTorsionForce::createImpl() const {
void CustomTorsionForce::updateParametersInContext(Context& context) { void CustomTorsionForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void CustomTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool CustomTorsionForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -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) 2008-2009 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
using namespace OpenMM; using namespace OpenMM;
HarmonicAngleForce::HarmonicAngleForce() { HarmonicAngleForce::HarmonicAngleForce() : usePeriodic(false) {
} }
int HarmonicAngleForce::addAngle(int particle1, int particle2, int particle3, double angle, double k) { int HarmonicAngleForce::addAngle(int particle1, int particle2, int particle3, double angle, double k) {
...@@ -70,3 +70,11 @@ ForceImpl* HarmonicAngleForce::createImpl() const { ...@@ -70,3 +70,11 @@ ForceImpl* HarmonicAngleForce::createImpl() const {
void HarmonicAngleForce::updateParametersInContext(Context& context) { void HarmonicAngleForce::updateParametersInContext(Context& context) {
dynamic_cast<HarmonicAngleForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<HarmonicAngleForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void HarmonicAngleForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool HarmonicAngleForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
using namespace OpenMM; using namespace OpenMM;
HarmonicBondForce::HarmonicBondForce() { HarmonicBondForce::HarmonicBondForce() : usePeriodic(false) {
} }
int HarmonicBondForce::addBond(int particle1, int particle2, double length, double k) { int HarmonicBondForce::addBond(int particle1, int particle2, double length, double k) {
...@@ -68,3 +68,11 @@ ForceImpl* HarmonicBondForce::createImpl() const { ...@@ -68,3 +68,11 @@ ForceImpl* HarmonicBondForce::createImpl() const {
void HarmonicBondForce::updateParametersInContext(Context& context) { void HarmonicBondForce::updateParametersInContext(Context& context) {
dynamic_cast<HarmonicBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<HarmonicBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void HarmonicBondForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool HarmonicBondForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -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-2012 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -108,7 +108,8 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI ...@@ -108,7 +108,8 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI
if (x == NULL) if (x == NULL)
throw OpenMMException("LocalEnergyMinimizer: Failed to allocate memory"); throw OpenMMException("LocalEnergyMinimizer: Failed to allocate memory");
double constraintTol = context.getIntegrator().getConstraintTolerance(); double constraintTol = context.getIntegrator().getConstraintTolerance();
double k = tolerance/constraintTol; double workingConstraintTol = max(1e-4, constraintTol);
double k = tolerance/workingConstraintTol;
// Initialize the minimizer. // Initialize the minimizer.
...@@ -121,7 +122,7 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI ...@@ -121,7 +122,7 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI
// Make sure the initial configuration satisfies all constraints. // Make sure the initial configuration satisfies all constraints.
context.applyConstraints(constraintTol); context.applyConstraints(workingConstraintTol);
// Record the initial positions and determine a normalization constant for scaling the tolerance. // Record the initial positions and determine a normalization constant for scaling the tolerance.
...@@ -162,14 +163,14 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI ...@@ -162,14 +163,14 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI
if (error > maxError) if (error > maxError)
maxError = error; maxError = error;
} }
if (maxError <= constraintTol) if (maxError <= workingConstraintTol)
break; // All constraints are satisfied. break; // All constraints are satisfied.
context.setPositions(initialPos); context.setPositions(initialPos);
if (maxError >= prevMaxError) if (maxError >= prevMaxError)
break; // Further tightening the springs doesn't seem to be helping, so just give up. break; // Further tightening the springs doesn't seem to be helping, so just give up.
prevMaxError = maxError; prevMaxError = maxError;
k *= 10; k *= 10;
if (maxError > 100*constraintTol) { if (maxError > 100*workingConstraintTol) {
// We've gotten far enough from a valid state that we might have trouble getting // We've gotten far enough from a valid state that we might have trouble getting
// back, so reset to the original positions. // back, so reset to the original positions.
...@@ -181,5 +182,11 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI ...@@ -181,5 +182,11 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI
} }
} }
lbfgs_free(x); lbfgs_free(x);
// If necessary, do a final constraint projection to make sure they are satisfied
// to the full precision requested by the user.
if (constraintTol < workingConstraintTol)
context.applyConstraints(workingConstraintTol);
} }
...@@ -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-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
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 defaultTemperature, bool scaleX, bool scaleY, bool scaleZ, int frequency) :
defaultPressure(defaultPressure), temperature(temperature), scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), frequency(frequency) { defaultPressure(defaultPressure), defaultTemperature(defaultTemperature), scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), frequency(frequency) {
setRandomNumberSeed(0); setRandomNumberSeed(0);
} }
......
...@@ -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-2013 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman, Lee-Ping Wang * * Authors: Peter Eastman, Lee-Ping Wang *
* Contributors: * * Contributors: *
* * * *
...@@ -119,7 +119,7 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) ...@@ -119,7 +119,7 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
// Compute the energy of the modified system. // Compute the energy of the modified system.
double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy();
double kT = BOLTZ*owner.getTemperature(); double kT = BOLTZ*context.getParameter(MonteCarloAnisotropicBarostat::Temperature());
double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*std::log(newVolume/volume); double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*std::log(newVolume/volume);
if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) { if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) {
// Reject the step. // Reject the step.
...@@ -150,6 +150,7 @@ std::map<std::string, double> MonteCarloAnisotropicBarostatImpl::getDefaultParam ...@@ -150,6 +150,7 @@ std::map<std::string, double> MonteCarloAnisotropicBarostatImpl::getDefaultParam
parameters[MonteCarloAnisotropicBarostat::PressureX()] = getOwner().getDefaultPressure()[0]; parameters[MonteCarloAnisotropicBarostat::PressureX()] = getOwner().getDefaultPressure()[0];
parameters[MonteCarloAnisotropicBarostat::PressureY()] = getOwner().getDefaultPressure()[1]; parameters[MonteCarloAnisotropicBarostat::PressureY()] = getOwner().getDefaultPressure()[1];
parameters[MonteCarloAnisotropicBarostat::PressureZ()] = getOwner().getDefaultPressure()[2]; parameters[MonteCarloAnisotropicBarostat::PressureZ()] = getOwner().getDefaultPressure()[2];
parameters[MonteCarloAnisotropicBarostat::Temperature()] = getOwner().getDefaultTemperature();
return parameters; return parameters;
} }
......
...@@ -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-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
using namespace OpenMM; using namespace OpenMM;
MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double temperature, int frequency) : MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double defaultTemperature, int frequency) :
defaultPressure(defaultPressure), temperature(temperature), frequency(frequency) { defaultPressure(defaultPressure), defaultTemperature(defaultTemperature), frequency(frequency) {
setRandomNumberSeed(0); setRandomNumberSeed(0);
} }
......
...@@ -89,7 +89,7 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) { ...@@ -89,7 +89,7 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) {
double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy();
double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25); double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25);
double kT = BOLTZ*owner.getTemperature(); double kT = BOLTZ*context.getParameter(MonteCarloBarostat::Temperature());
double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*std::log(newVolume/volume); double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*std::log(newVolume/volume);
if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) { if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) {
// Reject the step. // Reject the step.
...@@ -118,6 +118,7 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) { ...@@ -118,6 +118,7 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) {
std::map<std::string, double> MonteCarloBarostatImpl::getDefaultParameters() { std::map<std::string, double> MonteCarloBarostatImpl::getDefaultParameters() {
std::map<std::string, double> parameters; std::map<std::string, double> parameters;
parameters[MonteCarloBarostat::Pressure()] = getOwner().getDefaultPressure(); parameters[MonteCarloBarostat::Pressure()] = getOwner().getDefaultPressure();
parameters[MonteCarloBarostat::Temperature()] = getOwner().getDefaultTemperature();
return parameters; return parameters;
} }
......
...@@ -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-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
using namespace OpenMM; using namespace OpenMM;
MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double temperature, XYMode xymode, ZMode zmode, int frequency) : MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode, int frequency) :
defaultPressure(defaultPressure), defaultSurfaceTension(defaultSurfaceTension), temperature(temperature), defaultPressure(defaultPressure), defaultSurfaceTension(defaultSurfaceTension), defaultTemperature(defaultTemperature),
xymode(xymode), zmode(zmode), frequency(frequency) { xymode(xymode), zmode(zmode), frequency(frequency) {
setRandomNumberSeed(0); setRandomNumberSeed(0);
} }
......
...@@ -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-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman, Lee-Ping Wang * * Authors: Peter Eastman, Lee-Ping Wang *
* Contributors: * * Contributors: *
* * * *
...@@ -120,7 +120,7 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) { ...@@ -120,7 +120,7 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) {
// Compute the energy of the modified system. // Compute the energy of the modified system.
double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy();
double kT = BOLTZ*owner.getTemperature(); double kT = BOLTZ*context.getParameter(MonteCarloMembraneBarostat::Temperature());
double w = finalEnergy-initialEnergy + pressure*deltaVolume - tension*deltaArea - context.getMolecules().size()*kT*std::log(newVolume/volume); 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)) { if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) {
// Reject the step. // Reject the step.
...@@ -150,6 +150,7 @@ std::map<std::string, double> MonteCarloMembraneBarostatImpl::getDefaultParamete ...@@ -150,6 +150,7 @@ std::map<std::string, double> MonteCarloMembraneBarostatImpl::getDefaultParamete
std::map<std::string, double> parameters; std::map<std::string, double> parameters;
parameters[MonteCarloMembraneBarostat::Pressure()] = getOwner().getDefaultPressure(); parameters[MonteCarloMembraneBarostat::Pressure()] = getOwner().getDefaultPressure();
parameters[MonteCarloMembraneBarostat::SurfaceTension()] = getOwner().getDefaultSurfaceTension(); parameters[MonteCarloMembraneBarostat::SurfaceTension()] = getOwner().getDefaultSurfaceTension();
parameters[MonteCarloMembraneBarostat::Temperature()] = getOwner().getDefaultTemperature();
return parameters; return parameters;
} }
......
...@@ -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) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
using namespace OpenMM; using namespace OpenMM;
PeriodicTorsionForce::PeriodicTorsionForce() { PeriodicTorsionForce::PeriodicTorsionForce() : usePeriodic(false) {
} }
int PeriodicTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, int periodicity, double phase, double k) { int PeriodicTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, int periodicity, double phase, double k) {
...@@ -74,3 +74,11 @@ ForceImpl* PeriodicTorsionForce::createImpl() const { ...@@ -74,3 +74,11 @@ ForceImpl* PeriodicTorsionForce::createImpl() const {
void PeriodicTorsionForce::updateParametersInContext(Context& context) { void PeriodicTorsionForce::updateParametersInContext(Context& context) {
dynamic_cast<PeriodicTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<PeriodicTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void PeriodicTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool PeriodicTorsionForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -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) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
using namespace OpenMM; using namespace OpenMM;
RBTorsionForce::RBTorsionForce() { RBTorsionForce::RBTorsionForce() : usePeriodic(false) {
} }
int RBTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, double c0, double c1, double c2, double c3, double c4, double c5) { int RBTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, double c0, double c1, double c2, double c3, double c4, double c5) {
...@@ -80,3 +80,11 @@ ForceImpl* RBTorsionForce::createImpl() const { ...@@ -80,3 +80,11 @@ ForceImpl* RBTorsionForce::createImpl() const {
void RBTorsionForce::updateParametersInContext(Context& context) { void RBTorsionForce::updateParametersInContext(Context& context) {
dynamic_cast<RBTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<RBTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context));
} }
void RBTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) {
usePeriodic = periodic;
}
bool RBTorsionForce::usesPeriodicBoundaryConditions() const {
return usePeriodic;
}
...@@ -91,6 +91,7 @@ public: ...@@ -91,6 +91,7 @@ public:
private: private:
CpuPlatform::PlatformData& data; CpuPlatform::PlatformData& data;
Kernel referenceKernel; Kernel referenceKernel;
std::vector<RealVec> lastPositions;
}; };
/** /**
...@@ -99,7 +100,7 @@ private: ...@@ -99,7 +100,7 @@ private:
class CpuCalcHarmonicAngleForceKernel : public CalcHarmonicAngleForceKernel { class CpuCalcHarmonicAngleForceKernel : public CalcHarmonicAngleForceKernel {
public: public:
CpuCalcHarmonicAngleForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) : CpuCalcHarmonicAngleForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) :
CalcHarmonicAngleForceKernel(name, platform), data(data), angleIndexArray(NULL), angleParamArray(NULL) { CalcHarmonicAngleForceKernel(name, platform), data(data), angleIndexArray(NULL), angleParamArray(NULL), usePeriodic(false) {
} }
~CpuCalcHarmonicAngleForceKernel(); ~CpuCalcHarmonicAngleForceKernel();
/** /**
...@@ -131,6 +132,7 @@ private: ...@@ -131,6 +132,7 @@ private:
int **angleIndexArray; int **angleIndexArray;
RealOpenMM **angleParamArray; RealOpenMM **angleParamArray;
CpuBondForce bondForce; CpuBondForce bondForce;
bool usePeriodic;
}; };
/** /**
...@@ -139,7 +141,7 @@ private: ...@@ -139,7 +141,7 @@ private:
class CpuCalcPeriodicTorsionForceKernel : public CalcPeriodicTorsionForceKernel { class CpuCalcPeriodicTorsionForceKernel : public CalcPeriodicTorsionForceKernel {
public: public:
CpuCalcPeriodicTorsionForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) : CpuCalcPeriodicTorsionForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) :
CalcPeriodicTorsionForceKernel(name, platform), data(data), torsionIndexArray(NULL), torsionParamArray(NULL) { CalcPeriodicTorsionForceKernel(name, platform), data(data), torsionIndexArray(NULL), torsionParamArray(NULL), usePeriodic(false) {
} }
~CpuCalcPeriodicTorsionForceKernel(); ~CpuCalcPeriodicTorsionForceKernel();
/** /**
...@@ -171,6 +173,7 @@ private: ...@@ -171,6 +173,7 @@ private:
int **torsionIndexArray; int **torsionIndexArray;
RealOpenMM **torsionParamArray; RealOpenMM **torsionParamArray;
CpuBondForce bondForce; CpuBondForce bondForce;
bool usePeriodic;
}; };
/** /**
...@@ -179,7 +182,7 @@ private: ...@@ -179,7 +182,7 @@ private:
class CpuCalcRBTorsionForceKernel : public CalcRBTorsionForceKernel { class CpuCalcRBTorsionForceKernel : public CalcRBTorsionForceKernel {
public: public:
CpuCalcRBTorsionForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) : CpuCalcRBTorsionForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) :
CalcRBTorsionForceKernel(name, platform), data(data), torsionIndexArray(NULL), torsionParamArray(NULL) { CalcRBTorsionForceKernel(name, platform), data(data), torsionIndexArray(NULL), torsionParamArray(NULL), usePeriodic(false) {
} }
~CpuCalcRBTorsionForceKernel(); ~CpuCalcRBTorsionForceKernel();
/** /**
...@@ -211,6 +214,7 @@ private: ...@@ -211,6 +214,7 @@ private:
int **torsionIndexArray; int **torsionIndexArray;
RealOpenMM **torsionParamArray; RealOpenMM **torsionParamArray;
CpuBondForce bondForce; CpuBondForce bondForce;
bool usePeriodic;
}; };
/** /**
...@@ -265,9 +269,7 @@ private: ...@@ -265,9 +269,7 @@ private:
bool useSwitchingFunction, useOptimizedPme, hasInitializedPme; bool useSwitchingFunction, useOptimizedPme, hasInitializedPme;
std::vector<std::set<int> > exclusions; std::vector<std::set<int> > exclusions;
std::vector<std::pair<float, float> > particleParams; std::vector<std::pair<float, float> > particleParams;
std::vector<RealVec> lastPositions;
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
CpuNeighborList* neighborList;
CpuNonbondedForce* nonbonded; CpuNonbondedForce* nonbonded;
Kernel optimizedPme; Kernel optimizedPme;
CpuBondForce bondForce; CpuBondForce bondForce;
...@@ -315,7 +317,6 @@ private: ...@@ -315,7 +317,6 @@ private:
std::vector<std::string> parameterNames, globalParameterNames; std::vector<std::string> parameterNames, globalParameterNames;
std::vector<std::pair<std::set<int>, std::set<int> > > interactionGroups; std::vector<std::pair<std::set<int>, std::set<int> > > interactionGroups;
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
CpuNeighborList* neighborList;
CpuCustomNonbondedForce* nonbonded; CpuCustomNonbondedForce* nonbonded;
}; };
...@@ -401,7 +402,6 @@ private: ...@@ -401,7 +402,6 @@ private:
std::vector<OpenMM::CustomGBForce::ComputationType> valueTypes; std::vector<OpenMM::CustomGBForce::ComputationType> valueTypes;
std::vector<OpenMM::CustomGBForce::ComputationType> energyTypes; std::vector<OpenMM::CustomGBForce::ComputationType> energyTypes;
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
CpuNeighborList* neighborList;
}; };
/** /**
......
...@@ -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-2015 Stanford University and the Authors. * * Portions copyright (c) 2013-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -51,6 +51,7 @@ public: ...@@ -51,6 +51,7 @@ public:
void computeNeighborList(int numAtoms, const AlignedArray<float>& atomLocations, const std::vector<std::set<int> >& exclusions, void computeNeighborList(int numAtoms, const AlignedArray<float>& atomLocations, const std::vector<std::set<int> >& exclusions,
const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads); const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads);
int getNumBlocks() const; int getNumBlocks() const;
int getBlockSize() const;
const std::vector<int>& getSortedAtoms() const; const std::vector<int>& getSortedAtoms() const;
const std::vector<int>& getBlockNeighbors(int blockIndex) const; const std::vector<int>& getBlockNeighbors(int blockIndex) const;
const std::vector<char>& getBlockExclusions(int blockIndex) const; const std::vector<char>& getBlockExclusions(int blockIndex) const;
......
...@@ -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 Stanford University and the Authors. * * Portions copyright (c) 2013-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "AlignedArray.h" #include "AlignedArray.h"
#include "CpuRandom.h" #include "CpuRandom.h"
#include "CpuNeighborList.h"
#include "ReferencePlatform.h" #include "ReferencePlatform.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ThreadPool.h" #include "openmm/internal/ThreadPool.h"
...@@ -64,7 +65,7 @@ public: ...@@ -64,7 +65,7 @@ public:
* This is the name of the parameter for selecting the number of threads to use. * This is the name of the parameter for selecting the number of threads to use.
*/ */
static const std::string& CpuThreads() { static const std::string& CpuThreads() {
static const std::string key = "CpuThreads"; static const std::string key = "Threads";
return key; return key;
} }
/** /**
...@@ -80,12 +81,18 @@ private: ...@@ -80,12 +81,18 @@ private:
class CpuPlatform::PlatformData { class CpuPlatform::PlatformData {
public: public:
PlatformData(int numParticles, int numThreads); PlatformData(int numParticles, int numThreads);
~PlatformData();
void requestNeighborList(double cutoffDistance, double padding, bool useExclusions, std::vector<std::set<int> >& exclusionList);
AlignedArray<float> posq; AlignedArray<float> posq;
std::vector<AlignedArray<float> > threadForce; std::vector<AlignedArray<float> > threadForce;
ThreadPool threads; ThreadPool threads;
bool isPeriodic; bool isPeriodic;
CpuRandom random; CpuRandom random;
std::map<std::string, std::string> propertyValues; std::map<std::string, std::string> propertyValues;
CpuNeighborList* neighborList;
double cutoff, paddedCutoff;
bool anyExclusions;
std::vector<std::set<int> > exclusions;
}; };
} // namespace OpenMM } // namespace OpenMM
......
/* Portions copyright (c) 2009-2014 Stanford University and Simbios. /* Portions copyright (c) 2009-2016 Stanford University and Simbios.
* Contributors: Peter Eastman * Contributors: Peter Eastman
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -294,12 +294,13 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, ThreadData& data, i ...@@ -294,12 +294,13 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, ThreadData& data, i
int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1); int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1);
if (blockIndex >= neighborList->getNumBlocks()) if (blockIndex >= neighborList->getNumBlocks())
break; break;
const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const int blockSize = neighborList->getBlockSize();
const int* blockAtom = &neighborList->getSortedAtoms()[blockSize*blockIndex];
const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex);
const vector<char>& blockExclusions = neighborList->getBlockExclusions(blockIndex); const vector<char>& blockExclusions = neighborList->getBlockExclusions(blockIndex);
for (int i = 0; i < (int) neighbors.size(); i++) { for (int i = 0; i < (int) neighbors.size(); i++) {
int first = neighbors[i]; int first = neighbors[i];
for (int k = 0; k < 4; k++) { for (int k = 0; k < blockSize; k++) {
if ((blockExclusions[i] & (1<<k)) == 0) { if ((blockExclusions[i] & (1<<k)) == 0) {
int second = blockAtom[k]; int second = blockAtom[k];
if (useExclusions && exclusions[first].find(second) != exclusions[first].end()) if (useExclusions && exclusions[first].find(second) != exclusions[first].end())
...@@ -379,12 +380,13 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, ThreadData& da ...@@ -379,12 +380,13 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, ThreadData& da
int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1); int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1);
if (blockIndex >= neighborList->getNumBlocks()) if (blockIndex >= neighborList->getNumBlocks())
break; break;
const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const int blockSize = neighborList->getBlockSize();
const int* blockAtom = &neighborList->getSortedAtoms()[blockSize*blockIndex];
const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex);
const vector<char>& blockExclusions = neighborList->getBlockExclusions(blockIndex); const vector<char>& blockExclusions = neighborList->getBlockExclusions(blockIndex);
for (int i = 0; i < (int) neighbors.size(); i++) { for (int i = 0; i < (int) neighbors.size(); i++) {
int first = neighbors[i]; int first = neighbors[i];
for (int k = 0; k < 4; k++) { for (int k = 0; k < blockSize; k++) {
if ((blockExclusions[i] & (1<<k)) == 0) { if ((blockExclusions[i] & (1<<k)) == 0) {
int second = blockAtom[k]; int second = blockAtom[k];
if (useExclusions && exclusions[first].find(second) != exclusions[first].end()) if (useExclusions && exclusions[first].find(second) != exclusions[first].end())
...@@ -460,12 +462,13 @@ void CpuCustomGBForce::calculateChainRuleForces(ThreadData& data, int numAtoms, ...@@ -460,12 +462,13 @@ void CpuCustomGBForce::calculateChainRuleForces(ThreadData& data, int numAtoms,
int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1); int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1);
if (blockIndex >= neighborList->getNumBlocks()) if (blockIndex >= neighborList->getNumBlocks())
break; break;
const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const int blockSize = neighborList->getBlockSize();
const int* blockAtom = &neighborList->getSortedAtoms()[blockSize*blockIndex];
const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex);
const vector<char>& blockExclusions = neighborList->getBlockExclusions(blockIndex); const vector<char>& blockExclusions = neighborList->getBlockExclusions(blockIndex);
for (int i = 0; i < (int) neighbors.size(); i++) { for (int i = 0; i < (int) neighbors.size(); i++) {
int first = neighbors[i]; int first = neighbors[i];
for (int k = 0; k < 4; k++) { for (int k = 0; k < blockSize; k++) {
if ((blockExclusions[i] & (1<<k)) == 0) { if ((blockExclusions[i] & (1<<k)) == 0) {
int second = blockAtom[k]; int second = blockAtom[k];
bool isExcluded = (exclusions[first].find(second) != exclusions[first].end()); bool isExcluded = (exclusions[first].find(second) != exclusions[first].end());
......
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