Commit ecaf8734 authored by sjplimp's avatar sjplimp
Browse files

git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@149 f3b2605a-c512-4ea7-a41b-209d697bcdaa
parent 458ec376
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ package:

yes-all:
	make yes-class2 yes-dpd yes-granular yes-kspace \
	yes-manybody yes-molecule yes-poems yes-xtc
	yes-manybody yes-meam yes-molecule yes-poems yes-xtc

no-all:
	@echo 'Removing files, ignore any rm errors ...'
@@ -60,6 +60,7 @@ no-all:
	@cd GRANULAR; csh -f Install.csh 0
	@cd KSPACE; csh -f Install.csh 0
	@cd MANYBODY; csh -f Install.csh 0
	@cd MEAM; csh -f Install.csh 0
	@cd MOLECULE; csh -f Install.csh 0
	@cd POEMS; csh -f Install.csh 0
	@cd XTC; csh -f Install.csh 0
@@ -100,6 +101,13 @@ no-manybody:
	@cd MANYBODY; csh -f Install.csh 0
	@make clean

yes-meam:
	@cd MEAM; csh -f Install.csh 1
no-meam:
	@echo 'Removing files, ignore any rm errors ...'
	@cd MEAM; csh -f Install.csh 0
	@make clean

yes-molecule:
	@cd MOLECULE; csh -f Install.csh 1
no-molecule:
@@ -129,6 +137,7 @@ package-update:
	@csh -f Package.csh GRANULAR update
	@csh -f Package.csh KSPACE update
	@csh -f Package.csh MANYBODY update
	@csh -f Package.csh MEAM update
	@csh -f Package.csh MOLECULE update
	@csh -f Package.csh POEMS update
	@csh -f Package.csh XTC update
@@ -141,6 +150,7 @@ package-overwrite:
	@csh -f Package.csh GRANULAR overwrite
	@csh -f Package.csh KSPACE overwrite
	@csh -f Package.csh MANYBODY overwrite
	@csh -f Package.csh MEAM overwrite
	@csh -f Package.csh MOLECULE overwrite
	@csh -f Package.csh POEMS overwrite
	@csh -f Package.csh XTC overwrite
@@ -153,6 +163,7 @@ package-check:
	@csh -f Package.csh GRANULAR check
	@csh -f Package.csh KSPACE check
	@csh -f Package.csh MANYBODY check
	@csh -f Package.csh MEAM check
	@csh -f Package.csh MOLECULE check
	@csh -f Package.csh POEMS check
	@csh -f Package.csh XTC check
+89 −225
Original line number Diff line number Diff line
@@ -17,22 +17,13 @@
#include "create_atoms.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "domain.h"
#include "update.h"
#include "lattice.h"
#include "region.h"
#include "error.h"

#define SC  1
#define BCC 2
#define FCC 3
#define SQ  4
#define SQ2 5
#define HEX 6
#define DIAMOND 7

#define MINATOMS 1000
#define MAXATOMS 0x7FFFFFFF
#define BIG      1.0e30
#define EPSILON  1.0e-6

/* ---------------------------------------------------------------------- */
@@ -41,30 +32,47 @@ 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");

  if (narg != 1 && narg != 2) error->all("Illegal create_atoms command");
  // parse arguments

  create_type = atoi(arg[0]);
  if (create_type > atom->ntypes) 
    error->all("Too large an atom type in create_atoms command");
  int nbasis = domain->lattice->nbasis;
  int basistype[nbasis];

  if (strcmp(domain->lattice_style,"none") == 0)
    error->all("Cannot create atoms with undefined lattice");
  if (!domain->orthogonality()) error->all("Non-orthogonal lattice vectors");
  if (!domain->right_handed())
    error->all("Orientation vectors are not right-handed");
  if (narg < 1) error->all("Illegal create_atoms command");
  int 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;

  // iregion = specified region (-1 if not specified)
  regionflag = -1;

  iregion = -1;
  if (narg == 2) {
  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[1],domain->regions[iregion]->id) == 0) break;
	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 (iarg+3 > narg) error->all("Illegal create_atoms command");
      int ibasis = atoi(arg[iarg+1]);
      itype = atoi(arg[iarg+2]);
      if (ibasis <= 0 || ibasis > nbasis || 
	  itype <= 0 || itype > atom->ntypes) 
	error->all("Illegal create_atoms command");
      basistype[ibasis-1] = itype;
      iarg += 3;
    } else error->all("Illegal create_atoms command");
  }

  // local copies of domain properties
  // convert 8 corners of my sub-box from box coords to lattice coords
  // min to max = bounding box around the pts in lattice space

  subxlo = domain->subxlo;
  subxhi = domain->subxhi;
