Syntax:
variable name style args ...
delete = no args index args = one or more strings loop args = N = integer size of loop world args = one string for each partition of processors universe args = one or more strings uloop args = N = integer size of loop equal or atom args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references numbers = 0.0, 100, -5.4, 2.8e-4, etc thermo keywords = vol, ke, press, etc from thermo_style math operations = (), -x, x+y, x-y, x*y, x/y, x^y, sqrt(x), exp(x), ln(x), log(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), ceil(x), floor(x), round(x) group functions = count(group), mass(group), charge(group), xcm(group,dim), vcm(group,dim), fcm(group,dim), bound(group,xmin), gyration(group), ke(group) region functions = count(group,region), mass(group,region), charge(group,region), xcm(group,dim,region), vcm(group,dim,region), fcm(group,dim,region), bound(group,xmin,region), gyration(group,region), ke(group,reigon) atom value = mass[N], type[N], x[N], y[N], z[N], vx[N], vy[N], vz[N], fx[N], fy[N], fz[N] atom vector = mass[], type[], x[], y[], z[], vx[], vy[], vz[], fx[], fy[], fz[] compute references = c_ID, c_ID[2], c_ID[N], c_ID[N][2], c_ID[], c_ID[][2] fix references = f_ID, f_ID[2], f_ID[N], f_ID[N][2], f_ID[], f_ID[][2] variable references = v_abc, v_abc[N], v_abc[]
Examples:
variable x index run1 run2 run3 run4 run5 run6 run7 run8 variable LoopVar loop $n variable beta equal temp/3.0 variable b1 equal x[234]+0.5*vol variable b1 equal "x[234] + 0.5*vol" variable b equal xcm(mol1,x)/2.0 variable b equal c_myTemp variable b atom x[]*y[]/vol variable temp world 300.0 310.0 320.0 ${Tfinal} variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 variable x uloop 15 variable x delete
Description:
This command assigns one or more strings to a variable name for evaluation later in the input script or during a simulation.
Variables can be used in several ways in LAMMPS. A variable can be referenced elsewhere in an input script to become part of a new input command. For variable styles that store multiple strings, the next command can be used to increment which string is assigned to the variable. Variables of style equal store a formula which when evaluated produces a single numeric value which can be output either directly (see the print, fix print, and run every commands) or as part of thermodynamic output (see the thermo_style command), or used as input to an averaging fix (see the fix ave/time command). Variables of style atom store a formula which when evaluated produces one numeric value per atom which can be output to a dump file (see the dump custom command) or used as input to an averaging fix (see the fix ave/spatial and fix ave/atom commands).
In the discussion that follows, the "name" of the variable is the arbitrary string that is the 1st argument in the variable command. This name can only contain alphanumeric characters and underscores. The "string" is one or more of the subsequent arguments. The "string" can be simple text as in the 1st example above, it can contain other variables as in the 2nd example, or it can be a formula as in the 3rd example. The "value" is the numeric quantity resulting from evaluation of the string. Note that the same string can generate different values when it is evaluated at different times during a simulation.
IMPORTANT NOTE: When the input script line that defines a variable of style equal or atom that contain a formula is encountered, the formula is NOT immediately evaluated and the result stored. See the discussion below about "Immediate Evaluation of Variables" if you want to do this.
IMPORTANT NOTE: When a variable command is encountered in the input script and the variable name has already been specified, the command is ignored. This means variables can NOT be re-defined in an input script (with 2 exceptions, read further). This is to allow an input script to be processed multiple times without resetting the variables; see the jump or include commands. It also means that using the command-line switch -var will override a corresponding index variable setting in the input script.
There are two exceptions to this rule. First, variables of style equal and atom ARE redefined each time the command is encountered. This only changes their associated formula if the formula contains a substitution for another variable, e.g. $x. But that can be useful, for example, in a loop.
Second, as described below, if a variable is iterated on to the end of its list of strings via the next command, it is removed from the list of active variables, and is thus available to be re-defined in a subsequent variable command. The delete style does the same thing.
This section of the manual explains how occurrences of a variable name in an input script line are replaced by the variable's string. The variable name can be referenced as $x if the name "x" is a single character, or as ${LoopVar} if the name "LoopVar" is one or more characters.
As described below, for variable styles index, loop, universe, and uloop, which string is assigned to a variable can be incremented via the next command. When there are no more strings to assign, the variable is exhausted and a flag is set that causes the next jump command encountered in the input script to be skipped. This enables the construction of simple loops in the input script that are iterated over and then exited from.
As explained above, an exhausted variable can be re-used in an input script. The delete style also removes the variable, the same as if it were exhausted, allowing it to be redefined later in the input script or when the input script is looped over. This can be useful when breaking out of a loop via the if and jump commands before the variable would become exhausted. For example,
label loop variable a loop 5 print "A = $a" if $a > 2 then "jump in.script break" next a jump in.script loop label break variable a delete
For the index style, one or more strings are specified. Initially, the 1st string is assigned to the variable. Each time a next command is used with the variable name, the next string is assigned. All processors assign the same string to the variable.
Index style variables with a single string value can also be set by using the command-line switch -var; see this section for details.
The loop style is identical to the index style except that the strings are the integers from 1 to N. This allows generation of a long list of runs (e.g. 1000) without having to list N strings in the input script. Initially, the string "1" is assigned to the variable. Each time a next command is used with the variable name, the next string ("2", "3", etc) is assigned. All processors assign the same string to the variable.
For the world style, one or more strings are specified. There must be one string for each processor partition or "world". See this section of the manual for information on running LAMMPS with multiple partitions via the "-partition" command-line switch. This variable command assigns one string to each world. All processors in the world are assigned the same string. The next command cannot be used with equal style variables, since there is only one value per world. This style of variable is useful when you wish to run different simulations on different partitions, or when performing a parallel tempering simulation (see the temper command), to assign different temperatures to different partitions.
For the universe style, one or more strings are specified. There must be at least as many strings as there are processor partitions or "worlds". See this page for information on running LAMMPS with multiple partitions via the "-partition" command-line switch. This variable command initially assigns one string to each world. When a next command is encountered using this variable, the first processor partition to encounter it, is assigned the next available string. This continues until all the variable strings are consumed. Thus, this command can be used to run 50 simulations on 8 processor partitions. The simulations will be run one after the other on whatever partition becomes available, until they are all finished. Universe style variables are incremented using the files "tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will see in your directory during such a LAMMPS run.
The uloop style is identical to the universe style except that the strings are the integers from 1 to N. This allows generation of long list of runs (e.g. 1000) without having to list N strings in the input script.
For the equal and atom styles, a single string is specified which represents a formula that will be evaluated afresh each time the variable is used. If you want spaces in the string, enclose it in double quotes so the parser will treat it as a single argument. For equal style variables the formula computes a scalar quantity, which becomes the value of the variable whenever it is evaluated. For atom style variables the formula computes one quantity for each atom whenever it is evaluated.
Note that equal and atom variables can produce different values at different stages of the input script or at different times during a run. For example, if an equal variable is used in a fix print command, different values could be printed each timestep it was invoked. If you want a variable to be evaluated immediately, so that the result is stored by the variable instead of the string, see the section below on "Immediate Evaluation of Variables".
The next command cannot be used with equal or atom style variables, since there is only one string.
The formula for an equal or atom variable can contain a variety of quantities. The syntax for each kind of quantity is simple, but multiple quantities can be nested and combined in various ways to build up formulas of arbitrary complexity. For example, this is a valid (though strange) variable formula:
variable x equal "pe + c_MyTemp / vol^(1/3)"
Specifically, an formula can contain numbers, thermo keywords, math operations, group functions, atom values, atom vectors, compute references, fix references, and references to other variables.
Number | 0.2, 100, 1.0e20, -15.4, etc |
Thermo keywords | vol, pe, ebond, etc |
Math operations | (), -x, x+y, x-y, x*y, x/y, x^y, sqrt(x), exp(x), ln(x), log(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), ceil(x), floor(x), round(x) |
Group functions | count(ID), mass(ID), charge(ID), xcm(ID,dim), vcm(ID,dim), fcm(ID,dim), bound(ID,dir), gyration(ID), ke(ID) |
Region functions | count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR) |
Atom values | mass[N], type[N], x[N], y[N], z[N], vx[N], vy[N], vz[N], fx[N], fy[N], fz[N] |
Atom vectors | mass[], type[], x[], y[], z[], vx[], vy[], vz[], fx[], fy[], fz[] |
Compute references | c_ID, c_ID[2], c_ID[N], c_ID[N][2], c_ID[], c_ID[][2] |
Fix references | f_ID, f_ID[2], f_ID[N], f_ID[N][2], f_ID[], f_ID[][2] |
Other variables | v_abc, v_abc[N], v_abc[] |
Note that formula elements that contain empty brackets, such as an atom vector, produce per-atom values. All other formula elements produce a global value.
A formula for equal-style variables cannot use any formula element that produces per-atom values. A formula for an atom-style variable can use formula elements that produce either global values or per-atom values.
The thermo keywords allowed in a formula are those defined by the "thermo_style custom" command. Thermo keywords that require a compute to calculate their values such as "temp" or "press", use computes stored and invoked by the thermo_style command. This means that you can only use those keywords in a variable if the style you are using with the thermo_style command (and the thermo keywords associated with that style) also define and use the needed compute. Note that some thermo keywords use a compute indirectly to calculate their value (e.g. the enthalpy keyword uses temp, pe, and pressure). If a variable is evaluated in an input script (not during a run), then the values accessed by the thermo keyword must be current. See the discussion below about "Variable Accuracy".
Math operations are written in the usual way, where the "x" and "y" in the examples above can be another section of the formula. Operators are evaluated left to right and have the usual precedence: unary minus before exponentiation ("^"), exponentiation before multiplication and division, and multiplication and division before addition and subtraction. Parenthesis can be used to group one or more portions of a formula and enforce a desired order of operations. Additional math operations can be specified as keywords followed by a parenthesized argument, e.g. sqrt(v_ke). Note that ln() is the natural log; log() is the base 10 log. The ceil(), floor(), and round() operations are those in the C math library. Ceil() is the smallest integer not less than its argument. Floor() if the largest integer not greater than its argument. Round() is the nearest integer to its argument.
Group functions take one or two arguments in a specific format. The first argument is the group-ID. The dim argument, if it exists, is x or y or z. The dir argument, if it exists, is xmin, xmax, ymin, ymax, zmin, or zmax. The group function count() is the number of atoms in the group. The group functions mass() and charge() are the total mass and charge of the group. Xcm() and vcm() return components of the position and velocity of the center of mass of the group. Fcm() returns a component of the total force on the group of atoms. Bound() returns the min/max of a particular coordinate for all atoms in the group. Gyration() computes the radius-of-gyration of the group of atoms. See the fix gyration command for a definition of the formula.
Region functions are exactly the same as group functions with an extra argument which is the region ID. The function is computed for all atoms that are in both the group and the region. If the group is "all", then the only criteria for atom inclusion is that it be in the region.
Atom values take a single integer argument from 1-N, which is the desired atom-ID, e.g. x[243]., which means use the x coordinate of the atom with ID=243.
Atom vectors use empty brackets, i.e. they take no argument. They generate one value per atom, so that a reference like x[] means the x-coord of each atom will be used when evaluating the variable.
Compute references access one or more quantities calculated by a compute. The ID in the reference should be replaced by the actual ID of the compute defined elsewhere in the input script. See the doc pages for individual computes to see which ones calculate global versus per-atom quantities. If the compute reference contains empty brackets, then per-atom values calculated by the compute are accessed. Otherwise a single value (global or per-atom) calculated by the compute is accessed. If a variable containing a compute is evaluated in an input script (not during a run), then the values accessed by the compute must be current. See the discussion below about "Variable Accuracy".
The different kinds of compute references are as follows. M is a positive integer <= the number of vector values calculated by the compute. N is a global atom ID (positive integer).
c_ID | scalar value of a global compute |
c_ID[2] | vector component of a global compute |
c_ID[N] | single atom's scalar value of a per-atom compute |
c_ID[N][M] | single atom's vector component of a per-atom compute |
c_ID[] | per-atom scalar from a per-atom compute |
c_ID[][M] | per-atom vector component from a per-atom compute |
Fix references access one or more quantities calculated by a fix. The ID in the reference should be replaced by the actual ID of the fix defined elsewhere in the input script. See the doc pages for individual computes to see which ones calculate global versus per-atom quantities. If the fix reference contains empty brackets, then per-atom values calculated by the fix are accessed. Otherwise a single value (global or per-atom) calculated by the fix is accessed.
Note that some fixes only generate quantities on certain timesteps. If a variable attempts to access the fix on non-allowed timesteps, an error is generated. For example, the fix ave/time command may only generate averaged quantities every 100 steps. See the doc pages for individual fix commands for details. If a variable containing a fix is evaluated in an input script (not during a run), then the values accessed by the fix should be current. See the discussion below about "Variable Accuracy".
The different kinds of fix references are exactly the same as the compute references listed in the above table, where "c_" is replaced by "f_", and the word "compute" is replaced by "fix".
The current values of other variables can be accessed by prepending a "v_" to the variable name. This will cause that variable to be evaluated. Atom-style variables generate per-atom values; all other styles of variables generate a single scalar value.
The different kinds of variable references are as follows. N is a global atom ID (positive integer).
v_ID | scalar value of a non atom-style variable |
v_ID[N] | single atom's scalar value from an atom-style variable |
v_ID[] | per-atom value from an atom-style variable |
IMPORTANT NOTE: If you define variables in circular manner like this:
variable a equal v_b variable b equal v_a print $a
then LAMMPS will run for a while when the print statement is invoked!
Immediate Evaluation of Variables:
There is a difference between referencing a variable with a leading $ sign (e.g. $x or ${abc}) versus with a leading "v_" (e.g. v_x or v_abc). The former can be used in any command, including a variable command, to force the immediate evaluation of the referenced variable and the substitution of its value into the command. The latter is a required kind of argument to some commands (e.g. the fix ave/spatial or dump custom or thermo_style commands) if you wish it to evaluate a variable periodically during a run. It can also be used in a variable formula if you wish to reference a second variable. The second variable will be evaluated whenever the first variable is evaluated.
As an example, suppose you use this command in your input script to define the variable "v" as
variable v equal vol
before a run where the simulation box size changes. You might think this will assign the initial volume to the variable "v". That is not the case. Rather it assigns a formula which evaluates the volume (using the thermo_style keyword "vol") to the variable "v". If you use the variable "v" in some other command like "fix ave/time" then the current volume of the box will be evaluated continuously during the run.
If you want to store the initial volume of the system, you can do it this way:
variable v equal vol variable v0 equal $v
The second command will force "v" to be evaluated (yielding the initial volume) and assign that value to the variable "v0". Thus the command
thermo_style custom step v_v v_v0
would print out both the current and initial volume periodically during the run.
Note that it is a mistake to enclose a variable formula in double quotes if it contains variables preceeded by $ signs. For example,
variable vratio equal "${vfinal}/${v0}"
This is because the quotes prevent variable substitution (see this section on parsing input script commands), and thus an error will occur when the formula for "vratio" is evaluated later.
Variable Accuracy:
Obviously, LAMMPS attempts to evaluate variables containing formulas (equal and atom style variables) accurately whenever the evaluation is performed. Depending on what is included in the formula, this may require invoking a compute, either directly or indirectly via a thermo keyword, or accessing a value previously calculated by a compute, or accessing a value calculated and stored by a fix. If the compute is one that calculates the pressure or energy of the system, then these quantities need to be tallied during the evaluation of the interatomic potentials (pair, bond, etc) on timesteps that the variable will need the values.
LAMMPS keeps track of all of this during a run or energy minimization. An error will be generated if you attempt to evaluate a variable on timesteps when it cannot produce accurate values. For example, if a thermo_style custom command prints a variable which accesses values stored by a fix ave/time command and the timesteps on which thermo output is generated are not multiples of the averaging frequency used in the fix command, then an error will occur.
An input script can also request variables be evaluated before or after or in between runs, e.g. by including them in a print command. In this case, if a compute is needed to evaluate a variable (either directly or indirectly), LAMMPS will not invoke the compute, but it will use a value previously calculated by the compute if it is current. Fixes will always provide a quantity needed by a variable, but the quantity may or may not be current. This leads to one of three kinds of behavior:
(1) The variable may be evaluated accurately. If it contains references to a compute or fix, and these values were calculated on the last timestep of a preceeding run, then they will be accessed and used by the variable and the result will be accurate.
(2) LAMMPS may not be able to evaluate the variable and generate an error. For example, if the variable requires a quantity from a compute that is not current, LAMMPS will not do it. This means, for example, that such a variable then the variable cannot be evaluated before the first run has occurred.
One way to get around this problem is to perform a 0-timestep run before using the variable. For example, these commands
variable t equal temp print "Initial temperature = $t" run 1000
will generate an error if the run is the first run specified in the input script, because generating a value for the "t" variable requires a compute for calculating the temperature to be invoked.
However, this sequence of commands would be fine:
run 0 variable t equal temp print "Initial temperature = $t" run 1000
The 0-timestep run initializes and invokes various computes, including the one for temperature, so that the value it stores is current and can be accessed by the variable "t" after the run has completed. Note that a 0-timestep run does not alter the state of the system, so it does not change the input state for the 1000-timestep run that follows. Also note that the 0-timestep run must actually use and invoke the compute in question (e.g. via thermo or dump output) in order for it to enable the compute to be used in a variable after the run.
Unlike computes, fixes will never generate an error if their values are accessed by a variable in between runs. They always return some value to the variable. However, the value may not be what you expect if the fix has not yet calculated the quantity of interest or it is not current. For example, the fix indent command stores the force on the indenter. But this is not computed until a run is performed. Thus if a variable attempts to print this value before the first run, zeroes will be output. Again, performing a 0-timestep run before printing the variable has the desired effect.
(3) The variable may be evaluated incorrectly. And LAMMPS may have no way to detect this has occurred. Consider the following sequence of commands:
pair_coeff 1 1 1.0 1.0 run 1000 pair_coeff 1 1 1.5 1.0 variable e equal pe print "Final potential energy = $e"
The first run is performed using one setting for the pairwise potential defined by the pair_style and pair_coeff commands. The potential energy is evaluated on the final timestep and stored by the compute pe compute (this is done by the thermo_style command). Then a pair coefficient is changed, altering the potential energy of the system. When the potential energy is printed via the "e" variable, LAMMPS will use the potential energy value stored by the compute pe compute, thinking it is current. There are many other commands which could alter the state of the system between runs, causing a variable to evaluate incorrectly.
The solution to this issue is the same as for case (2) above, namely perform a 0-timestep run before the variable is evaluated to insure the system is up-to-date. For example, this sequence of commands would print a potential energy that reflected the changed pairwise coefficient:
pair_coeff 1 1 1.0 1.0 run 1000 pair_coeff 1 1 1.5 1.0 run 0 variable e equal pe print "Final potential energy = $e"
Restrictions:
Indexing any formula element by global atom ID, such as an atom value, requires the atom style to use a global mapping in order to look up the vector indices. By default, only atom styles with molecular information create global maps. The atom_modify map command can override the default.
All universe- and uloop-style variables defined in an input script must have the same number of values.
Related commands:
next, jump, include, temper, fix print, print
Default: none