Merge branch 'develop' into next_release
This commit is contained in:
@ -113,7 +113,6 @@ OPT.
|
||||
* :doc:`mvv/tdpd <fix_mvv_dpd>`
|
||||
* :doc:`neb <fix_neb>`
|
||||
* :doc:`neb/spin <fix_neb_spin>`
|
||||
* :doc:`neighbor/swap <fix_neighbor_swap>`
|
||||
* :doc:`nonaffine/displacement <fix_nonaffine_displacement>`
|
||||
* :doc:`nph (ko) <fix_nh>`
|
||||
* :doc:`nph/asphere (o) <fix_nph_asphere>`
|
||||
@ -219,6 +218,7 @@ OPT.
|
||||
* :doc:`rigid/small (o) <fix_rigid>`
|
||||
* :doc:`rx (k) <fix_rx>`
|
||||
* :doc:`saed/vtk <fix_saed_vtk>`
|
||||
* :doc:`set <fix_set>`
|
||||
* :doc:`setforce (k) <fix_setforce>`
|
||||
* :doc:`setforce/spin <fix_setforce>`
|
||||
* :doc:`sgcmc <fix_sgcmc>`
|
||||
|
||||
@ -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`
|
||||
|
||||
--------
|
||||
|
||||
|
||||
@ -21,8 +21,8 @@ You can follow the LAMMPS development on 4 different git branches:
|
||||
|
||||
* **develop** : this branch follows the ongoing development and is
|
||||
updated with every merge commit of a pull request
|
||||
* **release** : this branch is updated with every "feature release";
|
||||
updates are always "fast-forward" merges from *develop*
|
||||
* **release** : this branch is updated with every "feature release"
|
||||
and updates are always "fast-forward" merges from *develop*
|
||||
* **maintenance** : this branch collects back-ported bug fixes from the
|
||||
*develop* branch to the *stable* branch. It is used to update the
|
||||
*stable* branch for "stable update releases".
|
||||
|
||||
@ -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
|
||||
|
||||
@ -75,15 +75,34 @@ section below for examples where this has been done.
|
||||
**Differences between the GPU and KOKKOS packages:**
|
||||
|
||||
* The GPU package accelerates only pair force, neighbor list, and (parts
|
||||
of) PPPM calculations. The KOKKOS package attempts to run most of the
|
||||
of) PPPM calculations (and runs the remaining force computations on
|
||||
the CPU concurrently). The KOKKOS package attempts to run most of the
|
||||
calculation on the GPU, but can transparently support non-accelerated
|
||||
code (with a performance penalty due to having data transfers between
|
||||
host and GPU).
|
||||
* The list of which styles are accelerated by the GPU or KOKKOS package
|
||||
differs with some overlap.
|
||||
* The GPU package requires neighbor lists to be built on the CPU when using
|
||||
hybrid pair styles, exclusion lists, or a triclinic simulation box.
|
||||
* The GPU package can be compiled for CUDA, HIP, or OpenCL and thus supports
|
||||
NVIDIA, AMD, and Intel GPUs well. On NVIDIA hardware, using CUDA is
|
||||
typically resulting in equal or better performance over OpenCL.
|
||||
* OpenCL in the GPU package does theoretically also support Intel CPUs or
|
||||
Intel Xeon Phi, but the native support for those in KOKKOS (or INTEL)
|
||||
is superior.
|
||||
* The GPU package benefits from running multiple MPI processes (2-8) per
|
||||
GPU to parallelize the non-GPU accelerated styles. The KOKKOS package
|
||||
usually not, especially when all parts of the calculation have KOKKOS
|
||||
support.
|
||||
* The GPU package can be compiled for CUDA, HIP, or OpenCL and thus
|
||||
supports NVIDIA, AMD, and Intel GPUs well. On NVIDIA or AMD hardware,
|
||||
using native CUDA or HIP compilation, respectively, with either GPU or
|
||||
KOKKOS results in equal or better performance over OpenCL.
|
||||
* OpenCL in the GPU package supports NVIDIA, AMD, and Intel GPUs at the
|
||||
*same time* and with the *same executable*. KOKKOS currently does not
|
||||
support OpenCL.
|
||||
* The GPU package supports single precision floating point, mixed
|
||||
precision floating point, and double precision floating point math on
|
||||
the GPU. This must be chosen at compile time. KOKKOS currently only
|
||||
supports double precision floating point math. Using single or mixed
|
||||
precision (recommended) results in significantly improved performance
|
||||
on consumer GPUs for some loss in accuracy (which is rather small with
|
||||
mixed precision). Single and mixed precision support for KOKKOS is in
|
||||
development (no ETA yet).
|
||||
* Some pair styles (for example :doc:`snap <pair_snap>`, :doc:`mliap
|
||||
<pair_mliap>` or :doc:`reaxff <pair_reaxff>` in the KOKKOS package have
|
||||
seen extensive optimizations and specializations for GPUs and CPUs.
|
||||
|
||||
@ -1,16 +1,218 @@
|
||||
Measuring performance
|
||||
=====================
|
||||
|
||||
Before trying to make your simulation run faster, you should
|
||||
understand how it currently performs and where the bottlenecks are.
|
||||
Factors that influence performance
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The best way to do this is run the your system (actual number of
|
||||
atoms) for a modest number of timesteps (say 100 steps) on several
|
||||
different processor counts, including a single processor if possible.
|
||||
Do this for an equilibrium version of your system, so that the
|
||||
100-step timings are representative of a much longer run. There is
|
||||
typically no need to run for 1000s of timesteps to get accurate
|
||||
timings; you can simply extrapolate from short runs.
|
||||
Before trying to make your simulation run faster, you should understand
|
||||
how it currently performs and where the bottlenecks are. We generally
|
||||
distinguish between serial performance (how fast can a single process do
|
||||
the calculations?) and parallel efficiency (how much faster does a
|
||||
calculation get by using more processes?). There are many factors
|
||||
affecting either and below are some lists discussing some commonly
|
||||
known but also some less known factors.
|
||||
|
||||
Factors affecting serial performance (in no specific order):
|
||||
|
||||
* CPU hardware: clock rate, cache sizes, CPU architecture (instructions
|
||||
per clock, vectorization support, fused multiply-add support and more)
|
||||
* RAM speed and number of channels that the CPU can use to access RAM
|
||||
* Cooling: CPUs can change the CPU clock based on thermal load, thus the
|
||||
degree of cooling can affect the speed of a CPU. Sometimes even the
|
||||
temperature of neighboring compute nodes in a cluster can make a
|
||||
difference.
|
||||
* Compiler optimization: most of LAMMPS is written to be easy to modify
|
||||
and thus compiler optimization can speed up calculations. However, too
|
||||
aggressive compiler optimization can produce incorrect results or
|
||||
crashes (during compilation or at runtime).
|
||||
* Source code improvements: styles in the OPT, OPENMP, and INTEL package
|
||||
can be faster than their base implementation due to improved data
|
||||
access patterns, cache efficiency, or vectorization. Compiler optimization
|
||||
is required to take full advantage of these.
|
||||
* Number and kind of fixes, computes, or variables used during a simulation,
|
||||
especially if they result in collective communication operations
|
||||
* Pair style cutoffs and system density: calculations get slower the more
|
||||
neighbors are in the neighbor list and thus for which interactions need
|
||||
to be computed. Force fields with pair styles that compute interactions
|
||||
between triples or quadruples of atoms or that use embedding energies or
|
||||
charge equilibration will need to walk the neighbor lists multiple times.
|
||||
* Neighbor list settings: tradeoff between neighbor list skin (larger
|
||||
skin = more neighbors, more distances to compute before applying the
|
||||
cutoff) and frequency of neighbor list builds (larger skin = fewer
|
||||
neighbor list builds).
|
||||
* Proximity of per-atom data in physical memory that for atoms that are
|
||||
close in space improves cache efficiency (thus LAMMPS will by default
|
||||
sort atoms in local storage accordingly)
|
||||
* Using r-RESPA multi-timestepping or a SHAKE or RATTLE fix to constrain
|
||||
bonds with higher-frequency vibrations may allow a larger (outer) timestep
|
||||
and thus fewer force evaluations (usually the most time consuming step in
|
||||
MD) for the same simulated time (with some tradeoff in accuracy).
|
||||
|
||||
Factors affecting parallel efficiency (in no specific order):
|
||||
|
||||
* Bandwidth and latency of communication between processes. This can vary a
|
||||
lot between processes on the same CPU or physical node and processes
|
||||
on different physical nodes and there vary between different
|
||||
communication technologies (like Ethernet or InfiniBand or other
|
||||
high-speed interconnects)
|
||||
* Frequency and complexity of communication patterns required
|
||||
* Number of "work units" (usually correlated with the number of atoms
|
||||
and choice of force field) per MPI-process required for one time step
|
||||
(if this number becomes too small, the cost of communication becomes
|
||||
dominant).
|
||||
* Choice of parallelization method (MPI-only, OpenMP-only, MPI+OpenMP,
|
||||
MPI+GPU, MPI+GPU+OpenMP)
|
||||
* Algorithmic complexity of the chosen force field (pair-wise vs. many-body
|
||||
potential, Ewald vs. PPPM vs. (compensated or smoothed) cutoff-Coulomb)
|
||||
* Communication cutoff: a larger cutoff results in more ghost atoms and
|
||||
thus more data that needs to be communicated
|
||||
* Frequency of neighbor list builds: during a neighbor list build the
|
||||
domain decomposition is updated and the list of ghost atoms rebuilt
|
||||
which requires multiple global communication steps
|
||||
* FFT-grid settings and number of MPI processes for kspace style PPPM:
|
||||
PPPM uses parallel 3d FFTs which will drop much faster in parallel
|
||||
efficiency with respect to the number of MPI processes than other
|
||||
parts of the force computation. Thus using MPI+OpenMP parallelization
|
||||
or :doc:`run style verlet/split <run_style>` can improve parallel
|
||||
efficiency by limiting the number of MPI processes used for the FFTs.
|
||||
* Load (im-)balance: LAMMPS' domain decomposition assumes that atoms are
|
||||
evenly distributed across the entire simulation box. If there are
|
||||
areas of vacuum, this may lead to different amounts of work for
|
||||
different MPI processes. Using the :doc:`processors command
|
||||
<processors>` to change the spatial decomposition, or MPI+OpenMP
|
||||
parallelization instead of only-MPI to have larger sub-domains, or the
|
||||
(fix) balance command (without or with switching to communication style
|
||||
tiled) to change the sub-domain volumes are all methods that
|
||||
can help to avoid load imbalances.
|
||||
|
||||
Examples comparing serial performance
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before looking at your own input deck(s), you should get some reference
|
||||
data from a known input so that you know what kind of performance you
|
||||
should expect from your input. For the following we therefore use the
|
||||
``in.rhodo.scaled`` input file and ``data.rhodo`` data file from the
|
||||
``bench`` folder. This is a system of 32000 atoms using the CHARMM force
|
||||
field and long-range electrostatics running for 100 MD steps. The
|
||||
performance data is printed at the end of a run and only measures the
|
||||
performance during propagation and excludes the setup phase.
|
||||
|
||||
Running with a single MPI process on an AMD Ryzen Threadripper PRO
|
||||
9985WX CPU (64 cores, 128 threads, base clock: 3.2GHz, max. clock
|
||||
5.4GHz, L1/L2/L3 cache 5MB/64MB/256MB, 8 DDR5-6400 memory channels) one
|
||||
gets the following performance report:
|
||||
|
||||
.. code-block::
|
||||
|
||||
Performance: 1.232 ns/day, 19.476 hours/ns, 7.131 timesteps/s, 228.197 katom-step/s
|
||||
99.2% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
The %CPU value should be at 100% or very close. Lower values would
|
||||
be an indication that there are *other* processes also using the same
|
||||
CPU core and thus invalidating the performance data. The katom-step/s
|
||||
value is best suited for comparisons, since it is fairly independent
|
||||
from the system size. The `in.rhodo.scaled` input can be easily made
|
||||
larger through replication in the three dimensions by settings variables
|
||||
"x", "y", "z" to values other than 1 from the command line with the
|
||||
"-var" flag. Example:
|
||||
|
||||
- 32000 atoms: 228.8 katom-step/s
|
||||
- 64000 atoms: 231.6 katom-step/s
|
||||
- 128000 atoms: 231.1 katom-step/s
|
||||
- 256000 atoms: 226.4 katom-step/s
|
||||
- 864000 atoms: 229.6 katom-step/s
|
||||
|
||||
Comparing to an AMD Ryzen 7 7840HS CPU (8 cores, 16 threads, base clock
|
||||
3.8GHz, max. clock 5.1GHz, L1/L2/L3 cache 512kB/8MB/16MB, 2 DDR5-5600
|
||||
memory channels), we get similar single core performance (~220
|
||||
katom-step/s vs. ~230 katom-step/s) due to the similar clock and
|
||||
architecture:
|
||||
|
||||
- 32000 atoms: 219.8 katom-step/s
|
||||
- 64000 atoms: 222.5 katom-step/s
|
||||
- 128000 atoms: 216.8 katom-step/s
|
||||
- 256000 atoms: 221.0 katom-step/s
|
||||
- 864000 atoms: 221.1 katom-step/s
|
||||
|
||||
Switching to an older Intel Xeon E5-2650 v4 CPU (12 cores, 12 threads,
|
||||
base clock 2.2GHz, max. clock 2.9GHz, L1/L2/L3 cache (64kB/256kB/30MB, 4
|
||||
DDR4-2400 memory channels) leads to a lower performance of approximately
|
||||
109 katom-step/s due to differences in architecture and clock. In all
|
||||
cases, when looking at multiple runs, the katom-step/s property
|
||||
fluctuates by approximately 1% around the average.
|
||||
|
||||
From here on we are looking at the performance for the 256000 atom system only
|
||||
and change several settings incrementally:
|
||||
|
||||
#. No compiler optimization GCC (-Og -g): 183.8 katom-step/s
|
||||
#. Moderate optimization with debug info GCC (-O2 -g): 231.1 katom-step/s
|
||||
#. Full compiler optimization GCC (-DNDEBUG -O3): 236.0 katom-step/s
|
||||
#. Aggressive compiler optimization GCC (-O3 -ffast-math -march=native): 239.9 katom-step/s
|
||||
#. Source code optimization in OPENMP package (1 thread): 266.7 katom-step/s
|
||||
#. Use *fix nvt* instead of *fix npt* (compute virial only every 50 steps): 272.9 katom-step/s
|
||||
#. Increase pair style cutoff by 2 :math:`\AA`: 181.2 katom-step/s
|
||||
#. Use tight PPPM convergence (1.0e-6 instead of 1.0e-4): 161.9 katom-step/s
|
||||
#. Use Ewald summation instead of PPPM (at 1.0e-4 convergence): 19.9 katom-step/s
|
||||
|
||||
The numbers show that gains from aggressive compiler optimizations are
|
||||
rather small in LAMMPS, the data access optimizations in the OPENMP (and
|
||||
OPT) packages are more prominent. On the other side, using more
|
||||
accurate force field settings causes, not unexpectedly, a significant
|
||||
slowdown (to about half the speed). Finally, using regular Ewald
|
||||
summation causes a massive slowdown due to the bad algorithmic scaling
|
||||
with system size.
|
||||
|
||||
Examples comparing parallel performance
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The parallel performance usually goes on top of the serial performance.
|
||||
Using twice as many processors should increase the performance metric
|
||||
by up to a factor of two. With the number of processors *N* and the
|
||||
serial performance :math:`p_1` and the performance for *N* processors
|
||||
:math:`p_N` we can define a *parallel efficiency* in percent as follows:
|
||||
|
||||
.. math::
|
||||
|
||||
P_{eff} = \frac{p_N}{p_1 \cdot N} \cdot 100\%
|
||||
|
||||
For the AMD Ryzen Threadripper PRO 9985WX CPU and the serial
|
||||
simulation settings of point 6. from above, we get the following
|
||||
parallel efficiency data for the 256000 atom system:
|
||||
|
||||
- 1 MPI task: 273.6 katom-step/s, :math:`P_{eff} = 100\%`
|
||||
- 2 MPI tasks: 530.6 katom-step/s, :math:`P_{eff} = 97\%`
|
||||
- 4 MPI tasks: 1.021 Matom-step/s, :math:`P_{eff} = 93\%`
|
||||
- 8 MPI tasks: 1.837 Matom-step/s, :math:`P_{eff} = 84\%`
|
||||
- 16 MPI tasks: 3.574 Matom-step/s, :math:`P_{eff} = 82\%`
|
||||
- 32 MPI tasks: 6.479 Matom-step/s, :math:`P_{eff} = 74\%`
|
||||
- 64 MPI tasks: 9.032 Matom-step/s, :math:`P_{eff} = 52\%`
|
||||
- 128 MPI tasks: 12.03 Matom-step/s, :math:`P_{eff} = 34\%`
|
||||
|
||||
The 128 MPI tasks run uses CPU cores from hyper-threading.
|
||||
|
||||
For a small system with only 32000 atoms the parallel efficiency
|
||||
drops off earlier when the number of work units is too small relative
|
||||
to the communication overhead:
|
||||
|
||||
- 1 MPI task: 270.8 katom-step/s, :math:`P_{eff} = 100\%`
|
||||
- 2 MPI tasks: 529.3 katom-step/s, :math:`P_{eff} = 98\%`
|
||||
- 4 MPI tasks: 989.8 katom-step/s, :math:`P_{eff} = 91\%`
|
||||
- 8 MPI tasks: 1.832 Matom-step/s, :math:`P_{eff} = 85\%`
|
||||
- 16 MPI tasks: 3.463 Matom-step/s, :math:`P_{eff} = 80\%`
|
||||
- 32 MPI tasks: 5.970 Matom-step/s, :math:`P_{eff} = 69\%`
|
||||
- 64 MPI tasks: 7.477 Matom-step/s, :math:`P_{eff} = 42\%`
|
||||
- 128 MPI tasks: 8.069 Matom-step/s, :math:`P_{eff} = 23\%`
|
||||
|
||||
Measuring performance of your input deck
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The best way to do this is run the your system (actual number of atoms)
|
||||
for a modest number of timesteps (say 100 steps) on several different
|
||||
processor counts, including a single processor if possible. Do this for
|
||||
an equilibrium version of your system, so that the 100-step timings are
|
||||
representative of a much longer run. There is typically no need to run
|
||||
for 1000s of timesteps to get accurate timings; you can simply
|
||||
extrapolate from short runs.
|
||||
|
||||
For the set of runs, look at the timing data printed to the screen and
|
||||
log file at the end of each LAMMPS run. The
|
||||
@ -28,12 +230,15 @@ breakdown and relative percentages. For example, trying different
|
||||
options for speeding up the long-range solvers will have little impact
|
||||
if they only consume 10% of the run time. If the pairwise time is
|
||||
dominating, you may want to look at GPU or OMP versions of the pair
|
||||
style, as discussed below. Comparing how the percentages change as
|
||||
you increase the processor count gives you a sense of how different
|
||||
operations within the timestep are scaling. Note that if you are
|
||||
running with a Kspace solver, there is additional output on the
|
||||
breakdown of the Kspace time. For PPPM, this includes the fraction
|
||||
spent on FFTs, which can be communication intensive.
|
||||
style, as discussed below. Comparing how the percentages change as you
|
||||
increase the processor count gives you a sense of how different
|
||||
operations within the timestep are scaling. If you are using PPPM as
|
||||
Kspace solver, you can turn on an additional output with
|
||||
:doc:`kspace_modify fftbench yes <kspace_modify>` which measures the
|
||||
time spent during PPPM on the 3d FFTs, which can be communication
|
||||
intensive for larger processor counts. This provides an indication
|
||||
whether it is worth trying out alternatives to the default FFT settings
|
||||
for additional performance.
|
||||
|
||||
Another important detail in the timing info are the histograms of
|
||||
atoms counts and neighbor counts. If these vary widely across
|
||||
|
||||
@ -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
|
||||
|
||||
@ -292,7 +292,6 @@ accelerated styles exist.
|
||||
* :doc:`mvv/tdpd <fix_mvv_dpd>` - constant temperature DPD using the modified velocity-Verlet algorithm
|
||||
* :doc:`neb <fix_neb>` - nudged elastic band (NEB) spring forces
|
||||
* :doc:`neb/spin <fix_neb_spin>` - nudged elastic band (NEB) spring forces for spins
|
||||
* :doc:`neighbor/swap <fix_neighbor_swap>` - kinetic Monte Carlo (kMC) atom swapping
|
||||
* :doc:`nonaffine/displacement <fix_nonaffine_displacement>` - calculate nonaffine displacement of atoms
|
||||
* :doc:`nph <fix_nh>` - constant NPH time integration via Nose/Hoover
|
||||
* :doc:`nph/asphere <fix_nph_asphere>` - NPH for aspherical particles
|
||||
@ -398,6 +397,7 @@ accelerated styles exist.
|
||||
* :doc:`rigid/small <fix_rigid>` - constrain many small clusters of atoms to move as a rigid body with NVE integration
|
||||
* :doc:`rx <fix_rx>` - solve reaction kinetic ODEs for a defined reaction set
|
||||
* :doc:`saed/vtk <fix_saed_vtk>` - time-average the intensities from :doc:`compute saed <compute_saed>`
|
||||
* :doc:`set <fix_set>` - reset an atom property via an atom-style variable every N steps
|
||||
* :doc:`setforce <fix_setforce>` - set the force on each atom
|
||||
* :doc:`setforce/spin <fix_setforce>` - set magnetic precession vectors on each atom
|
||||
* :doc:`sgcmc <fix_sgcmc>` - fix for hybrid semi-grand canonical MD/MC simulations
|
||||
|
||||
@ -82,10 +82,9 @@ specified values may represent calculations performed by computes and
|
||||
fixes which store their own "group" definitions.
|
||||
|
||||
Each listed value can be the result of a compute or fix or the
|
||||
evaluation of an equal-style or vector-style variable. For
|
||||
vector-style variables, the specified indices can include a wildcard
|
||||
character. See the :doc:`fix ave/correlate <fix_ave_correlate>` page
|
||||
for details.
|
||||
evaluation of an equal-style or vector-style variable. The specified
|
||||
indices can include a wildcard string. See the
|
||||
:doc:`fix ave/correlate <fix_ave_correlate>` page for details on that.
|
||||
|
||||
The *Nevery* and *Nfreq* arguments specify on what time steps the input
|
||||
values will be used to calculate correlation data and the frequency
|
||||
|
||||
@ -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::
|
||||
|
||||
|
||||
@ -1,264 +0,0 @@
|
||||
.. index:: fix neighbor/swap
|
||||
|
||||
fix neighbor/swap command
|
||||
=========================
|
||||
|
||||
Syntax
|
||||
""""""
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
fix ID group-ID neighbor/swap N X seed T R0 voro-ID keyword values ...
|
||||
|
||||
* ID, group-ID are documented in :doc:`fix <fix>` command
|
||||
* neighbor/swap = style name of this fix command
|
||||
* N = invoke this fix every N steps
|
||||
* X = number of swaps to attempt every N steps
|
||||
* seed = random # seed (positive integer)
|
||||
* T = scaling temperature of the MC swaps (temperature units)
|
||||
* R0 = scaling swap probability of the MC swaps (distance units)
|
||||
* voro-ID = valid voronoi compute id (compute voronoi/atom)
|
||||
* one or more keyword/value pairs may be appended to args
|
||||
* keywords *types* and *diff* are mutually exclusive, but one must be specified
|
||||
* keyword = *types* or *diff* or *ke* or *region* or *rates*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*types* values = two or more atom types (Integers in range [1,Ntypes] or type labels)
|
||||
*diff* values = one atom type
|
||||
*ke* value = *yes* or *no*
|
||||
*yes* = kinetic energy is conserved after atom swaps
|
||||
*no* = no conservation of kinetic energy after atom swaps
|
||||
*region* value = region-ID
|
||||
region-ID = ID of region to use as an exchange/move volume
|
||||
*rates* values = V1 V2 . . . Vntypes values to conduct variable diffusion for different atom types (unitless)
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
compute voroN all voronoi/atom neighbors yes
|
||||
fix mc all neighbor/swap 10 160 15238 1000.0 3.0 voroN diff 2
|
||||
fix myFix all neighbor/swap 100 1 12345 298.0 3.0 voroN region my_swap_region types 5 6
|
||||
fix kmc all neighbor/swap 1 100 345 1.0 3.0 voroN diff 3 rates 3 1 6
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
|
||||
.. versionadded:: 12Jun2025
|
||||
|
||||
This fix performs Monte-Carlo (MC) evaluations to enable kinetic
|
||||
Monte Carlo (kMC)-type behavior during MD simulation by allowing
|
||||
neighboring atoms to swap their positions. In contrast to the :doc:`fix
|
||||
atom/swap <fix_atom_swap>` command which swaps pairs of atoms anywhere
|
||||
in the simulation domain, the restriction of the MC swapping to
|
||||
neighbors enables a hybrid MD/kMC-like simulation.
|
||||
|
||||
Neighboring atoms are defined by using a Voronoi tesselation performed
|
||||
by the :doc:`compute voronoi/atom <compute_voronoi_atom>` command.
|
||||
Two atoms are neighbors if their Voronoi cells share a common face
|
||||
(3d) or edge (2d).
|
||||
|
||||
The selection of a swap neighbor is made using a distance-based
|
||||
criterion for weighting the selection probability of each swap, in the
|
||||
same manner as kMC selects a next event using relative probabilities.
|
||||
The acceptance or rejection of each swap is determined via the
|
||||
Metropolis criterion after evaluating the change in system energy due
|
||||
to the swap.
|
||||
|
||||
A detailed explanation of the original implementation of this
|
||||
algorithm can be found in :ref:`(Tavenner 2023) <TavennerMDkMC>`
|
||||
where it was used to simulated accelerated diffusion in an MD context.
|
||||
|
||||
Simulating inherently kinetically-limited behaviors which rely on rare
|
||||
events (such as atomic diffusion in a solid) is challenging for
|
||||
traditional MD since its relatively short timescale will not naturally
|
||||
sample many events. This fix addresses this challenge by allowing rare
|
||||
neighbor hopping events to be sampled in a kMC-like fashion at a much
|
||||
faster rate (set by the specified *N* and *X* parameters). This enables
|
||||
the processes of atomic diffusion to be approximated during an MD
|
||||
simulation, effectively decoupling the MD atomic vibrational timescale
|
||||
and the atomic hopping (kMC event) timescale.
|
||||
|
||||
The algorithm implemented by this fix is as follows:
|
||||
|
||||
- The MD simulation is paused every *N* steps
|
||||
- A Voronoi tesselation is performed for the current atom configuration.
|
||||
- Then *X* atom swaps are attempted, one after the other.
|
||||
- For each swap, an atom *I* is selected randomly from the list of
|
||||
atom types specified by either the *types* or *diff* keywords.
|
||||
- One of *I*'s Voronoi neighbors *J* is selected using the
|
||||
distance-weighted probability for each neighbor detailed below.
|
||||
- The *I,J* atom IDs are communicated to all processors so that a
|
||||
global energy evaluation can be performed for the post-swap state
|
||||
of the system.
|
||||
- The swap is accepted or rejected based on the Metropolis criterion
|
||||
using the energy change of the system and the specified temperature
|
||||
*T*.
|
||||
|
||||
Here are a few comments on the computational cost of the swapping
|
||||
algorithm.
|
||||
|
||||
1. The cost of a global energy evaluation is similar to that of an MD
|
||||
timestep.
|
||||
|
||||
2. Similar to other MC algorithms in LAMMPS, improved parallel
|
||||
efficiency is achieved with a smaller number of atoms per
|
||||
processor than would typically be used in an standard MD
|
||||
simulation. This is because the per-energy evaluation cost
|
||||
increases relative to the balance of MD/MC steps as indicated by
|
||||
1., but the communication cost remains relatively constant for a
|
||||
given number of MD steps.
|
||||
|
||||
3. The MC portion of the simulation will run dramatically slower if
|
||||
the pair style uses different cutoffs for different atom types (or
|
||||
type pairs). This is because each atom swap then requires a
|
||||
rebuild of the neighbor list to ensure the post-swap global energy
|
||||
can be computed correctly.
|
||||
|
||||
Limitations are imposed on selection of *I,J* atom pairs to avoid
|
||||
swapping of atoms which are outside of a reasonable cutoff (e.g. due to
|
||||
a Voronoi tesselation near free surfaces) though the use of a
|
||||
distance-weighted probability scaling.
|
||||
|
||||
----------
|
||||
|
||||
This section gives more details on other arguments and keywords.
|
||||
|
||||
The random number generator (RNG) used by all the processors for MC
|
||||
operations is initialized with the specified *seed*.
|
||||
|
||||
The distance-based probability is weighted by the specified *R0* which
|
||||
sets the radius :math:`r_0` in this formula
|
||||
|
||||
.. math::
|
||||
|
||||
p_{ij} = e^{(\frac{r_{ij}}{r_0})^2}
|
||||
|
||||
where :math:`p_{ij}` is the probability of selecting atom :math:`j` to
|
||||
swap with atom :math:`i`. Typically, a value for *R0* around the
|
||||
average nearest-neighbor spacing is appropriate. Since this is simply a
|
||||
probability weighting, the swapping behavior is not very sensitive to
|
||||
the exact value of *R0*.
|
||||
|
||||
The required *voro-ID* value is the compute-ID of a
|
||||
:doc:`compute voronoi/atom <compute_voronoi_atom>` command like
|
||||
this:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
compute compute-ID group-ID voronoi/atom neighbors yes
|
||||
|
||||
It must return per-atom list of valid neighbor IDs as in the
|
||||
:doc:`compute voronoi/atom <compute_voronoi_atom>` command.
|
||||
|
||||
The keyword *types* takes two or more atom types as its values. Only
|
||||
atoms *I* of the first atom type will be selected. Only atoms *J* of the
|
||||
remaining atom types will be considered as potential swap partners.
|
||||
|
||||
The keyword *diff* take a single atom type as its value. Only atoms
|
||||
*I* of the that atom type will be selected. Atoms *J* of all
|
||||
remaining atom types will be considered as potential swap partners.
|
||||
This includes the atom type specified with the *diff* keyword to
|
||||
account for self-diffusive hops between two atoms of the same type.
|
||||
|
||||
Note that the *neighbors yes* option must be enabled for use with this
|
||||
fix. The group-ID should include all the atoms which this fix will
|
||||
potentially select. I.e. the group-ID used in the voronoi compute should
|
||||
include the same atoms as that indicated by the *types* keyword. If the
|
||||
*diff* keyword is used, the group-ID should include atoms of all types
|
||||
in the simulation.
|
||||
|
||||
The keyword *ke* takes *yes* (default) or *no* as its value. It two
|
||||
atoms are swapped with different masses, then a value of *yes* will
|
||||
rescale their respective velocities to conserve the kinetic energy of
|
||||
the system. A value of *no* will perform no rescaling, so that
|
||||
kinetic energy is not conserved. See the restriction on this keyword
|
||||
below.
|
||||
|
||||
The *region* keyword takes a *region-ID* as its value. If specified,
|
||||
then only atoms *I* and *J* within the geometric region will be
|
||||
considered as swap partners. See the :doc:`region <region>` command
|
||||
for details. This means the group-ID for the :doc:`compute
|
||||
voronoi/atom <compute_voronoi_atom>` command also need only contain
|
||||
atoms within the region.
|
||||
|
||||
The keyword *rates* can modify the swap rate based on the type of atom
|
||||
*J*. Ntype values must be specified, where Ntype = the number of atom
|
||||
types in the system. Each value is used to scale the probability
|
||||
weighting given by the equation above. In the third example command
|
||||
above, a simulation has 3 atoms types. Atom *I*s of type 1 are
|
||||
eligible for swapping. Swaps may occur with atom *J*s of all 3 types.
|
||||
Assuming all *J* atoms are equidistant from an atom *I*, *J* atoms of
|
||||
type 1 will be 3x more likely to be selected as a swap partner than
|
||||
atoms of type 2. And *J* atoms of type 3 will be 6.5x more likely to
|
||||
be selected than atoms of type 2. If the *rates* keyword is not used,
|
||||
all atom types will be treated with the same probability during selection
|
||||
of swap attempts.
|
||||
|
||||
|
||||
Restart, fix_modify, output, run start/stop, minimize info
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
This fix writes the state of the fix to :doc:`binary restart files
|
||||
<restart>`. This includes information about the random number generator
|
||||
seed, the next timestep for MC exchanges, and the number of exchange
|
||||
attempts and successes. 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.
|
||||
|
||||
None of the :doc:`fix_modify <fix_modify>` options are relevant to this
|
||||
fix.
|
||||
|
||||
This fix computes a global vector of length 2, which can be accessed
|
||||
by various :doc:`output commands <Howto_output>`. The vector values are
|
||||
the following global cumulative quantities:
|
||||
|
||||
#. swap attempts
|
||||
#. swap accepts
|
||||
|
||||
The vector values calculated by this fix are "intensive".
|
||||
|
||||
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>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
|
||||
This fix is part of the MC package. It is only enabled if LAMMPS was
|
||||
built with that package. See the :doc:`Build package <Build_package>`
|
||||
doc page for more info. Also this fix requires that the :ref:`VORONOI
|
||||
package <PKG-VORONOI>` is installed, otherwise the fix will not be
|
||||
compiled.
|
||||
|
||||
The :doc:`compute voronoi/atom <compute_voronoi_atom>` command
|
||||
referenced by the required voro-ID must return neighboring atoms as
|
||||
illustrated in the examples above.
|
||||
|
||||
If this fix is used with systems that do not have per-type masses
|
||||
(e.g. atom style sphere), the *ke* keyword must be set to *off* since
|
||||
the implemented algorithm will not be able to re-scale velocities
|
||||
properly.
|
||||
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
|
||||
:doc:`fix nvt <fix_nh>`, :doc:`compute voronoi/atom <compute_voronoi_atom>`
|
||||
:doc:`delete_atoms <delete_atoms>`, :doc:`fix gcmc <fix_gcmc>`,
|
||||
:doc:`fix atom/swap <fix_atom_swap>`, :doc:`fix mol/swap <fix_mol_swap>`,
|
||||
:doc:`fix sgcmc <fix_sgcmc>`
|
||||
|
||||
Default
|
||||
"""""""
|
||||
|
||||
The option defaults are *ke* = yes and *rates* = 1 for all atom types.
|
||||
|
||||
----------
|
||||
|
||||
.. _TavennerMDkMC:
|
||||
|
||||
**(Tavenner 2023)** J Tavenner, M Mendelev, J Lawson, Computational
|
||||
Materials Science, 218, 111929 (2023).
|
||||
173
doc/src/fix_set.rst
Normal file
173
doc/src/fix_set.rst
Normal file
@ -0,0 +1,173 @@
|
||||
.. index:: fix set
|
||||
|
||||
fix set command
|
||||
===============
|
||||
|
||||
Syntax
|
||||
""""""
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
fix ID group-ID set Nfreq rnflag set-args
|
||||
|
||||
* ID, group-ID are documented in :doc:`fix <fix>` command
|
||||
* set = style name of this fix command
|
||||
* Nfreq = reset per-atom properties every this many timesteps
|
||||
* rnflag = 1 to reneighbor on next timestep, 0 to not
|
||||
* set-args = identical to args for the :doc:`set <set>` command
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
fix 10 all set 1 0 group all i_dump v_new
|
||||
fix 10 all set 1 0 group all i_dump v_turnoff
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
|
||||
Reset one or more properties of one or more atoms once every *Nfreq*
|
||||
steps during a simulation.
|
||||
|
||||
If the *rnflag* for reneighboring is set to 1, then a reneighboring
|
||||
will be triggered on the next timestep (since the fix set operation
|
||||
occurs at the end of the current timestep). This is important to do
|
||||
if this command changes per-atom properties that need to be
|
||||
communicated to ghost atoms. If this is not the case, an *rnflag*
|
||||
setting of 0 can be used; reneighboring will only be triggered on
|
||||
subsequent timesteps by the usual neighbor list criteria; see the
|
||||
:doc:`neigh_modify command <neigh_modify>`.
|
||||
|
||||
Here are two examples where an *rnflag* setting of 1 are needed. If a
|
||||
custom per-atom property is changed and the :doc:`fix property/atom
|
||||
<fix_property_atom>` command to create the property used the *ghost
|
||||
yes* keyword. Or if per-atom charges are changed, all pair styles
|
||||
which compute Coulombic interactions require charge values for ghost
|
||||
atoms. In both these examples, the re-neighboring will trigger the
|
||||
changes in the owned atom properties to be immediately communicated to
|
||||
ghost atoms.
|
||||
|
||||
The arguments following *Nfreq* and *rnflag* are identical to those
|
||||
allowed for the :doc:`set <set>` command, as in the examples above and
|
||||
below.
|
||||
|
||||
Note that the group-ID setting for this command is ignored. The
|
||||
syntax for the :doc:`set <set>` arguments allows selection of which
|
||||
atoms have their properties reset.
|
||||
|
||||
This command can only be used to reset an atom property using a
|
||||
per-atom variable. This option in allowed by many, but not all, of
|
||||
the keyword/value pairs supported by the :doc:`set <set>` command.
|
||||
The reason for this restriction is that if a per-atom variable is not
|
||||
used, this command will typically not change atom properties during
|
||||
the simulation.
|
||||
|
||||
The :doc:`set <set>` command can be used with similar syntax to this
|
||||
command to reset atom properties once before or between simulations.
|
||||
|
||||
----------
|
||||
|
||||
Here is an example of input script commands which will output atoms
|
||||
into a dump file only when their x-velocity crosses a threshold value
|
||||
*vthresh* for the first time. Their position and x-velocity will then
|
||||
be output every step for *twindow* timesteps.
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
variable vthresh equal 2 # threshold velocity
|
||||
variable twindow equal 10 # dump for this many steps
|
||||
#
|
||||
# define custom property i_dump to store timestep threshold is crossed
|
||||
#
|
||||
fix 2 all property/atom i_dump
|
||||
set group all i_dump -1
|
||||
#
|
||||
# fix set command checks for threshold crossings every step
|
||||
# resets i_dump from -1 to current timestep when crossing occurs
|
||||
#
|
||||
variable start atom "vx > v_vthresh && i_dump == -1"
|
||||
variable new atom ternary(v_start,step,i_dump)
|
||||
fix 3 all set 1 0 group all i_dump v_new
|
||||
#
|
||||
# dump command with thresh which enforces twindow
|
||||
#
|
||||
dump 1 all custom 1 tmp.dump id x y vx i_dump
|
||||
variable dumpflag atom "i_dump >= 0 && (step-i_dump) < v_twindow"
|
||||
dump_modify 1 thresh v_dumpflag == 1
|
||||
#
|
||||
# run the simulation
|
||||
# final dump with all atom IDs which crossed threshold on which timestep
|
||||
#
|
||||
run 1000
|
||||
write_dump all custom tmp.dump.final id i_dump modify thresh i_dump >= 0
|
||||
|
||||
The tmp.dump.final file lists which atoms crossed the velocity
|
||||
threshold. This command will print the *twindow* timesteps when a
|
||||
specific atom ID (104 in this case) was output in the tmp.dump file:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
% grep "^104 " tmp.dump
|
||||
|
||||
If these commands are used instead of the above, then an atom can
|
||||
cross the velocity threshold multiple times, and will be output for
|
||||
*twindow* timesteps each time. However the write_dump command is no
|
||||
longer useful.
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
variable vthresh equal 2 # threshold velocity
|
||||
variable twindow equal 10 # dump for this many steps
|
||||
#
|
||||
# define custom property i_dump to store timestep threshold is crossed
|
||||
#
|
||||
fix 2 all property/atom i_dump
|
||||
set group all i_dump -1
|
||||
#
|
||||
# fix set command checks for threshold crossings every step
|
||||
# resets i_dump from -1 to current timestep when crossing occurs
|
||||
#
|
||||
variable start atom "vx > v_vthresh && i_dump == -1"
|
||||
variable turnon atom ternary(v_start,step,i_dump)
|
||||
variable stop atom "v_turnon >= 0 && (step-v_turnon) < v_twindow"
|
||||
variable turnoff atom ternary(v_stop,v_turnon,-1)
|
||||
fix 3 all set 1 0 group all i_dump v_turnoff
|
||||
#
|
||||
# dump command with thresh which enforces twindow
|
||||
#
|
||||
dump 1 all custom 1 tmp.dump id x y vx i_dump
|
||||
variable dumpflag atom "i_dump >= 0 && (step-i_dump) < v_twindow"
|
||||
dump_modify 1 thresh v_dumpflag == 1
|
||||
#
|
||||
# run the simulation
|
||||
#
|
||||
run 1000
|
||||
|
||||
----------
|
||||
|
||||
Restart, fix_modify, output, run start/stop, minimize info
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
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. No global or per-atom quantities are stored by
|
||||
this fix for access by various :doc:`output commands <Howto_output>`.
|
||||
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>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
|
||||
none
|
||||
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
|
||||
:doc:`set <set>`
|
||||
|
||||
Default
|
||||
"""""""
|
||||
|
||||
none
|
||||
@ -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
|
||||
""""""""""""
|
||||
|
||||
|
||||
@ -100,6 +100,56 @@ first is assigned to intra-molecular interactions (i.e. both atoms
|
||||
have the same molecule ID), the second to inter-molecular interactions
|
||||
(i.e. interacting atoms have different molecule IDs).
|
||||
|
||||
.. admonition:: When **NOT** to use a hybrid pair style
|
||||
:class: warning
|
||||
|
||||
Using pair style *hybrid* can be very tempting to use if you need a
|
||||
**many-body potential** supporting a mix of elements for which you
|
||||
cannot find a potential file that covers *all* of them. Regardless
|
||||
of how this is set up, there will be *errors*. The major use case
|
||||
where the error is *small*, is when the many-body sub-styles are used
|
||||
on different objects (for example a slab and a liquid, a metal and a
|
||||
nano-machining work piece). In that case the *mixed* terms
|
||||
**should** be provided by a pair-wise additive potential (like
|
||||
Lennard-Jones or Morse) to avoid unexpected behavior and reduce
|
||||
errors. LAMMPS cannot easily check for this condition and thus will
|
||||
accept good and bad choices alike.
|
||||
|
||||
Outside of this, we *strongly* recommend *against* using pair style
|
||||
hybrid with many-body potentials for the following reasons:
|
||||
|
||||
1. When trying to combine EAM or MEAM potentials, there is a *large*
|
||||
error in the embedding term, since it is computed separately for
|
||||
each sub-style only.
|
||||
|
||||
2. When trying to combine many-body potentials like Stillinger-Weber,
|
||||
Tersoff, AIREBO, Vashishta, or similar, you have to understand
|
||||
that the potential of a sub-style cannot be applied in a pair-wise
|
||||
fashion but will need to be applied to multiples of atoms
|
||||
(e.g. a Tersoff potential of elements A and B includes the
|
||||
interactions A-A, B-B, A-B, A-A-A, A-A-B, A-B-B, A-B-A, B-A-A,
|
||||
B-A-B, B-B-A, B-B-B; AIREBO also considers all quadruples of
|
||||
atom elements).
|
||||
|
||||
3. When one of the sub-styles uses charge-equilibration (= QEq; like
|
||||
in ReaxFF or COMB) you have inconsistent QEq behavior because
|
||||
either you try to apply QEq to *all* atoms but then you are
|
||||
missing the QEq parameters for the non-QEq pair style (and it
|
||||
would be inconsistent to apply QEq for pair styles that are not
|
||||
parameterized for QEq) or else you would have either no charges or
|
||||
fixed charges interacting with the QEq which also leads to
|
||||
inconsistent behavior between two sub-styles. When attempting to
|
||||
use multiple ReaxFF instances to combine different potential
|
||||
files, you might be able to work around the QEq limitations, but
|
||||
point 2. still applies.
|
||||
|
||||
We understand that it is frustrating to not be able to run simulations
|
||||
due to lack of available potential files, but that does not justify
|
||||
combining potentials in a broken way via pair style hybrid. This is
|
||||
not what the hybrid pair styles are designed for.
|
||||
|
||||
----------
|
||||
|
||||
Here are two examples of hybrid simulations. The *hybrid* style could
|
||||
be used for a simulation of a metal droplet on a LJ surface. The metal
|
||||
atoms interact with each other via an *eam* potential, the surface atoms
|
||||
@ -374,12 +424,11 @@ selected sub-style.
|
||||
|
||||
----------
|
||||
|
||||
.. note::
|
||||
|
||||
Several of the potentials defined via the pair_style command in
|
||||
LAMMPS are really many-body potentials, such as Tersoff, AIREBO, MEAM,
|
||||
ReaxFF, etc. The way to think about using these potentials in a
|
||||
hybrid setting is as follows.
|
||||
Even though the command name "pair_style" would suggest that these are
|
||||
pair-wise interactions, several of the potentials defined via the
|
||||
pair_style command in LAMMPS are really many-body potentials, such as
|
||||
Tersoff, AIREBO, MEAM, ReaxFF, etc. The way to think about using these
|
||||
potentials in a hybrid setting is as follows.
|
||||
|
||||
A subset of atom types is assigned to the many-body potential with a
|
||||
single :doc:`pair_coeff <pair_coeff>` command, using "\* \*" to include
|
||||
|
||||
@ -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
|
||||
"""""""
|
||||
|
||||
@ -103,14 +103,16 @@ must be done.
|
||||
|
||||
.. note::
|
||||
|
||||
If your input script changes the system between 2 runs, then the
|
||||
initial setup must be performed to ensure the change is recognized by
|
||||
all parts of the code that are affected. Examples are adding a
|
||||
:doc:`fix <fix>` or :doc:`dump <dump>` or :doc:`compute <compute>`, changing
|
||||
a :doc:`neighbor <neigh_modify>` list parameter, or writing restart file
|
||||
which can migrate atoms between processors. LAMMPS has no easy way to
|
||||
check if this has happened, but it is an error to use the *pre no*
|
||||
option in this case.
|
||||
If your input script "changes" the system between 2 runs, then the
|
||||
initial setup typically needs to be performed to ensure the change
|
||||
is recognized by all parts of the code that are affected. Examples
|
||||
are adding a :doc:`fix <fix>` or :doc:`dump <dump>` or
|
||||
:doc:`compute <compute>`, changing a :doc:`neighbor <neigh_modify>`
|
||||
list parameter, using the :doc:`set <set>` command, or writing a
|
||||
restart file via the :doc:`write_restart <write_restart>` command,
|
||||
which can migrate atoms between processors. LAMMPS has no easy way
|
||||
to check if this has happened, but it is an error to use the *pre
|
||||
no* option in these cases.
|
||||
|
||||
If *post* is specified as "no", the full timing summary is skipped;
|
||||
only a one-line summary timing is printed.
|
||||
|
||||
791
doc/src/set.rst
791
doc/src/set.rst
@ -22,21 +22,110 @@ Syntax
|
||||
for style = *region*, ID = a region ID
|
||||
|
||||
* one or more keyword/value pairs may be appended
|
||||
* keyword = *type* or *type/fraction* or *type/ratio* or *type/subset*
|
||||
or *mol* or *x* or *y* or *z* or *vx* or *vy* or *vz* or *charge* or
|
||||
*dipole* or *dipole/random* or *quat* or *spin/atom* or *spin/atom/random* or
|
||||
*spin/electron* or *radius/electron* or
|
||||
*quat* or *quat/random* or *diameter* or *shape* or *length* or *tri* or
|
||||
*theta* or *theta/random* or *angmom* or *omega* or
|
||||
*mass* or *density* or *density/disc* or *temperature* or
|
||||
*volume* or *image* or *bond* or *angle* or *dihedral* or
|
||||
*improper* or *sph/e* or *sph/cv* or *sph/rho* or
|
||||
*smd/contact/radius* or *smd/mass/density* or *dpd/theta* or
|
||||
*edpd/temp* or *edpd/cv* or *cc* or *epsilon* or
|
||||
*i_name* or *d_name* or *i2_name* or *d2_name*
|
||||
|
||||
* keyword = *angle* or *angmom* or *bond* or *cc* or *charge* or
|
||||
*density* or *density/disc* or *diameter* or *dihedral* or *dipole*
|
||||
or *dipole/random* or *dpd/theta* or *edpd/cv* or *edpd/temp* or
|
||||
*epsilon* or *image* or *improper* or *length* or *mass* or *mol* or
|
||||
*omega* or *quat* or *quat/random* or *radius/electron* or *shape* or
|
||||
*smd/contact/radius* or *smd/mass/density* or *sph/cv* or *sph/e* or
|
||||
*sph/rho* or *spin/atom* or *spin/atom/random* or *spin/electron* or
|
||||
*temperature* or *theta* or *theta/random* or *tri* or *type* or
|
||||
*type/fraction* or *type/ratio* or *type/subset* or *volume* or *vx*
|
||||
or *vy* or *vz* or *x* or *y* or *z* or *i_name* or *d_name* or
|
||||
*i2_name* or *d2_name*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*angle* value = numeric angle type or angle type label, for all angles between selected atoms
|
||||
*angmom* values = Lx Ly Lz
|
||||
Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units)
|
||||
any of Lx,Ly,Lz can be an atom-style variable (see below)
|
||||
*bond* value = numeric bond type or bond type label, for all bonds between selected atoms
|
||||
*cc* values = index cc
|
||||
index = index of a chemical species (1 to Nspecies)
|
||||
cc = chemical concentration of tDPD particles for a species (mole/volume units)
|
||||
cc can be an atom-style variable (see below)
|
||||
*charge* value = atomic charge (charge units)
|
||||
value can be an atom-style variable (see below)
|
||||
*density* value = particle density for a sphere or ellipsoid (mass/distance\^3 units), or for a triangle (mass/distance\^2 units) or line (mass/distance units) particle
|
||||
value can be an atom-style variable (see below)
|
||||
*density/disc* value = particle density for a 2d disc or ellipse (mass/distance\^2 units)
|
||||
value can be an atom-style variable (see below)
|
||||
*diameter* value = diameter of spherical particle (distance units)
|
||||
value can be an atom-style variable (see below)
|
||||
*dihedral* value = numeric dihedral type or dihedral type label, for all dihedrals between selected atoms
|
||||
*dipole* values = x y z
|
||||
x,y,z = orientation of dipole moment vector
|
||||
any of x,y,z can be an atom-style variable (see below)
|
||||
*dipole/random* values = seed Dlen
|
||||
seed = random # seed (positive integer) for dipole moment orientations
|
||||
Dlen = magnitude of dipole moment (dipole units)
|
||||
*dpd/theta* value = internal temperature of DPD particles (temperature units)
|
||||
value can be an atom-style variable (see below)
|
||||
value can be NULL which sets internal temp of each particle to KE temp
|
||||
*edpd/cv* value = volumetric heat capacity of eDPD particles (energy/temperature/volume units)
|
||||
value can be an atom-style variable (see below)
|
||||
*edpd/temp* value = temperature of eDPD particles (temperature units)
|
||||
value can be an atom-style variable (see below)
|
||||
*epsilon* value = dielectric constant of the medium where the atoms reside
|
||||
value can be an atom-style variable (see below)
|
||||
*image* values = nx ny nz
|
||||
nx,ny,nz = which periodic image of the simulation box the atom is in
|
||||
any of nx,ny,nz can be an atom-style variable (see below)
|
||||
*improper* value = numeric improper type or improper type label, for all impropers between selected atoms
|
||||
*length* value = len
|
||||
len = length of line segment (distance units)
|
||||
len can be an atom-style variable (see below)
|
||||
*mass* value = per-atom mass (mass units)
|
||||
value can be an atom-style variable (see below)
|
||||
*mol* value = molecule ID
|
||||
the moleclue ID can be an atom-style variable (see below)
|
||||
*omega* values = Wx Wy Wz
|
||||
Wx,Wy,Wz = components of angular velocity vector (radians/time units)
|
||||
any of Wx,Wy,Wz can be an atom-style variable (see below)
|
||||
*quat* values = a b c theta
|
||||
a,b,c = unit vector to rotate particle around via right-hand rule
|
||||
theta = rotation angle (degrees)
|
||||
any of a,b,c,theta values can be an atom-style variable (see below)
|
||||
*quat/random* value = seed
|
||||
seed = random # seed (positive integer) for quaternion orientations
|
||||
*radius/electron* value = eradius
|
||||
eradius = electron radius (or fixed-core radius) (distance units)
|
||||
value can be an atom-style variable (see below)
|
||||
*shape* values = Sx Sy Sz
|
||||
Sx,Sy,Sz = 3 diameters of ellipsoid (distance units)
|
||||
any of Sx,Sy,Sz can be an atom-style variable (see below)
|
||||
*smd/contact/radius* value = radius for short range interactions, i.e. contact and friction
|
||||
value can be an atom-style variable (see below)
|
||||
*smd/mass/density* value = set particle mass based on volume by providing a mass density
|
||||
value can be an atom-style variable (see below)
|
||||
*sph/cv* value = heat capacity of SPH particles (need units)
|
||||
value can be an atom-style variable (see below)
|
||||
*sph/e* value = energy of SPH particles (need units)
|
||||
value can be an atom-style variable (see below)
|
||||
*sph/rho* value = density of SPH particles (need units)
|
||||
value can be an atom-style variable (see below)
|
||||
*spin/atom* values = g x y z
|
||||
g = magnitude of magnetic spin vector (in Bohr magneton's unit)
|
||||
x,y,z = orientation of magnetic spin vector
|
||||
any of x,y,z can be an atom-style variable (see below)
|
||||
*spin/atom/random* values = seed Dlen
|
||||
seed = random # seed (positive integer) for magnetic spin orientations
|
||||
Dlen = magnitude of magnetic spin vector (in Bohr magneton's unit)
|
||||
*spin/electron* value = espin
|
||||
espin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP)
|
||||
value can be an atom-style variable (see below)
|
||||
*temperature* value = temperature for finite-size particles (temperature units)
|
||||
value can be an atom-style variable (see below)
|
||||
*theta* value = angle (degrees)
|
||||
angle = orientation of line segment with respect to x-axis
|
||||
value can be an atom-style variable (see below)
|
||||
*theta/random* value = seed
|
||||
seed = random # seed (positive integer) for line segment orienations
|
||||
*tri* value = side
|
||||
side = side length of equilateral triangle (distance units)
|
||||
value can be an atom-style variable (see below)
|
||||
*type* value = numeric atom type or type label
|
||||
value can be an atom-style variable (see below)
|
||||
*type/fraction* values = type fraction seed
|
||||
@ -51,104 +140,22 @@ Syntax
|
||||
type = numeric atom type or type label
|
||||
Nsubset = exact number of selected atoms to set to new atom type
|
||||
seed = random # seed (positive integer)
|
||||
*mol* value = molecule ID
|
||||
value can be an atom-style variable (see below)
|
||||
*x*,\ *y*,\ *z* value = atom coordinate (distance units)
|
||||
*volume* value = particle volume for Peridynamic particle (distance\^3 units)
|
||||
value can be an atom-style variable (see below)
|
||||
*vx*,\ *vy*,\ *vz* value = atom velocity (velocity units)
|
||||
value can be an atom-style variable (see below)
|
||||
*charge* value = atomic charge (charge units)
|
||||
*x*,\ *y*,\ *z* value = atom coordinate (distance units)
|
||||
value can be an atom-style variable (see below)
|
||||
*dipole* values = x y z
|
||||
x,y,z = orientation of dipole moment vector
|
||||
any of x,y,z can be an atom-style variable (see below)
|
||||
*dipole/random* value = seed Dlen
|
||||
seed = random # seed (positive integer) for dipole moment orientations
|
||||
Dlen = magnitude of dipole moment (dipole units)
|
||||
*spin/atom* values = g x y z
|
||||
g = magnitude of magnetic spin vector (in Bohr magneton's unit)
|
||||
x,y,z = orientation of magnetic spin vector
|
||||
any of x,y,z can be an atom-style variable (see below)
|
||||
*spin/atom/random* value = seed Dlen
|
||||
seed = random # seed (positive integer) for magnetic spin orientations
|
||||
Dlen = magnitude of magnetic spin vector (in Bohr magneton's unit)
|
||||
*radius/electron* values = eradius
|
||||
eradius = electron radius (or fixed-core radius) (distance units)
|
||||
*spin/electron* value = espin
|
||||
espin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP)
|
||||
*quat* values = a b c theta
|
||||
a,b,c = unit vector to rotate particle around via right-hand rule
|
||||
theta = rotation angle (degrees)
|
||||
any of a,b,c,theta can be an atom-style variable (see below)
|
||||
*quat/random* value = seed
|
||||
seed = random # seed (positive integer) for quaternion orientations
|
||||
*diameter* value = diameter of spherical particle (distance units)
|
||||
value can be an atom-style variable (see below)
|
||||
*shape* value = Sx Sy Sz
|
||||
Sx,Sy,Sz = 3 diameters of ellipsoid (distance units)
|
||||
*length* value = len
|
||||
len = length of line segment (distance units)
|
||||
len can be an atom-style variable (see below)
|
||||
*tri* value = side
|
||||
side = side length of equilateral triangle (distance units)
|
||||
side can be an atom-style variable (see below)
|
||||
*theta* value = angle (degrees)
|
||||
angle = orientation of line segment with respect to x-axis
|
||||
angle can be an atom-style variable (see below)
|
||||
*theta/random* value = seed
|
||||
seed = random # seed (positive integer) for line segment orienations
|
||||
*angmom* values = Lx Ly Lz
|
||||
Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units)
|
||||
any of Lx,Ly,Lz can be an atom-style variable (see below)
|
||||
*omega* values = Wx Wy Wz
|
||||
Wx,Wy,Wz = components of angular velocity vector (radians/time units)
|
||||
any of wx,wy,wz can be an atom-style variable (see below)
|
||||
*mass* value = per-atom mass (mass units)
|
||||
value can be an atom-style variable (see below)
|
||||
*density* value = particle density for a sphere or ellipsoid (mass/distance\^3 units), or for a triangle (mass/distance\^2 units) or line (mass/distance units) particle
|
||||
value can be an atom-style variable (see below)
|
||||
*density/disc* value = particle density for a 2d disc or ellipse (mass/distance\^2 units)
|
||||
value can be an atom-style variable (see below)
|
||||
*temperature* value = temperature for finite-size particles (temperature units)
|
||||
value can be an atom-style variable (see below)
|
||||
*volume* value = particle volume for Peridynamic particle (distance\^3 units)
|
||||
value can be an atom-style variable (see below)
|
||||
*image* nx ny nz
|
||||
nx,ny,nz = which periodic image of the simulation box the atom is in
|
||||
any of nx,ny,nz can be an atom-style variable (see below)
|
||||
*bond* value = numeric bond type or bond type label, for all bonds between selected atoms
|
||||
*angle* value = numeric angle type or angle type label, for all angles between selected atoms
|
||||
*dihedral* value = numeric dihedral type or dihedral type label, for all dihedrals between selected atoms
|
||||
*improper* value = numeric improper type or improper type label, for all impropers between selected atoms
|
||||
*rheo/rho* value = density of RHEO particles (mass/distance\^3)
|
||||
*rheo/status* value = status or phase of RHEO particles (unitless)
|
||||
*sph/e* value = energy of SPH particles (need units)
|
||||
value can be an atom-style variable (see below)
|
||||
*sph/cv* value = heat capacity of SPH particles (need units)
|
||||
value can be an atom-style variable (see below)
|
||||
*sph/rho* value = density of SPH particles (need units)
|
||||
value can be an atom-style variable (see below)
|
||||
*smd/contact/radius* = radius for short range interactions, i.e. contact and friction
|
||||
value can be an atom-style variable (see below)
|
||||
*smd/mass/density* = set particle mass based on volume by providing a mass density
|
||||
value can be an atom-style variable (see below)
|
||||
*dpd/theta* value = internal temperature of DPD particles (temperature units)
|
||||
value can be an atom-style variable (see below)
|
||||
value can be NULL which sets internal temp of each particle to KE temp
|
||||
*edpd/temp* value = temperature of eDPD particles (temperature units)
|
||||
value can be an atom-style variable (see below)
|
||||
*edpd/cv* value = volumetric heat capacity of eDPD particles (energy/temperature/volume units)
|
||||
value can be an atom-style variable (see below)
|
||||
*cc* values = index cc
|
||||
index = index of a chemical species (1 to Nspecies)
|
||||
cc = chemical concentration of tDPD particles for a species (mole/volume units)
|
||||
*epsilon* value = dielectric constant of the medium where the atoms reside
|
||||
*i_name* value = custom integer vector with name
|
||||
value can be an atom-style variable (see below)
|
||||
*d_name* value = custom floating-point vector with name
|
||||
*i2_name* value = column of a custom integer array with name
|
||||
value can be an atom-style variable (see below)
|
||||
*i2_name* value = custom integer array with name
|
||||
column specified as i2_name[N] where N is 1 to Ncol
|
||||
*d2_name* value = column of a custom floating-point array with name
|
||||
value can be an atom-style variable (see below)
|
||||
*d2_name* value = custom floating-point array with name
|
||||
column specified as d2_name[N] where N is 1 to Ncol
|
||||
value can be an atom-style variable (see below)
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
@ -177,22 +184,26 @@ Description
|
||||
|
||||
Set one or more properties of one or more atoms. Since atom
|
||||
properties are initially assigned by the :doc:`read_data <read_data>`,
|
||||
:doc:`read_restart <read_restart>` or :doc:`create_atoms <create_atoms>`
|
||||
commands, this command changes those assignments. This can be useful
|
||||
for overriding the default values assigned by the
|
||||
:doc:`create_atoms <create_atoms>` command (e.g. charge = 0.0). It can
|
||||
be useful for altering pairwise and molecular force interactions,
|
||||
:doc:`read_restart <read_restart>` or :doc:`create_atoms
|
||||
<create_atoms>` commands, this command changes those assignments.
|
||||
This can be useful for overriding the default values assigned by the
|
||||
:doc:`create_atoms <create_atoms>` command (e.g. charge = 0.0). It
|
||||
can be useful for altering pairwise and molecular force interactions,
|
||||
since force-field coefficients are defined in terms of types. It can
|
||||
be used to change the labeling of atoms by atom type or molecule ID
|
||||
when they are output in :doc:`dump <dump>` files. It can also be useful
|
||||
for debugging purposes; i.e. positioning an atom at a precise location
|
||||
to compute subsequent forces or energy.
|
||||
when they are output in :doc:`dump <dump>` files. It can also be
|
||||
useful for debugging purposes; i.e. positioning an atom at a precise
|
||||
location to compute subsequent forces or energy.
|
||||
|
||||
Note that the *style* and *ID* arguments determine which atoms have
|
||||
their properties reset. The remaining keywords specify which
|
||||
properties to reset and what the new values are. Some strings like
|
||||
*type* or *mol* can be used as a style and/or a keyword.
|
||||
|
||||
The :doc:`fix set <fix_set>` command can be used with similar syntax
|
||||
to this command to reset atom properties once every *N* steps during a
|
||||
simulation using via atom-style variables.
|
||||
|
||||
----------
|
||||
|
||||
This section describes how to select which atoms to change
|
||||
@ -211,8 +222,8 @@ can be specified, e.g. "C". The style *mol* selects all the atoms in
|
||||
a range of molecule IDs.
|
||||
|
||||
In each of the range cases, the range can be specified as a single
|
||||
numeric value, or a wildcard asterisk can be used to specify a range
|
||||
of values. This takes the form "\*" or "\*n" or "n\*" or "m\*n". For
|
||||
numeric value, or with a wildcard asterisk to specify a range of
|
||||
values. This takes the form "\*" or "\*n" or "n\*" or "m\*n". For
|
||||
example, for the style *type*, if N = the number of atom types, then
|
||||
an asterisk with no numeric values means all types from 1 to N. A
|
||||
leading asterisk means all types from 1 to n (inclusive). A trailing
|
||||
@ -222,25 +233,25 @@ means all types from m to n (inclusive). For all the styles except
|
||||
|
||||
The style *group* selects all the atoms in the specified group. The
|
||||
style *region* selects all the atoms in the specified geometric
|
||||
region. See the :doc:`group <group>` and :doc:`region <region>` commands
|
||||
for details of how to specify a group or region.
|
||||
region. See the :doc:`group <group>` and :doc:`region <region>`
|
||||
commands for details of how to specify a group or region.
|
||||
|
||||
----------
|
||||
|
||||
This section describes the keyword options for which properties to
|
||||
The next section describes the keyword options for which properties to
|
||||
change, for the selected atoms.
|
||||
|
||||
Note that except where explicitly prohibited below, all of the
|
||||
keywords allow an :doc:`atom-style or atomfile-style variable
|
||||
<variable>` to be used as the specified value(s). If the value is a
|
||||
variable, it should be specified as v_name, where name is the
|
||||
variable name. In this case, the variable will be evaluated, and its
|
||||
resulting per-atom value used to determine the value assigned to each
|
||||
selected atom. Note that the per-atom value from the variable will be
|
||||
ignored for atoms that are not selected via the *style* and *ID*
|
||||
settings explained above. A simple way to use per-atom values from
|
||||
the variable to reset a property for all atoms is to use style *atom*
|
||||
with *ID* = "\*"; this selects all atom IDs.
|
||||
variable, it should be specified as v_name, where name is the variable
|
||||
name. In this case, the variable will be evaluated, and its resulting
|
||||
per-atom value used to determine the value assigned to each selected
|
||||
atom. Note that the per-atom value from the variable will be ignored
|
||||
for atoms that are not selected via the *style* and *ID* settings
|
||||
explained above. A simple way to use per-atom values from the
|
||||
variable to reset a property for all atoms is to use style *atom* with
|
||||
*ID* = "\*"; this selects all atom IDs.
|
||||
|
||||
Atom-style variables can specify formulas with various mathematical
|
||||
functions, and include :doc:`thermo_style <thermo_style>` command
|
||||
@ -256,52 +267,110 @@ from a file.
|
||||
.. note::
|
||||
|
||||
Atom-style and atomfile-style variables return floating point
|
||||
per-atom values. If the values are assigned to an integer variable,
|
||||
such as the molecule ID, then the floating point value is truncated to
|
||||
its integer portion, e.g. a value of 2.6 would become 2.
|
||||
per-atom values. If the values are assigned to an integer
|
||||
variable, such as the molecule ID, then the floating point value is
|
||||
truncated to its integer portion, e.g. a value of 2.6 would
|
||||
become 2.
|
||||
|
||||
----------
|
||||
|
||||
.. versionchanged:: 28Mar2023
|
||||
|
||||
Support for type labels was added for setting atom, bond, angle,
|
||||
dihedral, and improper types
|
||||
Support for type labels was added for setting angle types
|
||||
|
||||
Keyword *type* sets the atom type for all selected atoms. A specified
|
||||
value can be either a numeric atom type or an atom type label. When
|
||||
using a numeric type, the specified value must be from 1 to ntypes,
|
||||
where ntypes was set by the :doc:`create_box <create_box>` command or
|
||||
the *atom types* field in the header of the data file read by the
|
||||
:doc:`read_data <read_data>` command. When using a type label it must
|
||||
have been defined previously. See the :doc:`Howto type labels
|
||||
<Howto_type_labels>` doc page for the allowed syntax of type labels
|
||||
and a general discussion of how type labels can be used.
|
||||
Keyword *angle* sets the angle type of all angles of selected atoms to
|
||||
the specified value. The value can be a numeric type from 1 to
|
||||
nangletypes. Or it can be a angle type label. See the :doc:`Howto
|
||||
type labels <Howto_type_labels>` doc page for the allowed syntax of
|
||||
type labels and a general discussion of how type labels can be used.
|
||||
All atoms in a particular angle must be selected atoms in order for
|
||||
the change to be made. The value of nangletypes was set by the *angle
|
||||
types* field in the header of the data file read by the
|
||||
:doc:`read_data <read_data>` command. This keyword does NOT allow use
|
||||
of an atom-style variable.
|
||||
|
||||
Keyword *type/fraction* sets the atom type for a fraction of the selected
|
||||
atoms. The actual number of atoms changed is not guaranteed
|
||||
to be exactly the specified fraction (0 <= *fraction* <= 1), but
|
||||
should be statistically close. Random numbers are used in such a way
|
||||
that a particular atom is changed or not changed, regardless of how
|
||||
many processors are being used. This keyword does not allow use of an
|
||||
atom-style variable.
|
||||
Keyword *angmom* sets the angular momentum of selected atoms. The
|
||||
particles must be ellipsoids as defined by the :doc:`atom_style
|
||||
ellipsoid <atom_style>` command or triangles as defined by the
|
||||
:doc:`atom_style tri <atom_style>` command. The angular momentum
|
||||
vector of the particles is set to the 3 specified components.
|
||||
|
||||
Keywords *type/ratio* and *type/subset* also set the atom type for a
|
||||
fraction of the selected atoms. The actual number of atoms changed
|
||||
will be exactly the requested number. For *type/ratio* the specified
|
||||
fraction (0 <= *fraction* <= 1) determines the number. For
|
||||
*type/subset*, the specified *Nsubset* is the number. An iterative
|
||||
algorithm is used which ensures the correct number of atoms are
|
||||
selected, in a perfectly random fashion. Which atoms are selected
|
||||
will change with the number of processors used. These keywords do not
|
||||
allow use of an atom-style variable.
|
||||
.. versionchanged:: 28Mar2023
|
||||
|
||||
Keyword *mol* sets the molecule ID for all selected atoms. The
|
||||
:doc:`atom style <atom_style>` being used must support the use of
|
||||
molecule IDs.
|
||||
Support for type labels was added for setting bond types
|
||||
|
||||
Keywords *x*, *y*, *z*, and *charge* set the coordinates or
|
||||
charge of all selected atoms. For *charge*, the :doc:`atom style
|
||||
<atom_style>` being used must support the use of atomic
|
||||
charge. Keywords *vx*, *vy*, and *vz* set the velocities of all
|
||||
selected atoms.
|
||||
Keyword *bond* sets the bond type of all bonds of selected atoms to
|
||||
the specified value. The value can be a numeric type from 1 to
|
||||
nbondtypes. Or it can be a bond type label. See the :doc:`Howto type
|
||||
labels <Howto_type_labels>` doc page for the allowed syntax of type
|
||||
labels and a general discussion of how type labels can be used. All
|
||||
atoms in a particular bond must be selected atoms in order for the
|
||||
change to be made. The value of nbondtypes was set by the *bond
|
||||
types* field in the header of the data file read by the
|
||||
:doc:`read_data <read_data>` command. This keyword does NOT allow use
|
||||
of an atom-style variable.
|
||||
|
||||
Keyword *cc* sets the chemical concentration of a tDPD particle for a
|
||||
specified species as defined by the DPD-MESO package. Currently, only
|
||||
:doc:`atom_style tdpd <atom_style>` defines particles with this
|
||||
attribute. An integer for "index" selects a chemical species (1 to
|
||||
Nspecies) where Nspecies is set by the atom_style command. The value
|
||||
for the chemical concentration must be >= 0.0.
|
||||
|
||||
Keyword *charge* set the charge of all selected atoms. The :doc:`atom
|
||||
style <atom_style>` being used must support the use of atomic charge.
|
||||
|
||||
Keyword *density* or *density/disc* also sets the mass of all selected
|
||||
particles, but in a different way. The particles must have a per-atom
|
||||
mass attribute, as defined by the :doc:`atom_style <atom_style>`
|
||||
command. If the atom has a radius attribute (see :doc:`atom_style
|
||||
sphere <atom_style>`) and its radius is non-zero, its mass is set from
|
||||
the density and particle volume for 3d systems (the input density is
|
||||
assumed to be in mass/distance\^3 units). For 2d, the default is for
|
||||
LAMMPS to model particles with a radius attribute as spheres.
|
||||
However, if the *density/disc* keyword is used, then they can be
|
||||
modeled as 2d discs (circles). Their mass is set from the density and
|
||||
particle area (the input density is assumed to be in mass/distance\^2
|
||||
units).
|
||||
|
||||
If the atom has a shape attribute (see :doc:`atom_style ellipsoid
|
||||
<atom_style>`) and its 3 shape parameters are non-zero, then its mass
|
||||
is set from the density and particle volume (the input density is
|
||||
assumed to be in mass/distance\^3 units). The *density/disc* keyword
|
||||
has no effect; it does not (yet) treat 3d ellipsoids as 2d ellipses.
|
||||
|
||||
If the atom has a length attribute (see :doc:`atom_style line
|
||||
<atom_style>`) and its length is non-zero, then its mass is set from
|
||||
the density and line segment length (the input density is assumed to
|
||||
be in mass/distance units). If the atom has an area attribute (see
|
||||
:doc:`atom_style tri <atom_style>`) and its area is non-zero, then its
|
||||
mass is set from the density and triangle area (the input density is
|
||||
assumed to be in mass/distance\^2 units).
|
||||
|
||||
If none of these cases are valid, then the mass is set to the density
|
||||
value directly (the input density is assumed to be in mass units).
|
||||
|
||||
Keyword *diameter* sets the size of the selected atoms. The particles
|
||||
must be finite-size spheres as defined by the :doc:`atom_style sphere
|
||||
<atom_style>` command. The diameter of a particle can be set to 0.0,
|
||||
which means they will be treated as point particles. Note that this
|
||||
command does not adjust the particle mass, even if it was defined with
|
||||
a density, e.g. via the :doc:`read_data <read_data>` command.
|
||||
|
||||
.. versionchanged:: 28Mar2023
|
||||
|
||||
Support for type labels was added for setting dihedral types
|
||||
|
||||
Keyword *dihedral* sets the dihedral type of all dihedrals of selected
|
||||
atoms to the specified value. The value can be a numeric type from 1
|
||||
to ndihedraltypes. Or it can be a dihedral type label. See the
|
||||
:doc:`Howto type labels <Howto_type_labels>` doc page for the allowed
|
||||
syntax of type labels and a general discussion of how type labels can
|
||||
be used. All atoms in a particular dihedral must be selected atoms in
|
||||
order for the change to be made. The value of ndihedraltypes was set
|
||||
by the *dihedral types* field in the header of the data file read by
|
||||
the :doc:`read_data <read_data>` command. This keyword does NOT allow
|
||||
use of an atom-style variable.
|
||||
|
||||
Keyword *dipole* uses the specified x,y,z values as components of a
|
||||
vector to set as the orientation of the dipole moment vectors of the
|
||||
@ -313,40 +382,106 @@ moment vectors for the selected atoms and sets the magnitude of each
|
||||
to the specified *Dlen* value. For 2d systems, the z component of the
|
||||
orientation is set to 0.0. Random numbers are used in such a way that
|
||||
the orientation of a particular atom is the same, regardless of how
|
||||
many processors are being used. This keyword does not allow use of an
|
||||
many processors are being used. This keyword does NOT allow use of an
|
||||
atom-style variable.
|
||||
|
||||
.. versionchanged:: 15Sep2022
|
||||
Keyword *dpd/theta* sets the internal temperature of a DPD particle as
|
||||
defined by the DPD-REACT package. If the specified value is a number
|
||||
it must be >= 0.0. If the specified value is NULL, then the kinetic
|
||||
temperature Tkin of each particle is computed as 3/2 k Tkin = KE = 1/2
|
||||
m v\^2 = 1/2 m (vx\*vx+vy\*vy+vz\*vz). Each particle's internal
|
||||
temperature is set to Tkin. If the specified value is an atom-style
|
||||
variable, then the variable is evaluated for each particle. If a
|
||||
value >= 0.0, the internal temperature is set to that value. If it is
|
||||
< 0.0, the computation of Tkin is performed and the internal
|
||||
temperature is set to that value.
|
||||
|
||||
Keyword *spin/atom* uses the specified g value to set the magnitude of the
|
||||
magnetic spin vectors, and the x,y,z values as components of a vector
|
||||
to set as the orientation of the magnetic spin vectors of the selected
|
||||
atoms. This keyword was previously called *spin*.
|
||||
Keywords *edpd/temp* and *edpd/cv* set the temperature and volumetric
|
||||
heat capacity of an eDPD particle as defined by the DPD-MESO package.
|
||||
Currently, only :doc:`atom_style edpd <atom_style>` defines particles
|
||||
with these attributes. The values for the temperature and heat
|
||||
capacity must be positive.
|
||||
|
||||
.. versionchanged:: 15Sep2022
|
||||
Keyword *epsilon* sets the dielectric constant of a particle to be
|
||||
that of the medium where the particle resides as defined by the
|
||||
DIELECTRIC package. Currently, only :doc:`atom_style dielectric
|
||||
<atom_style>` defines particles with this attribute. The value for the
|
||||
dielectric constant must be >= 0.0. Note that the set command with
|
||||
this keyword will rescale the particle charge accordingly so that the
|
||||
real charge (e.g., as read from a data file) stays intact. To change
|
||||
the real charges, one needs to use the set command with the *charge*
|
||||
keyword. Care must be taken to ensure that the real and scaled charges
|
||||
and the dielectric constants are consistent.
|
||||
|
||||
Keyword *spin/atom/random* randomizes the orientation of the magnetic spin
|
||||
vectors for the selected atoms and sets the magnitude of each to the
|
||||
specified *Dlen* value. This keyword was previously called *spin/random*.
|
||||
Keyword *image* sets which image of the simulation box the atom is
|
||||
considered to be in. An image of 0 means it is inside the box as
|
||||
defined. A value of 2 means add 2 box lengths to get the true value.
|
||||
A value of -1 means subtract 1 box length to get the true value.
|
||||
LAMMPS updates these flags as atoms cross periodic boundaries during
|
||||
the simulation. The flags can be output with atom snapshots via the
|
||||
:doc:`dump <dump>` command. If a value of NULL is specified for any
|
||||
of nx,ny,nz, then the current image value for that dimension is
|
||||
unchanged. For non-periodic dimensions only a value of 0 can be
|
||||
specified. This command can be useful after a system has been
|
||||
equilibrated and atoms have diffused one or more box lengths in
|
||||
various directions. This command can then reset the image values for
|
||||
atoms so that they are effectively inside the simulation box, e.g if a
|
||||
diffusion coefficient is about to be measured via the :doc:`compute
|
||||
msd <compute_msd>` command. Care should be taken not to reset the
|
||||
image flags of two atoms in a bond to the same value if the bond
|
||||
straddles a periodic boundary (rather they should be different by +/-
|
||||
1). This will not affect the dynamics of a simulation, but may mess
|
||||
up analysis of the trajectories if a LAMMPS diagnostic or your own
|
||||
analysis relies on the image flags to unwrap a molecule which
|
||||
straddles the periodic box.
|
||||
|
||||
.. versionadded:: 15Sep2022
|
||||
.. versionchanged:: 28Mar2023
|
||||
|
||||
Keyword *radius/electron* uses the specified value to set the radius of
|
||||
electrons or fixed cores.
|
||||
Support for type labels was added for setting improper types
|
||||
|
||||
.. versionadded:: 15Sep2022
|
||||
Keyword *improper* sets the improper type of all impropers of selected
|
||||
atoms to the specified value. The value can be a numeric type from 1
|
||||
to nimpropertypes. Or it can be a improper type label. See the
|
||||
:doc:`Howto type labels <Howto_type_labels>` doc page for the allowed
|
||||
syntax of type labels and a general discussion of how type labels can
|
||||
be used. All atoms in a particular improper must be selected atoms in
|
||||
order for the change to be made. The value of nimpropertypes was set
|
||||
by the *improper types* field in the header of the data file read by
|
||||
the :doc:`read_data <read_data>` command. This keyword does NOT allow
|
||||
use of an atom-style variable.
|
||||
|
||||
Keyword *spin/electron* sets the spin of an electron (+/- 1) or indicates
|
||||
nuclei (=0), fixed-cores (=2), or pseudo-cores (= 3).
|
||||
Keyword *length* sets the length of selected atoms. The particles
|
||||
must be line segments as defined by the :doc:`atom_style line
|
||||
<atom_style>` command. If the specified value is non-zero the line
|
||||
segment is (re)set to a length = the specified value, centered around
|
||||
the particle position, with an orientation along the x-axis. If the
|
||||
specified value is 0.0, the particle will become a point particle.
|
||||
Note that this command does not adjust the particle mass, even if it
|
||||
was defined with a density, e.g. via the :doc:`read_data <read_data>`
|
||||
command.
|
||||
|
||||
Keyword *mass* sets the mass of all selected particles. The particles
|
||||
must have a per-atom mass attribute, as defined by the
|
||||
:doc:`atom_style <atom_style>` command. See the "mass" command for
|
||||
how to set mass values on a per-type basis.
|
||||
|
||||
Keyword *mol* sets the molecule ID for all selected atoms. The
|
||||
:doc:`atom style <atom_style>` being used must support the use of
|
||||
molecule IDs.
|
||||
|
||||
Keyword *omega* sets the angular velocity of selected atoms. The
|
||||
particles must be spheres as defined by the :doc:`atom_style sphere
|
||||
<atom_style>` command. The angular velocity vector of the particles
|
||||
is set to the 3 specified components.
|
||||
|
||||
Keyword *quat* uses the specified values to create a quaternion
|
||||
(4-vector) that represents the orientation of the selected atoms. The
|
||||
particles must define a quaternion for their orientation
|
||||
(e.g. ellipsoids, triangles, body particles) as defined by the
|
||||
:doc:`atom_style <atom_style>` command. Note that particles defined by
|
||||
:doc:`atom_style ellipsoid <atom_style>` have 3 shape parameters. The 3
|
||||
values must be non-zero for each particle set by this command. They
|
||||
are used to specify the aspect ratios of an ellipsoidal particle,
|
||||
:doc:`atom_style <atom_style>` command. Note that particles defined
|
||||
by :doc:`atom_style ellipsoid <atom_style>` have 3 shape parameters.
|
||||
The 3 values must be non-zero for each particle set by this command.
|
||||
They are used to specify the aspect ratios of an ellipsoidal particle,
|
||||
which is oriented by default with its x-axis along the simulation
|
||||
box's x-axis, and similarly for y and z. If this body is rotated (via
|
||||
the right-hand rule) by an angle theta around a unit rotation vector
|
||||
@ -360,51 +495,77 @@ ignored, since a rotation vector of (0,0,1) is the only valid choice.
|
||||
Keyword *quat/random* randomizes the orientation of the quaternion for
|
||||
the selected atoms. The particles must define a quaternion for their
|
||||
orientation (e.g. ellipsoids, triangles, body particles) as defined by
|
||||
the :doc:`atom_style <atom_style>` command. Random numbers are used in
|
||||
such a way that the orientation of a particular atom is the same,
|
||||
the :doc:`atom_style <atom_style>` command. Random numbers are used
|
||||
in such a way that the orientation of a particular atom is the same,
|
||||
regardless of how many processors are being used. For 2d systems,
|
||||
only orientations in the xy plane are generated. As with keyword
|
||||
*quat*, for ellipsoidal particles, the 3 shape values must be non-zero
|
||||
for each particle set by this command. This keyword does not allow
|
||||
for each particle set by this command. This keyword does NOT allow
|
||||
use of an atom-style variable.
|
||||
|
||||
Keyword *diameter* sets the size of the selected atoms. The particles
|
||||
must be finite-size spheres as defined by the :doc:`atom_style sphere
|
||||
<atom_style>` command. The diameter of a particle can be set to 0.0,
|
||||
which means they will be treated as point particles. Note that this
|
||||
command does not adjust the particle mass, even if it was defined with
|
||||
a density, e.g. via the :doc:`read_data <read_data>` command.
|
||||
.. versionadded:: 15Sep2022
|
||||
|
||||
Keyword *radius/electron* uses the specified value to set the radius
|
||||
of electrons or fixed cores.
|
||||
|
||||
Keyword *shape* sets the size and shape of the selected atoms. The
|
||||
particles must be ellipsoids as defined by the :doc:`atom_style
|
||||
ellipsoid <atom_style>` command. The *Sx*, *Sy*, *Sz* settings
|
||||
are the 3 diameters of the ellipsoid in each direction. All 3 can be
|
||||
set to the same value, which means the ellipsoid is effectively a
|
||||
sphere. They can also all be set to 0.0 which means the particle will
|
||||
be treated as a point particle. Note that this command does not
|
||||
adjust the particle mass, even if it was defined with a density,
|
||||
e.g. via the :doc:`read_data <read_data>` command.
|
||||
ellipsoid <atom_style>` command. The *Sx*, *Sy*, *Sz* settings are
|
||||
the 3 diameters of the ellipsoid in each direction. All 3 can be set
|
||||
to the same value, which means the ellipsoid is effectively a sphere.
|
||||
They can also all be set to 0.0 which means the particle will be
|
||||
treated as a point particle. Note that this command does not adjust
|
||||
the particle mass, even if it was defined with a density, e.g. via the
|
||||
:doc:`read_data <read_data>` command.
|
||||
|
||||
Keyword *length* sets the length of selected atoms. The particles
|
||||
must be line segments as defined by the :doc:`atom_style line
|
||||
<atom_style>` command. If the specified value is non-zero the line
|
||||
segment is (re)set to a length = the specified value, centered around
|
||||
the particle position, with an orientation along the x-axis. If the
|
||||
specified value is 0.0, the particle will become a point particle.
|
||||
Note that this command does not adjust the particle mass, even if it
|
||||
was defined with a density, e.g. via the :doc:`read_data <read_data>`
|
||||
command.
|
||||
Keyword *smd/contact/radius* only applies to simulations with the
|
||||
Smooth Mach Dynamics package MACHDYN. Itsets an interaction radius
|
||||
for computing short-range interactions, e.g. repulsive forces to
|
||||
prevent different individual physical bodies from penetrating each
|
||||
other. Note that the SPH smoothing kernel diameter used for computing
|
||||
long range, nonlocal interactions, is set using the *diameter*
|
||||
keyword.
|
||||
|
||||
Keyword *tri* sets the size of selected atoms. The particles must be
|
||||
triangles as defined by the :doc:`atom_style tri <atom_style>` command.
|
||||
If the specified value is non-zero the triangle is (re)set to be an
|
||||
equilateral triangle in the xy plane with side length = the specified
|
||||
value, with a centroid at the particle position, with its base
|
||||
parallel to the x axis, and the y-axis running from the center of the
|
||||
base to the top point of the triangle. If the specified value is 0.0,
|
||||
the particle will become a point particle. Note that this command
|
||||
does not adjust the particle mass, even if it was defined with a
|
||||
density, e.g. via the :doc:`read_data <read_data>` command.
|
||||
Keyword *smd/mass/density* sets the mass of all selected particles,
|
||||
but it is only applicable to the Smooth Mach Dynamics package MACHDYN.
|
||||
It assumes that the particle volume has already been correctly set and
|
||||
calculates particle mass from the provided mass density value.
|
||||
|
||||
Keywords *sph/cv*, *sph/e*, and *sph/rho* set the heat capacity,
|
||||
energy, and density of smoothed particle hydrodynamics (SPH)
|
||||
particles. See `this PDF guide <PDF/SPH_LAMMPS_userguide.pdf>`_ to
|
||||
using SPH in LAMMPS.
|
||||
|
||||
.. note::
|
||||
|
||||
Note that the SPH PDF guide file has not been updated for many
|
||||
years and thus does not reflect the current *syntax* of the SPH
|
||||
package commands. For that, please refer to the LAMMPS manual.
|
||||
|
||||
.. versionchanged:: 15Sep2022
|
||||
|
||||
Keyword *spin/atom* uses the specified g value to set the magnitude of
|
||||
the magnetic spin vectors, and the x,y,z values as components of a
|
||||
vector to set as the orientation of the magnetic spin vectors of the
|
||||
selected atoms. This keyword was previously called *spin*.
|
||||
|
||||
.. versionchanged:: 15Sep2022
|
||||
|
||||
Keyword *spin/atom/random* randomizes the orientation of the magnetic
|
||||
spin vectors for the selected atoms and sets the magnitude of each to
|
||||
the specified *Dlen* value. This keyword does NOT allow use of an
|
||||
atom-style variable. This keyword was previously called
|
||||
*spin/random*.
|
||||
|
||||
.. versionadded:: 15Sep2022
|
||||
|
||||
Keyword *spin/electron* sets the spin of an electron (+/- 1) or
|
||||
indicates nuclei (=0), fixed-cores (=2), or pseudo-cores (= 3).
|
||||
|
||||
Keyword *temperature* sets the temperature of a finite-size particle.
|
||||
Currently, only the GRANULAR package supports this attribute. The
|
||||
temperature must be added using an instance of :doc:`fix property/atom
|
||||
<fix_property_atom>` The values for the temperature must be positive.
|
||||
|
||||
Keyword *theta* sets the orientation of selected atoms. The particles
|
||||
must be line segments as defined by the :doc:`atom_style line
|
||||
@ -413,169 +574,71 @@ orientation angle of the line segments with respect to the x axis.
|
||||
|
||||
Keyword *theta/random* randomizes the orientation of theta for the
|
||||
selected atoms. The particles must be line segments as defined by the
|
||||
:doc:`atom_style line <atom_style>` command. Random numbers are used in
|
||||
such a way that the orientation of a particular atom is the same,
|
||||
:doc:`atom_style line <atom_style>` command. Random numbers are used
|
||||
in such a way that the orientation of a particular atom is the same,
|
||||
regardless of how many processors are being used. This keyword does
|
||||
not allow use of an atom-style variable.
|
||||
NOT allow use of an atom-style variable.
|
||||
|
||||
Keyword *angmom* sets the angular momentum of selected atoms. The
|
||||
particles must be ellipsoids as defined by the :doc:`atom_style
|
||||
ellipsoid <atom_style>` command or triangles as defined by the
|
||||
:doc:`atom_style tri <atom_style>` command. The angular momentum
|
||||
vector of the particles is set to the 3 specified components.
|
||||
Keyword *tri* sets the size of selected atoms. The particles must be
|
||||
triangles as defined by the :doc:`atom_style tri <atom_style>`
|
||||
command. If the specified value is non-zero the triangle is (re)set
|
||||
to be an equilateral triangle in the xy plane with side length = the
|
||||
specified value, with a centroid at the particle position, with its
|
||||
base parallel to the x axis, and the y-axis running from the center of
|
||||
the base to the top point of the triangle. If the specified value is
|
||||
0.0, the particle will become a point particle. Note that this
|
||||
command does not adjust the particle mass, even if it was defined with
|
||||
a density, e.g. via the :doc:`read_data <read_data>` command.
|
||||
|
||||
Keyword *omega* sets the angular velocity of selected atoms. The
|
||||
particles must be spheres as defined by the :doc:`atom_style sphere
|
||||
<atom_style>` command. The angular velocity vector of the particles is
|
||||
set to the 3 specified components.
|
||||
.. versionchanged:: 28Mar2023
|
||||
|
||||
Keyword *mass* sets the mass of all selected particles. The particles
|
||||
must have a per-atom mass attribute, as defined by the :doc:`atom_style
|
||||
<atom_style>` command. See the "mass" command for how to set mass
|
||||
values on a per-type basis.
|
||||
Support for type labels was added for setting atom types
|
||||
|
||||
Keyword *density* or *density/disc* also sets the mass of all selected
|
||||
particles, but in a different way. The particles must have a per-atom
|
||||
mass attribute, as defined by the :doc:`atom_style <atom_style>`
|
||||
command. If the atom has a radius attribute (see :doc:`atom_style
|
||||
sphere <atom_style>`) and its radius is non-zero, its mass is set from
|
||||
the density and particle volume for 3d systems (the input density is
|
||||
assumed to be in mass/distance\^3 units). For 2d, the default is for
|
||||
LAMMPS to model particles with a radius attribute as spheres. However,
|
||||
if the *density/disc* keyword is used, then they can be modeled as 2d
|
||||
discs (circles). Their mass is set from the density and particle area
|
||||
(the input density is assumed to be in mass/distance\^2 units).
|
||||
|
||||
If the atom has a shape attribute (see :doc:`atom_style ellipsoid
|
||||
<atom_style>`) and its 3 shape parameters are non-zero, then its mass is
|
||||
set from the density and particle volume (the input density is assumed
|
||||
to be in mass/distance\^3 units). The *density/disc* keyword has no
|
||||
effect; it does not (yet) treat 3d ellipsoids as 2d ellipses.
|
||||
|
||||
If the atom has a length attribute (see :doc:`atom_style line
|
||||
<atom_style>`) and its length is non-zero, then its mass is set from the
|
||||
density and line segment length (the input density is assumed to be in
|
||||
mass/distance units). If the atom has an area attribute (see
|
||||
:doc:`atom_style tri <atom_style>`) and its area is non-zero, then its
|
||||
mass is set from the density and triangle area (the input density is
|
||||
assumed to be in mass/distance\^2 units).
|
||||
|
||||
If none of these cases are valid, then the mass is set to the density
|
||||
value directly (the input density is assumed to be in mass units).
|
||||
|
||||
Keyword *temperature* sets the temperature of a finite-size particle.
|
||||
Currently, only the GRANULAR package supports this attribute. The
|
||||
temperature must be added using an instance of
|
||||
:doc:`fix property/atom <fix_property_atom>` The values for the
|
||||
temperature must be positive.
|
||||
|
||||
Keyword *volume* sets the volume of all selected particles. Currently,
|
||||
only the :doc:`atom_style peri <atom_style>` command defines particles
|
||||
with a volume attribute. Note that this command does not adjust the
|
||||
particle mass.
|
||||
|
||||
Keyword *image* sets which image of the simulation box the atom is
|
||||
considered to be in. An image of 0 means it is inside the box as
|
||||
defined. A value of 2 means add 2 box lengths to get the true value. A
|
||||
value of -1 means subtract 1 box length to get the true value. LAMMPS
|
||||
updates these flags as atoms cross periodic boundaries during the
|
||||
simulation. The flags can be output with atom snapshots via the
|
||||
:doc:`dump <dump>` command. If a value of NULL is specified for any of
|
||||
nx,ny,nz, then the current image value for that dimension is unchanged.
|
||||
For non-periodic dimensions only a value of 0 can be specified. This
|
||||
command can be useful after a system has been equilibrated and atoms
|
||||
have diffused one or more box lengths in various directions. This
|
||||
command can then reset the image values for atoms so that they are
|
||||
effectively inside the simulation box, e.g if a diffusion coefficient is
|
||||
about to be measured via the :doc:`compute msd <compute_msd>` command.
|
||||
Care should be taken not to reset the image flags of two atoms in a bond
|
||||
to the same value if the bond straddles a periodic boundary (rather they
|
||||
should be different by +/- 1). This will not affect the dynamics of a
|
||||
simulation, but may mess up analysis of the trajectories if a LAMMPS
|
||||
diagnostic or your own analysis relies on the image flags to unwrap a
|
||||
molecule which straddles the periodic box.
|
||||
|
||||
Keywords *bond*, *angle*, *dihedral*, and *improper*, set the bond
|
||||
type (angle type, etc) of all bonds (angles, etc) of selected atoms to
|
||||
the specified value. The value can be a numeric type from 1 to
|
||||
nbondtypes (nangletypes, etc). Or it can be a type label (bond type
|
||||
label, angle type label, etc). See the :doc:`Howto type labels
|
||||
Keyword *type* sets the atom type for all selected atoms. A specified
|
||||
value can be either a numeric atom type or an atom type label. When
|
||||
using a numeric type, the specified value must be from 1 to ntypes,
|
||||
where ntypes was set by the :doc:`create_box <create_box>` command or
|
||||
the *atom types* field in the header of the data file read by the
|
||||
:doc:`read_data <read_data>` command. When using a type label it must
|
||||
have been defined previously. See the :doc:`Howto type labels
|
||||
<Howto_type_labels>` doc page for the allowed syntax of type labels
|
||||
and a general discussion of how type labels can be used. All atoms in
|
||||
a particular bond (angle, etc) must be selected atoms in order for the
|
||||
change to be made. The value of nbondtypes (nangletypes, etc) was set
|
||||
by the *bond types* (\ *angle types*, etc) field in the header of the
|
||||
data file read by the :doc:`read_data <read_data>` command. These
|
||||
keywords do not allow use of an atom-style variable.
|
||||
and a general discussion of how type labels can be used.
|
||||
|
||||
Keywords *rheo/rho* and *rheo/status* set the density and the status of
|
||||
rheo particles. In particular, one can only set the phase in the status
|
||||
as described by the :doc:`RHEO howto page <Howto_rheo>`.
|
||||
Keyword *type/fraction* sets the atom type for a fraction of the
|
||||
selected atoms. The actual number of atoms changed is not guaranteed
|
||||
to be exactly the specified fraction (0 <= *fraction* <= 1), but
|
||||
should be statistically close. Random numbers are used in such a way
|
||||
that a particular atom is changed or not changed, regardless of how
|
||||
many processors are being used. This keyword does NOT allow use of an
|
||||
atom-style variable.
|
||||
|
||||
Keywords *sph/e*, *sph/cv*, and *sph/rho* set the energy, heat capacity,
|
||||
and density of smoothed particle hydrodynamics (SPH) particles. See
|
||||
`this PDF guide <PDF/SPH_LAMMPS_userguide.pdf>`_ to using SPH in LAMMPS.
|
||||
Keywords *type/ratio* and *type/subset* also set the atom type for a
|
||||
fraction of the selected atoms. The actual number of atoms changed
|
||||
will be exactly the requested number. For *type/ratio* the specified
|
||||
fraction (0 <= *fraction* <= 1) determines the number. For
|
||||
*type/subset*, the specified *Nsubset* is the number. An iterative
|
||||
algorithm is used which ensures the correct number of atoms are
|
||||
selected, in a perfectly random fashion. Which atoms are selected
|
||||
will change with the number of processors used. These keywords do not
|
||||
allow use of an atom-style variable.
|
||||
|
||||
.. note::
|
||||
Keyword *volume* sets the volume of all selected particles.
|
||||
Currently, only the :doc:`atom_style peri <atom_style>` command
|
||||
defines particles with a volume attribute. Note that this command
|
||||
does not adjust the particle mass.
|
||||
|
||||
Please note that the SPH PDF guide file has not been updated for
|
||||
many years and thus does not reflect the current *syntax* of the
|
||||
SPH package commands. For that please refer to the LAMMPS manual.
|
||||
Keywords *vx*, *vy*, and *vz* set the velocities of all selected
|
||||
atoms.
|
||||
|
||||
Keyword *smd/mass/density* sets the mass of all selected particles, but
|
||||
it is only applicable to the Smooth Mach Dynamics package MACHDYN. It
|
||||
assumes that the particle volume has already been correctly set and
|
||||
calculates particle mass from the provided mass density value.
|
||||
|
||||
Keyword *smd/contact/radius* only applies to simulations with the Smooth
|
||||
Mach Dynamics package MACHDYN. Itsets an interaction radius for
|
||||
computing short-range interactions, e.g. repulsive forces to prevent
|
||||
different individual physical bodies from penetrating each other. Note
|
||||
that the SPH smoothing kernel diameter used for computing long range,
|
||||
nonlocal interactions, is set using the *diameter* keyword.
|
||||
|
||||
Keyword *dpd/theta* sets the internal temperature of a DPD particle as
|
||||
defined by the DPD-REACT package. If the specified value is a number it
|
||||
must be >= 0.0. If the specified value is NULL, then the kinetic
|
||||
temperature Tkin of each particle is computed as 3/2 k Tkin = KE = 1/2 m
|
||||
v\^2 = 1/2 m (vx\*vx+vy\*vy+vz\*vz). Each particle's internal
|
||||
temperature is set to Tkin. If the specified value is an atom-style
|
||||
variable, then the variable is evaluated for each particle. If a value
|
||||
>= 0.0, the internal temperature is set to that value. If it is < 0.0,
|
||||
the computation of Tkin is performed and the internal temperature is set
|
||||
to that value.
|
||||
|
||||
Keywords *edpd/temp* and *edpd/cv* set the temperature and volumetric
|
||||
heat capacity of an eDPD particle as defined by the DPD-MESO package.
|
||||
Currently, only :doc:`atom_style edpd <atom_style>` defines particles
|
||||
with these attributes. The values for the temperature and heat capacity
|
||||
must be positive.
|
||||
|
||||
Keyword *cc* sets the chemical concentration of a tDPD particle for a
|
||||
specified species as defined by the DPD-MESO package. Currently, only
|
||||
:doc:`atom_style tdpd <atom_style>` defines particles with this
|
||||
attribute. An integer for "index" selects a chemical species (1 to
|
||||
Nspecies) where Nspecies is set by the atom_style command. The value for
|
||||
the chemical concentration must be >= 0.0.
|
||||
|
||||
Keyword *epsilon* sets the dielectric constant of a particle, precisely
|
||||
of the medium where the particle resides as defined by the DIELECTRIC
|
||||
package. Currently, only :doc:`atom_style dielectric <atom_style>`
|
||||
defines particles with this attribute. The value for the dielectric
|
||||
constant must be >= 0.0. Note that the set command with this keyword
|
||||
will rescale the particle charge accordingly so that the real charge
|
||||
(e.g., as read from a data file) stays intact. To change the real
|
||||
charges, one needs to use the set command with the *charge*
|
||||
keyword. Care must be taken to ensure that the real and scaled charges,
|
||||
and dielectric constants are consistent.
|
||||
Keywords *x*, *y*, *z* set the coordinates of all selected atoms.
|
||||
|
||||
Keywords *i_name*, *d_name*, *i2_name*, *d2_name* refer to custom
|
||||
per-atom integer and floating-point vectors or arrays that have been
|
||||
added via the :doc:`fix property/atom <fix_property_atom>` command.
|
||||
When that command is used specific names are given to each attribute
|
||||
which are the "name" portion of these keywords. For arrays *i2_name*
|
||||
and *d2_name*, the column of the array must also be included following
|
||||
the name in brackets: e.g. d2_xyz[2], i2_mySpin[3].
|
||||
and *d2_name*, the column of the array to set must also be included
|
||||
following the name in brackets: e.g. d2_xyz[2] or i2_mySpin[3].
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
@ -584,7 +647,7 @@ You cannot set an atom attribute (e.g. *mol* or *q* or *volume*\ ) if
|
||||
the :doc:`atom_style <atom_style>` does not have that attribute.
|
||||
|
||||
This command requires inter-processor communication to coordinate the
|
||||
setting of bond types (angle types, etc). This means that your system
|
||||
setting of bond types (angle types, etc). This means that the system
|
||||
must be ready to perform a simulation before using one of these
|
||||
keywords (force fields set, atom mass set, etc). This is not
|
||||
necessary for other keywords.
|
||||
@ -599,7 +662,7 @@ Related commands
|
||||
""""""""""""""""
|
||||
|
||||
:doc:`create_box <create_box>`, :doc:`create_atoms <create_atoms>`,
|
||||
:doc:`read_data <read_data>`
|
||||
:doc:`read_data <read_data>`, :doc:`fix set <fix_set>`
|
||||
|
||||
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
|
||||
-----------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user