@@ -73,86 +81,57 @@ void CreateAtoms::command(int narg, char **arg)
  subzlo = domain->subzlo;
  subzhi = domain->subzhi;

  boxxhi = domain->boxxhi;
  boxyhi = domain->boxyhi;
  boxzhi = domain->boxzhi;

  // ilo:ihi,jlo:jhi,klo:khi = loop bounds of simple cubic lattice
  //   that entirely overlaps my proc's sub-box
  double xmin,ymin,zmin,xmax,ymax,zmax;
  xmin = ymin = zmin = BIG;
  xmax = ymax = zmax = -BIG;

  domain->lattice->bbox(1,subxlo,subylo,subzlo,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxhi,subylo,subzlo,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxlo,subyhi,subzlo,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxhi,subyhi,subzlo,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxlo,subylo,subzhi,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxhi,subylo,subzhi,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxlo,subyhi,subzhi,xmin,ymin,zmin,xmax,ymax,zmax);
  domain->lattice->bbox(1,subxhi,subyhi,subzhi,xmin,ymin,zmin,xmax,ymax,zmax);

  // ilo:ihi,jlo:jhi,klo:khi = loop bounds for lattice overlap of my sub-box
  // overlap = any part of a unit cell (face,edge,pt) in common with my sub-box
  // in lattice space, sub-box is a tilted box
  // but bbox of sub-box is aligned with lattice axes
  // so ilo:khi unit cells should completely tile bounding box
  // decrement lo values if min < 0, since static_cast(-1.5) = -1

  int ilo,ihi,jlo,jhi,klo,khi;
  ilo = static_cast<int> (xmin);
  jlo = static_cast<int> (ymin);
  klo = static_cast<int> (zmin);
  ihi = static_cast<int> (xmax);
  jhi = static_cast<int> (ymax);
  khi = static_cast<int> (zmax);

  loop_bounds(0,&ilo,&ihi);
  loop_bounds(1,&jlo,&jhi);
  loop_bounds(2,&klo,&khi);
  if (xmin < 0.0) ilo--;
  if (ymin < 0.0) jlo--;
  if (zmin < 0.0) klo--;

  // initialize 3d periodic lattice using overlapping loop bounds
  // lattice style determines how many atoms in cubic unit cell
  // sc = 1, bcc = 2, fcc = 4, sq = 1, sq2 = 2, hex = 2, diamond = 8
  // iterate on 3d periodic lattice using loop bounds
  // invoke add_atom for nbasis atoms in each unit cell
  // add_atom converts lattice coords to box coords, checks if in my sub-box

  boxxhi = domain->boxxhi;
  boxyhi = domain->boxyhi;
  boxzhi = domain->boxzhi;

  double natoms_previous = atom->natoms;
  int nlocal_previous = atom->nlocal;

  int style;
  if (strcmp(domain->lattice_style,"sc") == 0) style = SC;
  else if (strcmp(domain->lattice_style,"bcc") == 0) style = BCC;
  else if (strcmp(domain->lattice_style,"fcc") == 0) style = FCC;
  else if (strcmp(domain->lattice_style,"sq") == 0) style = SQ;
  else if (strcmp(domain->lattice_style,"sq2") == 0) style = SQ2;
  else if (strcmp(domain->lattice_style,"hex") == 0) style = HEX;
  else if (strcmp(domain->lattice_style,"diamond") == 0) style = DIAMOND;

  double ifull,ihalf,jfull,jhalf,kfull,khalf;
  double iquart,i3quart,jquart,j3quart,kquart,k3quart;
  int i,j,k;

  for (k = klo; k <= khi; k++) {
    kfull = (double) k;
    khalf = k + 0.5;
    kquart = k + 0.25;
    k3quart = k + 0.75;
    for (j = jlo; j <= jhi; j++) {
      jfull = (double) j;
      jhalf = j + 0.5;
      jquart = j + 0.25;
      j3quart = j + 0.75;
      for (i = ilo; i <= ihi; i++) {
	ifull = (double) i;
	ihalf = i + 0.5;
	iquart = i + 0.25;
	i3quart = i + 0.75;

	if (style == SC)
	  add_atom(ifull,jfull,kfull);
	else if (style == BCC) {
	  add_atom(ifull,jfull,kfull);
	  add_atom(ihalf,jhalf,khalf);
	} else if (style == FCC) {
	  add_atom(ifull,jfull,kfull);
	  add_atom(ihalf,jhalf,kfull);
	  add_atom(ihalf,jfull,khalf);
	  add_atom(ifull,jhalf,khalf);
	} else if (style == SQ) {
	  add_atom(ifull,jfull,kfull);
	} else if (style == SQ2) {
	  add_atom(ifull,jfull,kfull);
	  add_atom(ihalf,jhalf,kfull);
	} else if (style == HEX) {
	  add_atom(ifull,jfull,kfull);
	  add_atom(ihalf,jhalf,kfull);
	} else if (style == DIAMOND) {
	  add_atom(ifull,jfull,kfull);
	  add_atom(ifull,jhalf,khalf);
	  add_atom(ihalf,jfull,khalf);
	  add_atom(ihalf,jhalf,kfull);
	  add_atom(iquart,jquart,kquart);
	  add_atom(iquart,j3quart,k3quart);
	  add_atom(i3quart,jquart,k3quart);
	  add_atom(i3quart,j3quart,kquart);
	}
      }
    }
  }
  double **basis = domain->lattice->basis;

  int i,j,k,m;
  for (k = klo; k <= khi; k++)
    for (j = jlo; j <= jhi; j++)
      for (i = ilo; i <= ihi; i++)
	for (m = 0; m < nbasis; m++)
	  add_atom(basistype[m],i+basis[m][0],j+basis[m][1],k+basis[m][2]);

  // new total # of atoms

