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
18295108
Commit
18295108
authored
Sep 05, 2017
by
peastman
Browse files
Merge changes from main branch
parents
e6101f68
8d7234e5
Changes
154
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
412 additions
and
94 deletions
+412
-94
platforms/reference/src/SimTKReference/ReferenceCustomCVForce.cpp
...s/reference/src/SimTKReference/ReferenceCustomCVForce.cpp
+107
-0
platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp
.../reference/src/SimTKReference/ReferenceCustomDynamics.cpp
+33
-8
platforms/reference/src/SimTKReference/ReferenceVirtualSites.cpp
...ms/reference/src/SimTKReference/ReferenceVirtualSites.cpp
+55
-65
platforms/reference/tests/TestReferenceCustomCVForce.cpp
platforms/reference/tests/TestReferenceCustomCVForce.cpp
+36
-0
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaAngleForceImpl.h
.../openmmapi/include/openmm/internal/AmoebaAngleForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaBondForceImpl.h
...a/openmmapi/include/openmm/internal/AmoebaBondForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaGeneralizedKirkwoodForceImpl.h
...lude/openmm/internal/AmoebaGeneralizedKirkwoodForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaInPlaneAngleForceImpl.h
...api/include/openmm/internal/AmoebaInPlaneAngleForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h
...nmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaOutOfPlaneBendForceImpl.h
...i/include/openmm/internal/AmoebaOutOfPlaneBendForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaPiTorsionForceImpl.h
...nmmapi/include/openmm/internal/AmoebaPiTorsionForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaStretchBendForceImpl.h
...mapi/include/openmm/internal/AmoebaStretchBendForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h
...i/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaVdwForceImpl.h
...ba/openmmapi/include/openmm/internal/AmoebaVdwForceImpl.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h
...pi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h
+1
-1
plugins/cpupme/src/CpuPmeKernels.cpp
plugins/cpupme/src/CpuPmeKernels.cpp
+13
-6
plugins/cpupme/src/CpuPmeKernels.h
plugins/cpupme/src/CpuPmeKernels.h
+6
-2
plugins/cpupme/tests/TestCpuPme.cpp
plugins/cpupme/tests/TestCpuPme.cpp
+2
-2
serialization/include/openmm/serialization/CustomCVForceProxy.h
...ization/include/openmm/serialization/CustomCVForceProxy.h
+53
-0
serialization/src/CustomCVForceProxy.cpp
serialization/src/CustomCVForceProxy.cpp
+96
-0
No files found.
platforms/reference/src/SimTKReference/ReferenceCustomCVForce.cpp
0 → 100644
View file @
18295108
/* Portions copyright (c) 2009-2017 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 "ReferenceCustomCVForce.h"
#include "ReferencePlatform.h"
#include "ReferenceTabulatedFunction.h"
#include "lepton/CustomFunction.h"
#include "lepton/ParsedExpression.h"
#include "lepton/Parser.h"
using
namespace
OpenMM
;
using
namespace
std
;
ReferenceCustomCVForce
::
ReferenceCustomCVForce
(
const
CustomCVForce
&
force
)
{
// Create custom functions for the tabulated functions.
map
<
string
,
Lepton
::
CustomFunction
*>
functions
;
for
(
int
i
=
0
;
i
<
(
int
)
force
.
getNumTabulatedFunctions
();
i
++
)
functions
[
force
.
getTabulatedFunctionName
(
i
)]
=
createReferenceTabulatedFunction
(
force
.
getTabulatedFunction
(
i
));
// Create the expressions.
Lepton
::
ParsedExpression
energyExpr
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
);
energyExpression
=
energyExpr
.
createProgram
();
for
(
int
i
=
0
;
i
<
force
.
getNumCollectiveVariables
();
i
++
)
{
string
name
=
force
.
getCollectiveVariableName
(
i
);
variableNames
.
push_back
(
name
);
variableDerivExpressions
.
push_back
(
energyExpr
.
differentiate
(
name
).
optimize
().
createProgram
());
}
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
string
name
=
force
.
getEnergyParameterDerivativeName
(
i
);
paramDerivNames
.
push_back
(
name
);
paramDerivExpressions
.
push_back
(
energyExpr
.
differentiate
(
name
).
optimize
().
createProgram
());
}
// Delete the custom functions.
for
(
auto
&
function
:
functions
)
delete
function
.
second
;
}
ReferenceCustomCVForce
::~
ReferenceCustomCVForce
()
{
}
void
ReferenceCustomCVForce
::
calculateIxn
(
ContextImpl
&
innerContext
,
vector
<
Vec3
>&
atomCoordinates
,
const
map
<
string
,
double
>&
globalParameters
,
vector
<
Vec3
>&
forces
,
double
*
totalEnergy
,
map
<
string
,
double
>&
energyParamDerivs
)
const
{
// Compute the collective variables, and their derivatives with respect to particle positions.
int
numCVs
=
variableNames
.
size
();
ReferencePlatform
::
PlatformData
*
data
=
reinterpret_cast
<
ReferencePlatform
::
PlatformData
*>
(
innerContext
.
getPlatformData
());
vector
<
Vec3
>&
innerForces
=
*
((
vector
<
Vec3
>*
)
data
->
forces
);
map
<
string
,
double
>&
innerDerivs
=
*
((
map
<
string
,
double
>*
)
data
->
energyParameterDerivatives
);
vector
<
double
>
cvValues
;
vector
<
vector
<
Vec3
>
>
cvForces
;
vector
<
map
<
string
,
double
>
>
cvDerivs
;
for
(
int
i
=
0
;
i
<
numCVs
;
i
++
)
{
cvValues
.
push_back
(
innerContext
.
calcForcesAndEnergy
(
true
,
true
,
1
<<
i
));
cvForces
.
push_back
(
innerForces
);
cvDerivs
.
push_back
(
innerDerivs
);
}
// Compute the energy and forces.
int
numParticles
=
atomCoordinates
.
size
();
map
<
string
,
double
>
variables
=
globalParameters
;
for
(
int
i
=
0
;
i
<
numCVs
;
i
++
)
variables
[
variableNames
[
i
]]
=
cvValues
[
i
];
if
(
totalEnergy
!=
NULL
)
*
totalEnergy
+=
energyExpression
.
evaluate
(
variables
);
for
(
int
i
=
0
;
i
<
numCVs
;
i
++
)
{
double
dEdV
=
variableDerivExpressions
[
i
].
evaluate
(
variables
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
forces
[
j
]
+=
cvForces
[
i
][
j
]
*
dEdV
;
}
// Compute the energy parameter derivatives.
for
(
int
i
=
0
;
i
<
paramDerivExpressions
.
size
();
i
++
)
energyParamDerivs
[
paramDerivNames
[
i
]]
+=
paramDerivExpressions
[
i
].
evaluate
(
variables
);
for
(
int
i
=
0
;
i
<
numCVs
;
i
++
)
{
double
dEdV
=
variableDerivExpressions
[
i
].
evaluate
(
variables
);
for
(
auto
&
deriv
:
cvDerivs
[
i
])
energyParamDerivs
[
deriv
.
first
]
+=
dEdV
*
deriv
.
second
;
}
}
platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp
View file @
18295108
/* Portions copyright (c) 2011-201
6
Stanford University and Simbios.
/* Portions copyright (c) 2011-201
7
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -25,6 +25,7 @@
#include "SimTKOpenMMUtilities.h"
#include "ReferenceVirtualSites.h"
#include "ReferenceCustomDynamics.h"
#include "ReferenceTabulatedFunction.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ForceImpl.h"
...
...
@@ -113,12 +114,18 @@ void ReferenceCustomDynamics::initialize(ContextImpl& context, vector<double>& m
variableLocations
[
ename
.
str
()]
=
&
energy
;
}
// Create custom functions for the tabulated functions.
map
<
string
,
Lepton
::
CustomFunction
*>
functions
;
for
(
int
i
=
0
;
i
<
integrator
.
getNumTabulatedFunctions
();
i
++
)
functions
[
integrator
.
getTabulatedFunctionName
(
i
)]
=
createReferenceTabulatedFunction
(
integrator
.
getTabulatedFunction
(
i
));
// Parse the expressions.
int
numSteps
=
stepType
.
size
();
vector
<
int
>
forceGroup
;
vector
<
vector
<
ParsedExpression
>
>
expressions
;
CustomIntegratorUtilities
::
analyzeComputations
(
context
,
integrator
,
expressions
,
comparisons
,
blockEnd
,
invalidatesForces
,
needsForces
,
needsEnergy
,
computeBothForceAndEnergy
,
forceGroup
);
CustomIntegratorUtilities
::
analyzeComputations
(
context
,
integrator
,
expressions
,
comparisons
,
blockEnd
,
invalidatesForces
,
needsForces
,
needsEnergy
,
computeBothForceAndEnergy
,
forceGroup
,
functions
);
stepExpressions
.
resize
(
expressions
.
size
());
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
stepExpressions
[
i
].
resize
(
expressions
[
i
].
size
());
...
...
@@ -137,6 +144,11 @@ void ReferenceCustomDynamics::initialize(ContextImpl& context, vector<double>& m
if
(
kineticEnergyExpression
.
getVariables
().
find
(
"f"
)
!=
kineticEnergyExpression
.
getVariables
().
end
())
kineticEnergyNeedsForce
=
true
;
// Delete the custom functions.
for
(
auto
&
function
:
functions
)
delete
function
.
second
;
// Record the force group flags for each step.
forceGroupFlags
.
resize
(
numSteps
,
-
1
);
...
...
@@ -207,19 +219,26 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
for
(
auto
&
global
:
globals
)
expressionSet
.
setVariable
(
expressionSet
.
getVariableIndex
(
global
.
first
),
global
.
second
);
oldPos
=
atomCoordinates
;
map
<
int
,
double
>
groupEnergy
;
map
<
int
,
vector
<
Vec3
>
>
groupForces
;
if
(
forcesAreValid
)
groupForces
[
context
.
getLastForceGroups
()]
=
forces
;
// Loop over steps and execute them.
for
(
int
step
=
0
;
step
<
numSteps
;
)
{
if
((
needsForces
[
step
]
||
needsEnergy
[
step
])
&&
(
!
forcesAreValid
||
context
.
getLastForceGroups
()
!=
forceGroupFlags
[
step
]))
{
int
flags
=
forceGroupFlags
[
step
];
if
((
needsForces
[
step
]
&&
groupForces
.
find
(
flags
)
==
groupForces
.
end
())
||
(
needsEnergy
[
step
]
&&
groupEnergy
.
find
(
flags
)
==
groupEnergy
.
end
()))
{
// Recompute forces and/or energy.
bool
computeForce
=
needsForces
[
step
]
||
computeBothForceAndEnergy
[
step
];
bool
computeEnergy
=
needsEnergy
[
step
]
||
computeBothForceAndEnergy
[
step
];
recordChangedParameters
(
context
,
globals
);
double
e
=
context
.
calcForcesAndEnergy
(
computeForce
,
computeEnergy
,
forceGroupFlags
[
step
]);
if
(
computeForce
)
groupForces
[
flags
]
=
forces
;
if
(
computeEnergy
)
{
energy
=
e
;
groupEnergy
[
flags
]
=
e
;
context
.
getEnergyParameterDerivatives
(
energyParamDerivs
);
}
forcesAreValid
=
true
;
...
...
@@ -227,7 +246,10 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
// Execute the step.
energy
=
(
needsEnergy
[
step
]
?
groupEnergy
[
flags
]
:
0
);
vector
<
Vec3
>&
stepForces
=
(
needsForces
[
step
]
?
groupForces
[
flags
]
:
forces
);
int
nextStep
=
step
+
1
;
bool
stepInvalidatesForces
=
invalidatesForces
[
step
];
switch
(
stepType
[
step
])
{
case
CustomIntegrator
::
ComputeGlobal
:
{
uniform
=
SimTKOpenMMUtilities
::
getUniformlyDistributedRandomNumber
();
...
...
@@ -250,11 +272,11 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
}
if
(
results
==
NULL
)
throw
OpenMMException
(
"Illegal per-DOF output variable: "
+
stepVariable
[
step
]);
computePerDof
(
numberOfAtoms
,
*
results
,
atomCoordinates
,
velocities
,
f
orces
,
masses
,
perDof
,
stepExpressions
[
step
][
0
]);
computePerDof
(
numberOfAtoms
,
*
results
,
atomCoordinates
,
velocities
,
stepF
orces
,
masses
,
perDof
,
stepExpressions
[
step
][
0
]);
break
;
}
case
CustomIntegrator
::
ComputeSum
:
{
computePerDof
(
numberOfAtoms
,
sumBuffer
,
atomCoordinates
,
velocities
,
f
orces
,
masses
,
perDof
,
stepExpressions
[
step
][
0
]);
computePerDof
(
numberOfAtoms
,
sumBuffer
,
atomCoordinates
,
velocities
,
stepF
orces
,
masses
,
perDof
,
stepExpressions
[
step
][
0
]);
double
sum
=
0.0
;
for
(
int
j
=
0
;
j
<
numberOfAtoms
;
j
++
)
if
(
masses
[
j
]
!=
0.0
)
...
...
@@ -274,7 +296,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
}
case
CustomIntegrator
::
UpdateContextState
:
{
recordChangedParameters
(
context
,
globals
);
context
.
updateContextState
();
stepInvalidatesForces
=
context
.
updateContextState
();
globals
.
insert
(
context
.
getParameters
().
begin
(),
context
.
getParameters
().
end
());
for
(
auto
&
global
:
globals
)
expressionSet
.
setVariable
(
expressionSet
.
getVariableIndex
(
global
.
first
),
global
.
second
);
...
...
@@ -296,8 +318,11 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
break
;
}
}
if
(
i
nvalidatesForces
[
step
])
if
(
stepI
nvalidatesForces
)
{
forcesAreValid
=
false
;
groupForces
.
clear
();
groupEnergy
.
clear
();
}
step
=
nextStep
;
}
ReferenceVirtualSites
::
computePositions
(
context
.
getSystem
(),
atomCoordinates
);
...
...
platforms/reference/src/SimTKReference/ReferenceVirtualSites.cpp
View file @
18295108
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2012-201
4
Stanford University and the Authors. *
* Portions copyright (c) 2012-201
7
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -70,22 +70,30 @@ void ReferenceVirtualSites::computePositions(const OpenMM::System& system, vecto
// A local coordinates site.
const
LocalCoordinatesSite
&
site
=
dynamic_cast
<
const
LocalCoordinatesSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
Vec3
originWeights
=
site
.
getOriginWeights
();
Vec3
xWeights
=
site
.
getXWeights
();
Vec3
yWeights
=
site
.
getYWeights
();
int
numParticles
=
site
.
getNumParticles
();
vector
<
double
>
originWeights
,
xWeights
,
yWeights
;
site
.
getOriginWeights
(
originWeights
);
site
.
getXWeights
(
xWeights
);
site
.
getYWeights
(
yWeights
);
Vec3
origin
,
xdir
,
ydir
;
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
{
Vec3
pos
=
atomCoordinates
[
site
.
getParticle
(
j
)];
origin
+=
pos
*
originWeights
[
j
];
xdir
+=
pos
*
xWeights
[
j
];
ydir
+=
pos
*
yWeights
[
j
];
}
Vec3
localPosition
=
site
.
getLocalPosition
();
Vec3
origin
=
atomCoordinates
[
p1
]
*
originWeights
[
0
]
+
atomCoordinates
[
p2
]
*
originWeights
[
1
]
+
atomCoordinates
[
p3
]
*
originWeights
[
2
];
Vec3
xdir
=
atomCoordinates
[
p1
]
*
xWeights
[
0
]
+
atomCoordinates
[
p2
]
*
xWeights
[
1
]
+
atomCoordinates
[
p3
]
*
xWeights
[
2
];
Vec3
ydir
=
atomCoordinates
[
p1
]
*
yWeights
[
0
]
+
atomCoordinates
[
p2
]
*
yWeights
[
1
]
+
atomCoordinates
[
p3
]
*
yWeights
[
2
];
Vec3
zdir
=
xdir
.
cross
(
ydir
);
xdir
/=
sqrt
(
xdir
.
dot
(
xdir
));
zdir
/=
sqrt
(
zdir
.
dot
(
zdir
));
double
normXdir
=
sqrt
(
xdir
.
dot
(
xdir
));
double
normZdir
=
sqrt
(
zdir
.
dot
(
zdir
));
if
(
normXdir
>
0.0
)
xdir
/=
normXdir
;
if
(
normZdir
>
0.0
)
zdir
/=
normZdir
;
ydir
=
zdir
.
cross
(
xdir
);
atomCoordinates
[
i
]
=
origin
+
xdir
*
localPosition
[
0
]
+
ydir
*
localPosition
[
1
]
+
zdir
*
localPosition
[
2
];
}
}
}
void
ReferenceVirtualSites
::
distributeForces
(
const
OpenMM
::
System
&
system
,
const
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
vector
<
OpenMM
::
Vec3
>&
forces
)
{
...
...
@@ -133,71 +141,53 @@ void ReferenceVirtualSites::distributeForces(const OpenMM::System& system, const
// A local coordinates site.
const
LocalCoordinatesSite
&
site
=
dynamic_cast
<
const
LocalCoordinatesSite
&>
(
system
.
getVirtualSite
(
i
));
int
p1
=
site
.
getParticle
(
0
),
p2
=
site
.
getParticle
(
1
),
p3
=
site
.
getParticle
(
2
);
Vec3
originWeights
=
site
.
getOriginWeights
();
Vec3
wx
=
site
.
getXWeights
();
Vec3
wy
=
site
.
getYWeights
();
int
numParticles
=
site
.
getNumParticles
();
vector
<
double
>
originWeights
,
wx
,
wy
;
site
.
getOriginWeights
(
originWeights
);
site
.
getXWeights
(
wx
);
site
.
getYWeights
(
wy
);
Vec3
xdir
,
ydir
;
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
{
Vec3
pos
=
atomCoordinates
[
site
.
getParticle
(
j
)];
xdir
+=
pos
*
wx
[
j
];
ydir
+=
pos
*
wy
[
j
];
}
Vec3
localPosition
=
site
.
getLocalPosition
();
Vec3
xdir
=
atomCoordinates
[
p1
]
*
wx
[
0
]
+
atomCoordinates
[
p2
]
*
wx
[
1
]
+
atomCoordinates
[
p3
]
*
wx
[
2
];
Vec3
ydir
=
atomCoordinates
[
p1
]
*
wy
[
0
]
+
atomCoordinates
[
p2
]
*
wy
[
1
]
+
atomCoordinates
[
p3
]
*
wy
[
2
];
Vec3
zdir
=
xdir
.
cross
(
ydir
);
double
invNormXdir
=
1.0
/
sqrt
(
xdir
.
dot
(
xdir
));
double
invNormZdir
=
1.0
/
sqrt
(
zdir
.
dot
(
zdir
));
double
normXdir
=
sqrt
(
xdir
.
dot
(
xdir
));
double
normZdir
=
sqrt
(
zdir
.
dot
(
zdir
));
double
invNormXdir
=
(
normXdir
>
0.0
?
1.0
/
normXdir
:
0.0
);
double
invNormZdir
=
(
normZdir
>
0.0
?
1.0
/
normZdir
:
0.0
);
Vec3
dx
=
xdir
*
invNormXdir
;
Vec3
dz
=
zdir
*
invNormZdir
;
Vec3
dy
=
dz
.
cross
(
dx
);
// The derivatives for this case are very complicated. They were computed with SymPy then simplified by hand.
double
t11
=
(
wx
[
0
]
*
ydir
[
0
]
-
wy
[
0
]
*
xdir
[
0
])
*
invNormZdir
;
double
t12
=
(
wx
[
0
]
*
ydir
[
1
]
-
wy
[
0
]
*
xdir
[
1
])
*
invNormZdir
;
double
t13
=
(
wx
[
0
]
*
ydir
[
2
]
-
wy
[
0
]
*
xdir
[
2
])
*
invNormZdir
;
double
t21
=
(
wx
[
1
]
*
ydir
[
0
]
-
wy
[
1
]
*
xdir
[
0
])
*
invNormZdir
;
double
t22
=
(
wx
[
1
]
*
ydir
[
1
]
-
wy
[
1
]
*
xdir
[
1
])
*
invNormZdir
;
double
t23
=
(
wx
[
1
]
*
ydir
[
2
]
-
wy
[
1
]
*
xdir
[
2
])
*
invNormZdir
;
double
t31
=
(
wx
[
2
]
*
ydir
[
0
]
-
wy
[
2
]
*
xdir
[
0
])
*
invNormZdir
;
double
t32
=
(
wx
[
2
]
*
ydir
[
1
]
-
wy
[
2
]
*
xdir
[
1
])
*
invNormZdir
;
double
t33
=
(
wx
[
2
]
*
ydir
[
2
]
-
wy
[
2
]
*
xdir
[
2
])
*
invNormZdir
;
double
sx1
=
t13
*
dz
[
1
]
-
t12
*
dz
[
2
];
double
sy1
=
t11
*
dz
[
2
]
-
t13
*
dz
[
0
];
double
sz1
=
t12
*
dz
[
0
]
-
t11
*
dz
[
1
];
double
sx2
=
t23
*
dz
[
1
]
-
t22
*
dz
[
2
];
double
sy2
=
t21
*
dz
[
2
]
-
t23
*
dz
[
0
];
double
sz2
=
t22
*
dz
[
0
]
-
t21
*
dz
[
1
];
double
sx3
=
t33
*
dz
[
1
]
-
t32
*
dz
[
2
];
double
sy3
=
t31
*
dz
[
2
]
-
t33
*
dz
[
0
];
double
sz3
=
t32
*
dz
[
0
]
-
t31
*
dz
[
1
];
Vec3
wxScaled
=
wx
*
invNormXdir
;
vector
<
double
>
wxScaled
(
numParticles
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
wxScaled
[
j
]
=
wx
[
j
]
*
invNormXdir
;
Vec3
fp1
=
localPosition
*
f
[
0
];
Vec3
fp2
=
localPosition
*
f
[
1
];
Vec3
fp3
=
localPosition
*
f
[
2
];
forces
[
p1
][
0
]
+=
fp1
[
0
]
*
wxScaled
[
0
]
*
(
1
-
dx
[
0
]
*
dx
[
0
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sx1
)
+
fp1
[
1
]
*
((
-
dx
[
0
]
*
dy
[
0
]
)
*
wxScaled
[
0
]
+
dy
[
0
]
*
sx1
-
dx
[
1
]
*
t12
-
dx
[
2
]
*
t13
)
+
f
[
0
]
*
originWeights
[
0
];
forces
[
p1
][
1
]
+=
fp1
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
0
]
*
dx
[
1
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sy1
+
t13
)
+
fp1
[
1
]
*
((
-
dx
[
1
]
*
dy
[
0
]
-
dz
[
2
])
*
wxScaled
[
0
]
+
dy
[
0
]
*
sy1
+
dx
[
1
]
*
t11
);
forces
[
p1
][
2
]
+=
fp1
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
0
]
*
dx
[
2
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sz1
-
t12
)
+
fp1
[
1
]
*
((
-
dx
[
2
]
*
dy
[
0
]
+
dz
[
1
])
*
wxScaled
[
0
]
+
dy
[
0
]
*
sz1
+
dx
[
2
]
*
t11
);
forces
[
p2
][
0
]
+=
fp1
[
0
]
*
wxScaled
[
1
]
*
(
1
-
dx
[
0
]
*
dx
[
0
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sx2
)
+
fp1
[
1
]
*
((
-
dx
[
0
]
*
dy
[
0
]
)
*
wxScaled
[
1
]
+
dy
[
0
]
*
sx2
-
dx
[
1
]
*
t22
-
dx
[
2
]
*
t23
)
+
f
[
0
]
*
originWeights
[
1
];
forces
[
p2
][
1
]
+=
fp1
[
0
]
*
wxScaled
[
1
]
*
(
-
dx
[
0
]
*
dx
[
1
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sy2
+
t23
)
+
fp1
[
1
]
*
((
-
dx
[
1
]
*
dy
[
0
]
-
dz
[
2
])
*
wxScaled
[
1
]
+
dy
[
0
]
*
sy2
+
dx
[
1
]
*
t21
);
forces
[
p2
][
2
]
+=
fp1
[
0
]
*
wxScaled
[
1
]
*
(
-
dx
[
0
]
*
dx
[
2
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sz2
-
t22
)
+
fp1
[
1
]
*
((
-
dx
[
2
]
*
dy
[
0
]
+
dz
[
1
])
*
wxScaled
[
1
]
+
dy
[
0
]
*
sz2
+
dx
[
2
]
*
t21
);
forces
[
p3
][
0
]
+=
fp1
[
0
]
*
wxScaled
[
2
]
*
(
1
-
dx
[
0
]
*
dx
[
0
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sx3
)
+
fp1
[
1
]
*
((
-
dx
[
0
]
*
dy
[
0
]
)
*
wxScaled
[
2
]
+
dy
[
0
]
*
sx3
-
dx
[
1
]
*
t32
-
dx
[
2
]
*
t33
)
+
f
[
0
]
*
originWeights
[
2
];
forces
[
p3
][
1
]
+=
fp1
[
0
]
*
wxScaled
[
2
]
*
(
-
dx
[
0
]
*
dx
[
1
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sy3
+
t33
)
+
fp1
[
1
]
*
((
-
dx
[
1
]
*
dy
[
0
]
-
dz
[
2
])
*
wxScaled
[
2
]
+
dy
[
0
]
*
sy3
+
dx
[
1
]
*
t31
);
forces
[
p3
][
2
]
+=
fp1
[
0
]
*
wxScaled
[
2
]
*
(
-
dx
[
0
]
*
dx
[
2
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sz3
-
t32
)
+
fp1
[
1
]
*
((
-
dx
[
2
]
*
dy
[
0
]
+
dz
[
1
])
*
wxScaled
[
2
]
+
dy
[
0
]
*
sz3
+
dx
[
2
]
*
t31
);
forces
[
p1
][
0
]
+=
fp2
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
1
]
*
dx
[
0
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sx1
-
t13
)
-
fp2
[
1
]
*
((
dx
[
0
]
*
dy
[
1
]
-
dz
[
2
])
*
wxScaled
[
0
]
-
dy
[
1
]
*
sx1
-
dx
[
0
]
*
t12
);
forces
[
p1
][
1
]
+=
fp2
[
0
]
*
wxScaled
[
0
]
*
(
1
-
dx
[
1
]
*
dx
[
1
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sy1
)
-
fp2
[
1
]
*
((
dx
[
1
]
*
dy
[
1
]
)
*
wxScaled
[
0
]
-
dy
[
1
]
*
sy1
+
dx
[
0
]
*
t11
+
dx
[
2
]
*
t13
)
+
f
[
1
]
*
originWeights
[
0
];
forces
[
p1
][
2
]
+=
fp2
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
1
]
*
dx
[
2
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sz1
+
t11
)
-
fp2
[
1
]
*
((
dx
[
2
]
*
dy
[
1
]
+
dz
[
0
])
*
wxScaled
[
0
]
-
dy
[
1
]
*
sz1
-
dx
[
2
]
*
t12
);
forces
[
p2
][
0
]
+=
fp2
[
0
]
*
wxScaled
[
1
]
*
(
-
dx
[
1
]
*
dx
[
0
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sx2
-
t23
)
-
fp2
[
1
]
*
((
dx
[
0
]
*
dy
[
1
]
-
dz
[
2
])
*
wxScaled
[
1
]
-
dy
[
1
]
*
sx2
-
dx
[
0
]
*
t22
);
forces
[
p2
][
1
]
+=
fp2
[
0
]
*
wxScaled
[
1
]
*
(
1
-
dx
[
1
]
*
dx
[
1
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sy2
)
-
fp2
[
1
]
*
((
dx
[
1
]
*
dy
[
1
]
)
*
wxScaled
[
1
]
-
dy
[
1
]
*
sy2
+
dx
[
0
]
*
t21
+
dx
[
2
]
*
t23
)
+
f
[
1
]
*
originWeights
[
1
];
forces
[
p2
][
2
]
+=
fp2
[
0
]
*
wxScaled
[
1
]
*
(
-
dx
[
1
]
*
dx
[
2
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sz2
+
t21
)
-
fp2
[
1
]
*
((
dx
[
2
]
*
dy
[
1
]
+
dz
[
0
])
*
wxScaled
[
1
]
-
dy
[
1
]
*
sz2
-
dx
[
2
]
*
t22
);
forces
[
p3
][
0
]
+=
fp2
[
0
]
*
wxScaled
[
2
]
*
(
-
dx
[
1
]
*
dx
[
0
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sx3
-
t33
)
-
fp2
[
1
]
*
((
dx
[
0
]
*
dy
[
1
]
-
dz
[
2
])
*
wxScaled
[
2
]
-
dy
[
1
]
*
sx3
-
dx
[
0
]
*
t32
);
forces
[
p3
][
1
]
+=
fp2
[
0
]
*
wxScaled
[
2
]
*
(
1
-
dx
[
1
]
*
dx
[
1
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sy3
)
-
fp2
[
1
]
*
((
dx
[
1
]
*
dy
[
1
]
)
*
wxScaled
[
2
]
-
dy
[
1
]
*
sy3
+
dx
[
0
]
*
t31
+
dx
[
2
]
*
t33
)
+
f
[
1
]
*
originWeights
[
2
];
forces
[
p3
][
2
]
+=
fp2
[
0
]
*
wxScaled
[
2
]
*
(
-
dx
[
1
]
*
dx
[
2
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sz3
+
t31
)
-
fp2
[
1
]
*
((
dx
[
2
]
*
dy
[
1
]
+
dz
[
0
])
*
wxScaled
[
2
]
-
dy
[
1
]
*
sz3
-
dx
[
2
]
*
t32
);
forces
[
p1
][
0
]
+=
fp3
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
2
]
*
dx
[
0
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sx1
+
t12
)
+
fp3
[
1
]
*
((
-
dx
[
0
]
*
dy
[
2
]
-
dz
[
1
])
*
wxScaled
[
0
]
+
dy
[
2
]
*
sx1
+
dx
[
0
]
*
t13
);
forces
[
p1
][
1
]
+=
fp3
[
0
]
*
wxScaled
[
0
]
*
(
-
dx
[
2
]
*
dx
[
1
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sy1
-
t11
)
+
fp3
[
1
]
*
((
-
dx
[
1
]
*
dy
[
2
]
+
dz
[
0
])
*
wxScaled
[
0
]
+
dy
[
2
]
*
sy1
+
dx
[
1
]
*
t13
);
forces
[
p1
][
2
]
+=
fp3
[
0
]
*
wxScaled
[
0
]
*
(
1
-
dx
[
2
]
*
dx
[
2
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sz1
)
+
fp3
[
1
]
*
((
-
dx
[
2
]
*
dy
[
2
]
)
*
wxScaled
[
0
]
+
dy
[
2
]
*
sz1
-
dx
[
0
]
*
t11
-
dx
[
1
]
*
t12
)
+
f
[
2
]
*
originWeights
[
0
];
forces
[
p2
][
0
]
+=
fp3
[
0
]
*
wxScaled
[
1
]
*
(
-
dx
[
2
]
*
dx
[
0
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sx2
+
t22
)
+
fp3
[
1
]
*
((
-
dx
[
0
]
*
dy
[
2
]
-
dz
[
1
])
*
wxScaled
[
1
]
+
dy
[
2
]
*
sx2
+
dx
[
0
]
*
t23
);
forces
[
p2
][
1
]
+=
fp3
[
0
]
*
wxScaled
[
1
]
*
(
-
dx
[
2
]
*
dx
[
1
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sy2
-
t21
)
+
fp3
[
1
]
*
((
-
dx
[
1
]
*
dy
[
2
]
+
dz
[
0
])
*
wxScaled
[
1
]
+
dy
[
2
]
*
sy2
+
dx
[
1
]
*
t23
);
forces
[
p2
][
2
]
+=
fp3
[
0
]
*
wxScaled
[
1
]
*
(
1
-
dx
[
2
]
*
dx
[
2
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sz2
)
+
fp3
[
1
]
*
((
-
dx
[
2
]
*
dy
[
2
]
)
*
wxScaled
[
1
]
+
dy
[
2
]
*
sz2
-
dx
[
0
]
*
t21
-
dx
[
1
]
*
t22
)
+
f
[
2
]
*
originWeights
[
1
];
forces
[
p3
][
0
]
+=
fp3
[
0
]
*
wxScaled
[
2
]
*
(
-
dx
[
2
]
*
dx
[
0
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sx3
+
t32
)
+
fp3
[
1
]
*
((
-
dx
[
0
]
*
dy
[
2
]
-
dz
[
1
])
*
wxScaled
[
2
]
+
dy
[
2
]
*
sx3
+
dx
[
0
]
*
t33
);
forces
[
p3
][
1
]
+=
fp3
[
0
]
*
wxScaled
[
2
]
*
(
-
dx
[
2
]
*
dx
[
1
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sy3
-
t31
)
+
fp3
[
1
]
*
((
-
dx
[
1
]
*
dy
[
2
]
+
dz
[
0
])
*
wxScaled
[
2
]
+
dy
[
2
]
*
sy3
+
dx
[
1
]
*
t33
);
forces
[
p3
][
2
]
+=
fp3
[
0
]
*
wxScaled
[
2
]
*
(
1
-
dx
[
2
]
*
dx
[
2
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sz3
)
+
fp3
[
1
]
*
((
-
dx
[
2
]
*
dy
[
2
]
)
*
wxScaled
[
2
]
+
dy
[
2
]
*
sz3
-
dx
[
0
]
*
t31
-
dx
[
1
]
*
t32
)
+
f
[
2
]
*
originWeights
[
2
];
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
{
double
t1
=
(
wx
[
j
]
*
ydir
[
0
]
-
wy
[
j
]
*
xdir
[
0
])
*
invNormZdir
;
double
t2
=
(
wx
[
j
]
*
ydir
[
1
]
-
wy
[
j
]
*
xdir
[
1
])
*
invNormZdir
;
double
t3
=
(
wx
[
j
]
*
ydir
[
2
]
-
wy
[
j
]
*
xdir
[
2
])
*
invNormZdir
;
double
sx
=
t3
*
dz
[
1
]
-
t2
*
dz
[
2
];
double
sy
=
t1
*
dz
[
2
]
-
t3
*
dz
[
0
];
double
sz
=
t2
*
dz
[
0
]
-
t1
*
dz
[
1
];
int
p
=
site
.
getParticle
(
j
);
forces
[
p
][
0
]
+=
fp1
[
0
]
*
wxScaled
[
j
]
*
(
1
-
dx
[
0
]
*
dx
[
0
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sx
)
+
fp1
[
1
]
*
((
-
dx
[
0
]
*
dy
[
0
]
)
*
wxScaled
[
j
]
+
dy
[
0
]
*
sx
-
dx
[
1
]
*
t2
-
dx
[
2
]
*
t3
)
+
f
[
0
]
*
originWeights
[
j
];
forces
[
p
][
1
]
+=
fp1
[
0
]
*
wxScaled
[
j
]
*
(
-
dx
[
0
]
*
dx
[
1
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sy
+
t3
)
+
fp1
[
1
]
*
((
-
dx
[
1
]
*
dy
[
0
]
-
dz
[
2
])
*
wxScaled
[
j
]
+
dy
[
0
]
*
sy
+
dx
[
1
]
*
t1
);
forces
[
p
][
2
]
+=
fp1
[
0
]
*
wxScaled
[
j
]
*
(
-
dx
[
0
]
*
dx
[
2
])
+
fp1
[
2
]
*
(
dz
[
0
]
*
sz
-
t2
)
+
fp1
[
1
]
*
((
-
dx
[
2
]
*
dy
[
0
]
+
dz
[
1
])
*
wxScaled
[
j
]
+
dy
[
0
]
*
sz
+
dx
[
2
]
*
t1
);
forces
[
p
][
0
]
+=
fp2
[
0
]
*
wxScaled
[
j
]
*
(
-
dx
[
1
]
*
dx
[
0
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sx
-
t3
)
-
fp2
[
1
]
*
((
dx
[
0
]
*
dy
[
1
]
-
dz
[
2
])
*
wxScaled
[
j
]
-
dy
[
1
]
*
sx
-
dx
[
0
]
*
t2
);
forces
[
p
][
1
]
+=
fp2
[
0
]
*
wxScaled
[
j
]
*
(
1
-
dx
[
1
]
*
dx
[
1
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sy
)
-
fp2
[
1
]
*
((
dx
[
1
]
*
dy
[
1
]
)
*
wxScaled
[
j
]
-
dy
[
1
]
*
sy
+
dx
[
0
]
*
t1
+
dx
[
2
]
*
t3
)
+
f
[
1
]
*
originWeights
[
j
];
forces
[
p
][
2
]
+=
fp2
[
0
]
*
wxScaled
[
j
]
*
(
-
dx
[
1
]
*
dx
[
2
])
+
fp2
[
2
]
*
(
dz
[
1
]
*
sz
+
t1
)
-
fp2
[
1
]
*
((
dx
[
2
]
*
dy
[
1
]
+
dz
[
0
])
*
wxScaled
[
j
]
-
dy
[
1
]
*
sz
-
dx
[
2
]
*
t2
);
forces
[
p
][
0
]
+=
fp3
[
0
]
*
wxScaled
[
j
]
*
(
-
dx
[
2
]
*
dx
[
0
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sx
+
t2
)
+
fp3
[
1
]
*
((
-
dx
[
0
]
*
dy
[
2
]
-
dz
[
1
])
*
wxScaled
[
j
]
+
dy
[
2
]
*
sx
+
dx
[
0
]
*
t3
);
forces
[
p
][
1
]
+=
fp3
[
0
]
*
wxScaled
[
j
]
*
(
-
dx
[
2
]
*
dx
[
1
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sy
-
t1
)
+
fp3
[
1
]
*
((
-
dx
[
1
]
*
dy
[
2
]
+
dz
[
0
])
*
wxScaled
[
j
]
+
dy
[
2
]
*
sy
+
dx
[
1
]
*
t3
);
forces
[
p
][
2
]
+=
fp3
[
0
]
*
wxScaled
[
j
]
*
(
1
-
dx
[
2
]
*
dx
[
2
])
+
fp3
[
2
]
*
(
dz
[
2
]
*
sz
)
+
fp3
[
1
]
*
((
-
dx
[
2
]
*
dy
[
2
]
)
*
wxScaled
[
j
]
+
dy
[
2
]
*
sz
-
dx
[
0
]
*
t1
-
dx
[
1
]
*
t2
)
+
f
[
2
]
*
originWeights
[
j
];
}
}
}
}
platforms/reference/tests/TestReferenceCustomCVForce.cpp
0 → 100644
View file @
18295108
/* -------------------------------------------------------------------------- *
* 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) 2017 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 "ReferenceTests.h"
#include "TestCustomCVForce.h"
void
runPlatformTests
()
{
}
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaAngleForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaAngleForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaBondForceImpl.h
View file @
18295108
...
...
@@ -54,7 +54,7 @@ public:
const
AmoebaBondForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaGeneralizedKirkwoodForceImpl.h
View file @
18295108
...
...
@@ -50,7 +50,7 @@ public:
const
AmoebaGeneralizedKirkwoodForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaInPlaneAngleForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaInPlaneAngleForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaMultipoleForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaOutOfPlaneBendForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaOutOfPlaneBendForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaPiTorsionForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaPiTorsionForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaStretchBendForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaStretchBendForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h
View file @
18295108
...
...
@@ -52,7 +52,7 @@ public:
const
AmoebaTorsionTorsionForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaVdwForceImpl.h
View file @
18295108
...
...
@@ -55,7 +55,7 @@ public:
const
AmoebaVdwForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/amoeba/openmmapi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h
View file @
18295108
...
...
@@ -53,7 +53,7 @@ public:
const
AmoebaWcaDispersionForce
&
getOwner
()
const
{
return
owner
;
}
void
updateContextState
(
ContextImpl
&
context
)
{
void
updateContextState
(
ContextImpl
&
context
,
bool
&
forcesInvalid
)
{
// This force field doesn't update the state directly.
}
double
calcForcesAndEnergy
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
);
...
...
plugins/cpupme/src/CpuPmeKernels.cpp
View file @
18295108
...
...
@@ -51,7 +51,8 @@ static const int PME_ORDER = 5;
bool
CpuCalcDispersionPmeReciprocalForceKernel
::
hasInitializedThreads
=
false
;
int
CpuCalcDispersionPmeReciprocalForceKernel
::
numThreads
=
0
;
static
void
spreadCharge
(
float
*
posq
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
,
const
float
epsilonFactor
)
{
static
void
spreadCharge
(
float
*
posq
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
,
const
float
epsilonFactor
,
int
threadIndex
,
int
numThreads
,
bool
deterministic
)
{
float
temp
[
4
];
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
...
...
@@ -65,8 +66,10 @@ static void spreadCharge(float* posq, float* grid, int gridx, int gridy, int gri
float
posInBox
[
4
]
=
{
0
,
0
,
0
,
0
};
memset
(
grid
,
0
,
sizeof
(
float
)
*
gridx
*
gridy
*
gridz
);
int
i
=
threadIndex
;
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
&
atomicCounter
,
1
);
if
(
!
deterministic
)
i
=
gmx_atomic_fetch_add
(
&
atomicCounter
,
1
);
if
(
i
>=
numParticles
)
break
;
...
...
@@ -151,6 +154,8 @@ static void spreadCharge(float* posq, float* grid, int gridx, int gridy, int gri
}
}
}
if
(
deterministic
)
i
+=
numThreads
;
}
}
...
...
@@ -406,7 +411,7 @@ static void* threadBody(void* args) {
return
0
;
}
void
CpuCalcPmeReciprocalForceKernel
::
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
)
{
void
CpuCalcPmeReciprocalForceKernel
::
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
,
bool
deterministic
)
{
if
(
!
hasInitializedThreads
)
{
numThreads
=
getNumProcessors
();
char
*
threadsEnv
=
getenv
(
"OPENMM_CPU_THREADS"
);
...
...
@@ -421,6 +426,7 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize
gridz
=
findFFTDimension
(
zsize
,
true
);
this
->
numParticles
=
numParticles
;
this
->
alpha
=
alpha
;
this
->
deterministic
=
deterministic
;
force
.
resize
(
4
*
numParticles
);
recipEterm
.
resize
(
gridx
*
gridy
*
gridz
);
...
...
@@ -580,7 +586,7 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
int
complexStart
=
std
::
max
(
1
,
((
index
*
complexSize
)
/
numThreads
));
int
complexEnd
=
(((
index
+
1
)
*
complexSize
)
/
numThreads
);
const
float
epsilonFactor
=
sqrt
(
ONE_4PI_EPS0
);
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
);
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
,
index
,
numThreads
,
deterministic
);
threads
.
syncThreads
();
int
numGrids
=
tempGrid
.
size
();
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
...
...
@@ -696,7 +702,7 @@ static void* dispersionThreadBody(void* args) {
return
0
;
}
void
CpuCalcDispersionPmeReciprocalForceKernel
::
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
)
{
void
CpuCalcDispersionPmeReciprocalForceKernel
::
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
,
bool
deterministic
)
{
if
(
!
hasInitializedThreads
)
{
numThreads
=
getNumProcessors
();
char
*
threadsEnv
=
getenv
(
"OPENMM_CPU_THREADS"
);
...
...
@@ -711,6 +717,7 @@ void CpuCalcDispersionPmeReciprocalForceKernel::initialize(int xsize, int ysize,
gridz
=
findFFTDimension
(
zsize
,
true
);
this
->
numParticles
=
numParticles
;
this
->
alpha
=
alpha
;
this
->
deterministic
=
deterministic
;
force
.
resize
(
4
*
numParticles
);
recipEterm
.
resize
(
gridx
*
gridy
*
gridz
);
...
...
@@ -871,7 +878,7 @@ void CpuCalcDispersionPmeReciprocalForceKernel::runWorkerThread(ThreadPool& thre
int
complexStart
=
std
::
max
(
1
,
((
index
*
complexSize
)
/
numThreads
));
int
complexEnd
=
(((
index
+
1
)
*
complexSize
)
/
numThreads
);
const
float
epsilonFactor
=
1.0
f
;
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
);
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
,
epsilonFactor
,
index
,
numThreads
,
deterministic
);
threads
.
syncThreads
();
int
numGrids
=
tempGrid
.
size
();
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
...
...
plugins/cpupme/src/CpuPmeKernels.h
View file @
18295108
...
...
@@ -62,8 +62,9 @@ public:
* @param gridz the z size of the PME grid
* @param numParticles the number of particles in the system
* @param alpha the Ewald blending parameter
* @param deterministic whether it should attempt to make the resulting forces deterministic
*/
void
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
);
void
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
,
bool
deterministic
);
~
CpuCalcPmeReciprocalForceKernel
();
/**
* Begin computing the force and energy.
...
...
@@ -110,6 +111,7 @@ private:
static
int
numThreads
;
int
gridx
,
gridy
,
gridz
,
numParticles
;
double
alpha
;
bool
deterministic
;
bool
hasCreatedPlan
,
isFinished
,
isDeleted
;
std
::
vector
<
float
>
force
;
std
::
vector
<
float
>
bsplineModuli
[
3
];
...
...
@@ -153,8 +155,9 @@ public:
* @param gridz the z size of the PME grid
* @param numParticles the number of particles in the system
* @param alpha the Ewald blending parameter
* @param deterministic whether it should attempt to make the resulting forces deterministic
*/
void
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
);
void
initialize
(
int
xsize
,
int
ysize
,
int
zsize
,
int
numParticles
,
double
alpha
,
bool
deterministic
);
~
CpuCalcDispersionPmeReciprocalForceKernel
();
/**
* Begin computing the force and energy.
...
...
@@ -202,6 +205,7 @@ private:
static
int
numThreads
;
int
gridx
,
gridy
,
gridz
,
numParticles
;
double
alpha
;
bool
deterministic
;
bool
hasCreatedPlan
,
isFinished
,
isDeleted
;
std
::
vector
<
float
>
force
;
std
::
vector
<
float
>
bsplineModuli
[
3
];
...
...
plugins/cpupme/tests/TestCpuPme.cpp
View file @
18295108
...
...
@@ -535,7 +535,7 @@ void test_water2_dpme_energies_forces_no_exclusions() {
io
.
posq
.
push_back
(
c6
);
selfEwaldEnergy
+=
dalpha6
*
c6
*
c6
/
12.0
;
}
pme
.
initialize
(
grid
,
grid
,
grid
,
NATOMS
,
dalpha
);
pme
.
initialize
(
grid
,
grid
,
grid
,
NATOMS
,
dalpha
,
false
);
Vec3
boxVectors
[
3
];
system
.
getDefaultPeriodicBoxVectors
(
boxVectors
[
0
],
boxVectors
[
1
],
boxVectors
[
2
]);
pme
.
beginComputation
(
io
,
boxVectors
,
true
);
...
...
@@ -626,7 +626,7 @@ void testPME(bool triclinic) {
sumSquaredCharges
+=
charge
*
charge
;
}
double
ewaldSelfEnergy
=
-
ONE_4PI_EPS0
*
alpha
*
sumSquaredCharges
/
sqrt
(
M_PI
);
pme
.
initialize
(
gridx
,
gridy
,
gridz
,
numParticles
,
alpha
);
pme
.
initialize
(
gridx
,
gridy
,
gridz
,
numParticles
,
alpha
,
true
);
pme
.
beginComputation
(
io
,
boxVectors
,
true
);
double
energy
=
pme
.
finishComputation
(
io
);
...
...
serialization/include/openmm/serialization/CustomCVForceProxy.h
0 → 100644
View file @
18295108
#ifndef OPENMM_CUSTOMCVFORCE_PROXY_H_
#define OPENMM_CUSTOMCVFORCE_PROXY_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) 2017 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/internal/windowsExport.h"
#include "openmm/serialization/SerializationProxy.h"
namespace
OpenMM
{
/**
* This is a proxy for serializing CustomCVForce objects.
*/
class
OPENMM_EXPORT
CustomCVForceProxy
:
public
SerializationProxy
{
public:
CustomCVForceProxy
();
void
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
;
void
*
deserialize
(
const
SerializationNode
&
node
)
const
;
};
}
// namespace OpenMM
#endif
/*OPENMM_CUSTOMCVFORCE_PROXY_H_*/
serialization/src/CustomCVForceProxy.cpp
0 → 100644
View file @
18295108
/* -------------------------------------------------------------------------- *
* 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) 2010-2017 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/serialization/CustomCVForceProxy.h"
#include "openmm/serialization/SerializationNode.h"
#include "openmm/Force.h"
#include "openmm/CustomCVForce.h"
#include <sstream>
using
namespace
OpenMM
;
using
namespace
std
;
CustomCVForceProxy
::
CustomCVForceProxy
()
:
SerializationProxy
(
"CustomCVForce"
)
{
}
void
CustomCVForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
0
);
const
CustomCVForce
&
force
=
*
reinterpret_cast
<
const
CustomCVForce
*>
(
object
);
node
.
setIntProperty
(
"forceGroup"
,
force
.
getForceGroup
());
node
.
setStringProperty
(
"energy"
,
force
.
getEnergyFunction
());
SerializationNode
&
globalParams
=
node
.
createChildNode
(
"GlobalParameters"
);
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
globalParams
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getGlobalParameterName
(
i
)).
setDoubleProperty
(
"default"
,
force
.
getGlobalParameterDefaultValue
(
i
));
}
SerializationNode
&
energyDerivs
=
node
.
createChildNode
(
"EnergyParameterDerivatives"
);
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
energyDerivs
.
createChildNode
(
"Parameter"
).
setStringProperty
(
"name"
,
force
.
getEnergyParameterDerivativeName
(
i
));
}
SerializationNode
&
cvs
=
node
.
createChildNode
(
"CollectiveVariables"
);
for
(
int
i
=
0
;
i
<
force
.
getNumCollectiveVariables
();
i
++
)
{
SerializationNode
&
node
=
cvs
.
createChildNode
(
"CollectiveVariable"
).
setStringProperty
(
"name"
,
force
.
getCollectiveVariableName
(
i
));
node
.
createChildNode
(
"Force"
,
&
force
.
getCollectiveVariable
(
i
));
}
SerializationNode
&
functions
=
node
.
createChildNode
(
"Functions"
);
for
(
int
i
=
0
;
i
<
force
.
getNumTabulatedFunctions
();
i
++
)
functions
.
createChildNode
(
"Function"
,
&
force
.
getTabulatedFunction
(
i
)).
setStringProperty
(
"name"
,
force
.
getTabulatedFunctionName
(
i
));
}
void
*
CustomCVForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
int
version
=
node
.
getIntProperty
(
"version"
);
if
(
version
!=
0
)
throw
OpenMMException
(
"Unsupported version number"
);
CustomCVForce
*
force
=
NULL
;
try
{
CustomCVForce
*
force
=
new
CustomCVForce
(
node
.
getStringProperty
(
"energy"
));
force
->
setForceGroup
(
node
.
getIntProperty
(
"forceGroup"
,
0
));
const
SerializationNode
&
globalParams
=
node
.
getChildNode
(
"GlobalParameters"
);
for
(
auto
&
parameter
:
globalParams
.
getChildren
())
force
->
addGlobalParameter
(
parameter
.
getStringProperty
(
"name"
),
parameter
.
getDoubleProperty
(
"default"
));
const
SerializationNode
&
energyDerivs
=
node
.
getChildNode
(
"EnergyParameterDerivatives"
);
for
(
auto
&
parameter
:
energyDerivs
.
getChildren
())
force
->
addEnergyParameterDerivative
(
parameter
.
getStringProperty
(
"name"
));
const
SerializationNode
&
cvs
=
node
.
getChildNode
(
"CollectiveVariables"
);
for
(
auto
&
cv
:
cvs
.
getChildren
())
{
string
name
=
cv
.
getStringProperty
(
"name"
);
force
->
addCollectiveVariable
(
name
,
cv
.
getChildren
()[
0
].
decodeObject
<
Force
>
());
}
const
SerializationNode
&
functions
=
node
.
getChildNode
(
"Functions"
);
for
(
auto
&
function
:
functions
.
getChildren
())
force
->
addTabulatedFunction
(
function
.
getStringProperty
(
"name"
),
function
.
decodeObject
<
TabulatedFunction
>
());
return
force
;
}
catch
(...)
{
if
(
force
!=
NULL
)
delete
force
;
throw
;
}
}
Prev
1
2
3
4
5
6
7
8
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