Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
09786e4b
Commit
09786e4b
authored
Jun 23, 2009
by
Peter Eastman
Browse files
Created VariableVerletIntegrator
parent
eb6ebc43
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
944 additions
and
16 deletions
+944
-16
olla/include/openmm/kernels.h
olla/include/openmm/kernels.h
+27
-0
openmmapi/include/OpenMM.h
openmmapi/include/OpenMM.h
+1
-0
openmmapi/include/openmm/VariableVerletIntegrator.h
openmmapi/include/openmm/VariableVerletIntegrator.h
+107
-0
openmmapi/src/BrownianIntegrator.cpp
openmmapi/src/BrownianIntegrator.cpp
+0
-1
openmmapi/src/LangevinIntegrator.cpp
openmmapi/src/LangevinIntegrator.cpp
+0
-1
openmmapi/src/VariableVerletIntegrator.cpp
openmmapi/src/VariableVerletIntegrator.cpp
+66
-0
openmmapi/src/VerletIntegrator.cpp
openmmapi/src/VerletIntegrator.cpp
+0
-1
platforms/brook/src/BrookIntegrateLangevinStepKernel.cpp
platforms/brook/src/BrookIntegrateLangevinStepKernel.cpp
+1
-1
platforms/brook/src/BrookIntegrateVerletStepKernel.cpp
platforms/brook/src/BrookIntegrateVerletStepKernel.cpp
+1
-2
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+3
-0
platforms/reference/src/ReferenceKernelFactory.cpp
platforms/reference/src/ReferenceKernelFactory.cpp
+5
-3
platforms/reference/src/ReferenceKernels.cpp
platforms/reference/src/ReferenceKernels.cpp
+60
-0
platforms/reference/src/ReferenceKernels.h
platforms/reference/src/ReferenceKernels.h
+44
-6
platforms/reference/src/ReferencePlatform.cpp
platforms/reference/src/ReferencePlatform.cpp
+1
-0
platforms/reference/src/SimTKReference/ReferenceDynamics.cpp
platforms/reference/src/SimTKReference/ReferenceDynamics.cpp
+17
-0
platforms/reference/src/SimTKReference/ReferenceDynamics.h
platforms/reference/src/SimTKReference/ReferenceDynamics.h
+9
-1
platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp
...ce/src/SimTKReference/ReferenceVariableVerletDynamics.cpp
+264
-0
platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.h
...ence/src/SimTKReference/ReferenceVariableVerletDynamics.h
+123
-0
platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp
...reference/tests/TestReferenceVariableVerletIntegrator.cpp
+215
-0
No files found.
olla/include/openmm/kernels.h
View file @
09786e4b
...
...
@@ -32,6 +32,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/VariableVerletIntegrator.h"
#include "openmm/AndersenThermostat.h"
#include "openmm/BrownianIntegrator.h"
#include "openmm/CMMotionRemover.h"
...
...
@@ -417,6 +418,32 @@ public:
virtual
void
execute
(
OpenMMContextImpl
&
context
,
const
BrownianIntegrator
&
integrator
)
=
0
;
};
/**
* This kernel is invoked by VariableVerletIntegrator to take one time step.
*/
class
IntegrateVariableVerletStepKernel
:
public
KernelImpl
{
public:
static
std
::
string
Name
()
{
return
"IntegrateVariableVerletStep"
;
}
IntegrateVariableVerletStepKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
KernelImpl
(
name
,
platform
)
{
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param integrator the VariableVerletIntegrator this kernel will be used for
*/
virtual
void
initialize
(
const
System
&
system
,
const
VariableVerletIntegrator
&
integrator
)
=
0
;
/**
* Execute the kernel.
*
* @param context the context in which to execute this kernel
* @param integrator the VerletIntegrator this kernel is being used for
*/
virtual
void
execute
(
OpenMMContextImpl
&
context
,
const
VariableVerletIntegrator
&
integrator
)
=
0
;
};
/**
* This kernel is invoked by AndersenThermostat at the start of each time step to adjust the particle velocities.
*/
...
...
openmmapi/include/OpenMM.h
View file @
09786e4b
...
...
@@ -32,6 +32,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/VariableVerletIntegrator.h"
#include "openmm/AndersenThermostat.h"
#include "openmm/BrownianIntegrator.h"
#include "openmm/CMMotionRemover.h"
...
...
openmmapi/include/openmm/VariableVerletIntegrator.h
0 → 100644
View file @
09786e4b
#ifndef OPENMM_VARIABLEVERLETINTEGRATOR_H_
#define OPENMM_VARIABLEVERLETINTEGRATOR_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) 2008-2009 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 "Integrator.h"
#include "openmm/Kernel.h"
#include "internal/windowsExport.h"
namespace
OpenMM
{
/**
* This is an error contolled, variable time step Integrator that simulates a System using the
* velocity Verlet algorithm. It compares the result of the Verlet integrator to that of an
* explicit Euler integrator, takes the difference between the two as a measure of the integration
* error in each time step, and continuously adjusts the step size to keep the error below a
* specified tolerance. This allows it to take larger steps on average than a fixed step size
* integrator, while still maintaining comparable accuracy and stability.
*
* It is best not to think of the value of the accuracy parameter as having any absolute meaning.
* It is just an adjustable parameter that affects the step size and integration accuracy. You
* should try different values to find the largest value that produces a trajectory sufficiently
* accurate for your purposes. 0.001 is often a good starting point.
*
* Unlike a fixed step size Verlet integrator, variable step size Verlet is not symplectic. This
* means that at a given accuracy level, energy is not as precisely conserved over long time periods.
* This makes it most appropriate for constant temperate simulations. In constant energy simulations
* where precise energy conservation over long time periods is important, a fixed step size Verlet
* integrator may be more appropriate.
*/
class
OPENMM_EXPORT
VariableVerletIntegrator
:
public
Integrator
{
public:
/**
* Create a VariableVerletIntegrator.
*
* @param stepSize the initial step size to use (in picoseconds)
* @param accuracy the required accuracy
*/
VariableVerletIntegrator
(
double
stepSize
,
double
accuracy
);
/**
* Get the required accuracy.
*/
double
getAccuracy
()
const
{
return
accuracy
;
}
/**
* Set the required accuracy.
*/
void
setAccuracy
(
double
acc
)
{
accuracy
=
acc
;
}
/**
* Advance a simulation through time by taking a series of time steps.
*
* @param steps the number of time steps to take
*/
void
step
(
int
steps
);
protected:
/**
* This will be called by the OpenMMContext when it is created. It informs the Integrator
* of what context it will be integrating, and gives it a chance to do any necessary initialization.
* It will also get called again if the application calls reinitialize() on the OpenMMContext.
*/
void
initialize
(
OpenMMContextImpl
&
context
);
/**
* Get the names of all Kernels used by this Integrator.
*/
std
::
vector
<
std
::
string
>
getKernelNames
();
private:
double
accuracy
;
OpenMMContextImpl
*
context
;
Kernel
kernel
;
};
}
// namespace OpenMM
#endif
/*OPENMM_VARIABLEVERLETINTEGRATOR_H_*/
openmmapi/src/BrownianIntegrator.cpp
View file @
09786e4b
...
...
@@ -65,6 +65,5 @@ void BrownianIntegrator::step(int steps) {
context
->
updateContextState
();
context
->
calcForces
();
dynamic_cast
<
IntegrateBrownianStepKernel
&>
(
kernel
.
getImpl
()).
execute
(
*
context
,
*
this
);
context
->
setTime
(
context
->
getTime
()
+
getStepSize
());
}
}
openmmapi/src/LangevinIntegrator.cpp
View file @
09786e4b
...
...
@@ -65,6 +65,5 @@ void LangevinIntegrator::step(int steps) {
context
->
updateContextState
();
context
->
calcForces
();
dynamic_cast
<
IntegrateLangevinStepKernel
&>
(
kernel
.
getImpl
()).
execute
(
*
context
,
*
this
);
context
->
setTime
(
context
->
getTime
()
+
getStepSize
());
}
}
openmmapi/src/VariableVerletIntegrator.cpp
0 → 100644
View file @
09786e4b
/* -------------------------------------------------------------------------- *
* 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) 2008-2009 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/VariableVerletIntegrator.h"
#include "openmm/OpenMMContext.h"
#include "openmm/internal/OpenMMContextImpl.h"
#include "openmm/kernels.h"
#include <string>
using
namespace
OpenMM
;
using
std
::
string
;
using
std
::
vector
;
VariableVerletIntegrator
::
VariableVerletIntegrator
(
double
stepSize
,
double
accuracy
)
:
accuracy
(
accuracy
)
{
setStepSize
(
stepSize
);
setConstraintTolerance
(
1e-4
);
}
void
VariableVerletIntegrator
::
initialize
(
OpenMMContextImpl
&
contextRef
)
{
context
=
&
contextRef
;
kernel
=
context
->
getPlatform
().
createKernel
(
IntegrateVariableVerletStepKernel
::
Name
(),
contextRef
);
dynamic_cast
<
IntegrateVariableVerletStepKernel
&>
(
kernel
.
getImpl
()).
initialize
(
contextRef
.
getSystem
(),
*
this
);
}
vector
<
string
>
VariableVerletIntegrator
::
getKernelNames
()
{
std
::
vector
<
std
::
string
>
names
;
names
.
push_back
(
IntegrateVariableVerletStepKernel
::
Name
());
return
names
;
}
void
VariableVerletIntegrator
::
step
(
int
steps
)
{
for
(
int
i
=
0
;
i
<
steps
;
++
i
)
{
context
->
updateContextState
();
context
->
calcForces
();
dynamic_cast
<
IntegrateVariableVerletStepKernel
&>
(
kernel
.
getImpl
()).
execute
(
*
context
,
*
this
);
}
}
openmmapi/src/VerletIntegrator.cpp
View file @
09786e4b
...
...
@@ -61,6 +61,5 @@ void VerletIntegrator::step(int steps) {
context
->
updateContextState
();
context
->
calcForces
();
dynamic_cast
<
IntegrateVerletStepKernel
&>
(
kernel
.
getImpl
()).
execute
(
*
context
,
*
this
);
context
->
setTime
(
context
->
getTime
()
+
getStepSize
());
}
}
platforms/brook/src/BrookIntegrateLangevinStepKernel.cpp
View file @
09786e4b
...
...
@@ -250,5 +250,5 @@ void BrookIntegrateLangevinStepKernel::execute( OpenMMContextImpl& context, cons
_brookLangevinDynamics
->
update
(
*
(
_openMMBrookInterface
.
getParticlePositions
()),
*
(
_openMMBrookInterface
.
getParticleVelocities
()),
*
(
_openMMBrookInterface
.
getParticleForces
()),
*
_brookShakeAlgorithm
,
*
_brookRandomNumberGenerator
);
_openMMBrookInterface
->
setTime
(
_openMMBrookInterface
->
getTime
(
integrator
.
getStepSize
()));
}
platforms/brook/src/BrookIntegrateVerletStepKernel.cpp
View file @
09786e4b
...
...
@@ -202,6 +202,5 @@ void BrookIntegrateVerletStepKernel::execute( OpenMMContextImpl& context, const
_brookVerletDynamics
->
update
(
*
(
_openMMBrookInterface
.
getParticlePositions
()),
*
(
_openMMBrookInterface
.
getParticleVelocities
()),
*
(
_openMMBrookInterface
.
getParticleForces
()),
*
_brookShakeAlgorithm
);
_openMMBrookInterface
->
setTime
(
_openMMBrookInterface
->
getTime
(
stepSize
));
}
platforms/cuda/src/CudaKernels.cpp
View file @
09786e4b
...
...
@@ -458,6 +458,7 @@ void CudaIntegrateVerletStepKernel::execute(OpenMMContextImpl& context, const Ve
gpu
->
bCalculateCM
=
true
;
}
kVerletUpdatePart2
(
gpu
);
data
.
time
+=
stepSize
;
}
CudaIntegrateLangevinStepKernel
::~
CudaIntegrateLangevinStepKernel
()
{
...
...
@@ -500,6 +501,7 @@ void CudaIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, const
kApplySecondShake
(
gpu
);
kApplySecondSettle
(
gpu
);
kApplySecondCCMA
(
gpu
);
data
.
time
+=
stepSize
;
}
CudaIntegrateBrownianStepKernel
::~
CudaIntegrateBrownianStepKernel
()
{
...
...
@@ -539,6 +541,7 @@ void CudaIntegrateBrownianStepKernel::execute(OpenMMContextImpl& context, const
gpu
->
bCalculateCM
=
true
;
}
kBrownianUpdatePart2
(
gpu
);
data
.
time
+=
stepSize
;
}
CudaApplyAndersenThermostatKernel
::~
CudaApplyAndersenThermostatKernel
()
{
...
...
platforms/reference/src/ReferenceKernelFactory.cpp
View file @
09786e4b
...
...
@@ -59,11 +59,13 @@ KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Pla
if
(
name
==
CalcGBVIForceKernel
::
Name
())
return
new
ReferenceCalcGBVIForceKernel
(
name
,
platform
);
if
(
name
==
IntegrateVerletStepKernel
::
Name
())
return
new
ReferenceIntegrateVerletStepKernel
(
name
,
platform
);
return
new
ReferenceIntegrateVerletStepKernel
(
name
,
platform
,
data
);
if
(
name
==
IntegrateLangevinStepKernel
::
Name
())
return
new
ReferenceIntegrateLangevinStepKernel
(
name
,
platform
);
return
new
ReferenceIntegrateLangevinStepKernel
(
name
,
platform
,
data
);
if
(
name
==
IntegrateBrownianStepKernel
::
Name
())
return
new
ReferenceIntegrateBrownianStepKernel
(
name
,
platform
);
return
new
ReferenceIntegrateBrownianStepKernel
(
name
,
platform
,
data
);
if
(
name
==
IntegrateVariableVerletStepKernel
::
Name
())
return
new
ReferenceIntegrateVariableVerletStepKernel
(
name
,
platform
,
data
);
if
(
name
==
ApplyAndersenThermostatKernel
::
Name
())
return
new
ReferenceApplyAndersenThermostatKernel
(
name
,
platform
);
if
(
name
==
CalcKineticEnergyKernel
::
Name
())
...
...
platforms/reference/src/ReferenceKernels.cpp
View file @
09786e4b
...
...
@@ -33,6 +33,7 @@
#include "ReferenceFloatStreamImpl.h"
#include "gbsa/CpuObc.h"
#include "gbsa/CpuGBVI.h"
#include "SimTKReference/ReferenceVariableVerletDynamics.h"
#include "SimTKReference/ReferenceAndersenThermostat.h"
#include "SimTKReference/ReferenceAngleBondIxn.h"
#include "SimTKReference/ReferenceBondForce.h"
...
...
@@ -639,6 +640,7 @@ void ReferenceIntegrateVerletStepKernel::execute(OpenMMContextImpl& context, con
prevStepSize
=
stepSize
;
}
dynamics
->
update
(
context
.
getSystem
().
getNumParticles
(),
posData
,
velData
,
forceData
,
masses
);
data
.
time
+=
stepSize
;
}
ReferenceIntegrateLangevinStepKernel
::~
ReferenceIntegrateLangevinStepKernel
()
{
...
...
@@ -702,6 +704,7 @@ void ReferenceIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, c
prevStepSize
=
stepSize
;
}
dynamics
->
update
(
context
.
getSystem
().
getNumParticles
(),
posData
,
velData
,
forceData
,
masses
);
data
.
time
+=
stepSize
;
}
ReferenceIntegrateBrownianStepKernel
::~
ReferenceIntegrateBrownianStepKernel
()
{
...
...
@@ -764,6 +767,63 @@ void ReferenceIntegrateBrownianStepKernel::execute(OpenMMContextImpl& context, c
prevStepSize
=
stepSize
;
}
dynamics
->
update
(
context
.
getSystem
().
getNumParticles
(),
posData
,
velData
,
forceData
,
masses
);
data
.
time
+=
stepSize
;
}
ReferenceIntegrateVariableVerletStepKernel
::~
ReferenceIntegrateVariableVerletStepKernel
()
{
if
(
dynamics
)
delete
dynamics
;
if
(
constraints
)
delete
constraints
;
if
(
masses
)
delete
[]
masses
;
if
(
constraintIndices
)
disposeIntArray
(
constraintIndices
,
numConstraints
);
if
(
constraintDistances
)
delete
[]
constraintDistances
;
}
void
ReferenceIntegrateVariableVerletStepKernel
::
initialize
(
const
System
&
system
,
const
VariableVerletIntegrator
&
integrator
)
{
int
numParticles
=
system
.
getNumParticles
();
masses
=
new
RealOpenMM
[
numParticles
];
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
constraintIndices
=
allocateIntArray
(
numConstraints
,
2
);
constraintDistances
=
new
RealOpenMM
[
numConstraints
];
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
][
0
]
=
particle1
;
constraintIndices
[
i
][
1
]
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
}
}
void
ReferenceIntegrateVariableVerletStepKernel
::
execute
(
OpenMMContextImpl
&
context
,
const
VariableVerletIntegrator
&
integrator
)
{
double
stepSize
=
integrator
.
getStepSize
();
double
accuracy
=
integrator
.
getAccuracy
();
RealOpenMM
**
posData
=
((
ReferenceFloatStreamImpl
&
)
context
.
getPositions
().
getImpl
()).
getData
();
RealOpenMM
**
velData
=
((
ReferenceFloatStreamImpl
&
)
context
.
getVelocities
().
getImpl
()).
getData
();
RealOpenMM
**
forceData
=
const_cast
<
RealOpenMM
**>
(((
ReferenceFloatStreamImpl
&
)
context
.
getForces
().
getImpl
()).
getData
());
// Reference code needs to be made const correct
if
(
dynamics
==
0
||
stepSize
!=
prevStepSize
||
accuracy
!=
prevAccuracy
)
{
// Recreate the computation objects with the new parameters.
if
(
dynamics
)
{
delete
dynamics
;
delete
constraints
;
}
dynamics
=
new
ReferenceVariableVerletDynamics
(
context
.
getSystem
().
getNumParticles
(),
static_cast
<
RealOpenMM
>
(
stepSize
),
accuracy
);
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
context
.
getSystem
(),
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
context
.
getSystem
().
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
dynamics
->
setReferenceConstraintAlgorithm
(
constraints
);
prevStepSize
=
stepSize
;
prevAccuracy
=
accuracy
;
}
dynamics
->
update
(
context
.
getSystem
().
getNumParticles
(),
posData
,
velData
,
forceData
,
masses
);
data
.
time
+=
dynamics
->
getLastStepSize
();
}
ReferenceApplyAndersenThermostatKernel
::~
ReferenceApplyAndersenThermostatKernel
()
{
...
...
platforms/reference/src/ReferenceKernels.h
View file @
09786e4b
...
...
@@ -43,6 +43,7 @@ class ReferenceAndersenThermostat;
class
ReferenceBrownianDynamics
;
class
ReferenceStochasticDynamics
;
class
ReferenceConstraintAlgorithm
;
class
ReferenceVariableVerletDynamics
;
class
ReferenceVerletDynamics
;
namespace
OpenMM
{
...
...
@@ -343,8 +344,8 @@ private:
*/
class
ReferenceIntegrateVerletStepKernel
:
public
IntegrateVerletStepKernel
{
public:
ReferenceIntegrateVerletStepKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
IntegrateVerletStepKernel
(
name
,
platform
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
ReferenceIntegrateVerletStepKernel
(
std
::
string
name
,
const
Platform
&
platform
,
ReferencePlatform
::
PlatformData
&
data
)
:
IntegrateVerletStepKernel
(
name
,
platform
),
data
(
data
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
}
~
ReferenceIntegrateVerletStepKernel
();
/**
...
...
@@ -362,6 +363,7 @@ public:
*/
void
execute
(
OpenMMContextImpl
&
context
,
const
VerletIntegrator
&
integrator
);
private:
ReferencePlatform
::
PlatformData
&
data
;
ReferenceVerletDynamics
*
dynamics
;
ReferenceConstraintAlgorithm
*
constraints
;
RealOpenMM
*
masses
;
...
...
@@ -376,8 +378,8 @@ private:
*/
class
ReferenceIntegrateLangevinStepKernel
:
public
IntegrateLangevinStepKernel
{
public:
ReferenceIntegrateLangevinStepKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
IntegrateLangevinStepKernel
(
name
,
platform
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
ReferenceIntegrateLangevinStepKernel
(
std
::
string
name
,
const
Platform
&
platform
,
ReferencePlatform
::
PlatformData
&
data
)
:
IntegrateLangevinStepKernel
(
name
,
platform
),
data
(
data
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
}
~
ReferenceIntegrateLangevinStepKernel
();
/**
...
...
@@ -395,6 +397,7 @@ public:
*/
void
execute
(
OpenMMContextImpl
&
context
,
const
LangevinIntegrator
&
integrator
);
private:
ReferencePlatform
::
PlatformData
&
data
;
ReferenceStochasticDynamics
*
dynamics
;
ReferenceConstraintAlgorithm
*
constraints
;
RealOpenMM
*
masses
;
...
...
@@ -409,8 +412,8 @@ private:
*/
class
ReferenceIntegrateBrownianStepKernel
:
public
IntegrateBrownianStepKernel
{
public:
ReferenceIntegrateBrownianStepKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
IntegrateBrownianStepKernel
(
name
,
platform
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
ReferenceIntegrateBrownianStepKernel
(
std
::
string
name
,
const
Platform
&
platform
,
ReferencePlatform
::
PlatformData
&
data
)
:
IntegrateBrownianStepKernel
(
name
,
platform
),
data
(
data
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
}
~
ReferenceIntegrateBrownianStepKernel
();
/**
...
...
@@ -428,6 +431,7 @@ public:
*/
void
execute
(
OpenMMContextImpl
&
context
,
const
BrownianIntegrator
&
integrator
);
private:
ReferencePlatform
::
PlatformData
&
data
;
ReferenceBrownianDynamics
*
dynamics
;
ReferenceConstraintAlgorithm
*
constraints
;
RealOpenMM
*
masses
;
...
...
@@ -437,6 +441,40 @@ private:
double
prevTemp
,
prevFriction
,
prevStepSize
;
};
/**
* This kernel is invoked by VariableVerletIntegrator to take one time step.
*/
class
ReferenceIntegrateVariableVerletStepKernel
:
public
IntegrateVariableVerletStepKernel
{
public:
ReferenceIntegrateVariableVerletStepKernel
(
std
::
string
name
,
const
Platform
&
platform
,
ReferencePlatform
::
PlatformData
&
data
)
:
IntegrateVariableVerletStepKernel
(
name
,
platform
),
data
(
data
),
dynamics
(
0
),
constraints
(
0
),
masses
(
0
),
constraintDistances
(
0
),
constraintIndices
(
0
)
{
}
~
ReferenceIntegrateVariableVerletStepKernel
();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param integrator the VerletIntegrator this kernel will be used for
*/
void
initialize
(
const
System
&
system
,
const
VariableVerletIntegrator
&
integrator
);
/**
* Execute the kernel.
*
* @param context the context in which to execute this kernel
* @param integrator the VerletIntegrator this kernel is being used for
*/
void
execute
(
OpenMMContextImpl
&
context
,
const
VariableVerletIntegrator
&
integrator
);
private:
ReferencePlatform
::
PlatformData
&
data
;
ReferenceVariableVerletDynamics
*
dynamics
;
ReferenceConstraintAlgorithm
*
constraints
;
RealOpenMM
*
masses
;
RealOpenMM
*
constraintDistances
;
int
**
constraintIndices
;
int
numConstraints
;
double
prevStepSize
,
prevAccuracy
;
};
/**
* This kernel is invoked by AndersenThermostat at the start of each time step to adjust the particle velocities.
*/
...
...
platforms/reference/src/ReferencePlatform.cpp
View file @
09786e4b
...
...
@@ -51,6 +51,7 @@ ReferencePlatform::ReferencePlatform() {
registerKernelFactory
(
IntegrateVerletStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateLangevinStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateBrownianStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateVariableVerletStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
ApplyAndersenThermostatKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcKineticEnergyKernel
::
Name
(),
factory
);
registerKernelFactory
(
RemoveCMMotionKernel
::
Name
(),
factory
);
...
...
platforms/reference/src/SimTKReference/ReferenceDynamics.cpp
View file @
09786e4b
...
...
@@ -362,6 +362,23 @@ RealOpenMM ReferenceDynamics::getDeltaT( void ) const {
return
_deltaT
;
}
/**---------------------------------------------------------------------------------------
Set delta t
--------------------------------------------------------------------------------------- */
void
ReferenceDynamics
::
setDeltaT
(
RealOpenMM
deltaT
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::setDeltaT";
// ---------------------------------------------------------------------------------------
_deltaT
=
deltaT
;
}
/**---------------------------------------------------------------------------------------
Get temperature
...
...
platforms/reference/src/SimTKReference/ReferenceDynamics.h
View file @
09786e4b
...
...
@@ -164,7 +164,7 @@ class ReferenceDynamics {
--------------------------------------------------------------------------------------- */
~
ReferenceDynamics
(
);
virtual
~
ReferenceDynamics
(
);
/**---------------------------------------------------------------------------------------
...
...
@@ -206,6 +206,14 @@ class ReferenceDynamics {
RealOpenMM
getDeltaT
(
void
)
const
;
/**---------------------------------------------------------------------------------------
Set delta t
--------------------------------------------------------------------------------------- */
void
setDeltaT
(
RealOpenMM
deltaT
);
/**---------------------------------------------------------------------------------------
Get temperature
...
...
platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp
0 → 100644
View file @
09786e4b
/* Portions copyright (c) 2006-2009 Stanford University and Simbios.
* Contributors: Peter Eastman, Pande Group
*
* 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 <string.h>
#include <sstream>
#include "../SimTKUtilities/SimTKOpenMMCommon.h"
#include "../SimTKUtilities/SimTKOpenMMLog.h"
#include "../SimTKUtilities/SimTKOpenMMUtilities.h"
#include "ReferenceVariableVerletDynamics.h"
/**---------------------------------------------------------------------------------------
ReferenceVariableVerletDynamics constructor
@param numberOfAtoms number of atoms
@param deltaT initial delta t for dynamics
@param accuracy required accuracy
--------------------------------------------------------------------------------------- */
ReferenceVariableVerletDynamics
::
ReferenceVariableVerletDynamics
(
int
numberOfAtoms
,
RealOpenMM
deltaT
,
RealOpenMM
accuracy
)
:
ReferenceDynamics
(
numberOfAtoms
,
deltaT
,
0.0
),
_accuracy
(
accuracy
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVariableVerletDynamics::ReferenceVariableVerletDynamics"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
// ---------------------------------------------------------------------------------------
allocate2DArrays
(
numberOfAtoms
,
3
,
Max2DArrays
);
allocate1DArrays
(
numberOfAtoms
,
Max1DArrays
);
}
/**---------------------------------------------------------------------------------------
ReferenceVariableVerletDynamics destructor
--------------------------------------------------------------------------------------- */
ReferenceVariableVerletDynamics
::~
ReferenceVariableVerletDynamics
(
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceVariableVerletDynamics::~ReferenceVariableVerletDynamics";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
Get the required accuracy
@return accuracy
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceVariableVerletDynamics
::
getAccuracy
(
void
)
const
{
return
_accuracy
;
}
/**---------------------------------------------------------------------------------------
Set the required accuracy
--------------------------------------------------------------------------------------- */
void
ReferenceVariableVerletDynamics
::
setAccuracy
(
RealOpenMM
accuracy
)
{
_accuracy
=
accuracy
;
}
/**---------------------------------------------------------------------------------------
Get the actual size of the last step that was taken
@return step size
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceVariableVerletDynamics
::
getLastStepSize
(
void
)
const
{
return
_lastStepSize
;
}
/**---------------------------------------------------------------------------------------
Print parameters
@param message message
@return ReferenceDynamics::DefaultReturn
--------------------------------------------------------------------------------------- */
int
ReferenceVariableVerletDynamics
::
printParameters
(
std
::
stringstream
&
message
)
const
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVariableVerletDynamics::printParameters"
;
// ---------------------------------------------------------------------------------------
// print parameters
ReferenceDynamics
::
printParameters
(
message
);
return
ReferenceDynamics
::
DefaultReturn
;
}
/**---------------------------------------------------------------------------------------
Update -- driver routine for performing Verlet dynamics update of coordinates
and velocities
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param velocities velocities
@param forces forces
@param masses atom masses
@return ReferenceDynamics::DefaultReturn
--------------------------------------------------------------------------------------- */
int
ReferenceVariableVerletDynamics
::
update
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
velocities
,
RealOpenMM
**
forces
,
RealOpenMM
*
masses
){
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVariableVerletDynamics::update"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
int
debug
=
0
;
// ---------------------------------------------------------------------------------------
// get work arrays
RealOpenMM
**
xPrime
=
get2DArrayAtIndex
(
xPrime2D
);
RealOpenMM
**
vPrime
=
get2DArrayAtIndex
(
vPrime2D
);
RealOpenMM
*
inverseMasses
=
get1DArrayAtIndex
(
InverseMasses
);
// first-time-through initialization
if
(
getTimeStep
()
==
0
){
std
::
stringstream
message
;
message
<<
methodName
;
int
errors
=
0
;
// invert masses
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
if
(
masses
[
ii
]
<=
zero
){
message
<<
"mass at atom index="
<<
ii
<<
" ("
<<
masses
[
ii
]
<<
") is <= 0"
<<
std
::
endl
;
errors
++
;
}
else
{
inverseMasses
[
ii
]
=
one
/
masses
[
ii
];
}
}
// exit if errors
if
(
errors
){
SimTKOpenMMLog
::
printError
(
message
);
}
}
// Try different step sizes until the accuracy is acceptable.
bool
success
=
false
;
RealOpenMM
maxStepSize
=
5.0
f
*
getDeltaT
();
while
(
!
success
)
{
// Perform the integration and estimate the error.
_lastStepSize
=
getDeltaT
();
RealOpenMM
error
=
zero
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
RealOpenMM
xref
=
atomCoordinates
[
i
][
j
]
+
velocities
[
i
][
j
]
*
getDeltaT
();
vPrime
[
i
][
j
]
=
velocities
[
i
][
j
]
+
inverseMasses
[
i
]
*
forces
[
i
][
j
]
*
getDeltaT
();
xPrime
[
i
][
j
]
=
atomCoordinates
[
i
][
j
]
+
vPrime
[
i
][
j
]
*
getDeltaT
();
RealOpenMM
xerror
=
xPrime
[
i
][
j
]
-
xref
;
error
+=
xerror
*
xerror
;
}
}
error
=
SQRT
(
error
/
(
numberOfAtoms
*
3
));
// Select a new step size.
const
RealOpenMM
Safety
=
0.9
f
,
MinShrink
=
0.1
f
;
const
RealOpenMM
HysteresisLow
=
0.9
f
,
HysteresisHigh
=
1.0
f
,
ErrorOrder
=
2.0
f
;
RealOpenMM
newStepSize
=
Safety
*
getDeltaT
()
*
POW
(
getAccuracy
()
/
error
,
1.0
f
/
ErrorOrder
);
if
(
newStepSize
>
getDeltaT
())
{
if
(
newStepSize
<
HysteresisHigh
*
getDeltaT
())
newStepSize
=
getDeltaT
();
}
if
(
newStepSize
<
getDeltaT
()
&&
error
<=
getAccuracy
())
newStepSize
=
getDeltaT
();
newStepSize
=
std
::
min
(
newStepSize
,
maxStepSize
);
newStepSize
=
std
::
max
(
newStepSize
,
MinShrink
*
getDeltaT
());
if
(
newStepSize
<
getDeltaT
())
newStepSize
=
std
::
min
(
newStepSize
,
HysteresisLow
*
getDeltaT
());
success
=
(
newStepSize
>=
getDeltaT
());
if
(
success
)
{
ReferenceConstraintAlgorithm
*
referenceConstraintAlgorithm
=
getReferenceConstraintAlgorithm
();
if
(
referenceConstraintAlgorithm
)
success
=
(
referenceConstraintAlgorithm
->
apply
(
numberOfAtoms
,
atomCoordinates
,
xPrime
,
inverseMasses
)
!=
ErrorReturn
);
if
(
!
success
)
{
newStepSize
*=
0.5
f
;
maxStepSize
=
newStepSize
;
}
}
setDeltaT
(
newStepSize
);
}
// Update the positions and velocities.
RealOpenMM
velocityScale
=
static_cast
<
RealOpenMM
>
(
1.0
/
_lastStepSize
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
velocities
[
i
][
j
]
=
velocityScale
*
(
xPrime
[
i
][
j
]
-
atomCoordinates
[
i
][
j
]);
atomCoordinates
[
i
][
j
]
=
xPrime
[
i
][
j
];
}
}
incrementTimeStep
();
return
ReferenceDynamics
::
DefaultReturn
;
}
platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.h
0 → 100644
View file @
09786e4b
/* Portions copyright (c) 2006-2009 Stanford University and Simbios.
* Contributors: Peter Eastman, Pande Group
*
* 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.
*/
#ifndef __ReferenceVariableVerletDynamics_H__
#define __ReferenceVariableVerletDynamics_H__
#include "ReferenceDynamics.h"
// ---------------------------------------------------------------------------------------
class
ReferenceVariableVerletDynamics
:
public
ReferenceDynamics
{
private:
enum
TwoDArrayIndicies
{
xPrime2D
,
vPrime2D
,
Max2DArrays
};
enum
OneDArrayIndicies
{
InverseMasses
,
Max1DArrays
};
RealOpenMM
_accuracy
,
_lastStepSize
;
public:
/**---------------------------------------------------------------------------------------
Constructor
@param numberOfAtoms number of atoms
@param deltaT initial delta t for dynamics
@param accuracy required accuracy
--------------------------------------------------------------------------------------- */
ReferenceVariableVerletDynamics
(
int
numberOfAtoms
,
RealOpenMM
deltaT
,
RealOpenMM
accuracy
);
/**---------------------------------------------------------------------------------------
Destructor
--------------------------------------------------------------------------------------- */
~
ReferenceVariableVerletDynamics
(
);
/**---------------------------------------------------------------------------------------
Get the required accuracy
@return accuracy
--------------------------------------------------------------------------------------- */
RealOpenMM
getAccuracy
(
void
)
const
;
/**---------------------------------------------------------------------------------------
Set the required accuracy
--------------------------------------------------------------------------------------- */
void
setAccuracy
(
RealOpenMM
accuracy
);
/**---------------------------------------------------------------------------------------
Get the actual size of the last step that was taken
@return step size
--------------------------------------------------------------------------------------- */
RealOpenMM
getLastStepSize
(
void
)
const
;
/**---------------------------------------------------------------------------------------
Print parameters
@param message message
@return ReferenceDynamics::DefaultReturn
--------------------------------------------------------------------------------------- */
int
printParameters
(
std
::
stringstream
&
message
)
const
;
/**---------------------------------------------------------------------------------------
Update
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param velocities velocities
@param forces forces
@param masses atom masses
@return ReferenceDynamics::DefaultReturn
--------------------------------------------------------------------------------------- */
int
update
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
velocities
,
RealOpenMM
**
forces
,
RealOpenMM
*
masses
);
};
// ---------------------------------------------------------------------------------------
#endif // __ReferenceVariableVerletDynamics_H__
platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp
0 → 100644
View file @
09786e4b
/* -------------------------------------------------------------------------- *
* 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) 2008-2009 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. *
* -------------------------------------------------------------------------- */
/**
* This tests the reference implementation of VariableVerletIntegrator.
*/
#include "../../../tests/AssertionUtilities.h"
#include "openmm/OpenMMContext.h"
#include "ReferencePlatform.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/VariableVerletIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
#include "../src/sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testSingleBond
()
{
ReferencePlatform
platform
;
System
system
;
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
VariableVerletIntegrator
integrator
(
0.01
,
1e-6
);
HarmonicBondForce
*
forceField
=
new
HarmonicBondForce
();
forceField
->
addBond
(
0
,
1
,
1.5
,
1
);
system
.
addForce
(
forceField
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
context
.
setPositions
(
positions
);
// This is simply a harmonic oscillator, so compare it to the analytical solution.
const
double
freq
=
1.0
;
State
state
=
context
.
getState
(
State
::
Energy
);
const
double
initialEnergy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
state
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Energy
);
double
time
=
state
.
getTime
();
double
expectedDist
=
1.5
+
0.5
*
std
::
cos
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
1
],
0.02
);
double
expectedSpeed
=
-
0.5
*
freq
*
std
::
sin
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
1
],
0.02
);
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.05
);
integrator
.
step
(
1
);
}
ASSERT
(
state
.
getTime
()
>
1.0
);
}
void
testConstraints
()
{
const
int
numParticles
=
8
;
const
double
temp
=
500.0
;
ReferencePlatform
platform
;
System
system
;
VariableVerletIntegrator
integrator
(
0.002
,
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
i
%
2
==
0
?
5.0
:
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
for
(
int
i
=
0
;
i
<
numParticles
-
1
;
++
i
)
system
.
addConstraint
(
i
,
i
+
1
,
1.0
);
system
.
addForce
(
forceField
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
vector
<
Vec3
>
velocities
(
numParticles
);
init_gen_rand
(
0
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
positions
[
i
]
=
Vec3
(
i
/
2
,
(
i
+
1
)
/
2
,
0
);
velocities
[
i
]
=
Vec3
(
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
);
}
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
double
initialEnergy
=
0.0
;
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Energy
);
for
(
int
j
=
0
;
j
<
system
.
getNumConstraints
();
++
j
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
j
,
particle1
,
particle2
,
distance
);
Vec3
p1
=
state
.
getPositions
()[
particle1
];
Vec3
p2
=
state
.
getPositions
()[
particle2
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
distance
,
dist
,
2e-5
);
}
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
if
(
i
==
1
)
initialEnergy
=
energy
;
else
if
(
i
>
1
)
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.1
);
integrator
.
step
(
1
);
}
ASSERT
(
context
.
getState
(
State
::
Positions
).
getTime
()
>
0.1
);
}
void
testConstrainedClusters
()
{
const
int
numParticles
=
7
;
const
double
temp
=
500.0
;
ReferencePlatform
platform
;
System
system
;
VariableVerletIntegrator
integrator
(
0.002
,
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
i
>
1
?
1.0
:
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
system
.
addConstraint
(
0
,
1
,
1.0
);
system
.
addConstraint
(
0
,
2
,
1.0
);
system
.
addConstraint
(
0
,
3
,
1.0
);
system
.
addConstraint
(
0
,
4
,
1.0
);
system
.
addConstraint
(
1
,
5
,
1.0
);
system
.
addConstraint
(
1
,
6
,
1.0
);
system
.
addConstraint
(
2
,
3
,
sqrt
(
2.0
));
system
.
addConstraint
(
2
,
4
,
sqrt
(
2.0
));
system
.
addConstraint
(
3
,
4
,
sqrt
(
2.0
));
system
.
addConstraint
(
5
,
6
,
sqrt
(
2.0
));
system
.
addForce
(
forceField
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
positions
[
2
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
3
]
=
Vec3
(
0
,
1
,
0
);
positions
[
4
]
=
Vec3
(
0
,
0
,
1
);
positions
[
5
]
=
Vec3
(
2
,
0
,
0
);
positions
[
6
]
=
Vec3
(
1
,
1
,
0
);
vector
<
Vec3
>
velocities
(
numParticles
);
init_gen_rand
(
0
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
velocities
[
i
]
=
Vec3
(
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
);
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
double
initialEnergy
=
0.0
;
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Energy
);
for
(
int
j
=
0
;
j
<
system
.
getNumConstraints
();
++
j
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
j
,
particle1
,
particle2
,
distance
);
Vec3
p1
=
state
.
getPositions
()[
particle1
];
Vec3
p2
=
state
.
getPositions
()[
particle2
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
distance
,
dist
,
2e-5
);
}
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
if
(
i
==
1
)
initialEnergy
=
energy
;
else
if
(
i
>
1
)
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.05
);
integrator
.
step
(
1
);
}
ASSERT
(
context
.
getState
(
State
::
Positions
).
getTime
()
>
0.1
);
}
int
main
()
{
try
{
testSingleBond
();
testConstraints
();
testConstrainedClusters
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment