From 635d42c51fe6b4a43443b56bbd70b42bdf6b6a0e Mon Sep 17 00:00:00 2001 From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa> Date: Fri, 27 Jun 2014 19:32:00 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@12152 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/VORONOI/compute_voronoi_atom.cpp | 72 +++++++++++++++------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/VORONOI/compute_voronoi_atom.cpp b/src/VORONOI/compute_voronoi_atom.cpp index 0d86d55724..08f2379633 100644 --- a/src/VORONOI/compute_voronoi_atom.cpp +++ b/src/VORONOI/compute_voronoi_atom.cpp @@ -42,7 +42,7 @@ ComputeVoronoi::ComputeVoronoi(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { int sgroup; - + size_peratom_cols = 2; peratom_flag = 1; @@ -63,18 +63,18 @@ ComputeVoronoi::ComputeVoronoi(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[iarg], "occupation") == 0) { occupation = true; iarg++; - } + } else if (strcmp(arg[iarg], "only_group") == 0) { onlyGroup = true; iarg++; - } + } else if (strcmp(arg[iarg], "radius") == 0) { if (iarg + 2 > narg || strstr(arg[iarg+1],"v_") != arg[iarg+1] ) error->all(FLERR,"Missing atom style variable for radical voronoi tesselation radius."); int n = strlen(&arg[iarg+1][2]) + 1; radstr = new char[n]; strcpy(radstr,&arg[iarg+1][2]); iarg += 2; - } + } else if (strcmp(arg[iarg], "surface") == 0) { if (iarg + 2 > narg) error->all(FLERR,"Missing group name after keyword 'surface'."); // group all is a special case where we just skip group testing @@ -83,7 +83,7 @@ ComputeVoronoi::ComputeVoronoi(LAMMPS *lmp, int narg, char **arg) : } else { sgroup = group->find(arg[iarg+1]); if (sgroup == -1) error->all(FLERR,"Could not find compute/voronoi surface group ID"); - sgroupbit = group->bitmask[sgroup]; + sgroupbit = group->bitmask[sgroup]; surface = VOROSURF_GROUP; } size_peratom_cols = 3; @@ -100,12 +100,12 @@ ComputeVoronoi::ComputeVoronoi(LAMMPS *lmp, int narg, char **arg) : if (iarg + 2 > narg) error->all(FLERR,"Missing minimum edge length after keyword 'edge_threshold'."); ethresh = force->numeric(FLERR,arg[iarg+1]); iarg += 2; - } - else + } + else error->all(FLERR,"Illegal compute voronoi/atom command"); } - if (occupation && ( surface!=VOROSURF_NONE || maxedge>0 ) ) + if (occupation && ( surface!=VOROSURF_NONE || maxedge>0 ) ) error->all(FLERR,"Illegal compute voronoi/atom command (occupation and (surface or edges))"); nmax = rmax = 0; @@ -183,9 +183,9 @@ void ComputeVoronoi::compute_peratom() // linked list structure for cell occupation count on the atoms oldnall= nall; memory->create(lroot,nall,"voronoi/atom:lroot"); // point to first atom index in cell (or -1 for empty cell) - lnext = NULL; + lnext = NULL; lmax = 0; - + // build the occupation buffer oldnatoms = atom->natoms; memory->create(occvec,oldnatoms,"voronoi/atom:occvec"); @@ -208,11 +208,12 @@ void ComputeVoronoi::buildCells() int i; const double e = 0.01; int nlocal = atom->nlocal; + int dim = domain->dimension; // in the onlyGroup mode we are not setting values for all atoms later in the voro loop // initialize everything to zero here if (onlyGroup) { - if (surface == VOROSURF_NONE) + if (surface == VOROSURF_NONE) for (i = 0; i < nlocal; i++) voro[i][0] = voro[i][1] = 0.0; else for (i = 0; i < nlocal; i++) voro[i][0] = voro[i][1] = voro[i][2] = 0.0; @@ -223,7 +224,7 @@ void ComputeVoronoi::buildCells() double *cut = comm->cutghost; double sublo_bound[3], subhi_bound[3], cut_bound[3]; double **x = atom->x; - + // setup bounds for voro++ domain for orthogonal and triclinic simulation boxes if( domain->triclinic ) { // triclinic box: embed parallelepiped into orthogonal voro++ domain @@ -257,7 +258,7 @@ void ComputeVoronoi::buildCells() for( i=0; i<3; ++i ) { n[i] = round( n[i]*pow( double(nall)/(V*8.0), 0.333333 ) ); n[i] = n[i]==0 ? 1 : n[i]; - } + } // clear edge statistics for (i = 0; i < maxedge; ++i) edge[i]=0; @@ -289,8 +290,8 @@ void ComputeVoronoi::buildCells() delete con_poly; con_poly = new container_poly(sublo_bound[0]-cut_bound[0]-e,subhi_bound[0]+cut_bound[0]+e, sublo_bound[1]-cut_bound[1]-e,subhi_bound[1]+cut_bound[1]+e, - sublo_bound[2]-cut_bound[2]-e,subhi_bound[2]+cut_bound[2]+e, - int(n[0]),int(n[1]),int(n[2]),false,false,false,8); + sublo_bound[2]-(dim==3 ? cut_bound[2]-e : 0.0),subhi_bound[2]+(dim==3 ? cut_bound[2]+e : 0.0), + int(n[0]),int(n[1]),int(n[2]),false,false,false,8); // pass coordinates for local and ghost atoms to voro++ for (i = 0; i < nall; i++) @@ -301,8 +302,8 @@ void ComputeVoronoi::buildCells() delete con_mono; con_mono = new container(sublo_bound[0]-cut_bound[0]-e,subhi_bound[0]+cut_bound[0]+e, sublo_bound[1]-cut_bound[1]-e,subhi_bound[1]+cut_bound[1]+e, - sublo_bound[2]-cut_bound[2]-e,subhi_bound[2]+cut_bound[2]+e, - int(n[0]),int(n[1]),int(n[2]),false,false,false,8); + sublo_bound[2]-(dim==3 ? cut_bound[2]-e : 0.0),subhi_bound[2]+(dim==3 ? cut_bound[2]+e : 0.0), + int(n[0]),int(n[1]),int(n[2]),false,false,false,8); // pass coordinates for local and ghost atoms to voro++ for (i = 0; i < nall; i++) @@ -346,12 +347,12 @@ void ComputeVoronoi::checkOccupation() if (i<nlocal) occvec[tags[k]-1]++; // add this atom to the linked list of cell j - if (lroot[k]<0) + if (lroot[k]<0) lroot[k]=i; else { j = lroot[k]; while (lnext[j]>=0) j=lnext[j]; - lnext[j] = i; + lnext[j] = i; } } } @@ -382,7 +383,7 @@ void ComputeVoronoi::checkOccupation() } } - // cherry pick currently owned atoms + // cherry pick currently owned atoms for (i=0; i<nlocal; i++) { // set the new atom count in the atom's first frame voronoi cell voro[i][0] = occvec[atom->tag[i]-1]; @@ -412,7 +413,7 @@ void ComputeVoronoi::loopCells() /* ---------------------------------------------------------------------- memory usage of local atom-based array ------------------------------------------------------------------------- */ -void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i) +void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i) { int j,k, *mask = atom->mask; std::vector<int> neigh, norder, vlist; @@ -428,16 +429,18 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i) // number of cell faces c.neighbors(neigh); + int neighs = neigh.size(); + if (fthresh > 0) { // count only faces above area threshold c.face_areas(narea); have_narea = true; voro[i][1] = 0.0; - for (j=0; j<narea.size(); ++j) + for (j=0; j<narea.size(); ++j) if (narea[j] > fthresh) voro[i][1] += 1.0; } else { // unthresholded face count - voro[i][1] = neigh.size(); + voro[i][1] = neighs; } // cell surface area @@ -446,23 +449,29 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i) } else if (surface == VOROSURF_GROUP) { if (!have_narea) c.face_areas(narea); voro[i][2] = 0.0; + + // each entry in neigh should correspond to amn entry in narea + if (neighs != narea.size()) + error->all(FLERR,"voro++ error: 'narea' and 'neigh' have a different size."); + // loop over all faces (neighbors) and check if they are in the surface group - for (j=0; j<voro[i][1]; ++j) - if (mask[neigh[j]] & sgroupbit) voro[i][2] += narea[j]; + for (j=0; j<neighs; ++j) + if (neigh[j] >= 0 && mask[neigh[j]] & sgroupbit) + voro[i][2] += narea[j]; } // histogram of number of face edges if (maxedge>0) { if (ethresh > 0) { - // count only edges above length threshold + // count only edges above length threshold c.vertices(vcell); c.face_vertices(vlist); // for each face: vertex count followed list of vertex indices (n_1,v1_1,v2_1,v3_1,..,vn_1,n_2,v2_1,...) double dx, dy, dz, r2, t2 = ethresh*ethresh; - for( j=0; j<vlist.size(); j+=vlist[j]+1 ) { + for( j=0; j<vlist.size(); j+=vlist[j]+1 ) { int a, b, nedge = 0; // vlist[j] contains number of vertex indices for the current face - for( k=0; k<vlist[j]; ++k ) { - a = vlist[j+1+k]; // first vertex in edge + for( k=0; k<vlist[j]; ++k ) { + a = vlist[j+1+k]; // first vertex in edge b = vlist[j+1+(k+1)%vlist[j]]; // second vertex in edge (possible wrap around to first vertex in list) dx = vcell[a*3] - vcell[b*3]; dy = vcell[a*3+1] - vcell[b*3+1]; @@ -472,7 +481,7 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i) } // counted edges above threshold, now put into the correct bin if (nedge>0) { - if (nedge<=maxedge) + if (nedge<=maxedge) edge[nedge-1]++; else edge[maxedge]++; @@ -483,7 +492,7 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i) c.face_orders(norder); for (j=0; j<voro[i][1]; ++j) if (norder[j]>0) { - if (norder[j]<=maxedge) + if (norder[j]<=maxedge) edge[norder[j]-1]++; else edge[maxedge]++; @@ -526,4 +535,3 @@ void ComputeVoronoi::unpack_comm(int n, int first, double *buf) last = first + n; for (i = first; i < last; i++) rfield[i] = buf[m++]; } - -- GitLab