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
855ece90
Commit
855ece90
authored
Oct 17, 2013
by
leeping
Browse files
Merge branch 'master' of
https://github.com/SimTk/openmm
parents
471bea82
a42c55ad
Changes
115
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1069 additions
and
1327 deletions
+1069
-1327
platforms/reference/include/ReferencePME.h
platforms/reference/include/ReferencePME.h
+6
-6
platforms/reference/include/ReferencePairIxn.h
platforms/reference/include/ReferencePairIxn.h
+1
-0
platforms/reference/include/ReferenceSETTLEAlgorithm.h
platforms/reference/include/ReferenceSETTLEAlgorithm.h
+87
-0
platforms/reference/src/ReferenceKernels.cpp
platforms/reference/src/ReferenceKernels.cpp
+80
-106
platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp
...eference/src/SimTKReference/ReferenceBrownianDynamics.cpp
+3
-3
platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp
...s/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp
+232
-463
platforms/reference/src/SimTKReference/ReferenceConstraint.cpp
...orms/reference/src/SimTKReference/ReferenceConstraint.cpp
+0
-219
platforms/reference/src/SimTKReference/ReferenceConstraints.cpp
...rms/reference/src/SimTKReference/ReferenceConstraints.cpp
+217
-0
platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp
.../reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp
+24
-17
platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp
...s/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp
+24
-17
platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp
.../reference/src/SimTKReference/ReferenceCustomDynamics.cpp
+3
-3
platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp
...ference/src/SimTKReference/ReferenceCustomExternalIxn.cpp
+53
-22
platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp
...erence/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp
+33
-21
platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp
...eference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp
+25
-19
platforms/reference/src/SimTKReference/ReferenceForce.cpp
platforms/reference/src/SimTKReference/ReferenceForce.cpp
+12
-1
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+5
-2
platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp
...ms/reference/src/SimTKReference/ReferenceNeighborList.cpp
+16
-13
platforms/reference/src/SimTKReference/ReferencePME.cpp
platforms/reference/src/SimTKReference/ReferencePME.cpp
+8
-11
platforms/reference/src/SimTKReference/ReferenceSETTLEAlgorithm.cpp
...reference/src/SimTKReference/ReferenceSETTLEAlgorithm.cpp
+240
-0
platforms/reference/src/SimTKReference/ReferenceShakeAlgorithm.cpp
.../reference/src/SimTKReference/ReferenceShakeAlgorithm.cpp
+0
-404
No files found.
platforms/reference/
src/SimTK
Reference
/
PME.h
→
platforms/reference/
include/
ReferencePME.h
View file @
855ece90
...
...
@@ -54,11 +54,11 @@ pme_t;
*/
int
pme_init
(
pme_t
*
ppme
,
RealOpenMM
ewaldcoeff
,
RealOpenMM
ewaldcoeff
,
int
natoms
,
const
int
ngrid
[
3
],
const
int
ngrid
[
3
],
int
pme_order
,
RealOpenMM
epsilon_r
);
RealOpenMM
epsilon_r
);
/*
* Evaluate reciprocal space PME energy and forces.
...
...
@@ -75,9 +75,9 @@ pme_init(pme_t * ppme,
*/
int
pme_exec
(
pme_t
pme
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
RealOpenMM
**
atomParameter
s
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
forces
,
std
::
vector
<
RealOpenMM
>&
charge
s
,
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
pme_virial
[
3
][
3
]);
...
...
platforms/reference/include/ReferencePairIxn.h
View file @
855ece90
...
...
@@ -25,6 +25,7 @@
#ifndef __ReferencePairIxn_H__
#define __ReferencePairIxn_H__
#include "RealVec.h"
#include "openmm/internal/windowsExport.h"
// ---------------------------------------------------------------------------------------
...
...
platforms/reference/include/ReferenceSETTLEAlgorithm.h
0 → 100644
View file @
855ece90
#ifndef OPENMM_REFERENCESETTLEALGORITHM_H_
#define OPENMM_REFERENCESETTLEALGORITHM_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) 2013 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 "ReferenceConstraintAlgorithm.h"
#include <vector>
namespace
OpenMM
{
/**
* This implements the SETTLE algorithm for constraining water molecules.
*/
class
OPENMM_EXPORT
ReferenceSETTLEAlgorithm
:
public
ReferenceConstraintAlgorithm
{
public:
ReferenceSETTLEAlgorithm
(
const
std
::
vector
<
int
>&
atom1
,
const
std
::
vector
<
int
>&
atom2
,
const
std
::
vector
<
int
>&
atom3
,
const
std
::
vector
<
RealOpenMM
>&
distance1
,
const
std
::
vector
<
RealOpenMM
>&
distance2
,
std
::
vector
<
RealOpenMM
>&
masses
,
RealOpenMM
tolerance
);
/**
* Get the constraint tolerance.
*/
RealOpenMM
getTolerance
()
const
;
/**
* Set the constraint tolerance.
*/
void
setTolerance
(
RealOpenMM
tolerance
);
/**
* Apply the constraint algorithm.
*
* @param atomCoordinates the original atom coordinates
* @param atomCoordinatesP the new atom coordinates
* @param inverseMasses 1/mass
*/
void
apply
(
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinatesP
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
);
/**
* Apply the constraint algorithm to velocities.
*
* @param atomCoordinates the atom coordinates
* @param atomCoordinatesP the velocities to modify
* @param inverseMasses 1/mass
*/
void
applyToVelocities
(
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
velocities
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
);
private:
RealOpenMM
tolerance
;
std
::
vector
<
int
>
atom1
;
std
::
vector
<
int
>
atom2
;
std
::
vector
<
int
>
atom3
;
std
::
vector
<
RealOpenMM
>
distance1
;
std
::
vector
<
RealOpenMM
>
distance2
;
std
::
vector
<
RealOpenMM
>
masses
;
};
}
// namespace OpenMM
#endif
/*OPENMM_REFERENCESETTLEALGORITHM_H_*/
platforms/reference/src/ReferenceKernels.cpp
View file @
855ece90
...
...
@@ -38,6 +38,7 @@
#include "ReferenceBrownianDynamics.h"
#include "ReferenceCCMAAlgorithm.h"
#include "ReferenceCMAPTorsionIxn.h"
#include "ReferenceConstraints.h"
#include "ReferenceCustomAngleIxn.h"
#include "ReferenceCustomBondIxn.h"
#include "ReferenceCustomCompoundBondIxn.h"
...
...
@@ -132,20 +133,6 @@ static RealVec& extractBoxSize(ContextImpl& context) {
return
*
(
RealVec
*
)
data
->
periodicBoxSize
;
}
static
void
findAnglesForCCMA
(
const
System
&
system
,
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>&
angles
)
{
for
(
int
i
=
0
;
i
<
system
.
getNumForces
();
i
++
)
{
const
HarmonicAngleForce
*
force
=
dynamic_cast
<
const
HarmonicAngleForce
*>
(
&
system
.
getForce
(
i
));
if
(
force
!=
NULL
)
{
for
(
int
j
=
0
;
j
<
force
->
getNumAngles
();
j
++
)
{
int
atom1
,
atom2
,
atom3
;
double
angle
,
k
;
force
->
getAngleParameters
(
j
,
atom1
,
atom2
,
atom3
,
angle
,
k
);
angles
.
push_back
(
ReferenceCCMAAlgorithm
::
AngleInfo
(
atom1
,
atom2
,
atom3
,
(
RealOpenMM
)
angle
));
}
}
}
}
/**
* Compute the kinetic energy of the system, possibly shifting the velocities in time to account
* for a leapfrog integrator.
...
...
@@ -173,7 +160,7 @@ static double computeShiftedKineticEnergy(ContextImpl& context, vector<double>&
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
inverseMasses
[
i
]
=
(
masses
[
i
]
==
0
?
0
:
1
/
masses
[
i
]);
constraints
->
setTolerance
(
1e-4
);
constraints
->
applyToVelocities
(
numParticles
,
posData
,
shiftedVel
,
inverseMasses
);
constraints
->
applyToVelocities
(
posData
,
shiftedVel
,
inverseMasses
);
}
// Compute the kinetic energy.
...
...
@@ -315,17 +302,16 @@ void ReferenceApplyConstraintsKernel::initialize(const System& system) {
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
inverseMasses
[
i
]
=
1.0
/
masses
[
i
];
}
numConstraints
=
system
.
getNumConstraints
();
constraintIndices
.
resize
(
numConstraints
);
constraintDistances
.
resize
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
numConstraints
=
constraintIndices
.
size
();
}
ReferenceApplyConstraintsKernel
::~
ReferenceApplyConstraintsKernel
()
{
...
...
@@ -334,27 +320,21 @@ ReferenceApplyConstraintsKernel::~ReferenceApplyConstraintsKernel() {
}
void
ReferenceApplyConstraintsKernel
::
apply
(
ContextImpl
&
context
,
double
tol
)
{
if
(
constraints
==
NULL
)
{
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
context
.
getSystem
(),
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
context
.
getSystem
().
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
tol
);
}
if
(
constraints
==
NULL
)
constraints
=
new
ReferenceConstraints
(
context
.
getSystem
(),
(
RealOpenMM
)
tol
);
vector
<
RealVec
>&
positions
=
extractPositions
(
context
);
constraints
->
setTolerance
(
tol
);
constraints
->
apply
(
data
.
numParticles
,
positions
,
positions
,
inverseMasses
);
constraints
->
apply
(
positions
,
positions
,
inverseMasses
);
ReferenceVirtualSites
::
computePositions
(
context
.
getSystem
(),
positions
);
}
void
ReferenceApplyConstraintsKernel
::
applyToVelocities
(
ContextImpl
&
context
,
double
tol
)
{
if
(
constraints
==
NULL
)
{
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
context
.
getSystem
(),
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
context
.
getSystem
().
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
tol
);
}
if
(
constraints
==
NULL
)
constraints
=
new
ReferenceConstraints
(
context
.
getSystem
(),
(
RealOpenMM
)
tol
);
vector
<
RealVec
>&
positions
=
extractPositions
(
context
);
vector
<
RealVec
>&
velocities
=
extractVelocities
(
context
);
constraints
->
setTolerance
(
tol
);
constraints
->
applyToVelocities
(
data
.
numParticles
,
positions
,
velocities
,
inverseMasses
);
constraints
->
applyToVelocities
(
positions
,
velocities
,
inverseMasses
);
}
void
ReferenceVirtualSitesKernel
::
initialize
(
const
System
&
system
)
{
...
...
@@ -440,8 +420,8 @@ void ReferenceCalcCustomBondForceKernel::initialize(const System& system, const
// Parse the expression used to calculate the force.
Lepton
::
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
()).
optimize
();
energyExpression
=
expression
.
create
Program
();
forceExpression
=
expression
.
differentiate
(
"r"
).
optimize
().
createProgram
();
energyExpression
=
expression
.
create
CompiledExpression
();
forceExpression
=
expression
.
differentiate
(
"r"
).
createCompiledExpression
();
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
parameterNames
.
push_back
(
force
.
getPerBondParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
...
...
@@ -554,8 +534,8 @@ void ReferenceCalcCustomAngleForceKernel::initialize(const System& system, const
// Parse the expression used to calculate the force.
Lepton
::
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
()).
optimize
();
energyExpression
=
expression
.
create
Program
();
forceExpression
=
expression
.
differentiate
(
"theta"
).
optimize
().
createProgram
();
energyExpression
=
expression
.
create
CompiledExpression
();
forceExpression
=
expression
.
differentiate
(
"theta"
).
createCompiledExpression
();
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
parameterNames
.
push_back
(
force
.
getPerAngleParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
...
...
@@ -764,8 +744,8 @@ void ReferenceCalcCustomTorsionForceKernel::initialize(const System& system, con
// Parse the expression used to calculate the force.
Lepton
::
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
()).
optimize
();
energyExpression
=
expression
.
create
Program
();
forceExpression
=
expression
.
differentiate
(
"theta"
).
optimize
().
createProgram
();
energyExpression
=
expression
.
create
CompiledExpression
();
forceExpression
=
expression
.
differentiate
(
"theta"
).
createCompiledExpression
();
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
parameterNames
.
push_back
(
force
.
getPerTorsionParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
...
...
@@ -1048,8 +1028,8 @@ void ReferenceCalcCustomNonbondedForceKernel::initialize(const System& system, c
// Parse the various expressions used to calculate the force.
Lepton
::
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
).
optimize
();
energyExpression
=
expression
.
create
Program
();
forceExpression
=
expression
.
differentiate
(
"r"
).
optimize
().
createProgram
();
energyExpression
=
expression
.
create
CompiledExpression
();
forceExpression
=
expression
.
differentiate
(
"r"
).
createCompiledExpression
();
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
parameterNames
.
push_back
(
force
.
getPerParticleParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
...
...
@@ -1446,10 +1426,10 @@ void ReferenceCalcCustomExternalForceKernel::initialize(const System& system, co
// Parse the expression used to calculate the force.
Lepton
::
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
()).
optimize
();
energyExpression
=
expression
.
create
Program
();
forceExpressionX
=
expression
.
differentiate
(
"x"
).
optimize
().
createProgram
();
forceExpressionY
=
expression
.
differentiate
(
"y"
).
optimize
().
createProgram
();
forceExpressionZ
=
expression
.
differentiate
(
"z"
).
optimize
().
createProgram
();
energyExpression
=
expression
.
create
CompiledExpression
();
forceExpressionX
=
expression
.
differentiate
(
"x"
).
createCompiledExpression
();
forceExpressionY
=
expression
.
differentiate
(
"y"
).
createCompiledExpression
();
forceExpressionZ
=
expression
.
differentiate
(
"z"
).
createCompiledExpression
();
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
parameterNames
.
push_back
(
force
.
getPerParticleParameterName
(
i
));
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
...
...
@@ -1715,20 +1695,19 @@ void ReferenceIntegrateVerletStepKernel::initialize(const System& system, const
masses
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
vector
<
pair
<
int
,
int
>
>
constraintIndices
(
numConstraints
);
vector
<
RealOpenMM
>
constraintDistances
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
vector
<
pair
<
int
,
int
>
>
constraintIndices
;
vector
<
RealOpenMM
>
constraintDistances
;
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
system
,
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
system
.
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
numConstraints
=
constraintIndices
.
size
();
constraints
=
new
ReferenceConstraints
(
system
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
}
void
ReferenceIntegrateVerletStepKernel
::
execute
(
ContextImpl
&
context
,
const
VerletIntegrator
&
integrator
)
{
...
...
@@ -1767,21 +1746,20 @@ void ReferenceIntegrateLangevinStepKernel::initialize(const System& system, cons
masses
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
vector
<
pair
<
int
,
int
>
>
constraintIndices
(
numConstraints
);
vector
<
RealOpenMM
>
constraintDistances
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
vector
<
pair
<
int
,
int
>
>
constraintIndices
;
vector
<
RealOpenMM
>
constraintDistances
;
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
numConstraints
=
constraintIndices
.
size
();
SimTKOpenMMUtilities
::
setRandomNumberSeed
((
unsigned
int
)
integrator
.
getRandomNumberSeed
());
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
system
,
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
system
.
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
constraints
=
new
ReferenceConstraints
(
system
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
}
void
ReferenceIntegrateLangevinStepKernel
::
execute
(
ContextImpl
&
context
,
const
LangevinIntegrator
&
integrator
)
{
...
...
@@ -1829,21 +1807,20 @@ void ReferenceIntegrateBrownianStepKernel::initialize(const System& system, cons
masses
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
vector
<
pair
<
int
,
int
>
>
constraintIndices
(
numConstraints
);
vector
<
RealOpenMM
>
constraintDistances
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
vector
<
pair
<
int
,
int
>
>
constraintIndices
;
vector
<
RealOpenMM
>
constraintDistances
;
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
numConstraints
=
constraintIndices
.
size
();
SimTKOpenMMUtilities
::
setRandomNumberSeed
((
unsigned
int
)
integrator
.
getRandomNumberSeed
());
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
system
,
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
system
.
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
constraints
=
new
ReferenceConstraints
(
system
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
}
void
ReferenceIntegrateBrownianStepKernel
::
execute
(
ContextImpl
&
context
,
const
BrownianIntegrator
&
integrator
)
{
...
...
@@ -1890,21 +1867,20 @@ void ReferenceIntegrateVariableLangevinStepKernel::initialize(const System& syst
masses
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
vector
<
pair
<
int
,
int
>
>
constraintIndices
(
numConstraints
);
vector
<
RealOpenMM
>
constraintDistances
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
vector
<
pair
<
int
,
int
>
>
constraintIndices
;
vector
<
RealOpenMM
>
constraintDistances
;
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
numConstraints
=
constraintIndices
.
size
();
SimTKOpenMMUtilities
::
setRandomNumberSeed
((
unsigned
int
)
integrator
.
getRandomNumberSeed
());
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
system
,
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
system
.
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
constraints
=
new
ReferenceConstraints
(
system
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
}
double
ReferenceIntegrateVariableLangevinStepKernel
::
execute
(
ContextImpl
&
context
,
const
VariableLangevinIntegrator
&
integrator
,
double
maxTime
)
{
...
...
@@ -1952,20 +1928,19 @@ void ReferenceIntegrateVariableVerletStepKernel::initialize(const System& system
masses
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
vector
<
pair
<
int
,
int
>
>
constraintIndices
(
numConstraints
);
vector
<
RealOpenMM
>
constraintDistances
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
vector
<
pair
<
int
,
int
>
>
constraintIndices
;
vector
<
RealOpenMM
>
constraintDistances
;
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
system
,
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
system
.
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
numConstraints
=
constraintIndices
.
size
();
constraints
=
new
ReferenceConstraints
(
system
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
}
double
ReferenceIntegrateVariableVerletStepKernel
::
execute
(
ContextImpl
&
context
,
const
VariableVerletIntegrator
&
integrator
,
double
maxTime
)
{
...
...
@@ -2008,17 +1983,18 @@ void ReferenceIntegrateCustomStepKernel::initialize(const System& system, const
masses
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
static_cast
<
RealOpenMM
>
(
system
.
getParticleMass
(
i
));
numConstraints
=
system
.
getNumConstraints
();
vector
<
pair
<
int
,
int
>
>
constraintIndices
(
numConstraints
);
vector
<
RealOpenMM
>
constraintDistances
(
numConstraints
);
for
(
int
i
=
0
;
i
<
numConstraints
;
++
i
)
{
vector
<
pair
<
int
,
int
>
>
constraintIndices
;
vector
<
RealOpenMM
>
constraintDistances
;
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
++
i
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
i
,
particle1
,
particle2
,
distance
);
constraintIndices
[
i
].
first
=
particle1
;
constraintIndices
[
i
].
second
=
particle2
;
constraintDistances
[
i
]
=
static_cast
<
RealOpenMM
>
(
distance
);
if
(
system
.
getParticleMass
(
particle1
)
!=
0
||
system
.
getParticleMass
(
particle2
)
!=
0
)
{
constraintIndices
.
push_back
(
make_pair
(
particle1
,
particle2
));
constraintDistances
.
push_back
(
distance
);
}
}
numConstraints
=
constraintIndices
.
size
();
perDofValues
.
resize
(
integrator
.
getNumPerDofVariables
());
for
(
int
i
=
0
;
i
<
(
int
)
perDofValues
.
size
();
i
++
)
perDofValues
[
i
].
resize
(
numParticles
);
...
...
@@ -2027,9 +2003,7 @@ void ReferenceIntegrateCustomStepKernel::initialize(const System& system, const
dynamics
=
new
ReferenceCustomDynamics
(
system
.
getNumParticles
(),
integrator
);
SimTKOpenMMUtilities
::
setRandomNumberSeed
((
unsigned
int
)
integrator
.
getRandomNumberSeed
());
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
findAnglesForCCMA
(
system
,
angles
);
constraints
=
new
ReferenceCCMAAlgorithm
(
system
.
getNumParticles
(),
numConstraints
,
constraintIndices
,
constraintDistances
,
masses
,
angles
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
constraints
=
new
ReferenceConstraints
(
system
,
(
RealOpenMM
)
integrator
.
getConstraintTolerance
());
dynamics
->
setReferenceConstraintAlgorithm
(
constraints
);
}
...
...
platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp
View file @
855ece90
/* Portions copyright (c) 2006-201
2
Stanford University and Simbios.
/* Portions copyright (c) 2006-201
3
Stanford University and Simbios.
* Contributors: Peter Eastman, Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -161,8 +161,8 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<Real
}
}
ReferenceConstraintAlgorithm
*
referenceConstraintAlgorithm
=
getReferenceConstraintAlgorithm
();
if
(
referenceConstraintAlgorithm
)
referenceConstraintAlgorithm
->
apply
(
numberOfAtoms
,
atomCoordinates
,
xPrime
,
inverseMasses
);
if
(
referenceConstraintAlgorithm
)
referenceConstraintAlgorithm
->
apply
(
atomCoordinates
,
xPrime
,
inverseMasses
);
// Update the positions and velocities.
...
...
platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp
View file @
855ece90
/* Portions copyright (c) 2006-20
09
Stanford University and Simbios.
/* Portions copyright (c) 2006-20
13
Stanford University and Simbios.
* Contributors: Peter Eastman, Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -31,6 +31,7 @@
#include "ReferenceCCMAAlgorithm.h"
#include "ReferenceDynamics.h"
#include "quern.h"
#include "openmm/OpenMMException.h"
#include "openmm/Vec3.h"
#include <map>
...
...
@@ -38,501 +39,269 @@ using std::map;
using
std
::
pair
;
using
std
::
vector
;
using
std
::
set
;
using
OpenMM
::
OpenMMException
;
using
OpenMM
::
Vec3
;
using
OpenMM
::
RealVec
;
/**---------------------------------------------------------------------------------------
ReferenceCCMAAlgorithm constructor
@param numberOfAtoms number of atoms
@param numberOfConstraints number of constraints
@param atomIndices atom indices for contraints
@param distance distances for constraints
@param masses atom masses
@param angles angle force field terms
@param tolerance constraint tolerance
--------------------------------------------------------------------------------------- */
ReferenceCCMAAlgorithm
::
ReferenceCCMAAlgorithm
(
int
numberOfAtoms
,
ReferenceCCMAAlgorithm
::
ReferenceCCMAAlgorithm
(
int
numberOfAtoms
,
int
numberOfConstraints
,
const
vector
<
pair
<
int
,
int
>
>&
atomIndices
,
const
vector
<
RealOpenMM
>&
distance
,
vector
<
RealOpenMM
>&
masses
,
vector
<
AngleInfo
>&
angles
,
RealOpenMM
tolerance
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm";
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
// ---------------------------------------------------------------------------------------
_numberOfConstraints
=
numberOfConstraints
;
_atomIndices
=
atomIndices
;
_distance
=
distance
;
_maximumNumberOfIterations
=
150
;
_tolerance
=
tolerance
;
_hasInitializedMasses
=
false
;
// work arrays
if
(
_numberOfConstraints
>
0
)
{
_r_ij
.
resize
(
numberOfConstraints
);
_d_ij2
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
zero
,
"dij_2"
);
_distanceTolerance
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
zero
,
"distanceTolerance"
);
_reducedMasses
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
zero
,
"reducedMasses"
);
}
if
(
numberOfConstraints
>
0
)
{
// Compute the constraint coupling matrix
vector
<
vector
<
int
>
>
atomAngles
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
(
int
)
angles
.
size
();
i
++
)
atomAngles
[
angles
[
i
].
atom2
].
push_back
(
i
);
vector
<
vector
<
pair
<
int
,
double
>
>
>
matrix
(
numberOfConstraints
);
for
(
int
j
=
0
;
j
<
numberOfConstraints
;
j
++
)
{
for
(
int
k
=
0
;
k
<
numberOfConstraints
;
k
++
)
{
if
(
j
==
k
)
{
matrix
[
j
].
push_back
(
pair
<
int
,
double
>
(
j
,
1.0
));
continue
;
}
double
scale
;
int
atomj0
=
_atomIndices
[
j
].
first
;
int
atomj1
=
_atomIndices
[
j
].
second
;
int
atomk0
=
_atomIndices
[
k
].
first
;
int
atomk1
=
_atomIndices
[
k
].
second
;
RealOpenMM
invMass0
=
one
/
masses
[
atomj0
];
RealOpenMM
invMass1
=
one
/
masses
[
atomj1
];
int
atoma
,
atomb
,
atomc
;
if
(
atomj0
==
atomk0
)
{
atoma
=
atomj1
;
atomb
=
atomj0
;
atomc
=
atomk1
;
scale
=
invMass0
/
(
invMass0
+
invMass1
);
}
else
if
(
atomj1
==
atomk1
)
{
atoma
=
atomj0
;
atomb
=
atomj1
;
atomc
=
atomk0
;
scale
=
invMass1
/
(
invMass0
+
invMass1
);
}
else
if
(
atomj0
==
atomk1
)
{
atoma
=
atomj1
;
atomb
=
atomj0
;
atomc
=
atomk0
;
scale
=
invMass0
/
(
invMass0
+
invMass1
);
}
else
if
(
atomj1
==
atomk0
)
{
atoma
=
atomj0
;
atomb
=
atomj1
;
atomc
=
atomk1
;
scale
=
invMass1
/
(
invMass0
+
invMass1
);
}
else
continue
;
// These constraints are not connected.
// Look for a third constraint forming a triangle with these two.
bool
foundConstraint
=
false
;
for
(
int
other
=
0
;
other
<
numberOfConstraints
;
other
++
)
{
if
((
_atomIndices
[
other
].
first
==
atoma
&&
_atomIndices
[
other
].
second
==
atomc
)
||
(
_atomIndices
[
other
].
first
==
atomc
&&
_atomIndices
[
other
].
second
==
atoma
))
{
double
d1
=
_distance
[
j
];
double
d2
=
_distance
[
k
];
double
d3
=
_distance
[
other
];
matrix
[
j
].
push_back
(
pair
<
int
,
double
>
(
k
,
scale
*
(
d1
*
d1
+
d2
*
d2
-
d3
*
d3
)
/
(
2.0
*
d1
*
d2
)));
foundConstraint
=
true
;
break
;
}
}
if
(
!
foundConstraint
)
{
// We didn't find one, so look for an angle force field term.
const
vector
<
int
>&
angleCandidates
=
atomAngles
[
atomb
];
for
(
vector
<
int
>::
const_iterator
iter
=
angleCandidates
.
begin
();
iter
!=
angleCandidates
.
end
();
iter
++
)
{
const
AngleInfo
&
angle
=
angles
[
*
iter
];
if
((
angle
.
atom1
==
atoma
&&
angle
.
atom3
==
atomc
)
||
(
angle
.
atom3
==
atoma
&&
angle
.
atom1
==
atomc
))
{
matrix
[
j
].
push_back
(
pair
<
int
,
double
>
(
k
,
scale
*
cos
(
angle
.
angle
)));
break
;
}
}
}
}
}
// Invert it using QR.
vector
<
int
>
matrixRowStart
;
vector
<
int
>
matrixColIndex
;
vector
<
double
>
matrixValue
;
for
(
int
i
=
0
;
i
<
numberOfConstraints
;
i
++
)
{
matrixRowStart
.
push_back
(
matrixValue
.
size
());
for
(
int
j
=
0
;
j
<
(
int
)
matrix
[
i
].
size
();
j
++
)
{
pair
<
int
,
double
>
element
=
matrix
[
i
][
j
];
matrixColIndex
.
push_back
(
element
.
first
);
matrixValue
.
push_back
(
element
.
second
);
}
}
matrixRowStart
.
push_back
(
matrixValue
.
size
());
int
*
qRowStart
,
*
qColIndex
,
*
rRowStart
,
*
rColIndex
;
double
*
qValue
,
*
rValue
;
QUERN_compute_qr
(
numberOfConstraints
,
numberOfConstraints
,
&
matrixRowStart
[
0
],
&
matrixColIndex
[
0
],
&
matrixValue
[
0
],
NULL
,
&
qRowStart
,
&
qColIndex
,
&
qValue
,
&
rRowStart
,
&
rColIndex
,
&
rValue
);
vector
<
double
>
rhs
(
numberOfConstraints
);
_matrix
.
resize
(
numberOfConstraints
);
for
(
int
i
=
0
;
i
<
numberOfConstraints
;
i
++
)
{
// Extract column i of the inverse matrix.
for
(
int
j
=
0
;
j
<
numberOfConstraints
;
j
++
)
rhs
[
j
]
=
(
i
==
j
?
1.0
:
0.0
);
QUERN_multiply_with_q_transpose
(
numberOfConstraints
,
qRowStart
,
qColIndex
,
qValue
,
&
rhs
[
0
]);
QUERN_solve_with_r
(
numberOfConstraints
,
rRowStart
,
rColIndex
,
rValue
,
&
rhs
[
0
],
&
rhs
[
0
]);
for
(
int
j
=
0
;
j
<
numberOfConstraints
;
j
++
)
{
double
value
=
rhs
[
j
]
*
_distance
[
i
]
/
_distance
[
j
];
if
(
FABS
((
RealOpenMM
)
value
)
>
0.02
)
_matrix
[
j
].
push_back
(
pair
<
int
,
RealOpenMM
>
(
i
,
(
RealOpenMM
)
value
));
}
}
QUERN_free_result
(
qRowStart
,
qColIndex
,
qValue
);
QUERN_free_result
(
rRowStart
,
rColIndex
,
rValue
);
}
}
/**---------------------------------------------------------------------------------------
RealOpenMM
tolerance
)
{
_numberOfConstraints
=
numberOfConstraints
;
_atomIndices
=
atomIndices
;
_distance
=
distance
;
ReferenceCCMAAlgorithm destructor
_maximumNumberOfIterations
=
150
;
_tolerance
=
tolerance
;
_hasInitializedMasses
=
false
;
--------------------------------------------------------------------------------------- */
ReferenceCCMAAlgorithm
::~
ReferenceCCMAAlgorithm
(
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::~ReferenceCCMAAlgorithm";
// ---------------------------------------------------------------------------------------
// work arrays
if
(
_numberOfConstraints
>
0
)
{
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_d_ij2
,
"d_ij2"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_distanceTolerance
,
"distanceTolerance"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_reducedMasses
,
"reducedMasses"
);
_r_ij
.
resize
(
numberOfConstraints
);
_d_ij2
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
0.0
,
"dij_2"
);
_distanceTolerance
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
0.0
,
"distanceTolerance"
);
_reducedMasses
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
0.0
,
"reducedMasses"
);
}
if
(
numberOfConstraints
>
0
)
{
// Compute the constraint coupling matrix
vector
<
vector
<
int
>
>
atomAngles
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
(
int
)
angles
.
size
();
i
++
)
atomAngles
[
angles
[
i
].
atom2
].
push_back
(
i
);
vector
<
vector
<
pair
<
int
,
double
>
>
>
matrix
(
numberOfConstraints
);
for
(
int
j
=
0
;
j
<
numberOfConstraints
;
j
++
)
{
for
(
int
k
=
0
;
k
<
numberOfConstraints
;
k
++
)
{
if
(
j
==
k
)
{
matrix
[
j
].
push_back
(
pair
<
int
,
double
>
(
j
,
1.0
));
continue
;
}
double
scale
;
int
atomj0
=
_atomIndices
[
j
].
first
;
int
atomj1
=
_atomIndices
[
j
].
second
;
int
atomk0
=
_atomIndices
[
k
].
first
;
int
atomk1
=
_atomIndices
[
k
].
second
;
RealOpenMM
invMass0
=
1
/
masses
[
atomj0
];
RealOpenMM
invMass1
=
1
/
masses
[
atomj1
];
int
atoma
,
atomb
,
atomc
;
if
(
atomj0
==
atomk0
)
{
atoma
=
atomj1
;
atomb
=
atomj0
;
atomc
=
atomk1
;
scale
=
invMass0
/
(
invMass0
+
invMass1
);
}
else
if
(
atomj1
==
atomk1
)
{
atoma
=
atomj0
;
atomb
=
atomj1
;
atomc
=
atomk0
;
scale
=
invMass1
/
(
invMass0
+
invMass1
);
}
else
if
(
atomj0
==
atomk1
)
{
atoma
=
atomj1
;
atomb
=
atomj0
;
atomc
=
atomk0
;
scale
=
invMass0
/
(
invMass0
+
invMass1
);
}
else
if
(
atomj1
==
atomk0
)
{
atoma
=
atomj0
;
atomb
=
atomj1
;
atomc
=
atomk1
;
scale
=
invMass1
/
(
invMass0
+
invMass1
);
}
else
continue
;
// These constraints are not connected.
// Look for a third constraint forming a triangle with these two.
bool
foundConstraint
=
false
;
for
(
int
other
=
0
;
other
<
numberOfConstraints
;
other
++
)
{
if
((
_atomIndices
[
other
].
first
==
atoma
&&
_atomIndices
[
other
].
second
==
atomc
)
||
(
_atomIndices
[
other
].
first
==
atomc
&&
_atomIndices
[
other
].
second
==
atoma
))
{
double
d1
=
_distance
[
j
];
double
d2
=
_distance
[
k
];
double
d3
=
_distance
[
other
];
matrix
[
j
].
push_back
(
pair
<
int
,
double
>
(
k
,
scale
*
(
d1
*
d1
+
d2
*
d2
-
d3
*
d3
)
/
(
2.0
*
d1
*
d2
)));
foundConstraint
=
true
;
break
;
}
}
if
(
!
foundConstraint
)
{
// We didn't find one, so look for an angle force field term.
const
vector
<
int
>&
angleCandidates
=
atomAngles
[
atomb
];
for
(
vector
<
int
>::
const_iterator
iter
=
angleCandidates
.
begin
();
iter
!=
angleCandidates
.
end
();
iter
++
)
{
const
AngleInfo
&
angle
=
angles
[
*
iter
];
if
((
angle
.
atom1
==
atoma
&&
angle
.
atom3
==
atomc
)
||
(
angle
.
atom3
==
atoma
&&
angle
.
atom1
==
atomc
))
{
matrix
[
j
].
push_back
(
pair
<
int
,
double
>
(
k
,
scale
*
cos
(
angle
.
angle
)));
break
;
}
}
}
}
}
// Invert it using QR.
vector
<
int
>
matrixRowStart
;
vector
<
int
>
matrixColIndex
;
vector
<
double
>
matrixValue
;
for
(
int
i
=
0
;
i
<
numberOfConstraints
;
i
++
)
{
matrixRowStart
.
push_back
(
matrixValue
.
size
());
for
(
int
j
=
0
;
j
<
(
int
)
matrix
[
i
].
size
();
j
++
)
{
pair
<
int
,
double
>
element
=
matrix
[
i
][
j
];
matrixColIndex
.
push_back
(
element
.
first
);
matrixValue
.
push_back
(
element
.
second
);
}
}
matrixRowStart
.
push_back
(
matrixValue
.
size
());
int
*
qRowStart
,
*
qColIndex
,
*
rRowStart
,
*
rColIndex
;
double
*
qValue
,
*
rValue
;
QUERN_compute_qr
(
numberOfConstraints
,
numberOfConstraints
,
&
matrixRowStart
[
0
],
&
matrixColIndex
[
0
],
&
matrixValue
[
0
],
NULL
,
&
qRowStart
,
&
qColIndex
,
&
qValue
,
&
rRowStart
,
&
rColIndex
,
&
rValue
);
vector
<
double
>
rhs
(
numberOfConstraints
);
_matrix
.
resize
(
numberOfConstraints
);
for
(
int
i
=
0
;
i
<
numberOfConstraints
;
i
++
)
{
// Extract column i of the inverse matrix.
for
(
int
j
=
0
;
j
<
numberOfConstraints
;
j
++
)
rhs
[
j
]
=
(
i
==
j
?
1.0
:
0.0
);
QUERN_multiply_with_q_transpose
(
numberOfConstraints
,
qRowStart
,
qColIndex
,
qValue
,
&
rhs
[
0
]);
QUERN_solve_with_r
(
numberOfConstraints
,
rRowStart
,
rColIndex
,
rValue
,
&
rhs
[
0
],
&
rhs
[
0
]);
for
(
int
j
=
0
;
j
<
numberOfConstraints
;
j
++
)
{
double
value
=
rhs
[
j
]
*
_distance
[
i
]
/
_distance
[
j
];
if
(
FABS
((
RealOpenMM
)
value
)
>
0.02
)
_matrix
[
j
].
push_back
(
pair
<
int
,
RealOpenMM
>
(
i
,
(
RealOpenMM
)
value
));
}
}
QUERN_free_result
(
qRowStart
,
qColIndex
,
qValue
);
QUERN_free_result
(
rRowStart
,
rColIndex
,
rValue
);
}
}
/**---------------------------------------------------------------------------------------
Get number of constraints
@return number of constraints
--------------------------------------------------------------------------------------- */
int
ReferenceCCMAAlgorithm
::
getNumberOfConstraints
(
void
)
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::getNumberOfConstraints";
// ---------------------------------------------------------------------------------------
return
_numberOfConstraints
;
ReferenceCCMAAlgorithm
::~
ReferenceCCMAAlgorithm
()
{
if
(
_numberOfConstraints
>
0
)
{
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_d_ij2
,
"d_ij2"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_distanceTolerance
,
"distanceTolerance"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_reducedMasses
,
"reducedMasses"
);
}
}
/**---------------------------------------------------------------------------------------
Get maximum number of iterations
@return maximum number of iterations
--------------------------------------------------------------------------------------- */
int
ReferenceCCMAAlgorithm
::
getMaximumNumberOfIterations
(
void
)
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::getMaximumNumberOfIterations";
// ---------------------------------------------------------------------------------------
return
_maximumNumberOfIterations
;
int
ReferenceCCMAAlgorithm
::
getNumberOfConstraints
()
const
{
return
_numberOfConstraints
;
}
/**---------------------------------------------------------------------------------------
Set maximum number of iterations
@param maximumNumberOfIterations new maximum number of iterations
--------------------------------------------------------------------------------------- */
void
ReferenceCCMAAlgorithm
::
setMaximumNumberOfIterations
(
int
maximumNumberOfIterations
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::setMaximumNumberOfIterations";
// ---------------------------------------------------------------------------------------
_maximumNumberOfIterations
=
maximumNumberOfIterations
;
int
ReferenceCCMAAlgorithm
::
getMaximumNumberOfIterations
()
const
{
return
_maximumNumberOfIterations
;
}
/**---------------------------------------------------------------------------------------
Get tolerance
@return tolerance
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceCCMAAlgorithm
::
getTolerance
(
void
)
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::getTolerance";
// ---------------------------------------------------------------------------------------
return
_tolerance
;
void
ReferenceCCMAAlgorithm
::
setMaximumNumberOfIterations
(
int
maximumNumberOfIterations
)
{
_maximumNumberOfIterations
=
maximumNumberOfIterations
;
}
/**---------------------------------------------------------------------------------------
Set tolerance
@param tolerance new tolerance
--------------------------------------------------------------------------------------- */
void
ReferenceCCMAAlgorithm
::
setTolerance
(
RealOpenMM
tolerance
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCCMAAlgorithm::setTolerance";
// ---------------------------------------------------------------------------------------
_tolerance
=
tolerance
;;
RealOpenMM
ReferenceCCMAAlgorithm
::
getTolerance
()
const
{
return
_tolerance
;
}
/**---------------------------------------------------------------------------------------
Apply CCMA algorithm
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomCoordinatesP atom coordinates prime
@param inverseMasses 1/mass
@return SimTKOpenMMCommon::DefaultReturn if converge; else
return SimTKOpenMMCommon::ErrorReturn
--------------------------------------------------------------------------------------- */
void
ReferenceCCMAAlgorithm
::
setTolerance
(
RealOpenMM
tolerance
)
{
_tolerance
=
tolerance
;
}
int
ReferenceCCMAAlgorithm
::
apply
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
void
ReferenceCCMAAlgorithm
::
apply
(
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
){
return
applyConstraints
(
numberOfAtoms
,
atomCoordinates
,
atomCoordinatesP
,
inverseMasses
,
false
);
vector
<
RealOpenMM
>&
inverseMasses
)
{
applyConstraints
(
atomCoordinates
,
atomCoordinatesP
,
inverseMasses
,
false
);
}
/**---------------------------------------------------------------------------------------
Apply constraint algorithm to velocities.
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param velocities atom velocities
@param inverseMasses 1/mass
@return SimTKOpenMMCommon::DefaultReturn if converge; else
return SimTKOpenMMCommon::ErrorReturn
--------------------------------------------------------------------------------------- */
int
ReferenceCCMAAlgorithm
::
applyToVelocities
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
void
ReferenceCCMAAlgorithm
::
applyToVelocities
(
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
velocities
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
)
{
return
applyConstraints
(
numberOfAtoms
,
atomCoordinates
,
velocities
,
inverseMasses
,
true
);
applyConstraints
(
atomCoordinates
,
velocities
,
inverseMasses
,
true
);
}
int
ReferenceCCMAAlgorithm
::
applyConstraints
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
void
ReferenceCCMAAlgorithm
::
applyConstraints
(
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
,
bool
constrainingVelocities
){
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceCCMAAlgorithm::apply"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
half
=
0.5
;
static
const
RealOpenMM
epsilon6
=
(
RealOpenMM
)
1.0e-06
;
// ---------------------------------------------------------------------------------------
// temp arrays
vector
<
RealVec
>&
r_ij
=
_r_ij
;
RealOpenMM
*
d_ij2
=
_d_ij2
;
RealOpenMM
*
reducedMasses
=
_reducedMasses
;
// calculate reduced masses on 1st pass
if
(
!
_hasInitializedMasses
){
_hasInitializedMasses
=
true
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
reducedMasses
[
ii
]
=
half
/
(
inverseMasses
[
atomI
]
+
inverseMasses
[
atomJ
]
);
}
}
// setup: r_ij for each (i,j) constraint
RealOpenMM
tolerance
=
getTolerance
();
tolerance
*=
two
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
r_ij
[
ii
]
=
atomCoordinates
[
atomI
]
-
atomCoordinates
[
atomJ
];
d_ij2
[
ii
]
=
r_ij
[
ii
].
dot
(
r_ij
[
ii
]);
}
RealOpenMM
lowerTol
=
one
-
two
*
getTolerance
()
+
getTolerance
()
*
getTolerance
();
RealOpenMM
upperTol
=
one
+
two
*
getTolerance
()
+
getTolerance
()
*
getTolerance
();
// main loop
int
iterations
=
0
;
int
numberConverged
=
0
;
vector
<
RealOpenMM
>
constraintDelta
(
_numberOfConstraints
);
vector
<
RealOpenMM
>
tempDelta
(
_numberOfConstraints
);
while
(
iterations
<
getMaximumNumberOfIterations
())
{
numberConverged
=
0
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
RealVec
rp_ij
=
atomCoordinatesP
[
atomI
]
-
atomCoordinatesP
[
atomJ
];
if
(
constrainingVelocities
)
{
RealOpenMM
rrpr
=
rp_ij
.
dot
(
r_ij
[
ii
]);
constraintDelta
[
ii
]
=
-
2
*
reducedMasses
[
ii
]
*
rrpr
/
d_ij2
[
ii
];
if
(
fabs
(
constraintDelta
[
ii
])
<=
getTolerance
())
numberConverged
++
;
}
else
{
RealOpenMM
rp2
=
rp_ij
.
dot
(
rp_ij
);
RealOpenMM
dist2
=
_distance
[
ii
]
*
_distance
[
ii
];
RealOpenMM
diff
=
dist2
-
rp2
;
constraintDelta
[
ii
]
=
zero
;
RealOpenMM
rrpr
=
DOT3
(
rp_ij
,
r_ij
[
ii
]
);
if
(
rrpr
<
d_ij2
[
ii
]
*
epsilon6
){
std
::
stringstream
message
;
message
<<
iterations
<<
" "
<<
atomI
<<
" "
<<
atomJ
<<
" Error: sign of rrpr < 0?
\n
"
;
SimTKOpenMMLog
::
printMessage
(
message
);
}
else
{
constraintDelta
[
ii
]
=
reducedMasses
[
ii
]
*
diff
/
rrpr
;
}
if
(
rp2
>=
lowerTol
*
dist2
&&
rp2
<=
upperTol
*
dist2
)
numberConverged
++
;
}
}
if
(
numberConverged
==
_numberOfConstraints
)
break
;
iterations
++
;
if
(
_matrix
.
size
()
>
0
)
{
for
(
int
i
=
0
;
i
<
_numberOfConstraints
;
i
++
)
{
RealOpenMM
sum
=
0.0
;
for
(
int
j
=
0
;
j
<
(
int
)
_matrix
[
i
].
size
();
j
++
)
{
pair
<
int
,
RealOpenMM
>
element
=
_matrix
[
i
][
j
];
sum
+=
element
.
second
*
constraintDelta
[
element
.
first
];
}
tempDelta
[
i
]
=
sum
;
}
constraintDelta
=
tempDelta
;
}
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
RealVec
dr
=
r_ij
[
ii
]
*
constraintDelta
[
ii
];
atomCoordinatesP
[
atomI
]
+=
dr
*
inverseMasses
[
atomI
];
atomCoordinatesP
[
atomJ
]
-=
dr
*
inverseMasses
[
atomJ
];
}
}
return
(
numberConverged
==
_numberOfConstraints
?
SimTKOpenMMCommon
::
DefaultReturn
:
SimTKOpenMMCommon
::
ErrorReturn
);
}
/**---------------------------------------------------------------------------------------
Report any violated constriants
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param message report
@return number of violated constraints
--------------------------------------------------------------------------------------- */
int
ReferenceCCMAAlgorithm
::
reportCCMA
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
std
::
stringstream
&
message
){
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceCCMAAlgorithm::reportCCMA"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
RealOpenMM
half
=
0.5
;
// ---------------------------------------------------------------------------------------
int
numberOfConstraints
=
getNumberOfConstraints
();
// loop over constraints calculating distance and comparing to
// expected distance -- report any contraints that are violated
int
numberConverged
=
0
;
RealOpenMM
tolerance
=
getTolerance
();
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
RealOpenMM
rp2
=
zero
;
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
){
rp2
+=
(
atomCoordinates
[
atomI
][
jj
]
-
atomCoordinates
[
atomJ
][
jj
])
*
(
atomCoordinates
[
atomI
][
jj
]
-
atomCoordinates
[
atomJ
][
jj
]);
}
RealOpenMM
diff
=
FABS
(
rp2
-
(
_distance
[
ii
]
*
_distance
[
ii
])
);
if
(
diff
>
tolerance
){
message
<<
ii
<<
" constraint violated: "
<<
atomI
<<
" "
<<
atomJ
<<
"] d="
<<
SQRT
(
rp2
)
<<
" "
<<
rp2
<<
" d0="
<<
_distance
[
ii
];
message
<<
" diff="
<<
diff
;
message
<<
" ["
<<
atomCoordinates
[
atomI
][
0
]
<<
" "
<<
atomCoordinates
[
atomI
][
1
]
<<
" "
<<
atomCoordinates
[
atomI
][
2
]
<<
"] "
;
message
<<
" ["
<<
atomCoordinates
[
atomJ
][
0
]
<<
" "
<<
atomCoordinates
[
atomJ
][
1
]
<<
" "
<<
atomCoordinates
[
atomJ
][
2
]
<<
"] "
;
message
<<
"
\n
"
;
}
else
{
numberConverged
++
;
}
}
vector
<
RealOpenMM
>&
inverseMasses
,
bool
constrainingVelocities
)
{
// temp arrays
vector
<
RealVec
>&
r_ij
=
_r_ij
;
RealOpenMM
*
d_ij2
=
_d_ij2
;
RealOpenMM
*
reducedMasses
=
_reducedMasses
;
// calculate reduced masses on 1st pass
if
(
!
_hasInitializedMasses
)
{
_hasInitializedMasses
=
true
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
)
{
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
reducedMasses
[
ii
]
=
0.5
/
(
inverseMasses
[
atomI
]
+
inverseMasses
[
atomJ
]);
}
}
return
(
numberOfConstraints
-
numberConverged
);
// setup: r_ij for each (i,j) constraint
RealOpenMM
tolerance
=
getTolerance
()
*
2
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
)
{
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
r_ij
[
ii
]
=
atomCoordinates
[
atomI
]
-
atomCoordinates
[
atomJ
];
d_ij2
[
ii
]
=
r_ij
[
ii
].
dot
(
r_ij
[
ii
]);
}
RealOpenMM
lowerTol
=
1
-
2
*
getTolerance
()
+
getTolerance
()
*
getTolerance
();
RealOpenMM
upperTol
=
1
+
2
*
getTolerance
()
+
getTolerance
()
*
getTolerance
();
// main loop
int
iterations
=
0
;
int
numberConverged
=
0
;
vector
<
RealOpenMM
>
constraintDelta
(
_numberOfConstraints
);
vector
<
RealOpenMM
>
tempDelta
(
_numberOfConstraints
);
while
(
iterations
<
getMaximumNumberOfIterations
())
{
numberConverged
=
0
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
)
{
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
RealVec
rp_ij
=
atomCoordinatesP
[
atomI
]
-
atomCoordinatesP
[
atomJ
];
if
(
constrainingVelocities
)
{
RealOpenMM
rrpr
=
rp_ij
.
dot
(
r_ij
[
ii
]);
constraintDelta
[
ii
]
=
-
2
*
reducedMasses
[
ii
]
*
rrpr
/
d_ij2
[
ii
];
if
(
fabs
(
constraintDelta
[
ii
])
<=
getTolerance
())
numberConverged
++
;
}
else
{
RealOpenMM
rp2
=
rp_ij
.
dot
(
rp_ij
);
RealOpenMM
dist2
=
_distance
[
ii
]
*
_distance
[
ii
];
RealOpenMM
diff
=
dist2
-
rp2
;
constraintDelta
[
ii
]
=
0
;
RealOpenMM
rrpr
=
DOT3
(
rp_ij
,
r_ij
[
ii
]);
constraintDelta
[
ii
]
=
reducedMasses
[
ii
]
*
diff
/
rrpr
;
if
(
rp2
>=
lowerTol
*
dist2
&&
rp2
<=
upperTol
*
dist2
)
numberConverged
++
;
}
}
if
(
numberConverged
==
_numberOfConstraints
)
break
;
iterations
++
;
if
(
_matrix
.
size
()
>
0
)
{
for
(
int
i
=
0
;
i
<
_numberOfConstraints
;
i
++
)
{
RealOpenMM
sum
=
0.0
;
for
(
int
j
=
0
;
j
<
(
int
)
_matrix
[
i
].
size
();
j
++
)
{
pair
<
int
,
RealOpenMM
>
element
=
_matrix
[
i
][
j
];
sum
+=
element
.
second
*
constraintDelta
[
element
.
first
];
}
tempDelta
[
i
]
=
sum
;
}
constraintDelta
=
tempDelta
;
}
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
)
{
int
atomI
=
_atomIndices
[
ii
].
first
;
int
atomJ
=
_atomIndices
[
ii
].
second
;
RealVec
dr
=
r_ij
[
ii
]
*
constraintDelta
[
ii
];
atomCoordinatesP
[
atomI
]
+=
dr
*
inverseMasses
[
atomI
];
atomCoordinatesP
[
atomJ
]
-=
dr
*
inverseMasses
[
atomJ
];
}
}
}
platforms/reference/src/SimTKReference/ReferenceConstraint.cpp
deleted
100644 → 0
View file @
471bea82
/* Portions copyright (c) 2006 Stanford University and Simbios.
* Contributors: Pande Group
*
* 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 <string.h>
#include <sstream>
#include "SimTKOpenMMCommon.h"
#include "SimTKOpenMMLog.h"
#include "SimTKOpenMMUtilities.h"
#include "ReferenceConstraint.h"
#include "ReferenceDynamics.h"
/**---------------------------------------------------------------------------------------
ReferenceConstraint constructor
--------------------------------------------------------------------------------------- */
ReferenceConstraint
::
ReferenceConstraint
(
){
// ---------------------------------------------------------------------------------------
//static const char* methodName = "\nReferenceConstraint::ReferenceConstraint";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
ReferenceConstraint destructor
--------------------------------------------------------------------------------------- */
ReferenceConstraint
::~
ReferenceConstraint
(
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceConstraint::~ReferenceConstraint";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
ReferenceShakeConstraint constructor
@param numberOfAtoms number of atoms
@param deltaT delta t for dynamics
@param tau viscosity
@param temperature temperature
--------------------------------------------------------------------------------------- */
ReferenceShakeConstraint
::
ReferenceShakeConstraint
(
int
atomIndex1
,
int
atomIndex2
,
RealOpenMM
constraintDistance
,
RealOpenMM
inverseMass1
,
RealOpenMM
inverseMass2
)
:
ReferenceConstraint
(
)
{
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceShakeConstraint::ReferenceShakeConstraint"
;
// ---------------------------------------------------------------------------------------
// insure heavy atom is in 0 slot
if
(
inverseMass1
>
inverseMass2
){
int
temp
=
atomIndex1
;
atomIndex1
=
atomIndex2
;
atomIndex2
=
temp
;
RealOpenMM
tempR
=
inverseMass1
;
inverseMass1
=
inverseMass2
;
inverseMass2
=
tempR
;
}
_atomIndices
[
0
]
=
atomIndex1
;
_atomIndices
[
1
]
=
atomIndex2
;
_inverseMasses
[
0
]
=
inverseMass1
;
_inverseMasses
[
1
]
=
inverseMass2
;
_constraintDistance
=
constraintDistance
;
}
/**---------------------------------------------------------------------------------------
ReferenceShakeConstraint destructor
--------------------------------------------------------------------------------------- */
ReferenceShakeConstraint
::~
ReferenceShakeConstraint
(
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeConstraint::~ReferenceShakeConstraint";
// ---------------------------------------------------------------------------------------
}
/**---------------------------------------------------------------------------------------
Get constraint distance
@return constraintDistance
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceShakeConstraint
::
getConstraintDistance
(
void
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeConstraint::getConstraintDistance";
// ---------------------------------------------------------------------------------------
return
_constraintDistance
;
}
/**---------------------------------------------------------------------------------------
Get inverse mass of heavy atom
@return inverse mass
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceShakeConstraint
::
getHeavyAtomInverseMass
(
void
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeConstraint::getHeavyAtomInverseMass";
// ---------------------------------------------------------------------------------------
return
_inverseMasses
[
0
];
}
/**---------------------------------------------------------------------------------------
Get inverse mass of light atom
@return inverse mass
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceShakeConstraint
::
getLightAtomInverseMass
(
void
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeConstraint::getLightAtomInverseMass";
// ---------------------------------------------------------------------------------------
return
_inverseMasses
[
1
];
}
/**---------------------------------------------------------------------------------------
Get index of heavy atom
@return index
--------------------------------------------------------------------------------------- */
int
ReferenceShakeConstraint
::
getHeavyAtomIndex
(
void
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeConstraint::getHeavyAtomIndex";
// ---------------------------------------------------------------------------------------
return
_atomIndices
[
0
];
}
/**---------------------------------------------------------------------------------------
Get index of light atom
@return index
--------------------------------------------------------------------------------------- */
int
ReferenceShakeConstraint
::
getLightAtomIndex
(
void
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeConstraint::getLightAtomIndex";
// ---------------------------------------------------------------------------------------
return
_atomIndices
[
1
];
}
platforms/reference/src/SimTKReference/ReferenceConstraints.cpp
0 → 100644
View file @
855ece90
/* -------------------------------------------------------------------------- *
* 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) 2013 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 "ReferenceConstraints.h"
#include "openmm/HarmonicAngleForce.h"
#include "openmm/OpenMMException.h"
#include <map>
#include <utility>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
ReferenceConstraints
::
ReferenceConstraints
(
const
System
&
system
,
RealOpenMM
tolerance
)
:
ccma
(
NULL
),
settle
(
NULL
)
{
this
->
tolerance
=
tolerance
;
int
numParticles
=
system
.
getNumParticles
();
vector
<
RealOpenMM
>
masses
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
masses
[
i
]
=
(
RealOpenMM
)
system
.
getParticleMass
(
i
);
// Record the set of constraints and how many constraints each atom is involved in.
vector
<
int
>
atom1
;
vector
<
int
>
atom2
;
vector
<
double
>
distance
;
vector
<
int
>
constraintCount
(
numParticles
,
0
);
for
(
int
i
=
0
;
i
<
system
.
getNumConstraints
();
i
++
)
{
int
p1
,
p2
;
double
d
;
system
.
getConstraintParameters
(
i
,
p1
,
p2
,
d
);
if
(
masses
[
p1
]
!=
0
||
masses
[
p2
]
!=
0
)
{
atom1
.
push_back
(
p1
);
atom2
.
push_back
(
p2
);
distance
.
push_back
(
d
);
constraintCount
[
p1
]
++
;
constraintCount
[
p2
]
++
;
}
}
// Identify clusters of three atoms that can be treated with SETTLE. First, for every
// atom that might be part of such a cluster, make a list of the two other atoms it is
// connected to.
vector
<
map
<
int
,
float
>
>
settleConstraints
(
numParticles
);
for
(
int
i
=
0
;
i
<
(
int
)
atom1
.
size
();
i
++
)
{
if
(
constraintCount
[
atom1
[
i
]]
==
2
&&
constraintCount
[
atom2
[
i
]]
==
2
)
{
settleConstraints
[
atom1
[
i
]][
atom2
[
i
]]
=
(
float
)
distance
[
i
];
settleConstraints
[
atom2
[
i
]][
atom1
[
i
]]
=
(
float
)
distance
[
i
];
}
}
// Now remove the ones that don't actually form closed loops of three atoms.
vector
<
int
>
settleClusters
;
for
(
int
i
=
0
;
i
<
(
int
)
settleConstraints
.
size
();
i
++
)
{
if
(
settleConstraints
[
i
].
size
()
==
2
)
{
int
partner1
=
settleConstraints
[
i
].
begin
()
->
first
;
int
partner2
=
(
++
settleConstraints
[
i
].
begin
())
->
first
;
if
(
settleConstraints
[
partner1
].
size
()
!=
2
||
settleConstraints
[
partner2
].
size
()
!=
2
||
settleConstraints
[
partner1
].
find
(
partner2
)
==
settleConstraints
[
partner1
].
end
())
settleConstraints
[
i
].
clear
();
else
if
(
i
<
partner1
&&
i
<
partner2
)
settleClusters
.
push_back
(
i
);
}
else
settleConstraints
[
i
].
clear
();
}
// Record the SETTLE clusters.
vector
<
bool
>
isSettleAtom
(
numParticles
,
false
);
int
numSETTLE
=
settleClusters
.
size
();
if
(
numSETTLE
>
0
)
{
vector
<
int
>
atom1
(
numSETTLE
);
vector
<
int
>
atom2
(
numSETTLE
);
vector
<
int
>
atom3
(
numSETTLE
);
vector
<
RealOpenMM
>
distance1
(
numSETTLE
);
vector
<
RealOpenMM
>
distance2
(
numSETTLE
);
for
(
int
i
=
0
;
i
<
numSETTLE
;
i
++
)
{
int
p1
=
settleClusters
[
i
];
int
p2
=
settleConstraints
[
p1
].
begin
()
->
first
;
int
p3
=
(
++
settleConstraints
[
p1
].
begin
())
->
first
;
float
dist12
=
settleConstraints
[
p1
].
find
(
p2
)
->
second
;
float
dist13
=
settleConstraints
[
p1
].
find
(
p3
)
->
second
;
float
dist23
=
settleConstraints
[
p2
].
find
(
p3
)
->
second
;
if
(
dist12
==
dist13
)
{
// p1 is the central atom
atom1
[
i
]
=
p1
;
atom2
[
i
]
=
p2
;
atom3
[
i
]
=
p3
;
distance1
[
i
]
=
dist12
;
distance2
[
i
]
=
dist23
;
}
else
if
(
dist12
==
dist23
)
{
// p2 is the central atom
atom1
[
i
]
=
p2
;
atom2
[
i
]
=
p1
;
atom3
[
i
]
=
p3
;
distance1
[
i
]
=
dist12
;
distance2
[
i
]
=
dist13
;
}
else
if
(
dist13
==
dist23
)
{
// p3 is the central atom
atom1
[
i
]
=
p3
;
atom2
[
i
]
=
p1
;
atom3
[
i
]
=
p2
;
distance1
[
i
]
=
dist13
;
distance2
[
i
]
=
dist12
;
}
else
throw
OpenMMException
(
"Two of the three distances constrained with SETTLE must be the same."
);
isSettleAtom
[
p1
]
=
true
;
isSettleAtom
[
p2
]
=
true
;
isSettleAtom
[
p3
]
=
true
;
}
settle
=
new
ReferenceSETTLEAlgorithm
(
atom1
,
atom2
,
atom3
,
distance1
,
distance2
,
masses
,
tolerance
);
}
// All other constraints are handled with CCMA.
vector
<
int
>
ccmaConstraints
;
for
(
unsigned
i
=
0
;
i
<
atom1
.
size
();
i
++
)
if
(
!
isSettleAtom
[
atom1
[
i
]])
ccmaConstraints
.
push_back
(
i
);
int
numCCMA
=
ccmaConstraints
.
size
();
if
(
numCCMA
>
0
)
{
// Record particles and distances for CCMA.
vector
<
pair
<
int
,
int
>
>
ccmaIndices
(
numCCMA
);
vector
<
RealOpenMM
>
ccmaDistance
(
numCCMA
);
for
(
int
i
=
0
;
i
<
numCCMA
;
i
++
)
{
int
index
=
ccmaConstraints
[
i
];
ccmaIndices
[
i
]
=
make_pair
(
atom1
[
index
],
atom2
[
index
]);
ccmaDistance
[
i
]
=
distance
[
index
];
}
// Look up angles for CCMA.
vector
<
ReferenceCCMAAlgorithm
::
AngleInfo
>
angles
;
for
(
int
i
=
0
;
i
<
system
.
getNumForces
();
i
++
)
{
const
HarmonicAngleForce
*
force
=
dynamic_cast
<
const
HarmonicAngleForce
*>
(
&
system
.
getForce
(
i
));
if
(
force
!=
NULL
)
{
for
(
int
j
=
0
;
j
<
force
->
getNumAngles
();
j
++
)
{
int
atom1
,
atom2
,
atom3
;
double
angle
,
k
;
force
->
getAngleParameters
(
j
,
atom1
,
atom2
,
atom3
,
angle
,
k
);
angles
.
push_back
(
ReferenceCCMAAlgorithm
::
AngleInfo
(
atom1
,
atom2
,
atom3
,
(
RealOpenMM
)
angle
));
}
}
}
// Create the CCMA object.
ccma
=
new
ReferenceCCMAAlgorithm
(
numParticles
,
numCCMA
,
ccmaIndices
,
ccmaDistance
,
masses
,
angles
,
tolerance
);
}
}
ReferenceConstraints
::~
ReferenceConstraints
()
{
if
(
ccma
!=
NULL
)
delete
ccma
;
if
(
settle
!=
NULL
)
delete
settle
;
}
RealOpenMM
ReferenceConstraints
::
getTolerance
()
const
{
return
tolerance
;
}
void
ReferenceConstraints
::
setTolerance
(
RealOpenMM
tolerance
)
{
this
->
tolerance
=
tolerance
;
if
(
ccma
!=
NULL
)
ccma
->
setTolerance
(
tolerance
);
if
(
settle
!=
NULL
)
settle
->
setTolerance
(
tolerance
);
}
void
ReferenceConstraints
::
apply
(
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
vector
<
OpenMM
::
RealVec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
if
(
ccma
!=
NULL
)
ccma
->
apply
(
atomCoordinates
,
atomCoordinatesP
,
inverseMasses
);
if
(
settle
!=
NULL
)
settle
->
apply
(
atomCoordinates
,
atomCoordinatesP
,
inverseMasses
);
}
void
ReferenceConstraints
::
applyToVelocities
(
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
vector
<
OpenMM
::
RealVec
>&
velocities
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
if
(
ccma
!=
NULL
)
ccma
->
applyToVelocities
(
atomCoordinates
,
velocities
,
inverseMasses
);
if
(
settle
!=
NULL
)
settle
->
applyToVelocities
(
atomCoordinates
,
velocities
,
inverseMasses
);
}
platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp
View file @
855ece90
/* Portions copyright (c) 2010 Stanford University and Simbios.
/* Portions copyright (c) 2010
-2013
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -39,16 +39,21 @@ using namespace std;
--------------------------------------------------------------------------------------- */
ReferenceCustomAngleIxn
::
ReferenceCustomAngleIxn
(
const
Lepton
::
ExpressionProgram
&
energyExpression
,
const
Lepton
::
ExpressionProgram
&
forceExpression
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
),
paramNames
(
parameterNames
),
globalParameters
(
globalParameters
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCustomAngleIxn::ReferenceCustomAngleIxn";
// ---------------------------------------------------------------------------------------
ReferenceCustomAngleIxn
::
ReferenceCustomAngleIxn
(
const
Lepton
::
CompiledExpression
&
energyExpression
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
)
{
energyTheta
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"theta"
);
forceTheta
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
"theta"
);
numParameters
=
parameterNames
.
size
();
for
(
int
i
=
0
;
i
<
(
int
)
numParameters
;
i
++
)
{
energyParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
parameterNames
[
i
]));
forceParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
parameterNames
[
i
]));
}
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
.
begin
();
iter
!=
globalParameters
.
end
();
++
iter
)
{
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
iter
->
first
),
iter
->
second
);
}
}
/**---------------------------------------------------------------------------------------
...
...
@@ -91,9 +96,10 @@ void ReferenceCustomAngleIxn::calculateBondIxn( int* atomIndices,
static
const
RealOpenMM
one
=
1.0
;
RealOpenMM
deltaR
[
2
][
ReferenceForce
::
LastDeltaRIndex
];
map
<
string
,
double
>
variables
=
globalParameters
;
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
++
i
)
variables
[
paramNames
[
i
]]
=
parameters
[
i
];
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
{
ReferenceForce
::
setVariable
(
energyParams
[
i
],
parameters
[
i
]);
ReferenceForce
::
setVariable
(
forceParams
[
i
],
parameters
[
i
]);
}
// ---------------------------------------------------------------------------------------
...
...
@@ -118,12 +124,13 @@ void ReferenceCustomAngleIxn::calculateBondIxn( int* atomIndices,
angle
=
PI_M
;
else
angle
=
ACOS
(
cosine
);
variables
[
"theta"
]
=
angle
;
ReferenceForce
::
setVariable
(
energyTheta
,
angle
);
ReferenceForce
::
setVariable
(
forceTheta
,
angle
);
// Compute the force and energy, and apply them to the atoms.
RealOpenMM
energy
=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
RealOpenMM
dEdR
=
(
RealOpenMM
)
forceExpression
.
evaluate
(
variables
);
RealOpenMM
energy
=
(
RealOpenMM
)
energyExpression
.
evaluate
();
RealOpenMM
dEdR
=
(
RealOpenMM
)
forceExpression
.
evaluate
();
RealOpenMM
termA
=
dEdR
/
(
deltaR
[
0
][
ReferenceForce
::
R2Index
]
*
rp
);
RealOpenMM
termC
=
-
dEdR
/
(
deltaR
[
1
][
ReferenceForce
::
R2Index
]
*
rp
);
...
...
platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp
View file @
855ece90
/* Portions copyright (c) 2009 Stanford University and Simbios.
/* Portions copyright (c) 2009
-2013
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -40,16 +40,20 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceCustomBondIxn
::
ReferenceCustomBondIxn
(
const
Lepton
::
ExpressionProgram
&
energyExpression
,
const
Lepton
::
ExpressionProgram
&
forceExpression
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
),
paramNames
(
parameterNames
),
globalParameters
(
globalParameters
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCustomBondIxn::ReferenceCustomBondIxn";
// ---------------------------------------------------------------------------------------
ReferenceCustomBondIxn
::
ReferenceCustomBondIxn
(
const
Lepton
::
CompiledExpression
&
energyExpression
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
)
{
energyR
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"r"
);
forceR
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
"r"
);
numParameters
=
parameterNames
.
size
();
for
(
int
i
=
0
;
i
<
(
int
)
numParameters
;
i
++
)
{
energyParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
parameterNames
[
i
]));
forceParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
parameterNames
[
i
]));
}
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
.
begin
();
iter
!=
globalParameters
.
end
();
++
iter
)
{
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
iter
->
first
),
iter
->
second
);
}
}
/**---------------------------------------------------------------------------------------
...
...
@@ -95,9 +99,10 @@ void ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
static
const
RealOpenMM
half
=
0.5
;
RealOpenMM
deltaR
[
ReferenceForce
::
LastDeltaRIndex
];
map
<
string
,
double
>
variables
=
globalParameters
;
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
++
i
)
variables
[
paramNames
[
i
]]
=
parameters
[
i
];
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
{
ReferenceForce
::
setVariable
(
energyParams
[
i
],
parameters
[
i
]);
ReferenceForce
::
setVariable
(
forceParams
[
i
],
parameters
[
i
]);
}
// ---------------------------------------------------------------------------------------
...
...
@@ -106,8 +111,10 @@ void ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
int
atomAIndex
=
atomIndices
[
0
];
int
atomBIndex
=
atomIndices
[
1
];
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atomAIndex
],
atomCoordinates
[
atomBIndex
],
deltaR
);
variables
[
"r"
]
=
deltaR
[
ReferenceForce
::
RIndex
];
RealOpenMM
dEdR
=
(
RealOpenMM
)
forceExpression
.
evaluate
(
variables
);
ReferenceForce
::
setVariable
(
energyR
,
deltaR
[
ReferenceForce
::
RIndex
]);
ReferenceForce
::
setVariable
(
forceR
,
deltaR
[
ReferenceForce
::
RIndex
]);
RealOpenMM
dEdR
=
(
RealOpenMM
)
forceExpression
.
evaluate
();
dEdR
=
deltaR
[
ReferenceForce
::
RIndex
]
>
zero
?
(
dEdR
/
deltaR
[
ReferenceForce
::
RIndex
])
:
zero
;
forces
[
atomAIndex
][
0
]
+=
dEdR
*
deltaR
[
ReferenceForce
::
XIndex
];
...
...
@@ -119,5 +126,5 @@ void ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices,
forces
[
atomBIndex
][
2
]
-=
dEdR
*
deltaR
[
ReferenceForce
::
ZIndex
];
if
(
totalEnergy
!=
NULL
)
*
totalEnergy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
*
totalEnergy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
();
}
platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp
View file @
855ece90
/* Portions copyright (c) 2011 Stanford University and Simbios.
/* Portions copyright (c) 2011
-2013
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -252,12 +252,12 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
break
;
}
case
CustomIntegrator
::
ConstrainPositions
:
{
getReferenceConstraintAlgorithm
()
->
apply
(
numberOfAtoms
,
oldPos
,
atomCoordinates
,
inverseMasses
);
getReferenceConstraintAlgorithm
()
->
apply
(
oldPos
,
atomCoordinates
,
inverseMasses
);
oldPos
=
atomCoordinates
;
break
;
}
case
CustomIntegrator
::
ConstrainVelocities
:
{
getReferenceConstraintAlgorithm
()
->
applyToVelocities
(
numberOfAtoms
,
oldPos
,
velocities
,
inverseMasses
);
getReferenceConstraintAlgorithm
()
->
applyToVelocities
(
oldPos
,
velocities
,
inverseMasses
);
break
;
}
case
CustomIntegrator
::
UpdateContextState
:
{
...
...
platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp
View file @
855ece90
/* Portions copyright (c) 2009 Stanford University and Simbios.
/* Portions copyright (c) 2009
-2013
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -40,18 +40,37 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceCustomExternalIxn
::
ReferenceCustomExternalIxn
(
const
Lepton
::
Expression
Program
&
energyExpression
,
const
Lepton
::
Expression
Program
&
forceExpressionX
,
const
Lepton
::
Expression
Program
&
forceExpressionY
,
const
Lepton
::
Expression
Program
&
forceExpressionZ
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
ReferenceCustomExternalIxn
::
ReferenceCustomExternalIxn
(
const
Lepton
::
Compiled
Expression
&
energyExpression
,
const
Lepton
::
Compiled
Expression
&
forceExpressionX
,
const
Lepton
::
Compiled
Expression
&
forceExpressionY
,
const
Lepton
::
Compiled
Expression
&
forceExpressionZ
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpressionX
(
forceExpressionX
),
forceExpressionY
(
forceExpressionY
),
forceExpressionZ
(
forceExpressionZ
),
paramNames
(
parameterNames
),
globalParameters
(
globalParameters
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCustomExternalIxn::ReferenceCustomExternalIxn";
// ---------------------------------------------------------------------------------------
forceExpressionZ
(
forceExpressionZ
)
{
energyX
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"x"
);
energyY
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"y"
);
energyZ
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"z"
);
forceXX
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionX
,
"x"
);
forceXY
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionX
,
"y"
);
forceXZ
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionX
,
"z"
);
forceYX
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionY
,
"x"
);
forceYY
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionY
,
"y"
);
forceYZ
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionY
,
"z"
);
forceZX
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionZ
,
"x"
);
forceZY
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionZ
,
"y"
);
forceZZ
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionZ
,
"z"
);
numParameters
=
parameterNames
.
size
();
for
(
int
i
=
0
;
i
<
(
int
)
numParameters
;
i
++
)
{
energyParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
parameterNames
[
i
]));
forceXParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionX
,
parameterNames
[
i
]));
forceYParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionY
,
parameterNames
[
i
]));
forceZParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionZ
,
parameterNames
[
i
]));
}
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
.
begin
();
iter
!=
globalParameters
.
end
();
++
iter
)
{
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionX
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionY
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpressionZ
,
iter
->
first
),
iter
->
second
);
}
}
/**---------------------------------------------------------------------------------------
...
...
@@ -90,18 +109,30 @@ void ReferenceCustomExternalIxn::calculateForce( int atomIndex,
static
const
std
::
string
methodName
=
"
\n
ReferenceCustomExternalIxn::calculateBondIxn"
;
map
<
string
,
double
>
variables
=
globalParameters
;
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
++
i
)
variables
[
paramNames
[
i
]]
=
parameters
[
i
];
variables
[
"x"
]
=
atomCoordinates
[
atomIndex
][
0
];
variables
[
"y"
]
=
atomCoordinates
[
atomIndex
][
1
];
variables
[
"z"
]
=
atomCoordinates
[
atomIndex
][
2
];
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
{
ReferenceForce
::
setVariable
(
energyParams
[
i
],
parameters
[
i
]);
ReferenceForce
::
setVariable
(
forceXParams
[
i
],
parameters
[
i
]);
ReferenceForce
::
setVariable
(
forceYParams
[
i
],
parameters
[
i
]);
ReferenceForce
::
setVariable
(
forceZParams
[
i
],
parameters
[
i
]);
}
ReferenceForce
::
setVariable
(
energyX
,
atomCoordinates
[
atomIndex
][
0
]);
ReferenceForce
::
setVariable
(
energyY
,
atomCoordinates
[
atomIndex
][
1
]);
ReferenceForce
::
setVariable
(
energyZ
,
atomCoordinates
[
atomIndex
][
2
]);
ReferenceForce
::
setVariable
(
forceXX
,
atomCoordinates
[
atomIndex
][
0
]);
ReferenceForce
::
setVariable
(
forceXY
,
atomCoordinates
[
atomIndex
][
1
]);
ReferenceForce
::
setVariable
(
forceXZ
,
atomCoordinates
[
atomIndex
][
2
]);
ReferenceForce
::
setVariable
(
forceYX
,
atomCoordinates
[
atomIndex
][
0
]);
ReferenceForce
::
setVariable
(
forceYY
,
atomCoordinates
[
atomIndex
][
1
]);
ReferenceForce
::
setVariable
(
forceYZ
,
atomCoordinates
[
atomIndex
][
2
]);
ReferenceForce
::
setVariable
(
forceZX
,
atomCoordinates
[
atomIndex
][
0
]);
ReferenceForce
::
setVariable
(
forceZY
,
atomCoordinates
[
atomIndex
][
1
]);
ReferenceForce
::
setVariable
(
forceZZ
,
atomCoordinates
[
atomIndex
][
2
]);
// ---------------------------------------------------------------------------------------
forces
[
atomIndex
][
0
]
-=
(
RealOpenMM
)
forceExpressionX
.
evaluate
(
variables
);
forces
[
atomIndex
][
1
]
-=
(
RealOpenMM
)
forceExpressionY
.
evaluate
(
variables
);
forces
[
atomIndex
][
2
]
-=
(
RealOpenMM
)
forceExpressionZ
.
evaluate
(
variables
);
forces
[
atomIndex
][
0
]
-=
(
RealOpenMM
)
forceExpressionX
.
evaluate
();
forces
[
atomIndex
][
1
]
-=
(
RealOpenMM
)
forceExpressionY
.
evaluate
();
forces
[
atomIndex
][
2
]
-=
(
RealOpenMM
)
forceExpressionZ
.
evaluate
();
if
(
energy
!=
NULL
)
*
energy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
*
energy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
();
}
platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp
View file @
855ece90
/* Portions copyright (c) 2009 Stanford University and Simbios.
/* Portions copyright (c) 2009
-2013
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -45,8 +45,8 @@ using OpenMM::RealVec;
--------------------------------------------------------------------------------------- */
ReferenceCustomNonbondedIxn
::
ReferenceCustomNonbondedIxn
(
const
Lepton
::
Expression
Program
&
energyExpression
,
const
Lepton
::
Expression
Program
&
forceExpression
,
const
vector
<
string
>&
parameterNames
)
:
ReferenceCustomNonbondedIxn
::
ReferenceCustomNonbondedIxn
(
const
Lepton
::
Compiled
Expression
&
energyExpression
,
const
Lepton
::
Compiled
Expression
&
forceExpression
,
const
vector
<
string
>&
parameterNames
)
:
cutoff
(
false
),
useSwitch
(
false
),
periodic
(
false
),
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
),
paramNames
(
parameterNames
)
{
// ---------------------------------------------------------------------------------------
...
...
@@ -55,11 +55,14 @@ ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::Expressio
// ---------------------------------------------------------------------------------------
energyR
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"r"
);
forceR
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
"r"
);
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
for
(
int
j
=
1
;
j
<
3
;
j
++
)
{
stringstream
name
;
name
<<
paramNames
[
i
]
<<
j
;
particleParamNames
.
push_back
(
name
.
str
());
energyParticleParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
name
.
str
()));
forceParticleParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
name
.
str
()));
}
}
}
...
...
@@ -166,9 +169,12 @@ void ReferenceCustomNonbondedIxn::setUseSwitchingFunction( RealOpenMM distance )
void
ReferenceCustomNonbondedIxn
::
calculatePairIxn
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
**
atomParameters
,
vector
<
set
<
int
>
>&
exclusions
,
RealOpenMM
*
fixedParameters
,
const
map
<
string
,
double
>&
globalParameters
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
{
map
<
string
,
double
>
variables
=
globalParameters
;
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
.
begin
();
iter
!=
globalParameters
.
end
();
++
iter
)
{
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
energyExpression
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
forceExpression
,
iter
->
first
),
iter
->
second
);
}
if
(
interactionGroups
.
size
()
>
0
)
{
// The user has specified interaction groups, so compute only the requested interactions.
...
...
@@ -182,10 +188,12 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, vector<Re
if
(
*
atom1
>
*
atom2
&&
set1
.
find
(
*
atom2
)
!=
set1
.
end
()
&&
set2
.
find
(
*
atom1
)
!=
set2
.
end
())
continue
;
// Both atoms are in both sets, so skip duplicate interactions.
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
{
variables
[
particleParamNames
[
j
*
2
]]
=
atomParameters
[
*
atom1
][
j
];
variables
[
particleParamNames
[
j
*
2
+
1
]]
=
atomParameters
[
*
atom2
][
j
];
ReferenceForce
::
setVariable
(
energyParticleParams
[
j
*
2
],
atomParameters
[
*
atom1
][
j
]);
ReferenceForce
::
setVariable
(
energyParticleParams
[
j
*
2
+
1
],
atomParameters
[
*
atom2
][
j
]);
ReferenceForce
::
setVariable
(
forceParticleParams
[
j
*
2
],
atomParameters
[
*
atom1
][
j
]);
ReferenceForce
::
setVariable
(
forceParticleParams
[
j
*
2
+
1
],
atomParameters
[
*
atom2
][
j
]);
}
calculateOneIxn
(
*
atom1
,
*
atom2
,
atomCoordinates
,
variables
,
forces
,
energyByAtom
,
totalEnergy
);
calculateOneIxn
(
*
atom1
,
*
atom2
,
atomCoordinates
,
forces
,
energyByAtom
,
totalEnergy
);
}
}
}
...
...
@@ -196,10 +204,12 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, vector<Re
for
(
int
i
=
0
;
i
<
(
int
)
neighborList
->
size
();
i
++
)
{
OpenMM
::
AtomPair
pair
=
(
*
neighborList
)[
i
];
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
{
variables
[
particleParamNames
[
j
*
2
]]
=
atomParameters
[
pair
.
first
][
j
];
variables
[
particleParamNames
[
j
*
2
+
1
]]
=
atomParameters
[
pair
.
second
][
j
];
ReferenceForce
::
setVariable
(
energyParticleParams
[
j
*
2
],
atomParameters
[
pair
.
first
][
j
]);
ReferenceForce
::
setVariable
(
energyParticleParams
[
j
*
2
+
1
],
atomParameters
[
pair
.
second
][
j
]);
ReferenceForce
::
setVariable
(
forceParticleParams
[
j
*
2
],
atomParameters
[
pair
.
first
][
j
]);
ReferenceForce
::
setVariable
(
forceParticleParams
[
j
*
2
+
1
],
atomParameters
[
pair
.
second
][
j
]);
}
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
variables
,
forces
,
energyByAtom
,
totalEnergy
);
calculateOneIxn
(
pair
.
first
,
pair
.
second
,
atomCoordinates
,
forces
,
energyByAtom
,
totalEnergy
);
}
}
else
{
...
...
@@ -209,10 +219,12 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, vector<Re
for
(
int
jj
=
ii
+
1
;
jj
<
numberOfAtoms
;
jj
++
)
{
if
(
exclusions
[
jj
].
find
(
ii
)
==
exclusions
[
jj
].
end
())
{
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
{
variables
[
particleParamNames
[
j
*
2
]]
=
atomParameters
[
ii
][
j
];
variables
[
particleParamNames
[
j
*
2
+
1
]]
=
atomParameters
[
jj
][
j
];
ReferenceForce
::
setVariable
(
energyParticleParams
[
j
*
2
],
atomParameters
[
ii
][
j
]);
ReferenceForce
::
setVariable
(
energyParticleParams
[
j
*
2
+
1
],
atomParameters
[
jj
][
j
]);
ReferenceForce
::
setVariable
(
forceParticleParams
[
j
*
2
],
atomParameters
[
ii
][
j
]);
ReferenceForce
::
setVariable
(
forceParticleParams
[
j
*
2
+
1
],
atomParameters
[
jj
][
j
]);
}
calculateOneIxn
(
ii
,
jj
,
atomCoordinates
,
variables
,
forces
,
energyByAtom
,
totalEnergy
);
calculateOneIxn
(
ii
,
jj
,
atomCoordinates
,
forces
,
energyByAtom
,
totalEnergy
);
}
}
}
...
...
@@ -233,9 +245,8 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, vector<Re
--------------------------------------------------------------------------------------- */
void
ReferenceCustomNonbondedIxn
::
calculateOneIxn
(
int
ii
,
int
jj
,
vector
<
RealVec
>&
atomCoordinates
,
map
<
string
,
double
>&
variables
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
const
{
void
ReferenceCustomNonbondedIxn
::
calculateOneIxn
(
int
ii
,
int
jj
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
forces
,
RealOpenMM
*
energyByAtom
,
RealOpenMM
*
totalEnergy
)
{
// ---------------------------------------------------------------------------------------
...
...
@@ -266,9 +277,10 @@ void ReferenceCustomNonbondedIxn::calculateOneIxn( int ii, int jj, vector<RealVe
// accumulate forces
variables
[
"r"
]
=
r
;
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
forceExpression
.
evaluate
(
variables
)
/
(
deltaR
[
ReferenceForce
::
RIndex
]));
RealOpenMM
energy
=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
ReferenceForce
::
setVariable
(
energyR
,
r
);
ReferenceForce
::
setVariable
(
forceR
,
r
);
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
forceExpression
.
evaluate
()
/
(
deltaR
[
ReferenceForce
::
RIndex
]));
RealOpenMM
energy
=
(
RealOpenMM
)
energyExpression
.
evaluate
();
if
(
useSwitch
)
{
if
(
r
>
switchingDistance
)
{
RealOpenMM
t
=
(
r
-
switchingDistance
)
/
(
cutoffDistance
-
switchingDistance
);
...
...
platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp
View file @
855ece90
/* Portions copyright (c) 2010 Stanford University and Simbios.
/* Portions copyright (c) 2010
-2013
Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -39,16 +39,21 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */
ReferenceCustomTorsionIxn
::
ReferenceCustomTorsionIxn
(
const
Lepton
::
ExpressionProgram
&
energyExpression
,
const
Lepton
::
ExpressionProgram
&
forceExpression
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
),
paramNames
(
parameterNames
),
globalParameters
(
globalParameters
)
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCustomTorsionIxn::ReferenceCustomTorsionIxn";
// ---------------------------------------------------------------------------------------
ReferenceCustomTorsionIxn
::
ReferenceCustomTorsionIxn
(
const
Lepton
::
CompiledExpression
&
energyExpression
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
const
vector
<
string
>&
parameterNames
,
map
<
string
,
double
>
globalParameters
)
:
energyExpression
(
energyExpression
),
forceExpression
(
forceExpression
)
{
energyTheta
=
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
"theta"
);
forceTheta
=
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
"theta"
);
numParameters
=
parameterNames
.
size
();
for
(
int
i
=
0
;
i
<
(
int
)
numParameters
;
i
++
)
{
energyParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
parameterNames
[
i
]));
forceParams
.
push_back
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
parameterNames
[
i
]));
}
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
.
begin
();
iter
!=
globalParameters
.
end
();
++
iter
)
{
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
energyExpression
,
iter
->
first
),
iter
->
second
);
ReferenceForce
::
setVariable
(
ReferenceForce
::
getVariablePointer
(
this
->
forceExpression
,
iter
->
first
),
iter
->
second
);
}
}
/**---------------------------------------------------------------------------------------
...
...
@@ -91,9 +96,10 @@ void ReferenceCustomTorsionIxn::calculateBondIxn( int* atomIndices,
static
const
RealOpenMM
one
=
1.0
;
RealOpenMM
deltaR
[
3
][
ReferenceForce
::
LastDeltaRIndex
];
map
<
string
,
double
>
variables
=
globalParameters
;
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
++
i
)
variables
[
paramNames
[
i
]]
=
parameters
[
i
];
for
(
int
i
=
0
;
i
<
numParameters
;
i
++
)
{
ReferenceForce
::
setVariable
(
energyParams
[
i
],
parameters
[
i
]);
ReferenceForce
::
setVariable
(
forceParams
[
i
],
parameters
[
i
]);
}
// ---------------------------------------------------------------------------------------
...
...
@@ -118,13 +124,13 @@ void ReferenceCustomTorsionIxn::calculateBondIxn( int* atomIndices,
RealOpenMM
dotDihedral
;
RealOpenMM
signOfAngle
;
variables
[
"theta"
]
=
getDihedralAngleBetweenThreeVectors
(
deltaR
[
0
],
deltaR
[
1
],
deltaR
[
2
],
crossProduct
,
&
dotDihedral
,
deltaR
[
0
],
&
signOfA
ngle
,
1
);
RealOpenMM
angle
=
getDihedralAngleBetweenThreeVectors
(
deltaR
[
0
],
deltaR
[
1
],
deltaR
[
2
],
crossProduct
,
&
dotDihedral
,
deltaR
[
0
],
&
signOfAngle
,
1
);
ReferenceForce
::
setVariable
(
energyTheta
,
angle
);
ReferenceForce
::
setVariable
(
forceTheta
,
a
ngle
);
// evaluate delta angle, dE/d(angle)
RealOpenMM
dEdAngle
=
(
RealOpenMM
)
forceExpression
.
evaluate
(
variables
);
RealOpenMM
dEdAngle
=
(
RealOpenMM
)
forceExpression
.
evaluate
();
// compute force
...
...
@@ -166,6 +172,6 @@ void ReferenceCustomTorsionIxn::calculateBondIxn( int* atomIndices,
// accumulate energies
if
(
totalEnergy
!=
NULL
)
*
totalEnergy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
(
variables
);
*
totalEnergy
+=
(
RealOpenMM
)
energyExpression
.
evaluate
();
}
platforms/reference/src/SimTKReference/ReferenceForce.cpp
View file @
855ece90
/* Portions copyright (c) 2006 Stanford University and Simbios.
/* Portions copyright (c) 2006
-2013
Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
...
...
@@ -161,3 +161,14 @@ void ReferenceForce::getDeltaROnly( const RealOpenMM* atomCoordinatesI,
deltaR
[
YIndex
]
=
atomCoordinatesJ
[
1
]
-
atomCoordinatesI
[
1
];
deltaR
[
ZIndex
]
=
atomCoordinatesJ
[
2
]
-
atomCoordinatesI
[
2
];
}
double
*
ReferenceForce
::
getVariablePointer
(
Lepton
::
CompiledExpression
&
expression
,
const
std
::
string
&
name
)
{
if
(
expression
.
getVariables
().
find
(
name
)
==
expression
.
getVariables
().
end
())
return
NULL
;
return
&
expression
.
getVariableReference
(
name
);
}
void
ReferenceForce
::
setVariable
(
double
*
pointer
,
double
value
)
{
if
(
pointer
!=
NULL
)
*
pointer
=
value
;
}
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
855ece90
...
...
@@ -31,7 +31,7 @@
#include "SimTKOpenMMUtilities.h"
#include "ReferenceLJCoulombIxn.h"
#include "ReferenceForce.h"
#include "PME.h"
#include "
Reference
PME.h"
// In case we're using some primitive version of Visual Studio this will
// make sure that erf() and erfc() are defined.
...
...
@@ -233,7 +233,10 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
atomParameters
,
periodicBoxSize
,
&
recipEnergy
,
virial
);
vector
<
RealOpenMM
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
pme_exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxSize
,
&
recipEnergy
,
virial
);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
...
...
platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp
View file @
855ece90
...
...
@@ -44,9 +44,7 @@ void OPENMM_EXPORT computeNeighborListNaive(
bool
usePeriodic
,
double
maxDistance
,
double
minDistance
,
bool
reportSymmetricPairs
)
{
bool
reportSymmetricPairs
)
{
neighborList
.
clear
();
double
maxDistanceSquared
=
maxDistance
*
maxDistance
;
...
...
@@ -102,15 +100,19 @@ public:
nx
=
(
int
)
floor
(
periodicBoxSize
[
0
]
/
voxelSizeX
+
0.5
);
ny
=
(
int
)
floor
(
periodicBoxSize
[
1
]
/
voxelSizeY
+
0.5
);
nz
=
(
int
)
floor
(
periodicBoxSize
[
2
]
/
voxelSizeZ
+
0.5
);
voxelSizeX
=
periodicBoxSize
[
0
]
/
nx
;
voxelSizeY
=
periodicBoxSize
[
1
]
/
ny
;
voxelSizeZ
=
periodicBoxSize
[
2
]
/
nz
;
}
}
void
insert
(
const
AtomIndex
&
item
,
const
RealVec
&
location
)
{
VoxelIndex
voxelIndex
=
getVoxelIndex
(
location
);
if
(
voxelMap
.
find
(
voxelIndex
)
==
voxelMap
.
end
()
)
voxelMap
[
voxelIndex
]
=
Voxel
();
if
(
voxelMap
.
find
(
voxelIndex
)
==
voxelMap
.
end
())
voxelMap
[
voxelIndex
]
=
Voxel
();
Voxel
&
voxel
=
voxelMap
.
find
(
voxelIndex
)
->
second
;
voxel
.
push_back
(
VoxelItem
(
&
location
,
item
)
);
voxel
.
push_back
(
VoxelItem
(
&
location
,
item
));
}
...
...
@@ -180,8 +182,9 @@ public:
voxelIndex
.
y
=
(
y
+
ny
)
%
ny
;
voxelIndex
.
z
=
(
z
+
nz
)
%
nz
;
}
if
(
voxelMap
.
find
(
voxelIndex
)
==
voxelMap
.
end
())
continue
;
// no such voxel; skip
const
Voxel
&
voxel
=
voxelMap
.
find
(
voxelIndex
)
->
second
;
const
map
<
VoxelIndex
,
Voxel
>::
const_iterator
voxelEntry
=
voxelMap
.
find
(
voxelIndex
);
if
(
voxelEntry
==
voxelMap
.
end
())
continue
;
// no such voxel; skip
const
Voxel
&
voxel
=
voxelEntry
->
second
;
for
(
Voxel
::
const_iterator
itemIter
=
voxel
.
begin
();
itemIter
!=
voxel
.
end
();
++
itemIter
)
{
const
AtomIndex
atomJ
=
itemIter
->
second
;
...
...
@@ -190,13 +193,13 @@ public:
// Ignore self hits
if
(
atomI
==
atomJ
)
continue
;
// Ignore exclusions.
if
(
exclusions
[
atomI
].
find
(
atomJ
)
!=
exclusions
[
atomI
].
end
())
continue
;
double
dSquared
=
compPairDistanceSquared
(
locationI
,
locationJ
,
periodicBoxSize
,
usePeriodic
);
if
(
dSquared
>
maxDistanceSquared
)
continue
;
if
(
dSquared
<
minDistanceSquared
)
continue
;
// Ignore exclusions.
if
(
exclusions
[
atomI
].
find
(
atomJ
)
!=
exclusions
[
atomI
].
end
())
continue
;
neighbors
.
push_back
(
AtomPair
(
atomI
,
atomJ
)
);
if
(
reportSymmetricPairs
)
neighbors
.
push_back
(
AtomPair
(
atomJ
,
atomI
)
);
...
...
@@ -234,9 +237,9 @@ void OPENMM_EXPORT computeNeighborListVoxelHash(
if
(
!
usePeriodic
)
edgeSizeX
=
edgeSizeY
=
edgeSizeZ
=
maxDistance
;
// TODO - adjust this as needed
else
{
edgeSizeX
=
periodicBoxSize
[
0
]
/
floor
(
periodicBoxSize
[
0
]
/
maxDistance
);
edgeSizeY
=
periodicBoxSize
[
1
]
/
floor
(
periodicBoxSize
[
1
]
/
maxDistance
);
edgeSizeZ
=
periodicBoxSize
[
2
]
/
floor
(
periodicBoxSize
[
2
]
/
maxDistance
);
edgeSizeX
=
0.5
*
periodicBoxSize
[
0
]
/
floor
(
periodicBoxSize
[
0
]
/
maxDistance
);
edgeSizeY
=
0.5
*
periodicBoxSize
[
1
]
/
floor
(
periodicBoxSize
[
1
]
/
maxDistance
);
edgeSizeZ
=
0.5
*
periodicBoxSize
[
2
]
/
floor
(
periodicBoxSize
[
2
]
/
maxDistance
);
}
VoxelHash
voxelHash
(
edgeSizeX
,
edgeSizeY
,
edgeSizeZ
,
periodicBoxSize
,
usePeriodic
);
for
(
AtomIndex
atomJ
=
0
;
atomJ
<
(
AtomIndex
)
nAtoms
;
++
atomJ
)
// use "j", because j > i for pairs
...
...
platforms/reference/src/SimTKReference/PME.cpp
→
platforms/reference/src/SimTKReference/
Reference
PME.cpp
View file @
855ece90
...
...
@@ -33,7 +33,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "PME.h"
#include "
Reference
PME.h"
#include "fftpack.h"
using
std
::
vector
;
...
...
@@ -317,10 +317,8 @@ pme_update_bsplines(pme_t pme)
static
void
pme_grid_spread_charge
(
pme_t
pme
,
RealOpenMM
**
atomParameters
)
pme_grid_spread_charge
(
pme_t
pme
,
vector
<
RealOpenMM
>&
charges
)
{
static
const
int
QIndex
=
2
;
// atom charges are stored in atomParameters[atomID][2]
int
order
;
int
i
;
int
ix
,
iy
,
iz
;
...
...
@@ -342,7 +340,7 @@ pme_grid_spread_charge(pme_t pme,
for
(
i
=
0
;
i
<
pme
->
natoms
;
i
++
)
{
q
=
atomParameters
[
i
][
QIndex
];
q
=
charges
[
i
];
/* Grid index for the actual atom position */
x0index
=
pme
->
particleindex
[
i
][
0
];
...
...
@@ -523,10 +521,9 @@ pme_reciprocal_convolution(pme_t pme,
static
void
pme_grid_interpolate_force
(
pme_t
pme
,
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
**
atomParameter
s
,
vector
<
RealOpenMM
>&
charge
s
,
vector
<
RealVec
>&
forces
)
{
static
const
int
QIndex
=
2
;
// atom charges are stored in atomParameters[atomID][2]
int
i
;
int
ix
,
iy
,
iz
;
int
x0index
,
y0index
,
z0index
;
...
...
@@ -558,7 +555,7 @@ pme_grid_interpolate_force(pme_t pme,
{
fx
=
fy
=
fz
=
0
;
q
=
atomParameters
[
i
][
QIndex
];
q
=
charges
[
i
];
/* Grid index for the actual atom position */
x0index
=
pme
->
particleindex
[
i
][
0
];
...
...
@@ -671,7 +668,7 @@ pme_init(pme_t * ppme,
int
pme_exec
(
pme_t
pme
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
forces
,
RealOpenMM
**
atomParameter
s
,
vector
<
RealOpenMM
>&
charge
s
,
const
RealOpenMM
periodicBoxSize
[
3
],
RealOpenMM
*
energy
,
RealOpenMM
pme_virial
[
3
][
3
])
...
...
@@ -692,7 +689,7 @@ int pme_exec(pme_t pme,
pme_update_bsplines
(
pme
);
/* Spread the charges on grid (using newly calculated bsplines in the pme structure) */
pme_grid_spread_charge
(
pme
,
atomParameter
s
);
pme_grid_spread_charge
(
pme
,
charge
s
);
/* do 3d-fft */
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_FORWARD
,
pme
->
grid
,
pme
->
grid
);
...
...
@@ -704,7 +701,7 @@ int pme_exec(pme_t pme,
fftpack_exec_3d
(
pme
->
fftplan
,
FFTPACK_BACKWARD
,
pme
->
grid
,
pme
->
grid
);
/* Get the particle forces from the grid and bsplines in the pme structure */
pme_grid_interpolate_force
(
pme
,
periodicBoxSize
,
atomParameter
s
,
forces
);
pme_grid_interpolate_force
(
pme
,
periodicBoxSize
,
charge
s
,
forces
);
return
0
;
}
...
...
platforms/reference/src/SimTKReference/ReferenceSETTLEAlgorithm.cpp
0 → 100644
View file @
855ece90
/* -------------------------------------------------------------------------- *
* 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) 2013 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 "ReferenceSETTLEAlgorithm.h"
using
namespace
OpenMM
;
using
namespace
std
;
ReferenceSETTLEAlgorithm
::
ReferenceSETTLEAlgorithm
(
const
vector
<
int
>&
atom1
,
const
vector
<
int
>&
atom2
,
const
vector
<
int
>&
atom3
,
const
vector
<
RealOpenMM
>&
distance1
,
const
vector
<
RealOpenMM
>&
distance2
,
vector
<
RealOpenMM
>&
masses
,
RealOpenMM
tolerance
)
:
atom1
(
atom1
),
atom2
(
atom2
),
atom3
(
atom3
),
distance1
(
distance1
),
distance2
(
distance2
),
masses
(
masses
),
tolerance
(
tolerance
)
{
}
RealOpenMM
ReferenceSETTLEAlgorithm
::
getTolerance
()
const
{
return
tolerance
;
}
void
ReferenceSETTLEAlgorithm
::
setTolerance
(
RealOpenMM
tolerance
)
{
this
->
tolerance
=
tolerance
;
}
void
ReferenceSETTLEAlgorithm
::
apply
(
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
vector
<
OpenMM
::
RealVec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
for
(
int
index
=
0
;
index
<
(
int
)
atom1
.
size
();
++
index
)
{
RealVec
apos0
=
atomCoordinates
[
atom1
[
index
]];
RealVec
xp0
=
atomCoordinatesP
[
atom1
[
index
]]
-
apos0
;
RealVec
apos1
=
atomCoordinates
[
atom2
[
index
]];
RealVec
xp1
=
atomCoordinatesP
[
atom2
[
index
]]
-
apos1
;
RealVec
apos2
=
atomCoordinates
[
atom3
[
index
]];
RealVec
xp2
=
atomCoordinatesP
[
atom3
[
index
]]
-
apos2
;
RealOpenMM
m0
=
masses
[
atom1
[
index
]];
RealOpenMM
m1
=
masses
[
atom2
[
index
]];
RealOpenMM
m2
=
masses
[
atom3
[
index
]];
// Apply the SETTLE algorithm.
RealOpenMM
xb0
=
apos1
[
0
]
-
apos0
[
0
];
RealOpenMM
yb0
=
apos1
[
1
]
-
apos0
[
1
];
RealOpenMM
zb0
=
apos1
[
2
]
-
apos0
[
2
];
RealOpenMM
xc0
=
apos2
[
0
]
-
apos0
[
0
];
RealOpenMM
yc0
=
apos2
[
1
]
-
apos0
[
1
];
RealOpenMM
zc0
=
apos2
[
2
]
-
apos0
[
2
];
RealOpenMM
invTotalMass
=
1
/
(
m0
+
m1
+
m2
);
RealOpenMM
xcom
=
(
xp0
[
0
]
*
m0
+
(
xb0
+
xp1
[
0
])
*
m1
+
(
xc0
+
xp2
[
0
])
*
m2
)
*
invTotalMass
;
RealOpenMM
ycom
=
(
xp0
[
1
]
*
m0
+
(
yb0
+
xp1
[
1
])
*
m1
+
(
yc0
+
xp2
[
1
])
*
m2
)
*
invTotalMass
;
RealOpenMM
zcom
=
(
xp0
[
2
]
*
m0
+
(
zb0
+
xp1
[
2
])
*
m1
+
(
zc0
+
xp2
[
2
])
*
m2
)
*
invTotalMass
;
RealOpenMM
xa1
=
xp0
[
0
]
-
xcom
;
RealOpenMM
ya1
=
xp0
[
1
]
-
ycom
;
RealOpenMM
za1
=
xp0
[
2
]
-
zcom
;
RealOpenMM
xb1
=
xb0
+
xp1
[
0
]
-
xcom
;
RealOpenMM
yb1
=
yb0
+
xp1
[
1
]
-
ycom
;
RealOpenMM
zb1
=
zb0
+
xp1
[
2
]
-
zcom
;
RealOpenMM
xc1
=
xc0
+
xp2
[
0
]
-
xcom
;
RealOpenMM
yc1
=
yc0
+
xp2
[
1
]
-
ycom
;
RealOpenMM
zc1
=
zc0
+
xp2
[
2
]
-
zcom
;
RealOpenMM
xaksZd
=
yb0
*
zc0
-
zb0
*
yc0
;
RealOpenMM
yaksZd
=
zb0
*
xc0
-
xb0
*
zc0
;
RealOpenMM
zaksZd
=
xb0
*
yc0
-
yb0
*
xc0
;
RealOpenMM
xaksXd
=
ya1
*
zaksZd
-
za1
*
yaksZd
;
RealOpenMM
yaksXd
=
za1
*
xaksZd
-
xa1
*
zaksZd
;
RealOpenMM
zaksXd
=
xa1
*
yaksZd
-
ya1
*
xaksZd
;
RealOpenMM
xaksYd
=
yaksZd
*
zaksXd
-
zaksZd
*
yaksXd
;
RealOpenMM
yaksYd
=
zaksZd
*
xaksXd
-
xaksZd
*
zaksXd
;
RealOpenMM
zaksYd
=
xaksZd
*
yaksXd
-
yaksZd
*
xaksXd
;
RealOpenMM
axlng
=
sqrt
(
xaksXd
*
xaksXd
+
yaksXd
*
yaksXd
+
zaksXd
*
zaksXd
);
RealOpenMM
aylng
=
sqrt
(
xaksYd
*
xaksYd
+
yaksYd
*
yaksYd
+
zaksYd
*
zaksYd
);
RealOpenMM
azlng
=
sqrt
(
xaksZd
*
xaksZd
+
yaksZd
*
yaksZd
+
zaksZd
*
zaksZd
);
RealOpenMM
trns11
=
xaksXd
/
axlng
;
RealOpenMM
trns21
=
yaksXd
/
axlng
;
RealOpenMM
trns31
=
zaksXd
/
axlng
;
RealOpenMM
trns12
=
xaksYd
/
aylng
;
RealOpenMM
trns22
=
yaksYd
/
aylng
;
RealOpenMM
trns32
=
zaksYd
/
aylng
;
RealOpenMM
trns13
=
xaksZd
/
azlng
;
RealOpenMM
trns23
=
yaksZd
/
azlng
;
RealOpenMM
trns33
=
zaksZd
/
azlng
;
RealOpenMM
xb0d
=
trns11
*
xb0
+
trns21
*
yb0
+
trns31
*
zb0
;
RealOpenMM
yb0d
=
trns12
*
xb0
+
trns22
*
yb0
+
trns32
*
zb0
;
RealOpenMM
xc0d
=
trns11
*
xc0
+
trns21
*
yc0
+
trns31
*
zc0
;
RealOpenMM
yc0d
=
trns12
*
xc0
+
trns22
*
yc0
+
trns32
*
zc0
;
RealOpenMM
za1d
=
trns13
*
xa1
+
trns23
*
ya1
+
trns33
*
za1
;
RealOpenMM
xb1d
=
trns11
*
xb1
+
trns21
*
yb1
+
trns31
*
zb1
;
RealOpenMM
yb1d
=
trns12
*
xb1
+
trns22
*
yb1
+
trns32
*
zb1
;
RealOpenMM
zb1d
=
trns13
*
xb1
+
trns23
*
yb1
+
trns33
*
zb1
;
RealOpenMM
xc1d
=
trns11
*
xc1
+
trns21
*
yc1
+
trns31
*
zc1
;
RealOpenMM
yc1d
=
trns12
*
xc1
+
trns22
*
yc1
+
trns32
*
zc1
;
RealOpenMM
zc1d
=
trns13
*
xc1
+
trns23
*
yc1
+
trns33
*
zc1
;
// --- Step2 A2' ---
RealOpenMM
rc
=
0.5
*
distance2
[
index
];
RealOpenMM
rb
=
sqrt
(
distance1
[
index
]
*
distance1
[
index
]
-
rc
*
rc
);
RealOpenMM
ra
=
rb
*
(
m1
+
m2
)
*
invTotalMass
;
rb
-=
ra
;
RealOpenMM
sinphi
=
za1d
/
ra
;
RealOpenMM
cosphi
=
sqrt
(
1
-
sinphi
*
sinphi
);
RealOpenMM
sinpsi
=
(
zb1d
-
zc1d
)
/
(
2
*
rc
*
cosphi
);
RealOpenMM
cospsi
=
sqrt
(
1
-
sinpsi
*
sinpsi
);
RealOpenMM
ya2d
=
ra
*
cosphi
;
RealOpenMM
xb2d
=
-
rc
*
cospsi
;
RealOpenMM
yb2d
=
-
rb
*
cosphi
-
rc
*
sinpsi
*
sinphi
;
RealOpenMM
yc2d
=
-
rb
*
cosphi
+
rc
*
sinpsi
*
sinphi
;
RealOpenMM
xb2d2
=
xb2d
*
xb2d
;
RealOpenMM
hh2
=
4.0
f
*
xb2d2
+
(
yb2d
-
yc2d
)
*
(
yb2d
-
yc2d
)
+
(
zb1d
-
zc1d
)
*
(
zb1d
-
zc1d
);
RealOpenMM
deltx
=
2.0
f
*
xb2d
+
sqrt
(
4.0
f
*
xb2d2
-
hh2
+
distance2
[
index
]
*
distance2
[
index
]);
xb2d
-=
deltx
*
0.5
;
// --- Step3 al,be,ga ---
RealOpenMM
alpha
=
(
xb2d
*
(
xb0d
-
xc0d
)
+
yb0d
*
yb2d
+
yc0d
*
yc2d
);
RealOpenMM
beta
=
(
xb2d
*
(
yc0d
-
yb0d
)
+
xb0d
*
yb2d
+
xc0d
*
yc2d
);
RealOpenMM
gamma
=
xb0d
*
yb1d
-
xb1d
*
yb0d
+
xc0d
*
yc1d
-
xc1d
*
yc0d
;
RealOpenMM
al2be2
=
alpha
*
alpha
+
beta
*
beta
;
RealOpenMM
sintheta
=
(
alpha
*
gamma
-
beta
*
sqrt
(
al2be2
-
gamma
*
gamma
))
/
al2be2
;
// --- Step4 A3' ---
RealOpenMM
costheta
=
sqrt
(
1
-
sintheta
*
sintheta
);
RealOpenMM
xa3d
=
-
ya2d
*
sintheta
;
RealOpenMM
ya3d
=
ya2d
*
costheta
;
RealOpenMM
za3d
=
za1d
;
RealOpenMM
xb3d
=
xb2d
*
costheta
-
yb2d
*
sintheta
;
RealOpenMM
yb3d
=
xb2d
*
sintheta
+
yb2d
*
costheta
;
RealOpenMM
zb3d
=
zb1d
;
RealOpenMM
xc3d
=
-
xb2d
*
costheta
-
yc2d
*
sintheta
;
RealOpenMM
yc3d
=
-
xb2d
*
sintheta
+
yc2d
*
costheta
;
RealOpenMM
zc3d
=
zc1d
;
// --- Step5 A3 ---
RealOpenMM
xa3
=
trns11
*
xa3d
+
trns12
*
ya3d
+
trns13
*
za3d
;
RealOpenMM
ya3
=
trns21
*
xa3d
+
trns22
*
ya3d
+
trns23
*
za3d
;
RealOpenMM
za3
=
trns31
*
xa3d
+
trns32
*
ya3d
+
trns33
*
za3d
;
RealOpenMM
xb3
=
trns11
*
xb3d
+
trns12
*
yb3d
+
trns13
*
zb3d
;
RealOpenMM
yb3
=
trns21
*
xb3d
+
trns22
*
yb3d
+
trns23
*
zb3d
;
RealOpenMM
zb3
=
trns31
*
xb3d
+
trns32
*
yb3d
+
trns33
*
zb3d
;
RealOpenMM
xc3
=
trns11
*
xc3d
+
trns12
*
yc3d
+
trns13
*
zc3d
;
RealOpenMM
yc3
=
trns21
*
xc3d
+
trns22
*
yc3d
+
trns23
*
zc3d
;
RealOpenMM
zc3
=
trns31
*
xc3d
+
trns32
*
yc3d
+
trns33
*
zc3d
;
xp0
[
0
]
=
xcom
+
xa3
;
xp0
[
1
]
=
ycom
+
ya3
;
xp0
[
2
]
=
zcom
+
za3
;
xp1
[
0
]
=
xcom
+
xb3
-
xb0
;
xp1
[
1
]
=
ycom
+
yb3
-
yb0
;
xp1
[
2
]
=
zcom
+
zb3
-
zb0
;
xp2
[
0
]
=
xcom
+
xc3
-
xc0
;
xp2
[
1
]
=
ycom
+
yc3
-
yc0
;
xp2
[
2
]
=
zcom
+
zc3
-
zc0
;
// Record the new positions.
atomCoordinatesP
[
atom1
[
index
]]
=
xp0
+
apos0
;
atomCoordinatesP
[
atom2
[
index
]]
=
xp1
+
apos1
;
atomCoordinatesP
[
atom3
[
index
]]
=
xp2
+
apos2
;
}
}
void
ReferenceSETTLEAlgorithm
::
applyToVelocities
(
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
vector
<
OpenMM
::
RealVec
>&
velocities
,
vector
<
RealOpenMM
>&
inverseMasses
)
{
for
(
int
index
=
0
;
index
<
(
int
)
atom1
.
size
();
++
index
)
{
RealVec
apos0
=
atomCoordinates
[
atom1
[
index
]];
RealVec
apos1
=
atomCoordinates
[
atom2
[
index
]];
RealVec
apos2
=
atomCoordinates
[
atom3
[
index
]];
RealVec
v0
=
velocities
[
atom1
[
index
]];
RealVec
v1
=
velocities
[
atom2
[
index
]];
RealVec
v2
=
velocities
[
atom3
[
index
]];
// Compute intermediate quantities: the atom masses, the bond directions, the relative velocities,
// and the angle cosines and sines.
RealOpenMM
mA
=
masses
[
atom1
[
index
]];
RealOpenMM
mB
=
masses
[
atom2
[
index
]];
RealOpenMM
mC
=
masses
[
atom3
[
index
]];
RealVec
eAB
=
apos1
-
apos0
;
RealVec
eBC
=
apos2
-
apos1
;
RealVec
eCA
=
apos0
-
apos2
;
eAB
/=
sqrt
(
eAB
[
0
]
*
eAB
[
0
]
+
eAB
[
1
]
*
eAB
[
1
]
+
eAB
[
2
]
*
eAB
[
2
]);
eBC
/=
sqrt
(
eBC
[
0
]
*
eBC
[
0
]
+
eBC
[
1
]
*
eBC
[
1
]
+
eBC
[
2
]
*
eBC
[
2
]);
eCA
/=
sqrt
(
eCA
[
0
]
*
eCA
[
0
]
+
eCA
[
1
]
*
eCA
[
1
]
+
eCA
[
2
]
*
eCA
[
2
]);
RealOpenMM
vAB
=
(
v1
[
0
]
-
v0
[
0
])
*
eAB
[
0
]
+
(
v1
[
1
]
-
v0
[
1
])
*
eAB
[
1
]
+
(
v1
[
2
]
-
v0
[
2
])
*
eAB
[
2
];
RealOpenMM
vBC
=
(
v2
[
0
]
-
v1
[
0
])
*
eBC
[
0
]
+
(
v2
[
1
]
-
v1
[
1
])
*
eBC
[
1
]
+
(
v2
[
2
]
-
v1
[
2
])
*
eBC
[
2
];
RealOpenMM
vCA
=
(
v0
[
0
]
-
v2
[
0
])
*
eCA
[
0
]
+
(
v0
[
1
]
-
v2
[
1
])
*
eCA
[
1
]
+
(
v0
[
2
]
-
v2
[
2
])
*
eCA
[
2
];
RealOpenMM
cA
=
-
(
eAB
[
0
]
*
eCA
[
0
]
+
eAB
[
1
]
*
eCA
[
1
]
+
eAB
[
2
]
*
eCA
[
2
]);
RealOpenMM
cB
=
-
(
eAB
[
0
]
*
eBC
[
0
]
+
eAB
[
1
]
*
eBC
[
1
]
+
eAB
[
2
]
*
eBC
[
2
]);
RealOpenMM
cC
=
-
(
eBC
[
0
]
*
eCA
[
0
]
+
eBC
[
1
]
*
eCA
[
1
]
+
eBC
[
2
]
*
eCA
[
2
]);
RealOpenMM
s2A
=
1
-
cA
*
cA
;
RealOpenMM
s2B
=
1
-
cB
*
cB
;
RealOpenMM
s2C
=
1
-
cC
*
cC
;
// Solve the equations. These are different from those in the SETTLE paper (JCC 13(8), pp. 952-962, 1992), because
// in going from equations B1 to B2, they make the assumption that mB=mC (but don't bother to mention they're
// making that assumption). We allow all three atoms to have different masses.
RealOpenMM
mABCinv
=
1
/
(
mA
*
mB
*
mC
);
RealOpenMM
denom
=
(((
s2A
*
mB
+
s2B
*
mA
)
*
mC
+
(
s2A
*
mB
*
mB
+
2
*
(
cA
*
cB
*
cC
+
1
)
*
mA
*
mB
+
s2B
*
mA
*
mA
))
*
mC
+
s2C
*
mA
*
mB
*
(
mA
+
mB
))
*
mABCinv
;
RealOpenMM
tab
=
((
cB
*
cC
*
mA
-
cA
*
mB
-
cA
*
mC
)
*
vCA
+
(
cA
*
cC
*
mB
-
cB
*
mC
-
cB
*
mA
)
*
vBC
+
(
s2C
*
mA
*
mA
*
mB
*
mB
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vAB
)
/
denom
;
RealOpenMM
tbc
=
((
cA
*
cB
*
mC
-
cC
*
mB
-
cC
*
mA
)
*
vCA
+
(
s2A
*
mB
*
mB
*
mC
*
mC
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vBC
+
(
cA
*
cC
*
mB
-
cB
*
mA
-
cB
*
mC
)
*
vAB
)
/
denom
;
RealOpenMM
tca
=
((
s2B
*
mA
*
mA
*
mC
*
mC
*
mABCinv
+
(
mA
+
mB
+
mC
))
*
vCA
+
(
cA
*
cB
*
mC
-
cC
*
mB
-
cC
*
mA
)
*
vBC
+
(
cB
*
cC
*
mA
-
cA
*
mB
-
cA
*
mC
)
*
vAB
)
/
denom
;
v0
+=
(
eAB
*
tab
-
eCA
*
tca
)
*
inverseMasses
[
atom1
[
index
]];
v1
+=
(
eBC
*
tbc
-
eAB
*
tab
)
*
inverseMasses
[
atom2
[
index
]];
v2
+=
(
eCA
*
tca
-
eBC
*
tbc
)
*
inverseMasses
[
atom3
[
index
]];
velocities
[
atom1
[
index
]]
=
v0
;
velocities
[
atom2
[
index
]]
=
v1
;
velocities
[
atom3
[
index
]]
=
v2
;
}
}
platforms/reference/src/SimTKReference/ReferenceShakeAlgorithm.cpp
deleted
100644 → 0
View file @
471bea82
/* Portions copyright (c) 2006-2009 Stanford University and Simbios.
* Contributors: Pande Group
*
* 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 <string.h>
#include <sstream>
#include "SimTKOpenMMCommon.h"
#include "SimTKOpenMMUtilities.h"
#include "SimTKOpenMMLog.h"
#include "ReferenceShakeAlgorithm.h"
#include "ReferenceDynamics.h"
#include "openmm/OpenMMException.h"
using
std
::
vector
;
using
OpenMM
::
RealVec
;
/**---------------------------------------------------------------------------------------
ReferenceShakeAlgorithm constructor
@param numberOfConstraints number of constraints
@param atomIndices block of atom indices
@param shakeParameters Shake parameters
@param tolerance constraint tolerance
--------------------------------------------------------------------------------------- */
ReferenceShakeAlgorithm
::
ReferenceShakeAlgorithm
(
int
numberOfConstraints
,
int
**
atomIndices
,
RealOpenMM
*
distance
,
RealOpenMM
tolerance
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::ReferenceShakeAlgorithm";
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
int
threeI
=
3
;
// ---------------------------------------------------------------------------------------
_numberOfConstraints
=
numberOfConstraints
;
_atomIndices
=
atomIndices
;
_distance
=
distance
;
_maximumNumberOfIterations
=
150
;
_tolerance
=
tolerance
;
_hasInitializedMasses
=
false
;
// work arrays
if
(
_numberOfConstraints
>
0
)
{
_r_ij
=
SimTKOpenMMUtilities
::
allocateTwoDRealOpenMMArray
(
numberOfConstraints
,
threeI
,
NULL
,
1
,
zero
,
"r_ij"
);
_d_ij2
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
zero
,
"dij_2"
);
_distanceTolerance
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
zero
,
"distanceTolerance"
);
_reducedMasses
=
SimTKOpenMMUtilities
::
allocateOneDRealOpenMMArray
(
numberOfConstraints
,
NULL
,
1
,
zero
,
"reducedMasses"
);
}
}
/**---------------------------------------------------------------------------------------
ReferenceShakeAlgorithm destructor
--------------------------------------------------------------------------------------- */
ReferenceShakeAlgorithm
::~
ReferenceShakeAlgorithm
(
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::~ReferenceShakeAlgorithm";
// ---------------------------------------------------------------------------------------
if
(
_numberOfConstraints
>
0
)
{
SimTKOpenMMUtilities
::
freeTwoDRealOpenMMArray
(
_r_ij
,
"r_ij"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_d_ij2
,
"d_ij2"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_distanceTolerance
,
"distanceTolerance"
);
SimTKOpenMMUtilities
::
freeOneDRealOpenMMArray
(
_reducedMasses
,
"reducedMasses"
);
}
}
/**---------------------------------------------------------------------------------------
Get number of constraints
@return number of constraints
--------------------------------------------------------------------------------------- */
int
ReferenceShakeAlgorithm
::
getNumberOfConstraints
(
void
)
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::getNumberOfConstraints";
// ---------------------------------------------------------------------------------------
return
_numberOfConstraints
;
}
/**---------------------------------------------------------------------------------------
Get maximum number of iterations
@return maximum number of iterations
--------------------------------------------------------------------------------------- */
int
ReferenceShakeAlgorithm
::
getMaximumNumberOfIterations
(
void
)
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::getMaximumNumberOfIterations";
// ---------------------------------------------------------------------------------------
return
_maximumNumberOfIterations
;
}
/**---------------------------------------------------------------------------------------
Set maximum number of iterations
@param maximumNumberOfIterations new maximum number of iterations
--------------------------------------------------------------------------------------- */
void
ReferenceShakeAlgorithm
::
setMaximumNumberOfIterations
(
int
maximumNumberOfIterations
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::setMaximumNumberOfIterations";
// ---------------------------------------------------------------------------------------
_maximumNumberOfIterations
=
maximumNumberOfIterations
;
}
/**---------------------------------------------------------------------------------------
Get tolerance
@return tolerance
--------------------------------------------------------------------------------------- */
RealOpenMM
ReferenceShakeAlgorithm
::
getTolerance
(
void
)
const
{
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::getTolerance";
// ---------------------------------------------------------------------------------------
return
_tolerance
;
}
/**---------------------------------------------------------------------------------------
Set tolerance
@param tolerance new tolerance
--------------------------------------------------------------------------------------- */
void
ReferenceShakeAlgorithm
::
setTolerance
(
RealOpenMM
tolerance
){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceShakeAlgorithm::setTolerance";
// ---------------------------------------------------------------------------------------
_tolerance
=
tolerance
;;
}
/**---------------------------------------------------------------------------------------
Apply Shake algorithm
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomCoordinatesP atom coordinates prime
@param inverseMasses 1/mass
@return SimTKOpenMMCommon::DefaultReturn if converge; else
return SimTKOpenMMCommon::ErrorReturn
--------------------------------------------------------------------------------------- */
int
ReferenceShakeAlgorithm
::
apply
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
vector
<
RealVec
>&
atomCoordinatesP
,
vector
<
RealOpenMM
>&
inverseMasses
){
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceShakeAlgorithm::apply"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
RealOpenMM
half
=
0.5
;
static
const
RealOpenMM
epsilon6
=
(
RealOpenMM
)
1.0e-06
;
// ---------------------------------------------------------------------------------------
int
numberOfConstraints
=
getNumberOfConstraints
();
// temp arrays
RealOpenMM
**
r_ij
=
_r_ij
;
RealOpenMM
*
d_ij2
=
_d_ij2
;
RealOpenMM
*
distanceTolerance
=
_distanceTolerance
;
RealOpenMM
*
reducedMasses
=
_reducedMasses
;
// calculate reduced masses on 1st pass
if
(
!
_hasInitializedMasses
){
_hasInitializedMasses
=
true
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
][
0
];
int
atomJ
=
_atomIndices
[
ii
][
1
];
reducedMasses
[
ii
]
=
half
/
(
inverseMasses
[
atomI
]
+
inverseMasses
[
atomJ
]
);
}
}
// setup: r_ij for each (i,j) constraint
RealOpenMM
tolerance
=
getTolerance
();
tolerance
*=
two
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
][
0
];
int
atomJ
=
_atomIndices
[
ii
][
1
];
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
){
r_ij
[
ii
][
jj
]
=
atomCoordinates
[
atomI
][
jj
]
-
atomCoordinates
[
atomJ
][
jj
];
}
d_ij2
[
ii
]
=
DOT3
(
r_ij
[
ii
],
r_ij
[
ii
]
);
distanceTolerance
[
ii
]
=
d_ij2
[
ii
]
*
tolerance
;
if
(
distanceTolerance
[
ii
]
>
zero
){
distanceTolerance
[
ii
]
=
one
/
distanceTolerance
[
ii
];
}
}
// main loop
int
done
=
0
;
int
iterations
=
0
;
int
numberConverged
=
0
;
while
(
!
done
&&
iterations
++
<
getMaximumNumberOfIterations
()
){
numberConverged
=
0
;
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
][
0
];
int
atomJ
=
_atomIndices
[
ii
][
1
];
RealOpenMM
rp_ij
[
3
];
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
){
rp_ij
[
jj
]
=
atomCoordinatesP
[
atomI
][
jj
]
-
atomCoordinatesP
[
atomJ
][
jj
];
}
RealOpenMM
rp2
=
DOT3
(
rp_ij
,
rp_ij
);
RealOpenMM
dist2
=
_distance
[
ii
]
*
_distance
[
ii
];
RealOpenMM
diff
=
dist2
-
rp2
;
int
iconv
=
(
int
)
(
FABS
(
diff
)
*
distanceTolerance
[
ii
]
);
if
(
iconv
){
RealOpenMM
rrpr
=
DOT3
(
rp_ij
,
r_ij
[
ii
]
);
RealOpenMM
acor
;
if
(
rrpr
<
d_ij2
[
ii
]
*
epsilon6
){
std
::
stringstream
message
;
message
<<
iterations
<<
" Error: sign of rrpr < 0?
\n
"
;
SimTKOpenMMLog
::
printMessage
(
message
);
}
else
{
acor
=
reducedMasses
[
ii
]
*
diff
/
rrpr
;
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
){
RealOpenMM
dr
=
acor
*
r_ij
[
ii
][
jj
];
atomCoordinatesP
[
atomI
][
jj
]
+=
inverseMasses
[
atomI
]
*
dr
;
atomCoordinatesP
[
atomJ
][
jj
]
-=
inverseMasses
[
atomJ
]
*
dr
;
}
}
}
else
{
numberConverged
++
;
}
}
if
(
numberConverged
==
_numberOfConstraints
){
done
=
true
;
}
}
return
(
done
?
SimTKOpenMMCommon
::
DefaultReturn
:
SimTKOpenMMCommon
::
ErrorReturn
);
}
/**---------------------------------------------------------------------------------------
Apply constraint algorithm to velocities.
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param velocities atom velocities
@param inverseMasses 1/mass
@return SimTKOpenMMCommon::DefaultReturn if converge; else
return SimTKOpenMMCommon::ErrorReturn
--------------------------------------------------------------------------------------- */
int
ReferenceShakeAlgorithm
::
applyToVelocities
(
int
numberOfAtoms
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
RealVec
>&
velocities
,
std
::
vector
<
RealOpenMM
>&
inverseMasses
)
{
throw
OpenMM
::
OpenMMException
(
"applyToVelocities is not implemented"
);
}
/**---------------------------------------------------------------------------------------
Report any violated constriants
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param message report
@return number of violated constraints
--------------------------------------------------------------------------------------- */
int
ReferenceShakeAlgorithm
::
reportShake
(
int
numberOfAtoms
,
vector
<
RealVec
>&
atomCoordinates
,
std
::
stringstream
&
message
){
// ---------------------------------------------------------------------------------------
static
const
char
*
methodName
=
"
\n
ReferenceShakeAlgorithm::reportShake"
;
static
const
RealOpenMM
zero
=
0.0
;
static
const
RealOpenMM
one
=
1.0
;
static
const
RealOpenMM
two
=
2.0
;
static
const
RealOpenMM
three
=
3.0
;
static
const
RealOpenMM
oneM
=
-
1.0
;
static
const
RealOpenMM
half
=
0.5
;
// ---------------------------------------------------------------------------------------
int
numberOfConstraints
=
getNumberOfConstraints
();
// loop over constraints calculating distance and comparing to
// expected distance -- report any contraints that are violated
int
numberConverged
=
0
;
RealOpenMM
tolerance
=
getTolerance
();
for
(
int
ii
=
0
;
ii
<
_numberOfConstraints
;
ii
++
){
int
atomI
=
_atomIndices
[
ii
][
0
];
int
atomJ
=
_atomIndices
[
ii
][
1
];
RealOpenMM
rp2
=
zero
;
for
(
int
jj
=
0
;
jj
<
3
;
jj
++
){
rp2
+=
(
atomCoordinates
[
atomI
][
jj
]
-
atomCoordinates
[
atomJ
][
jj
])
*
(
atomCoordinates
[
atomI
][
jj
]
-
atomCoordinates
[
atomJ
][
jj
]);
}
RealOpenMM
diff
=
FABS
(
rp2
-
(
_distance
[
ii
]
*
_distance
[
ii
])
);
if
(
diff
>
tolerance
){
message
<<
ii
<<
" constraint violated: "
<<
atomI
<<
" "
<<
atomJ
<<
"] d="
<<
SQRT
(
rp2
)
<<
" "
<<
rp2
<<
" d0="
<<
_distance
[
ii
];
message
<<
" diff="
<<
diff
;
message
<<
" ["
<<
atomCoordinates
[
atomI
][
0
]
<<
" "
<<
atomCoordinates
[
atomI
][
1
]
<<
" "
<<
atomCoordinates
[
atomI
][
2
]
<<
"] "
;
message
<<
" ["
<<
atomCoordinates
[
atomJ
][
0
]
<<
" "
<<
atomCoordinates
[
atomJ
][
1
]
<<
" "
<<
atomCoordinates
[
atomJ
][
2
]
<<
"] "
;
message
<<
"
\n
"
;
}
else
{
numberConverged
++
;
}
}
return
(
numberOfConstraints
-
numberConverged
);
}
Prev
1
2
3
4
5
6
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