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

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