Unverified Commit 9270d590 authored by Peter Eastman's avatar Peter Eastman Committed by GitHub
Browse files

Created MonteCarloFlexibleBarostat (#3284)

* Created MonteCarloFlexibleBarostat

* Improved test cases

* Documentation for MonteCarloFlexibleBarostat

* Added a missing include

* Serialization for MonteCarloFlexibleBarostat

* Added MonteCarloFlexibleBarostat to C++ API docs index

* Added citation for MonteCarloFlexibleBarostat
parent d82bfb62
...@@ -30,7 +30,6 @@ These classes implement forces that are widely used in biomolecular simulation. ...@@ -30,7 +30,6 @@ These classes implement forces that are widely used in biomolecular simulation.
generated/GayBerneForce generated/GayBerneForce
generated/HarmonicAngleForce generated/HarmonicAngleForce
generated/HarmonicBondForce generated/HarmonicBondForce
generated/HippoNonbondedForce
generated/NonbondedForce generated/NonbondedForce
generated/PeriodicTorsionForce generated/PeriodicTorsionForce
generated/RBTorsionForce generated/RBTorsionForce
...@@ -49,6 +48,7 @@ These forces are used to implement the polarizable AMOEBA force fields. ...@@ -49,6 +48,7 @@ These forces are used to implement the polarizable AMOEBA force fields.
generated/AmoebaTorsionTorsionForce generated/AmoebaTorsionTorsionForce
generated/AmoebaVdwForce generated/AmoebaVdwForce
generated/AmoebaWcaDispersionForce generated/AmoebaWcaDispersionForce
generated/HippoNonbondedForce
Pseudo-forces Pseudo-forces
...@@ -67,6 +67,7 @@ be combined in arbitrary ways. ...@@ -67,6 +67,7 @@ be combined in arbitrary ways.
generated/CMMotionRemover generated/CMMotionRemover
generated/MonteCarloAnisotropicBarostat generated/MonteCarloAnisotropicBarostat
generated/MonteCarloBarostat generated/MonteCarloBarostat
generated/MonteCarloFlexibleBarostat
generated/MonteCarloMembraneBarostat generated/MonteCarloMembraneBarostat
generated/RMSDForce generated/RMSDForce
generated/RPMDMonteCarloBarostat generated/RPMDMonteCarloBarostat
......
...@@ -595,6 +595,17 @@ ...@@ -595,6 +595,17 @@
pages = {6363--6374}, pages = {6363--6374},
} }
@article{Vandenhaute2021
author = {Vandenhaute, Sander and Rogge, Sven M. J. and Van Speybroeck, Veronique},
title = {Large-Scale Molecular Dynamics Simulations Reveal New Insights Into the Phase Transition Mechanisms in MIL-53(Al)},
journal = {Frontiers in Chemistry},
volume = {9},
pages = {699},
year = {2021},
doi = {10.3389/fchem.2021.718920},
type = {Journal Article}
}
@article{Wang2000 @article{Wang2000
author = {Wang, J. and Cieplak, P. and Kollman, P.A.}, author = {Wang, J. and Cieplak, P. and Kollman, P.A.},
title = {How well does a restrained electrostatic potential ({RESP}) model perform in calculating conformational energies of organic and biological molecules?}, title = {How well does a restrained electrostatic potential ({RESP}) model perform in calculating conformational energies of organic and biological molecules?},
......
...@@ -671,6 +671,16 @@ behavior of the periodic box: ...@@ -671,6 +671,16 @@ behavior of the periodic box:
* inversely varying with the X and Y axes (so the total box volume does not * inversely varying with the X and Y axes (so the total box volume does not
change) change)
MonteCarloFlexibleBarostat
**************************
MonteCarloFlexibleBarostat is very similar to MonteCarloBarostat, but it allows
the periodic box to be fully flexible.\ :cite:`Vandenhaute2021` Monte Carlo
steps can change not just the lengths of the box sides, but also the angles. It
is especially useful for simulations of bulk materials where the shape of a
crystal's unit cell may not be known in advance, or could even change with time
as it transitions between phases.
CMMotionRemover CMMotionRemover
*************** ***************
......
...@@ -1444,10 +1444,11 @@ public: ...@@ -1444,10 +1444,11 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param barostat the MonteCarloBarostat this kernel will be used for * @param barostat the MonteCarloBarostat this kernel will be used for
* @param rigidMolecules whether molecules should be kept rigid while scaling coordinates
*/ */
virtual void initialize(const System& system, const Force& barostat) = 0; virtual void initialize(const System& system, const Force& barostat, bool rigidMolecules=true) = 0;
/** /**
* Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value. * Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value.
* This version scales the x, y, and z positions independently. * This version scales the x, y, and z positions independently.
......
...@@ -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-2017 Stanford University and the Authors. * * Portions copyright (c) 2009-2021 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include "openmm/LocalEnergyMinimizer.h" #include "openmm/LocalEnergyMinimizer.h"
#include "openmm/MonteCarloAnisotropicBarostat.h" #include "openmm/MonteCarloAnisotropicBarostat.h"
#include "openmm/MonteCarloBarostat.h" #include "openmm/MonteCarloBarostat.h"
#include "openmm/MonteCarloFlexibleBarostat.h"
#include "openmm/MonteCarloMembraneBarostat.h" #include "openmm/MonteCarloMembraneBarostat.h"
#include "openmm/NonbondedForce.h" #include "openmm/NonbondedForce.h"
#include "openmm/Context.h" #include "openmm/Context.h"
......
#ifndef OPENMM_MONTECARLOFLEXIBLEBAROSTAT_H_
#define OPENMM_MONTECARLOFLEXIBLEBAROSTAT_H_
/* -------------------------------------------------------------------------- *
* 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-2021 Stanford University and the Authors. *
* Authors: Peter Eastman, Sander Vandenhaute *
* 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 "Force.h"
#include <string>
#include "internal/windowsExport.h"
namespace OpenMM {
/**
* This class uses a Monte Carlo algorithm to adjust the size and shape of the periodic box, simulating the
* effect of constant pressure.
*
* This class is similar to MonteCarloBarostat, but it simulates a fully flexible periodic box
* in which all three lengths and all three angles are free to change independently. It is primarily
* useful for simulations of bulk materials where the shape of a crystal's unit cell may not
* be known in advance, or could even change with time as it transitions between phases.
*
* Like MonteCarloBarostat, the default behavior of this class is to scale the centroid position
* of each molecule while holding it rigid. In simulations of materials where all atoms are
* covalently bonded to each other, this behavior will not work well since the entire system
* then consists of a single molecule. You can use setScaleMoleculesAsRigid() to disable this
* behavior and instead have it scale the position of every atom independently.
*
* This class assumes the simulation is also being run at constant temperature, and requires you
* to specify the system temperature (since it affects the acceptance probability for Monte Carlo
* moves). It does not actually perform temperature regulation, however. You must use another
* mechanism along with it to maintain the temperature, such as LangevinIntegrator or AndersenThermostat.
*/
class OPENMM_EXPORT MonteCarloFlexibleBarostat : public Force {
public:
/**
* This is the name of the parameter which stores the current pressure acting on
* the system (in bar).
*/
static const std::string& Pressure() {
static const std::string key = "MonteCarloPressure";
return key;
}
/**
* This is the name of the parameter which stores the current temperature at which the
* system is being maintained (in Kelvin)
*/
static const std::string& Temperature() {
static const std::string key = "MonteCarloTemperature";
return key;
}
/**
* Create a MonteCarloFlexibleBarostat.
*
* @param defaultPressure the default pressure acting on the system (in bar)
* @param defaultTemperature the default temperature at which the system is being maintained (in Kelvin)
* @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
* @param scaleMoleculesAsRigid if true, coordinate scaling keeps molecules rigid, scaling only the center of mass
* of each one. If false, every atom is scaled independently.
*/
MonteCarloFlexibleBarostat(double defaultPressure, double defaultTemperature, int frequency = 25, bool scaleMoleculesAsRigid = true);
/**
* Get the default pressure acting on the system (in bar).
*
* @return the default pressure acting on the system, measured in bar.
*/
double getDefaultPressure() const {
return defaultPressure;
}
/**
* Set the default pressure acting on the system. This will affect any new Contexts you create,
* but not ones that already exist.
*
* @param pressure the default pressure acting on the system, measured in bar.
*/
void setDefaultPressure(double pressure) {
defaultPressure = pressure;
}
/**
* Get the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to
* 0, the barostat is disabled.
*/
int getFrequency() const {
return frequency;
}
/**
* Set the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to
* 0, the barostat is disabled.
*/
void setFrequency(int freq) {
frequency = freq;
}
/**
* Get the default temperature at which the system is being maintained, measured in Kelvin.
*/
double getDefaultTemperature() const {
return defaultTemperature;
}
/**
* Set the default temperature at which the system is being maintained. This will affect any new Contexts you create,
* but not ones that already exist.
*
* @param temp the system temperature, measured in Kelvin.
*/
void setDefaultTemperature(double temp) {
defaultTemperature = temp;
}
/**
* Get the random number seed. See setRandomNumberSeed() for details.
*/
int getRandomNumberSeed() const {
return randomNumberSeed;
}
/**
* Set the random number seed. It is guaranteed that if two simulations are run
* with different random number seeds, the sequence of Monte Carlo steps will be different. On
* the other hand, no guarantees are made about the behavior of simulations that use the same seed.
* In particular, Platforms are permitted to use non-deterministic algorithms which produce different
* results on successive runs, even if those runs were initialized identically.
*
* If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context
* is created from this Force. This is done to ensure that each Context receives unique random seeds
* without you needing to set them explicitly.
*/
void setRandomNumberSeed(int seed) {
randomNumberSeed = seed;
}
/**
* Returns whether or not this force makes use of periodic boundary
* conditions.
*
* @returns true if force uses PBC and false otherwise
*/
bool usesPeriodicBoundaryConditions() const {
return false;
}
/**
* Get whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*
* @returns true if scaling is applied to molecule centroids, false if it is applied to each atom independently.
*/
bool getScaleMoleculesAsRigid() const {
return scaleMoleculesAsRigid;
}
/**
* Set whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*/
void setScaleMoleculesAsRigid(bool rigid) {
scaleMoleculesAsRigid = rigid;
}
protected:
ForceImpl* createImpl() const;
private:
bool scaleMoleculesAsRigid;
double defaultPressure, defaultTemperature;
int frequency, randomNumberSeed;
};
} // namespace OpenMM
#endif /*OPENMM_MONTECARLOFLEXIBLEBAROSTAT_H_*/
#ifndef OPENMM_MONTECARLOFLEXIBLEBAROSTATIMPL_H_
#define OPENMM_MONTECARLOFLEXIBLEBAROSTATIMPL_H_
/* -------------------------------------------------------------------------- *
* 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-2021 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 "ForceImpl.h"
#include "openmm/MonteCarloFlexibleBarostat.h"
#include "openmm/Kernel.h"
#include <string>
namespace OpenMM {
/**
* This is the internal implementation of MonteCarloFlexibleBarostat.
*/
class MonteCarloFlexibleBarostatImpl : public ForceImpl {
public:
MonteCarloFlexibleBarostatImpl(const MonteCarloFlexibleBarostat& owner);
void initialize(ContextImpl& context);
const MonteCarloFlexibleBarostat& getOwner() const {
return owner;
}
void updateContextState(ContextImpl& context, bool& forcesInvalid);
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
// This force doesn't apply forces to particles.
return 0.0;
}
std::map<std::string, double> getDefaultParameters();
std::vector<std::string> getKernelNames();
private:
const MonteCarloFlexibleBarostat& owner;
int step, numAttempted, numAccepted;
double lengthScale;
Kernel kernel;
};
} // namespace OpenMM
#endif /*OPENMM_MONTECARLOFLEXIBLEBAROSTATIMPL_H_*/
...@@ -41,8 +41,7 @@ ...@@ -41,8 +41,7 @@
#include <algorithm> #include <algorithm>
using namespace OpenMM; using namespace OpenMM;
using namespace OpenMM_SFMT; using namespace std;
using std::vector;
MonteCarloAnisotropicBarostatImpl::MonteCarloAnisotropicBarostatImpl(const MonteCarloAnisotropicBarostat& owner) : owner(owner), step(0) { MonteCarloAnisotropicBarostatImpl::MonteCarloAnisotropicBarostatImpl(const MonteCarloAnisotropicBarostat& owner) : owner(owner), step(0) {
} }
...@@ -117,13 +116,12 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) ...@@ -117,13 +116,12 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double kT = BOLTZ*context.getParameter(MonteCarloAnisotropicBarostat::Temperature()); 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*log(newVolume/volume);
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > std::exp(-w/kT)) { if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step. // Reject the step.
kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context); kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context);
context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]); context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]);
volume = newVolume;
} }
else else
numAccepted[axis]++; numAccepted[axis]++;
...@@ -135,15 +133,15 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) ...@@ -135,15 +133,15 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
numAccepted[axis] = 0; numAccepted[axis] = 0;
} }
else if (numAccepted[axis] > 0.75*numAttempted[axis]) { else if (numAccepted[axis] > 0.75*numAttempted[axis]) {
volumeScale[axis] = std::min(volumeScale[axis]*1.1, volume*0.3); volumeScale[axis] = min(volumeScale[axis]*1.1, volume*0.3);
numAttempted[axis] = 0; numAttempted[axis] = 0;
numAccepted[axis] = 0; numAccepted[axis] = 0;
} }
} }
} }
std::map<std::string, double> MonteCarloAnisotropicBarostatImpl::getDefaultParameters() { map<string, double> MonteCarloAnisotropicBarostatImpl::getDefaultParameters() {
std::map<std::string, double> parameters; map<string, double> parameters;
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];
...@@ -151,8 +149,8 @@ std::map<std::string, double> MonteCarloAnisotropicBarostatImpl::getDefaultParam ...@@ -151,8 +149,8 @@ std::map<std::string, double> MonteCarloAnisotropicBarostatImpl::getDefaultParam
return parameters; return parameters;
} }
std::vector<std::string> MonteCarloAnisotropicBarostatImpl::getKernelNames() { vector<string> MonteCarloAnisotropicBarostatImpl::getKernelNames() {
std::vector<std::string> names; vector<string> names;
names.push_back(ApplyMonteCarloBarostatKernel::Name()); names.push_back(ApplyMonteCarloBarostatKernel::Name());
return names; return names;
} }
......
...@@ -41,8 +41,7 @@ ...@@ -41,8 +41,7 @@
#include <algorithm> #include <algorithm>
using namespace OpenMM; using namespace OpenMM;
using namespace OpenMM_SFMT; using namespace std;
using std::vector;
MonteCarloBarostatImpl::MonteCarloBarostatImpl(const MonteCarloBarostat& owner) : owner(owner), step(0) { MonteCarloBarostatImpl::MonteCarloBarostatImpl(const MonteCarloBarostat& owner) : owner(owner), step(0) {
} }
...@@ -78,7 +77,7 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc ...@@ -78,7 +77,7 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc
double volume = box[0][0]*box[1][1]*box[2][2]; double volume = box[0][0]*box[1][1]*box[2][2];
double deltaVolume = volumeScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5); double deltaVolume = volumeScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
double newVolume = volume+deltaVolume; double newVolume = volume+deltaVolume;
double lengthScale = std::pow(newVolume/volume, 1.0/3.0); double lengthScale = pow(newVolume/volume, 1.0/3.0);
kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale, lengthScale, lengthScale); kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale, lengthScale, lengthScale);
context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale, box[1]*lengthScale, box[2]*lengthScale); context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale, box[1]*lengthScale, box[2]*lengthScale);
...@@ -87,13 +86,12 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc ...@@ -87,13 +86,12 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25); double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25);
double kT = BOLTZ*context.getParameter(MonteCarloBarostat::Temperature()); 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*log(newVolume/volume);
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > std::exp(-w/kT)) { if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step. // Reject the step.
kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context); kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context);
context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]); context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]);
volume = newVolume;
} }
else { else {
numAccepted++; numAccepted++;
...@@ -107,22 +105,22 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc ...@@ -107,22 +105,22 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc
numAccepted = 0; numAccepted = 0;
} }
else if (numAccepted > 0.75*numAttempted) { else if (numAccepted > 0.75*numAttempted) {
volumeScale = std::min(volumeScale*1.1, volume*0.3); volumeScale = min(volumeScale*1.1, volume*0.3);
numAttempted = 0; numAttempted = 0;
numAccepted = 0; numAccepted = 0;
} }
} }
} }
std::map<std::string, double> MonteCarloBarostatImpl::getDefaultParameters() { map<string, double> MonteCarloBarostatImpl::getDefaultParameters() {
std::map<std::string, double> parameters; map<string, double> parameters;
parameters[MonteCarloBarostat::Pressure()] = getOwner().getDefaultPressure(); parameters[MonteCarloBarostat::Pressure()] = getOwner().getDefaultPressure();
parameters[MonteCarloBarostat::Temperature()] = getOwner().getDefaultTemperature(); parameters[MonteCarloBarostat::Temperature()] = getOwner().getDefaultTemperature();
return parameters; return parameters;
} }
std::vector<std::string> MonteCarloBarostatImpl::getKernelNames() { vector<string> MonteCarloBarostatImpl::getKernelNames() {
std::vector<std::string> names; vector<string> names;
names.push_back(ApplyMonteCarloBarostatKernel::Name()); names.push_back(ApplyMonteCarloBarostatKernel::Name());
return names; return names;
} }
......
/* -------------------------------------------------------------------------- *
* 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-2021 Stanford University and the Authors. *
* Authors: Peter Eastman, Sander Vandenhaute *
* 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/MonteCarloFlexibleBarostat.h"
#include "openmm/internal/MonteCarloFlexibleBarostatImpl.h"
using namespace OpenMM;
MonteCarloFlexibleBarostat::MonteCarloFlexibleBarostat(double defaultPressure, double defaultTemperature, int frequency, bool scaleMoleculesAsRigid) :
defaultPressure(defaultPressure), defaultTemperature(defaultTemperature), frequency(frequency), scaleMoleculesAsRigid(scaleMoleculesAsRigid) {
setRandomNumberSeed(0);
}
ForceImpl* MonteCarloFlexibleBarostat::createImpl() const {
return new MonteCarloFlexibleBarostatImpl(*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-2021 Stanford University and the Authors. *
* Authors: Peter Eastman, Sander Vandenhaute *
* 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/MonteCarloFlexibleBarostatImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/Context.h"
#include "openmm/kernels.h"
#include "openmm/OpenMMException.h"
#include "SimTKOpenMMUtilities.h"
#include <cmath>
#include <vector>
#include <algorithm>
using namespace OpenMM;
using namespace std;
MonteCarloFlexibleBarostatImpl::MonteCarloFlexibleBarostatImpl(const MonteCarloFlexibleBarostat& owner) : owner(owner), step(0) {
}
void MonteCarloFlexibleBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system");
kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context);
kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, owner.getScaleMoleculesAsRigid());
Vec3 box[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2];
lengthScale = 0.01*pow(volume, 1.0/3.0);
numAttempted = 0;
numAccepted = 0;
SimTKOpenMMUtilities::setRandomNumberSeed(owner.getRandomNumberSeed());
}
void MonteCarloFlexibleBarostatImpl::updateContextState(ContextImpl& context, bool& forcesInvalid) {
if (++step < owner.getFrequency() || owner.getFrequency() == 0)
return;
step = 0;
// Compute the current potential energy.
int groups = context.getIntegrator().getIntegrationForceGroups();
double initialEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double pressure = context.getParameter(MonteCarloFlexibleBarostat::Pressure())*(AVOGADRO*1e-25);
// Generate trial box vectors
Vec3 box[3], trial[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
trial[0][0] = box[0][0] + lengthScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
trial[1][0] = box[1][0] + lengthScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
trial[1][1] = box[1][1] + lengthScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
trial[2][0] = box[2][0] + lengthScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
trial[2][1] = box[2][1] + lengthScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
trial[2][2] = box[2][2] + lengthScale*2*(SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber()-0.5);
// Recompute reduced form by flipping/linear combinations.
for (auto i = 0; i < 3; i++)
if (trial[i][i] < 0)
trial[i] = -trial[i];
trial[2] -= trial[1]*round(trial[2][1]/trial[1][1]);
trial[2] -= trial[0]*round(trial[2][0]/trial[0][0]);
trial[1] -= trial[0]*round(trial[1][0]/trial[0][0]);
double volume = box[0][0]*box[1][1]*box[2][2];
double newVolume = trial[0][0]*trial[1][1]*trial[2][2];
// Scale particle coordinates and update box vectors in context.
kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, trial[0][0]/box[0][0], trial[1][1]/box[1][1], trial[2][2]/box[2][2]);
context.getOwner().setPeriodicBoxVectors(trial[0], trial[1], trial[2]);
// Compute the energy of the modified system.
double numberOfScaledParticles;
if (owner.getScaleMoleculesAsRigid())
numberOfScaledParticles = context.getMolecules().size();
else
numberOfScaledParticles = context.getSystem().getNumParticles();
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double kT = BOLTZ*context.getParameter(MonteCarloFlexibleBarostat::Temperature());
double w0 = finalEnergy-initialEnergy;
double w1 = pressure*(newVolume-volume);
double w2 = -(numberOfScaledParticles-2)*kT*log(newVolume/volume);
double w3 = -kT*log((trial[0][0]*trial[0][0]*trial[1][1])/(box[0][0]*box[0][0]*box[1][1]));
double w = w0+w1+w2+w3;
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step.
kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context);
context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]);
}
else {
numAccepted++;
forcesInvalid = true;
}
numAttempted++;
if (numAttempted >= 10) {
if (numAccepted < 0.25*numAttempted) {
lengthScale /= 1.1;
numAttempted = 0;
numAccepted = 0;
}
else if (numAccepted > 0.75*numAttempted) {
lengthScale = min(lengthScale*1.1, pow(newVolume, 1.0/3.0)*0.3);
numAttempted = 0;
numAccepted = 0;
}
}
}
map<string, double> MonteCarloFlexibleBarostatImpl::getDefaultParameters() {
map<string, double> parameters;
parameters[MonteCarloFlexibleBarostat::Pressure()] = getOwner().getDefaultPressure();
parameters[MonteCarloFlexibleBarostat::Temperature()] = getOwner().getDefaultTemperature();
return parameters;
}
vector<string> MonteCarloFlexibleBarostatImpl::getKernelNames() {
vector<string> names;
names.push_back(ApplyMonteCarloBarostatKernel::Name());
return names;
}
...@@ -41,8 +41,7 @@ ...@@ -41,8 +41,7 @@
#include <algorithm> #include <algorithm>
using namespace OpenMM; using namespace OpenMM;
using namespace OpenMM_SFMT; using namespace std;
using std::vector;
MonteCarloMembraneBarostatImpl::MonteCarloMembraneBarostatImpl(const MonteCarloMembraneBarostat& owner) : owner(owner), step(0) { MonteCarloMembraneBarostatImpl::MonteCarloMembraneBarostatImpl(const MonteCarloMembraneBarostat& owner) : owner(owner), step(0) {
} }
...@@ -118,13 +117,12 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) { ...@@ -118,13 +117,12 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) {
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double kT = BOLTZ*context.getParameter(MonteCarloMembraneBarostat::Temperature()); 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*log(newVolume/volume);
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > std::exp(-w/kT)) { if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step. // Reject the step.
kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context); kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context);
context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]); context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]);
volume = newVolume;
} }
else else
numAccepted[axis]++; numAccepted[axis]++;
...@@ -136,23 +134,23 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) { ...@@ -136,23 +134,23 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) {
numAccepted[axis] = 0; numAccepted[axis] = 0;
} }
else if (numAccepted[axis] > 0.75*numAttempted[axis]) { else if (numAccepted[axis] > 0.75*numAttempted[axis]) {
volumeScale[axis] = std::min(volumeScale[axis]*1.1, volume*0.3); volumeScale[axis] = min(volumeScale[axis]*1.1, volume*0.3);
numAttempted[axis] = 0; numAttempted[axis] = 0;
numAccepted[axis] = 0; numAccepted[axis] = 0;
} }
} }
} }
std::map<std::string, double> MonteCarloMembraneBarostatImpl::getDefaultParameters() { map<string, double> MonteCarloMembraneBarostatImpl::getDefaultParameters() {
std::map<std::string, double> parameters; map<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(); parameters[MonteCarloMembraneBarostat::Temperature()] = getOwner().getDefaultTemperature();
return parameters; return parameters;
} }
std::vector<std::string> MonteCarloMembraneBarostatImpl::getKernelNames() { vector<string> MonteCarloMembraneBarostatImpl::getKernelNames() {
std::vector<std::string> names; vector<string> names;
names.push_back(ApplyMonteCarloBarostatKernel::Name()); names.push_back(ApplyMonteCarloBarostatKernel::Name());
return names; return names;
} }
...@@ -1533,8 +1533,9 @@ public: ...@@ -1533,8 +1533,9 @@ public:
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param barostat the MonteCarloBarostat this kernel will be used for * @param barostat the MonteCarloBarostat this kernel will be used for
* @param rigidMolecules whether molecules should be kept rigid while scaling coordinates
*/ */
void initialize(const System& system, const Force& barostat); void initialize(const System& system, const Force& barostat, bool rigidMolecules=true);
/** /**
* Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value. * Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value.
* This version scales the x, y, and z positions independently. * This version scales the x, y, and z positions independently.
...@@ -1557,7 +1558,7 @@ public: ...@@ -1557,7 +1558,7 @@ public:
void restoreCoordinates(ContextImpl& context); void restoreCoordinates(ContextImpl& context);
private: private:
ComputeContext& cc; ComputeContext& cc;
bool hasInitializedKernels; bool hasInitializedKernels, rigidMolecules;
int numMolecules; int numMolecules;
ComputeArray savedPositions, savedFloatForces, savedLongForces; ComputeArray savedPositions, savedFloatForces, savedLongForces;
ComputeArray moleculeAtoms; ComputeArray moleculeAtoms;
......
...@@ -7680,7 +7680,8 @@ void CommonApplyAndersenThermostatKernel::execute(ContextImpl& context) { ...@@ -7680,7 +7680,8 @@ void CommonApplyAndersenThermostatKernel::execute(ContextImpl& context) {
kernel->execute(cc.getNumAtoms()); kernel->execute(cc.getNumAtoms());
} }
void CommonApplyMonteCarloBarostatKernel::initialize(const System& system, const Force& thermostat) { void CommonApplyMonteCarloBarostatKernel::initialize(const System& system, const Force& thermostat, bool rigidMolecules) {
this->rigidMolecules = rigidMolecules;
ContextSelector selector(cc); ContextSelector selector(cc);
savedPositions.initialize(cc, cc.getPaddedNumAtoms(), cc.getUseDoublePrecision() ? sizeof(mm_double4) : sizeof(mm_float4), "savedPositions"); savedPositions.initialize(cc, cc.getPaddedNumAtoms(), cc.getUseDoublePrecision() ? sizeof(mm_double4) : sizeof(mm_float4), "savedPositions");
savedLongForces.initialize<long long>(cc, cc.getPaddedNumAtoms()*3, "savedLongForces"); savedLongForces.initialize<long long>(cc, cc.getPaddedNumAtoms()*3, "savedLongForces");
...@@ -7702,7 +7703,14 @@ void CommonApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, ...@@ -7702,7 +7703,14 @@ void CommonApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context,
// Create the arrays with the molecule definitions. // Create the arrays with the molecule definitions.
vector<vector<int> > molecules = context.getMolecules(); vector<vector<int> > molecules;
if (rigidMolecules)
molecules = context.getMolecules();
else {
molecules.resize(cc.getNumAtoms());
for (int i = 0; i < molecules.size(); i++)
molecules[i].push_back(i);
}
numMolecules = molecules.size(); numMolecules = molecules.size();
moleculeAtoms.initialize<int>(cc, cc.getNumAtoms(), "moleculeAtoms"); moleculeAtoms.initialize<int>(cc, cc.getNumAtoms(), "moleculeAtoms");
moleculeStartIndex.initialize<int>(cc, numMolecules+1, "moleculeStartIndex"); moleculeStartIndex.initialize<int>(cc, numMolecules+1, "moleculeStartIndex");
......
/* -------------------------------------------------------------------------- *
* 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) 2021 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 "CudaTests.h"
#include "TestMonteCarloFlexibleBarostat.h"
void runPlatformTests() {
}
/* -------------------------------------------------------------------------- *
* 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) 2021 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 "OpenCLTests.h"
#include "TestMonteCarloFlexibleBarostat.h"
void runPlatformTests() {
}
...@@ -1546,8 +1546,9 @@ public: ...@@ -1546,8 +1546,9 @@ public:
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param barostat the MonteCarloBarostat this kernel will be used for * @param barostat the MonteCarloBarostat this kernel will be used for
* @param rigidMolecules whether molecules should be kept rigid while scaling coordinates
*/ */
void initialize(const System& system, const Force& barostat); void initialize(const System& system, const Force& barostat, bool rigidMolecules=true);
/** /**
* Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value. * Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value.
* This version scales the x, y, and z positions independently. * This version scales the x, y, and z positions independently.
...@@ -1569,6 +1570,7 @@ public: ...@@ -1569,6 +1570,7 @@ public:
*/ */
void restoreCoordinates(ContextImpl& context); void restoreCoordinates(ContextImpl& context);
private: private:
bool rigidMolecules;
ReferenceMonteCarloBarostat* barostat; ReferenceMonteCarloBarostat* barostat;
}; };
......
...@@ -2703,12 +2703,21 @@ ReferenceApplyMonteCarloBarostatKernel::~ReferenceApplyMonteCarloBarostatKernel( ...@@ -2703,12 +2703,21 @@ ReferenceApplyMonteCarloBarostatKernel::~ReferenceApplyMonteCarloBarostatKernel(
delete barostat; delete barostat;
} }
void ReferenceApplyMonteCarloBarostatKernel::initialize(const System& system, const Force& barostat) { void ReferenceApplyMonteCarloBarostatKernel::initialize(const System& system, const Force& barostat, bool rigidMolecules) {
this->rigidMolecules = rigidMolecules;
} }
void ReferenceApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, double scaleX, double scaleY, double scaleZ) { void ReferenceApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, double scaleX, double scaleY, double scaleZ) {
if (barostat == NULL) if (barostat == NULL) {
barostat = new ReferenceMonteCarloBarostat(context.getSystem().getNumParticles(), context.getMolecules()); if (rigidMolecules)
barostat = new ReferenceMonteCarloBarostat(context.getSystem().getNumParticles(), context.getMolecules());
else {
vector<vector<int> > molecules(context.getSystem().getNumParticles());
for (int i = 0; i < molecules.size(); i++)
molecules[i].push_back(i);
barostat = new ReferenceMonteCarloBarostat(context.getSystem().getNumParticles(), molecules);
}
}
vector<Vec3>& posData = extractPositions(context); vector<Vec3>& posData = extractPositions(context);
Vec3* boxVectors = extractBoxVectors(context); Vec3* boxVectors = extractBoxVectors(context);
barostat->applyBarostat(posData, boxVectors, scaleX, scaleY, scaleZ); barostat->applyBarostat(posData, boxVectors, scaleX, scaleY, scaleZ);
......
/* -------------------------------------------------------------------------- *
* 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) 2021 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 "ReferenceTests.h"
#include "TestMonteCarloFlexibleBarostat.h"
void runPlatformTests() {
}
#ifndef OPENMM_MONTECARLOFLEXIBLEBAROSTAT_PROXY_H_
#define OPENMM_MONTECARLOFLEXIBLEBAROSTAT_PROXY_H_
/* -------------------------------------------------------------------------- *
* 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 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/windowsExport.h"
#include "openmm/serialization/SerializationProxy.h"
namespace OpenMM {
/**
* This is a proxy for serializing MonteCarloFlexibleBarostat objects.
*/
class OPENMM_EXPORT MonteCarloFlexibleBarostatProxy : public SerializationProxy {
public:
MonteCarloFlexibleBarostatProxy();
void serialize(const void* object, SerializationNode& node) const;
void* deserialize(const SerializationNode& node) const;
};
} // namespace OpenMM
#endif /*OPENMM_MONTECARLOFLEXIBLEBAROSTAT_PROXY_H_*/
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