From d0f02811f2e792dae9c48f78c6020f6804740c47 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 16 Nov 2009 21:48:47 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@3410 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-IMD/fix_imd.cpp | 166 ++++++++++++++++++++++----------------- src/USER-IMD/fix_imd.h | 4 + 2 files changed, 100 insertions(+), 70 deletions(-) diff --git a/src/USER-IMD/fix_imd.cpp b/src/USER-IMD/fix_imd.cpp index 01c84798d2..22d567fb9b 100644 --- a/src/USER-IMD/fix_imd.cpp +++ b/src/USER-IMD/fix_imd.cpp @@ -234,6 +234,8 @@ FixIMD::FixIMD(LAMMPS *lmp, int narg, char **arg) : /* default values for optional flags */ unwrap_flag = 0; + nowait_flag = 0; + connect_msg = 1; imd_fscale = 1.0; imd_trate = 1; @@ -246,6 +248,12 @@ FixIMD::FixIMD(LAMMPS *lmp, int narg, char **arg) : } else { unwrap_flag = 0; } + } else if (0 == strcmp(arg[argsdone], "nowait")) { + if (0 == strcmp(arg[argsdone+1], "on")) { + nowait_flag = 1; + } else { + nowait_flag = 0; + } } else if (0 == strcmp(arg[argsdone], "fscale")) { imd_fscale = atof(arg[argsdone+1]); } else if (0 == strcmp(arg[argsdone], "trate")) { @@ -337,6 +345,72 @@ void FixIMD::init() return; } +/* ---------------------------------------------------------------------- */ + +/* (re-)connect to an IMD client (e.g. VMD). return 1 if + new connection was made, 0 if not. */ +int FixIMD::reconnect() +{ + /* set up IMD communication. */ + imd_terminate = 0; + imd_inactive = 0; + + if (me == 0) { + if (screen && connect_msg) + if (nowait_flag) + fprintf(screen,"Listening for IMD connection on port %d.\n",imd_port); + else + fprintf(screen,"Waiting for IMD connection on port %d.\n",imd_port); + + connect_msg = 0; + clientsock = NULL; + if (nowait_flag) { + int retval = imdsock_selread(localsock,0); + if (retval > 0) { + clientsock = imdsock_accept(localsock); + } else { + imd_inactive = 1; + return 0; + } + } else { + int retval=0; + do { + retval = imdsock_selread(localsock, 60); + } while (retval <= 0); + clientsock = imdsock_accept(localsock); + } + + if (!imd_inactive && !clientsock) { + if (screen) + fprintf(screen, "IMD socket accept error. Dropping connection.\n"); + imd_terminate = 1; + return 0; + } else { + /* check endianness and IMD protocol version. */ + if (imd_handshake(clientsock)) { + if (screen) + fprintf(screen, "IMD handshake error. Dropping connection.\n"); + imdsock_destroy(clientsock); + imd_terminate = 1; + return 0; + } else { + int32 length; + if (imdsock_selread(clientsock, 1) != 1 || + imd_recv_header(clientsock, &length) != IMD_GO) { + if (screen) + fprintf(screen, "Incompatible IMD client version? Dropping connection.\n"); + imdsock_destroy(clientsock); + imd_terminate = 1; + return 0; + } else { + return 1; + } + } + } + } + return 0; +} + /* ---------------------------------------------------------------------- */ /* wait for IMD client (e.g. VMD) to respond, initialize communication * buffers and collect tag/id maps. */ @@ -359,40 +433,9 @@ void FixIMD::setup(int) maxbuf = nmax*size_one; comm_buf = memory->smalloc(maxbuf,"imd:comm_buf"); - /* set up IMD communication. */ - if (me == 0) { - if (screen) - fprintf(screen,"Waiting for IMD connection on port %d.\n",imd_port); - - int retval=0; - do { - retval = imdsock_selread(localsock, 60); - } while (retval <= 0); - clientsock = imdsock_accept(localsock); - - if (!clientsock) { - if (screen) - fprintf(screen, "IMD socket accept error. Dropping connection.\n"); - imd_terminate = 1; - } else { - /* check endianness and IMD protocol version. */ - if (imd_handshake(clientsock)) { - if (screen) - fprintf(screen, "IMD handshake error. Dropping connection.\n"); - imdsock_destroy(clientsock); - imd_terminate = 1; - } else { - int32 length; - if (imdsock_selread(clientsock, 1) != 1 || - imd_recv_header(clientsock, &length) != IMD_GO) { - if (screen) - fprintf(screen, "Incompatible IMD client version? Dropping connection.\n"); - imdsock_destroy(clientsock); - imd_terminate = 1; - } - } - } - } + connect_msg = 1; + reconnect(); + MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world); MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world); if (imd_terminate) error->all("LAMMPS terminated on error in setting up IMD connection."); @@ -464,7 +507,16 @@ void FixIMD::setup(int) * Send coodinates, energies, and add IMD forces to atoms. */ void FixIMD::post_force(int vflag) { - if (imd_inactive) return; /* IMD client has detached. do nothing. */ + /* check for reconnect */ + if (imd_inactive) { + reconnect(); + MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world); + MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world); + if (imd_terminate) + error->all("LAMMPS terminated on error in setting up IMD connection."); + if (imd_inactive) + return; /* IMD client has detached and not yet come back. do nothing. */ + } int *tag = atom->tag; double **x = atom->x; @@ -614,37 +666,11 @@ void FixIMD::post_force(int vflag) force_buf = NULL; imdsock_destroy(clientsock); clientsock = NULL; - if (screen) { + if (screen) fprintf(screen, "IMD client detached. LAMMPS run continues.\n"); - fprintf(screen, "Waiting for new IMD connection on port %d.\n",imd_port); - } - int retval=0; - do { - retval = imdsock_selread(localsock, 60); - } while (retval <= 0); - clientsock = imdsock_accept(localsock); - if (!clientsock) { - if (screen) - fprintf(screen, "IMD socket accept error. Dropping connection.\n"); - imd_terminate = 1; - } else { - /* check endianness and IMD protocol version. */ - if (imd_handshake(clientsock)) { - if (screen) - fprintf(screen, "IMD handshake error. Dropping connection.\n"); - imdsock_destroy(clientsock); - imd_terminate = 1; - } else { - int32 length; - if (imdsock_selread(clientsock, 1) != 1 || - imd_recv_header(clientsock, &length) != IMD_GO) { - if (screen) - fprintf(screen, "Incompatible IMD client version? Dropping connection.\n"); - imdsock_destroy(clientsock); - imd_terminate = 1; - } - } - } + + connect_msg = 1; + reconnect(); if (imd_terminate) imd_inactive = 1; break; } @@ -708,11 +734,11 @@ void FixIMD::post_force(int vflag) buf = static_cast(force_buf); /* compare data to hash table */ - for (int i=0; i < length; ++i) { - buf[i].tag = rev_idmap[imd_tags[i]]; - buf[i].x = imd_fdat[3*i]; - buf[i].y = imd_fdat[3*i+1]; - buf[i].z = imd_fdat[3*i+2]; + for (int ii=0; ii < length; ++ii) { + buf[ii].tag = rev_idmap[imd_tags[ii]]; + buf[ii].x = imd_fdat[3*ii]; + buf[ii].y = imd_fdat[3*ii+1]; + buf[ii].z = imd_fdat[3*ii+2]; } delete[] imd_tags; delete[] imd_fdat; diff --git a/src/USER-IMD/fix_imd.h b/src/USER-IMD/fix_imd.h index 2c0d0213e1..906d8e7f8f 100644 --- a/src/USER-IMD/fix_imd.h +++ b/src/USER-IMD/fix_imd.h @@ -80,9 +80,13 @@ class FixIMD : public Fix { int imd_trate; // IMD transmission rate. int unwrap_flag; // true if coordinates need to be unwrapped before sending + int nowait_flag; // true if LAMMPS should not wait with the execution for VMD. + int connect_msg; // flag to indicate whether a "listen for connection message" is needed. int me; // my MPI rank in this "world". int nlevels_respa; // flag to determine respa levels. + + int reconnect(); }; }