Merge remote-tracking branch 'github/develop' into apip
This commit is contained in:
@ -31,3 +31,5 @@ OPT.
|
||||
* :doc:`pppm/dielectric <kspace_style>`
|
||||
* :doc:`pppm/electrode (i) <kspace_style>`
|
||||
* :doc:`scafacos <kspace_style>`
|
||||
* :doc:`zero <kspace_style>`
|
||||
|
||||
|
||||
@ -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
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@ -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`
|
||||
|
||||
--------
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
""""""""""""
|
||||
|
||||
@ -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::
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
""""""""""""
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
"""""""
|
||||
|
||||
@ -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
|
||||
-----------------------
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user