faster, simpler, 'more completely random' way to do this

This commit is contained in:
jrgissing
2018-03-11 17:10:42 -06:00
parent a1483989d8
commit d413eb9eee
2 changed files with 93 additions and 88 deletions

View File

@ -110,11 +110,11 @@ void CreateAtoms::command(int narg, char **arg)
remapflag = 0; remapflag = 0;
mode = ATOM; mode = ATOM;
int molseed; int molseed;
int nboxseed; int insertseed;
varflag = 0; varflag = 0;
vstr = xstr = ystr = zstr = NULL; vstr = xstr = ystr = zstr = NULL;
quatone[0] = quatone[1] = quatone[2] = 0.0; quatone[0] = quatone[1] = quatone[2] = 0.0;
nlattpts = created_Nmask = nbox = nboxflag = 0; nlattpts = ninsert = insertflag = 0;
Nmask = NULL; Nmask = NULL;
nbasis = domain->lattice->nbasis; nbasis = domain->lattice->nbasis;
@ -200,9 +200,9 @@ void CreateAtoms::command(int narg, char **arg)
iarg += 5; iarg += 5;
} else if (strcmp(arg[iarg],"insert") == 0) { } else if (strcmp(arg[iarg],"insert") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal create_atoms command"); if (iarg+3 > narg) error->all(FLERR,"Illegal create_atoms command");
nbox = force->inumeric(FLERR,arg[iarg+1]); ninsert = force->inumeric(FLERR,arg[iarg+1]);
nboxseed = force->inumeric(FLERR,arg[iarg+2]); insertseed = force->inumeric(FLERR,arg[iarg+2]);
nboxflag = 1; insertflag = 1;
iarg += 3; iarg += 3;
} else error->all(FLERR,"Illegal create_atoms command"); } else error->all(FLERR,"Illegal create_atoms command");
} }
@ -241,8 +241,8 @@ void CreateAtoms::command(int narg, char **arg)
ranmol = new RanMars(lmp,molseed+comm->me); ranmol = new RanMars(lmp,molseed+comm->me);
} }
if (nboxflag) { if (insertflag) {
ranbox = new RanMars(lmp,nboxseed+comm->me); ranbox = new RanMars(lmp,insertseed+comm->me);
} }
// error check and further setup for variable test // error check and further setup for variable test
@ -821,71 +821,78 @@ void CreateAtoms::add_lattice()
void CreateAtoms::lattice_mask() void CreateAtoms::lattice_mask()
{ {
// Nmask will be used to choose which lattice points to insert if (ninsert == 0 && insertflag && me == 0)
Nmask = new int[nlattpts]; error->warning(FLERR,"Specifying an 'insert' value of '0' is equivalent to no 'insert' keyword");
for (int i = 0; i < nlattpts; i++)
Nmask[i] = 1;
if (nbox == 0 && nboxflag && me == 0) error->warning(FLERR,"Specifying an 'insert' value of '0' is equivalent to no 'insert' keyword"); if (ninsert > 0) {
int nboxme;
int nboxme = 0;
if (nbox > 0) {
if (nprocs > 1) { if (nprocs > 1) {
int *allnlattpts = new int[nprocs](); int *allnlattpts = new int[nprocs]();
int allnboxmes[nprocs];
int cumsum_lattpts[nprocs];
for (size_t i = 0; i < nprocs; i++)
allnboxmes[i] = 0;
MPI_Allgather(&nlattpts, 1, MPI_INT, allnlattpts, 1, MPI_INT, world); MPI_Allgather(&nlattpts, 1, MPI_INT, allnlattpts, 1, MPI_INT, world);
if (me == 0) {
int total_lattpts = 0; int total_lattpts = 0;
for (int i = 0; i < nprocs; i++) for (int i = 0; i < nprocs; i++) {
total_lattpts += allnlattpts[i]; total_lattpts += allnlattpts[i];
cumsum_lattpts[i] = total_lattpts;
if (nbox > total_lattpts) error->all(FLERR,"Attempting to insert more particles than available lattice points");
if (nbox < 0) error->all(FLERR,"Cannot insert a negative number of particles (in this universe)");
// adjust nboxme based on personal number of eligible lattice points
nboxme = round(nbox*nlattpts/total_lattpts);
// limit nboxme to available lattice points on this processor
if (nboxme > nlattpts) nboxme = nlattpts;
// readjust so that all nboxme's add to exactly nbox
int sum_nboxme;
MPI_Allreduce(&nboxme,&sum_nboxme,1,MPI_INT,MPI_SUM,world);
if (nbox != sum_nboxme) {
int diff = nbox - sum_nboxme;
int diff_sign = 1;
if (diff < 0) {
diff_sign = -1;
diff = -diff;
} }
// go around adding or subtracting one from all processors (if there's space) until equal
int which_proc = 0; if (ninsert > total_lattpts)
int success_me = 0, success_all = 0; error->all(FLERR,"Attempting to insert more particles than available lattice points");
int failed_me = 0, failed_all = 0; if (ninsert < 0)
while (success_all < diff && failed_all < nprocs) { error->all(FLERR,"Cannot insert a negative number of particles (in this universe)");
if (me == which_proc++ && !failed_me)
if (nboxme < nlattpts) { // using proc 0, let's insert N particles onto available lattice points by instead
nboxme += diff_sign; // poking [nlattpts - N] holes into the lattice, randomly
success_me++; int allNmask[total_lattpts];
} else { for (int i = 0; i < total_lattpts; i++)
failed_me == 1; allNmask[i] = 1;
int nholes = total_lattpts - ninsert;
int noptions = total_lattpts;
for (int i = 0; i < nholes; i++) {
int hindex = ceil(ranbox->uniform()*noptions);
int optcount = 0;
for (int j = 0; j < total_lattpts; j++) {
if (allNmask[j] == 1) {
optcount++;
if (optcount == hindex) {
allNmask[j] = 0;
noptions--;
break;
} }
MPI_Allreduce(&success_me,&success_all,1,MPI_INT,MPI_SUM,world);
MPI_Allreduce(&failed_me,&failed_all,1,MPI_INT,MPI_SUM,world);
if (which_proc > nprocs)
which_proc = 0;
} }
// should have guaranteed success at this point
if (failed_all == nprocs) error->warning(FLERR,"This is an uncaught error. Ask developer");
} }
}
// tell individual procs their nboxme (personal # to insert)
int iproc = 0;
while (allnlattpts[iproc] == 0 && iproc < nprocs)
iproc++;
for (int i = 0; i < total_lattpts; i++) {
if (i == cumsum_lattpts[iproc]) {
iproc++;
while (allnlattpts[iproc] == 0 && iproc < nprocs)
iproc++;
}
allnboxmes[iproc] += allNmask[i];
}
}
MPI_Scatter(&allnboxmes, 1, MPI_INT, &nboxme, 1, MPI_INT, 0, world);
delete [] allnlattpts; delete [] allnlattpts;
} else nboxme = nbox; } else nboxme = ninsert;
// probably faster to have individual processors 're-choose' their random points
// Nmask will be used to indicate which lattice points to insert
if (nlattpts < nboxme) printf("WHOAA\n"); //debug
Nmask = new int[nlattpts];
for (int i = 0; i < nlattpts; i++)
Nmask[i] = 1;
// let's insert N particles onto available lattice points by instead // let's insert N particles onto available lattice points by instead
// poking [nlattpts - N] holes into the lattice, randomly // poking [nlattpts - N] holes into the lattice, randomly
@ -907,8 +914,6 @@ void CreateAtoms::lattice_mask()
} }
} }
created_Nmask = 1;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -54,7 +54,7 @@ class CreateAtoms : protected Pointers {
void add_molecule(double *, double * = NULL); void add_molecule(double *, double * = NULL);
int nlattpts; // number of eligible lattice points int nlattpts; // number of eligible lattice points
int *Nmask; // used to insert N number of particles on lattice int *Nmask; // used to insert N number of particles on lattice
int created_Nmask,nbox,nboxflag; int ninsert,insertflag;
int vartest(double *); // evaluate a variable with new atom position int vartest(double *); // evaluate a variable with new atom position
}; };