60 if ( numWorkingPes > 1 )
NAMD_die(
"FullDirect not supported for parallel runs.");
65 if ( !
patchList[0].p->flags.doFullElectrostatics )
67 for (ap = ap.begin(); ap != ap.end(); ap++) {
68 CompAtom *x = (*ap).positionBox->open();
69 Results *r = (*ap).forceBox->open();
70 (*ap).positionBox->close(&x);
71 (*ap).forceBox->close(&r);
79 for (ap = ap.begin(); ap != ap.end(); ap++) {
80 numLocalAtoms += (*ap).p->getNumAtoms();
83 localData =
new BigReal[4*numLocalAtoms];
84 localResults =
new BigReal[3*numLocalAtoms];
85 newLocalResults =
new BigReal[3*numLocalAtoms];
87 lattice = &((*(ap.begin())).p->lattice);
90 local_ptr = localData;
91 for (ap = ap.begin(); ap != ap.end(); ap++) {
92 CompAtom *x = (*ap).positionBox->open();
94 (*ap).positionBox->close(&x);
95 x = (*ap).avgPositionBox->open();
97 int numAtoms = (*ap).p->getNumAtoms();
99 for(
int i=0; i<numAtoms; ++i)
101 *(local_ptr++) = x[i].position.x;
103 *(local_ptr++) = x[i].position.z;
104 *(local_ptr++) = x[i].
charge;
107 if (
patchList[0].p->flags.doMolly ) { (*ap).avgPositionBox->close(&x); }
108 else { (*ap).positionBox->close(&x); }
112 local_ptr = localResults;
113 for(
int j=0; j<numLocalAtoms; ++j)
124 #define PEMOD(N) (((N)+numWorkingPes)%numWorkingPes) 126 int numStages = numWorkingPes / 2 + 2;
127 int lastStage = numStages - 2;
128 int sendDataPE =
PEMOD(CkMyPe()+1);
129 int recvDataPE =
PEMOD(CkMyPe()-1);
130 int sendResultsPE =
PEMOD(CkMyPe()-1);
131 int recvResultsPE =
PEMOD(CkMyPe()+1);
132 int numRemoteAtoms = numLocalAtoms;
133 int oldNumRemoteAtoms = 0;
139 MOStream *sendDataMsg=CkpvAccess(comm)->
141 MIStream *recvDataMsg=CkpvAccess(comm)->
142 newInputStream(recvDataPE,
FULLTAG);
144 for (
int stage = 0; stage < numStages; ++stage )
149 DebugM(4,
"send remoteResults to sendResultsPE " << sendResultsPE <<
"\n");
152 msg->
put(3*oldNumRemoteAtoms,remoteResults);
153 delete [] remoteResults;
156 sendResultsPE =
PEMOD(sendResultsPE-1);
160 if ( stage < lastStage )
162 DebugM(4,
"send remoteData to sendDataPE " << sendDataPE <<
"\n");
163 sendDataMsg->
put(numRemoteAtoms);
164 sendDataMsg->
put(4*numRemoteAtoms,(stage?remoteData:localData));
169 if ( stage > 0 && stage <= lastStage )
171 DebugM(4,
"allocate new result storage\n");
172 remoteResults =
new BigReal[3*numRemoteAtoms];
173 remote_ptr = remoteResults;
174 end_ptr = remoteResults + 3*numRemoteAtoms;
175 for ( ; remote_ptr != end_ptr; ++remote_ptr ) *remote_ptr = 0.;
181 DebugM(4,
"self interaction\n");
183 localData,localResults,numLocalAtoms,
184 localData,localResults,numLocalAtoms,1,lattice,virial);
186 else if ( stage < lastStage ||
187 ( stage == lastStage && ( numWorkingPes % 2 ) ) )
189 DebugM(4,
"full other interaction\n");
191 localData,localResults,numLocalAtoms,
192 remoteData,remoteResults,numRemoteAtoms,0,lattice,virial);
194 else if ( stage == lastStage )
196 DebugM(4,
"half other interaction\n");
197 if ( CkMyPe() < ( numWorkingPes / 2 ) )
199 localData,localResults,numLocalAtoms/2,
200 remoteData,remoteResults,numRemoteAtoms,0,lattice,virial);
203 localData,localResults,numLocalAtoms,
204 remoteData + 4*(numRemoteAtoms/2),
205 remoteResults + 3*(numRemoteAtoms/2),
206 numRemoteAtoms - (numRemoteAtoms/2), 0,lattice,virial);
209 delete [] remoteData; remoteData = 0;
210 oldNumRemoteAtoms = numRemoteAtoms;
215 DebugM(4,
"receive newLocalResults from recvResultsPE " 216 << recvResultsPE <<
"\n");
219 msg->
get(3*numLocalAtoms,newLocalResults);
221 recvResultsPE =
PEMOD(recvResultsPE+1);
222 remote_ptr = newLocalResults;
223 local_ptr = localResults;
224 end_ptr = localResults + 3*numLocalAtoms;
225 for ( ; local_ptr != end_ptr; ++local_ptr, ++remote_ptr )
226 *local_ptr += *remote_ptr;
230 if ( stage < lastStage )
232 DebugM(4,
"receive remoteData from recvDataPE " 233 << recvDataPE <<
"\n");
234 recvDataMsg->
get(numRemoteAtoms);
235 remoteData =
new BigReal[4*numRemoteAtoms];
236 recvDataMsg->
get(4*numRemoteAtoms,remoteData);
247 reduction->
item(REDUCTION_VIRIAL_SLOW_XX) += virial.
xx;
248 reduction->
item(REDUCTION_VIRIAL_SLOW_XY) += virial.
xy;
249 reduction->
item(REDUCTION_VIRIAL_SLOW_XZ) += virial.
xz;
250 reduction->
item(REDUCTION_VIRIAL_SLOW_YX) += virial.
yx;
251 reduction->
item(REDUCTION_VIRIAL_SLOW_YY) += virial.
yy;
252 reduction->
item(REDUCTION_VIRIAL_SLOW_YZ) += virial.
yz;
253 reduction->
item(REDUCTION_VIRIAL_SLOW_ZX) += virial.
zx;
254 reduction->
item(REDUCTION_VIRIAL_SLOW_ZY) += virial.
zy;
255 reduction->
item(REDUCTION_VIRIAL_SLOW_ZZ) += virial.
zz;
259 local_ptr = localResults;
260 for (ap = ap.begin(); ap != ap.end(); ap++) {
261 Results *r = (*ap).forceBox->open();
263 int numAtoms = (*ap).p->getNumAtoms();
265 for(
int i=0; i<numAtoms; ++i)
267 f[i].
x += *(local_ptr++);
268 f[i].
y += *(local_ptr++);
269 f[i].
z += *(local_ptr++);
272 (*ap).forceBox->close(&r);
277 delete [] localResults;
278 delete [] newLocalResults;
static PatchMap * Object()
ComputeHomePatchList patchList
register BigReal electEnergy
MIStream * get(char &data)
void NAMD_die(const char *err_msg)
BigReal calc_fulldirect(BigReal *data1, BigReal *results1, int n1, BigReal *data2, BigReal *results2, int n2, int selfmode, Lattice *lattice, Tensor &virial)
MOStream * put(char data)