diff --git a/src/compute_group_group.cpp b/src/compute_group_group.cpp index 79a6f63b90..a0bfbc34a7 100644 --- a/src/compute_group_group.cpp +++ b/src/compute_group_group.cpp @@ -16,6 +16,7 @@ ------------------------------------------------------------------------- */ #include "mpi.h" +#include "string.h" #include "compute_group_group.h" #include "atom.h" #include "update.h" @@ -41,7 +42,11 @@ ComputeGroupGroup::ComputeGroupGroup(LAMMPS *lmp, int narg, char **arg) : extscalar = 1; extvector = 1; - jgroup = group->find(arg[3]); + int n = strlen(arg[3]) + 1; + group2 = new char[n]; + strcpy(group2,arg[3]); + + jgroup = group->find(group2); if (jgroup == -1) error->all("Compute group/group group ID does not exist"); jgroupbit = group->bitmask[jgroup]; @@ -52,6 +57,7 @@ ComputeGroupGroup::ComputeGroupGroup(LAMMPS *lmp, int narg, char **arg) : ComputeGroupGroup::~ComputeGroupGroup() { + delete [] group2; delete [] vector; } @@ -64,6 +70,12 @@ void ComputeGroupGroup::init() pair = force->pair; cutsq = force->pair->cutsq; + // recheck that group 2 has not been deleted + + jgroup = group->find(group2); + if (jgroup == -1) error->all("Compute group/group group ID does not exist"); + jgroupbit = group->bitmask[jgroup]; + // need an occasional half neighbor list int irequest = neighbor->request((void *) this); diff --git a/src/compute_group_group.h b/src/compute_group_group.h index 9f37dd8c48..65d47e5fe6 100644 --- a/src/compute_group_group.h +++ b/src/compute_group_group.h @@ -28,6 +28,7 @@ class ComputeGroupGroup : public Compute { void compute_vector(); private: + char *group2; int jgroup,jgroupbit,othergroupbit; double **cutsq; class Pair *pair; diff --git a/src/fix_spring.cpp b/src/fix_spring.cpp index 3cfc495a0f..1e985a8569 100644 --- a/src/fix_spring.cpp +++ b/src/fix_spring.cpp @@ -49,6 +49,8 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : extscalar = 1; extvector = 1; + group2 = NULL; + if (strcmp(arg[3],"tether") == 0) { if (narg != 9) error->all("Illegal fix spring command"); styleflag = TETHER; @@ -66,12 +68,17 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[3],"couple") == 0) { if (narg != 10) error->all("Illegal fix spring command"); styleflag = COUPLE; + + int n = strlen(arg[4]) + 1; + group2 = new char[n]; + strcpy(group2,arg[4]); igroup2 = group->find(arg[4]); if (igroup2 == -1) - error->all("Could not find fix spring couple group ID"); + error->all("Fix spring couple group ID does not exist"); if (igroup2 == igroup) error->all("Two groups cannot be the same in fix spring couple"); group2bit = group->bitmask[igroup2]; + k_spring = atof(arg[5]); xflag = yflag = zflag = 1; if (strcmp(arg[6],"NULL") == 0) xflag = 0; @@ -90,6 +97,13 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : /* ---------------------------------------------------------------------- */ +FixSpring::~FixSpring() +{ + delete [] group2; +} + +/* ---------------------------------------------------------------------- */ + int FixSpring::setmask() { int mask = 0; @@ -104,6 +118,15 @@ int FixSpring::setmask() void FixSpring::init() { + // recheck that group 2 has not been deleted + + if (group2) { + igroup2 = group->find(group2); + if (igroup2 == -1) + error->all("Fix spring couple group ID does not exist"); + group2bit = group->bitmask[igroup2]; + } + masstotal = group->mass(igroup); if (styleflag == COUPLE) masstotal2 = group->mass(igroup2); diff --git a/src/fix_spring.h b/src/fix_spring.h index 0fb7df1dd4..a5b1f92c23 100644 --- a/src/fix_spring.h +++ b/src/fix_spring.h @@ -21,6 +21,7 @@ namespace LAMMPS_NS { class FixSpring : public Fix { public: FixSpring(class LAMMPS *, int, char **); + ~FixSpring(); int setmask(); void init(); void setup(int); @@ -36,6 +37,7 @@ class FixSpring : public Fix { double k_spring; int xflag,yflag,zflag; int styleflag; + char *group2; int igroup2,group2bit; double masstotal,masstotal2; int nlevels_respa; diff --git a/src/group.cpp b/src/group.cpp index 0b8196e08d..92fdaab220 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -21,7 +21,11 @@ #include "atom.h" #include "force.h" #include "region.h" -#include "memory.h" +#include "modify.h" +#include "fix.h" +#include "compute.h" +#include "output.h" +#include "dump.h" #include "error.h" using namespace LAMMPS_NS; @@ -44,9 +48,11 @@ Group::Group(LAMMPS *lmp) : Pointers(lmp) { MPI_Comm_rank(world,&me); - names = (char **) memory->smalloc(MAX_GROUP*sizeof(char *),"group:names"); + names = new char*[MAX_GROUP]; bitmask = new int[MAX_GROUP]; inversemask = new int[MAX_GROUP]; + + for (int i = 0; i < MAX_GROUP; i++) names[i] = NULL; for (int i = 0; i < MAX_GROUP; i++) bitmask[i] = 1 << i; for (int i = 0; i < MAX_GROUP; i++) inversemask[i] = bitmask[i] ^ ~0; @@ -54,7 +60,7 @@ Group::Group(LAMMPS *lmp) : Pointers(lmp) char *str = (char *) "all"; int n = strlen(str) + 1; - names[0] = (char *) memory->smalloc(n*sizeof(char),"group:names[]"); + names[0] = new char[n]; strcpy(names[0],str); ngroup = 1; } @@ -65,8 +71,8 @@ Group::Group(LAMMPS *lmp) : Pointers(lmp) Group::~Group() { - for (int i = 0; i < ngroup; i++) memory->sfree(names[i]); - memory->sfree(names); + for (int i = 0; i < MAX_GROUP; i++) delete [] names[i]; + delete [] names; delete [] bitmask; delete [] inversemask; } @@ -83,18 +89,49 @@ void Group::assign(int narg, char **arg) error->all("Group command before simulation box is defined"); if (narg < 2) error->all("Illegal group command"); + // delete the group if not being used elsewhere + // clear mask of each atom assigned to this group + + if (strcmp(arg[1],"delete") == 0) { + int igroup = find(arg[0]); + if (igroup == -1) error->all("Could not find delete group ID"); + if (igroup == 0) error->all("Cannot delete group all"); + for (i = 0; i < modify->nfix; i++) + if (modify->fix[i]->igroup == igroup) + error->all("Cannot delete group currently used by a fix"); + for (i = 0; i < modify->ncompute; i++) + if (modify->compute[i]->igroup == igroup) + error->all("Cannot delete group currently used by a compute"); + for (i = 0; i < output->ndump; i++) + if (output->dump[i]->igroup == igroup) + error->all("Cannot delete group currently used by a dump"); + if (atom->firstgroupname && strcmp(arg[0],atom->firstgroupname) == 0) + error->all("Cannot delete group currently used by atom_modify first"); + + int *mask = atom->mask; + int nlocal = atom->nlocal; + int bits = inversemask[igroup]; + for (i = 0; i < nlocal; i++) mask[i] &= bits; + + delete [] names[igroup]; + names[igroup] = NULL; + ngroup--; + + return; + } + // find group in existing list - // igroup = -1 requires a new group, add it + // add a new group if igroup = -1 int igroup = find(arg[0]); if (igroup == -1) { if (ngroup == MAX_GROUP) error->all("Too many groups"); - igroup = ngroup; - ngroup++; + igroup = find_unused(); int n = strlen(arg[0]) + 1; - names[igroup] = (char *) memory->smalloc(n*sizeof(char),"group:names[]"); + names[igroup] = new char[n]; strcpy(names[igroup],arg[0]); + ngroup++; } double **x = atom->x; @@ -329,20 +366,20 @@ void Group::create(char *name, int *flag) int i; // find group in existing list - // igroup = -1 requires a new group, add it + // add a new group if igroup = -1 int igroup = find(name); if (igroup == -1) { if (ngroup == MAX_GROUP) error->all("Too many groups"); - igroup = ngroup; - ngroup++; + igroup = find_unused(); int n = strlen(name) + 1; - names[igroup] = (char *) memory->smalloc(n*sizeof(char),"group:names[]"); + names[igroup] = new char[n]; strcpy(names[igroup],name); + ngroup++; } - // add atom to group if flag is set + // add atoms to group whose flags are set int *mask = atom->mask; int nlocal = atom->nlocal; @@ -358,8 +395,20 @@ void Group::create(char *name, int *flag) int Group::find(const char *name) { - for (int igroup = 0; igroup < ngroup; igroup++) - if (strcmp(name,names[igroup]) == 0) return igroup; + for (int igroup = 0; igroup < MAX_GROUP; igroup++) + if (names[igroup] && strcmp(name,names[igroup]) == 0) return igroup; + return -1; +} + +/* ---------------------------------------------------------------------- + return index of first available group + should never be called when group limit has been reached +------------------------------------------------------------------------- */ + +int Group::find_unused() +{ + for (int igroup = 0; igroup < MAX_GROUP; igroup++) + if (names[igroup] == NULL) return igroup; return -1; } @@ -373,10 +422,11 @@ void Group::write_restart(FILE *fp) fwrite(&ngroup,sizeof(int),1,fp); int n; - for (int i = 0; i < ngroup; i++) { - n = strlen(names[i]) + 1; + for (int i = 0; i < MAX_GROUP; i++) { + if (names[i]) n = strlen(names[i]) + 1; + else n = 0; fwrite(&n,sizeof(int),1,fp); - fwrite(names[i],sizeof(char),n,fp); + if (n) fwrite(names[i],sizeof(char),n,fp); } } @@ -389,17 +439,22 @@ void Group::read_restart(FILE *fp) { int i,n; - for (i = 0; i < ngroup; i++) memory->sfree(names[i]); + // delete existing group names + // atom masks will be overwritten by reading of restart file + + for (i = 0; i < MAX_GROUP; i++) delete [] names[i]; if (me == 0) fread(&ngroup,sizeof(int),1,fp); MPI_Bcast(&ngroup,1,MPI_INT,0,world); - for (i = 0; i < ngroup; i++) { + for (i = 0; i < MAX_GROUP; i++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); - names[i] = (char *) memory->smalloc(n*sizeof(char),"group:names[]"); - if (me == 0) fread(names[i],sizeof(char),n,fp); - MPI_Bcast(names[i],n,MPI_CHAR,0,world); + if (n) { + names[i] = new char[n]; + if (me == 0) fread(names[i],sizeof(char),n,fp); + MPI_Bcast(names[i],n,MPI_CHAR,0,world); + } else names[i] = NULL; } } diff --git a/src/group.h b/src/group.h index c3cd6bd29e..74565a3d68 100644 --- a/src/group.h +++ b/src/group.h @@ -21,11 +21,8 @@ namespace LAMMPS_NS { class Group : protected Pointers { public: - int me; - int ngroup; // # of defined groups char **names; // name of each group int *bitmask; // one-bit mask for each group - int *inversemask; // inverse mask for each group Group(class LAMMPS *); ~Group(); @@ -47,6 +44,13 @@ class Group : protected Pointers { void angmom(int, double *, double *); // angular momentum of group void inertia(int, double *, double [3][3]); // inertia tensor void omega(double *, double [3][3], double *); // angular velocity + + private: + int me; + int ngroup; // # of defined groups + int *inversemask; // inverse mask for each group + + int find_unused(); }; }