@@ -191,19 +170,19 @@ void CreateAtoms::command(int narg, char **arg)
}

/* ----------------------------------------------------------------------
   add an atom at x,y,z in lattice coords if it meets all criteria 
   add an atom of type at lattice coords x,y,z if it meets all criteria 
------------------------------------------------------------------------- */

void CreateAtoms::add_atom(double x, double y, double z)
void CreateAtoms::add_atom(int type, double x, double y, double z)
{
  // convert from lattice coords to box coords

  domain->lattice2box(&x,&y,&z);
  domain->lattice->lattice2box(x,y,z);

  // if a region was specified, test if atom is in it

  if (iregion >= 0)
    if (!domain->regions[iregion]->match(x,y,z)) return;
  if (regionflag >= 0)
    if (!domain->regions[regionflag]->match(x,y,z)) return;

  // test if atom is in my subbox

@@ -220,120 +199,5 @@ void CreateAtoms::add_atom(double x, double y, double z)

  // add the atom to my list of atoms

  atom->create_one(create_type,x,y,z);
}

/* ----------------------------------------------------------------------
   search for 2 bounding lattice planes that completely enclose my sub-box
   do this by testing if all corner points of my sub-box lie on correct side
     of a lattice plane via same_side function
   dim = 0,1,2 for x,y,z directions
   lo,hi = returned indices of 2 bounding lattice planes
   a lattice plane is defined by:
     point = point in lattice space through which the plane passes
     normal = vector normal to lattice plane
------------------------------------------------------------------------- */

