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
e8e4694d
Unverified
Commit
e8e4694d
authored
May 02, 2025
by
Peter Eastman
Committed by
GitHub
May 02, 2025
Browse files
Neutralizing plasma self energy for AMOEBA (#4920)
parent
dd320bcf
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
134 additions
and
9 deletions
+134
-9
plugins/amoeba/platforms/common/src/AmoebaCommonKernels.cpp
plugins/amoeba/platforms/common/src/AmoebaCommonKernels.cpp
+30
-2
plugins/amoeba/platforms/common/src/AmoebaCommonKernels.h
plugins/amoeba/platforms/common/src/AmoebaCommonKernels.h
+2
-2
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceHippoNonbondedForce.cpp
...src/SimTKReference/AmoebaReferenceHippoNonbondedForce.cpp
+8
-2
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
...ence/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
+6
-1
plugins/amoeba/tests/TestAmoebaMultipoleForce.h
plugins/amoeba/tests/TestAmoebaMultipoleForce.h
+44
-1
plugins/amoeba/tests/TestHippoNonbondedForce.h
plugins/amoeba/tests/TestHippoNonbondedForce.h
+44
-1
No files found.
plugins/amoeba/platforms/common/src/AmoebaCommonKernels.cpp
View file @
e8e4694d
...
@@ -233,11 +233,13 @@ void CommonCalcAmoebaMultipoleForceKernel::initialize(const System& system, cons
...
@@ -233,11 +233,13 @@ void CommonCalcAmoebaMultipoleForceKernel::initialize(const System& system, cons
vector
<
float
>
localDipolesVec
;
vector
<
float
>
localDipolesVec
;
vector
<
float
>
localQuadrupolesVec
;
vector
<
float
>
localQuadrupolesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
totalCharge
=
0.0
;
for
(
int
i
=
0
;
i
<
numMultipoles
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numMultipoles
;
i
++
)
{
double
charge
,
thole
,
damping
,
polarity
;
double
charge
,
thole
,
damping
,
polarity
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
vector
<
double
>
dipole
,
quadrupole
;
vector
<
double
>
dipole
,
quadrupole
;
force
.
getMultipoleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
axisType
,
atomZ
,
atomX
,
atomY
,
thole
,
damping
,
polarity
);
force
.
getMultipoleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
axisType
,
atomZ
,
atomX
,
atomY
,
thole
,
damping
,
polarity
);
totalCharge
+=
charge
;
if
(
cc
.
getUseDoublePrecision
())
if
(
cc
.
getUseDoublePrecision
())
posqd
[
i
]
=
mm_double4
(
0
,
0
,
0
,
charge
);
posqd
[
i
]
=
mm_double4
(
0
,
0
,
0
,
charge
);
else
else
...
@@ -1228,7 +1230,17 @@ double CommonCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool
...
@@ -1228,7 +1230,17 @@ double CommonCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool
cc
.
getPosq
().
copyTo
(
lastPositions
);
cc
.
getPosq
().
copyTo
(
lastPositions
);
multipolesAreValid
=
true
;
multipolesAreValid
=
true
;
return
0.0
;
// Correction for the neutralizing plasma.
if
(
usePME
)
{
Vec3
a
,
b
,
c
;
cc
.
getPeriodicBoxVectors
(
a
,
b
,
c
);
double
volume
=
a
[
0
]
*
b
[
1
]
*
c
[
2
];
return
-
totalCharge
*
totalCharge
/
(
8
*
EPSILON0
*
volume
*
pmeAlpha
*
pmeAlpha
);
}
else
return
0.0
;
}
}
void
CommonCalcAmoebaMultipoleForceKernel
::
computeInducedField
()
{
void
CommonCalcAmoebaMultipoleForceKernel
::
computeInducedField
()
{
...
@@ -1664,11 +1676,13 @@ void CommonCalcAmoebaMultipoleForceKernel::copyParametersToContext(ContextImpl&
...
@@ -1664,11 +1676,13 @@ void CommonCalcAmoebaMultipoleForceKernel::copyParametersToContext(ContextImpl&
vector
<
float
>
localDipolesVec
;
vector
<
float
>
localDipolesVec
;
vector
<
float
>
localQuadrupolesVec
;
vector
<
float
>
localQuadrupolesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
totalCharge
=
0.0
;
for
(
int
i
=
0
;
i
<
force
.
getNumMultipoles
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumMultipoles
();
i
++
)
{
double
charge
,
thole
,
damping
,
polarity
;
double
charge
,
thole
,
damping
,
polarity
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
vector
<
double
>
dipole
,
quadrupole
;
vector
<
double
>
dipole
,
quadrupole
;
force
.
getMultipoleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
axisType
,
atomZ
,
atomX
,
atomY
,
thole
,
damping
,
polarity
);
force
.
getMultipoleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
axisType
,
atomZ
,
atomX
,
atomY
,
thole
,
damping
,
polarity
);
totalCharge
+=
charge
;
if
(
cc
.
getUseDoublePrecision
())
if
(
cc
.
getUseDoublePrecision
())
posqd
[
i
].
w
=
charge
;
posqd
[
i
].
w
=
charge
;
else
else
...
@@ -2424,12 +2438,14 @@ void CommonCalcHippoNonbondedForceKernel::initialize(const System& system, const
...
@@ -2424,12 +2438,14 @@ void CommonCalcHippoNonbondedForceKernel::initialize(const System& system, const
vector
<
double
>
localDipolesVec
,
localQuadrupolesVec
;
vector
<
double
>
localDipolesVec
,
localQuadrupolesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
vector
<
vector
<
int
>
>
exclusions
(
numParticles
);
vector
<
vector
<
int
>
>
exclusions
(
numParticles
);
totalCharge
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
double
charge
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
polarizability
;
double
charge
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
polarizability
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
vector
<
double
>
dipole
,
quadrupole
;
vector
<
double
>
dipole
,
quadrupole
;
force
.
getParticleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
force
.
getParticleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
polarizability
,
axisType
,
atomZ
,
atomX
,
atomY
);
polarizability
,
axisType
,
atomZ
,
atomX
,
atomY
);
totalCharge
+=
charge
;
coreChargeVec
.
push_back
(
coreCharge
);
coreChargeVec
.
push_back
(
coreCharge
);
valenceChargeVec
.
push_back
(
charge
-
coreCharge
);
valenceChargeVec
.
push_back
(
charge
-
coreCharge
);
alphaVec
.
push_back
(
alpha
);
alphaVec
.
push_back
(
alpha
);
...
@@ -3378,7 +3394,17 @@ double CommonCalcHippoNonbondedForceKernel::execute(ContextImpl& context, bool i
...
@@ -3378,7 +3394,17 @@ double CommonCalcHippoNonbondedForceKernel::execute(ContextImpl& context, bool i
cc
.
getPosq
().
copyTo
(
lastPositions
);
cc
.
getPosq
().
copyTo
(
lastPositions
);
multipolesAreValid
=
true
;
multipolesAreValid
=
true
;
return
0.0
;
// Correction for the neutralizing plasma.
if
(
usePME
)
{
Vec3
a
,
b
,
c
;
cc
.
getPeriodicBoxVectors
(
a
,
b
,
c
);
double
volume
=
a
[
0
]
*
b
[
1
]
*
c
[
2
];
return
-
totalCharge
*
totalCharge
/
(
8
*
EPSILON0
*
volume
*
pmeAlpha
*
pmeAlpha
);
}
else
return
0.0
;
}
}
void
CommonCalcHippoNonbondedForceKernel
::
computeInducedField
(
int
optOrder
)
{
void
CommonCalcHippoNonbondedForceKernel
::
computeInducedField
(
int
optOrder
)
{
...
@@ -3513,12 +3539,14 @@ void CommonCalcHippoNonbondedForceKernel::copyParametersToContext(ContextImpl& c
...
@@ -3513,12 +3539,14 @@ void CommonCalcHippoNonbondedForceKernel::copyParametersToContext(ContextImpl& c
vector
<
double
>
coreChargeVec
,
valenceChargeVec
,
alphaVec
,
epsilonVec
,
dampingVec
,
c6Vec
,
pauliKVec
,
pauliQVec
,
pauliAlphaVec
,
polarizabilityVec
;
vector
<
double
>
coreChargeVec
,
valenceChargeVec
,
alphaVec
,
epsilonVec
,
dampingVec
,
c6Vec
,
pauliKVec
,
pauliQVec
,
pauliAlphaVec
,
polarizabilityVec
;
vector
<
double
>
localDipolesVec
,
localQuadrupolesVec
;
vector
<
double
>
localDipolesVec
,
localQuadrupolesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
vector
<
mm_int4
>
multipoleParticlesVec
;
totalCharge
=
0.0
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
double
charge
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
polarizability
;
double
charge
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
polarizability
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
int
axisType
,
atomX
,
atomY
,
atomZ
;
vector
<
double
>
dipole
,
quadrupole
;
vector
<
double
>
dipole
,
quadrupole
;
force
.
getParticleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
force
.
getParticleParameters
(
i
,
charge
,
dipole
,
quadrupole
,
coreCharge
,
alpha
,
epsilon
,
damping
,
c6
,
pauliK
,
pauliQ
,
pauliAlpha
,
polarizability
,
axisType
,
atomZ
,
atomX
,
atomY
);
polarizability
,
axisType
,
atomZ
,
atomX
,
atomY
);
totalCharge
+=
charge
;
coreChargeVec
.
push_back
(
coreCharge
);
coreChargeVec
.
push_back
(
coreCharge
);
valenceChargeVec
.
push_back
(
charge
-
coreCharge
);
valenceChargeVec
.
push_back
(
charge
-
coreCharge
);
alphaVec
.
push_back
(
alpha
);
alphaVec
.
push_back
(
alpha
);
...
...
plugins/amoeba/platforms/common/src/AmoebaCommonKernels.h
View file @
e8e4694d
...
@@ -168,7 +168,7 @@ protected:
...
@@ -168,7 +168,7 @@ protected:
int
numMultipoles
,
maxInducedIterations
,
maxExtrapolationOrder
;
int
numMultipoles
,
maxInducedIterations
,
maxExtrapolationOrder
;
int
fixedFieldThreads
,
inducedFieldThreads
,
electrostaticsThreads
;
int
fixedFieldThreads
,
inducedFieldThreads
,
electrostaticsThreads
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
double
pmeAlpha
,
inducedEpsilon
;
double
pmeAlpha
,
inducedEpsilon
,
totalCharge
;
bool
usePME
,
hasQuadrupoles
,
hasInitializedScaleFactors
,
multipolesAreValid
,
hasCreatedEvent
;
bool
usePME
,
hasQuadrupoles
,
hasInitializedScaleFactors
,
multipolesAreValid
,
hasCreatedEvent
;
AmoebaMultipoleForce
::
PolarizationType
polarizationType
;
AmoebaMultipoleForce
::
PolarizationType
polarizationType
;
ComputeContext
&
cc
;
ComputeContext
&
cc
;
...
@@ -507,7 +507,7 @@ protected:
...
@@ -507,7 +507,7 @@ protected:
int
numParticles
,
maxExtrapolationOrder
,
maxTiles
,
fieldThreadBlockSize
;
int
numParticles
,
maxExtrapolationOrder
,
maxTiles
,
fieldThreadBlockSize
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
gridSizeX
,
gridSizeY
,
gridSizeZ
;
int
dispersionGridSizeX
,
dispersionGridSizeY
,
dispersionGridSizeZ
;
int
dispersionGridSizeX
,
dispersionGridSizeY
,
dispersionGridSizeZ
;
double
pmeAlpha
,
dpmeAlpha
,
cutoff
;
double
pmeAlpha
,
dpmeAlpha
,
cutoff
,
totalCharge
;
bool
usePME
,
hasInitializedKernels
,
multipolesAreValid
;
bool
usePME
,
hasInitializedKernels
,
multipolesAreValid
;
std
::
vector
<
double
>
extrapolationCoefficients
;
std
::
vector
<
double
>
extrapolationCoefficients
;
ComputeContext
&
cc
;
ComputeContext
&
cc
;
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceHippoNonbondedForce.cpp
View file @
e8e4694d
/* Portions copyright (c) 2006-202
2
Stanford University and Simbios.
/* Portions copyright (c) 2006-202
5
Stanford University and Simbios.
* Contributors: Pande Group
* Contributors: Pande Group
*
*
* Permission is hereby granted, free of charge, to any person obtaining
* Permission is hereby granted, free of charge, to any person obtaining
...
@@ -2503,9 +2503,11 @@ double AmoebaReferencePmeHippoNonbondedForce::calculatePmeSelfEnergy(const vecto
...
@@ -2503,9 +2503,11 @@ double AmoebaReferencePmeHippoNonbondedForce::calculatePmeSelfEnergy(const vecto
double
dii
=
0.0
;
double
dii
=
0.0
;
double
qii
=
0.0
;
double
qii
=
0.0
;
double
c6ii
=
0.0
;
double
c6ii
=
0.0
;
double
totalCharge
=
0.0
;
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
const
MultipoleParticleData
&
particleI
=
particleData
[
i
];
const
MultipoleParticleData
&
particleI
=
particleData
[
i
];
double
charge
=
particleI
.
coreCharge
+
particleI
.
valenceCharge
;
double
charge
=
particleI
.
coreCharge
+
particleI
.
valenceCharge
;
totalCharge
+=
charge
;
cii
+=
charge
*
charge
;
cii
+=
charge
*
charge
;
dii
+=
particleI
.
dipole
.
dot
(
particleI
.
dipole
);
dii
+=
particleI
.
dipole
.
dot
(
particleI
.
dipole
);
qii
+=
particleI
.
quadrupole
[
QXX
]
*
particleI
.
quadrupole
[
QXX
]
+
qii
+=
particleI
.
quadrupole
[
QXX
]
*
particleI
.
quadrupole
[
QXX
]
+
...
@@ -2519,7 +2521,11 @@ double AmoebaReferencePmeHippoNonbondedForce::calculatePmeSelfEnergy(const vecto
...
@@ -2519,7 +2521,11 @@ double AmoebaReferencePmeHippoNonbondedForce::calculatePmeSelfEnergy(const vecto
double
term
=
2
*
_alphaEwald
*
_alphaEwald
;
double
term
=
2
*
_alphaEwald
*
_alphaEwald
;
double
fterm
=
-
_electric
*
_alphaEwald
/
SQRT_PI
;
double
fterm
=
-
_electric
*
_alphaEwald
/
SQRT_PI
;
double
alpha3
=
_dalphaEwald
*
_dalphaEwald
*
_dalphaEwald
;
double
alpha3
=
_dalphaEwald
*
_dalphaEwald
*
_dalphaEwald
;
return
fterm
*
(
cii
+
term
*
(
dii
/
3
+
2
*
term
*
qii
/
5
))
+
alpha3
*
alpha3
*
c6ii
/
12
;
double
energy
=
fterm
*
(
cii
+
term
*
(
dii
/
3
+
2
*
term
*
qii
/
5
))
+
alpha3
*
alpha3
*
c6ii
/
12
;
// Correction for the neutralizing plasma.
double
volume
=
_periodicBoxVectors
[
0
][
0
]
*
_periodicBoxVectors
[
1
][
1
]
*
_periodicBoxVectors
[
2
][
2
];
energy
-=
totalCharge
*
totalCharge
/
(
8
*
EPSILON0
*
volume
*
_alphaEwald
*
_alphaEwald
);
return
energy
;
}
}
void
AmoebaReferencePmeHippoNonbondedForce
::
calculatePmeSelfTorque
(
const
vector
<
MultipoleParticleData
>&
particleData
,
void
AmoebaReferencePmeHippoNonbondedForce
::
calculatePmeSelfTorque
(
const
vector
<
MultipoleParticleData
>&
particleData
,
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
View file @
e8e4694d
/* Portions copyright (c) 2006-2
22
Stanford University and Simbios.
/* Portions copyright (c) 2006-2
025
Stanford University and Simbios.
* Contributors: Pande Group
* Contributors: Pande Group
*
*
* Permission is hereby granted, free of charge, to any person obtaining
* Permission is hereby granted, free of charge, to any person obtaining
...
@@ -6370,10 +6370,12 @@ double AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector<Mul
...
@@ -6370,10 +6370,12 @@ double AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector<Mul
double cii = 0.0;
double cii = 0.0;
double dii = 0.0;
double dii = 0.0;
double qii = 0.0;
double qii = 0.0;
double totalCharge = 0.0;
for (unsigned int ii = 0; ii < _numParticles; ii++) {
for (unsigned int ii = 0; ii < _numParticles; ii++) {
const MultipoleParticleData& particleI = particleData[ii];
const MultipoleParticleData& particleI = particleData[ii];
totalCharge += particleI.charge;
cii += particleI.charge*particleI.charge;
cii += particleI.charge*particleI.charge;
Vec3 dipole(particleI.sphericalDipole[1], particleI.sphericalDipole[2], particleI.sphericalDipole[0]);
Vec3 dipole(particleI.sphericalDipole[1], particleI.sphericalDipole[2], particleI.sphericalDipole[0]);
...
@@ -6389,6 +6391,9 @@ double AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector<Mul
...
@@ -6389,6 +6391,9 @@ double AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector<Mul
double a2 = _alphaEwald * _alphaEwald;
double a2 = _alphaEwald * _alphaEwald;
double a4 = a2*a2;
double a4 = a2*a2;
double energy = prefac*(cii + twoThirds*a2*dii + fourOverFifteen*a4*qii);
double energy = prefac*(cii + twoThirds*a2*dii + fourOverFifteen*a4*qii);
// Correction for the neutralizing plasma.
double volume = _periodicBoxVectors[0][0] * _periodicBoxVectors[1][1] * _periodicBoxVectors[2][2];
energy -= totalCharge*totalCharge/(8*EPSILON0*volume*_alphaEwald*_alphaEwald);
return energy;
return energy;
}
}
...
...
plugins/amoeba/tests/TestAmoebaMultipoleForce.h
View file @
e8e4694d
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-20
1
2 Stanford University and the Authors. *
* Portions copyright (c) 2008-202
5
Stanford University and the Authors. *
* Authors: Mark Friedrichs *
* Authors: Mark Friedrichs *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -3261,6 +3261,48 @@ void testZOnly() {
...
@@ -3261,6 +3261,48 @@ void testZOnly() {
ASSERT_EQUAL_TOL
(
state2
.
getPotentialEnergy
(),
state3
.
getPotentialEnergy
()
+
norm
*
delta
,
1e-3
)
ASSERT_EQUAL_TOL
(
state2
.
getPotentialEnergy
(),
state3
.
getPotentialEnergy
()
+
norm
*
delta
,
1e-3
)
}
}
void
testNeutralizingPlasmaCorrection
()
{
// Verify that the energy of a system with nonzero charge doesn't depend on alpha.
System
system
;
AmoebaMultipoleForce
*
force
=
new
AmoebaMultipoleForce
();
force
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
PME
);
system
.
addForce
(
force
);
vector
<
double
>
d
(
3
,
-
.0
),
q
(
9
,
0.0
);
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addMultipole
(
1.0
,
d
,
q
,
AmoebaMultipoleForce
::
NoAxisType
,
0
,
0
,
0
,
0.39
,
0.33
,
0.001
);
}
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
();
positions
[
1
]
=
Vec3
(
0.3
,
0.4
,
0.0
);
// Compute the energy.
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
double
energy1
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
// Change the cutoff distance, which will change alpha, and see if the energy is the same.
force
->
setCutoffDistance
(
0.7
);
context
.
reinitialize
(
true
);
double
energy2
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
energy1
,
energy2
,
1e-4
);
// Try changing a particle charge with updateParametersInContext() and make sure the
// energy changes by the correct amount.
force
->
setMultipoleParameters
(
0
,
2.0
,
d
,
q
,
AmoebaMultipoleForce
::
NoAxisType
,
0
,
0
,
0
,
0.39
,
0.33
,
0.001
);
force
->
updateParametersInContext
(
context
);
double
energy3
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
force
->
setCutoffDistance
(
1.0
);
context
.
reinitialize
(
true
);
double
energy4
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
energy3
,
energy4
,
1e-4
);
}
void
setupKernels
(
int
argc
,
char
*
argv
[]);
void
setupKernels
(
int
argc
,
char
*
argv
[]);
void
runPlatformTests
();
void
runPlatformTests
();
...
@@ -3318,6 +3360,7 @@ int main(int argc, char* argv[]) {
...
@@ -3318,6 +3360,7 @@ int main(int argc, char* argv[]) {
// test the ZOnly axis type.
// test the ZOnly axis type.
testZOnly
();
testZOnly
();
testNeutralizingPlasmaCorrection
();
runPlatformTests
();
runPlatformTests
();
}
}
...
...
plugins/amoeba/tests/TestHippoNonbondedForce.h
View file @
e8e4694d
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2019 Stanford University and the Authors.
*
* Portions copyright (c) 2019
-2025
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -1542,6 +1542,48 @@ void testChangingParameters() {
...
@@ -1542,6 +1542,48 @@ void testChangingParameters() {
ASSERT_EQUAL_VEC
(
state2
.
getForces
()[
i
],
state3
.
getForces
()[
i
],
1e-5
);
ASSERT_EQUAL_VEC
(
state2
.
getForces
()[
i
],
state3
.
getForces
()[
i
],
1e-5
);
}
}
void
testNeutralizingPlasmaCorrection
()
{
// Verify that the energy of a system with nonzero charge doesn't depend on alpha.
System
system
;
HippoNonbondedForce
*
force
=
new
HippoNonbondedForce
();
force
->
setNonbondedMethod
(
HippoNonbondedForce
::
PME
);
system
.
addForce
(
force
);
vector
<
double
>
d
(
3
,
0.0
),
q
(
9
,
0.0
);
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
system
.
addParticle
(
1.0
);
force
->
addParticle
(
1.0
,
d
,
q
,
6.0
,
50.0
,
5000.0
,
400.0
,
0.04
,
1.5
,
-
2.4233
,
40.0
,
0.001
,
HippoNonbondedForce
::
NoAxisType
,
-
1
,
-
1
,
-
1
);
}
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
();
positions
[
1
]
=
Vec3
(
0.3
,
0.4
,
0.0
);
// Compute the energy.
VerletIntegrator
integrator
(
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
double
energy1
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
// Change the cutoff distance, which will change alpha, and see if the energy is the same.
force
->
setCutoffDistance
(
0.7
);
context
.
reinitialize
(
true
);
double
energy2
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
energy1
,
energy2
,
1e-4
);
// Try changing a particle charge with updateParametersInContext() and make sure the
// energy changes by the correct amount.
force
->
setParticleParameters
(
0
,
2.0
,
d
,
q
,
6.0
,
50.0
,
5000.0
,
400.0
,
0.04
,
1.5
,
-
2.4233
,
40.0
,
0.001
,
HippoNonbondedForce
::
NoAxisType
,
-
1
,
-
1
,
-
1
);
force
->
updateParametersInContext
(
context
);
double
energy3
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
force
->
setCutoffDistance
(
1.0
);
context
.
reinitialize
(
true
);
double
energy4
=
context
.
getState
(
State
::
Energy
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
energy3
,
energy4
,
1e-4
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
try
{
setupKernels
(
argc
,
argv
);
setupKernels
(
argc
,
argv
);
...
@@ -1562,6 +1604,7 @@ int main(int argc, char* argv[]) {
...
@@ -1562,6 +1604,7 @@ int main(int argc, char* argv[]) {
testWaterDimer
();
testWaterDimer
();
testWaterBox
();
testWaterBox
();
testChangingParameters
();
testChangingParameters
();
testNeutralizingPlasmaCorrection
();
}
}
catch
(
const
std
::
exception
&
e
)
{
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
std
::
cout
<<
"exception: "
<<
e
.
what
()
<<
std
::
endl
;
...
...
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