void IMD::calculate(){ if(comm.Get_rank()==0 && connected && plumed.getStep()%transferRate==0 && vmdsock_selwrite(clientsock,0)) { double scale=10.0*plumed.getAtoms().getUnits().getLength(); Vector ref; for(int i=0;i<natoms;i++){ Vector pos=getPosition(i); if(wrap) pos=pbcDistance(ref,pos); coord[3*i+0]=static_cast<float>((pos[0]*scale)); coord[3*i+1]=static_cast<float>((pos[1]*scale)); coord[3*i+2]=static_cast<float>((pos[2]*scale)); } imd_send_fcoords(clientsock,natoms,&coord[0]); } }
int tclcommand_imd_parse_pos(Tcl_Interp *interp, int argc, char **argv) { enum flag {NONE, UNFOLDED, FOLD_CHAINS}; double shift[3] = {0.0,0.0,0.0}; //double part_selected=n_total_particles; float *coord; int flag = NONE; int i, j; // Determine how many arguments we have and set the value of flag switch (argc) { case 2: flag = NONE; break; case 3: { if (ARG_IS_S(2,"-unfolded")) {flag = UNFOLDED;} else if (ARG_IS_S(2,"-fold_chains")) {flag = FOLD_CHAINS;} else{ Tcl_AppendResult(interp, "wrong flag to",argv[0], " positions: should be \" -fold_chains or -unfolded \"", (char *) NULL); return (TCL_ERROR); } } break; default: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " positions [-flag]\"", (char *) NULL); return (TCL_ERROR); } if (!initsock) { Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); } if (!sock) { if (tclcommand_imd_print_check_connect(interp) == TCL_ERROR) return (TCL_ERROR); /* no VMD is ok, but tell the user */ if (!sock) { Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); } } if (tclcommand_imd_print_drain_socket(interp) == TCL_ERROR) return (TCL_ERROR); /* we do not consider a non connected VMD as error, but tell the user */ if (!sock) { Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); } if (!(vmdsock_selwrite(sock, 60) > 0)) { Tcl_AppendResult(interp, "could not write to IMD socket.", (char *) NULL); return (TCL_ERROR); } if (n_part != max_seen_particle + 1) { Tcl_AppendResult(interp, "for IMD, store particles consecutively starting with 0.", (char *) NULL); return (TCL_ERROR); } updatePartCfg(WITH_BONDS); coord = (float*)Utils::malloc(n_part*3*sizeof(float)); /* sort partcles according to identities */ for (i = 0; i < n_part; i++) { int dummy[3] = {0,0,0}; double tmpCoord[3]; tmpCoord[0] = partCfg[i].r.p[0]; tmpCoord[1] = partCfg[i].r.p[1]; tmpCoord[2] = partCfg[i].r.p[2]; if (flag == NONE) { // perform folding by particle fold_position(tmpCoord, dummy); } j = 3*partCfg[i].p.identity; coord[j ] = tmpCoord[0]; coord[j + 1] = tmpCoord[1]; coord[j + 2] = tmpCoord[2]; } // Use information from the analyse set command to fold chain molecules if ( flag == FOLD_CHAINS ){ if(analyze_fold_molecules(coord, shift ) != TCL_OK){ Tcl_AppendResult(interp, "could not fold chains: \"analyze set chains <chain_start> <n_chains> <chain_length>\" must be used first", (char *) NULL); return (TCL_ERROR); } } if (imd_send_fcoords(sock, n_part, coord)) { Tcl_AppendResult(interp, "could not write to IMD socket.", (char *) NULL); return (TCL_ERROR); } free(coord); Tcl_AppendResult(interp, "connected", (char *) NULL); return (TCL_OK); }
void *VMDCollab::serverproc(void *serversock) { ResizeArray<void *>clients; char buf[VMDCOLLAB_MSGSIZE]; int i, j; while (1) { // if we have no clients, hang until someone connects // otherwise, just check for pending connections if (vmdsock_selread(serversock, 0) > 0) { msgInfo << "serversock became readable" << sendmsg; void *clientsock = vmdsock_accept(serversock); if (clientsock) { msgInfo << "VMDCollab accepting connection" << sendmsg; clients.append(clientsock); } } else if (vmdsock_selwrite(serversock, 0)) { msgInfo << "serversock became writable; exiting..." << sendmsg; break; } // Loop through one socket at a time. If incoming data is found, // drain it before moving on, on the assumption that we only want // commands from one VMD at a time to be propagated to the other // clients. for (i=0; i<clients.num(); i++) { void *client = clients[i]; while (vmdsock_selread(client, 0) > 0) { memset(buf, 0, VMDCOLLAB_MSGSIZE); if (imd_readn(client, buf, VMDCOLLAB_MSGSIZE) != VMDCOLLAB_MSGSIZE) { msgInfo << "client sent incomplete message, shutting it down" << sendmsg; vmdsock_shutdown(client); vmdsock_destroy(client); clients.remove(clients.find(client)); break; } // send to all other clients for (j=0; j<clients.num(); j++) { void *dest = clients[j]; if (dest != client) { imd_writen(clients[j], buf, VMDCOLLAB_MSGSIZE); } } // loop over clients other than sender } // while client is readable } // loop over clients vmd_msleep(10); } // if here, then the serversock got shut down, indicating that it's // time to die. msgInfo << "VMDCollab shutting down server" << sendmsg; for (i=0; i<clients.num(); i++) { void *client = clients[i]; strcpy(buf, "exit"); imd_writen(client, buf, VMDCOLLAB_MSGSIZE); vmdsock_shutdown(client); vmdsock_destroy(client); } vmdsock_destroy(serversock); return NULL; }