20 #include "ComputeMgr.decl.h"    27 #define MIN_DEBUG_LEVEL 1    41   int *table = 
new int[ntypes*ntypes];
    43   for (
int i=0; i<ntypes; i++) {
    44     for (
int j=i; j<ntypes; j++) {
    45       table[ntypes*i+j] = table[ntypes*j+i] = ind++;
    54   DebugM(3,
"Constructing client\n");
    61   ktot = (1+kxmax) * (2*kymax+1) * (2*kzmax+1);
    65   int nelements = 3*pressureProfileSlabs * (numAtomTypes*(numAtomTypes+1))/2;
    66   pressureProfileData = 
new float[nelements];
    72   masterNode = numWorkingPes - 1;
    76   localPartitions = NULL;
    78   expx = 
new float[kxmax+1];
    79   expy = 
new float[kymax+1];
    80   expz = 
new float[kzmax+1];
    82   if (CkMyPe() == masterNode) {
    83     eiktotal = 
new float[2 * ktot * numAtomTypes]; 
    84     memset(eiktotal, 0, 2 * ktot * numAtomTypes*
sizeof(
float));
    92   Qk = 
new float[3*ktot];
   106   delete [] pressureProfileData;
   108   delete [] gridsForAtomType;
   110   if (localAtoms) free(localAtoms);
   111   if (localPartitions) free(localPartitions);
   117   if ( ! 
patchList[0].p->flags.doFullElectrostatics )
   119     for (ap = ap.
begin(); ap != ap.
end(); ap++) {
   120       CompAtom *x = (*ap).positionBox->open();
   121       Results *r = (*ap).forceBox->open();
   122       (*ap).positionBox->close(&x);
   123       (*ap).forceBox->close(&r);
   134   pressureProfileThickness = lattice.
c().
z / pressureProfileSlabs;
   135   pressureProfileMin = lattice.
origin().
z - 0.5*lattice.
c().
z;
   142   for (ap = ap.
begin(); ap != ap.
end(); ap++) {
   143     numLocalAtoms += (*ap).p->getNumAtoms();
   146   localPartitions = (
int *)realloc(localPartitions, numLocalAtoms*
sizeof(
int));
   149   int *part_ptr = localPartitions;
   151   for (ap = ap.
begin(); ap != ap.
end(); ap++) {
   152     CompAtom *x = (*ap).positionBox->open();
   154     Results *r = (*ap).forceBox->open();
   156       (*ap).positionBox->close(&x);
   157       x = (*ap).avgPositionBox->open();
   159     int numAtoms = (*ap).p->getNumAtoms();
   161     for(
int i=0; i<numAtoms; ++i) {
   169       data_ptr->
cg = coulomb_sqrt * x[i].
charge;
   172     (*ap).positionBox->close(&x);
   173     (*ap).forceBox->close(&r);
   178   int msgsize = 2 * numAtomTypes * ktot;
   180   memset(msg->
eik, 0, msgsize*
sizeof(
float));
   181   compute_structurefactor(msg->
eik);
   189   int nvecs = 2 * ktot * numAtomTypes;
   190   for (
int i=0; i<nvecs; i++) {
   191     eiktotal[i] += msg->
eik[i];
   194   if (++recvCount == numWorkingPes) {
   196     int msgsize = 2 * ktot * numAtomTypes;
   198     memcpy(msg->
eik, eiktotal, msgsize*
sizeof(
float));
   199     memset(eiktotal, 0, msgsize*
sizeof(
float));
   206   computePprofile(msg->
eik);
   208   float scalefac = 1.0 / (2 * 
M_PI * lattice.
volume());
   210   int nelements = 3*pressureProfileSlabs * (numAtomTypes*(numAtomTypes+1))/2;
   211   for (
int i=0; i<nelements; i++) {
   212     reduction->
item(i) += pressureProfileData[i] * scalefac;
   217 void ComputeEwald::compute_structurefactor(
float *eik) {
   219   float recipx = lattice.
a_r().
x;
   220   float recipy = lattice.
b_r().
y;
   221   float recipz = lattice.
c_r().
z;
   223   for (i=0; i<numLocalAtoms; i++) {
   225     float krx = 2 * 
M_PI * localAtoms[i].
x * recipx;
   226     float kry = 2 * 
M_PI * localAtoms[i].
y * recipy;
   227     float krz = 2 * 
M_PI * localAtoms[i].
z * recipz;
   228     float cg = localAtoms[i].
cg;
   230     const int offset = 2*ktot*localPartitions[i];
   241     for (j=1; j<= kymax; j++) {
   252     for (j=1; j<= kzmax; j++) {
   261     for (
int kx=0; kx <= kxmax; kx++) {
   262       for (
int ky=0; ky <= 2*kymax; ky++) {
   265                                 const int max = 2*kzmax;
   266                                 const float exyr = exy.
r;
   267                                 const float exyi = exy.
i;
   268                     const float *eikzd = (
const float *)eikz;
   269 #pragma vector always   270         for (
int kz=0; kz <= max; kz++) {
   271                                         float ezr = *eikzd++;
   272                                         float ezi = *eikzd++;
   273                                         float eikr = ezr*exyr - ezi*exyi;
   274                                         float eiki = ezr*exyi + ezi*exyr;
   290 static void init_exp(
float *xp, 
int K, 
float recip, 
float kappa) {
   291   float piob = 
M_PI / kappa;
   293   float fac = -piob*recip*recip;
   294   for (
int i=0; i<= K; i++)
   295     xp[i] = exp(fac*i*i);
   298 void ComputeEwald::computePprofile(
const float *eik)
 const { 
   299   float recipx = lattice.
a_r().
x;
   300   float recipy = lattice.
b_r().
y;
   301   float recipz = lattice.
c_r().
z;
   303   init_exp(expx, kxmax, recipx, kappa);
   304   init_exp(expy, kymax, recipy, kappa);
   305   init_exp(expz, kzmax, recipz, kappa);
   308   float piob = 
M_PI / kappa;
   313   for (
int kx=0; kx <= kxmax; kx++) {
   314     float m11 = recipx * kx;
   316     float xfac = expx[kx] * (kx ? 2 : 1);
   317     for (
int ky=-kymax; ky <= kymax; ky++) {
   318       float m22 = recipy * ky;
   320       float xyfac = expy[abs(ky)] * xfac;
   321       for (
int kz=-kzmax; kz <= kzmax; kz++) {
   322         float m33 = recipz * kz;
   324         float msq = m11 + m22 + m33;
   325         float imsq = msq ? 1.0 / msq : 0;
   326         float fac = expz[abs(kz)] * xyfac * imsq;
   328         float pfac = 2*(imsq + piob);
   329         Qk[ind++] = fac*(1-pfac*m11);
   330         Qk[ind++] = fac*(1-pfac*m22);
   331         Qk[ind++] = fac*(1-pfac*m33);
   336   const int nslabs = pressureProfileSlabs;
   338   int nelements = 3*nslabs * (numAtomTypes*(numAtomTypes+1))/2;
   339   memset(pressureProfileData, 0, nelements*
sizeof(
float));
   341   for (i=0; i<numLocalAtoms; i++) {
   343     float krx = 2 * 
M_PI * localAtoms[i].
x * recipx;
   344     float kry = 2 * 
M_PI * localAtoms[i].
y * recipy;
   345     float krz = 2 * 
M_PI * localAtoms[i].
z * recipz;
   346     float cg = localAtoms[i].
cg;
   347     int atype = localPartitions[i];
   348     const int *grids = gridsForAtomType+atype*numAtomTypes;
   351     int slab = (int)floor((localAtoms[i].z - pressureProfileMin)/pressureProfileThickness);
   352     if (slab < 0) slab += nslabs;
   353     else if (slab >= nslabs) slab -= nslabs;
   354     float *pprofptr = pressureProfileData + 3*slab;
   365     for (j=1; j<= kymax; j++) {
   376     for (j=1; j<= kzmax; j++) {
   383     const float *Qkptr = Qk;
   385     const float *eikptr = eik;
   386     for (
int kx=0; kx <= kxmax; kx++) {
   387       for (
int ky=0; ky <= 2*kymax; ky++) {
   390         const int kzmax2 = 2*kzmax+1;
   391         const float exyr = exy.
r;
   392         const float exyi = exy.
i;
   393         const float *eikzptr = (
const float *)eikz;
   394 #pragma vector always   395         for (
int kz=0; kz < kzmax2; kz++) {
   396           float ezr = *eikzptr++;
   397           float ezi = *eikzptr++;
   398           float exyzr = ezr * exyr - ezi * exyi;
   399           float exyzi = ezr * exyi + ezi * exyr;
   405           for (
int igrid=0; igrid<numAtomTypes; igrid++) {
   406             float eikr = eikptr[igrid*2*ktot  ];
   407             float eiki = eikptr[igrid*2*ktot+1];
   408             int grid = grids[igrid];
   409             int offset = 3*nslabs*grid;
   411             float E = exyzr * eikr + exyzi * eiki;
   412             float vx = Qkptr[0] * E;
   413             float vy = Qkptr[1] * E;
   414             float vz = Qkptr[2] * E;
   415             pprofptr[offset  ] += vx;
   416             pprofptr[offset+1] += vy;
   417             pprofptr[offset+2] += vz;
 
static void init_exp(float *xp, int K, float recip, float kappa)
 
void recvData(ComputeEwaldMsg *)
 
void recvResults(ComputeEwaldMsg *)
 
int pressureProfileEwaldX
 
NAMD_HOST_DEVICE Vector c() const
 
static BigReal dielectric_1
 
static int * generateAtomTypeTable(int ntypes)
 
static PatchMap * Object()
 
virtual void submit(void)=0
 
SimParameters * simParameters
 
ComputeHomePatchList patchList
 
ComputeEwald(ComputeID, ComputeMgr *)
 
SubmitReduction * willSubmit(int setID, int size=-1)
 
ResizeArrayIter< T > begin(void) const
 
static ReductionMgr * Object(void)
 
void sendComputeEwaldData(ComputeEwaldMsg *)
 
NAMD_HOST_DEVICE BigReal volume(void) const
 
NAMD_HOST_DEVICE Vector a_r() const
 
NAMD_HOST_DEVICE Vector b_r() const
 
NAMD_HOST_DEVICE Vector c_r() const
 
int pressureProfileEwaldY
 
int pressureProfileAtomTypes
 
floatcomplex star() const
 
NAMD_HOST_DEVICE Vector wrap_delta(const Position &pos1) const
 
ResizeArrayIter< T > end(void) const
 
NAMD_HOST_DEVICE Vector origin() const
 
void sendComputeEwaldResults(ComputeEwaldMsg *)
 
int pressureProfileEwaldZ