NAMD
GlobalMasterTcl.C
Go to the documentation of this file.
1 
7 #include "InfoStream.h"
8 #include "Node.h"
9 #include "Molecule.h"
10 #include "ReductionMgr.h"
11 #include "ScriptTcl.h"
12 #include "ConfigList.h"
13 #include <stdio.h>
14 
15 #include "GlobalMaster.h"
16 #include "GlobalMasterTcl.h"
17 
18 #ifdef NAMD_TCL
19 #include <tcl.h>
20 #endif
21 
22 //#define DEBUGM
23 #define MIN_DEBUG_LEVEL 3
24 #include "Debug.h"
25 
26 
27 #ifdef NAMD_TCL
28 int GlobalMasterTcl::Tcl_print(ClientData,
29  Tcl_Interp *, int argc, const char *argv[]) {
30  int arglen = 1; int ai;
31  for (ai=1; ai<argc; ++ai) { arglen += strlen(argv[ai]) + 1; }
32  char *buf = new char[arglen]; *buf = 0;
33  for (ai=1; ai<argc; ++ai) { strcat(buf,argv[ai]); strcat(buf," "); }
34  ai = strlen(buf); if ( ai ) buf[ai-1] = 0;
35  CkPrintf("TCL: %s\n",buf);
36  delete [] buf;
37  return TCL_OK;
38 }
39 
40 
41 int GlobalMasterTcl::Tcl_atomid(ClientData clientData,
42  Tcl_Interp *interp, int argc, const char *argv[]) {
43  if (argc != 4) {
44  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
45  return TCL_ERROR;
46  }
47  const char *segid = argv[1];
48  int resid;
49  if (Tcl_GetInt(interp,argv[2],&resid) != TCL_OK) {
50  return TCL_ERROR;
51  }
52  const char *aname = argv[3];
53 
54  Molecule *mol = (Molecule *)clientData;
55  int atomid = mol->get_atom_from_name(segid,resid,aname);
56 
57  if (atomid < 0) {
58  Tcl_SetResult(interp,(char*)"atom not found",TCL_VOLATILE);
59  return TCL_ERROR;
60  }
61  atomid += 1;
62 
63  char s[16]; sprintf(s,"%d",atomid);
64  Tcl_SetResult(interp,s,TCL_VOLATILE);
65  DebugM(4,"Atom ID " << atomid << " identified by name\n");
66  return TCL_OK;
67 }
68 
69 
70 int GlobalMasterTcl::Tcl_addatom(ClientData clientData,
71  Tcl_Interp *interp, int argc, const char *argv[]) {
72  DebugM(2,"Tcl_addatom called\n");
73  if (argc != 2) {
74  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
75  return TCL_ERROR;
76  }
77  int atomid;
78  if (Tcl_GetInt(interp,argv[1],&atomid) != TCL_OK) {
79  return TCL_ERROR;
80  }
81  Molecule *mol = Node::Object()->molecule;
82  int numAtoms = mol->numAtoms;
83  if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
84  char errmsg[128];
85  sprintf(errmsg,"illegal atomid %d",atomid);
86  Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
87  return TCL_ERROR;
88  }
89  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
90  self->modifyRequestedAtoms().add(atomid-1);
91  DebugM(4,"Atom ID " << atomid << " added to config list\n");
92  return TCL_OK;
93 }
94 
95 
96 int GlobalMasterTcl::Tcl_addgroup(ClientData clientData,
97  Tcl_Interp *interp, int argc, const char *argv[]) {
98  DebugM(2,"Tcl_addgroup called\n");
99  if (argc != 2) {
100  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
101  return TCL_ERROR;
102  }
103 
104  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
105  ResizeArray<AtomIDList> &group_list = self->modifyRequestedGroups();
106 
107  /* set gcount to the number of groups after we add one, and add it! */
108  int gcount = 1 + group_list.size();
109  group_list.resize(gcount);
110 
111  /* get the list of atoms that go in the group */
112  int listc, i; const char **listv;
113  if (Tcl_SplitList(interp,argv[1],&listc,&listv) != TCL_OK) {
114  return TCL_ERROR;
115  }
116 
117  Molecule *mol = Node::Object()->molecule;
118  int numAtoms = mol->numAtoms;
119  /* add each atom to the new group */
120  for ( i = 0; i < listc; ++i ) {
121  int atomid;
122  if (Tcl_GetInt(interp,listv[i],&atomid) != TCL_OK) { // error getting int
123  group_list.resize(gcount-1); // remove the group we made
124  Tcl_Free((char*) listv);
125  return TCL_ERROR;
126  }
127  if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
128  char errmsg[128];
129  sprintf(errmsg,"illegal atomid %d",atomid);
130  Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
131  return TCL_ERROR;
132  }
133  group_list[gcount-1].add(atomid-1); // add the atom to the group
134  }
135  Tcl_Free((char*) listv);
136 
137  /* return the group number to TCL */
138  char s[16]; sprintf(s,"g%d",gcount);
139  Tcl_SetResult(interp,s,TCL_VOLATILE);
140 
141  DebugM(4,"Group " << s << " added to config list\n");
142  return TCL_OK;
143 }
144 
145 /* this function is useless - it reconfigures whenever you add atoms! */
146 int GlobalMasterTcl::Tcl_reconfig(ClientData clientData,
147  Tcl_Interp *interp, int argc, const char **) {
148  DebugM(2,"Tcl_reconfig called\n");
149  if (argc != 1) {
150  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
151  return TCL_ERROR;
152  }
153  iout << iWARN << "'reconfig' is obsolete - reconfiguration is now automatic." << endi;
154  iout << iWARN << "Use 'clearconfig' to clear the list of atoms and groups." << endi;
155  DebugM(4,"Reconfiguration turned on\n");
156  return TCL_OK;
157 }
158 
159 int GlobalMasterTcl::Tcl_clearconfig(ClientData clientData,
160  Tcl_Interp *interp, int argc, const char **) {
161  DebugM(2,"Tcl_reconfig called\n");
162  if (argc != 1) {
163  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
164  return TCL_ERROR;
165  }
166  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
167  self->modifyRequestedGroups().resize(0);
168  self->modifyRequestedAtoms().resize(0);
169  return TCL_OK;
170 }
171 
172 int GlobalMasterTcl::Tcl_getstep(ClientData clientData,
173  Tcl_Interp *interp, int argc, const char **) {
174  DebugM(2,"Tcl_reconfig called\n");
175  if (argc != 1) {
176  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
177  return TCL_ERROR;
178  }
179  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
180 
181  char s[16]; sprintf(s,"%d",self->step);
182  Tcl_SetResult(interp,s,TCL_VOLATILE);
183  return TCL_OK;
184 }
185 
186 int GlobalMasterTcl::Tcl_loadforces(ClientData clientData,
187  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
188  DebugM(1,"Making tcl force array\n");
189  if(objc != 2) {
190  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
191  return TCL_ERROR;
192  }
193  Tcl_Obj * const force_array_name = objv[1];
194 
195  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
197  AtomIDList::const_iterator forced_ids_e = self->getLastAtomsForcedEnd();
198  ForceList::const_iterator forces_i = self->getLastForcesBegin();
199 
200  // plf -- changed 06/12/2008 to check for more than one force on each atom
201 
202  // now make a Tcl array containing all of the requested atoms and
203  // their forces
204  DebugM(1,"Making Tcl array\n");
205  while(forced_ids_i != forced_ids_e) {
206  Tcl_Obj *array_key = Tcl_NewIntObj((int)((*forced_ids_i)+1)); // the id
207  Tcl_IncrRefCount(array_key);
208 
209  // Check if the element is already defined, and if so, add to it
210  Tcl_Obj *oldlist = Tcl_ObjGetVar2(interp, force_array_name, array_key, 0);
211  Tcl_Obj *newlist = Tcl_NewListObj(0,NULL); // the list <fx,fy,fz>
212  if (oldlist == NULL) {
213  Tcl_ListObjAppendElement(interp, newlist,
214  Tcl_NewDoubleObj((double)((*forces_i).x)));
215  Tcl_ListObjAppendElement(interp, newlist,
216  Tcl_NewDoubleObj((double)((*forces_i).y)));
217  Tcl_ListObjAppendElement(interp, newlist,
218  Tcl_NewDoubleObj((double)((*forces_i).z)));
219  } else {
220  Tcl_Obj** old_elems;
221  int num_old_elems;
222  double currval = 0.0;
223  Tcl_ListObjGetElements(interp, oldlist, &num_old_elems, &old_elems);
224  if (num_old_elems != 3) {
225  NAMD_die("TCL error in loadforces! Force list doesn't have 3 elements!");
226  }
227  Tcl_GetDoubleFromObj(interp, old_elems[0], &currval);
228  Tcl_ListObjAppendElement(interp, newlist,
229  Tcl_NewDoubleObj((double)((*forces_i).x) + currval));
230  Tcl_GetDoubleFromObj(interp, old_elems[1], &currval);
231  Tcl_ListObjAppendElement(interp, newlist,
232  Tcl_NewDoubleObj((double)((*forces_i).y + currval)));
233  Tcl_GetDoubleFromObj(interp, old_elems[2], &currval);
234  Tcl_ListObjAppendElement(interp, newlist,
235  Tcl_NewDoubleObj((double)((*forces_i).z + currval)));
236  }
237 
238  // add the pair (id,F) to the array
239  if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
240  NAMD_die("TCL error in loadforces!");
241  return TCL_ERROR;
242  }
243 
244  Tcl_DecrRefCount(array_key);
245 
246  // go to the next atom
247  forced_ids_i++;
248  forces_i++;
249  }
250 
251  DebugM(1,"Done making tcl force array\n");
252  return TCL_OK;
253 }
254 
255 
256 int GlobalMasterTcl::Tcl_enabletotalforces(ClientData clientData,
257  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
258 {
259  DebugM(2,"Tcl_enabletotalforces called\n");
260  if (objc != 1) {
261  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
262  return TCL_ERROR;
263  }
264  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
265  self->requestTotalForce(true);
266  return TCL_OK;
267 }
268 
269 int GlobalMasterTcl::Tcl_disabletotalforces(ClientData clientData,
270  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
271 {
272  DebugM(2,"Tcl_disabletotalforces called\n");
273  if (objc != 1) {
274  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
275  return TCL_ERROR;
276  }
277  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
278  self->requestTotalForce(false);
279  return TCL_OK;
280 }
281 
282 
283 // Here I simply copied the code from "Tcl_loadforces" above. The
284 // only difference is the source data.
285 int GlobalMasterTcl::Tcl_loadtotalforces(ClientData clientData,
286  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
287 {
288  if(objc != 2)
289  { Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
290  return TCL_ERROR;
291  }
292  Tcl_Obj * const force_array_name = objv[1];
293 
294  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
295  if ( ! self->requestedTotalForces() ) {
296  Tcl_SetResult(interp,
297  (char*)"must call enabletotalforces before loadtotalforces",
298  TCL_VOLATILE);
299  return TCL_ERROR;
300  }
301 
302  AtomIDList::const_iterator forced_ids_i = self->getForceIdBegin();
303  AtomIDList::const_iterator forced_ids_e = self->getForceIdEnd();
304  ForceList::const_iterator forces_i = self->getTotalForce();
305 
306  // now make a Tcl array containing all of the requested atoms and
307  // their forces
308  while(forced_ids_i != forced_ids_e) {
309  Tcl_Obj *array_key = Tcl_NewIntObj((int)((*forced_ids_i)+1)); // the id
310  Tcl_IncrRefCount(array_key);
311  Tcl_Obj *newlist = Tcl_NewListObj(0,NULL); // the list <fx,fy,fz>
312  Tcl_ListObjAppendElement(interp, newlist,
313  Tcl_NewDoubleObj((double)((*forces_i).x)));
314  Tcl_ListObjAppendElement(interp, newlist,
315  Tcl_NewDoubleObj((double)((*forces_i).y)));
316  Tcl_ListObjAppendElement(interp, newlist,
317  Tcl_NewDoubleObj((double)((*forces_i).z)));
318 
319  // add the pair (id,F) to the array
320  if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
321  NAMD_die("TCL error in loadtotalforces!");
322  return TCL_ERROR;
323  }
324 
325  Tcl_DecrRefCount(array_key);
326 
327  // go to the next atom
328  forced_ids_i++;
329  forces_i++;
330  }
331 
332  /* do the group stuff */
333  ForceList::const_iterator tf_i = self->getGroupTotalForceBegin();
334  ForceList::const_iterator tf_e = self->getGroupTotalForceEnd();
335  int gcount = 1;
336  for ( ; tf_i != tf_e; ++tf_i, ++gcount ) {
337  Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
338  char buf[10];
339  sprintf(buf, "g%d", gcount);
340  Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
341  Tcl_IncrRefCount(arrkey);
342 
343  Tcl_ListObjAppendElement(interp, newlist,
344  Tcl_NewDoubleObj((double)((*tf_i).x)));
345  Tcl_ListObjAppendElement(interp, newlist,
346  Tcl_NewDoubleObj((double)((*tf_i).y)));
347  Tcl_ListObjAppendElement(interp, newlist,
348  Tcl_NewDoubleObj((double)((*tf_i).z)));
349 
350  if (!Tcl_ObjSetVar2(interp, force_array_name, arrkey, newlist, 0)) {
351  NAMD_die("TCL error in loadtotalforces for groups!");
352  return TCL_ERROR;
353  }
354  Tcl_DecrRefCount(arrkey);
355  }
356  return TCL_OK;
357 }
358 
359 
360 int GlobalMasterTcl::Tcl_loadcoords(ClientData clientData,
361  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
362  if (objc != 2) {
363  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
364  return TCL_ERROR;
365  }
366  Tcl_Obj * const vname = objv[1];
367  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
369  AtomIDList::const_iterator a_e = self->getAtomIdEnd();
370  PositionList::const_iterator p_i = self->getAtomPositionBegin();
371  for ( ; a_i != a_e; ++a_i, ++p_i ) {
372  Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
373  Tcl_Obj *arrkey = Tcl_NewIntObj((int)((*a_i)+1));
374  Tcl_IncrRefCount(arrkey);
375 
376  Tcl_ListObjAppendElement(interp, newlist,
377  Tcl_NewDoubleObj((double)((*p_i).x)));
378  Tcl_ListObjAppendElement(interp, newlist,
379  Tcl_NewDoubleObj((double)((*p_i).y)));
380  Tcl_ListObjAppendElement(interp, newlist,
381  Tcl_NewDoubleObj((double)((*p_i).z)));
382 
383  if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
384  NAMD_die("TCL error in global force calculation!");
385  return TCL_ERROR;
386  }
387  Tcl_DecrRefCount(arrkey);
388  }
389 
390  /* do the group stuff */
391  PositionList::const_iterator c_i = self->getGroupPositionBegin();
392  PositionList::const_iterator c_e = self->getGroupPositionEnd();
393  int gcount = 1;
394  for ( ; c_i != c_e; ++c_i, ++gcount ) {
395  Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
396  char buf[10];
397  sprintf(buf, "g%d", gcount);
398  Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
399  Tcl_IncrRefCount(arrkey);
400 
401  Tcl_ListObjAppendElement(interp, newlist,
402  Tcl_NewDoubleObj((double)((*c_i).x)));
403  Tcl_ListObjAppendElement(interp, newlist,
404  Tcl_NewDoubleObj((double)((*c_i).y)));
405  Tcl_ListObjAppendElement(interp, newlist,
406  Tcl_NewDoubleObj((double)((*c_i).z)));
407 
408  if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
409  NAMD_die("TCL error in global force calculation!");
410  return TCL_ERROR;
411  }
412  Tcl_DecrRefCount(arrkey);
413  }
414  return TCL_OK;
415 }
416 
417 
418 int GlobalMasterTcl::Tcl_loadmasses(ClientData clientData,
419  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
420  if (objc != 2) {
421  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
422  return TCL_ERROR;
423  }
424  Tcl_Obj * const vname = objv[1];
425  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
426  Molecule *mol = Node::Object()->molecule;
427  AtomIDList::const_iterator a_i = self->getAtomIdBegin();
428  AtomIDList::const_iterator a_e = self->getAtomIdEnd();
429  for ( ; a_i != a_e; ++a_i) {
430  Tcl_Obj *arrkey = Tcl_NewIntObj((int)((*a_i)+1));
431  Tcl_IncrRefCount(arrkey);
432  if (!Tcl_ObjSetVar2(interp, vname, arrkey,
433  Tcl_NewDoubleObj((double)(mol->atommass(*a_i))),
434  0)) {
435  NAMD_die("TCL error in global force calculation!");
436  return TCL_ERROR;
437  }
438  Tcl_DecrRefCount(arrkey);
439  }
440 
441  const BigReal *g_i, *g_e;
442  g_i = self->getGroupMassBegin();
443  g_e = self->getGroupMassEnd();
444  int gcount = 1;
445  for ( ; g_i != g_e; ++g_i, ++gcount) {
446  char buf[10];
447  sprintf(buf, "g%d", gcount);
448  Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
449  Tcl_IncrRefCount(arrkey);
450  if (!Tcl_ObjSetVar2(interp, vname, arrkey,
451  Tcl_NewDoubleObj((double)(*g_i)),
452  0)) {
453  NAMD_die("TCL error in global force calculation!");
454  return TCL_ERROR;
455  }
456  Tcl_DecrRefCount(arrkey);
457  }
458  return TCL_OK;
459 }
460 
461 
462 int GlobalMasterTcl::Tcl_addforce(ClientData clientData,
463  Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
464  DebugM(2,"Tcl_addforce called\n");
465  if (objc != 3) {
466  Tcl_SetResult(interp,(char*)"wrong # args",TCL_VOLATILE);
467  return TCL_ERROR;
468  }
469  Tcl_Obj **force; int fnum; int atomid; double x, y, z;
470  int isgroup = 0;
471  char *id = Tcl_GetStringFromObj(objv[1], NULL);
472  if ( id[0] == 'g' ) {
473  isgroup = 1;
474  if ( Tcl_GetInt(interp,id+1,&atomid) != TCL_OK ) return TCL_ERROR;
475  } else {
476  if ( Tcl_GetInt(interp,id,&atomid) != TCL_OK ) return TCL_ERROR;
477  }
478  if (Tcl_ListObjGetElements(interp, objv[2], &fnum, &force) != TCL_OK) {
479  return TCL_ERROR;
480  }
481  if ( (fnum != 3) ||
482  (Tcl_GetDoubleFromObj(interp, force[0],&x) != TCL_OK) ||
483  (Tcl_GetDoubleFromObj(interp, force[1],&y) != TCL_OK) ||
484  (Tcl_GetDoubleFromObj(interp, force[2],&z) != TCL_OK) ) {
485  Tcl_SetResult(interp,(char*)"force not a vector",TCL_VOLATILE);
486  return TCL_ERROR;
487  }
488 
489  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
490  if ( isgroup ) {
491  int ngrps = self->getGroupMassEnd() - self->getGroupMassBegin();
492  if ( atomid < 1 || atomid > ngrps ) {
493  Tcl_SetResult(interp,(char*)"requested group not available",TCL_VOLATILE);
494  return TCL_ERROR;
495  }
496  self->modifyGroupForces().item(atomid-1) += Vector(x,y,z);
497  } else {
498  self->modifyForcedAtoms().add(atomid-1);
499  self->modifyAppliedForces().add(Vector(x,y,z));
500  }
501  DebugM(4,"Atom ID " << atomid << " added to force list\n");
502  return TCL_OK;
503 }
504 
505 
506 int GlobalMasterTcl::Tcl_addenergy(ClientData clientData,
507  Tcl_Interp *interp, int argc, const char *argv[])
508 {
509  double energy;
510 
511  if (argc != 2)
512  return TCL_ERROR;
513  if (Tcl_GetDouble(interp,argv[1],&energy) != TCL_OK)
514  return TCL_ERROR;
515 
516  GlobalMasterTcl *self = (GlobalMasterTcl *)clientData;
517  self->reduction->item(REDUCTION_MISC_ENERGY) += energy;
518 
519  return TCL_OK;
520 }
521 #endif
522 
523 
525  DebugM(3,"Constructing GlobalMasterTcl\n");
526 #ifdef NAMD_TCL
527  interp = 0;
528 #endif
530  initialize();
531  DebugM(2,"Done constructing ("<<requestedGroups().size()<<" initial groups)\n");
532 }
533 
535  DebugM(3,"Destructing GlobalMasterTcl\n");
536 #ifdef NAMD_TCL
537 /*
538  if ( interp ) Tcl_DeleteInterp(interp);
539 */
540 #endif
541  delete reduction;
542 }
543 
544 
545 void GlobalMasterTcl::initialize() {
546  DebugM(4,"Initializing master\n");
547 #ifdef NAMD_TCL
548  DebugM(1,"here\n");
549  if(Node::Object() == NULL) NAMD_die("Node::Object() == NULL");
550  if(Node::Object()->getScript() == NULL)
551  NAMD_die("Node::Object()->getScript() == NULL");
552 
553  interp = Node::Object()->getScript()->interp;
554  DebugM(1,"here\n");
555 
556  Tcl_CreateCommand(interp, "atomid", Tcl_atomid,
557  (ClientData) (Node::Object()->molecule), (Tcl_CmdDeleteProc *) NULL);
558 
559  DebugM(1,"here\n");
560  // Call interpreter to determine requested atoms
561  Tcl_CreateCommand(interp, "addatom", Tcl_addatom,
562  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
563  Tcl_CreateCommand(interp, "addgroup", Tcl_addgroup,
564  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
565  Tcl_CreateObjCommand(interp, (char *)"enabletotalforces", Tcl_enabletotalforces,
566  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
567  Tcl_CreateObjCommand(interp, (char *)"disabletotalforces", Tcl_disabletotalforces,
568  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
569 
570  DebugM(1,"here\n");
571  // Get the script
572  StringList *script = Node::Object()->configList->find("tclForcesScript");
573 
574  DebugM(1,"here\n");
575  for ( ; script; script = script->next ) {
576  int code;
577  DebugM(1,"here "<<script->data<<"\n");
578  if ( strstr(script->data,"\n") ) {
579  code = Tcl_Eval(interp,script->data);
580  }
581  else code = Tcl_EvalFile(interp,script->data);
582  DebugM(1,"here\n");
583  const char *result = Tcl_GetStringResult(interp);
584  DebugM(1,"here\n");
585  if (*result != 0) CkPrintf("TCL: %s\n",result);
586  DebugM(1,"here\n");
587  if (code != TCL_OK) {
588  const char *errorInfo = Tcl_GetVar(interp,"errorInfo",0);
589  NAMD_die(errorInfo ? errorInfo : "Unknown Tcl error");
590  }
591  }
592 
593  DebugM(1,"here\n");
594  Tcl_CreateObjCommand(interp, (char *)"loadforces", Tcl_loadforces,
595  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
596  Tcl_CreateObjCommand(interp, (char *)"loadtotalforces", Tcl_loadtotalforces,
597  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
598  Tcl_CreateObjCommand(interp, (char *)"loadcoords", Tcl_loadcoords,
599  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
600  Tcl_CreateObjCommand(interp, (char *)"loadmasses", Tcl_loadmasses,
601  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
602  Tcl_CreateObjCommand(interp, (char *)"addforce", Tcl_addforce,
603  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
604  Tcl_CreateCommand(interp, (char *)"addenergy", Tcl_addenergy,
605  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
606  Tcl_CreateCommand(interp, (char *)"reconfig", Tcl_reconfig,
607  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
608  Tcl_CreateCommand(interp, (char *)"clearconfig", Tcl_clearconfig,
609  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
610  Tcl_CreateCommand(interp, (char *)"getstep", Tcl_getstep,
611  (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
612 #else
613 
614  NAMD_die("Sorry, tclForces is not available; built without TCL.");
615 
616 #endif
617  DebugM(2,"done initializing master\n");
618 }
619 
620 
622  DebugM(4,"Calculating forces on master\n");
623 
624  /* clear out the requested forces first! */
628  modifyGroupForces().setall(Vector(0,0,0));
629 
630 #ifdef NAMD_TCL
631  // Call interpreter to calculate forces
632 
633  char cmd[129]; int code;
634  strcpy(cmd,"calcforces"); code = Tcl_Eval(interp,cmd);
635  const char *result = Tcl_GetStringResult(interp);
636  if (*result != 0) CkPrintf("TCL: %s\n",result);
637  if (code != TCL_OK) {
638  const char *errorInfo = Tcl_GetVar(interp,"errorInfo",0);
639  NAMD_die(errorInfo ? errorInfo : "Unknown Tcl error");
640  }
641 #endif
642 
643  reduction->submit();
644 
645 }
static Node * Object()
Definition: Node.h:86
ForceList & modifyAppliedForces()
Definition: GlobalMaster.C:163
AtomIDList & modifyRequestedAtoms()
Definition: GlobalMaster.C:128
int size(void) const
Definition: ResizeArray.h:131
AtomIDList::const_iterator getAtomIdBegin()
Definition: GlobalMaster.C:191
Definition: Vector.h:72
BigReal & item(int i)
Definition: ReductionMgr.h:313
#define DebugM(x, y)
Definition: Debug.h:75
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
SubmitReduction * willSubmit(int setID, int size=-1)
Definition: ReductionMgr.C:366
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
static ReductionMgr * Object(void)
Definition: ReductionMgr.h:279
#define iout
Definition: InfoStream.h:51
int add(const Elem &elem)
Definition: ResizeArray.h:101
BigRealList::const_iterator getGroupMassEnd()
Definition: GlobalMaster.C:240
Molecule stores the structural information for the system.
Definition: Molecule.h:175
const ResizeArray< AtomIDList > & requestedGroups()
Definition: GlobalMaster.C:150
void resize(int i)
Definition: ResizeArray.h:84
void setall(const Elem &elem)
Definition: ResizeArray.h:94
int get_atom_from_name(const char *segid, int resid, const char *aname) const
Definition: Molecule.C:126
const Elem * const_iterator
Definition: ResizeArray.h:38
AtomIDList & modifyForcedAtoms()
Definition: GlobalMaster.C:158
int numAtoms
Definition: Molecule.h:585
ResizeArray< AtomIDList > & modifyRequestedGroups()
Definition: GlobalMaster.C:185
void NAMD_die(const char *err_msg)
Definition: common.C:147
BigRealList::const_iterator getGroupMassBegin()
Definition: GlobalMaster.C:235
ForceList & modifyGroupForces()
Definition: GlobalMaster.C:168
Real atommass(int anum) const
Definition: Molecule.h:1107
ConfigList * configList
Definition: Node.h:182
void requestTotalForce(bool yesno=true)
Definition: GlobalMaster.h:134
StringList * next
Definition: ConfigList.h:49
char * data
Definition: ConfigList.h:48
AtomIDList::const_iterator getLastAtomsForcedBegin()
Definition: GlobalMaster.C:244
ScriptTcl * getScript()
Definition: Node.C:1599
void submit(void)
Definition: ReductionMgr.h:324
virtual void calculate()
StringList * find(const char *name) const
Definition: ConfigList.C:341
Molecule * molecule
Definition: Node.h:179
double BigReal
Definition: common.h:123