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
6186c067
Commit
6186c067
authored
Nov 19, 2009
by
Peter Eastman
Browse files
Fixed compiler warnings
parent
cd418100
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
431 additions
and
431 deletions
+431
-431
platforms/reference/src/SimTKReference/PME.cpp
platforms/reference/src/SimTKReference/PME.cpp
+412
-412
platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp
...s/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp
+2
-2
platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp
...ference/src/SimTKReference/ReferenceCustomExternalIxn.cpp
+4
-4
platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp
...rms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp
+4
-4
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+9
-9
No files found.
platforms/reference/src/SimTKReference/PME.cpp
View file @
6186c067
...
@@ -42,24 +42,24 @@ typedef int ivec[3];
...
@@ -42,24 +42,24 @@ typedef int ivec[3];
struct
pme
struct
pme
{
{
int
natoms
;
int
natoms
;
RealOpenMM
ewaldcoeff
;
RealOpenMM
ewaldcoeff
;
t_complex
*
grid
;
/* Memory for the grid we spread charges on.
t_complex
*
grid
;
/* Memory for the grid we spread charges on.
* Element (i,j,k) is accessed as:
* Element (i,j,k) is accessed as:
* grid[i*ngrid[1]*ngrid[2] + j*ngrid[2] + k]
* grid[i*ngrid[1]*ngrid[2] + j*ngrid[2] + k]
*/
*/
int
ngrid
[
3
];
/* Total grid dimensions (all data is complex!) */
int
ngrid
[
3
];
/* Total grid dimensions (all data is complex!) */
fftpack_t
fftplan
;
/* Handle to fourier transform setup */
fftpack_t
fftplan
;
/* Handle to fourier transform setup */
int
order
;
/* PME interpolation order. Almost always 4 */
int
order
;
/* PME interpolation order. Almost always 4 */
/* Data for bspline interpolation, see the Essman PME paper */
/* Data for bspline interpolation, see the Essman PME paper */
RealOpenMM
*
bsplines_moduli
[
3
];
/* 3 pointers, to x/y/z bspline moduli, each of length ngrid[x/y/z] */
RealOpenMM
*
bsplines_moduli
[
3
];
/* 3 pointers, to x/y/z bspline moduli, each of length ngrid[x/y/z] */
RealOpenMM
*
bsplines_theta
[
3
];
/* each of x/y/z has length order*natoms */
RealOpenMM
*
bsplines_theta
[
3
];
/* each of x/y/z has length order*natoms */
RealOpenMM
*
bsplines_dtheta
[
3
];
/* each of x/y/z has length order*natoms */
RealOpenMM
*
bsplines_dtheta
[
3
];
/* each of x/y/z has length order*natoms */
ivec
*
particleindex
;
/* Array of length natoms. Each element is
ivec
*
particleindex
;
/* Array of length natoms. Each element is
* an ivec (3 ints) that specify the grid
* an ivec (3 ints) that specify the grid
* indices for that particular atom. Updated every step!
* indices for that particular atom. Updated every step!
*/
*/
...
@@ -83,7 +83,7 @@ struct pme
...
@@ -83,7 +83,7 @@ struct pme
* the central cell, i.e., in this case we would assume all coordinates fall in -10 nm < x,y,z < 20 nm.
* the central cell, i.e., in this case we would assume all coordinates fall in -10 nm < x,y,z < 20 nm.
*/
*/
RealOpenMM
epsilon_r
;
/* Dielectric coefficient to use, typically 1.0 */
RealOpenMM
epsilon_r
;
/* Dielectric coefficient to use, typically 1.0 */
};
};
...
@@ -95,128 +95,128 @@ struct pme
...
@@ -95,128 +95,128 @@ struct pme
static
void
static
void
pme_calculate_bsplines_moduli
(
pme_t
pme
)
pme_calculate_bsplines_moduli
(
pme_t
pme
)
{
{
int
nmax
;
int
nmax
;
int
i
,
j
,
k
,
l
,
d
;
int
i
,
j
,
k
,
l
,
d
;
int
order
;
int
order
;
int
ndata
;
int
ndata
;
RealOpenMM
*
data
;
RealOpenMM
*
data
;
RealOpenMM
*
ddata
;
RealOpenMM
*
ddata
;
RealOpenMM
*
bsplines_data
;
RealOpenMM
*
bsplines_data
;
RealOpenMM
div
;
RealOpenMM
div
;
RealOpenMM
sc
,
ss
,
arg
;
RealOpenMM
sc
,
ss
,
arg
;
nmax
=
0
;
nmax
=
0
;
for
(
d
=
0
;
d
<
3
;
d
++
)
for
(
d
=
0
;
d
<
3
;
d
++
)
{
{
nmax
=
(
pme
->
ngrid
[
d
]
>
nmax
)
?
pme
->
ngrid
[
d
]
:
nmax
;
nmax
=
(
pme
->
ngrid
[
d
]
>
nmax
)
?
pme
->
ngrid
[
d
]
:
nmax
;
pme
->
bsplines_moduli
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme
->
ngrid
[
d
]);
pme
->
bsplines_moduli
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme
->
ngrid
[
d
]);
}
order
=
pme
->
order
;
/* temp storage in this routine */
data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
ddata
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
bsplines_data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
nmax
);
data
[
order
-
1
]
=
0
;
data
[
1
]
=
0
;
data
[
0
]
=
1
;
for
(
k
=
3
;
k
<
order
;
k
++
)
{
div
=
1.0
/
(
k
-
1.0
);
data
[
k
-
1
]
=
0
;
for
(
l
=
1
;
l
<
(
k
-
1
);
l
++
)
{
data
[
k
-
l
-
1
]
=
div
*
(
l
*
data
[
k
-
l
-
2
]
+
(
k
-
l
)
*
data
[
k
-
l
-
1
]);
}
data
[
0
]
=
div
*
data
[
0
];
}
/* differentiate */
ddata
[
0
]
=-
data
[
0
];
for
(
k
=
1
;
k
<
order
;
k
++
)
{
ddata
[
k
]
=
data
[
k
-
1
]
-
data
[
k
];
}
div
=
1.0
/
(
order
-
1
);
data
[
order
-
1
]
=
0
;
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
{
data
[
order
-
l
-
1
]
=
div
*
(
l
*
data
[
order
-
l
-
2
]
+
(
order
-
l
)
*
data
[
order
-
l
-
1
]);
}
data
[
0
]
=
div
*
data
[
0
];
for
(
i
=
0
;
i
<
nmax
;
i
++
)
{
bsplines_data
[
i
]
=
0
;
}
for
(
i
=
1
;
i
<=
order
;
i
++
)
{
bsplines_data
[
i
]
=
data
[
i
-
1
];
}
}
/* Evaluate the actual bspline moduli for X/Y/Z */
order
=
pme
->
order
;
for
(
d
=
0
;
d
<
3
;
d
++
)
{
/* temp storage in this routine */
ndata
=
pme
->
ngrid
[
d
];
data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
for
(
i
=
0
;
i
<
ndata
;
i
++
)
ddata
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
{
bsplines_data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
nmax
);
sc
=
ss
=
0
;
for
(
j
=
0
;
j
<
ndata
;
j
++
)
data
[
order
-
1
]
=
0
;
{
data
[
1
]
=
0
;
arg
=
(
2.0
*
M_PI
*
i
*
j
)
/
ndata
;
data
[
0
]
=
1
;
sc
+=
bsplines_data
[
j
]
*
cos
(
arg
);
ss
+=
bsplines_data
[
j
]
*
sin
(
arg
);
for
(
k
=
3
;
k
<
order
;
k
++
)
}
{
pme
->
bsplines_moduli
[
d
][
i
]
=
sc
*
sc
+
ss
*
ss
;
div
=
(
RealOpenMM
)
(
1.0
/
(
k
-
1.0
));
}
data
[
k
-
1
]
=
0
;
for
(
i
=
0
;
i
<
ndata
;
i
++
)
for
(
l
=
1
;
l
<
(
k
-
1
);
l
++
)
{
{
if
(
pme
->
bsplines_moduli
[
d
][
i
]
<
1.0e-7
)
data
[
k
-
l
-
1
]
=
div
*
(
l
*
data
[
k
-
l
-
2
]
+
(
k
-
l
)
*
data
[
k
-
l
-
1
]);
{
}
pme
->
bsplines_moduli
[
d
][
i
]
=
(
pme
->
bsplines_moduli
[
d
][
i
-
1
]
+
pme
->
bsplines_moduli
[
d
][
i
+
1
])
*
0.5
;
data
[
0
]
=
div
*
data
[
0
];
}
}
}
}
/* differentiate */
ddata
[
0
]
=-
data
[
0
];
/* Release temp storage */
for
(
k
=
1
;
k
<
order
;
k
++
)
free
(
data
);
{
free
(
ddata
);
ddata
[
k
]
=
data
[
k
-
1
]
-
data
[
k
];
free
(
bsplines_data
);
}
div
=
(
RealOpenMM
)
(
1.0
/
(
order
-
1
));
data
[
order
-
1
]
=
0
;
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
{
data
[
order
-
l
-
1
]
=
div
*
(
l
*
data
[
order
-
l
-
2
]
+
(
order
-
l
)
*
data
[
order
-
l
-
1
]);
}
data
[
0
]
=
div
*
data
[
0
];
for
(
i
=
0
;
i
<
nmax
;
i
++
)
{
bsplines_data
[
i
]
=
0
;
}
for
(
i
=
1
;
i
<=
order
;
i
++
)
{
bsplines_data
[
i
]
=
data
[
i
-
1
];
}
/* Evaluate the actual bspline moduli for X/Y/Z */
for
(
d
=
0
;
d
<
3
;
d
++
)
{
ndata
=
pme
->
ngrid
[
d
];
for
(
i
=
0
;
i
<
ndata
;
i
++
)
{
sc
=
ss
=
0
;
for
(
j
=
0
;
j
<
ndata
;
j
++
)
{
arg
=
(
RealOpenMM
)
((
2.0
*
M_PI
*
i
*
j
)
/
ndata
);
sc
+=
bsplines_data
[
j
]
*
cos
(
arg
);
ss
+=
bsplines_data
[
j
]
*
sin
(
arg
);
}
pme
->
bsplines_moduli
[
d
][
i
]
=
sc
*
sc
+
ss
*
ss
;
}
for
(
i
=
0
;
i
<
ndata
;
i
++
)
{
if
(
pme
->
bsplines_moduli
[
d
][
i
]
<
1.0e-7
)
{
pme
->
bsplines_moduli
[
d
][
i
]
=
(
pme
->
bsplines_moduli
[
d
][
i
-
1
]
+
pme
->
bsplines_moduli
[
d
][
i
+
1
])
/
2
;
}
}
}
/* Release temp storage */
free
(
data
);
free
(
ddata
);
free
(
bsplines_data
);
}
}
static
void
static
void
pme_update_grid_index_and_fraction
(
pme_t
pme
,
pme_update_grid_index_and_fraction
(
pme_t
pme
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomCoordinates
,
const
RealOpenMM
periodicBoxSize
[
3
])
const
RealOpenMM
periodicBoxSize
[
3
])
{
{
int
i
;
int
i
;
int
d
;
int
d
;
RealOpenMM
t
;
RealOpenMM
t
;
int
ti
;
int
ti
;
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
{
{
for
(
d
=
0
;
d
<
3
;
d
++
)
for
(
d
=
0
;
d
<
3
;
d
++
)
{
{
/* Index calculation (Look mom, no conditionals!):
/* Index calculation (Look mom, no conditionals!):
*
*
* Both for Cuda and modern CPUs it is nice to avoid conditionals, but we still need to apply periodic boundary conditions.
* Both for Cuda and modern CPUs it is nice to avoid conditionals, but we still need to apply periodic boundary conditions.
* Instead of having loops to add/subtract the box dimension, we do it this way:
* Instead of having loops to add/subtract the box dimension, we do it this way:
*
*
* 1. First add the box size, to make sure this atom coordinate isnt -0.1 or something.
* 1. First add the box size, to make sure this atom coordinate isnt -0.1 or something.
* After this we assume all fractional box positions are *positive*.
* After this we assume all fractional box positions are *positive*.
* The reason for this is that we always want to round coordinates _down_ to get
* The reason for this is that we always want to round coordinates _down_ to get
* their grid index, and when taking the integer part of -3.4 we would get -3, not -4 as we want.
* their grid index, and when taking the integer part of -3.4 we would get -3, not -4 as we want.
* Since we anyway need the grid indices to fall in the central box, it is more convenient
* Since we anyway need the grid indices to fall in the central box, it is more convenient
* to first manipulate the coordinates to be positive.
* to first manipulate the coordinates to be positive.
* 2. Convert to integer grid index
* 2. Convert to integer grid index
* Since we have added a whole box unit in step 1, this index might actually be larger than
* Since we have added a whole box unit in step 1, this index might actually be larger than
* the grid dimension. Examples, assuming 10*10*10nm box and grid dimension 100*100*100 (spacing 0.1 nm):
* the grid dimension. Examples, assuming 10*10*10nm box and grid dimension 100*100*100 (spacing 0.1 nm):
*
*
...
@@ -230,7 +230,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -230,7 +230,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
*
*
* The fraction is calculates as t-ti, which becomes { 0.43 , 0.35 , 0.7 }
* The fraction is calculates as t-ti, which becomes { 0.43 , 0.35 , 0.7 }
*
*
* 3. Take the first integer index part (which can be larger than the grid) modulo the grid dimension
* 3. Take the first integer index part (which can be larger than the grid) modulo the grid dimension
*
*
* Now we get { 5 , 62 , 92 }
* Now we get { 5 , 62 , 92 }
*
*
...
@@ -240,14 +240,14 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -240,14 +240,14 @@ pme_update_grid_index_and_fraction(pme_t pme,
* In practice, MD programs will apply PBC to reset particles inside the central box to avoid
* In practice, MD programs will apply PBC to reset particles inside the central box to avoid
* 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!)
*/
*/
t
=
(
atomCoordinates
[
i
][
d
]
/
periodicBoxSize
[
d
]
+
1
.0
)
*
pme
->
ngrid
[
d
];
t
=
(
atomCoordinates
[
i
][
d
]
/
periodicBoxSize
[
d
]
+
1
)
*
pme
->
ngrid
[
d
];
ti
=
(
int
)
t
;
ti
=
(
int
)
t
;
pme
->
particlefraction
[
i
][
d
]
=
t
-
ti
;
pme
->
particlefraction
[
i
][
d
]
=
t
-
ti
;
pme
->
particleindex
[
i
][
d
]
=
ti
%
pme
->
ngrid
[
d
];
pme
->
particleindex
[
i
][
d
]
=
ti
%
pme
->
ngrid
[
d
];
}
}
}
}
}
}
...
@@ -259,96 +259,96 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -259,96 +259,96 @@ pme_update_grid_index_and_fraction(pme_t pme,
static
void
static
void
pme_update_bsplines
(
pme_t
pme
)
pme_update_bsplines
(
pme_t
pme
)
{
{
int
i
,
j
,
k
,
l
;
int
i
,
j
,
k
,
l
;
int
order
;
int
order
;
RealOpenMM
dr
,
div
;
RealOpenMM
dr
,
div
;
RealOpenMM
*
data
;
RealOpenMM
*
data
;
RealOpenMM
*
ddata
;
RealOpenMM
*
ddata
;
order
=
pme
->
order
;
order
=
pme
->
order
;
for
(
i
=
0
;
(
i
<
pme
->
natoms
);
i
++
)
for
(
i
=
0
;
(
i
<
pme
->
natoms
);
i
++
)
{
{
for
(
j
=
0
;
j
<
3
;
j
++
)
for
(
j
=
0
;
j
<
3
;
j
++
)
{
{
/* dr is relative offset from lower cell limit */
/* dr is relative offset from lower cell limit */
dr
=
pme
->
particlefraction
[
i
][
j
];
dr
=
pme
->
particlefraction
[
i
][
j
];
data
=
&
(
pme
->
bsplines_theta
[
j
][
i
*
order
]);
data
=
&
(
pme
->
bsplines_theta
[
j
][
i
*
order
]);
ddata
=
&
(
pme
->
bsplines_dtheta
[
j
][
i
*
order
]);
ddata
=
&
(
pme
->
bsplines_dtheta
[
j
][
i
*
order
]);
data
[
order
-
1
]
=
0
;
data
[
order
-
1
]
=
0
;
data
[
1
]
=
dr
;
data
[
1
]
=
dr
;
data
[
0
]
=
1
-
dr
;
data
[
0
]
=
1
-
dr
;
for
(
k
=
3
;
k
<
order
;
k
++
)
for
(
k
=
3
;
k
<
order
;
k
++
)
{
{
div
=
1.0
/
(
k
-
1.0
);
div
=
(
RealOpenMM
)
(
1.0
/
(
k
-
1.0
)
)
;
data
[
k
-
1
]
=
div
*
dr
*
data
[
k
-
2
];
data
[
k
-
1
]
=
div
*
dr
*
data
[
k
-
2
];
for
(
l
=
1
;
l
<
(
k
-
1
);
l
++
)
for
(
l
=
1
;
l
<
(
k
-
1
);
l
++
)
{
{
data
[
k
-
l
-
1
]
=
div
*
((
dr
+
l
)
*
data
[
k
-
l
-
2
]
+
(
k
-
l
-
dr
)
*
data
[
k
-
l
-
1
]);
data
[
k
-
l
-
1
]
=
div
*
((
dr
+
l
)
*
data
[
k
-
l
-
2
]
+
(
k
-
l
-
dr
)
*
data
[
k
-
l
-
1
]);
}
}
data
[
0
]
=
div
*
(
1
-
dr
)
*
data
[
0
];
data
[
0
]
=
div
*
(
1
-
dr
)
*
data
[
0
];
}
}
/* differentiate */
/* differentiate */
ddata
[
0
]
=
-
data
[
0
];
ddata
[
0
]
=
-
data
[
0
];
for
(
k
=
1
;
k
<
order
;
k
++
)
for
(
k
=
1
;
k
<
order
;
k
++
)
{
{
ddata
[
k
]
=
data
[
k
-
1
]
-
data
[
k
];
ddata
[
k
]
=
data
[
k
-
1
]
-
data
[
k
];
}
}
div
=
1.0
/
(
order
-
1
);
div
=
(
RealOpenMM
)
(
1.0
/
(
order
-
1
)
)
;
data
[
order
-
1
]
=
div
*
dr
*
data
[
order
-
2
];
data
[
order
-
1
]
=
div
*
dr
*
data
[
order
-
2
];
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
{
{
data
[
order
-
l
-
1
]
=
div
*
((
dr
+
l
)
*
data
[
order
-
l
-
2
]
+
(
order
-
l
-
dr
)
*
data
[
order
-
l
-
1
]);
data
[
order
-
l
-
1
]
=
div
*
((
dr
+
l
)
*
data
[
order
-
l
-
2
]
+
(
order
-
l
-
dr
)
*
data
[
order
-
l
-
1
]);
}
}
data
[
0
]
=
div
*
(
1
-
dr
)
*
data
[
0
];
data
[
0
]
=
div
*
(
1
-
dr
)
*
data
[
0
];
}
}
}
}
}
}
static
void
static
void
pme_grid_spread_charge
(
pme_t
pme
,
pme_grid_spread_charge
(
pme_t
pme
,
RealOpenMM
**
atomParameters
)
RealOpenMM
**
atomParameters
)
{
{
static
const
int
QIndex
=
2
;
// atom charges are stored in atomParameters[atomID][2]
static
const
int
QIndex
=
2
;
// atom charges are stored in atomParameters[atomID][2]
int
order
;
int
order
;
int
i
;
int
i
;
int
ix
,
iy
,
iz
;
int
ix
,
iy
,
iz
;
int
x0index
,
y0index
,
z0index
;
int
x0index
,
y0index
,
z0index
;
int
xindex
,
yindex
,
zindex
;
int
xindex
,
yindex
,
zindex
;
int
index
;
int
index
;
RealOpenMM
q
;
RealOpenMM
q
;
RealOpenMM
*
thetax
;
RealOpenMM
*
thetax
;
RealOpenMM
*
thetay
;
RealOpenMM
*
thetay
;
RealOpenMM
*
thetaz
;
RealOpenMM
*
thetaz
;
order
=
pme
->
order
;
order
=
pme
->
order
;
/* Reset the grid */
/* Reset the grid */
for
(
i
=
0
;
i
<
pme
->
ngrid
[
0
]
*
pme
->
ngrid
[
1
]
*
pme
->
ngrid
[
2
];
i
++
)
for
(
i
=
0
;
i
<
pme
->
ngrid
[
0
]
*
pme
->
ngrid
[
1
]
*
pme
->
ngrid
[
2
];
i
++
)
{
{
pme
->
grid
[
i
].
re
=
pme
->
grid
[
i
].
im
=
0
;
pme
->
grid
[
i
].
re
=
pme
->
grid
[
i
].
im
=
0
;
}
}
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
{
{
q
=
atomParameters
[
i
][
QIndex
];
q
=
atomParameters
[
i
][
QIndex
];
/* Grid index for the actual atom position */
/* Grid index for the actual atom position */
x0index
=
pme
->
particleindex
[
i
][
0
];
x0index
=
pme
->
particleindex
[
i
][
0
];
y0index
=
pme
->
particleindex
[
i
][
1
];
y0index
=
pme
->
particleindex
[
i
][
1
];
z0index
=
pme
->
particleindex
[
i
][
2
];
z0index
=
pme
->
particleindex
[
i
][
2
];
/* Bspline factors for this atom in each dimension , calculated from fractional coordinates */
/* Bspline factors for this atom in each dimension , calculated from fractional coordinates */
thetax
=
&
(
pme
->
bsplines_theta
[
0
][
i
*
order
]);
thetax
=
&
(
pme
->
bsplines_theta
[
0
][
i
*
order
]);
thetay
=
&
(
pme
->
bsplines_theta
[
1
][
i
*
order
]);
thetay
=
&
(
pme
->
bsplines_theta
[
1
][
i
*
order
]);
thetaz
=
&
(
pme
->
bsplines_theta
[
2
][
i
*
order
]);
thetaz
=
&
(
pme
->
bsplines_theta
[
2
][
i
*
order
]);
/* Loop over norder*norder*norder (typically 4*4*4) neighbor cells.
/* Loop over norder*norder*norder (typically 4*4*4) neighbor cells.
*
*
...
@@ -368,90 +368,90 @@ pme_grid_spread_charge(pme_t pme,
...
@@ -368,90 +368,90 @@ pme_grid_spread_charge(pme_t pme,
* 3) When we parallelize things, we only need to communicate in one direction instead of two!
* 3) When we parallelize things, we only need to communicate in one direction instead of two!
*/
*/
for
(
ix
=
0
;
ix
<
order
;
ix
++
)
for
(
ix
=
0
;
ix
<
order
;
ix
++
)
{
{
/* Calculate index, apply PBC so we spread to index 0/1/2 when a particle is close to the upper limit of the grid */
/* Calculate index, apply PBC so we spread to index 0/1/2 when a particle is close to the upper limit of the grid */
xindex
=
(
x0index
+
ix
)
%
pme
->
ngrid
[
0
];
xindex
=
(
x0index
+
ix
)
%
pme
->
ngrid
[
0
];
for
(
iy
=
0
;
iy
<
order
;
iy
++
)
for
(
iy
=
0
;
iy
<
order
;
iy
++
)
{
{
yindex
=
(
y0index
+
iy
)
%
pme
->
ngrid
[
1
];
yindex
=
(
y0index
+
iy
)
%
pme
->
ngrid
[
1
];
for
(
iz
=
0
;
iz
<
order
;
iz
++
)
for
(
iz
=
0
;
iz
<
order
;
iz
++
)
{
{
/* Can be optimized, but we keep it simple here */
/* Can be optimized, but we keep it simple here */
zindex
=
(
z0index
+
iz
)
%
pme
->
ngrid
[
2
];
zindex
=
(
z0index
+
iz
)
%
pme
->
ngrid
[
2
];
/* Calculate index in the charge grid */
/* Calculate index in the charge grid */
index
=
xindex
*
pme
->
ngrid
[
1
]
*
pme
->
ngrid
[
2
]
+
yindex
*
pme
->
ngrid
[
2
]
+
zindex
;
index
=
xindex
*
pme
->
ngrid
[
1
]
*
pme
->
ngrid
[
2
]
+
yindex
*
pme
->
ngrid
[
2
]
+
zindex
;
/* Add the charge times the bspline spread/interpolation factors to this grid position */
/* Add the charge times the bspline spread/interpolation factors to this grid position */
pme
->
grid
[
index
].
re
+=
q
*
thetax
[
ix
]
*
thetay
[
iy
]
*
thetaz
[
iz
];
pme
->
grid
[
index
].
re
+=
q
*
thetax
[
ix
]
*
thetay
[
iy
]
*
thetaz
[
iz
];
}
}
}
}
}
}
}
}
}
}
static
void
static
void
pme_reciprocal_convolution
(
pme_t
pme
,
pme_reciprocal_convolution
(
pme_t
pme
,
const
RealOpenMM
periodicBoxSize
[
3
],
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
*
energy
,
RealOpenMM
pme_virial
[
3
][
3
])
RealOpenMM
pme_virial
[
3
][
3
])
{
{
int
kx
,
ky
,
kz
;
int
kx
,
ky
,
kz
;
int
nx
,
ny
,
nz
;
int
nx
,
ny
,
nz
;
RealOpenMM
mx
,
my
,
mz
;
RealOpenMM
mx
,
my
,
mz
;
RealOpenMM
mhx
,
mhy
,
mhz
,
m2
;
RealOpenMM
mhx
,
mhy
,
mhz
,
m2
;
RealOpenMM
one_4pi_eps
;
RealOpenMM
one_4pi_eps
;
RealOpenMM
virxx
,
virxy
,
virxz
,
viryy
,
viryz
,
virzz
;
RealOpenMM
virxx
,
virxy
,
virxz
,
viryy
,
viryz
,
virzz
;
RealOpenMM
bx
,
by
,
bz
;
RealOpenMM
bx
,
by
,
bz
;
RealOpenMM
d1
,
d2
;
RealOpenMM
d1
,
d2
;
RealOpenMM
eterm
,
vfactor
,
struct2
,
ets2
;
RealOpenMM
eterm
,
vfactor
,
struct2
,
ets2
;
RealOpenMM
esum
;
RealOpenMM
esum
;
RealOpenMM
factor
;
RealOpenMM
factor
;
RealOpenMM
denom
;
RealOpenMM
denom
;
RealOpenMM
boxfactor
;
RealOpenMM
boxfactor
;
RealOpenMM
maxkx
,
maxky
,
maxkz
;
RealOpenMM
maxkx
,
maxky
,
maxkz
;
t_complex
*
ptr
;
t_complex
*
ptr
;
nx
=
pme
->
ngrid
[
0
];
nx
=
pme
->
ngrid
[
0
];
ny
=
pme
->
ngrid
[
1
];
ny
=
pme
->
ngrid
[
1
];
nz
=
pme
->
ngrid
[
2
];
nz
=
pme
->
ngrid
[
2
];
one_4pi_eps
=
ONE_4PI_EPS0
/
pme
->
epsilon_r
;
one_4pi_eps
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
/
pme
->
epsilon_r
)
;
factor
=
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
);
factor
=
(
RealOpenMM
)
(
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
)
)
;
boxfactor
=
M_PI
*
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
];
boxfactor
=
(
RealOpenMM
)
(
M_PI
*
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
]
)
;
esum
=
0
;
esum
=
0
;
virxx
=
0
;
virxx
=
0
;
virxy
=
0
;
virxy
=
0
;
virxz
=
0
;
virxz
=
0
;
viryy
=
0
;
viryy
=
0
;
viryz
=
0
;
viryz
=
0
;
virzz
=
0
;
virzz
=
0
;
maxkx
=
(
nx
+
1
)
/
2
;
maxkx
=
(
RealOpenMM
)
(
(
nx
+
1
)
/
2
)
;
maxky
=
(
ny
+
1
)
/
2
;
maxky
=
(
RealOpenMM
)
(
(
ny
+
1
)
/
2
)
;
maxkz
=
(
nz
+
1
)
/
2
;
maxkz
=
(
RealOpenMM
)
(
(
nz
+
1
)
/
2
)
;
for
(
kx
=
0
;
kx
<
nx
;
kx
++
)
for
(
kx
=
0
;
kx
<
nx
;
kx
++
)
{
{
/* 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
=
(
kx
<
maxkx
)
?
kx
:
(
kx
-
nx
);
mx
=
(
RealOpenMM
)
(
(
kx
<
maxkx
)
?
kx
:
(
kx
-
nx
)
)
;
mhx
=
mx
/
periodicBoxSize
[
0
];
mhx
=
mx
/
periodicBoxSize
[
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
=
(
ky
<
maxky
)
?
ky
:
(
ky
-
ny
);
my
=
(
RealOpenMM
)
(
(
ky
<
maxky
)
?
ky
:
(
ky
-
ny
)
)
;
mhy
=
my
/
periodicBoxSize
[
1
];
mhy
=
my
/
periodicBoxSize
[
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
++
)
{
{
/* If the net charge of the system is 0.0, there will not be any DC (direct current, zero frequency) component. However,
/* If the net charge of the system is 0.0, there will not be any DC (direct current, zero frequency) component. However,
* we can still handle charged systems through a charge correction, in which case the DC
* we can still handle charged systems through a charge correction, in which case the DC
* component should be excluded from recprocal space. We will anyway run into problems below when dividing with the
* component should be excluded from recprocal space. We will anyway run into problems below when dividing with the
...
@@ -460,159 +460,159 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -460,159 +460,159 @@ pme_reciprocal_convolution(pme_t pme,
* In cuda you could probably work around this by setting something to 0.0 instead, but the short story is that we
* In cuda you could probably work around this by setting something to 0.0 instead, but the short story is that we
* should skip the zero frequency case!
* should skip the zero frequency case!
*/
*/
if
(
kx
==
0
&&
ky
==
0
&&
kz
==
0
)
if
(
kx
==
0
&&
ky
==
0
&&
kz
==
0
)
{
{
continue
;
continue
;
}
}
/* 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
=
(
kz
<
maxkz
)
?
kz
:
(
kz
-
nz
);
mz
=
(
RealOpenMM
)
(
(
kz
<
maxkz
)
?
kz
:
(
kz
-
nz
)
)
;
mhz
=
mz
/
periodicBoxSize
[
2
];
mhz
=
mz
/
periodicBoxSize
[
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
;
/* Get grid data for this frequency */
/* Get grid data for this frequency */
d1
=
ptr
->
re
;
d1
=
ptr
->
re
;
d2
=
ptr
->
im
;
d2
=
ptr
->
im
;
/* Calculate the convolution - see the Essman/Darden paper for the equation! */
/* Calculate the convolution - see the Essman/Darden paper for the equation! */
m2
=
mhx
*
mhx
+
mhy
*
mhy
+
mhz
*
mhz
;
m2
=
mhx
*
mhx
+
mhy
*
mhy
+
mhz
*
mhz
;
bz
=
pme
->
bsplines_moduli
[
2
][
kz
];
bz
=
pme
->
bsplines_moduli
[
2
][
kz
];
denom
=
m2
*
bx
*
by
*
bz
;
denom
=
m2
*
bx
*
by
*
bz
;
eterm
=
one_4pi_eps
*
exp
(
-
factor
*
m2
)
/
denom
;
eterm
=
one_4pi_eps
*
exp
(
-
factor
*
m2
)
/
denom
;
/* write back convolution data to grid */
/* write back convolution data to grid */
ptr
->
re
=
d1
*
eterm
;
ptr
->
re
=
d1
*
eterm
;
ptr
->
im
=
d2
*
eterm
;
ptr
->
im
=
d2
*
eterm
;
struct2
=
(
d1
*
d1
+
d2
*
d2
);
struct2
=
(
d1
*
d1
+
d2
*
d2
);
/* 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. */
/* PME long-range contribution to atomic virial. Since it is symmetric, we only calculate half the matrix inside this loop. */
vfactor
=
(
factor
*
m2
+
1
.0
)
*
2
.0
/
m2
;
vfactor
=
(
factor
*
m2
+
1
)
*
2
/
m2
;
virxx
+=
ets2
*
(
vfactor
*
mhx
*
mhx
-
1
.0
);
virxx
+=
ets2
*
(
vfactor
*
mhx
*
mhx
-
1
);
virxy
+=
ets2
*
vfactor
*
mhx
*
mhy
;
virxy
+=
ets2
*
vfactor
*
mhx
*
mhy
;
virxz
+=
ets2
*
vfactor
*
mhx
*
mhz
;
virxz
+=
ets2
*
vfactor
*
mhx
*
mhz
;
viryy
+=
ets2
*
(
vfactor
*
mhy
*
mhy
-
1
.0
);
viryy
+=
ets2
*
(
vfactor
*
mhy
*
mhy
-
1
);
viryz
+=
ets2
*
vfactor
*
mhy
*
mhz
;
viryz
+=
ets2
*
vfactor
*
mhy
*
mhz
;
virzz
+=
ets2
*
(
vfactor
*
mhz
*
mhz
-
1
.0
);
virzz
+=
ets2
*
(
vfactor
*
mhz
*
mhz
-
1
);
}
}
}
}
}
}
pme_virial
[
0
][
0
]
=
0.25
*
virxx
;
pme_virial
[
0
][
0
]
=
(
RealOpenMM
)
(
0.25
*
virxx
)
;
pme_virial
[
1
][
1
]
=
0.25
*
viryy
;
pme_virial
[
1
][
1
]
=
(
RealOpenMM
)
(
0.25
*
viryy
)
;
pme_virial
[
2
][
2
]
=
0.25
*
virzz
;
pme_virial
[
2
][
2
]
=
(
RealOpenMM
)
(
0.25
*
virzz
)
;
pme_virial
[
0
][
1
]
=
pme_virial
[
1
][
0
]
=
0.25
*
virxy
;
pme_virial
[
0
][
1
]
=
pme_virial
[
1
][
0
]
=
(
RealOpenMM
)
(
0.25
*
virxy
)
;
pme_virial
[
0
][
2
]
=
pme_virial
[
2
][
0
]
=
0.25
*
virxz
;
pme_virial
[
0
][
2
]
=
pme_virial
[
2
][
0
]
=
(
RealOpenMM
)
(
0.25
*
virxz
)
;
pme_virial
[
1
][
2
]
=
pme_virial
[
2
][
1
]
=
0.25
*
viryz
;
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
=
0.5
*
esum
;
*
energy
=
0.5
*
esum
;
}
}
static
void
static
void
pme_grid_interpolate_force
(
pme_t
pme
,
pme_grid_interpolate_force
(
pme_t
pme
,
const
RealOpenMM
periodicBoxSize
[
3
],
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
**
atomParameters
,
RealOpenMM
**
atomParameters
,
RealOpenMM
**
forces
)
RealOpenMM
**
forces
)
{
{
static
const
int
QIndex
=
2
;
// atom charges are stored in atomParameters[atomID][2]
static
const
int
QIndex
=
2
;
// atom charges are stored in atomParameters[atomID][2]
int
i
;
int
i
;
int
ix
,
iy
,
iz
;
int
ix
,
iy
,
iz
;
int
x0index
,
y0index
,
z0index
;
int
x0index
,
y0index
,
z0index
;
int
xindex
,
yindex
,
zindex
;
int
xindex
,
yindex
,
zindex
;
int
index
;
int
index
;
int
order
;
int
order
;
RealOpenMM
q
;
RealOpenMM
q
;
RealOpenMM
*
thetax
;
RealOpenMM
*
thetax
;
RealOpenMM
*
thetay
;
RealOpenMM
*
thetay
;
RealOpenMM
*
thetaz
;
RealOpenMM
*
thetaz
;
RealOpenMM
*
dthetax
;
RealOpenMM
*
dthetax
;
RealOpenMM
*
dthetay
;
RealOpenMM
*
dthetay
;
RealOpenMM
*
dthetaz
;
RealOpenMM
*
dthetaz
;
RealOpenMM
tx
,
ty
,
tz
;
RealOpenMM
tx
,
ty
,
tz
;
RealOpenMM
dtx
,
dty
,
dtz
;
RealOpenMM
dtx
,
dty
,
dtz
;
RealOpenMM
fx
,
fy
,
fz
;
RealOpenMM
fx
,
fy
,
fz
;
RealOpenMM
gridvalue
;
RealOpenMM
gridvalue
;
int
nx
,
ny
,
nz
;
int
nx
,
ny
,
nz
;
nx
=
pme
->
ngrid
[
0
];
nx
=
pme
->
ngrid
[
0
];
ny
=
pme
->
ngrid
[
1
];
ny
=
pme
->
ngrid
[
1
];
nz
=
pme
->
ngrid
[
2
];
nz
=
pme
->
ngrid
[
2
];
order
=
pme
->
order
;
order
=
pme
->
order
;
/* This is almost identical to the charge spreading routine! */
/* This is almost identical to the charge spreading routine! */
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
{
{
fx
=
fy
=
fz
=
0
;
fx
=
fy
=
fz
=
0
;
q
=
atomParameters
[
i
][
QIndex
];
q
=
atomParameters
[
i
][
QIndex
];
/* Grid index for the actual atom position */
/* Grid index for the actual atom position */
x0index
=
pme
->
particleindex
[
i
][
0
];
x0index
=
pme
->
particleindex
[
i
][
0
];
y0index
=
pme
->
particleindex
[
i
][
1
];
y0index
=
pme
->
particleindex
[
i
][
1
];
z0index
=
pme
->
particleindex
[
i
][
2
];
z0index
=
pme
->
particleindex
[
i
][
2
];
/* Bspline factors for this atom in each dimension , calculated from fractional coordinates */
/* Bspline factors for this atom in each dimension , calculated from fractional coordinates */
thetax
=
&
(
pme
->
bsplines_theta
[
0
][
i
*
order
]);
thetax
=
&
(
pme
->
bsplines_theta
[
0
][
i
*
order
]);
thetay
=
&
(
pme
->
bsplines_theta
[
1
][
i
*
order
]);
thetay
=
&
(
pme
->
bsplines_theta
[
1
][
i
*
order
]);
thetaz
=
&
(
pme
->
bsplines_theta
[
2
][
i
*
order
]);
thetaz
=
&
(
pme
->
bsplines_theta
[
2
][
i
*
order
]);
dthetax
=
&
(
pme
->
bsplines_dtheta
[
0
][
i
*
order
]);
dthetax
=
&
(
pme
->
bsplines_dtheta
[
0
][
i
*
order
]);
dthetay
=
&
(
pme
->
bsplines_dtheta
[
1
][
i
*
order
]);
dthetay
=
&
(
pme
->
bsplines_dtheta
[
1
][
i
*
order
]);
dthetaz
=
&
(
pme
->
bsplines_dtheta
[
2
][
i
*
order
]);
dthetaz
=
&
(
pme
->
bsplines_dtheta
[
2
][
i
*
order
]);
/* See pme_grid_spread_charge() for comments about the order here, and only interpolation in one direction */
/* See pme_grid_spread_charge() for comments about the order here, and only interpolation in one direction */
/* Since we will add order^3 (typically 4*4*4=64) terms to the force on each particle, we use temporary fx/fy/fz
/* Since we will add order^3 (typically 4*4*4=64) terms to the force on each particle, we use temporary fx/fy/fz
* variables, and only add it to memory forces[] at the end.
* variables, and only add it to memory forces[] at the end.
*/
*/
for
(
ix
=
0
;
ix
<
order
;
ix
++
)
for
(
ix
=
0
;
ix
<
order
;
ix
++
)
{
{
xindex
=
(
x0index
+
ix
)
%
pme
->
ngrid
[
0
];
xindex
=
(
x0index
+
ix
)
%
pme
->
ngrid
[
0
];
/* Get both the bspline factor and its derivative with respect to the x coordinate! */
/* Get both the bspline factor and its derivative with respect to the x coordinate! */
tx
=
thetax
[
ix
];
tx
=
thetax
[
ix
];
dtx
=
dthetax
[
ix
];
dtx
=
dthetax
[
ix
];
for
(
iy
=
0
;
iy
<
order
;
iy
++
)
for
(
iy
=
0
;
iy
<
order
;
iy
++
)
{
{
yindex
=
(
y0index
+
iy
)
%
pme
->
ngrid
[
1
];
yindex
=
(
y0index
+
iy
)
%
pme
->
ngrid
[
1
];
/* bspline + derivative wrt y */
/* bspline + derivative wrt y */
ty
=
thetay
[
iy
];
ty
=
thetay
[
iy
];
dty
=
dthetay
[
iy
];
dty
=
dthetay
[
iy
];
for
(
iz
=
0
;
iz
<
order
;
iz
++
)
for
(
iz
=
0
;
iz
<
order
;
iz
++
)
{
{
/* Can be optimized, but we keep it simple here */
/* Can be optimized, but we keep it simple here */
zindex
=
(
z0index
+
iz
)
%
pme
->
ngrid
[
2
];
zindex
=
(
z0index
+
iz
)
%
pme
->
ngrid
[
2
];
/* bspline + derivative wrt z */
/* bspline + derivative wrt z */
tz
=
thetaz
[
iz
];
tz
=
thetaz
[
iz
];
dtz
=
dthetaz
[
iz
];
dtz
=
dthetaz
[
iz
];
index
=
xindex
*
pme
->
ngrid
[
1
]
*
pme
->
ngrid
[
2
]
+
yindex
*
pme
->
ngrid
[
2
]
+
zindex
;
index
=
xindex
*
pme
->
ngrid
[
1
]
*
pme
->
ngrid
[
2
]
+
yindex
*
pme
->
ngrid
[
2
]
+
zindex
;
/* Get the fft+convoluted+ifft:d data from the grid, which must be real by definition */
/* Get the fft+convoluted+ifft:d data from the grid, which must be real by definition */
/* Checking that the imaginary part is indeed zero might be a good check :-) */
/* Checking that the imaginary part is indeed zero might be a good check :-) */
gridvalue
=
pme
->
grid
[
index
].
re
;
gridvalue
=
pme
->
grid
[
index
].
re
;
/* The d component of the force is calculated by taking the derived bspline in dimension d, normal bsplines in the other two */
/* The d component of the force is calculated by taking the derived bspline in dimension d, normal bsplines in the other two */
fx
+=
dtx
*
ty
*
tz
*
gridvalue
;
fx
+=
dtx
*
ty
*
tz
*
gridvalue
;
fy
+=
tx
*
dty
*
tz
*
gridvalue
;
fy
+=
tx
*
dty
*
tz
*
gridvalue
;
fz
+=
tx
*
ty
*
dtz
*
gridvalue
;
fz
+=
tx
*
ty
*
dtz
*
gridvalue
;
}
}
}
}
}
}
/* 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
/
periodicBoxSize
[
0
];
forces
[
i
][
1
]
-=
q
*
fy
*
ny
/
periodicBoxSize
[
1
];
forces
[
i
][
1
]
-=
q
*
fy
*
ny
/
periodicBoxSize
[
1
];
forces
[
i
][
2
]
-=
q
*
fz
*
nz
/
periodicBoxSize
[
2
];
forces
[
i
][
2
]
-=
q
*
fz
*
nz
/
periodicBoxSize
[
2
];
}
}
}
}
...
@@ -621,10 +621,10 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -621,10 +621,10 @@ pme_grid_interpolate_force(pme_t pme,
int
int
pme_init
(
pme_t
*
ppme
,
pme_init
(
pme_t
*
ppme
,
RealOpenMM
ewaldcoeff
,
RealOpenMM
ewaldcoeff
,
int
natoms
,
int
natoms
,
const
int
ngrid
[
3
],
const
int
ngrid
[
3
],
int
pme_order
,
int
pme_order
,
RealOpenMM
epsilon_r
)
RealOpenMM
epsilon_r
)
{
{
pme_t
pme
;
pme_t
pme
;
...
@@ -635,27 +635,27 @@ pme_init(pme_t * ppme,
...
@@ -635,27 +635,27 @@ pme_init(pme_t * ppme,
pme
->
order
=
pme_order
;
pme
->
order
=
pme_order
;
pme
->
epsilon_r
=
epsilon_r
;
pme
->
epsilon_r
=
epsilon_r
;
pme
->
ewaldcoeff
=
ewaldcoeff
;
pme
->
ewaldcoeff
=
ewaldcoeff
;
pme
->
natoms
=
natoms
;
pme
->
natoms
=
natoms
;
for
(
d
=
0
;
d
<
3
;
d
++
)
for
(
d
=
0
;
d
<
3
;
d
++
)
{
{
pme
->
ngrid
[
d
]
=
ngrid
[
d
];
pme
->
ngrid
[
d
]
=
ngrid
[
d
];
pme
->
bsplines_theta
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme_order
*
natoms
);
pme
->
bsplines_theta
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme_order
*
natoms
);
pme
->
bsplines_dtheta
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme_order
*
natoms
);
pme
->
bsplines_dtheta
[
d
]
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
pme_order
*
natoms
);
}
}
pme
->
particlefraction
=
(
rvec
*
)
malloc
(
sizeof
(
rvec
)
*
natoms
);
pme
->
particlefraction
=
(
rvec
*
)
malloc
(
sizeof
(
rvec
)
*
natoms
);
pme
->
particleindex
=
(
ivec
*
)
malloc
(
sizeof
(
ivec
)
*
natoms
);
pme
->
particleindex
=
(
ivec
*
)
malloc
(
sizeof
(
ivec
)
*
natoms
);
/* Allocate charge grid storage */
/* Allocate charge grid storage */
pme
->
grid
=
(
t_complex
*
)
malloc
(
sizeof
(
t_complex
)
*
ngrid
[
0
]
*
ngrid
[
1
]
*
ngrid
[
2
]);
pme
->
grid
=
(
t_complex
*
)
malloc
(
sizeof
(
t_complex
)
*
ngrid
[
0
]
*
ngrid
[
1
]
*
ngrid
[
2
]);
fftpack_init_3d
(
&
pme
->
fftplan
,
ngrid
[
0
],
ngrid
[
1
],
ngrid
[
2
]);
fftpack_init_3d
(
&
pme
->
fftplan
,
ngrid
[
0
],
ngrid
[
1
],
ngrid
[
2
]);
/* Setup bspline moduli (see Essman paper) */
/* Setup bspline moduli (see Essman paper) */
pme_calculate_bsplines_moduli
(
pme
);
pme_calculate_bsplines_moduli
(
pme
);
*
ppme
=
pme
;
*
ppme
=
pme
;
return
0
;
return
0
;
}
}
...
@@ -665,12 +665,12 @@ pme_init(pme_t * ppme,
...
@@ -665,12 +665,12 @@ pme_init(pme_t * ppme,
int
pme_exec
(
pme_t
pme
,
int
pme_exec
(
pme_t
pme
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
forces
,
RealOpenMM
**
forces
,
RealOpenMM
**
atomParameters
,
RealOpenMM
**
atomParameters
,
const
RealOpenMM
periodicBoxSize
[
3
],
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
*
energy
,
RealOpenMM
pme_virial
[
3
][
3
])
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 */
...
@@ -679,28 +679,28 @@ int pme_exec(pme_t pme,
...
@@ -679,28 +679,28 @@ int pme_exec(pme_t pme,
* and what its fractional offset in this grid cell is.
* and what its fractional offset in this grid cell is.
*/
*/
/* 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
,
periodicBoxSize
);
pme_update_grid_index_and_fraction
(
pme
,
atomCoordinates
,
periodicBoxSize
);
/* 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
);
/* Spread the charges on grid (using newly calculated bsplines in the pme structure) */
/* Spread the charges on grid (using newly calculated bsplines in the pme structure) */
pme_grid_spread_charge
(
pme
,
atomParameters
);
pme_grid_spread_charge
(
pme
,
atomParameters
);
/* do 3d-fft */
/* do 3d-fft */
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
,
periodicBoxSize
,
energy
,
pme_virial
);
pme_reciprocal_convolution
(
pme
,
periodicBoxSize
,
energy
,
pme_virial
);
/* 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
,
atomParameters
,
forces
);
pme_grid_interpolate_force
(
pme
,
periodicBoxSize
,
atomParameters
,
forces
);
return
0
;
return
0
;
}
}
...
@@ -710,24 +710,24 @@ int pme_exec(pme_t pme,
...
@@ -710,24 +710,24 @@ int pme_exec(pme_t pme,
int
int
pme_destroy
(
pme_t
pme
)
pme_destroy
(
pme_t
pme
)
{
{
int
d
;
int
d
;
free
(
pme
->
grid
);
free
(
pme
->
grid
);
for
(
d
=
0
;
d
<
3
;
d
++
)
for
(
d
=
0
;
d
<
3
;
d
++
)
{
{
free
(
pme
->
bsplines_moduli
[
d
]);
free
(
pme
->
bsplines_moduli
[
d
]);
free
(
pme
->
bsplines_theta
[
d
]);
free
(
pme
->
bsplines_theta
[
d
]);
free
(
pme
->
bsplines_dtheta
[
d
]);
free
(
pme
->
bsplines_dtheta
[
d
]);
}
}
free
(
pme
->
particlefraction
);
free
(
pme
->
particlefraction
);
free
(
pme
->
particleindex
);
free
(
pme
->
particleindex
);
fftpack_destroy
(
pme
->
fftplan
);
fftpack_destroy
(
pme
->
fftplan
);
/* destroy structure itself */
/* destroy structure itself */
free
(
pme
);
free
(
pme
);
return
0
;
return
0
;
}
}
platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp
View file @
6186c067
...
@@ -116,7 +116,7 @@ int ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
...
@@ -116,7 +116,7 @@ int ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
int
atomBIndex
=
atomIndices
[
1
];
int
atomBIndex
=
atomIndices
[
1
];
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomAIndex
],
atomCoordinates
[
atomBIndex
],
deltaR
);
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomAIndex
],
atomCoordinates
[
atomBIndex
],
deltaR
);
variables
[
"r"
]
=
deltaR
[
ReferenceForce
::
RIndex
];
variables
[
"r"
]
=
deltaR
[
ReferenceForce
::
RIndex
];
RealOpenMM
dEdR
=
forceExpression
.
evaluate
(
variables
);
RealOpenMM
dEdR
=
(
RealOpenMM
)
forceExpression
.
evaluate
(
variables
);
dEdR
=
deltaR
[
ReferenceForce
::
RIndex
]
>
zero
?
(
dEdR
/
deltaR
[
ReferenceForce
::
RIndex
])
:
zero
;
dEdR
=
deltaR
[
ReferenceForce
::
RIndex
]
>
zero
?
(
dEdR
/
deltaR
[
ReferenceForce
::
RIndex
])
:
zero
;
forces
[
atomAIndex
][
0
]
+=
dEdR
*
deltaR
[
ReferenceForce
::
XIndex
];
forces
[
atomAIndex
][
0
]
+=
dEdR
*
deltaR
[
ReferenceForce
::
XIndex
];
...
@@ -127,7 +127,7 @@ int ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
...
@@ -127,7 +127,7 @@ int ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
forces
[
atomBIndex
][
1
]
-=
dEdR
*
deltaR
[
ReferenceForce
::
YIndex
];
forces
[
atomBIndex
][
1
]
-=
dEdR
*
deltaR
[
ReferenceForce
::
YIndex
];
forces
[
atomBIndex
][
2
]
-=
dEdR
*
deltaR
[
ReferenceForce
::
ZIndex
];
forces
[
atomBIndex
][
2
]
-=
dEdR
*
deltaR
[
ReferenceForce
::
ZIndex
];
RealOpenMM
energy
=
energyExpression
.
evaluate
(
variables
);
RealOpenMM
energy
=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
updateEnergy
(
energy
,
energiesByBond
,
twoI
,
atomIndices
,
energiesByAtom
);
updateEnergy
(
energy
,
energiesByBond
,
twoI
,
atomIndices
,
energiesByAtom
);
return
ReferenceForce
::
DefaultReturn
;
return
ReferenceForce
::
DefaultReturn
;
...
...
platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp
View file @
6186c067
...
@@ -106,11 +106,11 @@ int ReferenceCustomExternalIxn::calculateForce( int atomIndex,
...
@@ -106,11 +106,11 @@ int ReferenceCustomExternalIxn::calculateForce( int atomIndex,
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
forces
[
atomIndex
][
0
]
-=
forceExpressionX
.
evaluate
(
variables
);
forces
[
atomIndex
][
0
]
-=
(
RealOpenMM
)
forceExpressionX
.
evaluate
(
variables
);
forces
[
atomIndex
][
1
]
-=
forceExpressionY
.
evaluate
(
variables
);
forces
[
atomIndex
][
1
]
-=
(
RealOpenMM
)
forceExpressionY
.
evaluate
(
variables
);
forces
[
atomIndex
][
2
]
-=
forceExpressionZ
.
evaluate
(
variables
);
forces
[
atomIndex
][
2
]
-=
(
RealOpenMM
)
forceExpressionZ
.
evaluate
(
variables
);
if
(
energy
!=
NULL
)
if
(
energy
!=
NULL
)
*
energy
+=
energyExpression
.
evaluate
(
variables
);
*
energy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
return
ReferenceForce
::
DefaultReturn
;
return
ReferenceForce
::
DefaultReturn
;
}
}
platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp
View file @
6186c067
...
@@ -157,9 +157,9 @@ int ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, RealOpenMM** atomC
...
@@ -157,9 +157,9 @@ int ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, RealOpenMM** atomC
RealOpenMM
dEdR
=
parameters
[
1
]
*
(
twelve
*
sig6
-
six
)
*
sig6
;
RealOpenMM
dEdR
=
parameters
[
1
]
*
(
twelve
*
sig6
-
six
)
*
sig6
;
if
(
cutoff
)
if
(
cutoff
)
dEdR
+=
ONE_4PI_EPS0
*
parameters
[
2
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
);
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
)
)
;
else
else
dEdR
+=
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
;
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
)
;
dEdR
*=
inverseR
*
inverseR
;
dEdR
*=
inverseR
*
inverseR
;
// accumulate forces
// accumulate forces
...
@@ -172,9 +172,9 @@ int ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, RealOpenMM** atomC
...
@@ -172,9 +172,9 @@ int ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, RealOpenMM** atomC
RealOpenMM
energy
=
parameters
[
1
]
*
(
sig6
-
one
)
*
sig6
;
RealOpenMM
energy
=
parameters
[
1
]
*
(
sig6
-
one
)
*
sig6
;
if
(
cutoff
)
if
(
cutoff
)
energy
+=
ONE_4PI_EPS0
*
parameters
[
2
]
*
(
inverseR
+
krf
*
r2
-
crf
);
energy
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
(
inverseR
+
krf
*
r2
-
crf
)
)
;
else
else
energy
+=
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
;
energy
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
parameters
[
2
]
*
inverseR
)
;
// accumulate energies
// accumulate energies
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
6186c067
...
@@ -206,7 +206,7 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -206,7 +206,7 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
// **************************************************************************************
// **************************************************************************************
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
RealOpenMM
selfEwaldEnergy
=
ONE_4PI_EPS0
*
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
;
RealOpenMM
selfEwaldEnergy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
)
;
totalSelfEwaldEnergy
-=
selfEwaldEnergy
;
totalSelfEwaldEnergy
-=
selfEwaldEnergy
;
if
(
energyByAtom
){
if
(
energyByAtom
){
...
@@ -373,8 +373,8 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -373,8 +373,8 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
dEdR
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
)
;
dEdR
=
(
RealOpenMM
)(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
dEdR
=
(
RealOpenMM
)
(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
sig2
=
inverseR
*
sig
;
RealOpenMM
sig2
=
inverseR
*
sig
;
...
@@ -423,8 +423,8 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -423,8 +423,8 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
dEdR
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
)
;
dEdR
=
(
RealOpenMM
)(
dEdR
*
(
erf
(
alphaR
)
-
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
dEdR
=
(
RealOpenMM
)
(
dEdR
*
(
erf
(
alphaR
)
-
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
// accumulate forces
// accumulate forces
...
@@ -582,9 +582,9 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
...
@@ -582,9 +582,9 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
RealOpenMM
dEdR
=
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
;
RealOpenMM
dEdR
=
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
;
if
(
cutoff
)
if
(
cutoff
)
dEdR
+=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
);
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
-
2.0
f
*
krf
*
r2
)
)
;
else
else
dEdR
+=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
;
dEdR
+=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
)
;
dEdR
*=
inverseR
*
inverseR
;
dEdR
*=
inverseR
*
inverseR
;
// accumulate forces
// accumulate forces
...
@@ -601,9 +601,9 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
...
@@ -601,9 +601,9 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
if
(
totalEnergy
||
energyByAtom
)
{
if
(
totalEnergy
||
energyByAtom
)
{
if
(
cutoff
)
if
(
cutoff
)
energy
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
+
krf
*
r2
-
crf
);
energy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
(
inverseR
+
krf
*
r2
-
crf
)
)
;
else
else
energy
=
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
;
energy
=
(
RealOpenMM
)
(
ONE_4PI_EPS0
*
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
)
;
energy
+=
eps
*
(
sig6
-
one
)
*
sig6
;
energy
+=
eps
*
(
sig6
-
one
)
*
sig6
;
if
(
totalEnergy
)
if
(
totalEnergy
)
*
totalEnergy
+=
energy
;
*
totalEnergy
+=
energy
;
...
...
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