diff --git a/src/fix.cpp b/src/fix.cpp index eb7698924c..2fe254298c 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -53,6 +53,7 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) virial_flag = 0; no_change_box = 0; time_integrate = 0; + restart_pbc = 0; scalar_flag = vector_flag = peratom_flag = 0; diff --git a/src/fix.h b/src/fix.h index 9401d5e2c8..f7b62b6a90 100644 --- a/src/fix.h +++ b/src/fix.h @@ -34,6 +34,8 @@ class Fix : protected Pointers { int virial_flag; // 1 if Fix contributes to virial, 0 if not int no_change_box; // 1 if cannot swap ortho <-> triclinic int time_integrate; // 1 if fix performs time integration, 0 if no + int restart_pbc; // 1 if fix moves atoms (except integrate) + // so that write_restart must remap to PBC int scalar_flag; // 0/1 if compute_scalar() function exists int vector_flag; // 0/1 if compute_vector() function exists diff --git a/src/modify.cpp b/src/modify.cpp index 4f128f1c38..bece86e77c 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -166,6 +166,12 @@ void Modify::init() for (i = 0; i < ncompute; i++) compute[i]->init(); modify->addstep_compute_all(update->ntimestep); + // set global flag if any fix has its restart_pbc flag set + + restart_pbc_any = 0; + for (i = 0; i < nfix; i++) + if (fix[i]->restart_pbc) restart_pbc_any = 1; + // warn if any particle is time integrated more than once int nlocal = atom->nlocal; diff --git a/src/modify.h b/src/modify.h index 719b3429cb..5ed6a12d6f 100644 --- a/src/modify.h +++ b/src/modify.h @@ -28,6 +28,8 @@ class Modify : protected Pointers { int n_min_post_force,n_min_energy; int nfix_restart_peratom; + int restart_pbc_any; // 1 if any fix sets restart_pbc + class Fix **fix; // list of fixes int *fmask; // bit mask for when each fix is applied diff --git a/src/write_restart.cpp b/src/write_restart.cpp index d6566457be..4d3ca6d26f 100644 --- a/src/write_restart.cpp +++ b/src/write_restart.cpp @@ -36,6 +36,9 @@ using namespace LAMMPS_NS; +#define MIN(A,B) ((A) < (B)) ? (A) : (B) +#define MAX(A,B) ((A) > (B)) ? (A) : (B) + // same as read_restart.cpp and tools/restart2data.cpp enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2, @@ -106,7 +109,7 @@ void WriteRestart::command(int narg, char **arg) } /* ---------------------------------------------------------------------- - called from output within run/minimize loop + called from command() and directly from output within run/minimize loop file = final file name to write, except may contain a "%" ------------------------------------------------------------------------- */ @@ -179,6 +182,55 @@ void WriteRestart::write(char *file) int n = 0; for (int i = 0; i < atom->nlocal; i++) n += avec->pack_restart(i,&buf[n]); + // if any fix requires it, remap each atom's coords via PBC + // is because fix changes atom coords (excepting an integrate fix) + // just remap in buffer, not actual atoms + + if (modify->restart_pbc_any) { + int triclinic = domain->triclinic; + double *lo,*hi,*period; + + if (triclinic == 0) { + lo = domain->boxlo; + hi = domain->boxhi; + period = domain->prd; + } else { + lo = domain->boxlo_lamda; + hi = domain->boxhi_lamda; + period = domain->prd_lamda; + } + + int xperiodic = domain->xperiodic; + int yperiodic = domain->yperiodic; + int zperiodic = domain->zperiodic; + + double *x; + int m = 0; + for (int i = 0; i < atom->nlocal; i++) { + x = &buf[m+1]; + if (triclinic) domain->x2lamda(x,x); + + if (xperiodic) { + if (x[0] < lo[0]) x[0] += period[0]; + if (x[0] >= hi[0]) x[0] -= period[0]; + x[0] = MAX(x[0],lo[0]); + } + if (yperiodic) { + if (x[1] < lo[1]) x[1] += period[1]; + if (x[1] >= hi[1]) x[1] -= period[1]; + x[1] = MAX(x[1],lo[1]); + } + if (zperiodic) { + if (x[2] < lo[2]) x[2] += period[2]; + if (x[2] >= hi[2]) x[2] -= period[2]; + x[2] = MAX(x[2],lo[2]); + } + + if (triclinic) domain->x2lamda(x,x); + m += static_cast (buf[m]); + } + } + // if single file: // write one chunk of atoms per proc to file // proc 0 pings each proc, receives its chunk, writes to file