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
6bde69d9
Commit
6bde69d9
authored
Sep 25, 2015
by
Andy Simmonett
Browse files
Merge branch 'master' of github.com:pandegroup/openmm into genpt
parents
e6dbc863
ec799972
Changes
207
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
504 additions
and
2938 deletions
+504
-2938
openmmapi/src/CustomCentroidBondForceImpl.cpp
openmmapi/src/CustomCentroidBondForceImpl.cpp
+17
-4
openmmapi/src/CustomCompoundBondForceImpl.cpp
openmmapi/src/CustomCompoundBondForceImpl.cpp
+17
-4
openmmapi/src/CustomExternalForce.cpp
openmmapi/src/CustomExternalForce.cpp
+4
-0
openmmapi/src/CustomHbondForceImpl.cpp
openmmapi/src/CustomHbondForceImpl.cpp
+13
-4
openmmapi/src/CustomManyParticleForceImpl.cpp
openmmapi/src/CustomManyParticleForceImpl.cpp
+20
-4
platforms/cpu/include/CpuKernels.h
platforms/cpu/include/CpuKernels.h
+41
-0
platforms/cpu/include/CpuLangevinDynamics.h
platforms/cpu/include/CpuLangevinDynamics.h
+14
-1
platforms/cpu/src/CpuKernelFactory.cpp
platforms/cpu/src/CpuKernelFactory.cpp
+2
-0
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+102
-3
platforms/cpu/src/CpuLangevinDynamics.cpp
platforms/cpu/src/CpuLangevinDynamics.cpp
+41
-1
platforms/cpu/src/CpuPlatform.cpp
platforms/cpu/src/CpuPlatform.cpp
+1
-0
platforms/cpu/tests/CpuTests.h
platforms/cpu/tests/CpuTests.h
+46
-0
platforms/cpu/tests/TestCpuCheckpoints.cpp
platforms/cpu/tests/TestCpuCheckpoints.cpp
+99
-0
platforms/cpu/tests/TestCpuCustomGBForce.cpp
platforms/cpu/tests/TestCpuCustomGBForce.cpp
+4
-451
platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp
platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp
+4
-709
platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp
platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp
+4
-959
platforms/cpu/tests/TestCpuEwald.cpp
platforms/cpu/tests/TestCpuEwald.cpp
+4
-307
platforms/cpu/tests/TestCpuGBSAOBCForce.cpp
platforms/cpu/tests/TestCpuGBSAOBCForce.cpp
+4
-240
platforms/cpu/tests/TestCpuHarmonicAngleForce.cpp
platforms/cpu/tests/TestCpuHarmonicAngleForce.cpp
+63
-0
platforms/cpu/tests/TestCpuLangevinIntegrator.cpp
platforms/cpu/tests/TestCpuLangevinIntegrator.cpp
+4
-251
No files found.
openmmapi/src/CustomCentroidBondForceImpl.cpp
View file @
6bde69d9
...
@@ -150,24 +150,37 @@ ParsedExpression CustomCentroidBondForceImpl::prepareExpression(const CustomCent
...
@@ -150,24 +150,37 @@ ParsedExpression CustomCentroidBondForceImpl::prepareExpression(const CustomCent
functions
[
"dihedral"
]
=
&
dihedral
;
functions
[
"dihedral"
]
=
&
dihedral
;
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
map
<
string
,
int
>
groups
;
map
<
string
,
int
>
groups
;
set
<
string
>
variables
;
for
(
int
i
=
0
;
i
<
force
.
getNumGroupsPerBond
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumGroupsPerBond
();
i
++
)
{
stringstream
name
;
stringstream
name
,
x
,
y
,
z
;
name
<<
'g'
<<
(
i
+
1
);
name
<<
'g'
<<
(
i
+
1
);
x
<<
'x'
<<
(
i
+
1
);
y
<<
'y'
<<
(
i
+
1
);
z
<<
'z'
<<
(
i
+
1
);
groups
[
name
.
str
()]
=
i
;
groups
[
name
.
str
()]
=
i
;
variables
.
insert
(
x
.
str
());
variables
.
insert
(
y
.
str
());
variables
.
insert
(
z
.
str
());
}
}
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
groups
,
distances
,
angles
,
dihedrals
)).
optimize
();
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
variables
.
insert
(
force
.
getGlobalParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumPerBondParameters
();
i
++
)
variables
.
insert
(
force
.
getPerBondParameterName
(
i
));
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
groups
,
distances
,
angles
,
dihedrals
,
variables
)).
optimize
();
}
}
ExpressionTreeNode
CustomCentroidBondForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
groups
,
ExpressionTreeNode
CustomCentroidBondForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
groups
,
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
)
{
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
,
set
<
string
>&
variables
)
{
const
Operation
&
op
=
node
.
getOperation
();
const
Operation
&
op
=
node
.
getOperation
();
if
(
op
.
getId
()
==
Operation
::
VARIABLE
&&
variables
.
find
(
op
.
getName
())
==
variables
.
end
())
throw
OpenMMException
(
"CustomCentroidBondForce: Unknown variable '"
+
op
.
getName
()
+
"'"
);
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
(
op
.
getName
()
!=
"distance"
&&
op
.
getName
()
!=
"angle"
&&
op
.
getName
()
!=
"dihedral"
))
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
(
op
.
getName
()
!=
"distance"
&&
op
.
getName
()
!=
"angle"
&&
op
.
getName
()
!=
"dihedral"
))
{
{
// This is not an angle or dihedral, so process its children.
// This is not an angle or dihedral, so process its children.
vector
<
ExpressionTreeNode
>
children
;
vector
<
ExpressionTreeNode
>
children
;
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
groups
,
distances
,
angles
,
dihedrals
));
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
groups
,
distances
,
angles
,
dihedrals
,
variables
));
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
}
}
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
...
...
openmmapi/src/CustomCompoundBondForceImpl.cpp
View file @
6bde69d9
...
@@ -136,24 +136,37 @@ ParsedExpression CustomCompoundBondForceImpl::prepareExpression(const CustomComp
...
@@ -136,24 +136,37 @@ ParsedExpression CustomCompoundBondForceImpl::prepareExpression(const CustomComp
functions
[
"dihedral"
]
=
&
dihedral
;
functions
[
"dihedral"
]
=
&
dihedral
;
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
map
<
string
,
int
>
atoms
;
map
<
string
,
int
>
atoms
;
set
<
string
>
variables
;
for
(
int
i
=
0
;
i
<
force
.
getNumParticlesPerBond
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumParticlesPerBond
();
i
++
)
{
stringstream
name
;
stringstream
name
,
x
,
y
,
z
;
name
<<
'p'
<<
(
i
+
1
);
name
<<
'p'
<<
(
i
+
1
);
x
<<
'x'
<<
(
i
+
1
);
y
<<
'y'
<<
(
i
+
1
);
z
<<
'z'
<<
(
i
+
1
);
atoms
[
name
.
str
()]
=
i
;
atoms
[
name
.
str
()]
=
i
;
variables
.
insert
(
x
.
str
());
variables
.
insert
(
y
.
str
());
variables
.
insert
(
z
.
str
());
}
}
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
)).
optimize
();
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
variables
.
insert
(
force
.
getGlobalParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumPerBondParameters
();
i
++
)
variables
.
insert
(
force
.
getPerBondParameterName
(
i
));
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
,
variables
)).
optimize
();
}
}
ExpressionTreeNode
CustomCompoundBondForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
atoms
,
ExpressionTreeNode
CustomCompoundBondForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
atoms
,
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
)
{
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
,
set
<
string
>&
variables
)
{
const
Operation
&
op
=
node
.
getOperation
();
const
Operation
&
op
=
node
.
getOperation
();
if
(
op
.
getId
()
==
Operation
::
VARIABLE
&&
variables
.
find
(
op
.
getName
())
==
variables
.
end
())
throw
OpenMMException
(
"CustomCompoundBondForce: Unknown variable '"
+
op
.
getName
()
+
"'"
);
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
(
op
.
getName
()
!=
"distance"
&&
op
.
getName
()
!=
"angle"
&&
op
.
getName
()
!=
"dihedral"
))
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
(
op
.
getName
()
!=
"distance"
&&
op
.
getName
()
!=
"angle"
&&
op
.
getName
()
!=
"dihedral"
))
{
{
// This is not an angle or dihedral, so process its children.
// This is not an angle or dihedral, so process its children.
vector
<
ExpressionTreeNode
>
children
;
vector
<
ExpressionTreeNode
>
children
;
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
));
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
,
variables
));
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
}
}
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
...
...
openmmapi/src/CustomExternalForce.cpp
View file @
6bde69d9
...
@@ -119,3 +119,7 @@ ForceImpl* CustomExternalForce::createImpl() const {
...
@@ -119,3 +119,7 @@ ForceImpl* CustomExternalForce::createImpl() const {
void
CustomExternalForce
::
updateParametersInContext
(
Context
&
context
)
{
void
CustomExternalForce
::
updateParametersInContext
(
Context
&
context
)
{
dynamic_cast
<
CustomExternalForceImpl
&>
(
getImplInContext
(
context
)).
updateParametersInContext
(
getContextImpl
(
context
));
dynamic_cast
<
CustomExternalForceImpl
&>
(
getImplInContext
(
context
)).
updateParametersInContext
(
getContextImpl
(
context
));
}
}
bool
CustomExternalForce
::
usesPeriodicBoundaryConditions
()
const
{
return
(
energyExpression
.
find
(
"periodicdistance"
)
!=
string
::
npos
);
}
openmmapi/src/CustomHbondForceImpl.cpp
View file @
6bde69d9
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
2
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
5
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -215,19 +215,28 @@ ParsedExpression CustomHbondForceImpl::prepareExpression(const CustomHbondForce&
...
@@ -215,19 +215,28 @@ ParsedExpression CustomHbondForceImpl::prepareExpression(const CustomHbondForce&
atoms
[
"d1"
]
=
3
;
atoms
[
"d1"
]
=
3
;
atoms
[
"d2"
]
=
4
;
atoms
[
"d2"
]
=
4
;
atoms
[
"d3"
]
=
5
;
atoms
[
"d3"
]
=
5
;
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
)).
optimize
();
set
<
string
>
variables
;
for
(
int
i
=
0
;
i
<
force
.
getNumPerDonorParameters
();
i
++
)
variables
.
insert
(
force
.
getPerDonorParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumPerAcceptorParameters
();
i
++
)
variables
.
insert
(
force
.
getPerAcceptorParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
variables
.
insert
(
force
.
getGlobalParameterName
(
i
));
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
,
variables
)).
optimize
();
}
}
ExpressionTreeNode
CustomHbondForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
atoms
,
ExpressionTreeNode
CustomHbondForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
atoms
,
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
)
{
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
,
set
<
string
>&
variables
)
{
const
Operation
&
op
=
node
.
getOperation
();
const
Operation
&
op
=
node
.
getOperation
();
if
(
op
.
getId
()
==
Operation
::
VARIABLE
&&
variables
.
find
(
op
.
getName
())
==
variables
.
end
())
throw
OpenMMException
(
"CustomHBondForce: Unknown variable '"
+
op
.
getName
()
+
"'"
);
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
op
.
getNumArguments
()
<
2
)
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
op
.
getNumArguments
()
<
2
)
{
{
// This is not an angle or dihedral, so process its children.
// This is not an angle or dihedral, so process its children.
vector
<
ExpressionTreeNode
>
children
;
vector
<
ExpressionTreeNode
>
children
;
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
));
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
,
variables
));
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
}
}
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
...
...
openmmapi/src/CustomManyParticleForceImpl.cpp
View file @
6bde69d9
...
@@ -165,24 +165,40 @@ ParsedExpression CustomManyParticleForceImpl::prepareExpression(const CustomMany
...
@@ -165,24 +165,40 @@ ParsedExpression CustomManyParticleForceImpl::prepareExpression(const CustomMany
functions
[
"dihedral"
]
=
&
dihedral
;
functions
[
"dihedral"
]
=
&
dihedral
;
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
map
<
string
,
int
>
atoms
;
map
<
string
,
int
>
atoms
;
set
<
string
>
variables
;
for
(
int
i
=
0
;
i
<
force
.
getNumParticlesPerSet
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumParticlesPerSet
();
i
++
)
{
stringstream
name
;
stringstream
name
,
x
,
y
,
z
;
name
<<
'p'
<<
(
i
+
1
);
name
<<
'p'
<<
(
i
+
1
);
x
<<
'x'
<<
(
i
+
1
);
y
<<
'y'
<<
(
i
+
1
);
z
<<
'z'
<<
(
i
+
1
);
atoms
[
name
.
str
()]
=
i
;
atoms
[
name
.
str
()]
=
i
;
variables
.
insert
(
x
.
str
());
variables
.
insert
(
y
.
str
());
variables
.
insert
(
z
.
str
());
for
(
int
j
=
0
;
j
<
force
.
getNumPerParticleParameters
();
j
++
)
{
stringstream
param
;
param
<<
force
.
getPerParticleParameterName
(
j
)
<<
(
i
+
1
);
variables
.
insert
(
param
.
str
());
}
}
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
)).
optimize
();
}
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
variables
.
insert
(
force
.
getGlobalParameterName
(
i
));
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
,
variables
)).
optimize
();
}
}
ExpressionTreeNode
CustomManyParticleForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
atoms
,
ExpressionTreeNode
CustomManyParticleForceImpl
::
replaceFunctions
(
const
ExpressionTreeNode
&
node
,
map
<
string
,
int
>
atoms
,
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
)
{
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
,
set
<
string
>&
variables
)
{
const
Operation
&
op
=
node
.
getOperation
();
const
Operation
&
op
=
node
.
getOperation
();
if
(
op
.
getId
()
==
Operation
::
VARIABLE
&&
variables
.
find
(
op
.
getName
())
==
variables
.
end
())
throw
OpenMMException
(
"CustomManyParticleForce: Unknown variable '"
+
op
.
getName
()
+
"'"
);
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
(
op
.
getName
()
!=
"distance"
&&
op
.
getName
()
!=
"angle"
&&
op
.
getName
()
!=
"dihedral"
))
if
(
op
.
getId
()
!=
Operation
::
CUSTOM
||
(
op
.
getName
()
!=
"distance"
&&
op
.
getName
()
!=
"angle"
&&
op
.
getName
()
!=
"dihedral"
))
{
{
// This is not an angle or dihedral, so process its children.
// This is not an angle or dihedral, so process its children.
vector
<
ExpressionTreeNode
>
children
;
vector
<
ExpressionTreeNode
>
children
;
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
));
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
,
variables
));
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
}
}
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
...
...
platforms/cpu/include/CpuKernels.h
View file @
6bde69d9
...
@@ -92,6 +92,46 @@ private:
...
@@ -92,6 +92,46 @@ private:
Kernel
referenceKernel
;
Kernel
referenceKernel
;
};
};
/**
* This kernel is invoked by HarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
*/
class
CpuCalcHarmonicAngleForceKernel
:
public
CalcHarmonicAngleForceKernel
{
public:
CpuCalcHarmonicAngleForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
CpuPlatform
::
PlatformData
&
data
)
:
CalcHarmonicAngleForceKernel
(
name
,
platform
),
data
(
data
),
angleIndexArray
(
NULL
),
angleParamArray
(
NULL
)
{
}
~
CpuCalcHarmonicAngleForceKernel
();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the HarmonicAngleForce this kernel will be used for
*/
void
initialize
(
const
System
&
system
,
const
HarmonicAngleForce
&
force
);
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
double
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
);
/**
* Copy changed parameters over to a context.
*
* @param context the context to copy parameters to
* @param force the HarmonicAngleForce to copy the parameters from
*/
void
copyParametersToContext
(
ContextImpl
&
context
,
const
HarmonicAngleForce
&
force
);
private:
CpuPlatform
::
PlatformData
&
data
;
int
numAngles
;
int
**
angleIndexArray
;
RealOpenMM
**
angleParamArray
;
CpuBondForce
bondForce
;
};
/**
/**
* This kernel is invoked by PeriodicTorsionForce to calculate the forces acting on the system and the energy of the system.
* This kernel is invoked by PeriodicTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
*/
...
@@ -229,6 +269,7 @@ private:
...
@@ -229,6 +269,7 @@ private:
CpuNeighborList
*
neighborList
;
CpuNeighborList
*
neighborList
;
CpuNonbondedForce
*
nonbonded
;
CpuNonbondedForce
*
nonbonded
;
Kernel
optimizedPme
;
Kernel
optimizedPme
;
CpuBondForce
bondForce
;
};
};
/**
/**
...
...
platforms/cpu/include/CpuLangevinDynamics.h
View file @
6bde69d9
/* Portions copyright (c) 2013 Stanford University and Simbios.
/* Portions copyright (c) 2013
-2015
Stanford University and Simbios.
* Authors: Peter Eastman
* Authors: Peter Eastman
* Contributors:
* Contributors:
*
*
...
@@ -37,6 +37,7 @@ class CpuLangevinDynamics : public ReferenceStochasticDynamics {
...
@@ -37,6 +37,7 @@ class CpuLangevinDynamics : public ReferenceStochasticDynamics {
public:
public:
class
Update1Task
;
class
Update1Task
;
class
Update2Task
;
class
Update2Task
;
class
Update3Task
;
/**
/**
* Constructor.
* Constructor.
*
*
...
@@ -80,9 +81,21 @@ public:
...
@@ -80,9 +81,21 @@ public:
void
updatePart2
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
velocities
,
void
updatePart2
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
velocities
,
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
,
std
::
vector
<
OpenMM
::
RealVec
>&
xPrime
);
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
,
std
::
vector
<
OpenMM
::
RealVec
>&
xPrime
);
/**
* Third update
*
* @param numberOfAtoms number of atoms
* @param atomCoordinates atom coordinates
* @param velocities velocities
* @param inverseMasses inverse atom masses
*/
void
updatePart3
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
velocities
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
,
std
::
vector
<
OpenMM
::
RealVec
>&
xPrime
);
private:
private:
void
threadUpdate1
(
int
threadIndex
);
void
threadUpdate1
(
int
threadIndex
);
void
threadUpdate2
(
int
threadIndex
);
void
threadUpdate2
(
int
threadIndex
);
void
threadUpdate3
(
int
threadIndex
);
OpenMM
::
ThreadPool
&
threads
;
OpenMM
::
ThreadPool
&
threads
;
OpenMM
::
CpuRandom
&
random
;
OpenMM
::
CpuRandom
&
random
;
std
::
vector
<
OpenMM_SFMT
::
SFMT
>
threadRandom
;
std
::
vector
<
OpenMM_SFMT
::
SFMT
>
threadRandom
;
...
...
platforms/cpu/src/CpuKernelFactory.cpp
View file @
6bde69d9
...
@@ -41,6 +41,8 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform&
...
@@ -41,6 +41,8 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform&
CpuPlatform
::
PlatformData
&
data
=
CpuPlatform
::
getPlatformData
(
context
);
CpuPlatform
::
PlatformData
&
data
=
CpuPlatform
::
getPlatformData
(
context
);
if
(
name
==
CalcForcesAndEnergyKernel
::
Name
())
if
(
name
==
CalcForcesAndEnergyKernel
::
Name
())
return
new
CpuCalcForcesAndEnergyKernel
(
name
,
platform
,
data
,
context
);
return
new
CpuCalcForcesAndEnergyKernel
(
name
,
platform
,
data
,
context
);
if
(
name
==
CalcHarmonicAngleForceKernel
::
Name
())
return
new
CpuCalcHarmonicAngleForceKernel
(
name
,
platform
,
data
);
if
(
name
==
CalcPeriodicTorsionForceKernel
::
Name
())
if
(
name
==
CalcPeriodicTorsionForceKernel
::
Name
())
return
new
CpuCalcPeriodicTorsionForceKernel
(
name
,
platform
,
data
);
return
new
CpuCalcPeriodicTorsionForceKernel
(
name
,
platform
,
data
);
if
(
name
==
CalcRBTorsionForceKernel
::
Name
())
if
(
name
==
CalcRBTorsionForceKernel
::
Name
())
...
...
platforms/cpu/src/CpuKernels.cpp
View file @
6bde69d9
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
#include "CpuKernels.h"
#include "CpuKernels.h"
#include "ReferenceAngleBondIxn.h"
#include "ReferenceBondForce.h"
#include "ReferenceBondForce.h"
#include "ReferenceConstraints.h"
#include "ReferenceConstraints.h"
#include "ReferenceKernelFactory.h"
#include "ReferenceKernelFactory.h"
...
@@ -47,6 +48,7 @@
...
@@ -47,6 +48,7 @@
#include "RealVec.h"
#include "RealVec.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CustomFunction.h"
#include "lepton/CustomFunction.h"
#include "lepton/Operation.h"
#include "lepton/Parser.h"
#include "lepton/Parser.h"
#include "lepton/ParsedExpression.h"
#include "lepton/ParsedExpression.h"
...
@@ -83,6 +85,17 @@ static ReferenceConstraints& extractConstraints(ContextImpl& context) {
...
@@ -83,6 +85,17 @@ static ReferenceConstraints& extractConstraints(ContextImpl& context) {
return
*
(
ReferenceConstraints
*
)
data
->
constraints
;
return
*
(
ReferenceConstraints
*
)
data
->
constraints
;
}
}
/**
* Make sure an expression doesn't use any undefined variables.
*/
static
void
validateVariables
(
const
Lepton
::
ExpressionTreeNode
&
node
,
const
set
<
string
>&
variables
)
{
const
Lepton
::
Operation
&
op
=
node
.
getOperation
();
if
(
op
.
getId
()
==
Lepton
::
Operation
::
VARIABLE
&&
variables
.
find
(
op
.
getName
())
==
variables
.
end
())
throw
OpenMMException
(
"Unknown variable in expression: "
+
op
.
getName
());
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
validateVariables
(
node
.
getChildren
()[
i
],
variables
);
}
/**
/**
* Compute the kinetic energy of the system, possibly shifting the velocities in time to account
* Compute the kinetic energy of the system, possibly shifting the velocities in time to account
* for a leapfrog integrator.
* for a leapfrog integrator.
...
@@ -240,6 +253,64 @@ double CpuCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, boo
...
@@ -240,6 +253,64 @@ double CpuCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, boo
return
referenceKernel
.
getAs
<
ReferenceCalcForcesAndEnergyKernel
>
().
finishComputation
(
context
,
includeForce
,
includeEnergy
,
groups
,
valid
);
return
referenceKernel
.
getAs
<
ReferenceCalcForcesAndEnergyKernel
>
().
finishComputation
(
context
,
includeForce
,
includeEnergy
,
groups
,
valid
);
}
}
CpuCalcHarmonicAngleForceKernel
::~
CpuCalcHarmonicAngleForceKernel
()
{
if
(
angleIndexArray
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
numAngles
;
i
++
)
{
delete
[]
angleIndexArray
[
i
];
delete
[]
angleParamArray
[
i
];
}
delete
[]
angleIndexArray
;
delete
[]
angleParamArray
;
}
}
void
CpuCalcHarmonicAngleForceKernel
::
initialize
(
const
System
&
system
,
const
HarmonicAngleForce
&
force
)
{
numAngles
=
force
.
getNumAngles
();
angleIndexArray
=
new
int
*
[
numAngles
];
for
(
int
i
=
0
;
i
<
numAngles
;
i
++
)
angleIndexArray
[
i
]
=
new
int
[
3
];
angleParamArray
=
new
RealOpenMM
*
[
numAngles
];
for
(
int
i
=
0
;
i
<
numAngles
;
i
++
)
angleParamArray
[
i
]
=
new
RealOpenMM
[
2
];
for
(
int
i
=
0
;
i
<
numAngles
;
++
i
)
{
int
particle1
,
particle2
,
particle3
;
double
angle
,
k
;
force
.
getAngleParameters
(
i
,
particle1
,
particle2
,
particle3
,
angle
,
k
);
angleIndexArray
[
i
][
0
]
=
particle1
;
angleIndexArray
[
i
][
1
]
=
particle2
;
angleIndexArray
[
i
][
2
]
=
particle3
;
angleParamArray
[
i
][
0
]
=
(
RealOpenMM
)
angle
;
angleParamArray
[
i
][
1
]
=
(
RealOpenMM
)
k
;
}
bondForce
.
initialize
(
system
.
getNumParticles
(),
numAngles
,
3
,
angleIndexArray
,
data
.
threads
);
}
double
CpuCalcHarmonicAngleForceKernel
::
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
{
vector
<
RealVec
>&
posData
=
extractPositions
(
context
);
vector
<
RealVec
>&
forceData
=
extractForces
(
context
);
RealOpenMM
energy
=
0
;
ReferenceAngleBondIxn
angleBond
;
bondForce
.
calculateForce
(
posData
,
angleParamArray
,
forceData
,
includeEnergy
?
&
energy
:
NULL
,
angleBond
);
return
energy
;
}
void
CpuCalcHarmonicAngleForceKernel
::
copyParametersToContext
(
ContextImpl
&
context
,
const
HarmonicAngleForce
&
force
)
{
if
(
numAngles
!=
force
.
getNumAngles
())
throw
OpenMMException
(
"updateParametersInContext: The number of angles has changed"
);
// Record the values.
for
(
int
i
=
0
;
i
<
numAngles
;
++
i
)
{
int
particle1
,
particle2
,
particle3
;
double
angle
,
k
;
force
.
getAngleParameters
(
i
,
particle1
,
particle2
,
particle3
,
angle
,
k
);
if
(
particle1
!=
angleIndexArray
[
i
][
0
]
||
particle2
!=
angleIndexArray
[
i
][
1
]
||
particle3
!=
angleIndexArray
[
i
][
2
])
throw
OpenMMException
(
"updateParametersInContext: The set of particles in an angle has changed"
);
angleParamArray
[
i
][
0
]
=
(
RealOpenMM
)
angle
;
angleParamArray
[
i
][
1
]
=
(
RealOpenMM
)
k
;
}
}
CpuCalcPeriodicTorsionForceKernel
::~
CpuCalcPeriodicTorsionForceKernel
()
{
CpuCalcPeriodicTorsionForceKernel
::~
CpuCalcPeriodicTorsionForceKernel
()
{
if
(
torsionIndexArray
!=
NULL
)
{
if
(
torsionIndexArray
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
numTorsions
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numTorsions
;
i
++
)
{
...
@@ -467,6 +538,7 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
...
@@ -467,6 +538,7 @@ void CpuCalcNonbondedForceKernel::initialize(const System& system, const Nonbond
bonded14ParamArray
[
i
][
1
]
=
static_cast
<
RealOpenMM
>
(
4.0
*
depth
);
bonded14ParamArray
[
i
][
1
]
=
static_cast
<
RealOpenMM
>
(
4.0
*
depth
);
bonded14ParamArray
[
i
][
2
]
=
static_cast
<
RealOpenMM
>
(
charge
);
bonded14ParamArray
[
i
][
2
]
=
static_cast
<
RealOpenMM
>
(
charge
);
}
}
bondForce
.
initialize
(
system
.
getNumParticles
(),
num14
,
2
,
bonded14IndexArray
,
data
.
threads
);
// Record other parameters.
// Record other parameters.
...
@@ -599,9 +671,8 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo
...
@@ -599,9 +671,8 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo
}
}
energy
+=
nonbondedEnergy
;
energy
+=
nonbondedEnergy
;
if
(
includeDirect
)
{
if
(
includeDirect
)
{
ReferenceBondForce
refBondForce
;
ReferenceLJCoulomb14
nonbonded14
;
ReferenceLJCoulomb14
nonbonded14
;
refB
ondForce
.
calculateForce
(
num14
,
bonded14IndexArray
,
posData
,
bonded14ParamArray
,
forceData
,
includeEnergy
?
&
energy
:
NULL
,
nonbonded14
);
b
ondForce
.
calculateForce
(
posData
,
bonded14ParamArray
,
forceData
,
includeEnergy
?
&
energy
:
NULL
,
nonbonded14
);
if
(
data
.
isPeriodic
)
if
(
data
.
isPeriodic
)
energy
+=
dispersionCoefficient
/
(
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
]);
energy
+=
dispersionCoefficient
/
(
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
]);
}
}
...
@@ -737,6 +808,14 @@ void CpuCalcCustomNonbondedForceKernel::initialize(const System& system, const C
...
@@ -737,6 +808,14 @@ void CpuCalcCustomNonbondedForceKernel::initialize(const System& system, const C
globalParameterNames
.
push_back
(
force
.
getGlobalParameterName
(
i
));
globalParameterNames
.
push_back
(
force
.
getGlobalParameterName
(
i
));
globalParamValues
[
force
.
getGlobalParameterName
(
i
)]
=
force
.
getGlobalParameterDefaultValue
(
i
);
globalParamValues
[
force
.
getGlobalParameterName
(
i
)]
=
force
.
getGlobalParameterDefaultValue
(
i
);
}
}
set
<
string
>
variables
;
variables
.
insert
(
"r"
);
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
{
variables
.
insert
(
parameterNames
[
i
]
+
"1"
);
variables
.
insert
(
parameterNames
[
i
]
+
"2"
);
}
variables
.
insert
(
globalParameterNames
.
begin
(),
globalParameterNames
.
end
());
validateVariables
(
expression
.
getRootNode
(),
variables
);
// Delete the custom functions.
// Delete the custom functions.
...
@@ -950,6 +1029,18 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
...
@@ -950,6 +1029,18 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
vector
<
vector
<
Lepton
::
CompiledExpression
>
>
valueGradientExpressions
(
force
.
getNumComputedValues
());
vector
<
vector
<
Lepton
::
CompiledExpression
>
>
valueGradientExpressions
(
force
.
getNumComputedValues
());
vector
<
Lepton
::
CompiledExpression
>
valueExpressions
;
vector
<
Lepton
::
CompiledExpression
>
valueExpressions
;
vector
<
Lepton
::
CompiledExpression
>
energyExpressions
;
vector
<
Lepton
::
CompiledExpression
>
energyExpressions
;
set
<
string
>
particleVariables
,
pairVariables
;
pairVariables
.
insert
(
"r"
);
particleVariables
.
insert
(
"x"
);
particleVariables
.
insert
(
"y"
);
particleVariables
.
insert
(
"z"
);
for
(
int
i
=
0
;
i
<
numPerParticleParameters
;
i
++
)
{
particleVariables
.
insert
(
particleParameterNames
[
i
]);
pairVariables
.
insert
(
particleParameterNames
[
i
]
+
"1"
);
pairVariables
.
insert
(
particleParameterNames
[
i
]
+
"2"
);
}
particleVariables
.
insert
(
globalParameterNames
.
begin
(),
globalParameterNames
.
end
());
pairVariables
.
insert
(
globalParameterNames
.
begin
(),
globalParameterNames
.
end
());
for
(
int
i
=
0
;
i
<
force
.
getNumComputedValues
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumComputedValues
();
i
++
)
{
string
name
,
expression
;
string
name
,
expression
;
CustomGBForce
::
ComputationType
type
;
CustomGBForce
::
ComputationType
type
;
...
@@ -958,15 +1049,21 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
...
@@ -958,15 +1049,21 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
valueExpressions
.
push_back
(
ex
.
createCompiledExpression
());
valueExpressions
.
push_back
(
ex
.
createCompiledExpression
());
valueTypes
.
push_back
(
type
);
valueTypes
.
push_back
(
type
);
valueNames
.
push_back
(
name
);
valueNames
.
push_back
(
name
);
if
(
i
==
0
)
if
(
i
==
0
)
{
valueDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"r"
).
createCompiledExpression
());
valueDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"r"
).
createCompiledExpression
());
validateVariables
(
ex
.
getRootNode
(),
pairVariables
);
}
else
{
else
{
valueGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"x"
).
createCompiledExpression
());
valueGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"x"
).
createCompiledExpression
());
valueGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"y"
).
createCompiledExpression
());
valueGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"y"
).
createCompiledExpression
());
valueGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"z"
).
createCompiledExpression
());
valueGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"z"
).
createCompiledExpression
());
for
(
int
j
=
0
;
j
<
i
;
j
++
)
for
(
int
j
=
0
;
j
<
i
;
j
++
)
valueDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
valueNames
[
j
]).
createCompiledExpression
());
valueDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
valueNames
[
j
]).
createCompiledExpression
());
validateVariables
(
ex
.
getRootNode
(),
particleVariables
);
}
}
particleVariables
.
insert
(
name
);
pairVariables
.
insert
(
name
+
"1"
);
pairVariables
.
insert
(
name
+
"2"
);
}
}
// Parse the expressions for energy terms.
// Parse the expressions for energy terms.
...
@@ -988,10 +1085,12 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
...
@@ -988,10 +1085,12 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
energyGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"x"
).
createCompiledExpression
());
energyGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"x"
).
createCompiledExpression
());
energyGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"y"
).
createCompiledExpression
());
energyGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"y"
).
createCompiledExpression
());
energyGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"z"
).
createCompiledExpression
());
energyGradientExpressions
[
i
].
push_back
(
ex
.
differentiate
(
"z"
).
createCompiledExpression
());
validateVariables
(
ex
.
getRootNode
(),
particleVariables
);
}
}
else
{
else
{
energyDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
valueNames
[
j
]
+
"1"
).
createCompiledExpression
());
energyDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
valueNames
[
j
]
+
"1"
).
createCompiledExpression
());
energyDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
valueNames
[
j
]
+
"2"
).
createCompiledExpression
());
energyDerivExpressions
[
i
].
push_back
(
ex
.
differentiate
(
valueNames
[
j
]
+
"2"
).
createCompiledExpression
());
validateVariables
(
ex
.
getRootNode
(),
pairVariables
);
}
}
}
}
}
}
...
...
platforms/cpu/src/CpuLangevinDynamics.cpp
View file @
6bde69d9
/* Portions copyright (c) 2006-201
3
Stanford University and Simbios.
/* Portions copyright (c) 2006-201
5
Stanford University and Simbios.
* Authors: Peter Eastman
* Authors: Peter Eastman
* Contributors:
* Contributors:
*
*
...
@@ -49,6 +49,16 @@ public:
...
@@ -49,6 +49,16 @@ public:
CpuLangevinDynamics
&
owner
;
CpuLangevinDynamics
&
owner
;
};
};
class
CpuLangevinDynamics
::
Update3Task
:
public
ThreadPool
::
Task
{
public:
Update3Task
(
CpuLangevinDynamics
&
owner
)
:
owner
(
owner
)
{
}
void
execute
(
ThreadPool
&
threads
,
int
threadIndex
)
{
owner
.
threadUpdate3
(
threadIndex
);
}
CpuLangevinDynamics
&
owner
;
};
CpuLangevinDynamics
::
CpuLangevinDynamics
(
int
numberOfAtoms
,
RealOpenMM
deltaT
,
RealOpenMM
tau
,
RealOpenMM
temperature
,
ThreadPool
&
threads
,
CpuRandom
&
random
)
:
CpuLangevinDynamics
::
CpuLangevinDynamics
(
int
numberOfAtoms
,
RealOpenMM
deltaT
,
RealOpenMM
tau
,
RealOpenMM
temperature
,
ThreadPool
&
threads
,
CpuRandom
&
random
)
:
ReferenceStochasticDynamics
(
numberOfAtoms
,
deltaT
,
tau
,
temperature
),
threads
(
threads
),
random
(
random
)
{
ReferenceStochasticDynamics
(
numberOfAtoms
,
deltaT
,
tau
,
temperature
),
threads
(
threads
),
random
(
random
)
{
}
}
...
@@ -92,6 +102,23 @@ void CpuLangevinDynamics::updatePart2(int numberOfAtoms, vector<RealVec>& atomCo
...
@@ -92,6 +102,23 @@ void CpuLangevinDynamics::updatePart2(int numberOfAtoms, vector<RealVec>& atomCo
threads
.
waitForThreads
();
threads
.
waitForThreads
();
}
}
void
CpuLangevinDynamics
::
updatePart3
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
velocities
,
vector
<
RealOpenMM
>&
inverseMasses
,
vector
<
RealVec
>&
xPrime
)
{
// Record the parameters for the threads.
this
->
numberOfAtoms
=
numberOfAtoms
;
this
->
atomCoordinates
=
&
atomCoordinates
[
0
];
this
->
velocities
=
&
velocities
[
0
];
this
->
inverseMasses
=
&
inverseMasses
[
0
];
this
->
xPrime
=
&
xPrime
[
0
];
// Signal the threads to start running and wait for them to finish.
Update3Task
task
(
*
this
);
threads
.
execute
(
task
);
threads
.
waitForThreads
();
}
void
CpuLangevinDynamics
::
threadUpdate1
(
int
threadIndex
)
{
void
CpuLangevinDynamics
::
threadUpdate1
(
int
threadIndex
)
{
const
RealOpenMM
tau
=
getTau
();
const
RealOpenMM
tau
=
getTau
();
const
RealOpenMM
vscale
=
EXP
(
-
getDeltaT
()
/
tau
);
const
RealOpenMM
vscale
=
EXP
(
-
getDeltaT
()
/
tau
);
...
@@ -122,3 +149,16 @@ void CpuLangevinDynamics::threadUpdate2(int threadIndex) {
...
@@ -122,3 +149,16 @@ void CpuLangevinDynamics::threadUpdate2(int threadIndex) {
}
}
}
}
}
}
void
CpuLangevinDynamics
::
threadUpdate3
(
int
threadIndex
)
{
const
RealOpenMM
invStepSize
=
1.0
/
getDeltaT
();
int
start
=
threadIndex
*
numberOfAtoms
/
threads
.
getNumThreads
();
int
end
=
(
threadIndex
+
1
)
*
numberOfAtoms
/
threads
.
getNumThreads
();
for
(
int
i
=
start
;
i
<
end
;
++
i
)
if
(
inverseMasses
[
i
]
!=
0.0
)
{
velocities
[
i
]
=
(
xPrime
[
i
]
-
atomCoordinates
[
i
])
*
invStepSize
;
atomCoordinates
[
i
]
=
xPrime
[
i
];
}
}
platforms/cpu/src/CpuPlatform.cpp
View file @
6bde69d9
...
@@ -61,6 +61,7 @@ map<const ContextImpl*, CpuPlatform::PlatformData*> CpuPlatform::contextData;
...
@@ -61,6 +61,7 @@ map<const ContextImpl*, CpuPlatform::PlatformData*> CpuPlatform::contextData;
CpuPlatform
::
CpuPlatform
()
{
CpuPlatform
::
CpuPlatform
()
{
CpuKernelFactory
*
factory
=
new
CpuKernelFactory
();
CpuKernelFactory
*
factory
=
new
CpuKernelFactory
();
registerKernelFactory
(
CalcForcesAndEnergyKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcForcesAndEnergyKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcHarmonicAngleForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcPeriodicTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcPeriodicTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcRBTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcRBTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcNonbondedForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcNonbondedForceKernel
::
Name
(),
factory
);
...
...
platforms/cpu/tests/CpuTests.h
0 → 100644
View file @
6bde69d9
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2015 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#ifdef WIN32
#define _USE_MATH_DEFINES // Needed to get M_PI
#endif
#include "CpuPlatform.h"
#include <cstdlib>
#include <iostream>
OpenMM
::
CpuPlatform
platform
;
void
initializeTests
(
int
argc
,
char
*
argv
[])
{
if
(
!
OpenMM
::
CpuPlatform
::
isProcessorSupported
())
{
std
::
cout
<<
"CPU is not supported. Exiting."
<<
std
::
endl
;
exit
(
0
);
}
}
platforms/cpu/tests/TestCpuCheckpoints.cpp
0 → 100644
View file @
6bde69d9
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2012-2015 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "CpuTests.h"
#include "TestCheckpoints.h"
void
testCheckpoint
()
{
const
int
numParticles
=
100
;
const
double
boxSize
=
5.0
;
const
double
temperature
=
200.0
;
System
system
;
system
.
addForce
(
new
AndersenThermostat
(
0.0
,
100.0
));
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
system
.
addForce
(
nonbonded
);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
nonbonded
->
addParticle
(
i
%
2
==
0
?
0.1
:
-
0.1
,
0.2
,
0.1
);
bool
clash
;
do
{
clash
=
false
;
positions
[
i
]
=
Vec3
(
boxSize
*
genrand_real2
(
sfmt
),
boxSize
*
genrand_real2
(
sfmt
),
boxSize
*
genrand_real2
(
sfmt
));
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
j
];
if
(
sqrt
(
delta
.
dot
(
delta
))
<
0.1
)
clash
=
true
;
}
}
while
(
clash
);
}
VerletIntegrator
integrator
(
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
context
.
setParameter
(
AndersenThermostat
::
Temperature
(),
temperature
);
// Run for a little while.
integrator
.
step
(
100
);
// Record the current state and make a checkpoint.
State
s1
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Parameters
);
stringstream
stream1
(
ios_base
::
out
|
ios_base
::
in
|
ios_base
::
binary
);
context
.
createCheckpoint
(
stream1
);
// Continue the simulation for a few more steps and record the state again.
integrator
.
step
(
10
);
State
s2
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Parameters
);
// Restore from the checkpoint and see if everything gets restored correctly.
context
.
setPeriodicBoxVectors
(
Vec3
(
2
*
boxSize
,
0
,
0
),
Vec3
(
0
,
2
*
boxSize
,
0
),
Vec3
(
0
,
0
,
2
*
boxSize
));
context
.
setParameter
(
AndersenThermostat
::
Temperature
(),
temperature
+
10
);
context
.
loadCheckpoint
(
stream1
);
State
s3
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Parameters
);
compareStates
(
s1
,
s3
);
// Now simulate from there and see if the trajectory is identical.
integrator
.
step
(
10
);
State
s4
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Parameters
);
compareStates
(
s2
,
s4
);
}
void
runPlatformTests
()
{
testCheckpoint
();
}
platforms/cpu/tests/TestCpuCustomGBForce.cpp
View file @
6bde69d9
This diff is collapsed.
Click to expand it.
platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp
View file @
6bde69d9
This diff is collapsed.
Click to expand it.
platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp
View file @
6bde69d9
This diff is collapsed.
Click to expand it.
platforms/cpu/tests/TestCpuEwald.cpp
View file @
6bde69d9
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 20
08-2013
Stanford University and the Authors. *
* Portions copyright (c) 20
15
Stanford University and the Authors.
*
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -29,311 +29,8 @@
...
@@ -29,311 +29,8 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "CpuTests.h"
* This tests the Ewald summation method CPU implementation of NonbondedForce.
#include "TestEwald.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{
#include "openmm/Context.h"
#include "CpuPlatform.h"
#include "ReferencePlatform.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
CpuPlatform
platform
;
const
double
TOL
=
1e-5
;
void
testEwaldPME
(
bool
includeExceptions
)
{
// Use amorphous NaCl system for the tests
const
int
numParticles
=
894
;
const
double
cutoff
=
1.2
;
const
double
boxSize
=
3.00646
;
double
tol
=
1e-5
;
ReferencePlatform
reference
;
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
Ewald
);
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setEwaldErrorTolerance
(
tol
);
for
(
int
i
=
0
;
i
<
numParticles
/
2
;
i
++
)
system
.
addParticle
(
22.99
);
for
(
int
i
=
0
;
i
<
numParticles
/
2
;
i
++
)
system
.
addParticle
(
35.45
);
for
(
int
i
=
0
;
i
<
numParticles
/
2
;
i
++
)
nonbonded
->
addParticle
(
1.0
,
1.0
,
0.0
);
for
(
int
i
=
0
;
i
<
numParticles
/
2
;
i
++
)
nonbonded
->
addParticle
(
-
1.0
,
1.0
,
0.0
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
system
.
addForce
(
nonbonded
);
vector
<
Vec3
>
positions
(
numParticles
);
#include "nacl_amorph.dat"
if
(
includeExceptions
)
{
// Add some exclusions.
for
(
int
i
=
0
;
i
<
numParticles
-
1
;
i
++
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
i
+
1
];
if
(
sqrt
(
delta
.
dot
(
delta
))
<
0.5
*
cutoff
)
nonbonded
->
addException
(
i
,
i
+
1
,
i
%
2
==
0
?
0.0
:
0.5
,
1.0
,
0.0
);
}
}
// (1) Check whether the Reference and CPU platforms agree when using Ewald Method
VerletIntegrator
integrator1
(
0.01
);
VerletIntegrator
integrator2
(
0.01
);
Context
cpuContext
(
system
,
integrator1
,
platform
);
Context
referenceContext
(
system
,
integrator2
,
reference
);
cpuContext
.
setPositions
(
positions
);
referenceContext
.
setPositions
(
positions
);
State
cpuState
=
cpuContext
.
getState
(
State
::
Forces
|
State
::
Energy
);
State
referenceState
=
referenceContext
.
getState
(
State
::
Forces
|
State
::
Energy
);
tol
=
1e-2
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
ASSERT_EQUAL_VEC
(
referenceState
.
getForces
()[
i
],
cpuState
.
getForces
()[
i
],
tol
);
}
tol
=
1e-5
;
ASSERT_EQUAL_TOL
(
referenceState
.
getPotentialEnergy
(),
cpuState
.
getPotentialEnergy
(),
tol
);
// (2) Check whether Ewald method in CPU is self-consistent
double
norm
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
Vec3
f
=
cpuState
.
getForces
()[
i
];
norm
+=
f
[
0
]
*
f
[
0
]
+
f
[
1
]
*
f
[
1
]
+
f
[
2
]
*
f
[
2
];
}
norm
=
std
::
sqrt
(
norm
);
const
double
delta
=
5e-3
;
double
step
=
delta
/
norm
;
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
Vec3
p
=
positions
[
i
];
Vec3
f
=
cpuState
.
getForces
()[
i
];
positions
[
i
]
=
Vec3
(
p
[
0
]
-
f
[
0
]
*
step
,
p
[
1
]
-
f
[
1
]
*
step
,
p
[
2
]
-
f
[
2
]
*
step
);
}
VerletIntegrator
integrator3
(
0.01
);
Context
cpuContext2
(
system
,
integrator3
,
platform
);
cpuContext2
.
setPositions
(
positions
);
tol
=
1e-2
;
State
cpuState2
=
cpuContext2
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
norm
,
(
cpuState2
.
getPotentialEnergy
()
-
cpuState
.
getPotentialEnergy
())
/
delta
,
tol
)
// (3) Check whether the Reference and CPU platforms agree when using PME
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
cpuContext
.
reinitialize
();
referenceContext
.
reinitialize
();
cpuContext
.
setPositions
(
positions
);
referenceContext
.
setPositions
(
positions
);
cpuState
=
cpuContext
.
getState
(
State
::
Forces
|
State
::
Energy
);
referenceState
=
referenceContext
.
getState
(
State
::
Forces
|
State
::
Energy
);
tol
=
1e-2
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
ASSERT_EQUAL_VEC
(
referenceState
.
getForces
()[
i
],
cpuState
.
getForces
()[
i
],
tol
);
}
tol
=
1e-5
;
ASSERT_EQUAL_TOL
(
referenceState
.
getPotentialEnergy
(),
cpuState
.
getPotentialEnergy
(),
tol
);
// (4) Check whether PME method in CPU is self-consistent
norm
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
Vec3
f
=
cpuState
.
getForces
()[
i
];
norm
+=
f
[
0
]
*
f
[
0
]
+
f
[
1
]
*
f
[
1
]
+
f
[
2
]
*
f
[
2
];
}
norm
=
std
::
sqrt
(
norm
);
step
=
delta
/
norm
;
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
Vec3
p
=
positions
[
i
];
Vec3
f
=
cpuState
.
getForces
()[
i
];
positions
[
i
]
=
Vec3
(
p
[
0
]
-
f
[
0
]
*
step
,
p
[
1
]
-
f
[
1
]
*
step
,
p
[
2
]
-
f
[
2
]
*
step
);
}
VerletIntegrator
integrator4
(
0.01
);
Context
cpuContext3
(
system
,
integrator4
,
platform
);
cpuContext3
.
setPositions
(
positions
);
tol
=
1e-2
;
State
cpuState3
=
cpuContext3
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
norm
,
(
cpuState3
.
getPotentialEnergy
()
-
cpuState
.
getPotentialEnergy
())
/
delta
,
tol
)
}
void
testEwald2Ions
()
{
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
VerletIntegrator
integrator
(
0.01
);
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
nonbonded
->
addParticle
(
1.0
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.0
,
1
,
0
);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
Ewald
);
const
double
cutoff
=
2.0
;
nonbonded
->
setCutoffDistance
(
cutoff
);
nonbonded
->
setEwaldErrorTolerance
(
TOL
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
6
,
0
,
0
),
Vec3
(
0
,
6
,
0
),
Vec3
(
0
,
0
,
6
));
system
.
addForce
(
nonbonded
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
3.048000
,
2.764000
,
3.156000
);
positions
[
1
]
=
Vec3
(
2.809000
,
2.888000
,
2.571000
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
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_TOL
(
-
217.276
,
state
.
getPotentialEnergy
(),
0.01
/*10*TOL*/
);
}
void
testTriclinic
()
{
// Create a triclinic box containing eight particles.
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
2.5
,
0
,
0
),
Vec3
(
0.5
,
3.0
,
0
),
Vec3
(
0.7
,
0.9
,
3.5
));
for
(
int
i
=
0
;
i
<
8
;
i
++
)
system
.
addParticle
(
1.0
);
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
force
->
setNonbondedMethod
(
NonbondedForce
::
PME
);
force
->
setCutoffDistance
(
1.0
);
force
->
setPMEParameters
(
3.45891
,
32
,
40
,
48
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
force
->
addParticle
(
-
1
,
0.440104
,
0.4184
);
// Cl parameters
for
(
int
i
=
0
;
i
<
4
;
i
++
)
force
->
addParticle
(
1
,
0.332840
,
0.0115897
);
// Na parameters
vector
<
Vec3
>
positions
(
8
);
positions
[
0
]
=
Vec3
(
1.744
,
2.788
,
3.162
);
positions
[
1
]
=
Vec3
(
1.048
,
0.762
,
2.340
);
positions
[
2
]
=
Vec3
(
2.489
,
1.570
,
2.817
);
positions
[
3
]
=
Vec3
(
1.027
,
1.893
,
3.271
);
positions
[
4
]
=
Vec3
(
0.937
,
0.825
,
0.009
);
positions
[
5
]
=
Vec3
(
2.290
,
1.887
,
3.352
);
positions
[
6
]
=
Vec3
(
1.266
,
1.111
,
2.894
);
positions
[
7
]
=
Vec3
(
0.933
,
1.862
,
3.490
);
// Compute the forces and energy.
VerletIntegrator
integ
(
0.001
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
// Compare them to values computed by Gromacs.
double
expectedEnergy
=
-
963.370
;
vector
<
Vec3
>
expectedForce
(
8
);
expectedForce
[
0
]
=
Vec3
(
4.25253e+01
,
-
1.23503e+02
,
1.22139e+02
);
expectedForce
[
1
]
=
Vec3
(
9.74752e+01
,
1.68213e+02
,
1.93169e+02
);
expectedForce
[
2
]
=
Vec3
(
-
1.50348e+02
,
1.29165e+02
,
3.70435e+02
);
expectedForce
[
3
]
=
Vec3
(
9.18644e+02
,
-
3.52571e+00
,
-
1.34772e+03
);
expectedForce
[
4
]
=
Vec3
(
-
1.61193e+02
,
9.01528e+01
,
-
7.12904e+01
);
expectedForce
[
5
]
=
Vec3
(
2.82630e+02
,
2.78029e+01
,
-
3.72864e+02
);
expectedForce
[
6
]
=
Vec3
(
-
1.47454e+02
,
-
2.14448e+02
,
-
3.55789e+02
);
expectedForce
[
7
]
=
Vec3
(
-
8.82195e+02
,
-
7.39132e+01
,
1.46202e+03
);
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
ASSERT_EQUAL_VEC
(
expectedForce
[
i
],
state
.
getForces
()[
i
],
1e-4
);
}
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-4
);
}
void
testErrorTolerance
(
NonbondedForce
::
NonbondedMethod
method
)
{
// Create a cloud of random point charges.
const
int
numParticles
=
51
;
const
double
boxWidth
=
5.0
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxWidth
,
0
,
0
),
Vec3
(
0
,
boxWidth
,
0
),
Vec3
(
0
,
0
,
boxWidth
));
NonbondedForce
*
force
=
new
NonbondedForce
();
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
-
1.0
+
i
*
2.0
/
(
numParticles
-
1
),
1.0
,
0.0
);
positions
[
i
]
=
Vec3
(
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
),
boxWidth
*
genrand_real2
(
sfmt
));
}
force
->
setNonbondedMethod
(
method
);
// For various values of the cutoff and error tolerance, see if the actual error is reasonable.
for
(
double
cutoff
=
1.0
;
cutoff
<
boxWidth
/
2
;
cutoff
*=
1.2
)
{
force
->
setCutoffDistance
(
cutoff
);
vector
<
Vec3
>
refForces
;
double
norm
=
0.0
;
for
(
double
tol
=
5e-5
;
tol
<
1e-3
;
tol
*=
2.0
)
{
force
->
setEwaldErrorTolerance
(
tol
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
);
if
(
refForces
.
size
()
==
0
)
{
refForces
=
state
.
getForces
();
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
norm
+=
refForces
[
i
].
dot
(
refForces
[
i
]);
norm
=
sqrt
(
norm
);
}
else
{
double
diff
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
Vec3
delta
=
refForces
[
i
]
-
state
.
getForces
()[
i
];
diff
+=
delta
.
dot
(
delta
);
}
diff
=
sqrt
(
diff
)
/
norm
;
ASSERT
(
diff
<
2
*
tol
);
}
if
(
method
==
NonbondedForce
::
PME
)
{
// See if the PME parameters were calculated correctly.
double
expectedAlpha
,
actualAlpha
;
int
expectedSize
[
3
],
actualSize
[
3
];
NonbondedForceImpl
::
calcPMEParameters
(
system
,
*
force
,
expectedAlpha
,
expectedSize
[
0
],
expectedSize
[
1
],
expectedSize
[
2
]);
force
->
getPMEParametersInContext
(
context
,
actualAlpha
,
actualSize
[
0
],
actualSize
[
1
],
actualSize
[
2
]);
ASSERT_EQUAL_TOL
(
expectedAlpha
,
actualAlpha
,
1e-5
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
ASSERT
(
actualSize
[
i
]
>=
expectedSize
[
i
]);
ASSERT
(
actualSize
[
i
]
<
expectedSize
[
i
]
+
10
);
}
}
}
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
if
(
!
CpuPlatform
::
isProcessorSupported
())
{
cout
<<
"CPU is not supported. Exiting."
<<
endl
;
return
0
;
}
testEwaldPME
(
false
);
testEwaldPME
(
true
);
// testEwald2Ions();
testTriclinic
();
testErrorTolerance
(
NonbondedForce
::
Ewald
);
testErrorTolerance
(
NonbondedForce
::
PME
);
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
}
platforms/cpu/tests/TestCpuGBSAOBCForce.cpp
View file @
6bde69d9
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 20
08-2014
Stanford University and the Authors. *
* Portions copyright (c) 20
15
Stanford University and the Authors.
*
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -29,244 +29,8 @@
...
@@ -29,244 +29,8 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "CpuTests.h"
* This tests the CPU implementation of GBSAOBCForce.
#include "TestGBSAOBCForce.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{
#include "openmm/Context.h"
#include "CpuPlatform.h"
#include "openmm/GBSAOBCForce.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h"
#include "openmm/NonbondedForce.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testSingleParticle
()
{
CpuPlatform
platform
;
System
system
;
system
.
addParticle
(
2.0
);
LangevinIntegrator
integrator
(
0
,
0.1
,
0.01
);
GBSAOBCForce
*
forceField
=
new
GBSAOBCForce
();
forceField
->
addParticle
(
0.5
,
0.15
,
1
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
1
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
bornRadius
=
0.15
-
0.009
;
// dielectric offset
double
eps0
=
EPSILON0
;
double
bornEnergy
=
(
-
0.5
*
0.5
/
(
8
*
PI_M
*
eps0
))
*
(
1.0
/
forceField
->
getSoluteDielectric
()
-
1.0
/
forceField
->
getSolventDielectric
())
/
bornRadius
;
double
extendedRadius
=
0.15
+
0.14
;
// probe radius
double
nonpolarEnergy
=
4
*
PI_M
*
2.25936
*
extendedRadius
*
extendedRadius
*
std
::
pow
(
0.15
/
bornRadius
,
6.0
);
ASSERT_EQUAL_TOL
((
bornEnergy
+
nonpolarEnergy
),
state
.
getPotentialEnergy
(),
0.01
);
// Change the parameters and see if it is still correct.
forceField
->
setParticleParameters
(
0
,
0.4
,
0.25
,
1
);
forceField
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
bornRadius
=
0.25
-
0.009
;
// dielectric offset
bornEnergy
=
(
-
0.4
*
0.4
/
(
8
*
PI_M
*
eps0
))
*
(
1.0
/
forceField
->
getSoluteDielectric
()
-
1.0
/
forceField
->
getSolventDielectric
())
/
bornRadius
;
extendedRadius
=
0.25
+
0.14
;
nonpolarEnergy
=
4
*
PI_M
*
2.25936
*
extendedRadius
*
extendedRadius
*
std
::
pow
(
0.25
/
bornRadius
,
6.0
);
ASSERT_EQUAL_TOL
((
bornEnergy
+
nonpolarEnergy
),
state
.
getPotentialEnergy
(),
0.01
);
}
void
testGlobalSettings
()
{
CpuPlatform
platform
;
System
system
;
system
.
addParticle
(
2.0
);
LangevinIntegrator
integrator
(
0
,
0.1
,
0.01
);
GBSAOBCForce
*
forceField
=
new
GBSAOBCForce
();
forceField
->
addParticle
(
0.5
,
0.15
,
1
);
const
double
soluteDielectric
=
2.1
;
const
double
solventDielectric
=
35.0
;
const
double
surfaceAreaEnergy
=
0.75
;
forceField
->
setSoluteDielectric
(
soluteDielectric
);
forceField
->
setSolventDielectric
(
solventDielectric
);
forceField
->
setSurfaceAreaEnergy
(
surfaceAreaEnergy
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
1
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
bornRadius
=
0.15
-
0.009
;
// dielectric offset
double
eps0
=
EPSILON0
;
double
bornEnergy
=
(
-
0.5
*
0.5
/
(
8
*
PI_M
*
eps0
))
*
(
1.0
/
soluteDielectric
-
1.0
/
solventDielectric
)
/
bornRadius
;
double
extendedRadius
=
0.15
+
0.14
;
// probe radius
double
nonpolarEnergy
=
4
*
PI_M
*
surfaceAreaEnergy
*
extendedRadius
*
extendedRadius
*
std
::
pow
(
0.15
/
bornRadius
,
6.0
);
ASSERT_EQUAL_TOL
((
bornEnergy
+
nonpolarEnergy
),
state
.
getPotentialEnergy
(),
0.01
);
}
void
testCutoffAndPeriodic
()
{
CpuPlatform
platform
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
LangevinIntegrator
integrator
(
0
,
0.1
,
0.01
);
GBSAOBCForce
*
gbsa
=
new
GBSAOBCForce
();
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
gbsa
->
addParticle
(
-
1
,
0.15
,
1
);
nonbonded
->
addParticle
(
-
1
,
1
,
0
);
gbsa
->
addParticle
(
1
,
0.15
,
1
);
nonbonded
->
addParticle
(
1
,
1
,
0
);
const
double
cutoffDistance
=
3.0
;
const
double
boxSize
=
10.0
;
nonbonded
->
setCutoffDistance
(
cutoffDistance
);
gbsa
->
setCutoffDistance
(
cutoffDistance
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
system
.
addForce
(
gbsa
);
system
.
addForce
(
nonbonded
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
// Calculate the forces for both cutoff and periodic with two different atom positions.
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffNonPeriodic
);
gbsa
->
setNonbondedMethod
(
GBSAOBCForce
::
CutoffNonPeriodic
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state1
=
context
.
getState
(
State
::
Forces
);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
gbsa
->
setNonbondedMethod
(
GBSAOBCForce
::
CutoffPeriodic
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
State
state2
=
context
.
getState
(
State
::
Forces
);
positions
[
1
][
0
]
+=
boxSize
;
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffNonPeriodic
);
gbsa
->
setNonbondedMethod
(
GBSAOBCForce
::
CutoffNonPeriodic
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
State
state3
=
context
.
getState
(
State
::
Forces
);
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
gbsa
->
setNonbondedMethod
(
GBSAOBCForce
::
CutoffPeriodic
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
State
state4
=
context
.
getState
(
State
::
Forces
);
// All forces should be identical, exception state3 which should be zero.
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
0
],
state2
.
getForces
()[
0
],
0.01
);
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
1
],
state2
.
getForces
()[
1
],
0.01
);
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
0
],
state4
.
getForces
()[
0
],
0.01
);
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
1
],
state4
.
getForces
()[
1
],
0.01
);
ASSERT_EQUAL_VEC
(
state3
.
getForces
()[
0
],
Vec3
(
0
,
0
,
0
),
0.01
);
ASSERT_EQUAL_VEC
(
state3
.
getForces
()[
1
],
Vec3
(
0
,
0
,
0
),
0.01
);
}
void
testForce
(
int
numParticles
,
NonbondedForce
::
NonbondedMethod
method
,
GBSAOBCForce
::
NonbondedMethod
method2
)
{
CpuPlatform
platform
;
ReferencePlatform
reference
;
System
system
;
GBSAOBCForce
*
gbsa
=
new
GBSAOBCForce
();
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
1.0
);
double
charge
=
i
%
2
==
0
?
-
1
:
1
;
gbsa
->
addParticle
(
charge
,
0.15
,
1
);
nonbonded
->
addParticle
(
charge
,
1
,
0
);
}
nonbonded
->
setNonbondedMethod
(
method
);
gbsa
->
setNonbondedMethod
(
method2
);
nonbonded
->
setCutoffDistance
(
3.0
);
gbsa
->
setCutoffDistance
(
3.0
);
int
grid
=
(
int
)
floor
(
0.5
+
pow
(
numParticles
,
1.0
/
3.0
));
if
(
method
==
NonbondedForce
::
CutoffPeriodic
)
{
double
boxSize
=
(
grid
+
1
)
*
1.1
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
}
system
.
addForce
(
gbsa
);
system
.
addForce
(
nonbonded
);
LangevinIntegrator
integrator1
(
0
,
0.1
,
0.01
);
LangevinIntegrator
integrator2
(
0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator1
,
platform
);
Context
refContext
(
system
,
integrator2
,
reference
);
// Set random (but uniformly distributed) positions for all the particles.
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
grid
;
i
++
)
for
(
int
j
=
0
;
j
<
grid
;
j
++
)
for
(
int
k
=
0
;
k
<
grid
;
k
++
)
positions
[
i
*
grid
*
grid
+
j
*
grid
+
k
]
=
Vec3
(
i
*
1.1
,
j
*
1.1
,
k
*
1.1
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
positions
[
i
]
=
positions
[
i
]
+
Vec3
(
0.5
*
genrand_real2
(
sfmt
),
0.5
*
genrand_real2
(
sfmt
),
0.5
*
genrand_real2
(
sfmt
));
context
.
setPositions
(
positions
);
refContext
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
State
refState
=
refContext
.
getState
(
State
::
Forces
|
State
::
Energy
);
// Make sure the CPU and Reference platforms agree.
double
norm
=
0.0
;
double
diff
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
Vec3
f
=
state
.
getForces
()[
i
];
norm
+=
f
[
0
]
*
f
[
0
]
+
f
[
1
]
*
f
[
1
]
+
f
[
2
]
*
f
[
2
];
Vec3
delta
=
f
-
refState
.
getForces
()[
i
];
diff
+=
delta
[
0
]
*
delta
[
0
]
+
delta
[
1
]
*
delta
[
1
]
+
delta
[
2
]
*
delta
[
2
];
}
norm
=
std
::
sqrt
(
norm
);
diff
=
std
::
sqrt
(
diff
);
ASSERT_EQUAL_TOL
(
0.0
,
diff
,
0.001
*
norm
);
ASSERT_EQUAL_TOL
(
state
.
getPotentialEnergy
(),
refState
.
getPotentialEnergy
(),
1e-3
);
// Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount.
// (This doesn't work with cutoffs, since the energy changes discontinuously at the cutoff distance.)
if
(
method
==
NonbondedForce
::
NoCutoff
)
{
const
double
delta
=
0.3
;
double
step
=
0.5
*
delta
/
norm
;
vector
<
Vec3
>
positions2
(
numParticles
),
positions3
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
Vec3
p
=
positions
[
i
];
Vec3
f
=
state
.
getForces
()[
i
];
positions2
[
i
]
=
Vec3
(
p
[
0
]
-
f
[
0
]
*
step
,
p
[
1
]
-
f
[
1
]
*
step
,
p
[
2
]
-
f
[
2
]
*
step
);
positions3
[
i
]
=
Vec3
(
p
[
0
]
+
f
[
0
]
*
step
,
p
[
1
]
+
f
[
1
]
*
step
,
p
[
2
]
+
f
[
2
]
*
step
);
}
context
.
setPositions
(
positions2
);
State
state2
=
context
.
getState
(
State
::
Energy
);
context
.
setPositions
(
positions3
);
State
state3
=
context
.
getState
(
State
::
Energy
);
ASSERT_EQUAL_TOL
(
norm
,
(
state2
.
getPotentialEnergy
()
-
state3
.
getPotentialEnergy
())
/
delta
,
1e-2
)
}
}
int
main
()
{
try
{
if
(
!
CpuPlatform
::
isProcessorSupported
())
{
cout
<<
"CPU is not supported. Exiting."
<<
endl
;
return
0
;
}
testSingleParticle
();
testGlobalSettings
();
testCutoffAndPeriodic
();
for
(
int
i
=
5
;
i
<
11
;
i
++
)
{
testForce
(
i
*
i
*
i
,
NonbondedForce
::
NoCutoff
,
GBSAOBCForce
::
NoCutoff
);
testForce
(
i
*
i
*
i
,
NonbondedForce
::
CutoffNonPeriodic
,
GBSAOBCForce
::
CutoffNonPeriodic
);
testForce
(
i
*
i
*
i
,
NonbondedForce
::
CutoffPeriodic
,
GBSAOBCForce
::
CutoffPeriodic
);
}
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
}
platforms/cpu/tests/TestCpuHarmonicAngleForce.cpp
0 → 100644
View file @
6bde69d9
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2015 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "CpuTests.h"
#include "TestHarmonicAngleForce.h"
void
testParallelComputation
()
{
System
system
;
const
int
numParticles
=
200
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
system
.
addParticle
(
1.0
);
HarmonicAngleForce
*
force
=
new
HarmonicAngleForce
();
for
(
int
i
=
2
;
i
<
numParticles
;
i
++
)
force
->
addAngle
(
i
-
2
,
i
-
1
,
i
,
1.1
,
i
);
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
positions
[
i
]
=
Vec3
(
i
,
i
%
2
,
0
);
VerletIntegrator
integrator1
(
0.01
);
ReferencePlatform
reference
;
Context
context1
(
system
,
integrator1
,
reference
);
context1
.
setPositions
(
positions
);
State
state1
=
context1
.
getState
(
State
::
Forces
|
State
::
Energy
);
VerletIntegrator
integrator2
(
0.01
);
Context
context2
(
system
,
integrator2
,
platform
);
context2
.
setPositions
(
positions
);
State
state2
=
context2
.
getState
(
State
::
Forces
|
State
::
Energy
);
ASSERT_EQUAL_TOL
(
state1
.
getPotentialEnergy
(),
state2
.
getPotentialEnergy
(),
1e-5
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
i
],
state2
.
getForces
()[
i
],
1e-5
);
}
void
runPlatformTests
()
{
testParallelComputation
();
}
platforms/cpu/tests/TestCpuLangevinIntegrator.cpp
View file @
6bde69d9
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 20
08-2013
Stanford University and the Authors. *
* Portions copyright (c) 20
15
Stanford University and the Authors.
*
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -29,255 +29,8 @@
...
@@ -29,255 +29,8 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/**
#include "CpuTests.h"
* This tests the reference implementation of LangevinIntegrator.
#include "TestLangevinIntegrator.h"
*/
#include "openmm/internal/AssertionUtilities.h"
void
runPlatformTests
()
{
#include "openmm/Context.h"
#include "CpuPlatform.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testSingleBond
()
{
CpuPlatform
platform
;
System
system
;
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
LangevinIntegrator
integrator
(
0
,
0.1
,
0.01
);
HarmonicBondForce
*
forceField
=
new
HarmonicBondForce
();
forceField
->
addBond
(
0
,
1
,
1.5
,
1
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
context
.
setPositions
(
positions
);
// This is simply a damped harmonic oscillator, so compare it to the analytical solution.
double
freq
=
std
::
sqrt
(
1
-
0.05
*
0.05
);
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
);
double
time
=
state
.
getTime
();
double
expectedDist
=
1.5
+
0.5
*
std
::
exp
(
-
0.05
*
time
)
*
std
::
cos
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
1
],
0.02
);
double
expectedSpeed
=
-
0.5
*
std
::
exp
(
-
0.05
*
time
)
*
(
0.05
*
std
::
cos
(
freq
*
time
)
+
freq
*
std
::
sin
(
freq
*
time
));
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
1
],
0.02
);
integrator
.
step
(
1
);
}
// Not set the friction to a tiny value and see if it conserves energy.
integrator
.
setFriction
(
5e-5
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
initialEnergy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
state
=
context
.
getState
(
State
::
Energy
);
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.01
);
integrator
.
step
(
1
);
}
}
void
testTemperature
()
{
const
int
numParticles
=
8
;
const
double
temp
=
100.0
;
CpuPlatform
platform
;
System
system
;
LangevinIntegrator
integrator
(
temp
,
2.0
,
0.01
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
2.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
1.0
:
-
1.0
),
1.0
,
5.0
);
}
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
positions
[
i
]
=
Vec3
((
i
%
2
==
0
?
2
:
-
2
),
(
i
%
4
<
2
?
2
:
-
2
),
(
i
<
4
?
2
:
-
2
));
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
10000
);
// Now run it for a while and see if the temperature is correct.
double
ke
=
0.0
;
for
(
int
i
=
0
;
i
<
10000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Energy
);
ke
+=
state
.
getKineticEnergy
();
integrator
.
step
(
1
);
}
ke
/=
10000
;
double
expected
=
0.5
*
numParticles
*
3
*
BOLTZ
*
temp
;
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
ke
,
6
/
std
::
sqrt
(
10000.0
));
}
void
testConstraints
()
{
const
int
numParticles
=
8
;
const
double
temp
=
100.0
;
CpuPlatform
platform
;
System
system
;
LangevinIntegrator
integrator
(
temp
,
2.0
,
0.01
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
for
(
int
i
=
0
;
i
<
numParticles
-
1
;
++
i
)
system
.
addConstraint
(
i
,
i
+
1
,
1.0
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
vector
<
Vec3
>
velocities
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
positions
[
i
]
=
Vec3
(
i
/
2
,
(
i
+
1
)
/
2
,
0
);
velocities
[
i
]
=
Vec3
(
genrand_real2
(
sfmt
)
-
0.5
,
genrand_real2
(
sfmt
)
-
0.5
,
genrand_real2
(
sfmt
)
-
0.5
);
}
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
);
for
(
int
j
=
0
;
j
<
numParticles
-
1
;
++
j
)
{
Vec3
p1
=
state
.
getPositions
()[
j
];
Vec3
p2
=
state
.
getPositions
()[
j
+
1
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
1.0
,
dist
,
2e-5
);
}
integrator
.
step
(
1
);
}
}
void
testConstrainedMasslessParticles
()
{
CpuPlatform
platform
;
System
system
;
system
.
addParticle
(
0.0
);
system
.
addParticle
(
1.0
);
system
.
addConstraint
(
0
,
1
,
1.5
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
LangevinIntegrator
integrator
(
300.0
,
2.0
,
0.01
);
bool
failed
=
false
;
try
{
// This should throw an exception.
Context
context
(
system
,
integrator
,
platform
);
}
catch
(
exception
&
ex
)
{
failed
=
true
;
}
ASSERT
(
failed
);
// Now make both particles massless, which should work.
system
.
setParticleMass
(
1
,
0.0
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
300.0
);
integrator
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
ASSERT_EQUAL
(
0.0
,
state
.
getVelocities
()[
0
][
0
]);
}
void
testRandomSeed
()
{
const
int
numParticles
=
8
;
const
double
temp
=
100.0
;
const
double
collisionFreq
=
10.0
;
CpuPlatform
platform
;
System
system
;
LangevinIntegrator
integrator
(
temp
,
2.0
,
0.01
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
2.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
1.0
:
-
1.0
),
1.0
,
5.0
);
}
system
.
addForce
(
forceField
);
vector
<
Vec3
>
positions
(
numParticles
);
vector
<
Vec3
>
velocities
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
positions
[
i
]
=
Vec3
((
i
%
2
==
0
?
2
:
-
2
),
(
i
%
4
<
2
?
2
:
-
2
),
(
i
<
4
?
2
:
-
2
));
velocities
[
i
]
=
Vec3
(
0
,
0
,
0
);
}
// Try twice with the same random seed.
integrator
.
setRandomNumberSeed
(
5
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
integrator
.
step
(
10
);
State
state1
=
context
.
getState
(
State
::
Positions
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
integrator
.
step
(
10
);
State
state2
=
context
.
getState
(
State
::
Positions
);
// Try twice with a different random seed.
integrator
.
setRandomNumberSeed
(
10
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
integrator
.
step
(
10
);
State
state3
=
context
.
getState
(
State
::
Positions
);
context
.
reinitialize
();
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
integrator
.
step
(
10
);
State
state4
=
context
.
getState
(
State
::
Positions
);
// Compare the results.
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
ASSERT_EQUAL_TOL
(
state1
.
getPositions
()[
i
][
j
],
state2
.
getPositions
()[
i
][
j
],
1e-5
);
ASSERT_EQUAL_TOL
(
state3
.
getPositions
()[
i
][
j
],
state4
.
getPositions
()[
i
][
j
],
1e-5
);
ASSERT
(
state1
.
getPositions
()[
i
][
j
]
!=
state3
.
getPositions
()[
i
][
j
]);
}
}
}
int
main
()
{
try
{
if
(
!
CpuPlatform
::
isProcessorSupported
())
{
cout
<<
"CPU is not supported. Exiting."
<<
endl
;
return
0
;
}
testSingleBond
();
testTemperature
();
testConstraints
();
testConstrainedMasslessParticles
();
testRandomSeed
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
}
Prev
1
2
3
4
5
6
…
11
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment