Merge remote-tracking branch 'github/develop' into apip

This commit is contained in:
Axel Kohlmeyer
2025-06-12 22:27:03 -04:00
85 changed files with 8080 additions and 726 deletions

View File

@ -31,3 +31,5 @@ OPT.
* :doc:`pppm/dielectric <kspace_style>`
* :doc:`pppm/electrode (i) <kspace_style>`
* :doc:`scafacos <kspace_style>`
* :doc:`zero <kspace_style>`

View File

@ -68,24 +68,25 @@ Members of ``lammpsplugin_t``
* - author
- String with the name and email of the author
* - creator.v1
- Pointer to factory function for pair, bond, angle, dihedral, improper, kspace, or command styles
- Pointer to factory function for pair, bond, angle, dihedral, improper, kspace, command, or minimize styles
* - creator.v2
- Pointer to factory function for compute, fix, or region styles
- Pointer to factory function for compute, fix, region, or run styles
* - handle
- Pointer to the open DSO file handle
Only one of the two alternate creator entries can be used at a time and
which of those is determined by the style of plugin. The "creator.v1"
element is for factory functions of supported styles computing forces
(i.e. pair, bond, angle, dihedral, or improper styles) or command styles
and the function takes as single argument the pointer to the LAMMPS
instance. The factory function is cast to the ``lammpsplugin_factory1``
type before assignment. The "creator.v2" element is for factory
functions creating an instance of a fix, compute, or region style and
takes three arguments: a pointer to the LAMMPS instance, an integer with
the length of the argument list and a ``char **`` pointer to the list of
arguments. The factory function pointer needs to be cast to the
``lammpsplugin_factory2`` type before assignment.
(i.e. pair, bond, angle, dihedral, or improper styles), command styles,
or minimize styles and the function takes as single argument the pointer
to the LAMMPS instance. The factory function is cast to the
``lammpsplugin_factory1`` type before assignment. The "creator.v2"
element is for factory functions creating an instance of a fix, compute,
region, or run style and takes three arguments: a pointer to the LAMMPS
instance, an integer with the length of the argument list and a ``char
**`` pointer to the list of arguments. The factory function pointer
needs to be cast to the ``lammpsplugin_factory2`` type before
assignment.
Pair style example
^^^^^^^^^^^^^^^^^^
@ -247,8 +248,8 @@ DSO handle. The registration function is called with a pointer to the address
of this struct and the pointer of the LAMMPS class. The registration function
will then add the factory function of the plugin style to the respective
style map under the provided name. It will also make a copy of the struct
in a list of all loaded plugins and update the reference counter for loaded
plugins from this specific DSO file.
in a global list of all loaded plugins and update the reference counter for
loaded plugins from this specific DSO file.
The pair style itself (i.e. the PairMorse2 class in this example) can be
written just like any other pair style that is included in LAMMPS. For
@ -263,6 +264,21 @@ the plugin will override the existing code. This can be used to modify
the behavior of existing styles or to debug new versions of them without
having to re-compile or re-install all of LAMMPS.
.. versionchanged:: 12Jun2025
When using the :doc:`clear <clear>` command, plugins are not unloaded
but restored to their respective style maps. This also applies when
multiple LAMMPS instances are created and deleted through the library
interface. The :doc:`plugin load <plugin>` load command may be issued
again, but for existing plugins they will be skipped. To replace
plugins they must be explicitly unloaded with :doc:`plugin unload
<plugin>`. When multiple LAMMPS instances are created concurrently, any
loaded plugins will be added to the global list of plugins, but are not
immediately available to any LAMMPS instance that was created before
loading the plugin. To "import" such plugins, the :doc:`plugin restore
<plugin>` may be used. Plugins are only removed when they are explicitly
unloaded or the LAMMPS interface is "finalized".
Compiling plugins
^^^^^^^^^^^^^^^^^

View File

