ComputeFmmSerialMgr Class Reference

List of all members.

Public Member Functions

 ComputeFmmSerialMgr ()
 ~ComputeFmmSerialMgr ()
void setCompute (ComputeFmmSerial *c)
void recvCoord (FmmSerialCoordMsg *)
void recvForce (FmmSerialForceMsg *)

Detailed Description

Definition at line 77 of file ComputeFmmSerial.C.


Constructor & Destructor Documentation

ComputeFmmSerialMgr::ComputeFmmSerialMgr (  ) 

Definition at line 109 of file ComputeFmmSerial.C.

00109                                          :
00110   fmmProxy(thisgroup), fmmCompute(0), numSources(0), numArrived(0),
00111   coordMsgs(0), coord(0), force(0), oldmsg(0), numAtoms(0),
00112   fmmsolver(0), nlevels(0), scaling(0), center(0),
00113   chargebuffer(0), epotbuffer(0), posbuffer(0), forcebuffer(0)
00114 {
00115   CkpvAccess(BOCclass_group).computeFmmSerialMgr = thisgroup;
00116 }

ComputeFmmSerialMgr::~ComputeFmmSerialMgr (  ) 

Definition at line 118 of file ComputeFmmSerial.C.

00119 {
00120   for (int i=0;  i < numSources;  i++)  delete coordMsgs[i];
00121   delete [] coordMsgs;
00122   delete [] coord;
00123   delete [] force;
00124   delete oldmsg;
00125   if (chargebuffer) delete[] chargebuffer;
00126   if (epotbuffer)   delete[] epotbuffer;
00127   if (posbuffer)    delete[] posbuffer;
00128   if (forcebuffer)  delete[] forcebuffer;
00129 }


Member Function Documentation

void ComputeFmmSerialMgr::recvCoord ( FmmSerialCoordMsg  ) 

Definition at line 200 of file ComputeFmmSerial.C.

References Lattice::a_p(), Lattice::b_p(), Lattice::c_p(), FmmSerialCoordMsg::coord, COULOMB, endi(), FmmSerialForceMsg::energy, FmmSerialForceMsg::force, ComputeFmmSerialAtom::id, if(), iINFO(), iout, j, FmmSerialCoordMsg::lattice, Node::molecule, NAMD_die(), FmmSerialCoordMsg::numAtoms, Molecule::numAtoms, Node::Object(), PatchMap::Object(), ComputeFmmSerialAtom::position, Node::simParameters, simParams, FmmSerialForceMsg::virial, Vector::x, Vector::y, and Vector::z.