void CreateAtoms::loop_bounds(int dim, int *lo, int *hi)
{
  int normal[3],point[3];

  // start search at origin

  point[0] = point[1] = point[2] = 0;

  // set lattice plane direction along positive lattice axis

  normal[0] = normal[1] = normal[2] = 0;
  normal[dim] = 1;

  // step down (if needed) until entire box is above the plane
  // step up until 1st time entire box is not above the plane

  while (!same_side(point,normal)) point[dim]--;
  while (same_side(point,normal)) point[dim]++;

  // lower loop bound = current loc minus 1 (subtract 1 more for safety)

  *lo = point[dim] - 2;

  // flip plane direction
  // step up until entire box is below the plane

  normal[dim] = -1;
  while (!same_side(point,normal)) point[dim]++;

  // lower loop bound = current loc (add 1 more for safety)

  *hi = point[dim] + 1;
}

/* ----------------------------------------------------------------------
   test if all 8 corner points of my sub-box are on "correct" side of a plane
   plane is defined by point[3] it goes thru and a normal[3]
   normal also defines the correct side 
------------------------------------------------------------------------- */

int CreateAtoms::same_side(int *point, int *normal)
{
  // p1 = plane center point in box coords
  // p2 = point on correct side of plane, in box coords

  double p1x = point[0];
  double p1y = point[1];
  double p1z = point[2];
  domain->lattice2box(&p1x,&p1y,&p1z);

  double p2x = point[0] + normal[0];
  double p2y = point[1] + normal[1];
  double p2z = point[2] + normal[2];
  domain->lattice2box(&p2x,&p2y,&p2z);

  // for each of 8 sub-box corner points, dot these 2 vectors:
  //   v1 = from plane center point to point on correct side of plane
  //   v2 = from plane center point to box corner point
  // negative result = portion of box is on wrong side of plane, return 0

  double v1[3],v2[3];

  points2vec(p1x,p1y,p1z,p2x,p2y,p2z,v1);

  points2vec(p1x,p1y,p1z,subxlo,subylo,subzlo,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxhi,subylo,subzlo,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxlo,subyhi,subzlo,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxhi,subyhi,subzlo,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxlo,subylo,subzhi,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxhi,subylo,subzhi,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxlo,subyhi,subzhi,v2);
  if (dot(v1,v2) < 0.0) return 0;
  points2vec(p1x,p1y,p1z,subxhi,subyhi,subzhi,v2);
  if (dot(v1,v2) < 0.0) return 0;

  // all 8 points were on correct side

  return 1;
}

/* ---------------------------------------------------------------------- */
				 
double CreateAtoms::dot(double *vec1, double *vec2)
{
  double sum = vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
  return sum;
}

/* ---------------------------------------------------------------------- */

void CreateAtoms::points2vec(double p1x, double p1y, double p1z,
			     double p2x, double p2y, double p2z, double *v)
{
  v[0] = p2x - p1x;
  v[1] = p2y - p1y;
  v[2] = p2z - p1z;
  atom->create_one(type,x,y,z);
}
+3 −8
Original line number Diff line number Diff line
@@ -23,16 +23,11 @@ class CreateAtoms : public LAMMPS {
  void command(int, char **);

 private:
  int create_type;
  double subxlo,subxhi,subylo,subyhi,subzlo,subzhi;
  int regionflag;
  double boxxhi,boxyhi,boxzhi;
  int iregion;
  double subxlo,subxhi,subylo,subyhi,subzlo,subzhi;

  void add_atom(double, double, double);
  void loop_bounds(int, int *, int *);
  int same_side(int *, int *);
  double dot(double *, double *);
  void points2vec(double, double, double, double, double, double, double *);
  void add_atom(int, double, double, double);
};

