better documention and error checking for 2d general triclinic

This commit is contained in:
Steve Plimpton
2024-04-08 10:43:20 -06:00
parent 1a019889f2
commit c2b91ccc8a
10 changed files with 170 additions and 95 deletions

View File

@ -8,25 +8,85 @@ simulation. The default is 3d.
A 2d simulation box must be periodic in z as set by the :doc:`boundary
<boundary>` command. This is the default.
If using the :doc:`create_box <create_box>` command, you must define a
simulation box which straddles z = 0.0 in the z dimension since all
the atoms will have a z coordinate of zero. Typically the width of
box in the z dimension should be narrow, e.g. -0.5 to 0.5, but that is
not required. Example are:
Simulation boxes in LAMMPS can be either orthogonal or triclinic in
shape. Orthogonal boxes in 2d are a rectangle with 4 edges that are
each perpendicular to either the x or y coordinate axes. Triclinic
boxes in 2d are a parallelogram with opposite pairs of faces parallel
to each other. LAMMPS supports two forms of triclinic boxes,
restricted and general, which for 2d differ in how the box is oriented
with respect to the xy coordinate axes. See the :doc:`Howto triclinic
<Howto_triclinic>` for a detailed description of all 3 kinds of
simulation boxes.
Here are examples of using the :doc:`create_box <create_box>` command
to define the simulation box for a 2d system.
.. code-block:: LAMMPS
create_box 1 -10 10 0 10 -0.5 0.5
create_box 1 -10 10 0 10 -0.25 0.25
# 2d orthogonal box using a block-style region
region mybox block -10 10 0 10 -0.5 0.5
create_box 1 mybox
Likewise, if using the :doc:`read_data <read_data>` command to define
the simulation box and read in a data file of atom coordinates, the
default "zlo zhi" values are -0.5 0.5 for 2d simulations. If the data
file includes that header keyword the zlo/zhi values must straddle z =
0.0. Also, the z coord for each atom listed in the file must be 0.0.
A value within epsilon of zero is also allowed in case the data file
was generated by another program with finite precision, in which case
the z coord for the atom will be set to 0.0.
# 2d restricted triclinic box using a prism-style region with only xy tilt
region mybox prism 0 10 0 10 -0.5 0.5 2.0 0.0 0.0
create_box 1 mybox
# 2d general triclinic box using a primitive cell for a 2d hex lattice
lattice custom 1.0 a1 1.0 0.0 0.0 a2 0.5 0.86602540378 0.0 &
a3 0.0 0.0 1.0 basis 0.0 0.0 0.0 triclinic/general
create_box 1 NULL 0 5 0 5 -0.5 0.5
Note that for 2d orthogonal or restricted triclinic boxes, the box has
a 3rd dimension which must straddle z = 0.0 in the z dimension.
Typically the width of box in the z dimension should be narrow,
e.g. -0.5 to 0.5, but that is not required. For a 2d general
triclinic box, the *a3* vector defined by the :doc:`lattice <lattice>`
command must be (0.0,0.0,1.0), which is its default value. Also the
*clo* and *chi* arguments of the :doc:`create_box <create_box>`
command must be -0.5 and 0.5.
Here are examples of using the :doc:`read_data <read_data>` command
to define the simulation box for a 2d system via keywords in the
header section of the data file. These are the same boxes as the examples
for the :doc:`create_box <create_box>` command
.. code-block:: LAMMPS
# 2d orthogonal box
-10 10 xlo xhi
0 10 ylo yhi
-0.5 0.5 zlo zhi # this is the default, so no need to specify
# 2d restricted triclinic box with only xy tilt
-10 10 xlo xhi
0 10 ylo yhi
-0.5 0.5 zlo zhi # this is the default, so no need to specify
2.0 0.0 0.0 xy xz yz
# 3d general triclinic box using a primitive cell for a 2d hex lattice
5 0 0 avec
2.5 4.3301270189 0 bvec
0 0 1 cvec # this is the default, so no need to specify
0 0 -0.5 abc origin # this is the default for 2d, so no need to specify
Note that for 2d orthogonal or restricted triclinic boxes, the box has
a 3rd dimension specified by the *zlo zhi* values, which must straddle
z = 0.0. Typically the width of box in the z dimension should be
narrow, e.g. -0.5 to 0.5, but that is not required. For a 2d general
triclinic box, the z component of *avec* and *bvec* must be zero, and
*cvec* must be (0,0,1), which is the default. The z component of *abc
origin* must also be -0.5, which is the default.
If using the :doc:`create_atoms <create_atoms>` command to create
atoms in the 2d simulation box, all the z coordinates of created atoms
will be zero.
If using the :doc:`read_data <read_data>` command to read in a data
file of atom coordinates for a 2d system, the z coordinates of all
atoms should be zero. A value within epsilon of zero is also allowed
in case the data file was generated by another program with finite
numeric precision, in which case the z coord for the atom will be set
to zero.
Use the :doc:`fix enforce2d <fix_enforce2d>` command as the last fix
defined in the input script. It ensures that the z-components of

