Syntax:
variable name style args ...
delete = no args index args = one or more strings loop args = N N = integer size of loop, loop from 1 to N inclusive loop args = N pad N = integer size of loop, loop from 1 to N inclusive pad = all values will be same length, e.g. 001, 002, ..., 100 loop args = N1 N2 N1,N2 = loop from N1 to N2 inclusive loop args = N1 N2 pad N1,N2 = loop from N1 to N2 inclusive pad = all values will be same length, e.g. 050, 051, ..., 100 world args = one string for each partition of processors universe args = one or more strings uloop args = N N = integer size of loop uloop args = N pad N = integer size of loop pad = all values will be same length, e.g. 001, 002, ..., 100 string arg = one string equal args = one formula containing numbers, keywords, math operations, variable references numbers = 0.0, 100, -5.4, 2.8e-4, etc constants = PI keywords = nprocs, time math operators = (), -x, x+y, x-y, x*y, x/y, x^y, x==y, x!=y, xy, x>=y, x&&y, x||y, !x math functions = sqrt(x), exp(x), ln(x), log(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x) ramp(x,y), stagger(x,y), logfreq(x,y,z), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) variable references = v_name
Examples:
variable x index run1 run2 run3 run4 run5 run6 run7 run8 variable LoopVar loop $n variable p equal nprocs variable b1 equal 0.5*v_flag variable b1 equal "10 + 0.5*v_flag" variable foo myfile variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 variable x uloop 15 pad 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 OINK. 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 via the print command. Variables that store a collection of strings can be used as input to a named command, e.g. to process a collection of filenames. See the named command doc page for details.
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 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 string and equal ARE redefined each time the command is encountered. This allows these style of variables to be redefined multiple times in an input script. In a loop, this means the formula associated with an equal-style variable can change if it contains a substitution for another variable, e.g. $x.
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 inclusive, if only one argument N is specified. 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. The loop style can also be specified with two arguments N1 and N2. In this case the loop runs from N1 to N2 inclusive, and the string N1 is initially assigned 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 OINK 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 perform different calculations on 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 OINK 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.oink.variable" and "tmp.oink.variable.lock" which you will see in your directory during such a OINK 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.
All universe- and uloop-style variables defined in an input script must have the same number of values.
For the equal style, 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. The formula computes a scalar quantity, which becomes the value of the variable whenever it is evaluated.
Note that equal variables can produce different values at different stages of the input script or at different times during a run. For example, if the equal variable is printed during a loop, different values could be printed each time 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 style variables, since there is only one string.
The formula for an equal 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.
Specifically, an formula can contain numbers, keywords, math operators, math functions, and references to other variables.
Number | 0.2, 100, 1.0e20, -15.4, etc |
Constant | PI |
Keywords | nprocs, time |
Math operators | (), -x, x+y, x-y, x*y, x/y, x^y, x==y, x!=y, x |
Math functions | sqrt(x), exp(x), ln(x), log(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), ramp(x,y), stagger(x,y), logfreq(x,y,z), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) |
Other variables | v_name |
The keywords allowed in a formula are nprocs and time. Nprocs is the number of processors being used. Time is the elapsed time of the most recently executed named command or MR-MPI library command.
Math operators are written in the usual way, where the "x" and "y" in the examples can themselves be arbitrarily complex formulas, as in the examples above.
Operators are evaluated left to right and have the usual C-style precedence: unary minus and unary logical NOT operator "!" have the highest precedence, exponentiation "^" is next; multiplication and division are next; addition and subtraction are next; the 4 relational operators "<", "<=", ">", and ">=" are next; the two remaining relational operators "==" and "!=" are next; then the logical AND operator "&&"; and finally the logical OR operator "||" has the lowest precedence. Parenthesis can be used to group one or more portions of a formula and/or enforce a different order of evaluation than what would occur with the default precedence.
The 6 relational operators return either a 1.0 or 0.0 depending on whether the relationship between x and y is TRUE or FALSE. For example the expression x<10.0 in an atom-style variable formula will return 1.0 for all atoms whose x-coordinate is less than 10.0, and 0.0 for the others. The logical AND operator will return 1.0 if both its arguments are non-zero, else it returns 0.0. The logical OR operator will return 1.0 if either of its arguments is non-zero, else it returns 0.0. The logical NOT operator returns 1.0 if its argument is 0.0, else it returns 0.0.
Math functions are specified as keywords followed by one or more parenthesized arguments "x", "y", "z", each of which can themselves be arbitrarily complex formulas.
Most of the math functions perform obvious operations. The ln() is the natural log; log() is the base 10 log.
The random(x,y,z) function takes 3 arguments: x = lo, y = hi, and z = seed. It generates a uniform random number between lo and hi. The normal(x,y,z) function also takes 3 arguments: x = mu, y = sigma, and z = seed. It generates a Gaussian variate centered on mu with variance sigma^2. In both cases the seed is used the first time the internal random number generator is invoked, to initialize it. For equal-style variables, every processor uses the same seed so that they each generate the same sequence of random numbers.
IMPORTANT NOTE: Internally, there is just one random number generator for all equal-style variables. If you define multiple variables (of each style) which use the random() or normal() math functions, then the internal random number generators will only be initialized once, which means only one of the specified seeds will determine the sequence of generated random numbers.
The ceil(), floor(), and round() functions 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.
Variable references access quantities calulated by other variables, which will cause those variables to be evaluated. The name in the reference should be replaced by the name of a variable defined elsewhere in the input script.
IMPORTANT NOTE: If you define variables in circular manner like this:
variable a equal v_b variable b equal v_a print $a
then OINK may 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.
Related commands: