diff --git a/doc/Manual.html b/doc/Manual.html index 7f8d9a4ba2..e6185ede65 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -1,7 +1,7 @@
thermo keywords = ke, vol, atoms, ... +
thermo keywords = ke, vol, atoms, ... other variables = v_a, v_myvar, ... math functions = div(x,y), mult(x,y), add(x,y), ... group functions = mass(group), xcm(group,x), ... -atom values = x123, y3, vx34, ... -compute values = c_mytemp0, c_thermo_press3, ... - +atom values = x[123], y[3], vx[34], ... +compute values = c_mytemp[0], c_thermo_press[3], ... +
Adding keywords for the thermo_style custom command (which can then be accessed by variables) was discussed here on this page. diff --git a/doc/Section_start.html b/doc/Section_start.html index 0321152035..270f7985a0 100644 --- a/doc/Section_start.html +++ b/doc/Section_start.html @@ -901,11 +901,24 @@ interface and how to extend it for your needs.
By default, LAMMPS runs by reading commands from stdin; e.g. lmp_linux -< in.file. This means you first create an input script (e.g. in.file) -containing the desired commands. This section -describes how input scripts are structured and what commands they -contain. +
By default, LAMMPS runs by reading commands from standard input. Thus +if you run the LAMMPS executable by itself, e.g. +
+lmp_linux ++
it will simply wait, expecting commands from the keyboard. Typically +you should put commands in an input script and use I/O redirection, +e.g. +
+lmp_linux < in.file ++
For parallel environments this should also work. If it does not, use +the '-in' command-line switch, e.g. +
+lmp_linux -in in.file ++
This section describes how input scripts are +structured and what commands they contain.
You can test LAMMPS on any of the sample inputs provided in the examples or bench directory. Input scripts are named in.* and sample @@ -921,8 +934,9 @@ cp lmp_linux ../bench cd ../bench mpirun -np 4 lmp_linux < in.lj -
See this page for timings for this and the other benchmarks -on various platforms. +
See this page for timings for this and the other benchmarks on +various platforms. Note that some of the example scripts require +LAMMPS to be built with one or more of its optional packages.
@@ -951,12 +965,13 @@ with the name of your LAMMPS input script.For the MPI version, which allows you to run LAMMPS under Windows on multiple processors, follow these steps:
-Specify a file to use as an input script. This is an optional switch when running LAMMPS in one-partition mode. If it is not specified, -LAMMPS reads its input script from stdin - e.g. lmp_linux < in.run. -This is a required switch when running LAMMPS in multi-partition mode, -since multiple processors cannot all read from stdin. +LAMMPS reads its script from standard input, typically from a script +via I/O redirection; e.g. lmp_linux < in.run. I/O redirection should +also work in parallel, but if it does not (in the unlikely case that +an MPI implementation does not support it), then use the -in flag. +Note that this is a required switch when running LAMMPS in +multi-partition mode, since multiple processors cannot all read from +stdin.
-help-
Print a list of options compiled into this executable for each LAMMPS -style (atom_style, fix, compute, pair_style, bond_style, etc). This -can help you know if the command you want to use was included via the -appropriate package. LAMMPS will print the info and immediately exit -if this switch is used. +
Print a brief help summary and a list of options compiled into this +executable for each LAMMPS style (atom_style, fix, compute, +pair_style, bond_style, etc). This can tell you if the command you +want to use was included via the appropriate package at compile time. +LAMMPS will print the info and immediately exit if this switch is +used.
-log filediff --git a/doc/Section_start.txt b/doc/Section_start.txt index 8a39977318..d559f8d92a 100644 --- a/doc/Section_start.txt +++ b/doc/Section_start.txt @@ -895,14 +895,24 @@ interface and how to extend it for your needs. 2.6 Running LAMMPS :h4,link(start_6) -By default, LAMMPS runs by reading commands from standard input, i.e. -if you run the LAMMPS executable by itself it will expect commands from -the keyboard; it is more convenient to use I/O redirection, e.g. lmp_linux -< in.file. This means you first create an input script (e.g. in.file) -containing the desired commands. For parallel environments that does -not always work, so it is safer to use the '-in' command line flag, e.g. -lmp_linux -in in.file. "This section"_Section_commands.html describes -how input scripts are structured and what commands they contain. +By default, LAMMPS runs by reading commands from standard input. Thus +if you run the LAMMPS executable by itself, e.g. + +lmp_linux :pre + +it will simply wait, expecting commands from the keyboard. Typically +you should put commands in an input script and use I/O redirection, +e.g. + +lmp_linux < in.file :pre + +For parallel environments this should also work. If it does not, use +the '-in' command-line switch, e.g. + +lmp_linux -in in.file :pre + +"This section"_Section_commands.html describes how input scripts are +structured and what commands they contain. You can test LAMMPS on any of the sample inputs provided in the examples or bench directory. Input scripts are named in.* and sample @@ -918,8 +928,9 @@ cp lmp_linux ../bench cd ../bench mpirun -np 4 lmp_linux -in in.lj :pre -See "this page"_bench for timings for this and the other benchmarks -on various platforms. +See "this page"_bench for timings for this and the other benchmarks on +various platforms. Note that some of the example scripts require +LAMMPS to be built with one or more of its optional packages. :link(bench,http://lammps.sandia.gov/bench.html) @@ -948,12 +959,13 @@ with the name of your LAMMPS input script. :l,ule For the MPI version, which allows you to run LAMMPS under Windows on multiple processors, follow these steps: -Download and install +Download and install "MPICH2"_http://www.mcs.anl.gov/research/projects/mpich2/downloads/index.php?s=downloads for Windows. :ulb,l -You'll need to use the mpiexec.exe and smpd.exe files from the MPICH2 package. Put them in -same directory (or path) as the LAMMPS Windows executable. :l +You'll need to use the mpiexec.exe and smpd.exe files from the MPICH2 +package. Put them in same directory (or path) as the LAMMPS Windows +executable. :l Get a command prompt by going to Start->Run... , then typing "cmd". :l @@ -961,15 +973,17 @@ then typing "cmd". :l Move to the directory where you have saved lmp_win_mpi.exe (e.g. by typing: cd "Documents"). :l -Then type something like this: "mpiexec -localonly 4 lmp_win_mpi -in in.lj", -replacing in.lj with the name of your LAMMPS input script. :l -Note that you may need to provide smpd with a passphrase --- it doesn't matter what you -type. :l -In this mode, output may not immediately show up on the screen, so -if your input script takes a long time to execute, you may need to be -patient before the output shows up. :l -Alternatively, you can still use this executable to run on a single processor by -typing something like: "lmp_win_mpi -in in.lj". :l,ule +Then type something like this: "mpiexec -localonly 4 lmp_win_mpi -in +in.lj", replacing in.lj with the name of your LAMMPS input script. :l + +Note that you may need to provide smpd with a passphrase (it doesn't +matter what you type). :l + +In this mode, output may not immediately show up on the screen, so if +your input script takes a long time to execute, you may need to be +patient before the output shows up. :l Alternatively, you can still +use this executable to run on a single processor by typing something +like: "lmp_win_mpi -in in.lj". :l,ule :line @@ -1057,18 +1071,21 @@ set by using the "echo"_echo.html command in the input script itself. Specify a file to use as an input script. This is an optional switch when running LAMMPS in one-partition mode. If it is not specified, LAMMPS reads its script from standard input, typically from a script -via I/O redirection; e.g. lmp_linux < in.run. Using the -in flag is -recommended for parallel run, since some MPI implementations do not -fully replicate standard input across all parallel processes. It is -a [required] switch when running LAMMPS in multi-partition mode. +via I/O redirection; e.g. lmp_linux < in.run. I/O redirection should +also work in parallel, but if it does not (in the unlikely case that +an MPI implementation does not support it), then use the -in flag. +Note that this is a required switch when running LAMMPS in +multi-partition mode, since multiple processors cannot all read from +stdin. -help :pre Print a brief help summary and a list of options compiled into this -executable for each LAMMPS style (atom_style, fix, compute, pair_style, -bond_style, etc). This can help you know if the command you want to -use was included via the appropriate package at compile time. LAMMPS -will print the info and immediately exit if this switch is used. +executable for each LAMMPS style (atom_style, fix, compute, +pair_style, bond_style, etc). This can tell you if the command you +want to use was included via the appropriate package at compile time. +LAMMPS will print the info and immediately exit if this switch is +used. -log file :pre diff --git a/doc/Section_tools.html b/doc/Section_tools.html index 5c72e09e76..c6b44e6fb2 100644 --- a/doc/Section_tools.html +++ b/doc/Section_tools.html @@ -47,6 +47,7 @@ own sub-directories with their own Makefiles.
The colvars directory contains a collection of tools for postprocessing +data produced by the colvars collective variable library. +To compile the tools, edit the makefile for your system and run "make". +
+Please report problems and issues the colvars library and its tools +at: https://github.com/colvars/colvars/issues +
+abf_integrate: +
+MC-based integration of multidimensional free energy gradient +Version 20110511 +
+Syntax: ./abf_integrate < filename > [-n < nsteps >] [-t < temp >] [-m [0|1] (metadynamics)] [-h < hill_height >] [-f < variable_hill_factor >] ++
The LAMMPS interface to the colvars collective variable library, as +well as these tools, were created by Axel Kohlmeyer (akohlmey at +gmail.com) at ICTP, Italy. +
+The tools/createatoms directory contains a Fortran program called @@ -156,7 +179,7 @@ suitable for visualizing with the xmovie tool, as if it been output with a dump command from LAMMPS itself. The syntax for running the tool is
-data2xmovie options < infile > outfile +data2xmovie [options] < infile > outfileSee the top of the data2xmovie.c file for a discussion of the options.
@@ -495,7 +518,7 @@ it can find the appropriate X libraries to link against.The syntax for running xmovie is
-xmovie options dump.file1 dump.file2 ... +xmovie [options] dump.file1 dump.file2 ...If you just type "xmovie" you will see a list of options. Note that by default, LAMMPS dump files are in scaled coordinates, so you diff --git a/doc/Section_tools.txt b/doc/Section_tools.txt index c117ee0423..26da1a6d9e 100644 --- a/doc/Section_tools.txt +++ b/doc/Section_tools.txt @@ -149,6 +149,10 @@ Version 20110511 Syntax: ./abf_integrate < filename > \[-n < nsteps >\] \[-t < temp >\] \[-m \[0|1\] (metadynamics)\] \[-h < hill_height >\] \[-f < variable_hill_factor >\] :pre +The LAMMPS interface to the colvars collective variable library, as +well as these tools, were created by Axel Kohlmeyer (akohlmey at +gmail.com) at ICTP, Italy. + :line createatoms tool :h4,link(create) @@ -171,7 +175,7 @@ suitable for visualizing with the "xmovie"_#xmovie tool, as if it had been output with a dump command from LAMMPS itself. The syntax for running the tool is -data2xmovie \[options\] < infile > outfile :pre +data2xmovie \[options\] < infile > outfile :pre See the top of the data2xmovie.c file for a discussion of the options. diff --git a/doc/compute_atom_molecule.html b/doc/compute_atom_molecule.html index cf51daf83b..612812d85c 100644 --- a/doc/compute_atom_molecule.html +++ b/doc/compute_atom_molecule.html @@ -34,7 +34,7 @@
Examples:
compute 1 all atom/molecule c_ke c_pe -compute 1 top atom/molecule v_myFormula c_stress3 +compute 1 top atom/molecule v_myFormula c_stress[3]Description:
diff --git a/doc/compute_reduce.html b/doc/compute_reduce.html index 6ca3e563d5..6a02a01eea 100644 --- a/doc/compute_reduce.html +++ b/doc/compute_reduce.html @@ -52,8 +52,8 @@compute 1 all reduce sum c_force compute 1 all reduce/region subbox sum c_force -compute 2 all reduce min c_press2 f_ave v_myKE -compute 3 fluid reduce max c_index1 c_index2 c_dist replace 1 3 replace 2 3 +compute 2 all reduce min c_press[2] f_ave v_myKE +compute 3 fluid reduce max c_index[1] c_index[2] c_dist replace 1 3 replace 2 3Description:
diff --git a/doc/fix_property_atom.html b/doc/fix_property_atom.html index 43b9f66c41..133e21322d 100644 --- a/doc/fix_property_atom.html +++ b/doc/fix_property_atom.html @@ -175,7 +175,7 @@ dump file:fix prop all property/atom i_flag1 d_flag2 compute 1 all property/atom i_flag1 d_flag2 -dump 1 all custom 100 tmp.dump id x y z c_11 c_12 +dump 1 all custom 100 tmp.dump id x y z c_1[1] c_1[2]
diff --git a/doc/group.html b/doc/group.html index d8a3be8f9d..ad8855f83d 100644 --- a/doc/group.html +++ b/doc/group.html @@ -17,7 +17,7 @@
delete = no args
region args = region-ID
@@ -32,10 +32,17 @@
args = logical value1 value2
logical = "<>"
value1,value2 = atom types or atom IDs or molecule IDs (depending on style)
- variable args = variable-ID
+ variable args = variable-name
subtract args = two or more group IDs
union args = one or more group IDs
- intersect args = two or more group IDs
+ intersect args = two or more group IDs
+ dynamic args = parent-ID keyword value ...
+ one or more keyword/value pairs may be appended
+ keyword = region or var or every
+ region value = region-ID
+ var value = name of variable
+ every value = N = update group every this many timesteps
+ static = no args
Description:
@@ -64,6 +72,18 @@ to act on those atoms together.If the group ID already exists, the group command adds the specified atoms to the group.
+IMPORTANT NOTE: By default groups are static, meaning the atoms are +permanently assigned to the group. For example, if the region style +is used to assign atoms to a group, the atoms will remain in the group +even if they later move out of the region. As explained below, the +dynamic style can be used to make a group dynamic so that a periodic +determination is made as to which atoms are in the group. Since many +LAMMPS commands operate on groups of atoms, you should think carefully +about whether making a group dynamic makes sense for your model. +
+A group with the ID all is predefined. All atoms belong to this +group. This group cannot be deleted, or made dynamic. +
The delete style removes the named group and un-assigns all atoms that were assigned to that group. Since there is a restriction (see below) that no more than 32 groups can be defined at any time, the @@ -156,14 +176,63 @@ added to the specified group. as arguments. Atoms that belong to every one of the listed groups are added to the specified group.
-A group with the ID all is predefined. All atoms belong to this -group. This group cannot be deleted. +
The dynamic style flags an existing or new group as dynamic. This +means atoms will be (re)assigned to the group periodically as a +simulation runs. This is in contrast to static groups where atoms are +permanently assigned to the group. The way the assignment occurs is +as follows. Only atoms in the group specified as the parent group via +the parent-ID are initially assigned to the dynamic group. If the +region keyword is used, atoms not in the specified region are +removed from the dynamic group. If the var keyword is used, the +variable name must be an atom-style or atomfile-style variable. The +variable is evaluated and atoms whose per-atom values are 0.0, are +removed from the dynamic group.
+The assignment of atoms to a dynamic group is done at the beginning of +each run and on every timestep that is a multiple of N, which is the +argument for the every keyword (N = 1 is the default). For an +energy minimization, via the minimize command, an +assignement is made at the beginning of the minimization, but not +during the iterations of the minimizer. +
+The point in the timestep at which atoms are assigned to a dynamic +group is after the initial stage of velocity Verlet time integration +has been performed, and before neighbor lists or forces are computed. +This is the point in the timestep where atom positions have just +changed due to the time integration, so the region criterion should be +accurate, if applied. +
+Here is an example of using a dynamic group to shrink the set of atoms +being integrated by using a spherical region with a variable radius +(shrinking from 18 to 5 over the course of the run). This could be +used to model a quench of the system, freezing atoms outside the +shrinking sphere, then converting the remaining atoms to a static +group and running further. +
+variable nsteps equal 5000 +variable rad equal 18-(step/v_nsteps)*(18-5) +region ss sphere 20 20 0 v_rad +group mobile dynamic all region ss +fix 1 mobile nve +run $nsteps +group mobile static +run $nsteps ++
The static style removes the setting for a dynamic group, converting +it to a static group (the default). The atoms in the static group are +those currently in the dynamic group. +
+Restrictions:
There can be no more than 32 groups defined at one time, including "all".
+The parent group of a dynamic group cannot itself be a dynamic group. +
Related commands:
dump, fix, region, diff --git a/doc/group.txt b/doc/group.txt index 4f258fe7dc..c7551cf43a 100644 --- a/doc/group.txt +++ b/doc/group.txt @@ -14,7 +14,7 @@ group ID style args :pre ID = user-defined name of the group :ulb,l style = {delete} or {region} or {type} or {id} or {molecule} or {variable} or \ - {subtract} or {union} or {intersect} :l + {subtract} or {union} or {intersect} or {dynamic} or {static} :l {delete} = no args {region} args = region-ID {type} or {id} or {molecule} @@ -28,10 +28,17 @@ style = {delete} or {region} or {type} or {id} or {molecule} or {variable} or \ args = logical value1 value2 logical = "<>" value1,value2 = atom types or atom IDs or molecule IDs (depending on {style}) - {variable} args = variable-ID + {variable} args = variable-name {subtract} args = two or more group IDs {union} args = one or more group IDs - {intersect} args = two or more group IDs :pre + {intersect} args = two or more group IDs + {dynamic} args = parent-ID keyword value ... + one or more keyword/value pairs may be appended + keyword = {region} or {var} or {every} + {region} value = region-ID + {var} value = name of variable + {every} value = N = update group every this many timesteps + {static} = no args :pre :ule [Examples:] @@ -47,7 +54,9 @@ group hienergy variable eng group boundary subtract all a2 a3 group boundary union lower upper group boundary intersect upper flow -group boundary delete :pre +group boundary delete +group mine dynamic all region myRegion every 100 :pre + [Description:] @@ -59,6 +68,18 @@ to act on those atoms together. If the group ID already exists, the group command adds the specified atoms to the group. +IMPORTANT NOTE: By default groups are static, meaning the atoms are +permanently assigned to the group. For example, if the {region} style +is used to assign atoms to a group, the atoms will remain in the group +even if they later move out of the region. As explained below, the +{dynamic} style can be used to make a group dynamic so that a periodic +determination is made as to which atoms are in the group. Since many +LAMMPS commands operate on groups of atoms, you should think carefully +about whether making a group dynamic makes sense for your model. + +A group with the ID {all} is predefined. All atoms belong to this +group. This group cannot be deleted, or made dynamic. + The {delete} style removes the named group and un-assigns all atoms that were assigned to that group. Since there is a restriction (see below) that no more than 32 groups can be defined at any time, the @@ -151,14 +172,63 @@ The {intersect} style takes a list of two or more existing group names as arguments. Atoms that belong to every one of the listed groups are added to the specified group. -A group with the ID {all} is predefined. All atoms belong to this -group. This group cannot be deleted. +:line + +The {dynamic} style flags an existing or new group as dynamic. This +means atoms will be (re)assigned to the group periodically as a +simulation runs. This is in contrast to static groups where atoms are +permanently assigned to the group. The way the assignment occurs is +as follows. Only atoms in the group specified as the parent group via +the parent-ID are initially assigned to the dynamic group. If the +{region} keyword is used, atoms not in the specified region are +removed from the dynamic group. If the {var} keyword is used, the +variable name must be an atom-style or atomfile-style variable. The +variable is evaluated and atoms whose per-atom values are 0.0, are +removed from the dynamic group. + +The assignment of atoms to a dynamic group is done at the beginning of +each run and on every timestep that is a multiple of {N}, which is the +argument for the {every} keyword (N = 1 is the default). For an +energy minimization, via the "minimize"_minimize.html command, an +assignement is made at the beginning of the minimization, but not +during the iterations of the minimizer. + +The point in the timestep at which atoms are assigned to a dynamic +group is after the initial stage of velocity Verlet time integration +has been performed, and before neighbor lists or forces are computed. +This is the point in the timestep where atom positions have just +changed due to the time integration, so the region criterion should be +accurate, if applied. + +Here is an example of using a dynamic group to shrink the set of atoms +being integrated by using a spherical region with a variable radius +(shrinking from 18 to 5 over the course of the run). This could be +used to model a quench of the system, freezing atoms outside the +shrinking sphere, then converting the remaining atoms to a static +group and running further. + +variable nsteps equal 5000 +variable rad equal 18-(step/v_nsteps)*(18-5) +region ss sphere 20 20 0 v_rad +group mobile dynamic all region ss +fix 1 mobile nve +run ${nsteps} +group mobile static +run ${nsteps} :pre + +The {static} style removes the setting for a dynamic group, converting +it to a static group (the default). The atoms in the static group are +those currently in the dynamic group. + +:line [Restrictions:] There can be no more than 32 groups defined at one time, including "all". +The parent group of a dynamic group cannot itself be a dynamic group. + [Related commands:] "dump"_dump.html, "fix"_fix.html, "region"_region.html, diff --git a/doc/if.html b/doc/if.html index c15fb22b3d..a4b18dad82 100644 --- a/doc/if.html +++ b/doc/if.html @@ -26,6 +26,7 @@
Examples:
if "${steps} > 1000" then quit
+if "${myString} == a10" then quit
if "$x <= $y" then "print X is smaller = $x" else "print Y is smaller = $y"
if "(${eng} > 0.0) || ($n < 1000)" then &
"timestep 0.005" &
@@ -116,19 +117,25 @@ syntax. Note that each expression is a single argument within the if
command. Thus if you want to include spaces in the expression for
clarity, you must enclose the entire expression in quotes.
-An expression is built out of numbers:
+
An expression is built out of numbers (which start with a digit or
+period or minus sign) or strings (which start with a letter and can
+contain alphanumeric characters or underscores):
0.2, 100, 1.0e20, -15.4, etc
+InP, myString, a123, ab_23_cd, etc
and Boolean operators:
A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, !A
-Each A and B is a number or a variable reference like $a or ${abc},
-or another Boolean expression.
+
Each A and B is a number or string or a variable reference like $a or
+${abc}, or A or B can be another Boolean expression.
-If a variable is used it must produce a number when evaluated and
-substituted for in the expression, else an error will be generated.
+
If a variable is used it can produce a number when evaluated, like an
+equal-style variable. Or it can produce a string,
+like an index-style variable. For an individual
+Boolean operator, A and B must both be numbers or must both be
+strings. You cannot compare a number to a string.
Expressions are evaluated left to right and have the usual C-style
precedence: the unary logical NOT operator "!" has the highest
@@ -139,13 +146,21 @@ operator "||" has the lowest precedence. Parenthesis can be used to
group one or more portions of an expression 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. The
+
When the 6 relational operators (first 6 in list above) compare 2
+numbers, they return either a 1.0 or 0.0 depending on whether the
+relationship between A and B is TRUE or FALSE. When the 6 relational
+operators compare 2 strings, they also return a 1.0 or 0.0 for TRUE or
+FALSE, but the comparison is done by the C function strcmp().
+
+When the 3 logical operators (last 3 in list above) compare 2 numbers,
+they also return either a 1.0 or 0.0 depending on whether the
+relationship between A and B is TRUE or FALSE (or just A). 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.
+returns 0.0. The 3 logical operators can only be used to operate on
+numbers, not on strings.
The overall Boolean expression produces a TRUE result if the result is
non-zero. If the result is zero, the expression result is FALSE.
diff --git a/doc/if.txt b/doc/if.txt
index bea660aa9d..fe037fd72c 100644
--- a/doc/if.txt
+++ b/doc/if.txt
@@ -23,6 +23,7 @@ e1,e2,...,eN = one or more LAMMPS commands to execute if no condition is met, ea
[Examples:]
if "$\{steps\} > 1000" then quit
+if "$\{myString\} == a10" then quit
if "$x <= $y" then "print X is smaller = $x" else "print Y is smaller = $y"
if "($\{eng\} > 0.0) || ($n < 1000)" then &
"timestep 0.005" &
@@ -112,19 +113,25 @@ syntax. Note that each expression is a single argument within the if
command. Thus if you want to include spaces in the expression for
clarity, you must enclose the entire expression in quotes.
-An expression is built out of numbers:
+An expression is built out of numbers (which start with a digit or
+period or minus sign) or strings (which start with a letter and can
+contain alphanumeric characters or underscores):
-0.2, 100, 1.0e20, -15.4, etc :pre
+0.2, 100, 1.0e20, -15.4, etc
+InP, myString, a123, ab_23_cd, etc :pre
and Boolean operators:
A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, !A :pre
-Each A and B is a number or a variable reference like $a or $\{abc\},
-or another Boolean expression.
+Each A and B is a number or string or a variable reference like $a or
+$\{abc\}, or A or B can be another Boolean expression.
-If a variable is used it must produce a number when evaluated and
-substituted for in the expression, else an error will be generated.
+If a variable is used it can produce a number when evaluated, like an
+"equal-style variable"_variable.html. Or it can produce a string,
+like an "index-style variable"_variable.html. For an individual
+Boolean operator, A and B must both be numbers or must both be
+strings. You cannot compare a number to a string.
Expressions are evaluated left to right and have the usual C-style
precedence: the unary logical NOT operator "!" has the highest
@@ -135,13 +142,21 @@ operator "||" has the lowest precedence. Parenthesis can be used to
group one or more portions of an expression 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. The
+When the 6 relational operators (first 6 in list above) compare 2
+numbers, they return either a 1.0 or 0.0 depending on whether the
+relationship between A and B is TRUE or FALSE. When the 6 relational
+operators compare 2 strings, they also return a 1.0 or 0.0 for TRUE or
+FALSE, but the comparison is done by the C function strcmp().
+
+When the 3 logical operators (last 3 in list above) compare 2 numbers,
+they also return either a 1.0 or 0.0 depending on whether the
+relationship between A and B is TRUE or FALSE (or just A). 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.
+returns 0.0. The 3 logical operators can only be used to operate on
+numbers, not on strings.
The overall Boolean expression produces a TRUE result if the result is
non-zero. If the result is zero, the expression result is FALSE.
diff --git a/src/Makefile b/src/Makefile
index 4c81ad9fe7..21895be295 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -147,26 +147,21 @@ package:
@echo ''
@echo 'User-contributed packages:' $(PACKUSER)
@echo ''
- @echo 'make package list available packages'
- @echo 'make package-status (ps) status of all packages'
- @echo 'make yes-package install a single package in src dir'
- @echo 'make no-package remove a single package from src dir'
- @echo 'make yes-all install all packages in src dir'
- @echo 'make no-all remove all packages from src dir'
- @echo 'make yes-standard install all standard packages'
- @echo 'make no-standard remove all standard packages'
- @echo 'make yes-user install all user packages'
- @echo 'make no-user remove all user packages'
- @echo 'make no-lib remove all packages with external libs'
+ @echo 'make package list available packages'
+ @echo 'make package-status (ps) status of all packages'
+ @echo 'make yes-package install a single package in src dir'
+ @echo 'make no-package remove a single package from src dir'
+ @echo 'make yes-all install all packages in src dir'
+ @echo 'make no-all remove all packages from src dir'
+ @echo 'make yes-standard install all standard packages'
+ @echo 'make no-standard remove all standard packages'
+ @echo 'make yes-user install all user packages'
+ @echo 'make no-user remove all user packages'
+ @echo 'make no-lib remove all packages with external libs'
@echo ''
- @echo 'make package-update (pu) replace src files with package files'
- @echo 'make package-overwrite replace package files with src files'
- @echo 'make package-diff (pd) diff src files against package file'
-
-# backward compatibility
-yes-user-openmp no-user-openmp:
- @echo 'The user-openmp package has been superseded by the user-omp package'
- exit 1
+ @echo 'make package-update (pu) replace src files with package files'
+ @echo 'make package-overwrite replace package files with src files'
+ @echo 'make package-diff (pd) diff src files against package file'
yes-all:
@for p in $(PACKALL); do $(MAKE) yes-$$p; done
diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp
index d4eb9718a1..bf14e5a54a 100644
--- a/src/fix_langevin.cpp
+++ b/src/fix_langevin.cpp
@@ -201,7 +201,6 @@ int FixLangevin::setmask()
int mask = 0;
mask |= POST_FORCE;
mask |= POST_FORCE_RESPA;
- mask |= POST_INTEGRATE;
mask |= END_OF_STEP;
mask |= THERMO_ENERGY;
return mask;
diff --git a/src/fix_vector.cpp b/src/fix_vector.cpp
index 5e2ae4b562..7ecd49d049 100644
--- a/src/fix_vector.cpp
+++ b/src/fix_vector.cpp
@@ -11,10 +11,6 @@
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-/* ----------------------------------------------------------------------
- Contributing author: Pieter in 't Veld (SNL)
-------------------------------------------------------------------------- */
-
#include "string.h"
#include "fix_vector.h"
#include "update.h"
diff --git a/src/fix_vector.h b/src/fix_vector.h
index 4bfed79e0c..0d3511d695 100644
--- a/src/fix_vector.h
+++ b/src/fix_vector.h
@@ -20,7 +20,6 @@ FixStyle(vector,FixVector)
#ifndef LMP_FIX_VECTOR_H
#define LMP_FIX_VECTOR_H
-#include "stdio.h"
#include "fix.h"
namespace LAMMPS_NS {
@@ -53,99 +52,4 @@ class FixVector : public Fix {
/* ERROR/WARNING messages:
-E: Illegal ... command
-
-Self-explanatory. Check the input script syntax and compare to the
-documentation for the command. You can use -echo screen as a
-command-line option when running LAMMPS to see the offending line.
-
-E: Compute ID for fix ave/time does not exist
-
-Self-explanatory.
-
-E: Fix ID for fix ave/time does not exist
-
-Self-explanatory.
-
-E: Invalid fix ave/time off column
-
-Self-explantory.
-
-E: Fix ave/time compute does not calculate a scalar
-
-Self-explantory.
-
-E: Fix ave/time compute does not calculate a vector
-
-Self-explantory.
-
-E: Fix ave/time compute vector is accessed out-of-range
-
-The index for the vector is out of bounds.
-
-E: Fix ave/time compute does not calculate an array
-
-Self-explanatory.
-
-E: Fix ave/time compute array is accessed out-of-range
-
-An index for the array is out of bounds.
-
-E: Fix ave/time fix does not calculate a scalar
-
-Self-explanatory.
-
-E: Fix ave/time fix does not calculate a vector
-
-Self-explanatory.
-
-E: Fix ave/time fix vector is accessed out-of-range
-
-The index for the vector is out of bounds.
-
-E: Fix for fix ave/time not computed at compatible time
-
-Fixes generate their values on specific timesteps. Fix ave/time
-is requesting a value on a non-allowed timestep.
-
-E: Fix ave/time fix does not calculate an array
-
-Self-explanatory.
-
-E: Fix ave/time fix array is accessed out-of-range
-
-An index for the array is out of bounds.
-
-E: Variable name for fix ave/time does not exist
-
-Self-explanatory.
-
-E: Fix ave/time variable is not equal-style variable
-
-Self-explanatory.
-
-E: Fix ave/time cannot use variable with vector mode
-
-Variables produce scalar values.
-
-E: Fix ave/time columns are inconsistent lengths
-
-Self-explanatory.
-
-E: Fix ave/time cannot set output array intensive/extensive from these inputs
-
-One of more of the vector inputs has individual elements which are
-flagged as intensive or extensive. Such an input cannot be flagged as
-all intensive/extensive when turned into an array by fix ave/time.
-
-E: Cannot open fix ave/time file %s
-
-The specified file cannot be opened. Check that the path and name are
-correct.
-
-E: Fix ave/time missed timestep
-
-You cannot reset the timestep to a value beyond where the fix
-expects to next perform averaging.
-
*/
diff --git a/src/group.cpp b/src/group.cpp
index ce99834a6e..04afbf462a 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -51,10 +51,12 @@ Group::Group(LAMMPS *lmp) : Pointers(lmp)
names = new char*[MAX_GROUP];
bitmask = new int[MAX_GROUP];
inversemask = new int[MAX_GROUP];
+ dynamic = new int[MAX_GROUP];
for (int i = 0; i < MAX_GROUP; i++) names[i] = NULL;
for (int i = 0; i < MAX_GROUP; i++) bitmask[i] = 1 << i;
for (int i = 0; i < MAX_GROUP; i++) inversemask[i] = bitmask[i] ^ ~0;
+ for (int i = 0; i < MAX_GROUP; i++) dynamic[i] = 0;
// create "all" group
@@ -75,6 +77,7 @@ Group::~Group()
delete [] names;
delete [] bitmask;
delete [] inversemask;
+ delete [] dynamic;
}
/* ----------------------------------------------------------------------
@@ -114,8 +117,17 @@ void Group::assign(int narg, char **arg)
int bits = inversemask[igroup];
for (i = 0; i < nlocal; i++) mask[i] &= bits;
+ if (dynamic[igroup]) {
+ int n = strlen("GROUP_") + strlen(names[igroup]) + 1;
+ char *fixID = new char[n];
+ sprintf(fixID,"GROUP_%s",names[igroup]);
+ modify->delete_fix(fixID);
+ delete [] fixID;
+ }
+
delete [] names[igroup];
names[igroup] = NULL;
+ dynamic[igroup] = 0;
ngroup--;
return;
@@ -156,6 +168,7 @@ void Group::assign(int narg, char **arg)
mask[i] |= bit;
// style = type, molecule, id
+ // add to group if atom matches type/molecule/id or condition
} else if (strcmp(arg[1],"type") == 0 || strcmp(arg[1],"molecule") == 0 ||
strcmp(arg[1],"id") == 0) {
@@ -296,6 +309,7 @@ void Group::assign(int narg, char **arg)
}
// style = variable
+ // add to group if atom-atyle variable is non-zero
} else if (strcmp(arg[1],"variable") == 0) {
@@ -331,6 +345,8 @@ void Group::assign(int narg, char **arg)
for (int iarg = 2; iarg < narg; iarg++) {
jgroup = find(arg[iarg]);
if (jgroup == -1) error->all(FLERR,"Group ID does not exist");
+ if (dynamic[jgroup])
+ error->all(FLERR,"Cannot subtract groups using a dynamic group");
list[iarg-2] = jgroup;
}
@@ -367,6 +383,8 @@ void Group::assign(int narg, char **arg)
for (int iarg = 2; iarg < narg; iarg++) {
jgroup = find(arg[iarg]);
if (jgroup == -1) error->all(FLERR,"Group ID does not exist");
+ if (dynamic[jgroup])
+ error->all(FLERR,"Cannot union groups using a dynamic group");
list[iarg-2] = jgroup;
}
@@ -395,6 +413,8 @@ void Group::assign(int narg, char **arg)
for (int iarg = 2; iarg < narg; iarg++) {
jgroup = find(arg[iarg]);
if (jgroup == -1) error->all(FLERR,"Group ID does not exist");
+ if (dynamic[jgroup])
+ error->all(FLERR,"Cannot intersect groups using a dynamic group");
list[iarg-2] = jgroup;
}
@@ -413,6 +433,60 @@ void Group::assign(int narg, char **arg)
delete [] list;
+ // style = dynamic
+ // create a new FixGroup to dynamically determine atoms in group
+
+ } else if (strcmp(arg[1],"dynamic") == 0) {
+
+ if (narg < 4) error->all(FLERR,"Illegal group command");
+ if (strcmp(arg[0],arg[2]) == 0)
+ error->all(FLERR,"Group dynamic cannot reference itself");
+ if (find(arg[2]) < 0)
+ error->all(FLERR,"Group dynamic parent group does not exist");
+ if (igroup == 0) error->all(FLERR,"Group all cannot be made dynamic");
+
+ // if group is already dynamic, delete existing FixGroup
+
+ if (dynamic[igroup]) {
+ int n = strlen("GROUP_") + strlen(names[igroup]) + 1;
+ char *fixID = new char[n];
+ sprintf(fixID,"GROUP_%s",names[igroup]);
+ modify->delete_fix(fixID);
+ delete [] fixID;
+ }
+
+ dynamic[igroup] = 1;
+
+ int n = strlen("GROUP_") + strlen(names[igroup]) + 1;
+ char *fixID = new char[n];
+ sprintf(fixID,"GROUP_%s",names[igroup]);
+
+ char **newarg = new char*[narg];
+ newarg[0] = fixID;
+ newarg[1] = arg[2];
+ newarg[2] = (char *) "GROUP";
+ for (int i = 3; i < narg; i++) newarg[i] = arg[i];
+ modify->add_fix(narg,newarg);
+ delete [] newarg;
+ delete [] fixID;
+
+ // style = static
+ // remove dynamic FixGroup if necessary
+
+ } else if (strcmp(arg[1],"static") == 0) {
+
+ if (narg != 2) error->all(FLERR,"Illegal group command");
+
+ if (dynamic[igroup]) {
+ int n = strlen("GROUP_") + strlen(names[igroup]) + 1;
+ char *fixID = new char[n];
+ sprintf(fixID,"GROUP_%s",names[igroup]);
+ modify->delete_fix(fixID);
+ delete [] fixID;
+ }
+
+ dynamic[igroup] = 0;
+
// not a valid group style
} else error->all(FLERR,"Illegal group command");
diff --git a/src/group.h b/src/group.h
index a66f5cca24..002094640a 100644
--- a/src/group.h
+++ b/src/group.h
@@ -25,6 +25,7 @@ class Group : protected Pointers {
char **names; // name of each group
int *bitmask; // one-bit mask for each group
int *inversemask; // inverse mask for each group
+ int *dynamic; // 1 if dynamic, 0 if not
Group(class LAMMPS *);
~Group();
diff --git a/src/variable.cpp b/src/variable.cpp
index 081ffc4fb6..c4dc1c0bf2 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -3700,11 +3700,18 @@ void Variable::print_tree(Tree *tree, int level)
double Variable::evaluate_boolean(char *str)
{
- int op,opprevious;
+ int op,opprevious,flag1,flag2;
double value1,value2;
char onechar;
+ char *str1,*str2;
- double argstack[MAXLEVEL];
+ struct Arg {
+ int flag; // 0 for numeric value, 1 for string
+ double value; // stored numeric value
+ char *str; // stored string
+ };
+
+ Arg argstack[MAXLEVEL];
int opstack[MAXLEVEL];
int nargstack = 0;
int nopstack = 0;
@@ -3734,7 +3741,9 @@ double Variable::evaluate_boolean(char *str)
// evaluate contents and push on stack
- argstack[nargstack++] = evaluate_boolean(contents);
+ argstack[nargstack].value = evaluate_boolean(contents);
+ argstack[nargstack].flag = 0;
+ nargstack++;
delete [] contents;
@@ -3747,7 +3756,7 @@ double Variable::evaluate_boolean(char *str)
error->all(FLERR,"Invalid Boolean syntax in if command");
expect = OP;
- // istop = end of number, including scientific notation
+ // set I to end of number, including scientific notation
int istart = i++;
while (isdigit(str[i]) || str[i] == '.') i++;
@@ -3756,16 +3765,36 @@ double Variable::evaluate_boolean(char *str)
if (str[i] == '+' || str[i] == '-') i++;
while (isdigit(str[i])) i++;
}
- int istop = i - 1;
- int n = istop - istart + 1;
- char *number = new char[n+1];
- strncpy(number,&str[istart],n);
- number[n] = '\0';
+ onechar = str[i];
+ str[i] = '\0';
+ argstack[nargstack].value = atof(&str[istart]);
+ str[i] = onechar;
- argstack[nargstack++] = atof(number);
+ argstack[nargstack++].flag = 0;
- delete [] number;
+ // ----------------
+ // string: push string onto stack
+ // ----------------
+
+ } else if (isalpha(onechar)) {
+ if (expect == OP)
+ error->all(FLERR,"Invalid Boolean syntax in if command");
+ expect = OP;
+
+ // set I to end of string
+
+ int istart = i++;
+ while (isalnum(str[i]) || str[i] == '_') i++;
+
+ int n = i - istart + 1;
+ argstack[nargstack].str = new char[n];
+ onechar = str[i];
+ str[i] = '\0';
+ strcpy(argstack[nargstack].str,&str[istart]);
+ str[i] = onechar;
+
+ argstack[nargstack++].flag = 1;
// ----------------
// Boolean operator, including end-of-string
@@ -3823,37 +3852,72 @@ double Variable::evaluate_boolean(char *str)
while (nopstack && precedence[opstack[nopstack-1]] >= precedence[op]) {
opprevious = opstack[--nopstack];
- value2 = argstack[--nargstack];
- if (opprevious != NOT) value1 = argstack[--nargstack];
+ nargstack--;
+ flag2 = argstack[nargstack].flag;
+ value2 = argstack[nargstack].value;
+ str2 = argstack[nargstack].str;
+ if (opprevious != NOT) {
+ nargstack--;
+ flag1 = argstack[nargstack].flag;
+ value1 = argstack[nargstack].value;
+ str1 = argstack[nargstack].str;
+ }
if (opprevious == NOT) {
- if (value2 == 0.0) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value2 == 0.0) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
} else if (opprevious == EQ) {
- if (value1 == value2) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag1 != flag2)
+ error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (flag2 == 0) {
+ if (value1 == value2) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
+ } else {
+ if (strcmp(str1,str2) == 0) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
+ delete [] str1;
+ delete [] str2;
+ }
} else if (opprevious == NE) {
- if (value1 != value2) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag1 != flag2)
+ error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (flag2 == 0) {
+ if (value1 != value2) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
+ } else {
+ if (strcmp(str1,str2) != 0) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
+ delete [] str1;
+ delete [] str2;
+ }
} else if (opprevious == LT) {
- if (value1 < value2) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value1 < value2) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
} else if (opprevious == LE) {
- if (value1 <= value2) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value1 <= value2) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
} else if (opprevious == GT) {
- if (value1 > value2) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value1 > value2) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
} else if (opprevious == GE) {
- if (value1 >= value2) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value1 >= value2) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
} else if (opprevious == AND) {
- if (value1 != 0.0 && value2 != 0.0) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value1 != 0.0 && value2 != 0.0) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
} else if (opprevious == OR) {
- if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0;
- else argstack[nargstack++] = 0.0;
+ if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
+ if (value1 != 0.0 || value2 != 0.0) argstack[nargstack].value = 1.0;
+ else argstack[nargstack].value = 0.0;
}
+
+ argstack[nargstack++].flag = 0;
}
// if end-of-string, break out of entire formula evaluation loop
@@ -3869,7 +3933,7 @@ double Variable::evaluate_boolean(char *str)
if (nopstack) error->all(FLERR,"Invalid Boolean syntax in if command");
if (nargstack != 1) error->all(FLERR,"Invalid Boolean syntax in if command");
- return argstack[0];
+ return argstack[0].value;
}
/* ---------------------------------------------------------------------- */
diff --git a/src/version.h b/src/version.h
index 4512f18ed9..95613ff5fe 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "7 Feb 2014"
+#define LAMMPS_VERSION "9 Feb 2014"
diff --git a/tools/README b/tools/README
index b09334fee0..b611b6c97f 100644
--- a/tools/README
+++ b/tools/README
@@ -16,6 +16,7 @@ amber2lmp python scripts for using AMBER to setup LAMMPS input
binary2txt convert a LAMMPS dump file from binary to ASCII text
ch2lmp convert CHARMM files to LAMMPS input
chain create a data file of bead-spring chains
+colvars post-process output of the fix colvars command
createatoms generate lattices of atoms within a geometry
data2xmovie convert a data file to a snapshot that xmovie can viz
eam_database one tool to generate EAM alloy potential files
@@ -30,7 +31,7 @@ lmp2vmd tools for visualizing and analyzing LAMMPS data with VMD
matlab MatLab scripts for post-processing LAMMPS output
micelle2d create a data file of small lipid chains in solvent
msi2lmp use Accelrys Insight code to setup LAMMPS input
-phonon post-process output of fix phonon command
+phonon post-process output of the fix phonon command
pymol_asphere convert LAMMPS output of ellipsoids to PyMol format
python Python scripts for post-processing LAMMPS output
reax Tools for analyzing output of ReaxFF simulations