View File

@ -175,11 +175,10 @@ This is the list of commands which have general triclinic options:
* :doc:`read_data <read_data>` - read a data file for a general triclinic system
* :doc:`write_data <write_data>` - write a data file for a general triclinic system
* :doc:`dump atom, dump custom <dump>` - output dump snapshots in general triclinic format
* :doc:`dump_modify <dump_modify>` - toggle a dump file between restricted and general triclinic format
* :doc:`dump_modify triclinic/general <dump_modify>` - select general triclinic format for dump output
* :doc:`thermo_style <thermo_style>` - output the pressure tensor in
general triclinic format
* :doc:`thermo_modify <thermo_modify>` - toggle thermo-style output
between restricted and general triclinic format
* :doc:`thermo_modify triclinic/general <thermo_modify>` - select general triclinic format for thermo output
* :doc:`read_restart <read_restart>` - read a restart file for a general triclinic system
* :doc:`write_restart <read_restart>` - write a restart file for a general triclinic system

View File

@ -171,25 +171,28 @@ a simulation box which replicates that unit cell along each of the
input to LAMMPS. However, as explained on the
:doc:`Howto_triclinic <Howto_triclinic>` doc page, internally,
LAMMPS only uses restricted triclinic simulation boxes. This means
the box created by the :doc:`create_box <create_box>` command and
the atoms with their per-atom information (e.g. coordinates,
velocities) created by this command are converted (rotated) from
general to restricted triclinic form when the two commands are
the box created by the :doc:`create_box <create_box>` command as
well as the atoms created by this command with their per-atom
information (e.g. coordinates, velocities) are converted (rotated)
from general to restricted triclinic form when the two commands are
invoked. The <Howto_triclinic>` doc page also discusses other
LAMMPS commands which can input/output general triclinic
representations of the simulation box and per-atom data.
The *box* style will fill the entire general triclinic box with
particles on the lattice, as explained above. The *region* style also
operates as explained above, but the check for particles inside the
region is performed *after* the particle coordinates have been
converted to the restricted triclinic box. This means the region must
also be defined with respect to the restricted triclinic box, not the
general triclinic box.
particles on the lattice, as explained above.
.. note::
The *region* style also operates as explained above, but the check
for particles inside the region is performed *after* the particle
coordinates have been converted to the restricted triclinic box.
This means the region must also be defined with respect to the
restricted triclinic box, not the general triclinic box.
If the simulation box is general triclinic, the *single*, *random*,
and *mesh* styles described next operate on the box after it has been
converted to restricted triclinic. So all the settings for those
and *mesh* styles described next operate on the box *after* it has
been converted to restricted triclinic. So all the settings for those
styles should be made in that context.
----------

View File

@ -42,13 +42,13 @@ Examples
# 2d general triclinic box using primitive cell for 2d hex lattice
lattice custom 1.0 a1 1.0 0.0 0.0 a2 0.5 0.86602540378 0.0 &
a3 0.0 0.0 1.0 basis 0.0 0.0 0.0
a3 0.0 0.0 1.0 basis 0.0 0.0 0.0 triclinic/general
create_box 1 NULL 0 5 0 5 -0.5 0.5
.. code-block:: LAMMPS
# 3d general triclinic box using primitive cell for 3d fcc lattice
lattice custom 1.0 a2 0.0 0.5 0.5 a1 0.5 0.0 0.5 a3 0.5 0.5 0.0 basis 0.0 0.0 0.0
lattice custom 1.0 a2 0.0 0.5 0.5 a1 0.5 0.0 0.5 a3 0.5 0.5 0.0 basis 0.0 0.0 0.0 triclinic/general
create box 1 NULL -5 5 -10 10 0 20
Description
@ -164,13 +164,13 @@ using the :doc:`change box <change_box>` command with its *ortho* and
----------
As noted above, general triclinic boxes in LAMMPS allow for arbitrary
edge vectors **A**, **B**, **C**. The only restrictions are that the
three vectors be distinct, non-zero, and not co-planar. They must
also define a right-handed system such that (**A** x **B**) points in
the direction of **C**. Note that a left-handed system can be
converted to a right-handed system by simply swapping the order of any
pair of the **A**, **B**, **C** vectors.
As noted above, general triclinic boxes in LAMMPS allow the box to
have arbitrary edge vectors **A**, **B**, **C**. The only
restrictions are that the three vectors be distinct, non-zero, and not
co-planar. They must also define a right-handed system such that
(**A** x **B**) points in the direction of **C**. Note that a
left-handed system can be converted to a right-handed system by simply
swapping the order of any pair of the **A**, **B**, **C** vectors.
To create a general triclinic boxes, the region is specified as NULL
and the next 6 parameters (alo,ahi,blo,bhi,clo,chi) define the three
@ -189,10 +189,7 @@ vectors and origin of the general triclinic box as:
* **C** = (chi-clo) * *a3*
* origin = (alo*a1 + blo*a2 + clo*a3)
For 2d general triclinic boxes, **C** = (0,0,1) is required, and the
z-component of the simulation box origin must be -0.5. The easy way
to do this is to specify clo = -0.5 and chi = 0.5 and use the
:doc:`lattice <lattice>` command default for a3 = (0,0,1).
For 2d general triclinic boxes, clo = -0.5 and chi = 0.5 is required.
.. note::
@ -214,27 +211,27 @@ to do this is to specify clo = -0.5 and chi = 0.5 and use the
The optional keywords can be used to create a system that allows for
bond (angle, dihedral, improper) interactions, or for molecules with
special 1--2, 1--3, or 1--4 neighbors to be added later. These optional
keywords serve the same purpose as the analogous keywords that can be
used in a data file which are recognized by the
special 1--2, 1--3, or 1--4 neighbors to be added later. These
optional keywords serve the same purpose as the analogous keywords
that can be used in a data file which are recognized by the
:doc:`read_data <read_data>` command when it sets up a system.
Note that if these keywords are not used, then the create_box command
creates an atomic (non-molecular) simulation that does not allow bonds
between pairs of atoms to be defined, or a
:doc:`bond potential <bond_style>` to be specified, or for molecules with
special neighbors to be added to the system by commands such as
:doc:`create_atoms mol <create_atoms>`, :doc:`fix deposit <fix_deposit>`
or :doc:`fix pour <fix_pour>`.
between pairs of atoms to be defined, or a :doc:`bond potential
<bond_style>` to be specified, or for molecules with special neighbors
to be added to the system by commands such as :doc:`create_atoms mol
<create_atoms>`, :doc:`fix deposit <fix_deposit>` or :doc:`fix pour
<fix_pour>`.
As an example, see the examples/deposit/in.deposit.molecule script,
which deposits molecules onto a substrate. Initially there are no
molecules in the system, but they are added later by the
:doc:`fix deposit <fix_deposit>` command. The create_box command in the
script uses the bond/types and extra/bond/per/atom keywords to allow
this. If the added molecule contained more than one special bond
(allowed by default), an extra/special/per/atom keyword would also
need to be specified.
molecules in the system, but they are added later by the :doc:`fix
deposit <fix_deposit>` command. The create_box command in the script
uses the bond/types and extra/bond/per/atom keywords to allow this.
If the added molecule contained more than one special bond (allowed by
default), an extra/special/per/atom keyword would also need to be
specified.
----------

View File

@ -34,7 +34,7 @@ Syntax
x,y,z = primitive vector components that define unit cell
*basis* values = x y z
x,y,z = fractional coords of a basis atom (0 <= x,y,z < 1)
*triclinic/general* values = no values, assume lattice tiles
*triclinic/general* values = no values
Examples
""""""""
@ -172,18 +172,21 @@ The *origin* option specifies how the unit cell will be shifted or
translated when mapping it into the simulation box. The x,y,z values
are fractional values (0.0 <= x,y,z < 1.0) meaning shift the lattice
by a fraction of the lattice spacing in each dimension. The meaning
of "lattice spacing" is discussed below.
of "lattice spacing" is discussed below. For 2d simulations, the
*origin* z value must be 0.0.
The *orient* option specifies how the unit cell will be rotated when
mapping it into the simulation box. The *dim* argument is one of the
3 coordinate axes in the simulation box. The other 3 arguments are
the crystallographic direction in the lattice that you want to orient
along that axis, specified as integers. E.g. "orient x 2 1 0" means
the x-axis in the simulation box will be the [210] lattice
direction, and similarly for y and z. The 3 lattice directions you
specify do not have to be unit vectors, but they must be mutually
orthogonal and obey the right-hand rule, i.e. (X cross Y) points in
the Z direction.
the x-axis in the simulation box will be the [210] lattice direction,
and similarly for y and z. The 3 lattice directions you specify do
not have to be unit vectors, but they must be mutually orthogonal and
obey the right-hand rule, i.e. (X cross Y) points in the Z direction.
For 2d simulations, the *orient* x and y vectors must define 0 for
their 3rd component. Similarly the *orient* z vector must define 0
for its 1st and 2nd components.
.. note::
@ -211,10 +214,12 @@ and not co-planar. In addition, they must define a right-handed
system, such that (*a1* cross *a2*) points in the direction of *a3*.
Note that a left-handed system can be converted to a right-handed
system by simply swapping the order of any pair of the *a1*, *a2*,
*a3* vectors.
*a3* vectors. For 2d simulations, the *a3* vector must be specified
as (0.0,0.0,1.0), which is its default value.
If this option is used, the *origin* and *orient* settings must have
their default values.
their default values. Namely (0.0,0.0,0.0) for the *origin* and
(100), (010), (001) for the *orient* vectors.
The :doc:`create_box <create_box>` command can be used to create a
general triclinic box that replicates the *a1*, *a2*, *a3* unit cell

View File

@ -385,11 +385,18 @@ changed by the :doc:`balance <balance>` or :doc:`fix balance
For an orthogonal box, only the *xlo xhi*, *ylo yhi*, *zlo zhi*
keywords are used. They define the extent of the simulation box in
each dimension. The origin (lower left corner) of the orthogonal box
is at (xlo,ylo,zlo). The default values for these 3 keywords are -0.5
and 0.5 for each lo/hi pair. For a 2d simulation, the zlo and zhi
values must straddle zero. The default zlo/zhi values do this, so
that keyword is not needed in 2d.
each dimension so that the resulting edge vectors of an orthogonal box
are:
* **A** = (xhi-xlo,0,0)
* **B** = (0,yhi-ylo,0)
* **C** = (0,0,zhi-zlo)
The origin (lower left corner) of the orthogonal box is at
(xlo,ylo,zlo). The default values for these 3 keywords are -0.5 and
0.5 for each lo/hi pair. For a 2d simulation, the zlo and zhi values
must straddle zero. The default zlo/zhi values do this, so that
keyword is not needed in 2d.
For a restricted triclinic box, the *xy xz yz* keyword is used in
addition to the *xlo xhi*, *ylo yhi*, *zlo zhi* keywords. The three
@ -453,10 +460,10 @@ restricted triclinic simulation box is effectively a parallelogram.
For a general triclinic box, the *avec*, *bvec*, *cvec*, and *abc
origin* keywords are used. The *xlo xhi*, *ylo yhi*, *zlo zhi*, and
*xy xz yz* keywords are not used. The first 3 keywords define the 3
edge vectors **A**, **B**, **C** of a general triclinic box. They can
be arbitrary vectors so long as they are distinct, non-zero, and not
co-planar. They must also define a right-handed system such that
*xy xz yz* keywords are NOT used. The first 3 keywords define the 3
edge vectors **A**, **B**, **C** of the general triclinic box. They
can be arbitrary vectors so long as they are distinct, non-zero, and
not co-planar. They must also define a right-handed system such that
(**A** x **B**) points in the direction of **C**. Note that a
left-handed system can be converted to a right-handed system by simply
swapping the order of any pair of the **A**, **B**, **C** vectors.

