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
cd03350c
Commit
cd03350c
authored
Dec 15, 2015
by
Peter Eastman
Browse files
Lots of cleanup to extrapolated polarization
parent
51f82c02
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
133 additions
and
107 deletions
+133
-107
plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h
...ns/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h
+20
-13
plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp
plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp
+9
-10
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
...amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
+5
-5
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h
...s/amoeba/platforms/reference/src/AmoebaReferenceKernels.h
+1
-1
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
...ence/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
+49
-56
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h
...erence/src/SimTKReference/AmoebaReferenceMultipoleForce.h
+9
-9
plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPTPolarization.cpp
...rms/reference/tests/TestReferenceAmoebaPTPolarization.cpp
+8
-9
plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp
...ns/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp
+24
-4
plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp
...serialization/tests/TestSerializeAmoebaMultipoleForce.cpp
+8
-0
No files found.
plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h
View file @
cd03350c
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
2
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
5
Stanford University and the Authors. *
* Authors: Mark Friedrichs, Peter Eastman *
* Authors: Mark Friedrichs, Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -72,19 +72,24 @@ public:
...
@@ -72,19 +72,24 @@ public:
enum
PolarizationType
{
enum
PolarizationType
{
/**
/**
* Mutual polarization
* Full mutually induced polarization. The dipoles are iterated until the converge to the accuracy specified
* by getMutualInducedTargetEpsilon().
*/
*/
Mutual
=
0
,
Mutual
=
0
,
/**
/**
* Direct polarization
* Direct polarization approximation. The induced dipoles depend only on the fixed multipoles, not on other
* induced dipoles.
*/
*/
Direct
=
1
,
Direct
=
1
,
/**
/**
* Optimized perturbation theory
* Extrapolated perturbation theory approximation. The dipoles are iterated a few times, and then an analytic
* approximation is used to extrapolate to the fully converged values. Call setExtrapolationCoefficients()
* to set the coefficients used for the extrapolation. The default coefficients used in this release are
* [0, -0.3, 0, 1.3], but be aware that those may change in a future release.
*/
*/
OPT
=
2
Extrapolated
=
2
};
};
...
@@ -305,19 +310,21 @@ public:
...
@@ -305,19 +310,21 @@ public:
void
setMutualInducedTargetEpsilon
(
double
inputMutualInducedTargetEpsilon
);
void
setMutualInducedTargetEpsilon
(
double
inputMutualInducedTargetEpsilon
);
/**
/**
* Set the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the
perturb
ation
* Set the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the
extrapol
ation
*
theory
algorithm for induced dipoles.
* algorithm for induced dipoles.
*
*
* @param optCoefficients a vector whose mth entry specifies the coefficient for mu_m
* @param coefficients a vector whose mth entry specifies the coefficient for mu_m. The length of this
* vector determines how many iterations are performed.
*
*
*/
*/
void
set
OPT
Coefficients
(
const
std
::
vector
<
double
>
&
OPTFullC
oefficients
In
);
void
set
Extrapolation
Coefficients
(
const
std
::
vector
<
double
>
&
c
oefficients
);
/**
/**
* Get the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the perturbation
* Get the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the extrapolation
* theory algorithm for induced dipoles.
* algorithm for induced dipoles. In this release, the default values for the coefficients are
* [0, -0.3, 0, 1.3], but be aware that those may change in a future release.
*/
*/
const
std
::
vector
<
double
>&
get
OPT
Coefficients
()
const
;
const
std
::
vector
<
double
>&
get
Extrapolation
Coefficients
()
const
;
/**
/**
* Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces
* Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces
...
@@ -405,7 +412,7 @@ private:
...
@@ -405,7 +412,7 @@ private:
int
pmeBSplineOrder
;
int
pmeBSplineOrder
;
std
::
vector
<
int
>
pmeGridDimension
;
std
::
vector
<
int
>
pmeGridDimension
;
int
mutualInducedMaxIterations
;
int
mutualInducedMaxIterations
;
std
::
vector
<
double
>
OPTFull
Coefficients
;
std
::
vector
<
double
>
extrapolation
Coefficients
;
double
mutualInducedTargetEpsilon
;
double
mutualInducedTargetEpsilon
;
double
scalingDistanceCutoff
;
double
scalingDistanceCutoff
;
...
...
plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp
View file @
cd03350c
...
@@ -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
09
Stanford University and the Authors. *
* Portions copyright (c) 2008-20
15
Stanford University and the Authors. *
* Authors: *
* Authors: *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -43,6 +43,10 @@ AmoebaMultipoleForce::AmoebaMultipoleForce() : nonbondedMethod(NoCutoff), polari
...
@@ -43,6 +43,10 @@ AmoebaMultipoleForce::AmoebaMultipoleForce() : nonbondedMethod(NoCutoff), polari
mutualInducedTargetEpsilon
(
1.0e-02
),
scalingDistanceCutoff
(
100.0
),
electricConstant
(
138.9354558456
),
aewald
(
0.0
)
{
mutualInducedTargetEpsilon
(
1.0e-02
),
scalingDistanceCutoff
(
100.0
),
electricConstant
(
138.9354558456
),
aewald
(
0.0
)
{
pmeGridDimension
.
resize
(
3
);
pmeGridDimension
.
resize
(
3
);
pmeGridDimension
[
0
]
=
pmeGridDimension
[
1
]
=
pmeGridDimension
[
2
];
pmeGridDimension
[
0
]
=
pmeGridDimension
[
1
]
=
pmeGridDimension
[
2
];
extrapolationCoefficients
.
push_back
(
0.0
);
extrapolationCoefficients
.
push_back
(
-
0.3
);
extrapolationCoefficients
.
push_back
(
0.0
);
extrapolationCoefficients
.
push_back
(
1.3
);
}
}
AmoebaMultipoleForce
::
NonbondedMethod
AmoebaMultipoleForce
::
getNonbondedMethod
()
const
{
AmoebaMultipoleForce
::
NonbondedMethod
AmoebaMultipoleForce
::
getNonbondedMethod
()
const
{
...
@@ -61,19 +65,14 @@ void AmoebaMultipoleForce::setPolarizationType(AmoebaMultipoleForce::Polarizatio
...
@@ -61,19 +65,14 @@ void AmoebaMultipoleForce::setPolarizationType(AmoebaMultipoleForce::Polarizatio
polarizationType
=
type
;
polarizationType
=
type
;
}
}
void
AmoebaMultipoleForce
::
setOPTCoefficients
(
const
std
::
vector
<
double
>
&
OPTFullCoefficientsIn
)
void
AmoebaMultipoleForce
::
setExtrapolationCoefficients
(
const
std
::
vector
<
double
>
&
coefficients
)
{
{
extrapolationCoefficients
=
coefficients
;
size_t
maxPTOrder
=
OPTFullCoefficientsIn
.
size
();
OPTFullCoefficients
.
resize
(
maxPTOrder
);
std
::
copy
(
OPTFullCoefficientsIn
.
begin
(),
OPTFullCoefficientsIn
.
end
(),
OPTFullCoefficients
.
begin
());
}
}
const
std
::
vector
<
double
>
&
AmoebaMultipoleForce
::
getOPTCoefficients
()
const
const
std
::
vector
<
double
>
&
AmoebaMultipoleForce
::
getExtrapolationCoefficients
()
const
{
{
return
extrapolationCoefficients
;
return
OPTFullCoefficients
;
}
}
double
AmoebaMultipoleForce
::
getCutoffDistance
()
const
{
double
AmoebaMultipoleForce
::
getCutoffDistance
()
const
{
return
cutoffDistance
;
return
cutoffDistance
;
}
}
...
...
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
View file @
cd03350c
...
@@ -565,8 +565,8 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
...
@@ -565,8 +565,8 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
if
(
polarizationType
==
AmoebaMultipoleForce
::
Mutual
)
{
if
(
polarizationType
==
AmoebaMultipoleForce
::
Mutual
)
{
mutualInducedMaxIterations
=
force
.
getMutualInducedMaxIterations
();
mutualInducedMaxIterations
=
force
.
getMutualInducedMaxIterations
();
mutualInducedTargetEpsilon
=
force
.
getMutualInducedTargetEpsilon
();
mutualInducedTargetEpsilon
=
force
.
getMutualInducedTargetEpsilon
();
}
else
if
(
polarizationType
==
AmoebaMultipoleForce
::
OPT
)
{
}
else
if
(
polarizationType
==
AmoebaMultipoleForce
::
Extrapolated
)
{
OPTFull
Coefficients
=
force
.
get
OPT
Coefficients
();
extrapolation
Coefficients
=
force
.
get
Extrapolation
Coefficients
();
}
}
// PME
// PME
...
@@ -669,9 +669,9 @@ AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmo
...
@@ -669,9 +669,9 @@ AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmo
amoebaReferenceMultipoleForce
->
setMaximumMutualInducedDipoleIterations
(
mutualInducedMaxIterations
);
amoebaReferenceMultipoleForce
->
setMaximumMutualInducedDipoleIterations
(
mutualInducedMaxIterations
);
}
else
if
(
polarizationType
==
AmoebaMultipoleForce
::
Direct
)
{
}
else
if
(
polarizationType
==
AmoebaMultipoleForce
::
Direct
)
{
amoebaReferenceMultipoleForce
->
setPolarizationType
(
AmoebaReferenceMultipoleForce
::
Direct
);
amoebaReferenceMultipoleForce
->
setPolarizationType
(
AmoebaReferenceMultipoleForce
::
Direct
);
}
else
if
(
polarizationType
==
AmoebaMultipoleForce
::
OPT
)
{
}
else
if
(
polarizationType
==
AmoebaMultipoleForce
::
Extrapolated
)
{
amoebaReferenceMultipoleForce
->
setPolarizationType
(
AmoebaReferenceMultipoleForce
::
OPT
);
amoebaReferenceMultipoleForce
->
setPolarizationType
(
AmoebaReferenceMultipoleForce
::
Extrapolated
);
amoebaReferenceMultipoleForce
->
set
OPTCoefficients
(
OPTFull
Coefficients
);
amoebaReferenceMultipoleForce
->
set
ExtrapolationCoefficients
(
extrapolation
Coefficients
);
}
else
{
}
else
{
throw
OpenMMException
(
"Polarization type not recognzied."
);
throw
OpenMMException
(
"Polarization type not recognzied."
);
}
}
...
...
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h
View file @
cd03350c
...
@@ -432,7 +432,7 @@ private:
...
@@ -432,7 +432,7 @@ private:
int
mutualInducedMaxIterations
;
int
mutualInducedMaxIterations
;
RealOpenMM
mutualInducedTargetEpsilon
;
RealOpenMM
mutualInducedTargetEpsilon
;
std
::
vector
<
double
>
OPTFull
Coefficients
;
std
::
vector
<
double
>
extrapolation
Coefficients
;
bool
usePme
;
bool
usePme
;
RealOpenMM
alphaEwald
;
RealOpenMM
alphaEwald
;
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
View file @
cd03350c
...
@@ -161,16 +161,15 @@ RealOpenMM AmoebaReferenceMultipoleForce::getMutualInducedDipoleTargetEpsilon()
...
@@ -161,16 +161,15 @@ RealOpenMM AmoebaReferenceMultipoleForce::getMutualInducedDipoleTargetEpsilon()
return
_mutualInducedDipoleTargetEpsilon
;
return
_mutualInducedDipoleTargetEpsilon
;
}
}
void AmoebaReferenceMultipoleForce::set
OPT
Coefficients(const std::vector<RealOpenMM> &
OPTFullC
oefficients)
void
AmoebaReferenceMultipoleForce
::
set
Extrapolation
Coefficients
(
const
std
::
vector
<
RealOpenMM
>
&
c
oefficients
)
{
{
_maxPTOrder = OPTFullCoefficients.size(); // This accounts for the zero-based counting; actual highest order is 1 less
_maxPTOrder
=
coefficients
.
size
();
// This accounts for the zero-based counting; actual highest order is 1 less
_OPTFullCoefficients.resize(_maxPTOrder);
_extrapolationCoefficients
=
coefficients
;
_OPTPartCoefficients.resize(_maxPTOrder);
_extPartCoefficients
.
resize
(
_maxPTOrder
);
std::copy(OPTFullCoefficients.begin(), OPTFullCoefficients.end(), _OPTFullCoefficients.begin());
for
(
int
i
=
0
;
i
<
_maxPTOrder
;
++
i
)
{
for(int i = 0; i < _maxPTOrder; ++i){
_extPartCoefficients
[
i
]
=
0.0
;
_OPTPartCoefficients[i] = 0.0;
for
(
int
j
=
i
;
j
<
_maxPTOrder
;
++
j
)
for(int j = i; j < _maxPTOrder; ++j)
_extPartCoefficients
[
i
]
+=
_extrapolationCoefficients
[
j
];
_OPTPartCoefficients[i] += _OPTFullCoefficients[j];
}
}
}
}
...
@@ -568,7 +567,7 @@ void AmoebaReferenceMultipoleForce::formQIRotationMatrix(const RealVec& iPositio
...
@@ -568,7 +567,7 @@ void AmoebaReferenceMultipoleForce::formQIRotationMatrix(const RealVec& iPositio
{
{
RealVec
vectorZ
=
(
deltaR
)
/
r
;
RealVec
vectorZ
=
(
deltaR
)
/
r
;
RealVec
vectorX
(
vectorZ
);
RealVec
vectorX
(
vectorZ
);
if ((iPosition[1] != jPosition[1]) || (iPosition[2] != jPosition[2])){
if
((
iPosition
[
1
]
!=
jPosition
[
1
])
||
(
iPosition
[
2
]
!=
jPosition
[
2
]))
{
vectorX
[
0
]
+=
1.0
;
vectorX
[
0
]
+=
1.0
;
}
else
{
}
else
{
vectorX
[
1
]
+=
1.0
;
vectorX
[
1
]
+=
1.0
;
...
@@ -813,8 +812,8 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipolePairIxns(const Multipo
...
@@ -813,8 +812,8 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipolePairIxns(const Multipo
RealVec
deltaR
=
particleJ
.
position
-
particleI
.
position
;
RealVec
deltaR
=
particleJ
.
position
-
particleI
.
position
;
RealOpenMM
r
=
SQRT
(
deltaR
.
dot
(
deltaR
));
RealOpenMM
r
=
SQRT
(
deltaR
.
dot
(
deltaR
));
vector
<
RealOpenMM
>
rrI
(
2
);
vector
<
RealOpenMM
>
rrI
(
2
);
// If we're using the
OPT
algorithm, we need to compute the field gradient, so ask for one more rrI value.
// If we're using the
extrapolation
algorithm, we need to compute the field gradient, so ask for one more rrI value.
if (getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT
)
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
rrI
.
push_back
(
0.0
);
rrI
.
push_back
(
0.0
);
getAndScaleInverseRs
(
particleI
.
dampingFactor
,
particleJ
.
dampingFactor
,
getAndScaleInverseRs
(
particleI
.
dampingFactor
,
particleJ
.
dampingFactor
,
...
@@ -826,7 +825,7 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipolePairIxns(const Multipo
...
@@ -826,7 +825,7 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipolePairIxns(const Multipo
for
(
unsigned
int
ii
=
0
;
ii
<
updateInducedDipoleFields
.
size
();
ii
++
)
{
for
(
unsigned
int
ii
=
0
;
ii
<
updateInducedDipoleFields
.
size
();
ii
++
)
{
calculateInducedDipolePairIxn
(
particleI
.
particleIndex
,
particleJ
.
particleIndex
,
rr3
,
rr5
,
deltaR
,
calculateInducedDipolePairIxn
(
particleI
.
particleIndex
,
particleJ
.
particleIndex
,
rr3
,
rr5
,
deltaR
,
*
updateInducedDipoleFields
[
ii
].
inducedDipoles
,
updateInducedDipoleFields
[
ii
].
inducedDipoleField
);
*
updateInducedDipoleFields
[
ii
].
inducedDipoles
,
updateInducedDipoleFields
[
ii
].
inducedDipoleField
);
if (getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT)
{
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
{
// Compute and store the field gradient for later use.
// Compute and store the field gradient for later use.
RealOpenMM
dx
=
deltaR
[
0
];
RealOpenMM
dx
=
deltaR
[
0
];
RealOpenMM
dy
=
deltaR
[
1
];
RealOpenMM
dy
=
deltaR
[
1
];
...
@@ -959,13 +958,7 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesBySOR(const vector<Mult
...
@@ -959,13 +958,7 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesBySOR(const vector<Mult
}
}
void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<MultipoleParticleData>& particleData, vector<UpdateInducedDipoleFieldStruct>& updateInducedDipoleField) {
void
AmoebaReferenceMultipoleForce
::
convergeInduceDipolesByExtrapolation
(
const
vector
<
MultipoleParticleData
>&
particleData
,
vector
<
UpdateInducedDipoleFieldStruct
>&
updateInducedDipoleField
)
{
if (_OPTFullCoefficients.empty()){
std::stringstream message;
message << "An OPT calcultion was requested, but setOPTCoefficients() was not called.";
throw OpenMMException(message.str());
}
_ptDipoleD
.
clear
();
_ptDipoleD
.
clear
();
_ptDipoleP
.
clear
();
_ptDipoleP
.
clear
();
...
@@ -975,7 +968,7 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
...
@@ -975,7 +968,7 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
// Start by storing the direct dipoles as PT0
// Start by storing the direct dipoles as PT0
vector
<
RealVec
>
thisDipoleD
;
vector
<
RealVec
>
thisDipoleD
;
vector
<
RealVec
>
thisDipoleP
;
vector
<
RealVec
>
thisDipoleP
;
for(int atom = 0; atom < _numParticles; ++atom){
for
(
int
atom
=
0
;
atom
<
_numParticles
;
++
atom
)
{
thisDipoleD
.
push_back
((
*
fieldD
.
inducedDipoles
)[
atom
]);
thisDipoleD
.
push_back
((
*
fieldD
.
inducedDipoles
)[
atom
]);
thisDipoleP
.
push_back
((
*
fieldP
.
inducedDipoles
)[
atom
]);
thisDipoleP
.
push_back
((
*
fieldP
.
inducedDipoles
)[
atom
]);
}
}
...
@@ -988,13 +981,13 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
...
@@ -988,13 +981,13 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
fieldP
.
inducedDipoleFieldGradient
.
resize
(
_numParticles
);
fieldP
.
inducedDipoleFieldGradient
.
resize
(
_numParticles
);
// Recursively apply alpha.Tau to the µ_(n) components to generate µ_(n+1), and store the result
// Recursively apply alpha.Tau to the µ_(n) components to generate µ_(n+1), and store the result
for(int order = 1; order < _maxPTOrder; ++order){
for
(
int
order
=
1
;
order
<
_maxPTOrder
;
++
order
)
{
std
::
fill
(
fieldD
.
inducedDipoleFieldGradient
.
begin
(),
fieldD
.
inducedDipoleFieldGradient
.
end
(),
zeros
);
std
::
fill
(
fieldD
.
inducedDipoleFieldGradient
.
begin
(),
fieldD
.
inducedDipoleFieldGradient
.
end
(),
zeros
);
std
::
fill
(
fieldP
.
inducedDipoleFieldGradient
.
begin
(),
fieldP
.
inducedDipoleFieldGradient
.
end
(),
zeros
);
std
::
fill
(
fieldP
.
inducedDipoleFieldGradient
.
begin
(),
fieldP
.
inducedDipoleFieldGradient
.
end
(),
zeros
);
calculateInducedDipoleFields
(
particleData
,
updateInducedDipoleField
);
calculateInducedDipoleFields
(
particleData
,
updateInducedDipoleField
);
vector
<
RealVec
>
thisDipoleD
;
vector
<
RealVec
>
thisDipoleD
;
vector
<
RealVec
>
thisDipoleP
;
vector
<
RealVec
>
thisDipoleP
;
for(int atom = 0; atom < _numParticles; ++atom){
for
(
int
atom
=
0
;
atom
<
_numParticles
;
++
atom
)
{
(
*
fieldD
.
inducedDipoles
)[
atom
]
=
fieldD
.
inducedDipoleField
[
atom
]
*
particleData
[
atom
].
polarity
;
(
*
fieldD
.
inducedDipoles
)[
atom
]
=
fieldD
.
inducedDipoleField
[
atom
]
*
particleData
[
atom
].
polarity
;
(
*
fieldP
.
inducedDipoles
)[
atom
]
=
fieldP
.
inducedDipoleField
[
atom
]
*
particleData
[
atom
].
polarity
;
(
*
fieldP
.
inducedDipoles
)[
atom
]
=
fieldP
.
inducedDipoleField
[
atom
]
*
particleData
[
atom
].
polarity
;
thisDipoleD
.
push_back
((
*
fieldD
.
inducedDipoles
)[
atom
]);
thisDipoleD
.
push_back
((
*
fieldD
.
inducedDipoles
)[
atom
]);
...
@@ -1004,8 +997,8 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
...
@@ -1004,8 +997,8 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
_ptDipoleP
.
push_back
(
thisDipoleP
);
_ptDipoleP
.
push_back
(
thisDipoleP
);
vector
<
RealOpenMM
>
fieldGradD
(
6
*
_numParticles
,
0.0
);
vector
<
RealOpenMM
>
fieldGradD
(
6
*
_numParticles
,
0.0
);
vector
<
RealOpenMM
>
fieldGradP
(
6
*
_numParticles
,
0.0
);
vector
<
RealOpenMM
>
fieldGradP
(
6
*
_numParticles
,
0.0
);
for(int atom = 0; atom < _numParticles; ++atom){
for
(
int
atom
=
0
;
atom
<
_numParticles
;
++
atom
)
{
for(int component = 0; component < 6; ++component){
for
(
int
component
=
0
;
component
<
6
;
++
component
)
{
fieldGradD
[
6
*
atom
+
component
]
=
fieldD
.
inducedDipoleFieldGradient
[
atom
][
component
];
fieldGradD
[
6
*
atom
+
component
]
=
fieldD
.
inducedDipoleFieldGradient
[
atom
][
component
];
fieldGradP
[
6
*
atom
+
component
]
=
fieldP
.
inducedDipoleFieldGradient
[
atom
][
component
];
fieldGradP
[
6
*
atom
+
component
]
=
fieldP
.
inducedDipoleFieldGradient
[
atom
][
component
];
}
}
...
@@ -1019,16 +1012,16 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
...
@@ -1019,16 +1012,16 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesByOPT(const vector<Mult
std
::
fill
(
_inducedDipole
.
begin
(),
_inducedDipole
.
end
(),
zeroVec
);
std
::
fill
(
_inducedDipole
.
begin
(),
_inducedDipole
.
end
(),
zeroVec
);
std
::
fill
(
_inducedDipolePolar
.
begin
(),
_inducedDipolePolar
.
end
(),
zeroVec
);
std
::
fill
(
_inducedDipolePolar
.
begin
(),
_inducedDipolePolar
.
end
(),
zeroVec
);
for(int order = 0; order < _maxPTOrder; ++order){
for
(
int
order
=
0
;
order
<
_maxPTOrder
;
++
order
)
{
for(int atom = 0; atom < _numParticles; ++atom){
for
(
int
atom
=
0
;
atom
<
_numParticles
;
++
atom
)
{
_inducedDipole[atom] += _ptDipoleD[order][atom] * _
OPT
PartCoefficients[order];
_inducedDipole
[
atom
]
+=
_ptDipoleD
[
order
][
atom
]
*
_
ext
PartCoefficients
[
order
];
_inducedDipolePolar[atom] += _ptDipoleP[order][atom] * _
OPT
PartCoefficients[order];
_inducedDipolePolar
[
atom
]
+=
_ptDipoleP
[
order
][
atom
]
*
_
ext
PartCoefficients
[
order
];
}
}
}
}
// Copy the combined dipoles over to compute the field
// Copy the combined dipoles over to compute the field
for(int order = 0; order < _maxPTOrder; ++order){
for
(
int
order
=
0
;
order
<
_maxPTOrder
;
++
order
)
{
for(int atom = 0; atom < _numParticles; ++atom){
for
(
int
atom
=
0
;
atom
<
_numParticles
;
++
atom
)
{
(
*
fieldD
.
inducedDipoles
)[
atom
]
=
_inducedDipole
[
atom
];
(
*
fieldD
.
inducedDipoles
)[
atom
]
=
_inducedDipole
[
atom
];
(
*
fieldP
.
inducedDipoles
)[
atom
]
=
_inducedDipolePolar
[
atom
];
(
*
fieldP
.
inducedDipoles
)[
atom
]
=
_inducedDipolePolar
[
atom
];
}
}
...
@@ -1177,10 +1170,10 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipoles(const vector<Multipo
...
@@ -1177,10 +1170,10 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipoles(const vector<Multipo
// UpdateInducedDipoleFieldStruct contains induced dipole, fixed multipole fields and fields
// UpdateInducedDipoleFieldStruct contains induced dipole, fixed multipole fields and fields
// due to other induced dipoles at each site
// due to other induced dipoles at each site
if (getPolarizationType() == AmoebaReferenceMultipoleForce::Mutual){
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Mutual
)
{
convergeInduceDipolesByDIIS
(
particleData
,
updateInducedDipoleField
);
convergeInduceDipolesByDIIS
(
particleData
,
updateInducedDipoleField
);
}if (getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT)
{
}
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
{
convergeInduceDipolesBy
OPT
(particleData, updateInducedDipoleField);
convergeInduceDipolesBy
Extrapolation
(
particleData
,
updateInducedDipoleField
);
}
}
}
}
...
@@ -1298,7 +1291,7 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPairIxn(const Mu
...
@@ -1298,7 +1291,7 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPairIxn(const Mu
// The rInvVec array is defined such that the ith element is R^-i, with the
// The rInvVec array is defined such that the ith element is R^-i, with the
// dieleectric constant folded in, to avoid conversions later.
// dieleectric constant folded in, to avoid conversions later.
rInvVec
[
1
]
=
prefac
*
rInv
;
rInvVec
[
1
]
=
prefac
*
rInv
;
for(int i = 2; i < 7; ++i)
for
(
int
i
=
2
;
i
<
7
;
++
i
)
rInvVec
[
i
]
=
rInvVec
[
i
-
1
]
*
rInv
;
rInvVec
[
i
]
=
rInvVec
[
i
-
1
]
*
rInv
;
RealOpenMM
mScale
=
scalingFactors
[
M_SCALE
];
RealOpenMM
mScale
=
scalingFactors
[
M_SCALE
];
...
@@ -1504,7 +1497,7 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPairIxn(const Mu
...
@@ -1504,7 +1497,7 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPairIxn(const Mu
RealOpenMM
fIZ
=
qiQI
[
0
]
*
VijR
[
0
];
RealOpenMM
fIZ
=
qiQI
[
0
]
*
VijR
[
0
];
RealOpenMM
fJZ
=
qiQJ
[
0
]
*
VjiR
[
0
];
RealOpenMM
fJZ
=
qiQJ
[
0
]
*
VjiR
[
0
];
RealOpenMM
EIX
=
0.0
,
EIY
=
0.0
,
EIZ
=
0.0
,
EJX
=
0.0
,
EJY
=
0.0
,
EJZ
=
0.0
;
RealOpenMM
EIX
=
0.0
,
EIY
=
0.0
,
EIZ
=
0.0
,
EJX
=
0.0
,
EJY
=
0.0
,
EJZ
=
0.0
;
for(int i = 1; i < 9; ++i){
for
(
int
i
=
1
;
i
<
9
;
++
i
)
{
energy
+=
0.5
*
(
qiQI
[
i
]
*
Vij
[
i
]
+
qiQJ
[
i
]
*
Vji
[
i
]);
energy
+=
0.5
*
(
qiQI
[
i
]
*
Vij
[
i
]
+
qiQJ
[
i
]
*
Vji
[
i
]);
fIZ
+=
qiQI
[
i
]
*
VijR
[
i
];
fIZ
+=
qiQI
[
i
]
*
VijR
[
i
];
fJZ
+=
qiQJ
[
i
]
*
VjiR
[
i
];
fJZ
+=
qiQJ
[
i
]
*
VjiR
[
i
];
...
@@ -1532,7 +1525,7 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPairIxn(const Mu
...
@@ -1532,7 +1525,7 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPairIxn(const Mu
RealOpenMM
iEJY
=
qiUinpJ
[
0
]
*
Vjip
[
1
]
+
qiUindJ
[
0
]
*
Vjid
[
1
]
-
qiUinpJ
[
1
]
*
Vjip
[
0
]
-
qiUindJ
[
1
]
*
Vjid
[
0
];
RealOpenMM
iEJY
=
qiUinpJ
[
0
]
*
Vjip
[
1
]
+
qiUindJ
[
0
]
*
Vjid
[
1
]
-
qiUinpJ
[
1
]
*
Vjip
[
0
]
-
qiUindJ
[
1
]
*
Vjid
[
0
];
// Add in the induced-induced terms, if needed.
// Add in the induced-induced terms, if needed.
if(getPolarizationType() == AmoebaReferenceMultipoleForce::Mutual){
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Mutual
)
{
// Uind-Uind terms (m=0)
// Uind-Uind terms (m=0)
RealOpenMM
eCoef
=
-
4.0
*
rInvVec
[
3
]
*
uScale
*
thole_d0
;
RealOpenMM
eCoef
=
-
4.0
*
rInvVec
[
3
]
*
uScale
*
thole_d0
;
RealOpenMM
dCoef
=
6.0
*
rInvVec
[
4
]
*
uScale
*
dthole_d0
;
RealOpenMM
dCoef
=
6.0
*
rInvVec
[
4
]
*
uScale
*
dthole_d0
;
...
@@ -1846,13 +1839,13 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostatic(const vector<Mu
...
@@ -1846,13 +1839,13 @@ RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostatic(const vector<Mu
}
}
}
}
}
}
if (getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT)
{
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
{
RealOpenMM
prefac
=
(
_electric
/
_dielectric
);
RealOpenMM
prefac
=
(
_electric
/
_dielectric
);
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
// Compute the µ(m) T µ(n) force contributions here
// Compute the µ(m) T µ(n) force contributions here
for(int l = 0; l < _maxPTOrder-1; ++l) {
for
(
int
l
=
0
;
l
<
_maxPTOrder
-
1
;
++
l
)
{
for(int m = 0; m < _maxPTOrder-1-l; ++m) {
for
(
int
m
=
0
;
m
<
_maxPTOrder
-
1
-
l
;
++
m
)
{
RealOpenMM p = _
OPT
PartCoefficients[l+m+1];
RealOpenMM
p
=
_
ext
PartCoefficients
[
l
+
m
+
1
];
if
(
std
::
fabs
(
p
)
<
1e-6
)
continue
;
if
(
std
::
fabs
(
p
)
<
1e-6
)
continue
;
forces
[
i
][
0
]
+=
0.5
*
p
*
prefac
*
(
_ptDipoleD
[
l
][
i
][
0
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
0
]
forces
[
i
][
0
]
+=
0.5
*
p
*
prefac
*
(
_ptDipoleD
[
l
][
i
][
0
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
0
]
+
_ptDipoleD
[
l
][
i
][
1
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
3
]
+
_ptDipoleD
[
l
][
i
][
1
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
3
]
...
@@ -6091,7 +6084,7 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector
...
@@ -6091,7 +6084,7 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector
calculateReciprocalSpaceInducedDipoleField
(
updateInducedDipoleFields
);
calculateReciprocalSpaceInducedDipoleField
(
updateInducedDipoleFields
);
if(getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT)
{
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
{
// While we have the reciprocal space (fractional coordinate) field gradient available, add it to the real space
// While we have the reciprocal space (fractional coordinate) field gradient available, add it to the real space
// terms computed above, after transforming to Cartesian coordinates. This allows real and reciprocal space
// terms computed above, after transforming to Cartesian coordinates. This allows real and reciprocal space
// dipole response force contributions to be computed together.
// dipole response force contributions to be computed together.
...
@@ -6109,8 +6102,8 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector
...
@@ -6109,8 +6102,8 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector
};
};
RealOpenMM
Exx
=
0.0
,
Eyy
=
0.0
,
Ezz
=
0.0
,
Exy
=
0.0
,
Exz
=
0.0
,
Eyz
=
0.0
;
RealOpenMM
Exx
=
0.0
,
Eyy
=
0.0
,
Ezz
=
0.0
,
Exy
=
0.0
,
Exz
=
0.0
,
Eyz
=
0.0
;
for(int k = 0; k < 3; ++k){
for
(
int
k
=
0
;
k
<
3
;
++
k
)
{
for(int l = 0; l < 3; ++l){
for
(
int
l
=
0
;
l
<
3
;
++
l
)
{
Exx
+=
fracToCart
[
0
][
k
]
*
EmatD
[
k
][
l
]
*
fracToCart
[
0
][
l
];
Exx
+=
fracToCart
[
0
][
k
]
*
EmatD
[
k
][
l
]
*
fracToCart
[
0
][
l
];
Eyy
+=
fracToCart
[
1
][
k
]
*
EmatD
[
k
][
l
]
*
fracToCart
[
1
][
l
];
Eyy
+=
fracToCart
[
1
][
k
]
*
EmatD
[
k
][
l
]
*
fracToCart
[
1
][
l
];
Ezz
+=
fracToCart
[
2
][
k
]
*
EmatD
[
k
][
l
]
*
fracToCart
[
2
][
l
];
Ezz
+=
fracToCart
[
2
][
k
]
*
EmatD
[
k
][
l
]
*
fracToCart
[
2
][
l
];
...
@@ -6133,8 +6126,8 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector
...
@@ -6133,8 +6126,8 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector
};
};
Exx
=
0.0
;
Eyy
=
0.0
;
Ezz
=
0.0
;
Exy
=
0.0
;
Exz
=
0.0
;
Eyz
=
0.0
;
Exx
=
0.0
;
Eyy
=
0.0
;
Ezz
=
0.0
;
Exy
=
0.0
;
Exz
=
0.0
;
Eyz
=
0.0
;
for(int k = 0; k < 3; ++k){
for
(
int
k
=
0
;
k
<
3
;
++
k
)
{
for(int l = 0; l < 3; ++l){
for
(
int
l
=
0
;
l
<
3
;
++
l
)
{
Exx
+=
fracToCart
[
0
][
k
]
*
EmatP
[
k
][
l
]
*
fracToCart
[
0
][
l
];
Exx
+=
fracToCart
[
0
][
k
]
*
EmatP
[
k
][
l
]
*
fracToCart
[
0
][
l
];
Eyy
+=
fracToCart
[
1
][
k
]
*
EmatP
[
k
][
l
]
*
fracToCart
[
1
][
l
];
Eyy
+=
fracToCart
[
1
][
k
]
*
EmatP
[
k
][
l
]
*
fracToCart
[
1
][
l
];
Ezz
+=
fracToCart
[
2
][
k
]
*
EmatP
[
k
][
l
]
*
fracToCart
[
2
][
l
];
Ezz
+=
fracToCart
[
2
][
k
]
*
EmatP
[
k
][
l
]
*
fracToCart
[
2
][
l
];
...
@@ -6260,7 +6253,7 @@ void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxns(cons
...
@@ -6260,7 +6253,7 @@ void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxns(cons
calculateDirectInducedDipolePairIxn
(
particleI
.
particleIndex
,
particleJ
.
particleIndex
,
preFactor1
,
preFactor2
,
deltaR
,
calculateDirectInducedDipolePairIxn
(
particleI
.
particleIndex
,
particleJ
.
particleIndex
,
preFactor1
,
preFactor2
,
deltaR
,
*
updateInducedDipoleFields
[
ii
].
inducedDipoles
,
*
updateInducedDipoleFields
[
ii
].
inducedDipoles
,
updateInducedDipoleFields
[
ii
].
inducedDipoleField
);
updateInducedDipoleFields
[
ii
].
inducedDipoleField
);
if (getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT)
{
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
{
// Compute and store the field gradient for later use.
// Compute and store the field gradient for later use.
RealOpenMM
dx
=
deltaR
[
0
];
RealOpenMM
dx
=
deltaR
[
0
];
RealOpenMM
dy
=
deltaR
[
1
];
RealOpenMM
dy
=
deltaR
[
1
];
...
@@ -6468,13 +6461,13 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeDirectElectrostaticPair
...
@@ -6468,13 +6461,13 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeDirectElectrostaticPair
// The rInvVec array is defined such that the ith element is R^-i, with the
// The rInvVec array is defined such that the ith element is R^-i, with the
// dieleectric constant folded in, to avoid conversions later.
// dieleectric constant folded in, to avoid conversions later.
rInvVec
[
1
]
=
prefac
*
rInv
;
rInvVec
[
1
]
=
prefac
*
rInv
;
for(int i = 2; i < 7; ++i)
for
(
int
i
=
2
;
i
<
7
;
++
i
)
rInvVec
[
i
]
=
rInvVec
[
i
-
1
]
*
rInv
;
rInvVec
[
i
]
=
rInvVec
[
i
-
1
]
*
rInv
;
// The alpharVec array is defined such that the ith element is (alpha R)^i,
// The alpharVec array is defined such that the ith element is (alpha R)^i,
// where kappa (alpha in OpenMM parlance) is the Ewald attenuation parameter.
// where kappa (alpha in OpenMM parlance) is the Ewald attenuation parameter.
alphaRVec
[
1
]
=
_alphaEwald
*
r
;
alphaRVec
[
1
]
=
_alphaEwald
*
r
;
for(int i = 2; i < 8; ++i)
for
(
int
i
=
2
;
i
<
8
;
++
i
)
alphaRVec
[
i
]
=
alphaRVec
[
i
-
1
]
*
alphaRVec
[
1
];
alphaRVec
[
i
]
=
alphaRVec
[
i
-
1
]
*
alphaRVec
[
1
];
RealOpenMM
erfAlphaR
=
erf
(
alphaRVec
[
1
]);
RealOpenMM
erfAlphaR
=
erf
(
alphaRVec
[
1
]);
...
@@ -6487,7 +6480,7 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeDirectElectrostaticPair
...
@@ -6487,7 +6480,7 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeDirectElectrostaticPair
int
doubleFactorial
=
1
,
facCount
=
1
;
int
doubleFactorial
=
1
,
facCount
=
1
;
RealOpenMM
tmp
=
alphaRVec
[
1
];
RealOpenMM
tmp
=
alphaRVec
[
1
];
bVec
[
1
]
=
-
erfAlphaR
;
bVec
[
1
]
=
-
erfAlphaR
;
for(int i=2; i < 5; ++i){
for
(
int
i
=
2
;
i
<
5
;
++
i
)
{
bVec
[
i
]
=
bVec
[
i
-
1
]
+
tmp
*
X
/
(
RealOpenMM
)(
doubleFactorial
);
bVec
[
i
]
=
bVec
[
i
-
1
]
+
tmp
*
X
/
(
RealOpenMM
)(
doubleFactorial
);
facCount
=
facCount
+
2
;
facCount
=
facCount
+
2
;
doubleFactorial
=
doubleFactorial
*
facCount
;
doubleFactorial
=
doubleFactorial
*
facCount
;
...
@@ -6692,7 +6685,7 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeDirectElectrostaticPair
...
@@ -6692,7 +6685,7 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeDirectElectrostaticPair
RealOpenMM
fIZ
=
qiQI
[
0
]
*
VijR
[
0
];
RealOpenMM
fIZ
=
qiQI
[
0
]
*
VijR
[
0
];
RealOpenMM
fJZ
=
qiQJ
[
0
]
*
VjiR
[
0
];
RealOpenMM
fJZ
=
qiQJ
[
0
]
*
VjiR
[
0
];
RealOpenMM
EIX
=
0.0
,
EIY
=
0.0
,
EIZ
=
0.0
,
EJX
=
0.0
,
EJY
=
0.0
,
EJZ
=
0.0
;
RealOpenMM
EIX
=
0.0
,
EIY
=
0.0
,
EIZ
=
0.0
,
EJX
=
0.0
,
EJY
=
0.0
,
EJZ
=
0.0
;
for(int i = 1; i < 9; ++i){
for
(
int
i
=
1
;
i
<
9
;
++
i
)
{
energy
+=
0.5
*
(
qiQI
[
i
]
*
Vij
[
i
]
+
qiQJ
[
i
]
*
Vji
[
i
]);
energy
+=
0.5
*
(
qiQI
[
i
]
*
Vij
[
i
]
+
qiQJ
[
i
]
*
Vji
[
i
]);
fIZ
+=
qiQI
[
i
]
*
VijR
[
i
];
fIZ
+=
qiQI
[
i
]
*
VijR
[
i
];
fJZ
+=
qiQJ
[
i
]
*
VjiR
[
i
];
fJZ
+=
qiQJ
[
i
]
*
VjiR
[
i
];
...
@@ -6801,14 +6794,14 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculateElectrostatic(const vector
...
@@ -6801,14 +6794,14 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculateElectrostatic(const vector
energy
+=
calculatePmeSelfEnergy
(
particleData
);
energy
+=
calculatePmeSelfEnergy
(
particleData
);
// Now that both the direct and reciprocal space contributions have been added, we can compute the dipole
// Now that both the direct and reciprocal space contributions have been added, we can compute the dipole
// response contributions to the forces, if we're using the
OPT
polarization algorithm.
// response contributions to the forces, if we're using the
extrapolated
polarization algorithm.
if (getPolarizationType() == AmoebaReferenceMultipoleForce::
OPT)
{
if
(
getPolarizationType
()
==
AmoebaReferenceMultipoleForce
::
Extrapolated
)
{
RealOpenMM
prefac
=
(
_electric
/
_dielectric
);
RealOpenMM
prefac
=
(
_electric
/
_dielectric
);
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
// Compute the µ(m) T µ(n) force contributions here
// Compute the µ(m) T µ(n) force contributions here
for(int l = 0; l < _maxPTOrder-1; ++l) {
for
(
int
l
=
0
;
l
<
_maxPTOrder
-
1
;
++
l
)
{
for(int m = 0; m < _maxPTOrder-1-l; ++m) {
for
(
int
m
=
0
;
m
<
_maxPTOrder
-
1
-
l
;
++
m
)
{
RealOpenMM p = _
OPT
PartCoefficients[l+m+1];
RealOpenMM
p
=
_
ext
PartCoefficients
[
l
+
m
+
1
];
if
(
std
::
fabs
(
p
)
<
1e-6
)
continue
;
if
(
std
::
fabs
(
p
)
<
1e-6
)
continue
;
forces
[
i
][
0
]
+=
0.5
*
p
*
prefac
*
(
_ptDipoleD
[
l
][
i
][
0
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
0
]
forces
[
i
][
0
]
+=
0.5
*
p
*
prefac
*
(
_ptDipoleD
[
l
][
i
][
0
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
0
]
+
_ptDipoleD
[
l
][
i
][
1
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
3
]
+
_ptDipoleD
[
l
][
i
][
1
]
*
_ptDipoleFieldGradientP
[
m
][
6
*
i
+
3
]
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h
View file @
cd03350c
...
@@ -351,9 +351,9 @@ public:
...
@@ -351,9 +351,9 @@ public:
Direct
=
1
,
Direct
=
1
,
/**
/**
*
Optimiz
ed perturbation theory
*
Extrapolat
ed perturbation theory
*/
*/
OPT
=
2
Extrapolated
=
2
};
};
/**
/**
...
@@ -428,13 +428,13 @@ public:
...
@@ -428,13 +428,13 @@ public:
RealOpenMM
getMutualInducedDipoleEpsilon
()
const
;
RealOpenMM
getMutualInducedDipoleEpsilon
()
const
;
/**
/**
* Set the coefficients for the µ_0, µ_1, µ_2, µ_n terms in the
pertub
ation
* Set the coefficients for the µ_0, µ_1, µ_2, µ_n terms in the
extrapol
ation
* theory algorithm for induced dipoles
* theory algorithm for induced dipoles
*
*
* @param optCoefficients a vector whose mth entry specifies the coefficient for µ_m
* @param optCoefficients a vector whose mth entry specifies the coefficient for µ_m
*
*
*/
*/
void
set
OPT
Coefficients
(
const
std
::
vector
<
RealOpenMM
>
&
OPTFullC
oefficients
);
void
set
Extrapolation
Coefficients
(
const
std
::
vector
<
RealOpenMM
>
&
c
oefficients
);
/**
/**
* Set the target epsilon for converging mutual induced dipoles.
* Set the target epsilon for converging mutual induced dipoles.
...
@@ -677,8 +677,8 @@ protected:
...
@@ -677,8 +677,8 @@ protected:
int
_mutualInducedDipoleIterations
;
int
_mutualInducedDipoleIterations
;
int
_maximumMutualInducedDipoleIterations
;
int
_maximumMutualInducedDipoleIterations
;
int
_maxPTOrder
;
int
_maxPTOrder
;
std
::
vector
<
RealOpenMM
>
_
OPTFull
Coefficients
;
std
::
vector
<
RealOpenMM
>
_
extrapolation
Coefficients
;
std
::
vector
<
RealOpenMM
>
_
OPT
PartCoefficients
;
std
::
vector
<
RealOpenMM
>
_
ext
PartCoefficients
;
RealOpenMM
_mutualInducedDipoleEpsilon
;
RealOpenMM
_mutualInducedDipoleEpsilon
;
RealOpenMM
_mutualInducedDipoleTargetEpsilon
;
RealOpenMM
_mutualInducedDipoleTargetEpsilon
;
RealOpenMM
_polarSOR
;
RealOpenMM
_polarSOR
;
...
@@ -945,12 +945,12 @@ protected:
...
@@ -945,12 +945,12 @@ protected:
virtual
void
calculateInducedDipoleFields
(
const
std
::
vector
<
MultipoleParticleData
>&
particleData
,
virtual
void
calculateInducedDipoleFields
(
const
std
::
vector
<
MultipoleParticleData
>&
particleData
,
std
::
vector
<
UpdateInducedDipoleFieldStruct
>&
updateInducedDipoleFields
);
std
::
vector
<
UpdateInducedDipoleFieldStruct
>&
updateInducedDipoleFields
);
/**
/**
* Calculated induced dipoles using
Optimiz
ed
P
erturbation
T
heory.
* Calculated induced dipoles using
extrapolat
ed
p
erturbation
t
heory.
*
*
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
* @param updateInducedDipoleFields vector of UpdateInducedDipoleFieldStruct containing input induced dipoles and output fields
* @param updateInducedDipoleFields vector of UpdateInducedDipoleFieldStruct containing input induced dipoles and output fields
*/
*/
void
convergeInduceDipolesBy
OPT
(
const
std
::
vector
<
MultipoleParticleData
>&
particleData
,
void
convergeInduceDipolesBy
Extrapolation
(
const
std
::
vector
<
MultipoleParticleData
>&
particleData
,
std
::
vector
<
UpdateInducedDipoleFieldStruct
>&
calculateInducedDipoleField
);
std
::
vector
<
UpdateInducedDipoleFieldStruct
>&
calculateInducedDipoleField
);
/**
/**
* Converge induced dipoles.
* Converge induced dipoles.
...
...
plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPTPolarization.cpp
View file @
cd03350c
...
@@ -319,13 +319,13 @@ static void testWaterDimerExPTPolarizationTriclinicPME() {
...
@@ -319,13 +319,13 @@ static void testWaterDimerExPTPolarizationTriclinicPME() {
Vec3
(
0.2
,
2.0
,
0.0
),
Vec3
(
0.2
,
2.0
,
0.0
),
Vec3
(
0.1
,
0.5
,
2.0
));
Vec3
(
0.1
,
0.5
,
2.0
));
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
PME
);
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
PME
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
OPT
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
Extrapolated
);
std
::
vector
<
double
>
coefs
;
std
::
vector
<
double
>
coefs
;
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
amoebaMultipoleForce
->
set
OPT
Coefficients
(
coefs
);
amoebaMultipoleForce
->
set
Extrapolation
Coefficients
(
coefs
);
amoebaMultipoleForce
->
setCutoffDistance
(
9.0
*
OpenMM
::
NmPerAngstrom
);
amoebaMultipoleForce
->
setCutoffDistance
(
9.0
*
OpenMM
::
NmPerAngstrom
);
amoebaMultipoleForce
->
setAEwald
(
4
);
amoebaMultipoleForce
->
setAEwald
(
4
);
amoebaMultipoleForce
->
setEwaldErrorTolerance
(
1.0e-06
);
amoebaMultipoleForce
->
setEwaldErrorTolerance
(
1.0e-06
);
...
@@ -368,13 +368,13 @@ static void testWaterDimerExPTPolarizationTriclinicPMENoPolGroups() {
...
@@ -368,13 +368,13 @@ static void testWaterDimerExPTPolarizationTriclinicPMENoPolGroups() {
Vec3
(
0.2
,
2.0
,
0.0
),
Vec3
(
0.2
,
2.0
,
0.0
),
Vec3
(
0.1
,
0.5
,
2.0
));
Vec3
(
0.1
,
0.5
,
2.0
));
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
PME
);
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
PME
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
OPT
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
Extrapolated
);
std
::
vector
<
double
>
coefs
;
std
::
vector
<
double
>
coefs
;
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
amoebaMultipoleForce
->
set
OPT
Coefficients
(
coefs
);
amoebaMultipoleForce
->
set
Extrapolation
Coefficients
(
coefs
);
amoebaMultipoleForce
->
setCutoffDistance
(
9.0
*
OpenMM
::
NmPerAngstrom
);
amoebaMultipoleForce
->
setCutoffDistance
(
9.0
*
OpenMM
::
NmPerAngstrom
);
amoebaMultipoleForce
->
setAEwald
(
4
);
amoebaMultipoleForce
->
setAEwald
(
4
);
amoebaMultipoleForce
->
setEwaldErrorTolerance
(
1.0e-06
);
amoebaMultipoleForce
->
setEwaldErrorTolerance
(
1.0e-06
);
...
@@ -415,13 +415,13 @@ static void testWaterDimerExPTPolarizationNoCutoff() {
...
@@ -415,13 +415,13 @@ static void testWaterDimerExPTPolarizationNoCutoff() {
vector
<
Vec3
>
coords
=
setupWaterDimer
(
system
,
amoebaMultipoleForce
,
true
);
vector
<
Vec3
>
coords
=
setupWaterDimer
(
system
,
amoebaMultipoleForce
,
true
);
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
NoCutoff
);
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
NoCutoff
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
OPT
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
Extrapolated
);
std
::
vector
<
double
>
coefs
;
std
::
vector
<
double
>
coefs
;
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
amoebaMultipoleForce
->
set
OPT
Coefficients
(
coefs
);
amoebaMultipoleForce
->
set
Extrapolation
Coefficients
(
coefs
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"Reference"
));
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"Reference"
));
...
@@ -456,13 +456,13 @@ static void testWaterDimerExPTPolarizationNoCutoffNoPolGroups() {
...
@@ -456,13 +456,13 @@ static void testWaterDimerExPTPolarizationNoCutoffNoPolGroups() {
vector
<
Vec3
>
coords
=
setupWaterDimer
(
system
,
amoebaMultipoleForce
,
false
);
vector
<
Vec3
>
coords
=
setupWaterDimer
(
system
,
amoebaMultipoleForce
,
false
);
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
NoCutoff
);
amoebaMultipoleForce
->
setNonbondedMethod
(
AmoebaMultipoleForce
::
NoCutoff
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
OPT
);
amoebaMultipoleForce
->
setPolarizationType
(
AmoebaMultipoleForce
::
Extrapolated
);
std
::
vector
<
double
>
coefs
;
std
::
vector
<
double
>
coefs
;
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
0.0
);
// The mu_0 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
-
0.3
);
// The mu_1 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
0.0
);
// The mu_2 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
coefs
.
push_back
(
1.3
);
// The mu_3 coefficient
amoebaMultipoleForce
->
set
OPT
Coefficients
(
coefs
);
amoebaMultipoleForce
->
set
Extrapolation
Coefficients
(
coefs
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
LangevinIntegrator
integrator
(
0.0
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"Reference"
));
Context
context
(
system
,
integrator
,
Platform
::
getPlatformByName
(
"Reference"
));
...
@@ -492,7 +492,6 @@ static void testWaterDimerExPTPolarizationNoCutoffNoPolGroups() {
...
@@ -492,7 +492,6 @@ static void testWaterDimerExPTPolarizationNoCutoffNoPolGroups() {
int
main
(
int
numberOfArguments
,
char
*
argv
[])
{
int
main
(
int
numberOfArguments
,
char
*
argv
[])
{
try
{
try
{
std
::
cout
<<
"TestReferenceAmoebaPTPolarization running test..."
<<
std
::
endl
;
registerAmoebaReferenceKernelFactories
();
registerAmoebaReferenceKernelFactories
();
/*
/*
...
...
plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp
View file @
cd03350c
...
@@ -68,7 +68,7 @@ void loadCovalentMap(const SerializationNode& map, std::vector< int >& covalentM
...
@@ -68,7 +68,7 @@ void loadCovalentMap(const SerializationNode& map, std::vector< int >& covalentM
}
}
void
AmoebaMultipoleForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
void
AmoebaMultipoleForceProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
2
);
node
.
setIntProperty
(
"version"
,
3
);
const
AmoebaMultipoleForce
&
force
=
*
reinterpret_cast
<
const
AmoebaMultipoleForce
*>
(
object
);
const
AmoebaMultipoleForce
&
force
=
*
reinterpret_cast
<
const
AmoebaMultipoleForce
*>
(
object
);
node
.
setIntProperty
(
"nonbondedMethod"
,
force
.
getNonbondedMethod
());
node
.
setIntProperty
(
"nonbondedMethod"
,
force
.
getNonbondedMethod
());
...
@@ -88,6 +88,14 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode&
...
@@ -88,6 +88,14 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode&
SerializationNode
&
gridDimensionsNode
=
node
.
createChildNode
(
"MultipoleParticleGridDimension"
);
SerializationNode
&
gridDimensionsNode
=
node
.
createChildNode
(
"MultipoleParticleGridDimension"
);
gridDimensionsNode
.
setIntProperty
(
"d0"
,
gridDimensions
[
0
]).
setIntProperty
(
"d1"
,
gridDimensions
[
1
]).
setIntProperty
(
"d2"
,
gridDimensions
[
2
]);
gridDimensionsNode
.
setIntProperty
(
"d0"
,
gridDimensions
[
0
]).
setIntProperty
(
"d1"
,
gridDimensions
[
1
]).
setIntProperty
(
"d2"
,
gridDimensions
[
2
]);
SerializationNode
&
coefficients
=
node
.
createChildNode
(
"ExtrapolationCoefficients"
);
vector
<
double
>
coeff
=
force
.
getExtrapolationCoefficients
();
for
(
int
i
=
0
;
i
<
coeff
.
size
();
i
++
)
{
stringstream
key
;
key
<<
"c"
<<
i
;
coefficients
.
setDoubleProperty
(
key
.
str
(),
coeff
[
i
]);
}
std
::
vector
<
std
::
string
>
covalentTypes
;
std
::
vector
<
std
::
string
>
covalentTypes
;
getCovalentTypes
(
covalentTypes
);
getCovalentTypes
(
covalentTypes
);
...
@@ -124,16 +132,16 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode&
...
@@ -124,16 +132,16 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode&
}
}
void
*
AmoebaMultipoleForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
void
*
AmoebaMultipoleForceProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
if
(
node
.
getIntProperty
(
"version"
)
>
2
)
int
version
=
node
.
getIntProperty
(
"version"
);
if
(
version
<
0
||
version
>
3
)
throw
OpenMMException
(
"Unsupported version number"
);
throw
OpenMMException
(
"Unsupported version number"
);
AmoebaMultipoleForce
*
force
=
new
AmoebaMultipoleForce
();
AmoebaMultipoleForce
*
force
=
new
AmoebaMultipoleForce
();
try
{
try
{
force
->
setNonbondedMethod
(
static_cast
<
AmoebaMultipoleForce
::
NonbondedMethod
>
(
node
.
getIntProperty
(
"nonbondedMethod"
)));
force
->
setNonbondedMethod
(
static_cast
<
AmoebaMultipoleForce
::
NonbondedMethod
>
(
node
.
getIntProperty
(
"nonbondedMethod"
)));
if
(
node
.
getIntProperty
(
"
version
"
)
=
=
2
)
{
if
(
version
>
=
2
)
force
->
setPolarizationType
(
static_cast
<
AmoebaMultipoleForce
::
PolarizationType
>
(
node
.
getIntProperty
(
"polarizationType"
)));
force
->
setPolarizationType
(
static_cast
<
AmoebaMultipoleForce
::
PolarizationType
>
(
node
.
getIntProperty
(
"polarizationType"
)));
}
//force->setPmeBSplineOrder(node.getIntProperty("pmeBSplineOrder"));
//force->setPmeBSplineOrder(node.getIntProperty("pmeBSplineOrder"));
//force->setMutualInducedIterationMethod(static_cast<AmoebaMultipoleForce::MutualInducedIterationMethod>(node.getIntProperty("mutualInducedIterationMethod")));
//force->setMutualInducedIterationMethod(static_cast<AmoebaMultipoleForce::MutualInducedIterationMethod>(node.getIntProperty("mutualInducedIterationMethod")));
force
->
setMutualInducedMaxIterations
(
node
.
getIntProperty
(
"mutualInducedMaxIterations"
));
force
->
setMutualInducedMaxIterations
(
node
.
getIntProperty
(
"mutualInducedMaxIterations"
));
...
@@ -151,6 +159,18 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons
...
@@ -151,6 +159,18 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons
gridDimensions
.
push_back
(
gridDimensionsNode
.
getIntProperty
(
"d2"
));
gridDimensions
.
push_back
(
gridDimensionsNode
.
getIntProperty
(
"d2"
));
force
->
setPmeGridDimensions
(
gridDimensions
);
force
->
setPmeGridDimensions
(
gridDimensions
);
if
(
version
>=
3
)
{
const
SerializationNode
&
coefficients
=
node
.
getChildNode
(
"ExtrapolationCoefficients"
);
vector
<
double
>
coeff
;
for
(
int
i
=
0
;
;
i
++
)
{
stringstream
key
;
key
<<
"c"
<<
i
;
if
(
coefficients
.
getProperties
().
find
(
key
.
str
())
==
coefficients
.
getProperties
().
end
())
break
;
coeff
.
push_back
(
coefficients
.
getDoubleProperty
(
key
.
str
()));
}
force
->
setExtrapolationCoefficients
(
coeff
);
}
std
::
vector
<
std
::
string
>
covalentTypes
;
std
::
vector
<
std
::
string
>
covalentTypes
;
getCovalentTypes
(
covalentTypes
);
getCovalentTypes
(
covalentTypes
);
...
...
plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp
View file @
cd03350c
...
@@ -75,6 +75,12 @@ void testSerialization() {
...
@@ -75,6 +75,12 @@ void testSerialization() {
//force1.setElectricConstant(138.93);
//force1.setElectricConstant(138.93);
force1
.
setEwaldErrorTolerance
(
1.0e-05
);
force1
.
setEwaldErrorTolerance
(
1.0e-05
);
vector
<
double
>
coeff
;
coeff
.
push_back
(
0.0
);
coeff
.
push_back
(
-
0.1
);
coeff
.
push_back
(
1.1
);
force1
.
setExtrapolationCoefficients
(
coeff
);
std
::
vector
<
std
::
string
>
covalentTypes
;
std
::
vector
<
std
::
string
>
covalentTypes
;
getCovalentTypes
(
covalentTypes
);
getCovalentTypes
(
covalentTypes
);
...
@@ -125,6 +131,8 @@ void testSerialization() {
...
@@ -125,6 +131,8 @@ void testSerialization() {
ASSERT_EQUAL
(
gridDimension1
[
jj
],
gridDimension2
[
jj
]);
ASSERT_EQUAL
(
gridDimension1
[
jj
],
gridDimension2
[
jj
]);
}
}
ASSERT_EQUAL_CONTAINERS
(
force1
.
getExtrapolationCoefficients
(),
force2
.
getExtrapolationCoefficients
());
ASSERT_EQUAL
(
force1
.
getNumMultipoles
(),
force2
.
getNumMultipoles
());
ASSERT_EQUAL
(
force1
.
getNumMultipoles
(),
force2
.
getNumMultipoles
());
for
(
unsigned
int
ii
=
0
;
ii
<
static_cast
<
unsigned
int
>
(
force1
.
getNumMultipoles
());
ii
++
)
{
for
(
unsigned
int
ii
=
0
;
ii
<
static_cast
<
unsigned
int
>
(
force1
.
getNumMultipoles
());
ii
++
)
{
...
...
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