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