View File

@ -119,6 +119,10 @@ void CreateBox::command(int narg, char **arg)
double chi = utils::numeric(FLERR, arg[iarg + 5], false, lmp);
iarg += 6;
if (domain->dimension == 2)
if (clo != -0.5 || chi != 0.5)
error->all(FLERR,"Create_box for general triclinic requires clo = -0.5 and chi = 0.5");
// use lattice2box() to generate origin and ABC vectors
// origin = abc lo
// ABC vectors = hi in one dim - origin
@ -150,12 +154,6 @@ void CreateBox::command(int narg, char **arg)
cvec[1] = py - origin[1];
cvec[2] = pz - origin[2];
if (domain->dimension == 2) {
if (cvec[0] != 0.0 || cvec[1] != 0.0 || cvec[2] != 1.0 || origin[2] != -0.5)
error->all(FLERR,"Create_box C edge vector and/or origin is invalid "
"for 2d simulation with general triclinic box");
}
// define general triclinic box within Domain class
domain->define_general_triclinic(avec,bvec,cvec,origin);

View File

@ -670,9 +670,9 @@ void Domain::general_to_restricted_rotation(double *a, double *b, double *c,
// rotate general ABC to restricted triclinic A'B'C'
MathExtra::matvec(rotate_g2r,a,aprime);
MathExtra::matvec(rotate_g2r,b,bprime);
MathExtra::matvec(rotate_g2r,c,cprime);
MathExtra::matvec(rotmat,a,aprime);
MathExtra::matvec(rotmat,b,bprime);
MathExtra::matvec(rotmat,c,cprime);
}
/* ----------------------------------------------------------------------

View File

@ -245,6 +245,8 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
if (collinear())
error->all(FLERR,"Lattice primitive vectors are collinear");
// requirements for 2d system
if (dimension == 2) {
if (origin[2] != 0.0)
error->all(FLERR,
@ -261,32 +263,36 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
error->all(FLERR,"Lattice basis atom z coords must be zero for 2d simulation");
}
if (spaceflag) {
if (xlattice <= 0.0 || ylattice <= 0.0 || zlattice <= 0.0)
error->all(FLERR,"Lattice spacings are invalid");
}
// additional requirements for a general triclinic lattice
// a123 prime are used to compute lattice spacings
if (triclinic_general) {
if (style != CUSTOM)
error->all(FLERR,"Lattice triclnic/general must be style = CUSTOM");
error->all(FLERR,"Lattice triclinic/general must be style = CUSTOM");
if (origin[0] != 0.0 || origin[1] != 0.0 || origin[2] != 0.0)
error->all(FLERR,"Lattice triclnic/general must have default origin");
error->all(FLERR,"Lattice triclinic/general must have default origin");
int oriented = 0;
if (orientx[0] != 1 || orientx[1] != 0 || orientx[2] != 0) oriented = 1;
if (orienty[0] != 0 || orienty[1] != 1 || orienty[2] != 0) oriented = 1;
if (orientz[0] != 0 || orientz[1] != 0 || orientz[2] != 1) oriented = 1;
if (oriented)
error->all(FLERR,"Lattice triclnic/general must have default orientation");
error->all(FLERR,"Lattice triclinic/general must have default orientation");
if (dimension == 2 && (a3[0] != 0.0 || a3[1] != 0.0 || a3[2] != 1.0))
error->all(FLERR,"Lattice triclinic/general a3 vector for a 2d simulation must be (0,0,1)");
if (!right_handed_primitive())
error->all(FLERR,"Lattice triclnic/general a1,a2,a3 must be right-handed");
error->all(FLERR,"Lattice triclinic/general a1,a2,a3 must be right-handed");
double rotmat[3][3];
domain->general_to_restricted_rotation(a1,a2,a3,rotmat,a1_prime,a2_prime,a3_prime);
}
// user-defined lattice spacings must all be positive
if (spaceflag) {
if (xlattice <= 0.0 || ylattice <= 0.0 || zlattice <= 0.0)
error->all(FLERR,"Lattice spacings are invalid");
}
// reset scale for LJ units (input scale is rho*)
// scale = (Nbasis/(Vprimitive * rho*)) ^ (1/dim)
// use fabs() in case a1,a2,a3 are not right-handed for general triclinic
@ -334,7 +340,7 @@ Lattice::Lattice(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
// restore original general triclinic a123 transform
if (triclinic_general) setup_transform(a2,a2,a3);
if (triclinic_general) setup_transform(a1,a2,a3);
xlattice = xmax - xmin;
ylattice = ymax - ymin;

View File

@ -1394,7 +1394,7 @@ void ReadData::header(int firstpass)
if (addflag == NONE) atom->nimpropertypes = nimpropertypes + extra_improper_types;
// these settings only used by first data file
// NOTEL these are now obsolete, we parse them to maintain backward compatibility
// NOTE: these are now obsolete, we parse them to maintain backward compatibility
// the recommended way is to set them via command keywords in the input script
// if these flags are set both ways, the larger of the two values is used