#endif
+5 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "system.h"
#include "atom.h"
#include "domain.h"
#include "lattice.h"
#include "comm.h"
#include "group.h"
#include "error.h"
@@ -67,14 +68,14 @@ void DisplaceAtoms::command(int narg, char **arg)

  // setup scaling

  if (scaleflag && strcmp(domain->lattice_style,"none") == 0)
  if (scaleflag && domain->lattice == NULL)
    error->all("Use of displace_atoms with undefined lattice");

  double xscale,yscale,zscale;
  if (scaleflag) {
    xscale = domain->xlattice;
    yscale = domain->ylattice;
    zscale = domain->zlattice;
    xscale = domain->lattice->xlattice;
    yscale = domain->lattice->ylattice;
    zscale = domain->lattice->zlattice;
  }
  else xscale = yscale = zscale = 1.0;

+25 −166
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "modify.h"
#include "fix.h"
#include "region.h"
#include "lattice.h"
#include "comm.h"
#include "memory.h"
#include "error.h"
@@ -47,6 +48,10 @@ Domain::Domain()

  nonperiodic = 0;
  xperiodic = yperiodic = zperiodic = 1;
  periodicity[0] = xperiodic;
  periodicity[1] = yperiodic;
  periodicity[2] = zperiodic;

  boundary[0][0] = boundary[0][1] = 0;
  boundary[1][0] = boundary[1][1] = 0;
  boundary[2][0] = boundary[2][1] = 0;
@@ -54,16 +59,7 @@ Domain::Domain()
  boxxlo = boxylo = boxzlo = -0.5;
  boxxhi = boxyhi = boxzhi = 0.5;

  char *str = "none";
  int n = strlen(str) + 1;
  lattice_style = new char[n];
  strcpy(lattice_style,str);

  origin_x = origin_y = origin_z = 0.0;
  orient_x[0] = 1; orient_x[1] = 0; orient_x[2] = 0;
  orient_y[0] = 0; orient_y[1] = 1; orient_y[2] = 0;
  orient_z[0] = 0; orient_z[1] = 0; orient_z[2] = 1;

  lattice = NULL;
  nregion = maxregion = 0;
  regions = NULL;
}
@@ -72,7 +68,7 @@ Domain::Domain()

Domain::~Domain()
{
  delete [] lattice_style;
  delete lattice;
  for (int i = 0; i < nregion; i++) delete regions[i];
  memory->sfree(regions);
}
@@ -95,9 +91,8 @@ void Domain::init()
}

/* ----------------------------------------------------------------------
   setup initial global box, boxxlo-boxzhi are already set
   adjust for any shrink-wrapped boundaries
   store min values if boundary type = 3 = "m"
   set initial global box from boxlo/hi (already set by caller)
   adjust for shrink-wrapped dims
------------------------------------------------------------------------- */

void Domain::set_initial_box()
@@ -119,8 +114,7 @@ void Domain::set_initial_box()
}

/* ----------------------------------------------------------------------
   setup global box parameters
   set prd, prd_half, prd[], boxlo/hi[], periodicity[]
   set global prd, prd_half, prd[], boxlo/hi[] from boxlo/hi
------------------------------------------------------------------------- */

void Domain::set_global_box()
@@ -136,14 +130,10 @@ void Domain::set_global_box()
  prd[0]   = xprd;    prd[1]   = yprd;    prd[2]   = zprd;
  boxlo[0] = boxxlo;  boxlo[1] = boxylo;  boxlo[2] = boxzlo;
  boxhi[0] = boxxhi;  boxhi[1] = boxyhi;  boxhi[2] = boxzhi;
  periodicity[0] = xperiodic;
  periodicity[1] = yperiodic;
  periodicity[2] = zperiodic;
}

/* ----------------------------------------------------------------------
   set local subbox from global boxxlo-boxzhi and proc grid
   set subxlo-subzhi, sublo/hi[] 
   set local subxlo-subzhi, sublo/hi[] from global boxxlo-boxzhi and proc grid
   for uppermost proc, insure subhi = boxhi (in case round-off occurs)
------------------------------------------------------------------------- */

@@ -170,8 +160,8 @@ void Domain::set_local_box()

