505 lines
14 KiB
C++
505 lines
14 KiB
C++
/* ----------------------------------------------------------------------
|
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
|
http://lammps.sandia.gov, Sandia National Laboratories
|
|
Steve Plimpton, sjplimp@sandia.gov
|
|
|
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
|
certain rights in this software. This software is distributed under
|
|
the GNU General Public License.
|
|
|
|
See the README file in the top-level LAMMPS directory.
|
|
------------------------------------------------------------------------- */
|
|
|
|
#include "neighbor.h"
|
|
#include "neigh_list.h"
|
|
#include "atom.h"
|
|
#include "error.h"
|
|
|
|
using namespace LAMMPS_NS;
|
|
|
|
/* ----------------------------------------------------------------------
|
|
build half list from full list
|
|
pair stored once if i,j are both owned and i < j
|
|
pair stored by me if j is ghost (also stored by proc owning j)
|
|
works if full list is a skip list
|
|
------------------------------------------------------------------------- */
|
|
|
|
void Neighbor::half_from_full_no_newton(NeighList *list)
|
|
{
|
|
int i,j,ii,jj,n,jnum,joriginal;
|
|
int *neighptr,*jlist;
|
|
|
|
int *ilist = list->ilist;
|
|
int *numneigh = list->numneigh;
|
|
int **firstneigh = list->firstneigh;
|
|
int **pages = list->pages;
|
|
int *ilist_full = list->listfull->ilist;
|
|
int *numneigh_full = list->listfull->numneigh;
|
|
int **firstneigh_full = list->listfull->firstneigh;
|
|
int inum_full = list->listfull->inum;
|
|
|
|
int inum = 0;
|
|
int npage = 0;
|
|
int npnt = 0;
|
|
|
|
// loop over atoms in full list
|
|
|
|
for (ii = 0; ii < inum_full; ii++) {
|
|
|
|
if (pgsize - npnt < oneatom) {
|
|
npnt = 0;
|
|
npage++;
|
|
if (npage == list->maxpage) pages = list->add_pages();
|
|
}
|
|
|
|
neighptr = &pages[npage][npnt];
|
|
n = 0;
|
|
|
|
// loop over parent full list
|
|
|
|
i = ilist_full[ii];
|
|
jlist = firstneigh_full[i];
|
|
jnum = numneigh_full[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (j > i) neighptr[n++] = joriginal;
|
|
}
|
|
|
|
ilist[inum++] = i;
|
|
firstneigh[i] = neighptr;
|
|
numneigh[i] = n;
|
|
npnt += n;
|
|
if (n > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
}
|
|
|
|
list->inum = inum;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
build half list from full list
|
|
pair stored once if i,j are both owned and i < j
|
|
if j is ghost, only store if j coords are "above and to the right" of i
|
|
works if full list is a skip list
|
|
------------------------------------------------------------------------- */
|
|
|
|
void Neighbor::half_from_full_newton(NeighList *list)
|
|
{
|
|
int i,j,ii,jj,n,jnum,joriginal;
|
|
int *neighptr,*jlist;
|
|
double xtmp,ytmp,ztmp;
|
|
|
|
double **x = atom->x;
|
|
int nlocal = atom->nlocal;
|
|
|
|
int *ilist = list->ilist;
|
|
int *numneigh = list->numneigh;
|
|
int **firstneigh = list->firstneigh;
|
|
int **pages = list->pages;
|
|
int *ilist_full = list->listfull->ilist;
|
|
int *numneigh_full = list->listfull->numneigh;
|
|
int **firstneigh_full = list->listfull->firstneigh;
|
|
int inum_full = list->listfull->inum;
|
|
|
|
int inum = 0;
|
|
int npage = 0;
|
|
int npnt = 0;
|
|
|
|
// loop over parent full list
|
|
|
|
for (ii = 0; ii < inum_full; ii++) {
|
|
|
|
if (pgsize - npnt < oneatom) {
|
|
npnt = 0;
|
|
npage++;
|
|
if (npage == list->maxpage) pages = list->add_pages();
|
|
}
|
|
|
|
neighptr = &pages[npage][npnt];
|
|
n = 0;
|
|
|
|
i = ilist_full[ii];
|
|
xtmp = x[i][0];
|
|
ytmp = x[i][1];
|
|
ztmp = x[i][2];
|
|
|
|
// loop over full neighbor list
|
|
|
|
jlist = firstneigh_full[i];
|
|
jnum = numneigh_full[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (j < nlocal) {
|
|
if (i > j) continue;
|
|
} else {
|
|
if (x[j][2] < ztmp) continue;
|
|
if (x[j][2] == ztmp) {
|
|
if (x[j][1] < ytmp) continue;
|
|
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
|
|
}
|
|
}
|
|
neighptr[n++] = joriginal;
|
|
}
|
|
|
|
ilist[inum++] = i;
|
|
firstneigh[i] = neighptr;
|
|
numneigh[i] = n;
|
|
npnt += n;
|
|
if (n > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
}
|
|
|
|
list->inum = inum;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
build skip list for subset of types from parent list
|
|
iskip and ijskip flag which atom types and type pairs to skip
|
|
this is for half and full lists
|
|
if ghostflag, also store neighbors of ghost atoms & set inum,gnum correctly
|
|
------------------------------------------------------------------------- */
|
|
|
|
void Neighbor::skip_from(NeighList *list)
|
|
{
|
|
int i,j,ii,jj,n,itype,jnum,joriginal;
|
|
int *neighptr,*jlist;
|
|
|
|
int *type = atom->type;
|
|
int nlocal = atom->nlocal;
|
|
|
|
int *ilist = list->ilist;
|
|
int *numneigh = list->numneigh;
|
|
int **firstneigh = list->firstneigh;
|
|
int **pages = list->pages;
|
|
int *ilist_skip = list->listskip->ilist;
|
|
int *numneigh_skip = list->listskip->numneigh;
|
|
int **firstneigh_skip = list->listskip->firstneigh;
|
|
int num_skip = list->listskip->inum;
|
|
if (list->ghostflag) num_skip += list->listskip->gnum;
|
|
|
|
int *iskip = list->iskip;
|
|
int **ijskip = list->ijskip;
|
|
|
|
int inum = 0;
|
|
int npage = 0;
|
|
int npnt = 0;
|
|
|
|
// loop over atoms in other list
|
|
// skip I atom entirely if iskip is set for type[I]
|
|
// skip I,J pair if ijskip is set for type[I],type[J]
|
|
|
|
for (ii = 0; ii < num_skip; ii++) {
|
|
i = ilist_skip[ii];
|
|
itype = type[i];
|
|
if (iskip[itype]) continue;
|
|
|
|
if (pgsize - npnt < oneatom) {
|
|
npnt = 0;
|
|
npage++;
|
|
if (npage == list->maxpage) pages = list->add_pages();
|
|
}
|
|
|
|
neighptr = &pages[npage][npnt];
|
|
n = 0;
|
|
|
|
// loop over parent non-skip list
|
|
|
|
jlist = firstneigh_skip[i];
|
|
jnum = numneigh_skip[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (ijskip[itype][type[j]]) continue;
|
|
neighptr[n++] = joriginal;
|
|
}
|
|
|
|
ilist[inum++] = i;
|
|
firstneigh[i] = neighptr;
|
|
numneigh[i] = n;
|
|
npnt += n;
|
|
if (n > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
}
|
|
|
|
list->inum = inum;
|
|
if (list->ghostflag) {
|
|
int num = 0;
|
|
for (i = 0; i < inum; i++)
|
|
if (ilist[i] < nlocal) num++;
|
|
else break;
|
|
list->inum = num;
|
|
list->gnum = inum - num;
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
build skip list for subset of types from parent list
|
|
iskip and ijskip flag which atom types and type pairs to skip
|
|
this is for granular lists with history, copy the history values from parent
|
|
------------------------------------------------------------------------- */
|
|
|
|
void Neighbor::skip_from_granular(NeighList *list)
|
|
{
|
|
int i,j,ii,jj,n,nn,itype,jnum,joriginal;
|
|
int *neighptr,*jlist,*touchptr,*touchptr_skip;
|
|
double *shearptr,*shearptr_skip;
|
|
|
|
int *type = atom->type;
|
|
|
|
int *ilist = list->ilist;
|
|
int *numneigh = list->numneigh;
|
|
int **firstneigh = list->firstneigh;
|
|
int **pages = list->pages;
|
|
int *ilist_skip = list->listskip->ilist;
|
|
int *numneigh_skip = list->listskip->numneigh;
|
|
int **firstneigh_skip = list->listskip->firstneigh;
|
|
int **firsttouch_skip = list->listskip->listgranhistory->firstneigh;
|
|
double **firstshear_skip = list->listskip->listgranhistory->firstdouble;
|
|
int inum_skip = list->listskip->inum;
|
|
|
|
int *iskip = list->iskip;
|
|
int **ijskip = list->ijskip;
|
|
|
|
NeighList *listgranhistory = list->listgranhistory;
|
|
int **firsttouch = listgranhistory->firstneigh;
|
|
double **firstshear = listgranhistory->firstdouble;
|
|
int **pages_touch = listgranhistory->pages;
|
|
double **pages_shear = listgranhistory->dpages;
|
|
|
|
int inum = 0;
|
|
int npage = 0;
|
|
int npnt = 0;
|
|
|
|
// loop over atoms in other list
|
|
// skip I atom entirely if iskip is set for type[I]
|
|
// skip I,J pair if ijskip is set for type[I],type[J]
|
|
|
|
for (ii = 0; ii < inum_skip; ii++) {
|
|
i = ilist_skip[ii];
|
|
itype = type[i];
|
|
if (iskip[itype]) continue;
|
|
|
|
if (pgsize - npnt < oneatom) {
|
|
npnt = 0;
|
|
npage++;
|
|
if (npage == list->maxpage) {
|
|
pages = list->add_pages();
|
|
pages_touch = listgranhistory->add_pages();
|
|
pages_shear = listgranhistory->dpages;
|
|
}
|
|
}
|
|
|
|
n = 0;
|
|
neighptr = &pages[npage][npnt];
|
|
nn = 0;
|
|
touchptr = &pages_touch[npage][npnt];
|
|
shearptr = &pages_shear[npage][3*npnt];
|
|
|
|
// loop over parent non-skip granular list and its history info
|
|
|
|
touchptr_skip = firsttouch_skip[i];
|
|
shearptr_skip = firstshear_skip[i];
|
|
jlist = firstneigh_skip[i];
|
|
jnum = numneigh_skip[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (ijskip[itype][type[j]]) continue;
|
|
neighptr[n] = joriginal;
|
|
touchptr[n++] = touchptr_skip[jj];
|
|
shearptr[nn++] = shearptr_skip[3*jj];
|
|
shearptr[nn++] = shearptr_skip[3*jj+1];
|
|
shearptr[nn++] = shearptr_skip[3*jj+2];
|
|
}
|
|
|
|
ilist[inum++] = i;
|
|
firstneigh[i] = neighptr;
|
|
numneigh[i] = n;
|
|
firsttouch[i] = touchptr;
|
|
firstshear[i] = shearptr;
|
|
npnt += n;
|
|
if (n > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
}
|
|
|
|
list->inum = inum;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
build skip list for subset of types from parent list
|
|
iskip and ijskip flag which atom types and type pairs to skip
|
|
this is for respa lists, copy the inner/middle values from parent
|
|
------------------------------------------------------------------------- */
|
|
|
|
void Neighbor::skip_from_respa(NeighList *list)
|
|
{
|
|
int i,j,ii,jj,n,itype,jnum,joriginal,n_inner,n_middle;
|
|
int *neighptr,*jlist,*neighptr_inner,*neighptr_middle;
|
|
|
|
int *type = atom->type;
|
|
|
|
int *ilist = list->ilist;
|
|
int *numneigh = list->numneigh;
|
|
int **firstneigh = list->firstneigh;
|
|
int **pages = list->pages;
|
|
int *ilist_skip = list->listskip->ilist;
|
|
int *numneigh_skip = list->listskip->numneigh;
|
|
int **firstneigh_skip = list->listskip->firstneigh;
|
|
int inum_skip = list->listskip->inum;
|
|
|
|
int *iskip = list->iskip;
|
|
int **ijskip = list->ijskip;
|
|
|
|
NeighList *listinner = list->listinner;
|
|
int *numneigh_inner = listinner->numneigh;
|
|
int **firstneigh_inner = listinner->firstneigh;
|
|
int **pages_inner = listinner->pages;
|
|
int *numneigh_inner_skip = list->listskip->listinner->numneigh;
|
|
int **firstneigh_inner_skip = list->listskip->listinner->firstneigh;
|
|
|
|
NeighList *listmiddle;
|
|
int *numneigh_middle,**firstneigh_middle,**pages_middle;
|
|
int *numneigh_middle_skip,**firstneigh_middle_skip;
|
|
int respamiddle = list->respamiddle;
|
|
if (respamiddle) {
|
|
listmiddle = list->listmiddle;
|
|
numneigh_middle = listmiddle->numneigh;
|
|
firstneigh_middle = listmiddle->firstneigh;
|
|
pages_middle = listmiddle->pages;
|
|
numneigh_middle_skip = list->listskip->listmiddle->numneigh;
|
|
firstneigh_middle_skip = list->listskip->listmiddle->firstneigh;
|
|
}
|
|
|
|
int inum = 0;
|
|
int npage = 0;
|
|
int npnt = 0;
|
|
int npage_inner = 0;
|
|
int npnt_inner = 0;
|
|
int npage_middle = 0;
|
|
int npnt_middle = 0;
|
|
|
|
// loop over atoms in other list
|
|
// skip I atom entirely if iskip is set for type[I]
|
|
// skip I,J pair if ijskip is set for type[I],type[J]
|
|
|
|
for (ii = 0; ii < inum_skip; ii++) {
|
|
i = ilist_skip[ii];
|
|
itype = type[i];
|
|
if (iskip[itype]) continue;
|
|
|
|
if (pgsize - npnt < oneatom) {
|
|
npnt = 0;
|
|
npage++;
|
|
if (npage == list->maxpage) pages = list->add_pages();
|
|
}
|
|
neighptr = &pages[npage][npnt];
|
|
n = 0;
|
|
|
|
if (pgsize - npnt_inner < oneatom) {
|
|
npnt_inner = 0;
|
|
npage_inner++;
|
|
if (npage_inner == listinner->maxpage)
|
|
pages_inner = listinner->add_pages();
|
|
}
|
|
neighptr_inner = &pages_inner[npage_inner][npnt_inner];
|
|
n_inner = 0;
|
|
|
|
if (respamiddle) {
|
|
if (pgsize - npnt_middle < oneatom) {
|
|
npnt_middle = 0;
|
|
npage_middle++;
|
|
if (npage_middle == listmiddle->maxpage)
|
|
pages_middle = listmiddle->add_pages();
|
|
}
|
|
neighptr_middle = &pages_middle[npage_middle][npnt_middle];
|
|
n_middle = 0;
|
|
}
|
|
|
|
// loop over parent outer rRESPA list
|
|
|
|
jlist = firstneigh_skip[i];
|
|
jnum = numneigh_skip[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (ijskip[itype][type[j]]) continue;
|
|
neighptr[n++] = joriginal;
|
|
}
|
|
|
|
// loop over parent inner rRESPA list
|
|
|
|
jlist = firstneigh_inner_skip[i];
|
|
jnum = numneigh_inner_skip[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (ijskip[itype][type[j]]) continue;
|
|
neighptr_inner[n_inner++] = joriginal;
|
|
}
|
|
|
|
// loop over parent middle rRESPA list
|
|
|
|
if (respamiddle) {
|
|
jlist = firstneigh_middle_skip[i];
|
|
jnum = numneigh_middle_skip[i];
|
|
|
|
for (jj = 0; jj < jnum; jj++) {
|
|
joriginal = jlist[jj];
|
|
j = joriginal & NEIGHMASK;
|
|
if (ijskip[itype][type[j]]) continue;
|
|
neighptr_middle[n_middle++] = joriginal;
|
|
}
|
|
}
|
|
|
|
ilist[inum++] = i;
|
|
firstneigh[i] = neighptr;
|
|
numneigh[i] = n;
|
|
npnt += n;
|
|
if (n > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
|
|
firstneigh_inner[i] = neighptr_inner;
|
|
numneigh_inner[i] = n_inner;
|
|
npnt_inner += n_inner;
|
|
if (n_inner > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
|
|
if (respamiddle) {
|
|
firstneigh_middle[i] = neighptr_middle;
|
|
numneigh_middle[i] = n_middle;
|
|
npnt_middle += n_middle;
|
|
if (n_middle > oneatom)
|
|
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
|
|
}
|
|
}
|
|
|
|
list->inum = inum;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
create list which is simply a copy of parent list
|
|
------------------------------------------------------------------------- */
|
|
|
|
void Neighbor::copy_from(NeighList *list)
|
|
{
|
|
NeighList *listcopy = list->listcopy;
|
|
|
|
list->inum = listcopy->inum;
|
|
list->gnum = listcopy->gnum;
|
|
list->ilist = listcopy->ilist;
|
|
list->numneigh = listcopy->numneigh;
|
|
list->firstneigh = listcopy->firstneigh;
|
|
list->firstdouble = listcopy->firstdouble;
|
|
list->pages = listcopy->pages;
|
|
list->dpages = listcopy->dpages;
|
|
}
|