20 #include "ComputeMgr.decl.h"
22 #define MIN_DEBUG_LEVEL 3
28 class ComputeDPMEMaster {
30 friend class ComputeDPME;
32 ComputeDPMEMaster(ComputeDPME *);
47 DebugM(4,
"ComputeDPME created.\n");
52 masterNode = numWorkingPes - 1;
53 if ( CkMyPe() == masterNode ) {
54 master =
new ComputeDPMEMaster(
this);
55 master->numWorkingPes = numWorkingPes;
60 ComputeDPME::~ComputeDPME()
68 extern int cfftf(
int *,
double *,
double *);
69 extern int cfftb(
int *,
double *,
double *);
70 extern int cffti1(
int *,
double *,
int *);
71 extern int cfftf1(
int *n,
double *c,
double *ch,
double *wa,
int *ifac);
72 extern int cfftb1(
int *n,
double *c,
double *ch,
double *wa,
int *ifac);
77 return cfftf(n, (
double *)c, wsave);
82 return cfftb(n, (
double *)c, wsave);
85 int cffti1(
int *n,
double *wa,
double *ifac) {
87 return cffti1(n, wa, (
int *)ifac);
90 int cfftf1(
int *n,
double *c,
double *ch,
double *wa,
double *ifac) {
92 return cfftf1(n, c, ch, wa, (
int *)ifac);
95 int cfftb1(
int *n,
double *c,
double *ch,
double *wa,
double *ifac) {
97 return cfftb1(n, c, ch, wa, (
int *)ifac);
100 void ComputeDPME::doWork()
102 DebugM(4,
"Entering ComputeDPME::doWork().\n");
109 if ( ! patchList[0].p->flags.doFullElectrostatics )
111 for (ap = ap.begin(); ap != ap.end(); ap++) {
113 Results *r = (*ap).forceBox->open();
114 (*ap).positionBox->close(&x);
115 (*ap).forceBox->close(&r);
118 master->reduction->submit();
125 for (ap = ap.begin(); ap != ap.end(); ap++) {
126 numLocalAtoms += (*ap).p->getNumAtoms();
129 Lattice lattice = patchList[0].p->flags.lattice;
137 for (ap = ap.begin(); ap != ap.end(); ap++) {
138 CompAtom *x = (*ap).positionBox->open();
139 if ( patchList[0].p->flags.doMolly ) {
140 (*ap).positionBox->close(&x);
141 x = (*ap).avgPositionBox->open();
143 int numAtoms = (*ap).p->getNumAtoms();
145 for(
int i=0; i<numAtoms; ++i)
151 data_ptr->cg = coulomb_sqrt * x[i].
charge;
152 data_ptr->id = x[i].id;
156 if ( patchList[0].p->flags.doMolly ) { (*ap).avgPositionBox->close(&x); }
157 else { (*ap).positionBox->close(&x); }
162 msg->
node = CkMyPe();
165 comm->sendComputeDPMEData(msg);
171 master->recvData(msg);
173 else NAMD_die(
"ComputeDPME::master is NULL!");
176 ComputeDPMEMaster::ComputeDPMEMaster(ComputeDPME *h) :
177 host(h), numLocalAtoms(0), runcount(0)
184 ComputeDPMEMaster::~ComputeDPMEMaster()
193 <<
" particles from node " << msg->
node <<
"\n");
196 homeNode.add(msg->
node);
198 for (
int j = 0; j < msg->
numParticles; ++j, ++data_ptr ) {
202 endForNode.add(numLocalAtoms);
206 if ( homeNode.size() < numWorkingPes )
return;
208 DebugM(4,
"ComputeDPMEMaster::recvData() running serial code.\n");
212 Lattice lattice = host->getFlags()->lattice;
217 atom_info.numatoms = numLocalAtoms;
218 atom_info.atompnt = 0;
219 atom_info.freepnt = 0;
220 atom_info.nlocal = numLocalAtoms;
221 atom_info.nother = 0;
224 NAMD_die(
"DPME only supports orthogonal PBC's.");
228 box_info.box.x = lattice.
a().
x;
229 box_info.box.y = lattice.
b().
y;
230 box_info.box.z = lattice.
c().
z;
231 box_info.box.origin = 0.;
232 box_info.prd.x = box_info.box.x;
233 box_info.prd.y = box_info.box.y;
234 box_info.prd.z = box_info.box.z;
235 box_info.prd2.x = 0.5 * box_info.box.x;
236 box_info.prd2.y = 0.5 * box_info.box.y;
237 box_info.prd2.z = 0.5 * box_info.box.z;
238 box_info.cutoff = simParams->
cutoff;
239 box_info.rs = simParams->
cutoff;
240 box_info.mc2.x = 2. * ( box_info.prd.x - box_info.cutoff );
241 box_info.mc2.y = 2. * ( box_info.prd.y - box_info.cutoff );
242 box_info.mc2.z = 2. * ( box_info.prd.z - box_info.cutoff );
245 for (i = 0; i <= 8; i++) {
246 box_info.recip[i] = 0.;
248 box_info.recip[0] = 1.0/box_info.box.x;
249 box_info.recip[4] = 1.0/box_info.box.y;
250 box_info.recip[8] = 1.0/box_info.box.z;
258 grid_info.volume = lattice.
volume();
261 pe_info.myproc.node = 0;
262 pe_info.myproc.nprocs = 1;
263 pe_info.myproc.ncube = 0;
264 pe_info.inst_node[0] = 0;
278 for(i=0; i<numLocalAtoms; ++i)
280 electEnergy += data_ptr->cg * data_ptr->cg;
283 electEnergy *= -1. * box_info.ewaldcof /
SQRT_PI;
285 DebugM(4,
"Ewald self energy: " << electEnergy <<
"\n");
287 DebugM(4,
"Calling dpme_eval_recip().\n");
289 double pme_start_time = 0;
290 if ( runcount == 1 ) pme_start_time = CmiTimer();
292 electEnergy += dpme_eval_recip( atom_info, localData - 1, &localResults,
293 recip_vir, grid_info, box_info, pe_info,
294 time_count, tsteps, &mytime );
296 if ( runcount == 1 ) {
297 iout <<
iINFO <<
"PME reciprocal sum CPU time per evaluation: "
298 << (CmiTimer() - pme_start_time) <<
"\n" <<
endi;
301 DebugM(4,
"Returned from dpme_eval_recip().\n");
304 for(i=0; i<6; ++i) recip_vir[i] *= -1.;
307 DebugM(4,
"Timestep : " << host->getFlags()->step <<
"\n");
308 DebugM(4,
"Reciprocal sum energy: " << electEnergy <<
"\n");
309 DebugM(4,
"Reciprocal sum virial: " << recip_vir[0] <<
" " <<
310 recip_vir[1] <<
" " << recip_vir[2] <<
" " << recip_vir[3] <<
" " <<
311 recip_vir[4] <<
" " << recip_vir[5] <<
"\n");
313 reduction->item(REDUCTION_VIRIAL_SLOW_XX) += (
BigReal)(recip_vir[0]);
314 reduction->item(REDUCTION_VIRIAL_SLOW_XY) += (
BigReal)(recip_vir[1]);
315 reduction->item(REDUCTION_VIRIAL_SLOW_XZ) += (
BigReal)(recip_vir[2]);
316 reduction->item(REDUCTION_VIRIAL_SLOW_YX) += (
BigReal)(recip_vir[1]);
317 reduction->item(REDUCTION_VIRIAL_SLOW_YY) += (
BigReal)(recip_vir[3]);
318 reduction->item(REDUCTION_VIRIAL_SLOW_YZ) += (
BigReal)(recip_vir[4]);
319 reduction->item(REDUCTION_VIRIAL_SLOW_ZX) += (
BigReal)(recip_vir[2]);
320 reduction->item(REDUCTION_VIRIAL_SLOW_ZY) += (
BigReal)(recip_vir[4]);
321 reduction->item(REDUCTION_VIRIAL_SLOW_ZZ) += (
BigReal)(recip_vir[5]);
324 PmeVector *results_ptr = localResults + 1;
327 for ( i = 0; i < homeNode.size(); ++i ) {
329 msg->
node = homeNode[i];
332 for (
int j = 0; j < msg->
numParticles; ++j, ++results_ptr ) {
333 msg->
forces[j] = *results_ptr;
335 numLocalAtoms = endForNode[i];
336 host->comm->sendComputeDPMEResults(msg,homeNode[i]);
343 endForNode.resize(0);
349 if ( CkMyPe() != msg->
node ) {
350 NAMD_die(
"ComputeDPME results sent to wrong node!\n");
354 NAMD_die(
"ComputeDPME sent wrong number of results!\n");
362 for (ap = ap.begin(); ap != ap.end(); ap++) {
363 Results *r = (*ap).forceBox->open();
365 int numAtoms = (*ap).p->getNumAtoms();
367 for(
int i=0; i<numAtoms; ++i)
369 f[i].
x += results_ptr->x;
370 f[i].
y += results_ptr->y;
371 f[i].
z += results_ptr->z;
375 (*ap).forceBox->close(&r);
std::ostream & iINFO(std::ostream &s)
static BigReal dielectric_1
int cfftb(int *n, double *c, double *wsave)
static PatchMap * Object()
SimParameters * simParameters
register BigReal electEnergy
std::ostream & endi(std::ostream &s)
SubmitReduction * willSubmit(int setID, int size=-1)
static ReductionMgr * Object(void)
int cfftf1(int *n, double *c, double *ch, double *wa, int *ifac)
void recvData(DataMessage *dmsg)
int cffti1(int *n, double *wa, int *ifac)
int cfftf(int *n, double *c, double *wsave)
Vector delta(const Position &pos1, const Position &pos2) const
int cfftb1(int *n, double *c, double *ch, double *wa, int *ifac)
void NAMD_die(const char *err_msg)
BigReal volume(void) const