/* ----------------------------------------------------------------------
   reset global & local boxes due to global box boundary changes
   if shrink-wrapped, determine atom extent and reset boxxlo thru boxzhi
   call set_global_box and set_local_box 
   if shrink-wrapped, determine atom extent and reset boxlo/hi
   set global & local boxes from new boxlo/hi values
------------------------------------------------------------------------- */

void Domain::reset_box()
@@ -199,7 +189,6 @@ void Domain::reset_box()

    // compute extent across all procs
    // flip sign of MIN to do it in one Allreduce MAX
    // set box by extent in shrink-wrapped dims

    extent[0][0] = -extent[0][0];
    extent[1][0] = -extent[1][0];
@@ -207,8 +196,7 @@ void Domain::reset_box()

    MPI_Allreduce(extent,all,6,MPI_DOUBLE,MPI_MAX,world);

    // if any of 6 dims is shrink-wrapped, set it to extent of atoms +/- SMALL
    // enforce min extent for boundary type = 3 = "m"
    // in shrink-wrapped dims, set box by atom extent
    
    if (xperiodic == 0) {
      if (boundary[0][0] == 2) boxxlo = -all[0][0] - SMALL;
@@ -460,153 +448,20 @@ void Domain::unmap(double &x, double &y, double &z, int image)
}

/* ----------------------------------------------------------------------
   set lattice constant 
   create a lattice
   delete it if style = none
------------------------------------------------------------------------- */

