#include <ComputeFullDirect.h>
Inheritance diagram for ComputeFullDirect:

Public Member Functions | |
| ComputeFullDirect (ComputeID c) | |
| virtual | ~ComputeFullDirect () |
| void | doWork () |
|
|
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 }
|
|
|
Definition at line 29 of file ComputeFullDirect.C. 00030 {
00031 delete reduction;
00032 }
|
|
|
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 }
|
1.3.9.1