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
68e02e80
Commit
68e02e80
authored
Jul 17, 2009
by
Rossen Apostolov
Browse files
Combined the Ewald and PME routines into a single one and added calculation of vdW interactions.
parent
351f6455
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1327 additions
and
388 deletions
+1327
-388
platforms/reference/src/SimTKReference/PME.cpp
platforms/reference/src/SimTKReference/PME.cpp
+123
-123
platforms/reference/src/SimTKReference/PME.h
platforms/reference/src/SimTKReference/PME.h
+0
-0
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+117
-218
platforms/reference/tests/TestReferenceEwald.cpp
platforms/reference/tests/TestReferenceEwald.cpp
+45
-47
platforms/reference/tests/nacl_crystal.dat
platforms/reference/tests/nacl_crystal.dat
+1000
-0
platforms/reference/tests/water.dat
platforms/reference/tests/water.dat
+42
-0
No files found.
platforms/reference/src/SimTKReference/
pme
.cpp
→
platforms/reference/src/SimTKReference/
PME
.cpp
View file @
68e02e80
/*
/*
* Reference implementation of PME reciprocal space interactions.
* Reference implementation of PME reciprocal space interactions.
*
*
* Copyright (c) 2009, Erik Lindahl, Rossen Apostolov, Szilard Pall
* Copyright (c) 2009, Erik Lindahl, Rossen Apostolov, Szilard Pall
* All rights reserved.
* All rights reserved.
* Contact: lindahl@cbr.su.se Stockholm University, Sweden.
* Contact: lindahl@cbr.su.se Stockholm University, Sweden.
*
*
* Redistribution and use in source and binary forms, with or without
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* modification, are permitted provided that the following conditions are met:
*
*
* Redistributions of source code must retain the above copyright notice, this
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* with the distribution.
* Neither the name of the author/university nor the names of its contributors may
* Neither the name of the author/university nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* POSSIBILITY OF SUCH DAMAGE.
*/
*/
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include "
pme
.h"
#include "
PME
.h"
#include "fftpack.h"
#include "fftpack.h"
...
@@ -48,29 +48,29 @@ struct pme
...
@@ -48,29 +48,29 @@ 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!
*/
*/
rvec
*
particlefraction
;
/* Array of length natoms. Fractional offset in the grid for
rvec
*
particlefraction
;
/* Array of length natoms. Fractional offset in the grid for
* each atom in all three dimensions.
* each atom in all three dimensions.
*/
*/
/* Further explanation of index/fraction:
/* Further explanation of index/fraction:
*
*
* Assume we have a cell of size 10*10*10nm, and a total grid dimension of 100*100*100 cells.
* Assume we have a cell of size 10*10*10nm, and a total grid dimension of 100*100*100 cells.
...
@@ -86,9 +86,9 @@ struct pme
...
@@ -86,9 +86,9 @@ struct pme
* In the current code version we might assume that a particle is not more than a whole box length away from
* In the current code version we might assume that a particle is not more than a whole box length away from
* 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 */
};
};
/* Internal setup routines */
/* Internal setup routines */
...
@@ -96,7 +96,7 @@ struct pme
...
@@ -96,7 +96,7 @@ struct pme
/* Only called once from init_pme(), performance does not matter! */
/* Only called once from init_pme(), performance does not matter! */
static
void
static
void
pme_calculate_bsplines_moduli
(
pme_t
pme
)
pme_calculate_bsplines_moduli
(
pme_t
pme
)
{
{
int
nmax
;
int
nmax
;
...
@@ -115,18 +115,18 @@ pme_calculate_bsplines_moduli(pme_t pme)
...
@@ -115,18 +115,18 @@ pme_calculate_bsplines_moduli(pme_t pme)
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
;
order
=
pme
->
order
;
/* temp storage in this routine */
/* temp storage in this routine */
data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
ddata
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
ddata
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
order
);
bsplines_data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
nmax
);
bsplines_data
=
(
RealOpenMM
*
)
malloc
(
sizeof
(
RealOpenMM
)
*
nmax
);
data
[
order
-
1
]
=
0
;
data
[
order
-
1
]
=
0
;
data
[
1
]
=
0
;
data
[
1
]
=
0
;
data
[
0
]
=
1
;
data
[
0
]
=
1
;
for
(
k
=
3
;
k
<
order
;
k
++
)
for
(
k
=
3
;
k
<
order
;
k
++
)
{
{
div
=
1.0
/
(
k
-
1.0
);
div
=
1.0
/
(
k
-
1.0
);
...
@@ -137,23 +137,23 @@ pme_calculate_bsplines_moduli(pme_t pme)
...
@@ -137,23 +137,23 @@ pme_calculate_bsplines_moduli(pme_t pme)
}
}
data
[
0
]
=
div
*
data
[
0
];
data
[
0
]
=
div
*
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
=
1.0
/
(
order
-
1
);
data
[
order
-
1
]
=
0
;
data
[
order
-
1
]
=
0
;
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
for
(
l
=
1
;
l
<
(
order
-
1
);
l
++
)
{
{
data
[
order
-
l
-
1
]
=
div
*
(
l
*
data
[
order
-
l
-
2
]
+
(
order
-
l
)
*
data
[
order
-
l
-
1
]);
data
[
order
-
l
-
1
]
=
div
*
(
l
*
data
[
order
-
l
-
2
]
+
(
order
-
l
)
*
data
[
order
-
l
-
1
]);
}
}
data
[
0
]
=
div
*
data
[
0
];
data
[
0
]
=
div
*
data
[
0
];
for
(
i
=
0
;
i
<
nmax
;
i
++
)
for
(
i
=
0
;
i
<
nmax
;
i
++
)
{
{
bsplines_data
[
i
]
=
0
;
bsplines_data
[
i
]
=
0
;
...
@@ -162,7 +162,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
...
@@ -162,7 +162,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
{
{
bsplines_data
[
i
]
=
data
[
i
-
1
];
bsplines_data
[
i
]
=
data
[
i
-
1
];
}
}
/* Evaluate the actual bspline moduli for X/Y/Z */
/* Evaluate the actual bspline moduli for X/Y/Z */
for
(
d
=
0
;
d
<
3
;
d
++
)
for
(
d
=
0
;
d
<
3
;
d
++
)
{
{
...
@@ -170,7 +170,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
...
@@ -170,7 +170,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
for
(
i
=
0
;
i
<
ndata
;
i
++
)
for
(
i
=
0
;
i
<
ndata
;
i
++
)
{
{
sc
=
ss
=
0
;
sc
=
ss
=
0
;
for
(
j
=
0
;
j
<
ndata
;
j
++
)
for
(
j
=
0
;
j
<
ndata
;
j
++
)
{
{
arg
=
(
2.0
*
M_PI
*
i
*
j
)
/
ndata
;
arg
=
(
2.0
*
M_PI
*
i
*
j
)
/
ndata
;
sc
+=
bsplines_data
[
j
]
*
cos
(
arg
);
sc
+=
bsplines_data
[
j
]
*
cos
(
arg
);
...
@@ -185,7 +185,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
...
@@ -185,7 +185,7 @@ pme_calculate_bsplines_moduli(pme_t pme)
pme
->
bsplines_moduli
[
d
][
i
]
=
(
pme
->
bsplines_moduli
[
d
][
i
-
1
]
+
pme
->
bsplines_moduli
[
d
][
i
+
1
])
*
0.5
;
pme
->
bsplines_moduli
[
d
][
i
]
=
(
pme
->
bsplines_moduli
[
d
][
i
-
1
]
+
pme
->
bsplines_moduli
[
d
][
i
+
1
])
*
0.5
;
}
}
}
}
}
}
/* Release temp storage */
/* Release temp storage */
free
(
data
);
free
(
data
);
...
@@ -204,7 +204,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -204,7 +204,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
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
++
)
...
@@ -216,7 +216,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -216,7 +216,7 @@ pme_update_grid_index_and_fraction(pme_t pme,
*
*
* 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.
...
@@ -229,14 +229,14 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -229,14 +229,14 @@ pme_update_grid_index_and_fraction(pme_t pme,
* x[i][d]/box[d] becomes { 0.0543 , 0.6235 , -0.073 }
* x[i][d]/box[d] becomes { 0.0543 , 0.6235 , -0.073 }
* (x[i][d]/box[d] + 1.0) becomes { 1.0543 , 1.6235 , 0.927 }
* (x[i][d]/box[d] + 1.0) becomes { 1.0543 , 1.6235 , 0.927 }
* (x[i][d]/box[d] + 1.0)*ngrid[d] becomes { 105.43 , 162.35 , 92.7 }
* (x[i][d]/box[d] + 1.0)*ngrid[d] becomes { 105.43 , 162.35 , 92.7 }
*
*
* integer part is now { 105 , 162 , 92 }
* integer part is now { 105 , 162 , 92 }
*
*
* 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 }
*
*
* Voila, both index and fraction, entirely without conditionals. The one limitation here is that
* Voila, both index and fraction, entirely without conditionals. The one limitation here is that
* we only add one box length, so if the particle had a coordinate <=-10.0, we would be screwed.
* we only add one box length, so if the particle had a coordinate <=-10.0, we would be screwed.
...
@@ -247,20 +247,20 @@ pme_update_grid_index_and_fraction(pme_t pme,
...
@@ -247,20 +247,20 @@ pme_update_grid_index_and_fraction(pme_t pme,
*/
*/
t
=
(
atomCoordinates
[
i
][
d
]
/
periodicBoxSize
[
d
]
+
1.0
)
*
pme
->
ngrid
[
d
];
t
=
(
atomCoordinates
[
i
][
d
]
/
periodicBoxSize
[
d
]
+
1.0
)
*
pme
->
ngrid
[
d
];
ti
=
t
;
ti
=
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
];
}
}
}
}
}
}
/* Ugly bspline calculation taken from Tom Dardens reference equations.
/* Ugly bspline calculation taken from Tom Dardens reference equations.
* This probably very sub-optimal in Cuda? Separate kernel?
* This probably very sub-optimal in Cuda? Separate kernel?
*
*
* In practice, it might help to require order=4 for the cuda port.
* In practice, it might help to require order=4 for the cuda port.
*/
*/
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
;
...
@@ -268,27 +268,27 @@ pme_update_bsplines(pme_t pme)
...
@@ -268,27 +268,27 @@ pme_update_bsplines(pme_t pme)
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
=
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
]);
}
}
...
@@ -297,20 +297,20 @@ pme_update_bsplines(pme_t pme)
...
@@ -297,20 +297,20 @@ pme_update_bsplines(pme_t pme)
/* 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
=
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
];
}
}
}
}
}
}
...
@@ -331,64 +331,64 @@ pme_grid_spread_charge(pme_t pme,
...
@@ -331,64 +331,64 @@ pme_grid_spread_charge(pme_t pme,
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.
*
*
* As a neat optimization, we only spread in the forward direction, but apply PBC!
* As a neat optimization, we only spread in the forward direction, but apply PBC!
*
*
* Since we are going to do an FFT on the grid, it doesnt matter where the data is,
* Since we are going to do an FFT on the grid, it doesnt matter where the data is,
* in frequency space the result will be the same.
* in frequency space the result will be the same.
*
*
* So, the influence function (bsplines) will probably be something like (0.15,0.35,0.35,0.15),
* So, the influence function (bsplines) will probably be something like (0.15,0.35,0.35,0.15),
* with largest weight 2-3 steps forward (you dont need to understand that for the implementation :-)
* with largest weight 2-3 steps forward (you dont need to understand that for the implementation :-)
* Effectively, you can look at this as translating the entire grid.
* Effectively, you can look at this as translating the entire grid.
*
*
* Why do we do this stupid thing?
* Why do we do this stupid thing?
*
*
* 1) The loops get much simpler
* 1) The loops get much simpler
* 2) Just looking forward will hopefully get us more cache hits
* 2) Just looking forward will hopefully get us more cache hits
* 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
];
}
}
}
}
}
}
...
@@ -417,17 +417,17 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -417,17 +417,17 @@ pme_reciprocal_convolution(pme_t pme,
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
=
ONE_4PI_EPS0
/
pme
->
epsilon_r
;
factor
=
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
);
factor
=
M_PI
*
M_PI
/
(
pme
->
ewaldcoeff
*
pme
->
ewaldcoeff
);
boxfactor
=
M_PI
*
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
];
boxfactor
=
M_PI
*
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
];
esum
=
0
;
esum
=
0
;
virxx
=
0
;
virxx
=
0
;
virxy
=
0
;
virxy
=
0
;
...
@@ -435,7 +435,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -435,7 +435,7 @@ pme_reciprocal_convolution(pme_t pme,
viryy
=
0
;
viryy
=
0
;
viryz
=
0
;
viryz
=
0
;
virzz
=
0
;
virzz
=
0
;
maxkx
=
(
nx
+
1
)
/
2
;
maxkx
=
(
nx
+
1
)
/
2
;
maxky
=
(
ny
+
1
)
/
2
;
maxky
=
(
ny
+
1
)
/
2
;
maxkz
=
(
nz
+
1
)
/
2
;
maxkz
=
(
nz
+
1
)
/
2
;
...
@@ -453,7 +453,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -453,7 +453,7 @@ pme_reciprocal_convolution(pme_t pme,
my
=
(
ky
<
maxky
)
?
ky
:
(
ky
-
ny
);
my
=
(
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,
...
@@ -474,23 +474,23 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -474,23 +474,23 @@ pme_reciprocal_convolution(pme_t pme,
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 */
...
@@ -504,7 +504,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -504,7 +504,7 @@ pme_reciprocal_convolution(pme_t pme,
virxz
+=
ets2
*
vfactor
*
mhx
*
mhz
;
virxz
+=
ets2
*
vfactor
*
mhx
*
mhz
;
viryy
+=
ets2
*
(
vfactor
*
mhy
*
mhy
-
1.0
);
viryy
+=
ets2
*
(
vfactor
*
mhy
*
mhy
-
1.0
);
viryz
+=
ets2
*
vfactor
*
mhy
*
mhz
;
viryz
+=
ets2
*
vfactor
*
mhy
*
mhz
;
virzz
+=
ets2
*
(
vfactor
*
mhz
*
mhz
-
1.0
);
virzz
+=
ets2
*
(
vfactor
*
mhz
*
mhz
-
1.0
);
}
}
}
}
}
}
...
@@ -514,7 +514,7 @@ pme_reciprocal_convolution(pme_t pme,
...
@@ -514,7 +514,7 @@ pme_reciprocal_convolution(pme_t pme,
pme_virial
[
0
][
1
]
=
pme_virial
[
1
][
0
]
=
0.25
*
virxy
;
pme_virial
[
0
][
1
]
=
pme_virial
[
1
][
0
]
=
0.25
*
virxy
;
pme_virial
[
0
][
2
]
=
pme_virial
[
2
][
0
]
=
0.25
*
virxz
;
pme_virial
[
0
][
2
]
=
pme_virial
[
2
][
0
]
=
0.25
*
virxz
;
pme_virial
[
1
][
2
]
=
pme_virial
[
2
][
1
]
=
0.25
*
viryz
;
pme_virial
[
1
][
2
]
=
pme_virial
[
2
][
1
]
=
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
;
}
}
...
@@ -545,26 +545,26 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -545,26 +545,26 @@ pme_grid_interpolate_force(pme_t pme,
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
]);
...
@@ -574,7 +574,7 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -574,7 +574,7 @@ pme_grid_interpolate_force(pme_t pme,
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.
*/
*/
...
@@ -584,14 +584,14 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -584,14 +584,14 @@ pme_grid_interpolate_force(pme_t pme,
/* 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 */
...
@@ -600,7 +600,7 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -600,7 +600,7 @@ pme_grid_interpolate_force(pme_t pme,
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
;
...
@@ -623,7 +623,7 @@ pme_grid_interpolate_force(pme_t pme,
...
@@ -623,7 +623,7 @@ pme_grid_interpolate_force(pme_t pme,
/* EXPORTED ROUTINES */
/* EXPORTED ROUTINES */
int
int
pme_init
(
pme_t
*
ppme
,
pme_init
(
pme_t
*
ppme
,
RealOpenMM
ewaldcoeff
,
RealOpenMM
ewaldcoeff
,
int
natoms
,
int
natoms
,
...
@@ -633,14 +633,14 @@ pme_init(pme_t * ppme,
...
@@ -633,14 +633,14 @@ pme_init(pme_t * ppme,
{
{
pme_t
pme
;
pme_t
pme
;
int
d
;
int
d
;
pme
=
(
pme_t
)
malloc
(
sizeof
(
struct
pme
));
pme
=
(
pme_t
)
malloc
(
sizeof
(
struct
pme
));
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
];
...
@@ -650,17 +650,17 @@ pme_init(pme_t * ppme,
...
@@ -650,17 +650,17 @@ pme_init(pme_t * ppme,
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
;
}
}
...
@@ -677,32 +677,32 @@ int pme_exec(pme_t pme,
...
@@ -677,32 +677,32 @@ int pme_exec(pme_t pme,
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 */
/* 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.
*/
*/
/* 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
);
...
@@ -715,23 +715,23 @@ int
...
@@ -715,23 +715,23 @@ 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/
pme
.h
→
platforms/reference/src/SimTKReference/
PME
.h
View file @
68e02e80
File moved
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
68e02e80
...
@@ -31,8 +31,7 @@
...
@@ -31,8 +31,7 @@
#include "../SimTKUtilities/SimTKOpenMMUtilities.h"
#include "../SimTKUtilities/SimTKOpenMMUtilities.h"
#include "ReferenceLJCoulombIxn.h"
#include "ReferenceLJCoulombIxn.h"
#include "ReferenceForce.h"
#include "ReferenceForce.h"
#include "PME.h"
#include "pme.h"
// In case we're using some primitive version of Visual Studio this will
// In case we're using some primitive version of Visual Studio this will
// make sure that erf() and erfc() are defined.
// make sure that erf() and erfc() are defined.
...
@@ -85,13 +84,13 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){
...
@@ -85,13 +84,13 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
int
ReferenceLJCoulombIxn
::
setUseCutoff
(
RealOpenMM
distance
,
const
OpenMM
::
NeighborList
&
neighbors
,
RealOpenMM
solventDielectric
)
{
int
ReferenceLJCoulombIxn
::
setUseCutoff
(
RealOpenMM
distance
,
const
OpenMM
::
NeighborList
&
neighbors
,
RealOpenMM
solventDielectric
)
{
cutoff
=
true
;
cutoff
=
true
;
cutoffDistance
=
distance
;
cutoffDistance
=
distance
;
neighborList
=
&
neighbors
;
neighborList
=
&
neighbors
;
krf
=
pow
(
cutoffDistance
,
-
3.0
f
)
*
(
solventDielectric
-
1.0
f
)
/
(
2.0
f
*
solventDielectric
+
1.0
f
);
krf
=
pow
(
cutoffDistance
,
-
3.0
f
)
*
(
solventDielectric
-
1.0
f
)
/
(
2.0
f
*
solventDielectric
+
1.0
f
);
crf
=
(
1.0
f
/
cutoffDistance
)
*
(
3.0
f
*
solventDielectric
)
/
(
2.0
f
*
solventDielectric
+
1.0
f
);
crf
=
(
1.0
f
/
cutoffDistance
)
*
(
3.0
f
*
solventDielectric
)
/
(
2.0
f
*
solventDielectric
+
1.0
f
);
return
ReferenceForce
::
DefaultReturn
;
return
ReferenceForce
::
DefaultReturn
;
}
}
...
@@ -193,9 +192,9 @@ int ReferenceLJCoulombIxn::getDerivedParameters( RealOpenMM c6, RealOpenMM c12,
...
@@ -193,9 +192,9 @@ int ReferenceLJCoulombIxn::getDerivedParameters( RealOpenMM c6, RealOpenMM c12,
parameters
[
SigIndex
]
=
half
;
parameters
[
SigIndex
]
=
half
;
}
else
{
}
else
{
parameters
[
EpsIndex
]
=
c6
*
SQRT
(
one
/
c12
);
parameters
[
EpsIndex
]
=
c6
*
SQRT
(
one
/
c12
);
parameters
[
SigIndex
]
=
POW
(
(
c12
/
c6
),
oneSixth
);
parameters
[
SigIndex
]
=
POW
(
(
c12
/
c6
),
oneSixth
);
parameters
[
SigIndex
]
*=
half
;
parameters
[
SigIndex
]
*=
half
;
}
}
...
@@ -222,9 +221,9 @@ int ReferenceLJCoulombIxn::getDerivedParameters( RealOpenMM c6, RealOpenMM c12,
...
@@ -222,9 +221,9 @@ int ReferenceLJCoulombIxn::getDerivedParameters( RealOpenMM c6, RealOpenMM c12,
@param totalEnergy total energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
int
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
int
ReferenceLJCoulombIxn
::
calculateEwaldIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
...
@@ -233,40 +232,80 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -233,40 +232,80 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
#include "../SimTKUtilities/RealTypeSimTk.h"
#include "../SimTKUtilities/RealTypeSimTk.h"
typedef
std
::
complex
<
RealOpenMM
>
d_complex
;
typedef
std
::
complex
<
RealOpenMM
>
d_complex
;
int
kmax
=
std
::
max
(
numRx
,
std
::
max
(
numRy
,
numRz
));
RealOpenMM
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
RealOpenMM
SQRT_PI
=
sqrt
(
PI
);
RealOpenMM
TWO_PI
=
2.0
*
PI
;
static
const
RealOpenMM
epsilon
=
1.0
;
static
const
RealOpenMM
epsilon
=
1.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
six
=
6.0
;
static
const
RealOpenMM
twelve
=
12.0
;
RealOpenMM
recipCoeff
=
(
RealOpenMM
)(
4
*
PI
/
(
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
])
/
epsilon
);
int
kmax
=
std
::
max
(
numRx
,
std
::
max
(
numRy
,
numRz
));
RealOpenMM
factorEwald
=
-
1
/
(
4
*
alphaEwald
*
alphaEwald
);
RealOpenMM
SQRT_PI
=
sqrt
(
PI
);
RealOpenMM
TWO_PI
=
2.0
*
PI
;
RealOpenMM
recipCoeff
=
(
RealOpenMM
)(
4
*
PI
/
(
periodicBoxSize
[
0
]
*
periodicBoxSize
[
1
]
*
periodicBoxSize
[
2
])
/
epsilon
);
RealOpenMM
selfEwaldEnergy
=
0.0
;
RealOpenMM
selfEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
RealOpenMM
vdwEnergy
=
0.0
;
// **************************************************************************************
// **************************************************************************************
// SELF ENERGY
// SELF ENERGY
// **************************************************************************************
// **************************************************************************************
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
selfEwaldEnergy
=
selfEwaldEnergy
+
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
];
selfEwaldEnergy
=
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
]
*
alphaEwald
/
SQRT_PI
;
if
(
totalEnergy
)
*
totalEnergy
-=
selfEwaldEnergy
;
if
(
energyByAtom
){
energyByAtom
[
atomID
]
-=
selfEwaldEnergy
;
}
}
}
selfEwaldEnergy
=
selfEwaldEnergy
*
alphaEwald
/
SQRT_PI
;
// **************************************************************************************
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
// **************************************************************************************
// setup reciprocal box
// PME
if
(
pme
)
{
pme_t
pmedata
;
/* abstract handle for PME data */
int
ngrid
[
3
];
RealOpenMM
virial
[
3
][
3
];
/* PME grid dimensions.
* We typically want to set this as the spacing rather than absolute dimensions, but
* to be able to reproduce results from other programs (e.g. Gromacs) we need to be
* able to set exact grid dimenisions occasionally.
*/
ngrid
[
0
]
=
16
;
ngrid
[
1
]
=
16
;
ngrid
[
2
]
=
16
;
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
ngrid
,
4
,
1
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
atomParameters
,
periodicBoxSize
,
&
recipEnergy
,
virial
);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
}
// Ewald method
else
if
(
ewald
)
{
// setup reciprocal box
RealOpenMM
recipBoxSize
[
3
]
=
{
TWO_PI
/
periodicBoxSize
[
0
],
TWO_PI
/
periodicBoxSize
[
1
],
TWO_PI
/
periodicBoxSize
[
2
]};
RealOpenMM
recipBoxSize
[
3
]
=
{
TWO_PI
/
periodicBoxSize
[
0
],
TWO_PI
/
periodicBoxSize
[
1
],
TWO_PI
/
periodicBoxSize
[
2
]};
// setup K-vectors
// setup K-vectors
#define EIR(x, y, z) eir[(x)*numberOfAtoms*3+(y)*3+z]
#define EIR(x, y, z) eir[(x)*numberOfAtoms*3+(y)*3+z]
vector
<
d_complex
>
eir
(
kmax
*
numberOfAtoms
*
3
);
vector
<
d_complex
>
eir
(
kmax
*
numberOfAtoms
*
3
);
...
@@ -292,7 +331,8 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -292,7 +331,8 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
EIR
(
j
,
i
,
m
)
=
EIR
(
j
-
1
,
i
,
m
)
*
EIR
(
1
,
i
,
m
);
EIR
(
j
,
i
,
m
)
=
EIR
(
j
-
1
,
i
,
m
)
*
EIR
(
1
,
i
,
m
);
}
}
// calculate reciprocal space energy and forces
// calculate reciprocal space energy and forces
int
lowry
=
0
;
int
lowry
=
0
;
int
lowrz
=
1
;
int
lowrz
=
1
;
...
@@ -335,231 +375,92 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
...
@@ -335,231 +375,92 @@ int ReferenceLJCoulombIxn::calculateEwaldIxn( int numberOfAtoms, RealOpenMM** at
ss
+=
tab_qxyz
[
n
].
imag
();
ss
+=
tab_qxyz
[
n
].
imag
();
}
}
RealOpenMM
kz
=
rz
*
recipBoxSize
[
2
];
RealOpenMM
kz
=
rz
*
recipBoxSize
[
2
];
RealOpenMM
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
RealOpenMM
k2
=
kx
*
kx
+
ky
*
ky
+
kz
*
kz
;
RealOpenMM
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
RealOpenMM
ak
=
exp
(
k2
*
factorEwald
)
/
k2
;
recipEnergy
+=
ak
*
(
cs
*
cs
+
ss
*
ss
);
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
{
RealOpenMM
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
RealOpenMM
force
=
ak
*
(
cs
*
tab_qxyz
[
n
].
imag
()
-
ss
*
tab_qxyz
[
n
].
real
());
forces
[
n
][
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
forces
[
n
][
0
]
+=
2
*
recipCoeff
*
force
*
kx
;
forces
[
n
][
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
forces
[
n
][
1
]
+=
2
*
recipCoeff
*
force
*
ky
;
forces
[
n
][
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
forces
[
n
][
2
]
+=
2
*
recipCoeff
*
force
*
kz
;
}
}
recipEnergy
=
recipCoeff
*
ak
*
(
cs
*
cs
+
ss
*
ss
);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
if
(
energyByAtom
)
for
(
int
n
=
0
;
n
<
numberOfAtoms
;
n
++
)
energyByAtom
[
n
]
+=
recipEnergy
;
lowrz
=
1
-
numRz
;
lowrz
=
1
-
numRz
;
}
}
lowry
=
1
-
numRy
;
lowry
=
1
-
numRy
;
}
}
}
}
}
recipEnergy
*=
recipCoeff
;
else
{
std
::
stringstream
message
;
message
<<
" Wrong method for Ewald summation, Aborting"
<<
std
::
endl
;
SimTKOpenMMLog
::
printError
(
message
);
}
// **************************************************************************************
// **************************************************************************************
// SHORT-RANGE ENERGY AND FORCES
// SHORT-RANGE ENERGY AND FORCES
// **************************************************************************************
// **************************************************************************************
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
for
(
int
atomID1
=
0
;
atomID1
<
numberOfAtoms
;
atomID1
++
){
int
ii
=
pair
.
first
;
for
(
int
atomID2
=
atomID1
+
1
;
atomID2
<
numberOfAtoms
;
atomID2
++
){
int
jj
=
pair
.
second
;
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atomID2
],
atomCoordinates
[
atomID1
],
periodicBoxSize
,
deltaR
[
0
]
);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
realSpaceEwaldEnergy
=
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
(
RealOpenMM
)(
realSpaceEwaldEnergy
+
atomParameters
[
atomID1
][
QIndex
]
*
atomParameters
[
atomID2
][
QIndex
]
*
inverseR
*
erfc
(
alphaEwald
*
r
));
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxSize
,
deltaR
[
0
]
);
}
}
// allocate and initialize exclusion array
vector
<
int
>
exclusionIndices
(
numberOfAtoms
);
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
exclusionIndices
[
ii
]
=
-
1
;
}
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
// set exclusions
for
(
int
jj
=
1
;
jj
<=
exclusions
[
ii
][
0
];
jj
++
){
exclusionIndices
[
exclusions
[
ii
][
jj
]]
=
ii
;
}
// loop over atom pairs
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
){
if
(
exclusionIndices
[
jj
]
!=
ii
){
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxSize
,
deltaR
[
0
]
);
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
alphaR
=
alphaEwald
*
r
;
RealOpenMM
alphaR
=
alphaEwald
*
r
;
realSpaceEwaldEnergy
=
(
RealOpenMM
)(
realSpaceEwaldEnergy
+
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
));
RealOpenMM
dEdR
=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
dEdR
=
(
RealOpenMM
)(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
}
}
}
// ***********************************************************************
if
(
totalEnergy
)
{
*
totalEnergy
+=
recipEnergy
+
realSpaceEwaldEnergy
-
selfEwaldEnergy
;
}
return
ReferenceForce
::
DefaultReturn
;
}
/**---------------------------------------------------------------------------------------
Calculate PME ixn
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomParameters atom parameters atomParameters[atomIndex][paramterIndex]
@param exclusions atom exclusion indices exclusions[atomIndex][atomToExcludeIndex]
exclusions[atomIndex][0] = number of exclusions
exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from
interacting w/ atom atomIndex
@param fixedParameters non atom parameters (not currently used)
@param forces force array (forces added)
@param energyByAtom atom energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
int
ReferenceLJCoulombIxn
::
calculatePMEIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
RealOpenMM
SQRT_PI
=
sqrt
(
PI
);
static
const
RealOpenMM
one
=
1.0
;
RealOpenMM
selfEwaldEnergy
=
0.0
;
RealOpenMM
realSpaceEwaldEnergy
=
0.0
;
RealOpenMM
recipEnergy
=
0.0
;
// **************************************************************************************
// SELF ENERGY
// **************************************************************************************
for
(
int
atomID
=
0
;
atomID
<
numberOfAtoms
;
atomID
++
){
selfEwaldEnergy
=
selfEwaldEnergy
+
atomParameters
[
atomID
][
QIndex
]
*
atomParameters
[
atomID
][
QIndex
];
}
selfEwaldEnergy
=
selfEwaldEnergy
*
alphaEwald
/
SQRT_PI
;
// **************************************************************************************
// RECIPROCAL SPACE EWALD ENERGY AND FORCES
// **************************************************************************************
pme_t
pmedata
;
/* abstract handle for PME data */
int
ngrid
[
3
];
RealOpenMM
virial
[
3
][
3
];
/* PME grid dimensions.
* We typically want to set this as the spacing rather than absolute dimensions, but
* to be able to reproduce results from other programs (e.g. Gromacs) we need to be
* able to set exact grid dimenisions occasionally.
*/
ngrid
[
0
]
=
16
;
ngrid
[
1
]
=
16
;
ngrid
[
2
]
=
16
;
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
ngrid
,
4
,
1
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
atomParameters
,
periodicBoxSize
,
&
recipEnergy
,
virial
);
// **************************************************************************************
// SHORT-RANGE ENERGY AND FORCES
// **************************************************************************************
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
for
(
int
atomID1
=
0
;
atomID1
<
numberOfAtoms
;
atomID1
++
){
RealOpenMM
dEdR
=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
for
(
int
atomID2
=
atomID1
+
1
;
atomID2
<
numberOfAtoms
;
atomID2
++
){
dEdR
=
(
RealOpenMM
)(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atomID2
],
atomCoordinates
[
atomID1
],
periodicBoxSize
,
deltaR
[
0
]
);
RealOpenMM
sig
=
atomParameters
[
ii
][
SigIndex
]
+
atomParameters
[
jj
][
SigIndex
];
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
sig2
=
inverseR
*
sig
;
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
sig2
*=
sig2
;
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
sig6
=
sig2
*
sig2
*
sig2
;
RealOpenMM
eps
=
atomParameters
[
ii
][
EpsIndex
]
*
atomParameters
[
jj
][
EpsIndex
];
realSpaceEwaldEnergy
=
dEdR
+=
eps
*
(
twelve
*
sig6
-
six
)
*
sig6
;
(
RealOpenMM
)(
realSpaceEwaldEnergy
+
atomParameters
[
atomID1
][
QIndex
]
*
atomParameters
[
atomID2
][
QIndex
]
*
inverseR
*
erfc
(
alphaEwald
*
r
));
}
}
// a
llocate and initialize exclusion array
// a
ccumulate forces
vector
<
int
>
exclusionIndices
(
numberOfAtoms
);
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
exclusionIndices
[
ii
]
=
-
1
;
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
}
for
(
int
ii
=
0
;
ii
<
numberOfAtoms
;
ii
++
){
// accumulate energies
// set exclusions
realSpaceEwaldEnergy
=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
);
vdwEnergy
=
eps
*
(
sig6
-
one
)
*
sig6
;
for
(
int
jj
=
1
;
jj
<=
exclusions
[
ii
][
0
];
jj
++
){
if
(
totalEnergy
)
exclusionIndices
[
exclusions
[
ii
][
jj
]]
=
ii
;
*
totalEnergy
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
}
// loop over atom pairs
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
){
if
(
exclusionIndices
[
jj
]
!=
ii
){
if
(
energyByAtom
){
energyByAtom
[
ii
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
energyByAtom
[
jj
]
+=
realSpaceEwaldEnergy
+
vdwEnergy
;
}
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxSize
,
deltaR
[
0
]
);
}
RealOpenMM
r
=
deltaR
[
0
][
ReferenceForce
::
RIndex
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
alphaR
=
alphaEwald
*
r
;
realSpaceEwaldEnergy
=
(
RealOpenMM
)(
realSpaceEwaldEnergy
+
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
erfc
(
alphaR
));
RealOpenMM
dEdR
=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
*
inverseR
*
inverseR
;
dEdR
=
(
RealOpenMM
)(
dEdR
*
(
erfc
(
alphaR
)
+
2
*
alphaR
*
exp
(
-
alphaR
*
alphaR
)
/
SQRT_PI
));
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
RealOpenMM
force
=
dEdR
*
deltaR
[
0
][
kk
];
forces
[
ii
][
kk
]
+=
force
;
forces
[
jj
][
kk
]
-=
force
;
}
}
}
}
// ***********************************************************************
// ***********************************************************************
if
(
totalEnergy
)
{
*
totalEnergy
+=
recipEnergy
+
realSpaceEwaldEnergy
-
selfEwaldEnergy
;
}
return
ReferenceForce
::
DefaultReturn
;
return
ReferenceForce
::
DefaultReturn
;
}
}
...
@@ -582,18 +483,16 @@ int ReferenceLJCoulombIxn::calculatePMEIxn( int numberOfAtoms, RealOpenMM** atom
...
@@ -582,18 +483,16 @@ int ReferenceLJCoulombIxn::calculatePMEIxn( int numberOfAtoms, RealOpenMM** atom
@param totalEnergy total energy
@param totalEnergy total energy
@return ReferenceForce::DefaultReturn
@return ReferenceForce::DefaultReturn
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
int
ReferenceLJCoulombIxn
::
calculatePairIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
int
ReferenceLJCoulombIxn
::
calculatePairIxn
(
int
numberOfAtoms
,
RealOpenMM
**
atomCoordinates
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
**
atomParameters
,
int
**
exclusions
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
fixedParameters
,
RealOpenMM
**
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
if
(
ewald
)
if
(
ewald
||
pme
)
return
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
return
calculateEwaldIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
if
(
pme
)
return
calculatePMEIxn
(
numberOfAtoms
,
atomCoordinates
,
atomParameters
,
exclusions
,
fixedParameters
,
forces
,
energyByAtom
,
totalEnergy
);
if
(
cutoff
)
{
if
(
cutoff
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
...
@@ -681,9 +580,9 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
...
@@ -681,9 +580,9 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
// get deltaR, R2, and R between 2 atoms
// get deltaR, R2, and R between 2 atoms
if
(
periodic
)
if
(
periodic
)
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxSize
,
deltaR
[
0
]
);
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
periodicBoxSize
,
deltaR
[
0
]
);
else
else
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]
);
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
jj
],
atomCoordinates
[
ii
],
deltaR
[
0
]
);
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
r2
=
deltaR
[
0
][
ReferenceForce
::
R2Index
];
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
RealOpenMM
inverseR
=
one
/
(
deltaR
[
0
][
ReferenceForce
::
RIndex
]);
...
@@ -699,7 +598,7 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
...
@@ -699,7 +598,7 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
else
else
dEdR
+=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
;
dEdR
+=
atomParameters
[
ii
][
QIndex
]
*
atomParameters
[
jj
][
QIndex
]
*
inverseR
;
dEdR
*=
inverseR
*
inverseR
;
dEdR
*=
inverseR
*
inverseR
;
// accumulate forces
// accumulate forces
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
for
(
int
kk
=
0
;
kk
<
3
;
kk
++
){
...
@@ -726,7 +625,7 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
...
@@ -726,7 +625,7 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
}
}
}
}
// debug
// debug
if
(
debug
==
ii
){
if
(
debug
==
ii
){
static
bool
printHeader
=
false
;
static
bool
printHeader
=
false
;
...
@@ -734,11 +633,11 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
...
@@ -734,11 +633,11 @@ int ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, RealOpenMM** atomCoo
message
<<
methodName
;
message
<<
methodName
;
message
<<
std
::
endl
;
message
<<
std
::
endl
;
int
pairArray
[
2
]
=
{
ii
,
jj
};
int
pairArray
[
2
]
=
{
ii
,
jj
};
if
(
!
printHeader
){
if
(
!
printHeader
){
printHeader
=
true
;
printHeader
=
true
;
message
<<
std
::
endl
;
message
<<
std
::
endl
;
message
<<
methodName
.
c_str
()
<<
" a0 k [c q p s] r1 r2 angle dt rp p[] dot cosine angle dEdR*r F[]"
<<
std
::
endl
;
message
<<
methodName
.
c_str
()
<<
" a0 k [c q p s] r1 r2 angle dt rp p[] dot cosine angle dEdR*r F[]"
<<
std
::
endl
;
}
}
message
<<
std
::
endl
;
message
<<
std
::
endl
;
for
(
int
kk
=
0
;
kk
<
2
;
kk
++
){
for
(
int
kk
=
0
;
kk
<
2
;
kk
++
){
...
...
platforms/reference/tests/TestReferenceEwald.cpp
View file @
68e02e80
...
@@ -49,6 +49,41 @@ using namespace std;
...
@@ -49,6 +49,41 @@ using namespace std;
const
double
TOL
=
1e-5
;
const
double
TOL
=
1e-5
;
void
testLargeSystem
()
{
ReferencePlatform
platform
;
System
system
;
for
(
int
i
=
0
;
i
<
500
;
i
++
)
system
.
addParticle
(
22.99
);
for
(
int
i
=
0
;
i
<
500
;
i
++
)
system
.
addParticle
(
35.45
);
VerletIntegrator
integrator
(
0.01
);
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
500
;
i
++
)
nonbonded
->
addParticle
(
1.0
,
1.0
,
0.0
);
// nonbonded->addParticle(1.0, 0.33284,0.0115897);
for
(
int
i
=
0
;
i
<
500
;
i
++
)
nonbonded
->
addParticle
(
-
1.0
,
1.0
,
0.0
);
// nonbonded->addParticle(-1.0, 0.440104,0.4184);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
const
double
cutoff
=
1.0
;
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setPeriodicBoxVectors
(
Vec3
(
2.82
,
0
,
0
),
Vec3
(
0
,
2.82
,
0
),
Vec3
(
0
,
0
,
2.82
));
nonbonded
->
setEwaldErrorTolerance
(
TOL
);
system
.
addForce
(
nonbonded
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
1000
);
#include "nacl_crystal.dat"
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
// cout << "force 0: " << forces[0] << endl;
// cout << "force 1: " << forces[1] << endl;
cout
<<
"PotentialEnergy: "
<<
state
.
getPotentialEnergy
()
<<
endl
;
ASSERT_EQUAL_TOL
(
-
430355
,
state
.
getPotentialEnergy
(),
100
*
TOL
);
// ASSERT_EQUAL_VEC(Vec3(-123.711, 64.1877, -302.716), forces[0], 10*TOL);
// ASSERT_EQUAL_VEC(Vec3(123.711, -64.1877, 302.716), forces[1], 10*TOL);
}
void
testEwald
()
{
void
testEwald
()
{
ReferencePlatform
platform
;
ReferencePlatform
platform
;
System
system
;
System
system
;
...
@@ -58,6 +93,9 @@ void testEwald() {
...
@@ -58,6 +93,9 @@ void testEwald() {
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
nonbonded
->
addParticle
(
1.0
,
1
,
0
);
nonbonded
->
addParticle
(
1.0
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.0
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.0
,
1
,
0
);
// Sodium Chloride
// nonbonded->addParticle(1.0, 0.33284,0.0115897);
// nonbonded->addParticle(-1.0, 0.440104,0.4184);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
Ewald
);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
Ewald
);
const
double
cutoff
=
2.0
;
const
double
cutoff
=
2.0
;
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setCutoffDistance
(
cutoff
);
...
@@ -71,9 +109,9 @@ void testEwald() {
...
@@ -71,9 +109,9 @@ void testEwald() {
context
.
setPositions
(
positions
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
cout
<<
"force 0: "
<<
forces
[
0
]
<<
endl
;
//
cout << "force 0: " << forces[0] << endl;
cout
<<
"force 1: "
<<
forces
[
1
]
<<
endl
;
//
cout << "force 1: " << forces[1] << endl;
cout
<<
"PotentialEnergy: "
<<
state
.
getPotentialEnergy
()
<<
endl
;
//
cout << "PotentialEnergy: " << state.getPotentialEnergy() << endl;
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
123.711
,
64.1877
,
-
302.716
),
forces
[
0
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
10
*
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
123.711
,
-
64.1877
,
302.716
),
forces
[
1
],
10
*
TOL
);
}
}
...
@@ -101,48 +139,7 @@ void testPME() {
...
@@ -101,48 +139,7 @@ void testPME() {
system
.
addForce
(
nonbonded
);
system
.
addForce
(
nonbonded
);
Context
context
(
system
,
integrator
,
platform
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
42
);
vector
<
Vec3
>
positions
(
42
);
positions
[
0
]
=
Vec3
(
0.23
,
0.628
,
0.113
);
#include "water.dat"
positions
[
1
]
=
Vec3
(
0.137
,
0.626
,
0.15
);
positions
[
2
]
=
Vec3
(
0.231
,
0.589
,
0.021
);
positions
[
3
]
=
Vec3
(
-
0.307
,
-
0.351
,
0.703
);
positions
[
4
]
=
Vec3
(
-
0.364
,
-
0.367
,
0.784
);
positions
[
5
]
=
Vec3
(
-
0.366
,
-
0.341
,
0.623
);
positions
[
6
]
=
Vec3
(
-
0.569
,
-
0.634
,
-
0.439
);
positions
[
7
]
=
Vec3
(
-
0.532
,
-
0.707
,
-
0.497
);
positions
[
8
]
=
Vec3
(
-
0.517
,
-
0.629
,
-
0.354
);
positions
[
9
]
=
Vec3
(
-
0.871
,
0.41
,
-
0.62
);
positions
[
10
]
=
Vec3
(
-
0.948
,
0.444
,
-
0.566
);
positions
[
11
]
=
Vec3
(
-
0.905
,
0.359
,
-
0.699
);
positions
[
12
]
=
Vec3
(
0.249
,
-
0.077
,
-
0.621
);
positions
[
13
]
=
Vec3
(
0.306
,
-
0.142
,
-
0.571
);
positions
[
14
]
=
Vec3
(
0.233
,
-
0.11
,
-
0.714
);
positions
[
15
]
=
Vec3
(
0.561
,
0.222
,
-
0.715
);
positions
[
16
]
=
Vec3
(
0.599
,
0.138
,
-
0.678
);
positions
[
17
]
=
Vec3
(
0.473
,
0.241
,
-
0.671
);
positions
[
18
]
=
Vec3
(
-
0.515
,
-
0.803
,
-
0.628
);
positions
[
19
]
=
Vec3
(
-
0.491
,
-
0.866
,
-
0.702
);
positions
[
20
]
=
Vec3
(
-
0.605
,
-
0.763
,
-
0.646
);
positions
[
21
]
=
Vec3
(
-
0.021
,
0.175
,
-
0.899
);
positions
[
22
]
=
Vec3
(
0.018
,
0.09
,
-
0.935
);
positions
[
23
]
=
Vec3
(
-
0.119
,
0.177
,
-
0.918
);
positions
[
24
]
=
Vec3
(
-
0.422
,
0.856
,
-
0.464
);
positions
[
25
]
=
Vec3
(
-
0.479
,
0.908
,
-
0.527
);
positions
[
26
]
=
Vec3
(
-
0.326
,
0.868
,
-
0.488
);
positions
[
27
]
=
Vec3
(
-
0.369
,
-
0.095
,
-
0.903
);
positions
[
28
]
=
Vec3
(
-
0.336
,
-
0.031
,
-
0.972
);
positions
[
29
]
=
Vec3
(
-
0.303
,
-
0.101
,
-
0.828
);
positions
[
30
]
=
Vec3
(
0.594
,
0.745
,
0.652
);
positions
[
31
]
=
Vec3
(
0.644
,
0.83
,
0.633
);
positions
[
32
]
=
Vec3
(
0.506
,
0.747
,
0.604
);
positions
[
33
]
=
Vec3
(
-
0.157
,
-
0.375
,
-
0.758
);
positions
[
34
]
=
Vec3
(
-
0.25
,
-
0.4
,
-
0.785
);
positions
[
35
]
=
Vec3
(
-
0.131
,
-
0.425
,
-
0.676
);
positions
[
36
]
=
Vec3
(
0.618
,
-
0.295
,
-
0.578
);
positions
[
37
]
=
Vec3
(
0.613
,
-
0.213
,
-
0.521
);
positions
[
38
]
=
Vec3
(
0.707
,
-
0.298
,
-
0.623
);
positions
[
39
]
=
Vec3
(
0.039
,
-
0.785
,
0.3
);
positions
[
40
]
=
Vec3
(
0.138
,
-
0.796
,
0.291
);
positions
[
41
]
=
Vec3
(
-
0.001
,
-
0.871
,
0.332
);
context
.
setPositions
(
positions
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
...
@@ -156,8 +153,9 @@ positions[41] = Vec3(-0.001,-0.871,0.332);
...
@@ -156,8 +153,9 @@ positions[41] = Vec3(-0.001,-0.871,0.332);
int
main
()
{
int
main
()
{
try
{
try
{
testEwald
();
testLargeSystem
();
testPME
();
testEwald
();
testPME
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
platforms/reference/tests/nacl_crystal.dat
0 → 100644
View file @
68e02e80
positions[0] = Vec3(0.141000,0.141000,0.141000);
positions[1] = Vec3(0.141000,0.141000,0.705000);
positions[2] = Vec3(0.141000,0.141000,1.269000);
positions[3] = Vec3(0.141000,0.141000,1.833000);
positions[4] = Vec3(0.141000,0.141000,2.397000);
positions[5] = Vec3(0.141000,0.423000,0.423000);
positions[6] = Vec3(0.141000,0.423000,0.987000);
positions[7] = Vec3(0.141000,0.423000,1.551000);
positions[8] = Vec3(0.141000,0.423000,2.115000);
positions[9] = Vec3(0.141000,0.423000,2.679000);
positions[10] = Vec3(0.141000,0.705000,0.141000);
positions[11] = Vec3(0.141000,0.705000,0.705000);
positions[12] = Vec3(0.141000,0.705000,1.269000);
positions[13] = Vec3(0.141000,0.705000,1.833000);
positions[14] = Vec3(0.141000,0.705000,2.397000);
positions[15] = Vec3(0.141000,0.987000,0.423000);
positions[16] = Vec3(0.141000,0.987000,0.987000);
positions[17] = Vec3(0.141000,0.987000,1.551000);
positions[18] = Vec3(0.141000,0.987000,2.115000);
positions[19] = Vec3(0.141000,0.987000,2.679000);
positions[20] = Vec3(0.141000,1.269000,0.141000);
positions[21] = Vec3(0.141000,1.269000,0.705000);
positions[22] = Vec3(0.141000,1.269000,1.269000);
positions[23] = Vec3(0.141000,1.269000,1.833000);
positions[24] = Vec3(0.141000,1.269000,2.397000);
positions[25] = Vec3(0.141000,1.551000,0.423000);
positions[26] = Vec3(0.141000,1.551000,0.987000);
positions[27] = Vec3(0.141000,1.551000,1.551000);
positions[28] = Vec3(0.141000,1.551000,2.115000);
positions[29] = Vec3(0.141000,1.551000,2.679000);
positions[30] = Vec3(0.141000,1.833000,0.141000);
positions[31] = Vec3(0.141000,1.833000,0.705000);
positions[32] = Vec3(0.141000,1.833000,1.269000);
positions[33] = Vec3(0.141000,1.833000,1.833000);
positions[34] = Vec3(0.141000,1.833000,2.397000);
positions[35] = Vec3(0.141000,2.115000,0.423000);
positions[36] = Vec3(0.141000,2.115000,0.987000);
positions[37] = Vec3(0.141000,2.115000,1.551000);
positions[38] = Vec3(0.141000,2.115000,2.115000);
positions[39] = Vec3(0.141000,2.115000,2.679000);
positions[40] = Vec3(0.141000,2.397000,0.141000);
positions[41] = Vec3(0.141000,2.397000,0.705000);
positions[42] = Vec3(0.141000,2.397000,1.269000);
positions[43] = Vec3(0.141000,2.397000,1.833000);
positions[44] = Vec3(0.141000,2.397000,2.397000);
positions[45] = Vec3(0.141000,2.679000,0.423000);
positions[46] = Vec3(0.141000,2.679000,0.987000);
positions[47] = Vec3(0.141000,2.679000,1.551000);
positions[48] = Vec3(0.141000,2.679000,2.115000);
positions[49] = Vec3(0.141000,2.679000,2.679000);
positions[50] = Vec3(0.423000,0.141000,0.423000);
positions[51] = Vec3(0.423000,0.141000,0.987000);
positions[52] = Vec3(0.423000,0.141000,1.551000);
positions[53] = Vec3(0.423000,0.141000,2.115000);
positions[54] = Vec3(0.423000,0.141000,2.679000);
positions[55] = Vec3(0.423000,0.423000,0.141000);
positions[56] = Vec3(0.423000,0.423000,0.705000);
positions[57] = Vec3(0.423000,0.423000,1.269000);
positions[58] = Vec3(0.423000,0.423000,1.833000);
positions[59] = Vec3(0.423000,0.423000,2.397000);
positions[60] = Vec3(0.423000,0.705000,0.423000);
positions[61] = Vec3(0.423000,0.705000,0.987000);
positions[62] = Vec3(0.423000,0.705000,1.551000);
positions[63] = Vec3(0.423000,0.705000,2.115000);
positions[64] = Vec3(0.423000,0.705000,2.679000);
positions[65] = Vec3(0.423000,0.987000,0.141000);
positions[66] = Vec3(0.423000,0.987000,0.705000);
positions[67] = Vec3(0.423000,0.987000,1.269000);
positions[68] = Vec3(0.423000,0.987000,1.833000);
positions[69] = Vec3(0.423000,0.987000,2.397000);
positions[70] = Vec3(0.423000,1.269000,0.423000);
positions[71] = Vec3(0.423000,1.269000,0.987000);
positions[72] = Vec3(0.423000,1.269000,1.551000);
positions[73] = Vec3(0.423000,1.269000,2.115000);
positions[74] = Vec3(0.423000,1.269000,2.679000);
positions[75] = Vec3(0.423000,1.551000,0.141000);
positions[76] = Vec3(0.423000,1.551000,0.705000);
positions[77] = Vec3(0.423000,1.551000,1.269000);
positions[78] = Vec3(0.423000,1.551000,1.833000);
positions[79] = Vec3(0.423000,1.551000,2.397000);
positions[80] = Vec3(0.423000,1.833000,0.423000);
positions[81] = Vec3(0.423000,1.833000,0.987000);
positions[82] = Vec3(0.423000,1.833000,1.551000);
positions[83] = Vec3(0.423000,1.833000,2.115000);
positions[84] = Vec3(0.423000,1.833000,2.679000);
positions[85] = Vec3(0.423000,2.115000,0.141000);
positions[86] = Vec3(0.423000,2.115000,0.705000);
positions[87] = Vec3(0.423000,2.115000,1.269000);
positions[88] = Vec3(0.423000,2.115000,1.833000);
positions[89] = Vec3(0.423000,2.115000,2.397000);
positions[90] = Vec3(0.423000,2.397000,0.423000);
positions[91] = Vec3(0.423000,2.397000,0.987000);
positions[92] = Vec3(0.423000,2.397000,1.551000);
positions[93] = Vec3(0.423000,2.397000,2.115000);
positions[94] = Vec3(0.423000,2.397000,2.679000);
positions[95] = Vec3(0.423000,2.679000,0.141000);
positions[96] = Vec3(0.423000,2.679000,0.705000);
positions[97] = Vec3(0.423000,2.679000,1.269000);
positions[98] = Vec3(0.423000,2.679000,1.833000);
positions[99] = Vec3(0.423000,2.679000,2.397000);
positions[100] = Vec3(0.705000,0.141000,0.141000);
positions[101] = Vec3(0.705000,0.141000,0.705000);
positions[102] = Vec3(0.705000,0.141000,1.269000);
positions[103] = Vec3(0.705000,0.141000,1.833000);
positions[104] = Vec3(0.705000,0.141000,2.397000);
positions[105] = Vec3(0.705000,0.423000,0.423000);
positions[106] = Vec3(0.705000,0.423000,0.987000);
positions[107] = Vec3(0.705000,0.423000,1.551000);
positions[108] = Vec3(0.705000,0.423000,2.115000);
positions[109] = Vec3(0.705000,0.423000,2.679000);
positions[110] = Vec3(0.705000,0.705000,0.141000);
positions[111] = Vec3(0.705000,0.705000,0.705000);
positions[112] = Vec3(0.705000,0.705000,1.269000);
positions[113] = Vec3(0.705000,0.705000,1.833000);
positions[114] = Vec3(0.705000,0.705000,2.397000);
positions[115] = Vec3(0.705000,0.987000,0.423000);
positions[116] = Vec3(0.705000,0.987000,0.987000);
positions[117] = Vec3(0.705000,0.987000,1.551000);
positions[118] = Vec3(0.705000,0.987000,2.115000);
positions[119] = Vec3(0.705000,0.987000,2.679000);
positions[120] = Vec3(0.705000,1.269000,0.141000);
positions[121] = Vec3(0.705000,1.269000,0.705000);
positions[122] = Vec3(0.705000,1.269000,1.269000);
positions[123] = Vec3(0.705000,1.269000,1.833000);
positions[124] = Vec3(0.705000,1.269000,2.397000);
positions[125] = Vec3(0.705000,1.551000,0.423000);
positions[126] = Vec3(0.705000,1.551000,0.987000);
positions[127] = Vec3(0.705000,1.551000,1.551000);
positions[128] = Vec3(0.705000,1.551000,2.115000);
positions[129] = Vec3(0.705000,1.551000,2.679000);
positions[130] = Vec3(0.705000,1.833000,0.141000);
positions[131] = Vec3(0.705000,1.833000,0.705000);
positions[132] = Vec3(0.705000,1.833000,1.269000);
positions[133] = Vec3(0.705000,1.833000,1.833000);
positions[134] = Vec3(0.705000,1.833000,2.397000);
positions[135] = Vec3(0.705000,2.115000,0.423000);
positions[136] = Vec3(0.705000,2.115000,0.987000);
positions[137] = Vec3(0.705000,2.115000,1.551000);
positions[138] = Vec3(0.705000,2.115000,2.115000);
positions[139] = Vec3(0.705000,2.115000,2.679000);
positions[140] = Vec3(0.705000,2.397000,0.141000);
positions[141] = Vec3(0.705000,2.397000,0.705000);
positions[142] = Vec3(0.705000,2.397000,1.269000);
positions[143] = Vec3(0.705000,2.397000,1.833000);
positions[144] = Vec3(0.705000,2.397000,2.397000);
positions[145] = Vec3(0.705000,2.679000,0.423000);
positions[146] = Vec3(0.705000,2.679000,0.987000);
positions[147] = Vec3(0.705000,2.679000,1.551000);
positions[148] = Vec3(0.705000,2.679000,2.115000);
positions[149] = Vec3(0.705000,2.679000,2.679000);
positions[150] = Vec3(0.987000,0.141000,0.423000);
positions[151] = Vec3(0.987000,0.141000,0.987000);
positions[152] = Vec3(0.987000,0.141000,1.551000);
positions[153] = Vec3(0.987000,0.141000,2.115000);
positions[154] = Vec3(0.987000,0.141000,2.679000);
positions[155] = Vec3(0.987000,0.423000,0.141000);
positions[156] = Vec3(0.987000,0.423000,0.705000);
positions[157] = Vec3(0.987000,0.423000,1.269000);
positions[158] = Vec3(0.987000,0.423000,1.833000);
positions[159] = Vec3(0.987000,0.423000,2.397000);
positions[160] = Vec3(0.987000,0.705000,0.423000);
positions[161] = Vec3(0.987000,0.705000,0.987000);
positions[162] = Vec3(0.987000,0.705000,1.551000);
positions[163] = Vec3(0.987000,0.705000,2.115000);
positions[164] = Vec3(0.987000,0.705000,2.679000);
positions[165] = Vec3(0.987000,0.987000,0.141000);
positions[166] = Vec3(0.987000,0.987000,0.705000);
positions[167] = Vec3(0.987000,0.987000,1.269000);
positions[168] = Vec3(0.987000,0.987000,1.833000);
positions[169] = Vec3(0.987000,0.987000,2.397000);
positions[170] = Vec3(0.987000,1.269000,0.423000);
positions[171] = Vec3(0.987000,1.269000,0.987000);
positions[172] = Vec3(0.987000,1.269000,1.551000);
positions[173] = Vec3(0.987000,1.269000,2.115000);
positions[174] = Vec3(0.987000,1.269000,2.679000);
positions[175] = Vec3(0.987000,1.551000,0.141000);
positions[176] = Vec3(0.987000,1.551000,0.705000);
positions[177] = Vec3(0.987000,1.551000,1.269000);
positions[178] = Vec3(0.987000,1.551000,1.833000);
positions[179] = Vec3(0.987000,1.551000,2.397000);
positions[180] = Vec3(0.987000,1.833000,0.423000);
positions[181] = Vec3(0.987000,1.833000,0.987000);
positions[182] = Vec3(0.987000,1.833000,1.551000);
positions[183] = Vec3(0.987000,1.833000,2.115000);
positions[184] = Vec3(0.987000,1.833000,2.679000);
positions[185] = Vec3(0.987000,2.115000,0.141000);
positions[186] = Vec3(0.987000,2.115000,0.705000);
positions[187] = Vec3(0.987000,2.115000,1.269000);
positions[188] = Vec3(0.987000,2.115000,1.833000);
positions[189] = Vec3(0.987000,2.115000,2.397000);
positions[190] = Vec3(0.987000,2.397000,0.423000);
positions[191] = Vec3(0.987000,2.397000,0.987000);
positions[192] = Vec3(0.987000,2.397000,1.551000);
positions[193] = Vec3(0.987000,2.397000,2.115000);
positions[194] = Vec3(0.987000,2.397000,2.679000);
positions[195] = Vec3(0.987000,2.679000,0.141000);
positions[196] = Vec3(0.987000,2.679000,0.705000);
positions[197] = Vec3(0.987000,2.679000,1.269000);
positions[198] = Vec3(0.987000,2.679000,1.833000);
positions[199] = Vec3(0.987000,2.679000,2.397000);
positions[200] = Vec3(1.269000,0.141000,0.141000);
positions[201] = Vec3(1.269000,0.141000,0.705000);
positions[202] = Vec3(1.269000,0.141000,1.269000);
positions[203] = Vec3(1.269000,0.141000,1.833000);
positions[204] = Vec3(1.269000,0.141000,2.397000);
positions[205] = Vec3(1.269000,0.423000,0.423000);
positions[206] = Vec3(1.269000,0.423000,0.987000);
positions[207] = Vec3(1.269000,0.423000,1.551000);
positions[208] = Vec3(1.269000,0.423000,2.115000);
positions[209] = Vec3(1.269000,0.423000,2.679000);
positions[210] = Vec3(1.269000,0.705000,0.141000);
positions[211] = Vec3(1.269000,0.705000,0.705000);
positions[212] = Vec3(1.269000,0.705000,1.269000);
positions[213] = Vec3(1.269000,0.705000,1.833000);
positions[214] = Vec3(1.269000,0.705000,2.397000);
positions[215] = Vec3(1.269000,0.987000,0.423000);
positions[216] = Vec3(1.269000,0.987000,0.987000);
positions[217] = Vec3(1.269000,0.987000,1.551000);
positions[218] = Vec3(1.269000,0.987000,2.115000);
positions[219] = Vec3(1.269000,0.987000,2.679000);
positions[220] = Vec3(1.269000,1.269000,0.141000);
positions[221] = Vec3(1.269000,1.269000,0.705000);
positions[222] = Vec3(1.269000,1.269000,1.269000);
positions[223] = Vec3(1.269000,1.269000,1.833000);
positions[224] = Vec3(1.269000,1.269000,2.397000);
positions[225] = Vec3(1.269000,1.551000,0.423000);
positions[226] = Vec3(1.269000,1.551000,0.987000);
positions[227] = Vec3(1.269000,1.551000,1.551000);
positions[228] = Vec3(1.269000,1.551000,2.115000);
positions[229] = Vec3(1.269000,1.551000,2.679000);
positions[230] = Vec3(1.269000,1.833000,0.141000);
positions[231] = Vec3(1.269000,1.833000,0.705000);
positions[232] = Vec3(1.269000,1.833000,1.269000);
positions[233] = Vec3(1.269000,1.833000,1.833000);
positions[234] = Vec3(1.269000,1.833000,2.397000);
positions[235] = Vec3(1.269000,2.115000,0.423000);
positions[236] = Vec3(1.269000,2.115000,0.987000);
positions[237] = Vec3(1.269000,2.115000,1.551000);
positions[238] = Vec3(1.269000,2.115000,2.115000);
positions[239] = Vec3(1.269000,2.115000,2.679000);
positions[240] = Vec3(1.269000,2.397000,0.141000);
positions[241] = Vec3(1.269000,2.397000,0.705000);
positions[242] = Vec3(1.269000,2.397000,1.269000);
positions[243] = Vec3(1.269000,2.397000,1.833000);
positions[244] = Vec3(1.269000,2.397000,2.397000);
positions[245] = Vec3(1.269000,2.679000,0.423000);
positions[246] = Vec3(1.269000,2.679000,0.987000);
positions[247] = Vec3(1.269000,2.679000,1.551000);
positions[248] = Vec3(1.269000,2.679000,2.115000);
positions[249] = Vec3(1.269000,2.679000,2.679000);
positions[250] = Vec3(1.551000,0.141000,0.423000);
positions[251] = Vec3(1.551000,0.141000,0.987000);
positions[252] = Vec3(1.551000,0.141000,1.551000);
positions[253] = Vec3(1.551000,0.141000,2.115000);
positions[254] = Vec3(1.551000,0.141000,2.679000);
positions[255] = Vec3(1.551000,0.423000,0.141000);
positions[256] = Vec3(1.551000,0.423000,0.705000);
positions[257] = Vec3(1.551000,0.423000,1.269000);
positions[258] = Vec3(1.551000,0.423000,1.833000);
positions[259] = Vec3(1.551000,0.423000,2.397000);
positions[260] = Vec3(1.551000,0.705000,0.423000);
positions[261] = Vec3(1.551000,0.705000,0.987000);
positions[262] = Vec3(1.551000,0.705000,1.551000);
positions[263] = Vec3(1.551000,0.705000,2.115000);
positions[264] = Vec3(1.551000,0.705000,2.679000);
positions[265] = Vec3(1.551000,0.987000,0.141000);
positions[266] = Vec3(1.551000,0.987000,0.705000);
positions[267] = Vec3(1.551000,0.987000,1.269000);
positions[268] = Vec3(1.551000,0.987000,1.833000);
positions[269] = Vec3(1.551000,0.987000,2.397000);
positions[270] = Vec3(1.551000,1.269000,0.423000);
positions[271] = Vec3(1.551000,1.269000,0.987000);
positions[272] = Vec3(1.551000,1.269000,1.551000);
positions[273] = Vec3(1.551000,1.269000,2.115000);
positions[274] = Vec3(1.551000,1.269000,2.679000);
positions[275] = Vec3(1.551000,1.551000,0.141000);
positions[276] = Vec3(1.551000,1.551000,0.705000);
positions[277] = Vec3(1.551000,1.551000,1.269000);
positions[278] = Vec3(1.551000,1.551000,1.833000);
positions[279] = Vec3(1.551000,1.551000,2.397000);
positions[280] = Vec3(1.551000,1.833000,0.423000);
positions[281] = Vec3(1.551000,1.833000,0.987000);
positions[282] = Vec3(1.551000,1.833000,1.551000);
positions[283] = Vec3(1.551000,1.833000,2.115000);
positions[284] = Vec3(1.551000,1.833000,2.679000);
positions[285] = Vec3(1.551000,2.115000,0.141000);
positions[286] = Vec3(1.551000,2.115000,0.705000);
positions[287] = Vec3(1.551000,2.115000,1.269000);
positions[288] = Vec3(1.551000,2.115000,1.833000);
positions[289] = Vec3(1.551000,2.115000,2.397000);
positions[290] = Vec3(1.551000,2.397000,0.423000);
positions[291] = Vec3(1.551000,2.397000,0.987000);
positions[292] = Vec3(1.551000,2.397000,1.551000);
positions[293] = Vec3(1.551000,2.397000,2.115000);
positions[294] = Vec3(1.551000,2.397000,2.679000);
positions[295] = Vec3(1.551000,2.679000,0.141000);
positions[296] = Vec3(1.551000,2.679000,0.705000);
positions[297] = Vec3(1.551000,2.679000,1.269000);
positions[298] = Vec3(1.551000,2.679000,1.833000);
positions[299] = Vec3(1.551000,2.679000,2.397000);
positions[300] = Vec3(1.833000,0.141000,0.141000);
positions[301] = Vec3(1.833000,0.141000,0.705000);
positions[302] = Vec3(1.833000,0.141000,1.269000);
positions[303] = Vec3(1.833000,0.141000,1.833000);
positions[304] = Vec3(1.833000,0.141000,2.397000);
positions[305] = Vec3(1.833000,0.423000,0.423000);
positions[306] = Vec3(1.833000,0.423000,0.987000);
positions[307] = Vec3(1.833000,0.423000,1.551000);
positions[308] = Vec3(1.833000,0.423000,2.115000);
positions[309] = Vec3(1.833000,0.423000,2.679000);
positions[310] = Vec3(1.833000,0.705000,0.141000);
positions[311] = Vec3(1.833000,0.705000,0.705000);
positions[312] = Vec3(1.833000,0.705000,1.269000);
positions[313] = Vec3(1.833000,0.705000,1.833000);
positions[314] = Vec3(1.833000,0.705000,2.397000);
positions[315] = Vec3(1.833000,0.987000,0.423000);
positions[316] = Vec3(1.833000,0.987000,0.987000);
positions[317] = Vec3(1.833000,0.987000,1.551000);
positions[318] = Vec3(1.833000,0.987000,2.115000);
positions[319] = Vec3(1.833000,0.987000,2.679000);
positions[320] = Vec3(1.833000,1.269000,0.141000);
positions[321] = Vec3(1.833000,1.269000,0.705000);
positions[322] = Vec3(1.833000,1.269000,1.269000);
positions[323] = Vec3(1.833000,1.269000,1.833000);
positions[324] = Vec3(1.833000,1.269000,2.397000);
positions[325] = Vec3(1.833000,1.551000,0.423000);
positions[326] = Vec3(1.833000,1.551000,0.987000);
positions[327] = Vec3(1.833000,1.551000,1.551000);
positions[328] = Vec3(1.833000,1.551000,2.115000);
positions[329] = Vec3(1.833000,1.551000,2.679000);
positions[330] = Vec3(1.833000,1.833000,0.141000);
positions[331] = Vec3(1.833000,1.833000,0.705000);
positions[332] = Vec3(1.833000,1.833000,1.269000);
positions[333] = Vec3(1.833000,1.833000,1.833000);
positions[334] = Vec3(1.833000,1.833000,2.397000);
positions[335] = Vec3(1.833000,2.115000,0.423000);
positions[336] = Vec3(1.833000,2.115000,0.987000);
positions[337] = Vec3(1.833000,2.115000,1.551000);
positions[338] = Vec3(1.833000,2.115000,2.115000);
positions[339] = Vec3(1.833000,2.115000,2.679000);
positions[340] = Vec3(1.833000,2.397000,0.141000);
positions[341] = Vec3(1.833000,2.397000,0.705000);
positions[342] = Vec3(1.833000,2.397000,1.269000);
positions[343] = Vec3(1.833000,2.397000,1.833000);
positions[344] = Vec3(1.833000,2.397000,2.397000);
positions[345] = Vec3(1.833000,2.679000,0.423000);
positions[346] = Vec3(1.833000,2.679000,0.987000);
positions[347] = Vec3(1.833000,2.679000,1.551000);
positions[348] = Vec3(1.833000,2.679000,2.115000);
positions[349] = Vec3(1.833000,2.679000,2.679000);
positions[350] = Vec3(2.115000,0.141000,0.423000);
positions[351] = Vec3(2.115000,0.141000,0.987000);
positions[352] = Vec3(2.115000,0.141000,1.551000);
positions[353] = Vec3(2.115000,0.141000,2.115000);
positions[354] = Vec3(2.115000,0.141000,2.679000);
positions[355] = Vec3(2.115000,0.423000,0.141000);
positions[356] = Vec3(2.115000,0.423000,0.705000);
positions[357] = Vec3(2.115000,0.423000,1.269000);
positions[358] = Vec3(2.115000,0.423000,1.833000);
positions[359] = Vec3(2.115000,0.423000,2.397000);
positions[360] = Vec3(2.115000,0.705000,0.423000);
positions[361] = Vec3(2.115000,0.705000,0.987000);
positions[362] = Vec3(2.115000,0.705000,1.551000);
positions[363] = Vec3(2.115000,0.705000,2.115000);
positions[364] = Vec3(2.115000,0.705000,2.679000);
positions[365] = Vec3(2.115000,0.987000,0.141000);
positions[366] = Vec3(2.115000,0.987000,0.705000);
positions[367] = Vec3(2.115000,0.987000,1.269000);
positions[368] = Vec3(2.115000,0.987000,1.833000);
positions[369] = Vec3(2.115000,0.987000,2.397000);
positions[370] = Vec3(2.115000,1.269000,0.423000);
positions[371] = Vec3(2.115000,1.269000,0.987000);
positions[372] = Vec3(2.115000,1.269000,1.551000);
positions[373] = Vec3(2.115000,1.269000,2.115000);
positions[374] = Vec3(2.115000,1.269000,2.679000);
positions[375] = Vec3(2.115000,1.551000,0.141000);
positions[376] = Vec3(2.115000,1.551000,0.705000);
positions[377] = Vec3(2.115000,1.551000,1.269000);
positions[378] = Vec3(2.115000,1.551000,1.833000);
positions[379] = Vec3(2.115000,1.551000,2.397000);
positions[380] = Vec3(2.115000,1.833000,0.423000);
positions[381] = Vec3(2.115000,1.833000,0.987000);
positions[382] = Vec3(2.115000,1.833000,1.551000);
positions[383] = Vec3(2.115000,1.833000,2.115000);
positions[384] = Vec3(2.115000,1.833000,2.679000);
positions[385] = Vec3(2.115000,2.115000,0.141000);
positions[386] = Vec3(2.115000,2.115000,0.705000);
positions[387] = Vec3(2.115000,2.115000,1.269000);
positions[388] = Vec3(2.115000,2.115000,1.833000);
positions[389] = Vec3(2.115000,2.115000,2.397000);
positions[390] = Vec3(2.115000,2.397000,0.423000);
positions[391] = Vec3(2.115000,2.397000,0.987000);
positions[392] = Vec3(2.115000,2.397000,1.551000);
positions[393] = Vec3(2.115000,2.397000,2.115000);
positions[394] = Vec3(2.115000,2.397000,2.679000);
positions[395] = Vec3(2.115000,2.679000,0.141000);
positions[396] = Vec3(2.115000,2.679000,0.705000);
positions[397] = Vec3(2.115000,2.679000,1.269000);
positions[398] = Vec3(2.115000,2.679000,1.833000);
positions[399] = Vec3(2.115000,2.679000,2.397000);
positions[400] = Vec3(2.397000,0.141000,0.141000);
positions[401] = Vec3(2.397000,0.141000,0.705000);
positions[402] = Vec3(2.397000,0.141000,1.269000);
positions[403] = Vec3(2.397000,0.141000,1.833000);
positions[404] = Vec3(2.397000,0.141000,2.397000);
positions[405] = Vec3(2.397000,0.423000,0.423000);
positions[406] = Vec3(2.397000,0.423000,0.987000);
positions[407] = Vec3(2.397000,0.423000,1.551000);
positions[408] = Vec3(2.397000,0.423000,2.115000);
positions[409] = Vec3(2.397000,0.423000,2.679000);
positions[410] = Vec3(2.397000,0.705000,0.141000);
positions[411] = Vec3(2.397000,0.705000,0.705000);
positions[412] = Vec3(2.397000,0.705000,1.269000);
positions[413] = Vec3(2.397000,0.705000,1.833000);
positions[414] = Vec3(2.397000,0.705000,2.397000);
positions[415] = Vec3(2.397000,0.987000,0.423000);
positions[416] = Vec3(2.397000,0.987000,0.987000);
positions[417] = Vec3(2.397000,0.987000,1.551000);
positions[418] = Vec3(2.397000,0.987000,2.115000);
positions[419] = Vec3(2.397000,0.987000,2.679000);
positions[420] = Vec3(2.397000,1.269000,0.141000);
positions[421] = Vec3(2.397000,1.269000,0.705000);
positions[422] = Vec3(2.397000,1.269000,1.269000);
positions[423] = Vec3(2.397000,1.269000,1.833000);
positions[424] = Vec3(2.397000,1.269000,2.397000);
positions[425] = Vec3(2.397000,1.551000,0.423000);
positions[426] = Vec3(2.397000,1.551000,0.987000);
positions[427] = Vec3(2.397000,1.551000,1.551000);
positions[428] = Vec3(2.397000,1.551000,2.115000);
positions[429] = Vec3(2.397000,1.551000,2.679000);
positions[430] = Vec3(2.397000,1.833000,0.141000);
positions[431] = Vec3(2.397000,1.833000,0.705000);
positions[432] = Vec3(2.397000,1.833000,1.269000);
positions[433] = Vec3(2.397000,1.833000,1.833000);
positions[434] = Vec3(2.397000,1.833000,2.397000);
positions[435] = Vec3(2.397000,2.115000,0.423000);
positions[436] = Vec3(2.397000,2.115000,0.987000);
positions[437] = Vec3(2.397000,2.115000,1.551000);
positions[438] = Vec3(2.397000,2.115000,2.115000);
positions[439] = Vec3(2.397000,2.115000,2.679000);
positions[440] = Vec3(2.397000,2.397000,0.141000);
positions[441] = Vec3(2.397000,2.397000,0.705000);
positions[442] = Vec3(2.397000,2.397000,1.269000);
positions[443] = Vec3(2.397000,2.397000,1.833000);
positions[444] = Vec3(2.397000,2.397000,2.397000);
positions[445] = Vec3(2.397000,2.679000,0.423000);
positions[446] = Vec3(2.397000,2.679000,0.987000);
positions[447] = Vec3(2.397000,2.679000,1.551000);
positions[448] = Vec3(2.397000,2.679000,2.115000);
positions[449] = Vec3(2.397000,2.679000,2.679000);
positions[450] = Vec3(2.679000,0.141000,0.423000);
positions[451] = Vec3(2.679000,0.141000,0.987000);
positions[452] = Vec3(2.679000,0.141000,1.551000);
positions[453] = Vec3(2.679000,0.141000,2.115000);
positions[454] = Vec3(2.679000,0.141000,2.679000);
positions[455] = Vec3(2.679000,0.423000,0.141000);
positions[456] = Vec3(2.679000,0.423000,0.705000);
positions[457] = Vec3(2.679000,0.423000,1.269000);
positions[458] = Vec3(2.679000,0.423000,1.833000);
positions[459] = Vec3(2.679000,0.423000,2.397000);
positions[460] = Vec3(2.679000,0.705000,0.423000);
positions[461] = Vec3(2.679000,0.705000,0.987000);
positions[462] = Vec3(2.679000,0.705000,1.551000);
positions[463] = Vec3(2.679000,0.705000,2.115000);
positions[464] = Vec3(2.679000,0.705000,2.679000);
positions[465] = Vec3(2.679000,0.987000,0.141000);
positions[466] = Vec3(2.679000,0.987000,0.705000);
positions[467] = Vec3(2.679000,0.987000,1.269000);
positions[468] = Vec3(2.679000,0.987000,1.833000);
positions[469] = Vec3(2.679000,0.987000,2.397000);
positions[470] = Vec3(2.679000,1.269000,0.423000);
positions[471] = Vec3(2.679000,1.269000,0.987000);
positions[472] = Vec3(2.679000,1.269000,1.551000);
positions[473] = Vec3(2.679000,1.269000,2.115000);
positions[474] = Vec3(2.679000,1.269000,2.679000);
positions[475] = Vec3(2.679000,1.551000,0.141000);
positions[476] = Vec3(2.679000,1.551000,0.705000);
positions[477] = Vec3(2.679000,1.551000,1.269000);
positions[478] = Vec3(2.679000,1.551000,1.833000);
positions[479] = Vec3(2.679000,1.551000,2.397000);
positions[480] = Vec3(2.679000,1.833000,0.423000);
positions[481] = Vec3(2.679000,1.833000,0.987000);
positions[482] = Vec3(2.679000,1.833000,1.551000);
positions[483] = Vec3(2.679000,1.833000,2.115000);
positions[484] = Vec3(2.679000,1.833000,2.679000);
positions[485] = Vec3(2.679000,2.115000,0.141000);
positions[486] = Vec3(2.679000,2.115000,0.705000);
positions[487] = Vec3(2.679000,2.115000,1.269000);
positions[488] = Vec3(2.679000,2.115000,1.833000);
positions[489] = Vec3(2.679000,2.115000,2.397000);
positions[490] = Vec3(2.679000,2.397000,0.423000);
positions[491] = Vec3(2.679000,2.397000,0.987000);
positions[492] = Vec3(2.679000,2.397000,1.551000);
positions[493] = Vec3(2.679000,2.397000,2.115000);
positions[494] = Vec3(2.679000,2.397000,2.679000);
positions[495] = Vec3(2.679000,2.679000,0.141000);
positions[496] = Vec3(2.679000,2.679000,0.705000);
positions[497] = Vec3(2.679000,2.679000,1.269000);
positions[498] = Vec3(2.679000,2.679000,1.833000);
positions[499] = Vec3(2.679000,2.679000,2.397000);
positions[500] = Vec3(0.141000,0.141000,0.423000);
positions[501] = Vec3(0.141000,0.141000,0.987000);
positions[502] = Vec3(0.141000,0.141000,1.551000);
positions[503] = Vec3(0.141000,0.141000,2.115000);
positions[504] = Vec3(0.141000,0.141000,2.679000);
positions[505] = Vec3(0.141000,0.423000,0.141000);
positions[506] = Vec3(0.141000,0.423000,0.705000);
positions[507] = Vec3(0.141000,0.423000,1.269000);
positions[508] = Vec3(0.141000,0.423000,1.833000);
positions[509] = Vec3(0.141000,0.423000,2.397000);
positions[510] = Vec3(0.141000,0.705000,0.423000);
positions[511] = Vec3(0.141000,0.705000,0.987000);
positions[512] = Vec3(0.141000,0.705000,1.551000);
positions[513] = Vec3(0.141000,0.705000,2.115000);
positions[514] = Vec3(0.141000,0.705000,2.679000);
positions[515] = Vec3(0.141000,0.987000,0.141000);
positions[516] = Vec3(0.141000,0.987000,0.705000);
positions[517] = Vec3(0.141000,0.987000,1.269000);
positions[518] = Vec3(0.141000,0.987000,1.833000);
positions[519] = Vec3(0.141000,0.987000,2.397000);
positions[520] = Vec3(0.141000,1.269000,0.423000);
positions[521] = Vec3(0.141000,1.269000,0.987000);
positions[522] = Vec3(0.141000,1.269000,1.551000);
positions[523] = Vec3(0.141000,1.269000,2.115000);
positions[524] = Vec3(0.141000,1.269000,2.679000);
positions[525] = Vec3(0.141000,1.551000,0.141000);
positions[526] = Vec3(0.141000,1.551000,0.705000);
positions[527] = Vec3(0.141000,1.551000,1.269000);
positions[528] = Vec3(0.141000,1.551000,1.833000);
positions[529] = Vec3(0.141000,1.551000,2.397000);
positions[530] = Vec3(0.141000,1.833000,0.423000);
positions[531] = Vec3(0.141000,1.833000,0.987000);
positions[532] = Vec3(0.141000,1.833000,1.551000);
positions[533] = Vec3(0.141000,1.833000,2.115000);
positions[534] = Vec3(0.141000,1.833000,2.679000);
positions[535] = Vec3(0.141000,2.115000,0.141000);
positions[536] = Vec3(0.141000,2.115000,0.705000);
positions[537] = Vec3(0.141000,2.115000,1.269000);
positions[538] = Vec3(0.141000,2.115000,1.833000);
positions[539] = Vec3(0.141000,2.115000,2.397000);
positions[540] = Vec3(0.141000,2.397000,0.423000);
positions[541] = Vec3(0.141000,2.397000,0.987000);
positions[542] = Vec3(0.141000,2.397000,1.551000);
positions[543] = Vec3(0.141000,2.397000,2.115000);
positions[544] = Vec3(0.141000,2.397000,2.679000);
positions[545] = Vec3(0.141000,2.679000,0.141000);
positions[546] = Vec3(0.141000,2.679000,0.705000);
positions[547] = Vec3(0.141000,2.679000,1.269000);
positions[548] = Vec3(0.141000,2.679000,1.833000);
positions[549] = Vec3(0.141000,2.679000,2.397000);
positions[550] = Vec3(0.423000,0.141000,0.141000);
positions[551] = Vec3(0.423000,0.141000,0.705000);
positions[552] = Vec3(0.423000,0.141000,1.269000);
positions[553] = Vec3(0.423000,0.141000,1.833000);
positions[554] = Vec3(0.423000,0.141000,2.397000);
positions[555] = Vec3(0.423000,0.423000,0.423000);
positions[556] = Vec3(0.423000,0.423000,0.987000);
positions[557] = Vec3(0.423000,0.423000,1.551000);
positions[558] = Vec3(0.423000,0.423000,2.115000);
positions[559] = Vec3(0.423000,0.423000,2.679000);
positions[560] = Vec3(0.423000,0.705000,0.141000);
positions[561] = Vec3(0.423000,0.705000,0.705000);
positions[562] = Vec3(0.423000,0.705000,1.269000);
positions[563] = Vec3(0.423000,0.705000,1.833000);
positions[564] = Vec3(0.423000,0.705000,2.397000);
positions[565] = Vec3(0.423000,0.987000,0.423000);
positions[566] = Vec3(0.423000,0.987000,0.987000);
positions[567] = Vec3(0.423000,0.987000,1.551000);
positions[568] = Vec3(0.423000,0.987000,2.115000);
positions[569] = Vec3(0.423000,0.987000,2.679000);
positions[570] = Vec3(0.423000,1.269000,0.141000);
positions[571] = Vec3(0.423000,1.269000,0.705000);
positions[572] = Vec3(0.423000,1.269000,1.269000);
positions[573] = Vec3(0.423000,1.269000,1.833000);
positions[574] = Vec3(0.423000,1.269000,2.397000);
positions[575] = Vec3(0.423000,1.551000,0.423000);
positions[576] = Vec3(0.423000,1.551000,0.987000);
positions[577] = Vec3(0.423000,1.551000,1.551000);
positions[578] = Vec3(0.423000,1.551000,2.115000);
positions[579] = Vec3(0.423000,1.551000,2.679000);
positions[580] = Vec3(0.423000,1.833000,0.141000);
positions[581] = Vec3(0.423000,1.833000,0.705000);
positions[582] = Vec3(0.423000,1.833000,1.269000);
positions[583] = Vec3(0.423000,1.833000,1.833000);
positions[584] = Vec3(0.423000,1.833000,2.397000);
positions[585] = Vec3(0.423000,2.115000,0.423000);
positions[586] = Vec3(0.423000,2.115000,0.987000);
positions[587] = Vec3(0.423000,2.115000,1.551000);
positions[588] = Vec3(0.423000,2.115000,2.115000);
positions[589] = Vec3(0.423000,2.115000,2.679000);
positions[590] = Vec3(0.423000,2.397000,0.141000);
positions[591] = Vec3(0.423000,2.397000,0.705000);
positions[592] = Vec3(0.423000,2.397000,1.269000);
positions[593] = Vec3(0.423000,2.397000,1.833000);
positions[594] = Vec3(0.423000,2.397000,2.397000);
positions[595] = Vec3(0.423000,2.679000,0.423000);
positions[596] = Vec3(0.423000,2.679000,0.987000);
positions[597] = Vec3(0.423000,2.679000,1.551000);
positions[598] = Vec3(0.423000,2.679000,2.115000);
positions[599] = Vec3(0.423000,2.679000,2.679000);
positions[600] = Vec3(0.705000,0.141000,0.423000);
positions[601] = Vec3(0.705000,0.141000,0.987000);
positions[602] = Vec3(0.705000,0.141000,1.551000);
positions[603] = Vec3(0.705000,0.141000,2.115000);
positions[604] = Vec3(0.705000,0.141000,2.679000);
positions[605] = Vec3(0.705000,0.423000,0.141000);
positions[606] = Vec3(0.705000,0.423000,0.705000);
positions[607] = Vec3(0.705000,0.423000,1.269000);
positions[608] = Vec3(0.705000,0.423000,1.833000);
positions[609] = Vec3(0.705000,0.423000,2.397000);
positions[610] = Vec3(0.705000,0.705000,0.423000);
positions[611] = Vec3(0.705000,0.705000,0.987000);
positions[612] = Vec3(0.705000,0.705000,1.551000);
positions[613] = Vec3(0.705000,0.705000,2.115000);
positions[614] = Vec3(0.705000,0.705000,2.679000);
positions[615] = Vec3(0.705000,0.987000,0.141000);
positions[616] = Vec3(0.705000,0.987000,0.705000);
positions[617] = Vec3(0.705000,0.987000,1.269000);
positions[618] = Vec3(0.705000,0.987000,1.833000);
positions[619] = Vec3(0.705000,0.987000,2.397000);
positions[620] = Vec3(0.705000,1.269000,0.423000);
positions[621] = Vec3(0.705000,1.269000,0.987000);
positions[622] = Vec3(0.705000,1.269000,1.551000);
positions[623] = Vec3(0.705000,1.269000,2.115000);
positions[624] = Vec3(0.705000,1.269000,2.679000);
positions[625] = Vec3(0.705000,1.551000,0.141000);
positions[626] = Vec3(0.705000,1.551000,0.705000);
positions[627] = Vec3(0.705000,1.551000,1.269000);
positions[628] = Vec3(0.705000,1.551000,1.833000);
positions[629] = Vec3(0.705000,1.551000,2.397000);
positions[630] = Vec3(0.705000,1.833000,0.423000);
positions[631] = Vec3(0.705000,1.833000,0.987000);
positions[632] = Vec3(0.705000,1.833000,1.551000);
positions[633] = Vec3(0.705000,1.833000,2.115000);
positions[634] = Vec3(0.705000,1.833000,2.679000);
positions[635] = Vec3(0.705000,2.115000,0.141000);
positions[636] = Vec3(0.705000,2.115000,0.705000);
positions[637] = Vec3(0.705000,2.115000,1.269000);
positions[638] = Vec3(0.705000,2.115000,1.833000);
positions[639] = Vec3(0.705000,2.115000,2.397000);
positions[640] = Vec3(0.705000,2.397000,0.423000);
positions[641] = Vec3(0.705000,2.397000,0.987000);
positions[642] = Vec3(0.705000,2.397000,1.551000);
positions[643] = Vec3(0.705000,2.397000,2.115000);
positions[644] = Vec3(0.705000,2.397000,2.679000);
positions[645] = Vec3(0.705000,2.679000,0.141000);
positions[646] = Vec3(0.705000,2.679000,0.705000);
positions[647] = Vec3(0.705000,2.679000,1.269000);
positions[648] = Vec3(0.705000,2.679000,1.833000);
positions[649] = Vec3(0.705000,2.679000,2.397000);
positions[650] = Vec3(0.987000,0.141000,0.141000);
positions[651] = Vec3(0.987000,0.141000,0.705000);
positions[652] = Vec3(0.987000,0.141000,1.269000);
positions[653] = Vec3(0.987000,0.141000,1.833000);
positions[654] = Vec3(0.987000,0.141000,2.397000);
positions[655] = Vec3(0.987000,0.423000,0.423000);
positions[656] = Vec3(0.987000,0.423000,0.987000);
positions[657] = Vec3(0.987000,0.423000,1.551000);
positions[658] = Vec3(0.987000,0.423000,2.115000);
positions[659] = Vec3(0.987000,0.423000,2.679000);
positions[660] = Vec3(0.987000,0.705000,0.141000);
positions[661] = Vec3(0.987000,0.705000,0.705000);
positions[662] = Vec3(0.987000,0.705000,1.269000);
positions[663] = Vec3(0.987000,0.705000,1.833000);
positions[664] = Vec3(0.987000,0.705000,2.397000);
positions[665] = Vec3(0.987000,0.987000,0.423000);
positions[666] = Vec3(0.987000,0.987000,0.987000);
positions[667] = Vec3(0.987000,0.987000,1.551000);
positions[668] = Vec3(0.987000,0.987000,2.115000);
positions[669] = Vec3(0.987000,0.987000,2.679000);
positions[670] = Vec3(0.987000,1.269000,0.141000);
positions[671] = Vec3(0.987000,1.269000,0.705000);
positions[672] = Vec3(0.987000,1.269000,1.269000);
positions[673] = Vec3(0.987000,1.269000,1.833000);
positions[674] = Vec3(0.987000,1.269000,2.397000);
positions[675] = Vec3(0.987000,1.551000,0.423000);
positions[676] = Vec3(0.987000,1.551000,0.987000);
positions[677] = Vec3(0.987000,1.551000,1.551000);
positions[678] = Vec3(0.987000,1.551000,2.115000);
positions[679] = Vec3(0.987000,1.551000,2.679000);
positions[680] = Vec3(0.987000,1.833000,0.141000);
positions[681] = Vec3(0.987000,1.833000,0.705000);
positions[682] = Vec3(0.987000,1.833000,1.269000);
positions[683] = Vec3(0.987000,1.833000,1.833000);
positions[684] = Vec3(0.987000,1.833000,2.397000);
positions[685] = Vec3(0.987000,2.115000,0.423000);
positions[686] = Vec3(0.987000,2.115000,0.987000);
positions[687] = Vec3(0.987000,2.115000,1.551000);
positions[688] = Vec3(0.987000,2.115000,2.115000);
positions[689] = Vec3(0.987000,2.115000,2.679000);
positions[690] = Vec3(0.987000,2.397000,0.141000);
positions[691] = Vec3(0.987000,2.397000,0.705000);
positions[692] = Vec3(0.987000,2.397000,1.269000);
positions[693] = Vec3(0.987000,2.397000,1.833000);
positions[694] = Vec3(0.987000,2.397000,2.397000);
positions[695] = Vec3(0.987000,2.679000,0.423000);
positions[696] = Vec3(0.987000,2.679000,0.987000);
positions[697] = Vec3(0.987000,2.679000,1.551000);
positions[698] = Vec3(0.987000,2.679000,2.115000);
positions[699] = Vec3(0.987000,2.679000,2.679000);
positions[700] = Vec3(1.269000,0.141000,0.423000);
positions[701] = Vec3(1.269000,0.141000,0.987000);
positions[702] = Vec3(1.269000,0.141000,1.551000);
positions[703] = Vec3(1.269000,0.141000,2.115000);
positions[704] = Vec3(1.269000,0.141000,2.679000);
positions[705] = Vec3(1.269000,0.423000,0.141000);
positions[706] = Vec3(1.269000,0.423000,0.705000);
positions[707] = Vec3(1.269000,0.423000,1.269000);
positions[708] = Vec3(1.269000,0.423000,1.833000);
positions[709] = Vec3(1.269000,0.423000,2.397000);
positions[710] = Vec3(1.269000,0.705000,0.423000);
positions[711] = Vec3(1.269000,0.705000,0.987000);
positions[712] = Vec3(1.269000,0.705000,1.551000);
positions[713] = Vec3(1.269000,0.705000,2.115000);
positions[714] = Vec3(1.269000,0.705000,2.679000);
positions[715] = Vec3(1.269000,0.987000,0.141000);
positions[716] = Vec3(1.269000,0.987000,0.705000);
positions[717] = Vec3(1.269000,0.987000,1.269000);
positions[718] = Vec3(1.269000,0.987000,1.833000);
positions[719] = Vec3(1.269000,0.987000,2.397000);
positions[720] = Vec3(1.269000,1.269000,0.423000);
positions[721] = Vec3(1.269000,1.269000,0.987000);
positions[722] = Vec3(1.269000,1.269000,1.551000);
positions[723] = Vec3(1.269000,1.269000,2.115000);
positions[724] = Vec3(1.269000,1.269000,2.679000);
positions[725] = Vec3(1.269000,1.551000,0.141000);
positions[726] = Vec3(1.269000,1.551000,0.705000);
positions[727] = Vec3(1.269000,1.551000,1.269000);
positions[728] = Vec3(1.269000,1.551000,1.833000);
positions[729] = Vec3(1.269000,1.551000,2.397000);
positions[730] = Vec3(1.269000,1.833000,0.423000);
positions[731] = Vec3(1.269000,1.833000,0.987000);
positions[732] = Vec3(1.269000,1.833000,1.551000);
positions[733] = Vec3(1.269000,1.833000,2.115000);
positions[734] = Vec3(1.269000,1.833000,2.679000);
positions[735] = Vec3(1.269000,2.115000,0.141000);
positions[736] = Vec3(1.269000,2.115000,0.705000);
positions[737] = Vec3(1.269000,2.115000,1.269000);
positions[738] = Vec3(1.269000,2.115000,1.833000);
positions[739] = Vec3(1.269000,2.115000,2.397000);
positions[740] = Vec3(1.269000,2.397000,0.423000);
positions[741] = Vec3(1.269000,2.397000,0.987000);
positions[742] = Vec3(1.269000,2.397000,1.551000);
positions[743] = Vec3(1.269000,2.397000,2.115000);
positions[744] = Vec3(1.269000,2.397000,2.679000);
positions[745] = Vec3(1.269000,2.679000,0.141000);
positions[746] = Vec3(1.269000,2.679000,0.705000);
positions[747] = Vec3(1.269000,2.679000,1.269000);
positions[748] = Vec3(1.269000,2.679000,1.833000);
positions[749] = Vec3(1.269000,2.679000,2.397000);
positions[750] = Vec3(1.551000,0.141000,0.141000);
positions[751] = Vec3(1.551000,0.141000,0.705000);
positions[752] = Vec3(1.551000,0.141000,1.269000);
positions[753] = Vec3(1.551000,0.141000,1.833000);
positions[754] = Vec3(1.551000,0.141000,2.397000);
positions[755] = Vec3(1.551000,0.423000,0.423000);
positions[756] = Vec3(1.551000,0.423000,0.987000);
positions[757] = Vec3(1.551000,0.423000,1.551000);
positions[758] = Vec3(1.551000,0.423000,2.115000);
positions[759] = Vec3(1.551000,0.423000,2.679000);
positions[760] = Vec3(1.551000,0.705000,0.141000);
positions[761] = Vec3(1.551000,0.705000,0.705000);
positions[762] = Vec3(1.551000,0.705000,1.269000);
positions[763] = Vec3(1.551000,0.705000,1.833000);
positions[764] = Vec3(1.551000,0.705000,2.397000);
positions[765] = Vec3(1.551000,0.987000,0.423000);
positions[766] = Vec3(1.551000,0.987000,0.987000);
positions[767] = Vec3(1.551000,0.987000,1.551000);
positions[768] = Vec3(1.551000,0.987000,2.115000);
positions[769] = Vec3(1.551000,0.987000,2.679000);
positions[770] = Vec3(1.551000,1.269000,0.141000);
positions[771] = Vec3(1.551000,1.269000,0.705000);
positions[772] = Vec3(1.551000,1.269000,1.269000);
positions[773] = Vec3(1.551000,1.269000,1.833000);
positions[774] = Vec3(1.551000,1.269000,2.397000);
positions[775] = Vec3(1.551000,1.551000,0.423000);
positions[776] = Vec3(1.551000,1.551000,0.987000);
positions[777] = Vec3(1.551000,1.551000,1.551000);
positions[778] = Vec3(1.551000,1.551000,2.115000);
positions[779] = Vec3(1.551000,1.551000,2.679000);
positions[780] = Vec3(1.551000,1.833000,0.141000);
positions[781] = Vec3(1.551000,1.833000,0.705000);
positions[782] = Vec3(1.551000,1.833000,1.269000);
positions[783] = Vec3(1.551000,1.833000,1.833000);
positions[784] = Vec3(1.551000,1.833000,2.397000);
positions[785] = Vec3(1.551000,2.115000,0.423000);
positions[786] = Vec3(1.551000,2.115000,0.987000);
positions[787] = Vec3(1.551000,2.115000,1.551000);
positions[788] = Vec3(1.551000,2.115000,2.115000);
positions[789] = Vec3(1.551000,2.115000,2.679000);
positions[790] = Vec3(1.551000,2.397000,0.141000);
positions[791] = Vec3(1.551000,2.397000,0.705000);
positions[792] = Vec3(1.551000,2.397000,1.269000);
positions[793] = Vec3(1.551000,2.397000,1.833000);
positions[794] = Vec3(1.551000,2.397000,2.397000);
positions[795] = Vec3(1.551000,2.679000,0.423000);
positions[796] = Vec3(1.551000,2.679000,0.987000);
positions[797] = Vec3(1.551000,2.679000,1.551000);
positions[798] = Vec3(1.551000,2.679000,2.115000);
positions[799] = Vec3(1.551000,2.679000,2.679000);
positions[800] = Vec3(1.833000,0.141000,0.423000);
positions[801] = Vec3(1.833000,0.141000,0.987000);
positions[802] = Vec3(1.833000,0.141000,1.551000);
positions[803] = Vec3(1.833000,0.141000,2.115000);
positions[804] = Vec3(1.833000,0.141000,2.679000);
positions[805] = Vec3(1.833000,0.423000,0.141000);
positions[806] = Vec3(1.833000,0.423000,0.705000);
positions[807] = Vec3(1.833000,0.423000,1.269000);
positions[808] = Vec3(1.833000,0.423000,1.833000);
positions[809] = Vec3(1.833000,0.423000,2.397000);
positions[810] = Vec3(1.833000,0.705000,0.423000);
positions[811] = Vec3(1.833000,0.705000,0.987000);
positions[812] = Vec3(1.833000,0.705000,1.551000);
positions[813] = Vec3(1.833000,0.705000,2.115000);
positions[814] = Vec3(1.833000,0.705000,2.679000);
positions[815] = Vec3(1.833000,0.987000,0.141000);
positions[816] = Vec3(1.833000,0.987000,0.705000);
positions[817] = Vec3(1.833000,0.987000,1.269000);
positions[818] = Vec3(1.833000,0.987000,1.833000);
positions[819] = Vec3(1.833000,0.987000,2.397000);
positions[820] = Vec3(1.833000,1.269000,0.423000);
positions[821] = Vec3(1.833000,1.269000,0.987000);
positions[822] = Vec3(1.833000,1.269000,1.551000);
positions[823] = Vec3(1.833000,1.269000,2.115000);
positions[824] = Vec3(1.833000,1.269000,2.679000);
positions[825] = Vec3(1.833000,1.551000,0.141000);
positions[826] = Vec3(1.833000,1.551000,0.705000);
positions[827] = Vec3(1.833000,1.551000,1.269000);
positions[828] = Vec3(1.833000,1.551000,1.833000);
positions[829] = Vec3(1.833000,1.551000,2.397000);
positions[830] = Vec3(1.833000,1.833000,0.423000);
positions[831] = Vec3(1.833000,1.833000,0.987000);
positions[832] = Vec3(1.833000,1.833000,1.551000);
positions[833] = Vec3(1.833000,1.833000,2.115000);
positions[834] = Vec3(1.833000,1.833000,2.679000);
positions[835] = Vec3(1.833000,2.115000,0.141000);
positions[836] = Vec3(1.833000,2.115000,0.705000);
positions[837] = Vec3(1.833000,2.115000,1.269000);
positions[838] = Vec3(1.833000,2.115000,1.833000);
positions[839] = Vec3(1.833000,2.115000,2.397000);
positions[840] = Vec3(1.833000,2.397000,0.423000);
positions[841] = Vec3(1.833000,2.397000,0.987000);
positions[842] = Vec3(1.833000,2.397000,1.551000);
positions[843] = Vec3(1.833000,2.397000,2.115000);
positions[844] = Vec3(1.833000,2.397000,2.679000);
positions[845] = Vec3(1.833000,2.679000,0.141000);
positions[846] = Vec3(1.833000,2.679000,0.705000);
positions[847] = Vec3(1.833000,2.679000,1.269000);
positions[848] = Vec3(1.833000,2.679000,1.833000);
positions[849] = Vec3(1.833000,2.679000,2.397000);
positions[850] = Vec3(2.115000,0.141000,0.141000);
positions[851] = Vec3(2.115000,0.141000,0.705000);
positions[852] = Vec3(2.115000,0.141000,1.269000);
positions[853] = Vec3(2.115000,0.141000,1.833000);
positions[854] = Vec3(2.115000,0.141000,2.397000);
positions[855] = Vec3(2.115000,0.423000,0.423000);
positions[856] = Vec3(2.115000,0.423000,0.987000);
positions[857] = Vec3(2.115000,0.423000,1.551000);
positions[858] = Vec3(2.115000,0.423000,2.115000);
positions[859] = Vec3(2.115000,0.423000,2.679000);
positions[860] = Vec3(2.115000,0.705000,0.141000);
positions[861] = Vec3(2.115000,0.705000,0.705000);
positions[862] = Vec3(2.115000,0.705000,1.269000);
positions[863] = Vec3(2.115000,0.705000,1.833000);
positions[864] = Vec3(2.115000,0.705000,2.397000);
positions[865] = Vec3(2.115000,0.987000,0.423000);
positions[866] = Vec3(2.115000,0.987000,0.987000);
positions[867] = Vec3(2.115000,0.987000,1.551000);
positions[868] = Vec3(2.115000,0.987000,2.115000);
positions[869] = Vec3(2.115000,0.987000,2.679000);
positions[870] = Vec3(2.115000,1.269000,0.141000);
positions[871] = Vec3(2.115000,1.269000,0.705000);
positions[872] = Vec3(2.115000,1.269000,1.269000);
positions[873] = Vec3(2.115000,1.269000,1.833000);
positions[874] = Vec3(2.115000,1.269000,2.397000);
positions[875] = Vec3(2.115000,1.551000,0.423000);
positions[876] = Vec3(2.115000,1.551000,0.987000);
positions[877] = Vec3(2.115000,1.551000,1.551000);
positions[878] = Vec3(2.115000,1.551000,2.115000);
positions[879] = Vec3(2.115000,1.551000,2.679000);
positions[880] = Vec3(2.115000,1.833000,0.141000);
positions[881] = Vec3(2.115000,1.833000,0.705000);
positions[882] = Vec3(2.115000,1.833000,1.269000);
positions[883] = Vec3(2.115000,1.833000,1.833000);
positions[884] = Vec3(2.115000,1.833000,2.397000);
positions[885] = Vec3(2.115000,2.115000,0.423000);
positions[886] = Vec3(2.115000,2.115000,0.987000);
positions[887] = Vec3(2.115000,2.115000,1.551000);
positions[888] = Vec3(2.115000,2.115000,2.115000);
positions[889] = Vec3(2.115000,2.115000,2.679000);
positions[890] = Vec3(2.115000,2.397000,0.141000);
positions[891] = Vec3(2.115000,2.397000,0.705000);
positions[892] = Vec3(2.115000,2.397000,1.269000);
positions[893] = Vec3(2.115000,2.397000,1.833000);
positions[894] = Vec3(2.115000,2.397000,2.397000);
positions[895] = Vec3(2.115000,2.679000,0.423000);
positions[896] = Vec3(2.115000,2.679000,0.987000);
positions[897] = Vec3(2.115000,2.679000,1.551000);
positions[898] = Vec3(2.115000,2.679000,2.115000);
positions[899] = Vec3(2.115000,2.679000,2.679000);
positions[900] = Vec3(2.397000,0.141000,0.423000);
positions[901] = Vec3(2.397000,0.141000,0.987000);
positions[902] = Vec3(2.397000,0.141000,1.551000);
positions[903] = Vec3(2.397000,0.141000,2.115000);
positions[904] = Vec3(2.397000,0.141000,2.679000);
positions[905] = Vec3(2.397000,0.423000,0.141000);
positions[906] = Vec3(2.397000,0.423000,0.705000);
positions[907] = Vec3(2.397000,0.423000,1.269000);
positions[908] = Vec3(2.397000,0.423000,1.833000);
positions[909] = Vec3(2.397000,0.423000,2.397000);
positions[910] = Vec3(2.397000,0.705000,0.423000);
positions[911] = Vec3(2.397000,0.705000,0.987000);
positions[912] = Vec3(2.397000,0.705000,1.551000);
positions[913] = Vec3(2.397000,0.705000,2.115000);
positions[914] = Vec3(2.397000,0.705000,2.679000);
positions[915] = Vec3(2.397000,0.987000,0.141000);
positions[916] = Vec3(2.397000,0.987000,0.705000);
positions[917] = Vec3(2.397000,0.987000,1.269000);
positions[918] = Vec3(2.397000,0.987000,1.833000);
positions[919] = Vec3(2.397000,0.987000,2.397000);
positions[920] = Vec3(2.397000,1.269000,0.423000);
positions[921] = Vec3(2.397000,1.269000,0.987000);
positions[922] = Vec3(2.397000,1.269000,1.551000);
positions[923] = Vec3(2.397000,1.269000,2.115000);
positions[924] = Vec3(2.397000,1.269000,2.679000);
positions[925] = Vec3(2.397000,1.551000,0.141000);
positions[926] = Vec3(2.397000,1.551000,0.705000);
positions[927] = Vec3(2.397000,1.551000,1.269000);
positions[928] = Vec3(2.397000,1.551000,1.833000);
positions[929] = Vec3(2.397000,1.551000,2.397000);
positions[930] = Vec3(2.397000,1.833000,0.423000);
positions[931] = Vec3(2.397000,1.833000,0.987000);
positions[932] = Vec3(2.397000,1.833000,1.551000);
positions[933] = Vec3(2.397000,1.833000,2.115000);
positions[934] = Vec3(2.397000,1.833000,2.679000);
positions[935] = Vec3(2.397000,2.115000,0.141000);
positions[936] = Vec3(2.397000,2.115000,0.705000);
positions[937] = Vec3(2.397000,2.115000,1.269000);
positions[938] = Vec3(2.397000,2.115000,1.833000);
positions[939] = Vec3(2.397000,2.115000,2.397000);
positions[940] = Vec3(2.397000,2.397000,0.423000);
positions[941] = Vec3(2.397000,2.397000,0.987000);
positions[942] = Vec3(2.397000,2.397000,1.551000);
positions[943] = Vec3(2.397000,2.397000,2.115000);
positions[944] = Vec3(2.397000,2.397000,2.679000);
positions[945] = Vec3(2.397000,2.679000,0.141000);
positions[946] = Vec3(2.397000,2.679000,0.705000);
positions[947] = Vec3(2.397000,2.679000,1.269000);
positions[948] = Vec3(2.397000,2.679000,1.833000);
positions[949] = Vec3(2.397000,2.679000,2.397000);
positions[950] = Vec3(2.679000,0.141000,0.141000);
positions[951] = Vec3(2.679000,0.141000,0.705000);
positions[952] = Vec3(2.679000,0.141000,1.269000);
positions[953] = Vec3(2.679000,0.141000,1.833000);
positions[954] = Vec3(2.679000,0.141000,2.397000);
positions[955] = Vec3(2.679000,0.423000,0.423000);
positions[956] = Vec3(2.679000,0.423000,0.987000);
positions[957] = Vec3(2.679000,0.423000,1.551000);
positions[958] = Vec3(2.679000,0.423000,2.115000);
positions[959] = Vec3(2.679000,0.423000,2.679000);
positions[960] = Vec3(2.679000,0.705000,0.141000);
positions[961] = Vec3(2.679000,0.705000,0.705000);
positions[962] = Vec3(2.679000,0.705000,1.269000);
positions[963] = Vec3(2.679000,0.705000,1.833000);
positions[964] = Vec3(2.679000,0.705000,2.397000);
positions[965] = Vec3(2.679000,0.987000,0.423000);
positions[966] = Vec3(2.679000,0.987000,0.987000);
positions[967] = Vec3(2.679000,0.987000,1.551000);
positions[968] = Vec3(2.679000,0.987000,2.115000);
positions[969] = Vec3(2.679000,0.987000,2.679000);
positions[970] = Vec3(2.679000,1.269000,0.141000);
positions[971] = Vec3(2.679000,1.269000,0.705000);
positions[972] = Vec3(2.679000,1.269000,1.269000);
positions[973] = Vec3(2.679000,1.269000,1.833000);
positions[974] = Vec3(2.679000,1.269000,2.397000);
positions[975] = Vec3(2.679000,1.551000,0.423000);
positions[976] = Vec3(2.679000,1.551000,0.987000);
positions[977] = Vec3(2.679000,1.551000,1.551000);
positions[978] = Vec3(2.679000,1.551000,2.115000);
positions[979] = Vec3(2.679000,1.551000,2.679000);
positions[980] = Vec3(2.679000,1.833000,0.141000);
positions[981] = Vec3(2.679000,1.833000,0.705000);
positions[982] = Vec3(2.679000,1.833000,1.269000);
positions[983] = Vec3(2.679000,1.833000,1.833000);
positions[984] = Vec3(2.679000,1.833000,2.397000);
positions[985] = Vec3(2.679000,2.115000,0.423000);
positions[986] = Vec3(2.679000,2.115000,0.987000);
positions[987] = Vec3(2.679000,2.115000,1.551000);
positions[988] = Vec3(2.679000,2.115000,2.115000);
positions[989] = Vec3(2.679000,2.115000,2.679000);
positions[990] = Vec3(2.679000,2.397000,0.141000);
positions[991] = Vec3(2.679000,2.397000,0.705000);
positions[992] = Vec3(2.679000,2.397000,1.269000);
positions[993] = Vec3(2.679000,2.397000,1.833000);
positions[994] = Vec3(2.679000,2.397000,2.397000);
positions[995] = Vec3(2.679000,2.679000,0.423000);
positions[996] = Vec3(2.679000,2.679000,0.987000);
positions[997] = Vec3(2.679000,2.679000,1.551000);
positions[998] = Vec3(2.679000,2.679000,2.115000);
positions[999] = Vec3(2.679000,2.679000,2.679000);
platforms/reference/tests/water.dat
0 → 100644
View file @
68e02e80
positions[0] = Vec3( 0.23,0.628,0.113);
positions[1] = Vec3(0.137,0.626, 0.15);
positions[2] = Vec3(0.231,0.589,0.021);
positions[3] = Vec3(-0.307,-0.351,0.703);
positions[4] = Vec3(-0.364,-0.367,0.784);
positions[5] = Vec3(-0.366,-0.341,0.623);
positions[6] = Vec3(-0.569,-0.634,-0.439);
positions[7] = Vec3(-0.532,-0.707,-0.497);
positions[8] = Vec3(-0.517,-0.629,-0.354);
positions[9] = Vec3(-0.871, 0.41,-0.62);
positions[10] = Vec3(-0.948,0.444,-0.566);
positions[11] = Vec3(-0.905,0.359,-0.699);
positions[12] = Vec3(0.249,-0.077,-0.621);
positions[13] = Vec3(0.306,-0.142,-0.571);
positions[14] = Vec3(0.233,-0.11,-0.714);
positions[15] = Vec3(0.561,0.222,-0.715);
positions[16] = Vec3(0.599,0.138,-0.678);
positions[17] = Vec3(0.473,0.241,-0.671);
positions[18] = Vec3(-0.515,-0.803,-0.628);
positions[19] = Vec3(-0.491,-0.866,-0.702);
positions[20] = Vec3(-0.605,-0.763,-0.646);
positions[21] = Vec3(-0.021,0.175,-0.899);
positions[22] = Vec3(0.018, 0.09,-0.935);
positions[23] = Vec3(-0.119,0.177,-0.918);
positions[24] = Vec3(-0.422,0.856,-0.464);
positions[25] = Vec3(-0.479,0.908,-0.527);
positions[26] = Vec3(-0.326,0.868,-0.488);
positions[27] = Vec3(-0.369,-0.095,-0.903);
positions[28] = Vec3(-0.336,-0.031,-0.972);
positions[29] = Vec3(-0.303,-0.101,-0.828);
positions[30] = Vec3(0.594,0.745,0.652);
positions[31] = Vec3(0.644, 0.83,0.633);
positions[32] = Vec3(0.506,0.747,0.604);
positions[33] = Vec3(-0.157,-0.375,-0.758);
positions[34] = Vec3(-0.25, -0.4,-0.785);
positions[35] = Vec3(-0.131,-0.425,-0.676);
positions[36] = Vec3(0.618,-0.295,-0.578);
positions[37] = Vec3(0.613,-0.213,-0.521);
positions[38] = Vec3(0.707,-0.298,-0.623);
positions[39] = Vec3(0.039,-0.785, 0.3);
positions[40] = Vec3(0.138,-0.796,0.291);
positions[41] = Vec3(-0.001,-0.871,0.332);
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