lattice/create_atoms bug ?

I've had discussions related to rotated lattice issues many times, so I
feel obliged to chime in on this thread....

This is a difficult thing to understand, but LAMMPS is in fact correct (it is simply difficult, at least in my experince, to wrap one's head around the concept of a crystal structure when the coordinate vectors no longer line up with our usual x, y, and z axes). The "repeating unit" that is ultimately used can be obtained by rotating the lattice vectors according to the "orient" key words and then creating a rectangular prism that circumscribes the rotated unit cell. The three "orient" vectors you specify, when normalized, give the columns of a rotation matrix. The inverse of this matrix (since it's an orthogonal matrix, that's also its transpose) represents a rotation the other way (i.e., from the lattice vector back to the original).

Let R be the matrix that rotates from lattice coordinates back to the
originals. Then the bounding box is therefore the minimum x/y/z and
maximum x/y/z components of all the vectors R . v, where v is [hkl] (h,
k,l in {0,1}). In your case, the bounding box in the y-direction goes
from -2/sqrt(6) to +2/sqrt(6), which are the second components of
R . [1,1,0] and R . [0,0,1], respectively. Note that this assumes
a cubic lattice; in non-cubics, it's R . P . v, where P is the matrix of
cell vectors (a, b, and c; also called a1, a2, and a3).

As for how they line up at each boundary, that's slightly harder. I
think you're guaranteed, for this lattice, to get lined-up coordinates
for repeats in each direction that are multiples of 3, 6, and 2 for x,
y, and z, resp., but I have not tested that. You might, for specific
lattices, be able to use fractions of those numbers and still get a
"perfect" lattice, but I find trial-and-error to be the fastest method
in many instances.

Karl D. Hammond
University of Tennessee, Knoxville

The relevant part of the lattice doc page is this:

the lattice spacings are computed by LAMMPS in the following way. A unit cell of the lattice is mapped into the simulation box (scaled, shifted, rotated), so that it now has (perhaps) a modified size and orientation. The lattice spacing in X is defined as the difference between the min/max extent of the x coordinates of the 8 corner points of the modified unit cell. Similarly, the Y and Z lattice spacings are defined as the difference in the min/max of the y and z coordinates.

IMPORTANT NOTE: For non-orthogonal unit cells and/or when a rotation is applied via the orient keyword, then the lattice spacings may be less intuitive. In particular, in these cases, there is no guarantee that the lattice spacing is an integer multiple of the periodicity of the lattice in that direction. Thus, if you create an orthogonal periodic simulation box whose size in a dimension is a multiple of the lattice spacing, and then fill it with atoms via the create_atoms command, you will NOT necessarily create a periodic system. I.e. atoms may overlap incorrectly at the faces of the simulation box.

The issue LAMMPS is trying to deal with is that with a custom lattice
and/or orient vectors for rotation, the unit cell is effectively an
arbitrary parallelpiped (pp), with any orientiation. The pp can be replicated
to tile 2d or 3d space, but what is an appropriate “lattice spacing” in
x,y,z? I don’t know a good answer to that, so LAMMPS simply
punts and defines it as the max/min extents of the pp in x,y,z.

That isn’t always satisfying, but “lattice spacing” is simply a distance
used as a parameter in other commands. You can define it to
be whatever you want via the lattice spacing keyword.

One thought I’ve had is to do something more intuitive when
lattice custom is not used, but orient is. In that case the
unit cell is still a cube (or rectangular box for hcp or hex), but
has a different orientation. In that case a spacing could be
defined that would involve lattice planes and a more natural
periodicity. But at this point it would also break some people’s
scripts, so I’ve hesitated to do that.