diff --git a/doc/src/Howto_2d.rst b/doc/src/Howto_2d.rst index 8bce7000bd..76f583fd46 100644 --- a/doc/src/Howto_2d.rst +++ b/doc/src/Howto_2d.rst @@ -8,25 +8,85 @@ simulation. The default is 3d. A 2d simulation box must be periodic in z as set by the :doc:`boundary ` command. This is the default. -If using the :doc:`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 +` for a detailed description of all 3 kinds of +simulation boxes. + +Here are examples of using the :doc:`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 ` 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 ` +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 ` +command must be -0.5 and 0.5. + +Here are examples of using the :doc:`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 ` 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 ` 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 ` 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 ` command as the last fix defined in the input script. It ensures that the z-components of diff --git a/doc/src/Howto_triclinic.rst b/doc/src/Howto_triclinic.rst index d74243c888..3529579d65 100644 --- a/doc/src/Howto_triclinic.rst +++ b/doc/src/Howto_triclinic.rst @@ -175,11 +175,10 @@ This is the list of commands which have general triclinic options: * :doc:`read_data ` - read a data file for a general triclinic system * :doc:`write_data ` - write a data file for a general triclinic system * :doc:`dump atom, dump custom ` - output dump snapshots in general triclinic format -* :doc:`dump_modify ` - toggle a dump file between restricted and general triclinic format +* :doc:`dump_modify triclinic/general ` - select general triclinic format for dump output * :doc:`thermo_style ` - output the pressure tensor in general triclinic format -* :doc:`thermo_modify ` - toggle thermo-style output - between restricted and general triclinic format +* :doc:`thermo_modify triclinic/general ` - select general triclinic format for thermo output * :doc:`read_restart ` - read a restart file for a general triclinic system * :doc:`write_restart ` - write a restart file for a general triclinic system diff --git a/doc/src/create_atoms.rst b/doc/src/create_atoms.rst index be2cfab665..7935c676ef 100644 --- a/doc/src/create_atoms.rst +++ b/doc/src/create_atoms.rst @@ -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 ` doc page, internally, LAMMPS only uses restricted triclinic simulation boxes. This means - the box created by the :doc:`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 ` 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 ` 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. ---------- diff --git a/doc/src/create_box.rst b/doc/src/create_box.rst index e7f76f075a..062fa2b360 100644 --- a/doc/src/create_box.rst +++ b/doc/src/create_box.rst @@ -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 ` 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 ` 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 ` 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 ` to be specified, or for molecules with -special neighbors to be added to the system by commands such as -:doc:`create_atoms mol `, :doc:`fix deposit ` -or :doc:`fix pour `. +between pairs of atoms to be defined, or a :doc:`bond potential +` to be specified, or for molecules with special neighbors +to be added to the system by commands such as :doc:`create_atoms mol +`, :doc:`fix deposit ` or :doc:`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 ` 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 ` 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. ---------- diff --git a/doc/src/lattice.rst b/doc/src/lattice.rst index ad5ab364bd..99d954e43d 100644 --- a/doc/src/lattice.rst +++ b/doc/src/lattice.rst @@ -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 ` command can be used to create a general triclinic box that replicates the *a1*, *a2*, *a3* unit cell diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 951f583913..8dce9a5bcd 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -385,11 +385,18 @@ changed by the :doc:`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. diff --git a/src/create_box.cpp b/src/create_box.cpp index 7dd6f52e9d..8a74ffd7bd 100644 --- a/src/create_box.cpp +++ b/src/create_box.cpp @@ -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); diff --git a/src/domain.cpp b/src/domain.cpp index ee4819dc60..0ff06693c6 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -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); } /* ---------------------------------------------------------------------- diff --git a/src/lattice.cpp b/src/lattice.cpp index 031710a4fe..24c28864f9 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -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; diff --git a/src/read_data.cpp b/src/read_data.cpp index a6d0ec7f54..d83456e985 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -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