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
46f604a1
Commit
46f604a1
authored
Feb 08, 2017
by
peastman
Committed by
GitHub
Feb 08, 2017
Browse files
Merge pull request #4 from peastman/ljpme
Revised calculation for dispersion PME grid size
parents
52c7e744
edfcdec3
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
74 additions
and
12 deletions
+74
-12
docs-source/usersguide/theory.rst
docs-source/usersguide/theory.rst
+1
-1
openmmapi/src/NonbondedForceImpl.cpp
openmmapi/src/NonbondedForceImpl.cpp
+3
-3
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+10
-2
platforms/cuda/src/kernels/pme.cu
platforms/cuda/src/kernels/pme.cu
+1
-1
tests/TestDispersionPME.h
tests/TestDispersionPME.h
+59
-5
No files found.
docs-source/usersguide/theory.rst
View file @
46f604a1
...
@@ -458,7 +458,7 @@ The formula used to compute the number of nodes along each dimension of the mesh
...
@@ -458,7 +458,7 @@ The formula used to compute the number of nodes along each dimension of the mesh
is slightly different from the one used for Coulomb interactions:
is slightly different from the one used for Coulomb interactions:
.. math::
.. math::
n_\mathit{mesh}=\frac{\alpha d}{{3\delta}^{1/
20
}}
n_\mathit{mesh}=\frac{\alpha d}{{3\delta}^{1/
5
}}
As before, this is an empirical formula. It will usually produce an average
As before, this is an empirical formula. It will usually produce an average
relative error in the forces less than or similar to :math:`\delta`\ , but that
relative error in the forces less than or similar to :math:`\delta`\ , but that
...
...
openmmapi/src/NonbondedForceImpl.cpp
View file @
46f604a1
...
@@ -160,9 +160,9 @@ void NonbondedForceImpl::calcPMEParameters(const System& system, const Nonbonded
...
@@ -160,9 +160,9 @@ void NonbondedForceImpl::calcPMEParameters(const System& system, const Nonbonded
double
tol
=
force
.
getEwaldErrorTolerance
();
double
tol
=
force
.
getEwaldErrorTolerance
();
alpha
=
(
1.0
/
force
.
getCutoffDistance
())
*
std
::
sqrt
(
-
log
(
2.0
*
tol
));
alpha
=
(
1.0
/
force
.
getCutoffDistance
())
*
std
::
sqrt
(
-
log
(
2.0
*
tol
));
if
(
lj
)
{
if
(
lj
)
{
xsize
=
(
int
)
ceil
(
alpha
*
boxVectors
[
0
][
0
]
/
(
3
*
pow
(
tol
,
0.
05
)));
xsize
=
(
int
)
ceil
(
alpha
*
boxVectors
[
0
][
0
]
/
(
3
*
pow
(
tol
,
0.
2
)));
ysize
=
(
int
)
ceil
(
alpha
*
boxVectors
[
1
][
1
]
/
(
3
*
pow
(
tol
,
0.
05
)));
ysize
=
(
int
)
ceil
(
alpha
*
boxVectors
[
1
][
1
]
/
(
3
*
pow
(
tol
,
0.
2
)));
zsize
=
(
int
)
ceil
(
alpha
*
boxVectors
[
2
][
2
]
/
(
3
*
pow
(
tol
,
0.
05
)));
zsize
=
(
int
)
ceil
(
alpha
*
boxVectors
[
2
][
2
]
/
(
3
*
pow
(
tol
,
0.
2
)));
}
}
else
{
else
{
xsize
=
(
int
)
ceil
(
2
*
alpha
*
boxVectors
[
0
][
0
]
/
(
3
*
pow
(
tol
,
0.2
)));
xsize
=
(
int
)
ceil
(
2
*
alpha
*
boxVectors
[
0
][
0
]
/
(
3
*
pow
(
tol
,
0.2
)));
...
...
platforms/cuda/src/CudaKernels.cpp
View file @
46f604a1
...
@@ -1623,12 +1623,18 @@ CudaCalcNonbondedForceKernel::~CudaCalcNonbondedForceKernel() {
...
@@ -1623,12 +1623,18 @@ CudaCalcNonbondedForceKernel::~CudaCalcNonbondedForceKernel() {
delete sort;
delete sort;
if (fft != NULL)
if (fft != NULL)
delete fft;
delete fft;
if (dispersionFft != NULL)
delete dispersionFft;
if (pmeio != NULL)
if (pmeio != NULL)
delete pmeio;
delete pmeio;
if (hasInitializedFFT) {
if (hasInitializedFFT) {
if (useCudaFFT) {
if (useCudaFFT) {
cufftDestroy(fftForward);
cufftDestroy(fftForward);
cufftDestroy(fftBackward);
cufftDestroy(fftBackward);
if (doLJPME) {
cufftDestroy(dispersionFftForward);
cufftDestroy(dispersionFftBackward);
}
}
}
if (usePmeStream) {
if (usePmeStream) {
cuStreamDestroy(pmeStream);
cuStreamDestroy(pmeStream);
...
@@ -1911,6 +1917,8 @@ void CudaCalcNonbondedForceKernel::initialize(const System& system, const Nonbon
...
@@ -1911,6 +1917,8 @@ void CudaCalcNonbondedForceKernel::initialize(const System& system, const Nonbon
if (useCudaFFT) {
if (useCudaFFT) {
cufftSetStream(fftForward, pmeStream);
cufftSetStream(fftForward, pmeStream);
cufftSetStream(fftBackward, pmeStream);
cufftSetStream(fftBackward, pmeStream);
cufftSetStream(dispersionFftForward, pmeStream);
cufftSetStream(dispersionFftBackward, pmeStream);
}
}
CHECK_RESULT(cuEventCreate(&pmeSyncEvent, CU_EVENT_DISABLE_TIMING), "Error creating event for NonbondedForce");
CHECK_RESULT(cuEventCreate(&pmeSyncEvent, CU_EVENT_DISABLE_TIMING), "Error creating event for NonbondedForce");
int recipForceGroup = force.getReciprocalSpaceForceGroup();
int recipForceGroup = force.getReciprocalSpaceForceGroup();
...
@@ -2170,7 +2178,7 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF
...
@@ -2170,7 +2178,7 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF
cufftExecR2C(dispersionFftForward, (float*) directPmeGrid->getDevicePointer(), (float2*) reciprocalPmeGrid->getDevicePointer());
cufftExecR2C(dispersionFftForward, (float*) directPmeGrid->getDevicePointer(), (float2*) reciprocalPmeGrid->getDevicePointer());
}
}
else {
else {
f
ft->execFFT(*directPmeGrid, *reciprocalPmeGrid, true);
dispersionF
ft->execFFT(*directPmeGrid, *reciprocalPmeGrid, true);
}
}
if (includeEnergy) {
if (includeEnergy) {
...
@@ -2192,7 +2200,7 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF
...
@@ -2192,7 +2200,7 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF
cufftExecC2R(dispersionFftBackward, (float2*) reciprocalPmeGrid->getDevicePointer(), (float*) directPmeGrid->getDevicePointer());
cufftExecC2R(dispersionFftBackward, (float2*) reciprocalPmeGrid->getDevicePointer(), (float*) directPmeGrid->getDevicePointer());
}
}
else {
else {
f
ft->execFFT(*reciprocalPmeGrid, *directPmeGrid, false);
dispersionF
ft->execFFT(*reciprocalPmeGrid, *directPmeGrid, false);
}
}
void* interpolateArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &directPmeGrid->getDevicePointer(), cu.getPeriodicBoxSizePointer(),
void* interpolateArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &directPmeGrid->getDevicePointer(), cu.getPeriodicBoxSizePointer(),
...
...
platforms/cuda/src/kernels/pme.cu
View file @
46f604a1
...
@@ -238,7 +238,7 @@ gridEvaluateEnergy(real2* __restrict__ halfcomplex_pmeGrid, mixed* __restrict__
...
@@ -238,7 +238,7 @@ gridEvaluateEnergy(real2* __restrict__ halfcomplex_pmeGrid, mixed* __restrict__
#endif
#endif
energy
+=
eterm
*
(
grid
.
x
*
grid
.
x
+
grid
.
y
*
grid
.
y
);
energy
+=
eterm
*
(
grid
.
x
*
grid
.
x
+
grid
.
y
*
grid
.
y
);
}
}
#ifdef
USE_PME_STREAM
#if
def
ined(
USE_PME_STREAM
) && !defined(USE_LJPME)
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
=
0.5
f
*
energy
;
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
=
0.5
f
*
energy
;
#else
#else
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
+=
0.5
f
*
energy
;
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
+=
0.5
f
*
energy
;
...
...
tests/TestDispersionPME.h
View file @
46f604a1
...
@@ -43,8 +43,60 @@
...
@@ -43,8 +43,60 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
void
testConvergence
()
{
// Create a cloud of random particles.
const
int
numParticles
=
1000
;
const
double
boxWidth
=
6.0
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxWidth
,
0
,
0
),
Vec3
(
0
,
boxWidth
,
0
),
Vec3
(
0
,
0
,
boxWidth
));
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
0.0
,
0.1
+
0.3
*
genrand_real2
(
sfmt
),
genrand_real2
(
sfmt
));
while
(
true
)
{
Vec3
pos
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
double
minDist
=
boxWidth
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
Vec3
delta
=
pos
-
positions
[
j
];
minDist
=
min
(
minDist
,
sqrt
(
delta
.
dot
(
delta
)));
}
if
(
minDist
>
0.15
)
{
positions
[
i
]
=
pos
;
break
;
}
}
}
// Compute the energy with short and long cutoffs, and compare them to LJPME.
// The long cutoff should match the LJPME result better than the short cutoff.
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
force
->
setCutoffDistance
(
1.0
);
force
->
setEwaldErrorTolerance
(
1e-5
);
force
->
setUseDispersionCorrection
(
false
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
double
pmeEnergy
=
context
.
getState
(
State
::
Energy
,
false
,
1
).
getPotentialEnergy
();
force
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
double
shortEnergy
=
context
.
getState
(
State
::
Energy
,
false
,
1
).
getPotentialEnergy
();
force
->
setCutoffDistance
(
3.0
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
double
longEnergy
=
context
.
getState
(
State
::
Energy
,
false
,
1
).
getPotentialEnergy
();
ASSERT
(
fabs
(
longEnergy
-
pmeEnergy
)
<
fabs
(
shortEnergy
-
pmeEnergy
))
}
void
testErrorTolerance
()
{
void
testErrorTolerance
()
{
// Create a cloud of random p
oint charg
es.
// Create a cloud of random p
articl
es.
const
int
numParticles
=
200
;
const
int
numParticles
=
200
;
const
double
boxWidth
=
5.0
;
const
double
boxWidth
=
5.0
;
...
@@ -118,7 +170,7 @@ void testErrorTolerance() {
...
@@ -118,7 +170,7 @@ void testErrorTolerance() {
}
}
void
testPMEParameters
()
{
void
testPMEParameters
()
{
// Create a cloud of random p
oint charg
es.
// Create a cloud of random p
articl
es.
const
int
numParticles
=
51
;
const
int
numParticles
=
51
;
const
double
boxWidth
=
4.7
;
const
double
boxWidth
=
4.7
;
...
@@ -136,10 +188,11 @@ void testPMEParameters() {
...
@@ -136,10 +188,11 @@ void testPMEParameters() {
positions
[
i
]
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
positions
[
i
]
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
}
}
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
force
->
setCutoffDistance
(
0.5
);
// Compute the energy with an error tolerance of
1e-3
.
// Compute the energy with an error tolerance of
0.1
.
force
->
setEwaldErrorTolerance
(
1e-3
);
force
->
setEwaldErrorTolerance
(
0.1
);
VerletIntegrator
integrator1
(
0.01
);
VerletIntegrator
integrator1
(
0.01
);
Context
context1
(
system
,
integrator1
,
platform
);
Context
context1
(
system
,
integrator1
,
platform
);
context1
.
setPositions
(
positions
);
context1
.
setPositions
(
positions
);
...
@@ -157,7 +210,7 @@ void testPMEParameters() {
...
@@ -157,7 +210,7 @@ void testPMEParameters() {
double
energy2
=
context2
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
double
energy2
=
context2
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
// Now explicitly set the parameters. These should match the values that were
// Now explicitly set the parameters. These should match the values that were
// used for tolerance
1e-3
.
// used for tolerance
0.1
.
force
->
setLJPMEParameters
(
alpha
,
gridx
,
gridy
,
gridz
);
force
->
setLJPMEParameters
(
alpha
,
gridx
,
gridy
,
gridz
);
VerletIntegrator
integrator3
(
0.01
);
VerletIntegrator
integrator3
(
0.01
);
...
@@ -1806,6 +1859,7 @@ void runPlatformTests();
...
@@ -1806,6 +1859,7 @@ void runPlatformTests();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
try
{
initializeTests
(
argc
,
argv
);
initializeTests
(
argc
,
argv
);
testConvergence
();
testErrorTolerance
();
testErrorTolerance
();
testPMEParameters
();
testPMEParameters
();
testWater2DpmeEnergiesForcesNoExclusions
();
testWater2DpmeEnergiesForcesNoExclusions
();
...
...
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