void Domain::set_lattice(int narg, char **arg)
{
  if (narg < 1) error->all("Illegal lattice command");

  delete [] lattice_style;
  int n = strlen(arg[0]) + 1;
  lattice_style = new char[n];
  strcpy(lattice_style,arg[0]);

  if (strcmp(arg[0],"none") == 0) return;

  if (narg != 2) error->all("Illegal lattice command");

  if (strcmp(arg[0],"sc") && strcmp(arg[0],"bcc") && strcmp(arg[0],"fcc") &&
      strcmp(arg[0],"sq") && strcmp(arg[0],"sq2") && strcmp(arg[0],"hex") &&
      strcmp(arg[0],"diamond"))
    error->all("Illegal lattice command");

  // check that lattice matches dimension

  int dim = force->dimension;

  if (dim == 2) {
    if (strcmp(arg[0],"sq") && strcmp(arg[0],"sq2") && strcmp(arg[0],"hex"))
      error->all("Lattice style incompatible with dimension");
  }

  if (dim == 3) {
    if (strcmp(arg[0],"sc") && strcmp(arg[0],"bcc") &&
	strcmp(arg[0],"fcc") && strcmp(arg[0],"diamond"))
      error->all("Lattice style incompatible with dimension");
  }

  // set lattice constants depending on # of atoms per unit cell
  // hex is only case where xlattice = ylattice = zlattice is not true

  double value = atof(arg[1]);

  if (!strcmp(arg[0],"sc") || !strcmp(arg[0],"sq")) {
    if (strcmp(update->unit_style,"lj") == 0)
      xlattice = ylattice = zlattice = pow(1.0/value,1.0/dim);
    else xlattice = ylattice = zlattice = value;
  }

  if (!strcmp(arg[0],"bcc") || !strcmp(arg[0],"sq2")) {
    if (strcmp(update->unit_style,"lj") == 0)
      xlattice = ylattice = zlattice = pow(2.0/value,1.0/dim);
    else xlattice = ylattice = zlattice = value;
  }

  if (strcmp(arg[0],"fcc") == 0) {
    if (strcmp(update->unit_style,"lj") == 0)
      xlattice = ylattice = zlattice = pow(4.0/value,1.0/dim);
    else xlattice = ylattice = zlattice = value;
  }

  if (strcmp(arg[0],"hex") == 0) {
    if (strcmp(update->unit_style,"lj") == 0)
      xlattice = zlattice = pow(2.0/sqrt(3.0)/value,1.0/dim);
    else xlattice = zlattice = value;
    ylattice = xlattice * sqrt(3.0);
  }

  if (strcmp(arg[0],"diamond") == 0) {
    if (strcmp(update->unit_style,"lj") == 0)
      xlattice = ylattice = zlattice = pow(8.0/value,1.0/dim);
    else xlattice = ylattice = zlattice = value;
  delete lattice;
  lattice = new Lattice(narg,arg);
  if (lattice->style == 0) {
    delete lattice;
    lattice = NULL;
  }
}

/* ----------------------------------------------------------------------
   check if orientation vectors are mutually orthogonal 
------------------------------------------------------------------------- */

int Domain::orthogonality()
{
  if (orient_x[0]*orient_y[0] + orient_x[1]*orient_y[1] + 
      orient_x[2]*orient_y[2]) return 0;

  if (orient_y[0]*orient_z[0] + orient_y[1]*orient_z[1] + 
      orient_y[2]*orient_z[2]) return 0;

  if (orient_x[0]*orient_z[0] + orient_x[1]*orient_z[1] + 
      orient_x[2]*orient_z[2]) return 0;

  return 1;
}

/* ----------------------------------------------------------------------
   check righthandedness of orientation vectors
   x cross y must be in same direction as z 
------------------------------------------------------------------------- */

int Domain::right_handed()
{
  int xy0 = orient_x[1]*orient_y[2] - orient_x[2]*orient_y[1];
  int xy1 = orient_x[2]*orient_y[0] - orient_x[0]*orient_y[2];
  int xy2 = orient_x[0]*orient_y[1] - orient_x[1]*orient_y[0];
  if (xy0*orient_z[0] + xy1*orient_z[1] + xy2*orient_z[2] <= 0) return 0;
  return 1;
}

/* ----------------------------------------------------------------------
   convert lattice coords into box coords
   x,y,z = point in lattice coords
   orient_xyz = lattice vectors that point in positive x,y,z box directions
   origin_xyz = origin of lattice in lattice units
   return xnew,ynew,znew = point in box coords
   method:
     compute projection of vector from (0,0,0) to lattice onto each
       orient vector via dot product scaled by length of
       orient vector in lattice coords
     this projection (offset by origin and scaled by lattice constant)
       gives x,y,z box coords 
------------------------------------------------------------------------- */

void Domain::lattice2box(double *x, double *y, double *z)
{
  double length;
  double dotprod;

  length = orient_x[0]*orient_x[0] + orient_x[1]*orient_x[1] +
    orient_x[2]*orient_x[2];
  length = sqrt(length);
  dotprod = *x * orient_x[0] + *y * orient_x[1] + *z * orient_x[2];
  double xnew = (dotprod/length + origin_x) * xlattice;

  length = orient_y[0]*orient_y[0] + orient_y[1]*orient_y[1] +
    orient_y[2]*orient_y[2];
  length = sqrt(length);
  dotprod = *x * orient_y[0] + *y * orient_y[1] + *z * orient_y[2];
  double ynew = (dotprod/length + origin_y) * ylattice;

  length = orient_z[0]*orient_z[0] + orient_z[1]*orient_z[1] +
     orient_z[2]*orient_z[2];
  length = sqrt(length);
  dotprod = *x * orient_z[0] + *y * orient_z[1] + *z * orient_z[2];
  double znew = (dotprod/length + origin_z) * zlattice;

  *x = xnew;
  *y = ynew;
  *z = znew;
}

/* ----------------------------------------------------------------------
   create a new region 
------------------------------------------------------------------------- */
@@ -678,6 +533,10 @@ void Domain::set_boundary(int narg, char **arg)
  if (boundary[2][0] == 0) zperiodic = 1;
  else zperiodic = 0;

  periodicity[0] = xperiodic;
  periodicity[1] = yperiodic;
  periodicity[2] = zperiodic;

  nonperiodic = 0;
  if (xperiodic == 0 || yperiodic == 0 || zperiodic == 0) {
    nonperiodic = 1;
Loading