GlobalMasterTcl.C

Go to the documentation of this file.
00001 
00007 #include "InfoStream.h"
00008 #include "Node.h"
00009 #include "Molecule.h"
00010 #include "ReductionMgr.h"
00011 #include "ScriptTcl.h"
00012 #include <stdio.h>
00013 
00014 #include "GlobalMaster.h"
00015 #include "GlobalMasterTcl.h"
00016 
00017 #ifdef NAMD_TCL
00018 #include <tcl.h>
00019 #endif
00020 
00021 //#define DEBUGM
00022 #define MIN_DEBUG_LEVEL 3
00023 #include "Debug.h"
00024 
00025 
00026 #ifdef NAMD_TCL
00027 int GlobalMasterTcl::Tcl_print(ClientData,
00028         Tcl_Interp *, int argc, const char *argv[]) {
00029   int arglen = 1;  int ai;
00030   for (ai=1; ai<argc; ++ai) { arglen += strlen(argv[ai]) + 1; }
00031   char *buf = new char[arglen];  *buf = 0;
00032   for (ai=1; ai<argc; ++ai) { strcat(buf,argv[ai]); strcat(buf," "); }
00033   ai = strlen(buf);  if ( ai ) buf[ai-1] = 0;
00034   CkPrintf("TCL: %s\n",buf);
00035   delete [] buf;
00036   return TCL_OK;
00037 }
00038 
00039 
00040 int GlobalMasterTcl::Tcl_atomid(ClientData clientData,
00041         Tcl_Interp *interp, int argc, const char *argv[]) {
00042   if (argc != 4) {
00043     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00044     return TCL_ERROR;
00045   }
00046   const char *segid = argv[1];
00047   int resid;
00048   if (Tcl_GetInt(interp,argv[2],&resid) != TCL_OK) {
00049     return TCL_ERROR;
00050   }
00051   const char *aname = argv[3];
00052 
00053   Molecule *mol = (Molecule *)clientData;
00054   int atomid = mol->get_atom_from_name(segid,resid,aname);
00055 
00056   if (atomid < 0) {
00057     Tcl_SetResult(interp,"atom not found",TCL_VOLATILE);
00058     return TCL_ERROR;
00059   }
00060   atomid += 1;
00061 
00062   char s[10];  sprintf(s,"%d",atomid);
00063   Tcl_SetResult(interp,s,TCL_VOLATILE);
00064   DebugM(4,"Atom ID " << atomid << " identified by name\n");
00065   return TCL_OK;
00066 }
00067 
00068 
00069 int GlobalMasterTcl::Tcl_addatom(ClientData clientData,
00070         Tcl_Interp *interp, int argc, const char *argv[]) {
00071   DebugM(2,"Tcl_addatom called\n");
00072   if (argc != 2) {
00073     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00074     return TCL_ERROR;
00075   }
00076   int atomid;
00077   if (Tcl_GetInt(interp,argv[1],&atomid) != TCL_OK) {
00078     return TCL_ERROR;
00079   }
00080   Molecule *mol = Node::Object()->molecule;
00081   int numAtoms = mol->numAtoms;
00082   if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
00083     char errmsg[128];
00084     sprintf(errmsg,"illegal atomid %d",atomid);
00085     Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
00086     return TCL_ERROR;
00087   }
00088   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00089   self->modifyRequestedAtoms().add(atomid-1);
00090   DebugM(4,"Atom ID " << atomid << " added to config list\n");
00091   return TCL_OK;
00092 }
00093 
00094 
00095 int GlobalMasterTcl::Tcl_addgroup(ClientData clientData,
00096         Tcl_Interp *interp, int argc, const char *argv[]) {
00097   DebugM(2,"Tcl_addgroup called\n");
00098   if (argc != 2) {
00099     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00100     return TCL_ERROR;
00101   }
00102 
00103   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00104   ResizeArray<AtomIDList> &group_list = self->modifyRequestedGroups();
00105 
00106   /* set gcount to the number of groups after we add one, and add it! */
00107   int gcount = 1 + group_list.size();
00108   group_list.resize(gcount);
00109 
00110   /* get the list of atoms that go in the group */
00111   int listc, i;  const char **listv;
00112   if (Tcl_SplitList(interp,argv[1],&listc,&listv) != TCL_OK) {
00113     return TCL_ERROR;
00114   }
00115 
00116   Molecule *mol = Node::Object()->molecule;
00117   int numAtoms = mol->numAtoms;
00118   /* add each atom to the new group */
00119   for ( i = 0; i < listc; ++i ) {
00120     int atomid;
00121     if (Tcl_GetInt(interp,listv[i],&atomid) != TCL_OK) { // error getting int
00122       group_list.resize(gcount-1); // remove the group we made
00123       Tcl_Free((char*) listv);
00124       return TCL_ERROR;
00125     }
00126     if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
00127       char errmsg[128];
00128       sprintf(errmsg,"illegal atomid %d",atomid);
00129       Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
00130       return TCL_ERROR;
00131     }
00132     group_list[gcount-1].add(atomid-1); // add the atom to the group
00133   }
00134   Tcl_Free((char*) listv);
00135 
00136   /* return the group number to TCL */
00137   char s[10];  sprintf(s,"g%d",gcount);
00138   Tcl_SetResult(interp,s,TCL_VOLATILE);
00139 
00140   DebugM(4,"Group " << s << " added to config list\n");
00141   return TCL_OK;
00142 }
00143 
00144 /* this function is useless - it reconfigures whenever you add atoms! */
00145 int GlobalMasterTcl::Tcl_reconfig(ClientData clientData,
00146         Tcl_Interp *interp, int argc, const char **) {
00147   DebugM(2,"Tcl_reconfig called\n");
00148   if (argc != 1) {
00149     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00150     return TCL_ERROR;
00151   }
00152   iout << iWARN << "'reconfig' is obsolete - reconfiguration is now automatic." << endi;
00153   iout << iWARN << "Use 'clearconfig' to clear the list of atoms and groups." << endi;
00154   DebugM(4,"Reconfiguration turned on\n");
00155   return TCL_OK;
00156 }
00157 
00158 int GlobalMasterTcl::Tcl_clearconfig(ClientData clientData,
00159         Tcl_Interp *interp, int argc, const char **) {
00160   DebugM(2,"Tcl_reconfig called\n");
00161   if (argc != 1) {
00162     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00163     return TCL_ERROR;
00164   }
00165   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00166   self->modifyRequestedGroups().resize(0);
00167   self->modifyRequestedAtoms().resize(0);
00168   return TCL_OK;
00169 }
00170 
00171 int GlobalMasterTcl::Tcl_getstep(ClientData clientData,
00172         Tcl_Interp *interp, int argc, const char **) {
00173   DebugM(2,"Tcl_reconfig called\n");
00174   if (argc != 1) {
00175     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00176     return TCL_ERROR;
00177   }
00178   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00179   
00180   char s[16];  sprintf(s,"%d",self->step);
00181   Tcl_SetResult(interp,s,TCL_VOLATILE);
00182   return TCL_OK;
00183 }
00184 
00185 int GlobalMasterTcl::Tcl_loadforces(ClientData clientData,
00186         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00187   DebugM(1,"Making tcl force array\n");
00188   if(objc != 2) {
00189     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00190     return TCL_ERROR;
00191   }
00192   Tcl_Obj * const force_array_name = objv[1];
00193   
00194   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00195   AtomIDList::const_iterator forced_ids_i = self->getLastAtomsForcedBegin();
00196   AtomIDList::const_iterator forced_ids_e = self->getLastAtomsForcedEnd();
00197   ForceList::const_iterator forces_i = self->getLastForcesBegin();
00198 
00199   // plf -- changed 06/12/2008 to check for more than one force on each atom
00200 
00201   // now make a Tcl array containing all of the requested atoms and
00202   // their forces
00203   DebugM(1,"Making Tcl array\n");
00204   while(forced_ids_i != forced_ids_e) {
00205     Tcl_Obj *array_key = Tcl_NewIntObj((int)((*forced_ids_i)+1)); // the id
00206     Tcl_IncrRefCount(array_key);
00207 
00208     // Check if the element is already defined, and if so, add to it
00209     Tcl_Obj *oldlist = Tcl_ObjGetVar2(interp, force_array_name, array_key, 0);
00210     Tcl_Obj *newlist = Tcl_NewListObj(0,NULL); // the list <fx,fy,fz>
00211     if (oldlist == NULL) {
00212       Tcl_ListObjAppendElement(interp, newlist,
00213         Tcl_NewDoubleObj((double)((*forces_i).x)));
00214       Tcl_ListObjAppendElement(interp, newlist, 
00215         Tcl_NewDoubleObj((double)((*forces_i).y)));
00216       Tcl_ListObjAppendElement(interp, newlist, 
00217         Tcl_NewDoubleObj((double)((*forces_i).z)));
00218     } else {
00219       Tcl_Obj** old_elems;
00220       int num_old_elems;
00221       double currval = 0.0;
00222       Tcl_ListObjGetElements(interp, oldlist, &num_old_elems, &old_elems);
00223       if (num_old_elems != 3) {
00224         NAMD_die("TCL error in loadforces! Force list doesn't have 3 elements!");
00225       }
00226       Tcl_GetDoubleFromObj(interp, old_elems[0], &currval);
00227       Tcl_ListObjAppendElement(interp, newlist,
00228         Tcl_NewDoubleObj((double)((*forces_i).x) + currval));
00229       Tcl_GetDoubleFromObj(interp, old_elems[1], &currval);
00230       Tcl_ListObjAppendElement(interp, newlist, 
00231         Tcl_NewDoubleObj((double)((*forces_i).y + currval)));
00232       Tcl_GetDoubleFromObj(interp, old_elems[2], &currval);
00233       Tcl_ListObjAppendElement(interp, newlist, 
00234         Tcl_NewDoubleObj((double)((*forces_i).z + currval)));
00235     }
00236 
00237     // add the pair (id,F) to the array
00238     if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
00239       NAMD_die("TCL error in loadforces!");
00240       return TCL_ERROR;
00241     }
00242 
00243     Tcl_DecrRefCount(array_key);
00244 
00245     // go to the next atom
00246     forced_ids_i++;
00247     forces_i++;
00248   }
00249 
00250   DebugM(1,"Done making tcl force array\n");
00251   return TCL_OK;
00252 }
00253 
00254 
00255 int GlobalMasterTcl::Tcl_enabletotalforces(ClientData clientData,
00256         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
00257 {
00258   DebugM(2,"Tcl_enabletotalforces called\n");
00259   if (objc != 1) {
00260     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00261     return TCL_ERROR;
00262   }
00263   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00264   self->requestTotalForce(true);
00265   return TCL_OK;
00266 }
00267 
00268 int GlobalMasterTcl::Tcl_disabletotalforces(ClientData clientData,
00269         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
00270 {
00271   DebugM(2,"Tcl_disabletotalforces called\n");
00272   if (objc != 1) {
00273     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00274     return TCL_ERROR;
00275   }
00276   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00277   self->requestTotalForce(false);
00278   return TCL_OK;
00279 }
00280 
00281 
00282 // Here I simply copied the code from "Tcl_loadforces" above. The
00283 // only difference is the source data.
00284 int GlobalMasterTcl::Tcl_loadtotalforces(ClientData clientData,
00285         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
00286 {
00287   if(objc != 2)
00288   { Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00289     return TCL_ERROR;
00290   }
00291   Tcl_Obj * const force_array_name = objv[1];
00292   
00293   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00294   if ( ! self->requestedTotalForces() ) {
00295     Tcl_SetResult(interp,"must call enabletotalforces before loadtotalforces",TCL_VOLATILE);
00296     return TCL_ERROR;
00297   }
00298 
00299   AtomIDList::const_iterator forced_ids_i = self->getForceIdBegin();
00300   AtomIDList::const_iterator forced_ids_e = self->getForceIdEnd();
00301   ForceList::const_iterator forces_i = self->getTotalForce();
00302   
00303   // now make a Tcl array containing all of the requested atoms and
00304   // their forces
00305   while(forced_ids_i != forced_ids_e) {
00306     Tcl_Obj *array_key = Tcl_NewIntObj((int)((*forced_ids_i)+1)); // the id
00307     Tcl_IncrRefCount(array_key);
00308     Tcl_Obj *newlist = Tcl_NewListObj(0,NULL); // the list <fx,fy,fz>
00309     Tcl_ListObjAppendElement(interp, newlist,
00310       Tcl_NewDoubleObj((double)((*forces_i).x)));
00311     Tcl_ListObjAppendElement(interp, newlist, 
00312       Tcl_NewDoubleObj((double)((*forces_i).y)));
00313     Tcl_ListObjAppendElement(interp, newlist, 
00314       Tcl_NewDoubleObj((double)((*forces_i).z)));
00315 
00316     // add the pair (id,F) to the array
00317     if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
00318       NAMD_die("TCL error in loadtotalforces!");
00319       return TCL_ERROR;
00320     }
00321 
00322     Tcl_DecrRefCount(array_key);
00323 
00324     // go to the next atom
00325     forced_ids_i++;
00326     forces_i++;
00327   }
00328 
00329   /* do the group stuff */
00330   ForceList::const_iterator tf_i = self->getGroupTotalForceBegin();
00331   ForceList::const_iterator tf_e = self->getGroupTotalForceEnd();
00332   int gcount = 1;
00333   for ( ; tf_i != tf_e; ++tf_i, ++gcount ) {
00334     Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00335     char buf[10];
00336     sprintf(buf, "g%d", gcount);
00337     Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
00338     Tcl_IncrRefCount(arrkey);
00339  
00340     Tcl_ListObjAppendElement(interp, newlist,
00341       Tcl_NewDoubleObj((double)((*tf_i).x)));
00342     Tcl_ListObjAppendElement(interp, newlist,
00343       Tcl_NewDoubleObj((double)((*tf_i).y)));
00344     Tcl_ListObjAppendElement(interp, newlist,
00345       Tcl_NewDoubleObj((double)((*tf_i).z)));
00346    
00347     if (!Tcl_ObjSetVar2(interp, force_array_name, arrkey, newlist, 0)) {
00348       NAMD_die("TCL error in loadtotalforces for groups!");
00349       return TCL_ERROR;
00350     }
00351     Tcl_DecrRefCount(arrkey);
00352   }
00353   return TCL_OK;
00354 }
00355 
00356   
00357 int GlobalMasterTcl::Tcl_loadcoords(ClientData clientData,
00358         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00359   if (objc != 2) {
00360     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00361     return TCL_ERROR;
00362   }
00363   Tcl_Obj * const vname = objv[1];
00364   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00365   AtomIDList::const_iterator a_i = self->getAtomIdBegin();
00366   AtomIDList::const_iterator a_e = self->getAtomIdEnd();
00367   PositionList::const_iterator p_i = self->getAtomPositionBegin();
00368   for ( ; a_i != a_e; ++a_i, ++p_i ) {
00369     Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00370     Tcl_Obj *arrkey = Tcl_NewIntObj((int)((*a_i)+1));
00371     Tcl_IncrRefCount(arrkey);
00372     
00373     Tcl_ListObjAppendElement(interp, newlist, 
00374       Tcl_NewDoubleObj((double)((*p_i).x)));
00375     Tcl_ListObjAppendElement(interp, newlist, 
00376       Tcl_NewDoubleObj((double)((*p_i).y)));
00377     Tcl_ListObjAppendElement(interp, newlist, 
00378       Tcl_NewDoubleObj((double)((*p_i).z)));
00379    
00380     if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
00381       NAMD_die("TCL error in global force calculation!");
00382       return TCL_ERROR;
00383     }
00384     Tcl_DecrRefCount(arrkey);
00385   }
00386 
00387   /* do the group stuff */
00388   PositionList::const_iterator c_i = self->getGroupPositionBegin();
00389   PositionList::const_iterator c_e = self->getGroupPositionEnd();
00390   int gcount = 1;
00391   for ( ; c_i != c_e; ++c_i, ++gcount ) {
00392     Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00393     char buf[10];
00394     sprintf(buf, "g%d", gcount);
00395     Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
00396     Tcl_IncrRefCount(arrkey);
00397  
00398     Tcl_ListObjAppendElement(interp, newlist,
00399       Tcl_NewDoubleObj((double)((*c_i).x)));
00400     Tcl_ListObjAppendElement(interp, newlist,
00401       Tcl_NewDoubleObj((double)((*c_i).y)));
00402     Tcl_ListObjAppendElement(interp, newlist,
00403       Tcl_NewDoubleObj((double)((*c_i).z)));
00404    
00405     if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
00406       NAMD_die("TCL error in global force calculation!");
00407       return TCL_ERROR;
00408     }
00409     Tcl_DecrRefCount(arrkey);
00410   }
00411   return TCL_OK;
00412 }
00413 
00414 
00415 int GlobalMasterTcl::Tcl_loadmasses(ClientData clientData,
00416         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00417   if (objc != 2) {
00418     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00419     return TCL_ERROR;
00420   }
00421   Tcl_Obj * const vname = objv[1];
00422   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00423   Molecule *mol = Node::Object()->molecule;
00424   AtomIDList::const_iterator a_i = self->getAtomIdBegin();
00425   AtomIDList::const_iterator a_e = self->getAtomIdEnd();
00426   for ( ; a_i != a_e; ++a_i) {
00427     Tcl_Obj *arrkey = Tcl_NewIntObj((int)((*a_i)+1));
00428     Tcl_IncrRefCount(arrkey);
00429     if (!Tcl_ObjSetVar2(interp, vname, arrkey,
00430                         Tcl_NewDoubleObj((double)(mol->atommass(*a_i))),
00431                         0)) {
00432       NAMD_die("TCL error in global force calculation!");
00433       return TCL_ERROR;
00434     }
00435     Tcl_DecrRefCount(arrkey);
00436   }
00437 
00438   const BigReal *g_i, *g_e;
00439   g_i = self->getGroupMassBegin();
00440   g_e = self->getGroupMassEnd();
00441   int gcount = 1;
00442   for ( ; g_i != g_e; ++g_i, ++gcount) {
00443     char buf[10];
00444     sprintf(buf, "g%d", gcount);
00445     Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
00446     Tcl_IncrRefCount(arrkey);
00447     if (!Tcl_ObjSetVar2(interp, vname, arrkey,
00448                         Tcl_NewDoubleObj((double)(*g_i)),
00449                         0)) {
00450       NAMD_die("TCL error in global force calculation!");
00451       return TCL_ERROR;
00452     }
00453     Tcl_DecrRefCount(arrkey);
00454   }
00455   return TCL_OK;
00456 }
00457 
00458 
00459 int GlobalMasterTcl::Tcl_addforce(ClientData clientData,
00460         Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00461   DebugM(2,"Tcl_addforce called\n");
00462   if (objc != 3) {
00463     Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00464     return TCL_ERROR;
00465   }
00466   Tcl_Obj **force;  int fnum;  int atomid;  double x, y, z;
00467   int isgroup = 0;
00468   char *id = Tcl_GetStringFromObj(objv[1], NULL); 
00469   if ( id[0] == 'g' ) {
00470     isgroup = 1;
00471     if ( Tcl_GetInt(interp,id+1,&atomid) != TCL_OK ) return TCL_ERROR;
00472   } else {
00473     if ( Tcl_GetInt(interp,id,&atomid) != TCL_OK ) return TCL_ERROR;
00474   }
00475   if (Tcl_ListObjGetElements(interp, objv[2], &fnum, &force) != TCL_OK) {
00476     return TCL_ERROR;
00477   }
00478   if ( (fnum != 3) ||
00479        (Tcl_GetDoubleFromObj(interp, force[0],&x) != TCL_OK) ||
00480        (Tcl_GetDoubleFromObj(interp, force[1],&y) != TCL_OK) ||
00481        (Tcl_GetDoubleFromObj(interp, force[2],&z) != TCL_OK) ) {
00482     Tcl_SetResult(interp,"force not a vector",TCL_VOLATILE);
00483     return TCL_ERROR;
00484   }
00485 
00486   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00487   if ( isgroup ) {
00488     int ngrps = self->getGroupMassEnd() - self->getGroupMassBegin();
00489     if ( atomid < 1 || atomid > ngrps ) {
00490       Tcl_SetResult(interp,"requested group not available",TCL_VOLATILE);
00491       return TCL_ERROR;
00492     }
00493     self->modifyGroupForces().item(atomid-1) += Vector(x,y,z);
00494   } else {
00495     self->modifyForcedAtoms().add(atomid-1);
00496     self->modifyAppliedForces().add(Vector(x,y,z));
00497   }
00498   DebugM(4,"Atom ID " << atomid << " added to force list\n");
00499   return TCL_OK;
00500 }
00501 
00502 
00503 int GlobalMasterTcl::Tcl_addenergy(ClientData clientData,
00504         Tcl_Interp *interp, int argc, const char *argv[])
00505 {
00506   double energy;
00507   
00508   if (argc != 2)
00509     return TCL_ERROR;
00510   if (Tcl_GetDouble(interp,argv[1],&energy) != TCL_OK)
00511     return TCL_ERROR;
00512   
00513   GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00514   self->reduction->item(REDUCTION_MISC_ENERGY) += energy;
00515   
00516   return TCL_OK;
00517 }
00518 #endif
00519 
00520 
00521 GlobalMasterTcl::GlobalMasterTcl() {
00522   DebugM(3,"Constructing GlobalMasterTcl\n");
00523 #ifdef NAMD_TCL
00524   interp = 0;
00525 #endif
00526   reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00527   initialize();
00528   DebugM(2,"Done constructing ("<<requestedGroups().size()<<" initial groups)\n");
00529 }
00530 
00531 GlobalMasterTcl::~GlobalMasterTcl() {
00532   DebugM(3,"Destructing GlobalMasterTcl\n");
00533 #ifdef NAMD_TCL
00534 /*
00535   if ( interp ) Tcl_DeleteInterp(interp);
00536 */
00537 #endif
00538   delete reduction;
00539 }
00540 
00541 
00542 void GlobalMasterTcl::initialize() {
00543   DebugM(4,"Initializing master\n");
00544 #ifdef NAMD_TCL
00545   DebugM(1,"here\n");
00546   if(Node::Object() == NULL) NAMD_die("Node::Object() == NULL");
00547   if(Node::Object()->getScript() == NULL)
00548     NAMD_die("Node::Object()->getScript() == NULL");
00549 
00550   interp = Node::Object()->getScript()->interp;
00551   DebugM(1,"here\n");
00552 
00553   Tcl_CreateCommand(interp, "atomid", Tcl_atomid,
00554     (ClientData) (Node::Object()->molecule), (Tcl_CmdDeleteProc *) NULL);
00555 
00556   DebugM(1,"here\n");
00557   // Call interpreter to determine requested atoms
00558   Tcl_CreateCommand(interp, "addatom", Tcl_addatom,
00559     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00560   Tcl_CreateCommand(interp, "addgroup", Tcl_addgroup,
00561       (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00562   Tcl_CreateObjCommand(interp, (char *)"enabletotalforces", Tcl_enabletotalforces,
00563     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00564   Tcl_CreateObjCommand(interp, (char *)"disabletotalforces", Tcl_disabletotalforces,
00565     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00566 
00567   DebugM(1,"here\n");
00568   // Get the script
00569   StringList *script = Node::Object()->configList->find("tclForcesScript");
00570 
00571   DebugM(1,"here\n");
00572   for ( ; script; script = script->next ) {
00573     int code;
00574     DebugM(1,"here "<<script->data<<"\n");
00575     if ( strstr(script->data,"\n") ) {
00576        code = Tcl_Eval(interp,script->data);
00577     }
00578     else code = Tcl_EvalFile(interp,script->data);
00579     DebugM(1,"here\n");
00580     const char *result = Tcl_GetStringResult(interp);
00581     DebugM(1,"here\n");
00582     if (*result != 0) CkPrintf("TCL: %s\n",result);
00583     DebugM(1,"here\n");
00584     if (code != TCL_OK) {
00585       const char *errorInfo = Tcl_GetVar(interp,"errorInfo",0);
00586       NAMD_die(errorInfo ? errorInfo : "Unknown Tcl error");
00587     }
00588   }
00589 
00590   DebugM(1,"here\n");
00591   Tcl_CreateObjCommand(interp, (char *)"loadforces", Tcl_loadforces,
00592     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00593   Tcl_CreateObjCommand(interp, (char *)"loadtotalforces", Tcl_loadtotalforces,
00594     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00595   Tcl_CreateObjCommand(interp, (char *)"loadcoords", Tcl_loadcoords,
00596     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00597   Tcl_CreateObjCommand(interp, (char *)"loadmasses", Tcl_loadmasses,
00598     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00599   Tcl_CreateObjCommand(interp, (char *)"addforce", Tcl_addforce,
00600     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00601   Tcl_CreateCommand(interp, (char *)"addenergy", Tcl_addenergy,
00602     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00603   Tcl_CreateCommand(interp, (char *)"reconfig", Tcl_reconfig,
00604       (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00605   Tcl_CreateCommand(interp, (char *)"clearconfig", Tcl_clearconfig,
00606       (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00607   Tcl_CreateCommand(interp, (char *)"getstep", Tcl_getstep,
00608     (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00609 #else
00610 
00611   NAMD_die("Sorry, tclForces is not available; built without TCL.");
00612 
00613 #endif
00614   DebugM(2,"done initializing master\n");
00615 }
00616 
00617 
00618 void GlobalMasterTcl::calculate() {
00619   DebugM(4,"Calculating forces on master\n");
00620 
00621   /* clear out the requested forces first! */
00622   modifyAppliedForces().resize(0);
00623   modifyForcedAtoms().resize(0);
00624   modifyGroupForces().resize(getGroupMassEnd() - getGroupMassBegin());
00625   modifyGroupForces().setall(Vector(0,0,0));
00626 
00627 #ifdef NAMD_TCL
00628   // Call interpreter to calculate forces
00629 
00630   char cmd[129];  int code;
00631   strcpy(cmd,"calcforces");  code = Tcl_Eval(interp,cmd);
00632   const char *result = Tcl_GetStringResult(interp);
00633   if (*result != 0) CkPrintf("TCL: %s\n",result);
00634   if (code != TCL_OK) {
00635     const char *errorInfo = Tcl_GetVar(interp,"errorInfo",0);
00636     NAMD_die(errorInfo ? errorInfo : "Unknown Tcl error");
00637   }
00638 #endif
00639 
00640   reduction->submit();
00641 
00642 }

Generated on Fri Jul 20 01:17:14 2018 for NAMD by  doxygen 1.4.7