diff --git a/src/RIGID/fix_rigid.cpp b/src/RIGID/fix_rigid.cpp index fa409d32e9..9263c4906f 100644 --- a/src/RIGID/fix_rigid.cpp +++ b/src/RIGID/fix_rigid.cpp @@ -1094,6 +1094,8 @@ void FixRigid::pre_neighbor() } // adjust image flags of any atom in a rigid body whose xcm was remapped + // subtracting remapflag = new-old keeps ix,iy,iz near 0 + // so body is always in central simulation box tagint *image = atom->image; int nlocal = atom->nlocal; diff --git a/src/comm.cpp b/src/comm.cpp index 54a6e67209..be6970e4d9 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -116,9 +116,14 @@ Comm::Comm(LAMMPS *lmp) : Pointers(lmp) #endif // initialize comm buffers & exchange memory + // NOTE: allow for AtomVec to set maxexchange_atom, e.g. for atom_style body + + maxexchange_atom = maxexchange_fix = 0; + maxexchange = maxexchange_atom + maxexchange_fix; + bufextra = maxexchange + BUFEXTRA; maxsend = BUFMIN; - memory->create(buf_send,maxsend+BUFEXTRA,"comm:buf_send"); + memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); maxrecv = BUFMIN; memory->create(buf_recv,maxrecv,"comm:buf_recv"); @@ -334,12 +339,14 @@ void Comm::init() for (int i = 0; i < modify->nfix; i++) size_border += modify->fix[i]->comm_border; - + + // maxexchange = max # of datums/atom in exchange communication // maxforward = # of datums in largest forward communication // maxreverse = # of datums in largest reverse communication // query pair,fix,compute,dump for their requirements // pair style can force reverse comm even if newton off + maxexchange = BUFMIN + maxexchange_fix; maxforward = MAX(size_forward,size_border); maxreverse = size_reverse; @@ -537,8 +544,6 @@ void Comm::setup() maxneed[0] = MAX(all[0],all[1]); maxneed[1] = MAX(all[2],all[3]); maxneed[2] = MAX(all[4],all[5]); - //if (me == 0) - //printf("MAXNEED %d %d %d\n",maxneed[0],maxneed[1],maxneed[2]); } // allocate comm memory @@ -826,6 +831,15 @@ void Comm::exchange() atom->nghost = 0; atom->avec->clear_bonus(); + // insure send buf is large enough for single atom + // fixes can change per-atom size requirement on-the-fly + + int bufextra_old = bufextra; + maxexchange = maxexchange_atom + maxexchange_fix; + bufextra = maxexchange + BUFEXTRA; + if (bufextra > bufextra_old) + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); + // subbox bounds for orthogonal or triclinic if (triclinic == 0) { @@ -1584,7 +1598,7 @@ int Comm::read_lines_from_file(FILE *fp, int nlines, int maxline, char *buf) } /* ---------------------------------------------------------------------- - realloc the size of the send buffer as needed with BUFFACTOR & BUFEXTRA + realloc the size of the send buffer as needed with BUFFACTOR and bufextra if flag = 1, realloc if flag = 0, don't need to realloc with copy, just free/malloc ------------------------------------------------------------------------- */ @@ -1593,10 +1607,10 @@ void Comm::grow_send(int n, int flag) { maxsend = static_cast (BUFFACTOR * n); if (flag) - memory->grow(buf_send,(maxsend+BUFEXTRA),"comm:buf_send"); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); else { memory->destroy(buf_send); - memory->create(buf_send,maxsend+BUFEXTRA,"comm:buf_send"); + memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); } } @@ -1888,7 +1902,7 @@ bigint Comm::memory_usage() bytes += nprocs * sizeof(int); // grid2proc for (int i = 0; i < nswap; i++) bytes += memory->usage(sendlist[i],maxsendlist[i]); - bytes += memory->usage(buf_send,maxsend+BUFEXTRA); + bytes += memory->usage(buf_send,maxsend+bufextra); bytes += memory->usage(buf_recv,maxrecv); return bytes; } diff --git a/src/comm.h b/src/comm.h index 8333c8377f..2dfda26d75 100644 --- a/src/comm.h +++ b/src/comm.h @@ -36,6 +36,8 @@ class Comm : protected Pointers { // -1 if no recv or send int other_partition_style; // 0 = recv layout dims must be multiple of // my layout dims + int maxexchange_atom; // max contribution to exchange from AtomVec + int maxexchange_fix; // max contribution to exchange from Fixes int nthreads; // OpenMP threads per MPI process Comm(class LAMMPS *); @@ -117,6 +119,9 @@ class Comm : protected Pointers { int maxsend,maxrecv; // current size of send/recv buffer int maxforward,maxreverse; // max # of datums in forward/reverse comm + int maxexchange; // max # of datums/atom in exchange comm + int bufextra; // extra space beyond maxsend in send buffer + int updown(int, int, int, double, int, double *); // compare cutoff to procs virtual void grow_send(int, int); // reallocate send buffer diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 58bedaf67b..25b1ea6f6e 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -378,11 +378,14 @@ int FixPropertyAtom::unpack_exchange(int nlocal, double *buf) int FixPropertyAtom::pack_restart(int i, double *buf) { buf[0] = nvalue+1; - for (int m = 1; m <= nvalue; m++) { - if (style[m] == MOLECULE) buf[m] = atom->molecule[i]; - else if (style[m] == INTEGER) buf[m] = atom->ivector[index[m]][i]; - else if (style[m] == DOUBLE) buf[m] = atom->dvector[index[m]][i]; + + int m = 1; + for (int j = 0; j < nvalue; j++) { + if (style[j] == MOLECULE) buf[m++] = atom->molecule[i]; + else if (style[j] == INTEGER) buf[m++] = atom->ivector[index[m]][i]; + else if (style[j] == DOUBLE) buf[m++] = atom->dvector[index[m]][i]; } + return nvalue+1; } @@ -403,9 +406,9 @@ void FixPropertyAtom::unpack_restart(int nlocal, int nth) for (int i = 0; i < nvalue; i++) { if (style[i] == MOLECULE) atom->molecule[nlocal] = static_cast (extra[nlocal][m++]); - else if (style[m] == INTEGER) + else if (style[i] == INTEGER) atom->ivector[index[m]][nlocal] = static_cast (extra[nlocal][m++]); - else if (style[m] == DOUBLE) + else if (style[i] == DOUBLE) atom->dvector[index[m]][nlocal] = extra[nlocal][m++]; } } diff --git a/src/fix_shear_history.cpp b/src/fix_shear_history.cpp index bf2fe7b87c..c15c81806e 100644 --- a/src/fix_shear_history.cpp +++ b/src/fix_shear_history.cpp @@ -246,9 +246,11 @@ void FixShearHistory::pre_exchange() } // set maxtouch = max # of partners of any owned atom + // bump up comm->maxexchange_fix if necessary maxtouch = 0; for (i = 0; i < nlocal; i++) maxtouch = MAX(maxtouch,npartner[i]); + comm->maxexchange_fix = MAX(comm->maxexchange_fix,4*maxtouch+1); } /* ---------------------------------------------------------------------- */ @@ -421,7 +423,7 @@ void FixShearHistory::unpack_restart(int nlocal, int nth) int FixShearHistory::maxsize_restart() { - // maxtouch_all = max touching partners across all procs + // maxtouch_all = max # of touching partners across all procs int maxtouch_all; MPI_Allreduce(&maxtouch,&maxtouch_all,1,MPI_INT,MPI_MAX,world); diff --git a/src/modify.cpp b/src/modify.cpp index a887cb861c..4d637f1490 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -995,6 +995,7 @@ void Modify::write_restart(FILE *fp) for (int i = 0; i < nfix; i++) if (fix[i]->restart_peratom) { + int maxsize_restart = fix[i]->maxsize_restart(); if (me == 0) { n = strlen(fix[i]->id) + 1; fwrite(&n,sizeof(int),1,fp); @@ -1002,8 +1003,7 @@ void Modify::write_restart(FILE *fp) n = strlen(fix[i]->style) + 1; fwrite(&n,sizeof(int),1,fp); fwrite(fix[i]->style,sizeof(char),n,fp); - n = fix[i]->maxsize_restart(); - fwrite(&n,sizeof(int),1,fp); + fwrite(&maxsize_restart,sizeof(int),1,fp); } } }