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
6cc49dbe
Commit
6cc49dbe
authored
Aug 11, 2016
by
Andy Simmonett
Browse files
Initial reference implementation of LJPME.
parent
1e5b258c
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
719 additions
and
277 deletions
+719
-277
olla/include/openmm/kernels.h
olla/include/openmm/kernels.h
+12
-2
openmmapi/include/openmm/NonbondedForce.h
openmmapi/include/openmm/NonbondedForce.h
+41
-3
openmmapi/include/openmm/internal/NonbondedForceImpl.h
openmmapi/include/openmm/internal/NonbondedForceImpl.h
+2
-1
openmmapi/src/NonbondedForce.cpp
openmmapi/src/NonbondedForce.cpp
+18
-0
openmmapi/src/NonbondedForceImpl.cpp
openmmapi/src/NonbondedForceImpl.cpp
+10
-2
platforms/cpu/include/CpuKernels.h
platforms/cpu/include/CpuKernels.h
+14
-5
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+16
-3
platforms/opencl/include/OpenCLKernels.h
platforms/opencl/include/OpenCLKernels.h
+12
-2
platforms/opencl/include/OpenCLParallelKernels.h
platforms/opencl/include/OpenCLParallelKernels.h
+10
-1
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+14
-1
platforms/opencl/src/OpenCLParallelKernels.cpp
platforms/opencl/src/OpenCLParallelKernels.cpp
+4
-0
platforms/reference/include/ReferenceKernels.h
platforms/reference/include/ReferenceKernels.h
+11
-2
platforms/reference/include/ReferenceLJCoulombIxn.h
platforms/reference/include/ReferenceLJCoulombIxn.h
+20
-8
platforms/reference/include/ReferencePME.h
platforms/reference/include/ReferencePME.h
+23
-1
platforms/reference/src/ReferenceKernels.cpp
platforms/reference/src/ReferenceKernels.cpp
+27
-5
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+339
-238
platforms/reference/src/SimTKReference/ReferencePME.cpp
platforms/reference/src/SimTKReference/ReferencePME.cpp
+143
-0
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
...amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
+1
-1
plugins/cpupme/tests/TestCpuPme.cpp
plugins/cpupme/tests/TestCpuPme.cpp
+1
-1
tests/TestEwald.h
tests/TestEwald.h
+1
-1
No files found.
olla/include/openmm/kernels.h
View file @
6cc49dbe
...
@@ -555,7 +555,8 @@ public:
...
@@ -555,7 +555,8 @@ public:
CutoffNonPeriodic
=
1
,
CutoffNonPeriodic
=
1
,
CutoffPeriodic
=
2
,
CutoffPeriodic
=
2
,
Ewald
=
3
,
Ewald
=
3
,
PME
=
4
PME
=
4
,
LJPME
=
5
};
};
static
std
::
string
Name
()
{
static
std
::
string
Name
()
{
return
"CalcNonbondedForce"
;
return
"CalcNonbondedForce"
;
...
@@ -589,13 +590,22 @@ public:
...
@@ -589,13 +590,22 @@ public:
virtual
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
)
=
0
;
virtual
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
)
=
0
;
/**
/**
* Get the parameters being used for PME.
* Get the parameters being used for PME.
*
*
* @param alpha the separation parameter
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
* @param nz the number of grid points along the Z axis
*/
*/
virtual
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
=
0
;
virtual
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
=
0
;
/**
* Get the parameters being used for the dispersion terms in LJPME.
*
* @param dalpha the separation parameter
* @param dnx the number of grid points along the X axis
* @param dny the number of grid points along the Y axis
* @param dnz the number of grid points along the Z axis
*/
virtual
void
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
=
0
;
};
};
/**
/**
...
...
openmmapi/include/openmm/NonbondedForce.h
View file @
6cc49dbe
...
@@ -109,7 +109,12 @@ public:
...
@@ -109,7 +109,12 @@ public:
* Periodic boundary conditions are used, and Particle-Mesh Ewald (PME) summation is used to compute the interaction of each particle
* Periodic boundary conditions are used, and Particle-Mesh Ewald (PME) summation is used to compute the interaction of each particle
* with all periodic copies of every other particle.
* with all periodic copies of every other particle.
*/
*/
PME
=
4
PME
=
4
,
/**
* Periodic boundary conditions are used, and Particle-Mesh Ewald (PME) summation is used to compute the interaction of each particle
* with all periodic copies of every other particle for both electrostatics and dispersion. No switching is used for either interaction.
*/
LJPME
=
5
};
};
/**
/**
* Create a NonbondedForce.
* Create a NonbondedForce.
...
@@ -207,6 +212,16 @@ public:
...
@@ -207,6 +212,16 @@ public:
* @param[out] nz the number of grid points along the Z axis
* @param[out] nz the number of grid points along the Z axis
*/
*/
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
* Get the parameters to use for dispersion term in LJ-PME calculations. If alpha is 0 (the default),
* these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.
*
* @param[out] dalpha the separation parameter
* @param[out] dnx the number of dispersion grid points along the X axis
* @param[out] dny the number of dispersion grid points along the Y axis
* @param[out] dnz the number of dispersion grid points along the Z axis
*/
void
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
;
/**
/**
* Set the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are
* Set the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are
* ignored and instead their values are chosen based on the Ewald error tolerance.
* ignored and instead their values are chosen based on the Ewald error tolerance.
...
@@ -217,6 +232,16 @@ public:
...
@@ -217,6 +232,16 @@ public:
* @param nz the number of grid points along the Z axis
* @param nz the number of grid points along the Z axis
*/
*/
void
setPMEParameters
(
double
alpha
,
int
nx
,
int
ny
,
int
nz
);
void
setPMEParameters
(
double
alpha
,
int
nx
,
int
ny
,
int
nz
);
/**
* Set the parameters to use for the dispersion term in LJPME calculations. If alpha is 0 (the default),
* these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.
*
* @param dalpha the separation parameter
* @param dnx the number of grid points along the X axis
* @param dny the number of grid points along the Y axis
* @param dnz the number of grid points along the Z axis
*/
void
setLJPMEParameters
(
double
dalpha
,
int
dnx
,
int
dny
,
int
dnz
);
/**
/**
* Get the parameters being used for PME in a particular Context. Because some platforms have restrictions
* Get the parameters being used for PME in a particular Context. Because some platforms have restrictions
* on the allowed grid sizes, the values that are actually used may be slightly different from those
* on the allowed grid sizes, the values that are actually used may be slightly different from those
...
@@ -230,6 +255,19 @@ public:
...
@@ -230,6 +255,19 @@ public:
* @param[out] nz the number of grid points along the Z axis
* @param[out] nz the number of grid points along the Z axis
*/
*/
void
getPMEParametersInContext
(
const
Context
&
context
,
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParametersInContext
(
const
Context
&
context
,
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
* Get the PME parameters being used for the dispersion term for LJPME in a particular Context. Because some
* platforms have restrictions on the allowed grid sizes, the values that are actually used may be slightly different
* from those specified with setPMEParameters(), or the standard values calculated based on the Ewald error tolerance.
* See the manual for details.
*
* @param context the Context for which to get the parameters
* @param[out] dalpha the separation parameter
* @param[out] dnx the number of grid points along the X axis
* @param[out] dny the number of grid points along the Y axis
* @param[out] dnz the number of grid points along the Z axis
*/
void
getLJPMEParametersInContext
(
const
Context
&
context
,
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
;
/**
/**
* Add the nonbonded force parameters for a particle. This should be called once for each particle
* Add the nonbonded force parameters for a particle. This should be called once for each particle
* in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.
* in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.
...
@@ -382,9 +420,9 @@ private:
...
@@ -382,9 +420,9 @@ private:
class
ParticleInfo
;
class
ParticleInfo
;
class
ExceptionInfo
;
class
ExceptionInfo
;
NonbondedMethod
nonbondedMethod
;
NonbondedMethod
nonbondedMethod
;
double
cutoffDistance
,
switchingDistance
,
rfDielectric
,
ewaldErrorTol
,
alpha
;
double
cutoffDistance
,
switchingDistance
,
rfDielectric
,
ewaldErrorTol
,
alpha
,
dalpha
;
bool
useSwitchingFunction
,
useDispersionCorrection
;
bool
useSwitchingFunction
,
useDispersionCorrection
;
int
recipForceGroup
,
nx
,
ny
,
nz
;
int
recipForceGroup
,
nx
,
ny
,
nz
,
dnx
,
dny
,
dnz
;
void
addExclusionsToSet
(
const
std
::
vector
<
std
::
set
<
int
>
>&
bonded12
,
std
::
set
<
int
>&
exclusions
,
int
baseParticle
,
int
fromParticle
,
int
currentLevel
)
const
;
void
addExclusionsToSet
(
const
std
::
vector
<
std
::
set
<
int
>
>&
bonded12
,
std
::
set
<
int
>&
exclusions
,
int
baseParticle
,
int
fromParticle
,
int
currentLevel
)
const
;
std
::
vector
<
ParticleInfo
>
particles
;
std
::
vector
<
ParticleInfo
>
particles
;
std
::
vector
<
ExceptionInfo
>
exceptions
;
std
::
vector
<
ExceptionInfo
>
exceptions
;
...
...
openmmapi/include/openmm/internal/NonbondedForceImpl.h
View file @
6cc49dbe
...
@@ -65,6 +65,7 @@ public:
...
@@ -65,6 +65,7 @@ public:
std
::
vector
<
std
::
string
>
getKernelNames
();
std
::
vector
<
std
::
string
>
getKernelNames
();
void
updateParametersInContext
(
ContextImpl
&
context
);
void
updateParametersInContext
(
ContextImpl
&
context
);
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getLJPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
/**
* This is a utility routine that calculates the values to use for alpha and kmax when using
* This is a utility routine that calculates the values to use for alpha and kmax when using
* Ewald summation.
* Ewald summation.
...
@@ -74,7 +75,7 @@ public:
...
@@ -74,7 +75,7 @@ public:
* This is a utility routine that calculates the values to use for alpha and grid size when using
* This is a utility routine that calculates the values to use for alpha and grid size when using
* Particle Mesh Ewald.
* Particle Mesh Ewald.
*/
*/
static
void
calcPMEParameters
(
const
System
&
system
,
const
NonbondedForce
&
force
,
double
&
alpha
,
int
&
xsize
,
int
&
ysize
,
int
&
zsize
);
static
void
calcPMEParameters
(
const
System
&
system
,
const
NonbondedForce
&
force
,
double
&
alpha
,
int
&
xsize
,
int
&
ysize
,
int
&
zsize
,
bool
LJ
);
/**
/**
* Compute the coefficient which, when divided by the periodic box volume, gives the
* Compute the coefficient which, when divided by the periodic box volume, gives the
* long range dispersion correction to the energy.
* long range dispersion correction to the energy.
...
...
openmmapi/src/NonbondedForce.cpp
View file @
6cc49dbe
...
@@ -106,6 +106,13 @@ void NonbondedForce::getPMEParameters(double& alpha, int& nx, int& ny, int& nz)
...
@@ -106,6 +106,13 @@ void NonbondedForce::getPMEParameters(double& alpha, int& nx, int& ny, int& nz)
nz
=
this
->
nz
;
nz
=
this
->
nz
;
}
}
void
NonbondedForce
::
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
{
dalpha
=
this
->
dalpha
;
dnx
=
this
->
dnx
;
dny
=
this
->
dny
;
dnz
=
this
->
dnz
;
}
void
NonbondedForce
::
setPMEParameters
(
double
alpha
,
int
nx
,
int
ny
,
int
nz
)
{
void
NonbondedForce
::
setPMEParameters
(
double
alpha
,
int
nx
,
int
ny
,
int
nz
)
{
this
->
alpha
=
alpha
;
this
->
alpha
=
alpha
;
this
->
nx
=
nx
;
this
->
nx
=
nx
;
...
@@ -113,10 +120,21 @@ void NonbondedForce::setPMEParameters(double alpha, int nx, int ny, int nz) {
...
@@ -113,10 +120,21 @@ void NonbondedForce::setPMEParameters(double alpha, int nx, int ny, int nz) {
this
->
nz
=
nz
;
this
->
nz
=
nz
;
}
}
void
NonbondedForce
::
setLJPMEParameters
(
double
dalpha
,
int
dnx
,
int
dny
,
int
dnz
)
{
this
->
dalpha
=
dalpha
;
this
->
dnx
=
dnx
;
this
->
dny
=
dny
;
this
->
dnz
=
dnz
;
}
void
NonbondedForce
::
getPMEParametersInContext
(
const
Context
&
context
,
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
void
NonbondedForce
::
getPMEParametersInContext
(
const
Context
&
context
,
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
dynamic_cast
<
const
NonbondedForceImpl
&>
(
getImplInContext
(
context
)).
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
dynamic_cast
<
const
NonbondedForceImpl
&>
(
getImplInContext
(
context
)).
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
}
}
void
NonbondedForce
::
getLJPMEParametersInContext
(
const
Context
&
context
,
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
{
dynamic_cast
<
const
NonbondedForceImpl
&>
(
getImplInContext
(
context
)).
getLJPMEParameters
(
dalpha
,
dnx
,
dny
,
dnz
);
}
int
NonbondedForce
::
addParticle
(
double
charge
,
double
sigma
,
double
epsilon
)
{
int
NonbondedForce
::
addParticle
(
double
charge
,
double
sigma
,
double
epsilon
)
{
particles
.
push_back
(
ParticleInfo
(
charge
,
sigma
,
epsilon
));
particles
.
push_back
(
ParticleInfo
(
charge
,
sigma
,
epsilon
));
return
particles
.
size
()
-
1
;
return
particles
.
size
()
-
1
;
...
...
openmmapi/src/NonbondedForceImpl.cpp
View file @
6cc49dbe
...
@@ -151,8 +151,12 @@ void NonbondedForceImpl::calcEwaldParameters(const System& system, const Nonbond
...
@@ -151,8 +151,12 @@ void NonbondedForceImpl::calcEwaldParameters(const System& system, const Nonbond
kmaxz
++
;
kmaxz
++
;
}
}
void
NonbondedForceImpl
::
calcPMEParameters
(
const
System
&
system
,
const
NonbondedForce
&
force
,
double
&
alpha
,
int
&
xsize
,
int
&
ysize
,
int
&
zsize
)
{
void
NonbondedForceImpl
::
calcPMEParameters
(
const
System
&
system
,
const
NonbondedForce
&
force
,
double
&
alpha
,
int
&
xsize
,
int
&
ysize
,
int
&
zsize
,
bool
LJ
)
{
force
.
getPMEParameters
(
alpha
,
xsize
,
ysize
,
zsize
);
if
(
LJ
)
{
force
.
getLJPMEParameters
(
alpha
,
xsize
,
ysize
,
zsize
);
}
else
{
force
.
getPMEParameters
(
alpha
,
xsize
,
ysize
,
zsize
);
}
if
(
alpha
==
0.0
)
{
if
(
alpha
==
0.0
)
{
Vec3
boxVectors
[
3
];
Vec3
boxVectors
[
3
];
system
.
getDefaultPeriodicBoxVectors
(
boxVectors
[
0
],
boxVectors
[
1
],
boxVectors
[
2
]);
system
.
getDefaultPeriodicBoxVectors
(
boxVectors
[
0
],
boxVectors
[
1
],
boxVectors
[
2
]);
...
@@ -283,3 +287,7 @@ void NonbondedForceImpl::updateParametersInContext(ContextImpl& context) {
...
@@ -283,3 +287,7 @@ void NonbondedForceImpl::updateParametersInContext(ContextImpl& context) {
void
NonbondedForceImpl
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
void
NonbondedForceImpl
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
kernel
.
getAs
<
CalcNonbondedForceKernel
>
().
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
kernel
.
getAs
<
CalcNonbondedForceKernel
>
().
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
}
}
void
NonbondedForceImpl
::
getLJPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
kernel
.
getAs
<
CalcNonbondedForceKernel
>
().
getLJPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
}
platforms/cpu/include/CpuKernels.h
View file @
6cc49dbe
...
@@ -251,27 +251,36 @@ public:
...
@@ -251,27 +251,36 @@ public:
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
);
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
);
/**
/**
* Get the parameters being used for PME.
* Get the parameters being used for PME.
*
*
* @param alpha the separation parameter
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
* @param nz the number of grid points along the Z axis
*/
*/
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
* Get the parameters being used for the dispersion term in LJPME.
*
* @param dalpha the separation parameter
* @param dnx the number of grid points along the X axis
* @param dny the number of grid points along the Y axis
* @param dnz the number of grid points along the Z axis
*/
void
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
;
private:
private:
class
PmeIO
;
class
PmeIO
;
CpuPlatform
::
PlatformData
&
data
;
CpuPlatform
::
PlatformData
&
data
;
int
numParticles
,
num14
;
int
numParticles
,
num14
;
int
**
bonded14IndexArray
;
int
**
bonded14IndexArray
;
double
**
bonded14ParamArray
;
double
**
bonded14ParamArray
;
double
nonbondedCutoff
,
switchingDistance
,
rfDielectric
,
ewaldAlpha
,
ewaldSelfEnergy
,
dispersionCoefficient
;
double
nonbondedCutoff
,
switchingDistance
,
rfDielectric
,
ewaldAlpha
,
ewaldDispersionAlpha
,
ewaldSelfEnergy
,
dispersionCoefficient
;
int
kmax
[
3
],
gridSize
[
3
];
int
kmax
[
3
],
gridSize
[
3
]
,
dispersionGridSize
[
3
]
;
bool
useSwitchingFunction
,
useOptimizedPme
,
hasInitializedPme
;
bool
useSwitchingFunction
,
useOptimizedPme
,
hasInitializedPme
,
hasInitializedDispersionPme
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
pair
<
float
,
float
>
>
particleParams
;
std
::
vector
<
std
::
pair
<
float
,
float
>
>
particleParams
;
NonbondedMethod
nonbondedMethod
;
NonbondedMethod
nonbondedMethod
;
CpuNonbondedForce
*
nonbonded
;
CpuNonbondedForce
*
nonbonded
;
Kernel
optimizedPme
;
Kernel
optimizedPme
,
optimizedDispersionPme
;
CpuBondForce
bondForce
;
CpuBondForce
bondForce
;
};
};
...
...
platforms/cpu/src/CpuKernels.cpp
View file @
6cc49dbe
...
@@ -528,7 +528,7 @@ CpuNonbondedForce* createCpuNonbondedForceVec4();
...
@@ -528,7 +528,7 @@ CpuNonbondedForce* createCpuNonbondedForceVec4();
CpuNonbondedForce
*
createCpuNonbondedForceVec8
();
CpuNonbondedForce
*
createCpuNonbondedForceVec8
();
CpuCalcNonbondedForceKernel
::
CpuCalcNonbondedForceKernel
(
string
name
,
const
Platform
&
platform
,
CpuPlatform
::
PlatformData
&
data
)
:
CalcNonbondedForceKernel
(
name
,
platform
),
CpuCalcNonbondedForceKernel
::
CpuCalcNonbondedForceKernel
(
string
name
,
const
Platform
&
platform
,
CpuPlatform
::
PlatformData
&
data
)
:
CalcNonbondedForceKernel
(
name
,
platform
),
data
(
data
),
bonded14IndexArray
(
NULL
),
bonded14ParamArray
(
NULL
),
hasInitializedPme
(
false
),
nonbonded
(
NULL
)
{
data
(
data
),
bonded14IndexArray
(
NULL
),
bonded14ParamArray
(
NULL
),
hasInitializedPme
(
false
),
hasInitializedDispersionPme
(
false
),
nonbonded
(
NULL
)
{
if
(
isVec8Supported
())
if
(
isVec8Supported
())
nonbonded
=
createCpuNonbondedForceVec8
();
nonbonded
=
createCpuNonbondedForceVec8
();
else
else
...
@@ -616,7 +616,7 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
...
@@ -616,7 +616,7 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
}
}
else
if
(
nonbondedMethod
==
PME
)
{
else
if
(
nonbondedMethod
==
PME
)
{
double
alpha
;
double
alpha
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
force
,
alpha
,
gridSize
[
0
],
gridSize
[
1
],
gridSize
[
2
]);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
force
,
alpha
,
gridSize
[
0
],
gridSize
[
1
],
gridSize
[
2
]
,
false
);
ewaldAlpha
=
alpha
;
ewaldAlpha
=
alpha
;
}
}
if
(
nonbondedMethod
==
Ewald
||
nonbondedMethod
==
PME
)
if
(
nonbondedMethod
==
Ewald
||
nonbondedMethod
==
PME
)
...
@@ -739,7 +739,7 @@ void CpuCalcNonbondedForceKernel::copyParametersToContext(ContextImpl& context,
...
@@ -739,7 +739,7 @@ void CpuCalcNonbondedForceKernel::copyParametersToContext(ContextImpl& context,
}
}
void
CpuCalcNonbondedForceKernel
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
void
CpuCalcNonbondedForceKernel
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
if
(
nonbondedMethod
!=
PME
)
if
(
nonbondedMethod
!=
PME
&&
nonbondedMethod
!=
LJPME
)
throw
OpenMMException
(
"getPMEParametersInContext: This Context is not using PME"
);
throw
OpenMMException
(
"getPMEParametersInContext: This Context is not using PME"
);
if
(
useOptimizedPme
)
if
(
useOptimizedPme
)
optimizedPme
.
getAs
<
const
CalcPmeReciprocalForceKernel
>
().
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
optimizedPme
.
getAs
<
const
CalcPmeReciprocalForceKernel
>
().
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
...
@@ -751,6 +751,19 @@ void CpuCalcNonbondedForceKernel::getPMEParameters(double& alpha, int& nx, int&
...
@@ -751,6 +751,19 @@ void CpuCalcNonbondedForceKernel::getPMEParameters(double& alpha, int& nx, int&
}
}
}
}
void
CpuCalcNonbondedForceKernel
::
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
{
if
(
nonbondedMethod
!=
LJPME
)
throw
OpenMMException
(
"getPMEParametersInContext: This Context is not using PME"
);
if
(
useOptimizedPme
)
optimizedDispersionPme
.
getAs
<
const
CalcPmeReciprocalForceKernel
>
().
getPMEParameters
(
dalpha
,
dnx
,
dny
,
dnz
);
else
{
dalpha
=
ewaldDispersionAlpha
;
dnx
=
dispersionGridSize
[
0
];
dny
=
dispersionGridSize
[
1
];
dnz
=
dispersionGridSize
[
2
];
}
}
CpuCalcCustomNonbondedForceKernel
::
CpuCalcCustomNonbondedForceKernel
(
string
name
,
const
Platform
&
platform
,
CpuPlatform
::
PlatformData
&
data
)
:
CpuCalcCustomNonbondedForceKernel
::
CpuCalcCustomNonbondedForceKernel
(
string
name
,
const
Platform
&
platform
,
CpuPlatform
::
PlatformData
&
data
)
:
CalcCustomNonbondedForceKernel
(
name
,
platform
),
data
(
data
),
forceCopy
(
NULL
),
nonbonded
(
NULL
)
{
CalcCustomNonbondedForceKernel
(
name
,
platform
),
data
(
data
),
forceCopy
(
NULL
),
nonbonded
(
NULL
)
{
}
}
...
...
platforms/opencl/include/OpenCLKernels.h
View file @
6cc49dbe
...
@@ -607,13 +607,22 @@ public:
...
@@ -607,13 +607,22 @@ public:
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
);
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
);
/**
/**
* Get the parameters being used for PME.
* Get the parameters being used for PME.
*
*
* @param alpha the separation parameter
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
* @param nz the number of grid points along the Z axis
*/
*/
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
* Get the parameters being used for the dispersion term in LJPME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
;
private:
private:
class
SortTrait
:
public
OpenCLSort
::
SortTrait
{
class
SortTrait
:
public
OpenCLSort
::
SortTrait
{
int
getDataSize
()
const
{
return
8
;}
int
getDataSize
()
const
{
return
8
;}
...
@@ -664,8 +673,9 @@ private:
...
@@ -664,8 +673,9 @@ private:
cl
::
Kernel
pmeInterpolateForceKernel
;
cl
::
Kernel
pmeInterpolateForceKernel
;
std
::
map
<
std
::
string
,
std
::
string
>
pmeDefines
;
std
::
map
<
std
::
string
,
std
::
string
>
pmeDefines
;
std
::
vector
<
std
::
pair
<
int
,
int
>
>
exceptionAtoms
;
std
::
vector
<
std
::
pair
<
int
,
int
>
>
exceptionAtoms
;
double
ewaldSelfEnergy
,
dispersionCoefficient
,
alpha
;
double
ewaldSelfEnergy
,
dispersionCoefficient
,
alpha
,
dispersionAlpha
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
dispersionGridSizeX
,
dispersionGridSizeY
,
dispersionGridSizeZ
;
bool
hasCoulomb
,
hasLJ
,
usePmeQueue
;
bool
hasCoulomb
,
hasLJ
,
usePmeQueue
;
NonbondedMethod
nonbondedMethod
;
NonbondedMethod
nonbondedMethod
;
static
const
int
PmeOrder
=
5
;
static
const
int
PmeOrder
=
5
;
...
...
platforms/opencl/include/OpenCLParallelKernels.h
View file @
6cc49dbe
...
@@ -431,13 +431,22 @@ public:
...
@@ -431,13 +431,22 @@ public:
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
);
void
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
);
/**
/**
* Get the parameters being used for PME.
* Get the parameters being used for PME.
*
*
* @param alpha the separation parameter
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
* @param nz the number of grid points along the Z axis
*/
*/
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
* Get the parameters being used for the dispersion term in LJPME.
*
* @param dalpha the separation parameter
* @param dnx the number of grid points along the X axis
* @param dny the number of grid points along the Y axis
* @param dnz the number of grid points along the Z axis
*/
void
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
;
private:
private:
class
Task
;
class
Task
;
OpenCLPlatform
::
PlatformData
&
data
;
OpenCLPlatform
::
PlatformData
&
data
;
...
...
platforms/opencl/src/OpenCLKernels.cpp
View file @
6cc49dbe
...
@@ -1733,7 +1733,7 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb
...
@@ -1733,7 +1733,7 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb
else if (nonbondedMethod == PME) {
else if (nonbondedMethod == PME) {
// Compute the PME parameters.
// Compute the PME parameters.
NonbondedForceImpl::calcPMEParameters(system, force, alpha, gridSizeX, gridSizeY, gridSizeZ);
NonbondedForceImpl::calcPMEParameters(system, force, alpha, gridSizeX, gridSizeY, gridSizeZ
, false
);
gridSizeX = OpenCLFFT3D::findLegalDimension(gridSizeX);
gridSizeX = OpenCLFFT3D::findLegalDimension(gridSizeX);
gridSizeY = OpenCLFFT3D::findLegalDimension(gridSizeY);
gridSizeY = OpenCLFFT3D::findLegalDimension(gridSizeY);
gridSizeZ = OpenCLFFT3D::findLegalDimension(gridSizeZ);
gridSizeZ = OpenCLFFT3D::findLegalDimension(gridSizeZ);
...
@@ -2205,6 +2205,19 @@ void OpenCLCalcNonbondedForceKernel::getPMEParameters(double& alpha, int& nx, in
...
@@ -2205,6 +2205,19 @@ void OpenCLCalcNonbondedForceKernel::getPMEParameters(double& alpha, int& nx, in
}
}
}
}
void OpenCLCalcNonbondedForceKernel::getLJPMEParameters(double& dalpha, int& dnx, int& dny, int& dnz) const {
if (nonbondedMethod != LJPME)
throw OpenMMException("getPMEParametersInContext: This Context is not using PME");
if (cl.getPlatformData().useCpuPme)
cpuPme.getAs<CalcPmeReciprocalForceKernel>().getPMEParameters(dalpha, dnx, dny, dnz);
else {
dalpha = this->alpha;
dnx = gridSizeX;
dny = gridSizeY;
dnz = gridSizeZ;
}
}
class OpenCLCustomNonbondedForceInfo : public OpenCLForceInfo {
class OpenCLCustomNonbondedForceInfo : public OpenCLForceInfo {
public:
public:
OpenCLCustomNonbondedForceInfo(int requiredBuffers, const CustomNonbondedForce& force) : OpenCLForceInfo(requiredBuffers), force(force) {
OpenCLCustomNonbondedForceInfo(int requiredBuffers, const CustomNonbondedForce& force) : OpenCLForceInfo(requiredBuffers), force(force) {
...
...
platforms/opencl/src/OpenCLParallelKernels.cpp
View file @
6cc49dbe
...
@@ -583,6 +583,10 @@ void OpenCLParallelCalcNonbondedForceKernel::getPMEParameters(double& alpha, int
...
@@ -583,6 +583,10 @@ void OpenCLParallelCalcNonbondedForceKernel::getPMEParameters(double& alpha, int
dynamic_cast
<
const
OpenCLCalcNonbondedForceKernel
&>
(
kernels
[
0
].
getImpl
()).
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
dynamic_cast
<
const
OpenCLCalcNonbondedForceKernel
&>
(
kernels
[
0
].
getImpl
()).
getPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
}
}
void
OpenCLParallelCalcNonbondedForceKernel
::
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
{
dynamic_cast
<
const
OpenCLCalcNonbondedForceKernel
&>
(
kernels
[
0
].
getImpl
()).
getLJPMEParameters
(
dalpha
,
dnx
,
dny
,
dnz
);
}
class
OpenCLParallelCalcCustomNonbondedForceKernel
::
Task
:
public
OpenCLContext
::
WorkTask
{
class
OpenCLParallelCalcCustomNonbondedForceKernel
::
Task
:
public
OpenCLContext
::
WorkTask
{
public:
public:
Task
(
ContextImpl
&
context
,
OpenCLCalcCustomNonbondedForceKernel
&
kernel
,
bool
includeForce
,
Task
(
ContextImpl
&
context
,
OpenCLCalcCustomNonbondedForceKernel
&
kernel
,
bool
includeForce
,
...
...
platforms/reference/include/ReferenceKernels.h
View file @
6cc49dbe
...
@@ -604,12 +604,21 @@ public:
...
@@ -604,12 +604,21 @@ public:
* @param nz the number of grid points along the Z axis
* @param nz the number of grid points along the Z axis
*/
*/
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
/**
* Get the dispersion parameters being used for the dispersion term in LJPME.
*
* @param dalpha the separation parameter
* @param dnx the number of grid points along the X axis
* @param dny the number of grid points along the Y axis
* @param dnz the number of grid points along the Z axis
*/
void
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
;
private:
private:
int
numParticles
,
num14
;
int
numParticles
,
num14
;
int
**
bonded14IndexArray
;
int
**
bonded14IndexArray
;
RealOpenMM
**
particleParamArray
,
**
bonded14ParamArray
;
RealOpenMM
**
particleParamArray
,
**
bonded14ParamArray
;
RealOpenMM
nonbondedCutoff
,
switchingDistance
,
rfDielectric
,
ewaldAlpha
,
dispersionCoefficient
;
RealOpenMM
nonbondedCutoff
,
switchingDistance
,
rfDielectric
,
ewaldAlpha
,
ewaldDispersionAlpha
,
dispersionCoefficient
;
int
kmax
[
3
],
gridSize
[
3
];
int
kmax
[
3
],
gridSize
[
3
]
,
dispersionGridSize
[
3
]
;
bool
useSwitchingFunction
;
bool
useSwitchingFunction
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
NonbondedMethod
nonbondedMethod
;
NonbondedMethod
nonbondedMethod
;
...
...
platforms/reference/include/ReferenceLJCoulombIxn.h
View file @
6cc49dbe
...
@@ -38,14 +38,14 @@ class ReferenceLJCoulombIxn {
...
@@ -38,14 +38,14 @@ class ReferenceLJCoulombIxn {
bool
useSwitch
;
bool
useSwitch
;
bool
periodic
;
bool
periodic
;
bool
ewald
;
bool
ewald
;
bool
pme
;
bool
pme
,
ljpme
;
const
OpenMM
::
NeighborList
*
neighborList
;
const
OpenMM
::
NeighborList
*
neighborList
;
OpenMM
::
RealVec
periodicBoxVectors
[
3
];
OpenMM
::
RealVec
periodicBoxVectors
[
3
];
RealOpenMM
cutoffDistance
,
switchingDistance
;
RealOpenMM
cutoffDistance
,
switchingDistance
;
RealOpenMM
krf
,
crf
;
RealOpenMM
krf
,
crf
;
RealOpenMM
alphaEwald
;
RealOpenMM
alphaEwald
,
alphaDispersionEwald
;
int
numRx
,
numRy
,
numRz
;
int
numRx
,
numRy
,
numRz
;
int
meshDim
[
3
];
int
meshDim
[
3
]
,
dispersionMeshDim
[
3
]
;
// parameter indices
// parameter indices
...
@@ -139,16 +139,28 @@ class ReferenceLJCoulombIxn {
...
@@ -139,16 +139,28 @@ class ReferenceLJCoulombIxn {
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation.
Set the force to use Particle-Mesh Ewald (PME) summation.
@param alpha the Ewald separation parameter
@param alpha the Ewald separation parameter
@param gridSize the dimensions of the mesh
@param gridSize the dimensions of the mesh
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
setUsePME
(
RealOpenMM
alpha
,
int
meshSize
[
3
]);
void
setUsePME
(
RealOpenMM
alpha
,
int
meshSize
[
3
]);
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation for dispersion.
@param dalpha the dispersion Ewald separation parameter
@param dgridSize the dimensions of the dispersion mesh
--------------------------------------------------------------------------------------- */
void
setUseLJPME
(
RealOpenMM
dalpha
,
int
dmeshSize
[
3
]);
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn
Calculate LJ Coulomb pair ixn
...
...
platforms/reference/include/ReferencePME.h
View file @
6cc49dbe
...
@@ -87,6 +87,28 @@ pme_exec(pme_t pme,
...
@@ -87,6 +87,28 @@ pme_exec(pme_t pme,
RealOpenMM
*
energy
);
RealOpenMM
*
energy
);
/*
* Evaluate reciprocal space PME dispersion energy and forces.
*
* Args:
*
* pme Opaque pme_t object, must have been initialized with pme_init()
* x Pointer to coordinate data array (nm)
* f Pointer to force data array (will be written as kJ/mol/nm)
* c6s Array of c6 coefficients (units of sqrt(kJ/mol).nm^3 )
* box Simulation cell dimensions (nm)
* energy Total energy (will be written in units of kJ/mol)
*/
int
OPENMM_EXPORT
pme_exec_dpme
(
pme_t
pme
,
const
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
const
std
::
vector
<
RealOpenMM
>&
c6s
,
const
OpenMM
::
RealVec
periodicBoxVectors
[
3
],
RealOpenMM
*
energy
);
/* Release all memory in pme structure */
/* Release all memory in pme structure */
int
OPENMM_EXPORT
int
OPENMM_EXPORT
...
@@ -94,4 +116,4 @@ pme_destroy(pme_t pme);
...
@@ -94,4 +116,4 @@ pme_destroy(pme_t pme);
}
// namespace OpenMM
}
// namespace OpenMM
#endif // __ReferencePME_H__
#endif // __ReferencePME_H__
\ No newline at end of file
platforms/reference/src/ReferenceKernels.cpp
View file @
6cc49dbe
...
@@ -969,9 +969,17 @@ void ReferenceCalcNonbondedForceKernel::initialize(const System& system, const N
...
@@ -969,9 +969,17 @@ void ReferenceCalcNonbondedForceKernel::initialize(const System& system, const N
}
}
else
if
(
nonbondedMethod
==
PME
)
{
else
if
(
nonbondedMethod
==
PME
)
{
double
alpha
;
double
alpha
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
force
,
alpha
,
gridSize
[
0
],
gridSize
[
1
],
gridSize
[
2
]);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
force
,
alpha
,
gridSize
[
0
],
gridSize
[
1
],
gridSize
[
2
]
,
false
);
ewaldAlpha
=
(
RealOpenMM
)
alpha
;
ewaldAlpha
=
(
RealOpenMM
)
alpha
;
}
}
else
if
(
nonbondedMethod
==
LJPME
)
{
double
alpha
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
force
,
alpha
,
gridSize
[
0
],
gridSize
[
1
],
gridSize
[
2
],
false
);
ewaldAlpha
=
(
RealOpenMM
)
alpha
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
force
,
alpha
,
dispersionGridSize
[
0
],
dispersionGridSize
[
1
],
dispersionGridSize
[
2
],
true
);
ewaldDispersionAlpha
=
(
RealOpenMM
)
alpha
;
useSwitchingFunction
=
false
;
}
rfDielectric
=
(
RealOpenMM
)
force
.
getReactionFieldDielectric
();
rfDielectric
=
(
RealOpenMM
)
force
.
getReactionFieldDielectric
();
if
(
force
.
getUseDispersionCorrection
())
if
(
force
.
getUseDispersionCorrection
())
dispersionCoefficient
=
NonbondedForceImpl
::
calcDispersionCorrection
(
system
,
force
);
dispersionCoefficient
=
NonbondedForceImpl
::
calcDispersionCorrection
(
system
,
force
);
...
@@ -987,11 +995,12 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc
...
@@ -987,11 +995,12 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
pme
=
(
nonbondedMethod
==
PME
);
bool
pme
=
(
nonbondedMethod
==
PME
);
bool
ljpme
=
(
nonbondedMethod
==
LJPME
);
if
(
nonbondedMethod
!=
NoCutoff
)
{
if
(
nonbondedMethod
!=
NoCutoff
)
{
computeNeighborListVoxelHash
(
*
neighborList
,
numParticles
,
posData
,
exclusions
,
extractBoxVectors
(
context
),
periodic
||
ewald
||
pme
,
nonbondedCutoff
,
0.0
);
computeNeighborListVoxelHash
(
*
neighborList
,
numParticles
,
posData
,
exclusions
,
extractBoxVectors
(
context
),
periodic
||
ewald
||
pme
||
ljpme
,
nonbondedCutoff
,
0.0
);
clj
.
setUseCutoff
(
nonbondedCutoff
,
*
neighborList
,
rfDielectric
);
clj
.
setUseCutoff
(
nonbondedCutoff
,
*
neighborList
,
rfDielectric
);
}
}
if
(
periodic
||
ewald
||
pme
)
{
if
(
periodic
||
ewald
||
pme
||
ljpme
)
{
RealVec
*
boxVectors
=
extractBoxVectors
(
context
);
RealVec
*
boxVectors
=
extractBoxVectors
(
context
);
double
minAllowedSize
=
1.999999
*
nonbondedCutoff
;
double
minAllowedSize
=
1.999999
*
nonbondedCutoff
;
if
(
boxVectors
[
0
][
0
]
<
minAllowedSize
||
boxVectors
[
1
][
1
]
<
minAllowedSize
||
boxVectors
[
2
][
2
]
<
minAllowedSize
)
if
(
boxVectors
[
0
][
0
]
<
minAllowedSize
||
boxVectors
[
1
][
1
]
<
minAllowedSize
||
boxVectors
[
2
][
2
]
<
minAllowedSize
)
...
@@ -1002,6 +1011,10 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc
...
@@ -1002,6 +1011,10 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
if
(
pme
)
if
(
pme
)
clj
.
setUsePME
(
ewaldAlpha
,
gridSize
);
clj
.
setUsePME
(
ewaldAlpha
,
gridSize
);
if
(
ljpme
){
clj
.
setUsePME
(
ewaldAlpha
,
gridSize
);
clj
.
setUseLJPME
(
ewaldDispersionAlpha
,
dispersionGridSize
);
}
if
(
useSwitchingFunction
)
if
(
useSwitchingFunction
)
clj
.
setUseSwitchingFunction
(
switchingDistance
);
clj
.
setUseSwitchingFunction
(
switchingDistance
);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusions
,
0
,
forceData
,
0
,
includeEnergy
?
&
energy
:
NULL
,
includeDirect
,
includeReciprocal
);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusions
,
0
,
forceData
,
0
,
includeEnergy
?
&
energy
:
NULL
,
includeDirect
,
includeReciprocal
);
...
@@ -1059,14 +1072,23 @@ void ReferenceCalcNonbondedForceKernel::copyParametersToContext(ContextImpl& con
...
@@ -1059,14 +1072,23 @@ void ReferenceCalcNonbondedForceKernel::copyParametersToContext(ContextImpl& con
}
}
void
ReferenceCalcNonbondedForceKernel
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
void
ReferenceCalcNonbondedForceKernel
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
if
(
nonbondedMethod
!=
PME
)
if
(
nonbondedMethod
!=
PME
&&
nonbondedMethod
!=
LJPME
)
throw
OpenMMException
(
"getPMEParametersInContext: This Context is not using PME"
);
throw
OpenMMException
(
"getPMEParametersInContext: This Context is not using PME
or LJPME
"
);
alpha
=
ewaldAlpha
;
alpha
=
ewaldAlpha
;
nx
=
gridSize
[
0
];
nx
=
gridSize
[
0
];
ny
=
gridSize
[
1
];
ny
=
gridSize
[
1
];
nz
=
gridSize
[
2
];
nz
=
gridSize
[
2
];
}
}
void
ReferenceCalcNonbondedForceKernel
::
getLJPMEParameters
(
double
&
dalpha
,
int
&
dnx
,
int
&
dny
,
int
&
dnz
)
const
{
if
(
nonbondedMethod
!=
LJPME
)
throw
OpenMMException
(
"getPMEParametersInContext: This Context is not using LJPME"
);
dalpha
=
ewaldDispersionAlpha
;
dnx
=
dispersionGridSize
[
0
];
dny
=
dispersionGridSize
[
1
];
dnz
=
dispersionGridSize
[
2
];
}
ReferenceCalcCustomNonbondedForceKernel
::~
ReferenceCalcCustomNonbondedForceKernel
()
{
ReferenceCalcCustomNonbondedForceKernel
::~
ReferenceCalcCustomNonbondedForceKernel
()
{
disposeRealArray
(
particleParamArray
,
numParticles
);
disposeRealArray
(
particleParamArray
,
numParticles
);
if
(
neighborList
!=
NULL
)
if
(
neighborList
!=
NULL
)
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
6cc49dbe
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <sstream>
#include <sstream>
#include <complex>
#include <complex>
#include <algorithm>
#include <algorithm>
#include <iostream>
#include "SimTKOpenMMUtilities.h"
#include "SimTKOpenMMUtilities.h"
#include "ReferenceLJCoulombIxn.h"
#include "ReferenceLJCoulombIxn.h"
...
@@ -47,13 +48,13 @@ using namespace OpenMM;
...
@@ -47,13 +48,13 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
()
:
cutoff
(
false
),
useSwitch
(
false
),
periodic
(
false
),
ewald
(
false
),
pme
(
false
)
{
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
()
:
cutoff
(
false
),
useSwitch
(
false
),
periodic
(
false
),
ewald
(
false
),
pme
(
false
)
,
ljpme
(
false
)
{
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLJCoulombIxn::ReferenceLJCoulombIxn";
// static const char* methodName = "\nReferenceLJCoulombIxn::ReferenceLJCoulombIxn";
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
}
}
...
@@ -65,15 +66,15 @@ ReferenceLJCoulombIxn::ReferenceLJCoulombIxn() : cutoff(false), useSwitch(false)
...
@@ -65,15 +66,15 @@ ReferenceLJCoulombIxn::ReferenceLJCoulombIxn() : cutoff(false), useSwitch(false)
ReferenceLJCoulombIxn
::~
ReferenceLJCoulombIxn
()
{
ReferenceLJCoulombIxn
::~
ReferenceLJCoulombIxn
()
{
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLJCoulombIxn::~ReferenceLJCoulombIxn";
// static const char* methodName = "\nReferenceLJCoulombIxn::~ReferenceLJCoulombIxn";
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use a cutoff.
Set the force to use a cutoff.
...
@@ -83,14 +84,14 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn() {
...
@@ -83,14 +84,14 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn() {
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseCutoff
(
RealOpenMM
distance
,
const
OpenMM
::
NeighborList
&
neighbors
,
RealOpenMM
solventDielectric
)
{
void
ReferenceLJCoulombIxn
::
setUseCutoff
(
RealOpenMM
distance
,
const
OpenMM
::
NeighborList
&
neighbors
,
RealOpenMM
solventDielectric
)
{
cutoff
=
true
;
cutoff
=
true
;
cutoffDistance
=
distance
;
cutoffDistance
=
distance
;
neighborList
=
&
neighbors
;
neighborList
=
&
neighbors
;
krf
=
pow
(
cutoffDistance
,
-
3.0
)
*
(
solventDielectric
-
1.0
)
/
(
2.0
*
solventDielectric
+
1.0
);
krf
=
pow
(
cutoffDistance
,
-
3.0
)
*
(
solventDielectric
-
1.0
)
/
(
2.0
*
solventDielectric
+
1.0
);
crf
=
(
1.0
/
cutoffDistance
)
*
(
3.0
*
solventDielectric
)
/
(
2.0
*
solventDielectric
+
1.0
);
crf
=
(
1.0
/
cutoffDistance
)
*
(
3.0
*
solventDielectric
)
/
(
2.0
*
solventDielectric
+
1.0
);
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
...
@@ -105,7 +106,7 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
...
@@ -105,7 +106,7 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
switchingDistance
=
distance
;
switchingDistance
=
distance
;
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions. This requires that a cutoff has
Set the force to use periodic boundary conditions. This requires that a cutoff has
also been set, and the smallest side of the periodic box is at least twice the cutoff
also been set, and the smallest side of the periodic box is at least twice the cutoff
...
@@ -115,7 +116,7 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
...
@@ -115,7 +116,7 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setPeriodic
(
OpenMM
::
RealVec
*
vectors
)
{
void
ReferenceLJCoulombIxn
::
setPeriodic
(
OpenMM
::
RealVec
*
vectors
)
{
assert
(
cutoff
);
assert
(
cutoff
);
assert
(
vectors
[
0
][
0
]
>=
2.0
*
cutoffDistance
);
assert
(
vectors
[
0
][
0
]
>=
2.0
*
cutoffDistance
);
...
@@ -125,9 +126,9 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
...
@@ -125,9 +126,9 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
periodicBoxVectors
[
0
]
=
vectors
[
0
];
periodicBoxVectors
[
0
]
=
vectors
[
0
];
periodicBoxVectors
[
1
]
=
vectors
[
1
];
periodicBoxVectors
[
1
]
=
vectors
[
1
];
periodicBoxVectors
[
2
]
=
vectors
[
2
];
periodicBoxVectors
[
2
]
=
vectors
[
2
];
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use Ewald summation.
Set the force to use Ewald summation.
...
@@ -138,15 +139,15 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
...
@@ -138,15 +139,15 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
)
{
void
ReferenceLJCoulombIxn
::
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
)
{
alphaEwald
=
alpha
;
alphaEwald
=
alpha
;
numRx
=
kmaxx
;
numRx
=
kmaxx
;
numRy
=
kmaxy
;
numRy
=
kmaxy
;
numRz
=
kmaxz
;
numRz
=
kmaxz
;
ewald
=
true
;
ewald
=
true
;
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation.
Set the force to use Particle-Mesh Ewald (PME) summation.
...
@@ -155,13 +156,30 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
...
@@ -155,13 +156,30 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUsePME
(
RealOpenMM
alpha
,
int
meshSize
[
3
])
{
void
ReferenceLJCoulombIxn
::
setUsePME
(
RealOpenMM
alpha
,
int
meshSize
[
3
])
{
alphaEwald
=
alpha
;
alphaEwald
=
alpha
;
meshDim
[
0
]
=
meshSize
[
0
];
meshDim
[
0
]
=
meshSize
[
0
];
meshDim
[
1
]
=
meshSize
[
1
];
meshDim
[
1
]
=
meshSize
[
1
];
meshDim
[
2
]
=
meshSize
[
2
];
meshDim
[
2
]
=
meshSize
[
2
];
pme
=
true
;
pme
=
true
;
}
}
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation for dispersion and terms.
@param dalpha the dispersion Ewald separation parameter
@param dgridSize the dimensions of the dispersion mesh
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseLJPME
(
RealOpenMM
dalpha
,
int
dmeshSize
[
3
])
{
alphaDispersionEwald
=
dalpha
;
dispersionMeshDim
[
0
]
=
dmeshSize
[
0
];
dispersionMeshDim
[
1
]
=
dmeshSize
[
1
];
dispersionMeshDim
[
2
]
=
dmeshSize
[
2
];
ljpme
=
true
;
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
...
@@ -182,9 +200,9 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
...
@@ -182,9 +200,9 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
void
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
RealOpenMM
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
RealOpenMM
*
fixedParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
fixedParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
typedef
std
::
complex
<
RealOpenMM
>
d_complex
;
typedef
std
::
complex
<
RealOpenMM
>
d_complex
;
static
const
RealOpenMM
epsilon
=
1.0
;
static
const
RealOpenMM
epsilon
=
1.0
;
...
@@ -201,16 +219,27 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
...
@@ -201,16 +219,27 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
RealOpenMM
totalSelfEwaldEnergy
=
0.0
;
RealOpenMM
totalSelfEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
RealOpenMM
recipDispersionEnergy
=
0.0
;
RealOpenMM
totalRecipEnergy
=
0.0
;
RealOpenMM
totalRecipEnergy
=
0.0
;
RealOpenMM
vdwEnergy
=
0.0
;
RealOpenMM
vdwEnergy
=
0.0
;
// **************************************************************************************
// A couple of sanity checks for
// SELF ENERGY
if
(
ljpme
&&
useSwitch
)
// **************************************************************************************
throw
OpenMMException
(
"Switching cannot be used with LJPME"
);
if
(
ljpme
&&
!
pme
)
throw
OpenMMException
(
"LJPME has been set, without PME being set"
);
// **************************************************************************************
// SELF ENERGY
// **************************************************************************************
if
(
includeReciprocal
)
{
if
(
includeReciprocal
)
{
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
)
{
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
)
{
RealOpenMM
selfEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
);
RealOpenMM
selfEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
);
if
(
ljpme
)
{
// Dispersion self term
selfEwaldEnergy
-=
pow
(
alphaDispersionEwald
,
6.0
)
*
64.0
*
pow
(
atomParameters
[
atomID
][
SigIndex
],
6.0
)
*
pow
(
atomParameters
[
atomID
][
EpsIndex
],
2.0
)
/
12.0
;
}
totalSelfEwaldEnergy
-=
selfEwaldEnergy
;
totalSelfEwaldEnergy
-=
selfEwaldEnergy
;
if
(
energyByAtom
)
{
if
(
energyByAtom
)
{
energyByAtom
[
atomID
]
-=
selfEwaldEnergy
;
energyByAtom
[
atomID
]
-=
selfEwaldEnergy
;
...
@@ -222,194 +251,248 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
...
@@ -222,194 +251,248 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
*
totalEnergy
+=
totalSelfEwaldEnergy
;
*
totalEnergy
+=
totalSelfEwaldEnergy
;
}
}
// **************************************************************************************
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
// **************************************************************************************
// PME
// PME
if
(
pme
&&
includeReciprocal
)
{
if
(
pme
&&
includeReciprocal
)
{
pme_t
pmedata
;
/* abstract handle for PME data */
pme_t
pmedata
;
/* abstract handle for PME data */
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
if
(
totalEnergy
)
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
*
totalEnergy
+=
recipEnergy
;
if
(
energyByAtom
)
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
energyByAtom
[
n
]
+=
recipEnergy
;
pme_destroy
(
pmedata
);
pme_destroy
(
pmedata
);
}
if
(
ljpme
)
{
// Dispersion reciprocal space terms
pme_init
(
&
pmedata
,
alphaDispersionEwald
,
numberOfAtoms
,
dispersionMeshDim
,
5
,
1
);
std
::
vector
<
RealVec
>
dpmeforces
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
){
charges
[
i
]
=
8.0
*
pow
(
atomParameters
[
i
][
SigIndex
],
3.0
)
*
atomParameters
[
i
][
EpsIndex
];
dpmeforces
.
push_back
(
RealVec
());
}
pme_exec_dpme
(
pmedata
,
atomCoordinates
,
dpmeforces
,
charges
,
periodicBoxVectors
,
&
recipDispersionEnergy
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
){
forces
[
i
][
0
]
-=
2.0
*
dpmeforces
[
i
][
0
];
forces
[
i
][
1
]
-=
2.0
*
dpmeforces
[
i
][
1
];
forces
[
i
][
2
]
-=
2.0
*
dpmeforces
[
i
][
2
];
}
if
(
totalEnergy
)
*
totalEnergy
+=
recipDispersionEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipDispersionEnergy
;
pme_destroy
(
pmedata
);
}
}
// Ewald method
// Ewald method
else
if
(
ewald
&&
includeReciprocal
)
{
else
if
(
ewald
&&
includeReciprocal
)
{
// setup reciprocal box
// setup reciprocal box
RealOpenMM
recipBoxSize
[
3
]
=
{
TWO_PI
/
periodicBoxVectors
[
0
][
0
],
TWO_PI
/
periodicBoxVectors
[
1
][
1
],
TWO_PI
/
periodicBoxVectors
[
2
][
2
]};
RealOpenMM
recipBoxSize
[
3
]
=
{
TWO_PI
/
periodicBoxVectors
[
0
][
0
],
TWO_PI
/
periodicBoxVectors
[
1
][
1
],
TWO_PI
/
periodicBoxVectors
[
2
][
2
]};
// setup K-vectors
// setup K-vectors
#define EIR(x, y, z) eir[(x)*numberOfAtoms*3+(y)*3+z]
#define EIR(x, y, z) eir[(x)*numberOfAtoms*3+(y)*3+z]
vector
<
d_complex
>
eir
(
kmax
*
numberOfAtoms
*
3
);
vector
<
d_complex
>
eir
(
kmax
*
numberOfAtoms
*
3
);
vector
<
d_complex
>
tab_xy
(
numberOfAtoms
);
vector
<
d_complex
>
tab_xy
(
numberOfAtoms
);
vector
<
d_complex
>
tab_qxyz
(
numberOfAtoms
);
vector
<
d_complex
>
tab_qxyz
(
numberOfAtoms
);
if
(
kmax
<
1
)
if
(
kmax
<
1
)
throw
OpenMMException
(
"kmax for Ewald summation < 1"
);
throw
OpenMMException
(
"kmax for Ewald summation < 1"
);
for
(
int
i
=
0
;
(
i
<
numberOfAtoms
);
i
++
)
{
for
(
int
i
=
0
;
(
i
<
numberOfAtoms
);
i
++
)
{
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
0
,
i
,
m
)
=
d_complex
(
1
,
0
);
EIR
(
0
,
i
,
m
)
=
d_complex
(
1
,
0
);
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
1
,
i
,
m
)
=
d_complex
(
cos
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]),
EIR
(
1
,
i
,
m
)
=
d_complex
(
cos
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]),
sin
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]));
sin
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]));
for
(
int
j
=
2
;
(
j
<
kmax
);
j
++
)
for
(
int
j
=
2
;
(
j
<
kmax
);
j
++
)
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
j
,
i
,
m
)
=
EIR
(
j
-
1
,
i
,
m
)
*
EIR
(
1
,
i
,
m
);
EIR
(
j
,
i
,
m
)
=
EIR
(
j
-
1
,
i
,
m
)
*
EIR
(
1
,
i
,
m
);
}
}
// calculate reciprocal space energy and forces
// calculate reciprocal space energy and forces
int
lowry
=
0
;
int
lowry
=
0
;
int
lowrz
=
1
;
int
lowrz
=
1
;
for
(
int
rx
=
0
;
rx
<
numRx
;
rx
++
)
{
for
(
int
rx
=
0
;
rx
<
numRx
;
rx
++
)
{
RealOpenMM
kx
=
rx
*
recipBoxSize
[
0
];
RealOpenMM
kx
=
rx
*
recipBoxSize
[
0
];
for
(
int
ry
=
lowry
;
ry
<
numRy
;
ry
++
)
{
for
(
int
ry
=
lowry
;
ry
<
numRy
;
ry
++
)
{
RealOpenMM
ky
=
ry
*
recipBoxSize
[
1
];
RealOpenMM
ky
=
ry
*
recipBoxSize
[
1
];
if
(
ry
>=
0
)
{
if
(
ry
>=
0
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_xy
[
n
]
=
EIR
(
rx
,
n
,
0
)
*
EIR
(
ry
,
n
,
1
);
tab_xy
[
n
]
=
EIR
(
rx
,
n
,
0
)
*
EIR
(
ry
,
n
,
1
);
}
}
else
{
else
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_xy
[
n
]
=
EIR
(
rx
,
n
,
0
)
*
conj
(
EIR
(
-
ry
,
n
,
1
));
tab_xy
[
n
]
=
EIR
(
rx
,
n
,
0
)
*
conj
(
EIR
(
-
ry
,
n
,
1
));
}
}
for
(
int
rz
=
lowrz
;
rz
<
numRz
;
rz
++
)
{
for
(
int
rz
=
lowrz
;
rz
<
numRz
;
rz
++
)
{
if
(
rz
>=
0
)
{
if
(
rz
>=
0
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
EIR
(
rz
,
n
,
2
));
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
EIR
(
rz
,
n
,
2
));
}
}
else
{
else
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
conj
(
EIR
(
-
rz
,
n
,
2
)));
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
conj
(
EIR
(
-
rz
,
n
,
2
)));
}
}
RealOpenMM
cs
=
0.0
f
;
RealOpenMM
cs
=
0.0
f
;
RealOpenMM
ss
=
0.0
f
;
RealOpenMM
ss
=
0.0
f
;
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
cs
+=
tab_qxyz
[
n
].
real
();
cs
+=
tab_qxyz
[
n
].
real
();
ss
+=
tab_qxyz
[
n
].
imag
();
ss
+=
tab_qxyz
[
n
].
imag
();
}
}
RealOpenMM
kz
=
rz
*
recipBoxSize
[
2
];
RealOpenMM
kz
=
rz
*
recipBoxSize
[
2
];
RealOpenMM
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
RealOpenMM
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
RealOpenMM
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
RealOpenMM
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
RealOpenMM
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
RealOpenMM
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
forces
[
n
][
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
forces
[
n
][
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
forces
[
n
][
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
forces
[
n
][
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
forces
[
n
][
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
forces
[
n
][
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
}
}
recipEnergy
=
recipCoeff
*
ak
*
(
cs
*
cs
+
ss
*
ss
);
recipEnergy
=
recipCoeff
*
ak
*
(
cs
*
cs
+
ss
*
ss
);
totalRecipEnergy
+=
recipEnergy
;
totalRecipEnergy
+=
recipEnergy
;
if
(
totalEnergy
)
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
*
totalEnergy
+=
recipEnergy
;
if
(
energyByAtom
)
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
energyByAtom
[
n
]
+=
recipEnergy
;
lowrz
=
1
-
numRz
;
lowrz
=
1
-
numRz
;
}
lowry
=
1
-
numRy
;
}
}
}
lowry
=
1
-
numRy
;
}
}
}
}
// **************************************************************************************
// **************************************************************************************
// SHORT-RANGE ENERGY AND FORCES
// SHORT-RANGE ENERGY AND FORCES
// **************************************************************************************
// **************************************************************************************
if
(
!
includeDirect
)
if
(
!
includeDirect
)
return
;
return
;
RealOpenMM
totalVdwEnergy
=
0.0
f
;
RealOpenMM
totalVdwEnergy
=
0.0
f
;
RealOpenMM
totalRealSpaceEwaldEnergy
=
0.0
f
;
RealOpenMM
totalRealSpaceEwaldEnergy
=
0.0
f
;
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
int
ii
=
pair
.
first
;
int
ii
=
pair
.
first
;
int
jj
=
pair
.
second
;
int
jj
=
pair
.
second
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxVectors
,
deltaR
[
0
]);
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxVectors
,
deltaR
[
0
]);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
switchValue
=
1
,
switchDeriv
=
0
;
RealOpenMM
switchValue
=
1
,
switchDeriv
=
0
;
if
(
useSwitch
&&
r
>
switchingDistance
)
{
if
(
useSwitch
&&
r
>
switchingDistance
)
{
RealOpenMM
t
=
(
r
-
switchingDistance
)
/
(
cutoffDistance
-
switchingDistance
);
RealOpenMM
t
=
(
r
-
switchingDistance
)
/
(
cutoffDistance
-
switchingDistance
);
switchValue
=
1
+
t
*
t
*
t
*
(
-
10
+
t
*
(
15
-
t
*
6
));
switchValue
=
1
+
t
*
t
*
t
*
(
-
10
+
t
*
(
15
-
t
*
6
));
switchDeriv
=
t
*
t
*
(
-
30
+
t
*
(
60
-
t
*
30
))
/
(
cutoffDistance
-
switchingDistance
);
switchDeriv
=
t
*
t
*
(
-
30
+
t
*
(
60
-
t
*
30
))
/
(
cutoffDistance
-
switchingDistance
);
}
}
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
);
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
);
dEdR
=
(
RealOpenMM
)
(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
dEdR
=
(
RealOpenMM
)
(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig2
=
inverseR
*
sig
;
RealOpenMM
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
sig2
*=
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
dEdR
+=
switchValue
*
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
*
inverseR
*
inverseR
;
dEdR
+=
switchValue
*
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
*
inverseR
*
inverseR
;
vdwEnergy
=
eps
*
(
sig6
-
one
)
*
sig6
;
vdwEnergy
=
eps
*
(
sig6
-
one
)
*
sig6
;
if
(
useSwitch
)
{
dEdR
-=
vdwEnergy
*
switchDeriv
*
inverseR
;
if
(
ljpme
)
{
vdwEnergy
*=
switchValue
;
RealOpenMM
dalphaR
=
alphaDispersionEwald
*
r
;
}
RealOpenMM
dar2
=
dalphaR
*
dalphaR
;
RealOpenMM
dar4
=
dar2
*
dar2
;
// accumulate forces
RealOpenMM
dar6
=
dar4
*
dar2
;
RealOpenMM
inverseR2
=
inverseR
*
inverseR
;
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
RealOpenMM
c6i
=
8.0
*
pow
(
atomParameters
[
ii
][
SigIndex
],
3.0
)
*
atomParameters
[
ii
][
EpsIndex
];
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
RealOpenMM
c6j
=
8.0
*
pow
(
atomParameters
[
jj
][
SigIndex
],
3.0
)
*
atomParameters
[
jj
][
EpsIndex
];
forces
[
ii
][
kk
]
+=
force
;
// For the energies and forces, we first add the regular Lorentz−Berthelot terms. The C12 term is treated as usual
forces
[
jj
][
kk
]
-=
force
;
// but we then subtract out (remembering that the C6 term is negative) the multiplicative C6 term that has been
}
// computed in real space. Finally, we add a potential shift term to account for the difference between the LB
// and multiplicative functional forms at the cutoff.
// accumulate energies
RealOpenMM
emult
=
c6i
*
c6j
*
inverseR2
*
inverseR2
*
inverseR2
*
(
1.0
-
EXP
(
-
dar2
)
*
(
1.0
+
dar2
+
0.5
*
dar4
));
dEdR
+=
6.0
*
c6i
*
c6j
*
inverseR2
*
inverseR2
*
inverseR2
*
inverseR2
*
(
1.0
-
EXP
(
-
dar2
)
*
(
1.0
+
dar2
+
0.5
*
dar4
+
dar6
/
6.0
));
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
));
// The additive part of the potential shift
RealOpenMM
inverseCut2
=
1.0
/
(
cutoffDistance
*
cutoffDistance
);
totalVdwEnergy
+=
vdwEnergy
;
RealOpenMM
inverseCut6
=
inverseCut2
*
inverseCut2
*
inverseCut2
;
totalRealSpaceEwaldEnergy
+=
realSpaceEwaldEnergy
;
sig2
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
sig2
*=
sig2
;
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
potentialshift
=
eps
*
sig6
*
inverseCut6
;
dalphaR
=
alphaDispersionEwald
*
cutoffDistance
;
dar2
=
dalphaR
*
dalphaR
;
dar4
=
dar2
*
dar2
;
// The multiplicative part of the potential shift
potentialshift
-=
c6i
*
c6j
*
inverseCut6
*
(
1.0
-
EXP
(
-
dar2
)
*
(
1.0
+
dar2
+
0.5
*
dar4
));
vdwEnergy
+=
emult
+
potentialshift
;
}
if
(
useSwitch
)
{
dEdR
-=
vdwEnergy
*
switchDeriv
*
inverseR
;
vdwEnergy
*=
switchValue
;
}
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
// accumulate energies
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
));
totalVdwEnergy
+=
vdwEnergy
;
totalRealSpaceEwaldEnergy
+=
realSpaceEwaldEnergy
;
if
(
energyByAtom
)
{
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
ii
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
jj
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
jj
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
}
}
}
}
...
@@ -424,39 +507,57 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
...
@@ -424,39 +507,57 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
for
(
set
<
int
>::
const_iterator
iter
=
exclusions
[
i
].
begin
();
iter
!=
exclusions
[
i
].
end
();
++
iter
)
{
for
(
set
<
int
>::
const_iterator
iter
=
exclusions
[
i
].
begin
();
iter
!=
exclusions
[
i
].
end
();
++
iter
)
{
if
(
*
iter
>
i
)
{
if
(
*
iter
>
i
)
{
int
ii
=
i
;
int
ii
=
i
;
int
jj
=
*
iter
;
int
jj
=
*
iter
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]);
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
alphaR
=
alphaEwald
*
r
;
if
(
erf
(
alphaR
)
>
1e-6
)
{
if
(
erf
(
alphaR
)
>
1e-6
)
{
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
);
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
);
dEdR
=
(
RealOpenMM
)
(
dEdR
*
(
erf
(
alphaR
)
-
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
dEdR
=
(
RealOpenMM
)
(
dEdR
*
(
erf
(
alphaR
)
-
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
// accumulate forces
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
-=
force
;
forces
[
ii
][
kk
]
-=
force
;
forces
[
jj
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
+=
force
;
}
}
// accumulate energies
// accumulate energies
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erf
(
alphaR
));
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erf
(
alphaR
));
}
}
else
{
else
{
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
alphaEwald
*
TWO_OVER_SQRT_PI
*
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]);
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
alphaEwald
*
TWO_OVER_SQRT_PI
*
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]);
}
}
totalExclusionEnergy
+=
realSpaceEwaldEnergy
;
if
(
ljpme
){
if
(
energyByAtom
)
{
// Dispersion terms. Here we just back out the reciprocal space terms, and don't add any extra real space terms.
energyByAtom
[
ii
]
-=
realSpaceEwaldEnergy
;
RealOpenMM
dalphaR
=
alphaDispersionEwald
*
r
;
energyByAtom
[
jj
]
-=
realSpaceEwaldEnergy
;
RealOpenMM
inverseR2
=
inverseR
*
inverseR
;
}
RealOpenMM
dar2
=
dalphaR
*
dalphaR
;
RealOpenMM
dar4
=
dar2
*
dar2
;
RealOpenMM
dar6
=
dar4
*
dar2
;
RealOpenMM
c6i
=
8.0
*
pow
(
atomParameters
[
ii
][
SigIndex
],
3.0
)
*
atomParameters
[
ii
][
EpsIndex
];
RealOpenMM
c6j
=
8.0
*
pow
(
atomParameters
[
jj
][
SigIndex
],
3.0
)
*
atomParameters
[
jj
][
EpsIndex
];
realSpaceEwaldEnergy
-=
c6i
*
c6j
*
inverseR2
*
inverseR2
*
inverseR2
*
(
1.0
-
EXP
(
-
dar2
)
*
(
1.0
+
dar2
+
0.5
*
dar4
));
RealOpenMM
dEdR
=
-
6.0
*
c6i
*
c6j
*
inverseR2
*
inverseR2
*
inverseR2
*
inverseR2
*
(
1.0
-
EXP
(
-
dar2
)
*
(
1.0
+
dar2
+
0.5
*
dar4
+
dar6
/
6.0
));
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
-=
force
;
forces
[
jj
][
kk
]
+=
force
;
}
}
totalExclusionEnergy
+=
realSpaceEwaldEnergy
;
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
-=
realSpaceEwaldEnergy
;
energyByAtom
[
jj
]
-=
realSpaceEwaldEnergy
;
}
}
}
}
}
...
@@ -488,31 +589,31 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector<RealVec>&
...
@@ -488,31 +589,31 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector<RealVec>&
RealOpenMM
*
fixedParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
fixedParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
if
(
ewald
||
pme
)
{
if
(
ewald
||
pme
||
ljpme
)
{
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
,
includeDirect
,
includeReciprocal
);
totalEnergy
,
includeDirect
,
includeReciprocal
);
return
;
return
;
}
}
if
(
!
includeDirect
)
if
(
!
includeDirect
)
return
;
return
;
if
(
cutoff
)
{
if
(
cutoff
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
atomParameters
,
forces
,
energyByAtom
,
totalEnergy
);
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
atomParameters
,
forces
,
energyByAtom
,
totalEnergy
);
}
}
}
}
else
{
else
{
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
// loop over atom pairs
// loop over atom pairs
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
)
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
)
if
(
exclusions
[
jj
].
find
(
ii
)
==
exclusions
[
jj
].
end
())
if
(
exclusions
[
jj
].
find
(
ii
)
==
exclusions
[
jj
].
end
())
calculateOneIxn
(
ii
,
jj
,
atomCoordinates
,
atomParameters
,
forces
,
energyByAtom
,
totalEnergy
);
calculateOneIxn
(
ii
,
jj
,
atomCoordinates
,
atomParameters
,
forces
,
energyByAtom
,
totalEnergy
);
}
}
}
}
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn between two atoms
Calculate LJ Coulomb pair ixn between two atoms
...
@@ -527,8 +628,8 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector<RealVec>&
...
@@ -527,8 +628,8 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector<RealVec>&
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
calculateOneIxn
(
int
ii
,
int
jj
,
vector
<
RealVec
>&
atomCoordinates
,
void
ReferenceLJCoulombIxn
::
calculateOneIxn
(
int
ii
,
int
jj
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
**
atomParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
**
atomParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
...
@@ -572,7 +673,7 @@ void ReferenceLJCoulombIxn::calculateOneIxn(int ii, int jj, vector<RealVec>& ato
...
@@ -572,7 +673,7 @@ void ReferenceLJCoulombIxn::calculateOneIxn(int ii, int jj, vector<RealVec>& ato
}
}
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig2
=
inverseR
*
sig
;
RealOpenMM
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
sig2
*=
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
...
@@ -595,18 +696,18 @@ void ReferenceLJCoulombIxn::calculateOneIxn(int ii, int jj, vector<RealVec>& ato
...
@@ -595,18 +696,18 @@ void ReferenceLJCoulombIxn::calculateOneIxn(int ii, int jj, vector<RealVec>& ato
// accumulate forces
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
}
// accumulate energies
// accumulate energies
if
(
totalEnergy
)
if
(
totalEnergy
)
*
totalEnergy
+=
energy
;
*
totalEnergy
+=
energy
;
if
(
energyByAtom
)
{
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
+=
energy
;
energyByAtom
[
ii
]
+=
energy
;
energyByAtom
[
jj
]
+=
energy
;
energyByAtom
[
jj
]
+=
energy
;
}
}
}
}
platforms/reference/src/SimTKReference/ReferencePME.cpp
View file @
6cc49dbe
...
@@ -513,6 +513,106 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -513,6 +513,106 @@ pme_reciprocal_convolution(pme_t pme,
}
}
static
void
dpme_reciprocal_convolution
(
pme_t
pme
,
const
RealVec
periodicBoxVectors
[
3
],
const
RealVec
recipBoxVectors
[
3
],
RealOpenMM
*
energy
)
{
int
kx
,
ky
,
kz
;
int
nx
,
ny
,
nz
;
RealOpenMM
mx
,
my
,
mz
;
RealOpenMM
mhx
,
mhy
,
mhz
,
m2
;
RealOpenMM
bx
,
by
,
bz
;
RealOpenMM
d1
,
d2
;
RealOpenMM
eterm
,
struct2
,
ets2
;
RealOpenMM
esum
;
RealOpenMM
denom
;
RealOpenMM
boxfactor
;
RealOpenMM
maxkx
,
maxky
,
maxkz
;
t_complex
*
ptr
;
nx
=
pme
->
ngrid
[
0
];
ny
=
pme
->
ngrid
[
1
];
nz
=
pme
->
ngrid
[
2
];
boxfactor
=
(
RealOpenMM
)
M_PI
*
sqrt
(
M_PI
)
/
(
6.0
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]);
esum
=
0
;
maxkx
=
(
RealOpenMM
)
((
nx
+
1
)
/
2
);
maxky
=
(
RealOpenMM
)
((
ny
+
1
)
/
2
);
maxkz
=
(
RealOpenMM
)
((
nz
+
1
)
/
2
);
RealOpenMM
bfac
=
M_PI
/
pme
->
ewaldcoeff
;
RealOpenMM
fac1
=
2.0
*
M_PI
*
M_PI
*
M_PI
*
sqrt
(
M_PI
);
RealOpenMM
fac2
=
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
;
RealOpenMM
fac3
=
-
2.0
*
pme
->
ewaldcoeff
*
M_PI
*
M_PI
;
RealOpenMM
b
,
m
,
m3
,
expfac
,
expterm
,
erfcterm
;
for
(
kx
=
0
;
kx
<
nx
;
kx
++
)
{
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
mx
=
(
RealOpenMM
)
((
kx
<
maxkx
)
?
kx
:
(
kx
-
nx
));
mhx
=
mx
*
recipBoxVectors
[
0
][
0
];
bx
=
pme
->
bsplines_moduli
[
0
][
kx
];
for
(
ky
=
0
;
ky
<
ny
;
ky
++
)
{
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
my
=
(
RealOpenMM
)
((
ky
<
maxky
)
?
ky
:
(
ky
-
ny
));
mhy
=
mx
*
recipBoxVectors
[
1
][
0
]
+
my
*
recipBoxVectors
[
1
][
1
];
by
=
pme
->
bsplines_moduli
[
1
][
ky
];
for
(
kz
=
0
;
kz
<
nz
;
kz
++
)
{
/*
* Unlike the Coulombic case, there's an m=0 term so all terms are considered here.
*/
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
mz
=
(
RealOpenMM
)
((
kz
<
maxkz
)
?
kz
:
(
kz
-
nz
));
mhz
=
mx
*
recipBoxVectors
[
2
][
0
]
+
my
*
recipBoxVectors
[
2
][
1
]
+
mz
*
recipBoxVectors
[
2
][
2
];
/* Pointer to the grid cell in question */
ptr
=
pme
->
grid
+
kx
*
ny
*
nz
+
ky
*
nz
+
kz
;
/* Get grid data for this frequency */
d1
=
ptr
->
re
;
d2
=
ptr
->
im
;
/* Calculate the convolution - see the Essman/Darden paper for the equation! */
m2
=
mhx
*
mhx
+
mhy
*
mhy
+
mhz
*
mhz
;
bz
=
pme
->
bsplines_moduli
[
2
][
kz
];
denom
=
boxfactor
/
(
bx
*
by
*
bz
);
m
=
sqrt
(
m2
);
m3
=
m
*
m2
;
b
=
bfac
*
m
;
expfac
=
-
b
*
b
;
erfcterm
=
erfc
(
b
);
expterm
=
exp
(
expfac
);
eterm
=
(
fac1
*
erfcterm
*
m3
+
expterm
*
(
fac2
+
fac3
*
m2
))
*
denom
;
/* write back convolution data to grid */
ptr
->
re
=
d1
*
eterm
;
ptr
->
im
=
d2
*
eterm
;
struct2
=
(
d1
*
d1
+
d2
*
d2
);
/* Long-range PME contribution to the energy for this frequency */
ets2
=
eterm
*
struct2
;
esum
+=
ets2
;
}
}
}
// Remember the C6 energy is attractive, hence the negative sign.
*
energy
=
(
RealOpenMM
)
(
-
esum
);
}
static
void
static
void
pme_grid_interpolate_force
(
pme_t
pme
,
pme_grid_interpolate_force
(
pme_t
pme
,
const
RealVec
recipBoxVectors
[
3
],
const
RealVec
recipBoxVectors
[
3
],
...
@@ -704,6 +804,49 @@ int pme_exec(pme_t pme,
...
@@ -704,6 +804,49 @@ int pme_exec(pme_t pme,
}
}
int
pme_exec_dpme
(
pme_t
pme
,
const
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
forces
,
const
vector
<
RealOpenMM
>&
c6s
,
const
RealVec
periodicBoxVectors
[
3
],
RealOpenMM
*
energy
)
{
/* Routine is called with coordinates in x, a box, and charges in q */
RealVec
recipBoxVectors
[
3
];
invert_box_vectors
(
periodicBoxVectors
,
recipBoxVectors
);
/* Before we can do the actual interpolation, we need to recalculate and update
* the indices for each particle in the charge grid (initialized in pme_init()),
* and what its fractional offset in this grid cell is.
*/
/* Update charge grid indices and fractional offsets for each atom.
* The indices/fractions are stored internally in the pme datatype
*/
pme_update_grid_index_and_fraction
(
pme
,
atomCoordinates
,
periodicBoxVectors
,
recipBoxVectors
);
/* Calculate bsplines (and their differentials) from current fractional coordinates, store in pme structure */
pme_update_bsplines
(
pme
);
/* Spread the charges on grid (using newly calculated bsplines in the pme structure) */
pme_grid_spread_charge
(
pme
,
c6s
);
/* do 3d-fft */
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_FORWARD
,
pme
->
grid
,
pme
->
grid
);
/* solve in k-space */
dpme_reciprocal_convolution
(
pme
,
periodicBoxVectors
,
recipBoxVectors
,
energy
);
/* do 3d-invfft */
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_BACKWARD
,
pme
->
grid
,
pme
->
grid
);
/* Get the particle forces from the grid and bsplines in the pme structure */
pme_grid_interpolate_force
(
pme
,
recipBoxVectors
,
c6s
,
forces
);
return
0
;
}
int
int
pme_destroy
(
pme_t
pme
)
pme_destroy
(
pme_t
pme
)
...
...
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
View file @
6cc49dbe
...
@@ -602,7 +602,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
...
@@ -602,7 +602,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
nb
.
setEwaldErrorTolerance
(
force
.
getEwaldErrorTolerance
());
nb
.
setEwaldErrorTolerance
(
force
.
getEwaldErrorTolerance
());
nb
.
setCutoffDistance
(
force
.
getCutoffDistance
());
nb
.
setCutoffDistance
(
force
.
getCutoffDistance
());
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
nb
,
alphaEwald
,
gridSizeX
,
gridSizeY
,
gridSizeZ
);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
nb
,
alphaEwald
,
gridSizeX
,
gridSizeY
,
gridSizeZ
,
false
);
pmeGridDimension
[
0
]
=
gridSizeX
;
pmeGridDimension
[
0
]
=
gridSizeX
;
pmeGridDimension
[
1
]
=
gridSizeY
;
pmeGridDimension
[
1
]
=
gridSizeY
;
pmeGridDimension
[
2
]
=
gridSizeZ
;
pmeGridDimension
[
2
]
=
gridSizeZ
;
...
...
plugins/cpupme/tests/TestCpuPme.cpp
View file @
6cc49dbe
...
@@ -108,7 +108,7 @@ void testPME(bool triclinic) {
...
@@ -108,7 +108,7 @@ void testPME(bool triclinic) {
double
alpha
;
double
alpha
;
int
gridx
,
gridy
,
gridz
;
int
gridx
,
gridy
,
gridz
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
alpha
,
gridx
,
gridy
,
gridz
);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
alpha
,
gridx
,
gridy
,
gridz
,
false
);
CpuCalcPmeReciprocalForceKernel
pme
(
CalcPmeReciprocalForceKernel
::
Name
(),
platform
);
CpuCalcPmeReciprocalForceKernel
pme
(
CalcPmeReciprocalForceKernel
::
Name
(),
platform
);
IO
io
;
IO
io
;
double
sumSquaredCharges
=
0
;
double
sumSquaredCharges
=
0
;
...
...
tests/TestEwald.h
View file @
6cc49dbe
...
@@ -365,7 +365,7 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) {
...
@@ -365,7 +365,7 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) {
double
expectedAlpha
,
actualAlpha
;
double
expectedAlpha
,
actualAlpha
;
int
expectedSize
[
3
],
actualSize
[
3
];
int
expectedSize
[
3
],
actualSize
[
3
];
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
expectedAlpha
,
expectedSize
[
0
],
expectedSize
[
1
],
expectedSize
[
2
]);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
expectedAlpha
,
expectedSize
[
0
],
expectedSize
[
1
],
expectedSize
[
2
]
,
false
);
force
->
getPMEParametersInContext
(
context
,
actualAlpha
,
actualSize
[
0
],
actualSize
[
1
],
actualSize
[
2
]);
force
->
getPMEParametersInContext
(
context
,
actualAlpha
,
actualSize
[
0
],
actualSize
[
1
],
actualSize
[
2
]);
ASSERT_EQUAL_TOL
(
expectedAlpha
,
actualAlpha
,
1e-5
);
ASSERT_EQUAL_TOL
(
expectedAlpha
,
actualAlpha
,
1e-5
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
...
...
Prev
1
2
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