Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 38 additions & 11 deletions src/MISC/fix_ipi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "kspace.h"
#include "modify.h"
#include "neighbor.h"
#include "timer.h"
#include "update.h"

#include <cstring>
Expand Down Expand Up @@ -208,6 +209,7 @@ FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), irregul
error->all(FLERR, "Invalid port for fix ipi: {}", port);

hasdata = bsize = 0;
exit_flag = 0;

// creates a temperature compute for all atoms
modify->add_compute("IPI_TEMP all temp");
Expand Down Expand Up @@ -302,12 +304,11 @@ void FixIPI::initial_integrate(int /*vflag*/)
else break;
}

if (strcmp(header,"EXIT ") == 0)
error->one(FLERR, "Got EXIT message from i-PI. Now leaving!");

// when i-PI signals it has positions to evaluate new forces,
// read positions and cell data
if (strcmp(header,"POSDATA ") == 0) {
// on EXIT set nat to -1 so all ranks can break out of
// the run loop cleanly (via timer->force_timeout)
if (strcmp(header,"EXIT ") == 0) {
nat = -1;
} else if (strcmp(header,"POSDATA ") == 0) {
readbuffer(ipisock, (char*) cellh, 9*8, error);
readbuffer(ipisock, (char*) cellih, 9*8, error);
readbuffer(ipisock, (char*) &nat, 4, error);
Expand All @@ -327,6 +328,16 @@ void FixIPI::initial_integrate(int /*vflag*/)

// shares the atomic coordinates with everyone
MPI_Bcast(&nat,1,MPI_INT,0,world);

// trigger a clean run termination so the main loop breaks out and
// Finish::end() can be triggered. exit_flag is set so final_integrate
// no-ops.
if (nat == -1) {
timer->force_timeout();
exit_flag = 1;
return;
}

// must also allocate the buffer on the non-head nodes
if (bsize==0) {
bsize=3*nat;
Expand Down Expand Up @@ -373,7 +384,7 @@ void FixIPI::initial_integrate(int /*vflag*/)

// ensure atoms are in current box & update box via shrink-wrap
// has to be be done before invoking Irregular::migrate_atoms()
// since it requires atoms be inside simulation box
// since it requires atoms be inside simulation box

// folds atomic coordinates close to the origin
if (domain->triclinic) domain->x2lamda(atom->nlocal);
Expand Down Expand Up @@ -440,6 +451,14 @@ void FixIPI::final_integrate()
double forceconv, potconv, posconv, pressconv, posconv3;
char retstr[1024] = { '\0' };

// initial_integrate signalled an EXIT for this step. The intervening
// force compute already ran on stale positions; just skip the socket
// I/O so the run loop can break out at the next check_timeout.
if (exit_flag) {
hasdata = 0;
return;
}

// conversions from LAMMPS units to atomic units, which are used by i-PI
potconv=3.1668152e-06/force->boltz;
posconv=0.52917721*force->angstrom;
Expand Down Expand Up @@ -491,6 +510,7 @@ void FixIPI::final_integrate()
retstr[0] = '\0';
}

int exit_now = 0;
if (master) {
// check for new messages
while (true) {
Expand All @@ -501,10 +521,9 @@ void FixIPI::final_integrate()
else break;
}

if (strcmp(header,"EXIT ") == 0)
error->one(FLERR, "Got EXIT message from i-PI. Now leaving!");

if (strcmp(header,"GETFORCE ") == 0) {
if (strcmp(header,"EXIT ") == 0) {
exit_now = 1;
} else if (strcmp(header,"GETFORCE ") == 0) {
// return force and energy data
writebuffer(ipisock,"FORCEREADY ",MSGLEN, error);
writebuffer(ipisock,(char*) &pot,8, error);
Expand All @@ -519,5 +538,13 @@ void FixIPI::final_integrate()
error->one(FLERR, "Wrapper did not ask for forces, I will now die!");
}

// propagate the EXIT decision so all ranks force_timeout together;
// the next Verlet iteration's check_timeout will then end the run cleanly
MPI_Bcast(&exit_now, 1, MPI_INT, 0, world);
if (exit_now) {
timer->force_timeout();
exit_flag = 1;
}

hasdata=0;
}
1 change: 1 addition & 0 deletions src/MISC/fix_ipi.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class FixIPI : public Fix {
int kspace_flag;
int reset_flag;
int firsttime;
int exit_flag;

private:
class Irregular *irregular;
Expand Down