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
a381a3ab
Commit
a381a3ab
authored
Aug 01, 2016
by
peastman
Browse files
Merge branch 'master' into gayberne
parents
5ecc8e00
1f7866ad
Changes
199
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
806 additions
and
272 deletions
+806
-272
plugins/amoeba/platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu
.../platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu
+22
-23
plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp
.../amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp
+3
-0
plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp
...eba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp
+70
-0
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
...amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
+46
-4
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h
...s/amoeba/platforms/reference/src/AmoebaReferenceKernels.h
+14
-0
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
...ence/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
+269
-211
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h
...erence/src/SimTKReference/AmoebaReferenceMultipoleForce.h
+69
-0
plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp
...atforms/reference/tests/TestReferenceAmoebaAngleForce.cpp
+3
-0
plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp
...rms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp
+70
-0
plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp
...ns/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp
+6
-16
plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp
plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp
+2
-2
plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp
...serialization/tests/TestSerializeAmoebaMultipoleForce.cpp
+0
-3
plugins/drude/platforms/cuda/src/CudaDrudeKernels.cpp
plugins/drude/platforms/cuda/src/CudaDrudeKernels.cpp
+5
-3
plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
.../platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
+62
-1
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
+2
-1
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
...tforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
+62
-1
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
.../reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
+62
-1
serialization/src/CustomAngleForceProxy.cpp
serialization/src/CustomAngleForceProxy.cpp
+13
-2
serialization/src/CustomBondForceProxy.cpp
serialization/src/CustomBondForceProxy.cpp
+13
-2
serialization/src/CustomCentroidBondForceProxy.cpp
serialization/src/CustomCentroidBondForceProxy.cpp
+13
-2
No files found.
plugins/amoeba/platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu
View file @
a381a3ab
...
...
@@ -555,6 +555,8 @@ extern "C" __global__ void computeElectrostatics(
#ifdef USE_CUTOFF
const
unsigned
int
numTiles
=
interactionCount
[
0
];
if
(
numTiles
>
maxTiles
)
return
;
// There wasn't enough memory for the neighbor list.
int
pos
=
(
int
)
(
numTiles
>
maxTiles
?
startTileIndex
+
warp
*
(
long
long
)
numTileIndices
/
totalWarps
:
warp
*
(
long
long
)
numTiles
/
totalWarps
);
int
end
=
(
int
)
(
numTiles
>
maxTiles
?
startTileIndex
+
(
warp
+
1
)
*
(
long
long
)
numTileIndices
/
totalWarps
:
(
warp
+
1
)
*
(
long
long
)
numTiles
/
totalWarps
);
#else
...
...
@@ -575,11 +577,8 @@ extern "C" __global__ void computeElectrostatics(
int
x
,
y
;
#ifdef USE_CUTOFF
if
(
numTiles
<=
maxTiles
)
x
=
tiles
[
pos
];
else
#endif
{
#else
y
=
(
int
)
floor
(
NUM_BLOCKS
+
0.5
f
-
SQRT
((
NUM_BLOCKS
+
0.5
f
)
*
(
NUM_BLOCKS
+
0.5
f
)
-
2
*
pos
));
x
=
(
pos
-
y
*
NUM_BLOCKS
+
y
*
(
y
+
1
)
/
2
);
if
(
x
<
y
||
x
>=
NUM_BLOCKS
)
{
// Occasionally happens due to roundoff error.
...
...
@@ -602,7 +601,7 @@ extern "C" __global__ void computeElectrostatics(
while
(
skipTiles
[
currentSkipIndex
]
<
pos
)
currentSkipIndex
++
;
includeTile
=
(
skipTiles
[
currentSkipIndex
]
!=
pos
);
}
#endif
if
(
includeTile
)
{
unsigned
int
atom1
=
x
*
TILE_SIZE
+
tgx
;
...
...
plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp
View file @
a381a3ab
...
...
@@ -33,6 +33,9 @@
* This tests the CUDA implementation of CudaAmoebaAngleForce.
*/
#ifdef WIN32
#define _USE_MATH_DEFINES // Needed to get M_PI
#endif
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/CustomAngleForce.h"
...
...
plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp
View file @
a381a3ab
...
...
@@ -2666,6 +2666,76 @@ static void testParticleInducedDipoles() {
ASSERT_EQUAL_VEC
(
expectedDipole
[
i
],
dipole
[
i
],
1e-4
);
}
// test querying particle lab frame permanent dipoles
static
void
testParticleLabFramePermanentDipoles
()
{
int
numberOfParticles
=
8
;
int
inputPmeGridDimension
=
0
;
double
cutoff
=
9000000.0
;
std
::
vector
<
Vec3
>
forces
;
double
energy
;
System
system
;
AmoebaMultipoleForce
*
amoebaMultipoleForce
=
new
AmoebaMultipoleForce
();;
setupMultipoleAmmonia
(
system
,
amoebaMultipoleForce
,
AmoebaMultipoleForce
::
NoCutoff
,
AmoebaMultipoleForce
::
Mutual
,
cutoff
,
inputPmeGridDimension
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"CUDA"
));
getForcesEnergyMultipoleAmmonia
(
context
,
forces
,
energy
);
std
::
vector
<
Vec3
>
dipole
;
amoebaMultipoleForce
->
getLabFramePermanentDipoles
(
context
,
dipole
);
// Compare to values calculated by TINKER.
std
::
vector
<
Vec3
>
expectedDipole
(
numberOfParticles
);
expectedDipole
[
0
]
=
Vec3
(
0.00876454250
,
-
2.04310718E-06
,
-
0.00227593519
);
expectedDipole
[
1
]
=
Vec3
(
0.000780382180
,
-
0.00432882849
,
0.00236926761
);
expectedDipole
[
2
]
=
Vec3
(
0.000801345883
,
0.00431830946
,
0.00238143437
);
expectedDipole
[
3
]
=
Vec3
(
-
0.00109746996
,
1.16087953e-5
,
-
0.00487407492
);
expectedDipole
[
4
]
=
Vec3
(
0.00203814102
,
-
2.26554196e-5
,
0.00882284298
);
expectedDipole
[
5
]
=
Vec3
(
-
0.00239443187
,
0.00432388648
,
0.000729303209
);
expectedDipole
[
6
]
=
Vec3
(
0.00491086743
,
2.86430963e-6
,
-
0.000918996348
);
expectedDipole
[
7
]
=
Vec3
(
-
0.00239301946
,
-
0.00432743976
,
0.000712674115
);
for
(
int
i
=
0
;
i
<
numberOfParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
expectedDipole
[
i
],
dipole
[
i
],
1e-4
);
}
// test querying particle total dipoles (fixed + induced)
static
void
testParticleTotalDipoles
()
{
int
numberOfParticles
=
8
;
int
inputPmeGridDimension
=
0
;
double
cutoff
=
9000000.0
;
std
::
vector
<
Vec3
>
forces
;
double
energy
;
System
system
;
AmoebaMultipoleForce
*
amoebaMultipoleForce
=
new
AmoebaMultipoleForce
();;
setupMultipoleAmmonia
(
system
,
amoebaMultipoleForce
,
AmoebaMultipoleForce
::
NoCutoff
,
AmoebaMultipoleForce
::
Mutual
,
cutoff
,
inputPmeGridDimension
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"CUDA"
));
getForcesEnergyMultipoleAmmonia
(
context
,
forces
,
energy
);
std
::
vector
<
Vec3
>
dipole
;
amoebaMultipoleForce
->
getTotalDipoles
(
context
,
dipole
);
// Compare to values calculated by TINKER.
std
::
vector
<
Vec3
>
expectedDipole
(
numberOfParticles
);
expectedDipole
[
0
]
=
Vec3
(
0.0119356307
,
-
1.11302433e-6
,
-
0.00296793872
);
expectedDipole
[
1
]
=
Vec3
(
8.60636211e-4
,
-
0.00460821816
,
0.00241705344
);
expectedDipole
[
2
]
=
Vec3
(
8.80646403e-4
,
0.00459728769
,
0.00243013245
);
expectedDipole
[
3
]
=
Vec3
(
-
0.00123822377
,
1.31555550e-5
,
-
0.00558185336
);
expectedDipole
[
4
]
=
Vec3
(
0.00399455556
,
-
2.27511931e-5
,
0.00955607952
);
expectedDipole
[
5
]
=
Vec3
(
-
0.00157302682
,
0.00354892386
,
3.40921137e-4
);
expectedDipole
[
6
]
=
Vec3
(
0.00952428069
,
2.14171505e-6
,
-
6.68945865e-4
);
expectedDipole
[
7
]
=
Vec3
(
-
0.00157252460
,
-
0.00355015528
,
3.27055162e-4
);
for
(
int
i
=
0
;
i
<
numberOfParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
expectedDipole
[
i
],
dipole
[
i
],
1e-4
);
}
// test computation of system multipole moments
static
void
testSystemMultipoleMoments
()
{
...
...
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
View file @
a381a3ab
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-20
09
Stanford University and the Authors. *
* Portions copyright (c) 2008-20
16
Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
...
...
@@ -594,9 +594,9 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
nonbondedMethod
=
force
.
getNonbondedMethod
();
if
(
nonbondedMethod
==
AmoebaMultipoleForce
::
PME
)
{
usePme
=
true
;
alphaEwald
=
force
.
getAEwald
();
pmeGridDimension
.
resize
(
3
);
force
.
getPMEParameters
(
alphaEwald
,
pmeGridDimension
[
0
],
pmeGridDimension
[
1
],
pmeGridDimension
[
2
]);
cutoffDistance
=
force
.
getCutoffDistance
();
force
.
getPmeGridDimensions
(
pmeGridDimension
);
if
(
pmeGridDimension
[
0
]
==
0
||
alphaEwald
==
0.0
)
{
NonbondedForce
nb
;
nb
.
setEwaldErrorTolerance
(
force
.
getEwaldErrorTolerance
());
...
...
@@ -735,6 +735,48 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& con
delete
amoebaReferenceMultipoleForce
;
}
void
ReferenceCalcAmoebaMultipoleForceKernel
::
getLabFramePermanentDipoles
(
ContextImpl
&
context
,
vector
<
Vec3
>&
outputDipoles
)
{
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
outputDipoles
.
resize
(
numParticles
);
// Create an AmoebaReferenceMultipoleForce to do the calculation.
AmoebaReferenceMultipoleForce
*
amoebaReferenceMultipoleForce
=
setupAmoebaReferenceMultipoleForce
(
context
);
vector
<
RealVec
>&
posData
=
extractPositions
(
context
);
// Retrieve the permanent dipoles in the lab frame.
vector
<
RealVec
>
labFramePermanentDipoles
;
amoebaReferenceMultipoleForce
->
calculateLabFramePermanentDipoles
(
posData
,
charges
,
dipoles
,
quadrupoles
,
tholes
,
dampingFactors
,
polarity
,
axisTypes
,
multipoleAtomZs
,
multipoleAtomXs
,
multipoleAtomYs
,
multipoleAtomCovalentInfo
,
labFramePermanentDipoles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
outputDipoles
[
i
]
=
labFramePermanentDipoles
[
i
];
delete
amoebaReferenceMultipoleForce
;
}
void
ReferenceCalcAmoebaMultipoleForceKernel
::
getTotalDipoles
(
ContextImpl
&
context
,
vector
<
Vec3
>&
outputDipoles
)
{
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
outputDipoles
.
resize
(
numParticles
);
// Create an AmoebaReferenceMultipoleForce to do the calculation.
AmoebaReferenceMultipoleForce
*
amoebaReferenceMultipoleForce
=
setupAmoebaReferenceMultipoleForce
(
context
);
vector
<
RealVec
>&
posData
=
extractPositions
(
context
);
// Retrieve the permanent dipoles in the lab frame.
vector
<
RealVec
>
totalDipoles
;
amoebaReferenceMultipoleForce
->
calculateTotalDipoles
(
posData
,
charges
,
dipoles
,
quadrupoles
,
tholes
,
dampingFactors
,
polarity
,
axisTypes
,
multipoleAtomZs
,
multipoleAtomXs
,
multipoleAtomYs
,
multipoleAtomCovalentInfo
,
totalDipoles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
outputDipoles
[
i
]
=
totalDipoles
[
i
];
delete
amoebaReferenceMultipoleForce
;
}
void
ReferenceCalcAmoebaMultipoleForceKernel
::
getElectrostaticPotential
(
ContextImpl
&
context
,
const
std
::
vector
<
Vec3
>&
inputGrid
,
std
::
vector
<
double
>&
outputElectrostaticPotential
)
{
...
...
@@ -996,7 +1038,7 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A
epsilonCombiningRule
=
force
.
getEpsilonCombiningRule
();
useCutoff
=
(
force
.
getNonbondedMethod
()
!=
AmoebaVdwForce
::
NoCutoff
);
usePBC
=
(
force
.
getNonbondedMethod
()
==
AmoebaVdwForce
::
CutoffPeriodic
);
cutoff
=
force
.
getCutoff
();
cutoff
=
force
.
getCutoff
Distance
();
neighborList
=
useCutoff
?
new
NeighborList
()
:
NULL
;
dispersionCoefficient
=
force
.
getUseDispersionCorrection
()
?
AmoebaVdwForceImpl
::
calcDispersionCorrection
(
system
,
force
)
:
0.0
;
...
...
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h
View file @
a381a3ab
...
...
@@ -381,6 +381,20 @@ public:
* @param dipoles the induced dipole moment of particle i is stored into the i'th element
*/
void
getInducedDipoles
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
dipoles
);
/**
* Get the fixed dipole moments of all particles in the global reference frame.
*
* @param context the Context for which to get the fixed dipoles
* @param dipoles the fixed dipole moment of particle i is stored into the i'th element
*/
void
getLabFramePermanentDipoles
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
dipoles
);
/**
* Get the total dipole moments of all particles in the global reference frame.
*
* @param context the Context for which to get the fixed dipoles
* @param dipoles the fixed dipole moment of particle i is stored into the i'th element
*/
void
getTotalDipoles
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
dipoles
);
/**
* Calculate the electrostatic potential given vector of grid coordinates.
*
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
View file @
a381a3ab
...
...
@@ -1943,6 +1943,64 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipoles(const vector<RealVec
outputInducedDipoles
=
_inducedDipole
;
}
void
AmoebaReferenceMultipoleForce
::
calculateLabFramePermanentDipoles
(
const
vector
<
RealVec
>&
particlePositions
,
const
vector
<
RealOpenMM
>&
charges
,
const
vector
<
RealOpenMM
>&
dipoles
,
const
vector
<
RealOpenMM
>&
quadrupoles
,
const
vector
<
RealOpenMM
>&
tholes
,
const
vector
<
RealOpenMM
>&
dampingFactors
,
const
vector
<
RealOpenMM
>&
polarity
,
const
vector
<
int
>&
axisTypes
,
const
vector
<
int
>&
multipoleAtomZs
,
const
vector
<
int
>&
multipoleAtomXs
,
const
vector
<
int
>&
multipoleAtomYs
,
const
vector
<
vector
<
vector
<
int
>
>
>&
multipoleAtomCovalentInfo
,
vector
<
RealVec
>&
outputRotatedPermanentDipoles
)
{
// setup, including calculating permanent dipoles
vector
<
MultipoleParticleData
>
particleData
;
setup
(
particlePositions
,
charges
,
dipoles
,
quadrupoles
,
tholes
,
dampingFactors
,
polarity
,
axisTypes
,
multipoleAtomZs
,
multipoleAtomXs
,
multipoleAtomYs
,
multipoleAtomCovalentInfo
,
particleData
);
outputRotatedPermanentDipoles
.
resize
(
_numParticles
);
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
outputRotatedPermanentDipoles
[
i
]
=
particleData
[
i
].
dipole
;
}
}
void
AmoebaReferenceMultipoleForce
::
calculateTotalDipoles
(
const
vector
<
RealVec
>&
particlePositions
,
const
vector
<
RealOpenMM
>&
charges
,
const
vector
<
RealOpenMM
>&
dipoles
,
const
vector
<
RealOpenMM
>&
quadrupoles
,
const
vector
<
RealOpenMM
>&
tholes
,
const
vector
<
RealOpenMM
>&
dampingFactors
,
const
vector
<
RealOpenMM
>&
polarity
,
const
vector
<
int
>&
axisTypes
,
const
vector
<
int
>&
multipoleAtomZs
,
const
vector
<
int
>&
multipoleAtomXs
,
const
vector
<
int
>&
multipoleAtomYs
,
const
vector
<
vector
<
vector
<
int
>
>
>&
multipoleAtomCovalentInfo
,
vector
<
RealVec
>&
outputTotalDipoles
)
{
// setup, including calculating permanent dipoles
vector
<
MultipoleParticleData
>
particleData
;
setup
(
particlePositions
,
charges
,
dipoles
,
quadrupoles
,
tholes
,
dampingFactors
,
polarity
,
axisTypes
,
multipoleAtomZs
,
multipoleAtomXs
,
multipoleAtomYs
,
multipoleAtomCovalentInfo
,
particleData
);
outputTotalDipoles
.
resize
(
_numParticles
);
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
outputTotalDipoles
[
i
][
j
]
=
particleData
[
i
].
dipole
[
j
]
+
_inducedDipole
[
i
][
j
];
}
}
}
void
AmoebaReferenceMultipoleForce
::
calculateAmoebaSystemMultipoleMoments
(
const
vector
<
RealOpenMM
>&
masses
,
const
vector
<
RealVec
>&
particlePositions
,
const
vector
<
RealOpenMM
>&
charges
,
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h
View file @
a381a3ab
...
...
@@ -533,6 +533,75 @@ public:
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>
>
>&
multipoleAtomCovalentInfo
,
std
::
vector
<
RealVec
>&
outputInducedDipoles
);
/**
* Calculate particle permanent dipoles rotated in the lab frame.
*
* @param masses particle masses
* @param particlePositions Cartesian coordinates of particles
* @param charges scalar charges for each particle
* @param dipoles molecular frame dipoles for each particle
* @param quadrupoles molecular frame quadrupoles for each particle
* @param tholes Thole factors for each particle
* @param dampingFactors dampling factors for each particle
* @param polarity polarity for each particle
* @param axisTypes axis type (Z-then-X, ...) for each particle
* @param multipoleAtomZs indicies of particle specifying the molecular frame z-axis for each particle
* @param multipoleAtomXs indicies of particle specifying the molecular frame x-axis for each particle
* @param multipoleAtomYs indicies of particle specifying the molecular frame y-axis for each particle
* @param multipoleAtomCovalentInfo covalent info needed to set scaling factors
* @param outputMultipoleMoments output multipole moments
*/
void
calculateLabFramePermanentDipoles
(
const
std
::
vector
<
RealVec
>&
particlePositions
,
const
std
::
vector
<
RealOpenMM
>&
charges
,
const
std
::
vector
<
RealOpenMM
>&
dipoles
,
const
std
::
vector
<
RealOpenMM
>&
quadrupoles
,
const
std
::
vector
<
RealOpenMM
>&
tholes
,
const
std
::
vector
<
RealOpenMM
>&
dampingFactors
,
const
std
::
vector
<
RealOpenMM
>&
polarity
,
const
std
::
vector
<
int
>&
axisTypes
,
const
std
::
vector
<
int
>&
multipoleAtomZs
,
const
std
::
vector
<
int
>&
multipoleAtomXs
,
const
std
::
vector
<
int
>&
multipoleAtomYs
,
const
std
::
vector
<
vector
<
vector
<
int
>
>
>&
multipoleAtomCovalentInfo
,
std
::
vector
<
RealVec
>&
outputRotatedPermanentDipoles
);
/**
* Calculate particle total dipoles.
*
* @param masses particle masses
* @param particlePositions Cartesian coordinates of particles
* @param charges scalar charges for each particle
* @param dipoles molecular frame dipoles for each particle
* @param quadrupoles molecular frame quadrupoles for each particle
* @param tholes Thole factors for each particle
* @param dampingFactors dampling factors for each particle
* @param polarity polarity for each particle
* @param axisTypes axis type (Z-then-X, ...) for each particle
* @param multipoleAtomZs indicies of particle specifying the molecular frame z-axis for each particle
* @param multipoleAtomXs indicies of particle specifying the molecular frame x-axis for each particle
* @param multipoleAtomYs indicies of particle specifying the molecular frame y-axis for each particle
* @param multipoleAtomCovalentInfo covalent info needed to set scaling factors
* @param outputMultipoleMoments output multipole moments
*/
void
calculateTotalDipoles
(
const
std
::
vector
<
RealVec
>&
particlePositions
,
const
std
::
vector
<
RealOpenMM
>&
charges
,
const
std
::
vector
<
RealOpenMM
>&
dipoles
,
const
std
::
vector
<
RealOpenMM
>&
quadrupoles
,
const
std
::
vector
<
RealOpenMM
>&
tholes
,
const
std
::
vector
<
RealOpenMM
>&
dampingFactors
,
const
std
::
vector
<
RealOpenMM
>&
polarity
,
const
std
::
vector
<
int
>&
axisTypes
,
const
std
::
vector
<
int
>&
multipoleAtomZs
,
const
std
::
vector
<
int
>&
multipoleAtomXs
,
const
std
::
vector
<
int
>&
multipoleAtomYs
,
const
std
::
vector
<
vector
<
vector
<
int
>
>
>&
multipoleAtomCovalentInfo
,
std
::
vector
<
RealVec
>&
outputRotatedPermanentDipoles
);
/**
* Calculate system multipole moments.
*
...
...
plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp
View file @
a381a3ab
...
...
@@ -33,6 +33,9 @@
* This tests the Cuda implementation of CudaAmoebaAngleForce.
*/
#ifdef WIN32
#define _USE_MATH_DEFINES // Needed to get M_PI
#endif
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/CustomAngleForce.h"
...
...
plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp
View file @
a381a3ab
...
...
@@ -2587,6 +2587,76 @@ static void testParticleInducedDipoles() {
ASSERT_EQUAL_VEC
(
expectedDipole
[
i
],
dipole
[
i
],
1e-4
);
}
// test querying particle lab frame permanent dipoles
static
void
testParticleLabFramePermanentDipoles
()
{
int
numberOfParticles
=
8
;
int
inputPmeGridDimension
=
0
;
double
cutoff
=
9000000.0
;
std
::
vector
<
Vec3
>
forces
;
double
energy
;
System
system
;
AmoebaMultipoleForce
*
amoebaMultipoleForce
=
new
AmoebaMultipoleForce
();;
setupMultipoleAmmonia
(
system
,
amoebaMultipoleForce
,
AmoebaMultipoleForce
::
NoCutoff
,
AmoebaMultipoleForce
::
Mutual
,
cutoff
,
inputPmeGridDimension
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"Reference"
));
getForcesEnergyMultipoleAmmonia
(
context
,
forces
,
energy
);
std
::
vector
<
Vec3
>
dipole
;
amoebaMultipoleForce
->
getLabFramePermanentDipoles
(
context
,
dipole
);
// Compare to values calculated by TINKER.
std
::
vector
<
Vec3
>
expectedDipole
(
numberOfParticles
);
expectedDipole
[
0
]
=
Vec3
(
0.00876454250
,
-
2.04310718E-06
,
-
0.00227593519
);
expectedDipole
[
1
]
=
Vec3
(
0.000780382180
,
-
0.00432882849
,
0.00236926761
);
expectedDipole
[
2
]
=
Vec3
(
0.000801345883
,
0.00431830946
,
0.00238143437
);
expectedDipole
[
3
]
=
Vec3
(
-
0.00109746996
,
1.16087953e-5
,
-
0.00487407492
);
expectedDipole
[
4
]
=
Vec3
(
0.00203814102
,
-
2.26554196e-5
,
0.00882284298
);
expectedDipole
[
5
]
=
Vec3
(
-
0.00239443187
,
0.00432388648
,
0.000729303209
);
expectedDipole
[
6
]
=
Vec3
(
0.00491086743
,
2.86430963e-6
,
-
0.000918996348
);
expectedDipole
[
7
]
=
Vec3
(
-
0.00239301946
,
-
0.00432743976
,
0.000712674115
);
for
(
int
i
=
0
;
i
<
numberOfParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
expectedDipole
[
i
],
dipole
[
i
],
1e-4
);
}
// test querying particle total dipoles (fixed + induced)
static
void
testParticleTotalDipoles
()
{
int
numberOfParticles
=
8
;
int
inputPmeGridDimension
=
0
;
double
cutoff
=
9000000.0
;
std
::
vector
<
Vec3
>
forces
;
double
energy
;
System
system
;
AmoebaMultipoleForce
*
amoebaMultipoleForce
=
new
AmoebaMultipoleForce
();;
setupMultipoleAmmonia
(
system
,
amoebaMultipoleForce
,
AmoebaMultipoleForce
::
NoCutoff
,
AmoebaMultipoleForce
::
Mutual
,
cutoff
,
inputPmeGridDimension
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"Reference"
));
getForcesEnergyMultipoleAmmonia
(
context
,
forces
,
energy
);
std
::
vector
<
Vec3
>
dipole
;
amoebaMultipoleForce
->
getTotalDipoles
(
context
,
dipole
);
// Compare to values calculated by TINKER.
std
::
vector
<
Vec3
>
expectedDipole
(
numberOfParticles
);
expectedDipole
[
0
]
=
Vec3
(
0.0119356307
,
-
1.11302433e-6
,
-
0.00296793872
);
expectedDipole
[
1
]
=
Vec3
(
8.60636211e-4
,
-
0.00460821816
,
0.00241705344
);
expectedDipole
[
2
]
=
Vec3
(
8.80646403e-4
,
0.00459728769
,
0.00243013245
);
expectedDipole
[
3
]
=
Vec3
(
-
0.00123822377
,
1.31555550e-5
,
-
0.00558185336
);
expectedDipole
[
4
]
=
Vec3
(
0.00399455556
,
-
2.27511931e-5
,
0.00955607952
);
expectedDipole
[
5
]
=
Vec3
(
-
0.00157302682
,
0.00354892386
,
3.40921137e-4
);
expectedDipole
[
6
]
=
Vec3
(
0.00952428069
,
2.14171505e-6
,
-
6.68945865e-4
);
expectedDipole
[
7
]
=
Vec3
(
-
0.00157252460
,
-
0.00355015528
,
3.27055162e-4
);
for
(
int
i
=
0
;
i
<
numberOfParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
expectedDipole
[
i
],
dipole
[
i
],
1e-4
);
}
// test computation of system multipole moments
static
void
testSystemMultipoleMoments
()
{
...
...
plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp
View file @
a381a3ab
...
...
@@ -74,20 +74,18 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode&
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setIntProperty
(
"nonbondedMethod"
,
force
.
getNonbondedMethod
());
node
.
setIntProperty
(
"polarizationType"
,
force
.
getPolarizationType
());
//node.setIntProperty("pmeBSplineOrder", force.getPmeBSplineOrder());
//node.setIntProperty("mutualInducedIterationMethod", force.getMutualInducedIterationMethod());
node
.
setIntProperty
(
"mutualInducedMaxIterations"
,
force
.
getMutualInducedMaxIterations
());
node
.
setDoubleProperty
(
"cutoffDistance"
,
force
.
getCutoffDistance
());
node
.
setDoubleProperty
(
"aEwald"
,
force
.
getAEwald
());
double
alpha
;
int
nx
,
ny
,
nz
;
force
.
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
node
.
setDoubleProperty
(
"aEwald"
,
alpha
);
node
.
setDoubleProperty
(
"mutualInducedTargetEpsilon"
,
force
.
getMutualInducedTargetEpsilon
());
//node.setDoubleProperty("electricConstant", force.getElectricConstant());
node
.
setDoubleProperty
(
"ewaldErrorTolerance"
,
force
.
getEwaldErrorTolerance
());
std
::
vector
<
int
>
gridDimensions
;
force
.
getPmeGridDimensions
(
gridDimensions
);
SerializationNode
&
gridDimensionsNode
=
node
.
createChildNode
(
"MultipoleParticleGridDimension"
);
gridDimensionsNode
.
setIntProperty
(
"d0"
,
gridDimensions
[
0
]
).
setIntProperty
(
"d1"
,
gridDimensions
[
1
]
).
setIntProperty
(
"d2"
,
gridDimensions
[
2
]
);
gridDimensionsNode
.
setIntProperty
(
"d0"
,
nx
).
setIntProperty
(
"d1"
,
ny
).
setIntProperty
(
"d2"
,
nz
);
SerializationNode
&
coefficients
=
node
.
createChildNode
(
"ExtrapolationCoefficients"
);
vector
<
double
>
coeff
=
force
.
getExtrapolationCoefficients
();
...
...
@@ -144,22 +142,14 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons
force
->
setNonbondedMethod
(
static_cast
<
AmoebaMultipoleForce
::
NonbondedMethod
>
(
node
.
getIntProperty
(
"nonbondedMethod"
)));
if
(
version
>=
2
)
force
->
setPolarizationType
(
static_cast
<
AmoebaMultipoleForce
::
PolarizationType
>
(
node
.
getIntProperty
(
"polarizationType"
)));
//force->setPmeBSplineOrder(node.getIntProperty("pmeBSplineOrder"));
//force->setMutualInducedIterationMethod(static_cast<AmoebaMultipoleForce::MutualInducedIterationMethod>(node.getIntProperty("mutualInducedIterationMethod")));
force
->
setMutualInducedMaxIterations
(
node
.
getIntProperty
(
"mutualInducedMaxIterations"
));
force
->
setCutoffDistance
(
node
.
getDoubleProperty
(
"cutoffDistance"
));
force
->
setAEwald
(
node
.
getDoubleProperty
(
"aEwald"
));
force
->
setMutualInducedTargetEpsilon
(
node
.
getDoubleProperty
(
"mutualInducedTargetEpsilon"
));
//force->setElectricConstant(node.getDoubleProperty("electricConstant"));
force
->
setEwaldErrorTolerance
(
node
.
getDoubleProperty
(
"ewaldErrorTolerance"
));
std
::
vector
<
int
>
gridDimensions
;
const
SerializationNode
&
gridDimensionsNode
=
node
.
getChildNode
(
"MultipoleParticleGridDimension"
);
gridDimensions
.
push_back
(
gridDimensionsNode
.
getIntProperty
(
"d0"
));
gridDimensions
.
push_back
(
gridDimensionsNode
.
getIntProperty
(
"d1"
));
gridDimensions
.
push_back
(
gridDimensionsNode
.
getIntProperty
(
"d2"
));
force
->
setPmeGridDimensions
(
gridDimensions
);
force
->
setPMEParameters
(
node
.
getDoubleProperty
(
"aEwald"
),
gridDimensionsNode
.
getIntProperty
(
"d0"
),
gridDimensionsNode
.
getIntProperty
(
"d1"
),
gridDimensionsNode
.
getIntProperty
(
"d2"
));
if
(
version
>=
3
)
{
const
SerializationNode
&
coefficients
=
node
.
getChildNode
(
"ExtrapolationCoefficients"
);
...
...
plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp
View file @
a381a3ab
...
...
@@ -48,7 +48,7 @@ void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node)
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setStringProperty
(
"SigmaCombiningRule"
,
force
.
getSigmaCombiningRule
());
node
.
setStringProperty
(
"EpsilonCombiningRule"
,
force
.
getEpsilonCombiningRule
());
node
.
setDoubleProperty
(
"VdwCutoff"
,
force
.
getCutoff
());
node
.
setDoubleProperty
(
"VdwCutoff"
,
force
.
getCutoff
Distance
());
node
.
setIntProperty
(
"method"
,
(
int
)
force
.
getNonbondedMethod
());
...
...
@@ -82,7 +82,7 @@ void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const {
force
->
setForceGroup
(
node
.
getIntProperty
(
"forceGroup"
,
0
));
force
->
setSigmaCombiningRule
(
node
.
getStringProperty
(
"SigmaCombiningRule"
));
force
->
setEpsilonCombiningRule
(
node
.
getStringProperty
(
"EpsilonCombiningRule"
));
force
->
setCutoff
(
node
.
getDoubleProperty
(
"VdwCutoff"
));
force
->
setCutoff
Distance
(
node
.
getDoubleProperty
(
"VdwCutoff"
));
force
->
setNonbondedMethod
((
AmoebaVdwForce
::
NonbondedMethod
)
node
.
getIntProperty
(
"method"
));
const
SerializationNode
&
particles
=
node
.
getChildNode
(
"VdwParticles"
);
...
...
plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp
View file @
a381a3ab
...
...
@@ -116,11 +116,8 @@ void testSerialization() {
ASSERT_EQUAL
(
force1
.
getCutoffDistance
(),
force2
.
getCutoffDistance
());
ASSERT_EQUAL
(
force1
.
getNonbondedMethod
(),
force2
.
getNonbondedMethod
());
ASSERT_EQUAL
(
force1
.
getAEwald
(),
force2
.
getAEwald
());
//ASSERT_EQUAL(force1.getPmeBSplineOrder(), force2.getPmeBSplineOrder());
//ASSERT_EQUAL(force1.getMutualInducedIterationMethod(), force2.getMutualInducedIterationMethod());
ASSERT_EQUAL
(
force1
.
getMutualInducedMaxIterations
(),
force2
.
getMutualInducedMaxIterations
());
ASSERT_EQUAL
(
force1
.
getMutualInducedTargetEpsilon
(),
force2
.
getMutualInducedTargetEpsilon
());
//ASSERT_EQUAL(force1.getElectricConstant(), force2.getElectricConstant());
ASSERT_EQUAL
(
force1
.
getEwaldErrorTolerance
(),
force2
.
getEwaldErrorTolerance
());
...
...
plugins/drude/platforms/cuda/src/CudaDrudeKernels.cpp
View file @
a381a3ab
...
...
@@ -364,9 +364,11 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
// Apply hard wall constraints.
if
(
maxDrudeDistance
>
0
)
{
void
*
hardwallArgs
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
posCorrection
,
&
cu
.
getVelm
().
getDevicePointer
(),
&
pairParticles
->
getDevicePointer
(),
&
integration
.
getStepSize
().
getDevicePointer
(),
maxDrudeDistancePtr
,
hardwallscaleDrudePtr
};
cu
.
executeKernel
(
hardwallKernel
,
hardwallArgs
,
pairParticles
->
getSize
());
}
integration
.
computeVirtualSites
();
// Update the time and step count.
...
...
plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
View file @
a381a3ab
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2013-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -179,6 +179,66 @@ void testWater() {
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
(
"CUDA"
);
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
{
registerDrudeCudaKernelFactories
();
...
...
@@ -186,6 +246,7 @@ int main(int argc, char* argv[]) {
Platform
::
getPlatformByName
(
"CUDA"
).
setPropertyDefaultValue
(
"Precision"
,
string
(
argv
[
1
]));
testSinglePair
();
testWater
();
testForceEnergyConsistency
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
...
...
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
View file @
a381a3ab
...
...
@@ -376,6 +376,7 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
// Apply hard wall constraints.
if
(
maxDrudeDistance
>
0
)
cl
.
executeKernel
(
hardwallKernel
,
pairParticles
->
getSize
());
integration
.
computeVirtualSites
();
...
...
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
View file @
a381a3ab
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2013-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -179,6 +179,66 @@ void testWater() {
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
();
...
...
@@ -186,6 +246,7 @@ int main(int argc, char* argv[]) {
Platform
::
getPlatformByName
(
"OpenCL"
).
setPropertyDefaultValue
(
"Precision"
,
string
(
argv
[
1
]));
testSinglePair
();
testWater
();
testForceEnergyConsistency
();
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
...
...
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
View file @
a381a3ab
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2013-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -179,11 +179,72 @@ void testWater() {
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
;
...
...
serialization/src/CustomAngleForceProxy.cpp
View file @
a381a3ab
...
...
@@ -42,7 +42,7 @@ CustomAngleForceProxy::CustomAngleForceProxy() : SerializationProxy("CustomAngle
}
void
CustomAngleForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
2
);
node
.
setIntProperty
(
"version"
,
3
);
const
CustomAngleForce
&
force
=
*
reinterpret_cast
<
const
CustomAngleForce
*>
(
object
);
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setBoolProperty
(
"usesPeriodic"
,
force
.
usesPeriodicBoundaryConditions
());
...
...
@@ -55,6 +55,10 @@ void CustomAngleForceProxy::serialize(const void* object, SerializationNode& nod
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
globalParams
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getGlobalParameterName
(
i
)).
setDoubleProperty
(
"default"
,
force
.
getGlobalParameterDefaultValue
(
i
));
}
SerializationNode
&
energyDerivs
=
node
.
createChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
energyDerivs
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getEnergyParameterDerivativeName
(
i
));
}
SerializationNode
&
angles
=
node
.
createChildNode
(
"Angles"
);
for
(
int
i
=
0
;
i
<
force
.
getNumAngles
();
i
++
)
{
int
p1
,
p2
,
p3
;
...
...
@@ -72,7 +76,7 @@ void CustomAngleForceProxy::serialize(const void* object, SerializationNode& nod
void
*
CustomAngleForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
int
version
=
node
.
getIntProperty
(
"version"
);
if
(
version
<
1
||
version
>
2
)
if
(
version
<
1
||
version
>
3
)
throw
OpenMMException
(
"Unsupported version number"
);
CustomAngleForce
*
force
=
NULL
;
try
{
...
...
@@ -90,6 +94,13 @@ void* CustomAngleForceProxy::deserialize(const SerializationNode& node) const {
const
SerializationNode
&
parameter
=
globalParams
.
getChildren
()[
i
];
force
->
addGlobalParameter
(
parameter
.
getStringProperty
(
"name"
),
parameter
.
getDoubleProperty
(
"default"
));
}
if
(
version
>
2
)
{
const
SerializationNode
&
energyDerivs
=
node
.
getChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
(
int
)
energyDerivs
.
getChildren
().
size
();
i
++
)
{
const
SerializationNode
&
parameter
=
energyDerivs
.
getChildren
()[
i
];
force
->
addEnergyParameterDerivative
(
parameter
.
getStringProperty
(
"name"
));
}
}
const
SerializationNode
&
angles
=
node
.
getChildNode
(
"Angles"
);
vector
<
double
>
params
(
force
->
getNumPerAngleParameters
());
for
(
int
i
=
0
;
i
<
(
int
)
angles
.
getChildren
().
size
();
i
++
)
{
...
...
serialization/src/CustomBondForceProxy.cpp
View file @
a381a3ab
...
...
@@ -42,7 +42,7 @@ CustomBondForceProxy::CustomBondForceProxy() : SerializationProxy("CustomBondFor
}
void
CustomBondForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
2
);
node
.
setIntProperty
(
"version"
,
3
);
const
CustomBondForce
&
force
=
*
reinterpret_cast
<
const
CustomBondForce
*>
(
object
);
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setBoolProperty
(
"usesPeriodic"
,
force
.
usesPeriodicBoundaryConditions
());
...
...
@@ -55,6 +55,10 @@ void CustomBondForceProxy::serialize(const void* object, SerializationNode& node
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
globalParams
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getGlobalParameterName
(
i
)).
setDoubleProperty
(
"default"
,
force
.
getGlobalParameterDefaultValue
(
i
));
}
SerializationNode
&
energyDerivs
=
node
.
createChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
energyDerivs
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getEnergyParameterDerivativeName
(
i
));
}
SerializationNode
&
bonds
=
node
.
createChildNode
(
"Bonds"
);
for
(
int
i
=
0
;
i
<
force
.
getNumBonds
();
i
++
)
{
int
p1
,
p2
;
...
...
@@ -72,7 +76,7 @@ void CustomBondForceProxy::serialize(const void* object, SerializationNode& node
void
*
CustomBondForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
int
version
=
node
.
getIntProperty
(
"version"
);
if
(
version
<
1
||
version
>
2
)
if
(
version
<
1
||
version
>
3
)
throw
OpenMMException
(
"Unsupported version number"
);
CustomBondForce
*
force
=
NULL
;
try
{
...
...
@@ -90,6 +94,13 @@ void* CustomBondForceProxy::deserialize(const SerializationNode& node) const {
const
SerializationNode
&
parameter
=
globalParams
.
getChildren
()[
i
];
force
->
addGlobalParameter
(
parameter
.
getStringProperty
(
"name"
),
parameter
.
getDoubleProperty
(
"default"
));
}
if
(
version
>
2
)
{
const
SerializationNode
&
energyDerivs
=
node
.
getChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
(
int
)
energyDerivs
.
getChildren
().
size
();
i
++
)
{
const
SerializationNode
&
parameter
=
energyDerivs
.
getChildren
()[
i
];
force
->
addEnergyParameterDerivative
(
parameter
.
getStringProperty
(
"name"
));
}
}
const
SerializationNode
&
bonds
=
node
.
getChildNode
(
"Bonds"
);
vector
<
double
>
params
(
force
->
getNumPerBondParameters
());
for
(
int
i
=
0
;
i
<
(
int
)
bonds
.
getChildren
().
size
();
i
++
)
{
...
...
serialization/src/CustomCentroidBondForceProxy.cpp
View file @
a381a3ab
...
...
@@ -42,7 +42,7 @@ CustomCentroidBondForceProxy::CustomCentroidBondForceProxy() : SerializationProx
}
void
CustomCentroidBondForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
2
);
node
.
setIntProperty
(
"version"
,
3
);
const
CustomCentroidBondForce
&
force
=
*
reinterpret_cast
<
const
CustomCentroidBondForce
*>
(
object
);
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setBoolProperty
(
"usesPeriodic"
,
force
.
usesPeriodicBoundaryConditions
());
...
...
@@ -56,6 +56,10 @@ void CustomCentroidBondForceProxy::serialize(const void* object, SerializationNo
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
globalParams
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getGlobalParameterName
(
i
)).
setDoubleProperty
(
"default"
,
force
.
getGlobalParameterDefaultValue
(
i
));
}
SerializationNode
&
energyDerivs
=
node
.
createChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
energyDerivs
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getEnergyParameterDerivativeName
(
i
));
}
SerializationNode
&
groups
=
node
.
createChildNode
(
"Groups"
);
for
(
int
i
=
0
;
i
<
force
.
getNumGroups
();
i
++
)
{
vector
<
int
>
particles
;
...
...
@@ -95,7 +99,7 @@ void CustomCentroidBondForceProxy::serialize(const void* object, SerializationNo
void
*
CustomCentroidBondForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
int
version
=
node
.
getIntProperty
(
"version"
);
if
(
version
<
1
||
version
>
2
)
if
(
version
<
1
||
version
>
3
)
throw
OpenMMException
(
"Unsupported version number"
);
CustomCentroidBondForce
*
force
=
NULL
;
try
{
...
...
@@ -113,6 +117,13 @@ void* CustomCentroidBondForceProxy::deserialize(const SerializationNode& node) c
const
SerializationNode
&
parameter
=
globalParams
.
getChildren
()[
i
];
force
->
addGlobalParameter
(
parameter
.
getStringProperty
(
"name"
),
parameter
.
getDoubleProperty
(
"default"
));
}
if
(
version
>
2
)
{
const
SerializationNode
&
energyDerivs
=
node
.
getChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
(
int
)
energyDerivs
.
getChildren
().
size
();
i
++
)
{
const
SerializationNode
&
parameter
=
energyDerivs
.
getChildren
()[
i
];
force
->
addEnergyParameterDerivative
(
parameter
.
getStringProperty
(
"name"
));
}
}
const
SerializationNode
&
groups
=
node
.
getChildNode
(
"Groups"
);
for
(
int
i
=
0
;
i
<
(
int
)
groups
.
getChildren
().
size
();
i
++
)
{
const
SerializationNode
&
group
=
groups
.
getChildren
()[
i
];
...
...
Prev
1
…
4
5
6
7
8
9
10
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