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
9bc194b9
Commit
9bc194b9
authored
Oct 10, 2013
by
peastman
Browse files
Began creating optimized implementation of direct space nonbonded calculation
parent
50d4f9d0
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
905 additions
and
90 deletions
+905
-90
platforms/cpu/include/CpuKernels.h
platforms/cpu/include/CpuKernels.h
+3
-1
platforms/cpu/include/CpuNonbondedForce.h
platforms/cpu/include/CpuNonbondedForce.h
+204
-0
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+104
-87
platforms/cpu/src/CpuNonbondedForce.cpp
platforms/cpu/src/CpuNonbondedForce.cpp
+591
-0
platforms/reference/include/ReferencePME.h
platforms/reference/include/ReferencePME.h
+0
-0
platforms/reference/include/ReferencePairIxn.h
platforms/reference/include/ReferencePairIxn.h
+1
-0
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+1
-1
platforms/reference/src/SimTKReference/ReferencePME.cpp
platforms/reference/src/SimTKReference/ReferencePME.cpp
+1
-1
No files found.
platforms/cpu/include/CpuKernels.h
View file @
9bc194b9
...
@@ -75,12 +75,14 @@ public:
...
@@ -75,12 +75,14 @@ public:
private:
private:
int
numParticles
,
num14
;
int
numParticles
,
num14
;
int
**
bonded14IndexArray
;
int
**
bonded14IndexArray
;
double
**
particleParamArray
,
**
bonded14ParamArray
;
float
**
particleParamArray
;
double
**
bonded14ParamArray
;
double
nonbondedCutoff
,
switchingDistance
,
rfDielectric
,
ewaldAlpha
,
dispersionCoefficient
;
double
nonbondedCutoff
,
switchingDistance
,
rfDielectric
,
ewaldAlpha
,
dispersionCoefficient
;
int
kmax
[
3
],
gridSize
[
3
];
int
kmax
[
3
],
gridSize
[
3
];
bool
useSwitchingFunction
;
bool
useSwitchingFunction
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
float
>
posq
;
std
::
vector
<
float
>
posq
;
std
::
vector
<
float
>
forces
;
NonbondedMethod
nonbondedMethod
;
NonbondedMethod
nonbondedMethod
;
CpuNeighborList
neighborList
;
CpuNeighborList
neighborList
;
};
};
...
...
platforms/cpu/include/CpuNonbondedForce.h
0 → 100644
View file @
9bc194b9
/* Portions copyright (c) 2006-2013 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef OPENMM_CPU_NONBONDED_FORCE_H__
#define OPENMM_CPU_NONBONDED_FORCE_H__
#include "ReferencePairIxn.h"
#include <set>
#include <utility>
#include <vector>
// ---------------------------------------------------------------------------------------
class
CpuNonbondedForce
{
private:
bool
cutoff
;
bool
useSwitch
;
bool
periodic
;
bool
ewald
;
bool
pme
;
const
std
::
vector
<
std
::
pair
<
int
,
int
>
>*
neighborList
;
float
periodicBoxSize
[
3
];
float
cutoffDistance
,
switchingDistance
;
float
krf
,
crf
;
float
alphaEwald
;
int
numRx
,
numRy
,
numRz
;
int
meshDim
[
3
];
// parameter indices
static
const
int
SigIndex
=
0
;
static
const
int
EpsIndex
=
1
;
static
const
int
QIndex
=
2
;
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn between two atoms
@param atom1 the index of the first atom
@param atom2 the index of the second atom
@param atomCoordinates atom coordinates
@param atomParameters atom parameters (charges, c6, c12, ...) atomParameters[atomIndex][paramterIndex]
@param forces force array (forces added)
@param totalEnergy total energy
--------------------------------------------------------------------------------------- */
void
calculateOneIxn
(
int
atom1
,
int
atom2
,
float
*
atomCoordinates
,
float
**
atomParameters
,
float
*
forces
,
float
*
totalEnergy
)
const
;
public:
/**---------------------------------------------------------------------------------------
Constructor
--------------------------------------------------------------------------------------- */
CpuNonbondedForce
(
);
/**---------------------------------------------------------------------------------------
Destructor
--------------------------------------------------------------------------------------- */
~
CpuNonbondedForce
(
);
/**---------------------------------------------------------------------------------------
Set the force to use a cutoff.
@param distance the cutoff distance
@param neighbors the neighbor list to use
@param solventDielectric the dielectric constant of the bulk solvent
--------------------------------------------------------------------------------------- */
void
setUseCutoff
(
float
distance
,
const
std
::
vector
<
std
::
pair
<
int
,
int
>
>&
neighbors
,
float
solventDielectric
);
/**---------------------------------------------------------------------------------------
Set the force to use a switching function on the Lennard-Jones interaction.
@param distance the switching distance
--------------------------------------------------------------------------------------- */
void
setUseSwitchingFunction
(
float
distance
);
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions. This requires that a cutoff has
already been set, and the smallest side of the periodic box is at least twice the cutoff
distance.
@param boxSize the X, Y, and Z widths of the periodic box
--------------------------------------------------------------------------------------- */
void
setPeriodic
(
float
*
boxSize
);
/**---------------------------------------------------------------------------------------
Set the force to use Ewald summation.
@param alpha the Ewald separation parameter
@param kmaxx the largest wave vector in the x direction
@param kmaxy the largest wave vector in the y direction
@param kmaxz the largest wave vector in the z direction
--------------------------------------------------------------------------------------- */
void
setUseEwald
(
float
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
);
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation.
@param alpha the Ewald separation parameter
@param gridSize the dimensions of the mesh
--------------------------------------------------------------------------------------- */
void
setUsePME
(
float
alpha
,
int
meshSize
[
3
]);
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters (charges, c6, c12, ...) atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices
exclusions[atomIndex] contains the list of exclusions for that atom
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param totalEnergy total energy
@param includeDirect true if direct space interactions should be included
@param includeReciprocal true if reciprocal space interactions should be included
--------------------------------------------------------------------------------------- */
void
calculatePairIxn
(
int
numberOfAtoms
,
float
*
atomCoordinates
,
float
**
atomParameters
,
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
float
*
fixedParameters
,
float
*
forces
,
float
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
;
private:
/**---------------------------------------------------------------------------------------
Calculate Ewald ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters (charges, c6, c12, ...) atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices
exclusions[atomIndex] contains the list of exclusions for that atom
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param totalEnergy total energy
@param includeDirect true if direct space interactions should be included
@param includeReciprocal true if reciprocal space interactions should be included
--------------------------------------------------------------------------------------- */
void
calculateEwaldIxn
(
int
numberOfAtoms
,
float
*
atomCoordinates
,
float
**
atomParameters
,
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
float
*
fixedParameters
,
float
*
forces
,
float
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
;
void
getDeltaR
(
const
float
*
atomCoordinatesI
,
const
float
*
atomCoordinatesJ
,
const
float
*
boxSize
,
float
*
deltaR
,
bool
periodic
)
const
;
};
// ---------------------------------------------------------------------------------------
#endif // OPENMM_CPU_NONBONDED_FORCE_H__
platforms/cpu/src/CpuKernels.cpp
View file @
9bc194b9
...
@@ -30,7 +30,11 @@
...
@@ -30,7 +30,11 @@
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
#include "CpuKernels.h"
#include "CpuKernels.h"
#include "CpuNonbondedForce.h"
#include "ReferenceBondForce.h"
#include "ReferenceLJCoulomb14.h"
#include "openmm/Context.h"
#include "openmm/Context.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "RealVec.h"
#include "RealVec.h"
...
@@ -59,6 +63,9 @@ static RealVec& extractBoxSize(ContextImpl& context) {
...
@@ -59,6 +63,9 @@ static RealVec& extractBoxSize(ContextImpl& context) {
}
}
CpuCalcNonbondedForceKernel
::~
CpuCalcNonbondedForceKernel
()
{
CpuCalcNonbondedForceKernel
::~
CpuCalcNonbondedForceKernel
()
{
delete
bonded14IndexArray
;
// Do this properly
delete
bonded14ParamArray
;
// Do this properly
delete
particleParamArray
;
// Do this properly
}
}
void
CpuCalcNonbondedForceKernel
::
initialize
(
const
System
&
system
,
const
NonbondedForce
&
force
)
{
void
CpuCalcNonbondedForceKernel
::
initialize
(
const
System
&
system
,
const
NonbondedForce
&
force
)
{
...
@@ -66,6 +73,8 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
...
@@ -66,6 +73,8 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
// Identify which exceptions are 1-4 interactions.
// Identify which exceptions are 1-4 interactions.
numParticles
=
force
.
getNumParticles
();
numParticles
=
force
.
getNumParticles
();
posq
.
resize
(
4
*
numParticles
,
0
);
forces
.
resize
(
4
*
numParticles
,
0
);
exclusions
.
resize
(
numParticles
);
exclusions
.
resize
(
numParticles
);
vector
<
int
>
nb14s
;
vector
<
int
>
nb14s
;
for
(
int
i
=
0
;
i
<
force
.
getNumExceptions
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumExceptions
();
i
++
)
{
...
@@ -81,29 +90,33 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
...
@@ -81,29 +90,33 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
// Record the particle parameters.
// Record the particle parameters.
num14
=
nb14s
.
size
();
num14
=
nb14s
.
size
();
// bonded14IndexArray = allocateIntArray(num14, 2);
bonded14IndexArray
=
new
int
*
[
num14
];
// bonded14ParamArray = allocateRealArray(num14, 3);
for
(
int
i
=
0
;
i
<
num14
;
i
++
)
// particleParamArray = allocateRealArray(numParticles, 3);
bonded14IndexArray
[
i
]
=
new
int
[
2
];
posq
.
resize
(
4
*
numParticles
,
0
);
bonded14ParamArray
=
new
double
*
[
num14
];
for
(
int
i
=
0
;
i
<
num14
;
i
++
)
bonded14ParamArray
[
i
]
=
new
double
[
3
];
particleParamArray
=
new
float
*
[
numParticles
];
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
particleParamArray
[
i
]
=
new
float
[
3
];
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
double
charge
,
radius
,
depth
;
double
charge
,
radius
,
depth
;
force
.
getParticleParameters
(
i
,
charge
,
radius
,
depth
);
force
.
getParticleParameters
(
i
,
charge
,
radius
,
depth
);
posq
[
4
*
i
+
3
]
=
(
float
)
charge
;
posq
[
4
*
i
+
3
]
=
(
float
)
charge
;
// particleParamArray[i][0] = static_cast<RealOpenMM>(0.5*radius);
particleParamArray
[
i
][
0
]
=
(
float
)
(
0.5
*
radius
);
// particleParamArray[i][1] = static_cast<RealOpenMM>(2.0*sqrt(depth));
particleParamArray
[
i
][
1
]
=
(
float
)
(
2.0
*
sqrt
(
depth
));
// particleParamArray[i][2] = static_cast<RealOpenMM>(charge);
particleParamArray
[
i
][
2
]
=
(
float
)
(
charge
);
}
for
(
int
i
=
0
;
i
<
num14
;
++
i
)
{
int
particle1
,
particle2
;
double
charge
,
radius
,
depth
;
force
.
getExceptionParameters
(
nb14s
[
i
],
particle1
,
particle2
,
charge
,
radius
,
depth
);
bonded14IndexArray
[
i
][
0
]
=
particle1
;
bonded14IndexArray
[
i
][
1
]
=
particle2
;
bonded14ParamArray
[
i
][
0
]
=
static_cast
<
RealOpenMM
>
(
radius
);
bonded14ParamArray
[
i
][
1
]
=
static_cast
<
RealOpenMM
>
(
4.0
*
depth
);
bonded14ParamArray
[
i
][
2
]
=
static_cast
<
RealOpenMM
>
(
charge
);
}
}
// this->exclusions = exclusions;
// for (int i = 0; i < num14; ++i) {
// int particle1, particle2;
// double charge, radius, depth;
// force.getExceptionParameters(nb14s[i], particle1, particle2, charge, radius, depth);
// bonded14IndexArray[i][0] = particle1;
// bonded14IndexArray[i][1] = particle2;
// bonded14ParamArray[i][0] = static_cast<RealOpenMM>(radius);
// bonded14ParamArray[i][1] = static_cast<RealOpenMM>(4.0*depth);
// bonded14ParamArray[i][2] = static_cast<RealOpenMM>(charge);
// }
nonbondedMethod
=
CalcNonbondedForceKernel
::
NonbondedMethod
(
force
.
getNonbondedMethod
());
nonbondedMethod
=
CalcNonbondedForceKernel
::
NonbondedMethod
(
force
.
getNonbondedMethod
());
nonbondedCutoff
=
force
.
getCutoffDistance
();
nonbondedCutoff
=
force
.
getCutoffDistance
();
if
(
nonbondedMethod
==
NoCutoff
)
if
(
nonbondedMethod
==
NoCutoff
)
...
@@ -135,7 +148,7 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo
...
@@ -135,7 +148,7 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo
RealVec
boxSize
=
extractBoxSize
(
context
);
RealVec
boxSize
=
extractBoxSize
(
context
);
float
floatBoxSize
[
3
]
=
{(
float
)
boxSize
[
0
],
(
float
)
boxSize
[
1
],
(
float
)
boxSize
[
2
]};
float
floatBoxSize
[
3
]
=
{(
float
)
boxSize
[
0
],
(
float
)
boxSize
[
1
],
(
float
)
boxSize
[
2
]};
double
energy
=
0
;
double
energy
=
0
;
//
Cpu
LJCoulombIxn
clj;
Cpu
NonbondedForce
clj
;
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
pme
=
(
nonbondedMethod
==
PME
);
bool
pme
=
(
nonbondedMethod
==
PME
);
...
@@ -155,75 +168,79 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo
...
@@ -155,75 +168,79 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo
posq
[
4
*
i
+
1
]
=
(
float
)
posData
[
i
][
1
];
posq
[
4
*
i
+
1
]
=
(
float
)
posData
[
i
][
1
];
posq
[
4
*
i
+
2
]
=
(
float
)
posData
[
i
][
2
];
posq
[
4
*
i
+
2
]
=
(
float
)
posData
[
i
][
2
];
}
}
neighborList
.
computeNeighborList
(
numParticles
,
posq
,
exclusions
,
floatBoxSize
,
periodic
||
ewald
||
pme
,
nonbondedCutoff
);
for
(
int
i
=
0
;
i
<
4
*
numParticles
;
i
++
)
// if (nonbondedMethod != NoCutoff) {
forces
[
i
]
=
0.0
f
;
// computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxSize(context), periodic || ewald || pme, nonbondedCutoff, 0.0);
if
(
nonbondedMethod
!=
NoCutoff
)
{
// clj.setUseCutoff(nonbondedCutoff, *neighborList, rfDielectric);
neighborList
.
computeNeighborList
(
numParticles
,
posq
,
exclusions
,
floatBoxSize
,
periodic
||
ewald
||
pme
,
nonbondedCutoff
);
// }
clj
.
setUseCutoff
(
nonbondedCutoff
,
neighborList
.
getNeighbors
(),
rfDielectric
);
// if (periodic || ewald || pme) {
}
// RealVec& box = extractBoxSize(context);
if
(
periodic
||
ewald
||
pme
)
{
// double minAllowedSize = 1.999999*nonbondedCutoff;
double
minAllowedSize
=
1.999999
*
nonbondedCutoff
;
// if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize)
if
(
boxSize
[
0
]
<
minAllowedSize
||
boxSize
[
1
]
<
minAllowedSize
||
boxSize
[
2
]
<
minAllowedSize
)
// throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff.");
throw
OpenMMException
(
"The periodic box size has decreased to less than twice the nonbonded cutoff."
);
// clj.setPeriodic(box);
clj
.
setPeriodic
(
floatBoxSize
);
// }
}
// if (ewald)
if
(
ewald
)
// 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 (useSwitchingFunction)
if
(
useSwitchingFunction
)
// clj.setUseSwitchingFunction(switchingDistance);
clj
.
setUseSwitchingFunction
(
switchingDistance
);
// clj.calculatePairIxn(numParticles, posData, particleParamArray, exclusions, 0, forceData, 0, includeEnergy ? &energy : NULL, includeDirect, includeReciprocal);
float
directEnergy
=
0
;
// if (includeDirect) {
clj
.
calculatePairIxn
(
numParticles
,
&
posq
[
0
],
particleParamArray
,
exclusions
,
0
,
&
forces
[
0
],
includeEnergy
?
&
directEnergy
:
NULL
,
includeDirect
,
includeReciprocal
);
// CpuBondForce refBondForce;
energy
+=
directEnergy
;
// CpuLJCoulomb14 nonbonded14;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
// refBondForce.calculateForce(num14, bonded14IndexArray, posData, bonded14ParamArray, forceData, includeEnergy ? &energy : NULL, nonbonded14);
forceData
[
i
][
0
]
+=
forces
[
4
*
i
];
// if (periodic || ewald || pme) {
forceData
[
i
][
1
]
+=
forces
[
4
*
i
+
1
];
// RealVec& boxSize = extractBoxSize(context);
forceData
[
i
][
2
]
+=
forces
[
4
*
i
+
2
];
// energy += dispersionCoefficient/(boxSize[0]*boxSize[1]*boxSize[2]);
}
// }
if
(
includeDirect
)
{
// }
ReferenceBondForce
refBondForce
;
// return energy;
ReferenceLJCoulomb14
nonbonded14
;
return
0.0
;
refBondForce
.
calculateForce
(
num14
,
bonded14IndexArray
,
posData
,
bonded14ParamArray
,
forceData
,
includeEnergy
?
&
energy
:
NULL
,
nonbonded14
);
if
(
periodic
||
ewald
||
pme
)
energy
+=
dispersionCoefficient
/
(
boxSize
[
0
]
*
boxSize
[
1
]
*
boxSize
[
2
]);
}
return
energy
;
}
}
void
CpuCalcNonbondedForceKernel
::
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
)
{
void
CpuCalcNonbondedForceKernel
::
copyParametersToContext
(
ContextImpl
&
context
,
const
NonbondedForce
&
force
)
{
//
if (force.getNumParticles() != numParticles)
if
(
force
.
getNumParticles
()
!=
numParticles
)
//
throw OpenMMException("updateParametersInContext: The number of particles has changed");
throw
OpenMMException
(
"updateParametersInContext: The number of particles has changed"
);
//
vector<int> nb14s;
vector
<
int
>
nb14s
;
//
for (int i = 0; i < force.getNumExceptions(); i++) {
for
(
int
i
=
0
;
i
<
force
.
getNumExceptions
();
i
++
)
{
//
int particle1, particle2;
int
particle1
,
particle2
;
//
double chargeProd, sigma, epsilon;
double
chargeProd
,
sigma
,
epsilon
;
//
force.getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon);
force
.
getExceptionParameters
(
i
,
particle1
,
particle2
,
chargeProd
,
sigma
,
epsilon
);
//
if (chargeProd != 0.0 || epsilon != 0.0)
if
(
chargeProd
!=
0.0
||
epsilon
!=
0.0
)
//
nb14s.push_back(i);
nb14s
.
push_back
(
i
);
//
}
}
//
if (nb14s.size() != num14)
if
(
nb14s
.
size
()
!=
num14
)
//
throw OpenMMException("updateParametersInContext: The number of non-excluded exceptions has changed");
throw
OpenMMException
(
"updateParametersInContext: The number of non-excluded exceptions has changed"
);
//
//
// Record the values.
// Record the values.
//
//
for (int i = 0; i < numParticles; ++i) {
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
//
double charge, radius, depth;
double
charge
,
radius
,
depth
;
//
force.getParticleParameters(i, charge, radius, depth);
force
.
getParticleParameters
(
i
,
charge
,
radius
,
depth
);
//
particleParamArray[i][0] =
static_cast<RealOpenMM>
(0.5*radius);
particleParamArray
[
i
][
0
]
=
(
float
)
(
0.5
*
radius
);
//
particleParamArray[i][1] =
static_cast<RealOpenMM>
(2.0*sqrt(depth));
particleParamArray
[
i
][
1
]
=
(
float
)
(
2.0
*
sqrt
(
depth
));
//
particleParamArray[i][2] =
static_cast<RealOpenMM>
(charge);
particleParamArray
[
i
][
2
]
=
(
float
)
(
charge
);
//
}
}
//
for (int i = 0; i < num14; ++i) {
for
(
int
i
=
0
;
i
<
num14
;
++
i
)
{
//
int particle1, particle2;
int
particle1
,
particle2
;
//
double charge, radius, depth;
double
charge
,
radius
,
depth
;
//
force.getExceptionParameters(nb14s[i], particle1, particle2, charge, radius, depth);
force
.
getExceptionParameters
(
nb14s
[
i
],
particle1
,
particle2
,
charge
,
radius
,
depth
);
//
bonded14IndexArray[i][0] = particle1;
bonded14IndexArray
[
i
][
0
]
=
particle1
;
//
bonded14IndexArray[i][1] = particle2;
bonded14IndexArray
[
i
][
1
]
=
particle2
;
//
bonded14ParamArray[i][0] = static_cast<RealOpenMM>(radius);
bonded14ParamArray
[
i
][
0
]
=
static_cast
<
RealOpenMM
>
(
radius
);
//
bonded14ParamArray[i][1] = static_cast<RealOpenMM>(4.0*depth);
bonded14ParamArray
[
i
][
1
]
=
static_cast
<
RealOpenMM
>
(
4.0
*
depth
);
//
bonded14ParamArray[i][2] = static_cast<RealOpenMM>(charge);
bonded14ParamArray
[
i
][
2
]
=
static_cast
<
RealOpenMM
>
(
charge
);
//
}
}
//
//
// Recompute the coefficient for the dispersion correction.
// Recompute the coefficient for the dispersion correction.
//
//
NonbondedForce::NonbondedMethod method = force.getNonbondedMethod();
NonbondedForce
::
NonbondedMethod
method
=
force
.
getNonbondedMethod
();
//
if (force.getUseDispersionCorrection() && (method == NonbondedForce::CutoffPeriodic || method == NonbondedForce::Ewald || method == NonbondedForce::PME))
if
(
force
.
getUseDispersionCorrection
()
&&
(
method
==
NonbondedForce
::
CutoffPeriodic
||
method
==
NonbondedForce
::
Ewald
||
method
==
NonbondedForce
::
PME
))
//
dispersionCoefficient = NonbondedForceImpl::calcDispersionCorrection(context.getSystem(), force);
dispersionCoefficient
=
NonbondedForceImpl
::
calcDispersionCorrection
(
context
.
getSystem
(),
force
);
}
}
platforms/cpu/src/CpuNonbondedForce.cpp
0 → 100644
View file @
9bc194b9
/* Portions copyright (c) 2006-2013 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <sstream>
#include <complex>
#include "SimTKOpenMMCommon.h"
#include "SimTKOpenMMLog.h"
#include "SimTKOpenMMUtilities.h"
#include "CpuNonbondedForce.h"
#include "ReferenceForce.h"
#include "ReferencePME.h"
// In case we're using some primitive version of Visual Studio this will
// make sure that erf() and erfc() are defined.
#include "openmm/internal/MSVC_erfc.h"
using
namespace
std
;
/**---------------------------------------------------------------------------------------
CpuNonbondedForce constructor
--------------------------------------------------------------------------------------- */
CpuNonbondedForce
::
CpuNonbondedForce
()
:
cutoff
(
false
),
useSwitch
(
false
),
periodic
(
false
),
ewald
(
false
),
pme
(
false
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nCpuNonbondedForce::CpuNonbondedForce";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
CpuNonbondedForce destructor
--------------------------------------------------------------------------------------- */
CpuNonbondedForce
::~
CpuNonbondedForce
(){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nCpuNonbondedForce::~CpuNonbondedForce";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
Set the force to use a cutoff.
@param distance the cutoff distance
@param neighbors the neighbor list to use
@param solventDielectric the dielectric constant of the bulk solvent
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
setUseCutoff
(
float
distance
,
const
vector
<
pair
<
int
,
int
>
>&
neighbors
,
float
solventDielectric
)
{
cutoff
=
true
;
cutoffDistance
=
distance
;
neighborList
=
&
neighbors
;
krf
=
pow
(
cutoffDistance
,
-
3.0
f
)
*
(
solventDielectric
-
1.0
)
/
(
2.0
*
solventDielectric
+
1.0
);
crf
=
(
1.0
/
cutoffDistance
)
*
(
3.0
*
solventDielectric
)
/
(
2.0
*
solventDielectric
+
1.0
);
}
/**---------------------------------------------------------------------------------------
Set the force to use a switching function on the Lennard-Jones interaction.
@param distance the switching distance
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
setUseSwitchingFunction
(
float
distance
)
{
useSwitch
=
true
;
switchingDistance
=
distance
;
}
/**---------------------------------------------------------------------------------------
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
distance.
@param boxSize the X, Y, and Z widths of the periodic box
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
setPeriodic
(
float
*
boxSize
)
{
assert
(
cutoff
);
assert
(
boxSize
[
0
]
>=
2
*
cutoffDistance
);
assert
(
boxSize
[
1
]
>=
2
*
cutoffDistance
);
assert
(
boxSize
[
2
]
>=
2
*
cutoffDistance
);
periodic
=
true
;
periodicBoxSize
[
0
]
=
boxSize
[
0
];
periodicBoxSize
[
1
]
=
boxSize
[
1
];
periodicBoxSize
[
2
]
=
boxSize
[
2
];
}
/**---------------------------------------------------------------------------------------
Set the force to use Ewald summation.
@param alpha the Ewald separation parameter
@param kmaxx the largest wave vector in the x direction
@param kmaxy the largest wave vector in the y direction
@param kmaxz the largest wave vector in the z direction
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
setUseEwald
(
float
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
)
{
alphaEwald
=
alpha
;
numRx
=
kmaxx
;
numRy
=
kmaxy
;
numRz
=
kmaxz
;
ewald
=
true
;
}
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation.
@param alpha the Ewald separation parameter
@param gridSize the dimensions of the mesh
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
setUsePME
(
float
alpha
,
int
meshSize
[
3
])
{
alphaEwald
=
alpha
;
meshDim
[
0
]
=
meshSize
[
0
];
meshDim
[
1
]
=
meshSize
[
1
];
meshDim
[
2
]
=
meshSize
[
2
];
pme
=
true
;
}
/**---------------------------------------------------------------------------------------
Calculate Ewald ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices
exclusions[atomIndex] contains the list of exclusions for that atom
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param totalEnergy total energy
@param includeDirect true if direct space interactions should be included
@param includeReciprocal true if reciprocal space interactions should be included
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
calculateEwaldIxn
(
int
numberOfAtoms
,
float
*
atomCoordinates
,
float
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
float
*
fixedParameters
,
float
*
forces
,
float
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
typedef
std
::
complex
<
float
>
d_complex
;
static
const
float
epsilon
=
1.0
;
static
const
float
one
=
1.0
;
static
const
float
six
=
6.0
;
static
const
float
twelve
=
12.0
;
int
kmax
=
(
ewald
?
std
::
max
(
numRx
,
std
::
max
(
numRy
,
numRz
))
:
0
);
float
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
float
SQRT_PI
=
sqrt
(
PI_M
);
float
TWO_PI
=
2.0
*
PI_M
;
float
recipCoeff
=
(
float
)(
ONE_4PI_EPS0
*
4
*
PI_M
/
(
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
])
/
epsilon
);
float
totalSelfEwaldEnergy
=
0.0
;
float
realSpaceEwaldEnergy
=
0.0
;
float
recipEnergy
=
0.0
;
float
totalRecipEnergy
=
0.0
;
float
vdwEnergy
=
0.0
;
// **************************************************************************************
// SELF ENERGY
// **************************************************************************************
if
(
includeReciprocal
)
{
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
float
selfEwaldEnergy
=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
);
totalSelfEwaldEnergy
-=
selfEwaldEnergy
;
}
}
if
(
totalEnergy
){
*
totalEnergy
+=
totalSelfEwaldEnergy
;
}
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
// PME
if
(
pme
&&
includeReciprocal
)
{
pme_t
pmedata
;
/* abstract handle for PME data */
float
virial
[
3
][
3
];
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
// pme_exec(pmedata,atomCoordinates,forces,atomParameters,periodicBoxSize,&recipEnergy,virial);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
pme_destroy
(
pmedata
);
}
// Ewald method
else
if
(
ewald
&&
includeReciprocal
)
{
// setup reciprocal box
float
recipBoxSize
[
3
]
=
{
TWO_PI
/
periodicBoxSize
[
0
],
TWO_PI
/
periodicBoxSize
[
1
],
TWO_PI
/
periodicBoxSize
[
2
]};
// setup K-vectors
#define EIR(x, y, z) eir[(x)*numberOfAtoms*3+(y)*3+z]
vector
<
d_complex
>
eir
(
kmax
*
numberOfAtoms
*
3
);
vector
<
d_complex
>
tab_xy
(
numberOfAtoms
);
vector
<
d_complex
>
tab_qxyz
(
numberOfAtoms
);
if
(
kmax
<
1
)
{
std
::
stringstream
message
;
message
<<
" kmax < 1 , Aborting"
<<
std
::
endl
;
SimTKOpenMMLog
::
printError
(
message
);
}
for
(
int
i
=
0
;
(
i
<
numberOfAtoms
);
i
++
)
{
float
*
pos
=
atomCoordinates
+
4
*
i
;
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
0
,
i
,
m
)
=
d_complex
(
1
,
0
);
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
1
,
i
,
m
)
=
d_complex
(
cos
(
pos
[
m
]
*
recipBoxSize
[
m
]),
sin
(
pos
[
m
]
*
recipBoxSize
[
m
]));
for
(
int
j
=
2
;
(
j
<
kmax
);
j
++
)
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
j
,
i
,
m
)
=
EIR
(
j
-
1
,
i
,
m
)
*
EIR
(
1
,
i
,
m
);
}
// calculate reciprocal space energy and forces
int
lowry
=
0
;
int
lowrz
=
1
;
for
(
int
rx
=
0
;
rx
<
numRx
;
rx
++
)
{
float
kx
=
rx
*
recipBoxSize
[
0
];
for
(
int
ry
=
lowry
;
ry
<
numRy
;
ry
++
)
{
float
ky
=
ry
*
recipBoxSize
[
1
];
if
(
ry
>=
0
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_xy
[
n
]
=
EIR
(
rx
,
n
,
0
)
*
EIR
(
ry
,
n
,
1
);
}
else
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_xy
[
n
]
=
EIR
(
rx
,
n
,
0
)
*
conj
(
EIR
(
-
ry
,
n
,
1
));
}
for
(
int
rz
=
lowrz
;
rz
<
numRz
;
rz
++
)
{
if
(
rz
>=
0
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
EIR
(
rz
,
n
,
2
));
}
else
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
conj
(
EIR
(
-
rz
,
n
,
2
)));
}
float
cs
=
0.0
f
;
float
ss
=
0.0
f
;
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
cs
+=
tab_qxyz
[
n
].
real
();
ss
+=
tab_qxyz
[
n
].
imag
();
}
float
kz
=
rz
*
recipBoxSize
[
2
];
float
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
float
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
float
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
float
*
f
=
forces
+
4
*
n
;
f
[
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
f
[
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
f
[
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
}
recipEnergy
=
recipCoeff
*
ak
*
(
cs
*
cs
+
ss
*
ss
);
totalRecipEnergy
+=
recipEnergy
;
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
lowrz
=
1
-
numRz
;
}
lowry
=
1
-
numRy
;
}
}
}
// **************************************************************************************
// SHORT-RANGE ENERGY AND FORCES
// **************************************************************************************
if
(
!
includeDirect
)
return
;
float
totalVdwEnergy
=
0.0
f
;
float
totalRealSpaceEwaldEnergy
=
0.0
f
;
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
pair
<
int
,
int
>
pair
=
(
*
neighborList
)[
i
];
int
ii
=
pair
.
first
;
int
jj
=
pair
.
second
;
float
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
getDeltaR
(
atomCoordinates
+
4
*
jj
,
atomCoordinates
+
4
*
ii
,
periodicBoxSize
,
deltaR
[
0
],
true
);
float
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
float
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
float
switchValue
=
1
,
switchDeriv
=
0
;
if
(
useSwitch
&&
r
>
switchingDistance
)
{
float
t
=
(
r
-
switchingDistance
)
/
(
cutoffDistance
-
switchingDistance
);
switchValue
=
1
+
t
*
t
*
t
*
(
-
10
+
t
*
(
15
-
t
*
6
));
switchDeriv
=
t
*
t
*
(
-
30
+
t
*
(
60
-
t
*
30
))
/
(
cutoffDistance
-
switchingDistance
);
}
float
alphaR
=
alphaEwald
*
r
;
float
dEdR
=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
);
dEdR
=
(
float
)
(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
float
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
float
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
float
sig6
=
sig2
*
sig2
*
sig2
;
float
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
dEdR
+=
switchValue
*
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
*
inverseR
*
inverseR
;
vdwEnergy
=
eps
*
(
sig6
-
one
)
*
sig6
;
if
(
useSwitch
)
{
dEdR
-=
vdwEnergy
*
switchDeriv
*
inverseR
;
vdwEnergy
*=
switchValue
;
}
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
float
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
4
*
ii
+
kk
]
+=
force
;
forces
[
4
*
jj
+
kk
]
-=
force
;
}
// accumulate energies
realSpaceEwaldEnergy
=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
));
totalVdwEnergy
+=
vdwEnergy
;
totalRealSpaceEwaldEnergy
+=
realSpaceEwaldEnergy
;
}
if
(
totalEnergy
)
*
totalEnergy
+=
totalRealSpaceEwaldEnergy
+
totalVdwEnergy
;
// Now subtract off the exclusions, since they were implicitly included in the reciprocal space sum.
float
totalExclusionEnergy
=
0.0
f
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
for
(
set
<
int
>::
const_iterator
iter
=
exclusions
[
i
].
begin
();
iter
!=
exclusions
[
i
].
end
();
++
iter
)
{
if
(
*
iter
>
i
)
{
int
ii
=
i
;
int
jj
=
*
iter
;
float
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
getDeltaR
(
atomCoordinates
+
4
*
jj
,
atomCoordinates
+
4
*
ii
,
periodicBoxSize
,
deltaR
[
0
],
false
);
float
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
float
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
float
alphaR
=
alphaEwald
*
r
;
if
(
erf
(
alphaR
)
>
1e-6
)
{
float
dEdR
=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
);
dEdR
=
(
float
)
(
dEdR
*
(
erf
(
alphaR
)
-
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
float
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
4
*
ii
+
kk
]
-=
force
;
forces
[
4
*
jj
+
kk
]
+=
force
;
}
// accumulate energies
realSpaceEwaldEnergy
=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erf
(
alphaR
));
totalExclusionEnergy
+=
realSpaceEwaldEnergy
;
}
}
}
if
(
totalEnergy
)
*
totalEnergy
-=
totalExclusionEnergy
;
}
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices
exclusions[atomIndex] contains the list of exclusions for that atom
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param totalEnergy total energy
@param includeDirect true if direct space interactions should be included
@param includeReciprocal true if reciprocal space interactions should be included
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
calculatePairIxn
(
int
numberOfAtoms
,
float
*
atomCoordinates
,
float
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
float
*
fixedParameters
,
float
*
forces
,
float
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
if
(
ewald
||
pme
)
{
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
totalEnergy
,
includeDirect
,
includeReciprocal
);
return
;
}
if
(
!
includeDirect
)
return
;
if
(
cutoff
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
pair
<
int
,
int
>
pair
=
(
*
neighborList
)[
i
];
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
atomParameters
,
forces
,
totalEnergy
);
}
}
else
{
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
// loop over atom pairs
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
)
if
(
exclusions
[
jj
].
find
(
ii
)
==
exclusions
[
jj
].
end
())
calculateOneIxn
(
ii
,
jj
,
atomCoordinates
,
atomParameters
,
forces
,
totalEnergy
);
}
}
}
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn between two atoms
@param ii the index of the first atom
@param jj the index of the second atom
@param atomCoordinates atom coordinates
@param atomParameters atom parameters (charges, c6, c12, ...) atomParameters[atomIndex][paramterIndex]
@param forces force array (forces added)
@param totalEnergy total energy
--------------------------------------------------------------------------------------- */
void
CpuNonbondedForce
::
calculateOneIxn
(
int
ii
,
int
jj
,
float
*
atomCoordinates
,
float
**
atomParameters
,
float
*
forces
,
float
*
totalEnergy
)
const
{
// ---------------------------------------------------------------------------------------
static
const
std
::
string
methodName
=
"
\n
CpuNonbondedForce::calculateOneIxn"
;
// ---------------------------------------------------------------------------------------
// constants -- reduce Visual Studio warnings regarding conversions between float & double
static
const
float
zero
=
0.0
;
static
const
float
one
=
1.0
;
static
const
float
two
=
2.0
;
static
const
float
three
=
3.0
;
static
const
float
six
=
6.0
;
static
const
float
twelve
=
12.0
;
static
const
float
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
static
const
int
LastAtomIndex
=
2
;
float
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
// get deltaR, R2, and R between 2 atoms
getDeltaR
(
atomCoordinates
+
4
*
jj
,
atomCoordinates
+
4
*
ii
,
periodicBoxSize
,
deltaR
[
0
],
periodic
);
float
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
float
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
float
switchValue
=
1
,
switchDeriv
=
0
;
if
(
useSwitch
)
{
float
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
if
(
r
>
switchingDistance
)
{
float
t
=
(
r
-
switchingDistance
)
/
(
cutoffDistance
-
switchingDistance
);
switchValue
=
1
+
t
*
t
*
t
*
(
-
10
+
t
*
(
15
-
t
*
6
));
switchDeriv
=
t
*
t
*
(
-
30
+
t
*
(
60
-
t
*
30
))
/
(
cutoffDistance
-
switchingDistance
);
}
}
float
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
float
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
float
sig6
=
sig2
*
sig2
*
sig2
;
float
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
float
dEdR
=
switchValue
*
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
;
if
(
cutoff
)
dEdR
+=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
));
else
dEdR
+=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
);
dEdR
*=
inverseR
*
inverseR
;
float
energy
=
eps
*
(
sig6
-
one
)
*
sig6
;
if
(
useSwitch
)
{
dEdR
-=
energy
*
switchDeriv
*
inverseR
;
energy
*=
switchValue
;
}
if
(
cutoff
)
energy
+=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
+
krf
*
r2
-
crf
));
else
energy
+=
(
float
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
);
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
float
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
4
*
ii
+
kk
]
+=
force
;
forces
[
4
*
jj
+
kk
]
-=
force
;
}
// accumulate energies
if
(
totalEnergy
)
*
totalEnergy
+=
energy
;
}
void
CpuNonbondedForce
::
getDeltaR
(
const
float
*
atomCoordinatesI
,
const
float
*
atomCoordinatesJ
,
const
float
*
boxSize
,
float
*
deltaR
,
bool
periodic
)
const
{
deltaR
[
ReferenceForce
::
XIndex
]
=
atomCoordinatesJ
[
0
]
-
atomCoordinatesI
[
0
];
deltaR
[
ReferenceForce
::
YIndex
]
=
atomCoordinatesJ
[
1
]
-
atomCoordinatesI
[
1
];
deltaR
[
ReferenceForce
::
ZIndex
]
=
atomCoordinatesJ
[
2
]
-
atomCoordinatesI
[
2
];
if
(
periodic
)
{
deltaR
[
ReferenceForce
::
XIndex
]
-=
(
float
)
(
floor
(
deltaR
[
ReferenceForce
::
XIndex
]
/
boxSize
[
0
]
+
0.5
)
*
boxSize
[
0
]);
deltaR
[
ReferenceForce
::
YIndex
]
-=
(
float
)
(
floor
(
deltaR
[
ReferenceForce
::
YIndex
]
/
boxSize
[
1
]
+
0.5
)
*
boxSize
[
1
]);
deltaR
[
ReferenceForce
::
ZIndex
]
-=
(
float
)
(
floor
(
deltaR
[
ReferenceForce
::
ZIndex
]
/
boxSize
[
2
]
+
0.5
)
*
boxSize
[
2
]);
}
deltaR
[
ReferenceForce
::
R2Index
]
=
DOT3
(
deltaR
,
deltaR
);
deltaR
[
ReferenceForce
::
RIndex
]
=
(
float
)
SQRT
(
deltaR
[
ReferenceForce
::
R2Index
]);
}
platforms/reference/
src/SimTK
Reference
/
PME.h
→
platforms/reference/
include/
ReferencePME.h
View file @
9bc194b9
File moved
platforms/reference/include/ReferencePairIxn.h
View file @
9bc194b9
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#ifndef __ReferencePairIxn_H__
#ifndef __ReferencePairIxn_H__
#define __ReferencePairIxn_H__
#define __ReferencePairIxn_H__
#include "RealVec.h"
#include "openmm/internal/windowsExport.h"
#include "openmm/internal/windowsExport.h"
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
9bc194b9
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
#include "SimTKOpenMMUtilities.h"
#include "SimTKOpenMMUtilities.h"
#include "ReferenceLJCoulombIxn.h"
#include "ReferenceLJCoulombIxn.h"
#include "ReferenceForce.h"
#include "ReferenceForce.h"
#include "PME.h"
#include "
Reference
PME.h"
// In case we're using some primitive version of Visual Studio this will
// In case we're using some primitive version of Visual Studio this will
// make sure that erf() and erfc() are defined.
// make sure that erf() and erfc() are defined.
...
...
platforms/reference/src/SimTKReference/PME.cpp
→
platforms/reference/src/SimTKReference/
Reference
PME.cpp
View file @
9bc194b9
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include "PME.h"
#include "
Reference
PME.h"
#include "fftpack.h"
#include "fftpack.h"
using
std
::
vector
;
using
std
::
vector
;
...
...
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