00200                                                           {
00201   int i;
00202   if ( ! numSources ) {
00203     numSources = (PatchMap::Object())->numNodesWithPatches();
00204     coordMsgs = new FmmSerialCoordMsg*[numSources];
00205     for ( i=0; i<numSources; ++i ) { coordMsgs[i] = 0; }
00206     numArrived = 0;
00207     numAtoms = Node::Object()->molecule->numAtoms;
00208     coord = new ComputeFmmSerialAtom[numAtoms];
00209     force = new FmmSerialForce[numAtoms];
00210   }
00211 
00212   for ( i=0; i < msg->numAtoms; ++i ) {
00213     coord[msg->coord[i].id] = msg->coord[i];
00214   }
00215 
00216   coordMsgs[numArrived] = msg;
00217   ++numArrived;
00218 
00219   if ( numArrived < numSources ) return;
00220   numArrived = 0;
00221 
00222   // ALL DATA ARRIVED --- CALCULATE FORCES
00223   Lattice lattice = msg->lattice;
00224   SimParameters *simParams = Node::Object()->simParameters;
00225 
00226   double energy = 0;
00227   double virial[3][3] = { 0 };  // FMM does not calculate virial
00228 
00229   int rc = 0;  // return code
00230 
00231   if ( ! fmmsolver ) {
00232     //
00233     // setup FMM solver
00234     //
00235 
00236     // check boundary conditions
00237     if (lattice.a_p() || lattice.b_p() || lattice.c_p()) {
00238       NAMD_die("FMM solver requires non-periodic boundaries");
00239     }
00240 
00241     // setup number of levels
00242     if (simParams->FMMLevels > 0) {
00243       // explicitly set in config file
00244       nlevels = simParams->FMMLevels;
00245     }
00246     else {
00247       // otherwise estimate number of levels as round(log_8(numAtoms))
00248       nlevels = (int) floor(log((double)numAtoms) / log(8.) + 0.5);
00249     }
00250 
00251     // find bounding cube length
00252     if (numAtoms <= 0) {
00253       NAMD_die("setting up FMM with no atoms");
00254     }
00255     Vector min, max;
00256     min = max = coord[0].position;
00257     for (i = 1;  i < numAtoms;  i++) {
00258       Vector r = coord[i].position;
00259       if      (r.x < min.x)  min.x = r.x;
00260       else if (r.x > max.x)  max.x = r.x;
00261       if      (r.y < min.y)  min.y = r.y;
00262       else if (r.y > max.y)  max.y = r.y;
00263       if      (r.z < min.z)  min.z = r.z;
00264       else if (r.z > max.z)  max.z = r.z;
00265     }
00266     double padding = simParams->FMMPadding;
00267     if (padding <= 0) padding = 0.01;  // pad by at least a delta margin
00268     min -= padding;
00269     max += padding;
00270     double len = max.x - min.x;
00271     if (len < max.y - min.y)  len = max.y - min.y;
00272     if (len < max.z - min.z)  len = max.z - min.z;
00273     scaling = 1.0 / len;  // scale coordinates by length of the cube
00274     center = 0.5*(min + max);  // center of cube
00275     iout << iINFO << "FMM scaling length set to " << len << " A\n" << endi;
00276     iout << iINFO << "FMM center set to " << center << "\n" << endi;
00277 
00278     // allocate buffer space
00279     chargebuffer = new double[numAtoms];     // double *
00280     epotbuffer   = new double[numAtoms];     // double *
00281     posbuffer    = new double[numAtoms][3];  // double(*)[3]
00282     forcebuffer  = new double[numAtoms][3];  // double(*)[3]
00283     if (chargebuffer == 0 || epotbuffer == 0 ||
00284         posbuffer == 0 || forcebuffer == 0) {
00285       NAMD_die("can't allocate buffer space for FMM data");
00286     }
00287 
00288     // scale the charges - these won't change
00289     double celec = sqrt(COULOMB / simParams->dielectric);
00290     for (i = 0;  i < numAtoms;  i++) {
00291       chargebuffer[i] = celec * coord[i].charge;
00292     }
00293     fmmsolver = 1;  // is setup
00294   }
00295 
00296   // translate and scale positions into [-1/2,1/2]^3
00297   for (i = 0;  i < numAtoms;  i++) {
00298     posbuffer[i][0] = scaling*(coord[i].position.x - center.x);
00299     posbuffer[i][1] = scaling*(coord[i].position.y - center.y);
00300     posbuffer[i][2] = scaling*(coord[i].position.z - center.z);
00301   }
00302 
00303   // call the FMM solver
00304   int errcode = 0;
00305 #ifdef FMM_SOLVER
00306   fmmlap_uni_(&numAtoms, posbuffer, chargebuffer, epotbuffer, forcebuffer,
00307       &nlevels, &errcode);
00308 #else
00309   NAMD_die("Must link to FMM library to use FMM\n");
00310 #endif
00311 
00312   // scale force and potentials
00313   for (i = 0;  i < numAtoms;  i++) {
00314     double qs = chargebuffer[i] * scaling;
00315     force[i].x = qs * scaling * forcebuffer[i][0];
00316     force[i].y = qs * scaling * forcebuffer[i][1];
00317     force[i].z = qs * scaling * forcebuffer[i][2];
00318     energy += qs * epotbuffer[i];
00319   }
00320   energy *= 0.5;
00321 
00322   // distribute forces
00323   for (int j=0;  j < numSources;  j++) {
00324     FmmSerialCoordMsg *cmsg = coordMsgs[j];
00325     coordMsgs[j] = 0;
00326     FmmSerialForceMsg *fmsg = new (cmsg->numAtoms, 0) FmmSerialForceMsg;
00327 
00328     for (int i=0;  i < cmsg->numAtoms;  i++) {
00329       fmsg->force[i] = force[cmsg->coord[i].id];
00330     }
00331 
00332     if ( ! j ) {  // set virial and energy only for first message
00333       fmsg->energy = energy;
00334       for (int k=0;  k < 3;  k++) {
00335         for (int l=0;  l < 3;  l++) {
00336           fmsg->virial[k][l] = virial[k][l];
00337         }
00338       }
00339     }
00340     else {  // set other messages to zero, add into reduction only once
00341       fmsg->energy = 0;
00342       for (int k=0;  k < 3;  k++) {
00343         for (int l=0;  l < 3;  l++) {
00344           fmsg->virial[k][l] = 0;
00345         }
00346       }
00347     }
00348 
00349     fmmProxy[cmsg->sourceNode].recvForce(fmsg);
00350     delete cmsg;
00351   }
00352 }

void ComputeFmmSerialMgr::recvForce ( FmmSerialForceMsg  ) 

Definition at line 354 of file ComputeFmmSerial.C.

References ComputeFmmSerial::saveResults().

00354                                                           {
00355   fmmCompute->saveResults(msg);
00356   delete oldmsg;
00357   oldmsg = msg;
00358 }

void ComputeFmmSerialMgr::setCompute ( ComputeFmmSerial c  )  [inline]

Definition at line 82 of file ComputeFmmSerial.C.

00082 { fmmCompute = c; }


The documentation for this class was generated from the following file:
Generated on Tue Nov 21 01:17:17 2017 for NAMD by  doxygen 1.4.7