void ComputeGridForce::doForce(FullAtom* p, Results* r) { SimParameters *simParams = Node::Object()->simParameters; Molecule *mol = Node::Object()->molecule; Force *forces = r->f[Results::normal]; BigReal energy = 0; Force extForce = 0.; Tensor extVirial; int numAtoms = homePatch->getNumAtoms(); if ( mol->numGridforceGrids < 1 ) NAMD_bug("No grids loaded in ComputeGridForce::doForce()"); for (int gridnum = 0; gridnum < mol->numGridforceGrids; gridnum++) { GridforceGrid *grid = mol->get_gridfrc_grid(gridnum); if (homePatch->flags.step % GF_OVERLAPCHECK_FREQ == 0) { // only check on node 0 and every GF_OVERLAPCHECK_FREQ steps if (simParams->langevinPistonOn || simParams->berendsenPressureOn) { // check for grid overlap if pressure control is on // not needed without pressure control, since the check is also performed on startup if (!grid->fits_lattice(homePatch->lattice)) { char errmsg[512]; if (simParams->gridforcechecksize) { sprintf(errmsg, "Warning: Periodic cell basis too small for Gridforce grid %d. Set gridforcechecksize off in configuration file to ignore.\n", gridnum); NAMD_die(errmsg); } } } } Position center = grid->get_center(); if (homePatch->flags.step % 100 == 1) { DebugM(3, "center = " << center << "\n" << endi); DebugM(3, "e = " << grid->get_e() << "\n" << endi); } if (grid->get_grid_type() == GridforceGrid::GridforceGridTypeFull) { GridforceFullMainGrid *g = (GridforceFullMainGrid *)grid; do_calc(g, gridnum, p, numAtoms, mol, forces, energy, extForce, extVirial); } else if (grid->get_grid_type() == GridforceGrid::GridforceGridTypeLite) { GridforceLiteGrid *g = (GridforceLiteGrid *)grid; do_calc(g, gridnum, p, numAtoms, mol, forces, energy, extForce, extVirial); } } reduction->item(REDUCTION_MISC_ENERGY) += energy; ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,extForce); ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,extVirial); reduction->submit(); }
void ComputeGlobal::recvResults(ComputeGlobalResultsMsg *msg) { DebugM(3,"Receiving results (" << msg->aid.size() << " forces, " << msg->newgdef.size() << " new group atoms) on client\n"); // set the forces only if we aren't going to resend the data int setForces = !msg->resendCoordinates; if(setForces) { // we are requested to // Store forces to patches PatchMap *patchMap = PatchMap::Object(); int numPatches = patchMap->numPatches(); AtomMap *atomMap = AtomMap::Object(); const Lattice & lattice = patchList[0].p->lattice; ResizeArrayIter<PatchElem> ap(patchList); Force **f = new Force*[numPatches]; FullAtom **t = new FullAtom*[numPatches]; for ( int i = 0; i < numPatches; ++i ) { f[i] = 0; t[i] = 0; } Force extForce = 0.; Tensor extVirial; for (ap = ap.begin(); ap != ap.end(); ap++) { (*ap).r = (*ap).forceBox->open(); f[(*ap).patchID] = (*ap).r->f[Results::normal]; t[(*ap).patchID] = (*ap).p->getAtomList().begin(); } AtomIDList::iterator a = msg->aid.begin(); AtomIDList::iterator a_e = msg->aid.end(); ForceList::iterator f2 = msg->f.begin(); for ( ; a != a_e; ++a, ++f2 ) { DebugM(1,"processing atom "<<(*a)<<", F="<<(*f2)<<"...\n"); /* XXX if (*a) is out of bounds here we get a segfault */ LocalID localID = atomMap->localID(*a); if ( localID.pid == notUsed || ! f[localID.pid] ) continue; Force f_atom = (*f2); f[localID.pid][localID.index] += f_atom; Position x_orig = t[localID.pid][localID.index].position; Transform trans = t[localID.pid][localID.index].transform; Position x_atom = lattice.reverse_transform(x_orig,trans); extForce += f_atom; extVirial += outer(f_atom,x_atom); } DebugM(1,"done with the loop\n"); // calculate forces for atoms in groups Molecule *mol = Node::Object()->molecule; AtomIDList::iterator g_i, g_e; g_i = gdef.begin(); g_e = gdef.end(); ResizeArray<BigReal>::iterator gm_i = gmass.begin(); ForceList::iterator gf_i = msg->gforce.begin(); //iout << iDEBUG << "recvResults\n" << endi; for ( ; g_i != g_e; ++g_i, ++gm_i, ++gf_i ) { //iout << iDEBUG << *gf_i << '\n' << endi; Vector accel = (*gf_i) / (*gm_i); for ( ; *g_i != -1; ++g_i ) { //iout << iDEBUG << *g_i << '\n' << endi; LocalID localID = atomMap->localID(*g_i); if ( localID.pid == notUsed || ! f[localID.pid] ) continue; Force f_atom = accel * mol->atommass(*g_i); f[localID.pid][localID.index] += f_atom; Position x_orig = t[localID.pid][localID.index].position; Transform trans = t[localID.pid][localID.index].transform; Position x_atom = lattice.reverse_transform(x_orig,trans); extForce += f_atom; extVirial += outer(f_atom,x_atom); } } DebugM(1,"done with the groups\n"); for (ap = ap.begin(); ap != ap.end(); ap++) { (*ap).forceBox->close(&((*ap).r)); } delete [] f; delete [] t; ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,extForce); ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,extVirial); reduction->submit(); } // done setting the forces // Get reconfiguration if present if ( msg->reconfig ) configure(msg->newaid, msg->newgdef); // send another round of data if requested if(msg->resendCoordinates) { DebugM(3,"Sending requested data right away\n"); sendData(); } delete msg; DebugM(3,"Done processing results\n"); }