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
604881dc
Commit
604881dc
authored
Sep 05, 2014
by
peastman
Browse files
Merge pull request #604 from peastman/many
Created CustomManyParticleForce
parents
f2eb95d0
1515e2bc
Changes
50
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2672 additions
and
300 deletions
+2672
-300
docs-source/usersguide/application.rst
docs-source/usersguide/application.rst
+55
-0
docs-source/usersguide/theory.rst
docs-source/usersguide/theory.rst
+48
-0
olla/include/openmm/kernels.h
olla/include/openmm/kernels.h
+41
-0
openmmapi/include/OpenMM.h
openmmapi/include/OpenMM.h
+1
-0
openmmapi/include/openmm/CustomManyParticleForce.h
openmmapi/include/openmm/CustomManyParticleForce.h
+558
-0
openmmapi/include/openmm/internal/CustomManyParticleForceImpl.h
...api/include/openmm/internal/CustomManyParticleForceImpl.h
+109
-0
openmmapi/include/openmm/internal/vectorize_neon.h
openmmapi/include/openmm/internal/vectorize_neon.h
+6
-0
openmmapi/include/openmm/internal/vectorize_pnacl.h
openmmapi/include/openmm/internal/vectorize_pnacl.h
+6
-0
openmmapi/include/openmm/internal/vectorize_sse.h
openmmapi/include/openmm/internal/vectorize_sse.h
+305
-299
openmmapi/src/CustomManyParticleForce.cpp
openmmapi/src/CustomManyParticleForce.cpp
+224
-0
openmmapi/src/CustomManyParticleForceImpl.cpp
openmmapi/src/CustomManyParticleForceImpl.cpp
+333
-0
platforms/cpu/include/CompiledExpressionSet.h
platforms/cpu/include/CompiledExpressionSet.h
+71
-0
platforms/cpu/include/CpuCustomManyParticleForce.h
platforms/cpu/include/CpuCustomManyParticleForce.h
+223
-0
platforms/cpu/include/CpuKernels.h
platforms/cpu/include/CpuKernels.h
+43
-0
platforms/cpu/src/CompiledExpressionSet.cpp
platforms/cpu/src/CompiledExpressionSet.cpp
+56
-0
platforms/cpu/src/CpuCustomManyParticleForce.cpp
platforms/cpu/src/CpuCustomManyParticleForce.cpp
+521
-0
platforms/cpu/src/CpuKernelFactory.cpp
platforms/cpu/src/CpuKernelFactory.cpp
+2
-0
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+66
-0
platforms/cpu/src/CpuPlatform.cpp
platforms/cpu/src/CpuPlatform.cpp
+1
-0
platforms/cpu/src/CpuSETTLE.cpp
platforms/cpu/src/CpuSETTLE.cpp
+3
-1
No files found.
docs-source/usersguide/application.rst
View file @
604881dc
...
...
@@ -2400,6 +2400,61 @@ must include an attribute called :code:`radius`\ .
CustomGBForce
also
allows
you
to
define
tabulated
functions
.
See
section
:
ref
:`
tabulated
-
functions
`
for
details
.
<
CustomManyParticleForce
>
=========================
To
add
a
CustomManyParticleForce
to
the
System
,
include
a
tag
that
looks
like
this
:
..
code
-
block
::
xml
<
CustomManyParticleForce
particlesPerSet
=
"3"
permutationMode
=
"UniqueCentralParticle"
bondCutoff
=
"3"
energy
=
"scale*(distance(p1,p2)-r1)*(distance(p1,p3)-r1)"
>
<
GlobalParameter
name
=
"scale"
defaultValue
=
"1"
/>
<
PerParticleParameter
name
=
"r"
/>
<
TypeFilter
index
=
"0"
types
=
"1,2"
/>
<
Atom
type
=
"0"
r
=
"0.31"
filterType
=
"0"
/>
<
Atom
type
=
"1"
r
=
"0.25"
filterType
=
"0"
/>
<
Atom
type
=
"2"
r
=
"0.33"
filterType
=
"1"
/>
...
</
CustomManyParticleForce
>
The
energy
expression
for
the
CustomManyParticleForce
is
specified
by
the
:
code
:`
energy
`
attribute
.
This
is
a
mathematical
expression
that
gives
the
energy
of
each
pairwise
interaction
as
a
function
of
various
particle
coordinates
,
distances
,
and
angles
.
See
the
API
documentation
for
details
.
:
code
:`
particlesPerSet
`
specifies
the
number
of
particles
involved
in
the
interaction
and
:
code
:`
permutationMode
`
specifies
the
permutation
mode
.
The
expression
may
depend
on
an
arbitrary
list
of
global
or
per
-
atom
parameters
.
Use
a
:
code
:`<
GlobalParameter
>`
tag
to
define
a
global
parameter
,
and
a
:
code
:`<
PerAtomParameter
>`
tag
to
define
a
per
-
atom
parameter
.
Exclusions
are
created
automatically
based
on
the
:
code
:`
bondCutoff
`
attribute
.
After
setting
the
nonbonded
parameters
for
all
atoms
,
the
force
field
calls
:
code
:`
createExclusionsFromBonds
()`
on
the
CustomManyParticleForce
,
passing
in
this
value
as
its
argument
.
To
avoid
creating
exclusions
,
set
:
code
:`
bondCutoff
`
to
0.
Type
filters
may
be
specified
with
a
:
code
:`<
TypeFilter
>`
tag
.
The
:
code
:`
index
`
attribute
specifies
the
index
of
the
particle
to
apply
the
filter
to
,
and
:
code
:`
types
`
is
a
comma
separated
list
of
allowed
types
.
Each
:
code
:`<
Atom
>`
tag
specifies
the
parameters
for
one
atom
type
(
specified
with
the
:
code
:`
type
`
attribute
)
or
atom
class
(
specified
with
the
:
code
:`
class
`
attribute
).
It
is
fine
to
mix
these
two
methods
,
having
some
tags
specify
a
type
and
others
specify
a
class
.
However
you
do
it
,
you
must
make
sure
that
a
unique
set
of
parameters
is
defined
for
every
atom
type
.
In
addition
,
each
:
code
:`<
Atom
>`
tag
must
include
the
:
code
:`
filterType
`
attribute
,
which
specifies
the
atom
type
for
use
in
type
filters
.
The
remaining
attributes
are
the
values
to
use
for
the
per
-
atom
parameters
.
All
per
-
atom
parameters
must
be
specified
for
every
:
code
:`<
Atom
>`
tag
,
and
the
attribute
name
must
match
the
name
of
the
parameter
.
For
instance
,
if
there
is
a
per
-
atom
parameter
with
the
name
“
radius
”
,
then
every
:
code
:`<
Atom
>`
tag
must
include
an
attribute
called
:
code
:`
radius
`\
.
CustomManyParticleForce
also
allows
you
to
define
tabulated
functions
.
See
section
:
ref
:`
tabulated
-
functions
`
for
details
.
Writing
Custom
Expressions
==========================
...
...
docs-source/usersguide/theory.rst
View file @
604881dc
...
...
@@ -828,6 +828,54 @@ Parameters may be specified in two ways:
* Per-bond parameters are defined by specifying a value for each bond.
CustomManyParticleForce
***********************
CustomManyParticleForce is similar to CustomNonbondedForce in that it represents
a custom nonbonded interaction between particles, but it allows the interaction
to depend on more than two particles. This allows it to represent a wide range
of non-pairwise interactions. It is defined by specifying the number of
particles :math:`N` involved in the interaction and how the energy depends on
their positions. More specifically, it takes a user specified energy function
.. math::
E=f(\{x_i\},\{r_i\},\{\theta_i\},\{\phi_i\})
that may depend on an arbitrary set of positions {\ :math:`x_i`\ }, distances
{\ :math:`r_i`\ }, angles {\ :math:`\theta_i`\ }, and dihedral angles
{\ :math:`\phi_i`\ } from a particular set of :math:`N` particles.
Each distance, angle, or dihedral is defined by specifying a sequence of
particles chosen from among the particles in the set. A distance
variable is defined by two particles, and equals the distance between them. An
angle variable is defined by three particles, and equals the angle between them.
A dihedral variable is defined by four particles, and equals the angle between
the first and last particles about the axis formed by the middle two particles.
It is equal to zero when the first and last particles are on the same side of
the axis.
In addition to depending on positions, distances, angles, and dihedrals, the
energy may also depend on an arbitrary set of user defined parameters.
Parameters may be specified in two ways:
* Global parameters have a single, fixed value.
* Per-particle parameters are defined by specifying a value for each particle.
The energy function is evaluated one or more times for every unique set of
:math:`N` particles in the system. The exact number of times depends on the
*permutation mode*\ . A set of :math:`N` particles has :math:`N!` possible
permutations. In :code:`SinglePermutation` mode, the function is evaluated
for a single arbitrarily chosen one of those permutations. In
:code:`UniqueCentralParticle` mode, the function is evaluated for :math:`N` of
those permutations, once with each particle as the "central particle".
The number of times the energy function is evaluated can be further restricted
by specifying *type filters*\ . Each particle may have a "type" assigned to it,
and then each of the :math:`N` particles involved in an interaction may be
restricted to only a specified set of types. This provides a great deal of
flexibility in controlling which particles interact with each other.
CustomGBForce
*************
...
...
olla/include/openmm/kernels.h
View file @
604881dc
...
...
@@ -44,6 +44,7 @@
#include "openmm/CustomHbondForce.h"
#include "openmm/CustomIntegrator.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/CustomManyParticleForce.h"
#include "openmm/CustomTorsionForce.h"
#include "openmm/GBSAOBCForce.h"
#include "openmm/GBVIForce.h"
...
...
@@ -826,6 +827,46 @@ public:
virtual
void
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomCompoundBondForce
&
force
)
=
0
;
};
/**
* This kernel is invoked by CustomManyParticleForce to calculate the forces acting on the system and the energy of the system.
*/
class
CalcCustomManyParticleForceKernel
:
public
KernelImpl
{
public:
enum
NonbondedMethod
{
NoCutoff
=
0
,
CutoffNonPeriodic
=
1
,
CutoffPeriodic
=
2
};
static
std
::
string
Name
()
{
return
"CalcCustomManyParticleForce"
;
}
CalcCustomManyParticleForceKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
KernelImpl
(
name
,
platform
)
{
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the CustomManyParticleForce this kernel will be used for
*/
virtual
void
initialize
(
const
System
&
system
,
const
CustomManyParticleForce
&
force
)
=
0
;
/**
* 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
*/
virtual
double
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
=
0
;
/**
* Copy changed parameters over to a context.
*
* @param context the context to copy parameters to
* @param force the CustomManyParticleForce to copy the parameters from
*/
virtual
void
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomManyParticleForce
&
force
)
=
0
;
};
/**
* This kernel is invoked by VerletIntegrator to take one time step.
*/
...
...
openmmapi/include/OpenMM.h
View file @
604881dc
...
...
@@ -44,6 +44,7 @@
#include "openmm/CustomGBForce.h"
#include "openmm/CustomHbondForce.h"
#include "openmm/CustomIntegrator.h"
#include "openmm/CustomManyParticleForce.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/Force.h"
#include "openmm/GBSAOBCForce.h"
...
...
openmmapi/include/openmm/CustomManyParticleForce.h
0 → 100644
View file @
604881dc
This diff is collapsed.
Click to expand it.
openmmapi/include/openmm/internal/CustomManyParticleForceImpl.h
0 → 100644
View file @
604881dc
#ifndef OPENMM_CUSTOMMANYPARTICLEFORCEIMPL_H_
#define OPENMM_CUSTOMMANYPARTICLEFORCEIMPL_H_
/* -------------------------------------------------------------------------- *
* 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-2014 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 "ForceImpl.h"
#include "openmm/CustomManyParticleForce.h"
#include "openmm/Kernel.h"
#include "lepton/CustomFunction.h"
#include "lepton/ExpressionTreeNode.h"
#include "lepton/ParsedExpression.h"
#include <utility>
#include <map>
#include <string>
namespace
OpenMM
{
/**
* This is the internal implementation of CustomManyParticleForce.
*/
class
OPENMM_EXPORT
CustomManyParticleForceImpl
:
public
ForceImpl
{
public:
CustomManyParticleForceImpl
(
const
CustomManyParticleForce
&
owner
);
~
CustomManyParticleForceImpl
();
void
initialize
(
ContextImpl
&
context
);
const
CustomManyParticleForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
std
::
map
<
std
::
string
,
double
>
getDefaultParameters
();
std
::
vector
<
std
::
string
>
getKernelNames
();
void
updateParametersInContext
(
ContextImpl
&
context
);
/**
* This is a utility routine that parses the energy expression, identifies the angles and dihedrals
* in it, and replaces them with variables.
*
* @param force the CustomManyParticleForce to process
* @param functions definitions of custom function that may appear in the expression
* @param distances on exit, this will contain an entry for each distance used in the expression. The key is the name
* of the corresponding variable, and the value is the list of particle indices.
* @param angles on exit, this will contain an entry for each angle used in the expression. The key is the name
* of the corresponding variable, and the value is the list of particle indices.
* @param dihedrals on exit, this will contain an entry for each dihedral used in the expression. The key is the name
* of the corresponding variable, and the value is the list of particle indices.
* @return a Parsed expression for the energy
*/
static
Lepton
::
ParsedExpression
prepareExpression
(
const
CustomManyParticleForce
&
force
,
const
std
::
map
<
std
::
string
,
Lepton
::
CustomFunction
*>&
functions
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
/**
* Analyze the type filters for a force and build a set of arrays that can be used for reordering the
* particles in an interaction.
*
* @param force the CustomManyParticleForce to process
* @param numTypes on exit, the number of unique particle types
* @param particleTypes on exit, this contains a type code for each particle. These codes are <i>not</i> necessarily the
* same as the types assigned by the force. They are guaranteed to be successive integers starting from 0,
* whereas the force may have used arbitrary integers.
* @param orderIndex on exit, this contains a lookup table for selecting the particle order for an interaction.
* orderIndex[t1+numTypes*t2+numTypes*numTypes*t3+...] is the index of the order to use, where t1, t2, etc. are the type codes
* of the particles involved in the interaction. If this equals -1, the interaction should be omitted.
* @param particleOrder on exit, particleOrder[i][j] tells which particle to use as the j'th particle, where i is the value found in orderIndex.
*/
static
void
buildFilterArrays
(
const
CustomManyParticleForce
&
force
,
int
&
numTypes
,
std
::
vector
<
int
>&
particleTypes
,
std
::
vector
<
int
>&
orderIndex
,
std
::
vector
<
std
::
vector
<
int
>
>&
particleOrder
);
private:
class
FunctionPlaceholder
;
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
static
void
generatePermutations
(
std
::
vector
<
int
>&
values
,
int
numFixed
,
std
::
vector
<
std
::
vector
<
int
>
>&
result
);
const
CustomManyParticleForce
&
owner
;
Kernel
kernel
;
};
}
// namespace OpenMM
#endif
/*OPENMM_CUSTOMMANYPARTICLEFORCEIMPL_H_*/
openmmapi/include/openmm/internal/vectorize_neon.h
View file @
604881dc
...
...
@@ -268,6 +268,12 @@ static inline float dot4(const fvec4& v1, const fvec4& v2) {
return
vgetq_lane_f32
(
result
,
0
)
+
vgetq_lane_f32
(
result
,
1
)
+
vgetq_lane_f32
(
result
,
2
)
+
vgetq_lane_f32
(
result
,
3
);
}
static
inline
fvec4
cross
(
const
fvec4
&
v1
,
const
fvec4
&
v2
)
{
return
fvec4
(
v1
[
1
]
*
v2
[
2
]
-
v1
[
2
]
*
v2
[
1
],
v1
[
2
]
*
v2
[
0
]
-
v1
[
0
]
*
v2
[
2
],
v1
[
0
]
*
v2
[
1
]
-
v1
[
1
]
*
v2
[
0
],
0
);
}
static
inline
void
transpose
(
fvec4
&
v1
,
fvec4
&
v2
,
fvec4
&
v3
,
fvec4
&
v4
)
{
float32x4x2_t
t1
=
vuzpq_f32
(
v1
,
v3
);
float32x4x2_t
t2
=
vuzpq_f32
(
v2
,
v4
);
...
...
openmmapi/include/openmm/internal/vectorize_pnacl.h
View file @
604881dc
...
...
@@ -255,6 +255,12 @@ static inline float dot4(const fvec4& v1, const fvec4& v2) {
return
r
[
0
]
+
r
[
1
]
+
r
[
2
]
+
r
[
3
];
}
static
inline
fvec4
cross
(
const
fvec4
&
v1
,
const
fvec4
&
v2
)
{
__m128
temp
=
v2
.
val
*
__builtin_shufflevector
(
v1
.
val
,
v1
.
val
,
2
,
0
,
1
,
3
)
-
v1
.
val
*
__builtin_shufflevector
(
v2
.
val
,
v2
.
val
,
2
,
0
,
1
,
3
);
return
__builtin_shufflevector
(
temp
,
temp
,
2
,
0
,
1
,
3
);
}
static
inline
void
transpose
(
fvec4
&
v1
,
fvec4
&
v2
,
fvec4
&
v3
,
fvec4
&
v4
)
{
__m128
a1
=
__builtin_shufflevector
(
v1
.
val
,
v2
.
val
,
0
,
4
,
2
,
6
);
__m128
a2
=
__builtin_shufflevector
(
v1
.
val
,
v2
.
val
,
1
,
5
,
3
,
7
);
...
...
openmmapi/include/openmm/internal/vectorize_sse.h
View file @
604881dc
...
...
@@ -249,6 +249,12 @@ static inline float dot4(const fvec4& v1, const fvec4& v2) {
return
_mm_cvtss_f32
(
_mm_dp_ps
(
v1
,
v2
,
0xF1
));
}
static
inline
fvec4
cross
(
const
fvec4
&
v1
,
const
fvec4
&
v2
)
{
fvec4
temp
=
fvec4
(
_mm_mul_ps
(
v1
,
_mm_shuffle_ps
(
v2
,
v2
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
))))
-
fvec4
(
_mm_mul_ps
(
v2
,
_mm_shuffle_ps
(
v1
,
v1
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
))));
return
_mm_shuffle_ps
(
temp
,
temp
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
));
}
static
inline
void
transpose
(
fvec4
&
v1
,
fvec4
&
v2
,
fvec4
&
v3
,
fvec4
&
v4
)
{
_MM_TRANSPOSE4_PS
(
v1
,
v2
,
v3
,
v4
);
}
...
...
openmmapi/src/CustomManyParticleForce.cpp
0 → 100644
View file @
604881dc
/* -------------------------------------------------------------------------- *
* 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-2014 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 "openmm/Force.h"
#include "openmm/OpenMMException.h"
#include "openmm/CustomManyParticleForce.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/internal/CustomManyParticleForceImpl.h"
#include <cmath>
#include <map>
#include <set>
#include <sstream>
#include <utility>
using
namespace
OpenMM
;
using
namespace
std
;
CustomManyParticleForce
::
CustomManyParticleForce
(
int
particlesPerSet
,
const
string
&
energy
)
:
particlesPerSet
(
particlesPerSet
),
energyExpression
(
energy
),
nonbondedMethod
(
NoCutoff
),
permutationMode
(
SinglePermutation
),
cutoffDistance
(
1.0
),
typeFilters
(
particlesPerSet
)
{
}
CustomManyParticleForce
::~
CustomManyParticleForce
()
{
for
(
int
i
=
0
;
i
<
(
int
)
functions
.
size
();
i
++
)
delete
functions
[
i
].
function
;
}
const
string
&
CustomManyParticleForce
::
getEnergyFunction
()
const
{
return
energyExpression
;
}
void
CustomManyParticleForce
::
setEnergyFunction
(
const
string
&
energy
)
{
energyExpression
=
energy
;
}
CustomManyParticleForce
::
NonbondedMethod
CustomManyParticleForce
::
getNonbondedMethod
()
const
{
return
nonbondedMethod
;
}
void
CustomManyParticleForce
::
setNonbondedMethod
(
NonbondedMethod
method
)
{
nonbondedMethod
=
method
;
}
CustomManyParticleForce
::
PermutationMode
CustomManyParticleForce
::
getPermutationMode
()
const
{
return
permutationMode
;
}
void
CustomManyParticleForce
::
setPermutationMode
(
PermutationMode
mode
)
{
permutationMode
=
mode
;
}
double
CustomManyParticleForce
::
getCutoffDistance
()
const
{
return
cutoffDistance
;
}
void
CustomManyParticleForce
::
setCutoffDistance
(
double
distance
)
{
cutoffDistance
=
distance
;
}
int
CustomManyParticleForce
::
addPerParticleParameter
(
const
string
&
name
)
{
particleParameters
.
push_back
(
ParticleParameterInfo
(
name
));
return
particleParameters
.
size
()
-
1
;
}
const
string
&
CustomManyParticleForce
::
getPerParticleParameterName
(
int
index
)
const
{
ASSERT_VALID_INDEX
(
index
,
particleParameters
);
return
particleParameters
[
index
].
name
;
}
void
CustomManyParticleForce
::
setPerParticleParameterName
(
int
index
,
const
string
&
name
)
{
ASSERT_VALID_INDEX
(
index
,
particleParameters
);
particleParameters
[
index
].
name
=
name
;
}
int
CustomManyParticleForce
::
addGlobalParameter
(
const
string
&
name
,
double
defaultValue
)
{
globalParameters
.
push_back
(
GlobalParameterInfo
(
name
,
defaultValue
));
return
globalParameters
.
size
()
-
1
;
}
const
string
&
CustomManyParticleForce
::
getGlobalParameterName
(
int
index
)
const
{
ASSERT_VALID_INDEX
(
index
,
globalParameters
);
return
globalParameters
[
index
].
name
;
}
void
CustomManyParticleForce
::
setGlobalParameterName
(
int
index
,
const
string
&
name
)
{
ASSERT_VALID_INDEX
(
index
,
globalParameters
);
globalParameters
[
index
].
name
=
name
;
}
double
CustomManyParticleForce
::
getGlobalParameterDefaultValue
(
int
index
)
const
{
ASSERT_VALID_INDEX
(
index
,
globalParameters
);
return
globalParameters
[
index
].
defaultValue
;
}
void
CustomManyParticleForce
::
setGlobalParameterDefaultValue
(
int
index
,
double
defaultValue
)
{
ASSERT_VALID_INDEX
(
index
,
globalParameters
);
globalParameters
[
index
].
defaultValue
=
defaultValue
;
}
int
CustomManyParticleForce
::
addParticle
(
const
vector
<
double
>&
parameters
,
int
type
)
{
particles
.
push_back
(
ParticleInfo
(
parameters
,
type
));
return
particles
.
size
()
-
1
;
}
void
CustomManyParticleForce
::
getParticleParameters
(
int
index
,
vector
<
double
>&
parameters
,
int
&
type
)
const
{
ASSERT_VALID_INDEX
(
index
,
particles
);
parameters
=
particles
[
index
].
parameters
;
type
=
particles
[
index
].
type
;
}
void
CustomManyParticleForce
::
setParticleParameters
(
int
index
,
const
vector
<
double
>&
parameters
,
int
type
)
{
ASSERT_VALID_INDEX
(
index
,
particles
);
particles
[
index
].
parameters
=
parameters
;
particles
[
index
].
type
=
type
;
}
int
CustomManyParticleForce
::
addExclusion
(
int
particle1
,
int
particle2
)
{
exclusions
.
push_back
(
ExclusionInfo
(
particle1
,
particle2
));
return
exclusions
.
size
()
-
1
;
}
void
CustomManyParticleForce
::
getExclusionParticles
(
int
index
,
int
&
particle1
,
int
&
particle2
)
const
{
ASSERT_VALID_INDEX
(
index
,
exclusions
);
particle1
=
exclusions
[
index
].
particle1
;
particle2
=
exclusions
[
index
].
particle2
;
}
void
CustomManyParticleForce
::
setExclusionParticles
(
int
index
,
int
particle1
,
int
particle2
)
{
ASSERT_VALID_INDEX
(
index
,
exclusions
);
exclusions
[
index
].
particle1
=
particle1
;
exclusions
[
index
].
particle2
=
particle2
;
}
void
CustomManyParticleForce
::
createExclusionsFromBonds
(
const
vector
<
pair
<
int
,
int
>
>&
bonds
,
int
bondCutoff
)
{
if
(
bondCutoff
<
1
)
return
;
vector
<
set
<
int
>
>
exclusions
(
particles
.
size
());
vector
<
set
<
int
>
>
bonded12
(
exclusions
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)
bonds
.
size
();
++
i
)
{
int
p1
=
bonds
[
i
].
first
;
int
p2
=
bonds
[
i
].
second
;
exclusions
[
p1
].
insert
(
p2
);
exclusions
[
p2
].
insert
(
p1
);
bonded12
[
p1
].
insert
(
p2
);
bonded12
[
p2
].
insert
(
p1
);
}
for
(
int
level
=
0
;
level
<
bondCutoff
-
1
;
level
++
)
{
vector
<
set
<
int
>
>
currentExclusions
=
exclusions
;
for
(
int
i
=
0
;
i
<
(
int
)
particles
.
size
();
i
++
)
{
for
(
set
<
int
>::
const_iterator
iter
=
currentExclusions
[
i
].
begin
();
iter
!=
currentExclusions
[
i
].
end
();
++
iter
)
exclusions
[
*
iter
].
insert
(
bonded12
[
i
].
begin
(),
bonded12
[
i
].
end
());
}
}
for
(
int
i
=
0
;
i
<
(
int
)
exclusions
.
size
();
++
i
)
for
(
set
<
int
>::
const_iterator
iter
=
exclusions
[
i
].
begin
();
iter
!=
exclusions
[
i
].
end
();
++
iter
)
if
(
*
iter
<
i
)
addExclusion
(
*
iter
,
i
);
}
void
CustomManyParticleForce
::
getTypeFilter
(
int
index
,
set
<
int
>&
types
)
const
{
if
(
index
<
0
||
index
>=
particlesPerSet
)
throw
OpenMMException
(
"CustomManyParticleForce: index to getTypeFilter out of range"
);
types
=
typeFilters
[
index
];
}
void
CustomManyParticleForce
::
setTypeFilter
(
int
index
,
const
set
<
int
>&
types
)
{
if
(
index
<
0
||
index
>=
particlesPerSet
)
throw
OpenMMException
(
"CustomManyParticleForce: index to setTypeFilter out of range"
);
typeFilters
[
index
]
=
types
;
}
int
CustomManyParticleForce
::
addTabulatedFunction
(
const
string
&
name
,
TabulatedFunction
*
function
)
{
functions
.
push_back
(
FunctionInfo
(
name
,
function
));
return
functions
.
size
()
-
1
;
}
const
TabulatedFunction
&
CustomManyParticleForce
::
getTabulatedFunction
(
int
index
)
const
{
ASSERT_VALID_INDEX
(
index
,
functions
);
return
*
functions
[
index
].
function
;
}
TabulatedFunction
&
CustomManyParticleForce
::
getTabulatedFunction
(
int
index
)
{
ASSERT_VALID_INDEX
(
index
,
functions
);
return
*
functions
[
index
].
function
;
}
const
string
&
CustomManyParticleForce
::
getTabulatedFunctionName
(
int
index
)
const
{
ASSERT_VALID_INDEX
(
index
,
functions
);
return
functions
[
index
].
name
;
}
ForceImpl
*
CustomManyParticleForce
::
createImpl
()
const
{
return
new
CustomManyParticleForceImpl
(
*
this
);
}
void
CustomManyParticleForce
::
updateParametersInContext
(
Context
&
context
)
{
dynamic_cast
<
CustomManyParticleForceImpl
&>
(
getImplInContext
(
context
)).
updateParametersInContext
(
getContextImpl
(
context
));
}
openmmapi/src/CustomManyParticleForceImpl.cpp
0 → 100644
View file @
604881dc
/* -------------------------------------------------------------------------- *
* 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-2014 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 "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/CustomManyParticleForceImpl.h"
#include "openmm/kernels.h"
#include "lepton/Operation.h"
#include "lepton/Parser.h"
#include <sstream>
using
namespace
OpenMM
;
using
Lepton
::
CustomFunction
;
using
Lepton
::
ExpressionTreeNode
;
using
Lepton
::
Operation
;
using
Lepton
::
ParsedExpression
;
using
std
::
map
;
using
std
::
pair
;
using
std
::
vector
;
using
std
::
set
;
using
std
::
string
;
using
std
::
stringstream
;
/**
* This class serves as a placeholder for angles and dihedrals in expressions.
*/
class
CustomManyParticleForceImpl
::
FunctionPlaceholder
:
public
CustomFunction
{
public:
int
numArguments
;
FunctionPlaceholder
(
int
numArguments
)
:
numArguments
(
numArguments
)
{
}
int
getNumArguments
()
const
{
return
numArguments
;
}
double
evaluate
(
const
double
*
arguments
)
const
{
return
0.0
;
}
double
evaluateDerivative
(
const
double
*
arguments
,
const
int
*
derivOrder
)
const
{
return
0.0
;
}
CustomFunction
*
clone
()
const
{
return
new
FunctionPlaceholder
(
numArguments
);
}
};
CustomManyParticleForceImpl
::
CustomManyParticleForceImpl
(
const
CustomManyParticleForce
&
owner
)
:
owner
(
owner
)
{
}
CustomManyParticleForceImpl
::~
CustomManyParticleForceImpl
()
{
}
void
CustomManyParticleForceImpl
::
initialize
(
ContextImpl
&
context
)
{
kernel
=
context
.
getPlatform
().
createKernel
(
CalcCustomManyParticleForceKernel
::
Name
(),
context
);
// Check for errors in the specification of parameters and exclusions.
const
System
&
system
=
context
.
getSystem
();
if
(
owner
.
getNumParticles
()
!=
system
.
getNumParticles
())
throw
OpenMMException
(
"CustomManyParticleForce must have exactly as many particles as the System it belongs to."
);
vector
<
set
<
int
>
>
exclusions
(
owner
.
getNumParticles
());
vector
<
double
>
parameters
;
int
type
;
int
numParameters
=
owner
.
getNumPerParticleParameters
();
for
(
int
i
=
0
;
i
<
owner
.
getNumParticles
();
i
++
)
{
owner
.
getParticleParameters
(
i
,
parameters
,
type
);
if
(
parameters
.
size
()
!=
numParameters
)
{
stringstream
msg
;
msg
<<
"CustomManyParticleForce: Wrong number of parameters for particle "
;
msg
<<
i
;
throw
OpenMMException
(
msg
.
str
());
}
}
for
(
int
i
=
0
;
i
<
owner
.
getNumExclusions
();
i
++
)
{
int
particle1
,
particle2
;
owner
.
getExclusionParticles
(
i
,
particle1
,
particle2
);
if
(
particle1
<
0
||
particle1
>=
owner
.
getNumParticles
())
{
stringstream
msg
;
msg
<<
"CustomManyParticleForce: Illegal particle index for an exclusion: "
;
msg
<<
particle1
;
throw
OpenMMException
(
msg
.
str
());
}
if
(
particle2
<
0
||
particle2
>=
owner
.
getNumParticles
())
{
stringstream
msg
;
msg
<<
"CustomManyParticleForce: Illegal particle index for an exclusion: "
;
msg
<<
particle2
;
throw
OpenMMException
(
msg
.
str
());
}
if
(
exclusions
[
particle1
].
count
(
particle2
)
>
0
||
exclusions
[
particle2
].
count
(
particle1
)
>
0
)
{
stringstream
msg
;
msg
<<
"CustomManyParticleForce: Multiple exclusions are specified for particles "
;
msg
<<
particle1
;
msg
<<
" and "
;
msg
<<
particle2
;
throw
OpenMMException
(
msg
.
str
());
}
exclusions
[
particle1
].
insert
(
particle2
);
exclusions
[
particle2
].
insert
(
particle1
);
}
if
(
owner
.
getNonbondedMethod
()
==
CustomManyParticleForce
::
CutoffPeriodic
)
{
Vec3
boxVectors
[
3
];
system
.
getDefaultPeriodicBoxVectors
(
boxVectors
[
0
],
boxVectors
[
1
],
boxVectors
[
2
]);
double
cutoff
=
owner
.
getCutoffDistance
();
if
(
cutoff
>
0.5
*
boxVectors
[
0
][
0
]
||
cutoff
>
0.5
*
boxVectors
[
1
][
1
]
||
cutoff
>
0.5
*
boxVectors
[
2
][
2
])
throw
OpenMMException
(
"CustomManyParticleForce: The cutoff distance cannot be greater than half the periodic box size."
);
}
kernel
.
getAs
<
CalcCustomManyParticleForceKernel
>
().
initialize
(
context
.
getSystem
(),
owner
);
}
double
CustomManyParticleForceImpl
::
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
)
{
if
((
groups
&
(
1
<<
owner
.
getForceGroup
()))
!=
0
)
return
kernel
.
getAs
<
CalcCustomManyParticleForceKernel
>
().
execute
(
context
,
includeForces
,
includeEnergy
);
return
0.0
;
}
vector
<
string
>
CustomManyParticleForceImpl
::
getKernelNames
()
{
vector
<
string
>
names
;
names
.
push_back
(
CalcCustomManyParticleForceKernel
::
Name
());
return
names
;
}
map
<
string
,
double
>
CustomManyParticleForceImpl
::
getDefaultParameters
()
{
map
<
string
,
double
>
parameters
;
for
(
int
i
=
0
;
i
<
owner
.
getNumGlobalParameters
();
i
++
)
parameters
[
owner
.
getGlobalParameterName
(
i
)]
=
owner
.
getGlobalParameterDefaultValue
(
i
);
return
parameters
;
}
ParsedExpression
CustomManyParticleForceImpl
::
prepareExpression
(
const
CustomManyParticleForce
&
force
,
const
map
<
string
,
CustomFunction
*>&
customFunctions
,
map
<
string
,
vector
<
int
>
>&
distances
,
map
<
string
,
vector
<
int
>
>&
angles
,
map
<
string
,
vector
<
int
>
>&
dihedrals
)
{
CustomManyParticleForceImpl
::
FunctionPlaceholder
custom
(
1
);
CustomManyParticleForceImpl
::
FunctionPlaceholder
distance
(
2
);
CustomManyParticleForceImpl
::
FunctionPlaceholder
angle
(
3
);
CustomManyParticleForceImpl
::
FunctionPlaceholder
dihedral
(
4
);
map
<
string
,
CustomFunction
*>
functions
=
customFunctions
;
functions
[
"distance"
]
=
&
distance
;
functions
[
"angle"
]
=
&
angle
;
functions
[
"dihedral"
]
=
&
dihedral
;
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
map
<
string
,
int
>
atoms
;
for
(
int
i
=
0
;
i
<
force
.
getNumParticlesPerSet
();
i
++
)
{
stringstream
name
;
name
<<
'p'
<<
(
i
+
1
);
atoms
[
name
.
str
()]
=
i
;
}
return
ParsedExpression
(
replaceFunctions
(
expression
.
getRootNode
(),
atoms
,
distances
,
angles
,
dihedrals
)).
optimize
();
}
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
)
{
const
Operation
&
op
=
node
.
getOperation
();
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.
vector
<
ExpressionTreeNode
>
children
;
for
(
int
i
=
0
;
i
<
(
int
)
node
.
getChildren
().
size
();
i
++
)
children
.
push_back
(
replaceFunctions
(
node
.
getChildren
()[
i
],
atoms
,
distances
,
angles
,
dihedrals
));
return
ExpressionTreeNode
(
op
.
clone
(),
children
);
}
const
Operation
::
Custom
&
custom
=
static_cast
<
const
Operation
::
Custom
&>
(
op
);
// Identify the atoms this term is based on.
int
numArgs
=
custom
.
getNumArguments
();
vector
<
int
>
indices
(
numArgs
);
for
(
int
i
=
0
;
i
<
numArgs
;
i
++
)
{
map
<
string
,
int
>::
const_iterator
iter
=
atoms
.
find
(
node
.
getChildren
()[
i
].
getOperation
().
getName
());
if
(
iter
==
atoms
.
end
())
throw
OpenMMException
(
"CustomManyParticleForce: Unknown particle '"
+
node
.
getChildren
()[
i
].
getOperation
().
getName
()
+
"'"
);
indices
[
i
]
=
iter
->
second
;
}
// Select a name for the variable and add it to the appropriate map.
stringstream
variable
;
if
(
numArgs
==
2
)
variable
<<
"distance"
;
else
if
(
numArgs
==
3
)
variable
<<
"angle"
;
else
variable
<<
"dihedral"
;
for
(
int
i
=
0
;
i
<
numArgs
;
i
++
)
variable
<<
indices
[
i
];
string
name
=
variable
.
str
();
if
(
numArgs
==
2
)
distances
[
name
]
=
indices
;
else
if
(
numArgs
==
3
)
angles
[
name
]
=
indices
;
else
dihedrals
[
name
]
=
indices
;
// Return a new node that represents it as a simple variable.
return
ExpressionTreeNode
(
new
Operation
::
Variable
(
name
));
}
void
CustomManyParticleForceImpl
::
updateParametersInContext
(
ContextImpl
&
context
)
{
kernel
.
getAs
<
CalcCustomManyParticleForceKernel
>
().
copyParametersToContext
(
context
,
owner
);
}
void
CustomManyParticleForceImpl
::
buildFilterArrays
(
const
CustomManyParticleForce
&
force
,
int
&
numTypes
,
vector
<
int
>&
particleTypes
,
vector
<
int
>&
orderIndex
,
vector
<
vector
<
int
>
>&
particleOrder
)
{
// Build a canonical list of type codes.
int
numParticles
=
force
.
getNumParticles
();
int
numParticlesPerSet
=
force
.
getNumParticlesPerSet
();
particleTypes
.
resize
(
numParticles
);
map
<
int
,
int
>
typeMap
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
vector
<
double
>
params
;
int
type
;
force
.
getParticleParameters
(
i
,
params
,
type
);
map
<
int
,
int
>::
const_iterator
element
=
typeMap
.
find
(
type
);
if
(
element
==
typeMap
.
end
())
{
int
newType
=
typeMap
.
size
();
typeMap
[
type
]
=
newType
;
particleTypes
[
i
]
=
newType
;
}
else
particleTypes
[
i
]
=
element
->
second
;
}
numTypes
=
typeMap
.
size
();
int
numIndices
=
1
;
for
(
int
i
=
0
;
i
<
numParticlesPerSet
;
i
++
)
numIndices
*=
numTypes
;
orderIndex
.
resize
(
numIndices
,
0
);
// Find the allowed type codes for each particle in an interaction.
vector
<
set
<
int
>
>
allowedTypes
(
numParticlesPerSet
);
bool
anyFilters
=
false
;
for
(
int
i
=
0
;
i
<
numParticlesPerSet
;
i
++
)
{
set
<
int
>
types
;
force
.
getTypeFilter
(
i
,
types
);
if
(
types
.
size
()
==
0
)
for
(
int
j
=
0
;
j
<
numTypes
;
j
++
)
allowedTypes
[
i
].
insert
(
j
);
else
{
for
(
set
<
int
>::
const_iterator
iter
=
types
.
begin
();
iter
!=
types
.
end
();
++
iter
)
if
(
typeMap
.
find
(
*
iter
)
!=
typeMap
.
end
())
allowedTypes
[
i
].
insert
(
typeMap
[
*
iter
]);
if
(
allowedTypes
[
i
].
size
()
<
numTypes
)
anyFilters
=
true
;
}
}
// If there are no filters, reordering is unnecessary.
if
(
!
anyFilters
)
{
particleOrder
.
resize
(
1
);
particleOrder
[
0
].
resize
(
numParticlesPerSet
);
for
(
int
i
=
0
;
i
<
numParticlesPerSet
;
i
++
)
particleOrder
[
0
][
i
]
=
i
;
return
;
}
// Build a list of every possible permutation of the particles.
particleOrder
.
clear
();
vector
<
int
>
values
;
for
(
int
i
=
0
;
i
<
numParticlesPerSet
;
i
++
)
values
.
push_back
(
i
);
generatePermutations
(
values
,
force
.
getPermutationMode
()
==
CustomManyParticleForce
::
SinglePermutation
?
0
:
1
,
particleOrder
);
int
numOrders
=
particleOrder
.
size
();
// Now we need to loop over every possible sequence of type codes, and for each one figure out which order to use.
for
(
int
i
=
0
;
i
<
numIndices
;
i
++
)
{
vector
<
int
>
types
(
numParticlesPerSet
);
int
temp
=
i
;
for
(
int
j
=
0
;
j
<
numParticlesPerSet
;
j
++
)
{
types
[
j
]
=
temp
%
numTypes
;
temp
/=
numTypes
;
}
// Loop over possible orders until we find one that matches the filters.
int
order
=
-
1
;
for
(
int
j
=
0
;
j
<
numOrders
&&
order
==
-
1
;
j
++
)
{
bool
matches
=
true
;
for
(
int
k
=
0
;
k
<
numParticlesPerSet
&&
matches
;
k
++
)
if
(
allowedTypes
[
k
].
find
(
types
[
particleOrder
[
j
][
k
]])
==
allowedTypes
[
k
].
end
())
matches
=
false
;
if
(
matches
)
order
=
j
;
}
orderIndex
[
i
]
=
order
;
}
}
void
CustomManyParticleForceImpl
::
generatePermutations
(
vector
<
int
>&
values
,
int
numFixed
,
vector
<
vector
<
int
>
>&
result
)
{
int
numValues
=
values
.
size
();
if
(
numFixed
==
numValues
)
{
result
.
push_back
(
values
);
return
;
}
for
(
int
i
=
numFixed
;
i
<
numValues
;
i
++
)
{
int
v1
=
values
[
numFixed
];
int
v2
=
values
[
i
];
values
[
numFixed
]
=
v2
;
values
[
i
]
=
v1
;
generatePermutations
(
values
,
numFixed
+
1
,
result
);
values
[
numFixed
]
=
v1
;
values
[
i
]
=
v2
;
}
}
\ No newline at end of file
platforms/cpu/include/CompiledExpressionSet.h
0 → 100644
View file @
604881dc
#ifndef OPENMM_COMPILEDEXPRESSIONSET_H_
#define OPENMM_COMPILEDEXPRESSIONSET_H_
/* -------------------------------------------------------------------------- *
* 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) 2014 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 "lepton/CompiledExpression.h"
#include "windowsExportCpu.h"
#include <string>
#include <vector>
namespace
OpenMM
{
/**
* This class simplifies the management of a set of related CompiledExpressions that share variables.
*/
class
OPENMM_EXPORT_CPU
CompiledExpressionSet
{
public:
CompiledExpressionSet
();
/**
* Add a CompiledExpression to the set.
*/
void
registerExpression
(
Lepton
::
CompiledExpression
&
expression
);
/**
* Get the index of a particular variable.
*/
int
getVariableIndex
(
const
std
::
string
&
name
);
/**
* Set the value of a variable on every CompiledExpression.
*
* @param index the index of the variable, as returned by getVariableIndex()
* @param value the value to set it to
*/
void
setVariable
(
int
index
,
double
value
);
private:
std
::
vector
<
Lepton
::
CompiledExpression
*>
expressions
;
std
::
vector
<
std
::
string
>
variables
;
std
::
vector
<
std
::
vector
<
double
*>
>
variableReferences
;
};
}
// namespace OpenMM
#endif
/*OPENMM_COMPILEDEXPRESSIONSET_H_*/
platforms/cpu/include/CpuCustomManyParticleForce.h
0 → 100644
View file @
604881dc
/* Portions copyright (c) 2009-2014 Stanford University and Simbios.
* Contributors: Peter Eastman
*
* 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.
*/
#ifndef OPENMM_CPU_CUSTOM_MANY_PARTICLE_FORCE_H__
#define OPENMM_CPU_CUSTOM_MANY_PARTICLE_FORCE_H__
#include "ReferenceForce.h"
#include "ReferenceBondIxn.h"
#include "CompiledExpressionSet.h"
#include "CpuNeighborList.h"
#include "openmm/CustomManyParticleForce.h"
#include "openmm/internal/ThreadPool.h"
#include "openmm/internal/vectorize.h"
#include "lepton/CompiledExpression.h"
#include "lepton/ParsedExpression.h"
#include <map>
#include <set>
#include <utility>
#include <vector>
namespace
OpenMM
{
class
CpuCustomManyParticleForce
{
private:
class
ParticleTermInfo
;
class
DistanceTermInfo
;
class
AngleTermInfo
;
class
DihedralTermInfo
;
class
ComputeForceTask
;
class
ThreadData
;
int
numParticles
,
numParticlesPerSet
,
numPerParticleParameters
,
numTypes
;
bool
useCutoff
,
usePeriodic
,
centralParticleMode
;
RealOpenMM
cutoffDistance
;
RealOpenMM
periodicBoxSize
[
3
];
CpuNeighborList
*
neighborList
;
ThreadPool
&
threads
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
int
>
particleTypes
;
std
::
vector
<
int
>
orderIndex
;
std
::
vector
<
std
::
vector
<
int
>
>
particleOrder
;
std
::
vector
<
std
::
vector
<
int
>
>
particleNeighbors
;
std
::
vector
<
ThreadData
*>
threadData
;
// The following variables are used to make information accessible to the individual threads.
float
*
posq
;
RealOpenMM
**
particleParameters
;
const
std
::
map
<
std
::
string
,
double
>*
globalParameters
;
std
::
vector
<
AlignedArray
<
float
>
>*
threadForce
;
bool
includeForces
,
includeEnergy
;
void
*
atomicCounter
;
/**
* This routine contains the code executed by each thread.
*/
void
threadComputeForce
(
ThreadPool
&
threads
,
int
threadIndex
);
/**
* This is called recursively to loop over all possible combination of a set of particles and evaluate the
* interaction for each one.
*/
void
loopOverInteractions
(
std
::
vector
<
int
>&
availableParticles
,
std
::
vector
<
int
>&
particleSet
,
int
loopIndex
,
int
startIndex
,
RealOpenMM
**
particleParameters
,
float
*
forces
,
ThreadData
&
data
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**---------------------------------------------------------------------------------------
Calculate custom interaction for one set of particles
@param particleSet the indices of the particles
@param posq atom coordinates in float format
@param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
@param forces force array (forces added)
@param totalEnergy total energy
--------------------------------------------------------------------------------------- */
/**
* Calculate the interaction for one set of particles
*
* @param particleSet the indices of the particles
* @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
* @param data information and workspace for the current thread
* @param boxSize the size of the periodic box
* @param invBoxSize the inverse size of the periodic box
*/
void
calculateOneIxn
(
std
::
vector
<
int
>&
particleSet
,
RealOpenMM
**
particleParameters
,
float
*
forces
,
ThreadData
&
data
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
* Compute the displacement and squared distance between two points, optionally using
* periodic boundary conditions.
*/
void
computeDelta
(
const
fvec4
&
posI
,
const
fvec4
&
posJ
,
fvec4
&
deltaR
,
float
&
r2
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
const
;
static
float
computeAngle
(
const
fvec4
&
vi
,
const
fvec4
&
vj
,
float
v2i
,
float
v2j
,
float
sign
);
static
float
getDihedralAngleBetweenThreeVectors
(
const
fvec4
&
v1
,
const
fvec4
&
v2
,
const
fvec4
&
v3
,
fvec4
&
cross1
,
fvec4
&
cross2
,
const
fvec4
&
signVector
);
public:
/**
* Create a new CpuCustomManyParticleForce.
*
* @param force the CustomManyParticleForce to create it for
* @param threads the thread pool to use
*/
CpuCustomManyParticleForce
(
const
OpenMM
::
CustomManyParticleForce
&
force
,
ThreadPool
&
threads
);
~
CpuCustomManyParticleForce
();
/**
* Set the force to use a cutoff.
*
* @param distance the cutoff distance
*/
void
setUseCutoff
(
RealOpenMM
distance
);
/**
* Set the force to use periodic boundary conditions. This requires that a cutoff has
* already been set, and the smallest side of the periodic box is at least twice the cutoff
* distance.
*
* @param boxSize the X, Y, and Z widths of the periodic box
*/
void
setPeriodic
(
OpenMM
::
RealVec
&
boxSize
);
/**
* Calculate the interaction.
*
* @param posq atom coordinates in float format
* @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
* @param globalParameters the values of global parameters
* @param threadForce the collection of arrays for each thread to add forces to
* @param includeForce whether to compute forces
* @param includeEnergy whether to compute energy
* @param energy the total energy is added to this
*/
void
calculateIxn
(
AlignedArray
<
float
>&
posq
,
RealOpenMM
**
particleParameters
,
const
std
::
map
<
std
::
string
,
double
>&
globalParameters
,
std
::
vector
<
AlignedArray
<
float
>
>&
threadForce
,
bool
includeForces
,
bool
includeEnergy
,
double
&
energy
);
};
class
CpuCustomManyParticleForce
::
ParticleTermInfo
{
public:
std
::
string
name
;
int
atom
,
component
,
variableIndex
;
Lepton
::
CompiledExpression
forceExpression
;
ParticleTermInfo
(
const
std
::
string
&
name
,
int
atom
,
int
component
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
);
};
class
CpuCustomManyParticleForce
::
DistanceTermInfo
{
public:
std
::
string
name
;
int
p1
,
p2
,
variableIndex
;
Lepton
::
CompiledExpression
forceExpression
;
int
delta
;
float
deltaSign
;
DistanceTermInfo
(
const
std
::
string
&
name
,
const
std
::
vector
<
int
>&
atoms
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
);
};
class
CpuCustomManyParticleForce
::
AngleTermInfo
{
public:
std
::
string
name
;
int
p1
,
p2
,
p3
,
variableIndex
;
Lepton
::
CompiledExpression
forceExpression
;
int
delta1
,
delta2
;
float
delta1Sign
,
delta2Sign
;
AngleTermInfo
(
const
std
::
string
&
name
,
const
std
::
vector
<
int
>&
atoms
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
);
};
class
CpuCustomManyParticleForce
::
DihedralTermInfo
{
public:
std
::
string
name
;
int
p1
,
p2
,
p3
,
p4
,
variableIndex
;
Lepton
::
CompiledExpression
forceExpression
;
int
delta1
,
delta2
,
delta3
;
DihedralTermInfo
(
const
std
::
string
&
name
,
const
std
::
vector
<
int
>&
atoms
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
);
};
class
CpuCustomManyParticleForce
::
ThreadData
{
public:
CompiledExpressionSet
expressionSet
;
Lepton
::
CompiledExpression
energyExpression
;
std
::
vector
<
std
::
vector
<
int
>
>
particleParamIndices
;
std
::
vector
<
int
>
permutedParticles
;
std
::
vector
<
std
::
pair
<
int
,
int
>
>
deltaPairs
;
std
::
vector
<
ParticleTermInfo
>
particleTerms
;
std
::
vector
<
DistanceTermInfo
>
distanceTerms
;
std
::
vector
<
AngleTermInfo
>
angleTerms
;
std
::
vector
<
DihedralTermInfo
>
dihedralTerms
;
AlignedArray
<
fvec4
>
delta
,
cross1
,
cross2
;
std
::
vector
<
float
>
normDelta
;
std
::
vector
<
float
>
norm2Delta
;
AlignedArray
<
fvec4
>
f
;
double
energy
;
ThreadData
(
const
CustomManyParticleForce
&
force
,
Lepton
::
ParsedExpression
&
energyExpr
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
/**
* Request a pair of particles whose distance or displacement vector is needed in the computation.
*/
void
requestDeltaPair
(
int
p1
,
int
p2
,
int
&
pairIndex
,
float
&
pairSign
,
bool
allowReversed
);
};
}
// namespace OpenMM
#endif // OPENMM_CPU_CUSTOM_MANY_PARTICLE_FORCE_H__
platforms/cpu/include/CpuKernels.h
View file @
604881dc
...
...
@@ -33,6 +33,7 @@
* -------------------------------------------------------------------------- */
#include "CpuBondForce.h"
#include "CpuCustomManyParticleForce.h"
#include "CpuCustomNonbondedForce.h"
#include "CpuGBSAOBCForce.h"
#include "CpuLangevinDynamics.h"
...
...
@@ -302,6 +303,48 @@ private:
CpuGBSAOBCForce
obc
;
};
/**
* This kernel is invoked by CustomManyParticleForce to calculate the forces acting on the system and the energy of the system.
*/
class
CpuCalcCustomManyParticleForceKernel
:
public
CalcCustomManyParticleForceKernel
{
public:
CpuCalcCustomManyParticleForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
CpuPlatform
::
PlatformData
&
data
)
:
CalcCustomManyParticleForceKernel
(
name
,
platform
),
data
(
data
),
ixn
(
NULL
)
{
}
~
CpuCalcCustomManyParticleForceKernel
();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the CustomManyParticleForce this kernel will be used for
*/
void
initialize
(
const
System
&
system
,
const
CustomManyParticleForce
&
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 CustomManyParticleForce to copy the parameters from
*/
void
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomManyParticleForce
&
force
);
private:
CpuPlatform
::
PlatformData
&
data
;
int
numParticles
;
RealOpenMM
cutoffDistance
;
RealOpenMM
**
particleParamArray
;
CpuCustomManyParticleForce
*
ixn
;
std
::
vector
<
std
::
string
>
globalParameterNames
;
NonbondedMethod
nonbondedMethod
;
};
/**
* This kernel is invoked by LangevinIntegrator to take one time step.
*/
...
...
platforms/cpu/src/CompiledExpressionSet.cpp
0 → 100644
View file @
604881dc
/* Portions copyright (c) 2014 Stanford University and Simbios.
* Contributors: Peter Eastman
*
* 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 "CompiledExpressionSet.h"
using
namespace
OpenMM
;
using
namespace
Lepton
;
using
namespace
std
;
CompiledExpressionSet
::
CompiledExpressionSet
()
{
}
void
CompiledExpressionSet
::
registerExpression
(
Lepton
::
CompiledExpression
&
expression
)
{
expressions
.
push_back
(
&
expression
);
for
(
int
i
=
0
;
i
<
(
int
)
variables
.
size
();
i
++
)
if
(
expression
.
getVariables
().
find
(
variables
[
i
])
!=
expression
.
getVariables
().
end
())
variableReferences
[
i
].
push_back
(
&
expression
.
getVariableReference
(
variables
[
i
]));
}
int
CompiledExpressionSet
::
getVariableIndex
(
const
std
::
string
&
name
)
{
for
(
int
i
=
0
;
i
<
(
int
)
variables
.
size
();
i
++
)
if
(
variables
[
i
]
==
name
)
return
i
;
int
index
=
variables
.
size
();
variables
.
push_back
(
name
);
variableReferences
.
push_back
(
vector
<
double
*>
());
for
(
int
i
=
0
;
i
<
(
int
)
expressions
.
size
();
i
++
)
if
(
expressions
[
i
]
->
getVariables
().
find
(
name
)
!=
expressions
[
i
]
->
getVariables
().
end
())
variableReferences
[
index
].
push_back
(
&
expressions
[
i
]
->
getVariableReference
(
name
));
return
index
;
}
void
CompiledExpressionSet
::
setVariable
(
int
index
,
double
value
)
{
for
(
int
i
=
0
;
i
<
(
int
)
variableReferences
[
index
].
size
();
i
++
)
*
variableReferences
[
index
][
i
]
=
value
;
}
platforms/cpu/src/CpuCustomManyParticleForce.cpp
0 → 100644
View file @
604881dc
This diff is collapsed.
Click to expand it.
platforms/cpu/src/CpuKernelFactory.cpp
View file @
604881dc
...
...
@@ -49,6 +49,8 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform&
return
new
CpuCalcNonbondedForceKernel
(
name
,
platform
,
data
);
if
(
name
==
CalcCustomNonbondedForceKernel
::
Name
())
return
new
CpuCalcCustomNonbondedForceKernel
(
name
,
platform
,
data
);
if
(
name
==
CalcCustomManyParticleForceKernel
::
Name
())
return
new
CpuCalcCustomManyParticleForceKernel
(
name
,
platform
,
data
);
if
(
name
==
CalcGBSAOBCForceKernel
::
Name
())
return
new
CpuCalcGBSAOBCForceKernel
(
name
,
platform
,
data
);
if
(
name
==
IntegrateLangevinStepKernel
::
Name
())
...
...
platforms/cpu/src/CpuKernels.cpp
View file @
604881dc
...
...
@@ -835,6 +835,72 @@ void CpuCalcGBSAOBCForceKernel::copyParametersToContext(ContextImpl& context, co
obc
.
setParticleParameters
(
particleParams
);
}
CpuCalcCustomManyParticleForceKernel
::~
CpuCalcCustomManyParticleForceKernel
()
{
if
(
particleParamArray
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
delete
[]
particleParamArray
[
i
];
delete
[]
particleParamArray
;
}
if
(
ixn
!=
NULL
)
delete
ixn
;
}
void
CpuCalcCustomManyParticleForceKernel
::
initialize
(
const
System
&
system
,
const
CustomManyParticleForce
&
force
)
{
// Build the arrays.
numParticles
=
system
.
getNumParticles
();
int
numParticleParameters
=
force
.
getNumPerParticleParameters
();
particleParamArray
=
new
double
*
[
numParticles
];
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
particleParamArray
[
i
]
=
new
double
[
numParticleParameters
];
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
vector
<
double
>
parameters
;
int
type
;
force
.
getParticleParameters
(
i
,
parameters
,
type
);
for
(
int
j
=
0
;
j
<
numParticleParameters
;
j
++
)
particleParamArray
[
i
][
j
]
=
parameters
[
j
];
}
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
globalParameterNames
.
push_back
(
force
.
getGlobalParameterName
(
i
));
ixn
=
new
CpuCustomManyParticleForce
(
force
,
data
.
threads
);
nonbondedMethod
=
CalcCustomManyParticleForceKernel
::
NonbondedMethod
(
force
.
getNonbondedMethod
());
cutoffDistance
=
force
.
getCutoffDistance
();
}
double
CpuCalcCustomManyParticleForceKernel
::
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
{
map
<
string
,
double
>
globalParameters
;
for
(
int
i
=
0
;
i
<
(
int
)
globalParameterNames
.
size
();
i
++
)
globalParameters
[
globalParameterNames
[
i
]]
=
context
.
getParameter
(
globalParameterNames
[
i
]);
if
(
nonbondedMethod
==
CutoffPeriodic
)
{
RealVec
&
box
=
extractBoxSize
(
context
);
double
minAllowedSize
=
2
*
cutoffDistance
;
if
(
box
[
0
]
<
minAllowedSize
||
box
[
1
]
<
minAllowedSize
||
box
[
2
]
<
minAllowedSize
)
throw
OpenMMException
(
"The periodic box size has decreased to less than twice the nonbonded cutoff."
);
ixn
->
setPeriodic
(
box
);
}
double
energy
=
0
;
ixn
->
calculateIxn
(
data
.
posq
,
particleParamArray
,
globalParameters
,
data
.
threadForce
,
includeForces
,
includeEnergy
,
energy
);
return
energy
;
}
void
CpuCalcCustomManyParticleForceKernel
::
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomManyParticleForce
&
force
)
{
if
(
numParticles
!=
force
.
getNumParticles
())
throw
OpenMMException
(
"updateParametersInContext: The number of particles has changed"
);
// Record the values.
int
numParameters
=
force
.
getNumPerParticleParameters
();
vector
<
double
>
params
;
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
vector
<
double
>
parameters
;
int
type
;
force
.
getParticleParameters
(
i
,
parameters
,
type
);
for
(
int
j
=
0
;
j
<
numParameters
;
j
++
)
particleParamArray
[
i
][
j
]
=
static_cast
<
RealOpenMM
>
(
parameters
[
j
]);
}
}
CpuIntegrateLangevinStepKernel
::~
CpuIntegrateLangevinStepKernel
()
{
if
(
dynamics
)
delete
dynamics
;
...
...
platforms/cpu/src/CpuPlatform.cpp
View file @
604881dc
...
...
@@ -65,6 +65,7 @@ CpuPlatform::CpuPlatform() {
registerKernelFactory
(
CalcRBTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcNonbondedForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcCustomNonbondedForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcCustomManyParticleForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcGBSAOBCForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateLangevinStepKernel
::
Name
(),
factory
);
platformProperties
.
push_back
(
CpuThreads
());
...
...
platforms/cpu/src/CpuSETTLE.cpp
View file @
604881dc
...
...
@@ -59,8 +59,10 @@ public:
inverseMasses
(
inverseMasses
),
tolerance
(
tolerance
),
threadSettle
(
threadSettle
)
{
}
void
execute
(
ThreadPool
&
threads
,
int
threadIndex
)
{
if
(
threadIndex
<
threadSettle
.
size
())
{
threadSettle
[
threadIndex
]
->
applyToVelocities
(
atomCoordinates
,
velocities
,
inverseMasses
,
tolerance
);
}
}
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
;
vector
<
OpenMM
::
RealVec
>&
velocities
;
vector
<
RealOpenMM
>&
inverseMasses
;
...
...
Prev
1
2
3
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