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
c5c0348a
Unverified
Commit
c5c0348a
authored
Mar 11, 2020
by
peastman
Committed by
GitHub
Mar 11, 2020
Browse files
Merge pull request #2518 from andysim/inittemp
Modify temperature initialization mechanism
parents
ef02e48d
58d2619e
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1063 additions
and
1139 deletions
+1063
-1139
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp
...ins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp
+3
-181
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
...tforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
+4
-227
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp
...rude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp
+2
-27
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp
...e/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp
+3
-112
plugins/drude/platforms/reference/tests/CMakeLists.txt
plugins/drude/platforms/reference/tests/CMakeLists.txt
+1
-0
plugins/drude/platforms/reference/tests/ReferenceDrudeTests.h
...ins/drude/platforms/reference/tests/ReferenceDrudeTests.h
+42
-0
plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp
...ude/platforms/reference/tests/TestReferenceDrudeForce.cpp
+3
-181
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
.../reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
+4
-225
plugins/drude/platforms/reference/tests/TestReferenceDrudeNoseHoover.cpp
...latforms/reference/tests/TestReferenceDrudeNoseHoover.cpp
+2
-17
plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp
...forms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp
+3
-109
plugins/drude/tests/TestDrudeForce.h
plugins/drude/tests/TestDrudeForce.h
+218
-0
plugins/drude/tests/TestDrudeLangevinIntegrator.h
plugins/drude/tests/TestDrudeLangevinIntegrator.h
+307
-0
plugins/drude/tests/TestDrudeNoseHoover.h
plugins/drude/tests/TestDrudeNoseHoover.h
+88
-60
plugins/drude/tests/TestDrudeSCFIntegrator.h
plugins/drude/tests/TestDrudeSCFIntegrator.h
+209
-0
tests/TestBrownianIntegrator.h
tests/TestBrownianIntegrator.h
+29
-0
tests/TestCustomIntegrator.h
tests/TestCustomIntegrator.h
+29
-0
tests/TestLangevinIntegrator.h
tests/TestLangevinIntegrator.h
+29
-0
tests/TestLangevinMiddleIntegrator.h
tests/TestLangevinMiddleIntegrator.h
+29
-0
tests/TestNoseHooverIntegrator.h
tests/TestNoseHooverIntegrator.h
+29
-0
tests/TestVariableLangevinIntegrator.h
tests/TestVariableLangevinIntegrator.h
+29
-0
No files found.
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp
View file @
c5c0348a
...
@@ -29,185 +29,7 @@
...
@@ -29,185 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "OpenCLDrudeTests.h"
* This tests the OpenCL implementation of DrudeForce.
#include "TestDrudeForce.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{}
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/DrudeForce.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
void
registerDrudeOpenCLKernelFactories
();
void
validateForce
(
System
&
system
,
vector
<
Vec3
>&
positions
,
double
expectedEnergy
)
{
// Given a System containing a Drude force, check that its energy has the expected value.
VerletIntegrator
integ
(
1.0
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
);
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-5
);
// Try moving each particle along each axis, and see if the energy changes by the correct amount.
double
offset
=
1e-2
;
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
vector
<
Vec3
>
offsetPos
=
positions
;
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
-
offset
;
context
.
setPositions
(
offsetPos
);
double
e1
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
+
offset
;
context
.
setPositions
(
offsetPos
);
double
e2
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
state
.
getForces
()[
i
][
j
],
(
e1
-
e2
)
/
(
2
*
offset
),
1e-3
);
}
}
void
testSingleParticle
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
validateForce
(
system
,
positions
,
0.5
*
k
*
3
*
3
);
}
void
testAnisotropicParticle
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
a1
=
0.8
;
const
double
a2
=
1.1
;
const
double
k1
=
k
/
a1
;
const
double
k2
=
k
/
a2
;
const
double
k3
=
k
/
(
3
-
a1
-
a2
);
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
2
,
3
,
4
,
charge
,
alpha
,
a1
,
a2
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
5
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0.1
,
-
0.5
,
0.8
);
positions
[
2
]
=
Vec3
(
0
,
2
,
0
);
positions
[
3
]
=
Vec3
(
1
,
2
,
0
);
positions
[
4
]
=
Vec3
(
1
,
2
,
3
);
validateForce
(
system
,
positions
,
0.5
*
k1
*
0.5
*
0.5
+
0.5
*
k2
*
0.8
*
0.8
+
0.5
*
k3
*
0.1
*
0.1
);
}
double
computeScreening
(
double
r
,
double
thole
,
double
alpha1
,
double
alpha2
)
{
double
u
=
r
*
thole
/
pow
(
alpha1
*
alpha2
,
1.0
/
6.0
);
return
1.0
-
(
1.0
+
u
/
2
)
*
exp
(
-
u
);
}
void
testThole
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
thole
=
2.5
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
drude
->
addParticle
(
3
,
2
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
drude
->
addScreenedPair
(
0
,
1
,
thole
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
4
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
-
0.5
,
0
);
positions
[
2
]
=
Vec3
(
1
,
0
,
0
);
positions
[
3
]
=
Vec3
(
1
,
0
,
0.3
);
double
energySpring1
=
0.5
*
k
*
0.5
*
0.5
;
double
energySpring2
=
0.5
*
k
*
0.3
*
0.3
;
double
energyDipole
=
0.0
;
double
q
[]
=
{
-
charge
,
charge
,
-
charge
,
charge
};
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
j
=
2
;
j
<
4
;
j
++
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
j
];
double
r
=
sqrt
(
delta
.
dot
(
delta
));
energyDipole
+=
ONE_4PI_EPS0
*
q
[
i
]
*
q
[
j
]
*
computeScreening
(
r
,
thole
,
alpha
,
alpha
)
/
r
;
}
validateForce
(
system
,
positions
,
energySpring1
+
energySpring2
+
energyDipole
);
}
void
testChangingParameters
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
// Create the system.
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
// Check the energy.
VerletIntegrator
integ
(
1.0
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.5
*
k
*
3
*
3
,
state
.
getPotentialEnergy
(),
1e-5
);
// Modify the parameters.
const
double
k2
=
ONE_4PI_EPS0
*
2.2
;
const
double
charge2
=
0.3
;
const
double
alpha2
=
ONE_4PI_EPS0
*
charge2
*
charge2
/
k2
;
drude
->
setParticleParameters
(
0
,
1
,
0
,
-
1
,
-
1
,
-
1
,
charge2
,
alpha2
,
1
,
1
);
drude
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.5
*
k2
*
3
*
3
,
state
.
getPotentialEnergy
(),
1e-5
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
registerDrudeOpenCLKernelFactories
();
if
(
argc
>
1
)
Platform
::
getPlatformByName
(
"OpenCL"
).
setPropertyDefaultValue
(
"Precision"
,
std
::
string
(
argv
[
1
]));
testSingleParticle
();
testAnisotropicParticle
();
testThole
();
testChangingParameters
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
View file @
c5c0348a
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2013
-2016
Stanford University and the Authors. *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -29,230 +29,7 @@
...
@@ -29,230 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "OpenCLDrudeTests.h"
* This tests the OpenCL implementation of DrudeLangevinIntegrator.
#include "TestDrudeLangevinIntegrator.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{}
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VirtualSite.h"
#include "openmm/DrudeForce.h"
#include "openmm/DrudeLangevinIntegrator.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeOpenCLKernelFactories
();
void
testSinglePair
()
{
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
mass1
=
1.0
;
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
const
double
reducedMass
=
(
mass1
*
mass2
)
/
(
mass1
+
mass2
);
const
double
maxDistance
=
0.05
;
System
system
;
system
.
addParticle
(
mass1
);
system
.
addParticle
(
mass2
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
0
,
0
);
DrudeLangevinIntegrator
integ
(
temperature
,
20.0
,
temperatureDrude
,
20.0
,
0.003
);
integ
.
setMaxDrudeDistance
(
maxDistance
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
// Equilibrate.
integ
.
step
(
1000
);
// Compute the internal and center of mass temperatures.
double
keCM
=
0
,
keInternal
=
0
;
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
10
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
const
vector
<
Vec3
>&
vel
=
state
.
getVelocities
();
Vec3
velCM
=
vel
[
0
]
*
(
mass1
/
totalMass
)
+
vel
[
1
]
*
(
mass2
/
totalMass
);
keCM
+=
0.5
*
totalMass
*
velCM
.
dot
(
velCM
);
Vec3
velInternal
=
vel
[
0
]
-
vel
[
1
];
keInternal
+=
0.5
*
reducedMass
*
velInternal
.
dot
(
velInternal
);
Vec3
delta
=
state
.
getPositions
()[
0
]
-
state
.
getPositions
()[
1
];
double
distance
=
sqrt
(
delta
.
dot
(
delta
));
ASSERT
(
distance
<=
maxDistance
*
(
1
+
1e-6
));
}
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperature
,
keCM
/
numSteps
,
0.1
);
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperatureDrude
,
keInternal
/
numSteps
,
0.01
);
}
void
testWater
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
gridSize
=
4
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.0
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
// Simulate it and check the temperature.
DrudeLangevinIntegrator
integ
(
temperature
,
50.0
,
temperatureDrude
,
50.0
,
0.0005
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
1e-5
);
// Equilibrate.
integ
.
step
(
1000
);
// Compute the internal and center of mass temperatures.
double
ke
=
0
;
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
ke
+=
context
.
getState
(
State
::
Energy
).
getKineticEnergy
();
}
ke
/=
numSteps
;
int
numStandardDof
=
3
*
3
*
numMolecules
-
system
.
getNumConstraints
();
int
numDrudeDof
=
3
*
numMolecules
;
int
numDof
=
numStandardDof
+
numDrudeDof
;
double
expectedTemp
=
(
numStandardDof
*
temperature
+
numDrudeDof
*
temperatureDrude
)
/
numDof
;
ASSERT_USUALLY_EQUAL_TOL
(
expectedTemp
,
ke
/
(
0.5
*
numDof
*
BOLTZ
),
0.02
);
}
void
testForceEnergyConsistency
()
{
// Create a box of polarizable particles.
const
int
gridSize
=
3
;
const
int
numAtoms
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
System
system
;
vector
<
Vec3
>
positions
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
nonbonded
->
setCutoffDistance
(
1.0
);
nonbonded
->
setUseSwitchingFunction
(
true
);
nonbonded
->
setSwitchingDistance
(
0.9
);
nonbonded
->
setEwaldErrorTolerance
(
5e-5
);
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
nonbonded
->
addParticle
(
1.0
,
0.3
,
1.0
);
nonbonded
->
addParticle
(
-
1.0
,
0.3
,
1.0
);
nonbonded
->
addException
(
startIndex
,
startIndex
+
1
,
0
,
1
,
0
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.0
,
0.001
,
1
,
1
);
}
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
}
// Simulate it and check that force and energy remain consistent.
DrudeLangevinIntegrator
integ
(
temperature
,
50.0
,
temperatureDrude
,
50.0
,
0.001
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
prevState
;
for
(
int
i
=
0
;
i
<
100
;
i
++
)
{
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
|
State
::
Positions
);
if
(
i
>
0
)
{
double
expectedEnergyChange
=
0
;
for
(
int
j
=
0
;
j
<
system
.
getNumParticles
();
j
++
)
{
Vec3
delta
=
state
.
getPositions
()[
j
]
-
prevState
.
getPositions
()[
j
];
expectedEnergyChange
-=
0.5
*
(
state
.
getForces
()[
j
]
+
prevState
.
getForces
()[
j
]).
dot
(
delta
);
}
ASSERT_EQUAL_TOL
(
expectedEnergyChange
,
state
.
getPotentialEnergy
()
-
prevState
.
getPotentialEnergy
(),
0.05
);
}
prevState
=
state
;
integ
.
step
(
1
);
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
registerDrudeOpenCLKernelFactories
();
if
(
argc
>
1
)
Platform
::
getPlatformByName
(
"OpenCL"
).
setPropertyDefaultValue
(
"Precision"
,
string
(
argv
[
1
]));
testSinglePair
();
testWater
();
testForceEnergyConsistency
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp
View file @
c5c0348a
...
@@ -29,32 +29,7 @@
...
@@ -29,32 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
//#include "ReferenceTests.h"
#include "OpenCLDrudeTests.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/DrudeForce.h"
#include "OpenCLPlatform.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeOpenCLKernelFactories
();
void
runPlatformTests
()
{
}
#include "TestDrudeNoseHoover.h"
#include "TestDrudeNoseHoover.h"
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[])
{
void
runPlatformTests
()
{}
registerDrudeOpenCLKernelFactories
();
if
(
argc
>
1
)
Platform
::
getPlatformByName
(
"OpenCL"
).
setPropertyDefaultValue
(
"Precision"
,
std
::
string
(
argv
[
1
]));
return
Platform
::
getPlatformByName
(
"OpenCL"
);
}
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp
View file @
c5c0348a
...
@@ -29,116 +29,7 @@
...
@@ -29,116 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "OpenCLDrudeTests.h"
* This tests the OpenCL implementation of DrudeSCFIntegrator.
#include "TestDrudeSCFIntegrator.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{}
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VirtualSite.h"
#include "openmm/DrudeForce.h"
#include "openmm/DrudeSCFIntegrator.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeOpenCLKernelFactories
();
void
testWater
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
gridSize
=
4
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.0
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
// Simulate it and check energy conservation and the total force on the Drude particles.
DrudeSCFIntegrator
integ
(
0.0005
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
1e-5
);
context
.
setVelocitiesToTemperature
(
300.0
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
initialEnergy
;
int
numSteps
=
1000
;
double
maxNorm
=
(
platform
.
getPropertyValue
(
context
,
"Precision"
)
==
"double"
?
1.0
:
5.0
);
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
);
if
(
i
==
0
)
initialEnergy
=
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
();
else
ASSERT_EQUAL_TOL
(
initialEnergy
,
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
(),
0.01
);
const
vector
<
Vec3
>&
force
=
state
.
getForces
();
double
norm
=
0.0
;
for
(
int
j
=
1
;
j
<
(
int
)
force
.
size
();
j
+=
5
)
norm
+=
sqrt
(
force
[
j
].
dot
(
force
[
j
]));
norm
=
(
norm
/
numMolecules
);
ASSERT
(
norm
<
maxNorm
);
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
registerDrudeOpenCLKernelFactories
();
if
(
argc
>
1
)
Platform
::
getPlatformByName
(
"OpenCL"
).
setPropertyDefaultValue
(
"Precision"
,
string
(
argv
[
1
]));
testWater
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/platforms/reference/tests/CMakeLists.txt
View file @
c5c0348a
...
@@ -5,6 +5,7 @@ ENABLE_TESTING()
...
@@ -5,6 +5,7 @@ ENABLE_TESTING()
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/include
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/include
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/openmmapi/include/openmm
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/openmmapi/include/openmm
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/src
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/src
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/tests
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/plugins/drude/tests
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/plugins/drude/tests
)
SET
(
SHARED_OPENMM_DRUDE_TARGET OpenMMDrude
)
SET
(
SHARED_OPENMM_DRUDE_TARGET OpenMMDrude
)
...
...
plugins/drude/platforms/reference/tests/ReferenceDrudeTests.h
0 → 100644
View file @
c5c0348a
/* -------------------------------------------------------------------------- *
* 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) 2013 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"
extern
"C"
void
registerDrudeReferenceKernelFactories
();
using
namespace
OpenMM
;
void
setupKernels
(
int
argc
,
char
*
argv
[])
{
registerDrudeReferenceKernelFactories
();
platform
=
dynamic_cast
<
ReferencePlatform
&>
(
Platform
::
getPlatformByName
(
"Reference"
));
initializeTests
(
argc
,
argv
);
}
plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp
View file @
c5c0348a
...
@@ -29,185 +29,7 @@
...
@@ -29,185 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "ReferenceDrudeTests.h"
* This tests the Reference implementation of DrudeForce.
#include "TestDrudeForce.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{}
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/DrudeForce.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeReferenceKernelFactories
();
void
validateForce
(
System
&
system
,
vector
<
Vec3
>&
positions
,
double
expectedEnergy
)
{
// Given a System containing a Drude force, check that its energy has the expected value.
VerletIntegrator
integ
(
1.0
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
);
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-5
);
// Try moving each particle along each axis, and see if the energy changes by the correct amount.
double
offset
=
1e-3
;
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
vector
<
Vec3
>
offsetPos
=
positions
;
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
-
offset
;
context
.
setPositions
(
offsetPos
);
double
e1
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
+
offset
;
context
.
setPositions
(
offsetPos
);
double
e2
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
state
.
getForces
()[
i
][
j
],
(
e1
-
e2
)
/
(
2
*
offset
),
1e-5
);
}
}
void
testSingleParticle
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
ASSERT
(
!
drude
->
usesPeriodicBoundaryConditions
());
ASSERT
(
!
system
.
usesPeriodicBoundaryConditions
());
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
validateForce
(
system
,
positions
,
0.5
*
k
*
3
*
3
);
}
void
testAnisotropicParticle
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
a1
=
0.8
;
const
double
a2
=
1.1
;
const
double
k1
=
k
/
a1
;
const
double
k2
=
k
/
a2
;
const
double
k3
=
k
/
(
3
-
a1
-
a2
);
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
2
,
3
,
4
,
charge
,
alpha
,
a1
,
a2
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
5
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0.1
,
-
0.5
,
0.8
);
positions
[
2
]
=
Vec3
(
0
,
2
,
0
);
positions
[
3
]
=
Vec3
(
1
,
2
,
0
);
positions
[
4
]
=
Vec3
(
1
,
2
,
3
);
validateForce
(
system
,
positions
,
0.5
*
k1
*
0.5
*
0.5
+
0.5
*
k2
*
0.8
*
0.8
+
0.5
*
k3
*
0.1
*
0.1
);
}
double
computeScreening
(
double
r
,
double
thole
,
double
alpha1
,
double
alpha2
)
{
double
u
=
r
*
thole
/
pow
(
alpha1
*
alpha2
,
1.0
/
6.0
);
return
1.0
-
(
1.0
+
u
/
2
)
*
exp
(
-
u
);
}
void
testThole
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
thole
=
2.5
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
drude
->
addParticle
(
3
,
2
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
drude
->
addScreenedPair
(
0
,
1
,
thole
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
4
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
-
0.5
,
0
);
positions
[
2
]
=
Vec3
(
1
,
0
,
0
);
positions
[
3
]
=
Vec3
(
1
,
0
,
0.3
);
double
energySpring1
=
0.5
*
k
*
0.5
*
0.5
;
double
energySpring2
=
0.5
*
k
*
0.3
*
0.3
;
double
energyDipole
=
0.0
;
double
q
[]
=
{
-
charge
,
charge
,
-
charge
,
charge
};
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
j
=
2
;
j
<
4
;
j
++
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
j
];
double
r
=
sqrt
(
delta
.
dot
(
delta
));
energyDipole
+=
ONE_4PI_EPS0
*
q
[
i
]
*
q
[
j
]
*
computeScreening
(
r
,
thole
,
alpha
,
alpha
)
/
r
;
}
validateForce
(
system
,
positions
,
energySpring1
+
energySpring2
+
energyDipole
);
}
void
testChangingParameters
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
// Create the system.
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
// Check the energy.
VerletIntegrator
integ
(
1.0
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.5
*
k
*
3
*
3
,
state
.
getPotentialEnergy
(),
1e-5
);
// Modify the parameters.
const
double
k2
=
ONE_4PI_EPS0
*
2.2
;
const
double
charge2
=
0.3
;
const
double
alpha2
=
ONE_4PI_EPS0
*
charge2
*
charge2
/
k2
;
drude
->
setParticleParameters
(
0
,
1
,
0
,
-
1
,
-
1
,
-
1
,
charge2
,
alpha2
,
1
,
1
);
drude
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.5
*
k2
*
3
*
3
,
state
.
getPotentialEnergy
(),
1e-5
);
}
int
main
()
{
try
{
registerDrudeReferenceKernelFactories
();
testSingleParticle
();
testAnisotropicParticle
();
testThole
();
testChangingParameters
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
View file @
c5c0348a
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2013
-2016
Stanford University and the Authors. *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -29,228 +29,7 @@
...
@@ -29,228 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "ReferenceDrudeTests.h"
* This tests the Reference implementation of DrudeLangevinIntegrator.
#include "TestDrudeLangevinIntegrator.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{}
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VirtualSite.h"
#include "openmm/DrudeForce.h"
#include "openmm/DrudeLangevinIntegrator.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeReferenceKernelFactories
();
void
testSinglePair
()
{
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
mass1
=
1.0
;
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
const
double
reducedMass
=
(
mass1
*
mass2
)
/
(
mass1
+
mass2
);
const
double
maxDistance
=
0.05
;
System
system
;
system
.
addParticle
(
mass1
);
system
.
addParticle
(
mass2
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
0
,
0
);
DrudeLangevinIntegrator
integ
(
temperature
,
20.0
,
temperatureDrude
,
20.0
,
0.003
);
integ
.
setMaxDrudeDistance
(
maxDistance
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
// Equilibrate.
integ
.
step
(
1000
);
// Compute the internal and center of mass temperatures.
double
keCM
=
0
,
keInternal
=
0
;
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
10
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
const
vector
<
Vec3
>&
vel
=
state
.
getVelocities
();
Vec3
velCM
=
vel
[
0
]
*
(
mass1
/
totalMass
)
+
vel
[
1
]
*
(
mass2
/
totalMass
);
keCM
+=
0.5
*
totalMass
*
velCM
.
dot
(
velCM
);
Vec3
velInternal
=
vel
[
0
]
-
vel
[
1
];
keInternal
+=
0.5
*
reducedMass
*
velInternal
.
dot
(
velInternal
);
Vec3
delta
=
state
.
getPositions
()[
0
]
-
state
.
getPositions
()[
1
];
double
distance
=
sqrt
(
delta
.
dot
(
delta
));
ASSERT
(
distance
<=
maxDistance
*
(
1
+
1e-6
));
}
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperature
,
keCM
/
numSteps
,
0.1
);
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperatureDrude
,
keInternal
/
numSteps
,
0.01
);
}
void
testWater
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
gridSize
=
3
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.0
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
// Simulate it and check the temperature.
DrudeLangevinIntegrator
integ
(
temperature
,
50.0
,
temperatureDrude
,
50.0
,
0.0005
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
1e-5
);
// Equilibrate.
integ
.
step
(
500
);
// Compute the internal and center of mass temperatures.
double
ke
=
0
;
int
numSteps
=
4000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
ke
+=
context
.
getState
(
State
::
Energy
).
getKineticEnergy
();
}
ke
/=
numSteps
;
int
numStandardDof
=
3
*
3
*
numMolecules
-
system
.
getNumConstraints
();
int
numDrudeDof
=
3
*
numMolecules
;
int
numDof
=
numStandardDof
+
numDrudeDof
;
double
expectedTemp
=
(
numStandardDof
*
temperature
+
numDrudeDof
*
temperatureDrude
)
/
numDof
;
ASSERT_USUALLY_EQUAL_TOL
(
expectedTemp
,
ke
/
(
0.5
*
numDof
*
BOLTZ
),
0.03
);
}
void
testForceEnergyConsistency
()
{
// Create a box of polarizable particles.
const
int
gridSize
=
3
;
const
int
numAtoms
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
System
system
;
vector
<
Vec3
>
positions
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
nonbonded
->
setCutoffDistance
(
1.0
);
nonbonded
->
setUseSwitchingFunction
(
true
);
nonbonded
->
setSwitchingDistance
(
0.9
);
nonbonded
->
setEwaldErrorTolerance
(
5e-5
);
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
nonbonded
->
addParticle
(
1.0
,
0.3
,
1.0
);
nonbonded
->
addParticle
(
-
1.0
,
0.3
,
1.0
);
nonbonded
->
addException
(
startIndex
,
startIndex
+
1
,
0
,
1
,
0
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.0
,
0.001
,
1
,
1
);
}
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
}
// Simulate it and check that force and energy remain consistent.
DrudeLangevinIntegrator
integ
(
temperature
,
50.0
,
temperatureDrude
,
50.0
,
0.001
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
prevState
;
for
(
int
i
=
0
;
i
<
100
;
i
++
)
{
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
|
State
::
Positions
);
if
(
i
>
0
)
{
double
expectedEnergyChange
=
0
;
for
(
int
j
=
0
;
j
<
system
.
getNumParticles
();
j
++
)
{
Vec3
delta
=
state
.
getPositions
()[
j
]
-
prevState
.
getPositions
()[
j
];
expectedEnergyChange
-=
0.5
*
(
state
.
getForces
()[
j
]
+
prevState
.
getForces
()[
j
]).
dot
(
delta
);
}
ASSERT_EQUAL_TOL
(
expectedEnergyChange
,
state
.
getPotentialEnergy
()
-
prevState
.
getPotentialEnergy
(),
0.05
);
}
prevState
=
state
;
integ
.
step
(
1
);
}
}
int
main
()
{
try
{
registerDrudeReferenceKernelFactories
();
testSinglePair
();
testWater
();
testForceEnergyConsistency
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/platforms/reference/tests/TestReferenceDrudeNoseHoover.cpp
View file @
c5c0348a
...
@@ -29,22 +29,7 @@
...
@@ -29,22 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
//#include "ReferenceTests.h"
#include "ReferenceDrudeTests.h"
#include "openmm/Platform.h"
using
namespace
OpenMM
;
using
namespace
std
;
//extern "C" OPENMM_EXPORT void registerDrudeReferenceKernelFactories();
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[])
{
/* registerDrudeReferenceKernelFactories();
*/
return
Platform
::
getPlatformByName
(
"Reference"
);
}
#include "TestDrudeNoseHoover.h"
#include "TestDrudeNoseHoover.h"
void
runPlatformTests
()
{
}
void
runPlatformTests
()
{}
plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp
View file @
c5c0348a
...
@@ -29,113 +29,7 @@
...
@@ -29,113 +29,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "ReferenceDrudeTests.h"
* This tests the Reference implementation of DrudeSCFIntegrator.
#include "TestDrudeSCFIntegrator.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{}
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VirtualSite.h"
#include "openmm/DrudeForce.h"
#include "openmm/DrudeSCFIntegrator.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeReferenceKernelFactories
();
void
testWater
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
gridSize
=
3
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.0
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
// Simulate it and check energy conservation and the total force on the Drude particles.
DrudeSCFIntegrator
integ
(
0.0005
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
1e-5
);
context
.
setVelocitiesToTemperature
(
300.0
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
initialEnergy
;
int
numSteps
=
1000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
);
if
(
i
==
0
)
initialEnergy
=
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
();
else
ASSERT_EQUAL_TOL
(
initialEnergy
,
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
(),
0.01
);
const
vector
<
Vec3
>&
force
=
state
.
getForces
();
double
norm
=
0.0
;
for
(
int
j
=
1
;
j
<
(
int
)
force
.
size
();
j
+=
5
)
norm
+=
sqrt
(
force
[
j
].
dot
(
force
[
j
]));
norm
=
(
norm
/
numMolecules
);
ASSERT
(
norm
<
1.0
);
}
}
int
main
()
{
try
{
registerDrudeReferenceKernelFactories
();
testWater
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/tests/TestDrudeForce.h
0 → 100644
View file @
c5c0348a
/* -------------------------------------------------------------------------- *
* 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) 2013 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/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/OpenMMException.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/DrudeForce.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
void
validateForce
(
System
&
system
,
vector
<
Vec3
>&
positions
,
double
expectedEnergy
)
{
// Given a System containing a Drude force, check that its energy has the expected value.
VerletIntegrator
integ
(
1.0
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
);
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-5
);
// Try moving each particle along each axis, and see if the energy changes by the correct amount.
double
offset
=
1e-3
;
double
TOL
=
1e-5
;
try
{
if
(
platform
.
getPropertyValue
(
context
,
"Precision"
)
!=
"double"
)
{
offset
=
1e-2
;
TOL
=
5e-4
;
}
}
catch
(
OpenMMException
)
{
// The defaults above are for double precision, which is assumed in this case
}
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
vector
<
Vec3
>
offsetPos
=
positions
;
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
-
offset
;
context
.
setPositions
(
offsetPos
);
double
e1
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
+
offset
;
context
.
setPositions
(
offsetPos
);
double
e2
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
state
.
getForces
()[
i
][
j
],
(
e1
-
e2
)
/
(
2
*
offset
),
TOL
);
}
}
void
testSingleParticle
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
ASSERT
(
!
drude
->
usesPeriodicBoundaryConditions
());
ASSERT
(
!
system
.
usesPeriodicBoundaryConditions
());
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
validateForce
(
system
,
positions
,
0.5
*
k
*
3
*
3
);
}
void
testAnisotropicParticle
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
a1
=
0.8
;
const
double
a2
=
1.1
;
const
double
k1
=
k
/
a1
;
const
double
k2
=
k
/
a2
;
const
double
k3
=
k
/
(
3
-
a1
-
a2
);
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
2
,
3
,
4
,
charge
,
alpha
,
a1
,
a2
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
5
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0.1
,
-
0.5
,
0.8
);
positions
[
2
]
=
Vec3
(
0
,
2
,
0
);
positions
[
3
]
=
Vec3
(
1
,
2
,
0
);
positions
[
4
]
=
Vec3
(
1
,
2
,
3
);
validateForce
(
system
,
positions
,
0.5
*
k1
*
0.5
*
0.5
+
0.5
*
k2
*
0.8
*
0.8
+
0.5
*
k3
*
0.1
*
0.1
);
}
double
computeScreening
(
double
r
,
double
thole
,
double
alpha1
,
double
alpha2
)
{
double
u
=
r
*
thole
/
pow
(
alpha1
*
alpha2
,
1.0
/
6.0
);
return
1.0
-
(
1.0
+
u
/
2
)
*
exp
(
-
u
);
}
void
testThole
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
thole
=
2.5
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
drude
->
addParticle
(
3
,
2
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
drude
->
addScreenedPair
(
0
,
1
,
thole
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
4
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
-
0.5
,
0
);
positions
[
2
]
=
Vec3
(
1
,
0
,
0
);
positions
[
3
]
=
Vec3
(
1
,
0
,
0.3
);
double
energySpring1
=
0.5
*
k
*
0.5
*
0.5
;
double
energySpring2
=
0.5
*
k
*
0.3
*
0.3
;
double
energyDipole
=
0.0
;
double
q
[]
=
{
-
charge
,
charge
,
-
charge
,
charge
};
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
j
=
2
;
j
<
4
;
j
++
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
j
];
double
r
=
sqrt
(
delta
.
dot
(
delta
));
energyDipole
+=
ONE_4PI_EPS0
*
q
[
i
]
*
q
[
j
]
*
computeScreening
(
r
,
thole
,
alpha
,
alpha
)
/
r
;
}
validateForce
(
system
,
positions
,
energySpring1
+
energySpring2
+
energyDipole
);
}
void
testChangingParameters
()
{
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
// Create the system.
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
// Check the energy.
VerletIntegrator
integ
(
1.0
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.5
*
k
*
3
*
3
,
state
.
getPotentialEnergy
(),
1e-5
);
// Modify the parameters.
const
double
k2
=
ONE_4PI_EPS0
*
2.2
;
const
double
charge2
=
0.3
;
const
double
alpha2
=
ONE_4PI_EPS0
*
charge2
*
charge2
/
k2
;
drude
->
setParticleParameters
(
0
,
1
,
0
,
-
1
,
-
1
,
-
1
,
charge2
,
alpha2
,
1
,
1
);
drude
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.5
*
k2
*
3
*
3
,
state
.
getPotentialEnergy
(),
1e-5
);
}
void
setupKernels
(
int
argc
,
char
*
argv
[]);
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
setupKernels
(
argc
,
argv
);
testSingleParticle
();
testAnisotropicParticle
();
testThole
();
testChangingParameters
();
runPlatformTests
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/tests/TestDrudeLangevinIntegrator.h
0 → 100644
View file @
c5c0348a
/* -------------------------------------------------------------------------- *
* 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) 2013-2016 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/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VirtualSite.h"
#include "openmm/DrudeForce.h"
#include "openmm/DrudeLangevinIntegrator.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
void
testSinglePair
()
{
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
mass1
=
1.0
;
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
const
double
reducedMass
=
(
mass1
*
mass2
)
/
(
mass1
+
mass2
);
const
double
maxDistance
=
0.05
;
System
system
;
system
.
addParticle
(
mass1
);
system
.
addParticle
(
mass2
);
DrudeForce
*
drude
=
new
DrudeForce
();
drude
->
addParticle
(
1
,
0
,
-
1
,
-
1
,
-
1
,
charge
,
alpha
,
1
,
1
);
system
.
addForce
(
drude
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
0
,
0
);
DrudeLangevinIntegrator
integ
(
temperature
,
20.0
,
temperatureDrude
,
20.0
,
0.003
);
integ
.
setMaxDrudeDistance
(
maxDistance
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
// Equilibrate.
integ
.
step
(
1000
);
// Compute the internal and center of mass temperatures.
double
keCM
=
0
,
keInternal
=
0
;
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
10
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
const
vector
<
Vec3
>&
vel
=
state
.
getVelocities
();
Vec3
velCM
=
vel
[
0
]
*
(
mass1
/
totalMass
)
+
vel
[
1
]
*
(
mass2
/
totalMass
);
keCM
+=
0.5
*
totalMass
*
velCM
.
dot
(
velCM
);
Vec3
velInternal
=
vel
[
0
]
-
vel
[
1
];
keInternal
+=
0.5
*
reducedMass
*
velInternal
.
dot
(
velInternal
);
Vec3
delta
=
state
.
getPositions
()[
0
]
-
state
.
getPositions
()[
1
];
double
distance
=
sqrt
(
delta
.
dot
(
delta
));
ASSERT
(
distance
<=
maxDistance
*
(
1
+
1e-6
));
}
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperature
,
keCM
/
numSteps
,
0.1
);
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperatureDrude
,
keInternal
/
numSteps
,
0.01
);
}
void
testWater
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
gridSize
=
3
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.0
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
// Simulate it and check the temperature.
DrudeLangevinIntegrator
integ
(
temperature
,
50.0
,
temperatureDrude
,
50.0
,
0.0005
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
1e-5
);
// Equilibrate.
integ
.
step
(
500
);
// Compute the internal and center of mass temperatures.
double
ke
=
0
;
int
numSteps
=
4000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
ke
+=
context
.
getState
(
State
::
Energy
).
getKineticEnergy
();
}
ke
/=
numSteps
;
int
numStandardDof
=
3
*
3
*
numMolecules
-
system
.
getNumConstraints
();
int
numDrudeDof
=
3
*
numMolecules
;
int
numDof
=
numStandardDof
+
numDrudeDof
;
double
expectedTemp
=
(
numStandardDof
*
temperature
+
numDrudeDof
*
temperatureDrude
)
/
numDof
;
ASSERT_USUALLY_EQUAL_TOL
(
expectedTemp
,
ke
/
(
0.5
*
numDof
*
BOLTZ
),
0.03
);
}
void
testForceEnergyConsistency
()
{
// Create a box of polarizable particles.
const
int
gridSize
=
3
;
const
int
numAtoms
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
System
system
;
vector
<
Vec3
>
positions
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
nonbonded
->
setCutoffDistance
(
1.0
);
nonbonded
->
setUseSwitchingFunction
(
true
);
nonbonded
->
setSwitchingDistance
(
0.9
);
nonbonded
->
setEwaldErrorTolerance
(
5e-5
);
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
nonbonded
->
addParticle
(
1.0
,
0.3
,
1.0
);
nonbonded
->
addParticle
(
-
1.0
,
0.3
,
1.0
);
nonbonded
->
addException
(
startIndex
,
startIndex
+
1
,
0
,
1
,
0
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.0
,
0.001
,
1
,
1
);
}
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
}
// Simulate it and check that force and energy remain consistent.
DrudeLangevinIntegrator
integ
(
temperature
,
50.0
,
temperatureDrude
,
50.0
,
0.001
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
prevState
;
for
(
int
i
=
0
;
i
<
100
;
i
++
)
{
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
|
State
::
Positions
);
if
(
i
>
0
)
{
double
expectedEnergyChange
=
0
;
for
(
int
j
=
0
;
j
<
system
.
getNumParticles
();
j
++
)
{
Vec3
delta
=
state
.
getPositions
()[
j
]
-
prevState
.
getPositions
()[
j
];
expectedEnergyChange
-=
0.5
*
(
state
.
getForces
()[
j
]
+
prevState
.
getForces
()[
j
]).
dot
(
delta
);
}
ASSERT_EQUAL_TOL
(
expectedEnergyChange
,
state
.
getPotentialEnergy
()
-
prevState
.
getPotentialEnergy
(),
0.05
);
}
prevState
=
state
;
integ
.
step
(
1
);
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numRealParticles
=
500000
;
const
int
numParticles
=
2
*
numRealParticles
;
const
int
nDoF
=
3
*
numRealParticles
;
const
double
targetTemperature
=
300
;
const
double
drudeTemperature
=
1
;
const
double
realMass
=
10
;
const
double
drudeMass
=
1
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
DrudeForce
*
drude
=
new
DrudeForce
();
for
(
int
i
=
0
;
i
<
numRealParticles
;
i
++
)
{
system
.
addParticle
(
realMass
);
system
.
addParticle
(
drudeMass
);
positions
[
2
*
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
][
2
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
0
]
=
positions
[
2
*
i
][
0
]
+
0.01
*
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
1
]
=
positions
[
2
*
i
][
1
]
+
0.01
*
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
2
]
=
positions
[
2
*
i
][
2
]
+
0.01
*
genrand_real2
(
sfmt
);
drude
->
addParticle
(
2
*
i
+
1
,
2
*
i
,
-
1
,
-
1
,
-
1
,
-
1.0
,
0.001
,
1
,
1
);
}
system
.
addForce
(
drude
);
DrudeLangevinIntegrator
integrator
(
targetTemperature
,
25
,
drudeTemperature
,
25
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
comKineticEnergy
=
0
;
double
relKineticEnergy
=
0
;
for
(
int
i
=
0
;
i
<
numRealParticles
;
i
++
)
{
int
m1
=
realMass
;
int
m2
=
drudeMass
;
Vec3
v1
=
velocities
[
2
*
i
];
Vec3
v2
=
velocities
[
2
*
i
+
1
];
double
invMass
=
1.0
/
(
m1
+
m2
);
double
redMass
=
m1
*
m2
*
invMass
;
double
fracM1
=
m1
*
invMass
;
double
fracM2
=
m2
*
invMass
;
Vec3
comVelocity
=
fracM1
*
v1
+
fracM2
*
v2
;
Vec3
relVelocity
=
v2
-
v1
;
comKineticEnergy
+=
0.5
*
(
m1
+
m2
)
*
comVelocity
.
dot
(
comVelocity
);
relKineticEnergy
+=
0.5
*
redMass
*
relVelocity
.
dot
(
relVelocity
);
}
double
comTemperature
=
(
2
*
comKineticEnergy
/
(
nDoF
*
BOLTZ
));
double
relTemperature
=
(
2
*
relKineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
comTemperature
,
0.01
);
ASSERT_USUALLY_EQUAL_TOL
(
drudeTemperature
,
relTemperature
,
0.01
);
}
void
setupKernels
(
int
argc
,
char
*
argv
[]);
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
setupKernels
(
argc
,
argv
);
testInitialTemperature
();
testSinglePair
();
testWater
();
testForceEnergyConsistency
();
runPlatformTests
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
plugins/drude/tests/TestDrudeNoseHoover.h
View file @
c5c0348a
...
@@ -52,9 +52,6 @@
...
@@ -52,9 +52,6 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeReferenceKernelFactories
();
extern
"C"
OPENMM_EXPORT
void
registerKernelFactories
();
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[]);
void
build_waterbox
(
System
&
system
,
int
gridSize
,
double
polarizability
,
vector
<
Vec3
>
&
positions
)
{
void
build_waterbox
(
System
&
system
,
int
gridSize
,
double
polarizability
,
vector
<
Vec3
>
&
positions
)
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
...
@@ -107,7 +104,7 @@ void build_waterbox(System &system, int gridSize, double polarizability, vector<
...
@@ -107,7 +104,7 @@ void build_waterbox(System &system, int gridSize, double polarizability, vector<
}
}
}
}
void
testWaterBox
(
Platform
&
platform
)
{
void
testWaterBox
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
// and Drude particles.
System
system
;
System
system
;
...
@@ -128,34 +125,25 @@ void testWaterBox(Platform& platform) {
...
@@ -128,34 +125,25 @@ void testWaterBox(Platform& platform) {
int
chainLength
=
4
;
int
chainLength
=
4
;
int
numMTS
=
4
;
int
numMTS
=
4
;
int
numYS
=
5
;
int
numYS
=
5
;
double
frequency
=
800.0
;
// N.B. These are higher frequencies than recommeded for production runs, but are used
double
frequencyDrude
=
2000.0
;
// here to achieve rapid equilibration to the target temperature, allowing a short run
double
frequency
=
1000.0
;
double
frequencyDrude
=
1000.0
;
int
randomSeed
=
100
;
int
randomSeed
=
100
;
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
temperatureDrude
,
frequencyDrude
,
0.0005
,
temperatureDrude
,
frequencyDrude
,
0.0005
,
chainLength
,
numMTS
,
numYS
);
chainLength
,
numMTS
,
numYS
);
Context
context
(
system
,
integ
,
platform
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
temperature
,
randomSeed
);
context
.
setVelocitiesToTemperature
(
temperature
,
randomSeed
);
std
::
vector
<
Vec3
>
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
){
Vec3
noize
;
for
(
int
j
=
0
;
j
<
3
;
j
++
){
noize
[
j
]
=
float
(((
i
+
18311
)
*
(
j
+
18253
)
*
313419097822414
)
%
18313
)
/
float
(
18313
);
noize
[
j
]
*=
sqrt
(
3
*
BOLTZ
*
temperatureDrude
/
0.4
);
}
velocities
[
5
*
i
+
1
]
=
velocities
[
5
*
i
]
+
noize
;
}
context
.
setVelocities
(
velocities
);
context
.
applyConstraints
(
1e-6
);
context
.
applyConstraints
(
1e-6
);
// Equilibrate
.
// Equilibrate
integ
.
step
(
500
);
integ
.
step
(
1
500
);
// Compute the internal and center of mass temperatures.
// Compute the internal and center of mass temperatures.
double
totalKE
=
0
;
double
totalKE
=
0
;
const
int
numSteps
=
40
00
;
const
int
numSteps
=
5
00
;
double
meanTemp
=
0.0
;
double
meanTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanConserved
=
0.0
;
double
meanConserved
=
0.0
;
...
@@ -174,15 +162,15 @@ void testWaterBox(Platform& platform) {
...
@@ -174,15 +162,15 @@ void testWaterBox(Platform& platform) {
double
conserved
=
PE
+
fullKE
+
heatBathEnergy
;
double
conserved
=
PE
+
fullKE
+
heatBathEnergy
;
meanConserved
=
(
i
*
meanConserved
+
conserved
)
/
(
i
+
1
);
meanConserved
=
(
i
*
meanConserved
+
conserved
)
/
(
i
+
1
);
totalKE
+=
KE
;
totalKE
+=
KE
;
ASSERT
(
fabs
(
meanConserved
-
conserved
)
<
0.
6
);
ASSERT
(
fabs
(
meanConserved
-
conserved
)
<
0.
3
);
}
}
totalKE
/=
numSteps
;
totalKE
/=
numSteps
;
ASSERT_USUALLY_EQUAL_TOL
(
temperature
,
meanTemp
,
0.0
04
);
ASSERT_USUALLY_EQUAL_TOL
(
temperature
,
meanTemp
,
0.0
3
);
ASSERT_USUALLY_EQUAL_TOL
(
temperatureDrude
,
meanDrudeTemp
,
0.0
04
);
ASSERT_USUALLY_EQUAL_TOL
(
temperatureDrude
,
meanDrudeTemp
,
0.0
3
);
}
}
double
testWaterBoxWithHardWallConstraint
(
Platform
&
platform
,
double
hardWallConstraint
){
double
testWaterBoxWithHardWallConstraint
(
double
hardWallConstraint
){
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
// and Drude particles.
System
system
;
System
system
;
...
@@ -206,31 +194,21 @@ double testWaterBoxWithHardWallConstraint(Platform& platform, double hardWallCon
...
@@ -206,31 +194,21 @@ double testWaterBoxWithHardWallConstraint(Platform& platform, double hardWallCon
double
frequency
=
25.0
;
double
frequency
=
25.0
;
double
frequencyDrude
=
25.0
;
double
frequencyDrude
=
25.0
;
int
randomSeed
=
100
;
int
randomSeed
=
100
;
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
temperatureDrude
,
frequencyDrude
,
0.0005
,
temperatureDrude
,
frequencyDrude
,
0.0005
,
chainLength
,
numMTS
,
numYS
);
chainLength
,
numMTS
,
numYS
);
integ
.
setMaxDrudeDistance
(
hardWallConstraint
);
integ
.
setMaxDrudeDistance
(
hardWallConstraint
);
Context
context
(
system
,
integ
,
platform
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
temperature
,
randomSeed
);
context
.
setVelocitiesToTemperature
(
temperature
,
randomSeed
);
std
::
vector
<
Vec3
>
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
){
Vec3
noize
;
for
(
int
j
=
0
;
j
<
3
;
j
++
){
noize
[
j
]
=
float
(((
i
+
18311
)
*
(
j
+
18253
)
*
313419097822414
)
%
18313
)
/
float
(
18313
);
noize
[
j
]
*=
sqrt
(
3
*
BOLTZ
*
temperatureDrude
/
0.4
);
}
velocities
[
5
*
i
+
1
]
=
velocities
[
5
*
i
]
+
noize
;
}
context
.
setVelocities
(
velocities
);
context
.
applyConstraints
(
1e-6
);
context
.
applyConstraints
(
1e-6
);
// Equilibrate.
// Equilibrate.
integ
.
step
(
50
);
integ
.
step
(
10
);
// Compute the internal and center of mass temperatures.
// Compute the internal and center of mass temperatures.
double
totalKE
=
0
;
double
totalKE
=
0
;
const
int
numSteps
=
1
0
;
const
int
numSteps
=
50
0
;
double
meanTemp
=
0.0
;
double
meanTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanConserved
=
0.0
;
double
meanConserved
=
0.0
;
...
@@ -238,40 +216,90 @@ double testWaterBoxWithHardWallConstraint(Platform& platform, double hardWallCon
...
@@ -238,40 +216,90 @@ double testWaterBoxWithHardWallConstraint(Platform& platform, double hardWallCon
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
integ
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Positions
);
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Positions
);
double
KE
=
state
.
getKineticEnergy
();
double
PE
=
state
.
getPotentialEnergy
();
double
fullKE
=
integ
.
computeTotalKineticEnergy
();
double
drudeKE
=
integ
.
computeDrudeKineticEnergy
();
double
temp
=
KE
/
(
0.5
*
numStandardDof
*
BOLTZ
);
double
drudeTemp
=
drudeKE
/
(
0.5
*
numDrudeDof
*
BOLTZ
);
meanTemp
=
(
i
*
meanTemp
+
temp
)
/
(
i
+
1
);
meanDrudeTemp
=
(
i
*
meanDrudeTemp
+
drudeTemp
)
/
(
i
+
1
);
double
heatBathEnergy
=
integ
.
computeHeatBathEnergy
();
double
conserved
=
PE
+
fullKE
+
heatBathEnergy
;
meanConserved
=
(
i
*
meanConserved
+
conserved
)
/
(
i
+
1
);
const
auto
&
positions
=
state
.
getPositions
();
const
auto
&
positions
=
state
.
getPositions
();
for
(
int
mol
=
0
;
mol
<
gridSize
*
gridSize
*
gridSize
;
++
mol
)
{
for
(
int
mol
=
0
;
mol
<
gridSize
*
gridSize
*
gridSize
;
++
mol
)
{
auto
dR
=
positions
[
5
*
mol
+
1
]
-
positions
[
5
*
mol
];
auto
dR
=
positions
[
5
*
mol
+
1
]
-
positions
[
5
*
mol
];
maxR
=
std
::
max
(
maxR
,
std
::
sqrt
(
dR
.
dot
(
dR
)));
maxR
=
std
::
max
(
maxR
,
std
::
sqrt
(
dR
.
dot
(
dR
)));
}
}
totalKE
+=
KE
;
}
}
totalKE
/=
numSteps
;
return
maxR
;
return
maxR
;
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numRealParticles
=
500000
;
const
int
numParticles
=
2
*
numRealParticles
;
const
int
nDoF
=
3
*
numRealParticles
;
const
double
targetTemperature
=
300
;
const
double
drudeTemperature
=
1
;
const
double
realMass
=
10
;
const
double
drudeMass
=
1
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
DrudeForce
*
drude
=
new
DrudeForce
();
for
(
int
i
=
0
;
i
<
numRealParticles
;
i
++
)
{
system
.
addParticle
(
realMass
);
system
.
addParticle
(
drudeMass
);
positions
[
2
*
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
][
2
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
0
]
=
positions
[
2
*
i
][
0
]
+
0.01
*
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
1
]
=
positions
[
2
*
i
][
1
]
+
0.01
*
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
2
]
=
positions
[
2
*
i
][
2
]
+
0.01
*
genrand_real2
(
sfmt
);
drude
->
addParticle
(
2
*
i
+
1
,
2
*
i
,
-
1
,
-
1
,
-
1
,
-
1.0
,
0.001
,
1
,
1
);
}
system
.
addForce
(
drude
);
CMMotionRemover
*
cmm
=
new
CMMotionRemover
(
1
);
system
.
addForce
(
cmm
);
DrudeNoseHooverIntegrator
integrator
(
targetTemperature
,
25
,
drudeTemperature
,
25
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
comKineticEnergy
=
0
;
double
relKineticEnergy
=
0
;
for
(
int
i
=
0
;
i
<
numRealParticles
;
i
++
)
{
int
m1
=
realMass
;
int
m2
=
drudeMass
;
Vec3
v1
=
velocities
[
2
*
i
];
Vec3
v2
=
velocities
[
2
*
i
+
1
];
double
invMass
=
1.0
/
(
m1
+
m2
);
double
redMass
=
m1
*
m2
*
invMass
;
double
fracM1
=
m1
*
invMass
;
double
fracM2
=
m2
*
invMass
;
Vec3
comVelocity
=
fracM1
*
v1
+
fracM2
*
v2
;
Vec3
relVelocity
=
v2
-
v1
;
comKineticEnergy
+=
0.5
*
(
m1
+
m2
)
*
comVelocity
.
dot
(
comVelocity
);
relKineticEnergy
+=
0.5
*
redMass
*
relVelocity
.
dot
(
relVelocity
);
}
double
comTemperature
=
(
2
*
comKineticEnergy
/
(
nDoF
*
BOLTZ
));
double
relTemperature
=
(
2
*
relKineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
comTemperature
,
0.01
);
ASSERT_USUALLY_EQUAL_TOL
(
drudeTemperature
,
relTemperature
,
0.01
);
}
void
setupKernels
(
int
argc
,
char
*
argv
[]);
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
try
{
registerKernelFactories
(
);
setupKernels
(
argc
,
argv
);
Platform
&
platform
=
initializePlatform
(
argc
,
argv
);
testWaterBox
();
testWaterBox
(
platform
);
double
maxDrudeDistance
=
0.005
;
double
maxDrudeDistance
=
0.005
;
double
observedDrudeDistance
=
testWaterBoxWithHardWallConstraint
(
platform
,
0.0
);
double
observedDrudeDistance
=
testWaterBoxWithHardWallConstraint
(
0.0
);
ASSERT
(
observedDrudeDistance
>
maxDrudeDistance
);
ASSERT
(
observedDrudeDistance
>
maxDrudeDistance
);
observedDrudeDistance
=
testWaterBoxWithHardWallConstraint
(
platform
,
maxDrudeDistance
);
observedDrudeDistance
=
testWaterBoxWithHardWallConstraint
(
maxDrudeDistance
);
// Remove later: just trying to find out why Jenkins is upset
if
(
observedDrudeDistance
>=
maxDrudeDistance
)
printf
(
"Max distance %16.10f
\n
"
,
observedDrudeDistance
);
ASSERT
(
observedDrudeDistance
<
maxDrudeDistance
);
ASSERT
(
observedDrudeDistance
<
maxDrudeDistance
);
testInitialTemperature
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
plugins/drude/tests/TestDrudeSCFIntegrator.h
0 → 100644
View file @
c5c0348a
/* -------------------------------------------------------------------------- *
* 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) 2013 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 DrudeSCFIntegrator.
*/
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/OpenMMException.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VirtualSite.h"
#include "openmm/DrudeForce.h"
#include "openmm/DrudeSCFIntegrator.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
void
testWater
()
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
gridSize
=
3
;
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.6
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.0
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
// Simulate it and check energy conservation and the total force on the Drude particles.
DrudeSCFIntegrator
integ
(
0.0005
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
1e-5
);
context
.
setVelocitiesToTemperature
(
300.0
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
initialEnergy
;
int
numSteps
=
1000
;
double
maxNorm
=
1.0
;
try
{
if
(
platform
.
getPropertyValue
(
context
,
"Precision"
)
!=
"double"
)
{
maxNorm
=
5.0
;
}
}
catch
(
OpenMMException
)
{
// The defaults above are for double precision, which is assumed in this case
}
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
state
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
);
if
(
i
==
0
)
initialEnergy
=
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
();
else
ASSERT_EQUAL_TOL
(
initialEnergy
,
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
(),
0.01
);
const
vector
<
Vec3
>&
force
=
state
.
getForces
();
double
norm
=
0.0
;
for
(
int
j
=
1
;
j
<
(
int
)
force
.
size
();
j
+=
5
)
norm
+=
sqrt
(
force
[
j
].
dot
(
force
[
j
]));
norm
=
(
norm
/
numMolecules
);
// Just to see what's going on with Travis. Remove later!
if
(
norm
<
maxNorm
)
{
printf
(
"norm: %8.2f, allowed %6.2f
\n
"
,
norm
,
maxNorm
);
}
ASSERT
(
norm
<
maxNorm
);
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numRealParticles
=
500000
;
const
int
numParticles
=
2
*
numRealParticles
;
const
int
nDoF
=
3
*
numRealParticles
;
const
double
targetTemperature
=
300
;
const
double
drudeTemperature
=
0
;
const
double
realMass
=
10
;
const
double
drudeMass
=
1
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
DrudeForce
*
drude
=
new
DrudeForce
();
for
(
int
i
=
0
;
i
<
numRealParticles
;
i
++
)
{
system
.
addParticle
(
realMass
);
system
.
addParticle
(
drudeMass
);
positions
[
2
*
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
][
2
]
=
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
0
]
=
positions
[
2
*
i
][
0
]
+
0.01
*
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
1
]
=
positions
[
2
*
i
][
1
]
+
0.01
*
genrand_real2
(
sfmt
);
positions
[
2
*
i
+
1
][
2
]
=
positions
[
2
*
i
][
2
]
+
0.01
*
genrand_real2
(
sfmt
);
drude
->
addParticle
(
2
*
i
+
1
,
2
*
i
,
-
1
,
-
1
,
-
1
,
-
1.0
,
0.001
,
1
,
1
);
}
system
.
addForce
(
drude
);
DrudeSCFIntegrator
integrator
(
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
comKineticEnergy
=
0
;
double
relKineticEnergy
=
0
;
for
(
int
i
=
0
;
i
<
numRealParticles
;
i
++
)
{
int
m1
=
realMass
;
int
m2
=
drudeMass
;
Vec3
v1
=
velocities
[
2
*
i
];
Vec3
v2
=
velocities
[
2
*
i
+
1
];
double
invMass
=
1.0
/
(
m1
+
m2
);
double
redMass
=
m1
*
m2
*
invMass
;
double
fracM1
=
m1
*
invMass
;
double
fracM2
=
m2
*
invMass
;
Vec3
comVelocity
=
fracM1
*
v1
+
fracM2
*
v2
;
Vec3
relVelocity
=
v2
-
v1
;
comKineticEnergy
+=
0.5
*
(
m1
+
m2
)
*
comVelocity
.
dot
(
comVelocity
);
relKineticEnergy
+=
0.5
*
redMass
*
relVelocity
.
dot
(
relVelocity
);
}
double
comTemperature
=
(
2
*
comKineticEnergy
/
(
nDoF
*
BOLTZ
));
double
relTemperature
=
(
2
*
relKineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
comTemperature
,
0.01
);
ASSERT_USUALLY_EQUAL_TOL
(
drudeTemperature
,
relTemperature
,
0.01
);
}
void
setupKernels
(
int
argc
,
char
*
argv
[]);
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
setupKernels
(
argc
,
argv
);
testWater
();
runPlatformTests
();
testInitialTemperature
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"FAIL - ERROR. Test failed."
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
return
0
;
}
tests/TestBrownianIntegrator.h
View file @
c5c0348a
...
@@ -251,6 +251,34 @@ void testRandomSeed() {
...
@@ -251,6 +251,34 @@ void testRandomSeed() {
}
}
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numParticles
=
500000
;
const
int
nDoF
=
3
*
numParticles
;
const
double
targetTemperature
=
300
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
positions
[
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
2
]
=
genrand_real2
(
sfmt
);
}
BrownianIntegrator
integrator
(
300
,
2
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
kineticEnergy
=
0
;
for
(
const
auto
&
v
:
velocities
)
kineticEnergy
+=
0.5
*
v
.
dot
(
v
);
double
temperature
=
(
2
*
kineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
temperature
,
0.01
);
}
void
runPlatformTests
();
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
@@ -261,6 +289,7 @@ int main(int argc, char* argv[]) {
...
@@ -261,6 +289,7 @@ int main(int argc, char* argv[]) {
testConstraints
();
testConstraints
();
testConstrainedMasslessParticles
();
testConstrainedMasslessParticles
();
testRandomSeed
();
testRandomSeed
();
testInitialTemperature
();
runPlatformTests
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
...
...
tests/TestCustomIntegrator.h
View file @
c5c0348a
...
@@ -1128,6 +1128,34 @@ void testRecordEnergy() {
...
@@ -1128,6 +1128,34 @@ void testRecordEnergy() {
}
}
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numParticles
=
500000
;
const
int
nDoF
=
3
*
numParticles
;
const
double
targetTemperature
=
300
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
positions
[
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
2
]
=
genrand_real2
(
sfmt
);
}
CustomIntegrator
integrator
(
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
kineticEnergy
=
0
;
for
(
const
auto
&
v
:
velocities
)
kineticEnergy
+=
0.5
*
v
.
dot
(
v
);
double
temperature
=
(
2
*
kineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
temperature
,
0.01
);
}
void
runPlatformTests
();
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
@@ -1155,6 +1183,7 @@ int main(int argc, char* argv[]) {
...
@@ -1155,6 +1183,7 @@ int main(int argc, char* argv[]) {
testUpdateContextState
();
testUpdateContextState
();
testVectorFunctions
();
testVectorFunctions
();
testRecordEnergy
();
testRecordEnergy
();
testInitialTemperature
();
runPlatformTests
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
...
...
tests/TestLangevinIntegrator.h
View file @
c5c0348a
...
@@ -258,6 +258,34 @@ void testRandomSeed() {
...
@@ -258,6 +258,34 @@ void testRandomSeed() {
}
}
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numParticles
=
500000
;
const
int
nDoF
=
3
*
numParticles
;
const
double
targetTemperature
=
300
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
positions
[
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
2
]
=
genrand_real2
(
sfmt
);
}
LangevinIntegrator
integrator
(
300
,
25
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
kineticEnergy
=
0
;
for
(
const
auto
&
v
:
velocities
)
kineticEnergy
+=
0.5
*
v
.
dot
(
v
);
double
temperature
=
(
2
*
kineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
temperature
,
0.01
);
}
void
runPlatformTests
();
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
@@ -268,6 +296,7 @@ int main(int argc, char* argv[]) {
...
@@ -268,6 +296,7 @@ int main(int argc, char* argv[]) {
testConstraints
();
testConstraints
();
testConstrainedMasslessParticles
();
testConstrainedMasslessParticles
();
testRandomSeed
();
testRandomSeed
();
testInitialTemperature
();
runPlatformTests
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
...
...
tests/TestLangevinMiddleIntegrator.h
View file @
c5c0348a
...
@@ -261,6 +261,34 @@ void testRandomSeed() {
...
@@ -261,6 +261,34 @@ void testRandomSeed() {
}
}
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numParticles
=
500000
;
const
int
nDoF
=
3
*
numParticles
;
const
double
targetTemperature
=
300
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
positions
[
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
2
]
=
genrand_real2
(
sfmt
);
}
LangevinMiddleIntegrator
integrator
(
300
,
25
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
kineticEnergy
=
0
;
for
(
const
auto
&
v
:
velocities
)
kineticEnergy
+=
0.5
*
v
.
dot
(
v
);
double
temperature
=
(
2
*
kineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
temperature
,
0.01
);
}
void
runPlatformTests
();
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
@@ -271,6 +299,7 @@ int main(int argc, char* argv[]) {
...
@@ -271,6 +299,7 @@ int main(int argc, char* argv[]) {
testConstraints
();
testConstraints
();
testConstrainedMasslessParticles
();
testConstrainedMasslessParticles
();
testRandomSeed
();
testRandomSeed
();
testInitialTemperature
();
runPlatformTests
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
...
...
tests/TestNoseHooverIntegrator.h
View file @
c5c0348a
...
@@ -269,6 +269,34 @@ void testThreeParticleVirtualSite() {
...
@@ -269,6 +269,34 @@ void testThreeParticleVirtualSite() {
}
}
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numParticles
=
500000
;
const
int
nDoF
=
3
*
numParticles
;
const
double
targetTemperature
=
300
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
positions
[
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
2
]
=
genrand_real2
(
sfmt
);
}
NoseHooverIntegrator
integrator
(
300
,
25
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
kineticEnergy
=
0
;
for
(
const
auto
&
v
:
velocities
)
kineticEnergy
+=
0.5
*
v
.
dot
(
v
);
double
temperature
=
(
2
*
kineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
temperature
,
0.01
);
}
void
runPlatformTests
();
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
@@ -279,6 +307,7 @@ int main(int argc, char* argv[]) {
...
@@ -279,6 +307,7 @@ int main(int argc, char* argv[]) {
testVVConstrainedClusters
();
testVVConstrainedClusters
();
testVVConstrainedMasslessParticles
();
testVVConstrainedMasslessParticles
();
testThreeParticleVirtualSite
();
testThreeParticleVirtualSite
();
testInitialTemperature
();
runPlatformTests
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
...
...
tests/TestVariableLangevinIntegrator.h
View file @
c5c0348a
...
@@ -330,6 +330,34 @@ void testArgonBox() {
...
@@ -330,6 +330,34 @@ void testArgonBox() {
}
}
}
}
void
testInitialTemperature
()
{
// Check temperature initialization for a collection of randomly placed particles
const
int
numParticles
=
500000
;
const
int
nDoF
=
3
*
numParticles
;
const
double
targetTemperature
=
300
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
std
::
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
positions
[
i
][
0
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
1
]
=
genrand_real2
(
sfmt
);
positions
[
i
][
2
]
=
genrand_real2
(
sfmt
);
}
VariableLangevinIntegrator
integrator
(
300
,
25
,
1e-5
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
targetTemperature
);
auto
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
double
kineticEnergy
=
0
;
for
(
const
auto
&
v
:
velocities
)
kineticEnergy
+=
0.5
*
v
.
dot
(
v
);
double
temperature
=
(
2
*
kineticEnergy
/
(
nDoF
*
BOLTZ
));
ASSERT_USUALLY_EQUAL_TOL
(
targetTemperature
,
temperature
,
0.01
);
}
void
runPlatformTests
();
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
@@ -341,6 +369,7 @@ int main(int argc, char* argv[]) {
...
@@ -341,6 +369,7 @@ int main(int argc, char* argv[]) {
testConstrainedMasslessParticles
();
testConstrainedMasslessParticles
();
testRandomSeed
();
testRandomSeed
();
testArgonBox
();
testArgonBox
();
testInitialTemperature
();
runPlatformTests
();
runPlatformTests
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
...
...
Prev
1
2
3
Next
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