Commit cf335495 authored by Mark Friedrichs's avatar Mark Friedrichs
Browse files

PME real space and self terms for fixed E-field

parent acb46362
......@@ -1420,6 +1420,18 @@ void gpuKirkwoodAllocate( amoebaGpuContext amoebaGpu )
}
static void tabulateErfc(gpuContext gpu)
{
int tableSize = 2048;
gpu->sim.tabulatedErfcSize = tableSize;
gpu->sim.tabulatedErfcScale = tableSize/(gpu->sim.alphaEwald*gpu->sim.nonbondedCutoff);
gpu->psTabulatedErfc = new CUDAStream<float>(tableSize, 1, "TabulatedErfc");
gpu->sim.pTabulatedErfc = gpu->psTabulatedErfc->_pDevData;
for (int i = 0; i < tableSize; ++i)
(*gpu->psTabulatedErfc)[i] = (float) erfc(i*(gpu->sim.alphaEwald*gpu->sim.nonbondedCutoff)/tableSize);
gpu->psTabulatedErfc->Upload();
}
/**---------------------------------------------------------------------------------------
Create/initialize data structs associated w/ molecular -> lab frame calculation
......@@ -1525,14 +1537,26 @@ void gpuSetAmoebaMultipoleParameters(amoebaGpuContext amoebaGpu, const std::vect
} else if( nonbondedMethod == 1 ){
amoebaGpu->multipoleNonbondedMethod = AMOEBA_PARTICLE_MESH_EWALD;
} else {
throw OpenMM::OpenMMException("multipoleNonbondedMethod not recognzied.\n" );
throw OpenMM::OpenMMException("multipoleNonbondedMethod not recognized.\n" );
}
amoebaGpu->amoebaSim.cutoffDistance2 = cutoffDistance*cutoffDistance;
amoebaGpu->amoebaSim.sqrtPi = sqrt( 3.1415926535897932384626433832795 );
amoebaGpu->amoebaSim.aewald = aewald;
amoebaGpu->amoebaSim.electric = electricConstant;
if( amoebaGpu->log ){
(void) fprintf( amoebaGpu->log,"%s Nonbonded method=%d %d [NoCutoff=%d PME=%d]\n",
methodName.c_str(), nonbondedMethod, amoebaGpu->multipoleNonbondedMethod,
AMOEBA_NO_CUTOFF, AMOEBA_PARTICLE_MESH_EWALD );
(void) fflush( amoebaGpu->log );
}
amoebaGpu->amoebaSim.cutoffDistance2 = cutoffDistance*cutoffDistance;
amoebaGpu->amoebaSim.sqrtPi = sqrt( 3.1415926535897932384626433832795 );
amoebaGpu->amoebaSim.aewald = aewald;
amoebaGpu->amoebaSim.electric = electricConstant;
amoebaGpu->gpuContext->sim.alphaEwald = aewald;
amoebaGpu->gpuContext->sim.nonbondedCutoff = cutoffDistance;
tabulateErfc(amoebaGpu->gpuContext);
if( amoebaGpu->amoebaSim.dielec < 1.0e-05 ){
amoebaGpu->amoebaSim.dielec = 1.0f;
amoebaGpu->amoebaSim.dielec = 1.0f;
}
for( int ii = 0; ii < static_cast<int>(charges.size()); ii++ ){
......@@ -2593,6 +2617,7 @@ void amoebaGpuSetConstants(amoebaGpuContext amoebaGpu)
SetCalculateAmoebaCudaVdw14_7Sim( amoebaGpu );
SetCalculateAmoebaCudaWcaDispersionSim( amoebaGpu );
SetCalculateAmoebaCudaMutualInducedFieldSim( amoebaGpu );
SetCalculateAmoebaCudaPmeFixedEFieldSim( amoebaGpu );
SetCalculateAmoebaElectrostaticSim( amoebaGpu );
SetCalculateAmoebaRealSpaceEwaldSim( amoebaGpu );
SetCalculateAmoebaCudaMapTorquesSim( amoebaGpu );
......
......@@ -65,12 +65,17 @@ extern void SetCalculateAmoebaCudaWcaDispersionSim(amoebaGpuContext gpu);
extern void GetCalculateAmoebaCudaWcaDispersionSim(amoebaGpuContext gpu);
extern void kCalculateAmoebaWcaDispersionForces(amoebaGpuContext amoebaGpu );
// fixed electric field
// fixed electric field -- no cutoff
extern void SetCalculateAmoebaCudaFixedEFieldSim(amoebaGpuContext gpu);
extern void GetCalculateAmoebaCudaFixedEFieldSim(amoebaGpuContext gpu);
extern void cudaComputeAmoebaFixedEField( amoebaGpuContext gpu);
// fixed electric field -- PME
extern void SetCalculateAmoebaCudaPmeFixedEFieldSim(amoebaGpuContext gpu);
extern void GetCalculateAmoebaCudaPmeFixedEFieldSim(amoebaGpuContext gpu);
extern void cudaComputeAmoebaPmeFixedEField( amoebaGpuContext gpu);
// fixed electric field and Gk
extern void SetCalculateAmoebaCudaFixedEAndGKFieldsSim(amoebaGpuContext gpu);
......
......@@ -83,6 +83,9 @@ void METHOD_NAME(kCalculateAmoebaFixedEAndGkField, _kernel)(
FixedFieldParticle* psA = &sA[tbx];
unsigned int atomI = x + tgx;
FixedFieldParticle localParticle;
loadFixedFieldShared( &localParticle, atomI, bornRadii );
float4 iCoord = atomCoord[atomI];
float eFieldSum[3];
......@@ -106,9 +109,7 @@ void METHOD_NAME(kCalculateAmoebaFixedEAndGkField, _kernel)(
// load coordinates, charge, ...
loadFixedFieldShared( &(sA[threadIdx.x]), atomI,
atomCoord, labFrameDipole, labFrameQuadrupole,
cAmoebaSim.pDampingFactorAndThole, bornRadii );
loadFixedFieldShared( &(sA[threadIdx.x]), atomI, bornRadii );
if (!bExclusionFlag)
{
......@@ -125,12 +126,7 @@ void METHOD_NAME(kCalculateAmoebaFixedEAndGkField, _kernel)(
loadFixedFieldParticleData( &(psA[j]), &jCoord, jDipole, jQuadrupole, &jBornRadius );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[j].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[j].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[j], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......@@ -182,12 +178,7 @@ void METHOD_NAME(kCalculateAmoebaFixedEAndGkField, _kernel)(
loadFixedFieldParticleData( &(psA[j]), &jCoord, jDipole, jQuadrupole, &jBornRadius );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[j].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[j].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[j], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......@@ -366,9 +357,7 @@ if( atomI == targetAtom ){
{
// load coordinates, charge, ...
loadFixedFieldShared( &(sA[threadIdx.x]), (y+tgx),
atomCoord, labFrameDipole, labFrameQuadrupole,
cAmoebaSim.pDampingFactorAndThole, bornRadii );
loadFixedFieldShared( &(sA[threadIdx.x]), (y+tgx), bornRadii );
}
......@@ -387,12 +376,7 @@ if( atomI == targetAtom ){
loadFixedFieldParticleData( &(psA[tj]), &jCoord, jDipole, jQuadrupole, &jBornRadius );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[tj].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[tj].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[tj], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......@@ -563,12 +547,7 @@ if( (atomI == targetAtom || (y + tj) == targetAtom) ){
loadFixedFieldParticleData( &(psA[tj]), &jCoord, jDipole, jQuadrupole, &jBornRadius );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[tj].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[tj].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[tj], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......
......@@ -61,46 +61,6 @@ static void kReduceE_Fields_kernel(amoebaGpuContext amoebaGpu )
#define METHOD_NAME(a, b) a##N2ByWarp##b
#include "kCalculateAmoebaCudaFixedEField.h"
#ifdef AMOEBA_DEBUG
#if 0
static void printEFieldBuffer( amoebaGpuContext amoebaGpu, unsigned int bufferIndex )
{
(void) fprintf( amoebaGpu->log, "EField Buffer %u\n", bufferIndex );
unsigned int start = bufferIndex*3*amoebaGpu->paddedNumberOfAtoms;
unsigned int stop = (bufferIndex+1)*3*amoebaGpu->paddedNumberOfAtoms;
for( unsigned int ii = start; ii < stop; ii += 3 ){
unsigned int ii3Index = ii/3;
unsigned int bufferIndex = ii3Index/(amoebaGpu->paddedNumberOfAtoms);
unsigned int particleIndex = ii3Index - bufferIndex*(amoebaGpu->paddedNumberOfAtoms);
(void) fprintf( amoebaGpu->log, " %6u %3u %6u [%14.6e %14.6e %14.6e] [%14.6e %14.6e %14.6e]\n",
ii/3, bufferIndex, particleIndex,
amoebaGpu->psWorkArray_3_1->_pSysStream[0][ii],
amoebaGpu->psWorkArray_3_1->_pSysStream[0][ii+1],
amoebaGpu->psWorkArray_3_1->_pSysStream[0][ii+2],
amoebaGpu->psWorkArray_3_2->_pSysStream[0][ii],
amoebaGpu->psWorkArray_3_2->_pSysStream[0][ii+1],
amoebaGpu->psWorkArray_3_2->_pSysStream[0][ii+2] );
}
}
static void printEFieldAtomBuffers( amoebaGpuContext amoebaGpu, unsigned int targetAtom )
{
(void) fprintf( amoebaGpu->log, "EField atom %u\n", targetAtom );
for( unsigned int ii = 0; ii < amoebaGpu->outputBuffers; ii++ ){
unsigned int particleIndex = targetAtom + ii*3*amoebaGpu->paddedNumberOfAtoms;
(void) fprintf( amoebaGpu->log, " %2u %6u [%14.6e %14.6e %14.6e] [%14.6e %14.6e %14.6e]\n",
ii, particleIndex,
amoebaGpu->psWorkArray_3_1->_pSysStream[0][particleIndex],
amoebaGpu->psWorkArray_3_1->_pSysStream[0][particleIndex+1],
amoebaGpu->psWorkArray_3_1->_pSysStream[0][particleIndex+2],
amoebaGpu->psWorkArray_3_2->_pSysStream[0][particleIndex],
amoebaGpu->psWorkArray_3_2->_pSysStream[0][particleIndex+1],
amoebaGpu->psWorkArray_3_2->_pSysStream[0][particleIndex+2] );
}
}
#endif
#endif
/**---------------------------------------------------------------------------------------
Compute fixed electric field
......@@ -145,9 +105,6 @@ void cudaComputeAmoebaFixedEField( amoebaGpuContext amoebaGpu )
(void) fprintf( amoebaGpu->log, "N2 warp\n" );
kCalculateAmoebaFixedE_FieldN2ByWarpForces_kernel<<<amoebaGpu->nonbondBlocks, amoebaGpu->nonbondThreadsPerBlock, sizeof(FixedFieldParticle)*amoebaGpu->nonbondThreadsPerBlock>>>(
amoebaGpu->psWorkUnit->_pDevStream[0],
gpu->psPosq4->_pDevStream[0],
amoebaGpu->psLabFrameDipole->_pDevStream[0],
amoebaGpu->psLabFrameQuadrupole->_pDevStream[0],
amoebaGpu->psWorkArray_3_1->_pDevStream[0],
#ifdef AMOEBA_DEBUG
amoebaGpu->psWorkArray_3_2->_pDevStream[0],
......@@ -167,9 +124,6 @@ void cudaComputeAmoebaFixedEField( amoebaGpuContext amoebaGpu )
kCalculateAmoebaFixedE_FieldN2Forces_kernel<<<amoebaGpu->nonbondBlocks, amoebaGpu->nonbondThreadsPerBlock, sizeof(FixedFieldParticle)*amoebaGpu->nonbondThreadsPerBlock>>>(
amoebaGpu->psWorkUnit->_pDevStream[0],
gpu->psPosq4->_pDevStream[0],
amoebaGpu->psLabFrameDipole->_pDevStream[0],
amoebaGpu->psLabFrameQuadrupole->_pDevStream[0],
amoebaGpu->psWorkArray_3_1->_pDevStream[0],
#ifdef AMOEBA_DEBUG
amoebaGpu->psWorkArray_3_2->_pDevStream[0],
......
......@@ -36,9 +36,6 @@ __launch_bounds__(G8X_NONBOND_THREADS_PER_BLOCK, 1)
#endif
void METHOD_NAME(kCalculateAmoebaFixedE_Field, Forces_kernel)(
unsigned int* workUnit,
float4* atomCoord,
float* labFrameDipole,
float* labFrameQuadrupole,
float* outputEField,
float* outputEFieldPolar
#ifdef AMOEBA_DEBUG
......@@ -59,10 +56,6 @@ void METHOD_NAME(kCalculateAmoebaFixedE_Field, Forces_kernel)(
unsigned int end = (warp+1)*numWorkUnits/totalWarps;
unsigned int lasty = 0xFFFFFFFF;
float4 jCoord;
float jDipole[3];
float jQuadrupole[9];
while (pos < end)
{
......@@ -80,7 +73,9 @@ void METHOD_NAME(kCalculateAmoebaFixedE_Field, Forces_kernel)(
FixedFieldParticle* psA = &sA[tbx];
unsigned int atomI = x + tgx;
float4 iCoord = atomCoord[atomI];
FixedFieldParticle localParticle;
loadFixedFieldShared( &localParticle, atomI );
float fieldSum[3];
float fieldPolarSum[3];
......@@ -98,9 +93,7 @@ void METHOD_NAME(kCalculateAmoebaFixedE_Field, Forces_kernel)(
// load coordinates, charge, ...
loadFixedFieldShared( &(sA[threadIdx.x]), atomI,
atomCoord, labFrameDipole, labFrameQuadrupole,
cAmoebaSim.pDampingFactorAndThole );
loadFixedFieldShared( &(sA[threadIdx.x]), atomI );
if (!bExclusionFlag)
{
......@@ -113,16 +106,7 @@ void METHOD_NAME(kCalculateAmoebaFixedE_Field, Forces_kernel)(
float ijField[2][3];
// load coords, charge, ...
loadFixedFieldParticleData( &(psA[j]), &jCoord, jDipole, jQuadrupole );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[j].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[j].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[j], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......@@ -156,14 +140,9 @@ void METHOD_NAME(kCalculateAmoebaFixedE_Field, Forces_kernel)(
float ijField[2][3];
loadFixedFieldParticleData( &(psA[j]), &jCoord, jDipole, jQuadrupole );
//loadFixedFieldParticleData( &(psA[j]), &jCoord, jDipole, jQuadrupole );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[j].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[j].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[j], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......@@ -280,9 +259,7 @@ if( 0 && atomI == targetAtom ){
// load coordinates, charge, ...
loadFixedFieldShared( &(sA[threadIdx.x]), (y+tgx),
atomCoord, labFrameDipole, labFrameQuadrupole,
cAmoebaSim.pDampingFactorAndThole );
loadFixedFieldShared( &(sA[threadIdx.x]), (y+tgx) );
}
......@@ -297,16 +274,7 @@ if( 0 && atomI == targetAtom ){
float ijField[2][3];
// load coords, charge, ...
loadFixedFieldParticleData( &(psA[tj]), &jCoord, jDipole, jQuadrupole );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[tj].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[tj].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[tj], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......@@ -420,14 +388,7 @@ if( 0 && (atomI == targetAtom || (y + tj) == targetAtom) ){
float ijField[2][3];
loadFixedFieldParticleData( &(psA[tj]), &jCoord, jDipole, jQuadrupole );
calculateFixedEFieldPairIxn_kernel( iCoord, jCoord,
cAmoebaSim.pDampingFactorAndThole[atomI].x, psA[tj].damp,
cAmoebaSim.pDampingFactorAndThole[atomI].y, psA[tj].thole,
&(labFrameDipole[atomI*3]), jDipole,
&(labFrameQuadrupole[atomI*9]), jQuadrupole,
cAmoebaSim.scalingDistanceCutoff, ijField
calculateFixedEFieldPairIxn_kernel( localParticle, psA[tj], ijField
#ifdef AMOEBA_DEBUG
, pullBack
#endif
......
......@@ -46,9 +46,7 @@ struct FixedFieldParticle {
#endif
};
__device__ void loadFixedFieldShared( struct FixedFieldParticle* sA, unsigned int atomI,
float4* atomCoord, float* labDipole, float* labQuadrupole,
float2* dampingFactorAndThole
__device__ static void loadFixedFieldShared( struct FixedFieldParticle* sA, unsigned int atomI
#ifdef GK
, float* bornR
#endif
......@@ -56,28 +54,28 @@ __device__ void loadFixedFieldShared( struct FixedFieldParticle* sA, unsigned in
{
// coordinates & charge
sA->x = atomCoord[atomI].x;
sA->y = atomCoord[atomI].y;
sA->z = atomCoord[atomI].z;
sA->q = atomCoord[atomI].w;
sA->x = cSim.pPosq[atomI].x;
sA->y = cSim.pPosq[atomI].y;
sA->z = cSim.pPosq[atomI].z;
sA->q = cSim.pPosq[atomI].w;
// lab dipole
sA->labFrameDipole_X = labDipole[atomI*3];
sA->labFrameDipole_Y = labDipole[atomI*3+1];
sA->labFrameDipole_Z = labDipole[atomI*3+2];
sA->labFrameDipole_X = cAmoebaSim.pLabFrameDipole[atomI*3];
sA->labFrameDipole_Y = cAmoebaSim.pLabFrameDipole[atomI*3+1];
sA->labFrameDipole_Z = cAmoebaSim.pLabFrameDipole[atomI*3+2];
// lab quadrupole
sA->labFrameQuadrupole_XX = labQuadrupole[atomI*9];
sA->labFrameQuadrupole_XY = labQuadrupole[atomI*9+1];
sA->labFrameQuadrupole_XZ = labQuadrupole[atomI*9+2];
sA->labFrameQuadrupole_YY = labQuadrupole[atomI*9+4];
sA->labFrameQuadrupole_YZ = labQuadrupole[atomI*9+5];
sA->labFrameQuadrupole_ZZ = labQuadrupole[atomI*9+8];
sA->labFrameQuadrupole_XX = cAmoebaSim.pLabFrameQuadrupole[atomI*9];
sA->labFrameQuadrupole_XY = cAmoebaSim.pLabFrameQuadrupole[atomI*9+1];
sA->labFrameQuadrupole_XZ = cAmoebaSim.pLabFrameQuadrupole[atomI*9+2];
sA->labFrameQuadrupole_YY = cAmoebaSim.pLabFrameQuadrupole[atomI*9+4];
sA->labFrameQuadrupole_YZ = cAmoebaSim.pLabFrameQuadrupole[atomI*9+5];
sA->labFrameQuadrupole_ZZ = cAmoebaSim.pLabFrameQuadrupole[atomI*9+8];
sA->damp = dampingFactorAndThole[atomI].x;
sA->thole = dampingFactorAndThole[atomI].y;
sA->damp = cAmoebaSim.pDampingFactorAndThole[atomI].x;
sA->thole = cAmoebaSim.pDampingFactorAndThole[atomI].y;
#ifdef GK
sA->bornR = bornR[atomI];
#endif
......@@ -86,8 +84,8 @@ __device__ void loadFixedFieldShared( struct FixedFieldParticle* sA, unsigned in
// load struct and arrays w/ shared data in sA
__device__ void loadFixedFieldParticleData( struct FixedFieldParticle* sA,
float4* jCoord, float* jDipole, float* jQuadrupole
__device__ static void loadFixedFieldParticleData( struct FixedFieldParticle* sA,
float4* jCoord, float* jDipole, float* jQuadrupole
#ifdef GK
, float* bornR
#endif
......@@ -142,15 +140,11 @@ __device__ static void zeroFixedFieldParticleSharedField( struct FixedFieldParti
#endif
}
// body of fixed E-field calculation
__device__ static void calculateFixedEFieldPairIxn_kernel( float4 atomCoordinatesI, float4 atomCoordinatesJ,
float dampingFactorI, float dampingFactorJ,
float tholeI, float tholeJ,
float* labDipoleI, float* labDipoleJ,
float* labQuadrupoleI, float* labQuadrupoleJ,
float scalingDistanceCutoff,
float field[2][3]
__device__ static void calculateFixedEFieldPairIxn_kernel( FixedFieldParticle& atomI, FixedFieldParticle& atomJ,
float field[2][3]
#ifdef AMOEBA_DEBUG
, float4 debugArray[12]
#endif
......@@ -163,9 +157,9 @@ __device__ static void calculateFixedEFieldPairIxn_kernel( float4 atomCoordinate
// get deltaR and r between 2 atoms
float deltaR[3];
deltaR[0] = atomCoordinatesJ.x - atomCoordinatesI.x;
deltaR[1] = atomCoordinatesJ.y - atomCoordinatesI.y;
deltaR[2] = atomCoordinatesJ.z - atomCoordinatesI.z;
deltaR[0] = atomJ.x - atomI.x;
deltaR[1] = atomJ.y - atomI.y;
deltaR[2] = atomJ.z - atomI.z;
float r = SQRT( deltaR[0]*deltaR[0] + deltaR[1]*deltaR[1] + deltaR[2]*deltaR[2] );
float rI = 1.0f/r;
......@@ -177,14 +171,14 @@ __device__ static void calculateFixedEFieldPairIxn_kernel( float4 atomCoordinate
// get scaling factors, if needed
float damp = dampingFactorI*dampingFactorJ;
float damp = atomI.damp*atomJ.damp;
float dampExp;
if( damp != 0.0f && r < scalingDistanceCutoff ){
if( damp != 0.0f && r < cAmoebaSim.scalingDistanceCutoff ){
// get scaling factors
float ratio = r/damp;
float pGamma = tholeJ > tholeI ? tholeI : tholeJ;
float pGamma = atomJ.thole > atomI.thole ? atomI.thole : atomJ.thole;
damp = ratio*ratio*ratio*pGamma;
dampExp = EXP( -damp );
} else {
......@@ -197,69 +191,30 @@ __device__ static void calculateFixedEFieldPairIxn_kernel( float4 atomCoordinate
float rr5_2 = rr5*2.0f;
#ifdef AMOEBA_DEBUG
int index = 0;
// 0-2
debugArray[index].x = r;
debugArray[index].y = rr3;
debugArray[index].z = rr5;
index++;
#endif
float* dipole = labDipoleJ;
float* quadrupole = labQuadrupoleJ;
float qDotDelta[3];
qDotDelta[0] = deltaR[0]*quadrupole[0] + deltaR[1]*quadrupole[1] + deltaR[2]*quadrupole[2];
qDotDelta[1] = deltaR[0]*quadrupole[3] + deltaR[1]*quadrupole[4] + deltaR[2]*quadrupole[5];
qDotDelta[2] = deltaR[0]*quadrupole[6] + deltaR[1]*quadrupole[7] + deltaR[2]*quadrupole[8];
float dotdd = deltaR[0]*dipole[0] + deltaR[1]*dipole[1] + deltaR[2]*dipole[2];
float dotqd = deltaR[0]*qDotDelta[0] + deltaR[1]*qDotDelta[1] + deltaR[2]*qDotDelta[2];
float factor = -rr3*atomCoordinatesJ.w + rr5*dotdd - rr7*dotqd;
qDotDelta[0] = deltaR[0]*atomJ.labFrameQuadrupole_XX + deltaR[1]*atomJ.labFrameQuadrupole_XY + deltaR[2]*atomJ.labFrameQuadrupole_XZ;
qDotDelta[1] = deltaR[0]*atomJ.labFrameQuadrupole_XY + deltaR[1]*atomJ.labFrameQuadrupole_YY + deltaR[2]*atomJ.labFrameQuadrupole_YZ;
qDotDelta[2] = deltaR[0]*atomJ.labFrameQuadrupole_XZ + deltaR[1]*atomJ.labFrameQuadrupole_YZ + deltaR[2]*atomJ.labFrameQuadrupole_ZZ;
#ifdef AMOEBA_DEBUG
// 3-5
debugArray[index].x = dotdd;
debugArray[index].y = dotqd;
debugArray[index].z = factor;
index++;
#endif
float dotdd = deltaR[0]*atomJ.labFrameDipole_X + deltaR[1]*atomJ.labFrameDipole_Y + deltaR[2]*atomJ.labFrameDipole_Z;
float dotqd = deltaR[0]*qDotDelta[0] + deltaR[1]*qDotDelta[1] + deltaR[2]*qDotDelta[2];
field[0][0] = deltaR[0]*factor - rr3*dipole[0] + rr5_2*qDotDelta[0];
field[0][1] = deltaR[1]*factor - rr3*dipole[1] + rr5_2*qDotDelta[1];
field[0][2] = deltaR[2]*factor - rr3*dipole[2] + rr5_2*qDotDelta[2];
float factor = -rr3*atomJ.q + rr5*dotdd - rr7*dotqd;
field[0][0] = deltaR[0]*factor - rr3*atomJ.labFrameDipole_X + rr5_2*qDotDelta[0];
field[0][1] = deltaR[1]*factor - rr3*atomJ.labFrameDipole_Y + rr5_2*qDotDelta[1];
field[0][2] = deltaR[2]*factor - rr3*atomJ.labFrameDipole_Z + rr5_2*qDotDelta[2];
dipole = labDipoleI;
quadrupole = labQuadrupoleI;
qDotDelta[0] = deltaR[0]*quadrupole[0] + deltaR[1]*quadrupole[1] + deltaR[2]*quadrupole[2];
qDotDelta[1] = deltaR[0]*quadrupole[3] + deltaR[1]*quadrupole[4] + deltaR[2]*quadrupole[5];
qDotDelta[2] = deltaR[0]*quadrupole[6] + deltaR[1]*quadrupole[7] + deltaR[2]*quadrupole[8];
qDotDelta[0] = deltaR[0]*atomI.labFrameQuadrupole_XX + deltaR[1]*atomI.labFrameQuadrupole_XY + deltaR[2]*atomI.labFrameQuadrupole_XZ;
qDotDelta[1] = deltaR[0]*atomI.labFrameQuadrupole_XY + deltaR[1]*atomI.labFrameQuadrupole_YY + deltaR[2]*atomI.labFrameQuadrupole_YZ;
qDotDelta[2] = deltaR[0]*atomI.labFrameQuadrupole_XZ + deltaR[1]*atomI.labFrameQuadrupole_YZ + deltaR[2]*atomI.labFrameQuadrupole_ZZ;
dotdd = deltaR[0]*dipole[0] + deltaR[1]*dipole[1] + deltaR[2]*dipole[2];
dotdd = deltaR[0]*atomI.labFrameDipole_X + deltaR[1]*atomI.labFrameDipole_Y + deltaR[2]*atomI.labFrameDipole_Z;
dotqd = deltaR[0]*qDotDelta[0] + deltaR[1]*qDotDelta[1] + deltaR[2]*qDotDelta[2];
factor = rr3*atomCoordinatesI.w + rr5*dotdd + rr7*dotqd;
factor = rr3*atomI.q + rr5*dotdd + rr7*dotqd;
#ifdef AMOEBA_DEBUG
// 6-8
debugArray[index].x = dotdd;
debugArray[index].y = dotqd;
debugArray[index].z = factor;
index++;
#endif
field[1][0] = deltaR[0]*factor - rr3*atomI.labFrameDipole_X - rr5_2*qDotDelta[0];
field[1][1] = deltaR[1]*factor - rr3*atomI.labFrameDipole_Y - rr5_2*qDotDelta[1];
field[1][2] = deltaR[2]*factor - rr3*atomI.labFrameDipole_Z - rr5_2*qDotDelta[2];
field[1][0] = deltaR[0]*factor - rr3*dipole[0] - rr5_2*qDotDelta[0];
field[1][1] = deltaR[1]*factor - rr3*dipole[1] - rr5_2*qDotDelta[1];
field[1][2] = deltaR[2]*factor - rr3*dipole[2] - rr5_2*qDotDelta[2];
#if 0
float testValue = 1.0f;
field[0][0] = testValue;
field[0][1] = testValue;
field[0][2] = testValue;
field[1][0] = testValue;
field[1][1] = testValue;
field[1][2] = testValue;
#endif
}
......@@ -1027,6 +1027,9 @@ void cudaComputeAmoebaRealSpaceEwald( amoebaGpuContext amoebaGpu )
(void) fflush( amoebaGpu->log );
#endif
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
cudaBindTexture(NULL, &tabulatedErfcRef, gpu->psTabulatedErfc->_pDevData, &channelDesc, gpu->psTabulatedErfc->_length*sizeof(float));
kCalculateAmoebaCudaRealSpaceEwaldN2Forces_kernel<<<amoebaGpu->nonbondBlocks, threadsPerBlock, sizeof(RealSpaceEwaldParticle)*threadsPerBlock>>>(
amoebaGpu->psWorkUnit->_pDevStream[0],
gpu->psPosq4->_pDevStream[0],
......
......@@ -368,8 +368,12 @@ void kCalculateAmoebaMultipoleForces(amoebaGpuContext amoebaGpu, bool hasAmoebaG
cudaComputeAmoebaFixedEAndGkFields( amoebaGpu );
cudaComputeAmoebaMutualInducedAndGkField( amoebaGpu );
} else {
cudaComputeAmoebaFixedEField( amoebaGpu );
cudaComputeAmoebaMutualInducedField( amoebaGpu );
if( amoebaGpu->multipoleNonbondedMethod == AMOEBA_NO_CUTOFF ){
cudaComputeAmoebaFixedEField( amoebaGpu );
cudaComputeAmoebaMutualInducedField( amoebaGpu );
} else {
cudaComputeAmoebaPmeFixedEField( amoebaGpu );
}
}
// check if induce dipole calculation converged -- abort if it did not
......
......@@ -1989,6 +1989,7 @@ static int readAmoebaMultipoleParameters( FILE* filePtr, int version, MapStringI
int usePme = 0;
double aewald = 0.0;
double cutoffDistance = 0.0;
double box[3] = { 10.0, 10.0, 10.0 };
// usePme, aewald, cutoffDistance added w/ Version 1
......@@ -1996,7 +1997,11 @@ static int readAmoebaMultipoleParameters( FILE* filePtr, int version, MapStringI
usePme = atoi( tokens[2].c_str() );
aewald = atof( tokens[3].c_str() );
cutoffDistance = atof( tokens[4].c_str() );
box[0] = atof( tokens[5].c_str() );
box[1] = atof( tokens[6].c_str() );
box[2] = atof( tokens[7].c_str() );
}
if( usePme ){
multipoleForce->setNonbondedMethod( AmoebaMultipoleForce::PME );
} else {
......@@ -2004,6 +2009,7 @@ static int readAmoebaMultipoleParameters( FILE* filePtr, int version, MapStringI
}
multipoleForce->setAEwald( aewald );
multipoleForce->setCutoffDistance( cutoffDistance );
system.setDefaultPeriodicBoxVectors( Vec3(box[0], 0.0, 0.0), Vec3(0.0, box[1], 0.0), Vec3(0.0, 0.0, box[2]) );
if( log ){
(void) fprintf( log, "%s number of MultipoleParameter terms=%d usePme=%d aewald=%15.7e cutoffDistance=%12.4f\n",
methodName.c_str(), numberOfMultipoles, usePme, aewald, cutoffDistance );
......@@ -2106,10 +2112,26 @@ static int readAmoebaMultipoleParameters( FILE* filePtr, int version, MapStringI
double polarityConversion = AngstromToNm*AngstromToNm*AngstromToNm;
double dampingFactorConversion = sqrt( AngstromToNm );
float scalingDistanceCutoff = static_cast<float>(multipoleForce->getScalingDistanceCutoff());
scalingDistanceCutoff *= static_cast<float>(AngstromToNm);
multipoleForce->setScalingDistanceCutoff( scalingDistanceCutoff );
multipoleForce->setAEwald( multipoleForce->getAEwald()/AngstromToNm);
multipoleForce->setCutoffDistance( multipoleForce->getCutoffDistance()*AngstromToNm );
multipoleForce->setScalingDistanceCutoff( multipoleForce->getScalingDistanceCutoff()*AngstromToNm );
Vec3 a,b,c;
system.getDefaultPeriodicBoxVectors( a, b, c);
a[0] *= AngstromToNm;
a[1] *= AngstromToNm;
a[2] *= AngstromToNm;
b[0] *= AngstromToNm;
b[1] *= AngstromToNm;
b[2] *= AngstromToNm;
c[0] *= AngstromToNm;
c[1] *= AngstromToNm;
c[2] *= AngstromToNm;
system.setDefaultPeriodicBoxVectors( a, b, c);
for( int ii = 0; ii < multipoleForce->getNumMultipoles(); ii++ ){
......@@ -2144,6 +2166,15 @@ static int readAmoebaMultipoleParameters( FILE* filePtr, int version, MapStringI
(void) fprintf( log, "%s Sample of parameters using %s units.\n", methodName.c_str(),
(useOpenMMUnits ? "OpenMM" : "Amoeba") );
std::string nonbondedMethod = multipoleForce->getNonbondedMethod( ) == AmoebaMultipoleForce::PME ? "PME" : "NoCutoff";
(void) fprintf( log, "NonbondedMethod=%s aEwald=%15.7e cutoff=%15.7e.\n", nonbondedMethod.c_str(),
multipoleForce->getAEwald(), multipoleForce->getCutoffDistance() );
Vec3 a,b,c;
system.getDefaultPeriodicBoxVectors( a, b, c );
(void) fprintf( log, "Box=[%12.3f %12.3f %12.3f] [%12.3f %12.3f %12.3f] [%12.3f %12.3f %12.3f]\n",
a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2] );
(void) fprintf( log, "Supplementary fields %u: ", static_cast<unsigned int>(supplementary.size()) );
for( MapStringVectorOfVectorsCI ii = supplementary.begin(); ii != supplementary.end(); ii++ ){
(void) fprintf( log, "%s ", (*ii).first.c_str() );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment