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

This commit is contained in:
sjplimp
2007-06-20 13:17:59 +00:00
parent bde732bced
commit aaed6ebc33
131 changed files with 4277 additions and 2222 deletions

View File

@ -17,7 +17,6 @@
#include "create_atoms.h"
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_hybrid.h"
#include "comm.h"
#include "domain.h"
#include "lattice.h"
@ -30,6 +29,8 @@ using namespace LAMMPS_NS;
#define BIG 1.0e30
#define EPSILON 1.0e-6
enum{BOX,REGION,SINGLE};
/* ---------------------------------------------------------------------- */
CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {}
@ -40,36 +41,48 @@ void CreateAtoms::command(int narg, char **arg)
{
if (domain->box_exist == 0)
error->all("Create_atoms command before simulation box is defined");
if (domain->lattice == NULL)
error->all("Cannot create atoms with undefined lattice");
// parse arguments
int nbasis = domain->lattice->nbasis;
int *basistype = new int[nbasis];
if (narg < 1) error->all("Illegal create_atoms command");
int itype = atoi(arg[0]);
if (narg < 2) error->all("Illegal create_atoms command");
itype = atoi(arg[0]);
if (itype <= 0 || itype > atom->ntypes)
error->all("Invalid atom type in create_atoms command");
for (int i = 0; i < nbasis; i++) basistype[i] = itype;
int regionflag = -1;
int nhybrid = 0;
int iarg;
if (strcmp(arg[1],"box") == 0) {
style = BOX;
iarg = 2;
} else if (strcmp(arg[1],"region") == 0) {
style = REGION;
if (narg < 3) error->all("Illegal create_atoms command");
int iregion = domain->find_region(arg[2]);
if (iregion == -1) error->all("Create_atoms region ID does not exist");
iarg = 3;;
} else if (strcmp(arg[1],"single") == 0) {
style = SINGLE;
if (narg < 5) error->all("Illegal create_atoms command");
xone[0] = atof(arg[2]);
xone[1] = atof(arg[3]);
xone[2] = atof(arg[4]);
iarg = 5;
} else error->all("Illegal create_atoms command");
// process optional keywords
int scaleflag = 1;
if (domain->lattice) {
nbasis = domain->lattice->nbasis;
basistype = new int[nbasis];
for (int i = 0; i < nbasis; i++) basistype[i] = itype;
}
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"region") == 0) {
if (iarg+2 > narg) error->all("Illegal create_atoms command");
int iregion;
for (iregion = 0; iregion < domain->nregion; iregion++)
if (strcmp(arg[iarg+1],domain->regions[iregion]->id) == 0) break;
if (iregion == domain->nregion)
error->all("Create_atoms region ID does not exist");
regionflag = iregion;
iarg += 2;
} else if (strcmp(arg[iarg],"basis") == 0) {
if (strcmp(arg[iarg],"basis") == 0) {
if (iarg+3 > narg) error->all("Illegal create_atoms command");
if (domain->lattice == NULL)
error->all("Cannot create atoms with undefined lattice");
int ibasis = atoi(arg[iarg+1]);
itype = atoi(arg[iarg+2]);
if (ibasis <= 0 || ibasis > nbasis ||
@ -77,19 +90,121 @@ void CreateAtoms::command(int narg, char **arg)
error->all("Illegal create_atoms command");
basistype[ibasis-1] = itype;
iarg += 3;
} else if (strcmp(arg[iarg],"hybrid") == 0) {
if (iarg+3 > narg) error->all("Illegal create_atoms command");
AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
int ihybrid;
for (ihybrid = 0; ihybrid < avec_hybrid->nstyles; ihybrid++)
if (strcmp(avec_hybrid->keywords[ihybrid],arg[iarg+1]) == 0) break;
if (ihybrid == avec_hybrid->nstyles)
error->all("Create atoms hybrid sub-style does not exist");
nhybrid = ihybrid;
iarg += 3;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all("Illegal create_atoms command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all("Illegal create_atoms command");
iarg += 2;
} else error->all("Illegal create_atoms command");
}
// demand lattice be defined
// else setup scaling for single atom
// could use domain->lattice->lattice2box() to do conversion of
// lattice to box, but not consistent with other uses of units=lattice
// triclinic remapping occurs in add_single()
if (style == BOX || style == REGION) {
if (domain->lattice == NULL)
error->all("Cannot create atoms with undefined lattice");
} else if (scaleflag == 1) {
if (domain->lattice == NULL)
error->all("Cannot create atoms with undefined lattice");
xone[0] *= domain->lattice->xlattice;
xone[1] *= domain->lattice->ylattice;
xone[2] *= domain->lattice->zlattice;
}
// add atoms
double natoms_previous = atom->natoms;
int nlocal_previous = atom->nlocal;
if (style == SINGLE) add_single();
else add_many();
// clean up
if (domain->lattice) delete [] basistype;
// new total # of atoms
double rlocal = atom->nlocal;
MPI_Allreduce(&rlocal,&atom->natoms,1,MPI_DOUBLE,MPI_SUM,world);
// print status
if (comm->me == 0) {
if (screen)
fprintf(screen,"Created %.15g atoms\n",atom->natoms-natoms_previous);
if (logfile)
fprintf(logfile,"Created %.15g atoms\n",atom->natoms-natoms_previous);
}
// reset simulation now that more atoms are defined
// add tags for newly created atoms if possible
// if global map exists, reset it
// if a molecular system, set nspecial to 0 for new atoms
if (atom->natoms > MAXATOMS) atom->tag_enable = 0;
if (atom->natoms <= MAXATOMS) atom->tag_extend();
if (atom->map_style) {
atom->map_init();
atom->map_set();
}
if (atom->molecular) {
int **nspecial = atom->nspecial;
for (int i = nlocal_previous; i < atom->nlocal; i++) {
nspecial[i][0] = 0;
nspecial[i][1] = 0;
nspecial[i][2] = 0;
}
}
}
/* ----------------------------------------------------------------------
add single atom with coords at xone if it's in my sub-box
if triclinic, xone is in lamda coords
------------------------------------------------------------------------- */
void CreateAtoms::add_single()
{
double sublo[3],subhi[3];
if (domain->triclinic == 0) {
sublo[0] = domain->sublo[0]; subhi[0] = domain->subhi[0];
sublo[1] = domain->sublo[1]; subhi[1] = domain->subhi[1];
sublo[2] = domain->sublo[2]; subhi[2] = domain->subhi[2];
} else {
sublo[0] = domain->sublo_lamda[0]; subhi[0] = domain->subhi_lamda[0];
sublo[1] = domain->sublo_lamda[1]; subhi[1] = domain->subhi_lamda[1];
sublo[2] = domain->sublo_lamda[2]; subhi[2] = domain->subhi_lamda[2];
}
// if triclinic, convert to lamda coords (0-1)
double lamda[3],*coord;
if (domain->triclinic) {
domain->x2lamda(xone,lamda);
coord = lamda;
} else coord = xone;
// if atom is in my subbox, create it
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
coord[2] >= sublo[2] && coord[2] < subhi[2])
atom->avec->create_atom(itype,xone);
}
/* ----------------------------------------------------------------------
add many atoms by looping over lattice
------------------------------------------------------------------------- */
void CreateAtoms::add_many()
{
// convert 8 corners of my subdomain from box coords to lattice coords
// for orthogonal, use corner pts of my subbox
// for triclinic, use bounding box of my subbox
@ -176,12 +291,9 @@ void CreateAtoms::command(int narg, char **arg)
// iterate on 3d periodic lattice using loop bounds
// invoke add_atom for nbasis atoms in each unit cell
// converts lattice coords to box coords
// convert lattice coords to box coords
// add atom if it meets all criteria
double natoms_previous = atom->natoms;
int nlocal_previous = atom->nlocal;
double **basis = domain->lattice->basis;
double x[3],lamda[3];
double *coord;
@ -202,8 +314,8 @@ void CreateAtoms::command(int narg, char **arg)
// if a region was specified, test if atom is in it
if (regionflag >= 0)
if (!domain->regions[regionflag]->match(x[0],x[1],x[2])) continue;
if (style == REGION)
if (!domain->regions[iregion]->match(x[0],x[1],x[2])) continue;
// test if atom is in my subbox
@ -218,45 +330,6 @@ void CreateAtoms::command(int narg, char **arg)
// add the atom to my list of atoms
atom->avec->create_atom(basistype[m],x,nhybrid);
atom->avec->create_atom(basistype[m],x);
}
// clean up
delete [] basistype;
// new total # of atoms
double rlocal = atom->nlocal;
MPI_Allreduce(&rlocal,&atom->natoms,1,MPI_DOUBLE,MPI_SUM,world);
// print status
if (comm->me == 0) {
if (screen)
fprintf(screen,"Created %.15g atoms\n",atom->natoms-natoms_previous);
if (logfile)
fprintf(logfile,"Created %.15g atoms\n",atom->natoms-natoms_previous);
}
// reset simulation now that more atoms are defined
// add tags for newly created atoms if possible
// if global map exists, reset it
// if a molecular system, set nspecial to 0 for new atoms
if (atom->natoms > MAXATOMS) atom->tag_enable = 0;
if (atom->natoms <= MAXATOMS) atom->tag_extend();
if (atom->map_style) {
atom->map_init();
atom->map_set();
}
if (atom->molecular) {
int **nspecial = atom->nspecial;
for (i = nlocal_previous; i < atom->nlocal; i++) {
nspecial[i][0] = 0;
nspecial[i][1] = 0;
nspecial[i][2] = 0;
}
}
}