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
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 ForceList &force_list = self->modifyGroupForces();
00107
00108
00109 int gcount = 1 + group_list.size();
00110 group_list.resize(gcount);
00111 force_list.add(Vector(0,0,0));
00112
00113
00114 int listc, i; char **listv;
00115 if (Tcl_SplitList(interp,argv[1],&listc,&listv) != TCL_OK) {
00116 return TCL_ERROR;
00117 }
00118
00119 Molecule *mol = Node::Object()->molecule;
00120 int numAtoms = mol->numAtoms;
00121
00122 for ( i = 0; i < listc; ++i ) {
00123 int atomid;
00124 if (Tcl_GetInt(interp,listv[i],&atomid) != TCL_OK) {
00125 group_list.resize(gcount-1);
00126 Tcl_Free((char*) listv);
00127 return TCL_ERROR;
00128 }
00129 if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
00130 char errmsg[128];
00131 sprintf(errmsg,"illegal atomid %d",atomid);
00132 Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
00133 return TCL_ERROR;
00134 }
00135 group_list[gcount-1].add(atomid-1);
00136 }
00137 Tcl_Free((char*) listv);
00138
00139
00140 char s[10]; sprintf(s,"g%d",gcount);
00141 Tcl_SetResult(interp,s,TCL_VOLATILE);
00142
00143 DebugM(4,"Group " << s << " added to config list\n");
00144 return TCL_OK;
00145 }
00146
00147
00148 int GlobalMasterTcl::Tcl_reconfig(ClientData clientData,
00149 Tcl_Interp *interp, int argc, char **) {
00150 DebugM(2,"Tcl_reconfig called\n");
00151 if (argc != 1) {
00152 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00153 return TCL_ERROR;
00154 }
00155 iout << iWARN << "'reconfig' is obsolete - reconfiguration is now automatic." << endi;
00156 iout << iWARN << "Use 'clearconfig' to clear the list of atoms and groups." << endi;
00157 DebugM(4,"Reconfiguration turned on\n");
00158 return TCL_OK;
00159 }
00160
00161 int GlobalMasterTcl::Tcl_clearconfig(ClientData clientData,
00162 Tcl_Interp *interp, int argc, char **) {
00163 DebugM(2,"Tcl_reconfig called\n");
00164 if (argc != 1) {
00165 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00166 return TCL_ERROR;
00167 }
00168 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00169 self->modifyRequestedGroups().resize(0);
00170 self->modifyGroupForces().resize(0);
00171 self->modifyRequestedAtoms().resize(0);
00172 self->modifyForcedAtoms().resize(0);
00173 self->modifyAppliedForces().resize(0);
00174 return TCL_OK;
00175 }
00176
00177 int GlobalMasterTcl::Tcl_getstep(ClientData clientData,
00178 Tcl_Interp *interp, int argc, char **) {
00179 DebugM(2,"Tcl_reconfig called\n");
00180 if (argc != 1) {
00181 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00182 return TCL_ERROR;
00183 }
00184 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00185
00186 char s[16]; sprintf(s,"%d",self->step);
00187 Tcl_SetResult(interp,s,TCL_VOLATILE);
00188 return TCL_OK;
00189 }
00190
00191 int GlobalMasterTcl::Tcl_loadforces(ClientData clientData,
00192 Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00193 DebugM(1,"Making tcl force array\n");
00194 if(objc != 2) {
00195 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00196 return TCL_ERROR;
00197 }
00198 Tcl_Obj * const force_array_name = objv[1];
00199
00200 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00201 AtomIDList::const_iterator forced_ids_i = self->getLastAtomsForcedBegin();
00202 AtomIDList::const_iterator forced_ids_e = self->getLastAtomsForcedEnd();
00203 ForceList::const_iterator forces_i = self->getLastForcesBegin();
00204
00205
00206
00207
00208
00209 DebugM(1,"Making Tcl array\n");
00210 while(forced_ids_i != forced_ids_e) {
00211 Tcl_Obj *array_key = Tcl_NewIntObj((int)((*forced_ids_i)+1));
00212
00213
00214 Tcl_Obj *oldlist = Tcl_ObjGetVar2(interp, force_array_name, array_key, 0);
00215 Tcl_Obj *newlist = Tcl_NewListObj(0,NULL);
00216 if (oldlist == NULL) {
00217 Tcl_ListObjAppendElement(interp, newlist,
00218 Tcl_NewDoubleObj((double)((*forces_i).x)));
00219 Tcl_ListObjAppendElement(interp, newlist,
00220 Tcl_NewDoubleObj((double)((*forces_i).y)));
00221 Tcl_ListObjAppendElement(interp, newlist,
00222 Tcl_NewDoubleObj((double)((*forces_i).z)));
00223 } else {
00224 Tcl_Obj** old_elems;
00225 int num_old_elems;
00226 double currval = 0.0;
00227 Tcl_ListObjGetElements(interp, oldlist, &num_old_elems, &old_elems);
00228 if (num_old_elems != 3) {
00229 NAMD_die("TCL error in loadforces! Force list doesn't have 3 elements!");
00230 }
00231 Tcl_GetDoubleFromObj(interp, old_elems[0], &currval);
00232 Tcl_ListObjAppendElement(interp, newlist,
00233 Tcl_NewDoubleObj((double)((*forces_i).x) + currval));
00234 Tcl_GetDoubleFromObj(interp, old_elems[1], &currval);
00235 Tcl_ListObjAppendElement(interp, newlist,
00236 Tcl_NewDoubleObj((double)((*forces_i).y + currval)));
00237 Tcl_GetDoubleFromObj(interp, old_elems[2], &currval);
00238 Tcl_ListObjAppendElement(interp, newlist,
00239 Tcl_NewDoubleObj((double)((*forces_i).z + currval)));
00240 }
00241
00242
00243 if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
00244 NAMD_die("TCL error in loadforces!");
00245 return TCL_ERROR;
00246 }
00247
00248
00249 Tcl_DecrRefCount(array_key);
00250
00251
00252 forced_ids_i++;
00253 forces_i++;
00254 }
00255
00256 DebugM(1,"Done making tcl force array\n");
00257 return TCL_OK;
00258 }
00259
00260
00261
00262
00263 int GlobalMasterTcl::Tcl_loadtotalforces(ClientData clientData,
00264 Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
00265 {
00266 if(objc != 2)
00267 { Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00268 return TCL_ERROR;
00269 }
00270 Tcl_Obj * const force_array_name = objv[1];
00271
00272 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00273 AtomIDList::const_iterator forced_ids_i = self->getForceIdBegin();
00274 AtomIDList::const_iterator forced_ids_e = self->getForceIdEnd();
00275 ForceList::const_iterator forces_i = self->getTotalForce();
00276
00277
00278
00279 while(forced_ids_i != forced_ids_e) {
00280 Tcl_Obj *array_key = Tcl_NewIntObj((int)((*forced_ids_i)+1));
00281 Tcl_Obj *newlist = Tcl_NewListObj(0,NULL);
00282 Tcl_ListObjAppendElement(interp, newlist,
00283 Tcl_NewDoubleObj((double)((*forces_i).x)));
00284 Tcl_ListObjAppendElement(interp, newlist,
00285 Tcl_NewDoubleObj((double)((*forces_i).y)));
00286 Tcl_ListObjAppendElement(interp, newlist,
00287 Tcl_NewDoubleObj((double)((*forces_i).z)));
00288
00289
00290 if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
00291 NAMD_die("TCL error in loadtotalforces!");
00292 return TCL_ERROR;
00293 }
00294
00295
00296 Tcl_DecrRefCount(array_key);
00297
00298
00299 forced_ids_i++;
00300 forces_i++;
00301 }
00302 return TCL_OK;
00303 }
00304
00305
00306 int GlobalMasterTcl::Tcl_loadcoords(ClientData clientData,
00307 Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00308 if (objc != 2) {
00309 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00310 return TCL_ERROR;
00311 }
00312 Tcl_Obj * const vname = objv[1];
00313 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00314 AtomIDList::const_iterator a_i = self->getAtomIdBegin();
00315 AtomIDList::const_iterator a_e = self->getAtomIdEnd();
00316 PositionList::const_iterator p_i = self->getAtomPositionBegin();
00317 for ( ; a_i != a_e; ++a_i, ++p_i ) {
00318 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00319 Tcl_Obj *arrkey = Tcl_NewIntObj((int)((*a_i)+1));
00320
00321 Tcl_ListObjAppendElement(interp, newlist,
00322 Tcl_NewDoubleObj((double)((*p_i).x)));
00323 Tcl_ListObjAppendElement(interp, newlist,
00324 Tcl_NewDoubleObj((double)((*p_i).y)));
00325 Tcl_ListObjAppendElement(interp, newlist,
00326 Tcl_NewDoubleObj((double)((*p_i).z)));
00327
00328 if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
00329 NAMD_die("TCL error in global force calculation!");
00330 return TCL_ERROR;
00331 }
00332 Tcl_DecrRefCount(arrkey);
00333 }
00334
00335
00336 PositionList::const_iterator c_i = self->getGroupPositionBegin();
00337 PositionList::const_iterator c_e = self->getGroupPositionEnd();
00338 int gcount = 1;
00339 for ( ; c_i != c_e; ++c_i, ++gcount ) {
00340 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00341 char buf[10];
00342 sprintf(buf, "g%d", gcount);
00343 Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
00344
00345 Tcl_ListObjAppendElement(interp, newlist,
00346 Tcl_NewDoubleObj((double)((*c_i).x)));
00347 Tcl_ListObjAppendElement(interp, newlist,
00348 Tcl_NewDoubleObj((double)((*c_i).y)));
00349 Tcl_ListObjAppendElement(interp, newlist,
00350 Tcl_NewDoubleObj((double)((*c_i).z)));
00351
00352 if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
00353 NAMD_die("TCL error in global force calculation!");
00354 return TCL_ERROR;
00355 }
00356 Tcl_DecrRefCount(arrkey);
00357 }
00358 return TCL_OK;
00359 }
00360
00361
00362 int GlobalMasterTcl::Tcl_loadmasses(ClientData clientData,
00363 Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00364 if (objc != 2) {
00365 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00366 return TCL_ERROR;
00367 }
00368 Tcl_Obj * const vname = objv[1];
00369 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00370 Molecule *mol = Node::Object()->molecule;
00371 AtomIDList::const_iterator a_i = self->getAtomIdBegin();
00372 AtomIDList::const_iterator a_e = self->getAtomIdEnd();
00373 for ( ; a_i != a_e; ++a_i) {
00374 Tcl_Obj *arrkey = Tcl_NewIntObj((int)((*a_i)+1));
00375 if (!Tcl_ObjSetVar2(interp, vname, arrkey,
00376 Tcl_NewDoubleObj((double)(mol->atommass(*a_i))),
00377 0)) {
00378 NAMD_die("TCL error in global force calculation!");
00379 return TCL_ERROR;
00380 }
00381 Tcl_DecrRefCount(arrkey);
00382 }
00383
00384 const BigReal *g_i, *g_e;
00385 g_i = self->getGroupMassBegin();
00386 g_e = self->getGroupMassEnd();
00387 int gcount = 1;
00388 for ( ; g_i != g_e; ++g_i, ++gcount) {
00389 char buf[10];
00390 sprintf(buf, "g%d", gcount);
00391 Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
00392 if (!Tcl_ObjSetVar2(interp, vname, arrkey,
00393 Tcl_NewDoubleObj((double)(*g_i)),
00394 0)) {
00395 NAMD_die("TCL error in global force calculation!");
00396 return TCL_ERROR;
00397 }
00398 Tcl_DecrRefCount(arrkey);
00399 }
00400 return TCL_OK;
00401 }
00402
00403
00404 int GlobalMasterTcl::Tcl_addforce(ClientData clientData,
00405 Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00406 DebugM(2,"Tcl_addforce called\n");
00407 if (objc != 3) {
00408 Tcl_SetResult(interp,"wrong # args",TCL_VOLATILE);
00409 return TCL_ERROR;
00410 }
00411 Tcl_Obj **force; int fnum; int atomid; double x, y, z;
00412 int isgroup = 0;
00413 char *id = Tcl_GetStringFromObj(objv[1], NULL);
00414 if ( id[0] == 'g' ) {
00415 isgroup = 1;
00416 if ( Tcl_GetInt(interp,id+1,&atomid) != TCL_OK ) return TCL_ERROR;
00417 } else {
00418 if ( Tcl_GetInt(interp,id,&atomid) != TCL_OK ) return TCL_ERROR;
00419 }
00420 if (Tcl_ListObjGetElements(interp, objv[2], &fnum, &force) != TCL_OK) {
00421 return TCL_ERROR;
00422 }
00423 if ( (fnum != 3) ||
00424 (Tcl_GetDoubleFromObj(interp, force[0],&x) != TCL_OK) ||
00425 (Tcl_GetDoubleFromObj(interp, force[1],&y) != TCL_OK) ||
00426 (Tcl_GetDoubleFromObj(interp, force[2],&z) != TCL_OK) ) {
00427 Tcl_SetResult(interp,"force not a vector",TCL_VOLATILE);
00428 return TCL_ERROR;
00429 }
00430
00431 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00432 if ( isgroup ) {
00433 self->modifyGroupForces().item(atomid-1) += Vector(x,y,z);
00434 } else {
00435 self->modifyForcedAtoms().add(atomid-1);
00436 self->modifyAppliedForces().add(Vector(x,y,z));
00437 }
00438 DebugM(4,"Atom ID " << atomid << " added to force list\n");
00439 return TCL_OK;
00440 }
00441
00442
00443 int GlobalMasterTcl::Tcl_addenergy(ClientData clientData,
00444 Tcl_Interp *interp, int argc, char *argv[])
00445 {
00446 double energy;
00447
00448 if (argc != 2)
00449 return TCL_ERROR;
00450 if (Tcl_GetDouble(interp,argv[1],&energy) != TCL_OK)
00451 return TCL_ERROR;
00452
00453 GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
00454 self->reduction->item(REDUCTION_MISC_ENERGY) += energy;
00455
00456 return TCL_OK;
00457 }
00458 #endif
00459
00460
00461 GlobalMasterTcl::GlobalMasterTcl() {
00462 DebugM(3,"Constructing GlobalMasterTcl\n");
00463 #ifdef NAMD_TCL
00464 interp = 0;
00465 #endif
00466 reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00467 initialize();
00468 DebugM(2,"Done constructing ("<<requestedGroups().size()<<" initial groups)\n");
00469 }
00470
00471 GlobalMasterTcl::~GlobalMasterTcl() {
00472 DebugM(3,"Destructing GlobalMasterTcl\n");
00473 #ifdef NAMD_TCL
00474
00475
00476
00477 #endif
00478 delete reduction;
00479 }
00480
00481
00482 void GlobalMasterTcl::initialize() {
00483 DebugM(4,"Initializing master\n");
00484 #ifdef NAMD_TCL
00485 DebugM(1,"here\n");
00486 if(Node::Object() == NULL) NAMD_die("Node::Object() == NULL");
00487 if(Node::Object()->getScript() == NULL)
00488 NAMD_die("Node::Object()->getScript() == NULL");
00489
00490 interp = Node::Object()->getScript()->interp;
00491 DebugM(1,"here\n");
00492
00493 Tcl_CreateCommand(interp, "atomid", Tcl_atomid,
00494 (ClientData) (Node::Object()->molecule), (Tcl_CmdDeleteProc *) NULL);
00495
00496 DebugM(1,"here\n");
00497
00498 Tcl_CreateCommand(interp, "addatom", Tcl_addatom,
00499 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00500 Tcl_CreateCommand(interp, "addgroup", Tcl_addgroup,
00501 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00502
00503 DebugM(1,"here\n");
00504
00505 StringList *script = Node::Object()->configList->find("tclForcesScript");
00506
00507 DebugM(1,"here\n");
00508 for ( ; script; script = script->next ) {
00509 int code;
00510 DebugM(1,"here "<<script->data<<"\n");
00511 if ( strstr(script->data,"\n") ) {
00512 code = Tcl_Eval(interp,script->data);
00513 }
00514 else code = Tcl_EvalFile(interp,script->data);
00515 DebugM(1,"here\n");
00516 const char *result = Tcl_GetStringResult(interp);
00517 DebugM(1,"here\n");
00518 if (*result != 0) CkPrintf("TCL: %s\n",result);
00519 DebugM(1,"here\n");
00520 if (code != TCL_OK) {
00521 const char *errorInfo = Tcl_GetVar(interp,"errorInfo",0);
00522 NAMD_die(errorInfo);
00523 }
00524 }
00525
00526 DebugM(1,"here\n");
00527 Tcl_DeleteCommand(interp, "addatom");
00528 Tcl_DeleteCommand(interp, "addgroup");
00529
00530 Tcl_CreateObjCommand(interp, (char *)"loadforces", Tcl_loadforces,
00531 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00532 Tcl_CreateObjCommand(interp, (char *)"loadtotalforces", Tcl_loadtotalforces,
00533 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00534 Tcl_CreateObjCommand(interp, (char *)"loadcoords", Tcl_loadcoords,
00535 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00536 Tcl_CreateObjCommand(interp, (char *)"loadmasses", Tcl_loadmasses,
00537 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00538 Tcl_CreateObjCommand(interp, (char *)"addforce", Tcl_addforce,
00539 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00540 Tcl_CreateCommand(interp, (char *)"addenergy", Tcl_addenergy,
00541 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00542 Tcl_CreateCommand(interp, (char *)"reconfig", Tcl_reconfig,
00543 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00544 Tcl_CreateCommand(interp, (char *)"clearconfig", Tcl_clearconfig,
00545 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00546 Tcl_CreateCommand(interp, (char *)"addatom", Tcl_addatom,
00547 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00548 Tcl_CreateCommand(interp, (char *)"addgroup", Tcl_addgroup,
00549 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00550 Tcl_CreateCommand(interp, (char *)"getstep", Tcl_getstep,
00551 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00552 #else
00553
00554 NAMD_die("Sorry, tclForces is not available; built without TCL.");
00555
00556 #endif
00557 DebugM(2,"done initializing master\n");
00558 }
00559
00560
00561 void GlobalMasterTcl::calculate() {
00562 DebugM(4,"Calculating forces on master\n");
00563
00564
00565 modifyAppliedForces().resize(0);
00566 modifyForcedAtoms().resize(0);
00567 modifyGroupForces().setall(Vector(0,0,0));
00568
00569 #ifdef NAMD_TCL
00570
00571
00572 char cmd[129]; int code;
00573 strcpy(cmd,"calcforces"); code = Tcl_Eval(interp,cmd);
00574 const char *result = Tcl_GetStringResult(interp);
00575 if (*result != 0) CkPrintf("TCL: %s\n",result);
00576 if (code != TCL_OK) {
00577 const char *errorInfo = Tcl_GetVar(interp,"errorInfo",0);
00578 NAMD_die(errorInfo);
00579 }
00580 #endif
00581
00582 reduction->submit();
00583
00584 }