diff --git a/src/MISC/fix_ipi.cpp b/src/MISC/fix_ipi.cpp index 30a6fe893d..80666790e2 100644 --- a/src/MISC/fix_ipi.cpp +++ b/src/MISC/fix_ipi.cpp @@ -48,6 +48,7 @@ using namespace FixConst; #ifndef _WIN32 #include #include +#include #include #include #include @@ -78,7 +79,7 @@ static void open_socket(int &sockfd, int inet, int port, char *host, Error *erro error: pointer to a LAMMPS Error object */ { - int ai_err; + int ai_err,flagNagle; #ifdef _WIN32 error->one(FLERR, "i-PI socket implementation requires UNIX environment"); @@ -100,6 +101,11 @@ static void open_socket(int &sockfd, int inet, int port, char *host, Error *erro sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) error->one(FLERR, "Error creating socket for fix ipi"); + // set TCP_NODELAY=1 to disable Nagle's algorithm as it slows down the small transactions for i-PI + flagNagle = 1; + int result_TCP = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flagNagle, sizeof(int)); + if (result_TCP < 0) { perror("Error setting TCP_NODELAY"); } + // makes connection if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) error->one(FLERR, "Error opening INET socket: wrong port or server unreachable"); @@ -182,6 +188,7 @@ FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), irregul master = (comm->me == 0) ? 1 : 0; inet = 1; reset_flag = 0; + firsttime = 1; int iarg = 5; while (iarg < narg) { @@ -247,6 +254,7 @@ void FixIPI::init() ipisock = 0; // TODO: should check for success in socket opening, // but the current open_socket routine dies brutally if unsuccessful + // tell lammps we have assigned a socket socketflag = 1; @@ -363,17 +371,40 @@ void FixIPI::initial_integrate(int /*vflag*/) // has to be be done before invoking Irregular::migrate_atoms() // since it requires atoms be inside simulation box + // folds atomic coordinates close to the origin if (domain->triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); domain->reset_box(); - if (domain->triclinic) domain->lamda2x(atom->nlocal); - // move atoms to new processors via irregular() // only needed if migrate_check() says an atom moves to far - if (domain->triclinic) domain->x2lamda(atom->nlocal); if (irregular->migrate_check()) irregular->migrate_atoms(); if (domain->triclinic) domain->lamda2x(atom->nlocal); + // ensures continuity of trajectories relative to the + // snapshot at neighbor list creation, minimizing the + // number of neighbor list updates + auto xhold = neighbor->get_xhold(); + if (xhold != NULL && !firsttime) { + // don't wrap if xhold is not used in the NL, or the + // first call (because the NL is initialized from the + // data file that might have nothing to do with the + // current structure + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + auto delx = x[i][0] - xhold[i][0]; + auto dely = x[i][1] - xhold[i][1]; + auto delz = x[i][2] - xhold[i][2]; + + domain->minimum_image(delx, dely, delz); + + x[i][0] = xhold[i][0] + delx; + x[i][1] = xhold[i][1] + dely; + x[i][2] = xhold[i][2] + delz; + } + } + } + firsttime = 0; + // check if kspace solver is used if (reset_flag && kspace_flag) { // reset kspace, pair, angles, ... b/c simulation box might have changed. @@ -452,6 +483,7 @@ void FixIPI::final_integrate() retstr[0]=0; if (master) { + // check for new messages while (true) { readbuffer(ipisock, header, MSGLEN, error); header[MSGLEN]=0; @@ -464,6 +496,7 @@ void FixIPI::final_integrate() error->one(FLERR, "Got EXIT message from i-PI. Now leaving!"); if (strcmp(header,"GETFORCE ") == 0) { + // return force and energy data writebuffer(ipisock,"FORCEREADY ",MSGLEN, error); writebuffer(ipisock,(char*) &pot,8, error); writebuffer(ipisock,(char*) &nat,4, error); @@ -478,5 +511,3 @@ void FixIPI::final_integrate() hasdata=0; } - - diff --git a/src/MISC/fix_ipi.h b/src/MISC/fix_ipi.h index de954c8578..31bd59b2fa 100644 --- a/src/MISC/fix_ipi.h +++ b/src/MISC/fix_ipi.h @@ -42,6 +42,7 @@ class FixIPI : public Fix { long bsize; int kspace_flag; int reset_flag; + int firsttime; private: class Irregular *irregular;