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
Expand all
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
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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