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
9c6011f8
Commit
9c6011f8
authored
Dec 09, 2014
by
peastman
Browse files
Implemented PME for triclinic boxes in reference platform
parent
9e2b5a12
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
128 additions
and
82 deletions
+128
-82
platforms/cpu/src/CpuNonbondedForce.cpp
platforms/cpu/src/CpuNonbondedForce.cpp
+2
-3
platforms/reference/include/ReferencePME.h
platforms/reference/include/ReferencePME.h
+2
-4
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+1
-3
platforms/reference/src/SimTKReference/ReferencePME.cpp
platforms/reference/src/SimTKReference/ReferencePME.cpp
+70
-72
platforms/reference/tests/TestReferenceEwald.cpp
platforms/reference/tests/TestReferenceEwald.cpp
+53
-0
No files found.
platforms/cpu/src/CpuNonbondedForce.cpp
View file @
9c6011f8
...
@@ -190,14 +190,13 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c
...
@@ -190,14 +190,13 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c
if
(
pme
)
{
if
(
pme
)
{
pme_t
pmedata
;
pme_t
pmedata
;
RealOpenMM
virial
[
3
][
3
];
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
posq
[
4
*
i
+
3
];
charges
[
i
]
=
posq
[
4
*
i
+
3
];
Real
OpenMM
boxSize
[
3
]
=
{
periodicBoxSize
[
0
],
periodicBoxSize
[
1
],
periodicBoxSize
[
2
]};
Real
Vec
boxVectors
[
3
]
=
{
Vec3
(
periodicBoxSize
[
0
],
0
,
0
),
Vec3
(
0
,
periodicBoxSize
[
1
],
0
),
Vec3
(
0
,
0
,
periodicBoxSize
[
2
]
)
};
RealOpenMM
recipEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
box
Size
,
&
recipEnergy
,
virial
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
box
Vectors
,
&
recipEnergy
);
if
(
totalEnergy
)
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
*
totalEnergy
+=
recipEnergy
;
pme_destroy
(
pmedata
);
pme_destroy
(
pmedata
);
...
...
platforms/reference/include/ReferencePME.h
View file @
9c6011f8
...
@@ -72,16 +72,14 @@ pme_init(pme_t * ppme,
...
@@ -72,16 +72,14 @@ pme_init(pme_t * ppme,
* charge Array of charges (units of e)
* charge Array of charges (units of e)
* box Simulation cell dimensions (nm)
* box Simulation cell dimensions (nm)
* energy Total energy (will be written in units of kJ/mol)
* energy Total energy (will be written in units of kJ/mol)
* pme_virial Long-range part of the virial, output.
*/
*/
int
OPENMM_EXPORT
int
OPENMM_EXPORT
pme_exec
(
pme_t
pme
,
pme_exec
(
pme_t
pme
,
const
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
const
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
const
std
::
vector
<
RealOpenMM
>&
charges
,
const
std
::
vector
<
RealOpenMM
>&
charges
,
const
RealOpenMM
periodicBoxSize
[
3
],
const
OpenMM
::
RealVec
periodicBoxVectors
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
*
energy
);
RealOpenMM
pme_virial
[
3
][
3
]);
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
9c6011f8
...
@@ -230,15 +230,13 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
...
@@ -230,15 +230,13 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
if
(
pme
&&
includeReciprocal
)
{
if
(
pme
&&
includeReciprocal
)
{
pme_t
pmedata
;
/* abstract handle for PME data */
pme_t
pmedata
;
/* abstract handle for PME data */
RealOpenMM
virial
[
3
][
3
];
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
RealOpenMM
periodicBoxSize
[]
=
{
periodicBoxVectors
[
0
][
0
],
periodicBoxVectors
[
1
][
1
],
periodicBoxVectors
[
2
][
2
]};
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxSize
,
&
recipEnergy
,
virial
);
if
(
totalEnergy
)
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
*
totalEnergy
+=
recipEnergy
;
...
...
platforms/reference/src/SimTKReference/ReferencePME.cpp
View file @
9c6011f8
...
@@ -192,11 +192,21 @@ pme_calculate_bsplines_moduli(pme_t pme)
...
@@ -192,11 +192,21 @@ pme_calculate_bsplines_moduli(pme_t pme)
}
}
static
void
invert_box_vectors
(
const
RealVec
boxVectors
[
3
],
RealVec
recipBoxVectors
[
3
])
{
RealOpenMM
determinant
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
assert
(
determinant
>
0
);
RealOpenMM
scale
=
1.0
/
determinant
;
recipBoxVectors
[
0
]
=
RealVec
(
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
],
0
,
0
)
*
scale
;
recipBoxVectors
[
1
]
=
RealVec
(
-
boxVectors
[
1
][
0
]
*
boxVectors
[
2
][
2
],
boxVectors
[
0
][
0
]
*
boxVectors
[
2
][
2
],
0
)
*
scale
;
recipBoxVectors
[
2
]
=
RealVec
(
boxVectors
[
1
][
0
]
*
boxVectors
[
2
][
1
]
-
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
0
],
-
boxVectors
[
0
][
0
]
*
boxVectors
[
2
][
1
],
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
])
*
scale
;
}
static
void
static
void
pme_update_grid_index_and_fraction
(
pme_t
pme
,
pme_update_grid_index_and_fraction
(
pme_t
pme
,
const
vector
<
RealVec
>&
atomCoordinates
,
const
vector
<
RealVec
>&
atomCoordinates
,
const
RealOpenMM
periodicBoxSize
[
3
])
const
RealVec
periodicBoxVectors
[
3
],
const
RealVec
recipBoxVectors
[
3
])
{
{
int
i
;
int
i
;
int
d
;
int
d
;
...
@@ -204,8 +214,6 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -204,8 +214,6 @@ pme_update_grid_index_and_fraction(pme_t pme,
int
ti
;
int
ti
;
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
{
for
(
d
=
0
;
d
<
3
;
d
++
)
{
{
/* Index calculation (Look mom, no conditionals!):
/* Index calculation (Look mom, no conditionals!):
*
*
...
@@ -243,9 +251,12 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -243,9 +251,12 @@ pme_update_grid_index_and_fraction(pme_t pme,
* numerical problems, so this shouldnt cause any problems.
* numerical problems, so this shouldnt cause any problems.
* (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!)
* (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!)
*/
*/
RealOpenMM
coord
=
atomCoordinates
[
i
][
d
];
RealVec
coord
=
atomCoordinates
[
i
];
coord
-=
floor
(
coord
/
periodicBoxSize
[
d
])
*
periodicBoxSize
[
d
];
for
(
d
=
0
;
d
<
3
;
d
++
)
t
=
(
coord
/
periodicBoxSize
[
d
])
*
pme
->
ngrid
[
d
];
coord
[
d
]
-=
floor
(
coord
[
d
]
*
recipBoxVectors
[
d
][
d
])
*
periodicBoxVectors
[
d
][
d
];
for
(
d
=
0
;
d
<
3
;
d
++
)
{
t
=
(
coord
[
0
]
*
recipBoxVectors
[
0
][
d
]
+
coord
[
1
]
*
recipBoxVectors
[
1
][
d
]
+
coord
[
2
]
*
recipBoxVectors
[
2
][
d
])
*
pme
->
ngrid
[
d
];
ti
=
(
int
)
t
;
ti
=
(
int
)
t
;
pme
->
particlefraction
[
i
][
d
]
=
t
-
ti
;
pme
->
particlefraction
[
i
][
d
]
=
t
-
ti
;
...
@@ -397,9 +408,9 @@ pme_grid_spread_charge(pme_t pme, const vector<RealOpenMM>& charges)
...
@@ -397,9 +408,9 @@ pme_grid_spread_charge(pme_t pme, const vector<RealOpenMM>& charges)
static
void
static
void
pme_reciprocal_convolution
(
pme_t
pme
,
pme_reciprocal_convolution
(
pme_t
pme
,
const
Real
OpenMM
periodicBox
Size
[
3
],
const
Real
Vec
periodicBox
Vectors
[
3
],
RealOpenMM
*
energy
,
const
RealVec
recipBoxVectors
[
3
]
,
RealOpenMM
pme_virial
[
3
][
3
]
)
RealOpenMM
*
energy
)
{
{
int
kx
,
ky
,
kz
;
int
kx
,
ky
,
kz
;
int
nx
,
ny
,
nz
;
int
nx
,
ny
,
nz
;
...
@@ -424,7 +435,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -424,7 +435,7 @@ pme_reciprocal_convolution(pme_t pme,
one_4pi_eps
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
/
pme
->
epsilon_r
);
one_4pi_eps
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
/
pme
->
epsilon_r
);
factor
=
(
RealOpenMM
)
(
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
));
factor
=
(
RealOpenMM
)
(
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
));
boxfactor
=
(
RealOpenMM
)
(
M_PI
*
periodicBox
Size
[
0
]
*
periodicBox
Size
[
1
]
*
periodicBox
Size
[
2
]);
boxfactor
=
(
RealOpenMM
)
(
M_PI
*
periodicBox
Vectors
[
0
]
[
0
]
*
periodicBox
Vectors
[
1
]
[
1
]
*
periodicBox
Vectors
[
2
]
[
2
]);
esum
=
0
;
esum
=
0
;
virxx
=
0
;
virxx
=
0
;
...
@@ -442,14 +453,14 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -442,14 +453,14 @@ pme_reciprocal_convolution(pme_t pme,
{
{
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
mx
=
(
RealOpenMM
)
((
kx
<
maxkx
)
?
kx
:
(
kx
-
nx
));
mx
=
(
RealOpenMM
)
((
kx
<
maxkx
)
?
kx
:
(
kx
-
nx
));
mhx
=
mx
/
periodicBoxSize
[
0
];
mhx
=
mx
*
recipBoxVectors
[
0
]
[
0
];
bx
=
boxfactor
*
pme
->
bsplines_moduli
[
0
][
kx
];
bx
=
boxfactor
*
pme
->
bsplines_moduli
[
0
][
kx
];
for
(
ky
=
0
;
ky
<
ny
;
ky
++
)
for
(
ky
=
0
;
ky
<
ny
;
ky
++
)
{
{
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
my
=
(
RealOpenMM
)
((
ky
<
maxky
)
?
ky
:
(
ky
-
ny
));
my
=
(
RealOpenMM
)
((
ky
<
maxky
)
?
ky
:
(
ky
-
ny
));
mhy
=
m
y
/
periodicBoxSize
[
1
];
mhy
=
m
x
*
recipBoxVectors
[
1
][
0
]
+
my
*
recipBoxVectors
[
1
]
[
1
];
by
=
pme
->
bsplines_moduli
[
1
][
ky
];
by
=
pme
->
bsplines_moduli
[
1
][
ky
];
for
(
kz
=
0
;
kz
<
nz
;
kz
++
)
for
(
kz
=
0
;
kz
<
nz
;
kz
++
)
...
@@ -469,7 +480,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -469,7 +480,7 @@ pme_reciprocal_convolution(pme_t pme,
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
/* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */
mz
=
(
RealOpenMM
)
((
kz
<
maxkz
)
?
kz
:
(
kz
-
nz
));
mz
=
(
RealOpenMM
)
((
kz
<
maxkz
)
?
kz
:
(
kz
-
nz
));
mhz
=
m
z
/
periodicBoxSize
[
2
];
mhz
=
m
x
*
recipBoxVectors
[
2
][
0
]
+
my
*
recipBoxVectors
[
2
][
1
]
+
mz
*
recipBoxVectors
[
2
]
[
2
];
/* Pointer to the grid cell in question */
/* Pointer to the grid cell in question */
ptr
=
pme
->
grid
+
kx
*
ny
*
nz
+
ky
*
nz
+
kz
;
ptr
=
pme
->
grid
+
kx
*
ny
*
nz
+
ky
*
nz
+
kz
;
...
@@ -494,24 +505,9 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -494,24 +505,9 @@ pme_reciprocal_convolution(pme_t pme,
/* Long-range PME contribution to the energy for this frequency */
/* Long-range PME contribution to the energy for this frequency */
ets2
=
eterm
*
struct2
;
ets2
=
eterm
*
struct2
;
esum
+=
ets2
;
esum
+=
ets2
;
/* PME long-range contribution to atomic virial. Since it is symmetric, we only calculate half the matrix inside this loop. */
vfactor
=
(
factor
*
m2
+
1
)
*
2
/
m2
;
virxx
+=
ets2
*
(
vfactor
*
mhx
*
mhx
-
1
);
virxy
+=
ets2
*
vfactor
*
mhx
*
mhy
;
virxz
+=
ets2
*
vfactor
*
mhx
*
mhz
;
viryy
+=
ets2
*
(
vfactor
*
mhy
*
mhy
-
1
);
viryz
+=
ets2
*
vfactor
*
mhy
*
mhz
;
virzz
+=
ets2
*
(
vfactor
*
mhz
*
mhz
-
1
);
}
}
}
}
}
}
pme_virial
[
0
][
0
]
=
(
RealOpenMM
)
(
0.25
*
virxx
);
pme_virial
[
1
][
1
]
=
(
RealOpenMM
)
(
0.25
*
viryy
);
pme_virial
[
2
][
2
]
=
(
RealOpenMM
)
(
0.25
*
virzz
);
pme_virial
[
0
][
1
]
=
pme_virial
[
1
][
0
]
=
(
RealOpenMM
)
(
0.25
*
virxy
);
pme_virial
[
0
][
2
]
=
pme_virial
[
2
][
0
]
=
(
RealOpenMM
)
(
0.25
*
virxz
);
pme_virial
[
1
][
2
]
=
pme_virial
[
2
][
1
]
=
(
RealOpenMM
)
(
0.25
*
viryz
);
/* The factor 0.5 is nothing special, but it is better to have it here than inside the loop :-) */
/* The factor 0.5 is nothing special, but it is better to have it here than inside the loop :-) */
*
energy
=
(
RealOpenMM
)
(
0.5
*
esum
);
*
energy
=
(
RealOpenMM
)
(
0.5
*
esum
);
...
@@ -520,7 +516,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -520,7 +516,7 @@ pme_reciprocal_convolution(pme_t pme,
static
void
static
void
pme_grid_interpolate_force
(
pme_t
pme
,
pme_grid_interpolate_force
(
pme_t
pme
,
const
Real
OpenMM
periodicBoxSize
[
3
],
const
Real
Vec
recipBoxVectors
[
3
],
const
vector
<
RealOpenMM
>&
charges
,
const
vector
<
RealOpenMM
>&
charges
,
vector
<
RealVec
>&
forces
)
vector
<
RealVec
>&
forces
)
{
{
...
@@ -610,9 +606,9 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -610,9 +606,9 @@ pme_grid_interpolate_force(pme_t pme,
}
}
}
}
/* Update memory force, note that we multiply by charge and some box stuff */
/* Update memory force, note that we multiply by charge and some box stuff */
forces
[
i
][
0
]
-=
q
*
fx
*
nx
/
periodicBoxSize
[
0
]
;
forces
[
i
][
0
]
-=
q
*
(
fx
*
nx
*
recipBoxVectors
[
0
][
0
])
;
forces
[
i
][
1
]
-=
q
*
fy
*
ny
/
periodicBoxSize
[
1
]
;
forces
[
i
][
1
]
-=
q
*
(
fx
*
nx
*
recipBoxVectors
[
1
][
0
]
+
fy
*
ny
*
recipBoxVectors
[
1
][
1
])
;
forces
[
i
][
2
]
-=
q
*
fz
*
nz
/
periodicBoxSize
[
2
]
;
forces
[
i
][
2
]
-=
q
*
(
fx
*
nx
*
recipBoxVectors
[
2
][
0
]
+
fy
*
ny
*
recipBoxVectors
[
2
][
1
]
+
fz
*
nz
*
recipBoxVectors
[
2
][
2
])
;
}
}
}
}
...
@@ -669,12 +665,14 @@ int pme_exec(pme_t pme,
...
@@ -669,12 +665,14 @@ int pme_exec(pme_t pme,
const
vector
<
RealVec
>&
atomCoordinates
,
const
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
forces
,
vector
<
RealVec
>&
forces
,
const
vector
<
RealOpenMM
>&
charges
,
const
vector
<
RealOpenMM
>&
charges
,
const
RealOpenMM
periodicBoxSize
[
3
],
const
RealVec
periodicBoxVectors
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
*
energy
)
RealOpenMM
pme_virial
[
3
][
3
])
{
{
/* Routine is called with coordinates in x, a box, and charges in q */
/* Routine is called with coordinates in x, a box, and charges in q */
RealVec
recipBoxVectors
[
3
];
invert_box_vectors
(
periodicBoxVectors
,
recipBoxVectors
);
/* Before we can do the actual interpolation, we need to recalculate and update
/* Before we can do the actual interpolation, we need to recalculate and update
* the indices for each particle in the charge grid (initialized in pme_init()),
* the indices for each particle in the charge grid (initialized in pme_init()),
* and what its fractional offset in this grid cell is.
* and what its fractional offset in this grid cell is.
...
@@ -683,7 +681,7 @@ int pme_exec(pme_t pme,
...
@@ -683,7 +681,7 @@ int pme_exec(pme_t pme,
/* Update charge grid indices and fractional offsets for each atom.
/* Update charge grid indices and fractional offsets for each atom.
* The indices/fractions are stored internally in the pme datatype
* The indices/fractions are stored internally in the pme datatype
*/
*/
pme_update_grid_index_and_fraction
(
pme
,
atomCoordinates
,
periodicBox
Size
);
pme_update_grid_index_and_fraction
(
pme
,
atomCoordinates
,
periodicBox
Vectors
,
recipBoxVectors
);
/* Calculate bsplines (and their differentials) from current fractional coordinates, store in pme structure */
/* Calculate bsplines (and their differentials) from current fractional coordinates, store in pme structure */
pme_update_bsplines
(
pme
);
pme_update_bsplines
(
pme
);
...
@@ -695,13 +693,13 @@ int pme_exec(pme_t pme,
...
@@ -695,13 +693,13 @@ int pme_exec(pme_t pme,
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_FORWARD
,
pme
->
grid
,
pme
->
grid
);
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_FORWARD
,
pme
->
grid
,
pme
->
grid
);
/* solve in k-space */
/* solve in k-space */
pme_reciprocal_convolution
(
pme
,
periodicBox
Size
,
energy
,
pme_virial
);
pme_reciprocal_convolution
(
pme
,
periodicBox
Vectors
,
recipBoxVectors
,
energy
);
/* do 3d-invfft */
/* do 3d-invfft */
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_BACKWARD
,
pme
->
grid
,
pme
->
grid
);
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_BACKWARD
,
pme
->
grid
,
pme
->
grid
);
/* Get the particle forces from the grid and bsplines in the pme structure */
/* Get the particle forces from the grid and bsplines in the pme structure */
pme_grid_interpolate_force
(
pme
,
periodicBoxSize
,
charges
,
forces
);
pme_grid_interpolate_force
(
pme
,
recipBoxVectors
,
charges
,
forces
);
return
0
;
return
0
;
}
}
...
...
platforms/reference/tests/TestReferenceEwald.cpp
View file @
9c6011f8
...
@@ -302,6 +302,58 @@ void testWaterSystem() {
...
@@ -302,6 +302,58 @@ void testWaterSystem() {
}
}
void
testTriclinic
()
{
// Create a triclinic box containing eight particles.
ReferencePlatform
platform
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
2.5
,
0
,
0
),
Vec3
(
0.5
,
3.0
,
0
),
Vec3
(
0.7
,
0.9
,
3.5
));
for
(
int
i
=
0
;
i
<
8
;
i
++
)
system
.
addParticle
(
1.0
);
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
force
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
force
->
setCutoffDistance
(
1.0
);
force
->
setPMEParameters
(
3.45891
,
32
,
40
,
48
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
force
->
addParticle
(
-
1
,
0.440104
,
0.4184
);
// Cl parameters
for
(
int
i
=
0
;
i
<
4
;
i
++
)
force
->
addParticle
(
1
,
0.332840
,
0.0115897
);
// Na parameters
vector
<
Vec3
>
positions
(
8
);
positions
[
0
]
=
Vec3
(
1.744
,
2.788
,
3.162
);
positions
[
1
]
=
Vec3
(
1.048
,
0.762
,
2.340
);
positions
[
2
]
=
Vec3
(
2.489
,
1.570
,
2.817
);
positions
[
3
]
=
Vec3
(
1.027
,
1.893
,
3.271
);
positions
[
4
]
=
Vec3
(
0.937
,
0.825
,
0.009
);
positions
[
5
]
=
Vec3
(
2.290
,
1.887
,
3.352
);
positions
[
6
]
=
Vec3
(
1.266
,
1.111
,
2.894
);
positions
[
7
]
=
Vec3
(
0.933
,
1.862
,
3.490
);
// Compute the forces and energy.
VerletIntegrator
integ
(
0.001
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
// Compare them to values computed by Gromacs.
double
expectedEnergy
=
-
963.370
;
vector
<
Vec3
>
expectedForce
(
8
);
expectedForce
[
0
]
=
Vec3
(
4.25253e+01
,
-
1.23503e+02
,
1.22139e+02
);
expectedForce
[
1
]
=
Vec3
(
9.74752e+01
,
1.68213e+02
,
1.93169e+02
);
expectedForce
[
2
]
=
Vec3
(
-
1.50348e+02
,
1.29165e+02
,
3.70435e+02
);
expectedForce
[
3
]
=
Vec3
(
9.18644e+02
,
-
3.52571e+00
,
-
1.34772e+03
);
expectedForce
[
4
]
=
Vec3
(
-
1.61193e+02
,
9.01528e+01
,
-
7.12904e+01
);
expectedForce
[
5
]
=
Vec3
(
2.82630e+02
,
2.78029e+01
,
-
3.72864e+02
);
expectedForce
[
6
]
=
Vec3
(
-
1.47454e+02
,
-
2.14448e+02
,
-
3.55789e+02
);
expectedForce
[
7
]
=
Vec3
(
-
8.82195e+02
,
-
7.39132e+01
,
1.46202e+03
);
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
ASSERT_EQUAL_VEC
(
expectedForce
[
i
],
state
.
getForces
()[
i
],
1e-4
);
}
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-4
);
}
void
testErrorTolerance
(
NonbondedForce
::
NonbondedMethod
method
)
{
void
testErrorTolerance
(
NonbondedForce
::
NonbondedMethod
method
)
{
// Create a cloud of random point charges.
// Create a cloud of random point charges.
...
@@ -409,6 +461,7 @@ int main() {
...
@@ -409,6 +461,7 @@ int main() {
testEwaldPME
();
testEwaldPME
();
// testEwald2Ions();
// testEwald2Ions();
// testWaterSystem();
// testWaterSystem();
testTriclinic
();
testErrorTolerance
(
NonbondedForce
::
Ewald
);
testErrorTolerance
(
NonbondedForce
::
Ewald
);
testErrorTolerance
(
NonbondedForce
::
PME
);
testErrorTolerance
(
NonbondedForce
::
PME
);
testPMEParameters
();
testPMEParameters
();
...
...
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