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
047934e2
Commit
047934e2
authored
Mar 01, 2017
by
Rafal P. Wiewiora
Browse files
Merge remote-tracking branch 'upstream/master'
parents
ce3a5dc0
d12c9bd1
Changes
351
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1280 additions
and
1373 deletions
+1280
-1373
platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp
...rms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp
+13
-51
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+375
-311
platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp
.../reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp
+31
-70
platforms/reference/src/SimTKReference/ReferenceMonteCarloBarostat.cpp
...erence/src/SimTKReference/ReferenceMonteCarloBarostat.cpp
+7
-7
platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp
...ms/reference/src/SimTKReference/ReferenceNeighborList.cpp
+13
-13
platforms/reference/src/SimTKReference/ReferenceObc.cpp
platforms/reference/src/SimTKReference/ReferenceObc.cpp
+102
-132
platforms/reference/src/SimTKReference/ReferencePME.cpp
platforms/reference/src/SimTKReference/ReferencePME.cpp
+232
-88
platforms/reference/src/SimTKReference/ReferencePairIxn.cpp
platforms/reference/src/SimTKReference/ReferencePairIxn.cpp
+0
-14
platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp
...erence/src/SimTKReference/ReferenceProperDihedralBond.cpp
+33
-48
platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp
.../reference/src/SimTKReference/ReferenceRbDihedralBond.cpp
+33
-48
platforms/reference/src/SimTKReference/ReferenceSETTLEAlgorithm.cpp
...reference/src/SimTKReference/ReferenceSETTLEAlgorithm.cpp
+134
-134
platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp
...erence/src/SimTKReference/ReferenceStochasticDynamics.cpp
+32
-76
platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp
...rc/SimTKReference/ReferenceVariableStochasticDynamics.cpp
+35
-76
platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp
...ce/src/SimTKReference/ReferenceVariableVerletDynamics.cpp
+18
-35
platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp
.../reference/src/SimTKReference/ReferenceVerletDynamics.cpp
+10
-37
platforms/reference/src/SimTKReference/ReferenceVirtualSites.cpp
...ms/reference/src/SimTKReference/ReferenceVirtualSites.cpp
+63
-62
platforms/reference/src/SimTKReference/SimTKOpenMMUtilities.cpp
...rms/reference/src/SimTKReference/SimTKOpenMMUtilities.cpp
+33
-91
platforms/reference/src/SimTKReference/fftpack.cpp
platforms/reference/src/SimTKReference/fftpack.cpp
+76
-76
platforms/reference/tests/TestReferenceDispersionPME.cpp
platforms/reference/tests/TestReferenceDispersionPME.cpp
+36
-0
platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp
...ference/tests/TestReferenceMonteCarloMembraneBarostat.cpp
+4
-4
No files found.
platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp
View file @
047934e2
...
...
@@ -39,13 +39,6 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceLJCoulomb14
::
ReferenceLJCoulomb14
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLJCoulomb14::ReferenceLJCoulomb14";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
...
...
@@ -55,13 +48,6 @@ ReferenceLJCoulomb14::ReferenceLJCoulomb14() {
--------------------------------------------------------------------------------------- */
ReferenceLJCoulomb14
::~
ReferenceLJCoulomb14
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLJCoulomb14::~ReferenceLJCoulomb14";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
...
...
@@ -79,33 +65,10 @@ ReferenceLJCoulomb14::~ReferenceLJCoulomb14() {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulomb14
::
calculateBondIxn
(
int
*
atomIndices
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
*
parameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
totalEnergy
,
double
*
energyParamDerivs
)
{
static
const
std
::
string
methodName
=
"
\n
ReferenceLJCoulomb14::calculateBondIxn"
;
// constants -- reduce Visual Studio warnings regarding conversions between float & double
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
six
=
6.0
;
static
const
RealOpenMM
twelve
=
12.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
// number of parameters
static
const
int
numberOfParameters
=
3
;
static
const
int
LastAtomIndex
=
2
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
// ---------------------------------------------------------------------------------------
void
ReferenceLJCoulomb14
::
calculateBondIxn
(
int
*
atomIndices
,
vector
<
Vec3
>&
atomCoordinates
,
double
*
parameters
,
vector
<
Vec3
>&
forces
,
double
*
totalEnergy
,
double
*
energyParamDerivs
)
{
double
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
// get deltaR, R2, and R between 2 atoms
...
...
@@ -113,20 +76,19 @@ void ReferenceLJCoulomb14::calculateBondIxn(int* atomIndices, vector<RealVec>& a
int
atomBIndex
=
atomIndices
[
1
];
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomBIndex
],
atomCoordinates
[
atomAIndex
],
deltaR
[
0
]);
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
sig2
=
inverseR
*
parameters
[
0
];
sig2
*=
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
double
inverseR
=
1.0
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
double
sig2
=
inverseR
*
parameters
[
0
];
sig2
*=
sig2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
dEdR
=
parameters
[
1
]
*
(
twelve
*
sig6
-
six
)
*
sig6
;
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
)
;
dEdR
*=
inverseR
*
inverseR
;
double
dEdR
=
parameters
[
1
]
*
(
12.0
*
sig6
-
6.0
)
*
sig6
;
dEdR
+=
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
;
dEdR
*=
inverseR
*
inverseR
;
// accumulate forces
for
(
int
ii
=
0
;
ii
<
3
;
ii
++
)
{
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
ii
];
double
force
=
dEdR
*
deltaR
[
0
][
ii
];
forces
[
atomAIndex
][
ii
]
+=
force
;
forces
[
atomBIndex
][
ii
]
-=
force
;
}
...
...
@@ -134,5 +96,5 @@ void ReferenceLJCoulomb14::calculateBondIxn(int* atomIndices, vector<RealVec>& a
// accumulate energies
if
(
totalEnergy
!=
NULL
)
*
totalEnergy
+=
parameters
[
1
]
*
(
sig6
-
one
)
*
sig6
+
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
);
*
totalEnergy
+=
parameters
[
1
]
*
(
sig6
-
1.0
)
*
sig6
+
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
);
}
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
047934e2
...
...
@@ -26,6 +26,7 @@
#include <sstream>
#include <complex>
#include <algorithm>
#include <iostream>
#include "SimTKOpenMMUtilities.h"
#include "ReferenceLJCoulombIxn.h"
...
...
@@ -47,14 +48,7 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
()
:
cutoff
(
false
),
useSwitch
(
false
),
periodic
(
false
),
ewald
(
false
),
pme
(
false
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLJCoulombIxn::ReferenceLJCoulombIxn";
// ---------------------------------------------------------------------------------------
ReferenceLJCoulombIxn
::
ReferenceLJCoulombIxn
()
:
cutoff
(
false
),
useSwitch
(
false
),
periodic
(
false
),
ewald
(
false
),
pme
(
false
),
ljpme
(
false
)
{
}
/**---------------------------------------------------------------------------------------
...
...
@@ -64,16 +58,9 @@ ReferenceLJCoulombIxn::ReferenceLJCoulombIxn() : cutoff(false), useSwitch(false)
--------------------------------------------------------------------------------------- */
ReferenceLJCoulombIxn
::~
ReferenceLJCoulombIxn
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLJCoulombIxn::~ReferenceLJCoulombIxn";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use a cutoff.
...
...
@@ -83,14 +70,14 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn() {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseCutoff
(
RealOpenMM
distance
,
const
OpenMM
::
NeighborList
&
neighbors
,
RealOpenMM
solventDielectric
)
{
void
ReferenceLJCoulombIxn
::
setUseCutoff
(
double
distance
,
const
OpenMM
::
NeighborList
&
neighbors
,
double
solventDielectric
)
{
cutoff
=
true
;
cutoffDistance
=
distance
;
neighborList
=
&
neighbors
;
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
);
}
}
/**---------------------------------------------------------------------------------------
...
...
@@ -100,12 +87,12 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn() {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseSwitchingFunction
(
RealOpenMM
distance
)
{
void
ReferenceLJCoulombIxn
::
setUseSwitchingFunction
(
double
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
...
...
@@ -115,7 +102,7 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setPeriodic
(
OpenMM
::
Real
Vec
*
vectors
)
{
void
ReferenceLJCoulombIxn
::
setPeriodic
(
OpenMM
::
Vec
3
*
vectors
)
{
assert
(
cutoff
);
assert
(
vectors
[
0
][
0
]
>=
2.0
*
cutoffDistance
);
...
...
@@ -125,9 +112,9 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
periodicBoxVectors
[
0
]
=
vectors
[
0
];
periodicBoxVectors
[
1
]
=
vectors
[
1
];
periodicBoxVectors
[
2
]
=
vectors
[
2
];
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Set the force to use Ewald summation.
...
...
@@ -138,15 +125,15 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseEwald
(
RealOpenMM
alpha
,
int
kmaxx
,
int
kmaxy
,
int
kmaxz
)
{
alphaEwald
=
alpha
;
numRx
=
kmaxx
;
numRy
=
kmaxy
;
numRz
=
kmaxz
;
ewald
=
true
;
}
void
ReferenceLJCoulombIxn
::
setUseEwald
(
double
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.
...
...
@@ -155,13 +142,30 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUsePME
(
RealOpenMM
alpha
,
int
meshSize
[
3
])
{
alphaEwald
=
alpha
;
meshDim
[
0
]
=
meshSize
[
0
];
meshDim
[
1
]
=
meshSize
[
1
];
meshDim
[
2
]
=
meshSize
[
2
];
pme
=
true
;
}
void
ReferenceLJCoulombIxn
::
setUsePME
(
double
alpha
,
int
meshSize
[
3
])
{
alphaEwald
=
alpha
;
meshDim
[
0
]
=
meshSize
[
0
];
meshDim
[
1
]
=
meshSize
[
1
];
meshDim
[
2
]
=
meshSize
[
2
];
pme
=
true
;
}
/**---------------------------------------------------------------------------------------
Set the force to use Particle-Mesh Ewald (PME) summation for dispersion terms.
@param alpha the dispersion Ewald separation parameter
@param gridSize the dimensions of the dispersion mesh
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
setUseLJPME
(
double
alpha
,
int
meshSize
[
3
])
{
alphaDispersionEwald
=
alpha
;
dispersionMeshDim
[
0
]
=
meshSize
[
0
];
dispersionMeshDim
[
1
]
=
meshSize
[
1
];
dispersionMeshDim
[
2
]
=
meshSize
[
2
];
ljpme
=
true
;
}
/**---------------------------------------------------------------------------------------
...
...
@@ -181,36 +185,44 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
vector
<
Real
Vec
>&
atomCoordinates
,
RealOpenMM
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
RealOpenMM
*
fixedParameters
,
vector
<
Real
Vec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
typedef
std
::
complex
<
RealOpenMM
>
d_complex
;
void
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
vector
<
Vec
3
>&
atomCoordinates
,
double
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
double
*
fixedParameters
,
vector
<
Vec
3
>&
forces
,
double
*
energyByAtom
,
double
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
typedef
std
::
complex
<
double
>
d_complex
;
static
const
RealOpenMM
epsilon
=
1.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
six
=
6.0
;
static
const
RealOpenMM
twelve
=
12.0
;
static
const
double
epsilon
=
1.0
;
int
kmax
=
(
ewald
?
std
::
max
(
numRx
,
std
::
max
(
numRy
,
numRz
))
:
0
);
RealOpenMM
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
RealOpenMM
SQRT_PI
=
sqrt
(
PI_M
);
RealOpenMM
TWO_PI
=
2.0
*
PI_M
;
RealOpenMM
recipCoeff
=
(
RealOpenMM
)(
ONE_4PI_EPS0
*
4
*
PI_M
/
(
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
])
/
epsilon
);
RealOpenMM
totalSelfEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
RealOpenMM
totalRecipEnergy
=
0.0
;
RealOpenMM
vdwEnergy
=
0.0
;
// **************************************************************************************
// SELF ENERGY
// **************************************************************************************
double
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
double
SQRT_PI
=
sqrt
(
PI_M
);
double
TWO_PI
=
2.0
*
PI_M
;
double
recipCoeff
=
ONE_4PI_EPS0
*
4
*
PI_M
/
(
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
])
/
epsilon
;
double
totalSelfEwaldEnergy
=
0.0
;
double
realSpaceEwaldEnergy
=
0.0
;
double
recipEnergy
=
0.0
;
double
recipDispersionEnergy
=
0.0
;
double
totalRecipEnergy
=
0.0
;
double
vdwEnergy
=
0.0
;
// A couple of sanity checks for
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
)
{
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
)
{
RealOpenMM
selfEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
);
double
selfEwaldEnergy
=
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
;
if
(
energyByAtom
)
{
energyByAtom
[
atomID
]
-=
selfEwaldEnergy
;
...
...
@@ -222,194 +234,249 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
*
totalEnergy
+=
totalSelfEwaldEnergy
;
}
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
// PME
if
(
pme
&&
includeReciprocal
)
{
pme_t
pmedata
;
/* abstract handle for PME data */
if
(
pme
&&
includeReciprocal
)
{
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
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
vector
<
double
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
pme_destroy
(
pmedata
);
}
if
(
ljpme
)
{
// Dispersion reciprocal space terms
pme_init
(
&
pmedata
,
alphaDispersionEwald
,
numberOfAtoms
,
dispersionMeshDim
,
5
,
1
);
std
::
vector
<
Vec3
>
dpmeforces
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
){
charges
[
i
]
=
8.0
*
pow
(
atomParameters
[
i
][
SigIndex
],
3.0
)
*
atomParameters
[
i
][
EpsIndex
];
dpmeforces
.
push_back
(
Vec3
());
}
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
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
]};
double
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]
vector
<
d_complex
>
eir
(
kmax
*
numberOfAtoms
*
3
);
vector
<
d_complex
>
tab_xy
(
numberOfAtoms
);
vector
<
d_complex
>
tab_qxyz
(
numberOfAtoms
);
#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
)
throw
OpenMMException
(
"kmax for Ewald summation < 1"
);
if
(
kmax
<
1
)
throw
OpenMMException
(
"kmax for Ewald summation < 1"
);
for
(
int
i
=
0
;
(
i
<
numberOfAtoms
);
i
++
)
{
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
0
,
i
,
m
)
=
d_complex
(
1
,
0
);
for
(
int
i
=
0
;
(
i
<
numberOfAtoms
);
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
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]),
sin
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]));
for
(
int
m
=
0
;
(
m
<
3
);
m
++
)
EIR
(
1
,
i
,
m
)
=
d_complex
(
cos
(
atomCoordinates
[
i
][
m
]
*
recipBoxSize
[
m
]),
sin
(
atomCoordinates
[
i
][
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
);
}
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
// calculate reciprocal space energy and forces
int
lowry
=
0
;
int
lowrz
=
1
;
int
lowry
=
0
;
int
lowrz
=
1
;
for
(
int
rx
=
0
;
rx
<
numRx
;
rx
++
)
{
for
(
int
rx
=
0
;
rx
<
numRx
;
rx
++
)
{
RealOpenMM
kx
=
rx
*
recipBoxSize
[
0
];
double
kx
=
rx
*
recipBoxSize
[
0
];
for
(
int
ry
=
lowry
;
ry
<
numRy
;
ry
++
)
{
for
(
int
ry
=
lowry
;
ry
<
numRy
;
ry
++
)
{
RealOpenMM
ky
=
ry
*
recipBoxSize
[
1
];
double
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
);
}
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
));
}
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
++
)
{
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
));
}
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
)));
}
else
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
tab_qxyz
[
n
]
=
atomParameters
[
n
][
QIndex
]
*
(
tab_xy
[
n
]
*
conj
(
EIR
(
-
rz
,
n
,
2
)));
}
RealOpenMM
cs
=
0.0
f
;
RealOpenMM
ss
=
0.0
f
;
double
cs
=
0.0
f
;
double
ss
=
0.0
f
;
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
cs
+=
tab_qxyz
[
n
].
real
();
ss
+=
tab_qxyz
[
n
].
imag
();
}
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
cs
+=
tab_qxyz
[
n
].
real
();
ss
+=
tab_qxyz
[
n
].
imag
();
}
RealOpenMM
kz
=
rz
*
recipBoxSize
[
2
];
RealOpenMM
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
RealOpenMM
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
double
kz
=
rz
*
recipBoxSize
[
2
];
double
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
double
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
RealOpenMM
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
forces
[
n
][
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
forces
[
n
][
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
forces
[
n
][
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
}
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
double
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
forces
[
n
][
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
forces
[
n
][
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
forces
[
n
][
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
}
recipEnergy
=
recipCoeff
*
ak
*
(
cs
*
cs
+
ss
*
ss
);
totalRecipEnergy
+=
recipEnergy
;
recipEnergy
=
recipCoeff
*
ak
*
(
cs
*
cs
+
ss
*
ss
);
totalRecipEnergy
+=
recipEnergy
;
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
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
)
return
;
RealOpenMM
totalVdwEnergy
=
0.0
f
;
RealOpenMM
totalRealSpaceEwaldEnergy
=
0.0
f
;
double
totalVdwEnergy
=
0.0
f
;
double
totalRealSpaceEwaldEnergy
=
0.0
f
;
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
int
ii
=
pair
.
first
;
int
jj
=
pair
.
second
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxVectors
,
deltaR
[
0
]);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
switchValue
=
1
,
switchDeriv
=
0
;
if
(
useSwitch
&&
r
>
switchingDistance
)
{
RealOpenMM
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
);
}
RealOpenMM
alphaR
=
alphaEwald
*
r
;
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
));
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
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
++
)
{
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
;
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
int
ii
=
pair
.
first
;
int
jj
=
pair
.
second
;
double
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxVectors
,
deltaR
[
0
]);
double
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
double
inverseR
=
1.0
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
double
switchValue
=
1
,
switchDeriv
=
0
;
if
(
useSwitch
&&
r
>
switchingDistance
)
{
double
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
);
}
double
alphaR
=
alphaEwald
*
r
;
double
dEdR
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
dEdR
=
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
double
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
double
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
double
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
dEdR
+=
switchValue
*
eps
*
(
12.0
*
sig6
-
6.0
)
*
sig6
*
inverseR
*
inverseR
;
vdwEnergy
=
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
ljpme
)
{
double
dalphaR
=
alphaDispersionEwald
*
r
;
double
dar2
=
dalphaR
*
dalphaR
;
double
dar4
=
dar2
*
dar2
;
double
dar6
=
dar4
*
dar2
;
double
inverseR2
=
inverseR
*
inverseR
;
double
c6i
=
8.0
*
pow
(
atomParameters
[
ii
][
SigIndex
],
3.0
)
*
atomParameters
[
ii
][
EpsIndex
];
double
c6j
=
8.0
*
pow
(
atomParameters
[
jj
][
SigIndex
],
3.0
)
*
atomParameters
[
jj
][
EpsIndex
];
// For the energies and forces, we first add the regular Lorentz−Berthelot terms. The C12 term is treated as usual
// 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.
double
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
));
double
inverseCut2
=
1.0
/
(
cutoffDistance
*
cutoffDistance
);
double
inverseCut6
=
inverseCut2
*
inverseCut2
*
inverseCut2
;
sig2
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
sig2
*=
sig2
;
sig6
=
sig2
*
sig2
*
sig2
;
// The additive part of the potential shift
double
potentialshift
=
eps
*
(
1.0
-
sig6
*
inverseCut6
)
*
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
++
)
{
double
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
// accumulate energies
realSpaceEwaldEnergy
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
);
totalVdwEnergy
+=
vdwEnergy
;
totalRealSpaceEwaldEnergy
+=
realSpaceEwaldEnergy
;
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
jj
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
ii
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
jj
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
}
}
...
...
@@ -419,44 +486,62 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
// Now subtract off the exclusions, since they were implicitly included in the reciprocal space sum.
RealOpenMM
totalExclusionEnergy
=
0.0
f
;
double
totalExclusionEnergy
=
0.0
f
;
const
double
TWO_OVER_SQRT_PI
=
2
/
sqrt
(
PI_M
);
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
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
alphaR
=
alphaEwald
*
r
;
if
(
erf
(
alphaR
)
>
1e-6
)
{
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
));
// 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
*
erf
(
alphaR
));
}
else
{
realSpaceEwaldEnergy
=
(
RealOpenMM
)
(
alphaEwald
*
TWO_OVER_SQRT_PI
*
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]);
}
totalExclusionEnergy
+=
realSpaceEwaldEnergy
;
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
-=
realSpaceEwaldEnergy
;
energyByAtom
[
jj
]
-=
realSpaceEwaldEnergy
;
}
int
ii
=
i
;
int
jj
=
*
iter
;
double
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]);
double
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
double
inverseR
=
1.0
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
double
alphaR
=
alphaEwald
*
r
;
if
(
erf
(
alphaR
)
>
1e-6
)
{
double
dEdR
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
dEdR
=
dEdR
*
(
erf
(
alphaR
)
-
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
);
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
double
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
-=
force
;
forces
[
jj
][
kk
]
+=
force
;
}
// accumulate energies
realSpaceEwaldEnergy
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erf
(
alphaR
);
}
else
{
realSpaceEwaldEnergy
=
alphaEwald
*
TWO_OVER_SQRT_PI
*
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
];
}
if
(
ljpme
){
// Dispersion terms. Here we just back out the reciprocal space terms, and don't add any extra real space terms.
double
dalphaR
=
alphaDispersionEwald
*
r
;
double
inverseR2
=
inverseR
*
inverseR
;
double
dar2
=
dalphaR
*
dalphaR
;
double
dar4
=
dar2
*
dar2
;
double
dar6
=
dar4
*
dar2
;
double
c6i
=
8.0
*
pow
(
atomParameters
[
ii
][
SigIndex
],
3.0
)
*
atomParameters
[
ii
][
EpsIndex
];
double
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
));
double
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
++
)
{
double
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
-=
force
;
forces
[
jj
][
kk
]
+=
force
;
}
}
totalExclusionEnergy
+=
realSpaceEwaldEnergy
;
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
-=
realSpaceEwaldEnergy
;
energyByAtom
[
jj
]
-=
realSpaceEwaldEnergy
;
}
}
}
...
...
@@ -483,36 +568,36 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
calculatePairIxn
(
int
numberOfAtoms
,
vector
<
Real
Vec
>&
atomCoordinates
,
RealOpenMM
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
RealOpenMM
*
fixedParameters
,
vector
<
Real
Vec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
if
(
ewald
||
pme
)
{
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
,
includeDirect
,
includeReciprocal
);
return
;
}
if
(
!
includeDirect
)
return
;
if
(
cutoff
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
atomParameters
,
forces
,
energyByAtom
,
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
,
energyByAtom
,
totalEnergy
);
}
}
void
ReferenceLJCoulombIxn
::
calculatePairIxn
(
int
numberOfAtoms
,
vector
<
Vec
3
>&
atomCoordinates
,
double
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
double
*
fixedParameters
,
vector
<
Vec
3
>&
forces
,
double
*
energyByAtom
,
double
*
totalEnergy
,
bool
includeDirect
,
bool
includeReciprocal
)
const
{
if
(
ewald
||
pme
||
ljpme
)
{
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
,
includeDirect
,
includeReciprocal
);
return
;
}
if
(
!
includeDirect
)
return
;
if
(
cutoff
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
atomParameters
,
forces
,
energyByAtom
,
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
,
energyByAtom
,
totalEnergy
);
}
}
}
/**---------------------------------------------------------------------------------------
/**---------------------------------------------------------------------------------------
Calculate LJ Coulomb pair ixn between two atoms
...
...
@@ -526,31 +611,10 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector<RealVec>&
--------------------------------------------------------------------------------------- */
void
ReferenceLJCoulombIxn
::
calculateOneIxn
(
int
ii
,
int
jj
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
**
atomParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
// ---------------------------------------------------------------------------------------
static
const
std
::
string
methodName
=
"
\n
ReferenceLJCoulombIxn::calculateOneIxn"
;
// ---------------------------------------------------------------------------------------
// constants -- reduce Visual Studio warnings regarding conversions between float & double
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
six
=
6.0
;
static
const
RealOpenMM
twelve
=
12.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
static
const
int
LastAtomIndex
=
2
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
void
ReferenceLJCoulombIxn
::
calculateOneIxn
(
int
ii
,
int
jj
,
vector
<
Vec3
>&
atomCoordinates
,
double
**
atomParameters
,
vector
<
Vec3
>&
forces
,
double
*
energyByAtom
,
double
*
totalEnergy
)
const
{
double
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
// get deltaR, R2, and R between 2 atoms
...
...
@@ -559,54 +623,54 @@ void ReferenceLJCoulombIxn::calculateOneIxn(int ii, int jj, vector<RealVec>& ato
else
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]);
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
switchValue
=
1
,
switchDeriv
=
0
;
double
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
double
inverseR
=
1.0
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
double
switchValue
=
1
,
switchDeriv
=
0
;
if
(
useSwitch
)
{
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
double
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
if
(
r
>
switchingDistance
)
{
RealOpenMM
t
=
(
r
-
switchingDistance
)
/
(
cutoffDistance
-
switchingDistance
);
double
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
);
}
}
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
double
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
double
sig2
=
inverseR
*
sig
;
sig2
*=
sig2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
RealOpenMM
dEdR
=
switchValue
*
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
;
double
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
double
dEdR
=
switchValue
*
eps
*
(
12.0
*
sig6
-
6.0
)
*
sig6
;
if
(
cutoff
)
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
)
)
;
dEdR
+=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
);
else
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
)
;
dEdR
+=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
;
dEdR
*=
inverseR
*
inverseR
;
RealOpenMM
energy
=
eps
*
(
sig6
-
one
)
*
sig6
;
double
energy
=
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
useSwitch
)
{
dEdR
-=
energy
*
switchDeriv
*
inverseR
;
energy
*=
switchValue
;
}
if
(
cutoff
)
energy
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
+
krf
*
r2
-
crf
)
)
;
energy
+=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
+
krf
*
r2
-
crf
);
else
energy
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
)
;
energy
+=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
;
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
)
{
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
double
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
// accumulate energies
if
(
totalEnergy
)
*
totalEnergy
+=
energy
;
*
totalEnergy
+=
energy
;
if
(
energyByAtom
)
{
energyByAtom
[
ii
]
+=
energy
;
energyByAtom
[
jj
]
+=
energy
;
energyByAtom
[
ii
]
+=
energy
;
energyByAtom
[
jj
]
+=
energy
;
}
}
}
platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp
View file @
047934e2
...
...
@@ -44,13 +44,7 @@ using namespace OpenMM;
ReferenceLincsAlgorithm
::
ReferenceLincsAlgorithm
(
int
numberOfConstraints
,
int
**
atomIndices
,
RealOpenMM
*
distance
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::ReferenceLincsAlgorithm";
// ---------------------------------------------------------------------------------------
double
*
distance
)
{
_numberOfConstraints
=
numberOfConstraints
;
_atomIndices
=
atomIndices
;
...
...
@@ -69,13 +63,6 @@ ReferenceLincsAlgorithm::ReferenceLincsAlgorithm(int numberOfConstraints,
--------------------------------------------------------------------------------------- */
int
ReferenceLincsAlgorithm
::
getNumberOfConstraints
()
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::getNumberOfConstraints";
// ---------------------------------------------------------------------------------------
return
_numberOfConstraints
;
}
...
...
@@ -88,13 +75,6 @@ int ReferenceLincsAlgorithm::getNumberOfConstraints() const {
--------------------------------------------------------------------------------------- */
int
ReferenceLincsAlgorithm
::
getNumTerms
()
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::getNumTerms";
// ---------------------------------------------------------------------------------------
return
_numTerms
;
}
...
...
@@ -105,13 +85,6 @@ int ReferenceLincsAlgorithm::getNumTerms() const {
--------------------------------------------------------------------------------------- */
void
ReferenceLincsAlgorithm
::
setNumTerms
(
int
terms
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::setNumTerms";
// ---------------------------------------------------------------------------------------
_numTerms
=
terms
;
}
...
...
@@ -125,8 +98,7 @@ void ReferenceLincsAlgorithm::setNumTerms(int terms) {
--------------------------------------------------------------------------------------- */
void
ReferenceLincsAlgorithm
::
initialize
(
int
numberOfAtoms
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
static
const
RealOpenMM
one
=
1.0
;
void
ReferenceLincsAlgorithm
::
initialize
(
int
numberOfAtoms
,
vector
<
double
>&
inverseMasses
)
{
_hasInitialized
=
true
;
vector
<
vector
<
int
>
>
atomConstraints
(
numberOfAtoms
);
for
(
int
constraint
=
0
;
constraint
<
_numberOfConstraints
;
constraint
++
)
{
...
...
@@ -145,7 +117,7 @@ void ReferenceLincsAlgorithm::initialize(int numberOfAtoms, vector<RealOpenMM>&
}
_sMatrix
.
resize
(
_numberOfConstraints
);
for
(
int
constraint
=
0
;
constraint
<
_numberOfConstraints
;
constraint
++
)
_sMatrix
[
constraint
]
=
one
/
SQRT
(
inverseMasses
[
_atomIndices
[
constraint
][
0
]]
+
inverseMasses
[
_atomIndices
[
constraint
][
1
]]);
_sMatrix
[
constraint
]
=
1.0
/
sqrt
(
inverseMasses
[
_atomIndices
[
constraint
][
0
]]
+
inverseMasses
[
_atomIndices
[
constraint
][
1
]]);
_couplingMatrix
.
resize
(
_numberOfConstraints
);
for
(
int
constraint
=
0
;
constraint
<
_numberOfConstraints
;
constraint
++
)
_couplingMatrix
[
constraint
].
resize
(
_linkedConstraints
[
constraint
].
size
());
...
...
@@ -162,12 +134,11 @@ void ReferenceLincsAlgorithm::initialize(int numberOfAtoms, vector<RealOpenMM>&
--------------------------------------------------------------------------------------- */
void
ReferenceLincsAlgorithm
::
solveMatrix
()
{
static
const
RealOpenMM
zero
=
0.0
;
for
(
int
iteration
=
0
;
iteration
<
_numTerms
;
iteration
++
)
{
vector
<
RealOpenMM
>&
rhs1
=
(
iteration
%
2
==
0
?
_rhs1
:
_rhs2
);
vector
<
RealOpenMM
>&
rhs2
=
(
iteration
%
2
==
0
?
_rhs2
:
_rhs1
);
vector
<
double
>&
rhs1
=
(
iteration
%
2
==
0
?
_rhs1
:
_rhs2
);
vector
<
double
>&
rhs2
=
(
iteration
%
2
==
0
?
_rhs2
:
_rhs1
);
for
(
int
c1
=
0
;
c1
<
_numberOfConstraints
;
c1
++
)
{
rhs2
[
c1
]
=
zero
;
rhs2
[
c1
]
=
0.0
;
for
(
int
j
=
0
;
j
<
(
int
)
_linkedConstraints
[
c1
].
size
();
j
++
)
{
int
c2
=
_linkedConstraints
[
c1
][
j
];
rhs2
[
c1
]
+=
_couplingMatrix
[
c1
][
j
]
*
rhs1
[
c2
];
...
...
@@ -187,19 +158,19 @@ void ReferenceLincsAlgorithm::solveMatrix() {
--------------------------------------------------------------------------------------- */
void
ReferenceLincsAlgorithm
::
updateAtomPositions
(
int
numberOfAtoms
,
vector
<
Real
Vec
>&
atomCoordinates
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
void
ReferenceLincsAlgorithm
::
updateAtomPositions
(
int
numberOfAtoms
,
vector
<
Vec
3
>&
atomCoordinates
,
vector
<
double
>&
inverseMasses
)
{
for
(
int
i
=
0
;
i
<
_numberOfConstraints
;
i
++
)
{
Real
Vec
delta
(
_sMatrix
[
i
]
*
_solution
[
i
]
*
_constraintDir
[
i
][
0
],
Vec
3
delta
(
_sMatrix
[
i
]
*
_solution
[
i
]
*
_constraintDir
[
i
][
0
],
_sMatrix
[
i
]
*
_solution
[
i
]
*
_constraintDir
[
i
][
1
],
_sMatrix
[
i
]
*
_solution
[
i
]
*
_constraintDir
[
i
][
2
]);
int
atom1
=
_atomIndices
[
i
][
0
];
int
atom2
=
_atomIndices
[
i
][
1
];
atomCoordinates
[
atom1
][
0
]
-=
(
RealOpenMM
)(
inverseMasses
[
atom1
]
*
delta
[
0
]
)
;
atomCoordinates
[
atom1
][
1
]
-=
(
RealOpenMM
)(
inverseMasses
[
atom1
]
*
delta
[
1
]
)
;
atomCoordinates
[
atom1
][
2
]
-=
(
RealOpenMM
)(
inverseMasses
[
atom1
]
*
delta
[
2
]
)
;
atomCoordinates
[
atom2
][
0
]
+=
(
RealOpenMM
)(
inverseMasses
[
atom2
]
*
delta
[
0
]
)
;
atomCoordinates
[
atom2
][
1
]
+=
(
RealOpenMM
)(
inverseMasses
[
atom2
]
*
delta
[
1
]
)
;
atomCoordinates
[
atom2
][
2
]
+=
(
RealOpenMM
)(
inverseMasses
[
atom2
]
*
delta
[
2
]
)
;
atomCoordinates
[
atom1
][
0
]
-=
inverseMasses
[
atom1
]
*
delta
[
0
];
atomCoordinates
[
atom1
][
1
]
-=
inverseMasses
[
atom1
]
*
delta
[
1
];
atomCoordinates
[
atom1
][
2
]
-=
inverseMasses
[
atom1
]
*
delta
[
2
];
atomCoordinates
[
atom2
][
0
]
+=
inverseMasses
[
atom2
]
*
delta
[
0
];
atomCoordinates
[
atom2
][
1
]
+=
inverseMasses
[
atom2
]
*
delta
[
1
];
atomCoordinates
[
atom2
][
2
]
+=
inverseMasses
[
atom2
]
*
delta
[
2
];
}
}
...
...
@@ -214,19 +185,9 @@ void ReferenceLincsAlgorithm::updateAtomPositions(int numberOfAtoms, vector<Real
--------------------------------------------------------------------------------------- */
void
ReferenceLincsAlgorithm
::
apply
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceLincsAlgorithm::apply"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
// ---------------------------------------------------------------------------------------
void
ReferenceLincsAlgorithm
::
apply
(
int
numberOfAtoms
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
atomCoordinatesP
,
vector
<
double
>&
inverseMasses
)
{
if
(
_numberOfConstraints
==
0
)
return
;
...
...
@@ -239,27 +200,27 @@ void ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector<RealVec>& atomCoor
for
(
int
i
=
0
;
i
<
_numberOfConstraints
;
i
++
)
{
int
atom1
=
_atomIndices
[
i
][
0
];
int
atom2
=
_atomIndices
[
i
][
1
];
_constraintDir
[
i
]
=
Real
Vec
(
atomCoordinatesP
[
atom1
][
0
]
-
atomCoordinatesP
[
atom2
][
0
],
_constraintDir
[
i
]
=
Vec
3
(
atomCoordinatesP
[
atom1
][
0
]
-
atomCoordinatesP
[
atom2
][
0
],
atomCoordinatesP
[
atom1
][
1
]
-
atomCoordinatesP
[
atom2
][
1
],
atomCoordinatesP
[
atom1
][
2
]
-
atomCoordinatesP
[
atom2
][
2
]);
RealOpenMM
invLength
=
(
RealOpenMM
)(
1
/
SQRT
((
RealOpenMM
)
_constraintDir
[
i
].
dot
(
_constraintDir
[
i
]))
)
;
double
invLength
=
1
/
sqrt
(
_constraintDir
[
i
].
dot
(
_constraintDir
[
i
]));
_constraintDir
[
i
][
0
]
*=
invLength
;
_constraintDir
[
i
][
1
]
*=
invLength
;
_constraintDir
[
i
][
2
]
*=
invLength
;
_rhs1
[
i
]
=
_solution
[
i
]
=
_sMatrix
[
i
]
*
(
one
/
invLength
-
_distance
[
i
]);
_rhs1
[
i
]
=
_solution
[
i
]
=
_sMatrix
[
i
]
*
(
1.0
/
invLength
-
_distance
[
i
]);
}
// Build the coupling matrix.
for
(
int
c1
=
0
;
c1
<
(
int
)
_couplingMatrix
.
size
();
c1
++
)
{
Real
Vec
&
dir1
=
_constraintDir
[
c1
];
Vec
3
&
dir1
=
_constraintDir
[
c1
];
for
(
int
j
=
0
;
j
<
(
int
)
_couplingMatrix
[
c1
].
size
();
j
++
)
{
int
c2
=
_linkedConstraints
[
c1
][
j
];
Real
Vec
&
dir2
=
_constraintDir
[
c2
];
Vec
3
&
dir2
=
_constraintDir
[
c2
];
if
(
_atomIndices
[
c1
][
0
]
==
_atomIndices
[
c2
][
0
]
||
_atomIndices
[
c1
][
1
]
==
_atomIndices
[
c2
][
1
])
_couplingMatrix
[
c1
][
j
]
=
(
RealOpenMM
)(
-
inverseMasses
[
_atomIndices
[
c1
][
0
]]
*
_sMatrix
[
c1
]
*
dir1
.
dot
(
dir2
)
*
_sMatrix
[
c2
]
)
;
_couplingMatrix
[
c1
][
j
]
=
-
inverseMasses
[
_atomIndices
[
c1
][
0
]]
*
_sMatrix
[
c1
]
*
dir1
.
dot
(
dir2
)
*
_sMatrix
[
c2
];
else
_couplingMatrix
[
c1
][
j
]
=
(
RealOpenMM
)(
inverseMasses
[
_atomIndices
[
c1
][
1
]]
*
_sMatrix
[
c1
]
*
dir1
.
dot
(
dir2
)
*
_sMatrix
[
c2
]
)
;
_couplingMatrix
[
c1
][
j
]
=
inverseMasses
[
_atomIndices
[
c1
][
1
]]
*
_sMatrix
[
c1
]
*
dir1
.
dot
(
dir2
)
*
_sMatrix
[
c2
];
}
}
...
...
@@ -273,13 +234,13 @@ void ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector<RealVec>& atomCoor
for
(
int
i
=
0
;
i
<
_numberOfConstraints
;
i
++
)
{
int
atom1
=
_atomIndices
[
i
][
0
];
int
atom2
=
_atomIndices
[
i
][
1
];
Real
Vec
delta
(
atomCoordinatesP
[
atom1
][
0
]
-
atomCoordinatesP
[
atom2
][
0
],
Vec
3
delta
(
atomCoordinatesP
[
atom1
][
0
]
-
atomCoordinatesP
[
atom2
][
0
],
atomCoordinatesP
[
atom1
][
1
]
-
atomCoordinatesP
[
atom2
][
1
],
atomCoordinatesP
[
atom1
][
2
]
-
atomCoordinatesP
[
atom2
][
2
]);
RealOpenMM
p2
=
(
RealOpenMM
)(
two
*
_distance
[
i
]
*
_distance
[
i
]
-
delta
.
dot
(
delta
)
)
;
if
(
p2
<
zero
)
p2
=
zero
;
_rhs1
[
i
]
=
_solution
[
i
]
=
_sMatrix
[
i
]
*
(
_distance
[
i
]
-
SQRT
(
p2
));
double
p2
=
2.0
*
_distance
[
i
]
*
_distance
[
i
]
-
delta
.
dot
(
delta
);
if
(
p2
<
0.0
)
p2
=
0.0
;
_rhs1
[
i
]
=
_solution
[
i
]
=
_sMatrix
[
i
]
*
(
_distance
[
i
]
-
sqrt
(
p2
));
}
solveMatrix
();
updateAtomPositions
(
numberOfAtoms
,
atomCoordinatesP
,
inverseMasses
);
...
...
@@ -296,7 +257,7 @@ void ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector<RealVec>& atomCoor
--------------------------------------------------------------------------------------- */
void
ReferenceLincsAlgorithm
::
applyToVelocities
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
Real
Vec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
Real
Vec
>&
velocities
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
)
{
void
ReferenceLincsAlgorithm
::
applyToVelocities
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
Vec
3
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
Vec
3
>&
velocities
,
std
::
vector
<
double
>&
inverseMasses
)
{
throw
OpenMM
::
OpenMMException
(
"applyToVelocities is not implemented"
);
}
platforms/reference/src/SimTKReference/ReferenceMonteCarloBarostat.cpp
View file @
047934e2
...
...
@@ -64,7 +64,7 @@ ReferenceMonteCarloBarostat::~ReferenceMonteCarloBarostat() {
--------------------------------------------------------------------------------------- */
void
ReferenceMonteCarloBarostat
::
applyBarostat
(
vector
<
Real
Vec
>&
atomPositions
,
const
Real
Vec
*
boxVectors
,
RealOpenMM
scaleX
,
RealOpenMM
scaleY
,
RealOpenMM
scaleZ
)
{
void
ReferenceMonteCarloBarostat
::
applyBarostat
(
vector
<
Vec
3
>&
atomPositions
,
const
Vec
3
*
boxVectors
,
double
scaleX
,
double
scaleY
,
double
scaleZ
)
{
int
numAtoms
=
savedAtomPositions
[
0
].
size
();
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
...
...
@@ -75,16 +75,16 @@ void ReferenceMonteCarloBarostat::applyBarostat(vector<RealVec>& atomPositions,
for
(
int
i
=
0
;
i
<
(
int
)
molecules
.
size
();
i
++
)
{
// Find the molecule center.
Real
Vec
pos
(
0
,
0
,
0
);
Vec
3
pos
(
0
,
0
,
0
);
for
(
int
j
=
0
;
j
<
(
int
)
molecules
[
i
].
size
();
j
++
)
{
Real
Vec
&
atomPos
=
atomPositions
[
molecules
[
i
][
j
]];
Vec
3
&
atomPos
=
atomPositions
[
molecules
[
i
][
j
]];
pos
+=
atomPos
;
}
pos
/=
molecules
[
i
].
size
();
// Move it into the first periodic box.
Real
Vec
newPos
=
pos
;
Vec
3
newPos
=
pos
;
newPos
-=
boxVectors
[
2
]
*
floor
(
newPos
[
2
]
/
boxVectors
[
2
][
2
]);
newPos
-=
boxVectors
[
1
]
*
floor
(
newPos
[
1
]
/
boxVectors
[
1
][
1
]);
newPos
-=
boxVectors
[
0
]
*
floor
(
newPos
[
0
]
/
boxVectors
[
0
][
0
]);
...
...
@@ -94,9 +94,9 @@ void ReferenceMonteCarloBarostat::applyBarostat(vector<RealVec>& atomPositions,
newPos
[
0
]
*=
scaleX
;
newPos
[
1
]
*=
scaleY
;
newPos
[
2
]
*=
scaleZ
;
Real
Vec
offset
=
newPos
-
pos
;
Vec
3
offset
=
newPos
-
pos
;
for
(
int
j
=
0
;
j
<
(
int
)
molecules
[
i
].
size
();
j
++
)
{
Real
Vec
&
atomPos
=
atomPositions
[
molecules
[
i
][
j
]];
Vec
3
&
atomPos
=
atomPositions
[
molecules
[
i
][
j
]];
atomPos
+=
offset
;
}
}
...
...
@@ -110,7 +110,7 @@ void ReferenceMonteCarloBarostat::applyBarostat(vector<RealVec>& atomPositions,
--------------------------------------------------------------------------------------- */
void
ReferenceMonteCarloBarostat
::
restorePositions
(
vector
<
Real
Vec
>&
atomPositions
)
{
void
ReferenceMonteCarloBarostat
::
restorePositions
(
vector
<
Vec
3
>&
atomPositions
)
{
int
numAtoms
=
savedAtomPositions
[
0
].
size
();
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
...
...
platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp
View file @
047934e2
...
...
@@ -13,8 +13,8 @@ namespace OpenMM {
typedef
std
::
vector
<
AtomIndex
>
AtomList
;
// squared distance between two points
static
double
compPairDistanceSquared
(
const
Real
Vec
&
pos1
,
const
Real
Vec
&
pos2
,
const
Real
Vec
*
periodicBoxVectors
,
bool
usePeriodic
)
{
Real
Vec
diff
=
pos2
-
pos1
;
static
double
compPairDistanceSquared
(
const
Vec
3
&
pos1
,
const
Vec
3
&
pos2
,
const
Vec
3
*
periodicBoxVectors
,
bool
usePeriodic
)
{
Vec
3
diff
=
pos2
-
pos1
;
if
(
usePeriodic
)
{
diff
-=
periodicBoxVectors
[
2
]
*
floor
(
diff
[
2
]
/
periodicBoxVectors
[
2
][
2
]
+
0.5
);
diff
-=
periodicBoxVectors
[
1
]
*
floor
(
diff
[
1
]
/
periodicBoxVectors
[
1
][
1
]
+
0.5
);
...
...
@@ -30,7 +30,7 @@ void OPENMM_EXPORT computeNeighborListNaive(
int
nAtoms
,
const
AtomLocationList
&
atomLocations
,
const
vector
<
set
<
int
>
>&
exclusions
,
const
Real
Vec
*
periodicBoxVectors
,
const
Vec
3
*
periodicBoxVectors
,
bool
usePeriodic
,
double
maxDistance
,
double
minDistance
,
...
...
@@ -78,13 +78,13 @@ public:
};
typedef
std
::
pair
<
const
Real
Vec
*
,
AtomIndex
>
VoxelItem
;
typedef
std
::
pair
<
const
Vec
3
*
,
AtomIndex
>
VoxelItem
;
typedef
std
::
vector
<
VoxelItem
>
Voxel
;
class
VoxelHash
{
public:
VoxelHash
(
double
vsx
,
double
vsy
,
double
vsz
,
const
Real
Vec
*
periodicBoxVectors
,
bool
usePeriodic
)
:
VoxelHash
(
double
vsx
,
double
vsy
,
double
vsz
,
const
Vec
3
*
periodicBoxVectors
,
bool
usePeriodic
)
:
voxelSizeX
(
vsx
),
voxelSizeY
(
vsy
),
voxelSizeZ
(
vsz
),
periodicBoxVectors
(
periodicBoxVectors
),
usePeriodic
(
usePeriodic
)
{
if
(
usePeriodic
)
{
nx
=
(
int
)
floor
(
periodicBoxVectors
[
0
][
0
]
/
voxelSizeX
+
0.5
);
...
...
@@ -96,7 +96,7 @@ public:
}
}
void
insert
(
const
AtomIndex
&
item
,
const
Real
Vec
&
location
)
void
insert
(
const
AtomIndex
&
item
,
const
Vec
3
&
location
)
{
VoxelIndex
voxelIndex
=
getVoxelIndex
(
location
);
if
(
voxelMap
.
find
(
voxelIndex
)
==
voxelMap
.
end
())
...
...
@@ -106,8 +106,8 @@ public:
}
VoxelIndex
getVoxelIndex
(
const
Real
Vec
&
location
)
const
{
Real
Vec
r
=
location
;
VoxelIndex
getVoxelIndex
(
const
Vec
3
&
location
)
const
{
Vec
3
r
=
location
;
if
(
usePeriodic
)
{
r
-=
periodicBoxVectors
[
2
]
*
floor
(
r
[
2
]
/
periodicBoxVectors
[
2
][
2
]);
r
-=
periodicBoxVectors
[
1
]
*
floor
(
r
[
1
]
/
periodicBoxVectors
[
1
][
1
]);
...
...
@@ -138,7 +138,7 @@ public:
assert
(
voxelSizeZ
>
0
);
const
AtomIndex
atomI
=
referencePoint
.
second
;
const
Real
Vec
&
locationI
=
*
referencePoint
.
first
;
const
Vec
3
&
locationI
=
*
referencePoint
.
first
;
double
maxDistanceSquared
=
maxDistance
*
maxDistance
;
double
minDistanceSquared
=
minDistance
*
minDistance
;
...
...
@@ -187,7 +187,7 @@ public:
for
(
Voxel
::
const_iterator
itemIter
=
voxel
.
begin
();
itemIter
!=
voxel
.
end
();
++
itemIter
)
{
const
AtomIndex
atomJ
=
itemIter
->
second
;
const
Real
Vec
&
locationJ
=
*
itemIter
->
first
;
const
Vec
3
&
locationJ
=
*
itemIter
->
first
;
// Ignore self hits
if
(
atomI
==
atomJ
)
continue
;
...
...
@@ -211,7 +211,7 @@ public:
private:
double
voxelSizeX
,
voxelSizeY
,
voxelSizeZ
;
int
nx
,
ny
,
nz
;
const
Real
Vec
*
periodicBoxVectors
;
const
Vec
3
*
periodicBoxVectors
;
const
bool
usePeriodic
;
std
::
map
<
VoxelIndex
,
Voxel
>
voxelMap
;
};
...
...
@@ -223,7 +223,7 @@ void OPENMM_EXPORT computeNeighborListVoxelHash(
int
nAtoms
,
const
AtomLocationList
&
atomLocations
,
const
vector
<
set
<
int
>
>&
exclusions
,
const
Real
Vec
*
periodicBoxVectors
,
const
Vec
3
*
periodicBoxVectors
,
bool
usePeriodic
,
double
maxDistance
,
double
minDistance
,
...
...
@@ -244,7 +244,7 @@ void OPENMM_EXPORT computeNeighborListVoxelHash(
for
(
AtomIndex
atomJ
=
0
;
atomJ
<
(
AtomIndex
)
nAtoms
;
++
atomJ
)
// use "j", because j > i for pairs
{
// 1) Find other atoms that are close to this one
const
Real
Vec
&
location
=
atomLocations
[
atomJ
];
const
Vec
3
&
location
=
atomLocations
[
atomJ
];
voxelHash
.
getNeighbors
(
neighborList
,
VoxelItem
(
&
location
,
atomJ
),
...
...
platforms/reference/src/SimTKReference/ReferenceObc.cpp
View file @
047934e2
...
...
@@ -111,7 +111,7 @@ void ReferenceObc::setIncludeAceApproximation(int includeAceApproximation) {
--------------------------------------------------------------------------------------- */
vector
<
RealOpenMM
>&
ReferenceObc
::
getObcChain
()
{
vector
<
double
>&
ReferenceObc
::
getObcChain
()
{
return
_obcChain
;
}
...
...
@@ -127,30 +127,19 @@ vector<RealOpenMM>& ReferenceObc::getObcChain() {
--------------------------------------------------------------------------------------- */
void
ReferenceObc
::
computeBornRadii
(
const
vector
<
Real
Vec
>&
atomCoordinates
,
vector
<
RealOpenMM
>&
bornRadii
)
{
void
ReferenceObc
::
computeBornRadii
(
const
vector
<
Vec
3
>&
atomCoordinates
,
vector
<
double
>&
bornRadii
)
{
// ---------------------------------------------------------------------------------------
static
const
RealOpenMM
zero
=
static_cast
<
RealOpenMM
>
(
0.0
);
static
const
RealOpenMM
one
=
static_cast
<
RealOpenMM
>
(
1.0
);
static
const
RealOpenMM
two
=
static_cast
<
RealOpenMM
>
(
2.0
);
static
const
RealOpenMM
three
=
static_cast
<
RealOpenMM
>
(
3.0
);
static
const
RealOpenMM
half
=
static_cast
<
RealOpenMM
>
(
0.5
);
static
const
RealOpenMM
fourth
=
static_cast
<
RealOpenMM
>
(
0.25
);
// ---------------------------------------------------------------------------------------
ObcParameters
*
obcParameters
=
getObcParameters
();
ObcParameters
*
obcParameters
=
getObcParameters
();
int
numberOfAtoms
=
obcParameters
->
getNumberOfAtoms
();
const
vector
<
double
>&
atomicRadii
=
obcParameters
->
getAtomicRadii
();
const
vector
<
double
>&
scaledRadiusFactor
=
obcParameters
->
getScaledRadiusFactors
();
vector
<
double
>&
obcChain
=
getObcChain
();
int
numberOfAtoms
=
obcParameters
->
getNumberOfAtoms
();
const
vector
<
RealOpenMM
>&
atomicRadii
=
obcParameters
->
getAtomicRadii
();
const
vector
<
RealOpenMM
>&
scaledRadiusFactor
=
obcParameters
->
getScaledRadiusFactors
();
vector
<
RealOpenMM
>&
obcChain
=
getObcChain
();
RealOpenMM
dielectricOffset
=
obcParameters
->
getDielectricOffset
();
RealOpenMM
alphaObc
=
obcParameters
->
getAlphaObc
();
RealOpenMM
betaObc
=
obcParameters
->
getBetaObc
();
RealOpenMM
gammaObc
=
obcParameters
->
getGammaObc
();
double
dielectricOffset
=
obcParameters
->
getDielectricOffset
();
double
alphaObc
=
obcParameters
->
getAlphaObc
();
double
betaObc
=
obcParameters
->
getBetaObc
();
double
gammaObc
=
obcParameters
->
getGammaObc
();
// ---------------------------------------------------------------------------------------
...
...
@@ -158,11 +147,11 @@ void ReferenceObc::computeBornRadii(const vector<RealVec>& atomCoordinates, vect
for
(
int
atomI
=
0
;
atomI
<
numberOfAtoms
;
atomI
++
)
{
RealOpenMM
radiusI
=
atomicRadii
[
atomI
];
RealOpenMM
offsetRadiusI
=
radiusI
-
dielectricOffset
;
double
radiusI
=
atomicRadii
[
atomI
];
double
offsetRadiusI
=
radiusI
-
dielectricOffset
;
RealOpenMM
radiusIInverse
=
one
/
offsetRadiusI
;
RealOpenMM
sum
=
zero
;
double
radiusIInverse
=
1.0
/
offsetRadiusI
;
double
sum
=
0.0
;
// HCT code
...
...
@@ -170,38 +159,38 @@ void ReferenceObc::computeBornRadii(const vector<RealVec>& atomCoordinates, vect
if
(
atomJ
!=
atomI
)
{
RealOpenMM
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
double
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
if
(
_obcParameters
->
getPeriodic
())
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atomI
],
atomCoordinates
[
atomJ
],
_obcParameters
->
getPeriodicBox
(),
deltaR
);
else
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomI
],
atomCoordinates
[
atomJ
],
deltaR
);
RealOpenMM
r
=
deltaR
[
ReferenceForce
::
RIndex
];
double
r
=
deltaR
[
ReferenceForce
::
RIndex
];
if
(
_obcParameters
->
getUseCutoff
()
&&
r
>
_obcParameters
->
getCutoffDistance
())
continue
;
RealOpenMM
offsetRadiusJ
=
atomicRadii
[
atomJ
]
-
dielectricOffset
;
RealOpenMM
scaledRadiusJ
=
offsetRadiusJ
*
scaledRadiusFactor
[
atomJ
];
RealOpenMM
rScaledRadiusJ
=
r
+
scaledRadiusJ
;
double
offsetRadiusJ
=
atomicRadii
[
atomJ
]
-
dielectricOffset
;
double
scaledRadiusJ
=
offsetRadiusJ
*
scaledRadiusFactor
[
atomJ
];
double
rScaledRadiusJ
=
r
+
scaledRadiusJ
;
if
(
offsetRadiusI
<
rScaledRadiusJ
)
{
RealOpenMM
rInverse
=
one
/
r
;
RealOpenMM
l_ij
=
offsetRadiusI
>
FABS
(
r
-
scaledRadiusJ
)
?
offsetRadiusI
:
FABS
(
r
-
scaledRadiusJ
);
l_ij
=
one
/
l_ij
;
double
rInverse
=
1.0
/
r
;
double
l_ij
=
offsetRadiusI
>
fabs
(
r
-
scaledRadiusJ
)
?
offsetRadiusI
:
fabs
(
r
-
scaledRadiusJ
);
l_ij
=
1.0
/
l_ij
;
RealOpenMM
u_ij
=
one
/
rScaledRadiusJ
;
double
u_ij
=
1.0
/
rScaledRadiusJ
;
RealOpenMM
l_ij2
=
l_ij
*
l_ij
;
RealOpenMM
u_ij2
=
u_ij
*
u_ij
;
double
l_ij2
=
l_ij
*
l_ij
;
double
u_ij2
=
u_ij
*
u_ij
;
RealOpenMM
ratio
=
LN
((
u_ij
/
l_ij
));
RealOpenMM
term
=
l_ij
-
u_ij
+
fourth
*
r
*
(
u_ij2
-
l_ij2
)
+
(
half
*
rInverse
*
ratio
)
+
(
fourth
*
scaledRadiusJ
*
scaledRadiusJ
*
rInverse
)
*
(
l_ij2
-
u_ij2
);
double
ratio
=
log
((
u_ij
/
l_ij
));
double
term
=
l_ij
-
u_ij
+
0.25
*
r
*
(
u_ij2
-
l_ij2
)
+
(
0.5
*
rInverse
*
ratio
)
+
(
0.25
*
scaledRadiusJ
*
scaledRadiusJ
*
rInverse
)
*
(
l_ij2
-
u_ij2
);
// this case (atom i completely inside atom j) is not considered in the original paper
// Jay Ponder and the authors of Tinker recognized this and
// worked out the details
if
(
offsetRadiusI
<
(
scaledRadiusJ
-
r
))
{
term
+=
two
*
(
radiusIInverse
-
l_ij
);
term
+=
2.0
*
(
radiusIInverse
-
l_ij
);
}
sum
+=
term
;
...
...
@@ -211,15 +200,15 @@ void ReferenceObc::computeBornRadii(const vector<RealVec>& atomCoordinates, vect
// OBC-specific code (Eqs. 6-8 in paper)
sum
*=
half
*
offsetRadiusI
;
RealOpenMM
sum2
=
sum
*
sum
;
RealOpenMM
sum3
=
sum
*
sum2
;
RealOpenMM
tanhSum
=
TANH
(
alphaObc
*
sum
-
betaObc
*
sum2
+
gammaObc
*
sum3
);
sum
*=
0.5
*
offsetRadiusI
;
double
sum2
=
sum
*
sum
;
double
sum3
=
sum
*
sum2
;
double
tanhSum
=
tanh
(
alphaObc
*
sum
-
betaObc
*
sum2
+
gammaObc
*
sum3
);
bornRadii
[
atomI
]
=
one
/
(
one
/
offsetRadiusI
-
tanhSum
/
radiusI
);
bornRadii
[
atomI
]
=
1.0
/
(
1.0
/
offsetRadiusI
-
tanhSum
/
radiusI
);
obcChain
[
atomI
]
=
offsetRadiusI
*
(
alphaObc
-
two
*
betaObc
*
sum
+
three
*
gammaObc
*
sum2
);
obcChain
[
atomI
]
=
(
one
-
tanhSum
*
tanhSum
)
*
obcChain
[
atomI
]
/
radiusI
;
obcChain
[
atomI
]
=
offsetRadiusI
*
(
alphaObc
-
2.0
*
betaObc
*
sum
+
3.0
*
gammaObc
*
sum2
);
obcChain
[
atomI
]
=
(
1.0
-
tanhSum
*
tanhSum
)
*
obcChain
[
atomI
]
/
radiusI
;
}
}
...
...
@@ -236,24 +225,16 @@ void ReferenceObc::computeBornRadii(const vector<RealVec>& atomCoordinates, vect
--------------------------------------------------------------------------------------- */
void
ReferenceObc
::
computeAceNonPolarForce
(
const
ObcParameters
*
obcParameters
,
const
vector
<
RealOpenMM
>&
bornRadii
,
RealOpenMM
*
energy
,
vector
<
RealOpenMM
>&
forces
)
const
{
// ---------------------------------------------------------------------------------------
static
const
RealOpenMM
zero
=
static_cast
<
RealOpenMM
>
(
0.0
);
static
const
RealOpenMM
minusSix
=
-
6.0
;
static
const
RealOpenMM
six
=
static_cast
<
RealOpenMM
>
(
6.0
);
// ---------------------------------------------------------------------------------------
const
vector
<
double
>&
bornRadii
,
double
*
energy
,
vector
<
double
>&
forces
)
const
{
// compute the nonpolar solvation via ACE approximation
const
RealOpenMM
probeRadius
=
obcParameters
->
getProbeRadius
();
const
RealOpenMM
surfaceAreaFactor
=
obcParameters
->
getPi4Asolv
();
const
double
probeRadius
=
obcParameters
->
getProbeRadius
();
const
double
surfaceAreaFactor
=
obcParameters
->
getPi4Asolv
();
const
vector
<
RealOpenMM
>&
atomicRadii
=
obcParameters
->
getAtomicRadii
();
const
vector
<
double
>&
atomicRadii
=
obcParameters
->
getAtomicRadii
();
int
numberOfAtoms
=
obcParameters
->
getNumberOfAtoms
();
// the original ACE equation is based on Eq.2 of
...
...
@@ -271,12 +252,12 @@ void ReferenceObc::computeAceNonPolarForce(const ObcParameters* obcParameters,
// no paper to cite.
for
(
int
atomI
=
0
;
atomI
<
numberOfAtoms
;
atomI
++
)
{
if
(
bornRadii
[
atomI
]
>
zero
)
{
RealOpenMM
r
=
atomicRadii
[
atomI
]
+
probeRadius
;
RealOpenMM
ratio6
=
POW
(
atomicRadii
[
atomI
]
/
bornRadii
[
atomI
],
six
);
RealOpenMM
saTerm
=
surfaceAreaFactor
*
r
*
r
*
ratio6
;
if
(
bornRadii
[
atomI
]
>
0.0
)
{
double
r
=
atomicRadii
[
atomI
]
+
probeRadius
;
double
ratio6
=
pow
(
atomicRadii
[
atomI
]
/
bornRadii
[
atomI
],
6.0
);
double
saTerm
=
surfaceAreaFactor
*
r
*
r
*
ratio6
;
*
energy
+=
saTerm
;
forces
[
atomI
]
+
=
minusSix
*
saTerm
/
bornRadii
[
atomI
];
forces
[
atomI
]
-
=
6.0
*
saTerm
/
bornRadii
[
atomI
];
}
}
}
...
...
@@ -293,44 +274,33 @@ void ReferenceObc::computeAceNonPolarForce(const ObcParameters* obcParameters,
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceObc
::
computeBornEnergyForces
(
const
vector
<
RealVec
>&
atomCoordinates
,
const
vector
<
RealOpenMM
>&
partialCharges
,
vector
<
RealVec
>&
inputForces
)
{
// ---------------------------------------------------------------------------------------
static
const
RealOpenMM
zero
=
static_cast
<
RealOpenMM
>
(
0.0
);
static
const
RealOpenMM
one
=
static_cast
<
RealOpenMM
>
(
1.0
);
static
const
RealOpenMM
two
=
static_cast
<
RealOpenMM
>
(
2.0
);
static
const
RealOpenMM
three
=
static_cast
<
RealOpenMM
>
(
3.0
);
static
const
RealOpenMM
four
=
static_cast
<
RealOpenMM
>
(
4.0
);
static
const
RealOpenMM
half
=
static_cast
<
RealOpenMM
>
(
0.5
);
static
const
RealOpenMM
fourth
=
static_cast
<
RealOpenMM
>
(
0.25
);
static
const
RealOpenMM
eighth
=
static_cast
<
RealOpenMM
>
(
0.125
);
double
ReferenceObc
::
computeBornEnergyForces
(
const
vector
<
Vec3
>&
atomCoordinates
,
const
vector
<
double
>&
partialCharges
,
vector
<
Vec3
>&
inputForces
)
{
// constants
const
int
numberOfAtoms
=
_obcParameters
->
getNumberOfAtoms
();
const
RealOpenMM
dielectricOffset
=
_obcParameters
->
getDielectricOffset
();
const
RealOpenMM
cutoffDistance
=
_obcParameters
->
getCutoffDistance
();
const
RealOpenMM
soluteDielectric
=
_obcParameters
->
getSoluteDielectric
();
const
RealOpenMM
solventDielectric
=
_obcParameters
->
getSolventDielectric
();
RealOpenMM
preFactor
;
if
(
soluteDielectric
!=
zero
&&
solventDielectric
!=
zero
)
preFactor
=
two
*
_obcParameters
->
getElectricConstant
()
*
((
one
/
soluteDielectric
)
-
(
one
/
solventDielectric
));
const
double
dielectricOffset
=
_obcParameters
->
getDielectricOffset
();
const
double
cutoffDistance
=
_obcParameters
->
getCutoffDistance
();
const
double
soluteDielectric
=
_obcParameters
->
getSoluteDielectric
();
const
double
solventDielectric
=
_obcParameters
->
getSolventDielectric
();
double
preFactor
;
if
(
soluteDielectric
!=
0.0
&&
solventDielectric
!=
0.0
)
preFactor
=
2.0
*
_obcParameters
->
getElectricConstant
()
*
((
1.0
/
soluteDielectric
)
-
(
1.0
/
solventDielectric
));
else
preFactor
=
zero
;
preFactor
=
0.0
;
// ---------------------------------------------------------------------------------------
// compute Born radii
vector
<
RealOpenMM
>
bornRadii
(
numberOfAtoms
);
vector
<
double
>
bornRadii
(
numberOfAtoms
);
computeBornRadii
(
atomCoordinates
,
bornRadii
);
// set energy/forces to zero
RealOpenMM
obcEnergy
=
zero
;
vector
<
RealOpenMM
>
bornForces
(
numberOfAtoms
,
0.0
);
double
obcEnergy
=
0.0
;
vector
<
double
>
bornForces
(
numberOfAtoms
,
0.0
);
// ---------------------------------------------------------------------------------------
...
...
@@ -346,10 +316,10 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector<RealVec>& atomCoor
for
(
int
atomI
=
0
;
atomI
<
numberOfAtoms
;
atomI
++
)
{
RealOpenMM
partialChargeI
=
preFactor
*
partialCharges
[
atomI
];
double
partialChargeI
=
preFactor
*
partialCharges
[
atomI
];
for
(
int
atomJ
=
atomI
;
atomJ
<
numberOfAtoms
;
atomJ
++
)
{
RealOpenMM
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
double
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
if
(
_obcParameters
->
getPeriodic
())
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atomI
],
atomCoordinates
[
atomJ
],
_obcParameters
->
getPeriodicBox
(),
deltaR
);
else
...
...
@@ -357,24 +327,24 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector<RealVec>& atomCoor
if
(
_obcParameters
->
getUseCutoff
()
&&
deltaR
[
ReferenceForce
::
RIndex
]
>
cutoffDistance
)
continue
;
RealOpenMM
r2
=
deltaR
[
ReferenceForce
::
R2Index
];
RealOpenMM
deltaX
=
deltaR
[
ReferenceForce
::
XIndex
];
RealOpenMM
deltaY
=
deltaR
[
ReferenceForce
::
YIndex
];
RealOpenMM
deltaZ
=
deltaR
[
ReferenceForce
::
ZIndex
];
double
r2
=
deltaR
[
ReferenceForce
::
R2Index
];
double
deltaX
=
deltaR
[
ReferenceForce
::
XIndex
];
double
deltaY
=
deltaR
[
ReferenceForce
::
YIndex
];
double
deltaZ
=
deltaR
[
ReferenceForce
::
ZIndex
];
RealOpenMM
alpha2_ij
=
bornRadii
[
atomI
]
*
bornRadii
[
atomJ
];
RealOpenMM
D_ij
=
r2
/
(
four
*
alpha2_ij
);
double
alpha2_ij
=
bornRadii
[
atomI
]
*
bornRadii
[
atomJ
];
double
D_ij
=
r2
/
(
4.0
*
alpha2_ij
);
RealOpenMM
expTerm
=
EXP
(
-
D_ij
);
RealOpenMM
denominator2
=
r2
+
alpha2_ij
*
expTerm
;
RealOpenMM
denominator
=
SQRT
(
denominator2
);
double
expTerm
=
exp
(
-
D_ij
);
double
denominator2
=
r2
+
alpha2_ij
*
expTerm
;
double
denominator
=
sqrt
(
denominator2
);
RealOpenMM
Gpol
=
(
partialChargeI
*
partialCharges
[
atomJ
])
/
denominator
;
RealOpenMM
dGpol_dr
=
-
Gpol
*
(
one
-
fourth
*
expTerm
)
/
denominator2
;
double
Gpol
=
(
partialChargeI
*
partialCharges
[
atomJ
])
/
denominator
;
double
dGpol_dr
=
-
Gpol
*
(
1.0
-
0.25
*
expTerm
)
/
denominator2
;
RealOpenMM
dGpol_dalpha2_ij
=
-
half
*
Gpol
*
expTerm
*
(
one
+
D_ij
)
/
denominator2
;
double
dGpol_dalpha2_ij
=
-
0.5
*
Gpol
*
expTerm
*
(
1.0
+
D_ij
)
/
denominator2
;
RealOpenMM
energy
=
Gpol
;
double
energy
=
Gpol
;
if
(
atomI
!=
atomJ
)
{
...
...
@@ -396,7 +366,7 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector<RealVec>& atomCoor
inputForces
[
atomJ
][
2
]
-=
deltaZ
;
}
else
{
energy
*=
half
;
energy
*=
0.5
;
}
obcEnergy
+=
energy
;
...
...
@@ -409,13 +379,13 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector<RealVec>& atomCoor
// second main loop
const
vector
<
RealOpenMM
>&
obcChain
=
getObcChain
();
const
vector
<
RealOpenMM
>&
atomicRadii
=
_obcParameters
->
getAtomicRadii
();
const
vector
<
double
>&
obcChain
=
getObcChain
();
const
vector
<
double
>&
atomicRadii
=
_obcParameters
->
getAtomicRadii
();
const
RealOpenMM
alphaObc
=
_obcParameters
->
getAlphaObc
();
const
RealOpenMM
betaObc
=
_obcParameters
->
getBetaObc
();
const
RealOpenMM
gammaObc
=
_obcParameters
->
getGammaObc
();
const
vector
<
RealOpenMM
>&
scaledRadiusFactor
=
_obcParameters
->
getScaledRadiusFactors
();
const
double
alphaObc
=
_obcParameters
->
getAlphaObc
();
const
double
betaObc
=
_obcParameters
->
getBetaObc
();
const
double
gammaObc
=
_obcParameters
->
getGammaObc
();
const
vector
<
double
>&
scaledRadiusFactor
=
_obcParameters
->
getScaledRadiusFactors
();
// compute factor that depends only on the outer loop index
...
...
@@ -427,14 +397,14 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector<RealVec>& atomCoor
// radius w/ dielectric offset applied
RealOpenMM
radiusI
=
atomicRadii
[
atomI
];
RealOpenMM
offsetRadiusI
=
radiusI
-
dielectricOffset
;
double
radiusI
=
atomicRadii
[
atomI
];
double
offsetRadiusI
=
radiusI
-
dielectricOffset
;
for
(
int
atomJ
=
0
;
atomJ
<
numberOfAtoms
;
atomJ
++
)
{
if
(
atomJ
!=
atomI
)
{
RealOpenMM
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
double
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
if
(
_obcParameters
->
getPeriodic
())
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atomI
],
atomCoordinates
[
atomJ
],
_obcParameters
->
getPeriodicBox
(),
deltaR
);
else
...
...
@@ -442,39 +412,39 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector<RealVec>& atomCoor
if
(
_obcParameters
->
getUseCutoff
()
&&
deltaR
[
ReferenceForce
::
RIndex
]
>
cutoffDistance
)
continue
;
RealOpenMM
deltaX
=
deltaR
[
ReferenceForce
::
XIndex
];
RealOpenMM
deltaY
=
deltaR
[
ReferenceForce
::
YIndex
];
RealOpenMM
deltaZ
=
deltaR
[
ReferenceForce
::
ZIndex
];
RealOpenMM
r
=
deltaR
[
ReferenceForce
::
RIndex
];
double
deltaX
=
deltaR
[
ReferenceForce
::
XIndex
];
double
deltaY
=
deltaR
[
ReferenceForce
::
YIndex
];
double
deltaZ
=
deltaR
[
ReferenceForce
::
ZIndex
];
double
r
=
deltaR
[
ReferenceForce
::
RIndex
];
// radius w/ dielectric offset applied
RealOpenMM
offsetRadiusJ
=
atomicRadii
[
atomJ
]
-
dielectricOffset
;
double
offsetRadiusJ
=
atomicRadii
[
atomJ
]
-
dielectricOffset
;
RealOpenMM
scaledRadiusJ
=
offsetRadiusJ
*
scaledRadiusFactor
[
atomJ
];
RealOpenMM
scaledRadiusJ2
=
scaledRadiusJ
*
scaledRadiusJ
;
RealOpenMM
rScaledRadiusJ
=
r
+
scaledRadiusJ
;
double
scaledRadiusJ
=
offsetRadiusJ
*
scaledRadiusFactor
[
atomJ
];
double
scaledRadiusJ2
=
scaledRadiusJ
*
scaledRadiusJ
;
double
rScaledRadiusJ
=
r
+
scaledRadiusJ
;
// dL/dr & dU/dr are zero (this can be shown analytically)
// removed from calculation
if
(
offsetRadiusI
<
rScaledRadiusJ
)
{
RealOpenMM
l_ij
=
offsetRadiusI
>
FABS
(
r
-
scaledRadiusJ
)
?
offsetRadiusI
:
FABS
(
r
-
scaledRadiusJ
);
l_ij
=
one
/
l_ij
;
double
l_ij
=
offsetRadiusI
>
fabs
(
r
-
scaledRadiusJ
)
?
offsetRadiusI
:
fabs
(
r
-
scaledRadiusJ
);
l_ij
=
1.0
/
l_ij
;
RealOpenMM
u_ij
=
one
/
rScaledRadiusJ
;
double
u_ij
=
1.0
/
rScaledRadiusJ
;
RealOpenMM
l_ij2
=
l_ij
*
l_ij
;
double
l_ij2
=
l_ij
*
l_ij
;
RealOpenMM
u_ij2
=
u_ij
*
u_ij
;
double
u_ij2
=
u_ij
*
u_ij
;
RealOpenMM
rInverse
=
one
/
r
;
RealOpenMM
r2Inverse
=
rInverse
*
rInverse
;
double
rInverse
=
1.0
/
r
;
double
r2Inverse
=
rInverse
*
rInverse
;
RealOpenMM
t3
=
eighth
*
(
one
+
scaledRadiusJ2
*
r2Inverse
)
*
(
l_ij2
-
u_ij2
)
+
fourth
*
LN
(
u_ij
/
l_ij
)
*
r2Inverse
;
double
t3
=
0.125
*
(
1.0
+
scaledRadiusJ2
*
r2Inverse
)
*
(
l_ij2
-
u_ij2
)
+
0.25
*
log
(
u_ij
/
l_ij
)
*
r2Inverse
;
RealOpenMM
de
=
bornForces
[
atomI
]
*
t3
*
rInverse
;
double
de
=
bornForces
[
atomI
]
*
t3
*
rInverse
;
deltaX
*=
de
;
deltaY
*=
de
;
...
...
platforms/reference/src/SimTKReference/ReferencePME.cpp
View file @
047934e2
...
...
@@ -35,6 +35,7 @@
#include "ReferencePME.h"
#include "fftpack.h"
#include "SimTKOpenMMRealType.h"
using
std
::
vector
;
...
...
@@ -45,7 +46,7 @@ namespace OpenMM {
struct
pme
{
int
natoms
;
RealOpenMM
ewaldcoeff
;
double
ewaldcoeff
;
t_complex
*
grid
;
/* Memory for the grid we spread charges on.
* Element (i,j,k) is accessed as:
...
...
@@ -57,9 +58,9 @@ struct pme
int
order
;
/* PME interpolation order. Almost always 4 */
/* Data for bspline interpolation, see the Essman PME paper */
RealOpenMM
*
bsplines_moduli
[
3
];
/* 3 pointers, to x/y/z bspline moduli, each of length ngrid[x/y/z] */
RealOpenMM
*
bsplines_theta
[
3
];
/* each of x/y/z has length order*natoms */
RealOpenMM
*
bsplines_dtheta
[
3
];
/* each of x/y/z has length order*natoms */
double
*
bsplines_moduli
[
3
];
/* 3 pointers, to x/y/z bspline moduli, each of length ngrid[x/y/z] */
double
*
bsplines_theta
[
3
];
/* each of x/y/z has length order*natoms */
double
*
bsplines_dtheta
[
3
];
/* each of x/y/z has length order*natoms */
ivec
*
particleindex
;
/* Array of length natoms. Each element is
* an ivec (3 ints) that specify the grid
...
...
@@ -85,7 +86,7 @@ struct pme
* the central cell, i.e., in this case we would assume all coordinates fall in -10 nm < x,y,z < 20 nm.
*/
RealOpenMM
epsilon_r
;
/* Dielectric coefficient to use, typically 1.0 */
double
epsilon_r
;
/* Dielectric coefficient to use, typically 1.0 */
};
...
...
@@ -101,25 +102,25 @@ pme_calculate_bsplines_moduli(pme_t pme)
int
i
,
j
,
k
,
l
,
d
;
int
order
;
int
ndata
;
RealOpenMM
*
data
;
RealOpenMM
*
ddata
;
RealOpenMM
*
bsplines_data
;
RealOpenMM
div
;
RealOpenMM
sc
,
ss
,
arg
;
double
*
data
;
double
*
ddata
;
double
*
bsplines_data
;
double
div
;
double
sc
,
ss
,
arg
;
nmax
=
0
;
for
(
d
=
0
;
d
<
3
;
d
++
)
{
nmax
=
(
pme
->
ngrid
[
d
]
>
nmax
)
?
pme
->
ngrid
[
d
]
:
nmax
;
pme
->
bsplines_moduli
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme
->
ngrid
[
d
]);
pme
->
bsplines_moduli
[
d
]
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
pme
->
ngrid
[
d
]);
}
order
=
pme
->
order
;
/* temp storage in this routine */
data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
ddata
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
bsplines_data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
nmax
);
data
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
order
);
ddata
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
order
);
bsplines_data
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
nmax
);
data
[
order
-
1
]
=
0
;
data
[
1
]
=
0
;
...
...
@@ -127,7 +128,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
for
(
k
=
3
;
k
<
order
;
k
++
)
{
div
=
(
RealOpenMM
)
(
1.0
/
(
k
-
1.0
)
)
;
div
=
1.0
/
(
k
-
1.0
);
data
[
k
-
1
]
=
0
;
for
(
l
=
1
;
l
<
(
k
-
1
);
l
++
)
{
...
...
@@ -143,7 +144,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
ddata
[
k
]
=
data
[
k
-
1
]
-
data
[
k
];
}
div
=
(
RealOpenMM
)
(
1.0
/
(
order
-
1
)
)
;
div
=
1.0
/
(
order
-
1
);
data
[
order
-
1
]
=
0
;
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
...
...
@@ -170,7 +171,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
sc
=
ss
=
0
;
for
(
j
=
0
;
j
<
ndata
;
j
++
)
{
arg
=
(
RealOpenMM
)
((
2.0
*
M_PI
*
i
*
j
)
/
ndata
)
;
arg
=
(
2.0
*
M_PI
*
i
*
j
)
/
ndata
;
sc
+=
bsplines_data
[
j
]
*
cos
(
arg
);
ss
+=
bsplines_data
[
j
]
*
sin
(
arg
);
}
...
...
@@ -192,25 +193,25 @@ pme_calculate_bsplines_moduli(pme_t pme)
}
static
void
invert_box_vectors
(
const
Real
Vec
boxVectors
[
3
],
Real
Vec
recipBoxVectors
[
3
])
static
void
invert_box_vectors
(
const
Vec
3
boxVectors
[
3
],
Vec
3
recipBoxVectors
[
3
])
{
RealOpenMM
determinant
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
double
determinant
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
assert
(
determinant
>
0
);
RealOpenMM
scale
=
1.0
/
determinant
;
recipBoxVectors
[
0
]
=
Real
Vec
(
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
],
0
,
0
)
*
scale
;
recipBoxVectors
[
1
]
=
Real
Vec
(
-
boxVectors
[
1
][
0
]
*
boxVectors
[
2
][
2
],
boxVectors
[
0
][
0
]
*
boxVectors
[
2
][
2
],
0
)
*
scale
;
recipBoxVectors
[
2
]
=
Real
Vec
(
boxVectors
[
1
][
0
]
*
boxVectors
[
2
][
1
]
-
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
0
],
-
boxVectors
[
0
][
0
]
*
boxVectors
[
2
][
1
],
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
])
*
scale
;
double
scale
=
1.0
/
determinant
;
recipBoxVectors
[
0
]
=
Vec
3
(
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
],
0
,
0
)
*
scale
;
recipBoxVectors
[
1
]
=
Vec
3
(
-
boxVectors
[
1
][
0
]
*
boxVectors
[
2
][
2
],
boxVectors
[
0
][
0
]
*
boxVectors
[
2
][
2
],
0
)
*
scale
;
recipBoxVectors
[
2
]
=
Vec
3
(
boxVectors
[
1
][
0
]
*
boxVectors
[
2
][
1
]
-
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
0
],
-
boxVectors
[
0
][
0
]
*
boxVectors
[
2
][
1
],
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
])
*
scale
;
}
static
void
pme_update_grid_index_and_fraction
(
pme_t
pme
,
const
vector
<
Real
Vec
>&
atomCoordinates
,
const
Real
Vec
periodicBoxVectors
[
3
],
const
Real
Vec
recipBoxVectors
[
3
])
const
vector
<
Vec
3
>&
atomCoordinates
,
const
Vec
3
periodicBoxVectors
[
3
],
const
Vec
3
recipBoxVectors
[
3
])
{
int
i
;
int
d
;
RealOpenMM
t
;
double
t
;
int
ti
;
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
...
...
@@ -251,7 +252,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
* numerical problems, so this shouldnt cause any problems.
* (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!)
*/
Real
Vec
coord
=
atomCoordinates
[
i
];
Vec
3
coord
=
atomCoordinates
[
i
];
for
(
d
=
0
;
d
<
3
;
d
++
)
{
t
=
coord
[
0
]
*
recipBoxVectors
[
0
][
d
]
+
coord
[
1
]
*
recipBoxVectors
[
1
][
d
]
+
coord
[
2
]
*
recipBoxVectors
[
2
][
d
];
...
...
@@ -275,9 +276,9 @@ pme_update_bsplines(pme_t pme)
{
int
i
,
j
,
k
,
l
;
int
order
;
RealOpenMM
dr
,
div
;
RealOpenMM
*
data
;
RealOpenMM
*
ddata
;
double
dr
,
div
;
double
*
data
;
double
*
ddata
;
order
=
pme
->
order
;
...
...
@@ -296,7 +297,7 @@ pme_update_bsplines(pme_t pme)
for
(
k
=
3
;
k
<
order
;
k
++
)
{
div
=
(
RealOpenMM
)
(
1.0
/
(
k
-
1.0
)
)
;
div
=
1.0
/
(
k
-
1.0
);
data
[
k
-
1
]
=
div
*
dr
*
data
[
k
-
2
];
for
(
l
=
1
;
l
<
(
k
-
1
);
l
++
)
{
...
...
@@ -313,7 +314,7 @@ pme_update_bsplines(pme_t pme)
ddata
[
k
]
=
data
[
k
-
1
]
-
data
[
k
];
}
div
=
(
RealOpenMM
)
(
1.0
/
(
order
-
1
)
)
;
div
=
1.0
/
(
order
-
1
);
data
[
order
-
1
]
=
div
*
dr
*
data
[
order
-
2
];
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
...
...
@@ -327,7 +328,7 @@ pme_update_bsplines(pme_t pme)
static
void
pme_grid_spread_charge
(
pme_t
pme
,
const
vector
<
RealOpenMM
>&
charges
)
pme_grid_spread_charge
(
pme_t
pme
,
const
vector
<
double
>&
charges
)
{
int
order
;
int
i
;
...
...
@@ -335,10 +336,10 @@ pme_grid_spread_charge(pme_t pme, const vector<RealOpenMM>& charges)
int
x0index
,
y0index
,
z0index
;
int
xindex
,
yindex
,
zindex
;
int
index
;
RealOpenMM
q
;
RealOpenMM
*
thetax
;
RealOpenMM
*
thetay
;
RealOpenMM
*
thetaz
;
double
q
;
double
*
thetax
;
double
*
thetay
;
double
*
thetaz
;
order
=
pme
->
order
;
...
...
@@ -407,24 +408,24 @@ pme_grid_spread_charge(pme_t pme, const vector<RealOpenMM>& charges)
static
void
pme_reciprocal_convolution
(
pme_t
pme
,
const
Real
Vec
periodicBoxVectors
[
3
],
const
Real
Vec
recipBoxVectors
[
3
],
RealOpenMM
*
energy
)
const
Vec
3
periodicBoxVectors
[
3
],
const
Vec
3
recipBoxVectors
[
3
],
double
*
energy
)
{
int
kx
,
ky
,
kz
;
int
nx
,
ny
,
nz
;
RealOpenMM
mx
,
my
,
mz
;
RealOpenMM
mhx
,
mhy
,
mhz
,
m2
;
RealOpenMM
one_4pi_eps
;
RealOpenMM
virxx
,
virxy
,
virxz
,
viryy
,
viryz
,
virzz
;
RealOpenMM
bx
,
by
,
bz
;
RealOpenMM
d1
,
d2
;
RealOpenMM
eterm
,
vfactor
,
struct2
,
ets2
;
RealOpenMM
esum
;
RealOpenMM
factor
;
RealOpenMM
denom
;
RealOpenMM
boxfactor
;
RealOpenMM
maxkx
,
maxky
,
maxkz
;
double
mx
,
my
,
mz
;
double
mhx
,
mhy
,
mhz
,
m2
;
double
one_4pi_eps
;
double
virxx
,
virxy
,
virxz
,
viryy
,
viryz
,
virzz
;
double
bx
,
by
,
bz
;
double
d1
,
d2
;
double
eterm
,
vfactor
,
struct2
,
ets2
;
double
esum
;
double
factor
;
double
denom
;
double
boxfactor
;
double
maxkx
,
maxky
,
maxkz
;
t_complex
*
ptr
;
...
...
@@ -432,9 +433,9 @@ pme_reciprocal_convolution(pme_t pme,
ny
=
pme
->
ngrid
[
1
];
nz
=
pme
->
ngrid
[
2
];
one_4pi_eps
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
/
pme
->
epsilon_r
)
;
factor
=
(
RealOpenMM
)
(
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
)
)
;
boxfactor
=
(
RealOpenMM
)
(
M_PI
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]
)
;
one_4pi_eps
=
ONE_4PI_EPS0
/
pme
->
epsilon_r
;
factor
=
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
);
boxfactor
=
M_PI
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
];
esum
=
0
;
virxx
=
0
;
...
...
@@ -444,21 +445,21 @@ pme_reciprocal_convolution(pme_t pme,
viryz
=
0
;
virzz
=
0
;
maxkx
=
(
RealOpenMM
)
(
(
nx
+
1
)
/
2
)
;
maxky
=
(
RealOpenMM
)
(
(
ny
+
1
)
/
2
)
;
maxkz
=
(
RealOpenMM
)
(
(
nz
+
1
)
/
2
)
;
maxkx
=
(
nx
+
1
)
/
2
;
maxky
=
(
ny
+
1
)
/
2
;
maxkz
=
(
nz
+
1
)
/
2
;
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
)
)
;
mx
=
(
kx
<
maxkx
)
?
kx
:
(
kx
-
nx
);
mhx
=
mx
*
recipBoxVectors
[
0
][
0
];
bx
=
boxfactor
*
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
)
)
;
my
=
(
ky
<
maxky
)
?
ky
:
(
ky
-
ny
);
mhy
=
mx
*
recipBoxVectors
[
1
][
0
]
+
my
*
recipBoxVectors
[
1
][
1
];
by
=
pme
->
bsplines_moduli
[
1
][
ky
];
...
...
@@ -478,7 +479,7 @@ pme_reciprocal_convolution(pme_t pme,
}
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
mz
=
(
RealOpenMM
)
(
(
kz
<
maxkz
)
?
kz
:
(
kz
-
nz
)
)
;
mz
=
(
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 */
...
...
@@ -509,15 +510,115 @@ pme_reciprocal_convolution(pme_t pme,
}
/* The factor 0.5 is nothing special, but it is better to have it here than inside the loop :-) */
*
energy
=
(
RealOpenMM
)
(
0.5
*
esum
);
*
energy
=
0.5
*
esum
;
}
static
void
dpme_reciprocal_convolution
(
pme_t
pme
,
const
Vec3
periodicBoxVectors
[
3
],
const
Vec3
recipBoxVectors
[
3
],
double
*
energy
)
{
int
kx
,
ky
,
kz
;
int
nx
,
ny
,
nz
;
double
mx
,
my
,
mz
;
double
mhx
,
mhy
,
mhz
,
m2
;
double
bx
,
by
,
bz
;
double
d1
,
d2
;
double
eterm
,
struct2
,
ets2
;
double
esum
;
double
denom
;
double
boxfactor
;
double
maxkx
,
maxky
,
maxkz
;
t_complex
*
ptr
;
nx
=
pme
->
ngrid
[
0
];
ny
=
pme
->
ngrid
[
1
];
nz
=
pme
->
ngrid
[
2
];
boxfactor
=
M_PI
*
sqrt
(
M_PI
)
/
(
6.0
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]);
esum
=
0
;
maxkx
=
(
nx
+
1
)
/
2
;
maxky
=
(
ny
+
1
)
/
2
;
maxkz
=
(
nz
+
1
)
/
2
;
double
bfac
=
M_PI
/
pme
->
ewaldcoeff
;
double
fac1
=
2.0
*
M_PI
*
M_PI
*
M_PI
*
sqrt
(
M_PI
);
double
fac2
=
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
;
double
fac3
=
-
2.0
*
pme
->
ewaldcoeff
*
M_PI
*
M_PI
;
double
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
=
((
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
=
((
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
=
((
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
=
-
esum
;
}
static
void
pme_grid_interpolate_force
(
pme_t
pme
,
const
Real
Vec
recipBoxVectors
[
3
],
const
vector
<
RealOpenMM
>&
charges
,
vector
<
Real
Vec
>&
forces
)
const
Vec
3
recipBoxVectors
[
3
],
const
vector
<
double
>&
charges
,
vector
<
Vec
3
>&
forces
)
{
int
i
;
int
ix
,
iy
,
iz
;
...
...
@@ -525,17 +626,17 @@ pme_grid_interpolate_force(pme_t pme,
int
xindex
,
yindex
,
zindex
;
int
index
;
int
order
;
RealOpenMM
q
;
RealOpenMM
*
thetax
;
RealOpenMM
*
thetay
;
RealOpenMM
*
thetaz
;
RealOpenMM
*
dthetax
;
RealOpenMM
*
dthetay
;
RealOpenMM
*
dthetaz
;
RealOpenMM
tx
,
ty
,
tz
;
RealOpenMM
dtx
,
dty
,
dtz
;
RealOpenMM
fx
,
fy
,
fz
;
RealOpenMM
gridvalue
;
double
q
;
double
*
thetax
;
double
*
thetay
;
double
*
thetaz
;
double
*
dthetax
;
double
*
dthetay
;
double
*
dthetaz
;
double
tx
,
ty
,
tz
;
double
dtx
,
dty
,
dtz
;
double
fx
,
fy
,
fz
;
double
gridvalue
;
int
nx
,
ny
,
nz
;
nx
=
pme
->
ngrid
[
0
];
...
...
@@ -617,11 +718,11 @@ pme_grid_interpolate_force(pme_t pme,
int
pme_init
(
pme_t
*
ppme
,
RealOpenMM
ewaldcoeff
,
double
ewaldcoeff
,
int
natoms
,
const
int
ngrid
[
3
],
const
int
ngrid
[
3
],
int
pme_order
,
RealOpenMM
epsilon_r
)
double
epsilon_r
)
{
pme_t
pme
;
int
d
;
...
...
@@ -636,8 +737,8 @@ pme_init(pme_t * ppme,
for
(
d
=
0
;
d
<
3
;
d
++
)
{
pme
->
ngrid
[
d
]
=
ngrid
[
d
];
pme
->
bsplines_theta
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme_order
*
natoms
);
pme
->
bsplines_dtheta
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme_order
*
natoms
);
pme
->
bsplines_theta
[
d
]
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
pme_order
*
natoms
);
pme
->
bsplines_dtheta
[
d
]
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
pme_order
*
natoms
);
}
pme
->
particlefraction
=
(
rvec
*
)
malloc
(
sizeof
(
rvec
)
*
natoms
);
...
...
@@ -661,15 +762,15 @@ pme_init(pme_t * ppme,
int
pme_exec
(
pme_t
pme
,
const
vector
<
Real
Vec
>&
atomCoordinates
,
vector
<
Real
Vec
>&
forces
,
const
vector
<
RealOpenMM
>&
charges
,
const
Real
Vec
periodicBoxVectors
[
3
],
RealOpenMM
*
energy
)
const
vector
<
Vec
3
>&
atomCoordinates
,
vector
<
Vec
3
>&
forces
,
const
vector
<
double
>&
charges
,
const
Vec
3
periodicBoxVectors
[
3
],
double
*
energy
)
{
/* Routine is called with coordinates in x, a box, and charges in q */
Real
Vec
recipBoxVectors
[
3
];
Vec
3
recipBoxVectors
[
3
];
invert_box_vectors
(
periodicBoxVectors
,
recipBoxVectors
);
/* Before we can do the actual interpolation, we need to recalculate and update
...
...
@@ -704,6 +805,49 @@ int pme_exec(pme_t pme,
}
int
pme_exec_dpme
(
pme_t
pme
,
const
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
forces
,
const
vector
<
double
>&
c6s
,
const
Vec3
periodicBoxVectors
[
3
],
double
*
energy
)
{
/* Routine is called with coordinates in x, a box, and charges in q */
Vec3
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
pme_destroy
(
pme_t
pme
)
...
...
platforms/reference/src/SimTKReference/ReferencePairIxn.cpp
View file @
047934e2
...
...
@@ -38,13 +38,6 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferencePairIxn
::
ReferencePairIxn
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferencePairIxn::ReferencePairIxn";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
...
...
@@ -54,11 +47,4 @@ ReferencePairIxn::ReferencePairIxn() {
--------------------------------------------------------------------------------------- */
ReferencePairIxn
::~
ReferencePairIxn
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferencePairIxn::~ReferencePairIxn";
// ---------------------------------------------------------------------------------------
}
platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp
View file @
047934e2
...
...
@@ -50,7 +50,7 @@ ReferenceProperDihedralBond::ReferenceProperDihedralBond() : usePeriodic(false)
ReferenceProperDihedralBond
::~
ReferenceProperDihedralBond
()
{
}
void
ReferenceProperDihedralBond
::
setPeriodic
(
OpenMM
::
Real
Vec
*
vectors
)
{
void
ReferenceProperDihedralBond
::
setPeriodic
(
OpenMM
::
Vec
3
*
vectors
)
{
usePeriodic
=
true
;
boxVectors
[
0
]
=
vectors
[
0
];
boxVectors
[
1
]
=
vectors
[
1
];
...
...
@@ -72,28 +72,13 @@ void ReferenceProperDihedralBond::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */
void
ReferenceProperDihedralBond
::
calculateBondIxn
(
int
*
atomIndices
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
*
parameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
totalEnergy
,
double
*
energyParamDerivs
)
{
vector
<
Vec3
>&
atomCoordinates
,
double
*
parameters
,
vector
<
Vec3
>&
forces
,
double
*
totalEnergy
,
double
*
energyParamDerivs
)
{
double
deltaR
[
3
][
ReferenceForce
::
LastDeltaRIndex
];
static
const
std
::
string
methodName
=
"
\n
ReferenceProperDihedralBond::calculateBondIxn"
;
// constants -- reduce Visual Studio warnings regarding conversions between float & double
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
static
const
int
LastAtomIndex
=
4
;
RealOpenMM
deltaR
[
3
][
ReferenceForce
::
LastDeltaRIndex
];
RealOpenMM
crossProductMemory
[
6
];
double
crossProductMemory
[
6
];
// ---------------------------------------------------------------------------------------
...
...
@@ -114,55 +99,55 @@ void ReferenceProperDihedralBond::calculateBondIxn(int* atomIndices,
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomDIndex
],
atomCoordinates
[
atomCIndex
],
deltaR
[
2
]);
}
RealOpenMM
dotDihedral
;
RealOpenMM
signOfAngle
;
int
hasREntry
=
1
;
double
dotDihedral
;
double
signOfAngle
;
int
hasREntry
=
1
;
// Visual Studio complains if crossProduct declared as 'crossProduct[2][3]'
RealOpenMM
*
crossProduct
[
2
];
double
*
crossProduct
[
2
];
crossProduct
[
0
]
=
crossProductMemory
;
crossProduct
[
1
]
=
crossProductMemory
+
3
;
// get dihedral angle
RealOpenMM
dihedralAngle
=
getDihedralAngleBetweenThreeVectors
(
deltaR
[
0
],
deltaR
[
1
],
deltaR
[
2
],
double
dihedralAngle
=
getDihedralAngleBetweenThreeVectors
(
deltaR
[
0
],
deltaR
[
1
],
deltaR
[
2
],
crossProduct
,
&
dotDihedral
,
deltaR
[
0
],
&
signOfAngle
,
hasREntry
);
// evaluate delta angle, dE/d(angle)
RealOpenMM
deltaAngle
=
parameters
[
2
]
*
dihedralAngle
-
parameters
[
1
];
RealOpenMM
sinDeltaAngle
=
SIN
(
deltaAngle
);
RealOpenMM
dEdAngle
=
-
parameters
[
0
]
*
parameters
[
2
]
*
sinDeltaAngle
;
RealOpenMM
energy
=
parameters
[
0
]
*
(
one
+
COS
(
deltaAngle
));
double
deltaAngle
=
parameters
[
2
]
*
dihedralAngle
-
parameters
[
1
];
double
sinDeltaAngle
=
SIN
(
deltaAngle
);
double
dEdAngle
=
-
parameters
[
0
]
*
parameters
[
2
]
*
sinDeltaAngle
;
double
energy
=
parameters
[
0
]
*
(
1.0
+
cos
(
deltaAngle
));
// compute force
RealOpenMM
internalF
[
4
][
3
];
RealOpenMM
forceFactors
[
4
];
RealOpenMM
normCross1
=
DOT3
(
crossProduct
[
0
],
crossProduct
[
0
]);
RealOpenMM
normBC
=
deltaR
[
1
][
ReferenceForce
::
RIndex
];
forceFactors
[
0
]
=
(
-
dEdAngle
*
normBC
)
/
normCross1
;
double
internalF
[
4
][
3
];
double
forceFactors
[
4
];
double
normCross1
=
DOT3
(
crossProduct
[
0
],
crossProduct
[
0
]);
double
normBC
=
deltaR
[
1
][
ReferenceForce
::
RIndex
];
forceFactors
[
0
]
=
(
-
dEdAngle
*
normBC
)
/
normCross1
;
RealOpenMM
normCross2
=
DOT3
(
crossProduct
[
1
],
crossProduct
[
1
]);
forceFactors
[
3
]
=
(
dEdAngle
*
normBC
)
/
normCross2
;
forceFactors
[
1
]
=
DOT3
(
deltaR
[
0
],
deltaR
[
1
]);
forceFactors
[
1
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
double
normCross2
=
DOT3
(
crossProduct
[
1
],
crossProduct
[
1
]);
forceFactors
[
3
]
=
(
dEdAngle
*
normBC
)
/
normCross2
;
forceFactors
[
1
]
=
DOT3
(
deltaR
[
0
],
deltaR
[
1
]);
forceFactors
[
1
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
forceFactors
[
2
]
=
DOT3
(
deltaR
[
2
],
deltaR
[
1
]);
forceFactors
[
2
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
forceFactors
[
2
]
=
DOT3
(
deltaR
[
2
],
deltaR
[
1
]);
forceFactors
[
2
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
for
(
int
ii
=
0
;
ii
<
3
;
ii
++
)
{
internalF
[
0
][
ii
]
=
forceFactors
[
0
]
*
crossProduct
[
0
][
ii
];
internalF
[
3
][
ii
]
=
forceFactors
[
3
]
*
crossProduct
[
1
][
ii
];
internalF
[
0
][
ii
]
=
forceFactors
[
0
]
*
crossProduct
[
0
][
ii
];
internalF
[
3
][
ii
]
=
forceFactors
[
3
]
*
crossProduct
[
1
][
ii
];
RealOpenMM
s
=
forceFactors
[
1
]
*
internalF
[
0
][
ii
]
-
forceFactors
[
2
]
*
internalF
[
3
][
ii
];
double
s
=
forceFactors
[
1
]
*
internalF
[
0
][
ii
]
-
forceFactors
[
2
]
*
internalF
[
3
][
ii
];
internalF
[
1
][
ii
]
=
internalF
[
0
][
ii
]
-
s
;
internalF
[
2
][
ii
]
=
internalF
[
3
][
ii
]
+
s
;
internalF
[
1
][
ii
]
=
internalF
[
0
][
ii
]
-
s
;
internalF
[
2
][
ii
]
=
internalF
[
3
][
ii
]
+
s
;
}
// accumulate forces
...
...
platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp
View file @
047934e2
...
...
@@ -50,7 +50,7 @@ ReferenceRbDihedralBond::ReferenceRbDihedralBond() : usePeriodic(false) {
ReferenceRbDihedralBond
::~
ReferenceRbDihedralBond
()
{
}
void
ReferenceRbDihedralBond
::
setPeriodic
(
OpenMM
::
Real
Vec
*
vectors
)
{
void
ReferenceRbDihedralBond
::
setPeriodic
(
OpenMM
::
Vec
3
*
vectors
)
{
usePeriodic
=
true
;
boxVectors
[
0
]
=
vectors
[
0
];
boxVectors
[
1
]
=
vectors
[
1
];
...
...
@@ -70,32 +70,17 @@ void ReferenceRbDihedralBond::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */
void
ReferenceRbDihedralBond
::
calculateBondIxn
(
int
*
atomIndices
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
*
parameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
totalEnergy
,
double
*
energyParamDerivs
)
{
static
const
std
::
string
methodName
=
"
\n
ReferenceRbDihedralBond::calculateBondIxn"
;
// constants -- reduce Visual Studio warnings regarding conversions between float & double
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
vector
<
Vec3
>&
atomCoordinates
,
double
*
parameters
,
vector
<
Vec3
>&
forces
,
double
*
totalEnergy
,
double
*
energyParamDerivs
)
{
// number of parameters
static
const
int
numberOfParameters
=
6
;
static
const
int
LastAtomIndex
=
4
;
RealOpenMM
deltaR
[
3
][
ReferenceForce
::
LastDeltaRIndex
];
double
deltaR
[
3
][
ReferenceForce
::
LastDeltaRIndex
];
RealOpenMM
crossProductMemory
[
6
];
double
crossProductMemory
[
6
];
// ---------------------------------------------------------------------------------------
...
...
@@ -116,65 +101,65 @@ void ReferenceRbDihedralBond::calculateBondIxn(int* atomIndices,
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomDIndex
],
atomCoordinates
[
atomCIndex
],
deltaR
[
2
]);
}
RealOpenMM
cosPhi
;
RealOpenMM
signOfAngle
;
int
hasREntry
=
1
;
double
cosPhi
;
double
signOfAngle
;
int
hasREntry
=
1
;
// Visual Studio complains if crossProduct declared as 'crossProduct[2][3]'
RealOpenMM
*
crossProduct
[
2
];
double
*
crossProduct
[
2
];
crossProduct
[
0
]
=
crossProductMemory
;
crossProduct
[
1
]
=
crossProductMemory
+
3
;
RealOpenMM
dihederalAngle
=
getDihedralAngleBetweenThreeVectors
(
deltaR
[
0
],
deltaR
[
1
],
deltaR
[
2
],
crossProduct
,
&
cosPhi
,
deltaR
[
0
],
&
signOfAngle
,
hasREntry
);
double
dihederalAngle
=
getDihedralAngleBetweenThreeVectors
(
deltaR
[
0
],
deltaR
[
1
],
deltaR
[
2
],
crossProduct
,
&
cosPhi
,
deltaR
[
0
],
&
signOfAngle
,
hasREntry
);
// Gromacs: use polymer convention
if
(
dihederalAngle
<
zero
)
{
if
(
dihederalAngle
<
0.0
)
{
dihederalAngle
+=
PI_M
;
}
else
{
dihederalAngle
-=
PI_M
;
}
cosPhi
*=
-
one
;
cosPhi
*=
-
1.0
;
// Ryckaert-Bellemans:
// V = sum over i: { C_i*cos(psi)**i }, where psi = phi - PI,
// C_i is ith RB coefficient
RealOpenMM
dEdAngle
=
zero
;
RealOpenMM
energy
=
parameters
[
0
];
RealOpenMM
cosFactor
=
one
;
double
dEdAngle
=
0.0
;
double
energy
=
parameters
[
0
];
double
cosFactor
=
1.0
;
for
(
int
ii
=
1
;
ii
<
numberOfParameters
;
ii
++
)
{
dEdAngle
-=
((
RealOpenMM
)
ii
)
*
parameters
[
ii
]
*
cosFactor
;
dEdAngle
-=
ii
*
parameters
[
ii
]
*
cosFactor
;
cosFactor
*=
cosPhi
;
energy
+=
cosFactor
*
parameters
[
ii
];
}
dEdAngle
*=
SIN
(
dihederalAngle
);
RealOpenMM
internalF
[
4
][
3
];
RealOpenMM
forceFactors
[
4
];
RealOpenMM
normCross1
=
DOT3
(
crossProduct
[
0
],
crossProduct
[
0
]);
RealOpenMM
normBC
=
deltaR
[
1
][
ReferenceForce
::
RIndex
];
forceFactors
[
0
]
=
(
-
dEdAngle
*
normBC
)
/
normCross1
;
double
internalF
[
4
][
3
];
double
forceFactors
[
4
];
double
normCross1
=
DOT3
(
crossProduct
[
0
],
crossProduct
[
0
]);
double
normBC
=
deltaR
[
1
][
ReferenceForce
::
RIndex
];
forceFactors
[
0
]
=
(
-
dEdAngle
*
normBC
)
/
normCross1
;
double
normCross2
=
DOT3
(
crossProduct
[
1
],
crossProduct
[
1
]);
forceFactors
[
3
]
=
(
dEdAngle
*
normBC
)
/
normCross2
;
RealOpenMM
normCross2
=
DOT3
(
crossProduct
[
1
],
crossProduct
[
1
]);
forceFactors
[
3
]
=
(
dEdAngle
*
normBC
)
/
normCross2
;
forceFactors
[
1
]
=
DOT3
(
deltaR
[
0
],
deltaR
[
1
]);
forceFactors
[
1
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
forceFactors
[
1
]
=
DOT3
(
deltaR
[
0
],
deltaR
[
1
]);
forceFactors
[
1
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
forceFactors
[
2
]
=
DOT3
(
deltaR
[
2
],
deltaR
[
1
]);
forceFactors
[
2
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
forceFactors
[
2
]
=
DOT3
(
deltaR
[
2
],
deltaR
[
1
]);
forceFactors
[
2
]
/=
deltaR
[
1
][
ReferenceForce
::
R2Index
];
for
(
int
ii
=
0
;
ii
<
3
;
ii
++
)
{
internalF
[
0
][
ii
]
=
forceFactors
[
0
]
*
crossProduct
[
0
][
ii
];
internalF
[
3
][
ii
]
=
forceFactors
[
3
]
*
crossProduct
[
1
][
ii
];
RealOpenMM
s
=
forceFactors
[
1
]
*
internalF
[
0
][
ii
]
-
forceFactors
[
2
]
*
internalF
[
3
][
ii
];
double
s
=
forceFactors
[
1
]
*
internalF
[
0
][
ii
]
-
forceFactors
[
2
]
*
internalF
[
3
][
ii
];
internalF
[
1
][
ii
]
=
internalF
[
0
][
ii
]
-
s
;
internalF
[
2
][
ii
]
=
internalF
[
3
][
ii
]
+
s
;
...
...
platforms/reference/src/SimTKReference/ReferenceSETTLEAlgorithm.cpp
View file @
047934e2
...
...
@@ -35,7 +35,7 @@ using namespace OpenMM;
using
namespace
std
;
ReferenceSETTLEAlgorithm
::
ReferenceSETTLEAlgorithm
(
const
vector
<
int
>&
atom1
,
const
vector
<
int
>&
atom2
,
const
vector
<
int
>&
atom3
,
const
vector
<
RealOpenMM
>&
distance1
,
const
vector
<
RealOpenMM
>&
distance2
,
vector
<
RealOpenMM
>&
masses
)
:
const
vector
<
double
>&
distance1
,
const
vector
<
double
>&
distance2
,
vector
<
double
>&
masses
)
:
atom1
(
atom1
),
atom2
(
atom2
),
atom3
(
atom3
),
distance1
(
distance1
),
distance2
(
distance2
),
masses
(
masses
)
{
}
...
...
@@ -43,7 +43,7 @@ int ReferenceSETTLEAlgorithm::getNumClusters() const {
return
atom1
.
size
();
}
void
ReferenceSETTLEAlgorithm
::
getClusterParameters
(
int
index
,
int
&
atom1
,
int
&
atom2
,
int
&
atom3
,
RealOpenMM
&
distance1
,
RealOpenMM
&
distance2
)
const
{
void
ReferenceSETTLEAlgorithm
::
getClusterParameters
(
int
index
,
int
&
atom1
,
int
&
atom2
,
int
&
atom3
,
double
&
distance1
,
double
&
distance2
)
const
{
atom1
=
this
->
atom1
[
index
];
atom2
=
this
->
atom2
[
index
];
atom3
=
this
->
atom3
[
index
];
...
...
@@ -51,130 +51,130 @@ void ReferenceSETTLEAlgorithm::getClusterParameters(int index, int& atom1, int&
distance2
=
this
->
distance2
[
index
];
}
void
ReferenceSETTLEAlgorithm
::
apply
(
vector
<
OpenMM
::
Real
Vec
>&
atomCoordinates
,
vector
<
OpenMM
::
Real
Vec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
,
RealOpenMM
tolerance
)
{
void
ReferenceSETTLEAlgorithm
::
apply
(
vector
<
OpenMM
::
Vec
3
>&
atomCoordinates
,
vector
<
OpenMM
::
Vec
3
>&
atomCoordinatesP
,
vector
<
double
>&
inverseMasses
,
double
tolerance
)
{
for
(
int
index
=
0
;
index
<
(
int
)
atom1
.
size
();
++
index
)
{
Real
Vec
apos0
=
atomCoordinates
[
atom1
[
index
]];
Real
Vec
xp0
=
atomCoordinatesP
[
atom1
[
index
]]
-
apos0
;
Real
Vec
apos1
=
atomCoordinates
[
atom2
[
index
]];
Real
Vec
xp1
=
atomCoordinatesP
[
atom2
[
index
]]
-
apos1
;
Real
Vec
apos2
=
atomCoordinates
[
atom3
[
index
]];
Real
Vec
xp2
=
atomCoordinatesP
[
atom3
[
index
]]
-
apos2
;
RealOpenMM
m0
=
masses
[
atom1
[
index
]];
RealOpenMM
m1
=
masses
[
atom2
[
index
]];
RealOpenMM
m2
=
masses
[
atom3
[
index
]];
Vec
3
apos0
=
atomCoordinates
[
atom1
[
index
]];
Vec
3
xp0
=
atomCoordinatesP
[
atom1
[
index
]]
-
apos0
;
Vec
3
apos1
=
atomCoordinates
[
atom2
[
index
]];
Vec
3
xp1
=
atomCoordinatesP
[
atom2
[
index
]]
-
apos1
;
Vec
3
apos2
=
atomCoordinates
[
atom3
[
index
]];
Vec
3
xp2
=
atomCoordinatesP
[
atom3
[
index
]]
-
apos2
;
double
m0
=
masses
[
atom1
[
index
]];
double
m1
=
masses
[
atom2
[
index
]];
double
m2
=
masses
[
atom3
[
index
]];
// Apply the SETTLE algorithm.
RealOpenMM
xb0
=
apos1
[
0
]
-
apos0
[
0
];
RealOpenMM
yb0
=
apos1
[
1
]
-
apos0
[
1
];
RealOpenMM
zb0
=
apos1
[
2
]
-
apos0
[
2
];
RealOpenMM
xc0
=
apos2
[
0
]
-
apos0
[
0
];
RealOpenMM
yc0
=
apos2
[
1
]
-
apos0
[
1
];
RealOpenMM
zc0
=
apos2
[
2
]
-
apos0
[
2
];
RealOpenMM
invTotalMass
=
1
/
(
m0
+
m1
+
m2
);
RealOpenMM
xcom
=
(
xp0
[
0
]
*
m0
+
(
xb0
+
xp1
[
0
])
*
m1
+
(
xc0
+
xp2
[
0
])
*
m2
)
*
invTotalMass
;
RealOpenMM
ycom
=
(
xp0
[
1
]
*
m0
+
(
yb0
+
xp1
[
1
])
*
m1
+
(
yc0
+
xp2
[
1
])
*
m2
)
*
invTotalMass
;
RealOpenMM
zcom
=
(
xp0
[
2
]
*
m0
+
(
zb0
+
xp1
[
2
])
*
m1
+
(
zc0
+
xp2
[
2
])
*
m2
)
*
invTotalMass
;
RealOpenMM
xa1
=
xp0
[
0
]
-
xcom
;
RealOpenMM
ya1
=
xp0
[
1
]
-
ycom
;
RealOpenMM
za1
=
xp0
[
2
]
-
zcom
;
RealOpenMM
xb1
=
xb0
+
xp1
[
0
]
-
xcom
;
RealOpenMM
yb1
=
yb0
+
xp1
[
1
]
-
ycom
;
RealOpenMM
zb1
=
zb0
+
xp1
[
2
]
-
zcom
;
RealOpenMM
xc1
=
xc0
+
xp2
[
0
]
-
xcom
;
RealOpenMM
yc1
=
yc0
+
xp2
[
1
]
-
ycom
;
RealOpenMM
zc1
=
zc0
+
xp2
[
2
]
-
zcom
;
RealOpenMM
xaksZd
=
yb0
*
zc0
-
zb0
*
yc0
;
RealOpenMM
yaksZd
=
zb0
*
xc0
-
xb0
*
zc0
;
RealOpenMM
zaksZd
=
xb0
*
yc0
-
yb0
*
xc0
;
RealOpenMM
xaksXd
=
ya1
*
zaksZd
-
za1
*
yaksZd
;
RealOpenMM
yaksXd
=
za1
*
xaksZd
-
xa1
*
zaksZd
;
RealOpenMM
zaksXd
=
xa1
*
yaksZd
-
ya1
*
xaksZd
;
RealOpenMM
xaksYd
=
yaksZd
*
zaksXd
-
zaksZd
*
yaksXd
;
RealOpenMM
yaksYd
=
zaksZd
*
xaksXd
-
xaksZd
*
zaksXd
;
RealOpenMM
zaksYd
=
xaksZd
*
yaksXd
-
yaksZd
*
xaksXd
;
RealOpenMM
axlng
=
sqrt
(
xaksXd
*
xaksXd
+
yaksXd
*
yaksXd
+
zaksXd
*
zaksXd
);
RealOpenMM
aylng
=
sqrt
(
xaksYd
*
xaksYd
+
yaksYd
*
yaksYd
+
zaksYd
*
zaksYd
);
RealOpenMM
azlng
=
sqrt
(
xaksZd
*
xaksZd
+
yaksZd
*
yaksZd
+
zaksZd
*
zaksZd
);
RealOpenMM
trns11
=
xaksXd
/
axlng
;
RealOpenMM
trns21
=
yaksXd
/
axlng
;
RealOpenMM
trns31
=
zaksXd
/
axlng
;
RealOpenMM
trns12
=
xaksYd
/
aylng
;
RealOpenMM
trns22
=
yaksYd
/
aylng
;
RealOpenMM
trns32
=
zaksYd
/
aylng
;
RealOpenMM
trns13
=
xaksZd
/
azlng
;
RealOpenMM
trns23
=
yaksZd
/
azlng
;
RealOpenMM
trns33
=
zaksZd
/
azlng
;
RealOpenMM
xb0d
=
trns11
*
xb0
+
trns21
*
yb0
+
trns31
*
zb0
;
RealOpenMM
yb0d
=
trns12
*
xb0
+
trns22
*
yb0
+
trns32
*
zb0
;
RealOpenMM
xc0d
=
trns11
*
xc0
+
trns21
*
yc0
+
trns31
*
zc0
;
RealOpenMM
yc0d
=
trns12
*
xc0
+
trns22
*
yc0
+
trns32
*
zc0
;
RealOpenMM
za1d
=
trns13
*
xa1
+
trns23
*
ya1
+
trns33
*
za1
;
RealOpenMM
xb1d
=
trns11
*
xb1
+
trns21
*
yb1
+
trns31
*
zb1
;
RealOpenMM
yb1d
=
trns12
*
xb1
+
trns22
*
yb1
+
trns32
*
zb1
;
RealOpenMM
zb1d
=
trns13
*
xb1
+
trns23
*
yb1
+
trns33
*
zb1
;
RealOpenMM
xc1d
=
trns11
*
xc1
+
trns21
*
yc1
+
trns31
*
zc1
;
RealOpenMM
yc1d
=
trns12
*
xc1
+
trns22
*
yc1
+
trns32
*
zc1
;
RealOpenMM
zc1d
=
trns13
*
xc1
+
trns23
*
yc1
+
trns33
*
zc1
;
double
xb0
=
apos1
[
0
]
-
apos0
[
0
];
double
yb0
=
apos1
[
1
]
-
apos0
[
1
];
double
zb0
=
apos1
[
2
]
-
apos0
[
2
];
double
xc0
=
apos2
[
0
]
-
apos0
[
0
];
double
yc0
=
apos2
[
1
]
-
apos0
[
1
];
double
zc0
=
apos2
[
2
]
-
apos0
[
2
];
double
invTotalMass
=
1
/
(
m0
+
m1
+
m2
);
double
xcom
=
(
xp0
[
0
]
*
m0
+
(
xb0
+
xp1
[
0
])
*
m1
+
(
xc0
+
xp2
[
0
])
*
m2
)
*
invTotalMass
;
double
ycom
=
(
xp0
[
1
]
*
m0
+
(
yb0
+
xp1
[
1
])
*
m1
+
(
yc0
+
xp2
[
1
])
*
m2
)
*
invTotalMass
;
double
zcom
=
(
xp0
[
2
]
*
m0
+
(
zb0
+
xp1
[
2
])
*
m1
+
(
zc0
+
xp2
[
2
])
*
m2
)
*
invTotalMass
;
double
xa1
=
xp0
[
0
]
-
xcom
;
double
ya1
=
xp0
[
1
]
-
ycom
;
double
za1
=
xp0
[
2
]
-
zcom
;
double
xb1
=
xb0
+
xp1
[
0
]
-
xcom
;
double
yb1
=
yb0
+
xp1
[
1
]
-
ycom
;
double
zb1
=
zb0
+
xp1
[
2
]
-
zcom
;
double
xc1
=
xc0
+
xp2
[
0
]
-
xcom
;
double
yc1
=
yc0
+
xp2
[
1
]
-
ycom
;
double
zc1
=
zc0
+
xp2
[
2
]
-
zcom
;
double
xaksZd
=
yb0
*
zc0
-
zb0
*
yc0
;
double
yaksZd
=
zb0
*
xc0
-
xb0
*
zc0
;
double
zaksZd
=
xb0
*
yc0
-
yb0
*
xc0
;
double
xaksXd
=
ya1
*
zaksZd
-
za1
*
yaksZd
;
double
yaksXd
=
za1
*
xaksZd
-
xa1
*
zaksZd
;
double
zaksXd
=
xa1
*
yaksZd
-
ya1
*
xaksZd
;
double
xaksYd
=
yaksZd
*
zaksXd
-
zaksZd
*
yaksXd
;
double
yaksYd
=
zaksZd
*
xaksXd
-
xaksZd
*
zaksXd
;
double
zaksYd
=
xaksZd
*
yaksXd
-
yaksZd
*
xaksXd
;
double
axlng
=
sqrt
(
xaksXd
*
xaksXd
+
yaksXd
*
yaksXd
+
zaksXd
*
zaksXd
);
double
aylng
=
sqrt
(
xaksYd
*
xaksYd
+
yaksYd
*
yaksYd
+
zaksYd
*
zaksYd
);
double
azlng
=
sqrt
(
xaksZd
*
xaksZd
+
yaksZd
*
yaksZd
+
zaksZd
*
zaksZd
);
double
trns11
=
xaksXd
/
axlng
;
double
trns21
=
yaksXd
/
axlng
;
double
trns31
=
zaksXd
/
axlng
;
double
trns12
=
xaksYd
/
aylng
;
double
trns22
=
yaksYd
/
aylng
;
double
trns32
=
zaksYd
/
aylng
;
double
trns13
=
xaksZd
/
azlng
;
double
trns23
=
yaksZd
/
azlng
;
double
trns33
=
zaksZd
/
azlng
;
double
xb0d
=
trns11
*
xb0
+
trns21
*
yb0
+
trns31
*
zb0
;
double
yb0d
=
trns12
*
xb0
+
trns22
*
yb0
+
trns32
*
zb0
;
double
xc0d
=
trns11
*
xc0
+
trns21
*
yc0
+
trns31
*
zc0
;
double
yc0d
=
trns12
*
xc0
+
trns22
*
yc0
+
trns32
*
zc0
;
double
za1d
=
trns13
*
xa1
+
trns23
*
ya1
+
trns33
*
za1
;
double
xb1d
=
trns11
*
xb1
+
trns21
*
yb1
+
trns31
*
zb1
;
double
yb1d
=
trns12
*
xb1
+
trns22
*
yb1
+
trns32
*
zb1
;
double
zb1d
=
trns13
*
xb1
+
trns23
*
yb1
+
trns33
*
zb1
;
double
xc1d
=
trns11
*
xc1
+
trns21
*
yc1
+
trns31
*
zc1
;
double
yc1d
=
trns12
*
xc1
+
trns22
*
yc1
+
trns32
*
zc1
;
double
zc1d
=
trns13
*
xc1
+
trns23
*
yc1
+
trns33
*
zc1
;
// --- Step2 A2' ---
RealOpenMM
rc
=
0.5
*
distance2
[
index
];
RealOpenMM
rb
=
sqrt
(
distance1
[
index
]
*
distance1
[
index
]
-
rc
*
rc
);
RealOpenMM
ra
=
rb
*
(
m1
+
m2
)
*
invTotalMass
;
double
rc
=
0.5
*
distance2
[
index
];
double
rb
=
sqrt
(
distance1
[
index
]
*
distance1
[
index
]
-
rc
*
rc
);
double
ra
=
rb
*
(
m1
+
m2
)
*
invTotalMass
;
rb
-=
ra
;
RealOpenMM
sinphi
=
za1d
/
ra
;
RealOpenMM
cosphi
=
sqrt
(
1
-
sinphi
*
sinphi
);
RealOpenMM
sinpsi
=
(
zb1d
-
zc1d
)
/
(
2
*
rc
*
cosphi
);
RealOpenMM
cospsi
=
sqrt
(
1
-
sinpsi
*
sinpsi
);
RealOpenMM
ya2d
=
ra
*
cosphi
;
RealOpenMM
xb2d
=
-
rc
*
cospsi
;
RealOpenMM
yb2d
=
-
rb
*
cosphi
-
rc
*
sinpsi
*
sinphi
;
RealOpenMM
yc2d
=
-
rb
*
cosphi
+
rc
*
sinpsi
*
sinphi
;
RealOpenMM
xb2d2
=
xb2d
*
xb2d
;
RealOpenMM
hh2
=
4.0
f
*
xb2d2
+
(
yb2d
-
yc2d
)
*
(
yb2d
-
yc2d
)
+
(
zb1d
-
zc1d
)
*
(
zb1d
-
zc1d
);
RealOpenMM
deltx
=
2.0
f
*
xb2d
+
sqrt
(
4.0
f
*
xb2d2
-
hh2
+
distance2
[
index
]
*
distance2
[
index
]);
double
sinphi
=
za1d
/
ra
;
double
cosphi
=
sqrt
(
1
-
sinphi
*
sinphi
);
double
sinpsi
=
(
zb1d
-
zc1d
)
/
(
2
*
rc
*
cosphi
);
double
cospsi
=
sqrt
(
1
-
sinpsi
*
sinpsi
);
double
ya2d
=
ra
*
cosphi
;
double
xb2d
=
-
rc
*
cospsi
;
double
yb2d
=
-
rb
*
cosphi
-
rc
*
sinpsi
*
sinphi
;
double
yc2d
=
-
rb
*
cosphi
+
rc
*
sinpsi
*
sinphi
;
double
xb2d2
=
xb2d
*
xb2d
;
double
hh2
=
4.0
f
*
xb2d2
+
(
yb2d
-
yc2d
)
*
(
yb2d
-
yc2d
)
+
(
zb1d
-
zc1d
)
*
(
zb1d
-
zc1d
);
double
deltx
=
2.0
f
*
xb2d
+
sqrt
(
4.0
f
*
xb2d2
-
hh2
+
distance2
[
index
]
*
distance2
[
index
]);
xb2d
-=
deltx
*
0.5
;
// --- Step3 al,be,ga ---
RealOpenMM
alpha
=
(
xb2d
*
(
xb0d
-
xc0d
)
+
yb0d
*
yb2d
+
yc0d
*
yc2d
);
RealOpenMM
beta
=
(
xb2d
*
(
yc0d
-
yb0d
)
+
xb0d
*
yb2d
+
xc0d
*
yc2d
);
RealOpenMM
gamma
=
xb0d
*
yb1d
-
xb1d
*
yb0d
+
xc0d
*
yc1d
-
xc1d
*
yc0d
;
double
alpha
=
(
xb2d
*
(
xb0d
-
xc0d
)
+
yb0d
*
yb2d
+
yc0d
*
yc2d
);
double
beta
=
(
xb2d
*
(
yc0d
-
yb0d
)
+
xb0d
*
yb2d
+
xc0d
*
yc2d
);
double
gamma
=
xb0d
*
yb1d
-
xb1d
*
yb0d
+
xc0d
*
yc1d
-
xc1d
*
yc0d
;
RealOpenMM
al2be2
=
alpha
*
alpha
+
beta
*
beta
;
RealOpenMM
sintheta
=
(
alpha
*
gamma
-
beta
*
sqrt
(
al2be2
-
gamma
*
gamma
))
/
al2be2
;
double
al2be2
=
alpha
*
alpha
+
beta
*
beta
;
double
sintheta
=
(
alpha
*
gamma
-
beta
*
sqrt
(
al2be2
-
gamma
*
gamma
))
/
al2be2
;
// --- Step4 A3' ---
RealOpenMM
costheta
=
sqrt
(
1
-
sintheta
*
sintheta
);
RealOpenMM
xa3d
=
-
ya2d
*
sintheta
;
RealOpenMM
ya3d
=
ya2d
*
costheta
;
RealOpenMM
za3d
=
za1d
;
RealOpenMM
xb3d
=
xb2d
*
costheta
-
yb2d
*
sintheta
;
RealOpenMM
yb3d
=
xb2d
*
sintheta
+
yb2d
*
costheta
;
RealOpenMM
zb3d
=
zb1d
;
RealOpenMM
xc3d
=
-
xb2d
*
costheta
-
yc2d
*
sintheta
;
RealOpenMM
yc3d
=
-
xb2d
*
sintheta
+
yc2d
*
costheta
;
RealOpenMM
zc3d
=
zc1d
;
double
costheta
=
sqrt
(
1
-
sintheta
*
sintheta
);
double
xa3d
=
-
ya2d
*
sintheta
;
double
ya3d
=
ya2d
*
costheta
;
double
za3d
=
za1d
;
double
xb3d
=
xb2d
*
costheta
-
yb2d
*
sintheta
;
double
yb3d
=
xb2d
*
sintheta
+
yb2d
*
costheta
;
double
zb3d
=
zb1d
;
double
xc3d
=
-
xb2d
*
costheta
-
yc2d
*
sintheta
;
double
yc3d
=
-
xb2d
*
sintheta
+
yc2d
*
costheta
;
double
zc3d
=
zc1d
;
// --- Step5 A3 ---
RealOpenMM
xa3
=
trns11
*
xa3d
+
trns12
*
ya3d
+
trns13
*
za3d
;
RealOpenMM
ya3
=
trns21
*
xa3d
+
trns22
*
ya3d
+
trns23
*
za3d
;
RealOpenMM
za3
=
trns31
*
xa3d
+
trns32
*
ya3d
+
trns33
*
za3d
;
RealOpenMM
xb3
=
trns11
*
xb3d
+
trns12
*
yb3d
+
trns13
*
zb3d
;
RealOpenMM
yb3
=
trns21
*
xb3d
+
trns22
*
yb3d
+
trns23
*
zb3d
;
RealOpenMM
zb3
=
trns31
*
xb3d
+
trns32
*
yb3d
+
trns33
*
zb3d
;
RealOpenMM
xc3
=
trns11
*
xc3d
+
trns12
*
yc3d
+
trns13
*
zc3d
;
RealOpenMM
yc3
=
trns21
*
xc3d
+
trns22
*
yc3d
+
trns23
*
zc3d
;
RealOpenMM
zc3
=
trns31
*
xc3d
+
trns32
*
yc3d
+
trns33
*
zc3d
;
double
xa3
=
trns11
*
xa3d
+
trns12
*
ya3d
+
trns13
*
za3d
;
double
ya3
=
trns21
*
xa3d
+
trns22
*
ya3d
+
trns23
*
za3d
;
double
za3
=
trns31
*
xa3d
+
trns32
*
ya3d
+
trns33
*
za3d
;
double
xb3
=
trns11
*
xb3d
+
trns12
*
yb3d
+
trns13
*
zb3d
;
double
yb3
=
trns21
*
xb3d
+
trns22
*
yb3d
+
trns23
*
zb3d
;
double
zb3
=
trns31
*
xb3d
+
trns32
*
yb3d
+
trns33
*
zb3d
;
double
xc3
=
trns11
*
xc3d
+
trns12
*
yc3d
+
trns13
*
zc3d
;
double
yc3
=
trns21
*
xc3d
+
trns22
*
yc3d
+
trns23
*
zc3d
;
double
zc3
=
trns31
*
xc3d
+
trns32
*
yc3d
+
trns33
*
zc3d
;
xp0
[
0
]
=
xcom
+
xa3
;
xp0
[
1
]
=
ycom
+
ya3
;
...
...
@@ -194,46 +194,46 @@ void ReferenceSETTLEAlgorithm::apply(vector<OpenMM::RealVec>& atomCoordinates, v
}
}
void
ReferenceSETTLEAlgorithm
::
applyToVelocities
(
vector
<
OpenMM
::
Real
Vec
>&
atomCoordinates
,
vector
<
OpenMM
::
Real
Vec
>&
velocities
,
vector
<
RealOpenMM
>&
inverseMasses
,
RealOpenMM
tolerance
)
{
void
ReferenceSETTLEAlgorithm
::
applyToVelocities
(
vector
<
OpenMM
::
Vec
3
>&
atomCoordinates
,
vector
<
OpenMM
::
Vec
3
>&
velocities
,
vector
<
double
>&
inverseMasses
,
double
tolerance
)
{
for
(
int
index
=
0
;
index
<
(
int
)
atom1
.
size
();
++
index
)
{
Real
Vec
apos0
=
atomCoordinates
[
atom1
[
index
]];
Real
Vec
apos1
=
atomCoordinates
[
atom2
[
index
]];
Real
Vec
apos2
=
atomCoordinates
[
atom3
[
index
]];
Real
Vec
v0
=
velocities
[
atom1
[
index
]];
Real
Vec
v1
=
velocities
[
atom2
[
index
]];
Real
Vec
v2
=
velocities
[
atom3
[
index
]];
Vec
3
apos0
=
atomCoordinates
[
atom1
[
index
]];
Vec
3
apos1
=
atomCoordinates
[
atom2
[
index
]];
Vec
3
apos2
=
atomCoordinates
[
atom3
[
index
]];
Vec
3
v0
=
velocities
[
atom1
[
index
]];
Vec
3
v1
=
velocities
[
atom2
[
index
]];
Vec
3
v2
=
velocities
[
atom3
[
index
]];
// Compute intermediate quantities: the atom masses, the bond directions, the relative velocities,
// and the angle cosines and sines.
RealOpenMM
mA
=
masses
[
atom1
[
index
]];
RealOpenMM
mB
=
masses
[
atom2
[
index
]];
RealOpenMM
mC
=
masses
[
atom3
[
index
]];
Real
Vec
eAB
=
apos1
-
apos0
;
Real
Vec
eBC
=
apos2
-
apos1
;
Real
Vec
eCA
=
apos0
-
apos2
;
double
mA
=
masses
[
atom1
[
index
]];
double
mB
=
masses
[
atom2
[
index
]];
double
mC
=
masses
[
atom3
[
index
]];
Vec
3
eAB
=
apos1
-
apos0
;
Vec
3
eBC
=
apos2
-
apos1
;
Vec
3
eCA
=
apos0
-
apos2
;
eAB
/=
sqrt
(
eAB
[
0
]
*
eAB
[
0
]
+
eAB
[
1
]
*
eAB
[
1
]
+
eAB
[
2
]
*
eAB
[
2
]);
eBC
/=
sqrt
(
eBC
[
0
]
*
eBC
[
0
]
+
eBC
[
1
]
*
eBC
[
1
]
+
eBC
[
2
]
*
eBC
[
2
]);
eCA
/=
sqrt
(
eCA
[
0
]
*
eCA
[
0
]
+
eCA
[
1
]
*
eCA
[
1
]
+
eCA
[
2
]
*
eCA
[
2
]);
RealOpenMM
vAB
=
(
v1
[
0
]
-
v0
[
0
])
*
eAB
[
0
]
+
(
v1
[
1
]
-
v0
[
1
])
*
eAB
[
1
]
+
(
v1
[
2
]
-
v0
[
2
])
*
eAB
[
2
];
RealOpenMM
vBC
=
(
v2
[
0
]
-
v1
[
0
])
*
eBC
[
0
]
+
(
v2
[
1
]
-
v1
[
1
])
*
eBC
[
1
]
+
(
v2
[
2
]
-
v1
[
2
])
*
eBC
[
2
];
RealOpenMM
vCA
=
(
v0
[
0
]
-
v2
[
0
])
*
eCA
[
0
]
+
(
v0
[
1
]
-
v2
[
1
])
*
eCA
[
1
]
+
(
v0
[
2
]
-
v2
[
2
])
*
eCA
[
2
];
RealOpenMM
cA
=
-
(
eAB
[
0
]
*
eCA
[
0
]
+
eAB
[
1
]
*
eCA
[
1
]
+
eAB
[
2
]
*
eCA
[
2
]);
RealOpenMM
cB
=
-
(
eAB
[
0
]
*
eBC
[
0
]
+
eAB
[
1
]
*
eBC
[
1
]
+
eAB
[
2
]
*
eBC
[
2
]);
RealOpenMM
cC
=
-
(
eBC
[
0
]
*
eCA
[
0
]
+
eBC
[
1
]
*
eCA
[
1
]
+
eBC
[
2
]
*
eCA
[
2
]);
RealOpenMM
s2A
=
1
-
cA
*
cA
;
RealOpenMM
s2B
=
1
-
cB
*
cB
;
RealOpenMM
s2C
=
1
-
cC
*
cC
;
double
vAB
=
(
v1
[
0
]
-
v0
[
0
])
*
eAB
[
0
]
+
(
v1
[
1
]
-
v0
[
1
])
*
eAB
[
1
]
+
(
v1
[
2
]
-
v0
[
2
])
*
eAB
[
2
];
double
vBC
=
(
v2
[
0
]
-
v1
[
0
])
*
eBC
[
0
]
+
(
v2
[
1
]
-
v1
[
1
])
*
eBC
[
1
]
+
(
v2
[
2
]
-
v1
[
2
])
*
eBC
[
2
];
double
vCA
=
(
v0
[
0
]
-
v2
[
0
])
*
eCA
[
0
]
+
(
v0
[
1
]
-
v2
[
1
])
*
eCA
[
1
]
+
(
v0
[
2
]
-
v2
[
2
])
*
eCA
[
2
];
double
cA
=
-
(
eAB
[
0
]
*
eCA
[
0
]
+
eAB
[
1
]
*
eCA
[
1
]
+
eAB
[
2
]
*
eCA
[
2
]);
double
cB
=
-
(
eAB
[
0
]
*
eBC
[
0
]
+
eAB
[
1
]
*
eBC
[
1
]
+
eAB
[
2
]
*
eBC
[
2
]);
double
cC
=
-
(
eBC
[
0
]
*
eCA
[
0
]
+
eBC
[
1
]
*
eCA
[
1
]
+
eBC
[
2
]
*
eCA
[
2
]);
double
s2A
=
1
-
cA
*
cA
;
double
s2B
=
1
-
cB
*
cB
;
double
s2C
=
1
-
cC
*
cC
;
// Solve the equations. These are different from those in the SETTLE paper (JCC 13(8), pp. 952-962, 1992), because
// in going from equations B1 to B2, they make the assumption that mB=mC (but don't bother to mention they're
// making that assumption). We allow all three atoms to have different masses.
RealOpenMM
mABCinv
=
1
/
(
mA
*
mB
*
mC
);
RealOpenMM
denom
=
(((
s2A
*
mB
+
s2B
*
mA
)
*
mC
+
(
s2A
*
mB
*
mB
+
2
*
(
cA
*
cB
*
cC
+
1
)
*
mA
*
mB
+
s2B
*
mA
*
mA
))
*
mC
+
s2C
*
mA
*
mB
*
(
mA
+
mB
))
*
mABCinv
;
RealOpenMM
tab
=
((
cB
*
cC
*
mA
-
cA
*
mB
-
cA
*
mC
)
*
vCA
+
(
cA
*
cC
*
mB
-
cB
*
mC
-
cB
*
mA
)
*
vBC
+
(
s2C
*
mA
*
mA
*
mB
*
mB
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vAB
)
/
denom
;
RealOpenMM
tbc
=
((
cA
*
cB
*
mC
-
cC
*
mB
-
cC
*
mA
)
*
vCA
+
(
s2A
*
mB
*
mB
*
mC
*
mC
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vBC
+
(
cA
*
cC
*
mB
-
cB
*
mA
-
cB
*
mC
)
*
vAB
)
/
denom
;
RealOpenMM
tca
=
((
s2B
*
mA
*
mA
*
mC
*
mC
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vCA
+
(
cA
*
cB
*
mC
-
cC
*
mB
-
cC
*
mA
)
*
vBC
+
(
cB
*
cC
*
mA
-
cA
*
mB
-
cA
*
mC
)
*
vAB
)
/
denom
;
double
mABCinv
=
1
/
(
mA
*
mB
*
mC
);
double
denom
=
(((
s2A
*
mB
+
s2B
*
mA
)
*
mC
+
(
s2A
*
mB
*
mB
+
2
*
(
cA
*
cB
*
cC
+
1
)
*
mA
*
mB
+
s2B
*
mA
*
mA
))
*
mC
+
s2C
*
mA
*
mB
*
(
mA
+
mB
))
*
mABCinv
;
double
tab
=
((
cB
*
cC
*
mA
-
cA
*
mB
-
cA
*
mC
)
*
vCA
+
(
cA
*
cC
*
mB
-
cB
*
mC
-
cB
*
mA
)
*
vBC
+
(
s2C
*
mA
*
mA
*
mB
*
mB
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vAB
)
/
denom
;
double
tbc
=
((
cA
*
cB
*
mC
-
cC
*
mB
-
cC
*
mA
)
*
vCA
+
(
s2A
*
mB
*
mB
*
mC
*
mC
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vBC
+
(
cA
*
cC
*
mB
-
cB
*
mA
-
cB
*
mC
)
*
vAB
)
/
denom
;
double
tca
=
((
s2B
*
mA
*
mA
*
mC
*
mC
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vCA
+
(
cA
*
cB
*
mC
-
cC
*
mB
-
cC
*
mA
)
*
vBC
+
(
cB
*
cC
*
mA
-
cA
*
mB
-
cA
*
mC
)
*
vAB
)
/
denom
;
v0
+=
(
eAB
*
tab
-
eCA
*
tca
)
*
inverseMasses
[
atom1
[
index
]];
v1
+=
(
eBC
*
tbc
-
eAB
*
tab
)
*
inverseMasses
[
atom2
[
index
]];
v2
+=
(
eCA
*
tca
-
eBC
*
tbc
)
*
inverseMasses
[
atom3
[
index
]];
...
...
platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp
View file @
047934e2
/* Portions copyright (c) 2006-201
3
Stanford University and Simbios.
/* Portions copyright (c) 2006-201
6
Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -41,20 +41,15 @@ using namespace OpenMM;
@param numberOfAtoms number of atoms
@param deltaT delta t for dynamics
@param
tau viscosity(?)
@param
friction friction coefficient
@param temperature temperature
--------------------------------------------------------------------------------------- */
ReferenceStochasticDynamics
::
ReferenceStochasticDynamics
(
int
numberOfAtoms
,
RealOpenMM
deltaT
,
RealOpenMM
tau
,
RealOpenMM
temperature
)
:
ReferenceDynamics
(
numberOfAtoms
,
deltaT
,
temperature
),
_tau
(
tau
)
{
if
(
tau
<=
0
)
{
std
::
stringstream
message
;
message
<<
"illegal tau value: "
<<
tau
;
throw
OpenMMException
(
message
.
str
());
}
double
deltaT
,
double
friction
,
double
temperature
)
:
ReferenceDynamics
(
numberOfAtoms
,
deltaT
,
temperature
),
friction
(
friction
)
{
xPrime
.
resize
(
numberOfAtoms
);
inverseMasses
.
resize
(
numberOfAtoms
);
}
...
...
@@ -66,32 +61,16 @@ ReferenceStochasticDynamics::ReferenceStochasticDynamics(int numberOfAtoms,
--------------------------------------------------------------------------------------- */
ReferenceStochasticDynamics
::~
ReferenceStochasticDynamics
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceStochasticDynamics::~ReferenceStochasticDynamics";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
Get tau
@return tau
Get friction coefficient
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceStochasticDynamics
::
getTau
()
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceStochasticDynamics::getTau";
// ---------------------------------------------------------------------------------------
return
_tau
;
double
ReferenceStochasticDynamics
::
getFriction
()
const
{
return
friction
;
}
/**---------------------------------------------------------------------------------------
...
...
@@ -107,28 +86,22 @@ RealOpenMM ReferenceStochasticDynamics::getTau() const {
--------------------------------------------------------------------------------------- */
void
ReferenceStochasticDynamics
::
updatePart1
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
inverseMasses
,
vector
<
RealVec
>&
xPrime
)
{
// ---------------------------------------------------------------------------------------
//static const char* methodName = "\nReferenceStochasticDynamics::updatePart1";
// ---------------------------------------------------------------------------------------
void
ReferenceStochasticDynamics
::
updatePart1
(
int
numberOfAtoms
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
inverseMasses
,
vector
<
Vec3
>&
xPrime
)
{
// perform first update
RealOpenMM
tau
=
getTau
();
const
RealOpenMM
vscale
=
EXP
(
-
getDeltaT
()
/
tau
);
const
RealOpenMM
fscale
=
(
1
-
vscale
)
*
tau
;
const
RealOpenMM
kT
=
BOLTZ
*
getTemperature
();
const
RealOpenMM
noisescale
=
SQRT
(
2
*
kT
/
tau
)
*
SQRT
(
0.5
*
(
1
-
vscale
*
vscale
)
*
tau
);
double
dt
=
getDeltaT
();
double
friction
=
getFriction
();
const
double
vscale
=
exp
(
-
dt
*
friction
);
const
double
fscale
=
(
friction
==
0
?
dt
:
(
1
-
vscale
)
/
friction
);
const
double
kT
=
BOLTZ
*
getTemperature
();
const
double
noisescale
=
sqrt
(
kT
*
(
1
-
vscale
*
vscale
));
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
if
(
inverseMasses
[
ii
]
!=
0.0
)
{
RealOpenMM
sqrtInvMass
=
SQRT
(
inverseMasses
[
ii
]);
double
sqrtInvMass
=
sqrt
(
inverseMasses
[
ii
]);
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
)
{
velocities
[
ii
][
jj
]
=
vscale
*
velocities
[
ii
][
jj
]
+
fscale
*
inverseMasses
[
ii
]
*
forces
[
ii
][
jj
]
+
noisescale
*
sqrtInvMass
*
SimTKOpenMMUtilities
::
getNormallyDistributedRandomNumber
();
}
...
...
@@ -148,17 +121,10 @@ void ReferenceStochasticDynamics::updatePart1(int numberOfAtoms, vector<RealVec>
--------------------------------------------------------------------------------------- */
void
ReferenceStochasticDynamics
::
updatePart2
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
inverseMasses
,
vector
<
RealVec
>&
xPrime
)
{
// ---------------------------------------------------------------------------------------
//static const char* methodName = "\nReferenceStochasticDynamics::updatePart2";
// ---------------------------------------------------------------------------------------
void
ReferenceStochasticDynamics
::
updatePart2
(
int
numberOfAtoms
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
inverseMasses
,
vector
<
Vec3
>&
xPrime
)
{
// perform second update
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
...
...
@@ -167,10 +133,10 @@ void ReferenceStochasticDynamics::updatePart2(int numberOfAtoms, vector<RealVec>
}
}
void
ReferenceStochasticDynamics
::
updatePart3
(
int
numberOfAtoms
,
vector
<
Real
Vec
>&
atomCoordinates
,
vector
<
Real
Vec
>&
velocities
,
vector
<
RealOpenMM
>&
inverseMasses
,
vector
<
Real
Vec
>&
xPrime
)
{
RealOpenMM
invStepSize
=
1.0
/
getDeltaT
();
void
ReferenceStochasticDynamics
::
updatePart3
(
int
numberOfAtoms
,
vector
<
Vec
3
>&
atomCoordinates
,
vector
<
Vec
3
>&
velocities
,
vector
<
double
>&
inverseMasses
,
vector
<
Vec
3
>&
xPrime
)
{
double
invStepSize
=
1.0
/
getDeltaT
();
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
if
(
inverseMasses
[
i
]
!=
0
)
{
velocities
[
i
]
=
(
xPrime
[
i
]
-
atomCoordinates
[
i
])
*
invStepSize
;
...
...
@@ -191,18 +157,8 @@ void ReferenceStochasticDynamics::updatePart3(int numberOfAtoms, vector<RealVec>
--------------------------------------------------------------------------------------- */
void
ReferenceStochasticDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
masses
,
RealOpenMM
tolerance
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceStochasticDynamics::update"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
// ---------------------------------------------------------------------------------------
void
ReferenceStochasticDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
masses
,
double
tolerance
)
{
// first-time-through initialization
int
numberOfAtoms
=
system
.
getNumParticles
();
...
...
@@ -210,10 +166,10 @@ void ReferenceStochasticDynamics::update(const OpenMM::System& system, vector<Re
// invert masses
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
if
(
masses
[
ii
]
==
zero
)
inverseMasses
[
ii
]
=
zero
;
if
(
masses
[
ii
]
==
0.0
)
inverseMasses
[
ii
]
=
0.0
;
else
inverseMasses
[
ii
]
=
one
/
masses
[
ii
];
inverseMasses
[
ii
]
=
1.0
/
masses
[
ii
];
}
}
...
...
platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp
View file @
047934e2
/* Portions copyright (c) 2006-201
3
Stanford University and Simbios.
/* Portions copyright (c) 2006-201
6
Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -42,21 +42,16 @@ using namespace OpenMM;
@param numberOfAtoms number of atoms
@param deltaT delta t for dynamics
@param
tau viscosity(?)
@param
friction friction coefficient
@param temperature temperature
@param accuracy required accuracy
--------------------------------------------------------------------------------------- */
ReferenceVariableStochasticDynamics
::
ReferenceVariableStochasticDynamics
(
int
numberOfAtoms
,
RealOpenMM
tau
,
RealOpenMM
temperature
,
RealOpenMM
accuracy
)
:
ReferenceDynamics
(
numberOfAtoms
,
0.0
f
,
temperature
),
_tau
(
tau
),
_accuracy
(
accuracy
)
{
if
(
tau
<=
0
)
{
std
::
stringstream
message
;
message
<<
"illegal tau value: "
<<
tau
;
throw
OpenMMException
(
message
.
str
());
}
double
friction
,
double
temperature
,
double
accuracy
)
:
ReferenceDynamics
(
numberOfAtoms
,
0.0
f
,
temperature
),
friction
(
friction
),
_accuracy
(
accuracy
)
{
xPrime
.
resize
(
numberOfAtoms
);
inverseMasses
.
resize
(
numberOfAtoms
);
}
...
...
@@ -68,13 +63,6 @@ ReferenceVariableStochasticDynamics::ReferenceVariableStochasticDynamics(int num
--------------------------------------------------------------------------------------- */
ReferenceVariableStochasticDynamics
::~
ReferenceVariableStochasticDynamics
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceVariableStochasticDynamics::~ReferenceVariableStochasticDynamics";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
...
...
@@ -85,7 +73,7 @@ ReferenceVariableStochasticDynamics::~ReferenceVariableStochasticDynamics() {
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceVariableStochasticDynamics
::
getAccuracy
()
const
{
double
ReferenceVariableStochasticDynamics
::
getAccuracy
()
const
{
return
_accuracy
;
}
...
...
@@ -95,27 +83,18 @@ RealOpenMM ReferenceVariableStochasticDynamics::getAccuracy() const {
--------------------------------------------------------------------------------------- */
void
ReferenceVariableStochasticDynamics
::
setAccuracy
(
RealOpenMM
accuracy
)
{
void
ReferenceVariableStochasticDynamics
::
setAccuracy
(
double
accuracy
)
{
_accuracy
=
accuracy
;
}
/**---------------------------------------------------------------------------------------
Get tau
@return tau
Get friction coefficient
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceVariableStochasticDynamics
::
getTau
()
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceVariableStochasticDynamics::getTau";
// ---------------------------------------------------------------------------------------
return
_tau
;
double
ReferenceVariableStochasticDynamics
::
getFriction
()
const
{
return
friction
;
}
/**---------------------------------------------------------------------------------------
...
...
@@ -133,18 +112,10 @@ RealOpenMM ReferenceVariableStochasticDynamics::getTau() const {
--------------------------------------------------------------------------------------- */
void
ReferenceVariableStochasticDynamics
::
updatePart1
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
masses
,
vector
<
RealOpenMM
>&
inverseMasses
,
vector
<
RealVec
>&
xPrime
,
RealOpenMM
maxStepSize
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVariableStochasticDynamics::updatePart1"
;
// ---------------------------------------------------------------------------------------
void
ReferenceVariableStochasticDynamics
::
updatePart1
(
int
numberOfAtoms
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
masses
,
vector
<
double
>&
inverseMasses
,
vector
<
Vec3
>&
xPrime
,
double
maxStepSize
)
{
// first-time-through initialization
if
(
getTimeStep
()
==
0
)
{
...
...
@@ -159,15 +130,15 @@ void ReferenceVariableStochasticDynamics::updatePart1(int numberOfAtoms, vector<
}
// Select the step size to use
RealOpenMM
error
=
0
;
double
error
=
0
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
RealOpenMM
xerror
=
inverseMasses
[
i
]
*
forces
[
i
][
j
];
double
xerror
=
inverseMasses
[
i
]
*
forces
[
i
][
j
];
error
+=
xerror
*
xerror
;
}
}
error
=
SQRT
(
error
/
(
numberOfAtoms
*
3
));
RealOpenMM
newStepSize
=
SQRT
(
getAccuracy
()
/
error
);
error
=
sqrt
(
error
/
(
numberOfAtoms
*
3
));
double
newStepSize
=
sqrt
(
getAccuracy
()
/
error
);
if
(
getDeltaT
()
>
0.0
f
)
newStepSize
=
std
::
min
(
newStepSize
,
getDeltaT
()
*
2.0
f
);
// For safety, limit how quickly dt can increase.
if
(
newStepSize
>
getDeltaT
()
&&
newStepSize
<
1.2
f
*
getDeltaT
())
...
...
@@ -178,15 +149,16 @@ void ReferenceVariableStochasticDynamics::updatePart1(int numberOfAtoms, vector<
// perform first update
RealOpenMM
tau
=
getTau
();
const
RealOpenMM
vscale
=
EXP
(
-
getDeltaT
()
/
tau
);
const
RealOpenMM
fscale
=
(
1
-
vscale
)
*
tau
;
const
RealOpenMM
kT
=
BOLTZ
*
getTemperature
();
const
RealOpenMM
noisescale
=
SQRT
(
2
*
kT
/
tau
)
*
SQRT
(
0.5
*
(
1
-
vscale
*
vscale
)
*
tau
);
double
dt
=
getDeltaT
();
double
friction
=
getFriction
();
const
double
vscale
=
exp
(
-
dt
*
friction
);
const
double
fscale
=
(
friction
==
0
?
dt
:
(
1
-
vscale
)
/
friction
);
const
double
kT
=
BOLTZ
*
getTemperature
();
const
double
noisescale
=
sqrt
(
kT
*
(
1
-
vscale
*
vscale
));
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
if
(
masses
[
ii
]
!=
0
)
{
RealOpenMM
sqrtInvMass
=
SQRT
(
inverseMasses
[
ii
]);
double
sqrtInvMass
=
sqrt
(
inverseMasses
[
ii
]);
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
)
{
velocities
[
ii
][
jj
]
=
vscale
*
velocities
[
ii
][
jj
]
+
fscale
*
inverseMasses
[
ii
]
*
forces
[
ii
][
jj
]
+
noisescale
*
sqrtInvMass
*
SimTKOpenMMUtilities
::
getNormallyDistributedRandomNumber
();
}
...
...
@@ -207,17 +179,10 @@ void ReferenceVariableStochasticDynamics::updatePart1(int numberOfAtoms, vector<
--------------------------------------------------------------------------------------- */
void
ReferenceVariableStochasticDynamics
::
updatePart2
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
inverseMasses
,
vector
<
RealVec
>&
xPrime
)
{
// ---------------------------------------------------------------------------------------
//static const char* methodName = "\nReferenceVariableStochasticDynamics::updatePart2";
// ---------------------------------------------------------------------------------------
void
ReferenceVariableStochasticDynamics
::
updatePart2
(
int
numberOfAtoms
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
inverseMasses
,
vector
<
Vec3
>&
xPrime
)
{
// perform second update
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
...
...
@@ -241,15 +206,9 @@ void ReferenceVariableStochasticDynamics::updatePart2(int numberOfAtoms, vector<
--------------------------------------------------------------------------------------- */
void
ReferenceVariableStochasticDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
masses
,
RealOpenMM
maxStepSize
,
RealOpenMM
tolerance
)
{
// ---------------------------------------------------------------------------------------
//static const char* methodName = "\nReferenceVariableStochasticDynamics::update";
// ---------------------------------------------------------------------------------------
void
ReferenceVariableStochasticDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
masses
,
double
maxStepSize
,
double
tolerance
)
{
// 1st update
...
...
@@ -266,11 +225,11 @@ void ReferenceVariableStochasticDynamics::update(const OpenMM::System& system, v
// copy xPrime -> atomCoordinates
double
invStepSize
=
1.0
/
getDeltaT
();
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
if
(
masses
[
ii
]
!=
0.0
)
{
atomCoordinates
[
ii
][
0
]
=
xPrime
[
ii
][
0
];
atomCoordinates
[
ii
][
1
]
=
xPrime
[
ii
][
1
];
atomCoordinates
[
ii
][
2
]
=
xPrime
[
ii
][
2
];
velocities
[
ii
]
=
(
xPrime
[
ii
]
-
atomCoordinates
[
ii
])
*
invStepSize
;
atomCoordinates
[
ii
]
=
xPrime
[
ii
];
}
}
...
...
platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp
View file @
047934e2
...
...
@@ -43,7 +43,7 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceVariableVerletDynamics
::
ReferenceVariableVerletDynamics
(
int
numberOfAtoms
,
RealOpenMM
accuracy
)
:
ReferenceVariableVerletDynamics
::
ReferenceVariableVerletDynamics
(
int
numberOfAtoms
,
double
accuracy
)
:
ReferenceDynamics
(
numberOfAtoms
,
0.0
f
,
0.0
f
),
_accuracy
(
accuracy
)
{
xPrime
.
resize
(
numberOfAtoms
);
inverseMasses
.
resize
(
numberOfAtoms
);
...
...
@@ -56,13 +56,6 @@ ReferenceVariableVerletDynamics::ReferenceVariableVerletDynamics(int numberOfAto
--------------------------------------------------------------------------------------- */
ReferenceVariableVerletDynamics
::~
ReferenceVariableVerletDynamics
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceVariableVerletDynamics::~ReferenceVariableVerletDynamics";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
...
...
@@ -73,7 +66,7 @@ ReferenceVariableVerletDynamics::~ReferenceVariableVerletDynamics() {
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceVariableVerletDynamics
::
getAccuracy
()
const
{
double
ReferenceVariableVerletDynamics
::
getAccuracy
()
const
{
return
_accuracy
;
}
...
...
@@ -83,7 +76,7 @@ RealOpenMM ReferenceVariableVerletDynamics::getAccuracy() const {
--------------------------------------------------------------------------------------- */
void
ReferenceVariableVerletDynamics
::
setAccuracy
(
RealOpenMM
accuracy
)
{
void
ReferenceVariableVerletDynamics
::
setAccuracy
(
double
accuracy
)
{
_accuracy
=
accuracy
;
}
...
...
@@ -101,19 +94,9 @@ void ReferenceVariableVerletDynamics::setAccuracy(RealOpenMM accuracy) {
--------------------------------------------------------------------------------------- */
void
ReferenceVariableVerletDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
masses
,
RealOpenMM
maxStepSize
,
RealOpenMM
tolerance
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVariableVerletDynamics::update"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
// ---------------------------------------------------------------------------------------
void
ReferenceVariableVerletDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
masses
,
double
maxStepSize
,
double
tolerance
)
{
// first-time-through initialization
int
numberOfAtoms
=
system
.
getNumParticles
();
...
...
@@ -121,34 +104,34 @@ void ReferenceVariableVerletDynamics::update(const OpenMM::System& system, vecto
// invert masses
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
if
(
masses
[
ii
]
==
zero
)
inverseMasses
[
ii
]
=
zero
;
if
(
masses
[
ii
]
==
0.0
)
inverseMasses
[
ii
]
=
0.0
;
else
inverseMasses
[
ii
]
=
one
/
masses
[
ii
];
inverseMasses
[
ii
]
=
1.0
/
masses
[
ii
];
}
}
RealOpenMM
error
=
zero
;
double
error
=
0.0
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
RealOpenMM
xerror
=
inverseMasses
[
i
]
*
forces
[
i
][
j
];
double
xerror
=
inverseMasses
[
i
]
*
forces
[
i
][
j
];
error
+=
xerror
*
xerror
;
}
}
error
=
SQRT
(
error
/
(
numberOfAtoms
*
3
));
RealOpenMM
newStepSize
=
SQRT
(
getAccuracy
()
/
error
);
error
=
sqrt
(
error
/
(
numberOfAtoms
*
3
));
double
newStepSize
=
sqrt
(
getAccuracy
()
/
error
);
if
(
getDeltaT
()
>
0.0
f
)
newStepSize
=
std
::
min
(
newStepSize
,
getDeltaT
()
*
2.0
f
);
// For safety, limit how quickly dt can increase.
if
(
newStepSize
>
getDeltaT
()
&&
newStepSize
<
1.2
f
*
getDeltaT
())
newStepSize
=
getDeltaT
();
// Keeping dt constant between steps improves the behavior of the integrator.
if
(
newStepSize
>
maxStepSize
)
newStepSize
=
maxStepSize
;
RealOpenMM
vstep
=
0.5
f
*
(
newStepSize
+
getDeltaT
());
// The time interval by which to advance the velocities
double
vstep
=
0.5
f
*
(
newStepSize
+
getDeltaT
());
// The time interval by which to advance the velocities
setDeltaT
(
newStepSize
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
if
(
masses
[
i
]
!=
zero
)
if
(
masses
[
i
]
!=
0.0
)
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
RealOpenMM
vPrime
=
velocities
[
i
][
j
]
+
inverseMasses
[
i
]
*
forces
[
i
][
j
]
*
vstep
;
double
vPrime
=
velocities
[
i
][
j
]
+
inverseMasses
[
i
]
*
forces
[
i
][
j
]
*
vstep
;
xPrime
[
i
][
j
]
=
atomCoordinates
[
i
][
j
]
+
vPrime
*
getDeltaT
();
}
}
...
...
@@ -158,9 +141,9 @@ void ReferenceVariableVerletDynamics::update(const OpenMM::System& system, vecto
// Update the positions and velocities.
RealOpenMM
velocityScale
=
one
/
getDeltaT
();
double
velocityScale
=
1.0
/
getDeltaT
();
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
if
(
masses
[
i
]
!=
zero
)
if
(
masses
[
i
]
!=
0.0
)
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
velocities
[
i
][
j
]
=
velocityScale
*
(
xPrime
[
i
][
j
]
-
atomCoordinates
[
i
][
j
]);
atomCoordinates
[
i
][
j
]
=
xPrime
[
i
][
j
];
...
...
platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp
View file @
047934e2
...
...
@@ -45,18 +45,8 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceVerletDynamics
::
ReferenceVerletDynamics
(
int
numberOfAtoms
,
RealOpenMM
deltaT
)
:
ReferenceVerletDynamics
::
ReferenceVerletDynamics
(
int
numberOfAtoms
,
double
deltaT
)
:
ReferenceDynamics
(
numberOfAtoms
,
deltaT
,
0.0
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVerletDynamics::ReferenceVerletDynamics"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
// ---------------------------------------------------------------------------------------
xPrime
.
resize
(
numberOfAtoms
);
inverseMasses
.
resize
(
numberOfAtoms
);
}
...
...
@@ -68,13 +58,6 @@ ReferenceVerletDynamics::ReferenceVerletDynamics(int numberOfAtoms, RealOpenMM d
--------------------------------------------------------------------------------------- */
ReferenceVerletDynamics
::~
ReferenceVerletDynamics
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceVerletDynamics::~ReferenceVerletDynamics";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
...
...
@@ -90,19 +73,9 @@ ReferenceVerletDynamics::~ReferenceVerletDynamics() {
--------------------------------------------------------------------------------------- */
void
ReferenceVerletDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealVec
>&
forces
,
vector
<
RealOpenMM
>&
masses
,
RealOpenMM
tolerance
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceVerletDynamics::update"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
// ---------------------------------------------------------------------------------------
void
ReferenceVerletDynamics
::
update
(
const
OpenMM
::
System
&
system
,
vector
<
Vec3
>&
atomCoordinates
,
vector
<
Vec3
>&
velocities
,
vector
<
Vec3
>&
forces
,
vector
<
double
>&
masses
,
double
tolerance
)
{
// first-time-through initialization
int
numberOfAtoms
=
system
.
getNumParticles
();
...
...
@@ -110,17 +83,17 @@ void ReferenceVerletDynamics::update(const OpenMM::System& system, vector<RealVe
// invert masses
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
)
{
if
(
masses
[
ii
]
==
zero
)
inverseMasses
[
ii
]
=
zero
;
if
(
masses
[
ii
]
==
0.0
)
inverseMasses
[
ii
]
=
0.0
;
else
inverseMasses
[
ii
]
=
one
/
masses
[
ii
];
inverseMasses
[
ii
]
=
1.0
/
masses
[
ii
];
}
}
// Perform the integration.
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
if
(
masses
[
i
]
!=
zero
)
if
(
masses
[
i
]
!=
0.0
)
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
velocities
[
i
][
j
]
+=
inverseMasses
[
i
]
*
forces
[
i
][
j
]
*
getDeltaT
();
xPrime
[
i
][
j
]
=
atomCoordinates
[
i
][
j
]
+
velocities
[
i
][
j
]
*
getDeltaT
();
...
...
@@ -132,9 +105,9 @@ void ReferenceVerletDynamics::update(const OpenMM::System& system, vector<RealVe
// Update the positions and velocities.
RealOpenMM
velocityScale
=
static_cast
<
RealOpenMM
>
(
1.0
/
getDeltaT
());
double
velocityScale
=
static_cast
<
double
>
(
1.0
/
getDeltaT
());
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
++
i
)
{
if
(
masses
[
i
]
!=
zero
)
if
(
masses
[
i
]
!=
0.0
)
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
velocities
[
i
][
j
]
=
velocityScale
*
(
xPrime
[
i
][
j
]
-
atomCoordinates
[
i
][
j
]);
atomCoordinates
[
i
][
j
]
=
xPrime
[
i
][
j
];
...
...
platforms/reference/src/SimTKReference/ReferenceVirtualSites.cpp
View file @
047934e2
...
...
@@ -31,11 +31,12 @@
#include "ReferenceVirtualSites.h"
#include "openmm/VirtualSite.h"
#include <cmath>
using
namespace
OpenMM
;
using
namespace
std
;
void
ReferenceVirtualSites
::
computePositions
(
const
OpenMM
::
System
&
system
,
vector
<
OpenMM
::
Real
Vec
>&
atomCoordinates
)
{
void
ReferenceVirtualSites
::
computePositions
(
const
OpenMM
::
System
&
system
,
vector
<
OpenMM
::
Vec
3
>&
atomCoordinates
)
{
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
if
(
system
.
isVirtualSite
(
i
))
{
if
(
dynamic_cast
<
const
TwoParticleAverageSite
*>
(
&
system
.
getVirtualSite
(
i
))
!=
NULL
)
{
...
...
@@ -43,7 +44,7 @@ void ReferenceVirtualSites::computePositions(const OpenMM::System& system, vecto
const
TwoParticleAverageSite
&
site
=
dynamic_cast
<
const
TwoParticleAverageSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
);
RealOpenMM
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
);
double
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
);
atomCoordinates
[
i
]
=
atomCoordinates
[
p1
]
*
w1
+
atomCoordinates
[
p2
]
*
w2
;
}
else
if
(
dynamic_cast
<
const
ThreeParticleAverageSite
*>
(
&
system
.
getVirtualSite
(
i
))
!=
NULL
)
{
...
...
@@ -51,7 +52,7 @@ void ReferenceVirtualSites::computePositions(const OpenMM::System& system, vecto
const
ThreeParticleAverageSite
&
site
=
dynamic_cast
<
const
ThreeParticleAverageSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
RealOpenMM
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
),
w3
=
site
.
getWeight
(
2
);
double
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
),
w3
=
site
.
getWeight
(
2
);
atomCoordinates
[
i
]
=
atomCoordinates
[
p1
]
*
w1
+
atomCoordinates
[
p2
]
*
w2
+
atomCoordinates
[
p3
]
*
w3
;
}
else
if
(
dynamic_cast
<
const
OutOfPlaneSite
*>
(
&
system
.
getVirtualSite
(
i
))
!=
NULL
)
{
...
...
@@ -59,10 +60,10 @@ void ReferenceVirtualSites::computePositions(const OpenMM::System& system, vecto
const
OutOfPlaneSite
&
site
=
dynamic_cast
<
const
OutOfPlaneSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
RealOpenMM
w12
=
site
.
getWeight12
(),
w13
=
site
.
getWeight13
(),
wcross
=
site
.
getWeightCross
();
Real
Vec
v12
=
atomCoordinates
[
p2
]
-
atomCoordinates
[
p1
];
Real
Vec
v13
=
atomCoordinates
[
p3
]
-
atomCoordinates
[
p1
];
Real
Vec
cross
=
v12
.
cross
(
v13
);
double
w12
=
site
.
getWeight12
(),
w13
=
site
.
getWeight13
(),
wcross
=
site
.
getWeightCross
();
Vec
3
v12
=
atomCoordinates
[
p2
]
-
atomCoordinates
[
p1
];
Vec
3
v13
=
atomCoordinates
[
p3
]
-
atomCoordinates
[
p1
];
Vec
3
cross
=
v12
.
cross
(
v13
);
atomCoordinates
[
i
]
=
atomCoordinates
[
p1
]
+
v12
*
w12
+
v13
*
w13
+
cross
*
wcross
;
}
else
if
(
dynamic_cast
<
const
LocalCoordinatesSite
*>
(
&
system
.
getVirtualSite
(
i
))
!=
NULL
)
{
...
...
@@ -70,14 +71,14 @@ void ReferenceVirtualSites::computePositions(const OpenMM::System& system, vecto
const
LocalCoordinatesSite
&
site
=
dynamic_cast
<
const
LocalCoordinatesSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
Real
Vec
originWeights
=
site
.
getOriginWeights
();
Real
Vec
xWeights
=
site
.
getXWeights
();
Real
Vec
yWeights
=
site
.
getYWeights
();
Real
Vec
localPosition
=
site
.
getLocalPosition
();
Real
Vec
origin
=
atomCoordinates
[
p1
]
*
originWeights
[
0
]
+
atomCoordinates
[
p2
]
*
originWeights
[
1
]
+
atomCoordinates
[
p3
]
*
originWeights
[
2
];
Real
Vec
xdir
=
atomCoordinates
[
p1
]
*
xWeights
[
0
]
+
atomCoordinates
[
p2
]
*
xWeights
[
1
]
+
atomCoordinates
[
p3
]
*
xWeights
[
2
];
Real
Vec
ydir
=
atomCoordinates
[
p1
]
*
yWeights
[
0
]
+
atomCoordinates
[
p2
]
*
yWeights
[
1
]
+
atomCoordinates
[
p3
]
*
yWeights
[
2
];
Real
Vec
zdir
=
xdir
.
cross
(
ydir
);
Vec
3
originWeights
=
site
.
getOriginWeights
();
Vec
3
xWeights
=
site
.
getXWeights
();
Vec
3
yWeights
=
site
.
getYWeights
();
Vec
3
localPosition
=
site
.
getLocalPosition
();
Vec
3
origin
=
atomCoordinates
[
p1
]
*
originWeights
[
0
]
+
atomCoordinates
[
p2
]
*
originWeights
[
1
]
+
atomCoordinates
[
p3
]
*
originWeights
[
2
];
Vec
3
xdir
=
atomCoordinates
[
p1
]
*
xWeights
[
0
]
+
atomCoordinates
[
p2
]
*
xWeights
[
1
]
+
atomCoordinates
[
p3
]
*
xWeights
[
2
];
Vec
3
ydir
=
atomCoordinates
[
p1
]
*
yWeights
[
0
]
+
atomCoordinates
[
p2
]
*
yWeights
[
1
]
+
atomCoordinates
[
p3
]
*
yWeights
[
2
];
Vec
3
zdir
=
xdir
.
cross
(
ydir
);
xdir
/=
sqrt
(
xdir
.
dot
(
xdir
));
zdir
/=
sqrt
(
zdir
.
dot
(
zdir
));
ydir
=
zdir
.
cross
(
xdir
);
...
...
@@ -87,16 +88,16 @@ void ReferenceVirtualSites::computePositions(const OpenMM::System& system, vecto
}
void
ReferenceVirtualSites
::
distributeForces
(
const
OpenMM
::
System
&
system
,
const
vector
<
OpenMM
::
Real
Vec
>&
atomCoordinates
,
vector
<
OpenMM
::
Real
Vec
>&
forces
)
{
void
ReferenceVirtualSites
::
distributeForces
(
const
OpenMM
::
System
&
system
,
const
vector
<
OpenMM
::
Vec
3
>&
atomCoordinates
,
vector
<
OpenMM
::
Vec
3
>&
forces
)
{
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
if
(
system
.
isVirtualSite
(
i
))
{
Real
Vec
f
=
forces
[
i
];
Vec
3
f
=
forces
[
i
];
if
(
dynamic_cast
<
const
TwoParticleAverageSite
*>
(
&
system
.
getVirtualSite
(
i
))
!=
NULL
)
{
// A two particle average.
const
TwoParticleAverageSite
&
site
=
dynamic_cast
<
const
TwoParticleAverageSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
);
RealOpenMM
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
);
double
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
);
forces
[
p1
]
+=
f
*
w1
;
forces
[
p2
]
+=
f
*
w2
;
}
...
...
@@ -105,7 +106,7 @@ void ReferenceVirtualSites::distributeForces(const OpenMM::System& system, const
const
ThreeParticleAverageSite
&
site
=
dynamic_cast
<
const
ThreeParticleAverageSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
RealOpenMM
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
),
w3
=
site
.
getWeight
(
2
);
double
w1
=
site
.
getWeight
(
0
),
w2
=
site
.
getWeight
(
1
),
w3
=
site
.
getWeight
(
2
);
forces
[
p1
]
+=
f
*
w1
;
forces
[
p2
]
+=
f
*
w2
;
forces
[
p3
]
+=
f
*
w3
;
...
...
@@ -115,15 +116,15 @@ void ReferenceVirtualSites::distributeForces(const OpenMM::System& system, const
const
OutOfPlaneSite
&
site
=
dynamic_cast
<
const
OutOfPlaneSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
RealOpenMM
w12
=
site
.
getWeight12
(),
w13
=
site
.
getWeight13
(),
wcross
=
site
.
getWeightCross
();
Real
Vec
v12
=
atomCoordinates
[
p2
]
-
atomCoordinates
[
p1
];
Real
Vec
v13
=
atomCoordinates
[
p3
]
-
atomCoordinates
[
p1
];
Real
Vec
f2
(
w12
*
f
[
0
]
-
wcross
*
v13
[
2
]
*
f
[
1
]
+
wcross
*
v13
[
1
]
*
f
[
2
],
wcross
*
v13
[
2
]
*
f
[
0
]
+
w12
*
f
[
1
]
-
wcross
*
v13
[
0
]
*
f
[
2
],
-
wcross
*
v13
[
1
]
*
f
[
0
]
+
wcross
*
v13
[
0
]
*
f
[
1
]
+
w12
*
f
[
2
]);
Real
Vec
f3
(
w13
*
f
[
0
]
+
wcross
*
v12
[
2
]
*
f
[
1
]
-
wcross
*
v12
[
1
]
*
f
[
2
],
-
wcross
*
v12
[
2
]
*
f
[
0
]
+
w13
*
f
[
1
]
+
wcross
*
v12
[
0
]
*
f
[
2
],
wcross
*
v12
[
1
]
*
f
[
0
]
-
wcross
*
v12
[
0
]
*
f
[
1
]
+
w13
*
f
[
2
]);
double
w12
=
site
.
getWeight12
(),
w13
=
site
.
getWeight13
(),
wcross
=
site
.
getWeightCross
();
Vec
3
v12
=
atomCoordinates
[
p2
]
-
atomCoordinates
[
p1
];
Vec
3
v13
=
atomCoordinates
[
p3
]
-
atomCoordinates
[
p1
];
Vec
3
f2
(
w12
*
f
[
0
]
-
wcross
*
v13
[
2
]
*
f
[
1
]
+
wcross
*
v13
[
1
]
*
f
[
2
],
wcross
*
v13
[
2
]
*
f
[
0
]
+
w12
*
f
[
1
]
-
wcross
*
v13
[
0
]
*
f
[
2
],
-
wcross
*
v13
[
1
]
*
f
[
0
]
+
wcross
*
v13
[
0
]
*
f
[
1
]
+
w12
*
f
[
2
]);
Vec
3
f3
(
w13
*
f
[
0
]
+
wcross
*
v12
[
2
]
*
f
[
1
]
-
wcross
*
v12
[
1
]
*
f
[
2
],
-
wcross
*
v12
[
2
]
*
f
[
0
]
+
w13
*
f
[
1
]
+
wcross
*
v12
[
0
]
*
f
[
2
],
wcross
*
v12
[
1
]
*
f
[
0
]
-
wcross
*
v12
[
0
]
*
f
[
1
]
+
w13
*
f
[
2
]);
forces
[
p1
]
+=
f
-
f2
-
f3
;
forces
[
p2
]
+=
f2
;
forces
[
p3
]
+=
f3
;
...
...
@@ -133,43 +134,43 @@ void ReferenceVirtualSites::distributeForces(const OpenMM::System& system, const
const
LocalCoordinatesSite
&
site
=
dynamic_cast
<
const
LocalCoordinatesSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
Real
Vec
originWeights
=
site
.
getOriginWeights
();
Real
Vec
wx
=
site
.
getXWeights
();
Real
Vec
wy
=
site
.
getYWeights
();
Real
Vec
localPosition
=
site
.
getLocalPosition
();
Real
Vec
xdir
=
atomCoordinates
[
p1
]
*
wx
[
0
]
+
atomCoordinates
[
p2
]
*
wx
[
1
]
+
atomCoordinates
[
p3
]
*
wx
[
2
];
Real
Vec
ydir
=
atomCoordinates
[
p1
]
*
wy
[
0
]
+
atomCoordinates
[
p2
]
*
wy
[
1
]
+
atomCoordinates
[
p3
]
*
wy
[
2
];
Real
Vec
zdir
=
xdir
.
cross
(
ydir
);
RealOpenMM
invNormXdir
=
1.0
/
SQRT
(
xdir
.
dot
(
xdir
));
RealOpenMM
invNormZdir
=
1.0
/
SQRT
(
zdir
.
dot
(
zdir
));
Real
Vec
dx
=
xdir
*
invNormXdir
;
Real
Vec
dz
=
zdir
*
invNormZdir
;
Real
Vec
dy
=
dz
.
cross
(
dx
);
Vec
3
originWeights
=
site
.
getOriginWeights
();
Vec
3
wx
=
site
.
getXWeights
();
Vec
3
wy
=
site
.
getYWeights
();
Vec
3
localPosition
=
site
.
getLocalPosition
();
Vec
3
xdir
=
atomCoordinates
[
p1
]
*
wx
[
0
]
+
atomCoordinates
[
p2
]
*
wx
[
1
]
+
atomCoordinates
[
p3
]
*
wx
[
2
];
Vec
3
ydir
=
atomCoordinates
[
p1
]
*
wy
[
0
]
+
atomCoordinates
[
p2
]
*
wy
[
1
]
+
atomCoordinates
[
p3
]
*
wy
[
2
];
Vec
3
zdir
=
xdir
.
cross
(
ydir
);
double
invNormXdir
=
1.0
/
sqrt
(
xdir
.
dot
(
xdir
));
double
invNormZdir
=
1.0
/
sqrt
(
zdir
.
dot
(
zdir
));
Vec
3
dx
=
xdir
*
invNormXdir
;
Vec
3
dz
=
zdir
*
invNormZdir
;
Vec
3
dy
=
dz
.
cross
(
dx
);
// The derivatives for this case are very complicated. They were computed with SymPy then simplified by hand.
RealOpenMM
t11
=
(
wx
[
0
]
*
ydir
[
0
]
-
wy
[
0
]
*
xdir
[
0
])
*
invNormZdir
;
RealOpenMM
t12
=
(
wx
[
0
]
*
ydir
[
1
]
-
wy
[
0
]
*
xdir
[
1
])
*
invNormZdir
;
RealOpenMM
t13
=
(
wx
[
0
]
*
ydir
[
2
]
-
wy
[
0
]
*
xdir
[
2
])
*
invNormZdir
;
RealOpenMM
t21
=
(
wx
[
1
]
*
ydir
[
0
]
-
wy
[
1
]
*
xdir
[
0
])
*
invNormZdir
;
RealOpenMM
t22
=
(
wx
[
1
]
*
ydir
[
1
]
-
wy
[
1
]
*
xdir
[
1
])
*
invNormZdir
;
RealOpenMM
t23
=
(
wx
[
1
]
*
ydir
[
2
]
-
wy
[
1
]
*
xdir
[
2
])
*
invNormZdir
;
RealOpenMM
t31
=
(
wx
[
2
]
*
ydir
[
0
]
-
wy
[
2
]
*
xdir
[
0
])
*
invNormZdir
;
RealOpenMM
t32
=
(
wx
[
2
]
*
ydir
[
1
]
-
wy
[
2
]
*
xdir
[
1
])
*
invNormZdir
;
RealOpenMM
t33
=
(
wx
[
2
]
*
ydir
[
2
]
-
wy
[
2
]
*
xdir
[
2
])
*
invNormZdir
;
RealOpenMM
sx1
=
t13
*
dz
[
1
]
-
t12
*
dz
[
2
];
RealOpenMM
sy1
=
t11
*
dz
[
2
]
-
t13
*
dz
[
0
];
RealOpenMM
sz1
=
t12
*
dz
[
0
]
-
t11
*
dz
[
1
];
RealOpenMM
sx2
=
t23
*
dz
[
1
]
-
t22
*
dz
[
2
];
RealOpenMM
sy2
=
t21
*
dz
[
2
]
-
t23
*
dz
[
0
];
RealOpenMM
sz2
=
t22
*
dz
[
0
]
-
t21
*
dz
[
1
];
RealOpenMM
sx3
=
t33
*
dz
[
1
]
-
t32
*
dz
[
2
];
RealOpenMM
sy3
=
t31
*
dz
[
2
]
-
t33
*
dz
[
0
];
RealOpenMM
sz3
=
t32
*
dz
[
0
]
-
t31
*
dz
[
1
];
Real
Vec
wxScaled
=
wx
*
invNormXdir
;
Real
Vec
fp1
=
localPosition
*
f
[
0
];
Real
Vec
fp2
=
localPosition
*
f
[
1
];
Real
Vec
fp3
=
localPosition
*
f
[
2
];
double
t11
=
(
wx
[
0
]
*
ydir
[
0
]
-
wy
[
0
]
*
xdir
[
0
])
*
invNormZdir
;
double
t12
=
(
wx
[
0
]
*
ydir
[
1
]
-
wy
[
0
]
*
xdir
[
1
])
*
invNormZdir
;
double
t13
=
(
wx
[
0
]
*
ydir
[
2
]
-
wy
[
0
]
*
xdir
[
2
])
*
invNormZdir
;
double
t21
=
(
wx
[
1
]
*
ydir
[
0
]
-
wy
[
1
]
*
xdir
[
0
])
*
invNormZdir
;
double
t22
=
(
wx
[
1
]
*
ydir
[
1
]
-
wy
[
1
]
*
xdir
[
1
])
*
invNormZdir
;
double
t23
=
(
wx
[
1
]
*
ydir
[
2
]
-
wy
[
1
]
*
xdir
[
2
])
*
invNormZdir
;
double
t31
=
(
wx
[
2
]
*
ydir
[
0
]
-
wy
[
2
]
*
xdir
[
0
])
*
invNormZdir
;
double
t32
=
(
wx
[
2
]
*
ydir
[
1
]
-
wy
[
2
]
*
xdir
[
1
])
*
invNormZdir
;
double
t33
=
(
wx
[
2
]
*
ydir
[
2
]
-
wy
[
2
]
*
xdir
[
2
])
*
invNormZdir
;
double
sx1
=
t13
*
dz
[
1
]
-
t12
*
dz
[
2
];
double
sy1
=
t11
*
dz
[
2
]
-
t13
*
dz
[
0
];
double
sz1
=
t12
*
dz
[
0
]
-
t11
*
dz
[
1
];
double
sx2
=
t23
*
dz
[
1
]
-
t22
*
dz
[
2
];
double
sy2
=
t21
*
dz
[
2
]
-
t23
*
dz
[
0
];
double
sz2
=
t22
*
dz
[
0
]
-
t21
*
dz
[
1
];
double
sx3
=
t33
*
dz
[
1
]
-
t32
*
dz
[
2
];
double
sy3
=
t31
*
dz
[
2
]
-
t33
*
dz
[
0
];
double
sz3
=
t32
*
dz
[
0
]
-
t31
*
dz
[
1
];
Vec
3
wxScaled
=
wx
*
invNormXdir
;
Vec
3
fp1
=
localPosition
*
f
[
0
];
Vec
3
fp2
=
localPosition
*
f
[
1
];
Vec
3
fp3
=
localPosition
*
f
[
2
];
forces
[
p1
][
0
]
+=
fp1
[
0
]
*
wxScaled
[
0
]
*
(
1
-
dx
[
0
]
*
dx
[
0
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sx1
)
+
fp1
[
1
]
*
((
-
dx
[
0
]
*
dy
[
0
]
)
*
wxScaled
[
0
]
+
dy
[
0
]
*
sx1
-
dx
[
1
]
*
t12
-
dx
[
2
]
*
t13
)
+
f
[
0
]
*
originWeights
[
0
];
forces
[
p1
][
1
]
+=
fp1
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
0
]
*
dx
[
1
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sy1
+
t13
)
+
fp1
[
1
]
*
((
-
dx
[
1
]
*
dy
[
0
]
-
dz
[
2
])
*
wxScaled
[
0
]
+
dy
[
0
]
*
sy1
+
dx
[
1
]
*
t11
);
forces
[
p1
][
2
]
+=
fp1
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
0
]
*
dx
[
2
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sz1
-
t12
)
+
fp1
[
1
]
*
((
-
dx
[
2
]
*
dy
[
0
]
+
dz
[
1
])
*
wxScaled
[
0
]
+
dy
[
0
]
*
sz1
+
dx
[
2
]
*
t11
);
...
...
platforms/reference/src/SimTKReference/SimTKOpenMMUtilities.cpp
View file @
047934e2
...
...
@@ -40,12 +40,12 @@ using namespace OpenMM;
uint32_t
SimTKOpenMMUtilities
::
_randomNumberSeed
=
0
;
bool
SimTKOpenMMUtilities
::
_randomInitialized
=
false
;
bool
SimTKOpenMMUtilities
::
nextGaussianIsValid
=
false
;
RealOpenMM
SimTKOpenMMUtilities
::
nextGaussian
=
0
;
double
SimTKOpenMMUtilities
::
nextGaussian
=
0
;
OpenMM_SFMT
::
SFMT
SimTKOpenMMUtilities
::
sfmt
;
/* ---------------------------------------------------------------------------------------
Allocate 1D
RealOpenMM
array (Simbios)
Allocate 1D
double
array (Simbios)
array[i]
...
...
@@ -59,27 +59,18 @@ OpenMM_SFMT::SFMT SimTKOpenMMUtilities::sfmt;
--------------------------------------------------------------------------------------- */
RealOpenMM
*
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
int
iSize
,
RealOpenMM
*
array1D
,
int
initialize
,
RealOpenMM
initialValue
,
double
*
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
int
iSize
,
double
*
array1D
,
int
initialize
,
double
initialValue
,
const
std
::
string
&
idString
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nSimTKOpenMMUtilities::allocate1DRealOpenMMArray";
static
const
RealOpenMM
zero
=
0.0
;
// ---------------------------------------------------------------------------------------
if
(
array1D
==
NULL
)
{
array1D
=
new
RealOpenMM
[
iSize
];
array1D
=
new
double
[
iSize
];
}
if
(
initialize
)
{
if
(
initialValue
==
zero
)
{
memset
(
array1D
,
0
,
iSize
*
sizeof
(
RealOpenMM
));
if
(
initialValue
==
0.0
)
{
memset
(
array1D
,
0
,
iSize
*
sizeof
(
double
));
}
else
{
for
(
int
ii
=
0
;
ii
<
iSize
;
ii
++
)
{
array1D
[
ii
]
=
initialValue
;
...
...
@@ -92,7 +83,7 @@ RealOpenMM* SimTKOpenMMUtilities::allocateOneDRealOpenMMArray(int iSize, RealOpe
/* ---------------------------------------------------------------------------------------
Allocate 2D
RealOpenMM
array (Simbios)
Allocate 2D
double
array (Simbios)
array[i][j]
...
...
@@ -107,23 +98,16 @@ RealOpenMM* SimTKOpenMMUtilities::allocateOneDRealOpenMMArray(int iSize, RealOpe
--------------------------------------------------------------------------------------- */
RealOpenMM
**
SimTKOpenMMUtilities
::
allocateTwoDRealOpenMMArray
(
int
iSize
,
int
jSize
,
RealOpenMM
**
array2D
,
int
initialize
,
RealOpenMM
initialValue
,
double
**
SimTKOpenMMUtilities
::
allocateTwoDRealOpenMMArray
(
int
iSize
,
int
jSize
,
double
**
array2D
,
int
initialize
,
double
initialValue
,
const
std
::
string
&
idString
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nSimTKOpenMMUtilities::allocate2DRealOpenMMArray";
// ---------------------------------------------------------------------------------------
if
(
array2D
==
NULL
)
{
array2D
=
new
RealOpenMM
*
[
iSize
];
array2D
=
new
double
*
[
iSize
];
std
::
string
blockString
=
idString
;
blockString
.
append
(
"Block"
);
RealOpenMM
*
block
=
new
RealOpenMM
[
jSize
*
iSize
];
double
*
block
=
new
double
[
jSize
*
iSize
];
for
(
int
ii
=
0
;
ii
<
iSize
;
ii
++
)
{
array2D
[
ii
]
=
block
;
...
...
@@ -140,7 +124,7 @@ RealOpenMM** SimTKOpenMMUtilities::allocateTwoDRealOpenMMArray(int iSize, int jS
/* ---------------------------------------------------------------------------------------
Free 2D
RealOpenMM
array (Simbios)
Free 2D
double
array (Simbios)
array[i][j]
...
...
@@ -149,14 +133,7 @@ RealOpenMM** SimTKOpenMMUtilities::allocateTwoDRealOpenMMArray(int iSize, int jS
--------------------------------------------------------------------------------------- */
void
SimTKOpenMMUtilities
::
freeTwoDRealOpenMMArray
(
RealOpenMM
**
array2D
,
const
std
::
string
&
idString
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nSimTKOpenMMUtilities::freeTwoDRealOpenMMArray";
// ---------------------------------------------------------------------------------------
void
SimTKOpenMMUtilities
::
freeTwoDRealOpenMMArray
(
double
**
array2D
,
const
std
::
string
&
idString
)
{
if
(
array2D
!=
NULL
)
{
std
::
string
blockString
=
idString
;
...
...
@@ -169,7 +146,7 @@ void SimTKOpenMMUtilities::freeTwoDRealOpenMMArray(RealOpenMM** array2D, const s
/* ---------------------------------------------------------------------------------------
Free 1D
RealOpenMM
array (Simbios)
Free 1D
double
array (Simbios)
array[i]
...
...
@@ -178,14 +155,7 @@ void SimTKOpenMMUtilities::freeTwoDRealOpenMMArray(RealOpenMM** array2D, const s
--------------------------------------------------------------------------------------- */
void
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
RealOpenMM
*
array1D
,
const
std
::
string
&
idString
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nSimTKOpenMMUtilities::freeOneDRealOpenMMArray";
// ---------------------------------------------------------------------------------------
void
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
double
*
array1D
,
const
std
::
string
&
idString
)
{
if
(
array1D
!=
NULL
)
{
delete
[]
array1D
;
}
...
...
@@ -193,7 +163,7 @@ void SimTKOpenMMUtilities::freeOneDRealOpenMMArray(RealOpenMM* array1D, const st
/* ---------------------------------------------------------------------------------------
Initialize 2D
RealOpenMM
array (Simbios)
Initialize 2D
double
array (Simbios)
array[i][j]
...
...
@@ -205,15 +175,8 @@ void SimTKOpenMMUtilities::freeOneDRealOpenMMArray(RealOpenMM* array1D, const st
--------------------------------------------------------------------------------------- */
void
SimTKOpenMMUtilities
::
initialize2DRealOpenMMArray
(
int
iSize
,
int
jSize
,
RealOpenMM
**
array2D
,
RealOpenMM
initialValue
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nSimTKOpenMMUtilities::initialize2DRealOpenMMArray";
// ---------------------------------------------------------------------------------------
double
**
array2D
,
double
initialValue
)
{
bool
useMemset
;
bool
useMemsetSingleBlock
;
...
...
@@ -231,10 +194,10 @@ void SimTKOpenMMUtilities::initialize2DRealOpenMMArray(int iSize, int jSize,
if
(
useMemset
)
{
if
(
useMemsetSingleBlock
)
{
memset
(
array2D
[
0
],
0
,
iSize
*
jSize
*
sizeof
(
RealOpenMM
));
memset
(
array2D
[
0
],
0
,
iSize
*
jSize
*
sizeof
(
double
));
}
else
{
for
(
int
ii
=
0
;
ii
<
iSize
;
ii
++
)
{
memset
(
array2D
[
ii
],
0
,
jSize
*
sizeof
(
RealOpenMM
));
memset
(
array2D
[
ii
],
0
,
jSize
*
sizeof
(
double
));
}
}
}
else
{
...
...
@@ -260,16 +223,9 @@ void SimTKOpenMMUtilities::initialize2DRealOpenMMArray(int iSize, int jSize,
--------------------------------------------------------------------------------------- */
void
SimTKOpenMMUtilities
::
crossProductVector3
(
RealOpenMM
*
vectorX
,
RealOpenMM
*
vectorY
,
RealOpenMM
*
vectorZ
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nSimTKOpenMMUtilities::crossProductVector3";
// ---------------------------------------------------------------------------------------
void
SimTKOpenMMUtilities
::
crossProductVector3
(
double
*
vectorX
,
double
*
vectorY
,
double
*
vectorZ
)
{
vectorZ
[
0
]
=
vectorX
[
1
]
*
vectorY
[
2
]
-
vectorX
[
2
]
*
vectorY
[
1
];
vectorZ
[
1
]
=
vectorX
[
2
]
*
vectorY
[
0
]
-
vectorX
[
0
]
*
vectorY
[
2
];
vectorZ
[
2
]
=
vectorX
[
0
]
*
vectorY
[
1
]
-
vectorX
[
1
]
*
vectorY
[
0
];
...
...
@@ -285,7 +241,7 @@ void SimTKOpenMMUtilities::crossProductVector3(RealOpenMM* vectorX,
--------------------------------------------------------------------------------------- */
RealOpenMM
SimTKOpenMMUtilities
::
getNormallyDistributedRandomNumber
()
{
double
SimTKOpenMMUtilities
::
getNormallyDistributedRandomNumber
()
{
if
(
nextGaussianIsValid
)
{
nextGaussianIsValid
=
false
;
return
nextGaussian
;
...
...
@@ -298,13 +254,13 @@ RealOpenMM SimTKOpenMMUtilities::getNormallyDistributedRandomNumber() {
// Use the polar form of the Box-Muller transformation to generate two Gaussian random numbers.
RealOpenMM
x
,
y
,
r2
;
double
x
,
y
,
r2
;
do
{
x
=
static_cast
<
RealOpenMM
>
(
2.0
*
genrand_real2
(
sfmt
)
-
1.0
)
;
y
=
static_cast
<
RealOpenMM
>
(
2.0
*
genrand_real2
(
sfmt
)
-
1.0
)
;
x
=
2.0
*
genrand_real2
(
sfmt
)
-
1.0
;
y
=
2.0
*
genrand_real2
(
sfmt
)
-
1.0
;
r2
=
x
*
x
+
y
*
y
;
}
while
(
r2
>=
1.0
||
r2
==
0.0
);
RealOpenMM
multiplier
=
static_cast
<
RealOpenMM
>
(
sqrt
((
-
2.0
*
log
(
r2
))
/
r2
)
)
;
double
multiplier
=
sqrt
((
-
2.0
*
log
(
r2
))
/
r2
);
nextGaussian
=
y
*
multiplier
;
nextGaussianIsValid
=
true
;
return
x
*
multiplier
;
...
...
@@ -318,13 +274,13 @@ RealOpenMM SimTKOpenMMUtilities::getNormallyDistributedRandomNumber() {
--------------------------------------------------------------------------------------- */
RealOpenMM
SimTKOpenMMUtilities
::
getUniformlyDistributedRandomNumber
()
{
double
SimTKOpenMMUtilities
::
getUniformlyDistributedRandomNumber
()
{
if
(
!
_randomInitialized
)
{
init_gen_rand
(
_randomNumberSeed
,
sfmt
);
_randomInitialized
=
true
;
nextGaussianIsValid
=
false
;
}
RealOpenMM
value
=
static_cast
<
RealOpenMM
>
(
genrand_real2
(
sfmt
)
)
;
double
value
=
genrand_real2
(
sfmt
);
return
value
;
}
...
...
@@ -337,13 +293,6 @@ RealOpenMM SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() {
--------------------------------------------------------------------------------------- */
uint32_t
SimTKOpenMMUtilities
::
getRandomNumberSeed
()
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getRandomNumberSeed";
// ---------------------------------------------------------------------------------------
return
_randomNumberSeed
;
}
...
...
@@ -356,13 +305,6 @@ uint32_t SimTKOpenMMUtilities::getRandomNumberSeed() {
--------------------------------------------------------------------------------------- */
void
SimTKOpenMMUtilities
::
setRandomNumberSeed
(
uint32_t
seed
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::setRandomNumberSeed";
// ---------------------------------------------------------------------------------------
// If the seed is 0, use a unique seed
if
(
seed
==
0
)
_randomNumberSeed
=
(
uint32_t
)
osrngseed
();
...
...
@@ -376,7 +318,7 @@ void SimTKOpenMMUtilities::createCheckpoint(std::ostream& stream) {
stream
.
write
((
char
*
)
&
_randomInitialized
,
sizeof
(
bool
));
if
(
_randomInitialized
)
{
stream
.
write
((
char
*
)
&
nextGaussianIsValid
,
sizeof
(
bool
));
stream
.
write
((
char
*
)
&
nextGaussian
,
sizeof
(
RealOpenMM
));
stream
.
write
((
char
*
)
&
nextGaussian
,
sizeof
(
double
));
sfmt
.
createCheckpoint
(
stream
);
}
}
...
...
@@ -389,7 +331,7 @@ void SimTKOpenMMUtilities::loadCheckpoint(std::istream& stream) {
if
(
!
prevInitialized
)
init_gen_rand
(
0
,
sfmt
);
stream
.
read
((
char
*
)
&
nextGaussianIsValid
,
sizeof
(
bool
));
stream
.
read
((
char
*
)
&
nextGaussian
,
sizeof
(
RealOpenMM
));
stream
.
read
((
char
*
)
&
nextGaussian
,
sizeof
(
double
));
sfmt
.
loadCheckpoint
(
stream
);
}
}
platforms/reference/src/SimTKReference/fftpack.cpp
View file @
047934e2
...
...
@@ -37,7 +37,7 @@ struct fftpack
int
n
;
/**< Number of points in this dimension. */
int
ifac
[
15
];
/**< 15 bytes needed for cfft and rfft */
struct
fftpack
*
next
;
/**< Pointer to next dimension, or NULL. */
RealOpenMM
*
work
;
/**< 1st 4n reserved for cfft, 1st 2n for rfft */
double
*
work
;
/**< 1st 4n reserved for cfft, 1st 2n for rfft */
};
...
...
@@ -48,15 +48,15 @@ struct fftpack
static
void
fftpack_passf2
(
int
ido
,
int
l1
,
RealOpenMM
cc
[],
RealOpenMM
ch
[],
RealOpenMM
wa1
[],
int
isign
)
fftpack_passf2
(
int
ido
,
int
l1
,
double
cc
[],
double
ch
[],
double
wa1
[],
int
isign
)
{
int
i
,
k
,
ah
,
ac
;
RealOpenMM
ti2
,
tr2
;
double
ti2
,
tr2
;
if
(
ido
<=
2
)
{
...
...
@@ -92,19 +92,19 @@ fftpack_passf2(int ido,
static
void
fftpack_passf3
(
int
ido
,
int
l1
,
RealOpenMM
cc
[],
RealOpenMM
ch
[],
RealOpenMM
wa1
[],
RealOpenMM
wa2
[],
int
isign
)
fftpack_passf3
(
int
ido
,
int
l1
,
double
cc
[],
double
ch
[],
double
wa1
[],
double
wa2
[],
int
isign
)
{
const
RealOpenMM
taur
=
(
RealOpenMM
)
-
0.5
;
const
RealOpenMM
taui
=
(
RealOpenMM
)
0.866025403784439
;
const
double
taur
=
-
0.5
;
const
double
taui
=
0.866025403784439
;
int
i
,
k
,
ac
,
ah
;
RealOpenMM
ci2
,
ci3
,
di2
,
di3
,
cr2
,
cr3
,
dr2
,
dr3
,
ti2
,
tr2
;
double
ci2
,
ci3
,
di2
,
di3
,
cr2
,
cr3
,
dr2
,
dr3
,
ti2
,
tr2
;
if
(
ido
==
2
)
{
...
...
@@ -159,17 +159,17 @@ fftpack_passf3(int ido,
static
void
fftpack_passf4
(
int
ido
,
int
l1
,
RealOpenMM
cc
[],
RealOpenMM
ch
[],
RealOpenMM
wa1
[],
RealOpenMM
wa2
[],
RealOpenMM
wa3
[],
int
isign
)
fftpack_passf4
(
int
ido
,
int
l1
,
double
cc
[],
double
ch
[],
double
wa1
[],
double
wa2
[],
double
wa3
[],
int
isign
)
{
int
i
,
k
,
ac
,
ah
;
RealOpenMM
ci2
,
ci3
,
ci4
,
cr2
,
cr3
,
cr4
,
ti1
,
ti2
,
ti3
,
ti4
,
tr1
,
tr2
,
tr3
,
tr4
;
double
ci2
,
ci3
,
ci4
,
cr2
,
cr3
,
cr4
,
ti1
,
ti2
,
ti3
,
ti4
,
tr1
,
tr2
,
tr3
,
tr4
;
if
(
ido
==
2
)
{
...
...
@@ -232,23 +232,23 @@ fftpack_passf4(int ido,
static
void
fftpack_passf5
(
int
ido
,
int
l1
,
RealOpenMM
cc
[],
RealOpenMM
ch
[],
RealOpenMM
wa1
[],
RealOpenMM
wa2
[],
RealOpenMM
wa3
[],
RealOpenMM
wa4
[],
int
isign
)
fftpack_passf5
(
int
ido
,
int
l1
,
double
cc
[],
double
ch
[],
double
wa1
[],
double
wa2
[],
double
wa3
[],
double
wa4
[],
int
isign
)
{
const
RealOpenMM
tr11
=
(
RealOpenMM
)
0.309016994374947
;
const
RealOpenMM
ti11
=
(
RealOpenMM
)
0.951056516295154
;
const
RealOpenMM
tr12
=
(
RealOpenMM
)
-
0.809016994374947
;
const
RealOpenMM
ti12
=
(
RealOpenMM
)
0.587785252292473
;
const
double
tr11
=
0.309016994374947
;
const
double
ti11
=
0.951056516295154
;
const
double
tr12
=
-
0.809016994374947
;
const
double
ti12
=
0.587785252292473
;
int
i
,
k
,
ac
,
ah
;
RealOpenMM
ci2
,
ci3
,
ci4
,
ci5
,
di3
,
di4
,
di5
,
di2
,
cr2
,
cr3
,
cr5
,
cr4
,
ti2
,
ti3
,
double
ci2
,
ci3
,
ci4
,
ci5
,
di3
,
di4
,
di5
,
di2
,
cr2
,
cr3
,
cr5
,
cr4
,
ti2
,
ti3
,
ti4
,
ti5
,
dr3
,
dr4
,
dr5
,
dr2
,
tr2
,
tr3
,
tr4
,
tr5
;
if
(
ido
==
2
)
...
...
@@ -334,18 +334,18 @@ fftpack_passf5(int ido,
static
void
fftpack_passf
(
int
*
nac
,
int
ido
,
int
ip
,
int
l1
,
int
idl1
,
RealOpenMM
cc
[],
RealOpenMM
ch
[],
RealOpenMM
wa
[],
int
isign
)
fftpack_passf
(
int
*
nac
,
int
ido
,
int
ip
,
int
l1
,
int
idl1
,
double
cc
[],
double
ch
[],
double
wa
[],
int
isign
)
{
int
idij
,
idlj
,
idot
,
ipph
,
i
,
j
,
k
,
l
,
jc
,
lc
,
ik
,
nt
,
idj
,
idl
,
inc
,
idp
;
RealOpenMM
wai
,
war
;
double
wai
,
war
;
idot
=
ido
/
2
;
nt
=
ip
*
idl1
;
...
...
@@ -495,17 +495,17 @@ fftpack_passf(int * nac,
static
void
fftpack_cfftf1
(
int
n
,
RealOpenMM
c
[],
RealOpenMM
ch
[],
RealOpenMM
wa
[],
int
ifac
[
15
],
int
isign
)
fftpack_cfftf1
(
int
n
,
double
c
[],
double
ch
[],
double
wa
[],
int
ifac
[
15
],
int
isign
)
{
int
idot
,
i
;
int
k1
,
l1
,
l2
;
int
na
,
nf
,
ip
,
iw
,
ix2
,
ix3
,
ix4
,
nac
,
ido
,
idl1
;
RealOpenMM
*
cinput
,
*
coutput
;
double
*
cinput
,
*
coutput
;
nf
=
ifac
[
1
];
na
=
0
;
l1
=
1
;
...
...
@@ -606,12 +606,12 @@ startloop:
static
void
fftpack_cffti1
(
int
n
,
RealOpenMM
wa
[],
int
ifac
[
15
])
fftpack_cffti1
(
int
n
,
double
wa
[],
int
ifac
[
15
])
{
const
RealOpenMM
twopi
=
(
RealOpenMM
)
6.28318530717959
;
RealOpenMM
arg
,
argh
,
argld
,
fi
;
const
double
twopi
=
6.28318530717959
;
double
arg
,
argh
,
argld
,
fi
;
int
idot
,
i
,
j
;
int
i1
,
k1
,
l1
,
l2
;
int
ld
,
ii
,
nf
,
ip
;
...
...
@@ -619,7 +619,7 @@ fftpack_cffti1(int n,
fftpack_factorize
(
n
,
ifac
);
nf
=
ifac
[
1
];
argh
=
twopi
/
(
RealOpenMM
)
n
;
argh
=
twopi
/
n
;
i
=
1
;
l1
=
1
;
for
(
k1
=
1
;
k1
<=
nf
;
k1
++
)
...
...
@@ -783,7 +783,7 @@ fftpack_init_1d(fftpack_t * pfft,
fft
->
n
=
nx
;
/* Need 4*n storage for 1D complex FFT */
if
((
fft
->
work
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
(
4
*
nx
)))
==
NULL
)
if
((
fft
->
work
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
(
4
*
nx
)))
==
NULL
)
{
free
(
fft
);
return
ENOMEM
;
...
...
@@ -860,7 +860,7 @@ fftpack_init_3d(fftpack_t * pfft,
/* Need 4*nx storage for 1D complex FFT.
*/
if
((
fft
->
work
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
(
4
*
nx
)))
==
NULL
)
if
((
fft
->
work
=
(
double
*
)
malloc
(
sizeof
(
double
)
*
(
4
*
nx
)))
==
NULL
)
{
free
(
fft
);
return
ENOMEM
;
...
...
@@ -887,16 +887,16 @@ fftpack_exec_1d (fftpack_t fft,
t_complex
*
in_data
,
t_complex
*
out_data
)
{
int
i
,
n
;
RealOpenMM
*
p1
;
RealOpenMM
*
p2
;
int
i
,
n
;
double
*
p1
;
double
*
p2
;
n
=
fft
->
n
;
if
(
n
==
1
)
{
p1
=
(
RealOpenMM
*
)
in_data
;
p2
=
(
RealOpenMM
*
)
out_data
;
p1
=
(
double
*
)
in_data
;
p2
=
(
double
*
)
out_data
;
p2
[
0
]
=
p1
[
0
];
p2
[
1
]
=
p1
[
1
];
}
...
...
@@ -906,10 +906,10 @@ fftpack_exec_1d (fftpack_t fft,
*/
if
(
in_data
!=
out_data
)
{
p1
=
(
RealOpenMM
*
)
in_data
;
p2
=
(
RealOpenMM
*
)
out_data
;
p1
=
(
double
*
)
in_data
;
p2
=
(
double
*
)
out_data
;
/* n complex = 2*n
RealOpenMM
elements */
/* n complex = 2*n
double
elements */
for
(
i
=
0
;
i
<
2
*
n
;
i
++
)
{
p2
[
i
]
=
p1
[
i
];
...
...
@@ -922,11 +922,11 @@ fftpack_exec_1d (fftpack_t fft,
if
(
dir
==
FFTPACK_FORWARD
)
{
fftpack_cfftf1
(
n
,(
RealOpenMM
*
)
out_data
,
fft
->
work
+
2
*
n
,
fft
->
work
,
fft
->
ifac
,
-
1
);
fftpack_cfftf1
(
n
,(
double
*
)
out_data
,
fft
->
work
+
2
*
n
,
fft
->
work
,
fft
->
ifac
,
-
1
);
}
else
if
(
dir
==
FFTPACK_BACKWARD
)
{
fftpack_cfftf1
(
n
,(
RealOpenMM
*
)
out_data
,
fft
->
work
+
2
*
n
,
fft
->
work
,
fft
->
ifac
,
1
);
fftpack_cfftf1
(
n
,(
double
*
)
out_data
,
fft
->
work
+
2
*
n
,
fft
->
work
,
fft
->
ifac
,
1
);
}
else
{
...
...
platforms/reference/tests/TestReferenceDispersionPME.cpp
0 → 100644
View file @
047934e2
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2017 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* 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 "ReferenceTests.h"
#include "TestDispersionPME.h"
void
runPlatformTests
()
{
}
platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp
View file @
047934e2
...
...
@@ -37,6 +37,7 @@
#include "openmm/MonteCarloMembraneBarostat.h"
#include "openmm/Context.h"
#include "ReferencePlatform.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h"
...
...
@@ -76,8 +77,9 @@ void testIdealGas(MonteCarloMembraneBarostat::XYMode xymode, MonteCarloMembraneB
}
MonteCarloMembraneBarostat
*
barostat
=
new
MonteCarloMembraneBarostat
(
pressure
,
tension
,
temp
[
0
],
xymode
,
zmode
,
frequency
);
system
.
addForce
(
barostat
);
ASSERT
(
barostat
->
usesPeriodicBoundaryConditions
());
ASSERT
(
system
.
usesPeriodicBoundaryConditions
());
HarmonicBondForce
*
bonds
=
new
HarmonicBondForce
();
bonds
->
setUsesPeriodicBoundaryConditions
(
true
);
system
.
addForce
(
bonds
);
// So it won't complain the system is non-periodic.
// Test it for three different temperatures.
...
...
@@ -134,8 +136,6 @@ void testRandomSeed() {
system
.
addForce
(
forceField
);
MonteCarloMembraneBarostat
*
barostat
=
new
MonteCarloMembraneBarostat
(
pressure
,
tension
,
temp
,
MonteCarloMembraneBarostat
::
XYAnisotropic
,
MonteCarloMembraneBarostat
::
ZFree
,
1
);
system
.
addForce
(
barostat
);
ASSERT
(
barostat
->
usesPeriodicBoundaryConditions
());
ASSERT
(
system
.
usesPeriodicBoundaryConditions
());
vector
<
Vec3
>
positions
(
numParticles
);
vector
<
Vec3
>
velocities
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
...
...
Prev
1
…
8
9
10
11
12
13
14
15
16
…
18
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