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
53f770f4
Commit
53f770f4
authored
Feb 21, 2017
by
peastman
Committed by
GitHub
Feb 21, 2017
Browse files
Merge pull request #1557 from andysim/dpme
Dispersion PME
parents
f36f36bf
c0850062
Changes
62
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
3358 additions
and
61 deletions
+3358
-61
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
...amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
+1
-1
plugins/cpupme/src/CpuPmeKernelFactory.cpp
plugins/cpupme/src/CpuPmeKernelFactory.cpp
+2
-0
plugins/cpupme/src/CpuPmeKernels.cpp
plugins/cpupme/src/CpuPmeKernels.cpp
+385
-25
plugins/cpupme/src/CpuPmeKernels.h
plugins/cpupme/src/CpuPmeKernels.h
+92
-0
plugins/cpupme/tests/TestCpuPme.cpp
plugins/cpupme/tests/TestCpuPme.cpp
+507
-2
serialization/src/NonbondedForceProxy.cpp
serialization/src/NonbondedForceProxy.cpp
+15
-2
serialization/tests/TestSerializeNonbondedForce.cpp
serialization/tests/TestSerializeNonbondedForce.cpp
+10
-0
tests/TestDispersionPME.h
tests/TestDispersionPME.h
+2295
-0
tests/TestEwald.h
tests/TestEwald.h
+1
-1
tests/TestNonbondedForce.h
tests/TestNonbondedForce.h
+1
-0
wrappers/python/simtk/openmm/app/__init__.py
wrappers/python/simtk/openmm/app/__init__.py
+1
-0
wrappers/python/simtk/openmm/app/amberprmtopfile.py
wrappers/python/simtk/openmm/app/amberprmtopfile.py
+5
-4
wrappers/python/simtk/openmm/app/charmmpsffile.py
wrappers/python/simtk/openmm/app/charmmpsffile.py
+7
-6
wrappers/python/simtk/openmm/app/desmonddmsfile.py
wrappers/python/simtk/openmm/app/desmonddmsfile.py
+5
-4
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+9
-3
wrappers/python/simtk/openmm/app/gromacstopfile.py
wrappers/python/simtk/openmm/app/gromacstopfile.py
+5
-4
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
...ers/python/simtk/openmm/app/internal/amber_file_parser.py
+3
-1
wrappers/python/tests/TestAPIUnits.py
wrappers/python/tests/TestAPIUnits.py
+2
-0
wrappers/python/tests/TestAmberPrmtopFile.py
wrappers/python/tests/TestAmberPrmtopFile.py
+6
-4
wrappers/python/tests/TestDesmondDMSFile.py
wrappers/python/tests/TestDesmondDMSFile.py
+6
-4
No files found.
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
View file @
53f770f4
...
@@ -602,7 +602,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
...
@@ -602,7 +602,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
nb
.
setEwaldErrorTolerance
(
force
.
getEwaldErrorTolerance
());
nb
.
setEwaldErrorTolerance
(
force
.
getEwaldErrorTolerance
());
nb
.
setCutoffDistance
(
force
.
getCutoffDistance
());
nb
.
setCutoffDistance
(
force
.
getCutoffDistance
());
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
nb
,
alphaEwald
,
gridSizeX
,
gridSizeY
,
gridSizeZ
);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
nb
,
alphaEwald
,
gridSizeX
,
gridSizeY
,
gridSizeZ
,
false
);
pmeGridDimension
[
0
]
=
gridSizeX
;
pmeGridDimension
[
0
]
=
gridSizeX
;
pmeGridDimension
[
1
]
=
gridSizeY
;
pmeGridDimension
[
1
]
=
gridSizeY
;
pmeGridDimension
[
2
]
=
gridSizeZ
;
pmeGridDimension
[
2
]
=
gridSizeZ
;
...
...
plugins/cpupme/src/CpuPmeKernelFactory.cpp
View file @
53f770f4
...
@@ -55,5 +55,7 @@ extern "C" OPENMM_EXPORT_PME void registerPlatforms() {
...
@@ -55,5 +55,7 @@ extern "C" OPENMM_EXPORT_PME void registerPlatforms() {
KernelImpl
*
CpuPmeKernelFactory
::
createKernelImpl
(
std
::
string
name
,
const
Platform
&
platform
,
ContextImpl
&
context
)
const
{
KernelImpl
*
CpuPmeKernelFactory
::
createKernelImpl
(
std
::
string
name
,
const
Platform
&
platform
,
ContextImpl
&
context
)
const
{
if
(
name
==
CalcPmeReciprocalForceKernel
::
Name
())
if
(
name
==
CalcPmeReciprocalForceKernel
::
Name
())
return
new
CpuCalcPmeReciprocalForceKernel
(
name
,
platform
);
return
new
CpuCalcPmeReciprocalForceKernel
(
name
,
platform
);
if
(
name
==
CalcDispersionPmeReciprocalForceKernel
::
Name
())
return
new
CpuCalcDispersionPmeReciprocalForceKernel
(
name
,
platform
);
throw
OpenMMException
((
std
::
string
(
"Tried to create kernel with illegal kernel name '"
)
+
name
+
"'"
).
c_str
());
throw
OpenMMException
((
std
::
string
(
"Tried to create kernel with illegal kernel name '"
)
+
name
+
"'"
).
c_str
());
}
}
plugins/cpupme/src/CpuPmeKernels.cpp
View file @
53f770f4
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
#include "SimTKOpenMMRealType.h"
#include "SimTKOpenMMRealType.h"
#include "openmm/internal/hardware.h"
#include "openmm/internal/hardware.h"
#include "openmm/internal/vectorize.h"
#include "openmm/internal/vectorize.h"
#include "openmm/OpenMMException.h"
#include <cmath>
#include <cmath>
#include <algorithm>
#include <algorithm>
#include <cstring>
#include <cstring>
...
@@ -47,10 +48,10 @@ using namespace std;
...
@@ -47,10 +48,10 @@ using namespace std;
static
const
int
PME_ORDER
=
5
;
static
const
int
PME_ORDER
=
5
;
bool
CpuCalcPmeReciprocalForceKernel
::
hasInitializedThreads
=
false
;
bool
CpuCalc
Dispersion
PmeReciprocalForceKernel
::
hasInitializedThreads
=
false
;
int
CpuCalcPmeReciprocalForceKernel
::
numThreads
=
0
;
int
CpuCalc
Dispersion
PmeReciprocalForceKernel
::
numThreads
=
0
;
static
void
spreadCharge
(
float
*
posq
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
)
{
static
void
spreadCharge
(
float
*
posq
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
,
const
float
epsilonFactor
)
{
float
temp
[
4
];
float
temp
[
4
];
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
...
@@ -62,7 +63,6 @@ static void spreadCharge(float* posq, float* grid, int gridx, int gridy, int gri
...
@@ -62,7 +63,6 @@ static void spreadCharge(float* posq, float* grid, int gridx, int gridy, int gri
fvec4
one
(
1
);
fvec4
one
(
1
);
fvec4
scale
(
1.0
f
/
(
PME_ORDER
-
1
));
fvec4
scale
(
1.0
f
/
(
PME_ORDER
-
1
));
float
posInBox
[
4
]
=
{
0
,
0
,
0
,
0
};
float
posInBox
[
4
]
=
{
0
,
0
,
0
,
0
};
const
float
epsilonFactor
=
sqrt
(
ONE_4PI_EPS0
);
memset
(
grid
,
0
,
sizeof
(
float
)
*
gridx
*
gridy
*
gridz
);
memset
(
grid
,
0
,
sizeof
(
float
)
*
gridx
*
gridy
*
gridz
);
while
(
true
)
{
while
(
true
)
{
...
@@ -154,42 +154,60 @@ static void spreadCharge(float* posq, float* grid, int gridx, int gridy, int gri
...
@@ -154,42 +154,60 @@ static void spreadCharge(float* posq, float* grid, int gridx, int gridy, int gri
}
}
}
}
static
void
computeReciprocalEterm
(
int
start
,
int
end
,
int
gridx
,
int
gridy
,
int
gridz
,
vector
<
float
>&
recipEterm
,
double
alpha
,
vector
<
float
>*
bsplineModuli
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
#define FAST_ERFC 1
static
void
computeReciprocalDispersionEterm
(
int
start
,
int
end
,
int
gridx
,
int
gridy
,
int
gridz
,
vector
<
float
>&
recipEterm
,
double
alpha
,
vector
<
float
>*
bsplineModuli
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
const
unsigned
int
zsize
=
gridz
/
2
+
1
;
const
unsigned
int
zsize
=
gridz
/
2
+
1
;
const
unsigned
int
yzsize
=
gridy
*
zsize
;
const
unsigned
int
yzsize
=
gridy
*
zsize
;
const
float
scaleFactor
=
(
float
)
(
M_PI
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]);
const
float
scaleFactor
=
(
float
)
-
2.0
f
*
M_PI
*
sqrtf
(
M_PI
)
/
(
6.0
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]);
const
float
recipExpFactor
=
(
float
)
(
M_PI
*
M_PI
/
(
alpha
*
alpha
));
float
bfac
=
M_PI
/
alpha
;
float
fac1
=
2.0
f
*
M_PI
*
M_PI
*
M_PI
*
sqrtf
(
M_PI
);
float
fac2
=
alpha
*
alpha
*
alpha
;
float
fac3
=
-
2.0
f
*
alpha
*
M_PI
*
M_PI
;
float
b
,
m
,
m3
,
expterm
,
erfcterm
,
t
;
int
firstz
=
(
start
==
0
?
1
:
0
);
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
int
mx
=
(
kx
<
(
gridx
+
1
)
/
2
)
?
kx
:
kx
-
gridx
;
int
mx
=
(
kx
<
(
gridx
+
1
)
/
2
)
?
kx
:
kx
-
gridx
;
float
mhx
=
mx
*
(
float
)
recipBoxVectors
[
0
][
0
];
float
mhx
=
mx
*
(
float
)
recipBoxVectors
[
0
][
0
];
float
bx
=
scaleFactor
*
bsplineModuli
[
0
][
kx
];
float
bx
=
bsplineModuli
[
0
][
kx
];
for
(
int
ky
=
0
;
ky
<
gridy
;
ky
++
)
{
for
(
int
ky
=
0
;
ky
<
gridy
;
ky
++
)
{
int
my
=
(
ky
<
(
gridy
+
1
)
/
2
)
?
ky
:
ky
-
gridy
;
int
my
=
(
ky
<
(
gridy
+
1
)
/
2
)
?
ky
:
ky
-
gridy
;
float
mhy
=
mx
*
(
float
)
recipBoxVectors
[
1
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
1
][
1
];
float
mhy
=
mx
*
(
float
)
recipBoxVectors
[
1
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
1
][
1
];
float
mhx2y2
=
mhx
*
mhx
+
mhy
*
mhy
;
float
mhx2y2
=
mhx
*
mhx
+
mhy
*
mhy
;
float
bxby
=
bx
*
bsplineModuli
[
1
][
ky
];
float
bxby
=
bx
*
bsplineModuli
[
1
][
ky
];
for
(
int
kz
=
firstz
;
kz
<
zsize
;
kz
++
)
{
for
(
int
kz
=
0
;
kz
<
zsize
;
kz
++
)
{
int
index
=
kx
*
yzsize
+
ky
*
zsize
+
kz
;
int
index
=
kx
*
yzsize
+
ky
*
zsize
+
kz
;
int
mz
=
(
kz
<
(
gridz
+
1
)
/
2
)
?
kz
:
kz
-
gridz
;
int
mz
=
(
kz
<
(
gridz
+
1
)
/
2
)
?
kz
:
kz
-
gridz
;
float
mhz
=
mx
*
(
float
)
recipBoxVectors
[
2
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
2
][
1
]
+
mz
*
(
float
)
recipBoxVectors
[
2
][
2
];
float
mhz
=
mx
*
(
float
)
recipBoxVectors
[
2
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
2
][
1
]
+
mz
*
(
float
)
recipBoxVectors
[
2
][
2
];
float
bz
=
bsplineModuli
[
2
][
kz
];
float
bz
=
bsplineModuli
[
2
][
kz
];
float
m2
=
mhx2y2
+
mhz
*
mhz
;
float
m2
=
mhx2y2
+
mhz
*
mhz
;
float
denom
=
m2
*
bxby
*
bz
;
float
denom
=
scaleFactor
/
(
bxby
*
bz
);
recipEterm
[
index
]
=
exp
(
-
recipExpFactor
*
m2
)
/
denom
;
m
=
sqrtf
(
m2
);
m3
=
m
*
m2
;
b
=
bfac
*
m
;
expterm
=
exp
(
-
b
*
b
);
#if FAST_ERFC
// This approximation for erfc is from Abramowitz and Stegun (1964) p. 299. They cite the following as
// the original source: C. Hastings, Jr., Approximations for Digital Computers (1955). It has a maximum
// error of 1.5e-7. Stolen by ACS from the CUDA platform's AMOEBA plugin.
t
=
1.0
f
/
(
1.0
f
+
0.3275911
f
*
b
);
erfcterm
=
(
0.254829592
f
+
(
-
0.284496736
f
+
(
1.421413741
f
+
(
-
1.453152027
f
+
1.061405429
f
*
t
)
*
t
)
*
t
)
*
t
)
*
t
*
expterm
;
#else
erfcterm
=
erfc
(
b
);
#endif
recipEterm
[
index
]
=
(
fac1
*
erfcterm
*
m3
+
expterm
*
(
fac2
+
fac3
*
m2
))
*
denom
;
}
}
firstz
=
0
;
}
}
}
}
}
}
static
double
r
eciprocalE
n
er
gy
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
double
alpha
,
vector
<
float
>*
bsplineModuli
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
static
void
computeR
eciprocalE
t
er
m
(
int
start
,
int
end
,
int
gridx
,
int
gridy
,
int
gridz
,
vector
<
float
>&
recipEterm
,
double
alpha
,
vector
<
float
>*
bsplineModuli
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
const
unsigned
int
zsize
Half
=
gridz
/
2
+
1
;
const
unsigned
int
zsize
=
gridz
/
2
+
1
;
const
unsigned
int
yzsize
Half
=
gridy
*
zsize
Half
;
const
unsigned
int
yzsize
=
gridy
*
zsize
;
const
float
scaleFactor
=
(
float
)
(
M_PI
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]);
const
float
scaleFactor
=
(
float
)
(
M_PI
*
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
]);
const
float
recipExpFactor
=
(
float
)
(
M_PI
*
M_PI
/
(
alpha
*
alpha
));
const
float
recipExpFactor
=
(
float
)
(
M_PI
*
M_PI
/
(
alpha
*
alpha
));
double
energy
=
0.0
;
int
firstz
=
(
start
==
0
?
1
:
0
);
int
firstz
=
(
start
==
0
?
1
:
0
);
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
...
@@ -201,13 +219,30 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
...
@@ -201,13 +219,30 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
float
mhy
=
mx
*
(
float
)
recipBoxVectors
[
1
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
1
][
1
];
float
mhy
=
mx
*
(
float
)
recipBoxVectors
[
1
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
1
][
1
];
float
mhx2y2
=
mhx
*
mhx
+
mhy
*
mhy
;
float
mhx2y2
=
mhx
*
mhx
+
mhy
*
mhy
;
float
bxby
=
bx
*
bsplineModuli
[
1
][
ky
];
float
bxby
=
bx
*
bsplineModuli
[
1
][
ky
];
for
(
int
kz
=
firstz
;
kz
<
gridz
;
kz
++
)
{
for
(
int
kz
=
firstz
;
kz
<
zsize
;
kz
++
)
{
int
index
=
kx
*
yzsize
+
ky
*
zsize
+
kz
;
int
mz
=
(
kz
<
(
gridz
+
1
)
/
2
)
?
kz
:
kz
-
gridz
;
int
mz
=
(
kz
<
(
gridz
+
1
)
/
2
)
?
kz
:
kz
-
gridz
;
float
mhz
=
mx
*
(
float
)
recipBoxVectors
[
2
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
2
][
1
]
+
mz
*
(
float
)
recipBoxVectors
[
2
][
2
];
float
mhz
=
mx
*
(
float
)
recipBoxVectors
[
2
][
0
]
+
my
*
(
float
)
recipBoxVectors
[
2
][
1
]
+
mz
*
(
float
)
recipBoxVectors
[
2
][
2
];
float
bz
=
bsplineModuli
[
2
][
kz
];
float
bz
=
bsplineModuli
[
2
][
kz
];
float
m2
=
mhx2y2
+
mhz
*
mhz
;
float
m2
=
mhx2y2
+
mhz
*
mhz
;
float
denom
=
m2
*
bxby
*
bz
;
float
denom
=
m2
*
bxby
*
bz
;
float
eterm
=
exp
(
-
recipExpFactor
*
m2
)
/
denom
;
recipEterm
[
index
]
=
exp
(
-
recipExpFactor
*
m2
)
/
denom
;
}
firstz
=
0
;
}
}
}
static
double
reciprocalEnergy
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
vector
<
float
>&
recipEterm
,
int
gridx
,
int
gridy
,
int
gridz
,
double
alpha
,
vector
<
float
>*
bsplineModuli
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
const
unsigned
int
zsizeHalf
=
gridz
/
2
+
1
;
const
unsigned
int
yzsizeHalf
=
gridy
*
zsizeHalf
;
double
energy
=
0.0
;
int
firstz
=
(
start
==
0
?
1
:
0
);
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
for
(
int
ky
=
0
;
ky
<
gridy
;
ky
++
)
{
for
(
int
kz
=
firstz
;
kz
<
gridz
;
kz
++
)
{
int
kx1
,
ky1
,
kz1
;
int
kx1
,
ky1
,
kz1
;
if
(
kz
>=
gridz
/
2
+
1
)
{
if
(
kz
>=
gridz
/
2
+
1
)
{
kx1
=
(
kx
==
0
?
kx
:
gridx
-
kx
);
kx1
=
(
kx
==
0
?
kx
:
gridx
-
kx
);
...
@@ -222,7 +257,7 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
...
@@ -222,7 +257,7 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
int
index
=
kx1
*
yzsizeHalf
+
ky1
*
zsizeHalf
+
kz1
;
int
index
=
kx1
*
yzsizeHalf
+
ky1
*
zsizeHalf
+
kz1
;
float
gridReal
=
grid
[
index
][
0
];
float
gridReal
=
grid
[
index
][
0
];
float
gridImag
=
grid
[
index
][
1
];
float
gridImag
=
grid
[
index
][
1
];
energy
+=
eterm
*
(
gridReal
*
gridReal
+
gridImag
*
gridImag
);
energy
+=
recipEterm
[
index
]
*
(
gridReal
*
gridReal
+
gridImag
*
gridImag
);
}
}
firstz
=
0
;
firstz
=
0
;
}
}
...
@@ -230,6 +265,38 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
...
@@ -230,6 +265,38 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
return
0.5
*
energy
;
return
0.5
*
energy
;
}
}
static
double
reciprocalDispersionEnergy
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
const
vector
<
float
>&
recipEterm
,
int
gridx
,
int
gridy
,
int
gridz
,
double
alpha
,
vector
<
float
>*
bsplineModuli
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
const
unsigned
int
zsizeHalf
=
gridz
/
2
+
1
;
const
unsigned
int
yzsizeHalf
=
gridy
*
zsizeHalf
;
double
energy
=
0.0
;
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
for
(
int
ky
=
0
;
ky
<
gridy
;
ky
++
)
{
for
(
int
kz
=
0
;
kz
<
gridz
;
kz
++
)
{
int
kx1
,
ky1
,
kz1
;
if
(
kz
>=
gridz
/
2
+
1
)
{
kx1
=
(
kx
==
0
?
kx
:
gridx
-
kx
);
ky1
=
(
ky
==
0
?
ky
:
gridy
-
ky
);
kz1
=
gridz
-
kz
;
}
else
{
kx1
=
kx
;
ky1
=
ky
;
kz1
=
kz
;
}
int
index
=
kx1
*
yzsizeHalf
+
ky1
*
zsizeHalf
+
kz1
;
float
gridReal
=
grid
[
index
][
0
];
float
gridImag
=
grid
[
index
][
1
];
energy
+=
recipEterm
[
index
]
*
(
gridReal
*
gridReal
+
gridImag
*
gridImag
);
}
}
}
return
0.5
f
*
energy
;
}
static
void
reciprocalConvolution
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
vector
<
float
>&
recipEterm
)
{
static
void
reciprocalConvolution
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
vector
<
float
>&
recipEterm
)
{
for
(
int
index
=
start
;
index
<
end
;
index
++
)
{
for
(
int
index
=
start
;
index
<
end
;
index
++
)
{
float
eterm
=
recipEterm
[
index
];
float
eterm
=
recipEterm
[
index
];
...
@@ -238,7 +305,7 @@ static void reciprocalConvolution(int start, int end, fftwf_complex* grid, vecto
...
@@ -238,7 +305,7 @@ static void reciprocalConvolution(int start, int end, fftwf_complex* grid, vecto
}
}
}
}
static
void
interpolateForces
(
float
*
posq
,
float
*
force
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
)
{
static
void
interpolateForces
(
float
*
posq
,
float
*
force
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
,
const
float
epsilonFactor
)
{
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
fvec4
recipBoxVec0
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
0
][
1
],
(
float
)
recipBoxVectors
[
0
][
2
],
0
);
fvec4
recipBoxVec0
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
0
][
1
],
(
float
)
recipBoxVectors
[
0
][
2
],
0
);
...
@@ -248,7 +315,6 @@ static void interpolateForces(float* posq, float* force, float* grid, int gridx,
...
@@ -248,7 +315,6 @@ static void interpolateForces(float* posq, float* force, float* grid, int gridx,
ivec4
gridSizeInt
(
gridx
,
gridy
,
gridz
,
0
);
ivec4
gridSizeInt
(
gridx
,
gridy
,
gridz
,
0
);
fvec4
one
(
1
);
fvec4
one
(
1
);
fvec4
scale
(
1.0
f
/
(
PME_ORDER
-
1
));
fvec4
scale
(
1.0
f
/
(
PME_ORDER
-
1
));
const
float
epsilonFactor
=
sqrt
(
ONE_4PI_EPS0
);
while
(
true
)
{
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
&
atomicCounter
,
1
);
int
i
=
gmx_atomic_fetch_add
(
&
atomicCounter
,
1
);
if
(
i
>=
numParticles
)
if
(
i
>=
numParticles
)
...
@@ -513,7 +579,8 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
...
@@ -513,7 +579,8 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
int
complexSize
=
gridx
*
gridy
*
(
gridz
/
2
+
1
);
int
complexSize
=
gridx
*
gridy
*
(
gridz
/
2
+
1
);
int
complexStart
=
std
::
max
(
1
,
((
index
*
complexSize
)
/
numThreads
));
int
complexStart
=
std
::
max
(
1
,
((
index
*
complexSize
)
/
numThreads
));
int
complexEnd
=
(((
index
+
1
)
*
complexSize
)
/
numThreads
);
int
complexEnd
=
(((
index
+
1
)
*
complexSize
)
/
numThreads
);
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
);
const
float
epsilonFactor
=
sqrt
(
ONE_4PI_EPS0
);
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
);
threads
.
syncThreads
();
threads
.
syncThreads
();
int
numGrids
=
tempGrid
.
size
();
int
numGrids
=
tempGrid
.
size
();
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
...
@@ -528,12 +595,12 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
...
@@ -528,12 +595,12 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
threads
.
syncThreads
();
threads
.
syncThreads
();
}
}
if
(
includeEnergy
)
{
if
(
includeEnergy
)
{
threadEnergy
[
index
]
=
reciprocalEnergy
(
gridxStart
,
gridxEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
threadEnergy
[
index
]
=
reciprocalEnergy
(
gridxStart
,
gridxEnd
,
complexGrid
,
recipEterm
,
gridx
,
gridy
,
gridz
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
threads
.
syncThreads
();
threads
.
syncThreads
();
}
}
reciprocalConvolution
(
complexStart
,
complexEnd
,
complexGrid
,
recipEterm
);
reciprocalConvolution
(
complexStart
,
complexEnd
,
complexGrid
,
recipEterm
);
threads
.
syncThreads
();
threads
.
syncThreads
();
interpolateForces
(
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
);
interpolateForces
(
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
);
}
}
void
CpuCalcPmeReciprocalForceKernel
::
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
)
{
void
CpuCalcPmeReciprocalForceKernel
::
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
)
{
...
@@ -603,3 +670,296 @@ int CpuCalcPmeReciprocalForceKernel::findFFTDimension(int minimum, bool isZ) {
...
@@ -603,3 +670,296 @@ int CpuCalcPmeReciprocalForceKernel::findFFTDimension(int minimum, bool isZ) {
minimum
++
;
minimum
++
;
}
}
}
}
/*
* Everything below here is just a clone of the above, but to handle the dispersion term
* instead of electrostatics.
*/
bool
CpuCalcPmeReciprocalForceKernel
::
hasInitializedThreads
=
false
;
int
CpuCalcPmeReciprocalForceKernel
::
numThreads
=
0
;
class
CpuCalcDispersionPmeReciprocalForceKernel
::
ComputeTask
:
public
ThreadPool
::
Task
{
public:
ComputeTask
(
CpuCalcDispersionPmeReciprocalForceKernel
&
owner
)
:
owner
(
owner
)
{
}
void
execute
(
ThreadPool
&
threads
,
int
threadIndex
)
{
owner
.
runWorkerThread
(
threads
,
threadIndex
);
}
CpuCalcDispersionPmeReciprocalForceKernel
&
owner
;
};
static
void
*
dispersionThreadBody
(
void
*
args
)
{
CpuCalcDispersionPmeReciprocalForceKernel
&
owner
=
*
reinterpret_cast
<
CpuCalcDispersionPmeReciprocalForceKernel
*>
(
args
);
owner
.
runMainThread
();
return
0
;
}
void
CpuCalcDispersionPmeReciprocalForceKernel
::
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
)
{
if
(
!
hasInitializedThreads
)
{
numThreads
=
getNumProcessors
();
char
*
threadsEnv
=
getenv
(
"OPENMM_CPU_THREADS"
);
if
(
threadsEnv
!=
NULL
)
stringstream
(
threadsEnv
)
>>
numThreads
;
fftwf_init_threads
();
hasInitializedThreads
=
true
;
}
threadEnergy
.
resize
(
numThreads
);
gridx
=
findFFTDimension
(
xsize
,
false
);
gridy
=
findFFTDimension
(
ysize
,
false
);
gridz
=
findFFTDimension
(
zsize
,
true
);
this
->
numParticles
=
numParticles
;
this
->
alpha
=
alpha
;
force
.
resize
(
4
*
numParticles
);
recipEterm
.
resize
(
gridx
*
gridy
*
gridz
);
// Initialize threads.
isFinished
=
false
;
pthread_cond_init
(
&
startCondition
,
NULL
);
pthread_cond_init
(
&
endCondition
,
NULL
);
pthread_mutex_init
(
&
lock
,
NULL
);
pthread_create
(
&
mainThread
,
NULL
,
dispersionThreadBody
,
this
);
// Wait until the main thread is up and running.
pthread_mutex_lock
(
&
lock
);
while
(
!
isFinished
)
pthread_cond_wait
(
&
endCondition
,
&
lock
);
pthread_mutex_unlock
(
&
lock
);
// Initialize FFTW.
for
(
int
i
=
0
;
i
<
numThreads
;
i
++
)
tempGrid
.
push_back
((
float
*
)
fftwf_malloc
(
sizeof
(
float
)
*
(
gridx
*
gridy
*
gridz
+
3
)));
realGrid
=
tempGrid
[
0
];
complexGrid
=
(
fftwf_complex
*
)
fftwf_malloc
(
sizeof
(
fftwf_complex
)
*
gridx
*
gridy
*
(
gridz
/
2
+
1
));
fftwf_plan_with_nthreads
(
numThreads
);
forwardFFT
=
fftwf_plan_dft_r2c_3d
(
gridx
,
gridy
,
gridz
,
realGrid
,
complexGrid
,
FFTW_MEASURE
);
backwardFFT
=
fftwf_plan_dft_c2r_3d
(
gridx
,
gridy
,
gridz
,
complexGrid
,
realGrid
,
FFTW_MEASURE
);
hasCreatedPlan
=
true
;
// Initialize the b-spline moduli.
int
maxSize
=
std
::
max
(
std
::
max
(
gridx
,
gridy
),
gridz
);
vector
<
double
>
data
(
PME_ORDER
);
vector
<
double
>
ddata
(
PME_ORDER
);
vector
<
double
>
bsplinesData
(
maxSize
);
data
[
PME_ORDER
-
1
]
=
0.0
;
data
[
1
]
=
0.0
;
data
[
0
]
=
1.0
;
for
(
int
i
=
3
;
i
<
PME_ORDER
;
i
++
)
{
double
div
=
1.0
/
(
i
-
1.0
);
data
[
i
-
1
]
=
0.0
;
for
(
int
j
=
1
;
j
<
(
i
-
1
);
j
++
)
data
[
i
-
j
-
1
]
=
div
*
(
j
*
data
[
i
-
j
-
2
]
+
(
i
-
j
)
*
data
[
i
-
j
-
1
]);
data
[
0
]
=
div
*
data
[
0
];
}
// Differentiate.
ddata
[
0
]
=
-
data
[
0
];
for
(
int
i
=
1
;
i
<
PME_ORDER
;
i
++
)
ddata
[
i
]
=
data
[
i
-
1
]
-
data
[
i
];
double
div
=
1.0
/
(
PME_ORDER
-
1
);
data
[
PME_ORDER
-
1
]
=
0.0
;
for
(
int
i
=
1
;
i
<
(
PME_ORDER
-
1
);
i
++
)
data
[
PME_ORDER
-
i
-
1
]
=
div
*
(
i
*
data
[
PME_ORDER
-
i
-
2
]
+
(
PME_ORDER
-
i
)
*
data
[
PME_ORDER
-
i
-
1
]);
data
[
0
]
=
div
*
data
[
0
];
for
(
int
i
=
0
;
i
<
maxSize
;
i
++
)
bsplinesData
[
i
]
=
0.0
;
for
(
int
i
=
1
;
i
<=
PME_ORDER
;
i
++
)
bsplinesData
[
i
]
=
data
[
i
-
1
];
// Evaluate the actual bspline moduli for X/Y/Z.
bsplineModuli
[
0
].
resize
(
gridx
);
bsplineModuli
[
1
].
resize
(
gridy
);
bsplineModuli
[
2
].
resize
(
gridz
);
for
(
int
dim
=
0
;
dim
<
3
;
dim
++
)
{
int
ndata
=
bsplineModuli
[
dim
].
size
();
vector
<
float
>&
moduli
=
bsplineModuli
[
dim
];
for
(
int
i
=
0
;
i
<
ndata
;
i
++
)
{
double
sc
=
0.0
;
double
ss
=
0.0
;
for
(
int
j
=
0
;
j
<
ndata
;
j
++
)
{
double
arg
=
(
2.0
*
M_PI
*
i
*
j
)
/
ndata
;
sc
+=
bsplinesData
[
j
]
*
cos
(
arg
);
ss
+=
bsplinesData
[
j
]
*
sin
(
arg
);
}
moduli
[
i
]
=
(
float
)
(
sc
*
sc
+
ss
*
ss
);
}
for
(
int
i
=
0
;
i
<
ndata
;
i
++
)
if
(
moduli
[
i
]
<
1.0e-7
f
)
moduli
[
i
]
=
(
moduli
[
i
-
1
]
+
moduli
[
i
+
1
])
*
0.5
f
;
}
}
CpuCalcDispersionPmeReciprocalForceKernel
::~
CpuCalcDispersionPmeReciprocalForceKernel
()
{
isDeleted
=
true
;
pthread_mutex_lock
(
&
lock
);
pthread_cond_broadcast
(
&
startCondition
);
pthread_mutex_unlock
(
&
lock
);
pthread_join
(
mainThread
,
NULL
);
pthread_mutex_destroy
(
&
lock
);
pthread_cond_destroy
(
&
startCondition
);
pthread_cond_destroy
(
&
endCondition
);
for
(
int
i
=
0
;
i
<
(
int
)
tempGrid
.
size
();
i
++
)
fftwf_free
(
tempGrid
[
i
]);
if
(
complexGrid
!=
NULL
)
fftwf_free
(
complexGrid
);
if
(
hasCreatedPlan
)
{
fftwf_destroy_plan
(
forwardFFT
);
fftwf_destroy_plan
(
backwardFFT
);
}
}
void
CpuCalcDispersionPmeReciprocalForceKernel
::
runMainThread
()
{
// This is the main thread that coordinates all the other ones.
pthread_mutex_lock
(
&
lock
);
isFinished
=
true
;
pthread_cond_signal
(
&
endCondition
);
ThreadPool
threads
(
numThreads
);
while
(
true
)
{
// Wait for the signal to start.
pthread_cond_wait
(
&
startCondition
,
&
lock
);
if
(
isDeleted
)
break
;
posq
=
io
->
getPosq
();
ComputeTask
task
(
*
this
);
gmx_atomic_set
(
&
atomicCounter
,
0
);
threads
.
execute
(
task
);
// Signal threads to perform charge spreading.
threads
.
waitForThreads
();
threads
.
resumeThreads
();
// Signal threads to sum the charge grids.
threads
.
waitForThreads
();
fftwf_execute_dft_r2c
(
forwardFFT
,
realGrid
,
complexGrid
);
if
(
lastBoxVectors
[
0
]
!=
periodicBoxVectors
[
0
]
||
lastBoxVectors
[
1
]
!=
periodicBoxVectors
[
1
]
||
lastBoxVectors
[
2
]
!=
periodicBoxVectors
[
2
])
{
threads
.
resumeThreads
();
// Signal threads to compute the reciprocal scale factors.
threads
.
waitForThreads
();
}
if
(
includeEnergy
)
{
threads
.
resumeThreads
();
// Signal threads to compute energy.
threads
.
waitForThreads
();
for
(
int
i
=
0
;
i
<
(
int
)
threadEnergy
.
size
();
i
++
)
energy
+=
threadEnergy
[
i
];
}
threads
.
resumeThreads
();
// Signal threads to perform reciprocal convolution.
threads
.
waitForThreads
();
fftwf_execute_dft_c2r
(
backwardFFT
,
complexGrid
,
realGrid
);
gmx_atomic_set
(
&
atomicCounter
,
0
);
threads
.
resumeThreads
();
// Signal threads to interpolate forces.
threads
.
waitForThreads
();
isFinished
=
true
;
lastBoxVectors
[
0
]
=
periodicBoxVectors
[
0
];
lastBoxVectors
[
1
]
=
periodicBoxVectors
[
1
];
lastBoxVectors
[
2
]
=
periodicBoxVectors
[
2
];
pthread_cond_signal
(
&
endCondition
);
}
pthread_mutex_unlock
(
&
lock
);
}
void
CpuCalcDispersionPmeReciprocalForceKernel
::
runWorkerThread
(
ThreadPool
&
threads
,
int
index
)
{
int
gridxStart
=
(
index
*
gridx
)
/
numThreads
;
int
gridxEnd
=
((
index
+
1
)
*
gridx
)
/
numThreads
;
int
gridSize
=
(
gridx
*
gridy
*
gridz
+
3
)
/
4
;
int
gridStart
=
4
*
((
index
*
gridSize
)
/
numThreads
);
int
gridEnd
=
4
*
(((
index
+
1
)
*
gridSize
)
/
numThreads
);
int
complexSize
=
gridx
*
gridy
*
(
gridz
/
2
+
1
);
int
complexStart
=
std
::
max
(
1
,
((
index
*
complexSize
)
/
numThreads
));
int
complexEnd
=
(((
index
+
1
)
*
complexSize
)
/
numThreads
);
const
float
epsilonFactor
=
1.0
f
;
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
);
threads
.
syncThreads
();
int
numGrids
=
tempGrid
.
size
();
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
fvec4
sum
(
&
realGrid
[
i
]);
for
(
int
j
=
1
;
j
<
numGrids
;
j
++
)
sum
+=
fvec4
(
&
tempGrid
[
j
][
i
]);
sum
.
store
(
&
realGrid
[
i
]);
}
threads
.
syncThreads
();
if
(
lastBoxVectors
[
0
]
!=
periodicBoxVectors
[
0
]
||
lastBoxVectors
[
1
]
!=
periodicBoxVectors
[
1
]
||
lastBoxVectors
[
2
]
!=
periodicBoxVectors
[
2
])
{
computeReciprocalDispersionEterm
(
gridxStart
,
gridxEnd
,
gridx
,
gridy
,
gridz
,
recipEterm
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
threads
.
syncThreads
();
}
if
(
includeEnergy
)
{
threadEnergy
[
index
]
=
reciprocalDispersionEnergy
(
gridxStart
,
gridxEnd
,
complexGrid
,
recipEterm
,
gridx
,
gridy
,
gridz
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
threads
.
syncThreads
();
}
// For dispersion, we include the {0,0,0} term, so the start point needs to be redefined
complexStart
=
(
index
*
complexSize
)
/
numThreads
;
reciprocalConvolution
(
complexStart
,
complexEnd
,
complexGrid
,
recipEterm
);
threads
.
syncThreads
();
interpolateForces
(
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
);
}
void
CpuCalcDispersionPmeReciprocalForceKernel
::
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
)
{
this
->
io
=
&
io
;
this
->
periodicBoxVectors
[
0
]
=
periodicBoxVectors
[
0
];
this
->
periodicBoxVectors
[
1
]
=
periodicBoxVectors
[
1
];
this
->
periodicBoxVectors
[
2
]
=
periodicBoxVectors
[
2
];
this
->
includeEnergy
=
includeEnergy
;
energy
=
0.0
;
// Invert the box vectors.
double
determinant
=
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
];
double
scale
=
1.0
/
determinant
;
recipBoxVectors
[
0
]
=
Vec3
(
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
],
0
,
0
)
*
scale
;
recipBoxVectors
[
1
]
=
Vec3
(
-
periodicBoxVectors
[
1
][
0
]
*
periodicBoxVectors
[
2
][
2
],
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
2
][
2
],
0
)
*
scale
;
recipBoxVectors
[
2
]
=
Vec3
(
periodicBoxVectors
[
1
][
0
]
*
periodicBoxVectors
[
2
][
1
]
-
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
0
],
-
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
2
][
1
],
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
])
*
scale
;
// Do the calculation.
pthread_mutex_lock
(
&
lock
);
isFinished
=
false
;
pthread_cond_signal
(
&
startCondition
);
pthread_mutex_unlock
(
&
lock
);
}
double
CpuCalcDispersionPmeReciprocalForceKernel
::
finishComputation
(
IO
&
io
)
{
pthread_mutex_lock
(
&
lock
);
while
(
!
isFinished
)
{
pthread_cond_wait
(
&
endCondition
,
&
lock
);
}
pthread_mutex_unlock
(
&
lock
);
io
.
setForce
(
&
force
[
0
]);
return
energy
;
}
bool
CpuCalcDispersionPmeReciprocalForceKernel
::
isProcessorSupported
()
{
return
isVec4Supported
();
}
void
CpuCalcDispersionPmeReciprocalForceKernel
::
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
{
alpha
=
this
->
alpha
;
nx
=
gridx
;
ny
=
gridy
;
nz
=
gridz
;
}
int
CpuCalcDispersionPmeReciprocalForceKernel
::
findFFTDimension
(
int
minimum
,
bool
isZ
)
{
if
(
minimum
<
1
)
return
1
;
while
(
true
)
{
// Attempt to factor the current value.
if
(
isZ
&&
minimum
%
2
==
1
)
{
// Force the last dimension to be even, since this produces better performance in FFTW.
minimum
++
;
continue
;
}
int
unfactored
=
minimum
;
for
(
int
factor
=
2
;
factor
<
8
;
factor
++
)
{
while
(
unfactored
>
1
&&
unfactored
%
factor
==
0
)
unfactored
/=
factor
;
}
if
(
unfactored
==
1
||
unfactored
==
11
||
unfactored
==
13
)
return
minimum
;
minimum
++
;
}
}
plugins/cpupme/src/CpuPmeKernels.h
View file @
53f770f4
...
@@ -133,6 +133,98 @@ private:
...
@@ -133,6 +133,98 @@ private:
gmx_atomic_t
atomicCounter
;
gmx_atomic_t
atomicCounter
;
};
};
/**
* This is an optimized CPU implementation of CalcDispersionPmeReciprocalForceKernel. It is both
* vectorized (requiring SSE 4.1) and multithreaded. It uses FFTW to perform the FFTs.
*/
class
OPENMM_EXPORT_PME
CpuCalcDispersionPmeReciprocalForceKernel
:
public
CalcPmeReciprocalForceKernel
{
public:
CpuCalcDispersionPmeReciprocalForceKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
CalcPmeReciprocalForceKernel
(
name
,
platform
),
hasCreatedPlan
(
false
),
isDeleted
(
false
),
realGrid
(
NULL
),
complexGrid
(
NULL
)
{
}
/**
* Initialize the kernel.
*
* @param gridx the x size of the PME grid
* @param gridy the y size of the PME grid
* @param gridz the z size of the PME grid
* @param numParticles the number of particles in the system
* @param alpha the Ewald blending parameter
*/
void
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
);
~
CpuCalcDispersionPmeReciprocalForceKernel
();
/**
* Begin computing the force and energy.
*
* @param io an object that coordinates data transfer
* @param periodicBoxVectors the vectors defining the periodic box (measured in nm)
* @param includeEnergy true if potential energy should be computed
*/
void
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
);
/**
* Finish computing the force and energy.
*
* @param io an object that coordinates data transfer
* @return the potential energy due to the PME reciprocal space interactions
*/
double
finishComputation
(
IO
&
io
);
/**
* This routine contains the code executed by the main thread.
*/
void
runMainThread
();
/**
* This routine contains the code executed by each worker thread.
*/
void
runWorkerThread
(
ThreadPool
&
threads
,
int
index
);
/**
* Get whether the current CPU supports all features needed by this kernel.
*/
static
bool
isProcessorSupported
();
/**
* Get the parameters being used for PME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void
getPMEParameters
(
double
&
alpha
,
int
&
nx
,
int
&
ny
,
int
&
nz
)
const
;
private:
class
ComputeTask
;
/**
* Select a size for one grid dimension that FFTW can handle efficiently.
*/
int
findFFTDimension
(
int
minimum
,
bool
isZ
);
static
bool
hasInitializedThreads
;
static
int
numThreads
;
int
gridx
,
gridy
,
gridz
,
numParticles
;
double
alpha
;
bool
hasCreatedPlan
,
isFinished
,
isDeleted
;
std
::
vector
<
float
>
force
;
std
::
vector
<
float
>
bsplineModuli
[
3
];
std
::
vector
<
float
>
recipEterm
;
Vec3
lastBoxVectors
[
3
];
std
::
vector
<
float
>
threadEnergy
;
std
::
vector
<
float
*>
tempGrid
;
float
*
realGrid
;
fftwf_complex
*
complexGrid
;
fftwf_plan
forwardFFT
,
backwardFFT
;
int
waitCount
;
pthread_cond_t
startCondition
,
endCondition
;
pthread_mutex_t
lock
;
pthread_t
mainThread
;
// The following variables are used to store information about the calculation currently being performed.
IO
*
io
;
float
energy
;
float
*
posq
;
Vec3
periodicBoxVectors
[
3
],
recipBoxVectors
[
3
];
bool
includeEnergy
;
gmx_atomic_t
atomicCounter
;
};
}
// namespace OpenMM
}
// namespace OpenMM
#endif
/*OPENMM_CPU_PME_KERNELS_H_*/
#endif
/*OPENMM_CPU_PME_KERNELS_H_*/
plugins/cpupme/tests/TestCpuPme.cpp
View file @
53f770f4
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include "openmm/System.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/Units.h"
#include "../src/CpuPmeKernels.h"
#include "../src/CpuPmeKernels.h"
#include "SimTKOpenMMRealType.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include "sfmt/SFMT.h"
...
@@ -61,6 +62,509 @@ public:
...
@@ -61,6 +62,509 @@ public:
}
}
};
};
void
make_waterbox
(
int
natoms
,
double
boxEdgeLength
,
NonbondedForce
*
forceField
,
vector
<
Vec3
>
&
positions
,
vector
<
double
>&
eps
,
vector
<
double
>&
sig
,
vector
<
pair
<
int
,
int
>
>&
bonds
,
System
&
system
,
bool
do_electrostatics
)
{
const
int
RESSIZE
=
3
;
const
double
masses
[
RESSIZE
]
=
{
8.0
,
1.0
,
1.0
};
const
double
charges
[
RESSIZE
]
=
{
-
0.834
,
0.417
,
0.417
};
// Values from the CHARMM force field, in AKMA units
const
double
epsilons
[
RESSIZE
]
=
{
-
0.1521
,
-
0.046
,
-
0.046
};
const
double
halfrmins
[
RESSIZE
]
=
{
1.7682
,
0.2245
,
0.2245
};
positions
.
clear
();
if
(
natoms
==
6
){
const
double
coords
[
6
][
3
]
=
{
{
2.000000
,
2.000000
,
2.000000
},
{
2.500000
,
2.000000
,
3.000000
},
{
1.500000
,
2.000000
,
3.000000
},
{
0.000000
,
0.000000
,
0.000000
},
{
0.500000
,
0.000000
,
1.000000
},
{
-
0.500000
,
0.000000
,
1.000000
}
};
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
positions
.
push_back
(
Vec3
(
coords
[
atom
][
0
],
coords
[
atom
][
1
],
coords
[
atom
][
2
])
*
OpenMM
::
NmPerAngstrom
);
}
else
if
(
natoms
==
375
){
const
double
coords
[
375
][
3
]
=
{
{
-
6.22
,
-
6.25
,
-
6.24
},
{
-
5.32
,
-
6.03
,
-
6.00
},
{
-
6.75
,
-
5.56
,
-
5.84
},
{
-
3.04
,
-
6.23
,
-
6.19
},
{
-
3.52
,
-
5.55
,
-
5.71
},
{
-
3.59
,
-
6.43
,
-
6.94
},
{
0.02
,
-
6.23
,
-
6.14
},
{
-
0.87
,
-
5.97
,
-
6.37
},
{
0.53
,
-
6.03
,
-
6.93
},
{
3.10
,
-
6.20
,
-
6.27
},
{
3.87
,
-
6.35
,
-
5.72
},
{
2.37
,
-
6.11
,
-
5.64
},
{
6.18
,
-
6.14
,
-
6.20
},
{
6.46
,
-
6.66
,
-
5.44
},
{
6.26
,
-
6.74
,
-
6.94
},
{
-
6.21
,
-
3.15
,
-
6.24
},
{
-
6.23
,
-
3.07
,
-
5.28
},
{
-
6.02
,
-
2.26
,
-
6.55
},
{
-
3.14
,
-
3.07
,
-
6.16
},
{
-
3.38
,
-
3.63
,
-
6.90
},
{
-
2.18
,
-
3.05
,
-
6.17
},
{
-
0.00
,
-
3.16
,
-
6.23
},
{
-
0.03
,
-
2.30
,
-
6.67
},
{
0.05
,
-
2.95
,
-
5.29
},
{
3.08
,
-
3.11
,
-
6.14
},
{
2.65
,
-
2.55
,
-
6.79
},
{
3.80
,
-
3.53
,
-
6.62
},
{
6.16
,
-
3.14
,
-
6.16
},
{
7.04
,
-
3.32
,
-
6.51
},
{
5.95
,
-
2.27
,
-
6.51
},
{
-
6.20
,
-
0.04
,
-
6.15
},
{
-
5.43
,
0.32
,
-
6.59
},
{
-
6.95
,
0.33
,
-
6.62
},
{
-
3.10
,
-
0.06
,
-
6.19
},
{
-
3.75
,
0.42
,
-
6.69
},
{
-
2.46
,
0.60
,
-
5.93
},
{
0.05
,
-
0.01
,
-
6.17
},
{
-
0.10
,
0.02
,
-
7.12
},
{
-
0.79
,
0.16
,
-
5.77
},
{
3.03
,
0.00
,
-
6.19
},
{
3.54
,
0.08
,
-
7.01
},
{
3.69
,
-
0.22
,
-
5.53
},
{
6.17
,
0.05
,
-
6.19
},
{
5.78
,
-
0.73
,
-
6.57
},
{
7.09
,
-
0.17
,
-
6.04
},
{
-
6.20
,
3.15
,
-
6.25
},
{
-
6.59
,
3.18
,
-
5.37
},
{
-
5.87
,
2.25
,
-
6.33
},
{
-
3.09
,
3.04
,
-
6.17
},
{
-
3.88
,
3.58
,
-
6.26
},
{
-
2.41
,
3.54
,
-
6.63
},
{
0.00
,
3.06
,
-
6.26
},
{
-
0.71
,
3.64
,
-
6.00
},
{
0.65
,
3.15
,
-
5.55
},
{
3.14
,
3.06
,
-
6.23
},
{
3.11
,
3.31
,
-
5.30
},
{
2.38
,
3.49
,
-
6.63
},
{
6.19
,
3.14
,
-
6.25
},
{
6.82
,
3.25
,
-
5.54
},
{
5.76
,
2.30
,
-
6.07
},
{
-
6.22
,
6.26
,
-
6.19
},
{
-
6.22
,
5.74
,
-
7.00
},
{
-
5.89
,
5.67
,
-
5.52
},
{
-
3.04
,
6.24
,
-
6.20
},
{
-
3.08
,
5.28
,
-
6.17
},
{
-
3.96
,
6.52
,
-
6.25
},
{
-
0.05
,
6.21
,
-
6.16
},
{
0.82
,
6.58
,
-
6.06
},
{
0.01
,
5.64
,
-
6.93
},
{
3.10
,
6.25
,
-
6.15
},
{
3.64
,
5.47
,
-
6.31
},
{
2.46
,
6.24
,
-
6.87
},
{
6.22
,
6.20
,
-
6.27
},
{
5.37
,
6.42
,
-
5.88
},
{
6.80
,
6.07
,
-
5.51
},
{
-
6.19
,
-
6.15
,
-
3.13
},
{
-
6.37
,
-
7.01
,
-
3.51
},
{
-
6.25
,
-
6.29
,
-
2.18
},
{
-
3.10
,
-
6.27
,
-
3.11
},
{
-
2.29
,
-
5.77
,
-
2.99
},
{
-
3.80
,
-
5.62
,
-
2.98
},
{
-
0.03
,
-
6.18
,
-
3.15
},
{
-
0.07
,
-
7.05
,
-
2.75
},
{
0.68
,
-
5.74
,
-
2.70
},
{
3.10
,
-
6.14
,
-
3.07
},
{
2.35
,
-
6.72
,
-
3.23
},
{
3.86
,
-
6.65
,
-
3.37
},
{
6.22
,
-
6.20
,
-
3.16
},
{
6.82
,
-
6.36
,
-
2.43
},
{
5.35
,
-
6.13
,
-
2.75
},
{
-
6.26
,
-
3.13
,
-
3.12
},
{
-
6.16
,
-
2.27
,
-
2.70
},
{
-
5.36
,
-
3.47
,
-
3.18
},
{
-
3.11
,
-
3.05
,
-
3.14
},
{
-
3.31
,
-
3.96
,
-
3.34
},
{
-
2.77
,
-
3.06
,
-
2.24
},
{
0.00
,
-
3.13
,
-
3.16
},
{
0.48
,
-
2.37
,
-
2.81
},
{
-
0.57
,
-
3.40
,
-
2.44
},
{
3.09
,
-
3.09
,
-
3.16
},
{
2.41
,
-
3.19
,
-
2.49
},
{
3.91
,
-
3.07
,
-
2.67
},
{
6.19
,
-
3.04
,
-
3.08
},
{
5.64
,
-
3.61
,
-
3.61
},
{
6.93
,
-
3.58
,
-
2.82
},
{
-
6.18
,
-
0.00
,
-
3.04
},
{
-
6.00
,
-
0.59
,
-
3.78
},
{
-
6.79
,
0.64
,
-
3.39
},
{
-
3.05
,
-
0.03
,
-
3.07
},
{
-
2.95
,
0.80
,
-
3.52
},
{
-
4.00
,
-
0.20
,
-
3.07
},
{
-
0.03
,
0.03
,
-
3.06
},
{
-
0.33
,
-
0.37
,
-
3.87
},
{
0.89
,
-
0.21
,
-
2.99
},
{
3.13
,
-
0.05
,
-
3.10
},
{
3.44
,
0.81
,
-
3.34
},
{
2.21
,
0.07
,
-
2.86
},
{
6.20
,
-
0.05
,
-
3.13
},
{
6.89
,
0.60
,
-
3.20
},
{
5.58
,
0.30
,
-
2.49
},
{
-
6.23
,
3.09
,
-
3.16
},
{
-
5.62
,
3.79
,
-
2.94
},
{
-
6.33
,
2.60
,
-
2.33
},
{
-
3.10
,
3.08
,
-
3.04
},
{
-
3.84
,
3.47
,
-
3.51
},
{
-
2.40
,
3.01
,
-
3.69
},
{
0.01
,
3.04
,
-
3.11
},
{
-
0.56
,
3.59
,
-
3.64
},
{
0.28
,
3.60
,
-
2.38
},
{
3.04
,
3.11
,
-
3.09
},
{
3.49
,
2.30
,
-
2.87
},
{
3.70
,
3.66
,
-
3.51
},
{
6.15
,
3.14
,
-
3.11
},
{
6.52
,
2.52
,
-
3.74
},
{
6.72
,
3.06
,
-
2.34
},
{
-
6.22
,
6.15
,
-
3.13
},
{
-
5.49
,
6.21
,
-
2.51
},
{
-
6.56
,
7.04
,
-
3.18
},
{
-
3.11
,
6.24
,
-
3.05
},
{
-
3.76
,
5.83
,
-
3.62
},
{
-
2.26
,
5.92
,
-
3.37
},
{
0.03
,
6.25
,
-
3.07
},
{
0.34
,
5.63
,
-
3.73
},
{
-
0.87
,
6.00
,
-
2.91
},
{
3.07
,
6.15
,
-
3.08
},
{
3.29
,
6.92
,
-
2.56
},
{
3.39
,
6.35
,
-
3.96
},
{
6.22
,
6.14
,
-
3.12
},
{
5.79
,
6.38
,
-
2.29
},
{
6.25
,
6.96
,
-
3.62
},
{
-
6.21
,
-
6.20
,
-
0.06
},
{
-
5.79
,
-
6.87
,
0.48
},
{
-
6.43
,
-
5.50
,
0.54
},
{
-
3.16
,
-
6.21
,
-
0.02
},
{
-
2.50
,
-
6.87
,
0.20
},
{
-
2.77
,
-
5.37
,
0.23
},
{
-
0.00
,
-
6.14
,
-
0.00
},
{
0.68
,
-
6.72
,
-
0.33
},
{
-
0.64
,
-
6.73
,
0.38
},
{
3.03
,
-
6.20
,
-
0.01
},
{
3.77
,
-
6.56
,
-
0.51
},
{
3.43
,
-
5.85
,
0.78
},
{
6.25
,
-
6.16
,
-
0.00
},
{
5.36
,
-
6.09
,
-
0.36
},
{
6.24
,
-
6.97
,
0.49
},
{
-
6.24
,
-
3.05
,
-
0.01
},
{
-
6.35
,
-
3.64
,
0.73
},
{
-
5.42
,
-
3.33
,
-
0.42
},
{
-
3.09
,
-
3.06
,
0.05
},
{
-
2.44
,
-
3.62
,
-
0.38
},
{
-
3.90
,
-
3.21
,
-
0.43
},
{
0.05
,
-
3.10
,
0.02
},
{
-
0.31
,
-
2.35
,
-
0.43
},
{
-
0.63
,
-
3.77
,
0.01
},
{
3.05
,
-
3.09
,
-
0.04
},
{
3.28
,
-
3.90
,
0.41
},
{
3.65
,
-
2.43
,
0.30
},
{
6.20
,
-
3.04
,
-
0.03
},
{
5.66
,
-
3.31
,
0.71
},
{
6.78
,
-
3.79
,
-
0.19
},
{
-
6.18
,
0.04
,
-
0.04
},
{
-
6.73
,
-
0.73
,
-
0.15
},
{
-
5.98
,
0.06
,
0.89
},
{
-
3.11
,
-
0.04
,
-
0.04
},
{
-
3.36
,
-
0.08
,
0.87
},
{
-
2.70
,
0.81
,
-
0.14
},
{
-
0.02
,
-
0.02
,
-
0.05
},
{
-
0.45
,
0.28
,
0.75
},
{
0.90
,
0.15
,
0.07
},
{
3.04
,
0.02
,
-
0.01
},
{
3.26
,
-
0.82
,
0.38
},
{
3.89
,
0.45
,
-
0.13
},
{
6.19
,
0.05
,
-
0.03
},
{
5.52
,
-
0.56
,
0.25
},
{
7.01
,
-
0.29
,
0.32
},
{
-
6.14
,
3.08
,
0.00
},
{
-
6.83
,
2.82
,
0.61
},
{
-
6.59
,
3.64
,
-
0.64
},
{
-
3.05
,
3.09
,
-
0.04
},
{
-
3.79
,
2.50
,
0.09
},
{
-
3.18
,
3.80
,
0.59
},
{
0.02
,
3.14
,
0.04
},
{
-
0.89
,
3.04
,
-
0.19
},
{
0.49
,
2.57
,
-
0.57
},
{
3.14
,
3.15
,
0.00
},
{
3.28
,
2.28
,
0.37
},
{
2.30
,
3.08
,
-
0.45
},
{
6.27
,
3.08
,
-
0.00
},
{
5.55
,
2.54
,
-
0.33
},
{
5.83
,
3.87
,
0.34
},
{
-
6.18
,
6.15
,
-
0.03
},
{
-
6.45
,
6.21
,
0.88
},
{
-
6.26
,
7.05
,
-
0.36
},
{
-
3.06
,
6.19
,
-
0.05
},
{
-
2.84
,
6.64
,
0.76
},
{
-
3.99
,
5.96
,
0.03
},
{
-
0.00
,
6.20
,
0.06
},
{
-
0.67
,
5.99
,
-
0.59
},
{
0.76
,
6.46
,
-
0.44
},
{
3.10
,
6.26
,
-
0.03
},
{
3.57
,
6.09
,
0.78
},
{
2.57
,
5.47
,
-
0.18
},
{
6.26
,
6.18
,
0.02
},
{
5.53
,
5.64
,
-
0.29
},
{
5.95
,
7.08
,
-
0.06
},
{
-
6.26
,
-
6.21
,
3.07
},
{
-
5.98
,
-
6.38
,
3.97
},
{
-
5.46
,
-
5.94
,
2.62
},
{
-
3.10
,
-
6.24
,
3.04
},
{
-
2.69
,
-
6.51
,
3.87
},
{
-
3.43
,
-
5.35
,
3.21
},
{
-
0.03
,
-
6.16
,
3.06
},
{
0.83
,
-
6.00
,
3.42
},
{
-
0.30
,
-
6.99
,
3.45
},
{
3.15
,
-
6.25
,
3.11
},
{
2.77
,
-
5.60
,
3.72
},
{
2.68
,
-
6.10
,
2.28
},
{
6.20
,
-
6.21
,
3.16
},
{
5.75
,
-
6.73
,
2.50
},
{
6.69
,
-
5.56
,
2.66
},
{
-
6.17
,
-
3.10
,
3.04
},
{
-
6.82
,
-
2.44
,
3.28
},
{
-
6.12
,
-
3.69
,
3.80
},
{
-
3.08
,
-
3.04
,
3.11
},
{
-
3.59
,
-
3.56
,
3.72
},
{
-
2.97
,
-
3.61
,
2.34
},
{
0.01
,
-
3.04
,
3.11
},
{
-
0.86
,
-
3.41
,
3.20
},
{
0.56
,
-
3.78
,
2.86
},
{
3.07
,
-
3.07
,
3.15
},
{
3.81
,
-
3.68
,
3.13
},
{
2.80
,
-
2.98
,
2.23
},
{
6.20
,
-
3.04
,
3.13
},
{
5.48
,
-
3.64
,
2.92
},
{
6.98
,
-
3.49
,
2.81
},
{
-
6.18
,
-
0.05
,
3.12
},
{
-
6.41
,
0.66
,
3.69
},
{
-
6.33
,
0.28
,
2.23
},
{
-
3.05
,
0.03
,
3.10
},
{
-
3.46
,
-
0.42
,
3.83
},
{
-
3.57
,
-
0.19
,
2.33
},
{
0.03
,
-
0.02
,
3.15
},
{
0.23
,
-
0.08
,
2.21
},
{
-
0.81
,
0.41
,
3.18
},
{
3.09
,
0.00
,
3.03
},
{
2.48
,
-
0.29
,
3.71
},
{
3.91
,
0.16
,
3.51
},
{
6.19
,
-
0.06
,
3.11
},
{
6.05
,
0.47
,
2.33
},
{
6.59
,
0.52
,
3.74
},
{
-
6.20
,
3.05
,
3.05
},
{
-
6.87
,
3.73
,
3.17
},
{
-
5.55
,
3.24
,
3.73
},
{
-
3.11
,
3.06
,
3.15
},
{
-
3.64
,
3.74
,
2.71
},
{
-
2.32
,
3.00
,
2.62
},
{
0.02
,
3.05
,
3.06
},
{
-
0.87
,
3.14
,
3.38
},
{
0.48
,
3.82
,
3.42
},
{
3.07
,
3.10
,
3.16
},
{
3.95
,
3.44
,
2.97
},
{
2.76
,
2.73
,
2.32
},
{
6.19
,
3.07
,
3.16
},
{
7.02
,
3.30
,
2.72
},
{
5.52
,
3.27
,
2.51
},
{
-
6.19
,
6.24
,
3.15
},
{
-
5.56
,
5.88
,
2.52
},
{
-
7.05
,
5.96
,
2.83
},
{
-
3.10
,
6.14
,
3.08
},
{
-
2.34
,
6.69
,
3.27
},
{
-
3.86
,
6.69
,
3.29
},
{
-
0.04
,
6.24
,
3.13
},
{
0.63
,
6.54
,
2.53
},
{
0.08
,
5.29
,
3.18
},
{
3.12
,
6.24
,
3.14
},
{
3.57
,
5.82
,
2.40
},
{
2.23
,
5.90
,
3.12
},
{
6.25
,
6.19
,
3.06
},
{
5.55
,
5.59
,
3.32
},
{
6.08
,
6.99
,
3.55
},
{
-
6.20
,
-
6.16
,
6.15
},
{
-
6.29
,
-
5.99
,
7.09
},
{
-
6.09
,
-
7.11
,
6.09
},
{
-
3.09
,
-
6.19
,
6.27
},
{
-
2.56
,
-
5.90
,
5.52
},
{
-
3.80
,
-
6.69
,
5.87
},
{
0.02
,
-
6.25
,
6.24
},
{
-
0.70
,
-
5.70
,
6.51
},
{
0.25
,
-
5.93
,
5.36
},
{
3.11
,
-
6.18
,
6.14
},
{
3.76
,
-
6.54
,
6.74
},
{
2.29
,
-
6.20
,
6.64
},
{
6.22
,
-
6.17
,
6.15
},
{
6.61
,
-
6.98
,
6.47
},
{
5.56
,
-
5.94
,
6.81
},
{
-
6.21
,
-
3.10
,
6.14
},
{
-
6.76
,
-
2.66
,
6.78
},
{
-
5.51
,
-
3.50
,
6.65
},
{
-
3.13
,
-
3.05
,
6.18
},
{
-
2.19
,
-
3.14
,
6.34
},
{
-
3.50
,
-
3.89
,
6.43
},
{
0.01
,
-
3.06
,
6.15
},
{
-
0.06
,
-
2.81
,
7.07
},
{
-
0.25
,
-
3.98
,
6.13
},
{
3.04
,
-
3.09
,
6.17
},
{
3.84
,
-
3.51
,
5.84
},
{
3.25
,
-
2.85
,
7.08
},
{
6.26
,
-
3.13
,
6.19
},
{
6.01
,
-
2.20
,
6.09
},
{
5.47
,
-
3.55
,
6.54
},
{
-
6.20
,
0.01
,
6.27
},
{
-
5.79
,
-
0.70
,
5.78
},
{
-
6.67
,
0.51
,
5.60
},
{
-
3.13
,
0.01
,
6.14
},
{
-
3.53
,
-
0.35
,
6.94
},
{
-
2.21
,
0.17
,
6.39
},
{
-
0.04
,
-
0.04
,
6.20
},
{
0.26
,
0.47
,
5.46
},
{
0.51
,
0.22
,
6.93
},
{
3.10
,
-
0.05
,
6.23
},
{
2.33
,
0.44
,
5.95
},
{
3.85
,
0.45
,
5.92
},
{
6.19
,
-
0.01
,
6.26
},
{
7.05
,
0.16
,
5.88
},
{
5.58
,
0.02
,
5.52
},
{
-
6.22
,
3.04
,
6.17
},
{
-
5.45
,
3.57
,
5.95
},
{
-
6.62
,
3.50
,
6.92
},
{
-
3.09
,
3.16
,
6.21
},
{
-
3.71
,
2.75
,
5.61
},
{
-
2.60
,
2.43
,
6.59
},
{
-
0.02
,
3.10
,
6.26
},
{
0.89
,
3.27
,
6.05
},
{
-
0.44
,
2.94
,
5.41
},
{
3.12
,
3.04
,
6.23
},
{
2.31
,
3.53
,
6.43
},
{
3.59
,
3.60
,
5.60
},
{
6.23
,
3.05
,
6.24
},
{
5.92
,
3.91
,
6.54
},
{
6.02
,
3.03
,
5.30
},
{
-
6.15
,
6.21
,
6.24
},
{
-
6.27
,
6.46
,
5.32
},
{
-
7.00
,
5.85
,
6.51
},
{
-
3.07
,
6.15
,
6.22
},
{
-
3.98
,
6.27
,
5.94
},
{
-
2.66
,
7.01
,
6.10
},
{
0.04
,
6.20
,
6.25
},
{
-
0.38
,
5.50
,
5.75
},
{
-
0.36
,
7.00
,
5.93
},
{
3.12
,
6.15
,
6.24
},
{
3.66
,
6.88
,
5.93
},
{
2.25
,
6.33
,
5.86
},
{
6.20
,
6.27
,
6.19
},
{
5.46
,
5.65
,
6.19
},
{
6.97
,
5.73
,
6.39
}
};
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
positions
.
push_back
(
Vec3
(
coords
[
atom
][
0
],
coords
[
atom
][
1
],
coords
[
atom
][
2
])
*
OpenMM
::
NmPerAngstrom
);
}
else
{
throw
exception
();
}
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxEdgeLength
,
0
,
0
),
Vec3
(
0
,
boxEdgeLength
,
0
),
Vec3
(
0
,
0
,
boxEdgeLength
));
sig
.
clear
();
eps
.
clear
();
bonds
.
clear
();
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
){
system
.
addParticle
(
masses
[
atom
%
RESSIZE
]);
double
sigma
=
2.0
*
pow
(
2.0
,
-
1.0
/
6.0
)
*
halfrmins
[
atom
%
RESSIZE
]
*
OpenMM
::
NmPerAngstrom
;
double
epsilon
=
fabs
(
epsilons
[
atom
%
RESSIZE
])
*
OpenMM
::
KJPerKcal
;
sig
.
push_back
(
0.5
*
sigma
);
eps
.
push_back
(
2.0
*
sqrt
(
epsilon
));
if
(
atom
%
RESSIZE
==
0
){
bonds
.
push_back
(
pair
<
int
,
int
>
(
atom
,
atom
+
1
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
atom
,
atom
+
2
));
}
double
charge
=
do_electrostatics
?
charges
[
atom
]
:
0
;
forceField
->
addParticle
(
charge
,
sigma
,
epsilon
);
}
}
void
test_water2_dpme_energies_forces_no_exclusions
()
{
const
double
cutoff
=
7.0
*
OpenMM
::
NmPerAngstrom
;
const
double
dalpha
=
4.0124063605
;
const
int
grid
=
32
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
double
>
epsvals
;
vector
<
double
>
sigvals
;
vector
<
pair
<
int
,
int
>
>
bonds
;
System
system
;
const
int
NATOMS
=
6
;
double
boxEdgeLength
=
25
*
OpenMM
::
NmPerAngstrom
;
make_waterbox
(
NATOMS
,
boxEdgeLength
,
forceField
,
positions
,
epsvals
,
sigvals
,
bonds
,
system
,
false
);
forceField
->
setNonbondedMethod
(
OpenMM
::
NonbondedForce
::
LJPME
);
forceField
->
setPMEParameters
(
0.0
f
,
grid
,
grid
,
grid
);
forceField
->
setReciprocalSpaceForceGroup
(
1
);
forceField
->
setLJPMEParameters
(
dalpha
,
grid
,
grid
,
grid
);
forceField
->
setCutoffDistance
(
cutoff
);
forceField
->
setReactionFieldDielectric
(
1.0
);
system
.
addForce
(
forceField
);
// Reference calculation
VerletIntegrator
integrator
(
0.01
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
,
false
,
1
<<
1
);
double
refenergy
=
state
.
getPotentialEnergy
();
const
vector
<
Vec3
>&
refforces
=
state
.
getForces
();
// Optimized CPU calculation
CpuCalcDispersionPmeReciprocalForceKernel
pme
(
CalcPmeReciprocalForceKernel
::
Name
(),
platform
);
IO
io
;
double
selfEwaldEnergy
=
0
;
double
dalpha6
=
pow
(
dalpha
,
6.0
);
for
(
int
i
=
0
;
i
<
NATOMS
;
i
++
)
{
io
.
posq
.
push_back
((
float
)
positions
[
i
][
0
]);
io
.
posq
.
push_back
((
float
)
positions
[
i
][
1
]);
io
.
posq
.
push_back
((
float
)
positions
[
i
][
2
]);
double
c6
=
8.0
f
*
pow
(
sigvals
[
i
],
3
)
*
epsvals
[
i
];
io
.
posq
.
push_back
(
c6
);
selfEwaldEnergy
+=
dalpha6
*
c6
*
c6
/
12.0
;
}
pme
.
initialize
(
grid
,
grid
,
grid
,
NATOMS
,
dalpha
);
Vec3
boxVectors
[
3
];
system
.
getDefaultPeriodicBoxVectors
(
boxVectors
[
0
],
boxVectors
[
1
],
boxVectors
[
2
]);
pme
.
beginComputation
(
io
,
boxVectors
,
true
);
double
recenergy
=
pme
.
finishComputation
(
io
);
ASSERT_EQUAL_TOL
(
recenergy
,
-
2.179629087
,
5e-3
);
ASSERT_EQUAL_TOL
(
selfEwaldEnergy
,
1.731404285
,
1e-5
);
std
::
vector
<
Vec3
>
knownforces
(
6
);
knownforces
[
0
]
=
Vec3
(
-
1.890360546
,
-
1.890723915
,
-
1.879662698
);
knownforces
[
1
]
=
Vec3
(
-
0.003161352455
,
-
0.000922244929
,
-
0.005391616425
);
knownforces
[
2
]
=
Vec3
(
0.0009199035545
,
-
0.001453894176
,
-
0.006188087146
);
knownforces
[
3
]
=
Vec3
(
1.887108856
,
1.887241446
,
1.89644647
);
knownforces
[
4
]
=
Vec3
(
0.0008242336483
,
0.003778910089
,
-
0.002116131106
);
knownforces
[
5
]
=
Vec3
(
0.004912763044
,
0.002324059399
,
-
0.002844482646
);
for
(
int
i
=
0
;
i
<
NATOMS
;
i
++
)
ASSERT_EQUAL_VEC
(
refforces
[
i
],
knownforces
[
i
],
5e-3
);
recenergy
+=
selfEwaldEnergy
;
// See if they match.
ASSERT_EQUAL_TOL
(
refenergy
,
recenergy
,
1e-3
);
for
(
int
i
=
0
;
i
<
NATOMS
;
i
++
)
ASSERT_EQUAL_VEC
(
refforces
[
i
],
Vec3
(
io
.
force
[
4
*
i
],
io
.
force
[
4
*
i
+
1
],
io
.
force
[
4
*
i
+
2
]),
5e-3
);
}
void
testPME
(
bool
triclinic
)
{
void
testPME
(
bool
triclinic
)
{
// Create a cloud of random point charges.
// Create a cloud of random point charges.
...
@@ -108,7 +612,7 @@ void testPME(bool triclinic) {
...
@@ -108,7 +612,7 @@ void testPME(bool triclinic) {
double
alpha
;
double
alpha
;
int
gridx
,
gridy
,
gridz
;
int
gridx
,
gridy
,
gridz
;
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
alpha
,
gridx
,
gridy
,
gridz
);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
alpha
,
gridx
,
gridy
,
gridz
,
false
);
CpuCalcPmeReciprocalForceKernel
pme
(
CalcPmeReciprocalForceKernel
::
Name
(),
platform
);
CpuCalcPmeReciprocalForceKernel
pme
(
CalcPmeReciprocalForceKernel
::
Name
(),
platform
);
IO
io
;
IO
io
;
double
sumSquaredCharges
=
0
;
double
sumSquaredCharges
=
0
;
...
@@ -125,7 +629,7 @@ void testPME(bool triclinic) {
...
@@ -125,7 +629,7 @@ void testPME(bool triclinic) {
pme
.
initialize
(
gridx
,
gridy
,
gridz
,
numParticles
,
alpha
);
pme
.
initialize
(
gridx
,
gridy
,
gridz
,
numParticles
,
alpha
);
pme
.
beginComputation
(
io
,
boxVectors
,
true
);
pme
.
beginComputation
(
io
,
boxVectors
,
true
);
double
energy
=
pme
.
finishComputation
(
io
);
double
energy
=
pme
.
finishComputation
(
io
);
// See if they match.
// See if they match.
ASSERT_EQUAL_TOL
(
refState
.
getPotentialEnergy
(),
energy
+
ewaldSelfEnergy
,
1e-3
);
ASSERT_EQUAL_TOL
(
refState
.
getPotentialEnergy
(),
energy
+
ewaldSelfEnergy
,
1e-3
);
...
@@ -141,6 +645,7 @@ int main(int argc, char* argv[]) {
...
@@ -141,6 +645,7 @@ int main(int argc, char* argv[]) {
}
}
testPME
(
false
);
testPME
(
false
);
testPME
(
true
);
testPME
(
true
);
test_water2_dpme_energies_forces_no_exclusions
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
serialization/src/NonbondedForceProxy.cpp
View file @
53f770f4
...
@@ -42,7 +42,7 @@ NonbondedForceProxy::NonbondedForceProxy() : SerializationProxy("NonbondedForce"
...
@@ -42,7 +42,7 @@ NonbondedForceProxy::NonbondedForceProxy() : SerializationProxy("NonbondedForce"
}
}
void
NonbondedForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
void
NonbondedForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
1
);
node
.
setIntProperty
(
"version"
,
2
);
const
NonbondedForce
&
force
=
*
reinterpret_cast
<
const
NonbondedForce
*>
(
object
);
const
NonbondedForce
&
force
=
*
reinterpret_cast
<
const
NonbondedForce
*>
(
object
);
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setIntProperty
(
"method"
,
(
int
)
force
.
getNonbondedMethod
());
node
.
setIntProperty
(
"method"
,
(
int
)
force
.
getNonbondedMethod
());
...
@@ -59,6 +59,11 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node)
...
@@ -59,6 +59,11 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node)
node
.
setIntProperty
(
"nx"
,
nx
);
node
.
setIntProperty
(
"nx"
,
nx
);
node
.
setIntProperty
(
"ny"
,
ny
);
node
.
setIntProperty
(
"ny"
,
ny
);
node
.
setIntProperty
(
"nz"
,
nz
);
node
.
setIntProperty
(
"nz"
,
nz
);
force
.
getLJPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
node
.
setDoubleProperty
(
"ljAlpha"
,
alpha
);
node
.
setIntProperty
(
"ljnx"
,
nx
);
node
.
setIntProperty
(
"ljny"
,
ny
);
node
.
setIntProperty
(
"ljnz"
,
nz
);
node
.
setIntProperty
(
"recipForceGroup"
,
force
.
getReciprocalSpaceForceGroup
());
node
.
setIntProperty
(
"recipForceGroup"
,
force
.
getReciprocalSpaceForceGroup
());
SerializationNode
&
particles
=
node
.
createChildNode
(
"Particles"
);
SerializationNode
&
particles
=
node
.
createChildNode
(
"Particles"
);
for
(
int
i
=
0
;
i
<
force
.
getNumParticles
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumParticles
();
i
++
)
{
...
@@ -76,7 +81,8 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node)
...
@@ -76,7 +81,8 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node)
}
}
void
*
NonbondedForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
void
*
NonbondedForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
if
(
node
.
getIntProperty
(
"version"
)
!=
1
)
int
version
=
node
.
getIntProperty
(
"version"
);
if
(
version
<
1
||
version
>
2
)
throw
OpenMMException
(
"Unsupported version number"
);
throw
OpenMMException
(
"Unsupported version number"
);
NonbondedForce
*
force
=
new
NonbondedForce
();
NonbondedForce
*
force
=
new
NonbondedForce
();
try
{
try
{
...
@@ -93,6 +99,13 @@ void* NonbondedForceProxy::deserialize(const SerializationNode& node) const {
...
@@ -93,6 +99,13 @@ void* NonbondedForceProxy::deserialize(const SerializationNode& node) const {
int
ny
=
node
.
getIntProperty
(
"ny"
,
0
);
int
ny
=
node
.
getIntProperty
(
"ny"
,
0
);
int
nz
=
node
.
getIntProperty
(
"nz"
,
0
);
int
nz
=
node
.
getIntProperty
(
"nz"
,
0
);
force
->
setPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
force
->
setPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
if
(
version
>=
2
)
{
alpha
=
node
.
getDoubleProperty
(
"ljAlpha"
,
0.0
);
nx
=
node
.
getIntProperty
(
"ljnx"
,
0
);
ny
=
node
.
getIntProperty
(
"ljny"
,
0
);
nz
=
node
.
getIntProperty
(
"ljnz"
,
0
);
force
->
setLJPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
}
force
->
setReciprocalSpaceForceGroup
(
node
.
getIntProperty
(
"recipForceGroup"
,
-
1
));
force
->
setReciprocalSpaceForceGroup
(
node
.
getIntProperty
(
"recipForceGroup"
,
-
1
));
const
SerializationNode
&
particles
=
node
.
getChildNode
(
"Particles"
);
const
SerializationNode
&
particles
=
node
.
getChildNode
(
"Particles"
);
for
(
int
i
=
0
;
i
<
(
int
)
particles
.
getChildren
().
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
particles
.
getChildren
().
size
();
i
++
)
{
...
...
serialization/tests/TestSerializeNonbondedForce.cpp
View file @
53f770f4
...
@@ -53,6 +53,9 @@ void testSerialization() {
...
@@ -53,6 +53,9 @@ void testSerialization() {
double
alpha
=
0.5
;
double
alpha
=
0.5
;
int
nx
=
3
,
ny
=
5
,
nz
=
7
;
int
nx
=
3
,
ny
=
5
,
nz
=
7
;
force
.
setPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
force
.
setPMEParameters
(
alpha
,
nx
,
ny
,
nz
);
double
dalpha
=
0.8
;
int
dnx
=
4
,
dny
=
6
,
dnz
=
7
;
force
.
setLJPMEParameters
(
dalpha
,
dnx
,
dny
,
dnz
);
force
.
addParticle
(
1
,
0.1
,
0.01
);
force
.
addParticle
(
1
,
0.1
,
0.01
);
force
.
addParticle
(
0.5
,
0.2
,
0.02
);
force
.
addParticle
(
0.5
,
0.2
,
0.02
);
force
.
addParticle
(
-
0.5
,
0.3
,
0.03
);
force
.
addParticle
(
-
0.5
,
0.3
,
0.03
);
...
@@ -84,6 +87,13 @@ void testSerialization() {
...
@@ -84,6 +87,13 @@ void testSerialization() {
ASSERT_EQUAL
(
nx
,
nx2
);
ASSERT_EQUAL
(
nx
,
nx2
);
ASSERT_EQUAL
(
ny
,
ny2
);
ASSERT_EQUAL
(
ny
,
ny2
);
ASSERT_EQUAL
(
nz
,
nz2
);
ASSERT_EQUAL
(
nz
,
nz2
);
double
dalpha2
;
int
dnx2
,
dny2
,
dnz2
;
force2
.
getLJPMEParameters
(
dalpha2
,
dnx2
,
dny2
,
dnz2
);
ASSERT_EQUAL
(
dalpha
,
dalpha2
);
ASSERT_EQUAL
(
dnx
,
dnx2
);
ASSERT_EQUAL
(
dny
,
dny2
);
ASSERT_EQUAL
(
dnz
,
dnz2
);
for
(
int
i
=
0
;
i
<
force
.
getNumParticles
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumParticles
();
i
++
)
{
double
charge1
,
sigma1
,
epsilon1
;
double
charge1
,
sigma1
,
epsilon1
;
double
charge2
,
sigma2
,
epsilon2
;
double
charge2
,
sigma2
,
epsilon2
;
...
...
tests/TestDispersionPME.h
0 → 100644
View file @
53f770f4
/* -------------------------------------------------------------------------- *
* 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) 2008-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. *
* -------------------------------------------------------------------------- */
#ifdef _MSC_VER
// Prevent Windows from defining macros that interfere with other code.
#define NOMINMAX
#endif
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/Units.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
#include <algorithm>
using
namespace
OpenMM
;
using
namespace
std
;
void
testConvergence
()
{
// Create a cloud of random particles.
const
int
numParticles
=
1000
;
const
double
boxWidth
=
6.0
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxWidth
,
0
,
0
),
Vec3
(
0
,
boxWidth
,
0
),
Vec3
(
0
,
0
,
boxWidth
));
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
0.0
,
0.1
+
0.3
*
genrand_real2
(
sfmt
),
genrand_real2
(
sfmt
));
while
(
true
)
{
Vec3
pos
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
double
minDist
=
boxWidth
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
Vec3
delta
=
pos
-
positions
[
j
];
minDist
=
std
::
min
(
minDist
,
sqrt
(
delta
.
dot
(
delta
)));
}
if
(
minDist
>
0.15
)
{
positions
[
i
]
=
pos
;
break
;
}
}
}
// Compute the energy with short and long cutoffs, and compare them to LJPME.
// The long cutoff should match the LJPME result better than the short cutoff.
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
force
->
setCutoffDistance
(
1.0
);
force
->
setEwaldErrorTolerance
(
1e-5
);
force
->
setUseDispersionCorrection
(
false
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
double
pmeEnergy
=
context
.
getState
(
State
::
Energy
,
false
,
1
).
getPotentialEnergy
();
force
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
double
shortEnergy
=
context
.
getState
(
State
::
Energy
,
false
,
1
).
getPotentialEnergy
();
force
->
setCutoffDistance
(
3.0
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
double
longEnergy
=
context
.
getState
(
State
::
Energy
,
false
,
1
).
getPotentialEnergy
();
ASSERT
(
fabs
(
longEnergy
-
pmeEnergy
)
<
fabs
(
shortEnergy
-
pmeEnergy
))
}
void
testErrorTolerance
()
{
// Create a cloud of random particles.
const
int
numParticles
=
200
;
const
double
boxWidth
=
5.0
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxWidth
,
0
,
0
),
Vec3
(
0
,
boxWidth
,
0
),
Vec3
(
0
,
0
,
boxWidth
));
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
0.0
,
0.1
+
0.2
*
genrand_real2
(
sfmt
),
genrand_real2
(
sfmt
));
while
(
true
)
{
Vec3
pos
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
double
minDist
=
boxWidth
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
Vec3
delta
=
pos
-
positions
[
j
];
minDist
=
std
::
min
(
minDist
,
sqrt
(
delta
.
dot
(
delta
)));
}
if
(
minDist
>
0.1
)
{
positions
[
i
]
=
pos
;
break
;
}
}
}
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
// For various values of the cutoff and error tolerance, see if the actual error is reasonable.
for
(
double
cutoff
=
0.8
;
cutoff
<
boxWidth
/
2
;
cutoff
*=
1.3
)
{
force
->
setCutoffDistance
(
cutoff
);
vector
<
Vec3
>
refForces
;
double
norm
=
0.0
;
for
(
double
tol
=
5e-5
;
tol
<
1e-3
;
tol
*=
2.0
)
{
force
->
setEwaldErrorTolerance
(
tol
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
);
if
(
refForces
.
size
()
==
0
)
{
refForces
=
state
.
getForces
();
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
norm
+=
refForces
[
i
].
dot
(
refForces
[
i
]);
norm
=
sqrt
(
norm
);
}
else
{
double
diff
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
Vec3
delta
=
refForces
[
i
]
-
state
.
getForces
()[
i
];
diff
+=
delta
.
dot
(
delta
);
}
diff
=
sqrt
(
diff
)
/
norm
;
ASSERT
(
diff
<
2
*
tol
);
}
// See if the PME parameters were calculated correctly.
double
expectedAlpha
,
actualAlpha
;
int
expectedSize
[
3
],
actualSize
[
3
];
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
expectedAlpha
,
expectedSize
[
0
],
expectedSize
[
1
],
expectedSize
[
2
],
true
);
force
->
getLJPMEParametersInContext
(
context
,
actualAlpha
,
actualSize
[
0
],
actualSize
[
1
],
actualSize
[
2
]);
ASSERT_EQUAL_TOL
(
expectedAlpha
,
actualAlpha
,
1e-5
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
ASSERT
(
actualSize
[
i
]
>=
expectedSize
[
i
]);
ASSERT
(
actualSize
[
i
]
<
expectedSize
[
i
]
+
10
);
}
}
}
}
void
testPMEParameters
()
{
// Create a cloud of random particles.
const
int
numParticles
=
51
;
const
double
boxWidth
=
4.7
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxWidth
,
0
,
0
),
Vec3
(
0
,
boxWidth
,
0
),
Vec3
(
0
,
0
,
boxWidth
));
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
0.0
,
0.1
+
0.2
*
genrand_real2
(
sfmt
),
genrand_real2
(
sfmt
));
positions
[
i
]
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
}
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
force
->
setCutoffDistance
(
0.5
);
// Compute the energy with an error tolerance of 0.1.
force
->
setEwaldErrorTolerance
(
0.1
);
VerletIntegrator
integrator1
(
0.01
);
Context
context1
(
system
,
integrator1
,
platform
);
context1
.
setPositions
(
positions
);
double
energy1
=
context1
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
double
alpha
;
int
gridx
,
gridy
,
gridz
;
force
->
getLJPMEParametersInContext
(
context1
,
alpha
,
gridx
,
gridy
,
gridz
);
// Try again with an error tolerance of 1e-4.
force
->
setEwaldErrorTolerance
(
1e-4
);
VerletIntegrator
integrator2
(
0.01
);
Context
context2
(
system
,
integrator2
,
platform
);
context2
.
setPositions
(
positions
);
double
energy2
=
context2
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
// Now explicitly set the parameters. These should match the values that were
// used for tolerance 0.1.
force
->
setLJPMEParameters
(
alpha
,
gridx
,
gridy
,
gridz
);
VerletIntegrator
integrator3
(
0.01
);
Context
context3
(
system
,
integrator3
,
platform
);
context3
.
setPositions
(
positions
);
double
energy3
=
context3
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
energy1
,
energy3
,
1e-5
);
ASSERT
(
fabs
((
energy1
-
energy2
)
/
energy1
)
>
1e-5
);
force
->
getLJPMEParametersInContext
(
context2
,
alpha
,
gridx
,
gridy
,
gridz
);
}
void
testCoulombAndLJ
()
{
// Create a cloud of random particles.
const
int
numParticles
=
200
;
const
double
boxWidth
=
5.0
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxWidth
,
0
,
0
),
Vec3
(
0
,
boxWidth
,
0
),
Vec3
(
0
,
0
,
boxWidth
));
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
vector
<
double
>
charge
(
numParticles
),
sigma
(
numParticles
),
epsilon
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
charge
[
i
]
=
-
1.0
+
i
*
2.0
/
(
numParticles
-
1
);
sigma
[
i
]
=
0.1
+
0.2
*
genrand_real2
(
sfmt
);
epsilon
[
i
]
=
genrand_real2
(
sfmt
);
force
->
addParticle
(
charge
[
i
],
1.0
,
0.0
);
while
(
true
)
{
Vec3
pos
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
double
minDist
=
boxWidth
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
Vec3
delta
=
pos
-
positions
[
j
];
minDist
=
std
::
min
(
minDist
,
sqrt
(
delta
.
dot
(
delta
)));
}
if
(
minDist
>
0.1
)
{
positions
[
i
]
=
pos
;
break
;
}
}
}
force
->
setNonbondedMethod
(
NonbondedForce
::
LJPME
);
// Compute forces and energy with only Coulomb interactions.
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state1
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
// Now repeat with only LJ interactions.
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
force
->
setParticleParameters
(
i
,
0.0
,
sigma
[
i
],
epsilon
[
i
]);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
State
state2
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
// Finally compute with both Coulomb and LJ.
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
force
->
setParticleParameters
(
i
,
charge
[
i
],
sigma
[
i
],
epsilon
[
i
]);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
State
state3
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
// Make sure the results agree.
ASSERT_EQUAL_TOL
(
state1
.
getPotentialEnergy
()
+
state2
.
getPotentialEnergy
(),
state3
.
getPotentialEnergy
(),
1e-5
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
i
]
+
state2
.
getForces
()[
i
],
state3
.
getForces
()[
i
],
1e-5
);
}
void
make_dmfbox
(
int
natoms
,
double
boxEdgeLength
,
NonbondedForce
*
forceField
,
vector
<
Vec3
>
&
positions
,
vector
<
double
>&
eps
,
vector
<
double
>&
sig
,
vector
<
pair
<
int
,
int
>
>&
bonds
,
System
&
system
,
bool
do_electrostatics
)
{
const
int
RESSIZE
=
12
;
const
double
charges
[
RESSIZE
]
=
{
0.08
,
0.43
,
-
0.54
,
-
0.33
,
-
0.09
,
0.09
,
0.09
,
0.09
,
-
0.09
,
0.09
,
0.09
,
0.09
};
const
double
masses
[
RESSIZE
]
=
{
1.008
,
12.011
,
15.9994
,
14.007
,
12.011
,
1.008
,
1.008
,
1.008
,
12.011
,
1.008
,
1.008
,
1.008
};
const
double
sigmas
[
RESSIZE
]
=
{
0.160361769265
,
0.356359487256
,
0.302905564168
,
0.329632525712
,
0.365268474438
,
0.238760856462
,
0.238760856462
,
0.238760856462
,
0.365268474438
,
0.238760856462
,
0.238760856462
,
0.238760856462
};
const
double
epsilons
[
RESSIZE
]
=
{
0.19246
,
0.46024
,
0.50208
,
0.83680
,
0.32635
,
0.10042
,
0.10042
,
0.10042
,
0.32635
,
0.10042
,
0.10042
,
0.10042
};
positions
.
clear
();
if
(
natoms
==
12
)
{
const
double
coords
[
12
][
3
]
=
{
{
0.620
,
0.945
,
0.128
},
{
0.560
,
0.905
,
0.045
},
{
0.502
,
0.987
,
-
0.026
},
{
0.556
,
0.770
,
0.028
},
{
0.643
,
0.685
,
0.106
},
{
0.680
,
0.741
,
0.193
},
{
0.729
,
0.653
,
0.045
},
{
0.587
,
0.597
,
0.140
},
{
0.477
,
0.708
,
-
0.072
},
{
0.377
,
0.688
,
-
0.032
},
{
0.524
,
0.614
,
-
0.102
},
{
0.468
,
0.775
,
-
0.158
}
};
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
positions
.
push_back
(
Vec3
(
coords
[
atom
][
0
],
coords
[
atom
][
1
],
coords
[
atom
][
2
]));
}
else
throw
exception
();
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxEdgeLength
,
0
,
0
),
Vec3
(
0
,
boxEdgeLength
,
0
),
Vec3
(
0
,
0
,
boxEdgeLength
));
sig
.
clear
();
eps
.
clear
();
bonds
.
clear
();
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
{
system
.
addParticle
(
masses
[
atom
%
RESSIZE
]);
double
sigma
=
sigmas
[
atom
%
RESSIZE
];
double
epsilon
=
epsilons
[
atom
%
RESSIZE
];
sig
.
push_back
(
sigma
);
eps
.
push_back
(
epsilon
);
if
(
atom
%
RESSIZE
==
0
)
{
int
offset
=
atom
-
1
;
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
1
,
offset
+
2
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
2
,
offset
+
3
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
2
,
offset
+
4
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
4
,
offset
+
5
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
4
,
offset
+
9
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
5
,
offset
+
6
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
5
,
offset
+
7
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
5
,
offset
+
8
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
9
,
offset
+
10
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
9
,
offset
+
11
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
offset
+
9
,
offset
+
12
));
}
double
charge
=
do_electrostatics
?
charges
[
atom
]
:
0
;
forceField
->
addParticle
(
charge
,
sigma
,
epsilon
);
}
// Make exceptions and replacement 1-4 parameters
forceField
->
createExceptionsFromBonds
(
bonds
,
1.0
,
1.0
);
int
nres
=
natoms
/
RESSIZE
;
double
newqq
=
do_electrostatics
?
charges
[
8
]
*
charges
[
8
]
:
0.0
;
double
newsig
=
0.293996576986
;
double
neweps
=
0.144938011577
;
for
(
int
i
=
0
;
i
<
forceField
->
getNumExceptions
();
++
i
){
for
(
int
res
=
0
;
res
<
nres
;
++
res
){
int
particle1
,
particle2
;
double
chargeProd
,
sigma
,
epsilon
;
forceField
->
getExceptionParameters
(
i
,
particle1
,
particle2
,
chargeProd
,
sigma
,
epsilon
);
if
((
particle1
==
res
+
2
&&
particle2
==
res
+
8
)
||
(
particle1
==
res
+
8
&&
particle2
==
res
+
2
)
||
(
particle1
==
res
+
2
&&
particle2
==
res
+
4
)
||
(
particle1
==
res
+
4
&&
particle2
==
res
+
2
))
forceField
->
setExceptionParameters
(
i
,
particle1
,
particle2
,
newqq
,
newsig
,
neweps
);
}
}
}
void
make_waterbox
(
int
natoms
,
double
boxEdgeLength
,
NonbondedForce
*
forceField
,
vector
<
Vec3
>
&
positions
,
vector
<
double
>&
eps
,
vector
<
double
>&
sig
,
vector
<
pair
<
int
,
int
>
>&
bonds
,
System
&
system
,
bool
do_electrostatics
)
{
const
int
RESSIZE
=
3
;
const
double
masses
[
RESSIZE
]
=
{
8.0
,
1.0
,
1.0
};
const
double
charges
[
RESSIZE
]
=
{
-
0.834
,
0.417
,
0.417
};
// Values from the CHARMM force field, in AKMA units
const
double
epsilons
[
RESSIZE
]
=
{
-
0.1521
,
-
0.046
,
-
0.046
};
const
double
halfrmins
[
RESSIZE
]
=
{
1.7682
,
0.2245
,
0.2245
};
positions
.
clear
();
if
(
natoms
==
6
)
{
const
double
coords
[
6
][
3
]
=
{
{
2.000000
,
2.000000
,
2.000000
},
{
2.500000
,
2.000000
,
3.000000
},
{
1.500000
,
2.000000
,
3.000000
},
{
0.000000
,
0.000000
,
0.000000
},
{
0.500000
,
0.000000
,
1.000000
},
{
-
0.500000
,
0.000000
,
1.000000
}
};
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
positions
.
push_back
(
Vec3
(
coords
[
atom
][
0
],
coords
[
atom
][
1
],
coords
[
atom
][
2
])
*
OpenMM
::
NmPerAngstrom
);
}
else
if
(
natoms
==
375
)
{
const
double
coords
[
375
][
3
]
=
{
{
-
6.22
,
-
6.25
,
-
6.24
},
{
-
5.32
,
-
6.03
,
-
6.00
},
{
-
6.75
,
-
5.56
,
-
5.84
},
{
-
3.04
,
-
6.23
,
-
6.19
},
{
-
3.52
,
-
5.55
,
-
5.71
},
{
-
3.59
,
-
6.43
,
-
6.94
},
{
0.02
,
-
6.23
,
-
6.14
},
{
-
0.87
,
-
5.97
,
-
6.37
},
{
0.53
,
-
6.03
,
-
6.93
},
{
3.10
,
-
6.20
,
-
6.27
},
{
3.87
,
-
6.35
,
-
5.72
},
{
2.37
,
-
6.11
,
-
5.64
},
{
6.18
,
-
6.14
,
-
6.20
},
{
6.46
,
-
6.66
,
-
5.44
},
{
6.26
,
-
6.74
,
-
6.94
},
{
-
6.21
,
-
3.15
,
-
6.24
},
{
-
6.23
,
-
3.07
,
-
5.28
},
{
-
6.02
,
-
2.26
,
-
6.55
},
{
-
3.14
,
-
3.07
,
-
6.16
},
{
-
3.38
,
-
3.63
,
-
6.90
},
{
-
2.18
,
-
3.05
,
-
6.17
},
{
-
0.00
,
-
3.16
,
-
6.23
},
{
-
0.03
,
-
2.30
,
-
6.67
},
{
0.05
,
-
2.95
,
-
5.29
},
{
3.08
,
-
3.11
,
-
6.14
},
{
2.65
,
-
2.55
,
-
6.79
},
{
3.80
,
-
3.53
,
-
6.62
},
{
6.16
,
-
3.14
,
-
6.16
},
{
7.04
,
-
3.32
,
-
6.51
},
{
5.95
,
-
2.27
,
-
6.51
},
{
-
6.20
,
-
0.04
,
-
6.15
},
{
-
5.43
,
0.32
,
-
6.59
},
{
-
6.95
,
0.33
,
-
6.62
},
{
-
3.10
,
-
0.06
,
-
6.19
},
{
-
3.75
,
0.42
,
-
6.69
},
{
-
2.46
,
0.60
,
-
5.93
},
{
0.05
,
-
0.01
,
-
6.17
},
{
-
0.10
,
0.02
,
-
7.12
},
{
-
0.79
,
0.16
,
-
5.77
},
{
3.03
,
0.00
,
-
6.19
},
{
3.54
,
0.08
,
-
7.01
},
{
3.69
,
-
0.22
,
-
5.53
},
{
6.17
,
0.05
,
-
6.19
},
{
5.78
,
-
0.73
,
-
6.57
},
{
7.09
,
-
0.17
,
-
6.04
},
{
-
6.20
,
3.15
,
-
6.25
},
{
-
6.59
,
3.18
,
-
5.37
},
{
-
5.87
,
2.25
,
-
6.33
},
{
-
3.09
,
3.04
,
-
6.17
},
{
-
3.88
,
3.58
,
-
6.26
},
{
-
2.41
,
3.54
,
-
6.63
},
{
0.00
,
3.06
,
-
6.26
},
{
-
0.71
,
3.64
,
-
6.00
},
{
0.65
,
3.15
,
-
5.55
},
{
3.14
,
3.06
,
-
6.23
},
{
3.11
,
3.31
,
-
5.30
},
{
2.38
,
3.49
,
-
6.63
},
{
6.19
,
3.14
,
-
6.25
},
{
6.82
,
3.25
,
-
5.54
},
{
5.76
,
2.30
,
-
6.07
},
{
-
6.22
,
6.26
,
-
6.19
},
{
-
6.22
,
5.74
,
-
7.00
},
{
-
5.89
,
5.67
,
-
5.52
},
{
-
3.04
,
6.24
,
-
6.20
},
{
-
3.08
,
5.28
,
-
6.17
},
{
-
3.96
,
6.52
,
-
6.25
},
{
-
0.05
,
6.21
,
-
6.16
},
{
0.82
,
6.58
,
-
6.06
},
{
0.01
,
5.64
,
-
6.93
},
{
3.10
,
6.25
,
-
6.15
},
{
3.64
,
5.47
,
-
6.31
},
{
2.46
,
6.24
,
-
6.87
},
{
6.22
,
6.20
,
-
6.27
},
{
5.37
,
6.42
,
-
5.88
},
{
6.80
,
6.07
,
-
5.51
},
{
-
6.19
,
-
6.15
,
-
3.13
},
{
-
6.37
,
-
7.01
,
-
3.51
},
{
-
6.25
,
-
6.29
,
-
2.18
},
{
-
3.10
,
-
6.27
,
-
3.11
},
{
-
2.29
,
-
5.77
,
-
2.99
},
{
-
3.80
,
-
5.62
,
-
2.98
},
{
-
0.03
,
-
6.18
,
-
3.15
},
{
-
0.07
,
-
7.05
,
-
2.75
},
{
0.68
,
-
5.74
,
-
2.70
},
{
3.10
,
-
6.14
,
-
3.07
},
{
2.35
,
-
6.72
,
-
3.23
},
{
3.86
,
-
6.65
,
-
3.37
},
{
6.22
,
-
6.20
,
-
3.16
},
{
6.82
,
-
6.36
,
-
2.43
},
{
5.35
,
-
6.13
,
-
2.75
},
{
-
6.26
,
-
3.13
,
-
3.12
},
{
-
6.16
,
-
2.27
,
-
2.70
},
{
-
5.36
,
-
3.47
,
-
3.18
},
{
-
3.11
,
-
3.05
,
-
3.14
},
{
-
3.31
,
-
3.96
,
-
3.34
},
{
-
2.77
,
-
3.06
,
-
2.24
},
{
0.00
,
-
3.13
,
-
3.16
},
{
0.48
,
-
2.37
,
-
2.81
},
{
-
0.57
,
-
3.40
,
-
2.44
},
{
3.09
,
-
3.09
,
-
3.16
},
{
2.41
,
-
3.19
,
-
2.49
},
{
3.91
,
-
3.07
,
-
2.67
},
{
6.19
,
-
3.04
,
-
3.08
},
{
5.64
,
-
3.61
,
-
3.61
},
{
6.93
,
-
3.58
,
-
2.82
},
{
-
6.18
,
-
0.00
,
-
3.04
},
{
-
6.00
,
-
0.59
,
-
3.78
},
{
-
6.79
,
0.64
,
-
3.39
},
{
-
3.05
,
-
0.03
,
-
3.07
},
{
-
2.95
,
0.80
,
-
3.52
},
{
-
4.00
,
-
0.20
,
-
3.07
},
{
-
0.03
,
0.03
,
-
3.06
},
{
-
0.33
,
-
0.37
,
-
3.87
},
{
0.89
,
-
0.21
,
-
2.99
},
{
3.13
,
-
0.05
,
-
3.10
},
{
3.44
,
0.81
,
-
3.34
},
{
2.21
,
0.07
,
-
2.86
},
{
6.20
,
-
0.05
,
-
3.13
},
{
6.89
,
0.60
,
-
3.20
},
{
5.58
,
0.30
,
-
2.49
},
{
-
6.23
,
3.09
,
-
3.16
},
{
-
5.62
,
3.79
,
-
2.94
},
{
-
6.33
,
2.60
,
-
2.33
},
{
-
3.10
,
3.08
,
-
3.04
},
{
-
3.84
,
3.47
,
-
3.51
},
{
-
2.40
,
3.01
,
-
3.69
},
{
0.01
,
3.04
,
-
3.11
},
{
-
0.56
,
3.59
,
-
3.64
},
{
0.28
,
3.60
,
-
2.38
},
{
3.04
,
3.11
,
-
3.09
},
{
3.49
,
2.30
,
-
2.87
},
{
3.70
,
3.66
,
-
3.51
},
{
6.15
,
3.14
,
-
3.11
},
{
6.52
,
2.52
,
-
3.74
},
{
6.72
,
3.06
,
-
2.34
},
{
-
6.22
,
6.15
,
-
3.13
},
{
-
5.49
,
6.21
,
-
2.51
},
{
-
6.56
,
7.04
,
-
3.18
},
{
-
3.11
,
6.24
,
-
3.05
},
{
-
3.76
,
5.83
,
-
3.62
},
{
-
2.26
,
5.92
,
-
3.37
},
{
0.03
,
6.25
,
-
3.07
},
{
0.34
,
5.63
,
-
3.73
},
{
-
0.87
,
6.00
,
-
2.91
},
{
3.07
,
6.15
,
-
3.08
},
{
3.29
,
6.92
,
-
2.56
},
{
3.39
,
6.35
,
-
3.96
},
{
6.22
,
6.14
,
-
3.12
},
{
5.79
,
6.38
,
-
2.29
},
{
6.25
,
6.96
,
-
3.62
},
{
-
6.21
,
-
6.20
,
-
0.06
},
{
-
5.79
,
-
6.87
,
0.48
},
{
-
6.43
,
-
5.50
,
0.54
},
{
-
3.16
,
-
6.21
,
-
0.02
},
{
-
2.50
,
-
6.87
,
0.20
},
{
-
2.77
,
-
5.37
,
0.23
},
{
-
0.00
,
-
6.14
,
-
0.00
},
{
0.68
,
-
6.72
,
-
0.33
},
{
-
0.64
,
-
6.73
,
0.38
},
{
3.03
,
-
6.20
,
-
0.01
},
{
3.77
,
-
6.56
,
-
0.51
},
{
3.43
,
-
5.85
,
0.78
},
{
6.25
,
-
6.16
,
-
0.00
},
{
5.36
,
-
6.09
,
-
0.36
},
{
6.24
,
-
6.97
,
0.49
},
{
-
6.24
,
-
3.05
,
-
0.01
},
{
-
6.35
,
-
3.64
,
0.73
},
{
-
5.42
,
-
3.33
,
-
0.42
},
{
-
3.09
,
-
3.06
,
0.05
},
{
-
2.44
,
-
3.62
,
-
0.38
},
{
-
3.90
,
-
3.21
,
-
0.43
},
{
0.05
,
-
3.10
,
0.02
},
{
-
0.31
,
-
2.35
,
-
0.43
},
{
-
0.63
,
-
3.77
,
0.01
},
{
3.05
,
-
3.09
,
-
0.04
},
{
3.28
,
-
3.90
,
0.41
},
{
3.65
,
-
2.43
,
0.30
},
{
6.20
,
-
3.04
,
-
0.03
},
{
5.66
,
-
3.31
,
0.71
},
{
6.78
,
-
3.79
,
-
0.19
},
{
-
6.18
,
0.04
,
-
0.04
},
{
-
6.73
,
-
0.73
,
-
0.15
},
{
-
5.98
,
0.06
,
0.89
},
{
-
3.11
,
-
0.04
,
-
0.04
},
{
-
3.36
,
-
0.08
,
0.87
},
{
-
2.70
,
0.81
,
-
0.14
},
{
-
0.02
,
-
0.02
,
-
0.05
},
{
-
0.45
,
0.28
,
0.75
},
{
0.90
,
0.15
,
0.07
},
{
3.04
,
0.02
,
-
0.01
},
{
3.26
,
-
0.82
,
0.38
},
{
3.89
,
0.45
,
-
0.13
},
{
6.19
,
0.05
,
-
0.03
},
{
5.52
,
-
0.56
,
0.25
},
{
7.01
,
-
0.29
,
0.32
},
{
-
6.14
,
3.08
,
0.00
},
{
-
6.83
,
2.82
,
0.61
},
{
-
6.59
,
3.64
,
-
0.64
},
{
-
3.05
,
3.09
,
-
0.04
},
{
-
3.79
,
2.50
,
0.09
},
{
-
3.18
,
3.80
,
0.59
},
{
0.02
,
3.14
,
0.04
},
{
-
0.89
,
3.04
,
-
0.19
},
{
0.49
,
2.57
,
-
0.57
},
{
3.14
,
3.15
,
0.00
},
{
3.28
,
2.28
,
0.37
},
{
2.30
,
3.08
,
-
0.45
},
{
6.27
,
3.08
,
-
0.00
},
{
5.55
,
2.54
,
-
0.33
},
{
5.83
,
3.87
,
0.34
},
{
-
6.18
,
6.15
,
-
0.03
},
{
-
6.45
,
6.21
,
0.88
},
{
-
6.26
,
7.05
,
-
0.36
},
{
-
3.06
,
6.19
,
-
0.05
},
{
-
2.84
,
6.64
,
0.76
},
{
-
3.99
,
5.96
,
0.03
},
{
-
0.00
,
6.20
,
0.06
},
{
-
0.67
,
5.99
,
-
0.59
},
{
0.76
,
6.46
,
-
0.44
},
{
3.10
,
6.26
,
-
0.03
},
{
3.57
,
6.09
,
0.78
},
{
2.57
,
5.47
,
-
0.18
},
{
6.26
,
6.18
,
0.02
},
{
5.53
,
5.64
,
-
0.29
},
{
5.95
,
7.08
,
-
0.06
},
{
-
6.26
,
-
6.21
,
3.07
},
{
-
5.98
,
-
6.38
,
3.97
},
{
-
5.46
,
-
5.94
,
2.62
},
{
-
3.10
,
-
6.24
,
3.04
},
{
-
2.69
,
-
6.51
,
3.87
},
{
-
3.43
,
-
5.35
,
3.21
},
{
-
0.03
,
-
6.16
,
3.06
},
{
0.83
,
-
6.00
,
3.42
},
{
-
0.30
,
-
6.99
,
3.45
},
{
3.15
,
-
6.25
,
3.11
},
{
2.77
,
-
5.60
,
3.72
},
{
2.68
,
-
6.10
,
2.28
},
{
6.20
,
-
6.21
,
3.16
},
{
5.75
,
-
6.73
,
2.50
},
{
6.69
,
-
5.56
,
2.66
},
{
-
6.17
,
-
3.10
,
3.04
},
{
-
6.82
,
-
2.44
,
3.28
},
{
-
6.12
,
-
3.69
,
3.80
},
{
-
3.08
,
-
3.04
,
3.11
},
{
-
3.59
,
-
3.56
,
3.72
},
{
-
2.97
,
-
3.61
,
2.34
},
{
0.01
,
-
3.04
,
3.11
},
{
-
0.86
,
-
3.41
,
3.20
},
{
0.56
,
-
3.78
,
2.86
},
{
3.07
,
-
3.07
,
3.15
},
{
3.81
,
-
3.68
,
3.13
},
{
2.80
,
-
2.98
,
2.23
},
{
6.20
,
-
3.04
,
3.13
},
{
5.48
,
-
3.64
,
2.92
},
{
6.98
,
-
3.49
,
2.81
},
{
-
6.18
,
-
0.05
,
3.12
},
{
-
6.41
,
0.66
,
3.69
},
{
-
6.33
,
0.28
,
2.23
},
{
-
3.05
,
0.03
,
3.10
},
{
-
3.46
,
-
0.42
,
3.83
},
{
-
3.57
,
-
0.19
,
2.33
},
{
0.03
,
-
0.02
,
3.15
},
{
0.23
,
-
0.08
,
2.21
},
{
-
0.81
,
0.41
,
3.18
},
{
3.09
,
0.00
,
3.03
},
{
2.48
,
-
0.29
,
3.71
},
{
3.91
,
0.16
,
3.51
},
{
6.19
,
-
0.06
,
3.11
},
{
6.05
,
0.47
,
2.33
},
{
6.59
,
0.52
,
3.74
},
{
-
6.20
,
3.05
,
3.05
},
{
-
6.87
,
3.73
,
3.17
},
{
-
5.55
,
3.24
,
3.73
},
{
-
3.11
,
3.06
,
3.15
},
{
-
3.64
,
3.74
,
2.71
},
{
-
2.32
,
3.00
,
2.62
},
{
0.02
,
3.05
,
3.06
},
{
-
0.87
,
3.14
,
3.38
},
{
0.48
,
3.82
,
3.42
},
{
3.07
,
3.10
,
3.16
},
{
3.95
,
3.44
,
2.97
},
{
2.76
,
2.73
,
2.32
},
{
6.19
,
3.07
,
3.16
},
{
7.02
,
3.30
,
2.72
},
{
5.52
,
3.27
,
2.51
},
{
-
6.19
,
6.24
,
3.15
},
{
-
5.56
,
5.88
,
2.52
},
{
-
7.05
,
5.96
,
2.83
},
{
-
3.10
,
6.14
,
3.08
},
{
-
2.34
,
6.69
,
3.27
},
{
-
3.86
,
6.69
,
3.29
},
{
-
0.04
,
6.24
,
3.13
},
{
0.63
,
6.54
,
2.53
},
{
0.08
,
5.29
,
3.18
},
{
3.12
,
6.24
,
3.14
},
{
3.57
,
5.82
,
2.40
},
{
2.23
,
5.90
,
3.12
},
{
6.25
,
6.19
,
3.06
},
{
5.55
,
5.59
,
3.32
},
{
6.08
,
6.99
,
3.55
},
{
-
6.20
,
-
6.16
,
6.15
},
{
-
6.29
,
-
5.99
,
7.09
},
{
-
6.09
,
-
7.11
,
6.09
},
{
-
3.09
,
-
6.19
,
6.27
},
{
-
2.56
,
-
5.90
,
5.52
},
{
-
3.80
,
-
6.69
,
5.87
},
{
0.02
,
-
6.25
,
6.24
},
{
-
0.70
,
-
5.70
,
6.51
},
{
0.25
,
-
5.93
,
5.36
},
{
3.11
,
-
6.18
,
6.14
},
{
3.76
,
-
6.54
,
6.74
},
{
2.29
,
-
6.20
,
6.64
},
{
6.22
,
-
6.17
,
6.15
},
{
6.61
,
-
6.98
,
6.47
},
{
5.56
,
-
5.94
,
6.81
},
{
-
6.21
,
-
3.10
,
6.14
},
{
-
6.76
,
-
2.66
,
6.78
},
{
-
5.51
,
-
3.50
,
6.65
},
{
-
3.13
,
-
3.05
,
6.18
},
{
-
2.19
,
-
3.14
,
6.34
},
{
-
3.50
,
-
3.89
,
6.43
},
{
0.01
,
-
3.06
,
6.15
},
{
-
0.06
,
-
2.81
,
7.07
},
{
-
0.25
,
-
3.98
,
6.13
},
{
3.04
,
-
3.09
,
6.17
},
{
3.84
,
-
3.51
,
5.84
},
{
3.25
,
-
2.85
,
7.08
},
{
6.26
,
-
3.13
,
6.19
},
{
6.01
,
-
2.20
,
6.09
},
{
5.47
,
-
3.55
,
6.54
},
{
-
6.20
,
0.01
,
6.27
},
{
-
5.79
,
-
0.70
,
5.78
},
{
-
6.67
,
0.51
,
5.60
},
{
-
3.13
,
0.01
,
6.14
},
{
-
3.53
,
-
0.35
,
6.94
},
{
-
2.21
,
0.17
,
6.39
},
{
-
0.04
,
-
0.04
,
6.20
},
{
0.26
,
0.47
,
5.46
},
{
0.51
,
0.22
,
6.93
},
{
3.10
,
-
0.05
,
6.23
},
{
2.33
,
0.44
,
5.95
},
{
3.85
,
0.45
,
5.92
},
{
6.19
,
-
0.01
,
6.26
},
{
7.05
,
0.16
,
5.88
},
{
5.58
,
0.02
,
5.52
},
{
-
6.22
,
3.04
,
6.17
},
{
-
5.45
,
3.57
,
5.95
},
{
-
6.62
,
3.50
,
6.92
},
{
-
3.09
,
3.16
,
6.21
},
{
-
3.71
,
2.75
,
5.61
},
{
-
2.60
,
2.43
,
6.59
},
{
-
0.02
,
3.10
,
6.26
},
{
0.89
,
3.27
,
6.05
},
{
-
0.44
,
2.94
,
5.41
},
{
3.12
,
3.04
,
6.23
},
{
2.31
,
3.53
,
6.43
},
{
3.59
,
3.60
,
5.60
},
{
6.23
,
3.05
,
6.24
},
{
5.92
,
3.91
,
6.54
},
{
6.02
,
3.03
,
5.30
},
{
-
6.15
,
6.21
,
6.24
},
{
-
6.27
,
6.46
,
5.32
},
{
-
7.00
,
5.85
,
6.51
},
{
-
3.07
,
6.15
,
6.22
},
{
-
3.98
,
6.27
,
5.94
},
{
-
2.66
,
7.01
,
6.10
},
{
0.04
,
6.20
,
6.25
},
{
-
0.38
,
5.50
,
5.75
},
{
-
0.36
,
7.00
,
5.93
},
{
3.12
,
6.15
,
6.24
},
{
3.66
,
6.88
,
5.93
},
{
2.25
,
6.33
,
5.86
},
{
6.20
,
6.27
,
6.19
},
{
5.46
,
5.65
,
6.19
},
{
6.97
,
5.73
,
6.39
}
};
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
positions
.
push_back
(
Vec3
(
coords
[
atom
][
0
],
coords
[
atom
][
1
],
coords
[
atom
][
2
])
*
OpenMM
::
NmPerAngstrom
);
}
else
throw
exception
();
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxEdgeLength
,
0
,
0
),
Vec3
(
0
,
boxEdgeLength
,
0
),
Vec3
(
0
,
0
,
boxEdgeLength
));
sig
.
clear
();
eps
.
clear
();
bonds
.
clear
();
for
(
int
atom
=
0
;
atom
<
natoms
;
++
atom
)
{
system
.
addParticle
(
masses
[
atom
%
RESSIZE
]);
double
sigma
=
2.0
*
pow
(
2.0
,
-
1.0
/
6.0
)
*
halfrmins
[
atom
%
RESSIZE
]
*
OpenMM
::
NmPerAngstrom
;
double
epsilon
=
fabs
(
epsilons
[
atom
%
RESSIZE
])
*
OpenMM
::
KJPerKcal
;
sig
.
push_back
(
0.5
*
sigma
);
eps
.
push_back
(
2.0
*
sqrt
(
epsilon
));
if
(
atom
%
RESSIZE
==
0
)
{
bonds
.
push_back
(
pair
<
int
,
int
>
(
atom
,
atom
+
1
));
bonds
.
push_back
(
pair
<
int
,
int
>
(
atom
,
atom
+
2
));
}
double
charge
=
do_electrostatics
?
charges
[
atom
]
:
0
;
forceField
->
addParticle
(
charge
,
sigma
,
epsilon
);
}
}
void
testWater2DpmeEnergiesForcesNoExclusions
()
{
const
double
cutoff
=
7.0
*
OpenMM
::
NmPerAngstrom
;
const
double
alpha
=
4.0124063605
;
const
double
dalpha
=
4.0124063605
;
const
int
grid
=
32
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
double
>
epsvals
;
vector
<
double
>
sigvals
;
vector
<
pair
<
int
,
int
>
>
bonds
;
System
system
;
const
int
numAtoms
=
6
;
double
boxEdgeLength
=
25
*
OpenMM
::
NmPerAngstrom
;
make_waterbox
(
numAtoms
,
boxEdgeLength
,
forceField
,
positions
,
epsvals
,
sigvals
,
bonds
,
system
,
false
);
forceField
->
setNonbondedMethod
(
OpenMM
::
NonbondedForce
::
LJPME
);
forceField
->
setPMEParameters
(
alpha
,
grid
,
grid
,
grid
);
forceField
->
setLJPMEParameters
(
dalpha
,
grid
,
grid
,
grid
);
forceField
->
setCutoffDistance
(
cutoff
);
forceField
->
setReactionFieldDielectric
(
1.0
);
system
.
addForce
(
forceField
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
//Gromacs reference values from the following inputs
//
//------------------------------------------------
// water2.gro
//------------------------------------------------
//MD of 2 waters, t= 0.0
// 6
// 1SOL OW1 1 0.200 0.200 0.200
// 1SOL HW1 2 0.250 0.200 0.300
// 1SOL HW2 3 0.150 0.200 0.300
// 2SOL OW1 4 0.000 0.000 0.000
// 2SOL HW1 5 0.050 0.000 0.100
// 2SOL HW2 6 -0.050 0.000 0.100
// 2.50000 2.50000 2.50000
//------------------------------------------------
//
//------------------------------------------------
// water2.gro
//------------------------------------------------
//[ defaults ]
//; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ
// 1 2 no 1.0 1.0
//
//[ atomtypes ]
//; full atom descriptions are available in ffoplsaa.atp
//; name bond_type mass charge ptype sigma epsilon
//OW OW 8 15.99940 -0.834 A 3.15057e-01 6.36386e-01
//HW HW 1 1.00800 0.417 A 4.00014e-02 1.92464e-01
//
//
//#ifdef NOEXCLUDE
//
//[ moleculetype ]
//; molname nrexcl
//SOL 0
//
//#else
//
//[ moleculetype ]
//; molname nrexcl
//SOL 3
//
//#endif
//
//#ifdef NOCHARGE
//[ atoms ]
//; id at type res nr residu name at name cg nr charge
//1 OW 1 SOL OW1 1 0.000
//2 HW 1 SOL HW1 1 0.000
//3 HW 1 SOL HW2 1 0.000
//#else
//[ atoms ]
//; id at type res nr residu name at name cg nr charge
//1 OW 1 SOL OW1 1 -0.834
//2 HW 1 SOL HW1 1 0.417
//3 HW 1 SOL HW2 1 0.417
//#endif
//
//[ settles ]
//; i j funct length
//1 1 0.09572 0.15139
//
//#ifndef NOEXCLUDE
//[ exclusions ]
//1 2 3
//2 1 3
//3 1 2
//#endif
//------------------------------------------------
//
//------------------------------------------------
// water2.top
//------------------------------------------------
//#include "tip3p.tpi"
//
//[ system ]
//Water dimer
//
//[ molecules ]
//SOL 2
//------------------------------------------------
//
//------------------------------------------------
// water2.mdp
//------------------------------------------------
//define = -DNOCHARGE -DNOEXCLUDE
//;define = -DNOCHARGE
//rvdw = 0.7
//vdw-modifier = Potential-Shift
//;vdw-modifier = None
//rlist = 0.9
//rcoulomb = 0.7
//nstfout = 1
//fourierspacing = 0.08
//pme-order = 5
//ewald-rtol = 1.5E-2
//ewald-rtol-lj = 1.5E-2
//vdwtype = PME
//lj-pme-comb-rule = geometric
//continuation = yes
//------------------------------------------------
//
//run commands:-
// gmx grompp -c water2.gro -p water2.top -f water2.mdp -o run.tpr
// gmx mdrun -s run.tpr -o traj.trr -pforce 1E-16
// gmx dump -f traj.trr
double
refenergy
=
1.34804e+03
;
vector
<
Vec3
>
refforces
(
6
);
refforces
[
0
]
=
Vec3
(
3.15301e-01
,
-
3.91114e-03
,
-
6.68965e+04
);
refforces
[
1
]
=
Vec3
(
1.67241e+04
,
-
3.79846e-02
,
3.34487e+04
);
refforces
[
2
]
=
Vec3
(
-
1.67243e+04
,
-
9.55931e-02
,
3.34486e+04
);
refforces
[
3
]
=
Vec3
(
-
1.71643e+00
,
-
1.76696e+00
,
-
6.68993e+04
);
refforces
[
4
]
=
Vec3
(
1.67254e+04
,
1.59080e+00
,
3.34495e+04
);
refforces
[
5
]
=
Vec3
(
-
1.67239e+04
,
3.13897e-01
,
3.34491e+04
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
double
energy
=
state
.
getPotentialEnergy
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_TOL
(
refenergy
,
energy
,
1E-4
);
for
(
int
n
=
0
;
n
<
numAtoms
;
++
n
)
ASSERT_EQUAL_VEC
(
refforces
[
n
],
forces
[
n
],
1E-4
);
}
void
testDMFDpmeEnergiesForcesWithExclusions
()
{
const
double
cutoff
=
7.0
*
OpenMM
::
NmPerAngstrom
;
const
double
alpha
=
4.0124063605
;
const
double
dalpha
=
4.0124063605
;
const
int
grid
=
32
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
double
>
epsvals
;
vector
<
double
>
sigvals
;
vector
<
pair
<
int
,
int
>
>
bonds
;
System
system
;
const
int
numAtoms
=
12
;
double
boxEdgeLength
=
20
*
OpenMM
::
NmPerAngstrom
;
make_dmfbox
(
numAtoms
,
boxEdgeLength
,
forceField
,
positions
,
epsvals
,
sigvals
,
bonds
,
system
,
false
);
forceField
->
setNonbondedMethod
(
OpenMM
::
NonbondedForce
::
LJPME
);
forceField
->
setPMEParameters
(
alpha
,
grid
,
grid
,
grid
);
forceField
->
setLJPMEParameters
(
dalpha
,
grid
,
grid
,
grid
);
forceField
->
setCutoffDistance
(
cutoff
);
forceField
->
setUseSwitchingFunction
(
false
);
forceField
->
setUseDispersionCorrection
(
false
);
forceField
->
setReactionFieldDielectric
(
1.0
);
system
.
addForce
(
forceField
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
double
refenergy
=
1.29545e+01
;
vector
<
Vec3
>
refforces
(
12
);
//Gromacs reference values from the following inputs
//------------------------------------------------
// dmf.mdp
//------------------------------------------------
//rvdw = 0.7
//vdw-modifier = Potential-Shift
//rlist = 0.9
//rcoulomb = 0.7
//nstfout = 1
//fourierspacing = 0.0625
//pme-order = 5
//ewald-rtol = 1.5E-2
//ewald-rtol-lj = 1.5E-2
//vdwtype = PME
//lj-pme-comb-rule = geometric
//continuation = yes
//------------------------------------------------
// dmf.gro
//------------------------------------------------
//Guyana Rwanda Oman Macau Angola Cameroon Senegal
// 12
// 101DMF HA 1 0.620 0.945 0.128
// 101DMF C 2 0.560 0.905 0.045
// 101DMF O 3 0.502 0.987 -0.026
// 101DMF N 4 0.556 0.770 0.028
// 101DMF CC 5 0.643 0.685 0.106
// 101DMF HC1 6 0.680 0.741 0.193
// 101DMF HC2 7 0.729 0.653 0.045
// 101DMF HC3 8 0.587 0.597 0.140
// 101DMF CT 9 0.477 0.708 -0.072
// 101DMF HT1 10 0.377 0.688 -0.032
// 101DMF HT2 11 0.524 0.614 -0.102
// 101DMF HT3 12 0.468 0.775 -0.158
// 2.00000 2.00000 2.00000
//------------------------------------------------
// dmf.top
//------------------------------------------------
//[ defaults ]
//; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ
//1 2 yes 1.0 1.0
//
//[ atomtypes ]
//HGR52 1 1.008000 0.000 A 0.160361769265 0.19246
//CG2O1 6 12.011000 0.000 A 0.356359487256 0.46024
//OG2D1 8 15.999400 0.000 A 0.302905564168 0.50208
//NG2S0 7 14.007000 0.000 A 0.329632525712 0.83680
//CG331 6 12.011000 0.000 A 0.365268474438 0.32635
// HGA3 1 1.008000 0.000 A 0.238760856462 0.10042
//
//[ pairtypes ]
//OG2D1 CG331 1 0.293996576986 0.144938011577
//
//[ bondtypes ]
//; i j func b0 kb
// CG2O1 HGR52 1 0.11000000 0.0000000000
// CG2O1 OG2D1 1 0.12300000 0.0000000000
// CG2O1 NG2S0 1 0.13500000 0.0000000000
// CG331 NG2S0 1 0.14340000 0.0000000000
// CG331 HGA3 1 0.11110000 0.0000000000
//
//[ angletypes ]
//; i j k func theta0 ktheta ub0 kub
// HGA3 CG331 HGA3 5 108.400000 0.0000000000000 0.18020000 0.0000000
// NG2S0 CG331 HGA3 5 105.000000 0.0000000000000 0.00000000 0.0000000
// CG331 NG2S0 CG331 5 121.000000 0.0000000000000 0.00000000 0.0000000
// CG2O1 NG2S0 CG331 5 119.500000 0.0000000000000 0.00000000 0.0000000
// NG2S0 CG2O1 OG2D1 5 124.000000 0.0000000000000 0.00000000 0.0000000
// NG2S0 CG2O1 HGR52 5 115.000000 0.0000000000000 0.00000000 0.0000000
// OG2D1 CG2O1 HGR52 5 122.000000 0.0000000000000 0.00000000 0.0000000
//
//[ dihedraltypes ]
//; i j k l func phi0 kphi mult
// OG2D1 CG2O1 NG2S0 CG331 9 180.000000 0.00000000 2
// HGR52 CG2O1 NG2S0 CG331 9 180.000000 0.00000000 2
// HGA3 CG331 NG2S0 CG331 9 0.000000 0.00000000 3
// HGA3 CG331 NG2S0 CG2O1 9 0.000000 0.00000000 3
//
//[ dihedraltypes ]
//; 'improper' dihedrals
//; i j k l func phi0 kphi
// CG2O1 NG2S0 OG2D1 HGR52 2 0.000000 0.0000000
//
//[ moleculetype ]
//; Name nrexcl
//DMF 3
//
//[ atoms ]
//; nr type resnr residue atom cgnr charge mass typeB chargeB massB
//; residue 101 DMF rtp DMF q 0.0
// 1 HGR52 101 DMF HA 1 0.00 1.008 ; qtot 0.00
// 2 CG2O1 101 DMF C 2 0.00 12.011 ; qtot 0.00
// 3 OG2D1 101 DMF O 3 0.00 15.9994 ; qtot 0.00
// 4 NG2S0 101 DMF N 4 0.00 14.007 ; qtot 0.00
// 5 CG331 101 DMF CC 5 0.00 12.011 ; qtot 0.00
// 6 HGA3 101 DMF HC1 6 0.00 1.008 ; qtot 0.00
// 7 HGA3 101 DMF HC2 7 0.00 1.008 ; qtot 0.00
// 8 HGA3 101 DMF HC3 8 0.00 1.008 ; qtot 0.00
// 9 CG331 101 DMF CT 9 0.00 12.011 ; qtot 0.00
// 10 HGA3 101 DMF HT1 10 0.00 1.008 ; qtot 0.00
// 11 HGA3 101 DMF HT2 11 0.00 1.008 ; qtot 0.00
// 12 HGA3 101 DMF HT3 12 0.00 1.008 ; qtot 0
//
//[ bonds ]
//; ai aj funct c0 c1 c2 c3
// 1 2 1
// 2 3 1
// 2 4 1
// 4 5 1
// 4 9 1
// 5 6 1
// 5 7 1
// 5 8 1
// 9 10 1
// 9 11 1
// 9 12 1
//
//[ pairs ]
//; ai aj funct c0 c1 c2 c3
// 1 5 1
// 1 9 1
// 2 6 1
// 2 7 1
// 2 8 1
// 2 10 1
// 2 11 1
// 2 12 1
// 3 5 1
// 3 9 1
// 5 10 1
// 5 11 1
// 5 12 1
// 6 9 1
// 7 9 1
// 8 9 1
//
//[ angles ]
//; ai aj ak funct c0 c1 c2 c3
// 1 2 3 5
// 1 2 4 5
// 3 2 4 5
// 2 4 5 5
// 2 4 9 5
// 5 4 9 5
// 4 5 6 5
// 4 5 7 5
// 4 5 8 5
// 6 5 7 5
// 6 5 8 5
// 7 5 8 5
// 4 9 10 5
// 4 9 11 5
// 4 9 12 5
// 10 9 11 5
// 10 9 12 5
// 11 9 12 5
//
//[ dihedrals ]
//; ai aj ak al funct c0 c1 c2 c3 c4 c5
// 1 2 4 5 9
// 1 2 4 9 9
// 3 2 4 5 9
// 3 2 4 9 9
// 2 4 5 6 9
// 2 4 5 7 9
// 2 4 5 8 9
// 9 4 5 6 9
// 9 4 5 7 9
// 9 4 5 8 9
// 2 4 9 10 9
// 2 4 9 11 9
// 2 4 9 12 9
// 5 4 9 10 9
// 5 4 9 11 9
// 5 4 9 12 9
//
//[ dihedrals ]
//; ai aj ak al funct c0 c1 c2 c3
// 1 3 4 2 2
//
//[ system ]
//; Name
//DMF Monomer
//
//[ molecules ]
//; Compound #mols
//DMF 1
//
//
//run commands:-
//gmx_d grompp -c dmf.gro -p dmf.top -f dmf.mdp -o run.tpr
//gmx_d mdrun -s run.tpr -o traj.trr -pforce 1E-16 -debug
//gmx_d dump -f traj.trr
// Gromacs reference values. See inputs above.
refforces
[
0
]
=
Vec3
(
-
3.19942e+00
,
2.19766e+01
,
2.72861e-01
);
refforces
[
1
]
=
Vec3
(
-
5.22879e+01
,
2.82006e+02
,
-
6.86534e+00
);
refforces
[
2
]
=
Vec3
(
1.23583e+01
,
7.31235e+01
,
4.08375e+01
);
refforces
[
3
]
=
Vec3
(
-
1.28656e-03
,
1.14097e-03
,
4.07527e-04
);
refforces
[
4
]
=
Vec3
(
1.51942e+02
,
5.65684e+01
,
2.41818e+02
);
refforces
[
5
]
=
Vec3
(
1.20290e+02
,
-
1.65176e+02
,
1.48309e+02
);
refforces
[
6
]
=
Vec3
(
4.57022e+01
,
-
1.65198e+01
,
1.88824e+01
);
refforces
[
7
]
=
Vec3
(
5.57228e+01
,
-
5.68770e+01
,
1.09979e+02
);
refforces
[
8
]
=
Vec3
(
-
9.58422e+01
,
4.41982e+01
,
-
1.27887e+02
);
refforces
[
9
]
=
Vec3
(
-
2.59754e+01
,
-
1.42402e+01
,
-
1.23475e+01
);
refforces
[
10
]
=
Vec3
(
-
1.37259e+02
,
-
7.97690e+01
,
-
2.39814e+02
);
refforces
[
11
]
=
Vec3
(
-
7.14520e+01
,
-
1.45287e+02
,
-
1.73189e+02
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
double
energy
=
state
.
getPotentialEnergy
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_TOL
(
refenergy
,
energy
,
1E-4
);
for
(
int
n
=
0
;
n
<
numAtoms
;
++
n
)
// The forces on atom 3 are much smaller in magnitude to the others,
// which causes problems for testing in single precision
if
(
n
!=
3
)
ASSERT_EQUAL_VEC
(
refforces
[
n
],
forces
[
n
],
5E-4
);
}
void
testWater2DpmeEnergiesForcesWithExclusions
()
{
const
double
cutoff
=
7.0
*
OpenMM
::
NmPerAngstrom
;
const
double
alpha
=
4.0124063605
;
const
double
dalpha
=
4.0124063605
;
const
int
grid
=
32
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
double
>
epsvals
;
vector
<
double
>
sigvals
;
vector
<
pair
<
int
,
int
>
>
bonds
;
System
system
;
const
int
numAtoms
=
6
;
double
boxEdgeLength
=
25
*
OpenMM
::
NmPerAngstrom
;
make_waterbox
(
numAtoms
,
boxEdgeLength
,
forceField
,
positions
,
epsvals
,
sigvals
,
bonds
,
system
,
false
);
forceField
->
setNonbondedMethod
(
OpenMM
::
NonbondedForce
::
LJPME
);
forceField
->
createExceptionsFromBonds
(
bonds
,
1.0
,
1.0
);
forceField
->
setPMEParameters
(
alpha
,
grid
,
grid
,
grid
);
forceField
->
setLJPMEParameters
(
dalpha
,
grid
,
grid
,
grid
);
forceField
->
setCutoffDistance
(
cutoff
);
forceField
->
setUseSwitchingFunction
(
false
);
forceField
->
setUseDispersionCorrection
(
false
);
forceField
->
setReactionFieldDielectric
(
1.0
);
system
.
addForce
(
forceField
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
double
refenergy
=
-
7.78060e-01
;
vector
<
Vec3
>
refforces
(
6
);
// Gromacs reference values. See comments in testWater2DpmeEnergiesForcesNoExclusions() for details.
refforces
[
0
]
=
Vec3
(
3.15301e-01
,
-
3.91114e-03
,
9.48373e-01
);
refforces
[
1
]
=
Vec3
(
-
4.74745e-02
,
-
3.79846e-02
,
-
5.69616e-02
);
refforces
[
2
]
=
Vec3
(
-
7.16866e-02
,
-
9.55931e-02
,
-
1.43348e-01
);
refforces
[
3
]
=
Vec3
(
-
1.78136e+00
,
-
1.76696e+00
,
-
1.70022e+00
);
refforces
[
4
]
=
Vec3
(
1.19309e+00
,
1.59080e+00
,
7.95443e-01
);
refforces
[
5
]
=
Vec3
(
3.92366e-01
,
3.13897e-01
,
1.56962e-01
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
double
energy
=
state
.
getPotentialEnergy
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_TOL
(
refenergy
,
energy
,
1E-4
);
for
(
int
n
=
0
;
n
<
numAtoms
;
++
n
)
ASSERT_EQUAL_VEC
(
refforces
[
n
],
forces
[
n
],
5E-4
);
}
void
testWater125DpmeVsLongCutoffNoExclusions
()
{
const
double
cutoff
=
8.5
*
OpenMM
::
NmPerAngstrom
;
const
double
alpha
=
0.45
*
OpenMM
::
AngstromsPerNm
;
const
double
dalpha
=
0.45
*
OpenMM
::
AngstromsPerNm
;
const
int
grid
=
32
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
double
>
epsvals
;
vector
<
double
>
sigvals
;
vector
<
pair
<
int
,
int
>
>
bonds
;
System
system
;
const
int
numAtoms
=
375
;
double
boxEdgeLength
=
17.01
*
OpenMM
::
NmPerAngstrom
;
make_waterbox
(
numAtoms
,
boxEdgeLength
,
forceField
,
positions
,
epsvals
,
sigvals
,
bonds
,
system
,
false
);
forceField
->
setNonbondedMethod
(
OpenMM
::
NonbondedForce
::
LJPME
);
forceField
->
setPMEParameters
(
alpha
,
grid
,
grid
,
grid
);
forceField
->
setLJPMEParameters
(
dalpha
,
grid
,
grid
,
grid
);
forceField
->
setCutoffDistance
(
cutoff
);
forceField
->
setReactionFieldDielectric
(
1.0
);
system
.
addForce
(
forceField
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
double
energy
=
state
.
getPotentialEnergy
();
//Gromacs reference values. See comments in testWater2DpmeEnergiesForcesNoExclusions() for details.
//Coordinates are from make_waterbox, and the .gro file looks like
//
//;define = -DNOCHARGE -DNOEXCLUDE
//define = -DNOCHARGE
//vdw-modifier = Potential-Shift
//rvdw = 1.15
//rlist = 1.15
//rcoulomb = 1.15
//fourierspacing = 0.04
//nstfout = 1
//pme-order = 5
//ewald-rtol = 1E-8
//ewald-rtol-lj = 1E-8
//vdwtype = PME
//lj-pme-comb-rule = geometric
//continuation = yes
double
gromacs_energy
=
5.63157e+05
;
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
vector
<
Vec3
>
refforces
(
numAtoms
);
refforces
[
0
]
=
Vec3
(
-
1.12446e+05
,
-
2.71952e+05
,
-
1.91471e+05
);
refforces
[
1
]
=
Vec3
(
2.70479e+05
,
6.61172e+04
,
7.21277e+04
);
refforces
[
2
]
=
Vec3
(
-
1.58058e+05
,
2.05779e+05
,
1.19292e+05
);
refforces
[
3
]
=
Vec3
(
3.16438e+05
,
-
1.27994e+05
,
1.08811e+05
);
refforces
[
4
]
=
Vec3
(
-
1.36520e+05
,
1.93405e+05
,
1.36521e+05
);
refforces
[
5
]
=
Vec3
(
-
1.79957e+05
,
-
6.54374e+04
,
-
2.45393e+05
);
refforces
[
6
]
=
Vec3
(
1.30626e+05
,
-
1.36728e+05
,
2.93833e+05
);
refforces
[
7
]
=
Vec3
(
-
2.74564e+05
,
8.02095e+04
,
-
7.09524e+04
);
refforces
[
8
]
=
Vec3
(
1.43952e+05
,
5.64523e+04
,
-
2.22980e+05
);
refforces
[
9
]
=
Vec3
(
-
4.22852e+04
,
2.14660e+04
,
-
3.23254e+05
);
refforces
[
10
]
=
Vec3
(
2.28059e+05
,
-
4.44251e+04
,
1.62898e+05
);
refforces
[
11
]
=
Vec3
(
-
1.85776e+05
,
2.29044e+04
,
1.60326e+05
);
refforces
[
12
]
=
Vec3
(
-
1.02075e+05
,
3.27346e+05
,
1.47993e+04
);
refforces
[
13
]
=
Vec3
(
7.77195e+04
,
-
1.44336e+05
,
2.10959e+05
);
refforces
[
14
]
=
Vec3
(
2.44142e+04
,
-
1.83111e+05
,
-
2.25837e+05
);
refforces
[
15
]
=
Vec3
(
-
4.81843e+04
,
-
2.72889e+05
,
-
1.75068e+05
);
refforces
[
16
]
=
Vec3
(
-
5.46666e+03
,
2.18711e+04
,
2.62456e+05
);
refforces
[
17
]
=
Vec3
(
5.35890e+04
,
2.51021e+05
,
-
8.74311e+04
);
refforces
[
18
]
=
Vec3
(
-
2.04721e+05
,
1.58918e+05
,
2.20448e+05
);
refforces
[
19
]
=
Vec3
(
-
7.05932e+04
,
-
1.64717e+05
,
-
2.17659e+05
);
refforces
[
20
]
=
Vec3
(
2.75339e+05
,
5.73611e+03
,
-
2.86718e+03
);
refforces
[
21
]
=
Vec3
(
-
5.65480e+03
,
-
2.81809e+05
,
-
1.38358e+05
);
refforces
[
22
]
=
Vec3
(
-
7.85576e+03
,
2.25204e+05
,
-
1.15217e+05
);
refforces
[
23
]
=
Vec3
(
1.34846e+04
,
5.66345e+04
,
2.53512e+05
);
refforces
[
24
]
=
Vec3
(
-
7.73167e+04
,
-
4.43114e+04
,
3.22354e+05
);
refforces
[
25
]
=
Vec3
(
-
1.24372e+05
,
1.61973e+05
,
-
1.88001e+05
);
refforces
[
26
]
=
Vec3
(
2.01689e+05
,
-
1.17651e+05
,
-
1.34455e+05
);
refforces
[
27
]
=
Vec3
(
-
1.79300e+05
,
-
1.97922e+05
,
1.94294e+05
);
refforces
[
28
]
=
Vec3
(
2.38945e+05
,
-
4.88761e+04
,
-
9.50350e+04
);
refforces
[
29
]
=
Vec3
(
-
5.95911e+04
,
2.46878e+05
,
-
9.93159e+04
);
refforces
[
30
]
=
Vec3
(
-
1.31892e+04
,
-
2.15675e+05
,
2.68757e+05
);
refforces
[
31
]
=
Vec3
(
2.31232e+05
,
1.08107e+05
,
-
1.32129e+05
);
refforces
[
32
]
=
Vec3
(
-
2.18089e+05
,
1.07592e+05
,
-
1.36669e+05
);
refforces
[
33
]
=
Vec3
(
1.90632e+04
,
-
3.62889e+05
,
8.61608e+04
);
refforces
[
34
]
=
Vec3
(
-
2.16178e+05
,
1.59639e+05
,
-
1.66288e+05
);
refforces
[
35
]
=
Vec3
(
1.97134e+05
,
2.03295e+05
,
8.00862e+04
);
refforces
[
36
]
=
Vec3
(
3.40071e+05
,
-
6.87734e+04
,
1.22584e+05
);
refforces
[
37
]
=
Vec3
(
-
4.17943e+04
,
8.35901e+03
,
-
2.64693e+05
);
refforces
[
38
]
=
Vec3
(
-
2.98358e+05
,
6.03813e+04
,
1.42075e+05
);
refforces
[
39
]
=
Vec3
(
-
3.21693e+05
,
4.40885e+04
,
1.41154e+04
);
refforces
[
40
]
=
Vec3
(
1.28817e+05
,
2.02067e+04
,
-
2.07114e+05
);
refforces
[
41
]
=
Vec3
(
1.92948e+05
,
-
6.43160e+04
,
1.92949e+05
);
refforces
[
42
]
=
Vec3
(
-
1.46001e+05
,
3.20840e+05
,
7.97305e+04
);
refforces
[
43
]
=
Vec3
(
-
1.27705e+05
,
-
2.55411e+05
,
-
1.24428e+05
);
refforces
[
44
]
=
Vec3
(
2.73737e+05
,
-
6.54594e+04
,
4.46323e+04
);
refforces
[
45
]
=
Vec3
(
1.50212e+04
,
2.43629e+05
,
-
2.20084e+05
);
refforces
[
46
]
=
Vec3
(
-
1.07432e+05
,
8.26408e+03
,
2.42419e+05
);
refforces
[
47
]
=
Vec3
(
9.23685e+04
,
-
2.51915e+05
,
-
2.23909e+04
);
refforces
[
48
]
=
Vec3
(
3.14327e+04
,
-
2.94199e+05
,
1.55484e+05
);
refforces
[
49
]
=
Vec3
(
-
2.23665e+05
,
1.52883e+05
,
-
2.54793e+04
);
refforces
[
50
]
=
Vec3
(
1.92227e+05
,
1.41342e+05
,
-
1.30033e+05
);
refforces
[
51
]
=
Vec3
(
5.73542e+04
,
-
2.08689e+05
,
-
2.68170e+05
);
refforces
[
52
]
=
Vec3
(
-
2.26784e+05
,
1.85259e+05
,
8.30474e+04
);
refforces
[
53
]
=
Vec3
(
1.69446e+05
,
2.34613e+04
,
1.85087e+05
);
refforces
[
54
]
=
Vec3
(
2.25490e+05
,
-
1.91311e+05
,
-
1.40103e+05
);
refforces
[
55
]
=
Vec3
(
-
8.20802e+03
,
6.83988e+04
,
2.54448e+05
);
refforces
[
56
]
=
Vec3
(
-
2.17315e+05
,
1.22953e+05
,
-
1.14373e+05
);
refforces
[
57
]
=
Vec3
(
-
7.09510e+04
,
2.05639e+05
,
-
2.69540e+05
);
refforces
[
58
]
=
Vec3
(
1.93603e+05
,
3.38041e+04
,
2.18192e+05
);
refforces
[
59
]
=
Vec3
(
-
1.22579e+05
,
-
2.39458e+05
,
5.13124e+04
);
refforces
[
60
]
=
Vec3
(
-
1.07250e+05
,
3.35982e+05
,
6.89600e+03
);
refforces
[
61
]
=
Vec3
(
6.90672e-01
,
-
1.44228e+05
,
-
2.24659e+05
);
refforces
[
62
]
=
Vec3
(
1.07222e+05
,
-
1.91701e+05
,
2.17695e+05
);
refforces
[
63
]
=
Vec3
(
2.64846e+05
,
1.94002e+05
,
5.27262e+03
);
refforces
[
64
]
=
Vec3
(
-
1.12985e+04
,
-
2.71176e+05
,
8.47510e+03
);
refforces
[
65
]
=
Vec3
(
-
2.53630e+05
,
7.71894e+04
,
-
1.37831e+04
);
refforces
[
66
]
=
Vec3
(
-
3.04551e+05
,
4.21918e+04
,
1.88948e+05
);
refforces
[
67
]
=
Vec3
(
2.87326e+05
,
1.22193e+05
,
3.30263e+04
);
refforces
[
68
]
=
Vec3
(
1.73006e+04
,
-
1.64358e+05
,
-
2.22023e+05
);
refforces
[
69
]
=
Vec3
(
2.45556e+04
,
2.20596e+05
,
2.41913e+05
);
refforces
[
70
]
=
Vec3
(
1.50804e+05
,
-
2.17829e+05
,
-
4.46813e+04
);
refforces
[
71
]
=
Vec3
(
-
1.75369e+05
,
-
2.74087e+03
,
-
1.97287e+05
);
refforces
[
72
]
=
Vec3
(
8.65787e+04
,
-
2.77188e+04
,
-
3.15014e+05
);
refforces
[
73
]
=
Vec3
(
-
2.42127e+05
,
6.26659e+04
,
1.11092e+05
);
refforces
[
74
]
=
Vec3
(
1.55591e+05
,
-
3.48752e+04
,
2.03883e+05
);
refforces
[
75
]
=
Vec3
(
7.06224e+04
,
2.96642e+05
,
-
1.51267e+05
);
refforces
[
76
]
=
Vec3
(
-
5.39280e+04
,
-
2.57657e+05
,
-
1.13850e+05
);
refforces
[
77
]
=
Vec3
(
-
1.67422e+04
,
-
3.90659e+04
,
2.65102e+05
);
refforces
[
78
]
=
Vec3
(
-
4.52577e+04
,
-
3.21552e+05
,
-
7.01075e+04
);
refforces
[
79
]
=
Vec3
(
2.35182e+05
,
1.45173e+05
,
3.48411e+04
);
refforces
[
80
]
=
Vec3
(
-
1.89931e+05
,
1.76363e+05
,
3.52722e+04
);
refforces
[
81
]
=
Vec3
(
-
2.29347e+05
,
1.06977e+05
,
-
2.70703e+05
);
refforces
[
82
]
=
Vec3
(
-
1.17929e+04
,
-
2.56493e+05
,
1.17929e+05
);
refforces
[
83
]
=
Vec3
(
2.41161e+05
,
1.49452e+05
,
1.52847e+05
);
refforces
[
84
]
=
Vec3
(
2.32633e+03
,
3.03443e+05
,
1.27473e+05
);
refforces
[
85
]
=
Vec3
(
-
2.11215e+05
,
-
1.63335e+05
,
-
4.50583e+04
);
refforces
[
86
]
=
Vec3
(
2.08887e+05
,
-
1.40170e+05
,
-
8.24544e+04
);
refforces
[
87
]
=
Vec3
(
5.83172e+04
,
2.82133e+04
,
-
3.26001e+05
);
refforces
[
88
]
=
Vec3
(
1.76890e+05
,
-
4.71698e+04
,
2.15220e+05
);
refforces
[
89
]
=
Vec3
(
-
2.35168e+05
,
1.89225e+04
,
1.10825e+05
);
refforces
[
90
]
=
Vec3
(
-
2.72444e+05
,
-
1.46998e+05
,
-
1.00637e+05
);
refforces
[
91
]
=
Vec3
(
2.78426e+04
,
2.39442e+05
,
1.16936e+05
);
refforces
[
92
]
=
Vec3
(
2.44570e+05
,
-
9.23920e+04
,
-
1.63042e+04
);
refforces
[
93
]
=
Vec3
(
-
3.10100e+04
,
2.93390e+05
,
-
1.87196e+05
);
refforces
[
94
]
=
Vec3
(
-
6.38830e+04
,
-
2.90671e+05
,
-
6.38833e+04
);
refforces
[
95
]
=
Vec3
(
9.48775e+04
,
-
2.79002e+03
,
2.51149e+05
);
refforces
[
96
]
=
Vec3
(
4.18753e+04
,
-
1.23438e+05
,
-
3.10188e+05
);
refforces
[
97
]
=
Vec3
(
1.29157e+05
,
2.04500e+05
,
9.41770e+04
);
refforces
[
98
]
=
Vec3
(
-
1.71038e+05
,
-
8.10180e+04
,
2.16049e+05
);
refforces
[
99
]
=
Vec3
(
-
5.61490e+04
,
2.26993e+04
,
-
3.44090e+05
);
refforces
[
100
]
=
Vec3
(
-
1.96230e+05
,
-
2.88572e+04
,
1.93344e+05
);
refforces
[
101
]
=
Vec3
(
2.52383e+05
,
6.15570e+03
,
1.50813e+05
);
refforces
[
102
]
=
Vec3
(
-
6.33126e+04
,
3.55941e+05
,
8.51300e+04
);
refforces
[
103
]
=
Vec3
(
-
1.75405e+05
,
-
1.81783e+05
,
-
1.69027e+05
);
refforces
[
104
]
=
Vec3
(
2.38759e+05
,
-
1.74232e+05
,
8.38891e+04
);
refforces
[
105
]
=
Vec3
(
1.51480e+05
,
-
4.90606e+04
,
3.17956e+05
);
refforces
[
106
]
=
Vec3
(
4.93229e+04
,
-
1.61668e+05
,
-
2.02771e+05
);
refforces
[
107
]
=
Vec3
(
-
2.00831e+05
,
2.10712e+05
,
-
1.15233e+05
);
refforces
[
108
]
=
Vec3
(
2.20204e+05
,
-
2.33820e+05
,
1.51386e+05
);
refforces
[
109
]
=
Vec3
(
3.36498e+04
,
2.79296e+05
,
-
1.51424e+05
);
refforces
[
110
]
=
Vec3
(
-
2.53896e+05
,
-
4.54334e+04
,
2.10242e-01
);
refforces
[
111
]
=
Vec3
(
-
1.94665e+05
,
2.05890e+05
,
2.40510e+05
);
refforces
[
112
]
=
Vec3
(
-
9.73233e+04
,
-
1.29764e+05
,
-
2.62775e+05
);
refforces
[
113
]
=
Vec3
(
2.92049e+05
,
-
7.61856e+04
,
2.22208e+04
);
refforces
[
114
]
=
Vec3
(
1.60261e+05
,
-
3.43716e+05
,
1.52456e+04
);
refforces
[
115
]
=
Vec3
(
1.11151e+05
,
3.08358e+05
,
-
8.60527e+04
);
refforces
[
116
]
=
Vec3
(
-
2.71443e+05
,
3.54056e+04
,
7.08103e+04
);
refforces
[
117
]
=
Vec3
(
-
4.27331e+04
,
-
3.19871e+05
,
-
1.68415e+05
);
refforces
[
118
]
=
Vec3
(
2.28408e+05
,
2.15171e+05
,
-
2.31720e+04
);
refforces
[
119
]
=
Vec3
(
-
1.85616e+05
,
1.04782e+05
,
1.91602e+05
);
refforces
[
120
]
=
Vec3
(
-
1.66057e+05
,
-
9.58191e+04
,
-
2.78448e+05
);
refforces
[
121
]
=
Vec3
(
1.91258e+05
,
2.19476e+05
,
6.89779e+04
);
refforces
[
122
]
=
Vec3
(
-
2.52379e+04
,
-
1.23674e+05
,
2.09489e+05
);
refforces
[
123
]
=
Vec3
(
6.55172e+03
,
-
9.23173e+04
,
3.29554e+05
);
refforces
[
124
]
=
Vec3
(
-
2.14685e+05
,
1.13143e+05
,
-
1.36353e+05
);
refforces
[
125
]
=
Vec3
(
2.08124e+05
,
-
2.08124e+04
,
-
1.93257e+05
);
refforces
[
126
]
=
Vec3
(
1.02696e+05
,
-
3.39299e+05
,
-
4.47114e+04
);
refforces
[
127
]
=
Vec3
(
-
1.81786e+05
,
1.75407e+05
,
-
1.69029e+05
);
refforces
[
128
]
=
Vec3
(
7.90534e+04
,
1.63962e+05
,
2.13738e+05
);
refforces
[
129
]
=
Vec3
(
-
3.45588e+05
,
9.36838e+04
,
5.67939e+04
);
refforces
[
130
]
=
Vec3
(
1.44967e+05
,
-
2.60943e+05
,
7.08730e+04
);
refforces
[
131
]
=
Vec3
(
2.00649e+05
,
1.67207e+05
,
-
1.27685e+05
);
refforces
[
132
]
=
Vec3
(
-
2.70181e+05
,
2.05707e+05
,
-
3.11852e+04
);
refforces
[
133
]
=
Vec3
(
1.09331e+05
,
-
1.83207e+05
,
-
1.86162e+05
);
refforces
[
134
]
=
Vec3
(
1.60883e+05
,
-
2.25804e+04
,
2.17340e+05
);
refforces
[
135
]
=
Vec3
(
-
1.04496e+05
,
-
2.97000e+05
,
-
1.63733e+05
);
refforces
[
136
]
=
Vec3
(
2.11303e+05
,
1.73661e+04
,
1.79462e+05
);
refforces
[
137
]
=
Vec3
(
-
1.06849e+05
,
2.79694e+05
,
-
1.57134e+04
);
refforces
[
138
]
=
Vec3
(
-
3.82271e+04
,
2.11942e+05
,
2.60118e+05
);
refforces
[
139
]
=
Vec3
(
-
1.96098e+05
,
-
1.23692e+05
,
-
1.71962e+05
);
refforces
[
140
]
=
Vec3
(
2.34334e+05
,
-
8.82195e+04
,
-
8.82188e+04
);
refforces
[
141
]
=
Vec3
(
2.17634e+05
,
2.72527e+05
,
1.42967e+05
);
refforces
[
142
]
=
Vec3
(
9.30924e+04
,
-
1.86185e+05
,
-
1.98197e+05
);
refforces
[
143
]
=
Vec3
(
-
3.10770e+05
,
-
8.63246e+04
,
5.52480e+04
);
refforces
[
144
]
=
Vec3
(
-
1.63880e+05
,
-
2.98869e+05
,
1.01299e+05
);
refforces
[
145
]
=
Vec3
(
6.83424e+04
,
2.39196e+05
,
1.61538e+05
);
refforces
[
146
]
=
Vec3
(
9.55787e+04
,
5.97354e+04
,
-
2.62846e+05
);
refforces
[
147
]
=
Vec3
(
1.06430e+05
,
-
2.97083e+05
,
-
7.97261e+04
);
refforces
[
148
]
=
Vec3
(
-
1.14920e+05
,
6.41394e+04
,
2.21823e+05
);
refforces
[
149
]
=
Vec3
(
8.52531e+03
,
2.33043e+05
,
-
1.42101e+05
);
refforces
[
150
]
=
Vec3
(
-
4.96390e+04
,
-
4.12076e+04
,
-
3.67834e+05
);
refforces
[
151
]
=
Vec3
(
1.25352e+05
,
-
1.99962e+05
,
1.61166e+05
);
refforces
[
152
]
=
Vec3
(
-
7.57841e+04
,
2.41138e+05
,
2.06689e+05
);
refforces
[
153
]
=
Vec3
(
-
3.06397e+05
,
-
5.15222e+04
,
-
1.37080e+05
);
refforces
[
154
]
=
Vec3
(
1.92949e+05
,
-
1.92945e+05
,
6.43163e+04
);
refforces
[
155
]
=
Vec3
(
1.13490e+05
,
2.44443e+05
,
7.27504e+04
);
refforces
[
156
]
=
Vec3
(
-
3.74471e+03
,
3.83223e+05
,
-
2.14754e+04
);
refforces
[
157
]
=
Vec3
(
2.17881e+05
,
-
1.85835e+05
,
-
1.05735e+05
);
refforces
[
158
]
=
Vec3
(
-
2.14191e+05
,
-
1.97454e+05
,
1.27176e+05
);
refforces
[
159
]
=
Vec3
(
-
3.33357e+05
,
-
1.38307e+04
,
-
1.17320e+05
);
refforces
[
160
]
=
Vec3
(
2.04157e+05
,
-
9.93173e+04
,
-
1.37945e+05
);
refforces
[
161
]
=
Vec3
(
1.29262e+05
,
1.13105e+05
,
2.55294e+05
);
refforces
[
162
]
=
Vec3
(
2.50185e+05
,
2.64217e+05
,
-
7.18219e+04
);
refforces
[
163
]
=
Vec3
(
-
2.46668e+05
,
1.94013e+04
,
-
9.97745e+04
);
refforces
[
164
]
=
Vec3
(
-
3.50266e+03
,
-
2.83658e+05
,
1.71598e+05
);
refforces
[
165
]
=
Vec3
(
-
2.05824e+05
,
2.71177e+05
,
-
1.16442e+05
);
refforces
[
166
]
=
Vec3
(
-
3.52163e+04
,
-
1.88897e+05
,
2.36923e+05
);
refforces
[
167
]
=
Vec3
(
2.41012e+05
,
-
8.22954e+04
,
-
1.20505e+05
);
refforces
[
168
]
=
Vec3
(
6.89329e+04
,
2.09489e+05
,
2.76583e+05
);
refforces
[
169
]
=
Vec3
(
1.87999e+05
,
-
1.61968e+05
,
-
1.24368e+05
);
refforces
[
170
]
=
Vec3
(
-
2.56932e+05
,
-
4.75793e+04
,
-
1.52255e+05
);
refforces
[
171
]
=
Vec3
(
3.39431e+05
,
-
5.75509e+04
,
1.62795e+05
);
refforces
[
172
]
=
Vec3
(
-
1.27767e+05
,
2.66184e+05
,
-
1.59709e+05
);
refforces
[
173
]
=
Vec3
(
-
2.11726e+05
,
-
2.08613e+05
,
-
3.11349e+03
);
refforces
[
174
]
=
Vec3
(
-
2.58601e+05
,
4.61975e+04
,
-
2.46016e+05
);
refforces
[
175
]
=
Vec3
(
7.15587e+04
,
-
2.52015e+05
,
1.40007e+05
);
refforces
[
176
]
=
Vec3
(
1.87109e+05
,
2.05820e+05
,
1.06028e+05
);
refforces
[
177
]
=
Vec3
(
3.92176e+03
,
2.94819e+05
,
-
1.84065e+05
);
refforces
[
178
]
=
Vec3
(
-
1.67230e+05
,
-
8.36141e+04
,
2.29167e+05
);
refforces
[
179
]
=
Vec3
(
1.63334e+05
,
-
2.11213e+05
,
-
4.50586e+04
);
refforces
[
180
]
=
Vec3
(
1.11151e+05
,
2.40551e+05
,
-
2.68210e+05
);
refforces
[
181
]
=
Vec3
(
-
1.76495e+05
,
-
2.47099e+05
,
-
3.53002e+04
);
refforces
[
182
]
=
Vec3
(
6.52872e+04
,
6.52855e+03
,
3.03586e+05
);
refforces
[
183
]
=
Vec3
(
-
4.84049e+04
,
-
2.73305e+05
,
-
2.95224e+05
);
refforces
[
184
]
=
Vec3
(
-
9.04206e+04
,
-
1.44672e+04
,
3.29135e+05
);
refforces
[
185
]
=
Vec3
(
1.38830e+05
,
2.87820e+05
,
-
3.38610e+04
);
refforces
[
186
]
=
Vec3
(
-
2.09072e+05
,
-
1.53610e+05
,
-
2.86654e+05
);
refforces
[
187
]
=
Vec3
(
-
1.30322e+05
,
9.09223e+04
,
2.42461e+05
);
refforces
[
188
]
=
Vec3
(
3.39380e+05
,
6.27113e+04
,
4.42669e+04
);
refforces
[
189
]
=
Vec3
(
-
3.15692e+05
,
1.48900e+05
,
-
9.20420e+04
);
refforces
[
190
]
=
Vec3
(
7.13687e+04
,
-
2.72503e+05
,
1.26518e+05
);
refforces
[
191
]
=
Vec3
(
2.44351e+05
,
1.23612e+05
,
-
3.44964e+04
);
refforces
[
192
]
=
Vec3
(
-
2.80727e+04
,
3.15077e+05
,
-
2.05427e+05
);
refforces
[
193
]
=
Vec3
(
-
2.29004e+05
,
-
2.08496e+05
,
9.57028e+04
);
refforces
[
194
]
=
Vec3
(
2.57096e+05
,
-
1.06603e+05
,
1.09738e+05
);
refforces
[
195
]
=
Vec3
(
3.33213e+05
,
-
7.80040e+04
,
-
5.04749e+03
);
refforces
[
196
]
=
Vec3
(
-
2.07680e+05
,
-
7.82574e+04
,
1.83605e+05
);
refforces
[
197
]
=
Vec3
(
-
1.25574e+05
,
1.56274e+05
,
-
1.78599e+05
);
refforces
[
198
]
=
Vec3
(
2.66795e+05
,
-
2.82879e+04
,
-
2.26620e+05
);
refforces
[
199
]
=
Vec3
(
-
2.28291e+05
,
-
1.82015e+05
,
4.01046e+04
);
refforces
[
200
]
=
Vec3
(
-
3.85027e+04
,
2.10288e+05
,
1.86592e+05
);
refforces
[
201
]
=
Vec3
(
1.93076e+05
,
2.05300e+05
,
2.64591e+05
);
refforces
[
202
]
=
Vec3
(
-
3.32259e+05
,
-
3.65117e+04
,
-
8.39768e+04
);
refforces
[
203
]
=
Vec3
(
1.39204e+05
,
-
1.68822e+05
,
-
1.80669e+05
);
refforces
[
204
]
=
Vec3
(
2.15422e+05
,
2.88264e+05
,
2.49786e+04
);
refforces
[
205
]
=
Vec3
(
4.29235e+04
,
-
2.66744e+05
,
1.13441e+05
);
refforces
[
206
]
=
Vec3
(
-
2.58339e+05
,
-
2.15280e+04
,
-
1.38395e+05
);
refforces
[
207
]
=
Vec3
(
3.27580e+05
,
-
4.93781e+04
,
7.43625e+03
);
refforces
[
208
]
=
Vec3
(
-
2.11622e+05
,
-
1.58716e+05
,
-
9.69925e+04
);
refforces
[
209
]
=
Vec3
(
-
1.15917e+05
,
2.08125e+05
,
8.95715e+04
);
refforces
[
210
]
=
Vec3
(
1.10967e+05
,
-
2.71544e+05
,
-
2.06279e+05
);
refforces
[
211
]
=
Vec3
(
-
8.86155e+04
,
1.96918e+04
,
2.98676e+05
);
refforces
[
212
]
=
Vec3
(
-
2.23913e+04
,
2.51912e+05
,
-
9.23690e+04
);
refforces
[
213
]
=
Vec3
(
1.91611e+05
,
-
7.99998e+04
,
-
2.83463e+05
);
refforces
[
214
]
=
Vec3
(
7.08725e+04
,
1.44963e+05
,
2.60941e+05
);
refforces
[
215
]
=
Vec3
(
-
2.62503e+05
,
-
6.49202e+04
,
2.25808e+04
);
refforces
[
216
]
=
Vec3
(
-
6.63168e+04
,
-
2.84265e+04
,
3.72700e+05
);
refforces
[
217
]
=
Vec3
(
-
2.02131e+05
,
-
6.33547e+04
,
-
1.96097e+05
);
refforces
[
218
]
=
Vec3
(
2.68466e+05
,
9.18414e+04
,
-
1.76621e+05
);
refforces
[
219
]
=
Vec3
(
-
6.80052e+03
,
2.72744e+05
,
-
2.21849e+05
);
refforces
[
220
]
=
Vec3
(
1.52709e+05
,
-
5.52356e+04
,
2.63181e+05
);
refforces
[
221
]
=
Vec3
(
-
1.45890e+05
,
-
2.17461e+05
,
-
4.12893e+04
);
refforces
[
222
]
=
Vec3
(
3.07522e+05
,
-
1.21146e+05
,
1.14593e+05
);
refforces
[
223
]
=
Vec3
(
-
2.11787e+05
,
-
1.56664e+05
,
-
8.99363e+04
);
refforces
[
224
]
=
Vec3
(
-
9.57076e+04
,
2.77857e+05
,
-
2.46987e+04
);
refforces
[
225
]
=
Vec3
(
-
3.24882e+05
,
-
3.09840e+04
,
-
1.31947e+05
);
refforces
[
226
]
=
Vec3
(
8.33124e+04
,
-
5.05809e+04
,
2.67793e+05
);
refforces
[
227
]
=
Vec3
(
2.41536e+05
,
8.15185e+04
,
-
1.35863e+05
);
refforces
[
228
]
=
Vec3
(
-
2.16561e+04
,
-
1.67607e+05
,
-
2.70252e+05
);
refforces
[
229
]
=
Vec3
(
1.10825e+05
,
-
7.29802e+04
,
2.24354e+05
);
refforces
[
230
]
=
Vec3
(
-
8.91995e+04
,
2.40572e+05
,
4.59512e+04
);
refforces
[
231
]
=
Vec3
(
-
2.22246e+05
,
1.96766e+05
,
-
2.46638e+05
);
refforces
[
232
]
=
Vec3
(
3.04748e+05
,
5.66971e+04
,
1.27568e+05
);
refforces
[
233
]
=
Vec3
(
-
8.24632e+04
,
-
2.53495e+05
,
1.19113e+05
);
refforces
[
234
]
=
Vec3
(
2.20621e+05
,
-
2.03896e+05
,
6.63128e+04
);
refforces
[
235
]
=
Vec3
(
-
9.59082e+04
,
1.64055e+05
,
1.53960e+05
);
refforces
[
236
]
=
Vec3
(
-
1.24758e+05
,
3.98170e+04
,
-
2.20320e+05
);
refforces
[
237
]
=
Vec3
(
-
7.79583e+03
,
-
3.49688e+04
,
3.64330e+05
);
refforces
[
238
]
=
Vec3
(
-
1.43293e+05
,
-
1.65580e+05
,
-
2.10163e+05
);
refforces
[
239
]
=
Vec3
(
1.51159e+05
,
2.00522e+05
,
-
1.54247e+05
);
refforces
[
240
]
=
Vec3
(
1.82058e+05
,
-
3.72909e+04
,
-
2.80373e+05
);
refforces
[
241
]
=
Vec3
(
-
1.95792e+05
,
1.98809e+05
,
7.22936e+04
);
refforces
[
242
]
=
Vec3
(
1.36910e+04
,
-
1.61546e+05
,
2.08094e+05
);
refforces
[
243
]
=
Vec3
(
1.40288e+05
,
3.27379e+05
,
4.78569e+03
);
refforces
[
244
]
=
Vec3
(
-
1.70016e+05
,
-
1.73349e+05
,
2.03353e+05
);
refforces
[
245
]
=
Vec3
(
2.97331e+04
,
-
1.54072e+05
,
-
2.08134e+05
);
refforces
[
246
]
=
Vec3
(
1.21932e+05
,
3.52267e+05
,
4.69291e+04
);
refforces
[
247
]
=
Vec3
(
-
2.91621e+05
,
-
1.24021e+05
,
3.01674e+04
);
refforces
[
248
]
=
Vec3
(
1.69673e+05
,
-
2.28288e+05
,
-
7.71238e+04
);
refforces
[
249
]
=
Vec3
(
-
1.41105e+05
,
1.52818e+05
,
2.59197e+05
);
refforces
[
250
]
=
Vec3
(
2.15511e+05
,
-
1.77650e+05
,
-
5.82442e+03
);
refforces
[
251
]
=
Vec3
(
-
7.43779e+04
,
2.47926e+04
,
-
2.53438e+05
);
refforces
[
252
]
=
Vec3
(
-
3.34214e+04
,
3.09554e+05
,
1.58194e+05
);
refforces
[
253
]
=
Vec3
(
-
2.05877e+05
,
-
1.71563e+05
,
-
6.00467e+04
);
refforces
[
254
]
=
Vec3
(
2.39329e+05
,
-
1.38076e+05
,
-
9.81875e+04
);
refforces
[
255
]
=
Vec3
(
1.32793e+05
,
-
3.72271e+05
,
2.88491e+04
);
refforces
[
256
]
=
Vec3
(
-
9.02633e+04
,
2.78646e+05
,
2.23700e+05
);
refforces
[
257
]
=
Vec3
(
-
4.25632e+04
,
9.36427e+04
,
-
2.52553e+05
);
refforces
[
258
]
=
Vec3
(
2.97252e+05
,
2.17294e+05
,
-
2.50945e+03
);
refforces
[
259
]
=
Vec3
(
-
1.35724e+05
,
-
1.48966e+05
,
2.41658e+05
);
refforces
[
260
]
=
Vec3
(
-
1.61536e+05
,
-
6.83423e+04
,
-
2.39199e+05
);
refforces
[
261
]
=
Vec3
(
2.50550e+05
,
-
1.39926e+05
,
2.48375e+05
);
refforces
[
262
]
=
Vec3
(
5.51783e+04
,
-
1.65530e+04
,
-
2.59341e+05
);
refforces
[
263
]
=
Vec3
(
-
3.05734e+05
,
1.56505e+05
,
1.09189e+04
);
refforces
[
264
]
=
Vec3
(
-
4.44616e+04
,
4.17040e+04
,
-
3.31507e+05
);
refforces
[
265
]
=
Vec3
(
-
1.79702e+05
,
-
8.54319e+04
,
2.00323e+05
);
refforces
[
266
]
=
Vec3
(
2.24182e+05
,
4.37421e+04
,
1.31227e+05
);
refforces
[
267
]
=
Vec3
(
-
9.89367e+04
,
-
3.76136e+05
,
2.17157e+04
);
refforces
[
268
]
=
Vec3
(
-
4.44424e+04
,
1.68244e+05
,
-
2.47606e+05
);
refforces
[
269
]
=
Vec3
(
1.43421e+05
,
2.07965e+05
,
2.25893e+05
);
refforces
[
270
]
=
Vec3
(
-
1.09030e+03
,
-
2.44686e+05
,
-
2.30145e+05
);
refforces
[
271
]
=
Vec3
(
-
1.86963e+05
,
1.89757e+05
,
3.34863e+04
);
refforces
[
272
]
=
Vec3
(
1.88003e+05
,
5.49541e+04
,
1.96680e+05
);
refforces
[
273
]
=
Vec3
(
-
1.15452e+05
,
-
1.55243e+05
,
2.81412e+05
);
refforces
[
274
]
=
Vec3
(
-
1.35893e+05
,
1.74355e+05
,
-
1.12817e+05
);
refforces
[
275
]
=
Vec3
(
2.51361e+05
,
-
1.90905e+04
,
-
1.68633e+05
);
refforces
[
276
]
=
Vec3
(
1.76202e+05
,
-
2.31601e+05
,
-
2.00886e+05
);
refforces
[
277
]
=
Vec3
(
-
2.96697e+05
,
3.00025e+04
,
1.06676e+05
);
refforces
[
278
]
=
Vec3
(
1.20457e+05
,
2.01635e+05
,
9.42700e+04
);
refforces
[
279
]
=
Vec3
(
-
1.66320e+05
,
-
9.08355e+02
,
2.65478e+05
);
refforces
[
280
]
=
Vec3
(
2.44823e+05
,
9.45895e+04
,
-
5.28589e+04
);
refforces
[
281
]
=
Vec3
(
-
7.84765e+04
,
-
9.36654e+04
,
-
2.12648e+05
);
refforces
[
282
]
=
Vec3
(
-
6.58002e+03
,
-
1.21918e+05
,
3.16459e+05
);
refforces
[
283
]
=
Vec3
(
2.15225e+05
,
5.96416e+04
,
-
1.14097e+05
);
refforces
[
284
]
=
Vec3
(
-
2.08615e+05
,
6.22725e+04
,
-
2.02387e+05
);
refforces
[
285
]
=
Vec3
(
7.09186e+04
,
1.83619e+05
,
2.71862e+05
);
refforces
[
286
]
=
Vec3
(
1.78911e+05
,
-
1.02234e+05
,
-
1.78910e+05
);
refforces
[
287
]
=
Vec3
(
-
2.49882e+05
,
-
8.13582e+04
,
-
9.29803e+04
);
refforces
[
288
]
=
Vec3
(
-
1.35529e+04
,
-
3.20226e+05
,
-
1.16293e+05
);
refforces
[
289
]
=
Vec3
(
2.28053e+05
,
1.65034e+05
,
5.70125e+04
);
refforces
[
290
]
=
Vec3
(
-
2.14515e+05
,
1.55237e+05
,
5.92732e+04
);
refforces
[
291
]
=
Vec3
(
-
2.65006e+05
,
1.75233e+05
,
1.91268e+05
);
refforces
[
292
]
=
Vec3
(
2.29905e+05
,
1.02940e+05
,
-
2.05886e+05
);
refforces
[
293
]
=
Vec3
(
3.51345e+04
,
-
2.78156e+05
,
1.46393e+04
);
refforces
[
294
]
=
Vec3
(
1.59458e+05
,
2.25128e+05
,
2.11611e+05
);
refforces
[
295
]
=
Vec3
(
1.24813e+05
,
-
1.16492e+05
,
-
2.05249e+05
);
refforces
[
296
]
=
Vec3
(
-
2.84281e+05
,
-
1.08601e+05
,
-
6.38824e+03
);
refforces
[
297
]
=
Vec3
(
2.61767e+05
,
-
7.55993e+04
,
-
2.32576e+05
);
refforces
[
298
]
=
Vec3
(
-
2.07803e+05
,
-
1.78116e+05
,
7.71831e+04
);
refforces
[
299
]
=
Vec3
(
-
5.39242e+04
,
2.53755e+05
,
1.55427e+05
);
refforces
[
300
]
=
Vec3
(
-
6.44117e+03
,
2.31328e+05
,
-
2.54922e+05
);
refforces
[
301
]
=
Vec3
(
-
2.61097e+04
,
4.93208e+04
,
2.72709e+05
);
refforces
[
302
]
=
Vec3
(
3.25053e+04
,
-
2.80718e+05
,
-
1.77304e+04
);
refforces
[
303
]
=
Vec3
(
7.06280e+04
,
7.26140e+04
,
3.28446e+05
);
refforces
[
304
]
=
Vec3
(
1.45890e+05
,
7.98271e+04
,
-
2.06449e+05
);
refforces
[
305
]
=
Vec3
(
-
2.16516e+05
,
-
1.52473e+05
,
-
1.21980e+05
);
refforces
[
306
]
=
Vec3
(
1.94879e+05
,
-
2.83084e+05
,
1.41824e+05
);
refforces
[
307
]
=
Vec3
(
-
2.57149e+05
,
1.96432e+05
,
9.64284e+04
);
refforces
[
308
]
=
Vec3
(
6.22633e+04
,
8.66280e+04
,
-
2.38228e+05
);
refforces
[
309
]
=
Vec3
(
3.26456e+04
,
1.17141e+05
,
-
3.28374e+05
);
refforces
[
310
]
=
Vec3
(
2.01298e+05
,
-
1.11486e+05
,
1.85810e+05
);
refforces
[
311
]
=
Vec3
(
-
2.33937e+05
,
-
5.70482e+03
,
1.42641e+05
);
refforces
[
312
]
=
Vec3
(
6.42964e+04
,
1.88719e+05
,
-
2.86572e+05
);
refforces
[
313
]
=
Vec3
(
1.22184e+05
,
-
2.53768e+05
,
1.00254e+05
);
refforces
[
314
]
=
Vec3
(
-
1.86433e+05
,
6.49694e+04
,
1.86429e+05
);
refforces
[
315
]
=
Vec3
(
-
4.12317e+04
,
-
1.73607e+04
,
-
3.68620e+05
);
refforces
[
316
]
=
Vec3
(
-
1.78981e+05
,
1.43186e+05
,
2.08269e+05
);
refforces
[
317
]
=
Vec3
(
2.20155e+05
,
-
1.25802e+05
,
1.60395e+05
);
refforces
[
318
]
=
Vec3
(
-
1.58613e+05
,
3.01594e+05
,
-
1.29345e+05
);
refforces
[
319
]
=
Vec3
(
2.79698e+05
,
-
2.67790e+04
,
4.76063e+04
);
refforces
[
320
]
=
Vec3
(
-
1.21063e+05
,
-
2.74847e+05
,
8.17976e+04
);
refforces
[
321
]
=
Vec3
(
1.00451e+05
,
2.03427e+05
,
-
2.75044e+05
);
refforces
[
322
]
=
Vec3
(
-
2.13956e+04
,
7.64144e+04
,
2.81199e+05
);
refforces
[
323
]
=
Vec3
(
-
7.91039e+04
,
-
2.79910e+05
,
-
6.08590e+03
);
refforces
[
324
]
=
Vec3
(
-
2.80664e+05
,
5.26142e+04
,
-
1.53706e+05
);
refforces
[
325
]
=
Vec3
(
2.23923e+05
,
-
1.17559e+05
,
-
9.23685e+04
);
refforces
[
326
]
=
Vec3
(
5.68062e+04
,
6.49218e+04
,
2.46158e+05
);
refforces
[
327
]
=
Vec3
(
2.88911e+05
,
-
1.17893e+05
,
-
7.40828e+04
);
refforces
[
328
]
=
Vec3
(
-
6.38612e+04
,
2.37565e+05
,
-
2.55450e+04
);
refforces
[
329
]
=
Vec3
(
-
2.25033e+05
,
-
1.19637e+05
,
9.96952e+04
);
refforces
[
330
]
=
Vec3
(
1.03510e+04
,
7.35559e+04
,
3.47129e+05
);
refforces
[
331
]
=
Vec3
(
1.26778e+05
,
-
2.19542e+05
,
-
1.51515e+05
);
refforces
[
332
]
=
Vec3
(
-
1.37190e+05
,
1.45950e+05
,
-
1.95573e+05
);
refforces
[
333
]
=
Vec3
(
-
1.31816e+05
,
5.57951e+04
,
-
2.81935e+05
);
refforces
[
334
]
=
Vec3
(
-
1.08367e+05
,
-
9.75306e+04
,
2.16731e+05
);
refforces
[
335
]
=
Vec3
(
2.40191e+05
,
4.17715e+04
,
6.52667e+04
);
refforces
[
336
]
=
Vec3
(
-
2.86680e+05
,
-
2.63007e+05
,
1.37964e+04
);
refforces
[
337
]
=
Vec3
(
1.03914e+05
,
1.76653e+05
,
-
2.56324e+05
);
refforces
[
338
]
=
Vec3
(
1.82779e+05
,
8.64040e+04
,
2.42594e+05
);
refforces
[
339
]
=
Vec3
(
1.09800e+03
,
-
3.11636e+05
,
1.85833e+05
);
refforces
[
340
]
=
Vec3
(
-
2.39750e+05
,
1.52568e+05
,
-
8.71817e+04
);
refforces
[
341
]
=
Vec3
(
2.38635e+05
,
1.59089e+05
,
-
9.86351e+04
);
refforces
[
342
]
=
Vec3
(
-
8.76706e+04
,
-
6.10520e+04
,
3.31680e+05
);
refforces
[
343
]
=
Vec3
(
2.64692e+05
,
5.23233e+04
,
-
1.16959e+05
);
refforces
[
344
]
=
Vec3
(
-
1.76973e+05
,
8.70353e+03
,
-
2.14689e+05
);
refforces
[
345
]
=
Vec3
(
-
1.15976e+05
,
-
2.72303e+05
,
-
1.33307e+05
);
refforces
[
346
]
=
Vec3
(
2.20682e+05
,
1.51896e+05
,
-
6.30516e+04
);
refforces
[
347
]
=
Vec3
(
-
1.04744e+05
,
1.20457e+05
,
1.96395e+05
);
refforces
[
348
]
=
Vec3
(
4.57064e+04
,
3.43550e+05
,
7.23245e+04
);
refforces
[
349
]
=
Vec3
(
-
1.91414e+05
,
-
1.26580e+05
,
-
1.85241e+05
);
refforces
[
350
]
=
Vec3
(
1.45684e+05
,
-
2.17040e+05
,
1.12977e+05
);
refforces
[
351
]
=
Vec3
(
-
1.88623e+05
,
-
1.22936e+04
,
3.10223e+05
);
refforces
[
352
]
=
Vec3
(
3.06931e+05
,
5.73380e+04
,
-
7.08300e+04
);
refforces
[
353
]
=
Vec3
(
-
1.18279e+05
,
-
4.50586e+04
,
-
2.39376e+05
);
refforces
[
354
]
=
Vec3
(
8.31603e+04
,
-
2.75958e+05
,
1.16877e+05
);
refforces
[
355
]
=
Vec3
(
-
2.08784e+05
,
1.26300e+05
,
5.15494e+04
);
refforces
[
356
]
=
Vec3
(
1.25608e+05
,
1.49661e+05
,
-
1.68370e+05
);
refforces
[
357
]
=
Vec3
(
1.44100e+05
,
-
2.34453e+05
,
1.73916e+05
);
refforces
[
358
]
=
Vec3
(
-
8.65072e+04
,
2.39988e+05
,
8.37141e+04
);
refforces
[
359
]
=
Vec3
(
-
5.75432e+04
,
-
5.48037e+03
,
-
2.57574e+05
);
refforces
[
360
]
=
Vec3
(
2.72504e+05
,
2.99781e+04
,
1.85778e+05
);
refforces
[
361
]
=
Vec3
(
-
3.41026e+04
,
7.10483e+04
,
-
2.61466e+05
);
refforces
[
362
]
=
Vec3
(
-
2.38458e+05
,
-
1.00996e+05
,
7.57451e+04
);
refforces
[
363
]
=
Vec3
(
1.45826e+05
,
-
2.81284e+05
,
1.15502e+05
);
refforces
[
364
]
=
Vec3
(
-
2.63407e+05
,
3.47332e+04
,
-
8.10477e+04
);
refforces
[
365
]
=
Vec3
(
1.17594e+05
,
2.46657e+05
,
-
3.44181e+04
);
refforces
[
366
]
=
Vec3
(
2.59381e+05
,
-
5.73297e+04
,
2.56690e+05
);
refforces
[
367
]
=
Vec3
(
-
1.25834e+05
,
-
2.09725e+05
,
-
1.49803e+05
);
refforces
[
368
]
=
Vec3
(
-
1.33554e+05
,
2.67105e+05
,
-
1.06844e+05
);
refforces
[
369
]
=
Vec3
(
7.18473e+04
,
-
2.59021e+05
,
1.89797e+05
);
refforces
[
370
]
=
Vec3
(
1.56664e+05
,
2.11783e+05
,
-
8.99369e+04
);
refforces
[
371
]
=
Vec3
(
-
2.28511e+05
,
4.72761e+04
,
-
9.98083e+04
);
refforces
[
372
]
=
Vec3
(
-
1.99083e+04
,
3.17042e+05
,
-
5.62792e+04
);
refforces
[
373
]
=
Vec3
(
-
1.96875e+05
,
-
1.64948e+05
,
-
7.96758e-01
);
refforces
[
374
]
=
Vec3
(
2.16840e+05
,
-
1.52072e+05
,
5.63215e+04
);
const
double
longcutoff
=
30.0
*
OpenMM
::
NmPerAngstrom
;
const
double
longcutoff2
=
longcutoff
*
longcutoff
;
const
double
cutoff2
=
cutoff
*
cutoff
;
const
double
cutoff6inv
=
1.0
/
(
cutoff2
*
cutoff2
*
cutoff2
);
const
int
nboxes
=
ceil
(
longcutoff
/
boxEdgeLength
);
double
refenergy
=
0.0
;
// Loop over home box first...
for
(
int
i
=
0
;
i
<
numAtoms
;
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
++
j
)
{
Vec3
dR
=
positions
[
i
]
-
positions
[
j
];
double
R2
=
dR
[
0
]
*
dR
[
0
]
+
dR
[
1
]
*
dR
[
1
]
+
dR
[
2
]
*
dR
[
2
];
double
sig2
=
(
sigvals
[
i
]
+
sigvals
[
j
])
*
(
sigvals
[
i
]
+
sigvals
[
j
])
/
R2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
double
eps
=
epsvals
[
i
]
*
epsvals
[
j
];
refenergy
+=
2.0
*
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
R2
<
cutoff2
)
{
// Add a shift term for direct space parts withing t
refenergy
+=
2.0
*
eps
*
(
pow
(
sigvals
[
i
]
+
sigvals
[
j
],
6
)
-
64.0
*
pow
(
sigvals
[
i
]
*
sigvals
[
j
],
3
))
*
cutoff6inv
;
}
}
}
// ... and now add in the image box terms
for
(
int
bx
=
-
nboxes
;
bx
<=
nboxes
;
++
bx
)
{
for
(
int
by
=
-
nboxes
;
by
<=
nboxes
;
++
by
)
{
for
(
int
bz
=
-
nboxes
;
bz
<=
nboxes
;
++
bz
)
{
if
(
bx
==
0
&&
by
==
0
&&
bz
==
0
)
continue
;
Vec3
offset
(
bx
*
boxEdgeLength
,
by
*
boxEdgeLength
,
bz
*
boxEdgeLength
);
for
(
int
i
=
0
;
i
<
numAtoms
;
++
i
)
{
for
(
int
j
=
0
;
j
<
numAtoms
;
++
j
)
{
Vec3
dR
=
positions
[
i
]
-
positions
[
j
]
+
offset
;
double
R2
=
dR
[
0
]
*
dR
[
0
]
+
dR
[
1
]
*
dR
[
1
]
+
dR
[
2
]
*
dR
[
2
];
if
(
R2
>
longcutoff2
)
continue
;
double
sig2
=
(
sigvals
[
i
]
+
sigvals
[
j
])
*
(
sigvals
[
i
]
+
sigvals
[
j
])
/
R2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
double
eps
=
epsvals
[
i
]
*
epsvals
[
j
];
refenergy
+=
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
R2
<
cutoff2
)
{
// Add a shift term for direct space parts withing teh
refenergy
+=
eps
*
(
pow
(
sigvals
[
i
]
+
sigvals
[
j
],
6
)
-
64.0
*
pow
(
sigvals
[
i
]
*
sigvals
[
j
],
3
))
*
cutoff6inv
;
}
}
}
}
}
}
refenergy
*=
0.5
;
// For this test the reference energy is 545636 kJ/mol, while the difference between DPME and 30A cutoffs
// is just 1.062 kJ/mol. The difference is due to the fact that arithmetic mean combination rules are used
// up to the cutoff, while the reciprocal space uses the geometric mean. See DOI: 10.1021/acs.jctc.5b00726
ASSERT_EQUAL_TOL
(
refenergy
,
energy
,
5E-6
);
ASSERT_EQUAL_TOL
(
gromacs_energy
,
energy
,
5E-4
);
for
(
int
n
=
0
;
n
<
numAtoms
;
++
n
)
ASSERT_EQUAL_VEC
(
refforces
[
n
],
forces
[
n
],
5E-4
);
}
void
testWater125DpmeVsLongCutoffWithExclusions
()
{
const
double
cutoff
=
11.5
*
OpenMM
::
NmPerAngstrom
;
const
double
alpha
=
0.45
*
OpenMM
::
AngstromsPerNm
;
const
double
dalpha
=
4.2760443169
;
const
int
grid
=
60
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
double
>
epsvals
;
vector
<
double
>
sigvals
;
vector
<
pair
<
int
,
int
>
>
bonds
;
System
system
;
const
int
numAtoms
=
375
;
double
boxEdgeLength
=
23.01
*
OpenMM
::
NmPerAngstrom
;
make_waterbox
(
numAtoms
,
boxEdgeLength
,
forceField
,
positions
,
epsvals
,
sigvals
,
bonds
,
system
,
false
);
forceField
->
setNonbondedMethod
(
OpenMM
::
NonbondedForce
::
LJPME
);
forceField
->
createExceptionsFromBonds
(
bonds
,
1.0
,
1.0
);
forceField
->
setPMEParameters
(
alpha
,
grid
,
grid
,
grid
);
forceField
->
setLJPMEParameters
(
dalpha
,
grid
,
grid
,
grid
);
forceField
->
setCutoffDistance
(
cutoff
);
forceField
->
setReactionFieldDielectric
(
1.0
);
system
.
addForce
(
forceField
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
double
energy
=
state
.
getPotentialEnergy
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
// Gromacs reference values. See comments in testWater2DpmeEnergiesForcesNoExclusions() for details.
double
gromacs_energy
=
-
2.17481e+02
;
vector
<
Vec3
>
refforces
(
numAtoms
);
refforces
[
0
]
=
Vec3
(
-
3.10130e+01
,
-
6.01219e+01
,
-
5.31302e+01
);
refforces
[
1
]
=
Vec3
(
4.21376e+00
,
9.13811e-01
,
9.61319e-01
);
refforces
[
2
]
=
Vec3
(
1.42363e+00
,
2.97219e+00
,
1.27185e+00
);
refforces
[
3
]
=
Vec3
(
-
3.70172e+01
,
-
2.95228e+01
,
-
6.27987e+01
);
refforces
[
4
]
=
Vec3
(
-
6.57386e-01
,
2.39279e+00
,
1.53243e+00
);
refforces
[
5
]
=
Vec3
(
-
1.61426e+00
,
7.11728e-01
,
9.99752e-01
);
refforces
[
6
]
=
Vec3
(
1.60813e+01
,
-
6.77979e+01
,
-
1.01302e+02
);
refforces
[
7
]
=
Vec3
(
-
4.23118e+00
,
9.25550e-01
,
1.28003e+00
);
refforces
[
8
]
=
Vec3
(
1.81589e+00
,
1.10083e+00
,
1.28615e+00
);
refforces
[
9
]
=
Vec3
(
-
2.24427e+00
,
-
5.71071e+01
,
-
3.18064e+01
);
refforces
[
10
]
=
Vec3
(
3.41715e+00
,
1.32918e+00
,
1.27908e+00
);
refforces
[
11
]
=
Vec3
(
-
3.09930e+00
,
9.91868e-01
,
1.69245e+00
);
refforces
[
12
]
=
Vec3
(
6.08033e+01
,
-
1.02990e+02
,
-
8.26733e+01
);
refforces
[
13
]
=
Vec3
(
-
1.01346e+00
,
1.35475e+00
,
4.13725e+00
);
refforces
[
14
]
=
Vec3
(
-
6.71645e-01
,
4.69536e-01
,
4.64774e-01
);
refforces
[
15
]
=
Vec3
(
-
6.39056e+01
,
-
9.85756e-01
,
-
4.97837e+01
);
refforces
[
16
]
=
Vec3
(
9.97113e-01
,
1.13195e-01
,
4.49387e+00
);
refforces
[
17
]
=
Vec3
(
9.48864e-01
,
4.22217e+00
,
1.56364e+00
);
refforces
[
18
]
=
Vec3
(
2.18124e+01
,
-
6.14078e+01
,
-
8.10129e+01
);
refforces
[
19
]
=
Vec3
(
-
5.59701e-01
,
-
1.47528e+00
,
1.40157e+00
);
refforces
[
20
]
=
Vec3
(
4.29539e+00
,
4.27738e-02
,
1.03009e+00
);
refforces
[
21
]
=
Vec3
(
-
2.62377e+01
,
2.55532e+01
,
-
6.89576e+01
);
refforces
[
22
]
=
Vec3
(
1.17222e-01
,
3.81618e+00
,
1.74502e+00
);
refforces
[
23
]
=
Vec3
(
1.46448e-01
,
1.06214e-01
,
4.27946e+00
);
refforces
[
24
]
=
Vec3
(
-
1.90819e+00
,
9.86513e+00
,
-
1.05364e+02
);
refforces
[
25
]
=
Vec3
(
-
1.18537e+00
,
1.75021e+00
,
1.54448e+00
);
refforces
[
26
]
=
Vec3
(
2.96182e+00
,
-
9.48323e-01
,
1.61299e+00
);
refforces
[
27
]
=
Vec3
(
5.61257e+01
,
7.69427e+01
,
-
5.84534e+01
);
refforces
[
28
]
=
Vec3
(
-
8.11821e-01
,
-
7.15455e-01
,
6.60049e-01
);
refforces
[
29
]
=
Vec3
(
-
9.20901e-01
,
3.76217e+00
,
1.35685e+00
);
refforces
[
30
]
=
Vec3
(
-
5.03791e+01
,
2.24324e+01
,
-
4.31606e+01
);
refforces
[
31
]
=
Vec3
(
3.72530e+00
,
3.48275e-01
,
1.40060e+00
);
refforces
[
32
]
=
Vec3
(
7.61265e-01
,
8.56416e-01
,
6.23359e-01
);
refforces
[
33
]
=
Vec3
(
1.95683e+01
,
4.16950e+01
,
-
4.33266e+01
);
refforces
[
34
]
=
Vec3
(
-
2.19677e+00
,
1.06287e+00
,
1.58260e+00
);
refforces
[
35
]
=
Vec3
(
1.70923e+00
,
2.09511e+00
,
9.84492e-01
);
refforces
[
36
]
=
Vec3
(
-
7.84273e+01
,
-
3.34396e+01
,
-
3.66486e+01
);
refforces
[
37
]
=
Vec3
(
-
1.53567e-01
,
1.74934e-01
,
1.15266e+00
);
refforces
[
38
]
=
Vec3
(
-
3.45548e+00
,
1.68633e-01
,
1.15923e+00
);
refforces
[
39
]
=
Vec3
(
6.90725e+01
,
-
2.09426e+01
,
-
5.31532e+01
);
refforces
[
40
]
=
Vec3
(
1.33274e+00
,
3.09504e-01
,
1.40065e+00
);
refforces
[
41
]
=
Vec3
(
1.65828e+00
,
-
1.96378e-01
,
2.68350e+00
);
refforces
[
42
]
=
Vec3
(
3.39954e+01
,
-
2.65418e+01
,
-
6.81184e+01
);
refforces
[
43
]
=
Vec3
(
-
1.17491e+00
,
-
2.88793e+00
,
1.40541e+00
);
refforces
[
44
]
=
Vec3
(
-
9.63132e-01
,
-
3.78178e-01
,
1.06756e+00
);
refforces
[
45
]
=
Vec3
(
-
4.44610e+01
,
-
1.81736e+01
,
-
6.19409e+01
);
refforces
[
46
]
=
Vec3
(
1.48529e+00
,
8.95548e-06
,
4.60732e+00
);
refforces
[
47
]
=
Vec3
(
1.00451e+00
,
-
3.88830e+00
,
1.27726e+00
);
refforces
[
48
]
=
Vec3
(
-
4.23022e+00
,
2.52963e+01
,
-
3.04756e+01
);
refforces
[
49
]
=
Vec3
(
-
3.45228e+00
,
7.61191e-01
,
9.40731e-01
);
refforces
[
50
]
=
Vec3
(
2.78622e+00
,
8.32081e-01
,
1.37588e+00
);
refforces
[
51
]
=
Vec3
(
1.63360e+01
,
3.02230e+01
,
-
3.91446e+01
);
refforces
[
52
]
=
Vec3
(
-
2.64761e+00
,
1.18509e+00
,
9.81393e-01
);
refforces
[
53
]
=
Vec3
(
1.74883e+00
,
-
1.51958e-01
,
2.56504e+00
);
refforces
[
54
]
=
Vec3
(
-
3.01111e+01
,
4.08021e+01
,
-
3.45058e+01
);
refforces
[
55
]
=
Vec3
(
-
1.17129e-01
,
9.74282e-02
,
4.56402e+00
);
refforces
[
56
]
=
Vec3
(
-
3.03696e+00
,
4.44012e-01
,
1.44269e+00
);
refforces
[
57
]
=
Vec3
(
7.57956e+01
,
-
1.12043e+01
,
-
3.92084e+01
);
refforces
[
58
]
=
Vec3
(
-
1.55617e+00
,
2.26444e-01
,
2.88234e+00
);
refforces
[
59
]
=
Vec3
(
-
1.37287e+00
,
-
3.79045e+00
,
8.55326e-01
);
refforces
[
60
]
=
Vec3
(
-
2.88831e+01
,
5.72484e+01
,
-
7.17030e+01
);
refforces
[
61
]
=
Vec3
(
6.88458e-01
,
-
2.06343e+00
,
1.03552e+00
);
refforces
[
62
]
=
Vec3
(
6.94194e-01
,
-
1.83673e+00
,
2.90979e+00
);
refforces
[
63
]
=
Vec3
(
-
7.87489e+01
,
2.17729e+01
,
-
3.72371e+01
);
refforces
[
64
]
=
Vec3
(
1.39267e-01
,
-
4.55150e+00
,
9.53893e-01
);
refforces
[
65
]
=
Vec3
(
-
4.27928e+00
,
-
1.14139e+00
,
9.25405e-01
);
refforces
[
66
]
=
Vec3
(
7.13947e+01
,
3.02722e+01
,
-
5.16551e+01
);
refforces
[
67
]
=
Vec3
(
4.07933e+00
,
-
1.28199e+00
,
9.34707e-01
);
refforces
[
68
]
=
Vec3
(
-
7.53668e-02
,
-
2.14888e+00
,
1.27713e+00
);
refforces
[
69
]
=
Vec3
(
-
9.36762e+00
,
2.98321e+01
,
-
5.70761e+01
);
refforces
[
70
]
=
Vec3
(
1.35989e+00
,
-
3.09988e+00
,
9.89945e-01
);
refforces
[
71
]
=
Vec3
(
-
2.20314e+00
,
-
7.81892e-01
,
1.21781e+00
);
refforces
[
72
]
=
Vec3
(
4.89194e+01
,
7.40749e+01
,
-
4.22017e+01
);
refforces
[
73
]
=
Vec3
(
-
4.25696e+00
,
-
1.18954e+00
,
1.04383e+00
);
refforces
[
74
]
=
Vec3
(
-
1.40510e+00
,
-
9.87719e-01
,
3.30559e+00
);
refforces
[
75
]
=
Vec3
(
-
4.95912e+01
,
-
8.24838e+01
,
-
1.82510e+01
);
refforces
[
76
]
=
Vec3
(
7.39933e-01
,
9.29483e-01
,
-
1.09883e+00
);
refforces
[
77
]
=
Vec3
(
9.70359e-01
,
1.03012e+00
,
4.01759e+00
);
refforces
[
78
]
=
Vec3
(
-
7.87499e+00
,
-
1.87981e+01
,
5.77017e+00
);
refforces
[
79
]
=
Vec3
(
3.82847e+00
,
1.01191e+00
,
-
7.30715e-02
);
refforces
[
80
]
=
Vec3
(
-
2.64831e+00
,
1.68402e+00
,
1.06474e-01
);
refforces
[
81
]
=
Vec3
(
1.81335e+01
,
-
6.72766e+01
,
7.21397e+01
);
refforces
[
82
]
=
Vec3
(
-
1.89188e-01
,
1.27803e+00
,
8.45103e-01
);
refforces
[
83
]
=
Vec3
(
2.47584e+00
,
1.54044e+00
,
6.55440e-01
);
refforces
[
84
]
=
Vec3
(
-
1.05824e+00
,
-
6.50833e+01
,
-
3.88413e+01
);
refforces
[
85
]
=
Vec3
(
-
3.21762e+00
,
1.58809e+00
,
-
1.32879e-01
);
refforces
[
86
]
=
Vec3
(
3.30285e+00
,
1.52154e+00
,
-
3.56471e-01
);
refforces
[
87
]
=
Vec3
(
4.41972e+01
,
-
3.58815e+01
,
4.01227e+01
);
refforces
[
88
]
=
Vec3
(
-
1.22923e+00
,
8.91826e-01
,
2.84505e+00
);
refforces
[
89
]
=
Vec3
(
-
4.31649e+00
,
1.00895e+00
,
4.43366e-01
);
refforces
[
90
]
=
Vec3
(
-
3.65176e+01
,
4.86616e+01
,
-
6.44163e+00
);
refforces
[
91
]
=
Vec3
(
1.03989e+00
,
3.91910e+00
,
7.93373e-01
);
refforces
[
92
]
=
Vec3
(
4.11089e+00
,
-
4.60733e-01
,
-
7.78461e-02
);
refforces
[
93
]
=
Vec3
(
-
1.58332e+01
,
-
6.82045e+01
,
6.62934e+01
);
refforces
[
94
]
=
Vec3
(
-
7.75645e-02
,
-
3.66897e+00
,
-
3.55044e-01
);
refforces
[
95
]
=
Vec3
(
4.08399e-01
,
2.84950e-01
,
3.80641e+00
);
refforces
[
96
]
=
Vec3
(
-
5.05975e+00
,
4.20346e+01
,
3.49518e+01
);
refforces
[
97
]
=
Vec3
(
9.82673e-01
,
2.64451e+00
,
4.02971e-01
);
refforces
[
98
]
=
Vec3
(
-
1.24992e+00
,
-
3.34479e-01
,
1.95012e+00
);
refforces
[
99
]
=
Vec3
(
2.31815e+00
,
-
2.30056e+00
,
6.49918e+01
);
refforces
[
100
]
=
Vec3
(
-
2.16986e+00
,
-
1.05184e-01
,
1.89395e+00
);
refforces
[
101
]
=
Vec3
(
3.51302e+00
,
1.83706e-01
,
7.08534e-01
);
refforces
[
102
]
=
Vec3
(
4.46929e+01
,
-
7.11604e+01
,
-
6.62201e+00
);
refforces
[
103
]
=
Vec3
(
-
1.87730e+00
,
-
1.10206e+00
,
-
1.47504e+00
);
refforces
[
104
]
=
Vec3
(
-
1.41639e+00
,
-
1.36347e+00
,
6.10811e-01
);
refforces
[
105
]
=
Vec3
(
-
3.12256e+01
,
-
1.73923e+01
,
-
4.47428e+01
);
refforces
[
106
]
=
Vec3
(
7.92004e-01
,
-
1.39066e+00
,
-
2.68309e+00
);
refforces
[
107
]
=
Vec3
(
1.54891e+00
,
2.50018e+00
,
-
6.21395e-01
);
refforces
[
108
]
=
Vec3
(
-
3.83585e+01
,
3.90231e+01
,
-
3.68876e+01
);
refforces
[
109
]
=
Vec3
(
1.86446e-01
,
3.49120e+00
,
-
4.00101e-01
);
refforces
[
110
]
=
Vec3
(
-
4.05592e+00
,
-
2.21609e-01
,
2.13257e-01
);
refforces
[
111
]
=
Vec3
(
5.70991e+01
,
-
5.95502e+01
,
-
4.08285e+01
);
refforces
[
112
]
=
Vec3
(
-
4.25039e-01
,
-
3.96206e-01
,
-
3.23550e+00
);
refforces
[
113
]
=
Vec3
(
4.14811e+00
,
-
1.47859e-01
,
1.11071e-01
);
refforces
[
114
]
=
Vec3
(
-
2.74979e+01
,
4.40260e+01
,
3.06766e+00
);
refforces
[
115
]
=
Vec3
(
2.22804e-01
,
3.48934e+00
,
-
1.96162e-01
);
refforces
[
116
]
=
Vec3
(
-
4.21754e+00
,
1.18655e-01
,
3.36974e-01
);
refforces
[
117
]
=
Vec3
(
6.32783e+01
,
8.02719e+01
,
1.38219e+01
);
refforces
[
118
]
=
Vec3
(
-
1.49058e+00
,
1.87045e+00
,
-
1.32164e-01
);
refforces
[
119
]
=
Vec3
(
-
2.30776e+00
,
1.73240e-01
,
1.92445e+00
);
refforces
[
120
]
=
Vec3
(
-
4.04272e+01
,
-
1.77143e+01
,
1.57461e+01
);
refforces
[
121
]
=
Vec3
(
1.82378e+00
,
2.60376e+00
,
2.33866e-01
);
refforces
[
122
]
=
Vec3
(
1.33379e+00
,
-
1.16675e+00
,
3.34265e+00
);
refforces
[
123
]
=
Vec3
(
-
8.78170e+00
,
1.35313e+01
,
-
5.40700e+01
);
refforces
[
124
]
=
Vec3
(
-
2.72817e+00
,
3.27413e-01
,
-
6.95012e-01
);
refforces
[
125
]
=
Vec3
(
2.41935e+00
,
-
2.66049e-01
,
-
1.62940e+00
);
refforces
[
126
]
=
Vec3
(
-
3.63273e+01
,
6.91610e+01
,
-
3.72663e+00
);
refforces
[
127
]
=
Vec3
(
-
1.40546e+00
,
7.48503e-01
,
-
9.73230e-01
);
refforces
[
128
]
=
Vec3
(
5.39530e-01
,
8.56302e-01
,
2.57617e+00
);
refforces
[
129
]
=
Vec3
(
2.54426e+01
,
-
5.04169e+01
,
-
1.76229e+01
);
refforces
[
130
]
=
Vec3
(
6.82595e-01
,
-
3.17362e+00
,
2.20610e-01
);
refforces
[
131
]
=
Vec3
(
1.94539e+00
,
1.53325e+00
,
-
4.24624e-01
);
refforces
[
132
]
=
Vec3
(
3.61678e+01
,
-
7.89030e+01
,
-
9.61808e+00
);
refforces
[
133
]
=
Vec3
(
-
1.29295e+00
,
-
1.55223e+00
,
-
1.88241e+00
);
refforces
[
134
]
=
Vec3
(
-
1.51438e+00
,
3.14594e-02
,
3.60043e+00
);
refforces
[
135
]
=
Vec3
(
-
4.60860e+01
,
6.18971e+01
,
1.38188e+01
);
refforces
[
136
]
=
Vec3
(
3.07506e+00
,
-
9.60659e-01
,
1.81485e+00
);
refforces
[
137
]
=
Vec3
(
6.46515e-01
,
-
7.30203e-01
,
-
2.17471e-01
);
refforces
[
138
]
=
Vec3
(
7.76539e+00
,
3.18751e+01
,
-
6.18739e+01
);
refforces
[
139
]
=
Vec3
(
-
2.12790e+00
,
-
1.06577e+00
,
-
1.03098e+00
);
refforces
[
140
]
=
Vec3
(
3.70469e+00
,
-
7.70591e-01
,
-
2.00619e-01
);
refforces
[
141
]
=
Vec3
(
-
4.02748e+01
,
1.93804e+01
,
1.92911e+01
);
refforces
[
142
]
=
Vec3
(
5.74429e-01
,
-
1.58840e+00
,
-
2.07083e+00
);
refforces
[
143
]
=
Vec3
(
-
4.21689e+00
,
-
7.25280e-01
,
1.61839e-01
);
refforces
[
144
]
=
Vec3
(
4.10890e+01
,
6.50772e+01
,
-
6.64661e+00
);
refforces
[
145
]
=
Vec3
(
2.02022e-01
,
-
1.46124e+00
,
1.99785e+00
);
refforces
[
146
]
=
Vec3
(
1.91733e-01
,
-
1.14906e+00
,
-
4.18291e+00
);
refforces
[
147
]
=
Vec3
(
3.77785e+01
,
1.01191e+02
,
-
6.07436e+00
);
refforces
[
148
]
=
Vec3
(
-
1.03030e+00
,
-
1.26650e+00
,
3.57188e+00
);
refforces
[
149
]
=
Vec3
(
-
7.42295e-01
,
-
1.05437e+00
,
-
1.47491e+00
);
refforces
[
150
]
=
Vec3
(
-
7.40150e+01
,
-
3.53477e+01
,
1.81946e+01
);
refforces
[
151
]
=
Vec3
(
1.65267e+00
,
1.39873e+00
,
1.46780e+00
);
refforces
[
152
]
=
Vec3
(
1.18632e+00
,
2.66165e+00
,
1.61236e+00
);
refforces
[
153
]
=
Vec3
(
3.89536e+01
,
-
2.96071e+01
,
-
1.38610e+01
);
refforces
[
154
]
=
Vec3
(
2.05061e+00
,
1.54050e+00
,
5.35476e-01
);
refforces
[
155
]
=
Vec3
(
4.98336e-01
,
3.85036e+00
,
4.21301e-01
);
refforces
[
156
]
=
Vec3
(
-
5.53456e+01
,
-
6.87157e+01
,
-
3.55693e+01
);
refforces
[
157
]
=
Vec3
(
3.17070e+00
,
1.65800e+00
,
-
3.99476e-01
);
refforces
[
158
]
=
Vec3
(
-
2.02395e+00
,
1.48143e+00
,
1.00879e+00
);
refforces
[
159
]
=
Vec3
(
5.94087e+01
,
-
4.57694e+01
,
2.77585e+01
);
refforces
[
160
]
=
Vec3
(
2.05570e+00
,
1.46552e+00
,
-
1.41447e+00
);
refforces
[
161
]
=
Vec3
(
2.97741e-01
,
9.12876e-01
,
3.27902e+00
);
refforces
[
162
]
=
Vec3
(
1.93442e+01
,
-
4.16391e+01
,
3.34803e-01
);
refforces
[
163
]
=
Vec3
(
-
3.93865e+00
,
8.46322e-01
,
-
4.47285e-01
);
refforces
[
164
]
=
Vec3
(
-
7.34898e-01
,
9.82679e-01
,
1.44017e+00
);
refforces
[
165
]
=
Vec3
(
-
3.34824e+01
,
-
1.38834e+01
,
-
2.62952e+01
);
refforces
[
166
]
=
Vec3
(
1.26693e+00
,
-
1.10171e+00
,
3.22806e+00
);
refforces
[
167
]
=
Vec3
(
3.49758e+00
,
-
1.84534e-01
,
-
4.62412e-01
);
refforces
[
168
]
=
Vec3
(
1.82122e+00
,
-
5.69776e+01
,
-
3.86605e+01
);
refforces
[
169
]
=
Vec3
(
1.92404e+00
,
-
1.05303e+00
,
-
4.52186e-01
);
refforces
[
170
]
=
Vec3
(
-
3.25172e+00
,
9.44050e-02
,
-
5.87318e-01
);
refforces
[
171
]
=
Vec3
(
-
5.98475e+01
,
1.85708e+01
,
-
2.67060e+01
);
refforces
[
172
]
=
Vec3
(
-
3.77230e-01
,
3.29609e+00
,
-
4.81590e-01
);
refforces
[
173
]
=
Vec3
(
-
1.66002e+00
,
-
2.41098e+00
,
1.03425e-01
);
refforces
[
174
]
=
Vec3
(
6.47852e+01
,
4.38661e+00
,
1.77482e+01
);
refforces
[
175
]
=
Vec3
(
-
1.29162e-01
,
-
3.40031e+00
,
3.91521e-01
);
refforces
[
176
]
=
Vec3
(
1.28253e+00
,
2.14633e+00
,
2.64792e-01
);
refforces
[
177
]
=
Vec3
(
2.95010e+01
,
-
5.60376e+00
,
4.16733e+01
);
refforces
[
178
]
=
Vec3
(
-
1.43378e+00
,
-
1.96178e-01
,
2.40594e+00
);
refforces
[
179
]
=
Vec3
(
-
1.56255e+00
,
-
3.08967e+00
,
-
3.14335e-01
);
refforces
[
180
]
=
Vec3
(
-
6.02384e+01
,
-
1.59585e+01
,
7.16798e+01
);
refforces
[
181
]
=
Vec3
(
1.68669e+00
,
-
3.54228e+00
,
-
2.98122e-01
);
refforces
[
182
]
=
Vec3
(
9.46412e-01
,
-
8.03852e-02
,
4.17305e+00
);
refforces
[
183
]
=
Vec3
(
3.87313e+00
,
4.46632e+01
,
4.59130e+01
);
refforces
[
184
]
=
Vec3
(
-
9.83299e-02
,
-
8.11669e-02
,
4.04515e+00
);
refforces
[
185
]
=
Vec3
(
6.64172e-01
,
3.66814e+00
,
-
2.58278e-01
);
refforces
[
186
]
=
Vec3
(
-
1.65450e+01
,
2.35336e+01
,
7.09485e+01
);
refforces
[
187
]
=
Vec3
(
-
6.98821e-01
,
2.45516e-01
,
2.69560e+00
);
refforces
[
188
]
=
Vec3
(
4.04145e+00
,
5.46258e-02
,
-
1.82210e-02
);
refforces
[
189
]
=
Vec3
(
2.39311e+01
,
1.22785e+01
,
-
2.13260e+01
);
refforces
[
190
]
=
Vec3
(
-
3.33802e-02
,
-
3.60205e+00
,
6.21747e-01
);
refforces
[
191
]
=
Vec3
(
3.50616e+00
,
6.09623e-01
,
-
7.40284e-02
);
refforces
[
192
]
=
Vec3
(
2.32693e+01
,
-
1.88836e+01
,
1.24193e+01
);
refforces
[
193
]
=
Vec3
(
-
2.25948e+00
,
-
1.74718e+00
,
2.65705e-01
);
refforces
[
194
]
=
Vec3
(
-
1.32949e+00
,
-
8.67446e-01
,
7.75386e-01
);
refforces
[
195
]
=
Vec3
(
-
4.40626e+01
,
1.17032e+01
,
-
4.18284e+01
);
refforces
[
196
]
=
Vec3
(
1.61723e+00
,
-
6.18309e-01
,
2.45312e+00
);
refforces
[
197
]
=
Vec3
(
1.42535e+00
,
1.71801e+00
,
-
1.86477e+00
);
refforces
[
198
]
=
Vec3
(
3.37157e+00
,
-
1.65818e+01
,
7.59773e+01
);
refforces
[
199
]
=
Vec3
(
-
2.81989e+00
,
-
1.37877e+00
,
-
9.60015e-02
);
refforces
[
200
]
=
Vec3
(
-
8.77602e-02
,
2.44299e+00
,
1.17362e+00
);
refforces
[
201
]
=
Vec3
(
2.44644e+01
,
-
3.26831e+01
,
-
5.34506e+01
);
refforces
[
202
]
=
Vec3
(
-
4.14853e+00
,
-
9.48873e-02
,
-
2.18126e-01
);
refforces
[
203
]
=
Vec3
(
8.13810e-01
,
-
1.30429e+00
,
-
1.62539e+00
);
refforces
[
204
]
=
Vec3
(
1.03414e+01
,
-
4.14898e+00
,
2.56841e+01
);
refforces
[
205
]
=
Vec3
(
-
1.50990e-01
,
-
3.90514e+00
,
2.98649e-01
);
refforces
[
206
]
=
Vec3
(
-
3.60035e+00
,
-
7.83546e-02
,
-
7.95300e-01
);
refforces
[
207
]
=
Vec3
(
4.49059e+01
,
2.88959e+01
,
1.53626e+01
);
refforces
[
208
]
=
Vec3
(
-
2.55855e+00
,
-
1.55231e+00
,
-
3.96734e-01
);
refforces
[
209
]
=
Vec3
(
-
1.14072e+00
,
3.25255e+00
,
2.39860e-01
);
refforces
[
210
]
=
Vec3
(
-
4.12850e+01
,
6.11654e+01
,
2.43179e+01
);
refforces
[
211
]
=
Vec3
(
1.20781e+00
,
-
8.28196e-01
,
4.26212e+00
);
refforces
[
212
]
=
Vec3
(
7.30387e-01
,
-
9.26965e-01
,
-
9.32605e-01
);
refforces
[
213
]
=
Vec3
(
-
1.64972e+01
,
4.58667e+01
,
5.58154e+01
);
refforces
[
214
]
=
Vec3
(
4.43484e-01
,
-
1.67205e+00
,
3.42164e+00
);
refforces
[
215
]
=
Vec3
(
-
4.14170e+00
,
-
9.68400e-01
,
-
9.21231e-02
);
refforces
[
216
]
=
Vec3
(
1.79252e+01
,
6.24205e+01
,
-
1.47777e+01
);
refforces
[
217
]
=
Vec3
(
-
2.53437e+00
,
-
9.16373e-01
,
-
1.63636e+00
);
refforces
[
218
]
=
Vec3
(
3.32247e+00
,
-
1.29776e+00
,
-
1.07427e+00
);
refforces
[
219
]
=
Vec3
(
1.79752e+01
,
5.16430e+01
,
3.90249e+01
);
refforces
[
220
]
=
Vec3
(
7.14180e-01
,
-
1.00018e+00
,
3.14118e+00
);
refforces
[
221
]
=
Vec3
(
-
1.07965e+00
,
-
3.41285e+00
,
-
2.24161e-01
);
refforces
[
222
]
=
Vec3
(
3.16317e+01
,
4.98025e+01
,
-
4.17518e+01
);
refforces
[
223
]
=
Vec3
(
-
2.55899e+00
,
-
1.63433e+00
,
-
3.76149e-01
);
refforces
[
224
]
=
Vec3
(
-
1.19443e+00
,
-
1.02227e+00
,
-
5.37349e-02
);
refforces
[
225
]
=
Vec3
(
-
3.77249e+01
,
-
4.85845e+01
,
-
2.11073e+01
);
refforces
[
226
]
=
Vec3
(
7.98995e-01
,
1.26056e+00
,
4.28442e+00
);
refforces
[
227
]
=
Vec3
(
3.35648e+00
,
9.11653e-01
,
-
8.07025e-01
);
refforces
[
228
]
=
Vec3
(
-
3.16004e+01
,
-
2.04156e+01
,
5.01542e+01
);
refforces
[
229
]
=
Vec3
(
8.97766e-01
,
1.34997e+00
,
2.86585e+00
);
refforces
[
230
]
=
Vec3
(
-
2.09603e-01
,
4.05651e+00
,
-
1.91043e-02
);
refforces
[
231
]
=
Vec3
(
3.61582e+01
,
-
3.35593e+01
,
4.19940e+01
);
refforces
[
232
]
=
Vec3
(
3.66075e+00
,
7.71021e-01
,
3.45598e-01
);
refforces
[
233
]
=
Vec3
(
-
7.50361e-01
,
1.22549e+00
,
7.98677e-01
);
refforces
[
234
]
=
Vec3
(
-
4.42511e+01
,
-
2.71049e+01
,
-
4.56576e+01
);
refforces
[
235
]
=
Vec3
(
-
3.30181e-01
,
1.98824e+00
,
2.21005e+00
);
refforces
[
236
]
=
Vec3
(
-
7.68719e-01
,
9.09063e-01
,
-
3.77633e+00
);
refforces
[
237
]
=
Vec3
(
7.33817e+01
,
-
3.03886e+01
,
-
7.59758e+01
);
refforces
[
238
]
=
Vec3
(
-
1.71701e+00
,
1.41048e+00
,
-
1.84182e+00
);
refforces
[
239
]
=
Vec3
(
-
1.35491e+00
,
2.27816e+00
,
-
1.08799e+00
);
refforces
[
240
]
=
Vec3
(
-
4.58218e+01
,
-
2.91931e+01
,
1.12369e+01
);
refforces
[
241
]
=
Vec3
(
1.68546e+00
,
2.81258e+00
,
3.93755e-01
);
refforces
[
242
]
=
Vec3
(
8.28917e-01
,
-
1.32237e+00
,
2.91182e+00
);
refforces
[
243
]
=
Vec3
(
5.44446e+00
,
-
3.99466e+01
,
6.77923e+00
);
refforces
[
244
]
=
Vec3
(
-
1.09231e+00
,
-
5.21927e-01
,
1.83581e+00
);
refforces
[
245
]
=
Vec3
(
5.24849e-02
,
-
7.21832e-01
,
-
3.35896e+00
);
refforces
[
246
]
=
Vec3
(
-
1.29863e+01
,
-
3.94851e+01
,
-
2.70347e+01
);
refforces
[
247
]
=
Vec3
(
-
3.94725e+00
,
-
2.01688e-01
,
5.93703e-02
);
refforces
[
248
]
=
Vec3
(
1.30447e+00
,
-
2.35362e+00
,
-
2.94278e-01
);
refforces
[
249
]
=
Vec3
(
2.56542e+01
,
-
3.79434e+01
,
-
6.19782e+01
);
refforces
[
250
]
=
Vec3
(
2.48025e+00
,
-
1.19994e+00
,
1.41640e-01
);
refforces
[
251
]
=
Vec3
(
-
5.01379e-01
,
2.48607e-01
,
-
3.97535e+00
);
refforces
[
252
]
=
Vec3
(
3.46461e+01
,
-
8.37214e+01
,
-
3.92225e+01
);
refforces
[
253
]
=
Vec3
(
-
2.80216e+00
,
-
1.13524e+00
,
1.85582e-02
);
refforces
[
254
]
=
Vec3
(
-
1.28421e+00
,
-
9.50174e-01
,
-
5.56828e-01
);
refforces
[
255
]
=
Vec3
(
-
3.56755e+01
,
1.44176e+01
,
-
7.63345e-01
);
refforces
[
256
]
=
Vec3
(
1.25547e+00
,
2.64846e+00
,
1.29226e+00
);
refforces
[
257
]
=
Vec3
(
1.22691e+00
,
5.72301e-01
,
-
4.09853e+00
);
refforces
[
258
]
=
Vec3
(
-
6.02997e+00
,
-
1.31579e+01
,
-
5.03304e+01
);
refforces
[
259
]
=
Vec3
(
-
4.59947e-01
,
-
8.09031e-01
,
3.08383e+00
);
refforces
[
260
]
=
Vec3
(
-
8.93872e-01
,
-
3.70797e-01
,
-
2.89773e+00
);
refforces
[
261
]
=
Vec3
(
-
1.92458e+00
,
2.50787e+01
,
-
4.30937e+01
);
refforces
[
262
]
=
Vec3
(
2.10381e-01
,
-
1.24125e-01
,
-
4.01554e+00
);
refforces
[
263
]
=
Vec3
(
-
3.85853e+00
,
6.72311e-01
,
4.06873e-02
);
refforces
[
264
]
=
Vec3
(
1.66952e+01
,
1.47383e+01
,
4.13458e+01
);
refforces
[
265
]
=
Vec3
(
-
2.12261e+00
,
-
5.40916e-01
,
1.54532e+00
);
refforces
[
266
]
=
Vec3
(
3.54041e+00
,
-
4.73740e-02
,
4.73489e-01
);
refforces
[
267
]
=
Vec3
(
4.43789e+01
,
6.96271e+01
,
4.06335e+00
);
refforces
[
268
]
=
Vec3
(
-
9.59563e-01
,
9.94730e-01
,
-
3.12464e+00
);
refforces
[
269
]
=
Vec3
(
-
1.42363e+00
,
1.62107e+00
,
1.87365e+00
);
refforces
[
270
]
=
Vec3
(
-
5.38380e+01
,
2.27365e+01
,
1.95666e+01
);
refforces
[
271
]
=
Vec3
(
1.47405e+00
,
2.11523e+00
,
1.97777e-01
);
refforces
[
272
]
=
Vec3
(
2.54377e+00
,
-
4.04439e-02
,
1.97927e+00
);
refforces
[
273
]
=
Vec3
(
1.33568e+01
,
1.88750e+01
,
-
3.59233e+01
);
refforces
[
274
]
=
Vec3
(
-
1.09293e+00
,
2.25841e+00
,
-
4.61222e-01
);
refforces
[
275
]
=
Vec3
(
3.27762e+00
,
-
1.71208e-01
,
-
8.67824e-01
);
refforces
[
276
]
=
Vec3
(
-
3.41864e+01
,
3.38579e+01
,
5.95219e+01
);
refforces
[
277
]
=
Vec3
(
-
4.18249e+00
,
-
8.81154e-02
,
1.97498e-01
);
refforces
[
278
]
=
Vec3
(
1.06177e+00
,
2.34089e+00
,
2.42037e-01
);
refforces
[
279
]
=
Vec3
(
2.35073e+01
,
1.61625e+01
,
-
2.58858e+01
);
refforces
[
280
]
=
Vec3
(
3.87903e+00
,
1.67313e-01
,
-
4.03473e-02
);
refforces
[
281
]
=
Vec3
(
-
5.12341e-01
,
-
5.62857e-01
,
-
3.19237e+00
);
refforces
[
282
]
=
Vec3
(
3.39154e+01
,
-
5.09470e+00
,
-
2.29146e+01
);
refforces
[
283
]
=
Vec3
(
-
1.24992e+00
,
5.24960e-01
,
-
1.16022e+00
);
refforces
[
284
]
=
Vec3
(
-
2.39537e+00
,
1.82818e-01
,
-
1.53421e+00
);
refforces
[
285
]
=
Vec3
(
-
5.56195e+01
,
2.89266e+01
,
-
2.61137e+01
);
refforces
[
286
]
=
Vec3
(
2.49596e+00
,
-
1.03213e+00
,
-
1.51258e+00
);
refforces
[
287
]
=
Vec3
(
1.02471e+00
,
-
1.05342e+00
,
-
6.79809e-01
);
refforces
[
288
]
=
Vec3
(
-
1.52895e+01
,
4.83734e+01
,
-
7.33233e+00
);
refforces
[
289
]
=
Vec3
(
3.77837e+00
,
-
1.59224e+00
,
2.02675e-01
);
refforces
[
290
]
=
Vec3
(
-
3.51854e+00
,
-
1.54234e+00
,
2.89348e-01
);
refforces
[
291
]
=
Vec3
(
3.22262e+01
,
2.32542e+01
,
2.37269e+01
);
refforces
[
292
]
=
Vec3
(
1.88520e+00
,
-
1.38396e+00
,
-
1.98750e+00
);
refforces
[
293
]
=
Vec3
(
4.99036e-02
,
-
4.53129e+00
,
-
2.13859e-01
);
refforces
[
294
]
=
Vec3
(
-
7.48274e+00
,
3.71318e+01
,
-
2.35667e+01
);
refforces
[
295
]
=
Vec3
(
7.81671e-01
,
-
1.07371e+00
,
-
2.37009e+00
);
refforces
[
296
]
=
Vec3
(
-
3.98896e+00
,
-
9.36146e-01
,
2.62843e-02
);
refforces
[
297
]
=
Vec3
(
4.33081e+01
,
4.24806e+01
,
3.21190e+01
);
refforces
[
298
]
=
Vec3
(
-
2.52531e+00
,
-
1.90285e+00
,
2.72091e-01
);
refforces
[
299
]
=
Vec3
(
-
9.70927e-01
,
-
1.13219e+00
,
1.47351e+00
);
refforces
[
300
]
=
Vec3
(
-
4.71070e+01
,
-
7.19253e+01
,
5.82986e+01
);
refforces
[
301
]
=
Vec3
(
6.82929e-01
,
1.00679e+00
,
-
6.94522e-01
);
refforces
[
302
]
=
Vec3
(
8.31359e-01
,
7.09804e-01
,
-
8.12652e-01
);
refforces
[
303
]
=
Vec3
(
3.62309e+00
,
-
3.42931e+01
,
1.98231e+01
);
refforces
[
304
]
=
Vec3
(
1.23138e+00
,
8.49297e-01
,
-
2.39283e+00
);
refforces
[
305
]
=
Vec3
(
-
2.87428e+00
,
1.41050e+00
,
-
1.03948e+00
);
refforces
[
306
]
=
Vec3
(
-
3.83149e+00
,
-
2.61638e+01
,
2.98550e+01
);
refforces
[
307
]
=
Vec3
(
-
2.90010e+00
,
1.38356e+00
,
-
1.22906e+00
);
refforces
[
308
]
=
Vec3
(
2.62337e-01
,
9.72795e-01
,
-
4.02660e+00
);
refforces
[
309
]
=
Vec3
(
7.84655e+00
,
-
5.09531e+01
,
7.96762e+01
);
refforces
[
310
]
=
Vec3
(
2.46967e+00
,
9.48901e-01
,
-
1.17317e+00
);
refforces
[
311
]
=
Vec3
(
-
4.11596e+00
,
7.95633e-01
,
-
1.39335e+00
);
refforces
[
312
]
=
Vec3
(
5.03705e+01
,
-
8.09993e+01
,
1.13172e+02
);
refforces
[
313
]
=
Vec3
(
-
4.48925e-01
,
4.29309e-01
,
-
5.50572e-01
);
refforces
[
314
]
=
Vec3
(
-
2.66201e+00
,
1.05662e+00
,
-
1.44247e+00
);
refforces
[
315
]
=
Vec3
(
-
6.12660e+01
,
2.31218e+01
,
4.57287e+01
);
refforces
[
316
]
=
Vec3
(
8.42017e-01
,
1.41042e+00
,
-
7.78795e-01
);
refforces
[
317
]
=
Vec3
(
3.11298e+00
,
-
8.04273e-01
,
-
1.51273e+00
);
refforces
[
318
]
=
Vec3
(
1.83823e+01
,
-
2.83588e+01
,
6.13597e+01
);
refforces
[
319
]
=
Vec3
(
4.37781e+00
,
8.12091e-02
,
-
1.33992e+00
);
refforces
[
320
]
=
Vec3
(
-
5.81396e-01
,
-
3.61991e+00
,
-
1.22489e+00
);
refforces
[
321
]
=
Vec3
(
-
4.85270e+01
,
-
6.50314e+01
,
7.16441e+01
);
refforces
[
322
]
=
Vec3
(
-
3.40093e-02
,
9.01514e-01
,
-
1.26573e+00
);
refforces
[
323
]
=
Vec3
(
-
8.67193e-02
,
-
3.94828e+00
,
-
8.97127e-01
);
refforces
[
324
]
=
Vec3
(
6.25833e+01
,
-
2.31957e+01
,
8.66089e+01
);
refforces
[
325
]
=
Vec3
(
2.49809e+00
,
-
7.64197e-01
,
-
1.27775e+00
);
refforces
[
326
]
=
Vec3
(
2.11019e-01
,
7.81764e-01
,
-
1.23664e+00
);
refforces
[
327
]
=
Vec3
(
2.04801e+01
,
3.14002e+01
,
6.96727e+01
);
refforces
[
328
]
=
Vec3
(
-
7.99932e-01
,
4.35586e+00
,
-
8.77957e-01
);
refforces
[
329
]
=
Vec3
(
-
2.87129e+00
,
-
1.02321e+00
,
-
1.42702e+00
);
refforces
[
330
]
=
Vec3
(
-
6.36347e+01
,
-
3.58428e+01
,
4.52682e+01
);
refforces
[
331
]
=
Vec3
(
1.32210e+00
,
-
2.58500e+00
,
-
1.43327e+00
);
refforces
[
332
]
=
Vec3
(
1.52218e+00
,
1.63513e+00
,
-
2.29784e+00
);
refforces
[
333
]
=
Vec3
(
4.36105e+00
,
3.70776e+01
,
6.46133e+01
);
refforces
[
334
]
=
Vec3
(
-
1.19452e+00
,
-
1.01252e+00
,
-
1.43172e+00
);
refforces
[
335
]
=
Vec3
(
4.34983e+00
,
-
6.52342e-02
,
-
1.33662e+00
);
refforces
[
336
]
=
Vec3
(
1.13050e+01
,
4.99187e+01
,
7.16119e+01
);
refforces
[
337
]
=
Vec3
(
2.29221e-01
,
6.35843e-01
,
-
3.59259e+00
);
refforces
[
338
]
=
Vec3
(
1.65239e+00
,
4.20995e-01
,
-
1.42878e+00
);
refforces
[
339
]
=
Vec3
(
-
1.79210e+01
,
1.92423e+01
,
1.77516e+01
);
refforces
[
340
]
=
Vec3
(
-
2.91278e+00
,
9.22214e-01
,
-
8.41281e-01
);
refforces
[
341
]
=
Vec3
(
2.96465e+00
,
1.05962e+00
,
-
6.85280e-01
);
refforces
[
342
]
=
Vec3
(
5.19378e+01
,
-
2.55266e+01
,
3.63518e+01
);
refforces
[
343
]
=
Vec3
(
-
1.13088e+00
,
4.54600e-01
,
-
1.30862e+00
);
refforces
[
344
]
=
Vec3
(
-
2.05369e+00
,
-
9.69459e-03
,
-
2.69351e+00
);
refforces
[
345
]
=
Vec3
(
-
4.22214e+01
,
4.88282e+01
,
3.76741e+01
);
refforces
[
346
]
=
Vec3
(
3.46996e+00
,
9.57280e-01
,
-
7.60128e-01
);
refforces
[
347
]
=
Vec3
(
7.62585e-01
,
1.14548e+00
,
-
8.06697e-01
);
refforces
[
348
]
=
Vec3
(
-
2.35024e+01
,
-
6.73585e+01
,
6.49050e+01
);
refforces
[
349
]
=
Vec3
(
-
1.58984e+00
,
-
6.44551e-01
,
-
2.37758e+00
);
refforces
[
350
]
=
Vec3
(
1.32604e+00
,
-
2.37576e+00
,
-
1.54939e+00
);
refforces
[
351
]
=
Vec3
(
2.57776e+01
,
-
1.40743e+01
,
2.06580e+01
);
refforces
[
352
]
=
Vec3
(
4.24916e+00
,
6.10665e-02
,
-
8.19360e-01
);
refforces
[
353
]
=
Vec3
(
-
7.94423e-01
,
-
1.75764e-01
,
-
3.51414e+00
);
refforces
[
354
]
=
Vec3
(
-
1.24260e+01
,
6.96334e-01
,
5.97705e+01
);
refforces
[
355
]
=
Vec3
(
-
3.38899e+00
,
9.44919e-01
,
-
1.25780e+00
);
refforces
[
356
]
=
Vec3
(
6.81664e-01
,
1.16965e+00
,
-
2.34256e+00
);
refforces
[
357
]
=
Vec3
(
5.15292e+01
,
5.13086e+01
,
6.16724e+01
);
refforces
[
358
]
=
Vec3
(
-
1.04216e+00
,
3.34685e+00
,
-
1.33787e+00
);
refforces
[
359
]
=
Vec3
(
-
9.57017e-01
,
-
1.59610e-01
,
-
4.31963e+00
);
refforces
[
360
]
=
Vec3
(
-
5.88173e+01
,
3.30524e+01
,
6.23031e+01
);
refforces
[
361
]
=
Vec3
(
9.35413e-01
,
-
1.09829e+00
,
-
4.65202e+00
);
refforces
[
362
]
=
Vec3
(
6.95250e-01
,
-
1.24375e+00
,
-
6.50832e-01
);
refforces
[
363
]
=
Vec3
(
1.64454e+01
,
1.08071e+02
,
3.76968e+01
);
refforces
[
364
]
=
Vec3
(
-
4.25249e+00
,
-
1.10053e+00
,
-
7.56357e-01
);
refforces
[
365
]
=
Vec3
(
1.17898e+00
,
-
1.10215e+00
,
-
8.21366e-01
);
refforces
[
366
]
=
Vec3
(
-
5.20527e+00
,
5.49522e+01
,
4.55303e+01
);
refforces
[
367
]
=
Vec3
(
-
7.98794e-01
,
-
2.78246e+00
,
-
1.27815e+00
);
refforces
[
368
]
=
Vec3
(
-
1.02109e+00
,
-
1.21921e+00
,
-
1.26706e+00
);
refforces
[
369
]
=
Vec3
(
3.05185e+00
,
3.99846e+01
,
5.39902e+01
);
refforces
[
370
]
=
Vec3
(
1.93675e+00
,
-
1.28986e+00
,
-
1.21655e+00
);
refforces
[
371
]
=
Vec3
(
-
4.14952e+00
,
-
1.06509e+00
,
-
9.52154e-01
);
refforces
[
372
]
=
Vec3
(
6.06000e+01
,
2.50872e+01
,
4.29623e+01
);
refforces
[
373
]
=
Vec3
(
-
3.50284e+00
,
-
1.47848e+00
,
-
7.98049e-01
);
refforces
[
374
]
=
Vec3
(
-
8.66087e-01
,
-
1.73056e+00
,
-
6.59554e-01
);
// Find the exclusion information
vector
<
set
<
int
>
>
exclusions
(
numAtoms
);
for
(
int
i
=
0
;
i
<
forceField
->
getNumExceptions
();
i
++
)
{
int
particle1
,
particle2
;
double
chargeProd
,
sigma
,
epsilon
;
forceField
->
getExceptionParameters
(
i
,
particle1
,
particle2
,
chargeProd
,
sigma
,
epsilon
);
exclusions
[
particle1
].
insert
(
particle2
);
exclusions
[
particle2
].
insert
(
particle1
);
}
const
double
longcutoff
=
35.0
*
OpenMM
::
NmPerAngstrom
;
const
double
longcutoff2
=
longcutoff
*
longcutoff
;
const
double
cutoff2
=
cutoff
*
cutoff
;
const
double
cutoff6inv
=
1.0
/
(
cutoff2
*
cutoff2
*
cutoff2
);
const
int
nboxes
=
ceil
(
longcutoff
/
boxEdgeLength
);
double
refenergy
=
0.0
;
// Loop over home box first...
for
(
int
i
=
0
;
i
<
numAtoms
;
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
++
j
)
{
Vec3
dR
=
positions
[
i
]
-
positions
[
j
];
double
R2
=
dR
[
0
]
*
dR
[
0
]
+
dR
[
1
]
*
dR
[
1
]
+
dR
[
2
]
*
dR
[
2
];
double
sig2
=
(
sigvals
[
i
]
+
sigvals
[
j
])
*
(
sigvals
[
i
]
+
sigvals
[
j
])
/
R2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
double
eps
=
epsvals
[
i
]
*
epsvals
[
j
];
refenergy
+=
2.0
*
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
R2
<
cutoff2
)
{
// Add a shift term for direct space parts withing t
refenergy
+=
2.0
*
eps
*
(
pow
(
sigvals
[
i
]
+
sigvals
[
j
],
6
)
-
64.0
*
pow
(
sigvals
[
i
]
*
sigvals
[
j
],
3
))
*
cutoff6inv
;
}
}
}
// ... back out exclusions
for
(
int
ii
=
0
;
ii
<
numAtoms
;
ii
++
)
{
for
(
set
<
int
>::
const_iterator
iter
=
exclusions
[
ii
].
begin
();
iter
!=
exclusions
[
ii
].
end
();
++
iter
)
{
if
(
*
iter
>
ii
)
{
int
i
=
ii
;
int
j
=
*
iter
;
Vec3
dR
=
positions
[
i
]
-
positions
[
j
];
double
R2
=
dR
[
0
]
*
dR
[
0
]
+
dR
[
1
]
*
dR
[
1
]
+
dR
[
2
]
*
dR
[
2
];
double
sig2
=
(
sigvals
[
i
]
+
sigvals
[
j
])
*
(
sigvals
[
i
]
+
sigvals
[
j
])
/
R2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
double
eps
=
epsvals
[
i
]
*
epsvals
[
j
];
refenergy
-=
2.0
*
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
R2
<
cutoff2
)
{
// Add a shift term for direct space parts withing t
refenergy
-=
2.0
*
eps
*
(
pow
(
sigvals
[
i
]
+
sigvals
[
j
],
6
)
-
64.0
*
pow
(
sigvals
[
i
]
*
sigvals
[
j
],
3
))
*
cutoff6inv
;
}
}
}
}
// ... and now add in the image box terms
for
(
int
bx
=
-
nboxes
;
bx
<=
nboxes
;
++
bx
)
{
for
(
int
by
=
-
nboxes
;
by
<=
nboxes
;
++
by
)
{
for
(
int
bz
=
-
nboxes
;
bz
<=
nboxes
;
++
bz
)
{
if
(
bx
==
0
&&
by
==
0
&&
bz
==
0
)
continue
;
Vec3
offset
(
bx
*
boxEdgeLength
,
by
*
boxEdgeLength
,
bz
*
boxEdgeLength
);
for
(
int
i
=
0
;
i
<
numAtoms
;
++
i
)
{
for
(
int
j
=
0
;
j
<
numAtoms
;
++
j
)
{
Vec3
dR
=
positions
[
i
]
-
positions
[
j
]
+
offset
;
double
R2
=
dR
[
0
]
*
dR
[
0
]
+
dR
[
1
]
*
dR
[
1
]
+
dR
[
2
]
*
dR
[
2
];
if
(
R2
>
longcutoff2
)
continue
;
double
sig2
=
(
sigvals
[
i
]
+
sigvals
[
j
])
*
(
sigvals
[
i
]
+
sigvals
[
j
])
/
R2
;
double
sig6
=
sig2
*
sig2
*
sig2
;
double
eps
=
epsvals
[
i
]
*
epsvals
[
j
];
refenergy
+=
eps
*
(
sig6
-
1.0
)
*
sig6
;
if
(
R2
<
cutoff2
)
{
// Add a shift term for direct space parts withing teh
refenergy
+=
eps
*
(
pow
(
sigvals
[
i
]
+
sigvals
[
j
],
6
)
-
64.0
*
pow
(
sigvals
[
i
]
*
sigvals
[
j
],
3
))
*
cutoff6inv
;
}
}
}
}
}
}
refenergy
*=
0.5
;
// For this test the reference energy is -294.078 kJ/mol, while the difference between DPME and 30A cutoffs
// is just 0.064 kJ/mol. The difference is due to the fact that arithmetic mean combination rules are used
// up to the cutoff, while the reciprocal space uses the geometric mean. See DOI: 10.1021/acs.jctc.5b00726
ASSERT_EQUAL_TOL
(
refenergy
,
energy
,
5E-4
);
ASSERT_EQUAL_TOL
(
gromacs_energy
,
energy
,
5E-5
);
// Forces accumulated in single precision are tested to a more permissive criterion; the double
// precision platform can match to 5E-5.
for
(
int
n
=
0
;
n
<
numAtoms
;
++
n
)
ASSERT_EQUAL_VEC
(
refforces
[
n
],
forces
[
n
],
1E-4
);
}
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
initializeTests
(
argc
,
argv
);
testDMFDpmeEnergiesForcesWithExclusions
();
testConvergence
();
testErrorTolerance
();
testPMEParameters
();
testCoulombAndLJ
();
testWater2DpmeEnergiesForcesNoExclusions
();
testWater2DpmeEnergiesForcesWithExclusions
();
testWater125DpmeVsLongCutoffNoExclusions
();
testWater125DpmeVsLongCutoffWithExclusions
();
runPlatformTests
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
tests/TestEwald.h
View file @
53f770f4
...
@@ -365,7 +365,7 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) {
...
@@ -365,7 +365,7 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) {
double
expectedAlpha
,
actualAlpha
;
double
expectedAlpha
,
actualAlpha
;
int
expectedSize
[
3
],
actualSize
[
3
];
int
expectedSize
[
3
],
actualSize
[
3
];
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
expectedAlpha
,
expectedSize
[
0
],
expectedSize
[
1
],
expectedSize
[
2
]);
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
expectedAlpha
,
expectedSize
[
0
],
expectedSize
[
1
],
expectedSize
[
2
]
,
false
);
force
->
getPMEParametersInContext
(
context
,
actualAlpha
,
actualSize
[
0
],
actualSize
[
1
],
actualSize
[
2
]);
force
->
getPMEParametersInContext
(
context
,
actualAlpha
,
actualSize
[
0
],
actualSize
[
1
],
actualSize
[
2
]);
ASSERT_EQUAL_TOL
(
expectedAlpha
,
actualAlpha
,
1e-5
);
ASSERT_EQUAL_TOL
(
expectedAlpha
,
actualAlpha
,
1e-5
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
...
...
tests/TestNonbondedForce.h
View file @
53f770f4
...
@@ -39,6 +39,7 @@
...
@@ -39,6 +39,7 @@
#include "SimTKOpenMMRealType.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <vector>
using
namespace
OpenMM
;
using
namespace
OpenMM
;
...
...
wrappers/python/simtk/openmm/app/__init__.py
View file @
53f770f4
...
@@ -40,6 +40,7 @@ CutoffNonPeriodic = forcefield.CutoffNonPeriodic
...
@@ -40,6 +40,7 @@ CutoffNonPeriodic = forcefield.CutoffNonPeriodic
CutoffPeriodic
=
forcefield
.
CutoffPeriodic
CutoffPeriodic
=
forcefield
.
CutoffPeriodic
Ewald
=
forcefield
.
Ewald
Ewald
=
forcefield
.
Ewald
PME
=
forcefield
.
PME
PME
=
forcefield
.
PME
LJPME
=
forcefield
.
LJPME
HBonds
=
forcefield
.
HBonds
HBonds
=
forcefield
.
HBonds
AllBonds
=
forcefield
.
AllBonds
AllBonds
=
forcefield
.
AllBonds
...
...
wrappers/python/simtk/openmm/app/amberprmtopfile.py
View file @
53f770f4
...
@@ -169,7 +169,7 @@ class AmberPrmtopFile(object):
...
@@ -169,7 +169,7 @@ class AmberPrmtopFile(object):
----------
----------
nonbondedMethod : object=NoCutoff
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald,
PME,
or
LJ
PME.
nonbondedCutoff : distance=1*nanometer
nonbondedCutoff : distance=1*nanometer
The cutoff distance to use for nonbonded interactions
The cutoff distance to use for nonbonded interactions
constraints : object=None
constraints : object=None
...
@@ -202,7 +202,7 @@ class AmberPrmtopFile(object):
...
@@ -202,7 +202,7 @@ class AmberPrmtopFile(object):
added to a hydrogen is subtracted from the heavy atom to keep their
added to a hydrogen is subtracted from the heavy atom to keep their
total mass the same.
total mass the same.
ewaldErrorTolerance : float=0.0005
ewaldErrorTolerance : float=0.0005
The error tolerance to use if nonbondedMethod is Ewald or PME.
The error tolerance to use if nonbondedMethod is Ewald
, PME,
or
LJ
PME.
switchDistance : float=0*nanometers
switchDistance : float=0*nanometers
The distance at which the potential energy switching function is
The distance at which the potential energy switching function is
turned on for Lennard-Jones interactions. If the switchDistance is 0
turned on for Lennard-Jones interactions. If the switchDistance is 0
...
@@ -222,10 +222,11 @@ class AmberPrmtopFile(object):
...
@@ -222,10 +222,11 @@ class AmberPrmtopFile(object):
ff
.
CutoffNonPeriodic
:
'CutoffNonPeriodic'
,
ff
.
CutoffNonPeriodic
:
'CutoffNonPeriodic'
,
ff
.
CutoffPeriodic
:
'CutoffPeriodic'
,
ff
.
CutoffPeriodic
:
'CutoffPeriodic'
,
ff
.
Ewald
:
'Ewald'
,
ff
.
Ewald
:
'Ewald'
,
ff
.
PME
:
'PME'
}
ff
.
PME
:
'PME'
,
ff
.
LJPME
:
'LJPME'
}
if
nonbondedMethod
not
in
methodMap
:
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal value for nonbonded method'
)
raise
ValueError
(
'Illegal value for nonbonded method'
)
if
not
self
.
_prmtop
.
getIfBox
()
and
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
):
if
not
self
.
_prmtop
.
getIfBox
()
and
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
,
ff
.
LJPME
):
raise
ValueError
(
'Illegal nonbonded method for a non-periodic system'
)
raise
ValueError
(
'Illegal nonbonded method for a non-periodic system'
)
constraintMap
=
{
None
:
None
,
constraintMap
=
{
None
:
None
,
ff
.
HBonds
:
'h-bonds'
,
ff
.
HBonds
:
'h-bonds'
,
...
...
wrappers/python/simtk/openmm/app/charmmpsffile.py
View file @
53f770f4
...
@@ -690,7 +690,7 @@ class CharmmPsfFile(object):
...
@@ -690,7 +690,7 @@ class CharmmPsfFile(object):
The parameter set to use to parametrize this molecule
The parameter set to use to parametrize this molecule
nonbondedMethod : object=NoCutoff
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald,
PME,
or
LJ
PME.
nonbondedCutoff : distance=1*nanometer
nonbondedCutoff : distance=1*nanometer
The cutoff distance to use for nonbonded interactions.
The cutoff distance to use for nonbonded interactions.
switchDistance : distance=0*nanometer
switchDistance : distance=0*nanometer
...
@@ -728,7 +728,7 @@ class CharmmPsfFile(object):
...
@@ -728,7 +728,7 @@ class CharmmPsfFile(object):
added to a hydrogen is subtracted from the heavy atom to keep their
added to a hydrogen is subtracted from the heavy atom to keep their
total mass the same.
total mass the same.
ewaldErrorTolerance : float=0.0005
ewaldErrorTolerance : float=0.0005
The error tolerance to use if the nonbonded method is Ewald or PME.
The error tolerance to use if the nonbonded method is Ewald
, PME,
or
LJ
PME.
flexibleConstraints : bool=True
flexibleConstraints : bool=True
Are our constraints flexible or not?
Are our constraints flexible or not?
verbose : bool=False
verbose : bool=False
...
@@ -746,10 +746,10 @@ class CharmmPsfFile(object):
...
@@ -746,10 +746,10 @@ class CharmmPsfFile(object):
cutoff
=
cutoff
.
value_in_unit
(
u
.
nanometers
)
cutoff
=
cutoff
.
value_in_unit
(
u
.
nanometers
)
if
nonbondedMethod
not
in
(
ff
.
NoCutoff
,
ff
.
CutoffNonPeriodic
,
if
nonbondedMethod
not
in
(
ff
.
NoCutoff
,
ff
.
CutoffNonPeriodic
,
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
):
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
,
ff
.
LJPME
):
raise
ValueError
(
'Illegal value for nonbonded method'
)
raise
ValueError
(
'Illegal value for nonbonded method'
)
if
not
hasbox
and
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
if
not
hasbox
and
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
):
ff
.
Ewald
,
ff
.
PME
,
ff
.
LJPME
):
raise
ValueError
(
'Illegal nonbonded method for a '
raise
ValueError
(
'Illegal nonbonded method for a '
'non-periodic system'
)
'non-periodic system'
)
if
implicitSolvent
not
in
(
HCT
,
OBC1
,
OBC2
,
GBn
,
GBn2
,
None
):
if
implicitSolvent
not
in
(
HCT
,
OBC1
,
OBC2
,
GBn
,
GBn2
,
None
):
...
@@ -1009,6 +1009,8 @@ class CharmmPsfFile(object):
...
@@ -1009,6 +1009,8 @@ class CharmmPsfFile(object):
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
Ewald
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
Ewald
)
elif
nonbondedMethod
is
ff
.
PME
:
elif
nonbondedMethod
is
ff
.
PME
:
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
PME
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
PME
)
elif
nonbondedMethod
is
ff
.
LJPME
:
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
LJPME
)
else
:
else
:
raise
ValueError
(
'Cutoff method is not understood'
)
raise
ValueError
(
'Cutoff method is not understood'
)
...
@@ -1088,8 +1090,7 @@ class CharmmPsfFile(object):
...
@@ -1088,8 +1090,7 @@ class CharmmPsfFile(object):
mm
.
Discrete2DFunction
(
num_lj_types
,
num_lj_types
,
bcoef
))
mm
.
Discrete2DFunction
(
num_lj_types
,
num_lj_types
,
bcoef
))
cforce
.
addPerParticleParameter
(
'type'
)
cforce
.
addPerParticleParameter
(
'type'
)
cforce
.
setForceGroup
(
self
.
NONBONDED_FORCE_GROUP
)
cforce
.
setForceGroup
(
self
.
NONBONDED_FORCE_GROUP
)
if
(
nonbondedMethod
is
ff
.
PME
or
nonbondedMethod
is
ff
.
Ewald
or
if
(
nonbondedMethod
in
(
ff
.
PME
,
ff
.
LJPME
,
ff
.
Ewald
,
ff
.
CutoffPeriodic
)):
nonbondedMethod
is
ff
.
CutoffPeriodic
):
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
cforce
.
setUseLongRangeCorrection
(
True
)
cforce
.
setUseLongRangeCorrection
(
True
)
...
...
wrappers/python/simtk/openmm/app/desmonddmsfile.py
View file @
53f770f4
...
@@ -165,11 +165,11 @@ class DesmondDMSFile(object):
...
@@ -165,11 +165,11 @@ class DesmondDMSFile(object):
----------
----------
nonbondedMethod : object=NoCutoff
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald,
PME,
or
LJ
PME.
nonbondedCutoff : distance=1*nanometer
nonbondedCutoff : distance=1*nanometer
The cutoff distance to use for nonbonded interactions
The cutoff distance to use for nonbonded interactions
ewaldErrorTolerance : float=0.0005
ewaldErrorTolerance : float=0.0005
The error tolerance to use if nonbondedMethod is Ewald or PME.
The error tolerance to use if nonbondedMethod is Ewald
, PME,
or
LJ
PME.
removeCMMotion : boolean=True
removeCMMotion : boolean=True
If true, a CMMotionRemover will be added to the System
If true, a CMMotionRemover will be added to the System
hydrogenMass : mass=None
hydrogenMass : mass=None
...
@@ -185,7 +185,7 @@ class DesmondDMSFile(object):
...
@@ -185,7 +185,7 @@ class DesmondDMSFile(object):
boxSize
=
self
.
topology
.
getUnitCellDimensions
()
boxSize
=
self
.
topology
.
getUnitCellDimensions
()
if
boxSize
is
not
None
:
if
boxSize
is
not
None
:
sys
.
setDefaultPeriodicBoxVectors
((
boxSize
[
0
],
0
,
0
),
(
0
,
boxSize
[
1
],
0
),
(
0
,
0
,
boxSize
[
2
]))
sys
.
setDefaultPeriodicBoxVectors
((
boxSize
[
0
],
0
,
0
),
(
0
,
boxSize
[
1
],
0
),
(
0
,
0
,
boxSize
[
2
]))
elif
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
):
elif
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
,
ff
.
LJPME
):
raise
ValueError
(
'Illegal nonbonded method for a non-periodic system'
)
raise
ValueError
(
'Illegal nonbonded method for a non-periodic system'
)
# Create all of the particles
# Create all of the particles
...
@@ -207,7 +207,8 @@ class DesmondDMSFile(object):
...
@@ -207,7 +207,8 @@ class DesmondDMSFile(object):
ff
.
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
ff
.
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
ff
.
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
ff
.
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
ff
.
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
ff
.
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
ff
.
PME
:
mm
.
NonbondedForce
.
PME
}
ff
.
PME
:
mm
.
NonbondedForce
.
PME
,
ff
.
LJPME
:
mm
.
NonbondedForce
.
LJPME
}
nb
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
nb
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
nb
.
setCutoffDistance
(
nonbondedCutoff
)
nb
.
setCutoffDistance
(
nonbondedCutoff
)
nb
.
setEwaldErrorTolerance
(
ewaldErrorTolerance
)
nb
.
setEwaldErrorTolerance
(
ewaldErrorTolerance
)
...
...
wrappers/python/simtk/openmm/app/forcefield.py
View file @
53f770f4
...
@@ -115,6 +115,11 @@ class PME(Singleton):
...
@@ -115,6 +115,11 @@ class PME(Singleton):
return
'PME'
return
'PME'
PME
=
PME
()
PME
=
PME
()
class
LJPME
(
Singleton
):
def
__repr__
(
self
):
return
'LJPME'
LJPME
=
LJPME
()
# Enumerated values for constraint type
# Enumerated values for constraint type
class
HBonds
(
Singleton
):
class
HBonds
(
Singleton
):
...
@@ -971,7 +976,7 @@ class ForceField(object):
...
@@ -971,7 +976,7 @@ class ForceField(object):
The Topology for which to create a System
The Topology for which to create a System
nonbondedMethod : object=NoCutoff
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald,
PME,
or
LJ
PME.
nonbondedCutoff : distance=1*nanometer
nonbondedCutoff : distance=1*nanometer
The cutoff distance to use for nonbonded interactions
The cutoff distance to use for nonbonded interactions
constraints : object=None
constraints : object=None
...
@@ -2195,7 +2200,8 @@ class NonbondedGenerator(object):
...
@@ -2195,7 +2200,8 @@ class NonbondedGenerator(object):
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
PME
:
mm
.
NonbondedForce
.
PME
}
PME
:
mm
.
NonbondedForce
.
PME
,
LJPME
:
mm
.
NonbondedForce
.
LJPME
}
if
nonbondedMethod
not
in
methodMap
:
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for NonbondedForce'
)
raise
ValueError
(
'Illegal nonbonded method for NonbondedForce'
)
force
=
mm
.
NonbondedForce
()
force
=
mm
.
NonbondedForce
()
...
@@ -2307,7 +2313,7 @@ class LennardJonesGenerator(object):
...
@@ -2307,7 +2313,7 @@ class LennardJonesGenerator(object):
self
.
force
.
addTabulatedFunction
(
'acoef'
,
mm
.
Discrete2DFunction
(
numLjTypes
,
numLjTypes
,
acoef
))
self
.
force
.
addTabulatedFunction
(
'acoef'
,
mm
.
Discrete2DFunction
(
numLjTypes
,
numLjTypes
,
acoef
))
self
.
force
.
addTabulatedFunction
(
'bcoef'
,
mm
.
Discrete2DFunction
(
numLjTypes
,
numLjTypes
,
bcoef
))
self
.
force
.
addTabulatedFunction
(
'bcoef'
,
mm
.
Discrete2DFunction
(
numLjTypes
,
numLjTypes
,
bcoef
))
self
.
force
.
addPerParticleParameter
(
'type'
)
self
.
force
.
addPerParticleParameter
(
'type'
)
if
nonbondedMethod
in
[
CutoffPeriodic
,
Ewald
,
PME
]:
if
nonbondedMethod
in
[
CutoffPeriodic
,
Ewald
,
PME
,
LJPME
]:
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
CutoffPeriodic
)
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
CutoffPeriodic
)
elif
nonbondedMethod
is
NoCutoff
:
elif
nonbondedMethod
is
NoCutoff
:
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
NoCutoff
)
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
NoCutoff
)
...
...
wrappers/python/simtk/openmm/app/gromacstopfile.py
View file @
53f770f4
...
@@ -552,7 +552,7 @@ class GromacsTopFile(object):
...
@@ -552,7 +552,7 @@ class GromacsTopFile(object):
----------
----------
nonbondedMethod : object=NoCutoff
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald,
PME,
or
LJ
PME.
nonbondedCutoff : distance=1*nanometer
nonbondedCutoff : distance=1*nanometer
The cutoff distance to use for nonbonded interactions
The cutoff distance to use for nonbonded interactions
constraints : object=None
constraints : object=None
...
@@ -570,7 +570,7 @@ class GromacsTopFile(object):
...
@@ -570,7 +570,7 @@ class GromacsTopFile(object):
The solvent dielectric constant to use in the implicit solvent
The solvent dielectric constant to use in the implicit solvent
model.
model.
ewaldErrorTolerance : float=0.0005
ewaldErrorTolerance : float=0.0005
The error tolerance to use if nonbondedMethod is Ewald or PME.
The error tolerance to use if nonbondedMethod is Ewald
, PME,
or
LJ
PME.
removeCMMotion : boolean=True
removeCMMotion : boolean=True
If true, a CMMotionRemover will be added to the System
If true, a CMMotionRemover will be added to the System
hydrogenMass : mass=None
hydrogenMass : mass=None
...
@@ -589,7 +589,7 @@ class GromacsTopFile(object):
...
@@ -589,7 +589,7 @@ class GromacsTopFile(object):
boxVectors
=
self
.
topology
.
getPeriodicBoxVectors
()
boxVectors
=
self
.
topology
.
getPeriodicBoxVectors
()
if
boxVectors
is
not
None
:
if
boxVectors
is
not
None
:
sys
.
setDefaultPeriodicBoxVectors
(
*
boxVectors
)
sys
.
setDefaultPeriodicBoxVectors
(
*
boxVectors
)
elif
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
):
elif
nonbondedMethod
in
(
ff
.
CutoffPeriodic
,
ff
.
Ewald
,
ff
.
PME
,
ff
.
LJPME
):
raise
ValueError
(
'Illegal nonbonded method for a non-periodic system'
)
raise
ValueError
(
'Illegal nonbonded method for a non-periodic system'
)
nb
=
mm
.
NonbondedForce
()
nb
=
mm
.
NonbondedForce
()
sys
.
addForce
(
nb
)
sys
.
addForce
(
nb
)
...
@@ -877,7 +877,8 @@ class GromacsTopFile(object):
...
@@ -877,7 +877,8 @@ class GromacsTopFile(object):
ff
.
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
ff
.
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
ff
.
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
ff
.
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
ff
.
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
ff
.
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
ff
.
PME
:
mm
.
NonbondedForce
.
PME
}
ff
.
PME
:
mm
.
NonbondedForce
.
PME
,
ff
.
LJPME
:
mm
.
NonbondedForce
.
LJPME
}
nb
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
nb
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
nb
.
setCutoffDistance
(
nonbondedCutoff
)
nb
.
setCutoffDistance
(
nonbondedCutoff
)
nb
.
setEwaldErrorTolerance
(
ewaldErrorTolerance
)
nb
.
setEwaldErrorTolerance
(
ewaldErrorTolerance
)
...
...
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
View file @
53f770f4
...
@@ -776,6 +776,8 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No
...
@@ -776,6 +776,8 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
Ewald
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
Ewald
)
elif
nonbondedMethod
==
'PME'
:
elif
nonbondedMethod
==
'PME'
:
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
PME
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
PME
)
elif
nonbondedMethod
==
'LJPME'
:
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
LJPME
)
else
:
else
:
raise
Exception
(
"Cutoff method not understood."
)
raise
Exception
(
"Cutoff method not understood."
)
...
@@ -885,7 +887,7 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No
...
@@ -885,7 +887,7 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No
ii
,
jj
,
chg
,
sig
,
eps
=
force
.
getExceptionParameters
(
i
)
ii
,
jj
,
chg
,
sig
,
eps
=
force
.
getExceptionParameters
(
i
)
cforce
.
addExclusion
(
ii
,
jj
)
cforce
.
addExclusion
(
ii
,
jj
)
# Now set the various properties based on the NonbondedForce object
# Now set the various properties based on the NonbondedForce object
if
nonbondedMethod
in
(
'PME'
,
'Ewald'
,
'CutoffPeriodic'
):
if
nonbondedMethod
in
(
'PME'
,
'LJPME'
,
'Ewald'
,
'CutoffPeriodic'
):
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
cforce
.
setUseLongRangeCorrection
(
True
)
cforce
.
setUseLongRangeCorrection
(
True
)
...
...
wrappers/python/tests/TestAPIUnits.py
View file @
53f770f4
...
@@ -186,6 +186,8 @@ class TestAPIUnits(unittest.TestCase):
...
@@ -186,6 +186,8 @@ class TestAPIUnits(unittest.TestCase):
self
.
assertTrue
(
force
.
usesPeriodicBoundaryConditions
())
self
.
assertTrue
(
force
.
usesPeriodicBoundaryConditions
())
force
.
setNonbondedMethod
(
NonbondedForce
.
PME
)
force
.
setNonbondedMethod
(
NonbondedForce
.
PME
)
self
.
assertTrue
(
force
.
usesPeriodicBoundaryConditions
())
self
.
assertTrue
(
force
.
usesPeriodicBoundaryConditions
())
force
.
setNonbondedMethod
(
NonbondedForce
.
LJPME
)
self
.
assertTrue
(
force
.
usesPeriodicBoundaryConditions
())
def
testCmapForce
(
self
):
def
testCmapForce
(
self
):
""" Tests the CMAPTorsionForce API features """
""" Tests the CMAPTorsionForce API features """
...
...
wrappers/python/tests/TestAmberPrmtopFile.py
View file @
53f770f4
...
@@ -21,12 +21,14 @@ class TestAmberPrmtopFile(unittest.TestCase):
...
@@ -21,12 +21,14 @@ class TestAmberPrmtopFile(unittest.TestCase):
"""Test the AmberPrmtopFile.createSystem() method."""
"""Test the AmberPrmtopFile.createSystem() method."""
def
test_NonbondedMethod
(
self
):
def
test_NonbondedMethod
(
self
):
"""Test all
five
options for the nonbondedMethod parameter."""
"""Test all
six
options for the nonbondedMethod parameter."""
methodMap
=
{
NoCutoff
:
NonbondedForce
.
NoCutoff
,
methodMap
=
{
NoCutoff
:
NonbondedForce
.
NoCutoff
,
CutoffNonPeriodic
:
NonbondedForce
.
CutoffNonPeriodic
,
CutoffNonPeriodic
:
NonbondedForce
.
CutoffNonPeriodic
,
CutoffPeriodic
:
NonbondedForce
.
CutoffPeriodic
,
CutoffPeriodic
:
NonbondedForce
.
CutoffPeriodic
,
Ewald
:
NonbondedForce
.
Ewald
,
PME
:
NonbondedForce
.
PME
}
Ewald
:
NonbondedForce
.
Ewald
,
PME
:
NonbondedForce
.
PME
,
LJPME
:
NonbondedForce
.
LJPME
}
for
method
in
methodMap
:
for
method
in
methodMap
:
system
=
prmtop1
.
createSystem
(
nonbondedMethod
=
method
)
system
=
prmtop1
.
createSystem
(
nonbondedMethod
=
method
)
forces
=
system
.
getForces
()
forces
=
system
.
getForces
()
...
@@ -37,7 +39,7 @@ class TestAmberPrmtopFile(unittest.TestCase):
...
@@ -37,7 +39,7 @@ class TestAmberPrmtopFile(unittest.TestCase):
def
test_Cutoff
(
self
):
def
test_Cutoff
(
self
):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for
method
in
[
CutoffNonPeriodic
,
CutoffPeriodic
,
Ewald
,
PME
]:
for
method
in
[
CutoffNonPeriodic
,
CutoffPeriodic
,
Ewald
,
PME
,
LJPME
]:
system
=
prmtop1
.
createSystem
(
nonbondedMethod
=
method
,
system
=
prmtop1
.
createSystem
(
nonbondedMethod
=
method
,
nonbondedCutoff
=
2
*
nanometer
,
nonbondedCutoff
=
2
*
nanometer
,
constraints
=
HBonds
)
constraints
=
HBonds
)
...
@@ -51,7 +53,7 @@ class TestAmberPrmtopFile(unittest.TestCase):
...
@@ -51,7 +53,7 @@ class TestAmberPrmtopFile(unittest.TestCase):
def
test_EwaldErrorTolerance
(
self
):
def
test_EwaldErrorTolerance
(
self
):
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
for
method
in
[
Ewald
,
PME
]:
for
method
in
[
Ewald
,
PME
,
LJPME
]:
system
=
prmtop1
.
createSystem
(
nonbondedMethod
=
method
,
system
=
prmtop1
.
createSystem
(
nonbondedMethod
=
method
,
ewaldErrorTolerance
=
1e-6
,
ewaldErrorTolerance
=
1e-6
,
constraints
=
HBonds
)
constraints
=
HBonds
)
...
...
wrappers/python/tests/TestDesmondDMSFile.py
View file @
53f770f4
...
@@ -14,12 +14,14 @@ class TestDesmondDMSFile(unittest.TestCase):
...
@@ -14,12 +14,14 @@ class TestDesmondDMSFile(unittest.TestCase):
self
.
dms
=
DesmondDMSFile
(
path
)
self
.
dms
=
DesmondDMSFile
(
path
)
def
test_NonbondedMethod
(
self
):
def
test_NonbondedMethod
(
self
):
"""Test all
five
options for the nonbondedMethod parameter."""
"""Test all
six
options for the nonbondedMethod parameter."""
methodMap
=
{
NoCutoff
:
NonbondedForce
.
NoCutoff
,
methodMap
=
{
NoCutoff
:
NonbondedForce
.
NoCutoff
,
CutoffNonPeriodic
:
NonbondedForce
.
CutoffNonPeriodic
,
CutoffNonPeriodic
:
NonbondedForce
.
CutoffNonPeriodic
,
CutoffPeriodic
:
NonbondedForce
.
CutoffPeriodic
,
CutoffPeriodic
:
NonbondedForce
.
CutoffPeriodic
,
Ewald
:
NonbondedForce
.
Ewald
,
PME
:
NonbondedForce
.
PME
}
Ewald
:
NonbondedForce
.
Ewald
,
PME
:
NonbondedForce
.
PME
,
LJPME
:
NonbondedForce
.
LJPME
}
for
method
in
methodMap
:
for
method
in
methodMap
:
system
=
self
.
dms
.
createSystem
(
nonbondedMethod
=
method
)
system
=
self
.
dms
.
createSystem
(
nonbondedMethod
=
method
)
forces
=
system
.
getForces
()
forces
=
system
.
getForces
()
...
@@ -30,7 +32,7 @@ class TestDesmondDMSFile(unittest.TestCase):
...
@@ -30,7 +32,7 @@ class TestDesmondDMSFile(unittest.TestCase):
def
test_Cutoff
(
self
):
def
test_Cutoff
(
self
):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for
method
in
[
CutoffNonPeriodic
,
CutoffPeriodic
,
Ewald
,
PME
]:
for
method
in
[
CutoffNonPeriodic
,
CutoffPeriodic
,
Ewald
,
PME
,
LJPME
]:
system
=
self
.
dms
.
createSystem
(
nonbondedMethod
=
method
,
system
=
self
.
dms
.
createSystem
(
nonbondedMethod
=
method
,
nonbondedCutoff
=
2
*
nanometer
)
nonbondedCutoff
=
2
*
nanometer
)
cutoff_distance
=
0.0
*
nanometer
cutoff_distance
=
0.0
*
nanometer
...
@@ -43,7 +45,7 @@ class TestDesmondDMSFile(unittest.TestCase):
...
@@ -43,7 +45,7 @@ class TestDesmondDMSFile(unittest.TestCase):
def
test_EwaldErrorTolerance
(
self
):
def
test_EwaldErrorTolerance
(
self
):
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
for
method
in
[
Ewald
,
PME
]:
for
method
in
[
Ewald
,
PME
,
LJPME
]:
system
=
self
.
dms
.
createSystem
(
nonbondedMethod
=
method
,
system
=
self
.
dms
.
createSystem
(
nonbondedMethod
=
method
,
ewaldErrorTolerance
=
1e-6
)
ewaldErrorTolerance
=
1e-6
)
tolerance
=
0
tolerance
=
0
...
...
Prev
1
2
3
4
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