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
c0ccf9e3
Commit
c0ccf9e3
authored
May 30, 2013
by
peastman
Browse files
Created API and reference implementation for ring polymer contraction
parent
178aa003
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
255 additions
and
24 deletions
+255
-24
plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h
plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h
+33
-1
plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp
plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp
+11
-3
plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp
...ins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp
+127
-19
plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.h
plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.h
+7
-1
plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp
plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp
+77
-0
No files found.
plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h
View file @
c0ccf9e3
...
@@ -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) 2008-201
2
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -37,6 +37,7 @@
...
@@ -37,6 +37,7 @@
#include "openmm/State.h"
#include "openmm/State.h"
#include "openmm/Vec3.h"
#include "openmm/Vec3.h"
#include "openmm/internal/windowsExportRpmd.h"
#include "openmm/internal/windowsExportRpmd.h"
#include <map>
namespace
OpenMM
{
namespace
OpenMM
{
...
@@ -52,6 +53,14 @@ namespace OpenMM {
...
@@ -52,6 +53,14 @@ namespace OpenMM {
* to set them for specific copies of the System. Similarly, you should retrieve state information
* to set them for specific copies of the System. Similarly, you should retrieve state information
* for particular copies by calling getState() on the Integrator. Do not query the Context for
* for particular copies by calling getState() on the Integrator. Do not query the Context for
* state information.
* state information.
*
* You can optionally specify a set of "ring polymer contractions", by which different force
* groups are evaluated on different numbers of copies, instead of computing every force on
* every copy. This can be much more efficient, since different forces may vary widely in
* how many times they must be evaluated to produce sufficient accuracy. For example, you
* might simulate a 32 copy ring polymer and evaluate bonded forces on every copy, but contract
* it down to only 6 copies for computing nonbonded interactions, and down to only a single
* copy (the centroid) for computing the reciprocal space part of PME.
*/
*/
class
OPENMM_EXPORT_RPMD
RPMDIntegrator
:
public
Integrator
{
class
OPENMM_EXPORT_RPMD
RPMDIntegrator
:
public
Integrator
{
...
@@ -65,6 +74,19 @@ public:
...
@@ -65,6 +74,19 @@ public:
* @param stepSize the step size with which to integrator the system (in picoseconds)
* @param stepSize the step size with which to integrator the system (in picoseconds)
*/
*/
RPMDIntegrator
(
int
numCopies
,
double
temperature
,
double
frictionCoeff
,
double
stepSize
);
RPMDIntegrator
(
int
numCopies
,
double
temperature
,
double
frictionCoeff
,
double
stepSize
);
/**
* Create a RPMDIntegrator.
*
* @param numCopies the number of copies of the system that should be simulated
* @param temperature the temperature of the heat bath (in Kelvin)
* @param frictionCoeff the friction coefficient which couples the system to the heat bath (in inverse picoseconds)
* @param stepSize the step size with which to integrator the system (in picoseconds)
* @param contractions the ring polymer contractions to use for evaluating different force groups. Each key in the
* map is the index of a force group, and the corresponding value is the number of copies to evaluate
* that force group on. If no entry is provided for a force group (the default), it is evaluated
* independently on every copy.
*/
RPMDIntegrator
(
int
numCopies
,
double
temperature
,
double
frictionCoeff
,
double
stepSize
,
const
std
::
map
<
int
,
int
>&
contractions
);
/**
/**
* Get the number of copies of the system being simulated.
* Get the number of copies of the system being simulated.
*/
*/
...
@@ -122,6 +144,15 @@ public:
...
@@ -122,6 +144,15 @@ public:
void
setRandomNumberSeed
(
int
seed
)
{
void
setRandomNumberSeed
(
int
seed
)
{
randomNumberSeed
=
seed
;
randomNumberSeed
=
seed
;
}
}
/**
* Get the ring polymer contractions to use for evaluating different force groups. Each key in the
* map is the index of a force group, and the corresponding value is the number of copies to evaluate
* that force group on. If no entry is provided for a force group, it is evaluated independently on
* every copy.
*/
const
std
::
map
<
int
,
int
>&
getContractions
()
const
{
return
contractions
;
}
/**
/**
* Set the positions of all particles in one copy of the system.
* Set the positions of all particles in one copy of the system.
*
*
...
@@ -182,6 +213,7 @@ protected:
...
@@ -182,6 +213,7 @@ protected:
private:
private:
double
temperature
,
friction
;
double
temperature
,
friction
;
int
numCopies
,
randomNumberSeed
;
int
numCopies
,
randomNumberSeed
;
std
::
map
<
int
,
int
>
contractions
;
bool
forcesAreValid
,
hasSetPosition
,
hasSetVelocity
,
isFirstStep
;
bool
forcesAreValid
,
hasSetPosition
,
hasSetVelocity
,
isFirstStep
;
Kernel
kernel
;
Kernel
kernel
;
};
};
...
...
plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp
View file @
c0ccf9e3
...
@@ -39,15 +39,23 @@
...
@@ -39,15 +39,23 @@
#include <string>
#include <string>
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
std
::
string
;
using
namespace
std
;
using
std
::
vector
;
RPMDIntegrator
::
RPMDIntegrator
(
int
numCopies
,
double
temperature
,
double
frictionCoeff
,
double
stepSize
,
const
map
<
int
,
int
>&
contractions
)
:
numCopies
(
numCopies
),
contractions
(
contractions
),
forcesAreValid
(
false
),
hasSetPosition
(
false
),
hasSetVelocity
(
false
),
isFirstStep
(
true
)
{
setTemperature
(
temperature
);
setFriction
(
frictionCoeff
);
setStepSize
(
stepSize
);
setConstraintTolerance
(
1e-5
);
setRandomNumberSeed
((
int
)
time
(
NULL
));
}
RPMDIntegrator
::
RPMDIntegrator
(
int
numCopies
,
double
temperature
,
double
frictionCoeff
,
double
stepSize
)
:
RPMDIntegrator
::
RPMDIntegrator
(
int
numCopies
,
double
temperature
,
double
frictionCoeff
,
double
stepSize
)
:
numCopies
(
numCopies
),
forcesAreValid
(
false
),
hasSetPosition
(
false
),
hasSetVelocity
(
false
),
isFirstStep
(
true
)
{
numCopies
(
numCopies
),
forcesAreValid
(
false
),
hasSetPosition
(
false
),
hasSetVelocity
(
false
),
isFirstStep
(
true
)
{
setTemperature
(
temperature
);
setTemperature
(
temperature
);
setFriction
(
frictionCoeff
);
setFriction
(
frictionCoeff
);
setStepSize
(
stepSize
);
setStepSize
(
stepSize
);
setConstraintTolerance
(
1e-
4
);
setConstraintTolerance
(
1e-
5
);
setRandomNumberSeed
((
int
)
time
(
NULL
));
setRandomNumberSeed
((
int
)
time
(
NULL
));
}
}
...
...
plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp
View file @
c0ccf9e3
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
#include "ReferenceRpmdKernels.h"
#include "ReferenceRpmdKernels.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "SimTKUtilities/SimTKOpenMMUtilities.h"
#include "SimTKUtilities/SimTKOpenMMUtilities.h"
...
@@ -54,7 +55,11 @@ static vector<RealVec>& extractForces(ContextImpl& context) {
...
@@ -54,7 +55,11 @@ static vector<RealVec>& extractForces(ContextImpl& context) {
ReferenceIntegrateRPMDStepKernel
::~
ReferenceIntegrateRPMDStepKernel
()
{
ReferenceIntegrateRPMDStepKernel
::~
ReferenceIntegrateRPMDStepKernel
()
{
if
(
fft
!=
NULL
)
if
(
fft
!=
NULL
)
fftpack_destroy
(
fft
);
fftpack_destroy
(
fft
);
for
(
map
<
int
,
fftpack
*>::
const_iterator
iter
=
contractionFFT
.
begin
();
iter
!=
contractionFFT
.
end
();
++
iter
)
if
(
iter
->
second
!=
NULL
)
fftpack_destroy
(
iter
->
second
);
}
}
void
ReferenceIntegrateRPMDStepKernel
::
initialize
(
const
System
&
system
,
const
RPMDIntegrator
&
integrator
)
{
void
ReferenceIntegrateRPMDStepKernel
::
initialize
(
const
System
&
system
,
const
RPMDIntegrator
&
integrator
)
{
int
numCopies
=
integrator
.
getNumCopies
();
int
numCopies
=
integrator
.
getNumCopies
();
int
numParticles
=
system
.
getNumParticles
();
int
numParticles
=
system
.
getNumParticles
();
...
@@ -68,6 +73,41 @@ void ReferenceIntegrateRPMDStepKernel::initialize(const System& system, const RP
...
@@ -68,6 +73,41 @@ void ReferenceIntegrateRPMDStepKernel::initialize(const System& system, const RP
}
}
fftpack_init_1d
(
&
fft
,
numCopies
);
fftpack_init_1d
(
&
fft
,
numCopies
);
SimTKOpenMMUtilities
::
setRandomNumberSeed
((
unsigned
int
)
integrator
.
getRandomNumberSeed
());
SimTKOpenMMUtilities
::
setRandomNumberSeed
((
unsigned
int
)
integrator
.
getRandomNumberSeed
());
// Build a list of contractions.
groupsNotContracted
=
-
1
;
const
map
<
int
,
int
>&
contractions
=
integrator
.
getContractions
();
int
maxContractedCopies
=
0
;
for
(
map
<
int
,
int
>::
const_iterator
iter
=
contractions
.
begin
();
iter
!=
contractions
.
end
();
++
iter
)
{
int
group
=
iter
->
first
;
int
copies
=
iter
->
second
;
if
(
group
<
0
||
group
>
31
)
throw
OpenMMException
(
"RPMDIntegrator: Force group must be between 0 and 31"
);
if
(
copies
<
0
||
copies
>
numCopies
)
throw
OpenMMException
(
"RPMDIntegrator: Number of copies for contraction cannot be greater than the total number of copies being simulated"
);
if
(
copies
!=
numCopies
)
{
if
(
groupsByCopies
.
find
(
copies
)
==
groupsByCopies
.
end
())
{
groupsByCopies
[
copies
]
=
1
<<
group
;
groupsNotContracted
-=
1
<<
group
;
contractionFFT
[
copies
]
=
NULL
;
fftpack_init_1d
(
&
contractionFFT
[
copies
],
copies
);
if
(
copies
>
maxContractedCopies
)
maxContractedCopies
=
copies
;
}
else
groupsByCopies
[
copies
]
|=
1
<<
group
;
}
}
// Create workspace for doing contractions.
contractedPositions
.
resize
(
maxContractedCopies
);
contractedForces
.
resize
(
maxContractedCopies
);
for
(
int
i
=
0
;
i
<
maxContractedCopies
;
i
++
)
{
contractedPositions
[
i
].
resize
(
numParticles
);
contractedForces
[
i
].
resize
(
numParticles
);
}
}
}
void
ReferenceIntegrateRPMDStepKernel
::
execute
(
ContextImpl
&
context
,
const
RPMDIntegrator
&
integrator
,
bool
forcesAreValid
)
{
void
ReferenceIntegrateRPMDStepKernel
::
execute
(
ContextImpl
&
context
,
const
RPMDIntegrator
&
integrator
,
bool
forcesAreValid
)
{
...
@@ -82,15 +122,8 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
...
@@ -82,15 +122,8 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
// Loop over copies and compute the force on each one.
// Loop over copies and compute the force on each one.
if
(
!
forcesAreValid
)
{
if
(
!
forcesAreValid
)
for
(
int
i
=
0
;
i
<
numCopies
;
i
++
)
{
computeForces
(
context
,
integrator
);
pos
=
positions
[
i
];
vel
=
velocities
[
i
];
context
.
computeVirtualSites
();
context
.
calcForcesAndEnergy
(
true
,
false
);
forces
[
i
]
=
f
;
}
}
// Apply the PILE-L thermostat.
// Apply the PILE-L thermostat.
...
@@ -176,16 +209,7 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
...
@@ -176,16 +209,7 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
// Calculate forces based on the updated positions.
// Calculate forces based on the updated positions.
for
(
int
i
=
0
;
i
<
numCopies
;
i
++
)
{
computeForces
(
context
,
integrator
);
pos
=
positions
[
i
];
vel
=
velocities
[
i
];
context
.
computeVirtualSites
();
context
.
updateContextState
();
positions
[
i
]
=
pos
;
velocities
[
i
]
=
vel
;
context
.
calcForcesAndEnergy
(
true
,
false
);
forces
[
i
]
=
f
;
}
// Update velocities.
// Update velocities.
...
@@ -234,6 +258,90 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
...
@@ -234,6 +258,90 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
context
.
setTime
(
context
.
getTime
()
+
dt
);
context
.
setTime
(
context
.
getTime
()
+
dt
);
}
}
void
ReferenceIntegrateRPMDStepKernel
::
computeForces
(
ContextImpl
&
context
,
const
RPMDIntegrator
&
integrator
)
{
const
int
totalCopies
=
positions
.
size
();
const
int
numParticles
=
positions
[
0
].
size
();
vector
<
RealVec
>&
pos
=
extractPositions
(
context
);
vector
<
RealVec
>&
vel
=
extractVelocities
(
context
);
vector
<
RealVec
>&
f
=
extractForces
(
context
);
// Compute forces from all groups that didn't have a specified contraction.
for
(
int
i
=
0
;
i
<
totalCopies
;
i
++
)
{
pos
=
positions
[
i
];
vel
=
velocities
[
i
];
context
.
computeVirtualSites
();
context
.
updateContextState
();
positions
[
i
]
=
pos
;
velocities
[
i
]
=
vel
;
context
.
calcForcesAndEnergy
(
true
,
false
,
groupsNotContracted
);
forces
[
i
]
=
f
;
}
// Now loop over contractions and compute forces from them.
for
(
map
<
int
,
int
>::
const_iterator
iter
=
groupsByCopies
.
begin
();
iter
!=
groupsByCopies
.
end
();
++
iter
)
{
int
copies
=
iter
->
first
;
int
groupFlags
=
iter
->
second
;
fftpack
*
shortFFT
=
contractionFFT
[
copies
];
// Find the contracted positions.
vector
<
t_complex
>
q
(
totalCopies
);
const
RealOpenMM
scale1
=
1.0
/
totalCopies
;
for
(
int
particle
=
0
;
particle
<
numParticles
;
particle
++
)
{
for
(
int
component
=
0
;
component
<
3
;
component
++
)
{
// Transform to the frequency domain, set high frequency components to zero, and transform back.
for
(
int
k
=
0
;
k
<
totalCopies
;
k
++
)
q
[
k
]
=
t_complex
(
positions
[
k
][
particle
][
component
],
0.0
);
fftpack_exec_1d
(
fft
,
FFTPACK_FORWARD
,
&
q
[
0
],
&
q
[
0
]);
if
(
copies
>
1
)
{
int
start
=
(
copies
+
1
)
/
2
;
int
end
=
totalCopies
-
copies
+
start
;
for
(
int
k
=
end
;
k
<
totalCopies
;
k
++
)
q
[
k
-
(
totalCopies
-
copies
)]
=
q
[
k
];
fftpack_exec_1d
(
shortFFT
,
FFTPACK_BACKWARD
,
&
q
[
0
],
&
q
[
0
]);
}
for
(
int
k
=
0
;
k
<
copies
;
k
++
)
contractedPositions
[
k
][
particle
][
component
]
=
scale1
*
q
[
k
].
re
;
}
}
// Compute forces.
for
(
int
i
=
0
;
i
<
copies
;
i
++
)
{
pos
=
contractedPositions
[
i
];
context
.
computeVirtualSites
();
context
.
calcForcesAndEnergy
(
true
,
false
,
groupFlags
);
contractedForces
[
i
]
=
f
;
}
// Apply the forces to the original copies.
const
RealOpenMM
scale2
=
1.0
/
copies
;
for
(
int
particle
=
0
;
particle
<
numParticles
;
particle
++
)
{
for
(
int
component
=
0
;
component
<
3
;
component
++
)
{
// Transform to the frequency domain, pad with zeros, and transform back.
for
(
int
k
=
0
;
k
<
copies
;
k
++
)
q
[
k
]
=
t_complex
(
contractedForces
[
k
][
particle
][
component
],
0.0
);
if
(
copies
>
1
)
fftpack_exec_1d
(
shortFFT
,
FFTPACK_FORWARD
,
&
q
[
0
],
&
q
[
0
]);
int
start
=
(
copies
+
1
)
/
2
;
int
end
=
totalCopies
-
copies
+
start
;
for
(
int
k
=
end
;
k
<
totalCopies
;
k
++
)
q
[
k
]
=
q
[
k
-
(
totalCopies
-
copies
)];
for
(
int
k
=
start
;
k
<
end
;
k
++
)
q
[
k
]
=
t_complex
(
0
,
0
);
fftpack_exec_1d
(
fft
,
FFTPACK_BACKWARD
,
&
q
[
0
],
&
q
[
0
]);
for
(
int
k
=
0
;
k
<
totalCopies
;
k
++
)
forces
[
k
][
particle
][
component
]
=
scale2
*
q
[
k
].
re
;
}
}
}
}
double
ReferenceIntegrateRPMDStepKernel
::
computeKineticEnergy
(
ContextImpl
&
context
,
const
RPMDIntegrator
&
integrator
)
{
double
ReferenceIntegrateRPMDStepKernel
::
computeKineticEnergy
(
ContextImpl
&
context
,
const
RPMDIntegrator
&
integrator
)
{
const
System
&
system
=
context
.
getSystem
();
const
System
&
system
=
context
.
getSystem
();
int
numParticles
=
system
.
getNumParticles
();
int
numParticles
=
system
.
getNumParticles
();
...
...
plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.h
View file @
c0ccf9e3
...
@@ -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) 2011 Stanford University and the Authors.
*
* Portions copyright (c) 2011
-2013
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -85,10 +85,16 @@ public:
...
@@ -85,10 +85,16 @@ public:
*/
*/
void
copyToContext
(
int
copy
,
ContextImpl
&
context
);
void
copyToContext
(
int
copy
,
ContextImpl
&
context
);
private:
private:
void
computeForces
(
ContextImpl
&
context
,
const
RPMDIntegrator
&
integrator
);
std
::
vector
<
std
::
vector
<
RealVec
>
>
positions
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
positions
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
velocities
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
velocities
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
forces
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
forces
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
contractedPositions
;
std
::
vector
<
std
::
vector
<
RealVec
>
>
contractedForces
;
std
::
map
<
int
,
int
>
groupsByCopies
;
int
groupsNotContracted
;
fftpack
*
fft
;
fftpack
*
fft
;
std
::
map
<
int
,
fftpack
*>
contractionFFT
;
};
};
}
// namespace OpenMM
}
// namespace OpenMM
...
...
plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp
View file @
c0ccf9e3
...
@@ -237,11 +237,88 @@ void testVirtualSites() {
...
@@ -237,11 +237,88 @@ void testVirtualSites() {
ASSERT_USUALLY_EQUAL_TOL
(
expectedKE
,
meanKE
,
1e-2
);
ASSERT_USUALLY_EQUAL_TOL
(
expectedKE
,
meanKE
,
1e-2
);
}
}
void
testContractions
()
{
const
int
gridSize
=
3
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
int
numParticles
=
numMolecules
*
2
;
const
int
numCopies
=
10
;
const
double
spacing
=
2.0
;
const
double
cutoff
=
3.0
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
HarmonicBondForce
*
bonds
=
new
HarmonicBondForce
();
system
.
addForce
(
bonds
);
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
nonbonded
->
setForceGroup
(
1
);
nonbonded
->
setReciprocalSpaceForceGroup
(
2
);
system
.
addForce
(
nonbonded
);
// Create a cloud of molecules.
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
nonbonded
->
addParticle
(
-
0.2
,
0.2
,
0.2
);
nonbonded
->
addParticle
(
0.2
,
0.2
,
0.2
);
nonbonded
->
addException
(
2
*
i
,
2
*
i
+
1
,
0
,
1
,
0
);
bonds
->
addBond
(
2
*
i
,
2
*
i
+
1
,
1.0
,
10000.0
);
}
map
<
int
,
int
>
contractions
;
contractions
[
1
]
=
3
;
contractions
[
2
]
=
1
;
RPMDIntegrator
integ
(
numCopies
,
temperature
,
10.0
,
0.001
,
contractions
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
for
(
int
copy
=
0
;
copy
<
numCopies
;
copy
++
)
{
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
=
Vec3
(
spacing
*
(
i
+
0.02
*
genrand_real2
(
sfmt
)),
spacing
*
(
j
+
0.02
*
genrand_real2
(
sfmt
)),
spacing
*
(
k
+
0.02
*
genrand_real2
(
sfmt
)));
int
index
=
k
+
gridSize
*
(
j
+
gridSize
*
i
);
positions
[
2
*
index
]
=
pos
;
positions
[
2
*
index
+
1
]
=
Vec3
(
pos
[
0
]
+
1.0
,
pos
[
1
],
pos
[
2
]);
}
integ
.
setPositions
(
copy
,
positions
);
}
// Check the temperature.
const
int
numSteps
=
1000
;
integ
.
step
(
1000
);
vector
<
double
>
ke
(
numCopies
,
0.0
);
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
vector
<
State
>
state
(
numCopies
);
for
(
int
j
=
0
;
j
<
numCopies
;
j
++
)
state
[
j
]
=
integ
.
getState
(
j
,
State
::
Velocities
,
true
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
{
for
(
int
k
=
0
;
k
<
numCopies
;
k
++
)
{
Vec3
v
=
state
[
k
].
getVelocities
()[
j
];
ke
[
k
]
+=
0.5
*
system
.
getParticleMass
(
j
)
*
v
.
dot
(
v
);
}
}
}
double
meanKE
=
0.0
;
for
(
int
i
=
0
;
i
<
numCopies
;
i
++
)
meanKE
+=
ke
[
i
];
meanKE
/=
numSteps
*
numCopies
;
double
expectedKE
=
0.5
*
numCopies
*
numParticles
*
3
*
BOLTZ
*
temperature
;
ASSERT_USUALLY_EQUAL_TOL
(
expectedKE
,
meanKE
,
1e-2
);
}
int
main
()
{
int
main
()
{
try
{
try
{
testFreeParticles
();
testFreeParticles
();
testCMMotionRemoval
();
testCMMotionRemoval
();
testVirtualSites
();
testVirtualSites
();
testContractions
();
}
}
catch
(
const
std
::
exception
&
e
)
{
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
...
...
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