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
c66dd5a3
Commit
c66dd5a3
authored
Jul 07, 2009
by
Rossen Apostolov
Browse files
Implemented the PME method in the reference platform.
parent
a5f8fb35
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
2413 additions
and
74 deletions
+2413
-74
olla/include/openmm/kernels.h
olla/include/openmm/kernels.h
+2
-1
openmmapi/include/openmm/NonbondedForce.h
openmmapi/include/openmm/NonbondedForce.h
+6
-1
platforms/reference/src/ReferenceKernels.cpp
platforms/reference/src/ReferenceKernels.cpp
+11
-5
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+154
-3
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.h
...orms/reference/src/SimTKReference/ReferenceLJCoulombIxn.h
+38
-1
platforms/reference/src/SimTKReference/fftpack.cpp
platforms/reference/src/SimTKReference/fftpack.cpp
+1098
-0
platforms/reference/src/SimTKReference/fftpack.h
platforms/reference/src/SimTKReference/fftpack.h
+213
-0
platforms/reference/src/SimTKReference/pme.cpp
platforms/reference/src/SimTKReference/pme.cpp
+737
-0
platforms/reference/src/SimTKReference/pme.h
platforms/reference/src/SimTKReference/pme.h
+88
-0
platforms/reference/tests/TestReferenceEwald.cpp
platforms/reference/tests/TestReferenceEwald.cpp
+66
-63
No files found.
olla/include/openmm/kernels.h
View file @
c66dd5a3
...
@@ -246,7 +246,8 @@ public:
...
@@ -246,7 +246,8 @@ public:
NoCutoff
=
0
,
NoCutoff
=
0
,
CutoffNonPeriodic
=
1
,
CutoffNonPeriodic
=
1
,
CutoffPeriodic
=
2
,
CutoffPeriodic
=
2
,
Ewald
=
3
Ewald
=
3
,
PME
=
4
};
};
static
std
::
string
Name
()
{
static
std
::
string
Name
()
{
return
"CalcNonbondedForce"
;
return
"CalcNonbondedForce"
;
...
...
openmmapi/include/openmm/NonbondedForce.h
View file @
c66dd5a3
...
@@ -91,7 +91,12 @@ public:
...
@@ -91,7 +91,12 @@ public:
* Periodic boundary conditions are used, and Ewald summation is used to compute the interaction of each particle
* Periodic boundary conditions are used, and Ewald 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.
*/
*/
Ewald
=
3
Ewald
=
3
,
/**
* 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.
*/
PME
=
4
};
};
/**
/**
* Create a NonbondedForce.
* Create a NonbondedForce.
...
...
platforms/reference/src/ReferenceKernels.cpp
View file @
c66dd5a3
...
@@ -392,7 +392,7 @@ void ReferenceCalcNonbondedForceKernel::initialize(const System& system, const N
...
@@ -392,7 +392,7 @@ void ReferenceCalcNonbondedForceKernel::initialize(const System& system, const N
neighborList
=
NULL
;
neighborList
=
NULL
;
else
else
neighborList
=
new
NeighborList
();
neighborList
=
new
NeighborList
();
if
(
nonbondedMethod
==
Ewald
)
{
if
(
nonbondedMethod
==
Ewald
||
nonbondedMethod
==
PME
)
{
RealOpenMM
ewaldErrorTol
=
(
RealOpenMM
)
force
.
getEwaldErrorTolerance
();
RealOpenMM
ewaldErrorTol
=
(
RealOpenMM
)
force
.
getEwaldErrorTolerance
();
ewaldAlpha
=
(
RealOpenMM
)
(
std
::
sqrt
(
-
std
::
log
(
ewaldErrorTol
))
/
nonbondedCutoff
);
ewaldAlpha
=
(
RealOpenMM
)
(
std
::
sqrt
(
-
std
::
log
(
ewaldErrorTol
))
/
nonbondedCutoff
);
RealOpenMM
mx
=
periodicBoxSize
[
0
]
/
nonbondedCutoff
;
RealOpenMM
mx
=
periodicBoxSize
[
0
]
/
nonbondedCutoff
;
...
@@ -417,14 +417,17 @@ void ReferenceCalcNonbondedForceKernel::executeForces(OpenMMContextImpl& context
...
@@ -417,14 +417,17 @@ void ReferenceCalcNonbondedForceKernel::executeForces(OpenMMContextImpl& context
ReferenceLJCoulombIxn
clj
;
ReferenceLJCoulombIxn
clj
;
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
pme
=
(
nonbondedMethod
==
PME
);
if
(
nonbondedMethod
!=
NoCutoff
)
{
if
(
nonbondedMethod
!=
NoCutoff
)
{
computeNeighborListVoxelHash
(
*
neighborList
,
numParticles
,
posData
,
exclusions
,
(
periodic
||
ewald
)
?
periodicBoxSize
:
NULL
,
nonbondedCutoff
,
0.0
);
computeNeighborListVoxelHash
(
*
neighborList
,
numParticles
,
posData
,
exclusions
,
(
periodic
||
ewald
||
pme
)
?
periodicBoxSize
:
NULL
,
nonbondedCutoff
,
0.0
);
clj
.
setUseCutoff
(
nonbondedCutoff
,
*
neighborList
,
78.3
f
);
clj
.
setUseCutoff
(
nonbondedCutoff
,
*
neighborList
,
78.3
f
);
}
}
if
(
periodic
||
ewald
)
if
(
periodic
||
ewald
||
pme
)
clj
.
setPeriodic
(
periodicBoxSize
);
clj
.
setPeriodic
(
periodicBoxSize
);
if
(
ewald
)
if
(
ewald
)
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
if
(
pme
)
clj
.
setUsePME
(
ewaldAlpha
);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
0
);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
0
);
ReferenceBondForce
refBondForce
;
ReferenceBondForce
refBondForce
;
ReferenceLJCoulomb14
nonbonded14
;
ReferenceLJCoulomb14
nonbonded14
;
...
@@ -440,14 +443,17 @@ double ReferenceCalcNonbondedForceKernel::executeEnergy(OpenMMContextImpl& conte
...
@@ -440,14 +443,17 @@ double ReferenceCalcNonbondedForceKernel::executeEnergy(OpenMMContextImpl& conte
ReferenceLJCoulombIxn
clj
;
ReferenceLJCoulombIxn
clj
;
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
periodic
=
(
nonbondedMethod
==
CutoffPeriodic
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
ewald
=
(
nonbondedMethod
==
Ewald
);
bool
pme
=
(
nonbondedMethod
==
PME
);
if
(
nonbondedMethod
!=
NoCutoff
)
{
if
(
nonbondedMethod
!=
NoCutoff
)
{
computeNeighborListVoxelHash
(
*
neighborList
,
numParticles
,
posData
,
exclusions
,
(
periodic
||
ewald
)
?
periodicBoxSize
:
NULL
,
nonbondedCutoff
,
0.0
);
computeNeighborListVoxelHash
(
*
neighborList
,
numParticles
,
posData
,
exclusions
,
(
periodic
||
ewald
||
pme
)
?
periodicBoxSize
:
NULL
,
nonbondedCutoff
,
0.0
);
clj
.
setUseCutoff
(
nonbondedCutoff
,
*
neighborList
,
78.3
f
);
clj
.
setUseCutoff
(
nonbondedCutoff
,
*
neighborList
,
78.3
f
);
}
}
if
(
periodic
||
ewald
)
if
(
periodic
||
ewald
||
pme
)
clj
.
setPeriodic
(
periodicBoxSize
);
clj
.
setPeriodic
(
periodicBoxSize
);
if
(
ewald
)
if
(
ewald
)
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
clj
.
setUseEwald
(
ewaldAlpha
,
kmax
[
0
],
kmax
[
1
],
kmax
[
2
]);
if
(
pme
)
clj
.
setUsePME
(
ewaldAlpha
);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
&
energy
);
clj
.
calculatePairIxn
(
numParticles
,
posData
,
particleParamArray
,
exclusionArray
,
0
,
forceData
,
0
,
&
energy
);
ReferenceBondForce
refBondForce
;
ReferenceBondForce
refBondForce
;
ReferenceLJCoulomb14
nonbonded14
;
ReferenceLJCoulomb14
nonbonded14
;
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
c66dd5a3
...
@@ -44,7 +44,7 @@ using std::vector;
...
@@ -44,7 +44,7 @@ using std::vector;
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
(
)
:
cutoff
(
false
),
periodic
(
false
),
ewald
(
false
)
{
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
(
)
:
cutoff
(
false
),
periodic
(
false
),
ewald
(
false
)
,
pme
(
false
)
{
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
...
@@ -138,6 +138,19 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){
...
@@ -138,6 +138,19 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){
ewald
=
true
;
ewald
=
true
;
}
}
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation.
@param alpha the Ewald separation parameter
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUsePME
(
RealOpenMM
alpha
)
{
alphaEwald
=
alpha
;
pme
=
true
;
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Calculate parameters for LJ Coulomb ixn
Calculate parameters for LJ Coulomb ixn
...
@@ -222,7 +235,6 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -222,7 +235,6 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
RealOpenMM
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
RealOpenMM
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
RealOpenMM
SQRT_PI
=
sqrt
(
PI
);
RealOpenMM
SQRT_PI
=
sqrt
(
PI
);
RealOpenMM
TWO_PI
=
2.0
*
PI
;
RealOpenMM
TWO_PI
=
2.0
*
PI
;
static
const
RealOpenMM
epsilon
=
1.0
;
static
const
RealOpenMM
epsilon
=
1.0
;
...
@@ -415,6 +427,143 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -415,6 +427,143 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
}
}
/**---------------------------------------------------------------------------------------
Calculate PME ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices exclusions[atomIndex][atomToExcludeIndex]
exclusions[atomIndex][0] = number of exclusions
exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from
interacting w/ atom atomIndex
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param energyByAtom atom energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
int
ReferenceLJCoulombIxn
::
calculatePMEIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
#include "../SimTKUtilities/RealTypeSimTk.h"
#include "pme.h"
RealOpenMM
SQRT_PI
=
sqrt
(
PI
);
static
const
RealOpenMM
one
=
1.0
;
RealOpenMM
selfEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
// **************************************************************************************
// SELF ENERGY
// **************************************************************************************
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
selfEwaldEnergy
=
selfEwaldEnergy
+
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
];
}
selfEwaldEnergy
=
selfEwaldEnergy
*
alphaEwald
/
SQRT_PI
;
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
pme_t
pmedata
;
/* abstract handle for PME data */
int
ngrid
[
3
];
RealOpenMM
virial
[
3
][
3
];
/* PME grid dimensions.
* We typically want to set this as the spacing rather than absolute dimensions, but
* to be able to reproduce results from other programs (e.g. Gromacs) we need to be
* able to set exact grid dimenisions occasionally.
*/
ngrid
[
0
]
=
16
;
ngrid
[
1
]
=
16
;
ngrid
[
2
]
=
16
;
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
ngrid
,
4
,
1
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
atomParameters
,
periodicBoxSize
,
&
recipEnergy
,
virial
);
// **************************************************************************************
// SHORT-RANGE ENERGY AND FORCES
// **************************************************************************************
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
for
(
int
atomID1
=
0
;
atomID1
<
numberOfAtoms
;
atomID1
++
){
for
(
int
atomID2
=
atomID1
+
1
;
atomID2
<
numberOfAtoms
;
atomID2
++
){
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atomID2
],
atomCoordinates
[
atomID1
],
periodicBoxSize
,
deltaR
[
0
]
);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
realSpaceEwaldEnergy
=
(
RealOpenMM
)(
realSpaceEwaldEnergy
+
atomParameters
[
atomID1
][
QIndex
]
*
atomParameters
[
atomID2
][
QIndex
]
*
inverseR
*
erfc
(
alphaEwald
*
r
));
}
}
// allocate and initialize exclusion array
vector
<
int
>
exclusionIndices
(
numberOfAtoms
);
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
exclusionIndices
[
ii
]
=
-
1
;
}
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
// set exclusions
for
(
int
jj
=
1
;
jj
<=
exclusions
[
ii
][
0
];
jj
++
){
exclusionIndices
[
exclusions
[
ii
][
jj
]]
=
ii
;
}
// loop over atom pairs
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
){
if
(
exclusionIndices
[
jj
]
!=
ii
){
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxSize
,
deltaR
[
0
]
);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
alphaR
=
alphaEwald
*
r
;
realSpaceEwaldEnergy
=
(
RealOpenMM
)(
realSpaceEwaldEnergy
+
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
));
RealOpenMM
dEdR
=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
dEdR
=
(
RealOpenMM
)(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
}
}
}
// ***********************************************************************
if
(
totalEnergy
)
{
*
totalEnergy
+=
recipEnergy
+
realSpaceEwaldEnergy
-
selfEwaldEnergy
;
}
return
ReferenceForce
::
DefaultReturn
;
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn
Calculate LJ Coulomb pair ixn
...
@@ -440,8 +589,10 @@ int ReferenceLJCoulombIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM** ato
...
@@ -440,8 +589,10 @@ int ReferenceLJCoulombIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM** ato
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
if
(
ewald
)
if
(
ewald
)
return
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
return
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
if
(
pme
)
return
calculatePMEIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
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
];
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.h
View file @
c66dd5a3
...
@@ -37,6 +37,7 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
...
@@ -37,6 +37,7 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
bool
cutoff
;
bool
cutoff
;
bool
periodic
;
bool
periodic
;
bool
ewald
;
bool
ewald
;
bool
pme
;
const
OpenMM
::
NeighborList
*
neighborList
;
const
OpenMM
::
NeighborList
*
neighborList
;
RealOpenMM
periodicBoxSize
[
3
];
RealOpenMM
periodicBoxSize
[
3
];
RealOpenMM
cutoffDistance
;
RealOpenMM
cutoffDistance
;
...
@@ -116,7 +117,7 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
...
@@ -116,7 +117,7 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
int
setPeriodic
(
RealOpenMM
*
boxSize
);
int
setPeriodic
(
RealOpenMM
*
boxSize
);
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use Ewald summation.
Set the force to use Ewald summation.
...
@@ -130,6 +131,17 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
...
@@ -130,6 +131,17 @@ class ReferenceLJCoulombIxn : public ReferencePairIxn {
void
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
);
void
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
);
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation.
@param alpha the Ewald separation parameter
--------------------------------------------------------------------------------------- */
void
setUsePME
(
RealOpenMM
alpha
);
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
...
@@ -203,6 +215,31 @@ private:
...
@@ -203,6 +215,31 @@ private:
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
;
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
;
/**---------------------------------------------------------------------------------------
Calculate PME ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters (charges, c6, c12, ...) atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices exclusions[atomIndex][atomToExcludeIndex]
exclusions[atomIndex][0] = number of exclusions
exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from
interacting w/ atom atomIndex
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param energyByAtom atom energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
int
calculatePMEIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
;
};
};
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
...
...
platforms/reference/src/SimTKReference/fftpack.cpp
0 → 100644
View file @
c66dd5a3
This diff is collapsed.
Click to expand it.
platforms/reference/src/SimTKReference/fftpack.h
0 → 100644
View file @
c66dd5a3
/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
*
*
* Gromacs 4.0 Copyright (c) 1991-2003
* David van der Spoel, Erik Lindahl, University of Groningen.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org
*
* And Hey:
* Gnomes, ROck Monsters And Chili Sauce
*/
#include "../SimTKUtilities/SimTKOpenMMCommon.h"
#ifndef _FFTPACK_H_
#define _FFTPACK_H_
#include <stdio.h>
#ifdef __cplusplus
extern
"C"
{
#endif
#if 0
} /* fixes auto-indentation problems */
#endif
typedef
struct
{
RealOpenMM
re
;
RealOpenMM
im
;
}
t_complex
;
/*! \brief Datatype for FFT setup
*
* The fftpack_t type contains all the setup information, e.g. twiddle
* factors, necessary to perform an FFT. Internally it is mapped to
* whatever FFT library we are using, or the built-in FFTPACK if no fast
* external library is available.
*/
typedef
struct
fftpack
*
fftpack_t
;
/*! \brief Specifier for FFT direction.
*
* The definition of the 1D forward transform from input x[] to output y[] is
* \f[
* y_{k} = \sum_{j=0}^{N-1} x_{j} \exp{-i 2 \pi j k /N}
* \f]
*
* while the corresponding backward transform is
*
* \f[
* y_{k} = \sum_{j=0}^{N-1} x_{j} \exp{i 2 \pi j k /N}
* \f]
*
* A forward-backward transform pair will this result in data scaled by N.
*
*/
typedef
enum
fftpack_direction
{
FFTPACK_FORWARD
,
/*!< Forward complex-to-complex transform */
FFTPACK_BACKWARD
,
/*!< Backward complex-to-complex transform */
}
fftpack_direction
;
/*! \brief Setup a 1-dimensional complex-to-complex transform
*
* \param fft Pointer to opaque Gromacs FFT datatype
* \param nx Length of transform
*
* \return status - 0 or a standard error message.
*/
int
fftpack_init_1d
(
fftpack_t
*
fft
,
int
nx
);
/*! \brief Setup a 2-dimensional complex-to-complex transform
*
* \param fft Pointer to opaque Gromacs FFT datatype
* \param nx Length of transform in first dimension
* \param ny Length of transform in second dimension
*
* \return status - 0 or a standard error message.
*
*/
int
fftpack_init_2d
(
fftpack_t
*
fft
,
int
nx
,
int
ny
);
/*! \brief Setup a 3-dimensional complex-to-complex transform
*
* \param fft Pointer to opaque Gromacs FFT datatype
* \param nx Length of transform in first dimension
* \param ny Length of transform in second dimension
* \param nz Length of transform in third dimension
*
* \return status - 0 or a standard error message.
*
*/
int
fftpack_init_3d
(
fftpack_t
*
fft
,
int
nx
,
int
ny
,
int
nz
);
/*! \brief Perform a 1-dimensional complex-to-complex transform
*
* Performs an instance of a transform previously initiated.
*
* \param setup Setup returned from fftpack_init_1d()
* \param dir Forward or Backward
* \param in_data Input grid data.
* \param out_data Output grid data.
* You can provide the same pointer for in_data and out_data
* to perform an in-place transform.
*
* \return 0 on success, or an error code.
*
* \note Data pointers are declared as void, to avoid casting pointers
* depending on your grid type.
*/
int
fftpack_exec_1d
(
fftpack_t
setup
,
enum
fftpack_direction
dir
,
t_complex
*
in_data
,
t_complex
*
out_data
);
/*! \brief Perform a 2-dimensional complex-to-complex transform
*
* Performs an instance of a transform previously initiated.
*
* \param setup Setup returned from fftpack_init_1d()
* \param dir Forward or Backward
* \param in_data Input grid data.
* \param out_data Output grid data.
* You can provide the same pointer for in_data and out_data
* to perform an in-place transform.
*
* \return 0 on success, or an error code.
*
* \note Data pointers are declared as void, to avoid casting pointers
* depending on your grid type.
*/
int
fftpack_exec_2d
(
fftpack_t
setup
,
enum
fftpack_direction
dir
,
t_complex
*
in_data
,
t_complex
*
out_data
);
/*! \brief Perform a 3-dimensional complex-to-complex transform
*
* Performs an instance of a transform previously initiated.
*
* \param setup Setup returned from fftpack_init_1d()
* \param dir Forward or Backward
* \param in_data Input grid data.
* \param out_data Output grid data.
* You can provide the same pointer for in_data and out_data
* to perform an in-place transform.
*
* \return 0 on success, or an error code.
*
* \note Data pointers are declared as void, to avoid casting pointers
* depending on your grid type.
*/
int
fftpack_exec_3d
(
fftpack_t
setup
,
enum
fftpack_direction
dir
,
t_complex
*
in_data
,
t_complex
*
out_data
);
/*! \brief Release an FFT setup structure
*
* Destroy setup and release all allocated memory.
*
* \param setup Setup returned from fftpack_init_1d(), or one
* of the other initializers.
*
*/
void
fftpack_destroy
(
fftpack_t
setup
);
#ifdef __cplusplus
}
#endif
#endif
/* _FFTPACK_H_ */
platforms/reference/src/SimTKReference/pme.cpp
0 → 100644
View file @
c66dd5a3
This diff is collapsed.
Click to expand it.
platforms/reference/src/SimTKReference/pme.h
0 → 100644
View file @
c66dd5a3
/*
* Reference implementation of PME reciprocal space interactions.
*
* Copyright (c) 2009, Erik Lindahl, Rossen Apostolov, Szilard Pall
* All rights reserved.
* Contact: lindahl@cbr.su.se Stockholm University, Sweden.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* Neither the name of the author/university nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "../SimTKUtilities/SimTKOpenMMCommon.h"
typedef
RealOpenMM
rvec
[
3
];
typedef
struct
pme
*
pme_t
;
/*
* Initialize a PME calculation and set up data structures
*
* Arguments:
*
* ppme Pointer to an opaque pme_t object
* ewaldcoeff Coefficient derived from the beta factor to participate
* direct/reciprocal space. See gromacs code for documentation!
* We assume that you are using nm units...
* natoms Number of atoms to set up data structure sof
* ngrid Size of the full pme grid
* pme_order Interpolation order, almost always 4
* epsilon_r Dielectric coefficient, typically 1.0.
*/
int
pme_init
(
pme_t
*
ppme
,
RealOpenMM
ewaldcoeff
,
int
natoms
,
int
ngrid
[
3
],
int
pme_order
,
RealOpenMM
epsilon_r
);
/*
* Evaluate reciprocal space PME 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)
* charge Array of charges (units of e)
* box Simulation cell dimensions (nm)
* energy Total energy (will be written in units of kJ/mol)
* pme_virial Long-range part of the virial, output.
*/
int
pme_exec
(
pme_t
pme
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
forces
,
RealOpenMM
**
atomParameters
,
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
pme_virial
[
3
][
3
]);
/* Release all memory in pme structure */
int
pme_destroy
(
pme_t
pme
);
platforms/reference/tests/TestReferenceEwald.cpp
View file @
c66dd5a3
...
@@ -76,85 +76,88 @@ void testEwald() {
...
@@ -76,85 +76,88 @@ void testEwald() {
cout
<<
"PotentialEnergy: "
<<
state
.
getPotentialEnergy
()
<<
endl
;
cout
<<
"PotentialEnergy: "
<<
state
.
getPotentialEnergy
()
<<
endl
;
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
10
*
TOL
);
// const double eps = 78.3;
// const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0);
// const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0);
// const double force = 138.935485*(1.0)*(1.0-2.0*krf*1.0);
// ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[0], TOL);
// ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[1], TOL);
// ASSERT_EQUAL_VEC(Vec3(0, 0, 0), forces[2], TOL);
// ASSERT_EQUAL_TOL(2*138.935485*(1.0)*(1.0+krf*1.0-crf), state.getPotentialEnergy(), TOL);
}
}
/*
void
testPME
()
{
void testEwald4() {
ReferencePlatform
platform
;
ReferencePlatform
platform
;
System system(4, 0);
System
system
;
for
(
int
i
=
0
;
i
<
42
;
i
++
)
{
system
.
addParticle
(
1.0
);
}
VerletIntegrator
integrator
(
0.01
);
VerletIntegrator
integrator
(
0.01
);
NonbondedForce* nonbonded = new NonbondedForce(4, 0);
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
nonbonded->setParticleParameters(0, 1.0, 1, 0);
for
(
int
i
=
0
;
i
<
14
;
i
++
)
nonbonded->setParticleParameters(1, 1.0, 1, 0);
{
nonbonded->setParticleParameters(2, -1.0, 1, 0);
nonbonded
->
addParticle
(
-
0.82
,
1
,
0
);
nonbonded->setParticleParameters(3, -1.0, 1, 0);
nonbonded
->
addParticle
(
0.41
,
1
,
0
);
nonbonded->setNonbondedMethod(NonbondedForce::Ewald);
nonbonded
->
addParticle
(
0.41
,
1
,
0
);
const double cutoff = 2.0;
}
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
const
double
cutoff
=
0.8
;
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded->setPeriodicBoxVectors(Vec3(6, 0, 0), Vec3(0, 6, 0), Vec3(0, 0, 6));
nonbonded
->
setPeriodicBoxVectors
(
Vec3
(
1.86206
,
0
,
0
),
Vec3
(
0
,
1.86206
,
0
),
Vec3
(
0
,
0
,
1.86206
));
nonbonded
->
setEwaldErrorTolerance
(
TOL
);
system
.
addForce
(
nonbonded
);
system
.
addForce
(
nonbonded
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
OpenMMContext
context
(
system
,
integrator
,
platform
);
vector<Vec3> positions(4);
vector
<
Vec3
>
positions
(
42
);
positions[0] = Vec3(3.048000,2.764000,3.156000);
positions
[
0
]
=
Vec3
(
0.23
,
0.628
,
0.113
);
positions[1] = Vec3(3.348000,2.764000,3.156000);
positions
[
1
]
=
Vec3
(
0.137
,
0.626
,
0.15
);
positions[2] = Vec3(2.809000,2.888000,2.571000);
positions
[
2
]
=
Vec3
(
0.231
,
0.589
,
0.021
);
positions[3] = Vec3(2.509000,2.888000,2.571000);
positions
[
3
]
=
Vec3
(
-
0.307
,
-
0.351
,
0.703
);
positions
[
4
]
=
Vec3
(
-
0.364
,
-
0.367
,
0.784
);
positions
[
5
]
=
Vec3
(
-
0.366
,
-
0.341
,
0.623
);
positions
[
6
]
=
Vec3
(
-
0.569
,
-
0.634
,
-
0.439
);
positions
[
7
]
=
Vec3
(
-
0.532
,
-
0.707
,
-
0.497
);
positions
[
8
]
=
Vec3
(
-
0.517
,
-
0.629
,
-
0.354
);
positions
[
9
]
=
Vec3
(
-
0.871
,
0.41
,
-
0.62
);
positions
[
10
]
=
Vec3
(
-
0.948
,
0.444
,
-
0.566
);
positions
[
11
]
=
Vec3
(
-
0.905
,
0.359
,
-
0.699
);
positions
[
12
]
=
Vec3
(
0.249
,
-
0.077
,
-
0.621
);
positions
[
13
]
=
Vec3
(
0.306
,
-
0.142
,
-
0.571
);
positions
[
14
]
=
Vec3
(
0.233
,
-
0.11
,
-
0.714
);
positions
[
15
]
=
Vec3
(
0.561
,
0.222
,
-
0.715
);
positions
[
16
]
=
Vec3
(
0.599
,
0.138
,
-
0.678
);
positions
[
17
]
=
Vec3
(
0.473
,
0.241
,
-
0.671
);
positions
[
18
]
=
Vec3
(
-
0.515
,
-
0.803
,
-
0.628
);
positions
[
19
]
=
Vec3
(
-
0.491
,
-
0.866
,
-
0.702
);
positions
[
20
]
=
Vec3
(
-
0.605
,
-
0.763
,
-
0.646
);
positions
[
21
]
=
Vec3
(
-
0.021
,
0.175
,
-
0.899
);
positions
[
22
]
=
Vec3
(
0.018
,
0.09
,
-
0.935
);
positions
[
23
]
=
Vec3
(
-
0.119
,
0.177
,
-
0.918
);
positions
[
24
]
=
Vec3
(
-
0.422
,
0.856
,
-
0.464
);
positions
[
25
]
=
Vec3
(
-
0.479
,
0.908
,
-
0.527
);
positions
[
26
]
=
Vec3
(
-
0.326
,
0.868
,
-
0.488
);
positions
[
27
]
=
Vec3
(
-
0.369
,
-
0.095
,
-
0.903
);
positions
[
28
]
=
Vec3
(
-
0.336
,
-
0.031
,
-
0.972
);
positions
[
29
]
=
Vec3
(
-
0.303
,
-
0.101
,
-
0.828
);
positions
[
30
]
=
Vec3
(
0.594
,
0.745
,
0.652
);
positions
[
31
]
=
Vec3
(
0.644
,
0.83
,
0.633
);
positions
[
32
]
=
Vec3
(
0.506
,
0.747
,
0.604
);
positions
[
33
]
=
Vec3
(
-
0.157
,
-
0.375
,
-
0.758
);
positions
[
34
]
=
Vec3
(
-
0.25
,
-
0.4
,
-
0.785
);
positions
[
35
]
=
Vec3
(
-
0.131
,
-
0.425
,
-
0.676
);
positions
[
36
]
=
Vec3
(
0.618
,
-
0.295
,
-
0.578
);
positions
[
37
]
=
Vec3
(
0.613
,
-
0.213
,
-
0.521
);
positions
[
38
]
=
Vec3
(
0.707
,
-
0.298
,
-
0.623
);
positions
[
39
]
=
Vec3
(
0.039
,
-
0.785
,
0.3
);
positions
[
40
]
=
Vec3
(
0.138
,
-
0.796
,
0.291
);
positions
[
41
]
=
Vec3
(
-
0.001
,
-
0.871
,
0.332
);
context
.
setPositions
(
positions
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
// cout << "force 0: " << forces[0] << endl;
// for (int i = 0 ; i < 42 ; i++)
// cout << "force 1: " << forces[1] << endl;
// cout << "f [" << i << " : ]" << forces[i] << endl;
cout << "energyPoten: " << state.getPotentialEnergy() << endl;
// cout << "PotentialEnergy: " << state.getPotentialEnergy() << endl;
// const double eps = 78.3;
// ASSERT_EQUAL_VEC(Vec3(-123.711, 64.1877, -302.716), forces[0], 10*TOL);
// const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0);
// ASSERT_EQUAL_VEC(Vec3(123.711, -64.1877, 302.716), forces[1], 10*TOL);
// const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0);
// const double force = 138.935485*(1.0)*(1.0-2.0*krf*1.0);
// ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[0], TOL);
// ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[1], TOL);
// ASSERT_EQUAL_VEC(Vec3(0, 0, 0), forces[2], TOL);
// ASSERT_EQUAL_TOL(2*138.935485*(1.0)*(1.0+krf*1.0-crf), state.getPotentialEnergy(), TOL);
}
}
*/
/*
void testPeriodic() {
ReferencePlatform platform;
System system(2, 0);
VerletIntegrator integrator(0.01);
NonbondedForce* nonbonded = new NonbondedForce(2, 0);
nonbonded->setParticleParameters(0, 1.0, 1, 0);
nonbonded->setParticleParameters(1, -1.0, 1, 0);
nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodci);
const double cutoff = 1.0;
nonbonded->setCutoffDistance(cutoff);
nonbonded->setPeriodicBoxVectors(Vec3(6, 0, 0), Vec3(0, 6, 0), Vec3(0, 0, 6));
system.addForce(nonbonded);
OpenMMContext context(system, integrator, platform);
vector<Vec3> positions(2);
positions[0] = Vec3(3.044293,2.765923,3.146914);
positions[1] = Vec3(2.812707,2.886077,2.580086);
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
const vector<Vec3>& forces = state.getForces();
cout << "force 0: " << forces[0] << endl;
cout << "force 1: " << forces[1] << endl;
cout << "energyPoten: " << state.getPotentialEnergy() << endl;
}
*/
int
main
()
{
int
main
()
{
try
{
try
{
// testPeriodic();
testEwald
();
testEwald
();
//
test
Ewald4
();
test
PME
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
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