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->GBISserOn || sp->GBISOn || 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 #if 0
00090 void ComputeGlobal::recvConfig(ComputeGlobalConfigMsg *msg) {
00091 DebugM(3,"Receiving configure on client\n");
00092 configure(msg->aid,msg->gdef);
00093 delete msg;
00094 sendData();
00095 }
00096 #endif
00097
00098 void ComputeGlobal::recvResults(ComputeGlobalResultsMsg *msg) {
00099 DebugM(3,"Receiving results (" << msg->aid.size() << " forces, "
00100 << msg->newgdef.size() << " new group atoms) on client\n");
00101
00102
00103 int setForces = !msg->resendCoordinates;
00104
00105 if(setForces) {
00106
00107 PatchMap *patchMap = PatchMap::Object();
00108 int numPatches = patchMap->numPatches();
00109 AtomMap *atomMap = AtomMap::Object();
00110 const Lattice & lattice = patchList[0].p->lattice;
00111 ResizeArrayIter<PatchElem> ap(patchList);
00112 Force **f = new Force*[numPatches];
00113 FullAtom **t = new FullAtom*[numPatches];
00114 for ( int i = 0; i < numPatches; ++i ) { f[i] = 0; t[i] = 0; }
00115 Force extForce = 0.;
00116 Tensor extVirial;
00117
00118 for (ap = ap.begin(); ap != ap.end(); ap++) {
00119 (*ap).r = (*ap).forceBox->open();
00120 f[(*ap).patchID] = (*ap).r->f[Results::normal];
00121 t[(*ap).patchID] = (*ap).p->getAtomList().begin();
00122 }
00123
00124 AtomIDList::iterator a = msg->aid.begin();
00125 AtomIDList::iterator a_e = msg->aid.end();
00126 ForceList::iterator f2 = msg->f.begin();
00127 for ( ; a != a_e; ++a, ++f2 ) {
00128 DebugM(1,"processing atom "<<(*a)<<", F="<<(*f2)<<"...\n");
00129
00130 LocalID localID = atomMap->localID(*a);
00131 if ( localID.pid == notUsed || ! f[localID.pid] ) continue;
00132 Force f_atom = (*f2);
00133 f[localID.pid][localID.index] += f_atom;
00134 Position x_orig = t[localID.pid][localID.index].position;
00135 Transform trans = t[localID.pid][localID.index].transform;
00136 Position x_atom = lattice.reverse_transform(x_orig,trans);
00137 extForce += f_atom;
00138 extVirial += outer(f_atom,x_atom);
00139 }
00140 DebugM(1,"done with the loop\n");
00141
00142
00143 Molecule *mol = Node::Object()->molecule;
00144 AtomIDList::iterator g_i, g_e;
00145 g_i = gdef.begin(); g_e = gdef.end();
00146 ResizeArray<BigReal>::iterator gm_i = gmass.begin();
00147 ForceList::iterator gf_i = msg->gforce.begin();
00148
00149 for ( ; g_i != g_e; ++g_i, ++gm_i, ++gf_i ) {
00150
00151 Vector accel = (*gf_i) / (*gm_i);
00152 for ( ; *g_i != -1; ++g_i ) {
00153
00154 LocalID localID = atomMap->localID(*g_i);
00155 if ( localID.pid == notUsed || ! f[localID.pid] ) continue;
00156 Force f_atom = accel * mol->atommass(*g_i);
00157 f[localID.pid][localID.index] += f_atom;
00158 Position x_orig = t[localID.pid][localID.index].position;
00159 Transform trans = t[localID.pid][localID.index].transform;
00160 Position x_atom = lattice.reverse_transform(x_orig,trans);
00161 extForce += f_atom;
00162 extVirial += outer(f_atom,x_atom);
00163 }
00164 }
00165 DebugM(1,"done with the groups\n");
00166
00167 for (ap = ap.begin(); ap != ap.end(); ap++) {
00168 (*ap).forceBox->close(&((*ap).r));
00169 }
00170
00171 delete [] f;
00172 delete [] t;
00173
00174 ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,extForce);
00175 ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,extVirial);
00176 reduction->submit();
00177 }
00178
00179
00180
00181 if ( msg->reconfig ) configure(msg->newaid, msg->newgdef);
00182
00183
00184
00185 if(msg->resendCoordinates) {
00186 DebugM(3,"Sending requested data right away\n");
00187 sendData();
00188 }
00189
00190 delete msg;
00191 DebugM(3,"Done processing results\n");
00192 }
00193
00194 void ComputeGlobal::doWork()
00195 {
00196 DebugM(2,"doWork\n");
00197 if(!firsttime) sendData();
00198 else {
00199 ComputeGlobalDataMsg *msg = new ComputeGlobalDataMsg;
00200 comm->sendComputeGlobalData(msg);
00201 firsttime = 0;
00202 }
00203 DebugM(2,"done with doWork\n");
00204 }
00205
00206 void ComputeGlobal::sendData()
00207 {
00208 DebugM(2,"sendData\n");
00209
00210 PatchMap *patchMap = PatchMap::Object();
00211 int numPatches = patchMap->numPatches();
00212 AtomMap *atomMap = AtomMap::Object();
00213 const Lattice & lattice = patchList[0].p->lattice;
00214 ResizeArrayIter<PatchElem> ap(patchList);
00215 CompAtom **x = new CompAtom*[numPatches];
00216 FullAtom **t = new FullAtom*[numPatches];
00217 for ( int i = 0; i < numPatches; ++i ) { x[i] = 0; t[i] = 0; }
00218
00219 int step = -1;
00220 for (ap = ap.begin(); ap != ap.end(); ap++) {
00221 x[(*ap).patchID] = (*ap).positionBox->open();
00222 t[(*ap).patchID] = (*ap).p->getAtomList().begin();
00223 step = (*ap).p->flags.step;
00224 }
00225
00226 ComputeGlobalDataMsg *msg = new ComputeGlobalDataMsg;
00227
00228 msg->step = step;
00229
00230 AtomIDList::iterator a = aid.begin();
00231 AtomIDList::iterator a_e = aid.end();
00232 for ( ; a != a_e; ++a ) {
00233 LocalID localID = atomMap->localID(*a);
00234 if ( localID.pid == notUsed || ! x[localID.pid] ) continue;
00235 msg->aid.add(*a);
00236 Position x_orig = x[localID.pid][localID.index].position;
00237 Transform trans = t[localID.pid][localID.index].transform;
00238 msg->p.add(lattice.reverse_transform(x_orig,trans));
00239 }
00240
00241
00242 Molecule *mol = Node::Object()->molecule;
00243 AtomIDList::iterator g_i, g_e;
00244 g_i = gdef.begin(); g_e = gdef.end();
00245 ResizeArray<BigReal>::iterator gm_i = gmass.begin();
00246 for ( ; g_i != g_e; ++g_i, ++gm_i ) {
00247 Vector com(0,0,0);
00248 for ( ; *g_i != -1; ++g_i ) {
00249 LocalID localID = atomMap->localID(*g_i);
00250 if ( localID.pid == notUsed || ! x[localID.pid] ) continue;
00251 Position x_orig = x[localID.pid][localID.index].position;
00252 Transform trans = t[localID.pid][localID.index].transform;
00253 com += lattice.reverse_transform(x_orig,trans) * mol->atommass(*g_i);
00254 }
00255 com /= *gm_i;
00256 DebugM(1,"Adding center of mass "<<com<<"\n");
00257 msg->gcom.add(com);
00258 }
00259
00260 for (ap = ap.begin(); ap != ap.end(); ap++) {
00261 (*ap).positionBox->close(&(x[(*ap).patchID]));
00262 }
00263
00264 msg->fid = *fid;
00265 msg->tf = *totalForce;
00266 delete fid;
00267 delete totalForce;
00268 fid = new AtomIDList;
00269 totalForce = new ForceList;
00270
00271 delete [] x;
00272 delete [] t;
00273
00274 DebugM(3,"Sending data (" << msg->aid.size() << " positions) on client\n");
00275 comm->sendComputeGlobalData(msg);
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 void ComputeGlobal::saveTotalForces(HomePatch *homePatch)
00288 {
00289 if ( Node::Object()->simParameters->accelMDOn && Node::Object()->simParameters->accelMDDebugOn && Node::Object()->simParameters->accelMDdihe ) {
00290 int i, index, num=homePatch->numAtoms;
00291 FullAtomList atoms = homePatch->atom;
00292 ForceList af=homePatch->f[Results::amdf];
00293
00294 for (i=0; i<num; ++i)
00295 if (isRequested[index=atoms[i].id]) {
00296 fid->add(index);
00297 totalForce->add(af[i]);
00298 }
00299 return;
00300 }
00301
00302 int fixedAtomsOn = Node::Object()->simParameters->fixedAtomsOn;
00303 int i, index, num=homePatch->numAtoms;
00304 FullAtomList atoms = homePatch->atom;
00305 ForceList f1=homePatch->f[Results::normal], f2=homePatch->f_saved[Results::nbond],
00306 f3=homePatch->f_saved[Results::slow];
00307 Force f_sum;
00308
00309 for (i=0; i<num; ++i)
00310 if (isRequested[index=atoms[i].id])
00311 { f_sum = f1[i]+f2[i];
00312 if (dofull)
00313 f_sum += f3[i];
00314 if ( fixedAtomsOn && atoms[i].atomFixed ) f_sum = 0.;
00315 fid->add(index);
00316 totalForce->add(f_sum);
00317 }
00318 }