--- /home/sjplimp/oldlammps/src/delete_atoms.cpp 2006-04-11 18:20:56.000000000 -0600 +++ /home/sjplimp/lammps/src/delete_atoms.cpp 2006-05-31 16:37:38.000000000 -0600 @@ -16,8 +16,12 @@ #include "atom.h" #include "comm.h" #include "domain.h" +#include "force.h" #include "group.h" #include "region.h" +#include "neighbor.h" +#include "comm.h" +#include "force.h" #include "error.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -31,7 +35,6 @@ { if (domain->box_exist == 0) error->all("Delete_atoms command before simulation box is defined"); - if (narg < 1) error->all("Illegal delete_atoms command"); // store state before delete @@ -42,79 +45,52 @@ int natoms_previous = static_cast (atom->natoms); int tag_lowest = natoms_previous + 1; - // delete group: delete all atoms in group, group still exists - - if (strcmp(arg[0],"group") == 0) { - - if (narg != 2) error->all("Illegal delete_atoms group command"); - - int igroup = group->find(arg[1]); - if (igroup == -1) error->all("Could not find delete_atoms group ID"); - - int *mask = atom->mask; - int *tag = atom->tag; - int nlocal = atom->nlocal; - int groupbit = group->bitmask[igroup]; - - int i = 0; - while (i < nlocal) { - if (mask[i] & groupbit) { - tag_lowest = MIN(tag_lowest,tag[i]); - atom->copy(nlocal-1,i); - nlocal--; - } else i++; - } - atom->nlocal = nlocal; - - // delete region: delete an atom if it is in region - - } else if (strcmp(arg[0],"region") == 0) { - - if (narg != 2) error->all("Illegal delete_atoms region command"); - - int iregion; - for (iregion = 0; iregion < domain->nregion; iregion++) - if (strcmp(arg[1],domain->regions[iregion]->id) == 0) break; - if (iregion == domain->nregion) - error->all("Delete_atoms region ID does not exist"); - - double **x = atom->x; - int *tag = atom->tag; - int nlocal = atom->nlocal; - - int i = 0; - while (i < nlocal) { - if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) { - tag_lowest = MIN(tag_lowest,tag[i]); - atom->copy(nlocal-1,i); - nlocal--; - } else i++; - } - atom->nlocal = nlocal; - - // delete overlap: delete one of any 2 atoms within overlap - - } else if (strcmp(arg[0],"overlap") == 0) { - - error->all("Delete_atoms overlap not yet implemented"); + // allocate and initialize deletion list + + int nlocal = atom->nlocal; + int *list = new int[nlocal]; + + for (int i = 0; i < nlocal; i++) list[i] = 0; + + // delete the atoms + // return tag_lowest = min tag of each proc's deleted atoms + + if (strcmp(arg[0],"group") == 0) delete_group(narg,arg,list); + else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg,list); + else if (strcmp(arg[0],"overlap") == 0) delete_overlap(narg,arg,list); + else error->all("Illegal delete_atoms command"); + + // delete local atoms in list + // reset nlocal + // tag_lowest_all = smallest deleted atom tag on any proc + + int *tag = atom->tag; + + int i = 0; + while (i < nlocal) { + if (list[i]) { + tag_lowest = MIN(tag_lowest,tag[i]); + atom->copy(nlocal-1,i); + list[i] = list[nlocal-1]; + nlocal--; + } else i++; + } + atom->nlocal = nlocal; + delete [] list; - } else error->all("Illegal delete_atoms command"); + int tag_lowest_all; + MPI_Allreduce(&tag_lowest,&tag_lowest_all,1,MPI_INT,MPI_MIN,world); // if non-molecular system, reset atom tags to be contiguous - // tag_lowest_all = lowest atom ID of a deleted atom // set all atom IDs >= tag_lowest_all to 0 - // tag_extend to reset tags for all those atoms + // tag_extend() will reset tags for those atoms if (atom->molecular == 0) { - int tag_lowest_all; - MPI_Allreduce(&tag_lowest,&tag_lowest_all,1,MPI_INT,MPI_MIN,world); - int *tag = atom->tag; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) + for (i = 0; i < nlocal; i++) if (tag[i] >= tag_lowest_all) tag[i] = 0; - atom->tag_extend(); } @@ -130,7 +106,7 @@ atom->map_set(); } - // print atoms before and after + // print before and after atom count int ndelete = static_cast (natoms_previous - atom->natoms); @@ -141,3 +117,181 @@ ndelete,atom->natoms); } } + +/* ---------------------------------------------------------------------- + delete all atoms in group + group will still exist +------------------------------------------------------------------------- */ + +void DeleteAtoms::delete_group(int narg, char **arg, int *list) +{ + if (narg != 2) error->all("Illegal delete_atoms command"); + + int igroup = group->find(arg[1]); + if (igroup == -1) error->all("Could not find delete_atoms group ID"); + + int *mask = atom->mask; + int nlocal = atom->nlocal; + int groupbit = group->bitmask[igroup]; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) list[i] = 1; +} + +/* ---------------------------------------------------------------------- + delete all atoms in region +------------------------------------------------------------------------- */ + +void DeleteAtoms::delete_region(int narg, char **arg, int *list) +{ + if (narg != 2) error->all("Illegal delete_atoms command"); + + int iregion; + for (iregion = 0; iregion < domain->nregion; iregion++) + if (strcmp(arg[1],domain->regions[iregion]->id) == 0) break; + if (iregion == domain->nregion) + error->all("Could not find delete_atoms region ID"); + + double **x = atom->x; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) + if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) list[i] = 1; +} + +/* ---------------------------------------------------------------------- + delete atoms so there are no pairs within cutoff + which atoms are deleted depends on ordering of atoms within proc + deletions can vary with processor count + no guarantee that minimium number of atoms will be deleted +------------------------------------------------------------------------- */ + +void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) +{ + if (narg < 2) error->all("Illegal delete_atoms command"); + + // read args including optional type info + + double cut = atof(arg[1]); + double cutsq = cut*cut; + + int typeflag,type1,type2; + if (narg == 2) typeflag = 0; + else if (narg == 3) { + typeflag = 1; + type1 = atoi(arg[2]); + } else if (narg == 4) { + typeflag = 2; + type1 = atoi(arg[2]); + type2 = atoi(arg[3]); + } else error->all("Illegal delete_atoms command"); + + // init entire system since comm->borders and neighbor->build is done + // comm::init needs neighbor::init needs pair::init needs kspace::init, etc + + if (comm->me == 0 && screen) + fprintf(screen,"System init for delete_atoms ...\n"); + System::init(); + + // setup domain, communication and neighboring + // acquire ghosts + // build neighbor lists + + domain->pbc(); + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + comm->exchange(); + comm->borders(); + neighbor->build(); + + // error check on cutoff + + if (cut > neighbor->cutneigh) + error->all("Delete_atoms cutoff > neighbor cutoff"); + + // create an atom map if one doesn't exist already + + int mapflag = 0; + if (atom->map_style == 0) { + mapflag = 1; + atom->map_style = 1; + atom->map_init(); + atom->map_set(); + } + + // double loop over owned atoms and their neighbors + // at end of loop, there are no more overlaps + // criteria for i,j to undergo a deletion event: + // weighting factor != 0.0 for this pair + // could be 0 and still be in neigh list for long-range Coulombics + // local copy of j (map[tag[j]]) has not already been deleted + // distance between i,j is less than cutoff + // i,j are of valid types + // if all criteria met, delete i and skip to next i in outer loop + // unless j is ghost and newton_pair off and tag[j] < tag[i] + // then rely on other proc to delete + + int *tag = atom->tag; + int *type = atom->type; + double **x = atom->x; + int nlocal = atom->nlocal; + int nall = atom->nlocal + atom->nghost; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + int i,j,k,m,itype,jtype,numneigh; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighs; + + for (i = 0; i < nlocal; i++) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + neighs = neighbor->firstneigh[i]; + numneigh = neighbor->numneigh[i]; + + for (k = 0; k < numneigh; k++) { + j = neighs[k]; + list[i] = 1; + if (j >= nall) { + if (special_coul[j/nall] == 0.0 && special_lj[j/nall] == 0.0) continue; + j %= nall; + } + + if (j < nlocal) { + if (list[j]) continue; + } else { + m = atom->map(tag[j]); + if (m < nlocal && list[m]) continue; + } + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + if (rsq >= cutsq) continue; + + if (typeflag) { + jtype = type[j]; + if (typeflag == 1 && itype != type1 && jtype != type1) continue; + if (typeflag == 2 && !(itype == type1 && jtype == type2) && + !(itype == type2 && jtype == type1)) continue; + } + + if (j >= nlocal && newton_pair == 0 && tag[j] < tag[i]) continue; + + list[i] = 1; + break; + } + } + + // delete temporary atom map + + if (mapflag) { + atom->map_delete(); + atom->map_style = 0; + } +} --- /home/sjplimp/oldlammps/src/delete_atoms.h 2006-04-11 18:20:56.000000000 -0600 +++ /home/sjplimp/lammps/src/delete_atoms.h 2006-05-19 10:21:59.000000000 -0600 @@ -21,6 +21,11 @@ DeleteAtoms() {} ~DeleteAtoms() {} void command(int, char **); + + private: + void delete_group(int, char **, int *); + void delete_region(int, char **, int *); + void delete_overlap(int, char **, int *); }; #endif --- /home/sjplimp/oldlammps/src/thermo.cpp 2006-05-31 16:57:18.000000000 -0600 +++ /home/sjplimp/lammps/src/thermo.cpp 2006-05-31 16:54:58.000000000 -0600 @@ -218,12 +218,12 @@ if ((tempflag || pressflag) && atom->check_style("granular")) error->all("Cannot use atom style granular with chosen thermo settings"); - // set normflag to default value unless user has specified a setting + // set normvalue to default setting unless user has specified it - if (normuserflag) normflag = normuser; - else if (strcmp(style,"granular") == 0) normflag = 0; - else if (strcmp(update->unit_style,"lj") == 0) normflag = 1; - else normflag = 0; + if (normuserflag) normvalue = normuser; + else if (strcmp(style,"granular") == 0) normvalue = 0; + else if (strcmp(update->unit_style,"lj") == 0) normvalue = 1; + else normvalue = 0; // check for granular freeze Fix and set freeze_group_bit @@ -340,9 +340,14 @@ { firststep = flag; - // check for lost atoms and compute requested thermo quantities + // check for lost atoms + // turn off normflag if natoms = 0 to avoid divide by 0 + // compute requested thermo quantities natoms = lost_check(); + if (natoms == 0) normflag = 0; + else normflag = normvalue; + if (tempflag) tempvalue = temperature->compute(); if (pressflag) pressure->compute(temperature); if (nextra) { --- /home/sjplimp/oldlammps/src/thermo.h 2006-05-31 16:57:18.000000000 -0600 +++ /home/sjplimp/lammps/src/thermo.h 2006-05-31 16:53:19.000000000 -0600 @@ -55,6 +55,7 @@ char **format; int normflag; // 0 if do not normalize by atoms, 1 if normalize + int normvalue; // use this for normflag unless natoms = 0 int normuserflag; // 0 if user has not set, 1 if has int normuser; --- /home/sjplimp/oldlammps/doc/delete_atoms.txt 2006-04-11 18:20:56.000000000 -0600 +++ /home/sjplimp/lammps/doc/delete_atoms.txt 2006-05-31 16:36:29.000000000 -0600 @@ -15,32 +15,61 @@ style = {group} or {region} or {overlap} :ulb,l {group} args = group-ID {region} args = region-ID - {overlap} args = distance (distance units) :pre + {overlap} args = distance type1 type2 + distance = delete atoms with neighbors within this cutoff (distance units) + type1 = type of first atom in pair (optional) + type2 = type of other atom in pair (optional) +:pre :ule [Examples:] delete_atoms group edge -delete_atoms region regsphere -delete_atoms overlap 0.3 :pre +delete_atoms region sphere +delete_atoms overlap 0.3 +delete_atoms overlap 0.3 1 1 :pre [Description:] -Delete the specfied atoms. For style {group}, it is all atoms -belonging to the group. For style {region}, it is any atom that is in -the region volume. For style {overlap}, pairs of atoms within the -specified distance are searched for, and one of the 2 atoms is -deleted. See the "units"_units.txt command for a discussion of -distance units. - -This command can be used to carve out voids from a block of material. +Delete the specfied atoms. This command can be used to carve out +voids from a block of material or to delete created atoms that are too +close to each other (e.g. at a grain boundary). + +For style {group}, all atoms belonging to the group are deleted. + +For style {region}, all atoms in the region volume are deleted. + +For style {overlap}, pairs of atoms within the specified cutoff +distance are searched for, and one of the 2 atoms is deleted. If no +atom types are specified, an atom will always be deleted if the cutoff +criterion is met. If a single atom type is specified, then one or +both of the atoms in the pair must be of the specified type for a +deletion to occur. If two atom types are specified, the two atoms in +the pair must be of the specified types for a deletion to occur. For +a given configuration of atoms, the only guarantee is that at the end +of the deletion operation, enough deletions will have occurred that no +atom pairs within the cutoff (and with the specified types) will +remain. There is no guarantee that the minimum number of atoms will +be deleted, or that the same atoms will be deleted when running on +different numbers of processors. After atoms are deleted, if the system is not molecular (no bonds), then atom IDs are re-assigned so that they run from 1 to the number of atoms in the system. This is not done for molecular systems, since it would foul up the bond connectivity that has already been assigned. -[Restrictions:] none +[Restrictions:] + +The {overlap} style requires inter-processor communication to acquire +ghost atoms and setup a neighbor list. This means that your system +must be ready to perform a simulation before using this command (force +fields setup, atom masses set, etc). + +If the "special_bonds"_special_bonds.html command is used with a +setting of 0, then a pair of bonded atoms (1-2, 1-3, or 1-4) will not +appear in the neighbor list, and thus will not be considered for +deltion by the {overlap} style. You probably don't want to be +deleting one atom in a bonded pair anyway. [Related commands:] --- /home/sjplimp/oldlammps/doc/delete_atoms.html 2006-04-11 18:20:56.000000000 -0600 +++ /home/sjplimp/lammps/doc/delete_atoms.html 2006-05-31 16:09:48.000000000 -0600 @@ -19,26 +19,44 @@
  group args = group-ID
   region args = region-ID
