Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ComputeFullDirect Class Reference

#include <ComputeFullDirect.h>

Inheritance diagram for ComputeFullDirect:

ComputeHomePatches Compute List of all members.

Public Member Functions

 ComputeFullDirect (ComputeID c)
virtual ~ComputeFullDirect ()
void doWork ()

Constructor & Destructor Documentation

ComputeFullDirect::ComputeFullDirect ComputeID  c  ) 
 

Definition at line 23 of file ComputeFullDirect.C.

References ReductionMgr::Object(), REDUCTIONS_BASIC, and ReductionMgr::willSubmit().

00023                                                 : ComputeHomePatches(c)
00024 {
00025   reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00026   useAvgPositions = 1;
00027 }

ComputeFullDirect::~ComputeFullDirect  )  [virtual]
 

Definition at line 29 of file ComputeFullDirect.C.

00030 {
00031   delete reduction;
00032 }


Member Function Documentation

void ComputeFullDirect::doWork  )  [virtual]
 

Reimplemented from Compute.

Definition at line 47 of file ComputeFullDirect.C.

References ResizeArrayIter< T >::begin(), BigReal, BUFSIZE, calc_fulldirect(), CompAtom::charge, DebugM, MOStream::end(), ResizeArrayIter< T >::end(), Results::f, Force, FULLFORCETAG, FULLTAG, MIStream::get(), SubmitReduction::item(), PatchMap::Object(), PEMOD, CompAtom::position, MOStream::put(), REDUCTION_ELECT_ENERGY_SLOW, SubmitReduction::submit(), Vector::x, Tensor::xx, Tensor::xy, Tensor::xz, Vector::y, Tensor::yx, Tensor::yy, Tensor::yz, Vector::z, Tensor::zx, Tensor::zy, and Tensor::zz.