@ -69,10 +69,11 @@ statement. Internally, it will call either
:cpp:func:`lammps_open_fortran` or :cpp:func:`lammps_open_no_mpi` from
the C library API to create the class instance. All arguments are
optional and :cpp:func:`lammps_mpi_init` will be called automatically
if it is needed. Similarly, a possible call to
:cpp:func:`lammps_mpi_finalize` is integrated into the :f:func:`close`
function and triggered with the optional logical argument set to
``.TRUE.``. Here is a simple example:
if it is needed. Similarly, optional calls to
:cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_kokkos_finalize`,
:cpp:func:`lammps_python_finalize`, and :cpp:func:`lammps_plugin_finalize`
are integrated into the :f:func:`close` function and triggered with the
optional logical argument set to ``.TRUE.``. Here is a simple example:
.. code-block:: fortran
@ -521,8 +522,8 @@ Procedures Bound to the :f:type:`lammps` Derived Type
This method will close down the LAMMPS instance through calling
:cpp:func:`lammps_close`. If the *finalize* argument is present and
has a value of ``.TRUE.``, then this subroutine also calls
:cpp:func:`lammps_kokkos_finalize` and
:cpp:func:`lammps_mpi_finalize`.
:cpp:func:`lammps_kokkos_finalize`, :cpp:func:`lammps_mpi_finalize`,
:cpp:func:`lammps_python_finalize`, and :cpp:func:`lammps_plugin_finalize`.
:o finalize: shut down the MPI environment of the LAMMPS
library if ``.TRUE.``.
@ -530,6 +531,8 @@ Procedures Bound to the :f:type:`lammps` Derived Type
:to: :cpp:func:`lammps_close`
:to: :cpp:func:`lammps_mpi_finalize`
:to: :cpp:func:`lammps_kokkos_finalize`
:to: :cpp:func:`lammps_python_finalize`
:to: :cpp:func:`lammps_plugin_finalize`
--------

View File

@ -11,6 +11,7 @@ This section documents the following functions:
- :cpp:func:`lammps_mpi_finalize`
- :cpp:func:`lammps_kokkos_finalize`
- :cpp:func:`lammps_python_finalize`
- :cpp:func:`lammps_plugin_finalize`
- :cpp:func:`lammps_error`
--------------------
@ -119,5 +120,10 @@ calling program.
-----------------------
.. doxygenfunction:: lammps_plugin_finalize
:project: progguide
-----------------------
.. doxygenfunction:: lammps_error
:project: progguide

View File

@ -5,18 +5,28 @@ LAMMPS has several commands which can be used to invoke Python
code directly from an input script:
* :doc:`python <python>`
* :doc:`variable python <variable>`
* :doc:`python-style variables <variable>`
* :doc:`equal-style and atom-style variables with formulas containing Python function wrappers <variable>`
* :doc:`fix python/invoke <fix_python_invoke>`
* :doc:`pair_style python <pair_python>`
The :doc:`python <python>` command which can be used to define and
execute a Python function that you write the code for. The Python
function can also be assigned to a LAMMPS python-style variable via
the :doc:`variable <variable>` command. Each time the variable is
The :doc:`python <python>` command can be used to define and execute a
Python function that you write the code for. The Python function can
also be assigned to a LAMMPS python-style variable via the
:doc:`variable <variable>` command. Each time the variable is
evaluated, either in the LAMMPS input script itself, or by another
LAMMPS command that uses the variable, this will trigger the Python
function to be invoked.
The Python function can also be referenced in the formula used to
define an :doc:`equal-style or atom-style variable <variable>`, using
the syntax for a :doc:`Python function wrapper <variable>`. This make
it easy to pass LAMMPS-related arguments to the Python function, as
well as to invoke it whenever the equal- or atom-style variable is
evaluated. For an atom-style variable it means the Python function
can be invoked once per atom, using per-atom properties as arguments
to the function.
The Python code for the function can be included directly in the input
script or in an auxiliary file. The function can have arguments which
are mapped to LAMMPS variables (also defined in the input script) and

View File

@ -92,6 +92,7 @@ Miscellaneous tools
* :ref:`LAMMPS coding standards <coding_standard>`
* :ref:`emacs <emacs>`
* :ref:`i-PI <ipi>`
* :ref:`JSON support <json>`
* :ref:`kate <kate>`
* :ref:`LAMMPS-GUI <lammps_gui>`
* :ref:`LAMMPS magic patterns for file(1) <magic>`
@ -364,7 +365,7 @@ These tools were provided by Aidan Thompson at Sandia
.. _fep:
fep tool
------------------
--------
The tools/fep directory contains Python scripts useful for
post-processing results from performing free-energy perturbation
@ -379,7 +380,7 @@ See README file in the tools/fep directory.
.. _ipi:
i-PI tool
-------------------
---------
.. versionchanged:: 27June2024
@ -432,6 +433,87 @@ tools/createatoms tool's input file.
----------
.. _json:
JSON support files
------------------
.. versionadded:: 12June2025
The ``tools/json`` directory contains files and tools to support
using `JSON format <https://www.json.org/>`_ files in LAMMPS.
Currently only the :doc:`molecule command <molecule>` supports
files in JSON format directly, but this is planned to be expanded
in the future.
JSON file validation
^^^^^^^^^^^^^^^^^^^^
The JSON syntax is independent of its content, and thus the data in the
file must follow suitable conventions to be correctly parsed during
input. This can be done in a portable fashion using a `JSON schema file
<https://json-schema.org/>`_ (which is in JSON format as well) to define
those conventions. A suitable JSON validator software can then validate
JSON files against the requirements. Validating a particular JSON file
against a schema ensures that both, the syntax *and* the conventions
are followed. This is useful when writing or editing JSON files in a
text editor or when writing a pre-processing script or tool to create
JSON files for a specific purpose in LAMMPS. It **cannot** check
whether the file contents are physically meaningful, though.
One such validator tool is `check-jsonschema
<https://check-jsonschema.readthedocs.io/>`_ which is written in Python
and can be installed using the `pip Python package manager
<https://pypi.org/>`_, best in a virtual environment as shown below (for
a Bourne Shell command line):
.. code-block:: sh
python -m venv validate-json
source validate-json/bin/activate
pip install --upgrade pip
pip install check-jsonschema
To validate a specific JSON file against a provided schema (here for
a :doc:`molecule command file <molecule>` you would then run for example:
.. code-block:: sh
check-jsonschema --schemafile molecule-schema.json tip3p.json
The latest schema files are also maintained and available for download
at https://download.lammps.org/json . This enables validation of JSON
files even if the LAMMPS sources are not locally available. Example:
.. code-block:: sh
check-jsonschema --schemafile https://download.lammps.org/json/molecule-schema.json tip3p.json
JSON file format normalization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are extensions to the strict JSON format that allow for comments
or ignore additional (dangling) commas. The ``reformat-json.cpp`` tool
will read JSON files in relaxed format, but write it out in strict format.
It is also possible to change the level of indentation from -1 (all data
one long line) to any positive integer value. The original file will be
backed up (.bak added to file name) and then overwritten.
Manual compilation (it will be automatically included in the CMake build
if building tools is requested during CMake configuration):
.. code-block:: sh
g++ -I <path/to/lammps/src> -o reformat-json reformat-json.cpp
Usage:
.. parsed-literal::
reformat-json <indent-width> <json-file-1> [<json-file-2> ...]
----------
.. _kate:
kate tool

View File

@ -53,15 +53,17 @@ The value *eng* is the interaction energy for the angle.
The value *v_name* can be used together with the *set* keyword to
compute a user-specified function of the angle theta. The *name*
specified for the *v_name* value is the name of an :doc:`equal-style variable <variable>` which should evaluate a formula based on a
specified for the *v_name* value is the name of an :doc:`equal-style
variable <variable>` which should evaluate a formula based on a
variable which will store the angle theta. This other variable must
be an :doc:`internal-style variable <variable>` defined in the input
script; its initial numeric value can be anything. It must be an
internal-style variable, because this command resets its value
directly. The *set* keyword is used to identify the name of this
other variable associated with theta.
be an :doc:`internal-style variable <variable>` specified by the *set*
keyword. It is an internal-style variable, because this command
resets its value directly. The internal-style variable does not need
to be defined in the input script (though it can be); if it is not
defined, then the *set* option creates an :doc:`internal-style
variable <variable>` with the specified name.
Note that the value of theta for each angle which stored in the
Note that the value of theta for each angle which is stored in the
internal variable is in radians, not degrees.
As an example, these commands can be added to the bench/in.rhodo
@ -70,7 +72,6 @@ system and output the statistics in various ways:
.. code-block:: LAMMPS
variable t internal 0.0
variable cos equal cos(v_t)
variable cossq equal cos(v_t)*cos(v_t)

View File

@ -130,13 +130,15 @@ moving apart.
The value *v_name* can be used together with the *set* keyword to
compute a user-specified function of the bond distance. The *name*
specified for the *v_name* value is the name of an :doc:`equal-style variable <variable>` which should evaluate a formula based on a
variable which will store the bond distance. This other variable must
be an :doc:`internal-style variable <variable>` defined in the input
script; its initial numeric value can be anything. It must be an
internal-style variable, because this command resets its value
directly. The *set* keyword is used to identify the name of this
other variable associated with theta.
specified for the *v_name* value is the name of an :doc:`equal-style
variable <variable>` which should evaluate a formula based on a
variable which stores the bond distance. This other variable must be
the :doc:`internal-style variable <variable>` specified by the *set*
keyword. It is an internal-style variable, because this command
resets its value directly. The internal-style variable does not need
to be defined in the input script (though it can be); if it is not
defined, then the *set* option creates an :doc:`internal-style
variable <variable>` with the specified name.
As an example, these commands can be added to the bench/in.rhodo
script to compute the length\ :math:`^2` of every bond in the system and
@ -144,7 +146,6 @@ output the statistics in various ways:
.. code-block:: LAMMPS
variable d internal 0.0
variable dsq equal v_d*v_d
compute 1 all property/local batom1 batom2 btype

View File

@ -45,30 +45,31 @@ interactions. The number of datums generated, aggregated across all
processors, equals the number of dihedral angles in the system, modified
by the group parameter as explained below.
The value *phi* (:math:`\phi`) is the dihedral angle, as defined in the diagram
on the :doc:`dihedral_style <dihedral_style>` doc page.
The value *phi* (:math:`\phi`) is the dihedral angle, as defined in
the diagram on the :doc:`dihedral_style <dihedral_style>` doc page.
The value *v_name* can be used together with the *set* keyword to compute a
user-specified function of the dihedral angle :math:`\phi`. The *name*
specified for the *v_name* value is the name of an
:doc:`equal-style variable <variable>` which should evaluate a formula based on
a variable which will store the angle :math:`\phi`. This other variable must
be an :doc:`internal-style variable <variable>` defined in the input
script; its initial numeric value can be anything. It must be an
internal-style variable, because this command resets its value
directly. The *set* keyword is used to identify the name of this
other variable associated with :math:`\phi`.
The value *v_name* can be used together with the *set* keyword to
compute a user-specified function of the dihedral angle :math:`\phi`.
The *name* specified for the *v_name* value is the name of an
:doc:`equal-style variable <variable>` which should evaluate a formula
based on a variable which will store the angle :math:`\phi`. This
other variable must be an :doc:`internal-style variable <variable>`
specified by the *set* keyword. It is an internal-style variable,
because this command resets its value directly. The internal-style
variable does not need to be defined in the input script (though it
can be); if it is not defined, then the *set* option creates an
:doc:`internal-style variable <variable>` with the specified name.
Note that the value of :math:`\phi` for each angle which stored in the internal
variable is in radians, not degrees.
Note that the value of :math:`\phi` for each angle which stored in the
internal variable is in radians, not degrees.
As an example, these commands can be added to the bench/in.rhodo
script to compute the :math:`\cos\phi` and :math:`\cos^2\phi` of every dihedral
angle in the system and output the statistics in various ways:
script to compute the :math:`\cos\phi` and :math:`\cos^2\phi` of every
dihedral angle in the system and output the statistics in various
ways:
.. code-block:: LAMMPS
variable p internal 0.0
variable cos equal cos(v_p)
variable cossq equal cos(v_p)*cos(v_p)
@ -100,10 +101,10 @@ no consistent ordering of the entries within the local vector or array
from one timestep to the next. The only consistency that is
guaranteed is that the ordering on a particular timestep will be the
same for local vectors or arrays generated by other compute commands.
For example, dihedral output from the
:doc:`compute property/local <compute_property_local>` command can be combined
with data from this command and output by the :doc:`dump local <dump>`
command in a consistent way.
For example, dihedral output from the :doc:`compute property/local
<compute_property_local>` command can be combined with data from this
command and output by the :doc:`dump local <dump>` command in a
consistent way.
Here is an example of how to do this:

View File

@ -416,24 +416,23 @@ atom, based on its coordinates. They apply to all styles except
*single*. The *name* specified for the *var* keyword is the name of
an :doc:`equal-style variable <variable>` that should evaluate to a
zero or non-zero value based on one or two or three variables that
will store the *x*, *y*, or *z* coordinates of an atom (one variable per
coordinate). If used, these other variables must be
:doc:`internal-style variables <variable>` defined in the input
script; their initial numeric value can be anything. They must be
internal-style variables, because this command resets their values
directly. The *set* keyword is used to identify the names of these
other variables, one variable for the *x*-coordinate of a created atom,
one for *y*, and one for *z*.
will store the *x*, *y*, or *z* coordinates of an atom (one variable
per coordinate). If used, these other variables must be specified by
the *set* keyword. They are internal-style variable, because this
command resets their values directly. The internal-style variables do
not need to be defined in the input script (though they can be); if
one (or more) is not defined, then the *set* option creates an
:doc:`internal-style variable <variable>` with the specified name.
.. figure:: img/sinusoid.jpg
:figwidth: 50%
:align: right
:target: _images/sinusoid.jpg
When an atom is created, its :math:`(x,y,z)` coordinates become the values for
any *set* variable that is defined. The *var* variable is then
evaluated. If the returned value is 0.0, the atom is not created. If
it is non-zero, the atom is created.
When an atom is about to be created, its :math:`(x,y,z)` coordinates
become the values for any *set* variable that is defined. The *var*
variable is then evaluated. If the returned value is 0.0, the atom is
not created. If it is non-zero, the atom is created.
As an example, these commands can be used in a 2d simulation, to
create a sinusoidal surface. Note that the surface is "rough" due to
@ -456,8 +455,6 @@ converts lattice spacings to distance.
region box block 0 $x 0 $y -0.5 0.5
create_box 1 box
variable xx internal 0.0
variable yy internal 0.0
variable v equal "(0.2*v_y*ylat * cos(v_xx/xlat * 2.0*PI*4.0/v_x) + 0.5*v_y*ylat - v_yy) > 0.0"
create_atoms 1 box var v set x xx set y yy
write_dump all atom sinusoid.lammpstrj

View File

@ -98,52 +98,53 @@ the following dynamic equation:
\frac{dc}{dt} = -\alpha (K_p e + K_i \int_0^t e \, dt + K_d \frac{de}{dt} )
where *c* is the continuous time analog of the control variable,
*e* =\ *pvar*\ -\ *setpoint* is the error in the process variable, and
:math:`\alpha`, :math:`K_p`, :math:`K_i` , and :math:`K_d` are constants
set by the corresponding
keywords described above. The discretized version of this equation is:
where *c* is the continuous time analog of the control variable, *e*
=\ *pvar*\ -\ *setpoint* is the error in the process variable, and
:math:`\alpha`, :math:`K_p`, :math:`K_i` , and :math:`K_d` are
constants set by the corresponding keywords described above. The
discretized version of this equation is:
.. math::
c_n = c_{n-1} -\alpha \left( K_p \tau e_n + K_i \tau^2 \sum_{i=1}^n e_i + K_d (e_n - e_{n-1}) \right)
where :math:`\tau = \mathtt{Nevery} \cdot \mathtt{timestep}` is the time
interval between updates,
and the subscripted variables indicate the values of *c* and *e* at
successive updates.
where :math:`\tau = \mathtt{Nevery} \cdot \mathtt{timestep}` is the
time interval between updates, and the subscripted variables indicate
the values of *c* and *e* at successive updates.
From the first equation, it is clear that if the three gain values
:math:`K_p`, :math:`K_i`, :math:`K_d` are dimensionless constants,
then :math:`\alpha` must have
units of [unit *cvar*\ ]/[unit *pvar*\ ]/[unit time] e.g. [ eV/K/ps
]. The advantage of this unit scheme is that the value of the
constants should be invariant under a change of either the MD timestep
size or the value of *Nevery*\ . Similarly, if the LAMMPS :doc:`unit style <units>` is changed, it should only be necessary to change
the value of :math:`\alpha` to reflect this, while leaving :math:`K_p`,
:math:`K_i`, and :math:`K_d` unaltered.
then :math:`\alpha` must have units of [unit *cvar*\ ]/[unit *pvar*\
]/[unit time] e.g. [ eV/K/ps ]. The advantage of this unit scheme is
that the value of the constants should be invariant under a change of
either the MD timestep size or the value of *Nevery*\ . Similarly, if
the LAMMPS :doc:`unit style <units>` is changed, it should only be
necessary to change the value of :math:`\alpha` to reflect this, while
leaving :math:`K_p`, :math:`K_i`, and :math:`K_d` unaltered.
When choosing the values of the four constants, it is best to first
pick a value and sign for :math:`\alpha` that is consistent with the
magnitudes and signs of *pvar* and *cvar*\ . The magnitude of :math:`K_p`
should then be tested over a large positive range keeping :math:`K_i = K_d =0`.
A good value for :math:`K_p` will produce a fast response in *pvar*,
without overshooting the *setpoint*\ . For many applications, proportional
feedback is sufficient, and so :math:`K_i = K_d =0` can be used. In cases
where there is a substantial lag time in the response of *pvar* to a change
in *cvar*, this can be counteracted by increasing :math:`K_d`. In situations
magnitudes and signs of *pvar* and *cvar*\ . The magnitude of
:math:`K_p` should then be tested over a large positive range keeping
:math:`K_i = K_d =0`. A good value for :math:`K_p` will produce a
fast response in *pvar*, without overshooting the *setpoint*\ . For
many applications, proportional feedback is sufficient, and so
:math:`K_i = K_d =0` can be used. In cases where there is a
substantial lag time in the response of *pvar* to a change in *cvar*,
this can be counteracted by increasing :math:`K_d`. In situations
where *pvar* plateaus without reaching *setpoint*, this can be
counteracted by increasing :math:`K_i`. In the language of Charles Dickens,
:math:`K_p` represents the error of the present, :math:`K_i` the error of
the past, and :math:`K_d` the error yet to come.
counteracted by increasing :math:`K_i`. In the language of Charles
Dickens, :math:`K_p` represents the error of the present, :math:`K_i`
the error of the past, and :math:`K_d` the error yet to come.
Because this fix updates *cvar*, but does not initialize its value,
the initial value :math:`c_0` is that assigned by the user in the input script via
the :doc:`internal-style variable <variable>` command. This value is
used (by every other LAMMPS command that uses the variable) until this
fix performs its first update of *cvar* after *Nevery* timesteps. On
the first update, the value of the derivative term is set to zero,
because the value of :math:`e_{n-1}` is not yet defined.
the initial value :math:`c_0` is that assigned by the user in the
input script via the :doc:`internal-style variable <variable>`
command. This value is used (by every other LAMMPS command that uses
the variable) until this fix performs its first update of *cvar* after
*Nevery* timesteps. On the first update, the value of the derivative
term is set to zero, because the value of :math:`e_{n-1}` is not yet
defined.
----------
@ -154,21 +155,23 @@ must produce a global quantity, not a per-atom or local quantity.
If *pvar* begins with "c\_", a compute ID must follow which has been
previously defined in the input script and which generates a global
scalar or vector. See the individual :doc:`compute <compute>` doc page
for details. If no bracketed integer is appended, the scalar
scalar or vector. See the individual :doc:`compute <compute>` doc
page for details. If no bracketed integer is appended, the scalar
calculated by the compute is used. If a bracketed integer is
appended, the Ith value of the vector calculated by the compute is
used. Users can also write code for their own compute styles and :doc:`add them to LAMMPS <Modify>`.
used. Users can also write code for their own compute styles and
:doc:`add them to LAMMPS <Modify>`.
If *pvar* begins with "f\_", a fix ID must follow which has been
previously defined in the input script and which generates a global
scalar or vector. See the individual :doc:`fix <fix>` page for
details. Note that some fixes only produce their values on certain
timesteps, which must be compatible with when fix controller
references the values, or else an error results. If no bracketed integer
is appended, the scalar calculated by the fix is used. If a bracketed
integer is appended, the Ith value of the vector calculated by the fix
is used. Users can also write code for their own fix style and :doc:`add them to LAMMPS <Modify>`.
references the values, or else an error results. If no bracketed
integer is appended, the scalar calculated by the fix is used. If a
bracketed integer is appended, the Ith value of the vector calculated
by the fix is used. Users can also write code for their own fix style
and :doc:`add them to LAMMPS <Modify>`.
If *pvar* begins with "v\_", a variable name must follow which has been
previously defined in the input script. Only equal-style variables
@ -182,19 +185,21 @@ variable.
The target value *setpoint* for the process variable must be a numeric
value, in whatever units *pvar* is defined for.
The control variable *cvar* must be the name of an :doc:`internal-style variable <variable>` previously defined in the input script. Note
that it is not specified with a "v\_" prefix, just the name of the
variable. It must be an internal-style variable, because this fix
updates its value directly. Note that other commands can use an
equal-style versus internal-style variable interchangeably.
The control variable *cvar* must be the name of an
:doc:`internal-style variable <variable>` previously defined in the
input script. Note that it is not specified with a "v\_" prefix, just
the name of the variable. It must be an internal-style variable,
because this fix updates its value directly. Note that other commands
can use an equal-style versus internal-style variable interchangeably.
----------
Restart, fix_modify, output, run start/stop, minimize info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Currently, no information about this fix is written to :doc:`binary restart files <restart>`. None of the :doc:`fix_modify <fix_modify>` options
are relevant to this fix.
Currently, no information about this fix is written to :doc:`binary
restart files <restart>`. None of the :doc:`fix_modify <fix_modify>`
options are relevant to this fix.
This fix produces a global vector with 3 values which can be accessed
by various :doc:`output commands <Howto_output>`. The values can be
@ -211,7 +216,8 @@ variable is in. The vector values calculated by this fix are
"extensive".
No parameter of this fix can be used with the *start/stop* keywords of
the :doc:`run <run>` command. This fix is not invoked during :doc:`energy minimization <minimize>`.
the :doc:`run <run>` command. This fix is not invoked during
:doc:`energy minimization <minimize>`.
Restrictions
""""""""""""

View File

@ -225,22 +225,25 @@ rotated configuration of the molecule.
.. versionadded:: 21Nov2023
The *var* and *set* keywords can be used together to provide a criterion
for accepting or rejecting the addition of an individual atom, based on its
coordinates. The *name* specified for the *var* keyword is the name of an
:doc:`equal-style variable <variable>` that should evaluate to a zero or
non-zero value based on one or two or three variables that will store the
*x*, *y*, or *z* coordinates of an atom (one variable per coordinate). If
used, these other variables must be :doc:`internal-style variables
<variable>` defined in the input script; their initial numeric value can be
anything. They must be internal-style variables, because this command
resets their values directly. The *set* keyword is used to identify the
names of these other variables, one variable for the *x*-coordinate of a
created atom, one for *y*, and one for *z*. When an atom is created, its
:math:`(x,y,z)` coordinates become the values for any *set* variable that
is defined. The *var* variable is then evaluated. If the returned value
is 0.0, the atom is not created. If it is non-zero, the atom is created.
For an example of how to use these keywords, see the
The *var* and *set* keywords can be used together to provide a
criterion for accepting or rejecting the addition of an individual
atom, based on its coordinates. The *name* specified for the *var*
keyword is the name of an :doc:`equal-style variable <variable>` that
should evaluate to a zero or non-zero value based on one or two or
three variables that will store the *x*, *y*, or *z* coordinates of an
atom (one variable per coordinate). If used, these other variables
must be :doc:`internal-style variables <variable>` specified by the
*set* keyword. They must be internal-style variables, because this
command resets their values directly. The internal-style variables do
not need to be defined in the input script (though they can be); if
one (or more) is not defined, then the *set* option creates an
:doc:`internal-style variable <variable>` with the specified name.
When an atom is about to be created, its :math:`(x,y,z)` coordinates
become the values for any *set* variable that is defined. The *var*
variable is then evaluated. If the returned value is 0.0, the atom is
not created. If it is non-zero, the atom is created. For an example
of how to use the set/var keywords in a similar context, see the
:doc:`create_atoms <create_atoms>` command.
The *rate* option moves the insertion volume in the z direction (3d)
@ -304,12 +307,13 @@ units of distance or velocity.
Restart, fix_modify, output, run start/stop, minimize info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
This fix writes the state of the deposition to :doc:`binary restart files <restart>`. This includes information about how many
particles have been deposited, the random number generator seed, the
next timestep for deposition, etc. See the
:doc:`read_restart <read_restart>` command for info on how to re-specify
a fix in an input script that reads a restart file, so that the
operation of the fix continues in an uninterrupted fashion.
This fix writes the state of the deposition to :doc:`binary restart
files <restart>`. This includes information about how many particles
have been deposited, the random number generator seed, the next
timestep for deposition, etc. See the :doc:`read_restart
<read_restart>` command for info on how to re-specify a fix in an
input script that reads a restart file, so that the operation of the
fix continues in an uninterrupted fashion.
.. note::

View File

@ -32,6 +32,7 @@
.. index:: kspace_style msm/cg/omp
.. index:: kspace_style msm/dielectric
.. index:: kspace_style scafacos
.. index:: kspace_style zero
kspace_style command
====================
@ -43,7 +44,7 @@ Syntax
kspace_style style value
* style = *none* or *ewald* or *ewald/dipole* or *ewald/dipole/spin* or *ewald/disp* or *ewald/disp/dipole* or *ewald/omp* or *ewald/electrode* or *pppm* or *pppm/cg* or *pppm/disp* or *pppm/tip4p* or *pppm/stagger* or *pppm/disp/tip4p* or *pppm/gpu* or *pppm/intel* or *pppm/disp/intel* or *pppm/kk* or *pppm/omp* or *pppm/cg/omp* or *pppm/disp/tip4p/omp* or *pppm/tip4p/omp* or *pppm/dielectic* or *pppm/disp/dielectric* or *pppm/electrode* or *pppm/electrode/intel* or *msm* or *msm/cg* or *msm/omp* or *msm/cg/omp* or *msm/dielectric* or *scafacos*
* style = *none* or *ewald* or *ewald/dipole* or *ewald/dipole/spin* or *ewald/disp* or *ewald/disp/dipole* or *ewald/omp* or *ewald/electrode* or *pppm* or *pppm/cg* or *pppm/disp* or *pppm/tip4p* or *pppm/stagger* or *pppm/disp/tip4p* or *pppm/gpu* or *pppm/intel* or *pppm/disp/intel* or *pppm/kk* or *pppm/omp* or *pppm/cg/omp* or *pppm/disp/tip4p/omp* or *pppm/tip4p/omp* or *pppm/dielectic* or *pppm/disp/dielectric* or *pppm/electrode* or *pppm/electrode/intel* or *msm* or *msm/cg* or *msm/omp* or *msm/cg/omp* or *msm/dielectric* or *scafacos* or *zero*
.. parsed-literal::
@ -121,6 +122,7 @@ Syntax
*scafacos* values = method accuracy
method = fmm or p2nfft or p3m or ewald or direct
accuracy = desired relative error in forces
*zero* value = none
Examples
""""""""
@ -132,6 +134,7 @@ Examples
kspace_style msm 1.0e-4
kspace_style scafacos fmm 1.0e-4
kspace_style none
kspace_style zero
Used in input scripts:
@ -375,6 +378,13 @@ other ScaFaCoS options currently exposed to LAMMPS.
----------
.. versionadded:: 12Jun2025
The *zero* style does not do any calculations, but is compatible
with all pair styles that require some version of a kspace style.
----------
The specified *accuracy* determines the relative RMS error in per-atom
forces calculated by the long-range solver. It is set as a
dimensionless number, relative to the force that two unit point

View File

@ -34,7 +34,7 @@ Syntax
*ioff* value = Ioff
Ioff = offset to add to improper types
*scale* value = sfactor
sfactor = scale factor to apply to the size and mass of the molecule
sfactor = scale factor to apply to the size, mass, and dipole of the molecule
Examples
""""""""
@ -42,6 +42,7 @@ Examples
.. code-block:: LAMMPS
molecule 1 mymol.txt
molecule water tip3p.json
molecule 1 co2.txt h2o.txt
molecule CO2 co2.txt boff 3 aoff 2
molecule 1 mymol.txt offset 6 9 18 23 14
@ -65,7 +66,7 @@ templates include:
* :doc:`atom_style template <atom_style>`
The ID of a molecule template can only contain alphanumeric characters
and underscores.
and underscores, same as other IDs in LAMMPS.
A single template can contain multiple molecules, listed one per file.
Some of the commands listed above currently use only the first
@ -74,6 +75,11 @@ contains multiple molecules. The :doc:`atom_style template
<atom_style>` command allows multiple-molecule templates to define a
system with more than one templated molecule.
The molecule file can be either in a *native* format or in `JSON format
<https://www.json.org/>`_. The details of the two formats are described
below. When referencing multiple molecule files in a single *molecule*
command, each of those files may be either format.
Each filename can be followed by optional keywords which are applied
only to the molecule in the file as used in this template. This is to
make it easy to use the same molecule file in different molecule
@ -95,40 +101,45 @@ use that attribute (e.g. no bonds).
labels will determine the actual types directly depending on the
current :doc:`labelmap <labelmap>` settings.
The *scale* keyword scales the size of the molecule. This can be
useful for modeling polydisperse granular rigid bodies. The scale
factor is applied to each of these properties in the molecule file, if
they are defined: the individual particle coordinates (Coords
section), the individual mass of each particle (Masses section), the
individual diameters of each particle (Diameters section), the total
mass of the molecule (header keyword = mass), the center-of-mass of
the molecule (header keyword = com), and the moments of inertia of the
molecule (header keyword = inertia).
The *scale* keyword scales the size of the molecule. This can be useful
for modeling polydisperse granular rigid bodies. The scale factor is
applied to each of these properties in the molecule file, if they are
defined: the individual particle coordinates (Coords or "coords"
section), the individual mass of each particle (Masses or "masses"
section), the individual diameters of each particle (Diameters or
"diameters" section), the per-atom dipoles (Dipoles or "dipoles"
section) the total mass of the molecule (header keyword = mass), the
center-of-mass of the molecule (header keyword = com), and the moments
of inertia of the molecule (header keyword = inertia).
.. note::
The molecule command can be used to define molecules with bonds,
angles, dihedrals, impropers, or special bond lists of neighbors
angles, dihedrals, impropers, and special bond lists of neighbors
within a molecular topology, so that you can later add the molecules
to your simulation, via one or more of the commands listed above.
Since this topology-related information requires that suitable storage
is reserved when LAMMPS creates the simulation box (e.g. when using
the :doc:`create_box <create_box>` command or the
:doc:`read_data <read_data>` command) suitable space has to be reserved
so you do not overflow those pre-allocated data structures when adding
molecules later. Both the :doc:`create_box <create_box>` command and
the :doc:`read_data <read_data>` command have "extra" options which
ensure space is allocated for storing topology info for molecules that
are added later.
Since this topology-related information requires that suitable
storage is reserved when LAMMPS creates the simulation box (e.g. when
using the :doc:`create_box <create_box>` command or the
:doc:`read_data <read_data>` command) suitable space has to be
reserved at that step so you do not overflow those pre-allocated data
structures when adding molecules later. Both the :doc:`create_box
<create_box>` command and the :doc:`read_data <read_data>` command
have "extra" options which ensure extra space is allocated for
storing topology info for molecules that are added later. This
feature is *not* available for the :doc:`read_restart command
<read_restart>`, thus binary restart files need to be converted
to data files first.
----------
Format of a molecule file
"""""""""""""""""""""""""
Format of a native molecule file
""""""""""""""""""""""""""""""""
The format of an individual molecule file looks similar but is
different than that of a data file read by the :doc:`read_data <read_data>`
commands. Here is a simple example for a TIP3P water molecule:
The format of an "native" individual molecule file looks similar but is
*different* from that of a data file read by the :doc:`read_data
<read_data>` commands. Here is a simple example for a TIP3P water
molecule:
.. code-block::
@ -669,6 +680,189 @@ the file format.
----------
Format of a JSON molecule file
""""""""""""""""""""""""""""""
The format of a JSON format individual molecule file must follow the
`JSON format <https://www.json.org/>`_, which evolved from the
JavaScript programming language as a programming-language-neutral data
interchange language. The JSON syntax is independent of its content,
and thus the data in the file must follow suitable conventions to be
correctly processed. LAMMPS provides a `JSON schema file
<https://json-schema.org/>`_ for JSON format molecule files in the
:ref:`tools/json folder <json>` to represent those conventions. Using
the schema file any JSON format molecule files can be validated.
Validating a particular JSON format molecule file against this schema
ensures that both, the JSON syntax requirement *and* the LAMMPS
conventions for molecule templates are followed. This is a formal check
only and thus it **cannot** check whether the file contents are
physically meaningful.
Here is a simple example for the same TIP3P water molecule from above in
JSON format and also using :doc:`type labels <labelmap>` instead of
numeric types:
.. code-block:: json
{
"application": "LAMMPS",
"format": "molecule",
"revision": 1,
"title": "Water molecule. TIP3P geometry",
"schema": "https://download.lammps.org/json/molecule-schema.json",
"units": "real",
"coords": {
"format": ["atom-id", "x", "y", "z"],
"data": [
[1, 0.00000, -0.06556, 0.00000],
[2, 0.75695, 0.52032, 0.00000],
[3, -0.75695, 0.52032, 0.00000]
]
},
"types": {
"format": ["atom-id", "type"],
"data": [
[1, "OW"],
[2, "HO1"],
[3, "HO1"]
]
},
"charges": {
"format": ["atom-id", "charge"],
"data": [
[1, -0.834],
[2, 0.417],
[3, 0.417]
]
},
"bonds": {
"format": ["bond-type", "atom1", "atom2"],
"data": [
["OW-HO1", 1, 2],
["OW-HO1", 1, 3]
]
},
"angles": {
"format": ["angle-type", "atom1", "atom2", "atom3"],
"data": [
["HO1-OW-HO1", 2, 1, 3]
]
}
}
Unlike with the native molecule file format, there are no header or body
sections, just a list of keywords with associated data. JSON format
data is read, parsed, and stored in an internal dictionary data
structure in one step and thus the order of keywords is not relevant.
Data for keywords is either provided directly following the keyword or
as a *data block*. A *data block* is a list that has to include two
keywords, "format" and "data", where the former lists keywords of the
properties that are stored in the columns of the "data" lists. The
names and order of entries in the "format" list (and thus how the data
is interpreted) are currently fixed.
Since the length of the various lists can be easily obtained from the
internal data structure, several header keywords of the "native" molecule
file are not needed. On the other hand, some additional keywords are
required to identify the conventions applied to the generic JSON file
format. The structure of the data itself mostly follows what is used
for the "native" molecule file format.
.. list-table::
:header-rows: 1
* - Keyword
- Argument(s)
- Required
- Description
* - application
- "LAMMPS"
- yes
- indicates a LAMMPS JSON file; files from other applications may be accepted in the future
* - format
- "molecule"
- yes
- indicates a molecule template file
* - revision
- an integer
- yes
- currently 1, to facility backward compatibility on changes to the conventions
* - title
- a string
- no
- information about the template which will echoed to the screen and log
* - schema
- URL as string
- no
- location of a JSON schema file for validating the molecule file format
* - units
- a string
- no
- indicates :doc:`units settings <units>` for this molecule template
* - com
- list with 3 doubles
- no
- overrides the auto-computed center-of-mass for the template
* - masstotal
- double
- no
- overrides the auto-computed total mass for the template
* - inertia
- list with 6 doubles
- no
- overrides the auto-computed moments of inertia
* - coords
- a data block
- no
- contains atom positions with the format "atom-id", "x", "y", "z" (same as Coords)
* - types
- a data block
- yes
- assigns atom types to atoms with the format "atom-id", "type" (same as Types)
* - molecule
- a data block
- no
- assigns molecule-IDs to atoms with the format "atom-id", "molecule-id" (same as Molecules)
* - fragments
- a data block
- no
- assigns atom-ids to fragment-IDs with the format "fragment-id", "atom-id-list" (same as Fragments)
* - charges
- a data block
- no
- assigns charges to atoms with the format "atom-id", "charge" (same as Charges)
* - dipoles
- a data block
- no
- assigns point dipoles to atoms with the format "atom-id", "mux", "muy", "muz" (same as Dipoles)
* - diameters
- a data block
- no
- assigns diameters to atoms with the format "atom-id", "diameter" (same as Diameters)
* - masses
- a data block
- no
- assigns per-atom masses to atoms with the format "atom-id", "mass" (same as Masses)
* - bonds
- a data block
- no
- defines bonds in the molecule template with the format "bond-type", "atom1", "atom2" (same as Bonds without bond-ID)
* - angles
- a data block
- no
- defines angles in the molecule template with the format "angle-type", "atom1", "atom2", "atom3" (same as Angles without angle-ID)
* - dihedrals
- a data block
- no
- defines dihedrals in the molecule template with the format "dihedral-type", "atom1", "atom2", "atom3", "atom4" (same as Dihedrals without dihedral-ID)
* - impropers
- a data block
- no
- defines impropers in the molecule template with the format "improper-type", "atom1", "atom2", "atom3", "atom4" (same as Impropers without improper-ID)
----------
Restrictions
""""""""""""

View File

@ -10,16 +10,17 @@ Syntax
plugin command args
* command = *load* or *unload* or *list* or *clear*
* command = *load* or *unload* or *list* or *clear* or *restore*
* args = list of arguments for a particular plugin command
.. parsed-literal::
*load* file = load plugin(s) from shared object in *file*
*unload* style name = unload plugin *name* of style *style*
*style* = *pair* or *bond* or *angle* or *dihedral* or *improper* or *kspace* or *compute* or *fix* or *region* or *command*
*style* = *pair* or *bond* or *angle* or *dihedral* or *improper* or *kspace* or *compute* or *fix* or *region* or *command* or *run* or *min*
*list* = print a list of currently loaded plugins
*clear* = unload all currently loaded plugins
*restore* = restore all loaded plugins
Examples
""""""""
@ -31,6 +32,7 @@ Examples
plugin unload command hello
plugin list
plugin clear
plugin restore
Description
"""""""""""
@ -40,22 +42,46 @@ commands into a LAMMPS binary from so-called dynamic shared object (DSO)
files. This enables to add new functionality to an existing LAMMPS
binary without having to recompile and link the entire executable.
.. admonition:: Plugins are a global, per-executable property
:class: Hint
Unlike most settings in LAMMPS, plugins are a per-executable global
property. Loading a plugin means that it is not only available for
the current LAMMPS instance but for all *future* LAMMPS instances.
After a :doc:`clear <clear>` command, all currently loaded plugins
will be restored and do not need to be loaded again.
When using the library interface or the Python or Fortran module
to create multiple concurrent LAMMPS instances, all plugins should
be loaded by the first created LAMMPS instance as all future instances
will inherit them. To import plugins that were loaded by a different
LAMMPS instance, use the *restore* command.
The *load* command will load and initialize all plugins contained in the
plugin DSO with the given filename. A message with information the
plugin style and name and more will be printed. Individual DSO files
may contain multiple plugins. More details about how to write and
plugin DSO with the given filename. A message with information about
the plugin style and name and more will be printed. Individual DSO
files may contain multiple plugins. If a plugin is already loaded
it will be skipped. More details about how to write and
compile the plugin DSO is given in programmer's guide part of the manual
under :doc:`Developer_plugins`.
The *unload* command will remove the given style or the given name from
the list of available styles. If the plugin style is currently in use,
that style instance will be deleted.
that style instance will be deleted and replaced by the default setting
for that style.
The *list* command will print a list of the loaded plugins and their
styles and names.
The *clear* command will unload all currently loaded plugins.
.. versionadded:: 12Jun2025
The *restore* command will restore all currently loaded plugins.
This allows to "import" plugins into a different LAMMPS instance.
.. admonition:: Automatic loading of plugins
:class: note
@ -79,7 +105,7 @@ If plugins access functions or classes from a package,
LAMMPS must have been compiled with that package included.
Plugins are dependent on the LAMMPS binary interface (ABI)
and particularly the MPI library used. So they are not guaranteed
and particularly the MPI library used. So they are not guaranteed
to work when the plugin was compiled with a different MPI library
or different compilation settings or a different LAMMPS version.
There are no checks, so if there is a mismatch the plugin object

View File

@ -10,7 +10,7 @@ Syntax
python mode keyword args ...
* mode = *source* or name of Python function
* mode = *source* or *name* of Python function
if mode is *source*:
@ -18,35 +18,39 @@ Syntax
keyword = *here* or name of a *Python file*
*here* arg = inline
inline = one or more lines of Python code which defines func
inline = one or more lines of Python code which will be executed immediately
must be a single argument, typically enclosed between triple quotes
*Python file* = name of a file with Python code which will be executed immediately
* if *mode* is the name of a Python function, one or more keywords with/without arguments must be appended
* if *mode* is *name* of a Python function:
.. parsed-literal::
one or more keywords with/without arguments must be appended
keyword = *invoke* or *input* or *return* or *format* or *length* or *file* or *here* or *exists*
*invoke* arg = none = invoke the previously defined Python function
*invoke* arg = logreturn (optional)
invoke the previously-defined Python function
if logreturn is specified, print the return value of the invoked function to the screen and logfile
*input* args = N i1 i2 ... iN
N = # of inputs to function
i1,...,iN = value, SELF, or LAMMPS variable name
value = integer number, floating point number, or string
SELF = reference to LAMMPS itself which can be accessed by Python function
variable = v_name, where name = name of LAMMPS variable, e.g. v_abc
SELF = reference to LAMMPS itself which can then be accessed by Python function
variable = v_name, where name = name of a LAMMPS variable, e.g. v_abc
internal variable = iv_name, where name = name of a LAMMPS internal-style variable, e.g. iv_xyz
*return* arg = varReturn
varReturn = v_name = LAMMPS variable name which the return value of the Python function will be assigned to
*format* arg = fstring with M characters
M = N if no return value, where N = # of inputs
M = N+1 if there is a return value
fstring = each character (i,f,s,p) corresponds in order to an input or return value
'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF
fstring = each character (i,f,s,p) corresponds (in order) to an input or return value
'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF
*length* arg = Nlen
Nlen = max length of string returned from Python function
*file* arg = filename
filename = file of Python code, which defines func
filename = file of Python code, which defines the Python function
*here* arg = inline
inline = one or more lines of Python code which defines func
inline = one or more lines of Python code which defines the Python function
must be a single argument, typically enclosed between triple quotes
*exists* arg = none = Python code has been loaded by previous python command
@ -56,7 +60,7 @@ Examples
.. code-block:: LAMMPS
python pForce input 2 v_x 20.0 return v_f format fff file force.py
python pForce invoke
python pForce invoke logreturn
python factorial input 1 myN return v_fac format ii here """
def factorial(n):
@ -87,75 +91,149 @@ Examples
Description
"""""""""""
The *python* command allows interfacing LAMMPS with an embedded Python
interpreter and enables either executing arbitrary python code in that
interpreter, registering a Python function for future execution (as a
python style variable, from a fix interfaced with python, or for direct
invocation), or invoking such a previously registered function.
The *python* command interfaces LAMMPS with an embedded Python
interpreter and enables executing arbitrary python code in that
interpreter. This can be done immediately, by using *mode* = *source*.
Or execution can be deferred, by registering a Python function for later
execution, by using *mode* = *name* of a Python function.
Arguments, including LAMMPS variables, can be passed to the function
from the LAMMPS input script and a value returned by the Python function
assigned to a LAMMPS variable. The Python code for the function can be included
directly in the input script or in a separate Python file. The function
can be standard Python code or it can make "callbacks" to LAMMPS through
its library interface to query or set internal values within LAMMPS.
This is a powerful mechanism for performing complex operations in a
LAMMPS input script that are not possible with the simple input script
and variable syntax which LAMMPS defines. Thus your input script can
operate more like a true programming language.
Later execution can be triggered in one of two ways. One is to use the
python command again with its *invoke* keyword. The other is to trigger
the evaluation of a python-style, equal-style, vector-style, or
atom-style variable. A python-style variable invokes its associated
Python function; its return value becomes the value of the python-style
variable. Equal-, vector-, and atom-style variables can use a Python
function wrapper in their formulas which encodes the python-style
variable name, and specifies arguments (which themselves can be numeric
formulas) to pass to the Python function associated with the
python-style variable.
As explained on the :doc:`variable <variable>` doc page, the definition
of a python-style variable associates a Python function name with the
variable. Its specification must match the *mode* argument of the
*python* command for the Python function name. For example these two
commands would be consistent:
.. code-block:: LAMMPS
variable foo python myMultiply
python myMultiply return v_foo format f file funcs.py
The two commands can appear in either order in the input script so long
as both are specified before the Python function is invoked for the
first time.
Note that python-style, equal-style, vector-style, and atom-style
variables can be used in many different ways within LAMMPS. They can be
evaluated directly in an input script, effectively replacing the
variable with its value. Or they can be passed to various commands as
arguments, so that the variable is evaluated multiple times during a
simulation run. See the :doc:`variable <variable>` command doc page for
more details on variable styles which enable Python function evaluation.
The Python code for a Python function can be included directly in the
input script or in a separate Python file. The function can be standard
Python code or it can make "callbacks" to LAMMPS through its library
interface to query or set internal values within LAMMPS. This is a
powerful mechanism for performing complex operations in a LAMMPS input
script that are not possible with the simple input script and variable
syntax which LAMMPS defines. Thus your input script can operate more
like a true programming language.
Use of this command requires building LAMMPS with the PYTHON package
which links to the Python library so that the Python interpreter is
embedded in LAMMPS. More details about this process are given below.
There are two ways to invoke a Python function once it has been
registered. One is using the *invoke* keyword. The other is to assign
the function to a :doc:`python-style variable <variable>` defined in
your input script. Whenever the variable is evaluated, it will execute
the Python function to assign a value to the variable. Note that
variables can be evaluated in many different ways within LAMMPS. They
can be substituted with their result directly in an input script, or
they can be passed to various commands as arguments, so that the
variable is evaluated during a simulation run.
A broader overview of how Python can be used with LAMMPS is given in the
:doc:`Use Python with LAMMPS <Python_head>` section of the
documentation. There also is an ``examples/python`` directory which
documentation. There is also an ``examples/python`` directory which
illustrates use of the python command.
----------
The first argument of the *python* command is either the *source*
keyword or the name of a Python function. This defines the mode
of the python command.
The first argument to the *python* command is the *mode* setting, which
is either *source* or the *name* of a Python function.
.. versionchanged:: 22Dec2022
If the *source* keyword is used, it is followed by either a file name or
the *here* keyword. No other keywords can be used. The *here* keyword
is followed by a string with python commands, either on a single line
enclosed in quotes, or as multiple lines enclosed in triple quotes.
These Python commands will be passed to the python interpreter and
executed immediately without registering a Python function for future
execution. The code will be loaded into and run in the "main" module of
the Python interpreter. This allows running arbitrary Python code at
any time while processing the LAMMPS input file. This can be used to
pre-load Python modules, initialize global variables, define functions
or classes, or perform operations using the python programming language.
The Python code will be executed in parallel on all MPI processes. No
arguments can be passed.
If *source* is used, it is followed by either the *here* keyword or a
file name containing Python code. The *here* keyword is followed by a
single *inline* argument which is a string containing one or more python
commands. The string can either be on the same line as the *python*
command, enclosed in quotes, or it can be multiple lines enclosed in
triple quotes.
In all other cases, the first argument is the name of a Python function
that will be registered with LAMMPS for future execution. The function
may already be defined (see *exists* keyword) or must be defined using
the *file* or *here* keywords as explained below.
In either case, the in-line code or the file contents are passed to the
python interpreter and executed immediately. The code will be loaded
into and run in the "main" module of the Python interpreter. This
allows running arbitrary Python code at any time while processing the
LAMMPS input file. This can be used to pre-load Python modules,
initialize global variables, define functions or classes, or perform
operations using the Python programming language. The Python code will
be executed in parallel on all the MPI processes being used to run
LAMMPS. Note that no arguments can be passed to the executed Python
code.
If the *invoke* keyword is used, no other keywords can be used, and a
If the *mode* setting is the *name* of a Python function, then it will
be registered with LAMMPS for future execution (or can already be
defined, see the *exists* keyword). One or more keywords must follow
the *mode* function name. One of the keywords must be *invoke*, *file*,
*here*, or *exists*, which specifies what Python code to load into the
Python interpreter. Note that only one of those 4 keywords is allowed
since their operations are mutually exclusive.
----------
If the *invoke* keyword is used, no other keywords can be used. A
previous *python* command must have registered the Python function
referenced by this command. This invokes the Python function with the
previously defined arguments and the return value is processed as
explained below. You can invoke the function as many times as you wish
in your input script.
referenced by this command, which can then be invoked multiple times in
an input script via the *invoke* keyword. Each invocation passes
current values for arguments to the Python function. A return value of
the Python function will be ignored unless the Python function is linked
to a :doc:`python style variable <variable>` with the *return* keyword.
This return value can be logged to the screen and logfile by adding the
optional *logreturn* argument to the *invoke* keyword. In that case a
message with the name of the python command and the return value is
printed. Note that return values of python functions are otherwise
*only* accessible when the function is invoked indirectly by evaluating
its associated :doc:`python style variable <variable>`, as described
below.
The *file* keyword gives the name of a file containing Python code,
which should end with a ".py" suffix. The code will be immediately
loaded into and run in the "main" module of the Python interpreter. The
Python code will be executed in parallel on all MPI processes. Note
that Python code which contains a function definition does NOT "execute"
the function when it is run; it simply defines the function so that it
can be invoked later.
The *here* keyword does the same thing, except that the Python code
follows as a single argument to the *here* keyword. This can be done
using triple quotes as delimiters, as in the examples above and below.
This allows Python code to be listed verbatim in your input script, with
proper indentation, blank lines, and comments, as desired. See the
:doc:`Commands parse <Commands_parse>` doc page, for an explanation of
how triple quotes can be used as part of input script syntax.
The *exists* keyword takes no argument. It simply means that Python
code containing the needed Python function has already been loaded into
the LAMMPS Python interpreter, for example by previous *python source*
command or in a file that was loaded previously with the *file*
keyword. This allows use of a single file of Python code which contains
multiple functions, any of which can be used in the same (or different)
input scripts (see below).
Note that the Python code that is loaded and run by the *file* or *here*
keyword must contain a function with the specified function *name*. To
operate properly when the function is later invoked, the code for the
function must match the *input* and *return* and *format* keywords
specified by the python command. Otherwise Python will generate an
error.
----------
The other keywords which can be used with the *python* command are
*input*, *return*, *format*, and *length*.
The *input* keyword defines how many arguments *N* the Python function
expects. If it takes no arguments, then the *input* keyword should not
@ -169,35 +247,63 @@ itself using the :doc:`LAMMPS Python module <Python_module>`. This
enables the function to call back to LAMMPS through its library
interface as explained below. This allows the Python function to query
or set values internal to LAMMPS which can affect the subsequent
execution of the input script. A LAMMPS variable can also be used as an
argument, specified as v_name, where "name" is the name of the variable.
Any style of LAMMPS variable returning a scalar or a string can be used,
as defined by the :doc:`variable <variable>` command. The *format*
keyword must be used to set the type of data that is passed to Python.
Each time the Python function is invoked, the LAMMPS variable is
evaluated and its value is passed to the Python function.
execution of the input script.
A LAMMPS variable can also be used as an *input* argument, specified as
v_name, where "name" is the name of the variable defined in the input
script. Any style of LAMMPS variable returning a scalar or a string can
be used, as defined by the :doc:`variable <variable>` command. The
style of variable must be consistent with the *format* keyword
specification for the type of data that is passed to Python. Each time
the Python function is invoked, the LAMMPS variable is evaluated and its
value is passed as an argument to the Python function. Note that a
python-style variable can be used as an argument, which means that the a
Python function can use arguments which invoke other Python functions.
A LAMMPS internal-style variable can also be used as an *input*
argument, specified as iv_name, where "name" is the name of the
internal-style variable. The internal-style variable does not have to
be defined in the input script (though it can be); if it is not defined,
this command creates an :doc:`internal-style variable <variable>` with
the specified name.
An internal-style variable must be used when an equal-style,
vector-style, or atom-style variable triggers the invocation of the
Python function defined by this command, by including a Python function
wrapper with arguments in its formula. Each of the arguments must be
specified as an internal-style variable via the *input* keyword.
In brief, the syntax for a Python function wrapper in a variable formula
is ``py_varname(arg1,arg2,...argN)``, where "varname" is the name of a
python-style variable associated with a Python function defined by this
command. One or more arguments to the function wrapper can themselves
be sub-formulas which the variable command will evaluate and pass as
arguments to the Python function. This is done by assigning the numeric
result for each argument to an internal-style variable; thus the *input*
keyword must specify the arguments as internal-style variables and their
format (see below) as "f" for floating point. This is because LAMMPS
variable formulas are calculated with floating point arithmetic (any
integer values are converted to floating point). Note that the Python
function can also have additional inputs, also specified by the *input*
keyword, which are NOT arguments in the Python function wrapper. See
the example below for the ``mixedargs`` Python function.
See the :doc:`variable <variable>` command doc page for full details on
formula syntax including for Python function wrappers. Examples using
Python function wrappers are shown below. Note that as explained above
with python-style variables, Python function wrappers can be nested; a
sub-formula for an argument can contain its own Python function wrapper
which invokes another Python function.
The *return* keyword is only needed if the Python function returns a
value. The specified *varReturn* must be of the form v_name, where
"name" is the name of a python-style LAMMPS variable, defined by the
value. The specified *varReturn* is of the form v_name, where "name" is
the name of a python-style LAMMPS variable, defined by the
:doc:`variable <variable>` command. The Python function can return a
numeric or string value, as specified by the *format* keyword.
As explained on the :doc:`variable <variable>` doc page, the definition
of a python-style variable associates a Python function name with the
variable. This must match the *Python function name* first argument of
the *python* command. For example these two commands would be
consistent:
.. code-block:: LAMMPS
variable foo python myMultiply
python myMultiply return v_foo format f file funcs.py
The two commands can appear in either order in the input script so
long as both are specified before the Python function is invoked for
the first time. Afterwards, the variable 'foo' is associated with
the Python function 'myMultiply'.
numeric or string value, as specified by the *format* keyword. This
return value is *only* accessible when its associated python-style
variable is evaluated. When the *invoke* keyword is used, the return
value of the python function is ignored unless the optional *logreturn*
argument is specified.
The *format* keyword must be used if the *input* or *return* keywords
are used. It defines an *fstring* with M characters, where M = sum of
@ -214,47 +320,16 @@ but only if the output of the Python function is flagged as a numeric
value ("i" or "f") via the *format* keyword.
If the *return* keyword is used and the *format* keyword specifies the
output as a string, then the default maximum length of that string is
63 characters (64-1 for the string terminator). If you want to return
a longer string, the *length* keyword can be specified with its *Nlen*
value set to a larger number (the code allocates space for Nlen+1 to
include the string terminator). If the Python function generates a
output as a string, then the default maximum length of that string is 63
characters (64-1 for the string terminator). If you want to return a
longer string, the *length* keyword can be specified with its *Nlen*
value set to a larger number. LAMMPS will then allocate Nlen+1 space to
include the string terminator. If the Python function generates a
string longer than the default 63 or the specified *Nlen*, it will be
truncated.
----------
Either the *file*, *here*, or *exists* keyword must be used, but only
one of them. These keywords specify what Python code to load into the
Python interpreter. The *file* keyword gives the name of a file
containing Python code, which should end with a ".py" suffix. The code
will be immediately loaded into and run in the "main" module of the
Python interpreter. The Python code will be executed in parallel on all
MPI processes. Note that Python code which contains a function
definition does not "execute" the function when it is run; it simply
defines the function so that it can be invoked later.
The *here* keyword does the same thing, except that the Python code
follows as a single argument to the *here* keyword. This can be done
using triple quotes as delimiters, as in the examples above. This
allows Python code to be listed verbatim in your input script, with
proper indentation, blank lines, and comments, as desired. See the
:doc:`Commands parse <Commands_parse>` doc page, for an explanation of
how triple quotes can be used as part of input script syntax.
The *exists* keyword takes no argument. It means that Python code
containing the required Python function with the given name has already
been executed, for example by a *python source* command or in the same
file that was used previously with the *file* keyword.
Note that the Python code that is loaded and run must contain a function
with the specified function name. To operate properly when later
invoked, the function code must match the *input* and *return* and
*format* keywords specified by the python command. Otherwise Python
will generate an error.
----------
This section describes how Python code can be written to work with
LAMMPS.
@ -275,16 +350,16 @@ keyword once to load several functions, and the *exists* keyword
thereafter in subsequent python commands to register the other functions
that were previously loaded with LAMMPS.
A Python function you define (or more generally, the code you load)
can import other Python modules or classes, it can make calls to other
A Python function you define (or more generally, the code you load) can
import other Python modules or classes, it can make calls to other
system functions or functions you define, and it can access or modify
global variables (in the "main" module) which will persist between
successive function calls. The latter can be useful, for example, to
prevent a function from being invoke multiple times per timestep by
different commands in a LAMMPS input script that access the returned
python-style variable associated with the function. For example,
consider this function loaded with two global variables defined
outside the function:
consider this function loaded with two global variables defined outside
the function:
.. code-block:: python
@ -308,32 +383,33 @@ previous value is simply returned, without re-computing it. The
"global" statement inside the Python function allows it to overwrite the
global variables from within the local context of the function.
Note that if you load Python code multiple times (via multiple python
commands), you can overwrite previously loaded variables and functions
if you are not careful. E.g. if the code above were loaded twice, the
global variables would be re-initialized, which might not be what you
want. Likewise, if a function with the same name exists in two chunks
of Python code you load, the function loaded second will override the
function loaded first.
Also note that if you load Python code multiple times (via multiple
python commands), you can overwrite previously loaded variables and
functions if you are not careful. E.g. if the code above were loaded
twice, the global variables would be re-initialized, which might not be
what you want. Likewise, if a function with the same name exists in two
chunks of Python code you load, the function loaded second will override
the function loaded first.
It's important to realize that if you are running LAMMPS in parallel,
each MPI task will load the Python interpreter and execute a local
copy of the Python function(s) you define. There is no connection
between the Python interpreters running on different processors.
This implies three important things.
each MPI task will load the Python interpreter and execute a local copy
of the Python function(s) you define. There is no connection between
the Python interpreters running on different processors. This implies
three important things.
First, if you put a print or other statement creating output to the
screen in your Python function, you will see P copies of the output,
when running on P processors. If the prints occur at (nearly) the same
time, the P copies of the output may be mixed together. When loading
the LAMMPS Python module into the embedded Python interpreter, it is
possible to pass the pointer to the current LAMMPS class instance and
via the Python interface to the LAMMPS library interface, it is possible
to determine the MPI rank of the current process and thus adapt the
Python code so that output will only appear on MPI rank 0. The
following LAMMPS input demonstrates how this could be done. The text
'Hello, LAMMPS!' should be printed only once, even when running LAMMPS
in parallel.
time, the P copies of the output may be mixed together.
It is possible to avoid this issue, by passing the pointer to the
current LAMMPS class instance to the Python function via the {input}
SELF argument described above. The Python function can then use the
Python interface to the LAMMPS library interface, and determine the MPI
rank of the current process. The Python code can then ensure output
will only appear on MPI rank 0. The following LAMMPS input demonstrates
how this could be done. The text 'Hello, LAMPS!' should be printed only
once, even when running LAMMPS in parallel.
.. code-block:: LAMMPS
@ -348,27 +424,26 @@ in parallel.
python python_hello invoke
If your Python code loads Python modules that are not pre-loaded by the
Python library, then it will load the module from disk. This may be a
bottleneck if 1000s of processors try to load a module at the same time.
On some large supercomputers, loading of modules from disk by Python may
be disabled. In this case you would need to pre-build a Python library
that has the required modules pre-loaded and link LAMMPS with that
library.
Second, if your Python code loads Python modules that are not pre-loaded
by the Python library, then it will load the module from disk. This may
be a bottleneck if 1000s of processors try to load a module at the same
time. On some large supercomputers, loading of modules from disk by
Python may be disabled. In this case you would need to pre-build a
Python library that has the required modules pre-loaded and link LAMMPS
with that library.
Third, if your Python code calls back to LAMMPS (discussed in the
next section) and causes LAMMPS to perform an MPI operation requires
global communication (e.g. via MPI_Allreduce), such as computing the
global temperature of the system, then you must ensure all your Python
Third, if your Python code calls back to LAMMPS (discussed in the next
section) and causes LAMMPS to perform an MPI operation requires global
communication (e.g. via MPI_Allreduce), such as computing the global
temperature of the system, then you must ensure all your Python
functions (running independently on different processors) call back to
LAMMPS. Otherwise the code may hang.
----------
Your Python function can "call back" to LAMMPS through its
library interface, if you use the SELF input to pass Python
a pointer to LAMMPS. The mechanism for doing this in your
Python function is as follows:
As mentioned above, a Python function can "call back" to LAMMPS through
its library interface, if the SELF input is used to pass Python a
pointer to LAMMPS. The mechanism for doing this is as follows:
.. code-block:: python
@ -393,15 +468,15 @@ appeared in your input script. In this case, LAMMPS should output
Hello from inside Python
to the screen and log file. Note that since the LAMMPS print command
itself takes a string in quotes as its argument, the Python string
must be delimited with a different style of quotes.
itself takes a string in quotes as its argument, the Python string must
be delimited with a different style of quotes.
The :doc:`Python_head` page describes the syntax
for how Python wraps the various functions included in the LAMMPS
library interface.
The :doc:`Python_head` page describes the syntax for how Python wraps
the various functions included in the LAMMPS library interface.
A more interesting example is in the ``examples/python/in.python`` script
which loads and runs the following function from ``examples/python/funcs.py``:
A more interesting example is in the ``examples/python/in.python``
script which loads and runs the following function from
``examples/python/funcs.py``:
.. code-block:: python
@ -416,7 +491,7 @@ which loads and runs the following function from ``examples/python/funcs.py``:
lmp.set_variable("cut",cut) # set a variable in LAMMPS
lmp.command("pair_style lj/cut ${cut}") # LAMMPS command
#lmp.command("pair_style lj/cut %d" % cut) # LAMMPS command option
#lmp.command("pair_style lj/cut %d" % cut) # alternate form of LAMMPS command
lmp.command("pair_coeff * * 1.0 1.0") # ditto
lmp.command("run 10") # ditto
@ -432,51 +507,160 @@ with these input script commands:
python loop invoke
This has the effect of looping over a series of 10 short runs (10
timesteps each) where the pair style cutoff is increased from a value
of 1.0 in distance units, in increments of 0.1. The looping stops
when the per-atom potential energy falls below a threshold of -4.0 in
energy units. More generally, Python can be used to implement a loop
with complex logic, much more so than can be created using the LAMMPS
timesteps each) where the pair style cutoff is increased from a value of
1.0 in distance units, in increments of 0.1. The looping stops when the
per-atom potential energy falls below a threshold of -4.0 in energy
units. More generally, Python can be used to implement a loop with
complex logic, much more so than can be created using the LAMMPS
:doc:`jump <jump>` and :doc:`if <if>` commands.
Several LAMMPS library functions are called from the loop function.
Get_natoms() returns the number of atoms in the simulation, so that it
can be used to normalize the potential energy that is returned by
extract_compute() for the "thermo_pe" compute that is defined by
default for LAMMPS thermodynamic output. Set_variable() sets the
value of a string variable defined in LAMMPS. This library function
is a useful way for a Python function to return multiple values to
LAMMPS, more than the single value that can be passed back via a
return statement. This cutoff value in the "cut" variable is then
substituted (by LAMMPS) in the pair_style command that is executed
next. Alternatively, the "LAMMPS command option" line could be used
in place of the 2 preceding lines, to have Python insert the value
into the LAMMPS command string.
extract_compute() for the "thermo_pe" compute that is defined by default
for LAMMPS thermodynamic output. Set_variable() sets the value of a
string variable defined in LAMMPS. This library function is a useful
way for a Python function to return multiple values to LAMMPS, more than
the single value that can be passed back via a return statement. This
cutoff value in the "cut" variable is then substituted (by LAMMPS) in
the pair_style command that is executed next. Alternatively, the
"alternate form of LAMMPS command" line could be used in place of the 2
preceding lines, to have Python insert the value into the LAMMPS command
string.
.. note::
When using the callback mechanism just described, recognize that
there are some operations you should not attempt because LAMMPS cannot
execute them correctly. If the Python function is invoked between
runs in the LAMMPS input script, then it should be OK to invoke any
LAMMPS input script command via the library interface command() or
file() functions, so long as the command would work if it were
executed in the LAMMPS input script directly at the same point.
there are some operations you should not attempt because LAMMPS
cannot execute them correctly. If the Python function is invoked
between runs in the LAMMPS input script, then it should be OK to
invoke any LAMMPS input script command via the library interface
command() or file() functions, so long as the command would work if
it were executed in the LAMMPS input script directly at the same
point.
However, a Python function can also be invoked during a run, whenever
an associated LAMMPS variable it is assigned to is evaluated. If the
variable is an input argument to another LAMMPS command (e.g. :doc:`fix setforce <fix_setforce>`), then the Python function will be invoked
inside the class for that command, in one of its methods that is
invoked in the middle of a timestep. You cannot execute arbitrary
input script commands from the Python function (again, via the
command() or file() functions) at that point in the run and expect it
to work. Other library functions such as those that invoke computes
or other variables may have hidden side effects as well. In these
cases, LAMMPS has no simple way to check that something illogical is
being attempted.
The same applies to Python functions called during a simulation run at
each time step using :doc:`fix python/invoke <fix_python_invoke>`.
----------
As noted above, a Python function can be invoked during a run, whenever
an associated python-style variable it is assigned to is evaluated.
If the variable is an input argument to another LAMMPS command
(e.g. :doc:`fix setforce <fix_setforce>`), then the Python function will
be invoked inside the class for that command, possibly in one of its
methods that is invoked in the middle of a timestep. You cannot execute
arbitrary input script commands from the Python function (again, via the
command() or file() functions) at that point in the run and expect it to
work. Other library functions such as those that invoke computes or
other variables may have hidden side effects as well. In these cases,
LAMMPS has no simple way to check that something illogical is being
attempted.
The same constraints apply to Python functions called during a
simulation run at each time step using the :doc:`fix python/invoke
<fix_python_invoke>` command.
----------
As noted above, a Python function can also be invoked within the formula
for an equal-style, vector-style, or atom-style variable. This means
the Python function will be invoked whenever that variable is invoked.
In the case of a vector-style variable, the Python function can be
invoked once per element of the global vector. In the case of an
atom-style variable, the Python function can be invoked once per atom.
Here are three simple examples using equal-, vector-, and atom-style
variables to trigger execution of a Python function:
.. code-block:: LAMMPS
variable foo python truncate
python truncate return v_foo input 1 iv_arg format fi here """
def truncate(x):
return int(x)
"""
variable ptrunc equal py_foo(press)
print "TRUNCATED pressure = ${ptrunc}"
The Python ``truncate`` function simply converts a floating-point value
to an integer value. When the LAMMPS print command evaluates the
equal-style ``ptrunc`` variable, the current thermodynamic pressure is
passed to the Python function. The truncated value is output to the
screen and logfile by the print command. Note that the *input* keyword
for the *python* command, specifies an internal-style variable named
"arg" as iv_arg which is required to invoke the Python function from a
Python function wrapper.
The last 2 lines can be replaced by these to define a vector-style
variable which invokes the same Python ``truncate`` function:
.. code-block:: LAMMPS
compute ke all temp
variable ke vector c_ke
variable ketrunc vector py_foo(v_ke)
thermo_style custom step temp epair v_ketrunc[*6]
The vector-style variable ``ketrunc`` invokes the Python ``truncate``
function on each of the 6 components of the global kinetic energy tensor
calculated by the :doc:`compute ke <compute_ke>` command. The 6
truncated values will be printed with thermo output to the screen and
log file.
Or the last 2 lines of the equal-style variable example can be replaced
by these to define atom-style variables which invoke the same Python
``truncate`` function:
.. code-block:: LAMMPS
variable xtrunc atom py_foo(x)
variable ytrunc atom py_foo(y)
variable ztrunc atom py_foo(z)
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
When the dump command invokes the 3 atom-style variables, their
arguments x,y,z to the Python function wrapper are the current per-atom
coordinates of each atom. The Python ``truncate`` function is thus
invoked 3 times for each atom, and the truncated coordinate values for
each atom are written to the dump file.
Note that when using a Python function wrapper in a variable, arguments
can be passed to the Python function either from the variable formula or
by *input* keyword to the :doc:`python command <python>`. For example,
consider these (made up) commands:
.. code-block:: LAMMPS
variable foo python mixedargs
python mixedargs return v_foo input 6 7.5 v_myValue iv_arg1 iv_argy iv_argz v_flag &
format fffffsf here """
def mixedargs(a,b,x,y,z,flag):
...
return result
"""
variable flag string optionABC
variable myValue equal "2.0*temp*c_pe"
compute pe all pe
compute peatom all pe/atom
variable field atom py_foo(x+3.0,sqrt(y),(z-zlo)*c_peatom)
They define a Python ``mixedargs`` function with 6 arguments. Three of
them are internal-style variables, which the variable formula calculates
as numeric values for each atom and passes to the function. In this
example, these arguments are themselves small formulas containing the
x,y,z coordinates of each atom as well as a per-atom compute (c_peratom)
and thermodynamic keyword (zlo).
The other three arguments ``(7.5,v_myValue,v_flag)`` are defined by the
*python* command. The first and last are constant values ("7.5" and the
``optionABC`` string). The second argument (``myValue``) is the result
of an equal-style variable formula which accesses the system temperature
and potential energy.
The "result" returned by each invocation of the Python ``mixedargs``
function becomes the per-atom value in the atom-style "field" variable,
which could be output to a dump file or used elsewhere in the input
script.
----------
@ -485,12 +669,11 @@ interactively or by using Python to launch a Python script stored in a
file, and your code has an error, you will typically see informative
error messages. That is not the case when you run Python code from
LAMMPS using an embedded Python interpreter. The code will typically
fail silently. LAMMPS will catch some errors but cannot tell you
where in the Python code the problem occurred. For example, if the
Python code cannot be loaded and run because it has syntax or other
logic errors, you may get an error from Python pointing to the
offending line, or you may get one of these generic errors from
LAMMPS:
fail silently. LAMMPS will catch some errors but cannot tell you where
in the Python code the problem occurred. For example, if the Python
code cannot be loaded and run because it has syntax or other logic
errors, you may get an error from Python pointing to the offending line,
or you may get one of these generic errors from LAMMPS:
.. parsed-literal::
@ -504,16 +687,16 @@ you will typically get this generic error from LAMMPS:
Python function evaluation failed
Here are three suggestions for debugging your Python code while
running it under LAMMPS.
Here are three suggestions for debugging your Python code while running
it under LAMMPS.
First, don't run it under LAMMPS, at least to start with! Debug it
using plain Python. Load and invoke your function, pass it arguments,
check return values, etc.
Second, add Python print statements to the function to check how far
it gets and intermediate values it calculates. See the discussion
above about printing from Python when running in parallel.
Second, add Python print statements to the function to check how far it
gets and intermediate values it calculates. See the discussion above
about printing from Python when running in parallel.
Third, use Python exception handling. For example, say this statement
in your Python function is failing, because you have not initialized the
@ -523,8 +706,7 @@ variable foo:
foo += 1
If you put one (or more) statements inside a "try" statement,
like this:
If you put one (or more) statements inside a "try" statement, like this:
.. code-block:: python
@ -563,13 +745,15 @@ If you use Python code which calls back to LAMMPS, via the SELF input
argument explained above, there is an extra step required when building
LAMMPS. LAMMPS must also be built as a shared library and your Python
function must be able to load the :doc:`"lammps" Python module
<Python_module>` that wraps the LAMMPS library interface. These are the
same steps required to use Python by itself to wrap LAMMPS. Details on
these steps are explained on the :doc:`Python <Python_head>` doc page.
Note that it is important that the stand-alone LAMMPS executable and the
LAMMPS shared library be consistent (built from the same source code
files) in order for this to work. If the two have been built at
different times using different source files, problems may occur.
<Python_module>` that wraps the LAMMPS library interface.
These are the same steps required to use Python by itself to wrap
LAMMPS. Details on these steps are explained on the :doc:`Python
<Python_head>` doc page. Note that it is important that the stand-alone
LAMMPS executable and the LAMMPS shared library be consistent (built
from the same source code files) in order for this to work. If the two
have been built at different times using different source files,
problems may occur.
Another limitation of calling back to Python from the LAMMPS module
using the *python* command in a LAMMPS input is that both, the Python
@ -583,7 +767,8 @@ global variables will become invisible.
Related commands
""""""""""""""""
:doc:`shell <shell>`, :doc:`variable <variable>`, :doc:`fix python/invoke <fix_python_invoke>`
:doc:`shell <shell>`, :doc:`variable <variable>`,
:doc:`fix python/invoke <fix_python_invoke>`
Default
"""""""

View File

@ -45,7 +45,8 @@ Syntax
*universe* args = one or more strings
*world* args = one string for each partition of processors
*equal* or *vector* or *atom* args = one formula containing numbers, thermo keywords, math operations, built-in functions, atom values and vectors, compute/fix/variable references
*equal* or *vector* or *atom* args = one formula containing numbers, thermo keywords,
math operations, built-in functions, atom values and vectors, compute/fix/variable references
numbers = 0.0, 100, -5.4, 2.8e-4, etc
constants = PI, version, on, off, true, false, yes, no
thermo keywords = vol, ke, press, etc from :doc:`thermo_style <thermo_style>`
@ -67,8 +68,12 @@ Syntax
bound(group,dir,region), gyration(group,region), ke(group,reigon),
angmom(group,dim,region), torque(group,dim,region),
inertia(group,dimdim,region), omega(group,dim,region)
special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), sort(x), rsort(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label), is_timeout()
feature functions = is_available(category,feature), is_active(category,feature), is_defined(category,id)
special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), sort(x), rsort(x), \ gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name),
extract_setting(name), label2type(kind,label),
is_typelabel(kind,label), is_timeout()
feature functions = is_available(category,feature), is_active(category,feature),
is_defined(category,id)
python function wrapper = py_varname(x,y,z,...)
atom value = id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i]
atom vector = id, mass, type, mol, radius, q, x, y, z, vx, vy, vz, fx, fy, fz
custom atom property = i_name, d_name, i_name[i], d_name[i], i2_name[i], d2_name[i], i2_name[i][j], d2_name[i][j]
@ -127,18 +132,21 @@ command), or used as input to an averaging fix (see the :doc:`fix
ave/time <fix_ave_time>` command). Variables of style *vector* store
a formula which produces a vector of such values which can be used as
input to various averaging fixes, or elements of which can be part of
thermodynamic output. 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 :doc:`dump custom <dump>` command) or used as
input to an averaging fix (see the :doc:`fix ave/chunk
<fix_ave_chunk>` and :doc:`fix ave/atom <fix_ave_atom>` commands).
Variables of style *atomfile* can be used anywhere in an input script
that atom-style variables are used; they get their per-atom values
from a file rather than from a formula. Variables of style *python*
can be hooked to Python functions using code you provide, so that the
variable gets its value from the evaluation of the Python code.
Variables of style *internal* are used by a few commands which set
their value directly.
thermodynamic output.
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 :doc:`dump custom <dump>` command) or used as input to an
averaging fix (see the :doc:`fix ave/chunk <fix_ave_chunk>` and
:doc:`fix ave/atom <fix_ave_atom>` commands). Variables of style
*atomfile* can be used anywhere in an input script that atom-style
variables are used; they get their per-atom values from a file rather
than from a formula.
Variables of style *python* can be hooked to Python functions using
Python code you provide, so that the variable gets its value from the
evaluation of the Python code. Variables of style *internal* are used
by a few commands which set their value directly.
.. note::
@ -166,15 +174,16 @@ simulation.
.. note::
When an input script line is encountered that defines a variable
of style *equal* or *vector* or *atom* or *python* that contains a
formula or Python code, the formula is NOT immediately evaluated. It
will be evaluated every time when the variable is **used** instead. If
you simply want to evaluate a formula in place you can use as
so-called. See the section below about "Immediate Evaluation of
Variables" for more details on the topic. This is also true of a
*format* style variable since it evaluates another variable when it is
invoked.
When an input script line is encountered that defines a variable of
style *equal* or *vector* or *atom* or *python* that contains a
formula or links to Python code, the formula or Python code is NOT
immediately evaluated. Instead, it is evaluated each time the
variable is **used**. If you simply want to evaluate a formula in
place you can use a so-called immediate variable. as described in
the preceding note. Or see the section below about "Immediate
Evaluation of Variables" for more details on the topic. This is
also true of a *format* style variable since it evaluates another
variable when it is invoked.
Variables of style *equal* and *vector* and *atom* can be used as
inputs to various other commands which evaluate their formulas as
@ -183,12 +192,12 @@ this context, variables of style *timer* or *internal* or *python* can
be used in place of an equal-style variable, with the following two
caveats.
First, internal-style variables can be used except by commands that
set the value stored by the internal variable. When the LAMMPS
command evaluates the internal-style variable, it will use the value
set (internally) by another command. Second, python-style variables
can be used so long as the associated Python function, as defined by
the :doc:`python <python>` command, returns a numeric value. When the
First, internal-style variables require their values be set by code
elsewhere in LAMMPS. When a LAMMPS input script or command evaluates
an internal-style variable, it must have a current value set
(internally) via that mechanism. Second, python-style variables can
be used so long as the associated Python function, as defined by the
:doc:`python <python>` command, returns a numeric value. When the
LAMMPS command evaluates the python-style variable, the Python
function will be executed.
@ -388,13 +397,24 @@ using the :doc:`command-line switch -var <Run_options>`.
For the *internal* style a numeric value is provided. This value will
be assigned to the variable until a LAMMPS command sets it to a new
value. There are currently only two LAMMPS commands that require
*internal* variables as inputs, because they reset them:
:doc:`create_atoms <create_atoms>` and :doc:`fix controller
<fix_controller>`. As mentioned above, an internal-style variable can
be used in place of an equal-style variable anywhere else in an input
script, e.g. as an argument to another command that allows for
equal-style variables.
value.
Note however, that most commands which use internal-style variables do
not require them to be defined in the input script. They create one or
more internal-style variables if they do not already exist. Examples
are these commands:
* :doc:`create_atoms <create_atoms>`
* :doc:`fix deposit <fix_deposit>`
* :doc:`compute bond/local <compute_bond_local>`
* :doc:`compute angle/local <compute_angle_local>`
* :doc:`compute dihedral/local <compute_dihedral_local>`
* :doc:`python <python>` command in conjunction with Python function wrappers used in equal- and atom-style variable formulas
A command which does require an internal-style variable to be defined in
the input script is the :doc:`fix controller <fix_controller>` command,
because another (arbitrary) command typically also references the
variable.
----------
@ -439,6 +459,15 @@ python-style variable can be used in place of an equal-style variable
anywhere in an input script, e.g. as an argument to another command
that allows for equal-style variables.
A python-style variable can also be used within the formula for an
equal-style or atom-style formula in a Python function wrapper, as
explained below for variable formulas. In this context, the usage
syntax is py_varname(arg1,arg2,...), where varname is the name of the
python-style variable. When a Python wrapper function is used in an
atom-style formula, it can be invoked once per atom using arguments
specific to each atom. The resulting values in the atom-style
variable can thus be calculated by Python code.
----------
For the *string* style, a single string is assigned to the variable.
@ -528,9 +557,9 @@ is a valid (though strange) variable formula:
Specifically, a formula can contain numbers, constants, thermo
keywords, math operators, math functions, group functions, region
functions, special functions, feature functions, atom values, atom
vectors, custom atom properties, compute references, fix references, and references to other
variables.
functions, special functions, feature functions, Python function
wrappers, atom values, atom vectors, custom atom properties, compute
references, fix references, and references to other variables.
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Number | 0.2, 100, 1.0e20, -15.4, etc |
@ -551,6 +580,8 @@ variables.
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) |
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Python func wrapper | py_varname(x,y,z,...) |
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Atom values | id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i] |
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Atom vectors | id, mass, type, mol, x, y, z, vx, vy, vz, fx, fy, fz, q |
@ -1161,6 +1192,84 @@ variable name.
----------
Python Function wrapper
------------------------
A Python function wrapper enables the formula for an equal-style or
atom-style variable to invoke functions coded in Python. In the case
of an equal-style variable, the Python-coded function will be invoked
once. In the case of an atom-style variable, it can be invoked once
per atom, if one or more of its arguments include a per-atom quantity,
e.g. the position of an atom. As illustrated below, the reason to use
a Python function wrapper is to make it easy to pass LAMMPS-related
arguments to the Python-coded function associated with a python-style
variable.
The syntax for defining a Python function wrapper is
.. code-block:: LAMMPS
py_varname(arg1,arg2,...argN)
where *varname* is the name of a python-style variable which couples
to a Python-coded function. The function will be passed the zero or
more arguments listed in parentheses: *arg1*, *arg2*, ... *argN*. As
with Math Functions, each argument can itself be an arbitrarily
complex formula.
A Python function wrapper can be used in the following manner by an
input script:
.. code-block:: LAMMPS
variable foo python truncate
python truncate return v_foo input 1 v_arg format fi here """
def truncate(x):
return int(x)
"""
variable xtrunc atom py_foo(x)
variable ytrunc atom py_foo(y)
variable ztrunc atom py_foo(z)
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
The first two commands define a python-style variable *foo* and couple
it to the Python-coded function *truncate()* which takes a single
floating point argument, and returns its truncated integer value. In
this case, the Python code for truncate() is included in the *python*
command; it could also be contained in a file. See the :doc:`python
<python>` command doc page for details.
The next three commands define atom-style variables *xtrunc*,
*ytrunc*, and *ztrunc*. Each of them include the same Python function
wrapper in their formula, with a different argument. The atom-style
variable *xtrunc* will invoke the python-style variable *foo*, which
will in turn invoke the Python-coded *truncate()* method. Because
*xtrunc* is an atom-style variable, and the argument *x* in the Python
function wrapper is a per-atom quantity (the x-coord of each atom),
each processor will invoke the *truncate()* method once per atom, for
the atoms it owns.
When invoked for the Ith atom, the value of the *arg* internal-style
variable, defined by the *python* command, is set to the x-coord of
the Ith atom. The call via python-style variable *foo* to the Python
*truncate()* function passes the value of the *arg* variable as the
function's first (and only) argument. Likewise, the return value of
the Python function is stored by the python-style variable *foo* and
used in the *xtrunc* atom-style variable formula for the Ith atom.
The resulting per-atom vector for *xtrunc* will thus contain the
truncated x-coord of every atom in the system. The dump command
includes the truncated xyz coords for each atom in its output.
See the :doc:`python <python>` command for more details on options the
*python* command can specify as well as examples of more complex Python
functions which can be wrapped in this manner. In particular, the
Python function can take a variety of arguments, some generated by the
*python* command, and others by the arguments of the Python function
wrapper.
----------
Atom Values and Vectors
-----------------------

View File

@ -232,6 +232,7 @@ Bagi
Bagnold
Baig
Bajaj
bak
Bal
balancer
Balankura
@ -3134,6 +3135,7 @@ Pxy
pxz
py
Py
pyargs
pydir
pylammps
PyLammps
@ -4077,6 +4079,7 @@ Vaiwala
valent
Valeriu
valgrind
validator
Valone
valuev
Valuev
@ -4086,6 +4089,7 @@ Vanduyfhuys
varargs
varavg
variational
varname
Varshalovich
Varshney
vashishta