19 #define WRAPMODE_PATCH 0 20 #define WRAPMODE_INPUT 1 21 #define WRAPMODE_CELL 2 22 #define WRAPMODE_NEAREST 3 36 if ( CkMyRank() && !
simParams->tclIsThreaded ) {
37 NAMD_die(
"Sorry, tclBC requires TCL to be built with --enable-threads to use multiple threads per process.");
40 interp = Tcl_CreateInterp();
43 Tcl_CreateCommand(interp,
"print", Tcl_print,
44 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
45 Tcl_CreateCommand(interp,
"wrapmode", Tcl_wrapmode,
46 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
47 Tcl_CreateObjCommand(interp,
"cleardrops", Tcl_cleardrops,
48 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
52 int code = Tcl_Eval(interp,
simParams->tclBCScript);
53 const char *result = Tcl_GetStringResult(interp);
54 if (result && *result != 0) CkPrintf(
"TCL: %s\n",result);
56 const char *errorInfo = Tcl_GetVar(interp,
"errorInfo",0);
57 NAMD_die(errorInfo ? errorInfo :
"Unknown Tcl error");
59 }
else NAMD_bug(
"tclBCScript pointer was NULL");
62 Tcl_CreateObjCommand(interp,
"dropatom", Tcl_dropatom,
63 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
64 Tcl_CreateObjCommand(interp,
"nextatom", Tcl_nextatom,
65 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
66 Tcl_CreateObjCommand(interp,
"getcoord", Tcl_getcoord,
67 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
68 Tcl_CreateObjCommand(interp,
"getcell", Tcl_getcell,
69 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
70 Tcl_CreateObjCommand(interp,
"getmass", Tcl_getmass,
71 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
72 Tcl_CreateObjCommand(interp,
"getcharge", Tcl_getcharge,
73 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
74 Tcl_CreateObjCommand(interp,
"getid", Tcl_getid,
75 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
76 Tcl_CreateObjCommand(interp,
"addforce", Tcl_addforce,
77 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
78 Tcl_CreateObjCommand(interp,
"addenergy", Tcl_addenergy,
79 (ClientData)
this, (Tcl_CmdDeleteProc *) NULL);
83 NAMD_die(
"Sorry, tclBC is not available; built without TCL.");
92 Tcl_DeleteInterp(interp);
102 const int step =
patchList[0].p->flags.step;
110 int code = Tcl_Eval(interp,cmd);
111 if (code != TCL_OK) {
112 const char *errorInfo = Tcl_GetVar(interp,
"errorInfo",0);
113 NAMD_die(errorInfo ? errorInfo :
"Unknown Tcl error");
116 NAMD_die(
"tclBCScript failed to call nextatom until failure");
127 int ComputeTclBC::Tcl_print(ClientData,
128 Tcl_Interp *,
int argc,
const char *argv[]) {
130 Tcl_DStringInit(&msg);
131 for (
int i = 1; i < argc; ++i ) {
132 Tcl_DStringAppend(&msg,
" ",-1);
133 Tcl_DStringAppend(&msg,argv[i],-1);
135 CkPrintf(
"TCL:%s\n",Tcl_DStringValue(&msg));
136 Tcl_DStringFree(&msg);
140 int ComputeTclBC::Tcl_wrapmode(ClientData clientData,
141 Tcl_Interp *interp,
int argc,
const char *argv[]) {
143 Tcl_SetResult(interp,(
char*)
"usage: wrapmode patch|input|cell|nearest",
150 else if ( ! strcmp(argv[1],
"input") ) self->wrapmode =
WRAPMODE_INPUT;
151 else if ( ! strcmp(argv[1],
"cell") ) self->wrapmode =
WRAPMODE_CELL;
154 Tcl_SetResult(interp,(
char*)
"usage: wrapmode patch|input|cell|nearest",
162 int ComputeTclBC::Tcl_cleardrops(ClientData clientData,
163 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
165 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
175 int ComputeTclBC::Tcl_dropatom(ClientData clientData,
176 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
178 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
182 if ( self->n_atom <= 0 ) {
183 Tcl_SetResult(interp,(
char*)
"no atom available",TCL_VOLATILE);
187 self->drops[
self->fullatoms[
self->i_atom].id] = 1;
192 int ComputeTclBC::Tcl_nextatom(ClientData clientData,
193 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
195 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
201 if (self->n_atom < -1) {
202 Tcl_SetObjResult(interp, Tcl_NewIntObj((
long)(0)));
207 do while ( self->n_atom < 0 || ++self->i_atom >= self->n_atom ) {
208 if ( self->n_atom < 0 ) {
209 self->ap =
self->ap.begin();
211 (*(
self->ap)).positionBox->close(&(self->atoms));
212 (*(
self->ap)).forceBox->close(&((*(self->ap)).r));
215 if ( self->ap == self->ap.end() ) {
217 Tcl_SetObjResult(interp, Tcl_NewIntObj((
long)(0)));
221 self->n_atom = (*(
self->ap)).p->getNumAtoms();
222 self->fullatoms = (*(
self->ap)).p->getAtomList().begin();
223 self->atoms = (*(
self->ap)).positionBox->open();
224 (*(
self->ap)).r = (*(
self->ap)).forceBox->open();
226 }
while ( self->drops[self->fullatoms[self->i_atom].id] );
228 Tcl_SetObjResult(interp, Tcl_NewIntObj((
long)(1)));
232 int ComputeTclBC::Tcl_getcoord(ClientData clientData,
233 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
235 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
239 if ( self->n_atom <= 0 ) {
240 Tcl_SetResult(interp,(
char*)
"no atom available",TCL_VOLATILE);
244 int i =
self->i_atom;
245 Position pos =
self->atoms[i].position;
246 switch ( self->wrapmode ) {
250 pos =
self->lattice->reverse_transform(pos,self->fullatoms[i].transform);
253 pos +=
self->lattice->wrap_delta(pos);
256 pos +=
self->lattice->wrap_nearest_delta(pos);
260 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
261 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(pos.
x)));
262 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(pos.
y)));
263 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(pos.
z)));
264 Tcl_SetObjResult(interp, newlist);
268 int ComputeTclBC::Tcl_getcell(ClientData clientData,
269 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
271 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
276 Tcl_Obj *newcell = Tcl_NewListObj(0, NULL);
277 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
278 Vector o(self->lattice->origin());
279 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(o.x)));
280 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(o.y)));
281 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(o.z)));
282 Tcl_ListObjAppendElement(interp, newcell, newlist);
283 if (self->lattice->a_p()) {
284 newlist = Tcl_NewListObj(0, NULL);
285 Vector a(self->lattice->a());
286 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(a.x)));
287 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(a.y)));
288 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(a.z)));
289 Tcl_ListObjAppendElement(interp, newcell, newlist);
291 if (self->lattice->b_p()) {
292 newlist = Tcl_NewListObj(0, NULL);
293 Vector b(self->lattice->b());
294 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(b.x)));
295 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(b.y)));
296 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(b.z)));
297 Tcl_ListObjAppendElement(interp, newcell, newlist);
299 if (self->lattice->c_p()) {
300 newlist = Tcl_NewListObj(0, NULL);
301 Vector c(self->lattice->c());
302 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(c.x)));
303 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(c.y)));
304 Tcl_ListObjAppendElement(interp, newlist, Tcl_NewDoubleObj((
double)(c.z)));
305 Tcl_ListObjAppendElement(interp, newcell, newlist);
307 Tcl_SetObjResult(interp, newcell);
311 int ComputeTclBC::Tcl_getmass(ClientData clientData,
312 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
314 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
318 if ( self->n_atom <= 0 ) {
319 Tcl_SetResult(interp,(
char*)
"no atom available",TCL_VOLATILE);
323 int i =
self->i_atom;
324 Tcl_SetObjResult(interp, Tcl_NewDoubleObj((
double)(self->fullatoms[i].mass)));
328 int ComputeTclBC::Tcl_getcharge(ClientData clientData,
329 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
331 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
335 if ( self->n_atom <= 0 ) {
336 Tcl_SetResult(interp,(
char*)
"no atom available",TCL_VOLATILE);
340 int i =
self->i_atom;
341 Tcl_SetObjResult(interp, Tcl_NewDoubleObj((
double)(self->atoms[i].charge)));
345 int ComputeTclBC::Tcl_getid(ClientData clientData,
346 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
348 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
352 if ( self->n_atom <= 0 ) {
353 Tcl_SetResult(interp,(
char*)
"no atom available",TCL_VOLATILE);
357 int i =
self->i_atom;
358 Tcl_SetObjResult(interp, Tcl_NewIntObj((
long)(self->fullatoms[i].id + 1)));
362 int ComputeTclBC::Tcl_addforce(ClientData clientData,
363 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
365 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
369 Tcl_Obj **force;
int fnum;
double x,y,z;
370 if (Tcl_ListObjGetElements(interp, objv[1], &fnum, &force) != TCL_OK) {
374 (Tcl_GetDoubleFromObj(interp, force[0],&x) != TCL_OK) ||
375 (Tcl_GetDoubleFromObj(interp, force[1],&y) != TCL_OK) ||
376 (Tcl_GetDoubleFromObj(interp, force[2],&z) != TCL_OK) ) {
377 Tcl_SetResult(interp,(
char*)
"force not a vector",TCL_VOLATILE);
382 if ( self->n_atom <= 0 ) {
383 Tcl_SetResult(interp,(
char*)
"no atom available",TCL_VOLATILE);
386 int i =
self->i_atom;
387 self->forces[i].x += x;
388 self->forces[i].y += y;
389 self->forces[i].z += z;
394 int ComputeTclBC::Tcl_addenergy(ClientData clientData,
395 Tcl_Interp *interp,
int objc, Tcl_Obj *
const objv[]) {
397 Tcl_SetResult(interp,(
char*)
"wrong # args",TCL_VOLATILE);
402 if ( Tcl_GetDoubleFromObj(interp, objv[1], &energy) != TCL_OK ) {
403 Tcl_SetResult(interp,(
char*)
"energy not a number",TCL_VOLATILE);
408 self->energy += energy;
SimParameters * simParameters
ComputeHomePatchList patchList
SubmitReduction * willSubmit(int setID, int size=-1)
static ReductionMgr * Object(void)
void NAMD_bug(const char *err_msg)
void NAMD_die(const char *err_msg)
int tcl_vector_math_init(Tcl_Interp *interp)
ComputeTclBC(ComputeID c)