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
83d57922
Commit
83d57922
authored
Jul 02, 2009
by
Peter Eastman
Browse files
Automatically select Ewald parameters based on error tolerance
parent
9eb02774
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
132 additions
and
140 deletions
+132
-140
openmmapi/include/openmm/NonbondedForce.h
openmmapi/include/openmm/NonbondedForce.h
+17
-3
openmmapi/src/NonbondedForce.cpp
openmmapi/src/NonbondedForce.cpp
+10
-1
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+10
-2
platforms/cuda/src/kernels/cudatypes.h
platforms/cuda/src/kernels/cudatypes.h
+3
-1
platforms/cuda/src/kernels/gpu.cpp
platforms/cuda/src/kernels/gpu.cpp
+5
-6
platforms/cuda/src/kernels/gputypes.h
platforms/cuda/src/kernels/gputypes.h
+1
-1
platforms/cuda/src/kernels/kCalculateCDLJEwaldFastReciprocal.h
...orms/cuda/src/kernels/kCalculateCDLJEwaldFastReciprocal.h
+15
-17
platforms/cuda/src/kernels/kCalculateCDLJEwaldReciprocal.h
platforms/cuda/src/kernels/kCalculateCDLJEwaldReciprocal.h
+5
-5
platforms/cuda/src/kernels/kCalculateCDLJForces.h
platforms/cuda/src/kernels/kCalculateCDLJForces.h
+5
-6
platforms/cuda/tests/TestCudaNonbondedForce.cpp
platforms/cuda/tests/TestCudaNonbondedForce.cpp
+4
-3
platforms/reference/src/ReferenceKernels.cpp
platforms/reference/src/ReferenceKernels.cpp
+17
-15
platforms/reference/src/ReferenceKernels.h
platforms/reference/src/ReferenceKernels.h
+2
-1
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+23
-47
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.h
...orms/reference/src/SimTKReference/ReferenceLJCoulombIxn.h
+12
-7
platforms/reference/src/SimTKReference/ReferencePairIxn.h
platforms/reference/src/SimTKReference/ReferencePairIxn.h
+0
-23
platforms/reference/tests/TestReferenceEwald.cpp
platforms/reference/tests/TestReferenceEwald.cpp
+3
-2
No files found.
openmmapi/include/openmm/NonbondedForce.h
View file @
83d57922
...
...
@@ -119,14 +119,28 @@ public:
void
setNonbondedMethod
(
NonbondedMethod
method
);
/**
* Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use
*
does not use c
utoff
s
, this value will have no effect.
*
is NoC
utoff, this value will have no effect.
*/
double
getCutoffDistance
()
const
;
/**
* Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use
*
does not use c
utoff
s
, this value will have no effect.
*
is NoC
utoff, this value will have no effect.
*/
void
setCutoffDistance
(
double
distance
);
/**
* Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces
* which is acceptable. This value is used to select the reciprocal space cutoff and separation
* parameter so that the average error level will be less than the tolerance. There is not a
* rigorous guarantee that all forces on all atoms will be less than the tolerance, however.
*/
double
getEwaldErrorTolerance
()
const
;
/**
* Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces
* which is acceptable. This value is used to select the reciprocal space cutoff and separation
* parameter so that the average error level will be less than the tolerance. There is not a
* rigorous guarantee that all forces on all atoms will be less than the tolerance, however.
*/
void
setEwaldErrorTolerance
(
double
tol
);
/**
* Get the vectors which define the axes of the periodic box (measured in nm). If the NonbondedMethod
* in use does not use periodic boundary conditions, these values will have no effect.
...
...
@@ -242,7 +256,7 @@ private:
class
ParticleInfo
;
class
ExceptionInfo
;
NonbondedMethod
nonbondedMethod
;
double
cutoffDistance
;
double
cutoffDistance
,
ewaldErrorTol
;
Vec3
periodicBoxVectors
[
3
];
void
addExclusionsToSet
(
const
std
::
vector
<
std
::
set
<
int
>
>&
bonded12
,
std
::
set
<
int
>&
exclusions
,
int
baseParticle
,
int
fromParticle
,
int
currentLevel
)
const
;
...
...
openmmapi/src/NonbondedForce.cpp
View file @
83d57922
...
...
@@ -41,7 +41,7 @@ using std::pair;
using
std
::
set
;
using
std
::
vector
;
NonbondedForce
::
NonbondedForce
()
:
nonbondedMethod
(
NoCutoff
),
cutoffDistance
(
1.0
)
{
NonbondedForce
::
NonbondedForce
()
:
nonbondedMethod
(
NoCutoff
),
cutoffDistance
(
1.0
)
,
ewaldErrorTol
(
1e-4
)
{
periodicBoxVectors
[
0
]
=
Vec3
(
2
,
0
,
0
);
periodicBoxVectors
[
1
]
=
Vec3
(
0
,
2
,
0
);
periodicBoxVectors
[
2
]
=
Vec3
(
0
,
0
,
2
);
...
...
@@ -63,6 +63,15 @@ void NonbondedForce::setCutoffDistance(double distance) {
cutoffDistance
=
distance
;
}
double
NonbondedForce
::
getEwaldErrorTolerance
()
const
{
return
ewaldErrorTol
;
}
void
NonbondedForce
::
setEwaldErrorTolerance
(
double
tol
)
{
ewaldErrorTol
=
tol
;
}
void
NonbondedForce
::
getPeriodicBoxVectors
(
Vec3
&
a
,
Vec3
&
b
,
Vec3
&
c
)
const
{
a
=
periodicBoxVectors
[
0
];
b
=
periodicBoxVectors
[
1
];
...
...
platforms/cuda/src/CudaKernels.cpp
View file @
83d57922
...
...
@@ -304,9 +304,17 @@ void CudaCalcNonbondedForceKernel::initialize(const System& system, const Nonbon
Vec3
boxVectors
[
3
];
force
.
getPeriodicBoxVectors
(
boxVectors
[
0
],
boxVectors
[
1
],
boxVectors
[
2
]);
gpuSetPeriodicBoxSize
(
gpu
,
(
float
)
boxVectors
[
0
][
0
],
(
float
)
boxVectors
[
1
][
1
],
(
float
)
boxVectors
[
2
][
2
]);
gpuSetEwaldParameters
(
gpu
);
//, (float)alphaEwald, (int)kmax);
double
ewaldErrorTol
=
force
.
getEwaldErrorTolerance
();
double
alpha
=
(
1.0
/
force
.
getCutoffDistance
())
*
std
::
sqrt
(
-
std
::
log
(
ewaldErrorTol
));
double
mx
=
boxVectors
[
0
][
0
]
/
force
.
getCutoffDistance
();
double
my
=
boxVectors
[
1
][
1
]
/
force
.
getCutoffDistance
();
double
mz
=
boxVectors
[
2
][
2
]
/
force
.
getCutoffDistance
();
double
pi
=
3.1415926535897932385
;
int
kmaxx
=
std
::
ceil
(
-
(
mx
/
pi
)
*
std
::
log
(
ewaldErrorTol
));;
int
kmaxy
=
std
::
ceil
(
-
(
my
/
pi
)
*
std
::
log
(
ewaldErrorTol
));;
int
kmaxz
=
std
::
ceil
(
-
(
mz
/
pi
)
*
std
::
log
(
ewaldErrorTol
));;
gpuSetEwaldParameters
(
gpu
,
alpha
,
kmaxx
,
kmaxy
,
kmaxz
);
method
=
EWALD
;
}
data
.
nonbondedMethod
=
method
;
gpuSetCoulombParameters
(
gpu
,
138.935485
f
,
particle
,
c6
,
c12
,
q
,
symbol
,
exclusionList
,
method
);
...
...
platforms/cuda/src/kernels/cudatypes.h
View file @
83d57922
...
...
@@ -300,7 +300,9 @@ struct cudaGmxSimulation {
float
cellVolume
;
// Ewald parameter alpha (a.k.a. kappa)
float
alphaEwald
;
// Ewald parameter alpha (a.k.a. kappa)
float
factorEwald
;
// - 1 ( 4 * alphaEwald * alphaEwald)
int
kmax
;
// Maximum number of reciprocal vectors
int
kmaxX
;
// Maximum number of reciprocal vectors in the X direction
int
kmaxY
;
// Maximum number of reciprocal vectors in the Y direction
int
kmaxZ
;
// Maximum number of reciprocal vectors in the Z direction
float
reactionFieldK
;
// Constant for reaction field correction
float
probeRadius
;
// SASA probe radius
float
surfaceAreaFactor
;
// ACE approximation surface area factor
...
...
platforms/cuda/src/kernels/gpu.cpp
View file @
83d57922
...
...
@@ -424,15 +424,14 @@ void gpuSetNonbondedCutoff(gpuContext gpu, float cutoffDistance, float solventDi
}
extern
"C"
void
gpuSetEwaldParameters
(
gpuContext
gpu
)
//
, float alpha
Ewald, int kmax
)
void
gpuSetEwaldParameters
(
gpuContext
gpu
,
float
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
)
{
// hard coded alphaEwald and kmax, no interface yet
float
alpha
=
3.123413
f
;
gpu
->
sim
.
alphaEwald
=
alpha
;
gpu
->
sim
.
factorEwald
=
-
1
/
(
4
*
alpha
*
alpha
);
gpu
->
sim
.
kmax
=
20
+
1
;
gpu
->
psEwaldCosSinSum
=
new
CUDAStream
<
float2
>
((
gpu
->
sim
.
kmax
*
2
-
1
)
*
(
gpu
->
sim
.
kmax
*
2
-
1
)
*
(
gpu
->
sim
.
kmax
*
2
-
1
),
1
,
"EwaldCosSinSum"
);
gpu
->
sim
.
kmaxX
=
kmaxx
;
gpu
->
sim
.
kmaxY
=
kmaxy
;
gpu
->
sim
.
kmaxZ
=
kmaxz
;
gpu
->
psEwaldCosSinSum
=
new
CUDAStream
<
float2
>
((
gpu
->
sim
.
kmaxX
*
2
-
1
)
*
(
gpu
->
sim
.
kmaxY
*
2
-
1
)
*
(
gpu
->
sim
.
kmaxZ
*
2
-
1
),
1
,
"EwaldCosSinSum"
);
gpu
->
sim
.
pEwaldCosSinSum
=
gpu
->
psEwaldCosSinSum
->
_pDevStream
[
0
];
}
...
...
platforms/cuda/src/kernels/gputypes.h
View file @
83d57922
...
...
@@ -176,7 +176,7 @@ extern "C"
void
gpuSetNonbondedCutoff
(
gpuContext
gpu
,
float
cutoffDistance
,
float
solventDielectric
);
extern
"C"
void
gpuSetEwaldParameters
(
gpuContext
gpu
);
//
, float alpha
Ewald
, int kmax);
void
gpuSetEwaldParameters
(
gpuContext
gpu
,
float
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmax
z
);
extern
"C"
void
gpuSetPeriodicBoxSize
(
gpuContext
gpu
,
float
xsize
,
float
ysize
,
float
zsize
);
...
...
platforms/cuda/src/kernels/kCalculateCDLJEwaldFastReciprocal.h
View file @
83d57922
...
...
@@ -53,18 +53,20 @@ __device__ float2 ConjMultofFloat2(float2 a, float2 b)
__global__
void
kCalculateEwaldFastCosSinSums_kernel
()
{
const
unsigned
int
ksize
=
2
*
cSim
.
kmax
-
1
;
const
unsigned
int
totalK
=
ksize
*
ksize
*
ksize
;
const
unsigned
int
ksizex
=
2
*
cSim
.
kmaxX
-
1
;
const
unsigned
int
ksizey
=
2
*
cSim
.
kmaxY
-
1
;
const
unsigned
int
ksizez
=
2
*
cSim
.
kmaxZ
-
1
;
const
unsigned
int
totalK
=
ksizex
*
ksizey
*
ksizez
;
unsigned
int
index
=
threadIdx
.
x
+
blockIdx
.
x
*
blockDim
.
x
;
while
(
index
<
totalK
)
{
// Find the wave vector (kx, ky, kz) this index corresponds to.
int
rx
=
index
/
(
ksize
*
ksize
);
int
remainder
=
index
-
rx
*
ksize
*
ksize
;
int
ry
=
remainder
/
ksize
;
int
rz
=
remainder
-
ry
*
ksize
-
cSim
.
kmax
+
1
;
ry
+=
-
cSim
.
kmax
+
1
;
int
rx
=
index
/
(
ksize
y
*
ksize
z
);
int
remainder
=
index
-
rx
*
ksize
y
*
ksize
z
;
int
ry
=
remainder
/
ksize
z
;
int
rz
=
remainder
-
ry
*
ksize
z
-
cSim
.
kmax
Z
+
1
;
ry
+=
-
cSim
.
kmax
Y
+
1
;
float
kx
=
rx
*
cSim
.
recipBoxSizeX
;
float
ky
=
ry
*
cSim
.
recipBoxSizeY
;
float
kz
=
rz
*
cSim
.
recipBoxSizeZ
;
...
...
@@ -101,10 +103,6 @@ __global__ void kCalculateEwaldFastForces_kernel()
const
float
epsilon
=
1
.
0
;
float
recipCoeff
=
cSim
.
epsfac
*
(
4
*
PI
/
cSim
.
cellVolume
/
epsilon
);
const
int
numRx
=
cSim
.
kmax
;
const
int
numRy
=
cSim
.
kmax
;
const
int
numRz
=
cSim
.
kmax
;
unsigned
int
atom
=
threadIdx
.
x
+
blockIdx
.
x
*
blockDim
.
x
;
while
(
atom
<
cSim
.
atoms
)
...
...
@@ -116,20 +114,20 @@ __global__ void kCalculateEwaldFastForces_kernel()
int
lowry
=
0
;
int
lowrz
=
1
;
for
(
int
rx
=
0
;
rx
<
numRx
;
rx
++
)
{
for
(
int
rx
=
0
;
rx
<
cSim
.
kmaxX
;
rx
++
)
{
float
kx
=
rx
*
cSim
.
recipBoxSizeX
;
for
(
int
ry
=
lowry
;
ry
<
numRy
;
ry
++
)
{
for
(
int
ry
=
lowry
;
ry
<
cSim
.
kmaxY
;
ry
++
)
{
float
ky
=
ry
*
cSim
.
recipBoxSizeY
;
float
phase
=
apos
.
x
*
kx
;
float2
tab_xy
=
make_float2
(
cos
(
phase
),
sin
(
phase
));
phase
=
apos
.
y
*
ky
;
tab_xy
=
MultofFloat2
(
tab_xy
,
make_float2
(
cos
(
phase
),
sin
(
phase
)));
for
(
int
rz
=
lowrz
;
rz
<
numRz
;
rz
++
)
{
for
(
int
rz
=
lowrz
;
rz
<
cSim
.
kmaxZ
;
rz
++
)
{
float
kz
=
rz
*
cSim
.
recipBoxSizeZ
;
// Compute the force contribution of this wave vector.
int
index
=
rx
*
(
numRy
*
2
-
1
)
*
(
numRz
*
2
-
1
)
+
(
ry
+
numRy
-
1
)
*
(
numRz
*
2
-
1
)
+
(
rz
+
numRz
-
1
);
int
index
=
rx
*
(
cSim
.
kmaxY
*
2
-
1
)
*
(
cSim
.
kmaxZ
*
2
-
1
)
+
(
ry
+
cSim
.
kmaxY
-
1
)
*
(
cSim
.
kmaxZ
*
2
-
1
)
+
(
rz
+
cSim
.
kmaxZ
-
1
);
float
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
float
ak
=
exp
(
k2
*
cSim
.
factorEwald
)
/
k2
;
phase
=
apos
.
z
*
kz
;
...
...
@@ -139,9 +137,9 @@ __global__ void kCalculateEwaldFastForces_kernel()
force
.
x
+=
2
*
recipCoeff
*
dEdR
*
kx
;
force
.
y
+=
2
*
recipCoeff
*
dEdR
*
ky
;
force
.
z
+=
2
*
recipCoeff
*
dEdR
*
kz
;
lowrz
=
1
-
numRz
;
lowrz
=
1
-
cSim
.
kmaxZ
;
}
lowry
=
1
-
numRy
;
lowry
=
1
-
cSim
.
kmaxY
;
}
}
...
...
platforms/cuda/src/kernels/kCalculateCDLJEwaldReciprocal.h
View file @
83d57922
...
...
@@ -49,13 +49,13 @@ __global__ void kCalculateCDLJEwaldReciprocalForces_kernel()
int
lowry
=
0
;
int
lowrz
=
1
;
for
(
int
rx
=
0
;
rx
<
cSim
.
kmax
;
rx
++
)
for
(
int
rx
=
0
;
rx
<
cSim
.
kmax
X
;
rx
++
)
{
float
kx
=
rx
*
cSim
.
recipBoxSizeX
;
for
(
int
ry
=
lowry
;
ry
<
cSim
.
kmax
;
ry
++
)
for
(
int
ry
=
lowry
;
ry
<
cSim
.
kmax
Y
;
ry
++
)
{
float
ky
=
ry
*
cSim
.
recipBoxSizeY
;
for
(
int
rz
=
lowrz
;
rz
<
cSim
.
kmax
;
rz
++
)
for
(
int
rz
=
lowrz
;
rz
<
cSim
.
kmax
Z
;
rz
++
)
{
float
kz
=
rz
*
cSim
.
recipBoxSizeZ
;
float
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
...
...
@@ -73,9 +73,9 @@ __global__ void kCalculateCDLJEwaldReciprocalForces_kernel()
af
.
y
-=
ky
*
f
;
af
.
z
-=
kz
*
f
;
lowrz
=
1
-
cSim
.
kmax
;
lowrz
=
1
-
cSim
.
kmax
Z
;
}
lowry
=
1
-
cSim
.
kmax
;
lowry
=
1
-
cSim
.
kmax
Y
;
}
}
atomID2
++
;
...
...
platforms/cuda/src/kernels/kCalculateCDLJForces.h
View file @
83d57922
...
...
@@ -43,7 +43,6 @@ __global__ void METHOD_NAME(kCalculateCDLJ, Forces_kernel)(unsigned int* workUni
#endif
#ifdef USE_EWALD
float
alphaEwald
=
3
.
123413
;
float
PI
=
3
.
14159265358979323846
f
;
float
SQRT_PI
=
sqrt
(
PI
);
#endif
...
...
@@ -112,7 +111,7 @@ __global__ void METHOD_NAME(kCalculateCDLJ, Forces_kernel)(unsigned int* workUni
#ifdef USE_CUTOFF
#ifdef USE_EWALD
float
r
=
sqrt
(
r2
);
float
alphaR
=
alphaEwald
*
r
;
float
alphaR
=
cSim
.
alphaEwald
*
r
;
dEdR
+=
apos
.
w
*
psA
[
j
].
q
*
invR
*
(
erfc
(
alphaR
)
+
2
.
0
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
#else
dEdR
+=
apos
.
w
*
psA
[
j
].
q
*
(
invR
-
2
.
0
f
*
cSim
.
reactionFieldK
*
r2
);
...
...
@@ -161,7 +160,7 @@ __global__ void METHOD_NAME(kCalculateCDLJ, Forces_kernel)(unsigned int* workUni
#ifdef USE_CUTOFF
#ifdef USE_EWALD
float
r
=
sqrt
(
r2
);
float
alphaR
=
alphaEwald
*
r
;
float
alphaR
=
cSim
.
alphaEwald
*
r
;
dEdR
+=
apos
.
w
*
psA
[
j
].
q
*
invR
*
(
erfc
(
alphaR
)
+
2
.
0
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
#else
dEdR
+=
apos
.
w
*
psA
[
j
].
q
*
(
invR
-
2
.
0
f
*
cSim
.
reactionFieldK
*
r2
);
...
...
@@ -259,7 +258,7 @@ __global__ void METHOD_NAME(kCalculateCDLJ, Forces_kernel)(unsigned int* workUni
#ifdef USE_CUTOFF
#ifdef USE_EWALD
float
r
=
sqrt
(
r2
);
float
alphaR
=
alphaEwald
*
r
;
float
alphaR
=
cSim
.
alphaEwald
*
r
;
dEdR
+=
apos
.
w
*
psA
[
tj
].
q
*
invR
*
(
erfc
(
alphaR
)
+
2
.
0
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
#else
dEdR
+=
apos
.
w
*
psA
[
tj
].
q
*
(
invR
-
2
.
0
f
*
cSim
.
reactionFieldK
*
r2
);
...
...
@@ -314,7 +313,7 @@ __global__ void METHOD_NAME(kCalculateCDLJ, Forces_kernel)(unsigned int* workUni
#ifdef USE_CUTOFF
#ifdef USE_EWALD
float
r
=
sqrt
(
r2
);
float
alphaR
=
alphaEwald
*
r
;
float
alphaR
=
cSim
.
alphaEwald
*
r
;
dEdR
+=
apos
.
w
*
psA
[
j
].
q
*
invR
*
(
erfc
(
alphaR
)
+
2
.
0
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
#else
dEdR
+=
apos
.
w
*
psA
[
j
].
q
*
(
invR
-
2
.
0
f
*
cSim
.
reactionFieldK
*
r2
);
...
...
@@ -405,7 +404,7 @@ __global__ void METHOD_NAME(kCalculateCDLJ, Forces_kernel)(unsigned int* workUni
#ifdef USE_CUTOFF
#ifdef USE_EWALD
float
r
=
sqrt
(
r2
);
float
alphaR
=
alphaEwald
*
r
;
float
alphaR
=
cSim
.
alphaEwald
*
r
;
dEdR
+=
apos
.
w
*
psA
[
tj
].
q
*
invR
*
(
erfc
(
alphaR
)
+
2
.
0
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
#else
dEdR
+=
apos
.
w
*
psA
[
tj
].
q
*
(
invR
-
2
.
0
f
*
cSim
.
reactionFieldK
*
r2
);
...
...
platforms/cuda/tests/TestCudaNonbondedForce.cpp
View file @
83d57922
...
...
@@ -369,6 +369,7 @@ void testEwald() {
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
Ewald
);
const
double
cutoff
=
2.0
;
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setEwaldErrorTolerance
(
TOL
);
nonbonded
->
setPeriodicBoxVectors
(
Vec3
(
6
,
0
,
0
),
Vec3
(
0
,
6
,
0
),
Vec3
(
0
,
0
,
6
));
system
.
addForce
(
nonbonded
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
...
...
@@ -379,9 +380,9 @@ void testEwald() {
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_TOL
(
-
217.276
,
state
.
getPotentialEnergy
(),
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
10
*
TOL
);
//
ASSERT_EQUAL_TOL(-217.276, state.getPotentialEnergy(),
10*
TOL);
}
...
...
platforms/reference/src/ReferenceKernels.cpp
View file @
83d57922
...
...
@@ -392,7 +392,17 @@ void ReferenceCalcNonbondedForceKernel::initialize(const System& system, const N
neighborList
=
NULL
;
else
neighborList
=
new
NeighborList
();
if
(
nonbondedMethod
==
Ewald
)
{
RealOpenMM
ewaldErrorTol
=
(
RealOpenMM
)
force
.
getEwaldErrorTolerance
();
ewaldAlpha
=
(
RealOpenMM
)
(
std
::
sqrt
(
-
std
::
log
(
ewaldErrorTol
))
/
nonbondedCutoff
);
RealOpenMM
mx
=
periodicBoxSize
[
0
]
/
nonbondedCutoff
;
RealOpenMM
my
=
periodicBoxSize
[
1
]
/
nonbondedCutoff
;
RealOpenMM
mz
=
periodicBoxSize
[
2
]
/
nonbondedCutoff
;
RealOpenMM
pi
=
(
RealOpenMM
)
3.1415926535897932385
;
kmax
[
0
]
=
std
::
ceil
(
-
(
mx
/
pi
)
*
std
::
log
(
ewaldErrorTol
));
kmax
[
1
]
=
std
::
ceil
(
-
(
my
/
pi
)
*
std
::
log
(
ewaldErrorTol
));
kmax
[
2
]
=
std
::
ceil
(
-
(
mz
/
pi
)
*
std
::
log
(
ewaldErrorTol
));
}
}
void
ReferenceCalcNonbondedForceKernel
::
executeForces
(
OpenMMContextImpl
&
context
)
{
...
...
@@ -407,13 +417,9 @@ void ReferenceCalcNonbondedForceKernel::executeForces(OpenMMContextImpl& context
}
if
(
periodic
||
ewald
)
clj
.
setPeriodic
(
periodicBoxSize
);
if
(
ewald
)
{
clj
.
setRecipVectors
();
clj
.
calculateEwaldIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
0
);
}
else
{
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
0
);
}
if
(
ewald
)
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
0
);
ReferenceBondForce
refBondForce
;
ReferenceLJCoulomb14
nonbonded14
;
if
(
nonbondedMethod
!=
NoCutoff
)
...
...
@@ -434,13 +440,9 @@ double ReferenceCalcNonbondedForceKernel::executeEnergy(OpenMMContextImpl& conte
}
if
(
periodic
||
ewald
)
clj
.
setPeriodic
(
periodicBoxSize
);
if
(
ewald
)
{
clj
.
setRecipVectors
();
clj
.
calculateEwaldIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
&
energy
);
}
else
{
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
&
energy
);
}
if
(
ewald
)
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
&
energy
);
ReferenceBondForce
refBondForce
;
ReferenceLJCoulomb14
nonbonded14
;
if
(
nonbondedMethod
!=
NoCutoff
)
...
...
platforms/reference/src/ReferenceKernels.h
View file @
83d57922
...
...
@@ -266,7 +266,8 @@ private:
int
numParticles
,
num14
;
int
**
exclusionArray
,
**
bonded14IndexArray
;
RealOpenMM
**
particleParamArray
,
**
bonded14ParamArray
;
RealOpenMM
nonbondedCutoff
,
periodicBoxSize
[
3
];
RealOpenMM
nonbondedCutoff
,
periodicBoxSize
[
3
],
ewaldAlpha
;
int
kmax
[
3
];
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
NonbondedMethod
nonbondedMethod
;
NeighborList
*
neighborList
;
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
83d57922
...
...
@@ -44,7 +44,7 @@ using std::vector;
--------------------------------------------------------------------------------------- */
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
(
)
:
cutoff
(
false
),
periodic
(
false
)
{
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
(
)
:
cutoff
(
false
),
periodic
(
false
)
,
ewald
(
false
)
{
// ---------------------------------------------------------------------------------------
...
...
@@ -119,6 +119,25 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){
}
/**---------------------------------------------------------------------------------------
Set the force to use Ewald summation.
@param alpha the Ewald separation parameter
@param kmaxx the largest wave vector in the x direction
@param kmaxy the largest wave vector in the y direction
@param kmaxz the largest wave vector in the z direction
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
)
{
alphaEwald
=
alpha
;
numRx
=
kmaxx
;
numRy
=
kmaxy
;
numRz
=
kmaxz
;
ewald
=
true
;
}
/**---------------------------------------------------------------------------------------
Calculate parameters for LJ Coulomb ixn
...
...
@@ -171,44 +190,6 @@ int ReferenceLJCoulombIxn::getDerivedParameters( RealOpenMM c6, RealOpenMM c12,
return
ReferenceForce
::
DefaultReturn
;
}
/**---------------------------------------------------------------------------------------
Set the reciprocal space vectors to use with Ewald
// Currently a dumb routine, vectors are set in calculateEwaldIxn
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
int
ReferenceLJCoulombIxn
::
setRecipVectors
()
{
return
ReferenceForce
::
DefaultReturn
;
}
/**---------------------------------------------------------------------------------------
Calculate the Ewald parameter based on the cutoff and the desired tolerance using
erfc( alpha*cutoff )/cutoff < tolerance
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
/* int ReferenceLJCoulombIxn::setAlphaEwald(RealOpenMM cutoff, RealOpenMM tolerance,
RealOpenMM alphaEwald) {
alphaEwald = 1.0f;
while ( erfc(alphaEwald*cutoff) >= tolerance*cutoff) {
alphaEwald= 1.2 * alphaEwald;
}
return ReferenceForce::DefaultReturn;
}
*/
/**---------------------------------------------------------------------------------------
Calculate Ewald ixn
...
...
@@ -232,20 +213,13 @@ int ReferenceLJCoulombIxn::getDerivedParameters( RealOpenMM c6, RealOpenMM c12,
int
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
#include "../SimTKUtilities/RealTypeSimTk.h"
typedef
std
::
complex
<
RealOpenMM
>
d_complex
;
// Number of R-vectors (real space vectors)
// to be calculated automatically eventually from alphaEwald and desired precision
int
numRx
=
20
+
1
;
int
numRy
=
20
+
1
;
int
numRz
=
20
+
1
;
int
kmax
=
std
::
max
(
numRx
,
std
::
max
(
numRy
,
numRz
));
static
const
RealOpenMM
alphaEwald
=
(
RealOpenMM
)
3.123413
;
RealOpenMM
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
...
...
@@ -466,6 +440,8 @@ int ReferenceLJCoulombIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM** ato
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
if
(
ewald
)
return
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
if
(
cutoff
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.h
View file @
83d57922
...
...
@@ -36,10 +36,13 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
bool
cutoff
;
bool
periodic
;
bool
ewald
;
const
OpenMM
::
NeighborList
*
neighborList
;
RealOpenMM
periodicBoxSize
[
3
];
RealOpenMM
cutoffDistance
;
RealOpenMM
krf
,
crf
;
RealOpenMM
alphaEwald
;
int
numRx
,
numRy
,
numRz
;
// parameter indices
...
...
@@ -116,15 +119,16 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
/**---------------------------------------------------------------------------------------
Set the
reciprocal vectors to use with Ewald
Set the
force to use Ewald summation.
@param
@return ReferenceForce::DefaultReturn
@param alpha the Ewald separation parameter
@param kmaxx the largest wave vector in the x direction
@param kmaxy the largest wave vector in the y direction
@param kmaxz the largest wave vector in the z direction
--------------------------------------------------------------------------------------- */
int
setRecipVectors
();
void
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
);
/**---------------------------------------------------------------------------------------
...
...
@@ -172,7 +176,8 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
;
private:
/**---------------------------------------------------------------------------------------
Calculate Ewald ixn
...
...
@@ -188,7 +193,7 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
@param forces force array (forces added)
@param energyByAtom atom energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
...
...
platforms/reference/src/SimTKReference/ReferencePairIxn.h
View file @
83d57922
...
...
@@ -72,30 +72,7 @@ class ReferencePairIxn {
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
=
0
;
/**---------------------------------------------------------------------------------------
Calculate Ewald ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters (charges, c6, c12, ...) atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices exclusions[atomIndex][atomToExcludeIndex]
@param fixedParameters non-atom parameters
@param forces force array (forces added)
@param energyByAtom atom energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
virtual
int
calculateEwaldIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
=
0
;
};
// ---------------------------------------------------------------------------------------
...
...
platforms/reference/tests/TestReferenceEwald.cpp
View file @
83d57922
...
...
@@ -62,6 +62,7 @@ void testEwald() {
const
double
cutoff
=
2.0
;
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setPeriodicBoxVectors
(
Vec3
(
6
,
0
,
0
),
Vec3
(
0
,
6
,
0
),
Vec3
(
0
,
0
,
6
));
nonbonded
->
setEwaldErrorTolerance
(
TOL
);
system
.
addForce
(
nonbonded
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
...
...
@@ -73,8 +74,8 @@ void testEwald() {
cout
<<
"force 0: "
<<
forces
[
0
]
<<
endl
;
cout
<<
"force 1: "
<<
forces
[
1
]
<<
endl
;
cout
<<
"PotentialEnergy: "
<<
state
.
getPotentialEnergy
()
<<
endl
;
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
10
*
TOL
);
// const double eps = 78.3;
// const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0);
// const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment