diff --git a/doc/src/fix_ipi.rst b/doc/src/fix_ipi.rst index 6a6ff9aa87..5e13d25971 100644 --- a/doc/src/fix_ipi.rst +++ b/doc/src/fix_ipi.rst @@ -90,6 +90,12 @@ coordinates are transferred. However, one could use this strategy to define an external potential acting on the atoms that are moved by i-PI. +Since the i-PI code uses atomic units internally, this fix needs to +convert LAMMPS data to and from its :doc:`specified units ` +accordingly when communicating with i-PI. This is not possible for +reduced units ("units lj") and thus *fix ipi* will stop with an error in +this case. + This fix is part of the MISC package. It is only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 9735284280..838b9812ad 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -156,6 +156,8 @@ This fix is part of the REPLICA package. It is only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +Fix pid cannot be used with :doc:`lj units `. + A PIMD simulation can be initialized with a single data file read via the :doc:`read_data ` command. However, this means all quasi-beads in a ring polymer will have identical positions and diff --git a/src/MISC/fix_ipi.cpp b/src/MISC/fix_ipi.cpp index c84607d0af..039ec225d7 100644 --- a/src/MISC/fix_ipi.cpp +++ b/src/MISC/fix_ipi.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -47,12 +46,12 @@ using namespace FixConst; // socket interface #ifndef _WIN32 -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #else #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -65,8 +64,7 @@ using namespace FixConst; /* Utility functions to simplify the interface with POSIX sockets */ -static void open_socket(int &sockfd, int inet, int port, char* host, - Error *error) +static void open_socket(int &sockfd, int inet, int port, char *host, Error *error) /* Opens a socket. Args: @@ -83,9 +81,9 @@ static void open_socket(int &sockfd, int inet, int port, char* host, int ai_err; #ifdef _WIN32 - error->one(FLERR,"i-PI socket implementation requires UNIX environment"); + error->one(FLERR, "i-PI socket implementation requires UNIX environment"); #else - if (inet>0) { // creates an internet socket + if (inet > 0) { // creates an internet socket // fetches information on the host struct addrinfo hints, *res; @@ -96,40 +94,39 @@ static void open_socket(int &sockfd, int inet, int port, char* host, hints.ai_flags = AI_PASSIVE; ai_err = getaddrinfo(host, std::to_string(port).c_str(), &hints, &res); - if (ai_err!=0) - error->one(FLERR,"Error fetching host data. Wrong host name?"); + if (ai_err != 0) error->one(FLERR, "Error fetching host data. Wrong host name?"); // creates socket sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sockfd < 0) - error->one(FLERR,"Error opening socket"); + if (sockfd < 0) error->one(FLERR, "Error opening socket"); // makes connection if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) - error->one(FLERR,"Error opening INET socket: wrong port or server unreachable"); + error->one(FLERR, "Error opening INET socket: wrong port or server unreachable"); freeaddrinfo(res); - } else { // creates a unix socket + } else { // creates a unix socket struct sockaddr_un serv_addr; // fills up details of the socket address memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sun_family = AF_UNIX; strcpy(serv_addr.sun_path, "/tmp/ipi_"); - strcpy(serv_addr.sun_path+9, host); + strcpy(serv_addr.sun_path + 9, host); // creates the socket sockfd = socket(AF_UNIX, SOCK_STREAM, 0); // connects if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - error->one(FLERR,"Error opening UNIX socket: server may not be running " + error->one(FLERR, + "Error opening UNIX socket: server may not be running " "or the path to the socket unavailable"); } #endif } -static void writebuffer(int sockfd, const char *data, int len, Error* error) +static void writebuffer(int sockfd, const char *data, int len, Error *error) /* Writes to a socket. Args: @@ -140,14 +137,11 @@ static void writebuffer(int sockfd, const char *data, int len, Error* error) { int n; - n = write(sockfd,data,len); - if (n < 0) - error->one(FLERR,"Error writing to socket: broken connection"); + n = write(sockfd, data, len); + if (n < 0) error->one(FLERR, "Error writing to socket: broken connection"); } - - -static void readbuffer(int sockfd, char *data, int len, Error* error) +static void readbuffer(int sockfd, char *data, int len, Error *error) /* Reads from a socket. Args: @@ -158,44 +152,52 @@ static void readbuffer(int sockfd, char *data, int len, Error* error) { int n, nr; - n = nr = read(sockfd,data,len); + n = nr = read(sockfd, data, len); - while (nr>0 && n 0 && n < len) { + nr = read(sockfd, &data[n], len - n); + n += nr; } - if (n == 0) - error->one(FLERR,"Error reading from socket: broken connection"); + if (n == 0) error->one(FLERR, "Error reading from socket: broken connection"); } /* ---------------------------------------------------------------------- */ -FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), irregular(nullptr) +FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), irregular(nullptr) { - /* format for fix: - * fix num group_id ipi host port [unix] - */ - if (strcmp(style,"ipi") != 0 && narg < 5) - error->all(FLERR,"Illegal fix ipi command"); + if (narg < 5) utils::missing_cmd_args(FLERR, "fix ipi", error); - if (atom->tag_enable == 0) - error->all(FLERR,"Cannot use fix ipi without atom IDs"); + if (atom->tag_enable == 0) error->all(FLERR, "Cannot use fix ipi without atom IDs"); + if (atom->tag_consecutive() == 0) error->all(FLERR, "Fix ipi requires consecutive atom IDs"); + if (strcmp(update->unit_style, "lj") == 0) error->all(FLERR, "Fix ipi does not support lj units"); - if (atom->tag_consecutive() == 0) - error->all(FLERR,"Fix ipi requires consecutive atom IDs"); - - if (strcmp(arg[1],"all") != 0) - error->warning(FLERR,"Fix ipi always uses group all"); + if ((strcmp(arg[1], "all") != 0) && (comm->me == 0)) + error->warning(FLERR, "Not using group 'all' with fix ipi can result in undefined behavior"); host = strdup(arg[3]); - port = utils::inumeric(FLERR,arg[4],false,lmp); + port = utils::inumeric(FLERR, arg[4], false, lmp); - inet = ((narg > 5) && (strcmp(arg[5],"unix") == 0) ) ? 0 : 1; - master = (comm->me==0) ? 1 : 0; - // check if forces should be reinitialized and set flag - reset_flag = ((narg > 6 && (strcmp(arg[5],"reset") == 0 )) || ((narg > 5) && (strcmp(arg[5],"reset") == 0)) ) ? 1 : 0; + master = (comm->me == 0) ? 1 : 0; + inet = 1; + reset_flag = 0; + + int iarg = 5; + while (iarg < narg) { + if (strcmp(arg[iarg], "unix") == 0) { + inet = 0; + ++iarg; + } else if (strcmp(arg[iarg], "reset") == 0) { + reset_flag = 1; + ++iarg; + } else { + error->all(FLERR, "Unknown fix ipi keyword: {}", arg[iarg]); + } + } + + // sanity check + if (inet && ((port <= 1024) || (port > 65536))) + error->all(FLERR, "Invalid port for fix ipi: {}", port); hasdata = bsize = 0; @@ -223,7 +225,6 @@ FixIPI::~FixIPI() delete irregular; } - /* ---------------------------------------------------------------------- */ int FixIPI::setmask() @@ -240,9 +241,11 @@ void FixIPI::init() { //only opens socket on master process if (master) { - if (!socketflag) open_socket(ipisock, inet, port, host, error); - } else ipisock=0; - //! should check for success in socket opening -- but the current open_socket routine dies brutally if unsuccessful + if (!socketflag) open_socket(ipisock, inet, port, host, error); + } else + 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; @@ -252,11 +255,13 @@ void FixIPI::init() kspace_flag = (force->kspace) ? 1 : 0; - // makes sure that neighbor lists are re-built at each step (cannot make assumptions when cycling over beads!) + // makes sure that neighbor lists are re-built at each step + // (cannot make assumptions when cycling over beads!) neighbor->delay = 0; neighbor->every = 1; } +// clang-format off void FixIPI::initial_integrate(int /*vflag*/) { /* This is called at the beginning of the integration loop, diff --git a/src/REPLICA/fix_pimd.cpp b/src/REPLICA/fix_pimd.cpp index 969d412b89..40e203d3c2 100644 --- a/src/REPLICA/fix_pimd.cpp +++ b/src/REPLICA/fix_pimd.cpp @@ -102,6 +102,9 @@ FixPIMD::FixPIMD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) error->universe_all(FLERR, fmt::format("Unknown keyword {} for fix pimd", arg[i])); } + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Fix pimd does not support lj units"); + /* Initiation */ size_peratom_cols = 12 * nhc_nchain + 3;