git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@3677 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2010-01-14 00:14:19 +00:00
parent 3f62cccb13
commit f78f394d01
5 changed files with 89 additions and 42 deletions

View File

@ -15,6 +15,7 @@
#include "stdio.h" #include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
#include "limits.h"
#include "atom.h" #include "atom.h"
#include "style_atom.h" #include "style_atom.h"
#include "atom_vec.h" #include "atom_vec.h"
@ -52,7 +53,8 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
extra_bond_per_atom = 0; extra_bond_per_atom = 0;
firstgroupname = NULL; firstgroupname = NULL;
sortfreq = 0; sortfreq = 1000;
userbinsize = 0.0;
maxbin = maxnext = 0; maxbin = maxnext = 0;
binhead = NULL; binhead = NULL;
next = permute = NULL; next = permute = NULL;
@ -307,15 +309,10 @@ void Atom::init()
void Atom::setup() void Atom::setup()
{ {
// setup for sorting // setup bins for sorting
// binsize = user setting or 1/2 of neighbor cutoff // cannot do this in init() because uses neighbor cutoff
if (sortfreq > 0) { if (sortfreq > 0) setup_sort_bins();
double binsize;
if (userbinsize > 0.0) binsize = userbinsize;
else binsize = 0.5 * neighbor->cutneighmax;
bininv = 1.0/binsize;
}
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -1331,37 +1328,20 @@ void Atom::first_reorder()
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
perform spatial sort of atoms within my sub-domain perform spatial sort of atoms within my sub-domain
always called between comm->exchange() and comm->borders()
don't have to worry about clearing/setting atom->map since done in comm
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void Atom::sort() void Atom::sort()
{ {
int i,m,n,ix,iy,iz,ibin,empty,ndone; int i,m,n,ix,iy,iz,ibin,empty,ndone;
// setup local bins, grow arrays as necessary // re-setup sort bins if needed
double *sublo = domain->sublo; if (domain->box_change) setup_sort_bins();
double *subhi = domain->subhi;
int nbinx = static_cast<int> ((subhi[0]-sublo[0]) * bininv);
int nbiny = static_cast<int> ((subhi[1]-sublo[1]) * bininv);
int nbinz = static_cast<int> ((subhi[2]-sublo[2]) * bininv);
nbinx = MAX(nbinx,1);
nbinx = MAX(nbiny,1);
nbinx = MAX(nbinz,1);
int nbins = nbinx*nbiny*nbinz;
if (nbins == 1) return; if (nbins == 1) return;
// reallocate per-bin memory if needed // reallocate per-atom vectors if needed
if (nbins > maxbin) {
memory->sfree(binhead);
maxbin = nbins;
binhead = (int *) memory->smalloc(maxbin*sizeof(int),"sort:binhead");
}
// reallocate per-atom memory if needed
if (nlocal > maxnext) { if (nlocal > maxnext) {
memory->sfree(next); memory->sfree(next);
@ -1380,9 +1360,9 @@ void Atom::sort()
for (i = 0; i < nbins; i++) binhead[i] = -1; for (i = 0; i < nbins; i++) binhead[i] = -1;
for (i = nlocal-1; i >= 0; i--) { for (i = nlocal-1; i >= 0; i--) {
ix = static_cast<int> ((x[i][0]-sublo[0])*bininv); ix = static_cast<int> ((x[i][0]-bboxlo[0])*bininv);
iy = static_cast<int> ((x[i][1]-sublo[1])*bininv); iy = static_cast<int> ((x[i][1]-bboxlo[1])*bininv);
iz = static_cast<int> ((x[i][2]-sublo[2])*bininv); iz = static_cast<int> ((x[i][2]-bboxlo[2])*bininv);
ix = MAX(ix,0); ix = MAX(ix,0);
iy = MAX(iy,0); iy = MAX(iy,0);
iz = MAX(iz,0); iz = MAX(iz,0);
@ -1433,16 +1413,68 @@ void Atom::sort()
// sanity check that current = permute // sanity check that current = permute
int flag = 0; //int flag = 0;
for (i = 0; i < nlocal; i++) //for (i = 0; i < nlocal; i++)
if (current[i] != permute[i]) flag = 1; // if (current[i] != permute[i]) flag = 1;
int flagall; //int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); //MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall) error->all("Atom sort did not operate correctly"); //if (flagall) error->all("Atom sort did not operate correctly");
// set next timestep for sorting to take place // set next timestep for sorting to take place
nextsort += sortfreq; nextsort = (update->ntimestep/sortfreq)*sortfreq + sortfreq;
}
/* ----------------------------------------------------------------------
setup bins for spatial sorting of atoms
------------------------------------------------------------------------- */
void Atom::setup_sort_bins()
{
// binsize = user setting or 1/2 of neighbor cutoff
// neighbor cutoff can be 0.0
double binsize;
if (userbinsize > 0.0) binsize = userbinsize;
else binsize = 0.5 * neighbor->cutneighmax;
if (binsize == 0.0) error->all("Atom sorting has bin size = 0.0");
bininv = 1.0/binsize;
// nbin xyz = local bins
// bbox lo/hi = bounding box of my sub-domain
if (domain->triclinic)
domain->bbox(domain->sublo_lamda,domain->subhi_lamda,bboxlo,bboxhi);
else {
bboxlo[0] = domain->sublo[0];
bboxlo[1] = domain->sublo[1];
bboxlo[2] = domain->sublo[2];
bboxhi[0] = domain->subhi[0];
bboxhi[1] = domain->subhi[1];
bboxhi[2] = domain->subhi[2];
}
nbinx = static_cast<int> ((bboxhi[0]-bboxlo[0]) * bininv);
nbiny = static_cast<int> ((bboxhi[1]-bboxlo[1]) * bininv);
nbinz = static_cast<int> ((bboxhi[2]-bboxlo[2]) * bininv);
nbinx = MAX(nbinx,1);
nbinx = MAX(nbiny,1);
nbinx = MAX(nbinz,1);
if (1.0*nbinx*nbiny*nbinz > INT_MAX)
error->one("Too many atom sorting bins");
nbins = nbinx*nbiny*nbinz;
// reallocate per-bin memory if needed
if (nbins > maxbin) {
memory->sfree(binhead);
maxbin = nbins;
binhead = (int *) memory->smalloc(maxbin*sizeof(int),"atom:binhead");
}
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -196,16 +196,21 @@ class Atom : protected Pointers {
// spatial sorting of atoms // spatial sorting of atoms
int maxbin; // # of bins memory is allocated for int nbins; // # of sorting bins
int nbinx,nbiny,nbinz; // bins in each dimension
int maxbin; // max # of bins
int maxnext; // max size of next,permute int maxnext; // max size of next,permute
int *binhead; // 1st atom in each bin int *binhead; // 1st atom in each bin
int *next; // next atom in bin int *next; // next atom in bin
int *permute; // permutation vector int *permute; // permutation vector
double userbinsize; // sorting bin size double userbinsize; // sorting bin size
double bininv; double bininv;
double bboxlo[3],bboxhi[3]; // bounding box of my sub-domain
int memlength; // allocated size of memstr int memlength; // allocated size of memstr
char *memstr; // string of array names already counted char *memstr; // string of array names already counted
void setup_sort_bins();
}; };
} }

View File

@ -203,12 +203,14 @@ void Min::setup()
// acquire ghosts // acquire ghosts
// build neighbor lists // build neighbor lists
atom->setup();
if (triclinic) domain->x2lamda(atom->nlocal); if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc(); domain->pbc();
domain->reset_box(); domain->reset_box();
comm->setup(); comm->setup();
if (neighbor->style) neighbor->setup_bins(); if (neighbor->style) neighbor->setup_bins();
comm->exchange(); comm->exchange();
if (atom->sortfreq > 0) atom->sort();
comm->borders(); comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
neighbor->build(); neighbor->build();
@ -407,6 +409,8 @@ double Min::energy_force(int resetflag)
} }
timer->stamp(); timer->stamp();
comm->exchange(); comm->exchange();
if (atom->sortfreq > 0 &&
update->ntimestep >= atom->nextsort) atom->sort();
comm->borders(); comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
timer->stamp(TIME_COMM); timer->stamp(TIME_COMM);

View File

@ -1255,6 +1255,8 @@ void Neighbor::setup_bins()
// memory for bin ptrs // memory for bin ptrs
if (1.0*mbinx*mbiny*mbinz > INT_MAX) error->one("Too many neighbor bins");
mbins = mbinx*mbiny*mbinz; mbins = mbinx*mbiny*mbinz;
if (mbins > maxhead) { if (mbins > maxhead) {
maxhead = mbins; maxhead = mbins;

View File

@ -316,12 +316,14 @@ void Respa::setup()
// acquire ghosts // acquire ghosts
// build neighbor lists // build neighbor lists
atom->setup();
if (triclinic) domain->x2lamda(atom->nlocal); if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc(); domain->pbc();
domain->reset_box(); domain->reset_box();
comm->setup(); comm->setup();
if (neighbor->style) neighbor->setup_bins(); if (neighbor->style) neighbor->setup_bins();
comm->exchange(); comm->exchange();
if (atom->sortfreq > 0) atom->sort();
comm->borders(); comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
neighbor->build(); neighbor->build();
@ -503,6 +505,8 @@ void Respa::recurse(int ilevel)
} }
timer->stamp(); timer->stamp();
comm->exchange(); comm->exchange();
if (atom->sortfreq > 0 &&
update->ntimestep >= atom->nextsort) atom->sort();
comm->borders(); comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
timer->stamp(TIME_COMM); timer->stamp(TIME_COMM);