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