00048 {
00049   int numLocalAtoms;
00050   BigReal *localData;
00051   BigReal *localResults;
00052   BigReal *newLocalResults;
00053   register BigReal *local_ptr;
00054   Lattice *lattice;
00055 
00056   int numWorkingPes = (PatchMap::Object())->numNodesWithPatches();
00057 
00058   ResizeArrayIter<PatchElem> ap(patchList);
00059 
00060   // Skip computations if nothing to do.
00061   if ( ! patchList[0].p->flags.doFullElectrostatics )
00062   {
00063     for (ap = ap.begin(); ap != ap.end(); ap++) {
00064       CompAtom *x = (*ap).positionBox->open();
00065       Results *r = (*ap).forceBox->open();
00066       (*ap).positionBox->close(&x);
00067       (*ap).forceBox->close(&r);
00068     }
00069     reduction->submit();
00070     return;
00071   }
00072 
00073   // allocate storage
00074   numLocalAtoms = 0;
00075   for (ap = ap.begin(); ap != ap.end(); ap++) {
00076     numLocalAtoms += (*ap).p->getNumAtoms();
00077   }
00078 
00079   localData = new BigReal[4*numLocalAtoms];     // freed at end of this method
00080   localResults = new BigReal[3*numLocalAtoms];  // freed at end of this method
00081   newLocalResults = new BigReal[3*numLocalAtoms];  // freed at end of this method
00082 
00083   lattice = &((*(ap.begin())).p->lattice);
00084 
00085   // get positions and charges
00086   local_ptr = localData;
00087   for (ap = ap.begin(); ap != ap.end(); ap++) {
00088     CompAtom *x = (*ap).positionBox->open();
00089     if ( patchList[0].p->flags.doMolly ) {
00090       (*ap).positionBox->close(&x);
00091       x = (*ap).avgPositionBox->open();
00092     }
00093     int numAtoms = (*ap).p->getNumAtoms();
00094 
00095     for(int i=0; i<numAtoms; ++i)
00096     {
00097       *(local_ptr++) = x[i].position.x;
00098       *(local_ptr++) = x[i].position.y;
00099       *(local_ptr++) = x[i].position.z;
00100       *(local_ptr++) = x[i].charge;
00101     }
00102 
00103     if ( patchList[0].p->flags.doMolly ) { (*ap).avgPositionBox->close(&x); }
00104     else { (*ap).positionBox->close(&x); }
00105   } 
00106 
00107   // zero out forces
00108   local_ptr = localResults;
00109   for(int j=0; j<numLocalAtoms; ++j)
00110   {
00111     *(local_ptr++) = 0.;
00112     *(local_ptr++) = 0.;
00113     *(local_ptr++) = 0.;
00114   }
00115 
00116   // perform calculations
00117   BigReal electEnergy = 0;
00118   Tensor virial;
00119 
00120 #define PEMOD(N) (((N)+numWorkingPes)%numWorkingPes)
00121 
00122   int numStages = numWorkingPes / 2 + 2;
00123   int lastStage = numStages - 2;
00124   int sendDataPE = PEMOD(CkMyPe()+1);
00125   int recvDataPE = PEMOD(CkMyPe()-1);
00126   int sendResultsPE = PEMOD(CkMyPe()-1);
00127   int recvResultsPE = PEMOD(CkMyPe()+1);
00128   int numRemoteAtoms = numLocalAtoms;
00129   int oldNumRemoteAtoms = 0;
00130   BigReal *remoteData = 0;
00131   BigReal *remoteResults = 0;
00132   register BigReal *remote_ptr;
00133   register BigReal *end_ptr;
00134 
00135   MOStream *sendDataMsg=CkpvAccess(comm)->
00136                 newOutputStream(sendDataPE, FULLTAG, BUFSIZE);
00137   MIStream *recvDataMsg=CkpvAccess(comm)->
00138                 newInputStream(recvDataPE, FULLTAG);
00139 
00140   for ( int stage = 0; stage < numStages; ++stage )
00141   {
00142     // send remoteResults to sendResultsPE
00143     if ( stage > 1 )
00144     {
00145       DebugM(4,"send remoteResults to sendResultsPE " << sendResultsPE << "\n");
00146       MOStream *msg=CkpvAccess(comm)->
00147                 newOutputStream(sendResultsPE, FULLFORCETAG, BUFSIZE);
00148       msg->put(3*oldNumRemoteAtoms,remoteResults);
00149       delete [] remoteResults;
00150       msg->end();
00151       delete msg;
00152       sendResultsPE = PEMOD(sendResultsPE-1);
00153     }
00154 
00155     // send remoteData to sendDataPE
00156     if ( stage < lastStage )
00157     {
00158       DebugM(4,"send remoteData to sendDataPE " << sendDataPE << "\n");
00159       sendDataMsg->put(numRemoteAtoms);
00160       sendDataMsg->put(4*numRemoteAtoms,(stage?remoteData:localData));
00161       sendDataMsg->end();
00162     }
00163 
00164     // allocate new result storage
00165     if ( stage > 0 && stage <= lastStage )
00166     {
00167       DebugM(4,"allocate new result storage\n");
00168       remoteResults = new BigReal[3*numRemoteAtoms];
00169       remote_ptr = remoteResults;
00170       end_ptr = remoteResults + 3*numRemoteAtoms;
00171       for ( ; remote_ptr != end_ptr; ++remote_ptr ) *remote_ptr = 0.;
00172     }
00173 
00174     // do calculation
00175     if ( stage == 0 )
00176     {  // self interaction
00177       DebugM(4,"self interaction\n");
00178       electEnergy += calc_fulldirect(
00179         localData,localResults,numLocalAtoms,
00180         localData,localResults,numLocalAtoms,1,lattice,virial);
00181     }
00182     else if ( stage < lastStage ||
00183             ( stage == lastStage && ( numWorkingPes % 2 ) ) )
00184     {  // full other interaction
00185       DebugM(4,"full other interaction\n");
00186       electEnergy += calc_fulldirect(
00187         localData,localResults,numLocalAtoms,
00188         remoteData,remoteResults,numRemoteAtoms,0,lattice,virial);
00189     }
00190     else if ( stage == lastStage )
00191     {  // half other interaction
00192       DebugM(4,"half other interaction\n");
00193       if ( CkMyPe() < ( numWorkingPes / 2 ) )
00194         electEnergy += calc_fulldirect(
00195           localData,localResults,numLocalAtoms/2,
00196           remoteData,remoteResults,numRemoteAtoms,0,lattice,virial);
00197       else
00198         electEnergy += calc_fulldirect(
00199           localData,localResults,numLocalAtoms,
00200           remoteData + 4*(numRemoteAtoms/2),
00201           remoteResults + 3*(numRemoteAtoms/2),
00202           numRemoteAtoms - (numRemoteAtoms/2), 0,lattice,virial);
00203     }
00204 
00205     delete [] remoteData;  remoteData = 0;
00206     oldNumRemoteAtoms = numRemoteAtoms;
00207 
00208     // receive newLocalResults from recvResultsPE
00209     if ( stage > 1 )
00210     {
00211       DebugM(4,"receive newLocalResults from recvResultsPE "
00212                                                 << recvResultsPE << "\n");
00213       MIStream *msg=CkpvAccess(comm)->
00214                 newInputStream(recvResultsPE, FULLFORCETAG);
00215       msg->get(3*numLocalAtoms,newLocalResults);
00216       delete msg;
00217       recvResultsPE = PEMOD(recvResultsPE+1);
00218       remote_ptr = newLocalResults;
00219       local_ptr = localResults;
00220       end_ptr = localResults + 3*numLocalAtoms;
00221       for ( ; local_ptr != end_ptr; ++local_ptr, ++remote_ptr )
00222         *local_ptr += *remote_ptr;
00223     }
00224 
00225     // receive remoteData from recvDataPE
00226     if ( stage < lastStage )
00227     {
00228       DebugM(4,"receive remoteData from recvDataPE "
00229                                                 << recvDataPE << "\n");
00230       recvDataMsg->get(numRemoteAtoms);
00231       remoteData = new BigReal[4*numRemoteAtoms];
00232       recvDataMsg->get(4*numRemoteAtoms,remoteData);
00233     }
00234 
00235   }
00236 
00237   delete sendDataMsg;
00238   delete recvDataMsg;
00239 
00240   // send out reductions
00241   DebugM(4,"Full-electrostatics energy: " << electEnergy << "\n");
00242   reduction->item(REDUCTION_ELECT_ENERGY_SLOW) += electEnergy;
00243   reduction->item(REDUCTION_VIRIAL_SLOW_XX) += virial.xx;
00244   reduction->item(REDUCTION_VIRIAL_SLOW_XY) += virial.xy;
00245   reduction->item(REDUCTION_VIRIAL_SLOW_XZ) += virial.xz;
00246   reduction->item(REDUCTION_VIRIAL_SLOW_YX) += virial.yx;
00247   reduction->item(REDUCTION_VIRIAL_SLOW_YY) += virial.yy;
00248   reduction->item(REDUCTION_VIRIAL_SLOW_YZ) += virial.yz;
00249   reduction->item(REDUCTION_VIRIAL_SLOW_ZX) += virial.zx;
00250   reduction->item(REDUCTION_VIRIAL_SLOW_ZY) += virial.zy;
00251   reduction->item(REDUCTION_VIRIAL_SLOW_ZZ) += virial.zz;
00252   reduction->submit();
00253 
00254   // add in forces
00255   local_ptr = localResults;
00256   for (ap = ap.begin(); ap != ap.end(); ap++) {
00257     Results *r = (*ap).forceBox->open();
00258     Force *f = r->f[Results::slow];
00259     int numAtoms = (*ap).p->getNumAtoms();
00260 
00261     for(int i=0; i<numAtoms; ++i)
00262     {
00263       f[i].x += *(local_ptr++);
00264       f[i].y += *(local_ptr++);
00265       f[i].z += *(local_ptr++);
00266     }
00267 
00268     (*ap).forceBox->close(&r);
00269   }
00270 
00271   // free storage
00272   delete [] localData;          // allocated at beginning of this method
00273   delete [] localResults;       // allocated at beginning of this method
00274   delete [] newLocalResults;    // allocated at beginning of this method
00275 }


The documentation for this class was generated from the following files:
Generated on Sat Sep 6 04:07:44 2008 for NAMD by  doxygen 1.3.9.1