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
5e3a0a05
Commit
5e3a0a05
authored
Jan 22, 2015
by
Peter Eastman
Browse files
Began implementing triclinic boxes for reference AmoebaMultipoleForce (not yet debugged)
parent
3b2579a5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
317 additions
and
176 deletions
+317
-176
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
...amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
+10
-10
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
...ence/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
+280
-152
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h
...erence/src/SimTKReference/AmoebaReferenceMultipoleForce.h
+27
-14
No files found.
plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp
View file @
5e3a0a05
...
...
@@ -640,17 +640,17 @@ AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmo
}
else
if
(
usePme
)
{
AmoebaReferencePmeMultipoleForce
*
amoebaReferencePmeMultipoleForce
=
new
AmoebaReferencePmeMultipoleForce
(
);
amoebaReferencePmeMultipoleForce
->
setAlphaEwald
(
alphaEwald
);
amoebaReferencePmeMultipoleForce
->
setCutoffDistance
(
cutoffDistance
);
amoebaReferencePmeMultipoleForce
->
setPmeGridDimensions
(
pmeGridDimension
);
RealVec
&
box
=
extractBox
Size
(
context
);
double
minAllowedSize
=
1.999999
*
cutoffDistance
;
if
(
box
[
0
]
<
minAllowedSize
||
box
[
1
]
<
minAllowedSize
||
box
[
2
]
<
minAllowedSize
){
AmoebaReferencePmeMultipoleForce
*
amoebaReferencePmeMultipoleForce
=
new
AmoebaReferencePmeMultipoleForce
(
);
amoebaReferencePmeMultipoleForce
->
setAlphaEwald
(
alphaEwald
);
amoebaReferencePmeMultipoleForce
->
setCutoffDistance
(
cutoffDistance
);
amoebaReferencePmeMultipoleForce
->
setPmeGridDimensions
(
pmeGridDimension
);
RealVec
*
box
Vectors
=
extractBox
Vectors
(
context
);
double
minAllowedSize
=
1.999999
*
cutoffDistance
;
if
(
box
Vectors
[
0
]
[
0
]
<
minAllowedSize
||
box
Vectors
[
1
]
[
1
]
<
minAllowedSize
||
box
Vectors
[
2
]
[
2
]
<
minAllowedSize
){
throw
OpenMMException
(
"The periodic box size has decreased to less than twice the nonbonded cutoff."
);
}
amoebaReferencePmeMultipoleForce
->
setPeriodicBoxSize
(
box
);
amoebaReferenceMultipoleForce
=
static_cast
<
AmoebaReferenceMultipoleForce
*>
(
amoebaReferencePmeMultipoleForce
);
}
amoebaReferencePmeMultipoleForce
->
setPeriodicBoxSize
(
box
Vectors
);
amoebaReferenceMultipoleForce
=
static_cast
<
AmoebaReferenceMultipoleForce
*>
(
amoebaReferencePmeMultipoleForce
);
}
else
{
amoebaReferenceMultipoleForce
=
new
AmoebaReferenceMultipoleForce
(
AmoebaReferenceMultipoleForce
::
NoCutoff
);
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
View file @
5e3a0a05
...
...
@@ -4608,22 +4608,24 @@ void AmoebaReferencePmeMultipoleForce::setPmeGridDimensions(vector<int>& pmeGrid
initializeBSplineModuli();
};
void
AmoebaReferencePmeMultipoleForce
::
setPeriodicBoxSize
(
RealVec
&
boxSize
)
void AmoebaReferencePmeMultipoleForce::setPeriodicBoxSize(
OpenMM::RealVec* vectors
)
{
if
(
boxSize
[
0
]
==
0.0
||
boxSize
[
1
]
==
0.0
||
boxSize
[
2
]
==
0.0
)
{
if (
vectors[0]
[0] == 0.0 ||
vectors[1]
[1] == 0.0 ||
vectors[2]
[2] == 0.0) {
std::stringstream message;
message << "Box size of zero is invalid.";
throw OpenMMException(message.str());
}
_periodicBoxSize
=
boxSize
;
_invPeriodicBoxSize
[
0
]
=
1.0
/
boxSize
[
0
];
_invPeriodicBoxSize
[
1
]
=
1.0
/
boxSize
[
1
];
_invPeriodicBoxSize
[
2
]
=
1.0
/
boxSize
[
2
];
return
;
_periodicBoxVectors[0] = vectors[0];
_periodicBoxVectors[1] = vectors[1];
_periodicBoxVectors[2] = vectors[2];
RealOpenMM determinant = vectors[0][0]*vectors[1][1]*vectors[2][2];
assert(determinant > 0);
RealOpenMM scale = 1.0/determinant;
_recipBoxVectors[0] = RealVec(vectors[1][1]*vectors[2][2], 0, 0)*scale;
_recipBoxVectors[1] = RealVec(-vectors[1][0]*vectors[2][2], vectors[0][0]*vectors[2][2], 0)*scale;
_recipBoxVectors[2] = RealVec(vectors[1][0]*vectors[2][1]-vectors[1][1]*vectors[2][0], -vectors[0][0]*vectors[2][1], vectors[0][0]*vectors[1][1])*scale;
};
int compareInt2(const int2& v1, const int2& v2)
...
...
@@ -4672,16 +4674,9 @@ void AmoebaReferencePmeMultipoleForce::initializePmeGrid()
void AmoebaReferencePmeMultipoleForce::getPeriodicDelta(RealVec& deltaR) const
{
deltaR
[
0
]
-=
FLOOR
(
deltaR
[
0
]
*
_invPeriodicBoxSize
[
0
]
+
0.5
)
*
_periodicBoxSize
[
0
];
deltaR
[
1
]
-=
FLOOR
(
deltaR
[
1
]
*
_invPeriodicBoxSize
[
1
]
+
0.5
)
*
_periodicBoxSize
[
1
];
deltaR
[
2
]
-=
FLOOR
(
deltaR
[
2
]
*
_invPeriodicBoxSize
[
2
]
+
0.5
)
*
_periodicBoxSize
[
2
];
}
void
AmoebaReferencePmeMultipoleForce
::
getPmeScale
(
RealVec
&
scale
)
const
{
scale
[
0
]
=
static_cast
<
RealOpenMM
>
(
_pmeGridDimensions
[
0
])
*
_invPeriodicBoxSize
[
0
];
scale
[
1
]
=
static_cast
<
RealOpenMM
>
(
_pmeGridDimensions
[
1
])
*
_invPeriodicBoxSize
[
1
];
scale
[
2
]
=
static_cast
<
RealOpenMM
>
(
_pmeGridDimensions
[
2
])
*
_invPeriodicBoxSize
[
2
];
deltaR -= _periodicBoxVectors[2]*FLOOR(deltaR[2]*_recipBoxVectors[2][2]+0.5);
deltaR -= _periodicBoxVectors[1]*FLOOR(deltaR[1]*_recipBoxVectors[1][1]+0.5);
deltaR -= _periodicBoxVectors[0]*FLOOR(deltaR[0]*_recipBoxVectors[0][0]+0.5);
}
void AmoebaReferencePmeMultipoleForce::getDampedInverseDistances(const MultipoleParticleData& particleI,
...
...
@@ -5039,7 +5034,7 @@ void AmoebaReferencePmeMultipoleForce::computeAmoebaBsplines(const vector<Multip
IntVec igrid;
for (unsigned int jj = 0; jj < 3; jj++) {
RealOpenMM
w
=
position
[
jj
]
*
_invPeriodicBoxSize
[
jj
];
RealOpenMM w = position[
0]*_recipBoxVectors[0][jj]+position[1]*_recipBoxVectors[1][jj]+position[2]*_recipBoxVectors[2]
[jj];
RealOpenMM fr = _pmeGridDimensions[jj]*(w-(int)(w+0.5)+0.5);
int ifr = static_cast<int>(fr);
w = fr - ifr;
...
...
@@ -5095,8 +5090,8 @@ void AmoebaReferencePmeMultipoleForce::findAmoebaAtomRangeForGrid(const vector<M
for (unsigned int ii = 0; ii < _numParticles; ii++) {
RealOpenMM posz = particleData[_pmeAtomGridIndex[ii][0]].position[2];
posz
-=
FLOOR
(
posz
*
_
invPeriodicBoxSize
[
2
])
*
_periodicBox
Size
[
2
];
RealOpenMM
w
=
posz
*
_
invPeriodicBoxSize
[
2
];
posz -= FLOOR(posz*_
recipBoxVectors[2]
[2])*_periodicBox
Vectors[2]
[2];
RealOpenMM w = posz*_
recipBoxVectors[2]
[2];
RealOpenMM fr = _pmeGridDimensions[2]*(w-(int)(w+0.5)+0.5);
int z = (static_cast<int>(fr)) - AMOEBA_PME_ORDER + 1;
_pmeAtomGridIndex[ii][1] = z;
...
...
@@ -5116,8 +5111,7 @@ void AmoebaReferencePmeMultipoleForce::getGridPointGivenGridIndex(int gridIndex,
return;
}
RealOpenMM
AmoebaReferencePmeMultipoleForce
::
computeFixedMultipolesGridValue
(
const
vector
<
MultipoleParticleData
>&
particleData
,
const
int2
&
particleGridIndices
,
const
RealVec
&
scale
,
RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(const int2& particleGridIndices,
int ix, int iy, const IntVec& gridPoint) const
{
...
...
@@ -5131,17 +5125,17 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(con
iz -= _pmeGridDimensions[2];
}
RealOpenMM
atomCharge
=
particleData
[
atomIndex
].
charge
;
RealVec
atomDipole
=
RealVec
(
scale
[
0
]
*
particleData
[
atomIndex
].
dipole
[
0
],
scale
[
1
]
*
particleData
[
atomIndex
].
dipole
[
1
],
scale
[
2
]
*
particleData
[
atomIndex
].
dipole
[
2
]);
RealOpenMM atomCharge =
_transformed
[atomIndex].charge;
RealVec atomDipole = RealVec(
_transformed
[atomIndex].dipole[0],
_transformed
[atomIndex].dipole[1],
_transformed
[atomIndex].dipole[2]);
RealOpenMM
atomQuadrupoleXX
=
scale
[
0
]
*
scale
[
0
]
*
particleData
[
atomIndex
].
quadrupole
[
QXX
];
RealOpenMM
atomQuadrupoleXY
=
2.0
*
scale
[
0
]
*
scale
[
1
]
*
particleData
[
atomIndex
].
quadrupole
[
QXY
];
RealOpenMM
atomQuadrupoleXZ
=
2.0
*
scale
[
0
]
*
scale
[
2
]
*
particleData
[
atomIndex
].
quadrupole
[
QXZ
];
RealOpenMM
atomQuadrupoleYY
=
scale
[
1
]
*
scale
[
1
]
*
particleData
[
atomIndex
].
quadrupole
[
QYY
];
RealOpenMM
atomQuadrupoleYZ
=
2.0
*
scale
[
1
]
*
scale
[
2
]
*
particleData
[
atomIndex
].
quadrupole
[
QYZ
];
RealOpenMM
atomQuadrupoleZZ
=
scale
[
2
]
*
scale
[
2
]
*
particleData
[
atomIndex
].
quadrupole
[
QZZ
];
RealOpenMM atomQuadrupoleXX =
_transformed
[atomIndex].quadrupole[QXX];
RealOpenMM atomQuadrupoleXY =
_transformed
[atomIndex].quadrupole[QXY];
RealOpenMM atomQuadrupoleXZ =
_transformed
[atomIndex].quadrupole[QXZ];
RealOpenMM atomQuadrupoleYY =
_transformed
[atomIndex].quadrupole[QYY];
RealOpenMM atomQuadrupoleYZ =
_transformed
[atomIndex].quadrupole[QYZ];
RealOpenMM atomQuadrupoleZZ =
_transformed
[atomIndex].quadrupole[QZZ];
RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix];
RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy];
...
...
@@ -5154,11 +5148,86 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(con
return gridValue;
}
void AmoebaReferencePmeMultipoleForce::transformMultipolesToFractionalCoordinates(const vector<MultipoleParticleData>& particleData) {
// Build matrices for transforming the dipoles and quadrupoles.
RealVec a[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a[j][i] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
int index1[] = {0, 0, 0, 1, 1, 2};
int index2[] = {0, 1, 2, 1, 2, 2};
RealOpenMM b[6][6];
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]];
if (index1[i] != index2[i])
b[i][j] += a[index1[i]][index2[j]]*a[index2[i]][index1[j]];
}
}
// Transform the multipoles.
_transformed.resize(particleData.size());
double quadScale[] = {1, 2, 2, 1, 2, 1};
for (int i = 0; i < (int) particleData.size(); i++) {
_transformed[i].charge = particleData[i].charge;
_transformed[i].dipole = Vec3();
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
_transformed[i].dipole[j] += a[j][k]*particleData[i].dipole[k];
for (int j = 0; j < 6; j++) {
_transformed[i].quadrupole[j] = 0;
for (int k = 0; k < 6; k++)
_transformed[i].quadrupole[j] += quadScale[k]*b[j][k]*particleData[i].quadrupole[k];
}
}
}
void AmoebaReferencePmeMultipoleForce::transformPotentialToCartesianCoordinates(const vector<RealOpenMM>& fphi, vector<RealOpenMM>& cphi) const {
// Build a matrix for transforming the potential.
RealVec a[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
int index1[] = {0, 1, 2, 0, 0, 1};
int index2[] = {0, 1, 2, 1, 2, 2};
RealOpenMM b[6][6];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 6; j++) {
b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]];
if (index1[i] != index2[i])
b[i][j] *= 2;
}
}
for (int i = 3; i < 6; i++) {
for (int j = 0; j < 6; j++) {
b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]];
if (index1[i] != index2[i])
b[i][j] += a[index1[i]][index2[j]]*a[index2[i]][index1[j]];
}
}
// Transform the potential.
for (int i = 0; i < _numParticles; i++) {
cphi[10*i] = fphi[20*i];
cphi[10*i+1] = a[0][0]*fphi[20*i+1] + a[0][1]*fphi[20*i+2] + a[0][2]*fphi[20*i+3];
cphi[10*i+2] = a[1][0]*fphi[20*i+1] + a[1][1]*fphi[20*i+2] + a[1][2]*fphi[20*i+3];
cphi[10*i+3] = a[2][0]*fphi[20*i+1] + a[2][1]*fphi[20*i+2] + a[2][2]*fphi[20*i+3];
for (int j = 0; j < 6; j++) {
cphi[10*i+4+j] = 0;
for (int k = 0; k < 6; k++)
cphi[10*i+4+j] += b[j][k]*fphi[20*i+4+k];
}
}
}
void AmoebaReferencePmeMultipoleForce::spreadFixedMultipolesOntoGrid(const vector<MultipoleParticleData>& particleData)
{
RealVec
scale
;
getPmeScale
(
scale
);
transformMultipolesToFractionalCoordinates(particleData);
for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) {
...
...
@@ -5179,13 +5248,13 @@ void AmoebaReferencePmeMultipoleForce::spreadFixedMultipolesOntoGrid(const vecto
int2 particleGridIndices;
particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z1;
particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z2;
result
+=
computeFixedMultipolesGridValue
(
particleData
,
particleGridIndices
,
scale
,
ix
,
iy
,
gridPoint
);
result += computeFixedMultipolesGridValue(particleGridIndices, ix, iy, gridPoint);
if (z1 > gridPoint[2]) {
particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2];
particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2];
result
+=
computeFixedMultipolesGridValue
(
particleData
,
particleGridIndices
,
scale
,
ix
,
iy
,
gridPoint
);
result += computeFixedMultipolesGridValue(particleGridIndices, ix, iy, gridPoint);
}
}
}
...
...
@@ -5198,7 +5267,7 @@ void AmoebaReferencePmeMultipoleForce::performAmoebaReciprocalConvolution()
{
RealOpenMM expFactor = (M_PI*M_PI)/(_alphaEwald*_alphaEwald);
RealOpenMM
scaleFactor
=
1.0
/
(
M_PI
*
_periodicBox
Size
[
0
]
*
_periodicBox
Size
[
1
]
*
_periodicBox
Size
[
2
]);
RealOpenMM scaleFactor = 1.0/(M_PI*_periodicBox
Vectors[0]
[0]*_periodicBox
Vectors[1]
[1]*_periodicBox
Vectors[2]
[2]);
for (int index = 0; index < _totalGridSize; index++)
{
...
...
@@ -5216,9 +5285,9 @@ void AmoebaReferencePmeMultipoleForce::performAmoebaReciprocalConvolution()
int my = (ky < (_pmeGridDimensions[1]+1)/2) ? ky : (ky-_pmeGridDimensions[1]);
int mz = (kz < (_pmeGridDimensions[2]+1)/2) ? kz : (kz-_pmeGridDimensions[2]);
RealOpenMM
mhx
=
mx
*
_
invPeriodicBoxSize
[
0
];
RealOpenMM
mhy
=
m
y
*
_
invPeriodicBoxSize
[
1
];
RealOpenMM
mhz
=
m
z
*
_
invPeriodicBoxSize
[
2
];
RealOpenMM mhx = mx*_
recipBoxVectors[0]
[0];
RealOpenMM mhy = m
x
*_
recipBoxVectors[1][0]+my*_recipBoxVectors[1]
[1];
RealOpenMM mhz = m
x
*_
recipBoxVectors[2][0]+my*_recipBoxVectors[2][1]+mz*_recipBoxVectors[2]
[2];
RealOpenMM bx = _pmeBsplineModuli[0][kx];
RealOpenMM by = _pmeBsplineModuli[1][ky];
...
...
@@ -5341,7 +5410,7 @@ void AmoebaReferencePmeMultipoleForce::computeFixedPotentialFromGrid()
}
}
t_complex
AmoebaReferencePmeMultipoleForce
::
computeInducedDipoleGridValue
(
const
int2
&
particleGridIndices
,
const
RealVec
&
scale
,
int
ix
,
int
iy
,
t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const int2& particleGridIndices, const RealVec
* fracToCart
, int ix, int iy,
const IntVec& gridPoint,
const vector<RealVec>& inputInducedDipole,
const vector<RealVec>& inputInducedDipolePolar) const
...
...
@@ -5361,13 +5430,16 @@ t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const
if (iz >= _pmeGridDimensions[2]) {
iz -= _pmeGridDimensions[2];
}
RealVec
inducedDipole
=
RealVec
(
scale
[
0
]
*
inputInducedDipole
[
atomIndex
][
0
],
scale
[
1
]
*
inputInducedDipole
[
atomIndex
][
1
],
scale
[
2
]
*
inputInducedDipole
[
atomIndex
][
2
]);
RealVec inducedDipole = RealVec(inputInducedDipole[atomIndex][0]*fracToCart[0][0] + inputInducedDipole[atomIndex][1]*fracToCart[0][1] + inputInducedDipole[atomIndex][2]*fracToCart[0][2],
inputInducedDipole[atomIndex][0]*fracToCart[1][0] + inputInducedDipole[atomIndex][1]*fracToCart[1][1] + inputInducedDipole[atomIndex][2]*fracToCart[1][2],
inputInducedDipole[atomIndex][0]*fracToCart[2][0] + inputInducedDipole[atomIndex][1]*fracToCart[2][1] + inputInducedDipole[atomIndex][2]*fracToCart[2][2]);
RealVec inducedDipolePolar = RealVec(inputInducedDipolePolar[atomIndex][0]*fracToCart[0][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[0][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[0][2],
inputInducedDipolePolar[atomIndex][0]*fracToCart[1][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[1][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[1][2],
inputInducedDipolePolar[atomIndex][0]*fracToCart[2][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[2][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[2][2]);
RealVec
inducedDipolePolar
=
RealVec
(
scale
[
0
]
*
inputInducedDipolePolar
[
atomIndex
][
0
],
scale
[
1
]
*
inputInducedDipolePolar
[
atomIndex
][
1
],
scale
[
2
]
*
inputInducedDipolePolar
[
atomIndex
][
2
]);
//
RealVec inducedDipolePolar = RealVec(scale[0]*inputInducedDipolePolar[atomIndex][0],
//
scale[1]*inputInducedDipolePolar[atomIndex][1],
//
scale[2]*inputInducedDipolePolar[atomIndex][2]);
RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix];
RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy];
...
...
@@ -5388,8 +5460,10 @@ t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const
void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector<RealVec>& inputInducedDipole,
const vector<RealVec>& inputInducedDipolePolar)
{
RealVec
scale
;
getPmeScale
(
scale
);
RealVec fracToCart[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++)
{
...
...
@@ -5412,13 +5486,13 @@ void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector<R
int2 particleGridIndices;
particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z1;
particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z2;
gridValue
+=
computeInducedDipoleGridValue
(
particleGridIndices
,
scale
,
ix
,
iy
,
gridPoint
,
inputInducedDipole
,
inputInducedDipolePolar
);
gridValue += computeInducedDipoleGridValue(particleGridIndices,
fracToCart
, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar);
if (z1 > gridPoint[2])
{
particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2];
particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2];
gridValue
+=
computeInducedDipoleGridValue
(
particleGridIndices
,
scale
,
ix
,
iy
,
gridPoint
,
inputInducedDipole
,
inputInducedDipolePolar
);
gridValue += computeInducedDipoleGridValue(particleGridIndices,
fracToCart
, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar);
}
}
}
...
...
@@ -5638,8 +5712,14 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol
const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19};
const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16};
const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18};
RealVec
scale
;
getPmeScale
(
scale
);
vector<RealOpenMM> cphi(10*_numParticles);
transformPotentialToCartesianCoordinates(_phi, cphi);
// RealVec scale;
// getPmeScale(scale);
RealVec fracToCart[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
RealOpenMM energy = 0.0;
for (int i = 0; i < _numParticles; i++) {
...
...
@@ -5659,46 +5739,73 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol
multipole[8] = particleData[i].quadrupole[QXZ]*2.0;
multipole[9] = particleData[i].quadrupole[QYZ]*2.0;
const
RealOpenMM
*
phi
=
&
_phi
[
20
*
i
];
torques
[
i
][
0
]
+=
_electric
*
(
multipole
[
3
]
*
scale
[
1
]
*
phi
[
2
]
-
multipole
[
2
]
*
scale
[
2
]
*
phi
[
3
]
+
2.0
*
(
multipole
[
6
]
-
multipole
[
5
])
*
scale
[
1
]
*
scale
[
2
]
*
phi
[
9
]
+
multipole
[
8
]
*
scale
[
0
]
*
scale
[
1
]
*
phi
[
7
]
+
multipole
[
9
]
*
scale
[
1
]
*
scale
[
1
]
*
phi
[
5
]
-
multipole
[
7
]
*
scale
[
0
]
*
scale
[
2
]
*
phi
[
8
]
-
multipole
[
9
]
*
scale
[
2
]
*
scale
[
2
]
*
phi
[
6
]);
torques
[
i
][
1
]
+=
_electric
*
(
multipole
[
1
]
*
scale
[
2
]
*
phi
[
3
]
-
multipole
[
3
]
*
scale
[
0
]
*
phi
[
1
]
+
2.0
*
(
multipole
[
4
]
-
multipole
[
6
])
*
scale
[
0
]
*
scale
[
2
]
*
phi
[
8
]
+
multipole
[
7
]
*
scale
[
1
]
*
scale
[
2
]
*
phi
[
9
]
+
multipole
[
8
]
*
scale
[
2
]
*
scale
[
2
]
*
phi
[
6
]
-
multipole
[
8
]
*
scale
[
0
]
*
scale
[
0
]
*
phi
[
4
]
-
multipole
[
9
]
*
scale
[
0
]
*
scale
[
1
]
*
phi
[
7
]);
torques
[
i
][
2
]
+=
_electric
*
(
multipole
[
2
]
*
scale
[
0
]
*
phi
[
1
]
-
multipole
[
1
]
*
scale
[
1
]
*
phi
[
2
]
+
2.0
*
(
multipole
[
5
]
-
multipole
[
4
])
*
scale
[
0
]
*
scale
[
1
]
*
phi
[
7
]
+
multipole
[
7
]
*
scale
[
0
]
*
scale
[
0
]
*
phi
[
4
]
+
multipole
[
9
]
*
scale
[
0
]
*
scale
[
2
]
*
phi
[
8
]
-
multipole
[
7
]
*
scale
[
1
]
*
scale
[
1
]
*
phi
[
5
]
-
multipole
[
8
]
*
scale
[
1
]
*
scale
[
2
]
*
phi
[
9
]);
// const RealOpenMM* phi = &_phi[20*i];
// torques[i][0] += _electric*(multipole[3]*scale[1]*phi[2] - multipole[2]*scale[2]*phi[3]
// + 2.0*(multipole[6]-multipole[5])*scale[1]*scale[2]*phi[9]
// + multipole[8]*scale[0]*scale[1]*phi[7] + multipole[9]*scale[1]*scale[1]*phi[5]
// - multipole[7]*scale[0]*scale[2]*phi[8] - multipole[9]*scale[2]*scale[2]*phi[6]);
//
// torques[i][1] += _electric*(multipole[1]*scale[2]*phi[3] - multipole[3]*scale[0]*phi[1]
// + 2.0*(multipole[4]-multipole[6])*scale[0]*scale[2]*phi[8]
// + multipole[7]*scale[1]*scale[2]*phi[9] + multipole[8]*scale[2]*scale[2]*phi[6]
// - multipole[8]*scale[0]*scale[0]*phi[4] - multipole[9]*scale[0]*scale[1]*phi[7]);
//
// torques[i][2] += _electric*(multipole[2]*scale[0]*phi[1] - multipole[1]*scale[1]*phi[2]
// + 2.0*(multipole[5]-multipole[4])*scale[0]*scale[1]*phi[7]
// + multipole[7]*scale[0]*scale[0]*phi[4] + multipole[9]*scale[0]*scale[2]*phi[8]
// - multipole[7]*scale[1]*scale[1]*phi[5] - multipole[8]*scale[1]*scale[2]*phi[9]);
const RealOpenMM* phi = &cphi[10*i];
torques[i][0] += _electric*(multipole[3]*phi[2] - multipole[2]*phi[3]
+ 2.0*(multipole[6]-multipole[5])*phi[9]
+ multipole[8]*phi[7] + multipole[9]*phi[5]
- multipole[7]*phi[8] - multipole[9]*phi[6]);
torques[i][1] += _electric*(multipole[1]*phi[3] - multipole[3]*phi[1]
+ 2.0*(multipole[4]-multipole[6])*phi[8]
+ multipole[7]*phi[9] + multipole[8]*phi[6]
- multipole[8]*phi[4] - multipole[9]*phi[7]);
torques[i][2] += _electric*(multipole[2]*phi[1] - multipole[1]*phi[2]
+ 2.0*(multipole[5]-multipole[4])*phi[7]
+ multipole[7]*phi[4] + multipole[9]*phi[8]
- multipole[7]*phi[5] - multipole[8]*phi[9]);
// Compute the force and energy.
multipole
[
1
]
*=
scale
[
0
];
multipole
[
2
]
*=
scale
[
1
];
multipole
[
3
]
*=
scale
[
2
];
multipole
[
4
]
*=
scale
[
0
]
*
scale
[
0
];
multipole
[
5
]
*=
scale
[
1
]
*
scale
[
1
];
multipole
[
6
]
*=
scale
[
2
]
*
scale
[
2
];
multipole
[
7
]
*=
scale
[
0
]
*
scale
[
1
];
multipole
[
8
]
*=
scale
[
0
]
*
scale
[
2
];
multipole
[
9
]
*=
scale
[
1
]
*
scale
[
2
];
multipole[1] = _transformed[i].dipole[0];
multipole[2] = _transformed[i].dipole[1];
multipole[3] = _transformed[i].dipole[2];
multipole[4] = _transformed[i].quadrupole[QXX];
multipole[5] = _transformed[i].quadrupole[QYY];
multipole[6] = _transformed[i].quadrupole[QZZ];
multipole[7] = _transformed[i].quadrupole[QXY];
multipole[8] = _transformed[i].quadrupole[QXZ];
multipole[9] = _transformed[i].quadrupole[QYZ];
// multipole[1] *= scale[0];
// multipole[2] *= scale[1];
// multipole[3] *= scale[2];
// multipole[4] *= scale[0]*scale[0];
// multipole[5] *= scale[1]*scale[1];
// multipole[6] *= scale[2]*scale[2];
// multipole[7] *= scale[0]*scale[1];
// multipole[8] *= scale[0]*scale[2];
// multipole[9] *= scale[1]*scale[2];
RealVec f = RealVec(0.0, 0.0, 0.0);
for (int k = 0; k < 10; k++) {
energy
+=
multipole
[
k
]
*
phi
[
k
];
f
[
0
]
+=
multipole
[
k
]
*
phi
[
deriv1
[
k
]];
f
[
1
]
+=
multipole
[
k
]
*
phi
[
deriv2
[
k
]];
f
[
2
]
+=
multipole
[
k
]
*
phi
[
deriv3
[
k
]];
energy += multipole[k]*
_
phi[
20*i+
k];
f[0] += multipole[k]*
_
phi[
20*i+
deriv1[k]];
f[1] += multipole[k]*
_
phi[
20*i+
deriv2[k]];
f[2] += multipole[k]*
_
phi[
20*i+
deriv3[k]];
}
f
[
0
]
*=
scale
[
0
];
f
[
1
]
*=
scale
[
1
];
f
[
2
]
*=
scale
[
2
];
//
f[0] *= scale[0];
//
f[1] *= scale[1];
//
f[2] *= scale[2];
f *= (_electric);
forces
[
i
]
-=
f
;
forces[i] -= RealVec(f[0]*fracToCart[0][0] + f[1]*fracToCart[0][1] + f[2]*fracToCart[0][2],
f[0]*fracToCart[1][0] + f[1]*fracToCart[1][1] + f[2]*fracToCart[1][2],
f[0]*fracToCart[2][0] + f[1]*fracToCart[2][1] + f[2]*fracToCart[2][2]);
}
return (0.5*_electric*energy);
...
...
@@ -5719,8 +5826,14 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole
const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19};
const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16};
const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18};
RealVec
scale
;
getPmeScale
(
scale
);
vector<RealOpenMM> cphi(10*_numParticles);
transformPotentialToCartesianCoordinates(_phidp, cphi);
RealVec cartToFrac[3], fracToCart[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
cartToFrac[j][i] = fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
// RealVec scale;
// getPmeScale(scale);
RealOpenMM energy = 0.0;
for (int i = 0; i < _numParticles; i++) {
...
...
@@ -5741,45 +5854,54 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole
multipole[8] = particleData[i].quadrupole[QXZ]*2.0;
multipole[9] = particleData[i].quadrupole[QYZ]*2.0;
torques
[
iIndex
][
0
]
+=
0.5
*
_electric
*
(
multipole
[
3
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
2
]
-
multipole
[
2
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
3
]
+
2.0
*
(
multipole
[
6
]
-
multipole
[
5
])
*
scale
[
1
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
9
]
+
multipole
[
8
]
*
scale
[
0
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
7
]
+
multipole
[
9
]
*
scale
[
1
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
5
]
-
multipole
[
7
]
*
scale
[
0
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
8
]
-
multipole
[
9
]
*
scale
[
2
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
6
]);
const RealOpenMM* phi = &cphi[10*i];
torques[iIndex][0] += 0.5*_electric*(multipole[3]*phi[2] - multipole[2]*phi[3]
+ 2.0*(multipole[6]-multipole[5])*phi[9]
+ multipole[8]*phi[7] + multipole[9]*phi[5]
- multipole[7]*phi[8] - multipole[9]*phi[6]);
torques
[
iIndex
][
1
]
+=
0.5
*
_electric
*
(
multipole
[
1
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
3
]
-
multipole
[
3
]
*
scale
[
0
]
*
_phidp
[
20
*
i
+
1
]
+
2.0
*
(
multipole
[
4
]
-
multipole
[
6
])
*
scale
[
0
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
8
]
+
multipole
[
7
]
*
scale
[
1
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
9
]
+
multipole
[
8
]
*
scale
[
2
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
6
]
-
multipole
[
8
]
*
scale
[
0
]
*
scale
[
0
]
*
_phidp
[
20
*
i
+
4
]
-
multipole
[
9
]
*
scale
[
0
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
7
]);
torques[iIndex][1] += 0.5*_electric*(multipole[1]*
phi[3] - multipole[3]*phi[
1]
+ 2.0*(multipole[4]-multipole[6])*
phi[
8]
+ multipole[7]*
phi[9] + multipole[8]*phi[
6]
- multipole[8]*
phi[4] - multipole[9]*phi[
7]);
torques
[
iIndex
][
2
]
+=
0.5
*
_electric
*
(
multipole
[
2
]
*
scale
[
0
]
*
_phidp
[
20
*
i
+
1
]
-
multipole
[
1
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
2
]
+
2.0
*
(
multipole
[
5
]
-
multipole
[
4
])
*
scale
[
0
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
7
]
+
multipole
[
7
]
*
scale
[
0
]
*
scale
[
0
]
*
_phidp
[
20
*
i
+
4
]
+
multipole
[
9
]
*
scale
[
0
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
8
]
-
multipole
[
7
]
*
scale
[
1
]
*
scale
[
1
]
*
_phidp
[
20
*
i
+
5
]
-
multipole
[
8
]
*
scale
[
1
]
*
scale
[
2
]
*
_phidp
[
20
*
i
+
9
]);
torques[iIndex][2] += 0.5*_electric*(multipole[2]*
phi[1] - multipole[1]*phi[
2]
+ 2.0*(multipole[5]-multipole[4])*
phi[
7]
+ multipole[7]*
phi[4] + multipole[9]*phi[
8]
- multipole[7]*
phi[5] - multipole[8]*phi[
9]);
// Compute the force and energy.
multipole
[
1
]
*=
scale
[
0
];
multipole
[
2
]
*=
scale
[
1
];
multipole
[
3
]
*=
scale
[
2
];
multipole
[
4
]
*=
scale
[
0
]
*
scale
[
0
];
multipole
[
5
]
*=
scale
[
1
]
*
scale
[
1
];
multipole
[
6
]
*=
scale
[
2
]
*
scale
[
2
];
multipole
[
7
]
*=
scale
[
0
]
*
scale
[
1
];
multipole
[
8
]
*=
scale
[
0
]
*
scale
[
2
];
multipole
[
9
]
*=
scale
[
1
]
*
scale
[
2
];
inducedDipole
[
0
]
=
_inducedDipole
[
i
][
0
];
inducedDipole
[
1
]
=
_inducedDipole
[
i
][
1
];
inducedDipole
[
2
]
=
_inducedDipole
[
i
][
2
];
inducedDipolePolar
[
0
]
=
_inducedDipolePolar
[
i
][
0
];
inducedDipolePolar
[
1
]
=
_inducedDipolePolar
[
i
][
1
];
inducedDipolePolar
[
2
]
=
_inducedDipolePolar
[
i
][
2
];
energy
+=
scale
[
0
]
*
inducedDipole
[
0
]
*
_phi
[
20
*
i
+
1
];
energy
+=
scale
[
1
]
*
inducedDipole
[
1
]
*
_phi
[
20
*
i
+
2
];
energy
+=
scale
[
2
]
*
inducedDipole
[
2
]
*
_phi
[
20
*
i
+
3
];
multipole[1] = _transformed[i].dipole[0];
multipole[2] = _transformed[i].dipole[1];
multipole[3] = _transformed[i].dipole[2];
multipole[4] = _transformed[i].quadrupole[QXX];
multipole[5] = _transformed[i].quadrupole[QYY];
multipole[6] = _transformed[i].quadrupole[QZZ];
multipole[7] = _transformed[i].quadrupole[QXY];
multipole[8] = _transformed[i].quadrupole[QXZ];
multipole[9] = _transformed[i].quadrupole[QYZ];
// multipole[1] *= scale[0];
// multipole[2] *= scale[1];
// multipole[3] *= scale[2];
//
// multipole[4] *= scale[0]*scale[0];
// multipole[5] *= scale[1]*scale[1];
// multipole[6] *= scale[2]*scale[2];
// multipole[7] *= scale[0]*scale[1];
// multipole[8] *= scale[0]*scale[2];
// multipole[9] *= scale[1]*scale[2];
inducedDipole[0] = _inducedDipole[i][0]*cartToFrac[0][0] + _inducedDipole[i][1]*cartToFrac[0][1] + _inducedDipole[i][2]*cartToFrac[0][2];
inducedDipole[1] = _inducedDipole[i][0]*cartToFrac[1][0] + _inducedDipole[i][1]*cartToFrac[1][1] + _inducedDipole[i][2]*cartToFrac[1][2];
inducedDipole[2] = _inducedDipole[i][0]*cartToFrac[2][0] + _inducedDipole[i][1]*cartToFrac[2][1] + _inducedDipole[i][2]*cartToFrac[2][2];
inducedDipolePolar[0] = _inducedDipolePolar[i][0]*cartToFrac[0][0] + _inducedDipolePolar[i][1]*cartToFrac[0][1] + _inducedDipolePolar[i][2]*cartToFrac[0][2];
inducedDipolePolar[1] = _inducedDipolePolar[i][0]*cartToFrac[1][0] + _inducedDipolePolar[i][1]*cartToFrac[1][1] + _inducedDipolePolar[i][2]*cartToFrac[1][2];
inducedDipolePolar[2] = _inducedDipolePolar[i][0]*cartToFrac[2][0] + _inducedDipolePolar[i][1]*cartToFrac[2][1] + _inducedDipolePolar[i][2]*cartToFrac[2][2];
energy += inducedDipole[0]*_phi[20*i+1];
energy += inducedDipole[1]*_phi[20*i+2];
energy += inducedDipole[2]*_phi[20*i+3];
RealVec f = RealVec(0.0, 0.0, 0.0);
...
...
@@ -5789,47 +5911,49 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole
int j2 = deriv2[k+1];
int j3 = deriv3[k+1];
f
[
0
]
+=
(
inducedDipole
[
k
]
+
inducedDipolePolar
[
k
])
*
_phi
[
20
*
i
+
j1
]
*
(
scale
[
k
]
/
scale
[
0
])
;
f
[
1
]
+=
(
inducedDipole
[
k
]
+
inducedDipolePolar
[
k
])
*
_phi
[
20
*
i
+
j2
]
*
(
scale
[
k
]
/
scale
[
1
])
;
f
[
2
]
+=
(
inducedDipole
[
k
]
+
inducedDipolePolar
[
k
])
*
_phi
[
20
*
i
+
j3
]
*
(
scale
[
k
]
/
scale
[
2
])
;
f[0] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j1];
f[1] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j2];
f[2] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j3];
if (polarizationType == AmoebaReferenceMultipoleForce::Mutual)
{
f
[
0
]
+=
(
inducedDipole
[
k
]
*
_phip
[
10
*
i
+
j1
]
+
inducedDipolePolar
[
k
]
*
_phid
[
10
*
i
+
j1
])
*
(
scale
[
k
]
/
scale
[
0
])
;
f
[
1
]
+=
(
inducedDipole
[
k
]
*
_phip
[
10
*
i
+
j2
]
+
inducedDipolePolar
[
k
]
*
_phid
[
10
*
i
+
j2
])
*
(
scale
[
k
]
/
scale
[
1
])
;
f
[
2
]
+=
(
inducedDipole
[
k
]
*
_phip
[
10
*
i
+
j3
]
+
inducedDipolePolar
[
k
]
*
_phid
[
10
*
i
+
j3
])
*
(
scale
[
k
]
/
scale
[
2
])
;
f[0] += (inducedDipole[k]*_phip[10*i+j1] + inducedDipolePolar[k]*_phid[10*i+j1]);
f[1] += (inducedDipole[k]*_phip[10*i+j2] + inducedDipolePolar[k]*_phid[10*i+j2]);
f[2] += (inducedDipole[k]*_phip[10*i+j3] + inducedDipolePolar[k]*_phid[10*i+j3]);
}
}
f
[
0
]
*=
scale
[
0
];
f
[
1
]
*=
scale
[
1
];
f
[
2
]
*=
scale
[
2
];
for (int k = 0; k < 10; k++) {
f[0] += multipole[k]*_phidp[20*i+deriv1[k]];
f[1] += multipole[k]*_phidp[20*i+deriv2[k]];
f[2] += multipole[k]*_phidp[20*i+deriv3[k]];
}
f
[
0
]
*=
scale
[
0
];
f
[
1
]
*=
scale
[
1
];
f
[
2
]
*=
scale
[
2
];
//
f[0] *= scale[0];
//
f[1] *= scale[1];
//
f[2] *= scale[2];
f *= (0.5*_electric);
forces
[
iIndex
]
-=
f
;
forces[iIndex] -= RealVec(f[0]*fracToCart[0][0] + f[1]*fracToCart[0][1] + f[2]*fracToCart[0][2],
f[0]*fracToCart[1][0] + f[1]*fracToCart[1][1] + f[2]*fracToCart[1][2],
f[0]*fracToCart[2][0] + f[1]*fracToCart[2][1] + f[2]*fracToCart[2][2]);
}
return (0.5*_electric*energy);
}
void AmoebaReferencePmeMultipoleForce::recordFixedMultipoleField()
{
RealVec
scale
;
getPmeScale
(
scale
);
scale
*=
-
1.0
;
// RealVec scale;
// getPmeScale(scale);
// scale *= -1.0;
RealVec fracToCart[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
for (int i = 0; i < _numParticles; i++) {
_fixedMultipoleField
[
i
][
0
]
=
scale
[
0
]
*
_phi
[
20
*
i
+
1
]
;
_fixedMultipoleField
[
i
][
1
]
=
scale
[
1
]
*
_phi
[
20
*
i
+
2
];
_fixedMultipoleField
[
i
][
2
]
=
scale
[
2
]
*
_phi
[
20
*
i
+
3
]
;
_fixedMultipoleField[i][0] =
-(_phi[20*i+1]*fracToCart[0][0] + _phi[20*i+2]*fracToCart[0][1] + _phi[20*i+3]*fracToCart[0][2])
;
_fixedMultipoleField[i][1] =
-(_phi[20*i+1]*fracToCart[1][0] + _phi[20*i+2]*fracToCart[1][1] + _phi[20*i+3]*fracToCart[1][
2]
)
;
_fixedMultipoleField[i][2] =
-(_phi[20*i+1]*fracToCart[2][0] + _phi[20*i+2]*fracToCart[2][1] + _phi[20*i+3]*fracToCart[2][2])
;
}
return;
}
...
...
@@ -5844,18 +5968,22 @@ void AmoebaReferencePmeMultipoleForce::initializeInducedDipoles(vector<UpdateInd
void AmoebaReferencePmeMultipoleForce::recordInducedDipoleField(vector<RealVec>& field, vector<RealVec>& fieldPolar)
{
RealVec
scale
;
getPmeScale
(
scale
);
scale
*=
-
1.0
;
// RealVec scale;
// getPmeScale(scale);
// scale *= -1.0;
RealVec fracToCart[3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j];
for (int i = 0; i < _numParticles; i++) {
field
[
i
][
0
]
+=
scale
[
0
]
*
_phid
[
10
*
i
+
1
];
field
[
i
][
1
]
+=
scale
[
1
]
*
_phid
[
10
*
i
+
2
];
field
[
i
][
2
]
+=
scale
[
2
]
*
_phid
[
10
*
i
+
3
];
field[i][0]
-= _phid[10*i+1]*fracToCart[0][0] + _phid[10*i+2]*fracToCart[0][1] + _phid[10*i+3]*fracToCart[0][2
];
field[i][1]
-= _phid[10*i+1]*fracToCart[1][0] + _phid[10*i+2]*fracToCart[1][1] + _phid[10*i+3]*fracToCart[1][
2];
field[i][2]
-= _phid[10*i+1]*fracToCart[2][0] + _phid[10*i+2]*fracToCart[2][1] + _phid[10*i+3]*fracToCart[2][2
];
fieldPolar
[
i
][
0
]
+
=
scale
[
0
]
*
_phip
[
10
*
i
+
1
];
fieldPolar
[
i
][
1
]
+
=
scale
[
1
]
*
_phip
[
10
*
i
+
2
];
fieldPolar
[
i
][
2
]
+
=
scale
[
2
]
*
_phip
[
10
*
i
+
3
];
fieldPolar[i][0]
-
= _phip[10*i+1
]*fracToCart[0][0] + _phip[10*i+2]*fracToCart[0][1] + _phip[10*i+3]*fracToCart[0][2
];
fieldPolar[i][1]
-
= _phip[10*i+
1]*fracToCart[1][0] + _phip[10*i+2]*fracToCart[1][1] + _phip[10*i+3]*fracToCart[1][
2];
fieldPolar[i][2]
-
=
_phip[10*i+1]*fracToCart[2][0] + _phip[10*i+2]*fracToCart[2][1] + _phip[10*i+3]*fracToCart[2][2
];
}
return;
}
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h
View file @
5e3a0a05
...
...
@@ -591,6 +591,16 @@ protected:
RealOpenMM
dampingFactor
;
RealOpenMM
polarity
;
};
/**
* Particle parameters transformed into fractional coordinates
*/
class
TransformedMultipole
{
public:
RealOpenMM
charge
;
RealVec
dipole
;
RealOpenMM
quadrupole
[
6
];
};
/*
* Helper class used in calculating induced dipoles
...
...
@@ -618,6 +628,7 @@ protected:
RealOpenMM
_mScale
[
5
];
RealOpenMM
_uScale
[
5
];
std
::
vector
<
TransformedMultipole
>
_transformed
;
std
::
vector
<
RealVec
>
_fixedMultipoleField
;
std
::
vector
<
RealVec
>
_fixedMultipoleFieldPolar
;
std
::
vector
<
RealVec
>
_inducedDipole
;
...
...
@@ -1327,9 +1338,9 @@ public:
/**
* Set periodic box size.
*
* @param
boxSize box dimensions
* @param
vectors the vectors defining the periodic box
*/
void
setPeriodicBoxSize
(
RealVec
&
boxSize
);
void
setPeriodicBoxSize
(
OpenMM
::
RealVec
*
vectors
);
private:
...
...
@@ -1340,8 +1351,8 @@ private:
RealOpenMM
_cutoffDistance
;
RealOpenMM
_cutoffDistanceSquared
;
RealVec
_
invPeriodicBoxSize
;
RealVec
_periodicBox
Size
;
RealVec
_
recipBoxVectors
[
3
]
;
RealVec
_periodicBox
Vectors
[
3
]
;
int
_totalGridSize
;
IntVec
_pmeGridDimensions
;
...
...
@@ -1382,12 +1393,6 @@ private:
*/
void
getPeriodicDelta
(
RealVec
&
deltaR
)
const
;
/**
* Get PME scale.
*
*/
void
getPmeScale
(
RealVec
&
scale
)
const
;
/**
* Calculate damped inverse distances.
*
...
...
@@ -1460,7 +1465,6 @@ private:
/**
* Compute induced dipole grid value.
*
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
* @param particleGridIndices particle grid indices
* @param scale integer grid dimension/box size for each dimension
* @param ix x-dimension offset value
...
...
@@ -1469,8 +1473,17 @@ private:
* @param inputInducedDipole induced dipole value
* @param inputInducedDipolePolar induced dipole value
*/
RealOpenMM
computeFixedMultipolesGridValue
(
const
vector
<
MultipoleParticleData
>&
particleData
,
const
int2
&
particleGridIndices
,
const
RealVec
&
scale
,
int
ix
,
int
iy
,
const
IntVec
&
gridPoint
)
const
;
RealOpenMM
computeFixedMultipolesGridValue
(
const
int2
&
particleGridIndices
,
int
ix
,
int
iy
,
const
IntVec
&
gridPoint
)
const
;
/**
* Transform multipoles from cartesian coordinates to fractional coordinates.
*/
void
transformMultipolesToFractionalCoordinates
(
const
vector
<
MultipoleParticleData
>&
particleData
);
/**
* Transform potential from fractional coordinates to cartesian coordinates.
*/
void
transformPotentialToCartesianCoordinates
(
const
std
::
vector
<
RealOpenMM
>&
fphi
,
std
::
vector
<
RealOpenMM
>&
cphi
)
const
;
/**
* Spread fixed multipoles onto PME grid.
...
...
@@ -1568,7 +1581,7 @@ private:
* @param inputInducedDipole induced dipole value
* @param inputInducedDipolePolar induced dipole polar value
*/
t_complex
computeInducedDipoleGridValue
(
const
int2
&
atomIndices
,
const
RealVec
&
scale
,
int
ix
,
int
iy
,
const
IntVec
&
gridPoint
,
t_complex
computeInducedDipoleGridValue
(
const
int2
&
atomIndices
,
const
RealVec
*
fracToCart
,
int
ix
,
int
iy
,
const
IntVec
&
gridPoint
,
const
std
::
vector
<
RealVec
>&
inputInducedDipole
,
const
std
::
vector
<
RealVec
>&
inputInducedDipolePolar
)
const
;
...
...
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