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

Generated on Sat Nov 18 01:17:14 2017 for NAMD by  doxygen 1.4.7