22 #define MIN_DEBUG_LEVEL 3
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);
40 int GlobalMasterTcl::Tcl_atomid(ClientData clientData,
41 Tcl_Interp *interp,
int argc,
const char *argv[]) {
43 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
46 const char *segid = argv[1];
48 if (Tcl_GetInt(interp,argv[2],&resid) != TCL_OK) {
51 const char *aname = argv[3];
57 Tcl_SetResult(interp,(
char*)
"atom not found",TCL_VOLATILE);
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");
69 int GlobalMasterTcl::Tcl_addatom(ClientData clientData,
70 Tcl_Interp *interp,
int argc,
const char *argv[]) {
71 DebugM(2,
"Tcl_addatom called\n");
73 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
77 if (Tcl_GetInt(interp,argv[1],&atomid) != TCL_OK) {
82 if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
84 sprintf(errmsg,
"illegal atomid %d",atomid);
85 Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
90 DebugM(4,
"Atom ID " << atomid <<
" added to config list\n");
95 int GlobalMasterTcl::Tcl_addgroup(ClientData clientData,
96 Tcl_Interp *interp,
int argc,
const char *argv[]) {
97 DebugM(2,
"Tcl_addgroup called\n");
99 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
107 int gcount = 1 + group_list.
size();
108 group_list.
resize(gcount);
111 int listc, i;
const char **listv;
112 if (Tcl_SplitList(interp,argv[1],&listc,&listv) != TCL_OK) {
119 for ( i = 0; i < listc; ++i ) {
121 if (Tcl_GetInt(interp,listv[i],&atomid) != TCL_OK) {
122 group_list.
resize(gcount-1);
123 Tcl_Free((
char*) listv);
126 if ( (atomid-1) < 0 || (atomid-1) >= numAtoms ) {
128 sprintf(errmsg,
"illegal atomid %d",atomid);
129 Tcl_SetResult(interp,errmsg,TCL_VOLATILE);
132 group_list[gcount-1].
add(atomid-1);
134 Tcl_Free((
char*) listv);
137 char s[16]; sprintf(s,
"g%d",gcount);
138 Tcl_SetResult(interp,s,TCL_VOLATILE);
140 DebugM(4,
"Group " << s <<
" added to config list\n");
145 int GlobalMasterTcl::Tcl_reconfig(ClientData clientData,
146 Tcl_Interp *interp,
int argc,
const char **) {
147 DebugM(2,
"Tcl_reconfig called\n");
149 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
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");
158 int GlobalMasterTcl::Tcl_clearconfig(ClientData clientData,
159 Tcl_Interp *interp,
int argc,
const char **) {
160 DebugM(2,
"Tcl_reconfig called\n");
162 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
167 self->modifyRequestedAtoms().resize(0);
171 int GlobalMasterTcl::Tcl_getstep(ClientData clientData,
172 Tcl_Interp *interp,
int argc,
const char **) {
173 DebugM(2,
"Tcl_reconfig called\n");
175 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
180 char s[16]; sprintf(s,
"%d",self->step);
181 Tcl_SetResult(interp,s,TCL_VOLATILE);
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");
189 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
192 Tcl_Obj *
const force_array_name = objv[1];
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));
206 Tcl_IncrRefCount(array_key);
209 Tcl_Obj *oldlist = Tcl_ObjGetVar2(interp, force_array_name, array_key, 0);
210 Tcl_Obj *newlist = Tcl_NewListObj(0,NULL);
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)));
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!");
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)));
238 if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
239 NAMD_die(
"TCL error in loadforces!");
243 Tcl_DecrRefCount(array_key);
250 DebugM(1,
"Done making tcl force array\n");
255 int GlobalMasterTcl::Tcl_enabletotalforces(ClientData clientData,
256 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[])
258 DebugM(2,
"Tcl_enabletotalforces called\n");
260 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
268 int GlobalMasterTcl::Tcl_disabletotalforces(ClientData clientData,
269 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[])
271 DebugM(2,
"Tcl_disabletotalforces called\n");
273 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
284 int GlobalMasterTcl::Tcl_loadtotalforces(ClientData clientData,
285 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[])
288 { Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
291 Tcl_Obj *
const force_array_name = objv[1];
294 if ( ! self->requestedTotalForces() ) {
295 Tcl_SetResult(interp,
296 (
char*)
"must call enabletotalforces before loadtotalforces",
307 while(forced_ids_i != forced_ids_e) {
308 Tcl_Obj *array_key = Tcl_NewIntObj((
int)((*forced_ids_i)+1));
309 Tcl_IncrRefCount(array_key);
310 Tcl_Obj *newlist = Tcl_NewListObj(0,NULL);
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)));
319 if (!Tcl_ObjSetVar2(interp, force_array_name, array_key, newlist, 0)) {
320 NAMD_die(
"TCL error in loadtotalforces!");
324 Tcl_DecrRefCount(array_key);
335 for ( ; tf_i != tf_e; ++tf_i, ++gcount ) {
336 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
338 sprintf(buf,
"g%d", gcount);
339 Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
340 Tcl_IncrRefCount(arrkey);
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)));
349 if (!Tcl_ObjSetVar2(interp, force_array_name, arrkey, newlist, 0)) {
350 NAMD_die(
"TCL error in loadtotalforces for groups!");
353 Tcl_DecrRefCount(arrkey);
359 int GlobalMasterTcl::Tcl_loadcoords(ClientData clientData,
360 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
362 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
365 Tcl_Obj *
const vname = objv[1];
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);
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)));
382 if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
383 NAMD_die(
"TCL error in global force calculation!");
386 Tcl_DecrRefCount(arrkey);
393 for ( ; c_i != c_e; ++c_i, ++gcount ) {
394 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
396 sprintf(buf,
"g%d", gcount);
397 Tcl_Obj *arrkey = Tcl_NewStringObj(buf, -1);
398 Tcl_IncrRefCount(arrkey);
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)));
407 if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0)) {
408 NAMD_die(
"TCL error in global force calculation!");
411 Tcl_DecrRefCount(arrkey);
417 int GlobalMasterTcl::Tcl_loadmasses(ClientData clientData,
418 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
420 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
423 Tcl_Obj *
const vname = objv[1];
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))),
434 NAMD_die(
"TCL error in global force calculation!");
437 Tcl_DecrRefCount(arrkey);
441 g_i =
self->getGroupMassBegin();
442 g_e =
self->getGroupMassEnd();
444 for ( ; g_i != g_e; ++g_i, ++gcount) {
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)),
452 NAMD_die(
"TCL error in global force calculation!");
455 Tcl_DecrRefCount(arrkey);
461 int GlobalMasterTcl::Tcl_addforce(ClientData clientData,
462 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
463 DebugM(2,
"Tcl_addforce called\n");
465 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
468 Tcl_Obj **force;
int fnum;
int atomid;
double x,
y,
z;
470 char *
id = Tcl_GetStringFromObj(objv[1], NULL);
471 if (
id[0] ==
'g' ) {
473 if ( Tcl_GetInt(interp,
id+1,&atomid) != TCL_OK )
return TCL_ERROR;
475 if ( Tcl_GetInt(interp,
id,&atomid) != TCL_OK )
return TCL_ERROR;
477 if (Tcl_ListObjGetElements(interp, objv[2], &fnum, &force) != TCL_OK) {
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);
491 if ( atomid < 1 || atomid > ngrps ) {
492 Tcl_SetResult(interp,(
char*)
"requested group not available",TCL_VOLATILE);
495 self->modifyGroupForces().item(atomid-1) +=
Vector(x,y,z);
497 self->modifyForcedAtoms().add(atomid-1);
498 self->modifyAppliedForces().add(
Vector(x,y,z));
500 DebugM(4,
"Atom ID " << atomid <<
" added to force list\n");
505 int GlobalMasterTcl::Tcl_addenergy(ClientData clientData,
506 Tcl_Interp *interp,
int argc,
const char *argv[])
512 if (Tcl_GetDouble(interp,argv[1],&energy) != TCL_OK)
524 DebugM(3,
"Constructing GlobalMasterTcl\n");
534 DebugM(3,
"Destructing GlobalMasterTcl\n");
544 void GlobalMasterTcl::initialize() {
545 DebugM(4,
"Initializing master\n");
550 NAMD_die(
"Node::Object()->getScript() == NULL");
555 Tcl_CreateCommand(interp,
"atomid", Tcl_atomid,
556 (ClientData) (
Node::Object()->molecule), (Tcl_CmdDeleteProc *) NULL);
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);
574 for ( ; script; script = script->
next ) {
577 if ( strstr(script->
data,
"\n") ) {
578 code = Tcl_Eval(interp,script->
data);
580 else code = Tcl_EvalFile(interp,script->
data);
582 const char *result = Tcl_GetStringResult(interp);
584 if (*result != 0) CkPrintf(
"TCL: %s\n",result);
586 if (code != TCL_OK) {
587 const char *errorInfo = Tcl_GetVar(interp,
"errorInfo",0);
588 NAMD_die(errorInfo ? errorInfo :
"Unknown Tcl error");
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);
613 NAMD_die(
"Sorry, tclForces is not available; built without TCL.");
616 DebugM(2,
"done initializing master\n");
621 DebugM(4,
"Calculating forces on master\n");
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");
int get_atom_from_name(const char *segid, int resid, const char *aname) const
ForceList & modifyAppliedForces()
AtomIDList & modifyRequestedAtoms()
const Elem * const_iterator
ScriptTcl * getScript(void)
AtomIDList::const_iterator getAtomIdBegin()
std::ostream & endi(std::ostream &s)
SubmitReduction * willSubmit(int setID, int size=-1)
std::ostream & iWARN(std::ostream &s)
static ReductionMgr * Object(void)
BigRealList::const_iterator getGroupMassEnd()
const ResizeArray< AtomIDList > & requestedGroups()
void setall(const Elem &elem)
AtomIDList & modifyForcedAtoms()
ResizeArray< AtomIDList > & modifyRequestedGroups()
void NAMD_die(const char *err_msg)
BigRealList::const_iterator getGroupMassBegin()
ForceList & modifyGroupForces()
int add(const Elem &elem)
void requestTotalForce(bool yesno=true)
AtomIDList::const_iterator getLastAtomsForcedBegin()
StringList * find(const char *name) const
Real atommass(int anum) const