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
96a37423
Commit
96a37423
authored
May 15, 2016
by
peastman
Browse files
Merge pull request #1487 from peastman/triclinic
Fixed bug in PME with triclinic boxes
parents
244dd6d7
e1181999
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
99 additions
and
53 deletions
+99
-53
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+5
-2
platforms/cuda/src/kernels/pme.cu
platforms/cuda/src/kernels/pme.cu
+9
-9
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+29
-29
platforms/opencl/src/kernels/pme.cl
platforms/opencl/src/kernels/pme.cl
+12
-13
tests/TestEwald.h
tests/TestEwald.h
+44
-0
No files found.
platforms/cuda/src/CudaKernels.cpp
View file @
96a37423
...
...
@@ -1938,12 +1938,14 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF
// Execute the reciprocal space kernels.
void
*
gridIndexArgs
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
pmeAtomGridIndex
->
getDevicePointer
(),
cu
.
getPeriodicBoxSizePointer
(),
cu
.
getInvPeriodicBoxSizePointer
(),
cu
.
getPeriodicBoxVecXPointer
(),
cu
.
getPeriodicBoxVecYPointer
(),
cu
.
getPeriodicBoxVecZPointer
(),
recipBoxVectorPointer
[
0
],
recipBoxVectorPointer
[
1
],
recipBoxVectorPointer
[
2
]};
cu
.
executeKernel
(
pmeGridIndexKernel
,
gridIndexArgs
,
cu
.
getNumAtoms
());
sort
->
sort
(
*
pmeAtomGridIndex
);
void
*
spreadArgs
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
directPmeGrid
->
getDevicePointer
(),
cu
.
getPeriodicBoxSizePointer
(),
cu
.
getInvPeriodicBoxSizePointer
(),
cu
.
getPeriodicBoxVecXPointer
(),
cu
.
getPeriodicBoxVecYPointer
(),
cu
.
getPeriodicBoxVecZPointer
(),
recipBoxVectorPointer
[
0
],
recipBoxVectorPointer
[
1
],
recipBoxVectorPointer
[
2
],
&
pmeAtomGridIndex
->
getDevicePointer
()};
cu
.
executeKernel
(
pmeSpreadChargeKernel
,
spreadArgs
,
cu
.
getNumAtoms
(),
128
);
...
...
@@ -1984,8 +1986,9 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF
fft
->
execFFT
(
*
reciprocalPmeGrid
,
*
directPmeGrid
,
false
);
}
void
*
interpolateArgs
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
cu
.
getForce
().
getDevicePointer
(),
&
directPmeGrid
->
getDevicePointer
(),
cu
.
getPeriodicBoxSizePointer
(),
recipBoxVectorPointer
[
0
],
recipBoxVectorPointer
[
1
],
recipBoxVectorPointer
[
2
],
&
pmeAtomGridIndex
->
getDevicePointer
()};
void
*
interpolateArgs
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
cu
.
getForce
().
getDevicePointer
(),
&
directPmeGrid
->
getDevicePointer
(),
cu
.
getPeriodicBoxSizePointer
(),
cu
.
getInvPeriodicBoxSizePointer
(),
cu
.
getPeriodicBoxVecXPointer
(),
cu
.
getPeriodicBoxVecYPointer
(),
cu
.
getPeriodicBoxVecZPointer
(),
recipBoxVectorPointer
[
0
],
recipBoxVectorPointer
[
1
],
recipBoxVectorPointer
[
2
],
&
pmeAtomGridIndex
->
getDevicePointer
()};
cu
.
executeKernel
(
pmeInterpolateForceKernel
,
interpolateArgs
,
cu
.
getNumAtoms
(),
128
);
if
(
usePmeStream
)
{
cuEventRecord
(
pmeSyncEvent
,
pmeStream
);
...
...
platforms/cuda/src/kernels/pme.cu
View file @
96a37423
extern
"C"
__global__
void
findAtomGridIndex
(
const
real4
*
__restrict__
posq
,
int2
*
__restrict__
pmeAtomGridIndex
,
real4
periodicBoxSize
,
real3
recipBoxVecX
,
real3
recipBoxVecY
,
real3
recipBoxVecZ
)
{
real4
periodicBoxSize
,
real4
invPeriodicBoxSize
,
real4
periodicBoxVecX
,
real4
periodicBoxVecY
,
real4
periodicBoxVecZ
,
real3
recipBoxVecX
,
real3
recipBoxVecY
,
real3
recipBoxVecZ
)
{
// Compute the index of the grid point each atom is associated with.
for
(
int
i
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
i
<
NUM_ATOMS
;
i
+=
blockDim
.
x
*
gridDim
.
x
)
{
real4
pos
=
posq
[
i
];
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
make_real3
(
pos
.
x
*
recipBoxVecX
.
x
+
pos
.
y
*
recipBoxVecY
.
x
+
pos
.
z
*
recipBoxVecZ
.
x
,
pos
.
y
*
recipBoxVecY
.
y
+
pos
.
z
*
recipBoxVecZ
.
y
,
pos
.
z
*
recipBoxVecZ
.
z
);
...
...
@@ -18,7 +20,8 @@ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int
}
extern
"C"
__global__
void
gridSpreadCharge
(
const
real4
*
__restrict__
posq
,
real
*
__restrict__
originalPmeGrid
,
real4
periodicBoxSize
,
real3
recipBoxVecX
,
real3
recipBoxVecY
,
real3
recipBoxVecZ
,
const
int2
*
__restrict__
pmeAtomGridIndex
)
{
real4
periodicBoxSize
,
real4
invPeriodicBoxSize
,
real4
periodicBoxVecX
,
real4
periodicBoxVecY
,
real4
periodicBoxVecZ
,
real3
recipBoxVecX
,
real3
recipBoxVecY
,
real3
recipBoxVecZ
,
const
int2
*
__restrict__
pmeAtomGridIndex
)
{
real3
data
[
PME_ORDER
];
const
real
scale
=
RECIP
(
PME_ORDER
-
1
);
...
...
@@ -28,9 +31,7 @@ extern "C" __global__ void gridSpreadCharge(const real4* __restrict__ posq, real
for
(
int
i
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
i
<
NUM_ATOMS
;
i
+=
blockDim
.
x
*
gridDim
.
x
)
{
int
atom
=
pmeAtomGridIndex
[
i
].
x
;
real4
pos
=
posq
[
atom
];
pos
.
x
-=
floor
(
pos
.
x
*
recipBoxVecX
.
x
)
*
periodicBoxSize
.
x
;
pos
.
y
-=
floor
(
pos
.
y
*
recipBoxVecY
.
y
)
*
periodicBoxSize
.
y
;
pos
.
z
-=
floor
(
pos
.
z
*
recipBoxVecZ
.
z
)
*
periodicBoxSize
.
z
;
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
make_real3
(
pos
.
x
*
recipBoxVecX
.
x
+
pos
.
y
*
recipBoxVecY
.
x
+
pos
.
z
*
recipBoxVecZ
.
x
,
pos
.
y
*
recipBoxVecY
.
y
+
pos
.
z
*
recipBoxVecZ
.
y
,
pos
.
z
*
recipBoxVecZ
.
z
);
...
...
@@ -197,7 +198,8 @@ gridEvaluateEnergy(real2* __restrict__ halfcomplex_pmeGrid, mixed* __restrict__
extern
"C"
__global__
void
gridInterpolateForce
(
const
real4
*
__restrict__
posq
,
unsigned
long
long
*
__restrict__
forceBuffers
,
const
real
*
__restrict__
originalPmeGrid
,
real4
periodicBoxSize
,
real3
recipBoxVecX
,
real3
recipBoxVecY
,
real3
recipBoxVecZ
,
const
int2
*
__restrict__
pmeAtomGridIndex
)
{
real4
periodicBoxSize
,
real4
invPeriodicBoxSize
,
real4
periodicBoxVecX
,
real4
periodicBoxVecY
,
real4
periodicBoxVecZ
,
real3
recipBoxVecX
,
real3
recipBoxVecY
,
real3
recipBoxVecZ
,
const
int2
*
__restrict__
pmeAtomGridIndex
)
{
real3
data
[
PME_ORDER
];
real3
ddata
[
PME_ORDER
];
const
real
scale
=
RECIP
(
PME_ORDER
-
1
);
...
...
@@ -209,9 +211,7 @@ void gridInterpolateForce(const real4* __restrict__ posq, unsigned long long* __
int
atom
=
pmeAtomGridIndex
[
i
].
x
;
real3
force
=
make_real3
(
0
);
real4
pos
=
posq
[
atom
];
pos
.
x
-=
floor
(
pos
.
x
*
recipBoxVecX
.
x
)
*
periodicBoxSize
.
x
;
pos
.
y
-=
floor
(
pos
.
y
*
recipBoxVecY
.
y
)
*
periodicBoxSize
.
y
;
pos
.
z
-=
floor
(
pos
.
z
*
recipBoxVecZ
.
z
)
*
periodicBoxSize
.
z
;
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
make_real3
(
pos
.
x
*
recipBoxVecX
.
x
+
pos
.
y
*
recipBoxVecY
.
x
+
pos
.
z
*
recipBoxVecZ
.
x
,
pos
.
y
*
recipBoxVecY
.
y
+
pos
.
z
*
recipBoxVecZ
.
y
,
pos
.
z
*
recipBoxVecZ
.
z
);
...
...
platforms/opencl/src/OpenCLKernels.cpp
View file @
96a37423
...
...
@@ -1913,7 +1913,7 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ
pmeInterpolateForceKernel
.
setArg
<
cl
::
Buffer
>
(
0
,
cl
.
getPosq
().
getDeviceBuffer
());
pmeInterpolateForceKernel
.
setArg
<
cl
::
Buffer
>
(
1
,
cl
.
getForceBuffers
().
getDeviceBuffer
());
pmeInterpolateForceKernel
.
setArg
<
cl
::
Buffer
>
(
2
,
pmeGrid
->
getDeviceBuffer
());
pmeInterpolateForceKernel
.
setArg
<
cl
::
Buffer
>
(
7
,
pmeAtomGridIndex
->
getDeviceBuffer
());
pmeInterpolateForceKernel
.
setArg
<
cl
::
Buffer
>
(
11
,
pmeAtomGridIndex
->
getDeviceBuffer
());
if
(
cl
.
getSupports64BitGlobalAtomics
())
{
pmeFinishSpreadChargeKernel
=
cl
::
Kernel
(
program
,
"finishSpreadCharge"
);
pmeFinishSpreadChargeKernel
.
setArg
<
cl
::
Buffer
>
(
0
,
pmeGrid2
->
getDeviceBuffer
());
...
...
@@ -1962,45 +1962,45 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ
// Execute the reciprocal space kernels.
setPeriodicBox
Size
Arg
(
cl
,
pmeUpdateBsplinesKernel
,
4
);
setPeriodicBoxArg
s
(
cl
,
pmeUpdateBsplinesKernel
,
4
);
if
(
cl
.
getUseDoublePrecision
())
{
pmeUpdateBsplinesKernel
.
setArg
<
mm_double4
>
(
5
,
recipBoxVectors
[
0
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_double4
>
(
6
,
recipBoxVectors
[
1
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_double4
>
(
7
,
recipBoxVectors
[
2
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_double4
>
(
9
,
recipBoxVectors
[
0
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_double4
>
(
10
,
recipBoxVectors
[
1
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_double4
>
(
11
,
recipBoxVectors
[
2
]);
}
else
{
pmeUpdateBsplinesKernel
.
setArg
<
mm_float4
>
(
5
,
recipBoxVectorsFloat
[
0
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_float4
>
(
6
,
recipBoxVectorsFloat
[
1
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_float4
>
(
7
,
recipBoxVectorsFloat
[
2
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_float4
>
(
9
,
recipBoxVectorsFloat
[
0
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_float4
>
(
10
,
recipBoxVectorsFloat
[
1
]);
pmeUpdateBsplinesKernel
.
setArg
<
mm_float4
>
(
11
,
recipBoxVectorsFloat
[
2
]);
}
cl
.
executeKernel
(
pmeUpdateBsplinesKernel
,
cl
.
getNumAtoms
());
if
(
deviceIsCpu
&&
!
cl
.
getSupports64BitGlobalAtomics
())
{
setPeriodicBox
Size
Arg
(
cl
,
pmeSpreadChargeKernel
,
5
);
setPeriodicBoxArg
s
(
cl
,
pmeSpreadChargeKernel
,
5
);
if
(
cl
.
getUseDoublePrecision
())
{
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
6
,
recipBoxVectors
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
7
,
recipBoxVectors
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
8
,
recipBoxVectors
[
2
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
10
,
recipBoxVectors
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
11
,
recipBoxVectors
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
12
,
recipBoxVectors
[
2
]);
}
else
{
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
6
,
recipBoxVectorsFloat
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
7
,
recipBoxVectorsFloat
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
8
,
recipBoxVectorsFloat
[
2
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
10
,
recipBoxVectorsFloat
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
11
,
recipBoxVectorsFloat
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
12
,
recipBoxVectorsFloat
[
2
]);
}
cl
.
executeKernel
(
pmeSpreadChargeKernel
,
2
*
cl
.
getDevice
().
getInfo
<
CL_DEVICE_MAX_COMPUTE_UNITS
>
(),
1
);
}
else
{
sort
->
sort
(
*
pmeAtomGridIndex
);
if
(
cl
.
getSupports64BitGlobalAtomics
())
{
setPeriodicBox
Size
Arg
(
cl
,
pmeSpreadChargeKernel
,
5
);
setPeriodicBoxArg
s
(
cl
,
pmeSpreadChargeKernel
,
5
);
if
(
cl
.
getUseDoublePrecision
())
{
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
6
,
recipBoxVectors
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
7
,
recipBoxVectors
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
8
,
recipBoxVectors
[
2
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
10
,
recipBoxVectors
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
11
,
recipBoxVectors
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_double4
>
(
12
,
recipBoxVectors
[
2
]);
}
else
{
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
6
,
recipBoxVectorsFloat
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
7
,
recipBoxVectorsFloat
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
8
,
recipBoxVectorsFloat
[
2
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
10
,
recipBoxVectorsFloat
[
0
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
11
,
recipBoxVectorsFloat
[
1
]);
pmeSpreadChargeKernel
.
setArg
<
mm_float4
>
(
12
,
recipBoxVectorsFloat
[
2
]);
}
cl
.
executeKernel
(
pmeSpreadChargeKernel
,
cl
.
getNumAtoms
());
cl
.
executeKernel
(
pmeFinishSpreadChargeKernel
,
pmeGrid
->
getSize
());
...
...
@@ -2038,16 +2038,16 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ
cl
.
executeKernel
(
pmeEvalEnergyKernel
,
cl
.
getNumAtoms
());
cl
.
executeKernel
(
pmeConvolutionKernel
,
cl
.
getNumAtoms
());
fft
->
execFFT
(
*
pmeGrid2
,
*
pmeGrid
,
false
);
setPeriodicBox
Size
Arg
(
cl
,
pmeInterpolateForceKernel
,
3
);
setPeriodicBoxArg
s
(
cl
,
pmeInterpolateForceKernel
,
3
);
if
(
cl
.
getUseDoublePrecision
())
{
pmeInterpolateForceKernel
.
setArg
<
mm_double4
>
(
4
,
recipBoxVectors
[
0
]);
pmeInterpolateForceKernel
.
setArg
<
mm_double4
>
(
5
,
recipBoxVectors
[
1
]);
pmeInterpolateForceKernel
.
setArg
<
mm_double4
>
(
6
,
recipBoxVectors
[
2
]);
pmeInterpolateForceKernel
.
setArg
<
mm_double4
>
(
8
,
recipBoxVectors
[
0
]);
pmeInterpolateForceKernel
.
setArg
<
mm_double4
>
(
9
,
recipBoxVectors
[
1
]);
pmeInterpolateForceKernel
.
setArg
<
mm_double4
>
(
10
,
recipBoxVectors
[
2
]);
}
else
{
pmeInterpolateForceKernel
.
setArg
<
mm_float4
>
(
4
,
recipBoxVectorsFloat
[
0
]);
pmeInterpolateForceKernel
.
setArg
<
mm_float4
>
(
5
,
recipBoxVectorsFloat
[
1
]);
pmeInterpolateForceKernel
.
setArg
<
mm_float4
>
(
6
,
recipBoxVectorsFloat
[
2
]);
pmeInterpolateForceKernel
.
setArg
<
mm_float4
>
(
8
,
recipBoxVectorsFloat
[
0
]);
pmeInterpolateForceKernel
.
setArg
<
mm_float4
>
(
9
,
recipBoxVectorsFloat
[
1
]);
pmeInterpolateForceKernel
.
setArg
<
mm_float4
>
(
10
,
recipBoxVectorsFloat
[
2
]);
}
if
(
deviceIsCpu
)
cl
.
executeKernel
(
pmeInterpolateForceKernel
,
2
*
cl
.
getDevice
().
getInfo
<
CL_DEVICE_MAX_COMPUTE_UNITS
>
(),
1
);
...
...
platforms/opencl/src/kernels/pme.cl
View file @
96a37423
__kernel
void
updateBsplines
(
__global
const
real4*
restrict
posq,
__global
real4*
restrict
pmeBsplineTheta,
__local
real4*
restrict
bsplinesCache,
__global
int2*
restrict
pmeAtomGridIndex,
real4
periodicBoxSize,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ
)
{
__global
int2*
restrict
pmeAtomGridIndex,
real4
periodicBoxSize,
real4
invPeriodicBoxSize,
real4
periodicBoxVecX,
real4
periodicBoxVecY,
real4
periodicBoxVecZ,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ
)
{
const
real4
scale
=
1/
(
real
)
(
PME_ORDER-1
)
;
for
(
int
i
=
get_global_id
(
0
)
; i < NUM_ATOMS; i += get_global_size(0)) {
__local
real4*
data
=
&bsplinesCache[get_local_id
(
0
)
*PME_ORDER]
;
real4
pos
=
posq[i]
;
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
(
real3
)
(
pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x,
pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y,
pos.z*recipBoxVecZ.z
)
;
...
...
@@ -83,7 +85,8 @@ __kernel void recordZIndex(__global int2* restrict pmeAtomGridIndex, __global co
#
pragma
OPENCL
EXTENSION
cl_khr_int64_base_atomics
:
enable
__kernel
void
gridSpreadCharge
(
__global
const
real4*
restrict
posq,
__global
const
int2*
restrict
pmeAtomGridIndex,
__global
const
int*
restrict
pmeAtomRange,
__global
long*
restrict
pmeGrid,
__global
const
real4*
restrict
pmeBsplineTheta,
real4
periodicBoxSize,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ
)
{
__global
long*
restrict
pmeGrid,
__global
const
real4*
restrict
pmeBsplineTheta,
real4
periodicBoxSize,
real4
invPeriodicBoxSize,
real4
periodicBoxVecX,
real4
periodicBoxVecY,
real4
periodicBoxVecZ,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ
)
{
const
real
scale
=
1/
(
real
)
(
PME_ORDER-1
)
;
real4
data[PME_ORDER]
;
...
...
@@ -93,9 +96,7 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con
for
(
int
i
=
get_global_id
(
0
)
; i < NUM_ATOMS; i += get_global_size(0)) {
int
atom
=
pmeAtomGridIndex[i].x
;
real4
pos
=
posq[atom]
;
pos.x
-=
floor
(
pos.x*recipBoxVecX.x
)
*periodicBoxSize.x
;
pos.y
-=
floor
(
pos.y*recipBoxVecY.y
)
*periodicBoxSize.y
;
pos.z
-=
floor
(
pos.z*recipBoxVecZ.z
)
*periodicBoxSize.z
;
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
(
real3
)
(
pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x,
pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y,
pos.z*recipBoxVecZ.z
)
;
...
...
@@ -165,7 +166,8 @@ __kernel void finishSpreadCharge(__global long* restrict fixedGrid, __global rea
}
#
elif
defined
(
DEVICE_IS_CPU
)
__kernel
void
gridSpreadCharge
(
__global
const
real4*
restrict
posq,
__global
const
int2*
restrict
pmeAtomGridIndex,
__global
const
int*
restrict
pmeAtomRange,
__global
real*
restrict
pmeGrid,
__global
const
real4*
restrict
pmeBsplineTheta,
real4
periodicBoxSize,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ
)
{
__global
real*
restrict
pmeGrid,
__global
const
real4*
restrict
pmeBsplineTheta,
real4
periodicBoxSize,
real4
invPeriodicBoxSize,
real4
periodicBoxVecX,
real4
periodicBoxVecY,
real4
periodicBoxVecZ,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ
)
{
const
int
firstx
=
get_global_id
(
0
)
*GRID_SIZE_X/get_global_size
(
0
)
;
const
int
lastx
=
(
get_global_id
(
0
)
+1
)
*GRID_SIZE_X/get_global_size
(
0
)
;
if
(
firstx
==
lastx
)
...
...
@@ -179,9 +181,7 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con
for
(
int
i
=
0
; i < NUM_ATOMS; i++) {
int
atom
=
i
;//pmeAtomGridIndex[i].x;
real4
pos
=
posq[atom]
;
pos.x
-=
floor
(
pos.x*recipBoxVecX.x
)
*periodicBoxSize.x
;
pos.y
-=
floor
(
pos.y*recipBoxVecY.y
)
*periodicBoxSize.y
;
pos.z
-=
floor
(
pos.z*recipBoxVecZ.z
)
*periodicBoxSize.z
;
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
(
real3
)
(
pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x,
pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y,
pos.z*recipBoxVecZ.z
)
;
...
...
@@ -370,7 +370,8 @@ __kernel void gridEvaluateEnergy(__global real2* restrict pmeGrid, __global mixe
}
__kernel
void
gridInterpolateForce
(
__global
const
real4*
restrict
posq,
__global
real4*
restrict
forceBuffers,
__global
const
real*
restrict
pmeGrid,
real4
periodicBoxSize,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ,
__global
int2*
restrict
pmeAtomGridIndex
)
{
real4
periodicBoxSize,
real4
invPeriodicBoxSize,
real4
periodicBoxVecX,
real4
periodicBoxVecY,
real4
periodicBoxVecZ,
real4
recipBoxVecX,
real4
recipBoxVecY,
real4
recipBoxVecZ,
__global
int2*
restrict
pmeAtomGridIndex
)
{
const
real
scale
=
1/
(
real
)
(
PME_ORDER-1
)
;
real4
data[PME_ORDER]
;
real4
ddata[PME_ORDER]
;
...
...
@@ -382,9 +383,7 @@ __kernel void gridInterpolateForce(__global const real4* restrict posq, __global
int
atom
=
pmeAtomGridIndex[i].x
;
real4
force
=
0.0f
;
real4
pos
=
posq[atom]
;
pos.x
-=
floor
(
pos.x*recipBoxVecX.x
)
*periodicBoxSize.x
;
pos.y
-=
floor
(
pos.y*recipBoxVecY.y
)
*periodicBoxSize.y
;
pos.z
-=
floor
(
pos.z*recipBoxVecZ.z
)
*periodicBoxSize.z
;
APPLY_PERIODIC_TO_POS
(
pos
)
real3
t
=
(
real3
)
(
pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x,
pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y,
pos.z*recipBoxVecZ.z
)
;
...
...
tests/TestEwald.h
View file @
96a37423
...
...
@@ -270,6 +270,49 @@ void testTriclinic() {
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-4
);
}
void
testTriclinic2
()
{
// Create a triclinic box containing a large molecule made up of randomly positioned particles and make sure the
// results match the reference platform.
if
(
platform
.
getName
()
==
"Reference"
)
return
;
const
int
numParticles
=
1000
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
3.2
,
0
,
0
),
Vec3
(
-
1.1
,
3.1
,
0
),
Vec3
(
-
1.1
,
-
1.5
,
2.7
));
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
NonbondedForce
*
force
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
i
%
2
==
0
?
-
1.0
:
1.0
,
1.0
,
0.0
);
positions
[
i
]
=
Vec3
(
10
*
genrand_real2
(
sfmt
)
-
2
,
10
*
genrand_real2
(
sfmt
)
-
2
,
10
*
genrand_real2
(
sfmt
)
-
2
);
if
(
i
>
0
)
{
Vec3
delta
=
positions
[
i
-
1
]
-
positions
[
i
];
system
.
addConstraint
(
i
-
1
,
i
,
sqrt
(
delta
.
dot
(
delta
)));
}
}
system
.
addForce
(
force
);
force
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
force
->
setCutoffDistance
(
1.0
);
force
->
setReciprocalSpaceForceGroup
(
1
);
force
->
setPMEParameters
(
2.62826
,
27
,
25
,
24
);
// Compute the forces and energy.
VerletIntegrator
integ1
(
0.001
);
Context
context1
(
system
,
integ1
,
platform
);
context1
.
setPositions
(
positions
);
VerletIntegrator
integ2
(
0.001
);
Context
context2
(
system
,
integ2
,
Platform
::
getPlatformByName
(
"Reference"
));
context2
.
setPositions
(
positions
);
State
state1
=
context1
.
getState
(
State
::
Forces
|
State
::
Energy
,
false
,
2
);
State
state2
=
context2
.
getState
(
State
::
Forces
|
State
::
Energy
,
false
,
2
);
ASSERT_EQUAL_TOL
(
state2
.
getPotentialEnergy
(),
state1
.
getPotentialEnergy
(),
1e-4
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
state2
.
getForces
()[
i
],
state1
.
getForces
()[
i
],
1e-4
);
}
void
testErrorTolerance
(
NonbondedForce
::
NonbondedMethod
method
)
{
// Create a cloud of random point charges.
...
...
@@ -391,6 +434,7 @@ int main(int argc, char* argv[]) {
testEwaldPME
(
false
);
testEwaldPME
(
true
);
testTriclinic
();
testTriclinic2
();
testErrorTolerance
(
NonbondedForce
::
Ewald
);
testErrorTolerance
(
NonbondedForce
::
PME
);
testPMEParameters
();
...
...
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