diff --git a/doc/Manual.html b/doc/Manual.html index ff5b14a936..1849ffdc32 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -1,7 +1,7 @@
fix ID group-ID bond/swap fraction cutoff seed-
Examples:
-fix 1 all bond/swap 0.5 1.3 598934 +fix 1 all bond/swap 50 0.5 1.3 598934Description:
@@ -55,13 +57,14 @@ undergone a dramatic conformational change. This reference provides more details on how the algorithm works and its application: (Sides). -The bond swapping operation is invoked each time neighbor lists are -built during a simulation, since it potentially alters the list of -which neighbors are considered for pairwise interaction. At each -reneighboring step, each processor considers a random specified -fraction of its atoms as potential swapping monomers for this -timestep. Choosing a small fraction value can reduce the likelihood -of a reverse swap occurring soon after an initial swap. +
The bond swapping operation is invoked every Nevery timesteps. If +any bond is swapped, a re-build of the neighbor lists is triggered, +since a swap alters the list of which neighbors are considered for +pairwise interaction. At each invocation, each processor considers a +random specified fraction of its atoms as potential swapping +monomers for this timestep. Choosing a small fraction value can +reduce the likelihood of a reverse swap occurring soon after an +initial swap.
For each monomer A1, its neighbors are examined to find a possible B1 monomer. Both A1 and B1 must be in the fix group, their separation diff --git a/doc/fix_bond_swap.txt b/doc/fix_bond_swap.txt index cb41bb7a9e..44844f1f47 100644 --- a/doc/fix_bond_swap.txt +++ b/doc/fix_bond_swap.txt @@ -14,13 +14,14 @@ fix ID group-ID bond/swap fraction cutoff seed :pre ID, group-ID are documented in "fix"_fix.html command bond/swap = style name of this fix command +Nevery = attempt bond swapping every this many steps :l fraction = fraction of group atoms to consider for swapping cutoff = distance at which swapping will be considered (distance units) seed = random # seed (positive integer) :ul [Examples:] -fix 1 all bond/swap 0.5 1.3 598934 :pre +fix 1 all bond/swap 50 0.5 1.3 598934 :pre [Description:] @@ -52,13 +53,14 @@ undergone a dramatic conformational change. This reference provides more details on how the algorithm works and its application: "(Sides)"_#Sides. -The bond swapping operation is invoked each time neighbor lists are -built during a simulation, since it potentially alters the list of -which neighbors are considered for pairwise interaction. At each -reneighboring step, each processor considers a random specified -{fraction} of its atoms as potential swapping monomers for this -timestep. Choosing a small {fraction} value can reduce the likelihood -of a reverse swap occurring soon after an initial swap. +The bond swapping operation is invoked every {Nevery} timesteps. If +any bond is swapped, a re-build of the neighbor lists is triggered, +since a swap alters the list of which neighbors are considered for +pairwise interaction. At each invocation, each processor considers a +random specified {fraction} of its atoms as potential swapping +monomers for this timestep. Choosing a small {fraction} value can +reduce the likelihood of a reverse swap occurring soon after an +initial swap. For each monomer A1, its neighbors are examined to find a possible B1 monomer. Both A1 and B1 must be in the fix group, their separation diff --git a/src/GRANULAR/fix_pour.h b/src/GRANULAR/fix_pour.h index c73fb8f6ac..3284621b5b 100644 --- a/src/GRANULAR/fix_pour.h +++ b/src/GRANULAR/fix_pour.h @@ -52,7 +52,7 @@ class FixPour : public Fix { char *idrigid,*idshake; class Molecule *onemol; - int natom; + int natom; // # of atoms per inserted particle double **coords; imageint *imageflags; class Fix *fixrigid,*fixshake; diff --git a/src/MANYBODY/fix_qeq_comb.cpp b/src/MANYBODY/fix_qeq_comb.cpp index 559a8acfb6..c40147f467 100644 --- a/src/MANYBODY/fix_qeq_comb.cpp +++ b/src/MANYBODY/fix_qeq_comb.cpp @@ -133,12 +133,6 @@ void FixQEQComb::init() ngroup = group->count(igroup); if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms"); - - int irequest = neighbor->request(this); - neighbor->requests[irequest]->pair = 0; - neighbor->requests[irequest]->fix = 1; - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 1; } /* ---------------------------------------------------------------------- */ @@ -320,5 +314,3 @@ void FixQEQComb::unpack_comm(int n, int first, double *buf) last = first + n ; for (i = first; i < last; i++) atom->q[i] = buf[m++]; } - -/* ---------------------------------------------------------------------- */ diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp index 24783ab8a7..c9042c0516 100644 --- a/src/MC/fix_bond_create.cpp +++ b/src/MC/fix_bond_create.cpp @@ -200,11 +200,12 @@ void FixBondCreate::init() "dihedrals, or impropers"); } - // need a half neighbor list, built when ever re-neighboring occurs + // need a half neighbor list, built every Nevery steps int irequest = neighbor->request((void *) this); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->occasional = 1; if (strstr(update->integrate_style,"respa")) nlevels_respa = ((Respa *) update->integrate)->nlevels; @@ -317,6 +318,7 @@ void FixBondCreate::post_integrate() int *mask = atom->mask; int *type = atom->type; + neighbor->build_one(list->index,1); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp index de5c9ebec2..efbe37065a 100644 --- a/src/MC/fix_bond_swap.cpp +++ b/src/MC/fix_bond_swap.cpp @@ -58,18 +58,23 @@ FixBondSwap::FixBondSwap(LAMMPS *lmp, int narg, char **arg) : if (narg != 6) error->all(FLERR,"Illegal fix bond/swap command"); + nevery = force->inumeric(FLERR,arg[3]); + if (nevery <= 0) error->all(FLERR,"Illegal fix bond/swap command"); + + force_reneighbor = 1; + next_reneighbor = -1; vector_flag = 1; size_vector = 2; global_freq = 1; extvector = 0; - fraction = force->numeric(FLERR,arg[3]); - double cutoff = force->numeric(FLERR,arg[4]); + fraction = force->numeric(FLERR,arg[4]); + double cutoff = force->numeric(FLERR,arg[5]); cutsq = cutoff*cutoff; // initialize Marsaglia RNG with processor-unique seed - int seed = force->inumeric(FLERR,arg[5]); + int seed = force->inumeric(FLERR,arg[6]); random = new RanMars(lmp,seed + comm->me); // error check @@ -120,7 +125,7 @@ FixBondSwap::~FixBondSwap() int FixBondSwap::setmask() { int mask = 0; - mask |= PRE_NEIGHBOR; + mask |= POST_INTEGRATE; return mask; } @@ -159,11 +164,12 @@ void FixBondSwap::init() force->special_lj[3] != 1.0) error->all(FLERR,"Fix bond/swap requires special_bonds = 0,1,1"); - // need a half neighbor list, built when ever re-neighboring occurs + // need a half neighbor list, built every Nevery steps int irequest = neighbor->request((void *) this); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->occasional = 1; // zero out stats @@ -179,9 +185,16 @@ void FixBondSwap::init_list(int id, NeighList *ptr) list = ptr; } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + look for and perform swaps + NOTE: used to do this every pre_neighbor(), but think that is a bug + b/c was doing it after exchange() and before neighbor->build() + which is when neigh lists are actually out-of-date or even bogus, + now do it based on user-specified Nevery, and trigger reneigh + if any swaps performed, like fix bond/create +------------------------------------------------------------------------- */ -void FixBondSwap::pre_neighbor() +void FixBondSwap::post_integrate() { int i,j,ii,jj,m,inum,jnum; int inext,iprev,ilast,jnext,jprev,jlast,ibond,iangle,jbond,jangle; @@ -191,6 +204,8 @@ void FixBondSwap::pre_neighbor() int *ilist,*jlist,*numneigh,**firstneigh; double delta,factor; + if (update->ntimestep % nevery) return; + // compute current temp for Boltzmann factor test double t_current = temperature->compute_scalar(); @@ -216,6 +231,7 @@ void FixBondSwap::pre_neighbor() type = atom->type; x = atom->x; + neighbor->build_one(list->index,1); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -418,6 +434,13 @@ void FixBondSwap::pre_neighbor() } done: + + // trigger immediate reneighboring if any swaps occurred + + int accept_any; + MPI_Allreduce(&accept,&accept_any,1,MPI_INT,MPI_SUM,world); + if (accept_any) next_reneighbor = update->ntimestep; + if (!accept) return; naccept++; @@ -629,11 +652,13 @@ int FixBondSwap::modify_param(int narg, char **arg) strcpy(id_temp,arg[1]); int icompute = modify->find_compute(id_temp); - if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID"); + if (icompute < 0) + error->all(FLERR,"Could not find fix_modify temperature ID"); temperature = modify->compute[icompute]; if (temperature->tempflag == 0) - error->all(FLERR,"Fix_modify temperature ID does not compute temperature"); + error->all(FLERR,"Fix_modify temperature ID does not " + "compute temperature"); if (temperature->igroup != igroup && comm->me == 0) error->warning(FLERR,"Group for fix_modify temp != fix group"); return 2; diff --git a/src/MC/fix_bond_swap.h b/src/MC/fix_bond_swap.h index 507e6beabf..0443144c23 100644 --- a/src/MC/fix_bond_swap.h +++ b/src/MC/fix_bond_swap.h @@ -32,7 +32,7 @@ class FixBondSwap : public Fix { int setmask(); void init(); void init_list(int, class NeighList *); - void pre_neighbor(); + void post_integrate(); int modify_param(int, char **); double compute_vector(int); double memory_usage(); diff --git a/src/PERI/fix_peri_neigh.cpp b/src/PERI/fix_peri_neigh.cpp index 190bc0460d..ffde6a84c4 100644 --- a/src/PERI/fix_peri_neigh.cpp +++ b/src/PERI/fix_peri_neigh.cpp @@ -177,7 +177,7 @@ void FixPeriNeigh::setup(int vflag) if (!first) return; first = 0; - // invoke full neighbor list (will copy or build if necessary) + // build full neighbor list, will copy or build as necessary neighbor->build_one(list->index); diff --git a/src/USER-REAXC/fix_qeq_reax.cpp b/src/USER-REAXC/fix_qeq_reax.cpp index ba96d7b211..6323d5138a 100644 --- a/src/USER-REAXC/fix_qeq_reax.cpp +++ b/src/USER-REAXC/fix_qeq_reax.cpp @@ -322,13 +322,14 @@ void FixQEqReax::init() error->all(FLERR,"Must use pair_style reax/c with fix qeq/reax"); // need a half neighbor list w/ Newton off and ghost neighbors - // built whenever re-neighboring occurs + // make it occasional if QeQ not performed every timestep int irequest = neighbor->request(this); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->fix = 1; neighbor->requests[irequest]->newton = 2; neighbor->requests[irequest]->ghost = 1; + if (nevery) neighbor->requests[irequest]->occasional = 1; init_shielding(); init_taper(); @@ -523,12 +524,14 @@ void FixQEqReax::compute_H() tagint *tag = atom->tag; x = atom->x; + if (nevery > 1) neighbor->build_one(list->index); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // fill in the H matrix + m_fill = 0; r_sqr = 0; for( ii = 0; ii < inum; ii++ ) { diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index 2db870416a..2501917d85 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -266,8 +266,7 @@ void DeleteAtoms::delete_overlap(int narg, char **arg) error->all(FLERR,"Delete_atoms cutoff > neighbor cutoff"); // setup domain, communication and neighboring - // acquire ghosts - // build neighbor list based on earlier request + // acquire ghosts and build standard neighbor lists if (domain->triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); @@ -277,6 +276,9 @@ void DeleteAtoms::delete_overlap(int narg, char **arg) comm->exchange(); comm->borders(); if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + neighbor->build(); + + // build neighbor list this command needs based on earlier request NeighList *list = neighbor->lists[irequest]; neighbor->build_one(irequest); diff --git a/src/modify.cpp b/src/modify.cpp index 4d637f1490..75f23f89b0 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -535,7 +535,7 @@ double Modify::min_energy(double *fextra) } /* ---------------------------------------------------------------------- - store current state of extra dof, only for relevant fixes + store current state of extra minimizer dof, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_store() @@ -545,7 +545,7 @@ void Modify::min_store() } /* ---------------------------------------------------------------------- - mange state of extra dof on a stack, only for relevant fixes + manage state of extra minimizer dof on a stack, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_clearstore() @@ -567,7 +567,7 @@ void Modify::min_popstore() } /* ---------------------------------------------------------------------- - displace extra dof along vector hextra, only for relevant fixes + displace extra minimizer dof along vector hextra, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_step(double alpha, double *hextra) @@ -602,7 +602,7 @@ double Modify::max_alpha(double *hextra) } /* ---------------------------------------------------------------------- - extract extra dof for minimization, only for relevant fixes + extract extra minimizer dof, only for relevant fixes ------------------------------------------------------------------------- */ int Modify::min_dof() @@ -614,7 +614,7 @@ int Modify::min_dof() } /* ---------------------------------------------------------------------- - reset reference state of fix, only for relevant fixes + reset minimizer reference state of fix, only for relevant fixes ------------------------------------------------------------------------- */ int Modify::min_reset_ref() diff --git a/src/neigh_full.cpp b/src/neigh_full.cpp index 9732d734f3..d9ff786d65 100644 --- a/src/neigh_full.cpp +++ b/src/neigh_full.cpp @@ -247,7 +247,7 @@ void Neighbor::full_bin(NeighList *list) // bin owned & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -355,7 +355,7 @@ void Neighbor::full_bin_ghost(NeighList *list) // bin owned & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -491,7 +491,7 @@ void Neighbor::full_multi(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; diff --git a/src/neigh_half_bin.cpp b/src/neigh_half_bin.cpp index 9bba2e6ef0..349deddae1 100644 --- a/src/neigh_half_bin.cpp +++ b/src/neigh_half_bin.cpp @@ -38,7 +38,7 @@ void Neighbor::half_bin_no_newton(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -151,7 +151,7 @@ void Neighbor::half_bin_no_newton_ghost(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -291,7 +291,7 @@ void Neighbor::half_bin_newton(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -433,7 +433,7 @@ void Neighbor::half_bin_newton_tri(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; diff --git a/src/neigh_half_multi.cpp b/src/neigh_half_multi.cpp index 08898be3f9..9d8375b68e 100644 --- a/src/neigh_half_multi.cpp +++ b/src/neigh_half_multi.cpp @@ -40,7 +40,7 @@ void Neighbor::half_multi_no_newton(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -156,7 +156,7 @@ void Neighbor::half_multi_newton(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -306,7 +306,7 @@ void Neighbor::half_multi_newton_tri(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 24570258de..dc925a6f90 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -42,6 +42,8 @@ NeighList::NeighList(LAMMPS *lmp) : dnum = 0; + last_build = -1; + iskip = NULL; ijskip = NULL; diff --git a/src/neigh_list.h b/src/neigh_list.h index 3264f94bc4..2374fde652 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -45,6 +45,8 @@ class NeighList : protected Pointers { MyPage
*ipage; // pages of neighbor indices MyPage *dpage; // pages of neighbor doubles, if dnum > 0 + bigint last_build; // timestep of last build for occasional lists + // atom types to skip when building list // iskip,ijskip are just ptrs to corresponding request diff --git a/src/neigh_respa.cpp b/src/neigh_respa.cpp index 91f85de6ea..777534746b 100644 --- a/src/neigh_respa.cpp +++ b/src/neigh_respa.cpp @@ -378,7 +378,7 @@ void Neighbor::respa_bin_no_newton(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -548,7 +548,7 @@ void Neighbor::respa_bin_newton(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; @@ -765,7 +765,7 @@ void Neighbor::respa_bin_newton_tri(NeighList *list) // bin local & ghost atoms - bin_atoms(); + if (binatomflag) bin_atoms(); double **x = atom->x; int *type = atom->type; diff --git a/src/neighbor.cpp b/src/neighbor.cpp index bc96075dd9..c38d8db7aa 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -83,6 +83,7 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) binsizeflag = 0; build_once = 0; cluster_check = 0; + binatomflag = 1; cutneighsq = NULL; cutneighghostsq = NULL; @@ -508,27 +509,6 @@ void Neighbor::init() // detect lists that are connected to other lists // if-then-else sequence and processed flag is important // since don't want to re-process skip or copy lists further down - // skip list needs to have granhistory or respa info added - // copy: point this list at request->otherlist, could be a skip list - // skip: point this list at request->otherlist, copy skip info from request - // also set granular and respa info if applicable - // half_from_full: point this list at preceeding full list - // granhistory: set preceeding list's listgranhistory to this list - // also set preceeding list's ptr to FixShearHistory - // respaouter: point this list at preceeding 1/2 inner/middle lists - // pair and half: if there is a full non-occasional non-skip list - // change this list to half_from_full and point at the full list - // parent could be copy list or pair or fix - // fix/compute requests: - // whether request is occasional or not doesn't matter - // if request = half and non-skip pair half/respaouter exists, - // become copy of that list if cudable flag matches - // if request = full and non-skip pair full exists, - // become copy of that list if cudable flag matches - // if request = half and non-skip pair full exists, - // become half_from_full of that list if cudable flag matches - // if no matches, do nothing, fix/compute list will be built directly - // ok if parent is copy list int processed; @@ -536,20 +516,32 @@ void Neighbor::init() if (!lists[i]) continue; processed = 0; + // copy: point this list at request->otherlist, could be a skip list + if (requests[i]->copy) { lists[i]->listcopy = lists[requests[i]->otherlist]; processed = 1; + // skip: point this list at request->otherlist, + // copy skip info from request + // skip list still needs to have granhistory or respa info added below + } else if (requests[i]->skip) { lists[i]->listskip = lists[requests[i]->otherlist]; lists[i]->copy_skip_info(requests[i]->iskip,requests[i]->ijskip); processed = 1; + // half_from_full: point this list at full list that comes right before + // will only be case if pair style requested one after other + } else if (requests[i]->half_from_full) { lists[i]->listfull = lists[i-1]; processed = 1; } + // granhistory: set preceeding list's listgranhistory to this list + // also set preceeding list's ptr to FixShearHistory + if (requests[i]->granhistory) { lists[i-1]->listgranhistory = lists[i]; for (int ifix = 0; ifix < modify->nfix; ifix++) @@ -557,6 +549,8 @@ void Neighbor::init() lists[i-1]->fix_history = (FixShearHistory *) modify->fix[ifix]; processed = 1; + // respaouter: point this list at preceeding 1/2 inner/middle lists + } else if (requests[i]->respaouter) { if (requests[i-1]->respainner) { lists[i]->respamiddle = 0; @@ -571,6 +565,10 @@ void Neighbor::init() if (processed) continue; + // pair and half: if there is a full non-occasional non-skip list + // change this list to half_from_full and point at the full list + // parent could be copy list or pair or fix + if (requests[i]->pair && requests[i]->half) { for (j = 0; j < nrequest; j++) { if (!lists[j]) continue; @@ -583,6 +581,18 @@ void Neighbor::init() lists[i]->listfull = lists[j]; } + // fix/compute requests: + // whether request is occasional or not doesn't matter + // if request = half and non-skip pair half/respaouter exists, + // become copy of that list if cudable flag matches + // if request = full and non-skip pair full exists, + // become copy of that list if cudable flag matches + // if request = half and non-skip pair full exists, + // become half_from_full of that list if cudable flag matches + // if no matches, do nothing + // fix/compute list will be built independently as needed + // ok if parent is itself a copy list + } else if (requests[i]->fix || requests[i]->compute) { for (j = 0; j < nrequest; j++) { if (!lists[j]) continue; @@ -1349,8 +1359,8 @@ int Neighbor::check_distance() } /* ---------------------------------------------------------------------- - build all perpetual neighbor lists every few timesteps - pairwise & topology lists are created as needed + build perpetuals neighbor lists + called at setup and every few timesteps during run or minimization topology lists only built if topoflag = 1, USER-CUDA calls with topoflag = 0 ------------------------------------------------------------------------- */ @@ -1419,12 +1429,12 @@ void Neighbor::build(int topoflag) memory->create(bins,maxbin,"bins"); } - // check that neighbor list with special bond flags will not overflow + // check that using special bond flags will not overflow neigh lists if (atom->nlocal+atom->nghost > NEIGHMASK) error->one(FLERR,"Too many local+ghost atoms for neighbor list"); - // invoke building of pair and molecular neighbor lists + // invoke building of pair and molecular topology neighbor lists // only for pairwise lists with buildflag set // blist is for standard neigh lists, otherwise is a Kokkos list @@ -1455,9 +1465,22 @@ void Neighbor::build_topology() called by other classes ------------------------------------------------------------------------- */ -void Neighbor::build_one(int i) +void Neighbor::build_one(int i, int preflag) { - // update stencils and grow atom arrays and bins as needed + // no need to build if already built since last re-neighbor + // preflag is set by fix bond/create and fix bond/swap + // b/c they invoke build_one() on same step neigh list is re-built, + // but before re-build, so need to use ">" instead of ">=" + + if (preflag) { + if (lists[i]->last_build > lastcall) return; + } else { + if (lists[i]->last_build >= lastcall) return; + } + + lists[i]->last_build = update->ntimestep; + + // update stencils and grow atom arrays as needed // only for relevant settings of stencilflag and growflag // grow atom array for this list to current size of perpetual lists @@ -1468,42 +1491,14 @@ void Neighbor::build_one(int i) if (lists[i]->growflag) lists[i]->grow(maxatom); - // extend atom bin list if necessary - - if (style != NSQ && atom->nmax > maxbin) { - maxbin = atom->nmax; - memory->destroy(bins); - memory->create(bins,maxbin,"bins"); - } - - // check that neighbor list with special bond flags will not overflow - - if (atom->nlocal+atom->nghost > NEIGHMASK) - error->one(FLERR,"Too many local+ghost atoms for neighbor list"); - - // when occasional list built, LAMMPS can crash if atoms have moved too far - // why is this? maybe b/c this list is derived from some now out-of-date list? - // give warning if this is the case - // no easy workaround b/c all neighbor lists really need to be rebuilt - // solution is for input script to check more often for rebuild - // only check_distance if running a simulation, not between simulations - // comment out for now - // is sometimes giving warning when there is no issue - // e.g. when a variable uses a fix with an occasional neigh list - // at the beginning of a timestep (e.g. fix move) where - // all neigh lists are about to be re-built anyway - - /* - int flag = 0; - if (dist_check && update->whichflag) flag = check_distance(); - if (flag && me == 0) { - printf("BUILD ONE ERROR: %ld\n",update->ntimestep); - error->warning(FLERR,"Building an occasional neighbor list when " - "atoms may have moved too far"); - } - */ + // build list I, turning off atom binning + // binning results from last re-neighbor should be used instead + // if re-bin now, atoms may have moved outside of proc domain & bin extent, + // leading to errors or even a crash + binatomflag = 0; (this->*pair_build[i])(lists[i]); + binatomflag = 1; } /* ---------------------------------------------------------------------- diff --git a/src/neighbor.h b/src/neighbor.h index ec6881d56d..3c0c4af889 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -75,7 +75,7 @@ class Neighbor : protected Pointers { void setup_bins(); // setup bins based on box and cutoff virtual void build(int topoflag=1); // create all neighbor lists (pair,bond) virtual void build_topology(); // create all topology neighbor lists - void build_one(int); // create a single neighbor list + void build_one(int, int preflag=0); // create a single neighbor list void set(int, char **); // set neighbor style and skin distance void modify_params(int, char**); // modify parameters that control builds bigint memory_usage(); @@ -107,6 +107,9 @@ class Neighbor : protected Pointers { double boxlo_hold[3],boxhi_hold[3]; // box size at last neighbor build double corners_hold[8][3]; // box corners at last neighbor build + int binatomflag; // bin atoms or not when build neigh list + // turned off by build_one() + int nbinx,nbiny,nbinz; // # of global bins int *bins; // ptr to next atom in each bin int maxbin; // size of bins array diff --git a/src/version.h b/src/version.h index ca1ad6060f..7e739f872f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "9 Apr 2014" +#define LAMMPS_VERSION "11 Apr 2014"