-  overlap args = distance (distance units) 
+  overlap args = distance type1 type2
+    distance = no atom pair will remain within this cutoff (distance units)
+    type1 = type of first atom in pair (optional)
+    type2 = type of other atom in pair (optional)
+
 

Examples:

delete_atoms group edge
-delete_atoms region regsphere
-delete_atoms overlap 0.3 
+delete_atoms region sphere
+delete_atoms overlap 0.3
+delete_atoms overlap 0.3 1 1 
 

Description:

-

Delete the specfied atoms. For style group, it is all atoms -belonging to the group. For style region, it is any atom that is in -the region volume. For style overlap, pairs of atoms within the -specified distance are searched for, and one of the 2 atoms is -deleted. See the units command for a discussion of -distance units. -

-

This command can be used to carve out voids from a block of material. +

Delete the specfied atoms. This command can be used to carve out +voids from a block of material or to delete atoms at a created grain +boundary that are too close to each other. +

+

For style group, all atoms belonging to the group are deleted. +

+

For style region, all atoms in the region volume are deleted. +

+

For style overlap, pairs of atoms within the specified cutoff +distance are searched for, and one of the 2 atoms is deleted. If no +atom types are specified, an atom will always be deleted if the cutoff +criterion is met. If a single atom type is specified, then one or +both of the atoms in the pair must be of the specified type for a +deletion to occur. If two atom types are specified, the two atoms in +the pair must be of the specified types for a deletion to occur. For +a given configuration of atoms, the only guarantee is that at the end +of the deletion operation, enough deletions will have occurred that no +atom pairs within the cutoff (and with the specified types) will +remain. There is no guarantee that the minimum number of atoms will +be deleted, or that the same atoms will be deleted when running on +different numbers of processors.

After atoms are deleted, if the system is not molecular (no bonds), then atom IDs are re-assigned so that they run from 1 to the number of