00001
00007
00008
00009
00010
00011 #include "InfoStream.h"
00012 #include "Node.h"
00013 #include "PatchMap.h"
00014 #include "PatchMap.inl"
00015 #include "AtomMap.h"
00016 #include "ComputeGlobal.h"
00017 #include "ComputeGlobalMsgs.h"
00018 #include "PatchMgr.h"
00019 #include "Molecule.h"
00020 #include "ReductionMgr.h"
00021 #include "ComputeMgr.h"
00022 #include "ComputeMgr.decl.h"
00023 #include "SimParameters.h"
00024 #include <stdio.h>
00025
00026
00027 #define MIN_DEBUG_LEVEL 1
00028 #include "Debug.h"
00029
00030
00031
00032 ComputeGlobal::ComputeGlobal(ComputeID c, ComputeMgr *m)
00033 : ComputeHomePatches(c)
00034 {
00035 DebugM(3,"Constructing client\n");
00036 aid.resize(0);
00037 gdef.resize(0);
00038 comm = m;
00039 firsttime = 1;
00040 int i, numAtoms=Node::Object()->molecule->numAtoms;
00041 isRequested = new int[numAtoms];
00042 for (i=0; i<numAtoms; ++i)
00043 isRequested[i] = 0;
00044 SimParameters *sp = Node::Object()->simParameters;
00045 dofull = (sp->fullDirectOn || sp->FMAOn || sp->PMEOn);
00046 fid = new AtomIDList;
00047 totalForce = new ForceList;
00048 reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00049 }
00050
00051 ComputeGlobal::~ComputeGlobal()
00052 {
00053 delete[] isRequested;
00054 delete fid;
00055 delete totalForce;
00056 delete reduction;
00057 }
00058
00059 void ComputeGlobal::configure(AtomIDList newaid, AtomIDList newgdef) {
00060 DebugM(4,"Receiving configuration (" << newaid.size() <<
00061 " atoms and " << newgdef.size() << " atoms/groups) on client\n");
00062
00063 AtomIDList::iterator a, a_e;
00064
00065 for (a=aid.begin(),a_e=aid.end(); a!=a_e; ++a)
00066 isRequested[*a] = 0;
00067
00068
00069 aid = newaid;
00070 gdef = newgdef;
00071
00072 for (a=aid.begin(),a_e=aid.end(); a!=a_e; ++a)
00073 isRequested[*a] = 1;
00074
00075
00076 Molecule *mol = Node::Object()->molecule;
00077 gmass.resize(0);
00078 AtomIDList::iterator g_i, g_e;
00079 g_i = gdef.begin(); g_e = gdef.end();
00080 for ( ; g_i != g_e; ++g_i ) {
00081 BigReal mass = 0;
00082 for ( ; *g_i != -1; ++g_i ) {
00083 mass += mol->atommass(*g_i);
00084 }
00085 gmass.add(mass);
00086 }
00087 }
00088
00089 void ComputeGlobal::recvConfig(ComputeGlobalConfigMsg *msg) {
00090 DebugM(3,"Receiving configure on client\n");
00091 configure(msg->aid,msg->gdef);
00092 delete msg;
00093 sendData();
00094 }
00095
00096 void ComputeGlobal::recvResults(ComputeGlobalResultsMsg *msg) {
00097 DebugM(3,"Receiving results (" << msg->aid.size() << " forces, "
00098 << msg->newgdef.size() << " new group atoms) on client\n");
00099
00100
00101 int setForces = !msg->resendCoordinates;
00102
00103 if(setForces) {
00104
00105 PatchMap *patchMap = PatchMap::Object();
00106 int numPatches = patchMap->numPatches();
00107 AtomMap *atomMap = AtomMap::Object();
00108 const Lattice & lattice = patchList[0].p->lattice;
00109 ResizeArrayIter<PatchElem> ap(patchList);
00110 Force **f = new Force*[numPatches];
00111 FullAtom **t = new FullAtom*[numPatches];
00112 for ( int i = 0; i < numPatches; ++i ) { f[i] = 0; t[i] = 0; }
00113 Force extForce = 0.;
00114 Tensor extVirial;
00115
00116 for (ap = ap.begin(); ap != ap.end(); ap++) {
00117 (*ap).r = (*ap).forceBox->open();
00118 f[(*ap).patchID] = (*ap).r->f[Results::normal];
00119 t[(*ap).patchID] = (*ap).p->getAtomList().begin();
00120 }
00121
00122 AtomIDList::iterator a = msg->aid.begin();
00123 AtomIDList::iterator a_e = msg->aid.end();
00124 ForceList::iterator f2 = msg->f.begin();
00125 for ( ; a != a_e; ++a, ++f2 ) {
00126 DebugM(1,"processing atom "<<(*a)<<", F="<<(*f2)<<"...\n");
00127
00128 LocalID localID = atomMap->localID(*a);
00129 if ( localID.pid == notUsed || ! f[localID.pid] ) continue;
00130 Force f_atom = (*f2);
00131 f[localID.pid][localID.index] += f_atom;
00132 Position x_orig = t[localID.pid][localID.index].position;
00133 Transform trans = t[localID.pid][localID.index].transform;
00134 Position x_atom = lattice.reverse_transform(x_orig,trans);
00135 extForce += f_atom;
00136 extVirial += outer(f_atom,x_atom);
00137 }
00138 DebugM(1,"done with the loop\n");
00139
00140
00141 Molecule *mol = Node::Object()->molecule;
00142 AtomIDList::iterator g_i, g_e;
00143 g_i = gdef.begin(); g_e = gdef.end();
00144 ResizeArray<BigReal>::iterator gm_i = gmass.begin();
00145 ForceList::iterator gf_i = msg->gforce.begin();
00146
00147 for ( ; g_i != g_e; ++g_i, ++gm_i, ++gf_i ) {
00148
00149 Vector accel = (*gf_i) / (*gm_i);
00150 for ( ; *g_i != -1; ++g_i ) {
00151
00152 LocalID localID = atomMap->localID(*g_i);
00153 if ( localID.pid == notUsed || ! f[localID.pid] ) continue;
00154 Force f_atom = accel * mol->atommass(*g_i);
00155 f[localID.pid][localID.index] += f_atom;
00156 Position x_orig = t[localID.pid][localID.index].position;
00157 Transform trans = t[localID.pid][localID.index].transform;
00158 Position x_atom = lattice.reverse_transform(x_orig,trans);
00159 extForce += f_atom;
00160 extVirial += outer(f_atom,x_atom);
00161 }
00162 }
00163 DebugM(1,"done with the groups\n");
00164
00165 for (ap = ap.begin(); ap != ap.end(); ap++) {
00166 (*ap).forceBox->close(&((*ap).r));
00167 }
00168
00169 delete [] f;
00170 delete [] t;
00171
00172 ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,extForce);
00173 ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,extVirial);
00174 reduction->submit();
00175 }
00176
00177
00178
00179 if ( msg->reconfig ) configure(msg->newaid, msg->newgdef);
00180
00181
00182
00183 if(msg->resendCoordinates) {
00184 DebugM(3,"Sending requested data right away\n");
00185 sendData();
00186 }
00187
00188 delete msg;
00189 DebugM(3,"Done processing results\n");
00190 }
00191
00192 void ComputeGlobal::doWork()
00193 {
00194 DebugM(2,"doWork\n");
00195 if(!firsttime) sendData();
00196 else {
00197 ComputeGlobalDataMsg *msg = new ComputeGlobalDataMsg;
00198 comm->sendComputeGlobalData(msg);
00199 firsttime = 0;
00200 }
00201 DebugM(2,"done with doWork\n");
00202 }
00203
00204 void ComputeGlobal::sendData()
00205 {
00206 DebugM(2,"sendData\n");
00207
00208 PatchMap *patchMap = PatchMap::Object();
00209 int numPatches = patchMap->numPatches();
00210 AtomMap *atomMap = AtomMap::Object();
00211 const Lattice & lattice = patchList[0].p->lattice;
00212 ResizeArrayIter<PatchElem> ap(patchList);
00213 CompAtom **x = new CompAtom*[numPatches];
00214 FullAtom **t = new FullAtom*[numPatches];
00215 for ( int i = 0; i < numPatches; ++i ) { x[i] = 0; t[i] = 0; }
00216
00217 int step = -1;
00218 for (ap = ap.begin(); ap != ap.end(); ap++) {
00219 x[(*ap).patchID] = (*ap).positionBox->open();
00220 t[(*ap).patchID] = (*ap).p->getAtomList().begin();
00221 step = (*ap).p->flags.step;
00222 }
00223
00224 ComputeGlobalDataMsg *msg = new ComputeGlobalDataMsg;
00225
00226 msg->step = step;
00227
00228 AtomIDList::iterator a = aid.begin();
00229 AtomIDList::iterator a_e = aid.end();
00230 for ( ; a != a_e; ++a ) {
00231 LocalID localID = atomMap->localID(*a);
00232 if ( localID.pid == notUsed || ! x[localID.pid] ) continue;
00233 msg->aid.add(*a);
00234 Position x_orig = x[localID.pid][localID.index].position;
00235 Transform trans = t[localID.pid][localID.index].transform;
00236 msg->p.add(lattice.reverse_transform(x_orig,trans));
00237 }
00238
00239
00240 Molecule *mol = Node::Object()->molecule;
00241 AtomIDList::iterator g_i, g_e;
00242 g_i = gdef.begin(); g_e = gdef.end();
00243 ResizeArray<BigReal>::iterator gm_i = gmass.begin();
00244 for ( ; g_i != g_e; ++g_i, ++gm_i ) {
00245 Vector com(0,0,0);
00246 for ( ; *g_i != -1; ++g_i ) {
00247 LocalID localID = atomMap->localID(*g_i);
00248 if ( localID.pid == notUsed || ! x[localID.pid] ) continue;
00249 Position x_orig = x[localID.pid][localID.index].position;
00250 Transform trans = t[localID.pid][localID.index].transform;
00251 com += lattice.reverse_transform(x_orig,trans) * mol->atommass(*g_i);
00252 }
00253 com /= *gm_i;
00254 DebugM(1,"Adding center of mass "<<com<<"\n");
00255 msg->gcom.add(com);
00256 }
00257
00258 for (ap = ap.begin(); ap != ap.end(); ap++) {
00259 (*ap).positionBox->close(&(x[(*ap).patchID]));
00260 }
00261
00262 msg->fid = *fid;
00263 msg->tf = *totalForce;
00264 delete fid;
00265 delete totalForce;
00266 fid = new AtomIDList;
00267 totalForce = new ForceList;
00268
00269 delete [] x;
00270 delete [] t;
00271
00272 DebugM(3,"Sending data (" << msg->aid.size() << " positions) on client\n");
00273 comm->sendComputeGlobalData(msg);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 void ComputeGlobal::saveTotalForces(HomePatch *homePatch)
00286 {
00287 int fixedAtomsOn = Node::Object()->simParameters->fixedAtomsOn;
00288 int i, index, num=homePatch->numAtoms;
00289 FullAtomList atoms = homePatch->atom;
00290 ForceList f1=homePatch->f[Results::normal], f2=homePatch->f_saved[Results::nbond],
00291 f3=homePatch->f_saved[Results::slow];
00292 Force f_sum;
00293
00294 for (i=0; i<num; ++i)
00295 if (isRequested[index=atoms[i].id])
00296 { f_sum = f1[i]+f2[i];
00297 if (dofull)
00298 f_sum += f3[i];
00299 if ( fixedAtomsOn && atoms[i].atomFixed ) f_sum = 0.;
00300 fid->add(index);
00301 totalForce->add(f_sum);
00302 }
00303 }