updated doc pages and code
This commit is contained in:
@ -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
|
The value *v_name* can be used together with the *set* keyword to
|
||||||
compute a user-specified function of the angle theta. The *name*
|
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
|
variable which will store the angle theta. This other variable must
|
||||||
be an :doc:`internal-style variable <variable>` defined in the input
|
be an :doc:`internal-style variable <variable>` specified by the *set*
|
||||||
script; its initial numeric value can be anything. It must be an
|
keyword. It is an internal-style variable, because this command
|
||||||
internal-style variable, because this command resets its value
|
resets its value directly. The internal-style variable does not need
|
||||||
directly. The *set* keyword is used to identify the name of this
|
to be defined in the input script (though it can be); if it is not
|
||||||
other variable associated with theta.
|
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.
|
internal variable is in radians, not degrees.
|
||||||
|
|
||||||
As an example, these commands can be added to the bench/in.rhodo
|
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
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
variable t internal 0.0
|
|
||||||
variable cos equal cos(v_t)
|
variable cos equal cos(v_t)
|
||||||
variable cossq equal cos(v_t)*cos(v_t)
|
variable cossq equal cos(v_t)*cos(v_t)
|
||||||
|
|
||||||
|
|||||||
@ -118,13 +118,15 @@ moving apart.
|
|||||||
|
|
||||||
The value *v_name* can be used together with the *set* keyword to
|
The value *v_name* can be used together with the *set* keyword to
|
||||||
compute a user-specified function of the bond distance. The *name*
|
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
|
specified for the *v_name* value is the name of an :doc:`equal-style
|
||||||
variable which will store the bond distance. This other variable must
|
variable <variable>` which should evaluate a formula based on a
|
||||||
be an :doc:`internal-style variable <variable>` defined in the input
|
variable which stores the bond distance. This other variable must be
|
||||||
script; its initial numeric value can be anything. It must be an
|
the :doc:`internal-style variable <variable>` specified by the *set*
|
||||||
internal-style variable, because this command resets its value
|
keyword. It is an internal-style variable, because this command
|
||||||
directly. The *set* keyword is used to identify the name of this
|
resets its value directly. The internal-style variable does not need
|
||||||
other variable associated with theta.
|
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
|
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
|
script to compute the length\ :math:`^2` of every bond in the system and
|
||||||
@ -132,7 +134,6 @@ output the statistics in various ways:
|
|||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
variable d internal 0.0
|
|
||||||
variable dsq equal v_d*v_d
|
variable dsq equal v_d*v_d
|
||||||
|
|
||||||
compute 1 all property/local batom1 batom2 btype
|
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
|
processors, equals the number of dihedral angles in the system, modified
|
||||||
by the group parameter as explained below.
|
by the group parameter as explained below.
|
||||||
|
|
||||||
The value *phi* (:math:`\phi`) is the dihedral angle, as defined in the diagram
|
The value *phi* (:math:`\phi`) is the dihedral angle, as defined in
|
||||||
on the :doc:`dihedral_style <dihedral_style>` doc page.
|
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
|
The value *v_name* can be used together with the *set* keyword to
|
||||||
user-specified function of the dihedral angle :math:`\phi`. The *name*
|
compute a user-specified function of the dihedral angle :math:`\phi`.
|
||||||
specified for the *v_name* value is the name of an
|
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
|
:doc:`equal-style variable <variable>` which should evaluate a formula
|
||||||
a variable which will store the angle :math:`\phi`. This other variable must
|
based on a variable which will store the angle :math:`\phi`. This
|
||||||
be an :doc:`internal-style variable <variable>` defined in the input
|
other variable must be an :doc:`internal-style variable <variable>`
|
||||||
script; its initial numeric value can be anything. It must be an
|
specified by the *set* keyword. It is an internal-style variable,
|
||||||
internal-style variable, because this command resets its value
|
because this command resets its value directly. The internal-style
|
||||||
directly. The *set* keyword is used to identify the name of this
|
variable does not need to be defined in the input script (though it
|
||||||
other variable associated with :math:`\phi`.
|
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
|
Note that the value of :math:`\phi` for each angle which stored in the
|
||||||
variable is in radians, not degrees.
|
internal variable is in radians, not degrees.
|
||||||
|
|
||||||
As an example, these commands can be added to the bench/in.rhodo
|
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
|
script to compute the :math:`\cos\phi` and :math:`\cos^2\phi` of every
|
||||||
angle in the system and output the statistics in various ways:
|
dihedral angle in the system and output the statistics in various
|
||||||
|
ways:
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
variable p internal 0.0
|
|
||||||
variable cos equal cos(v_p)
|
variable cos equal cos(v_p)
|
||||||
variable cossq equal cos(v_p)*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
|
from one timestep to the next. The only consistency that is
|
||||||
guaranteed is that the ordering on a particular timestep will be the
|
guaranteed is that the ordering on a particular timestep will be the
|
||||||
same for local vectors or arrays generated by other compute commands.
|
same for local vectors or arrays generated by other compute commands.
|
||||||
For example, dihedral output from the
|
For example, dihedral output from the :doc:`compute property/local
|
||||||
:doc:`compute property/local <compute_property_local>` command can be combined
|
<compute_property_local>` command can be combined with data from this
|
||||||
with data from this command and output by the :doc:`dump local <dump>`
|
command and output by the :doc:`dump local <dump>` command in a
|
||||||
command in a consistent way.
|
consistent way.
|
||||||
|
|
||||||
Here is an example of how to do this:
|
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
|
*single*. The *name* specified for the *var* keyword is the name of
|
||||||
an :doc:`equal-style variable <variable>` that should evaluate to a
|
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
|
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
|
will store the *x*, *y*, or *z* coordinates of an atom (one variable
|
||||||
coordinate). If used, these other variables must be
|
per coordinate). If used, these other variables must be specified by
|
||||||
:doc:`internal-style variables <variable>` defined in the input
|
the *set* keyword. They are internal-style variable, because this
|
||||||
script; their initial numeric value can be anything. They must be
|
command resets their values directly. The internal-style variables do
|
||||||
internal-style variables, because this command resets their values
|
not need to be defined in the input script (though they can be); if
|
||||||
directly. The *set* keyword is used to identify the names of these
|
one (or more) is not defined, then the *set* option creates an
|
||||||
other variables, one variable for the *x*-coordinate of a created atom,
|
:doc:`internal-style variable <variable>` with the specified name.
|
||||||
one for *y*, and one for *z*.
|
|
||||||
|
|
||||||
.. figure:: img/sinusoid.jpg
|
.. figure:: img/sinusoid.jpg
|
||||||
:figwidth: 50%
|
:figwidth: 50%
|
||||||
:align: right
|
:align: right
|
||||||
:target: _images/sinusoid.jpg
|
:target: _images/sinusoid.jpg
|
||||||
|
|
||||||
When an atom is created, its :math:`(x,y,z)` coordinates become the values for
|
When an atom is about to be created, its :math:`(x,y,z)` coordinates
|
||||||
any *set* variable that is defined. The *var* variable is then
|
become the values for any *set* variable that is defined. The *var*
|
||||||
evaluated. If the returned value is 0.0, the atom is not created. If
|
variable is then evaluated. If the returned value is 0.0, the atom is
|
||||||
it is non-zero, the atom is created.
|
not created. If it is non-zero, the atom is created.
|
||||||
|
|
||||||
As an example, these commands can be used in a 2d simulation, to
|
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
|
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
|
region box block 0 $x 0 $y -0.5 0.5
|
||||||
create_box 1 box
|
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"
|
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
|
create_atoms 1 box var v set x xx set y yy
|
||||||
write_dump all atom sinusoid.lammpstrj
|
write_dump all atom sinusoid.lammpstrj
|
||||||
|
|||||||
@ -98,52 +98,53 @@ the following dynamic equation:
|
|||||||
|
|
||||||
\frac{dc}{dt} = -\alpha (K_p e + K_i \int_0^t e \, dt + K_d \frac{de}{dt} )
|
\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,
|
where *c* is the continuous time analog of the control variable, *e*
|
||||||
*e* =\ *pvar*\ -\ *setpoint* is the error in the process variable, and
|
=\ *pvar*\ -\ *setpoint* is the error in the process variable, and
|
||||||
:math:`\alpha`, :math:`K_p`, :math:`K_i` , and :math:`K_d` are constants
|
:math:`\alpha`, :math:`K_p`, :math:`K_i` , and :math:`K_d` are
|
||||||
set by the corresponding
|
constants set by the corresponding keywords described above. The
|
||||||
keywords described above. The discretized version of this equation is:
|
discretized version of this equation is:
|
||||||
|
|
||||||
.. math::
|
.. 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)
|
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
|
where :math:`\tau = \mathtt{Nevery} \cdot \mathtt{timestep}` is the
|
||||||
interval between updates,
|
time interval between updates, and the subscripted variables indicate
|
||||||
and the subscripted variables indicate the values of *c* and *e* at
|
the values of *c* and *e* at successive updates.
|
||||||
successive updates.
|
|
||||||
|
|
||||||
From the first equation, it is clear that if the three gain values
|
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,
|
:math:`K_p`, :math:`K_i`, :math:`K_d` are dimensionless constants,
|
||||||
then :math:`\alpha` must have
|
then :math:`\alpha` must have units of [unit *cvar*\ ]/[unit *pvar*\
|
||||||
units of [unit *cvar*\ ]/[unit *pvar*\ ]/[unit time] e.g. [ eV/K/ps
|
]/[unit time] e.g. [ eV/K/ps ]. The advantage of this unit scheme is
|
||||||
]. The advantage of this unit scheme is that the value of the
|
that the value of the constants should be invariant under a change of
|
||||||
constants should be invariant under a change of either the MD timestep
|
either the MD timestep size or the value of *Nevery*\ . Similarly, if
|
||||||
size or the value of *Nevery*\ . Similarly, if the LAMMPS :doc:`unit style <units>` is changed, it should only be necessary to change
|
the LAMMPS :doc:`unit style <units>` is changed, it should only be
|
||||||
the value of :math:`\alpha` to reflect this, while leaving :math:`K_p`,
|
necessary to change the value of :math:`\alpha` to reflect this, while
|
||||||
:math:`K_i`, and :math:`K_d` unaltered.
|
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
|
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
|
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`
|
magnitudes and signs of *pvar* and *cvar*\ . The magnitude of
|
||||||
should then be tested over a large positive range keeping :math:`K_i = K_d =0`.
|
:math:`K_p` should then be tested over a large positive range keeping
|
||||||
A good value for :math:`K_p` will produce a fast response in *pvar*,
|
:math:`K_i = K_d =0`. A good value for :math:`K_p` will produce a
|
||||||
without overshooting the *setpoint*\ . For many applications, proportional
|
fast response in *pvar*, without overshooting the *setpoint*\ . For
|
||||||
feedback is sufficient, and so :math:`K_i = K_d =0` can be used. In cases
|
many applications, proportional feedback is sufficient, and so
|
||||||
where there is a substantial lag time in the response of *pvar* to a change
|
:math:`K_i = K_d =0` can be used. In cases where there is a
|
||||||
in *cvar*, this can be counteracted by increasing :math:`K_d`. In situations
|
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
|
where *pvar* plateaus without reaching *setpoint*, this can be
|
||||||
counteracted by increasing :math:`K_i`. In the language of Charles Dickens,
|
counteracted by increasing :math:`K_i`. In the language of Charles
|
||||||
:math:`K_p` represents the error of the present, :math:`K_i` the error of
|
Dickens, :math:`K_p` represents the error of the present, :math:`K_i`
|
||||||
the past, and :math:`K_d` the error yet to come.
|
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,
|
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 initial value :math:`c_0` is that assigned by the user in the
|
||||||
the :doc:`internal-style variable <variable>` command. This value is
|
input script via the :doc:`internal-style variable <variable>`
|
||||||
used (by every other LAMMPS command that uses the variable) until this
|
command. This value is used (by every other LAMMPS command that uses
|
||||||
fix performs its first update of *cvar* after *Nevery* timesteps. On
|
the variable) until this fix performs its first update of *cvar* after
|
||||||
the first update, the value of the derivative term is set to zero,
|
*Nevery* timesteps. On the first update, the value of the derivative
|
||||||
because the value of :math:`e_{n-1}` is not yet defined.
|
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
|
If *pvar* begins with "c\_", a compute ID must follow which has been
|
||||||
previously defined in the input script and which generates a global
|
previously defined in the input script and which generates a global
|
||||||
scalar or vector. See the individual :doc:`compute <compute>` doc page
|
scalar or vector. See the individual :doc:`compute <compute>` doc
|
||||||
for details. If no bracketed integer is appended, the scalar
|
page for details. If no bracketed integer is appended, the scalar
|
||||||
calculated by the compute is used. If a bracketed integer is
|
calculated by the compute is used. If a bracketed integer is
|
||||||
appended, the Ith value of the vector calculated by the compute 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
|
If *pvar* begins with "f\_", a fix ID must follow which has been
|
||||||
previously defined in the input script and which generates a global
|
previously defined in the input script and which generates a global
|
||||||
scalar or vector. See the individual :doc:`fix <fix>` page for
|
scalar or vector. See the individual :doc:`fix <fix>` page for
|
||||||
details. Note that some fixes only produce their values on certain
|
details. Note that some fixes only produce their values on certain
|
||||||
timesteps, which must be compatible with when fix controller
|
timesteps, which must be compatible with when fix controller
|
||||||
references the values, or else an error results. If no bracketed integer
|
references the values, or else an error results. If no bracketed
|
||||||
is appended, the scalar calculated by the fix is used. If a bracketed
|
integer is appended, the scalar calculated by the fix is used. If a
|
||||||
integer is appended, the Ith value of the vector calculated by the fix
|
bracketed integer is appended, the Ith value of the vector calculated
|
||||||
is used. Users can also write code for their own fix style and :doc:`add them to LAMMPS <Modify>`.
|
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
|
If *pvar* begins with "v\_", a variable name must follow which has been
|
||||||
previously defined in the input script. Only equal-style variables
|
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
|
The target value *setpoint* for the process variable must be a numeric
|
||||||
value, in whatever units *pvar* is defined for.
|
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
|
The control variable *cvar* must be the name of an
|
||||||
that it is not specified with a "v\_" prefix, just the name of the
|
:doc:`internal-style variable <variable>` previously defined in the
|
||||||
variable. It must be an internal-style variable, because this fix
|
input script. Note that it is not specified with a "v\_" prefix, just
|
||||||
updates its value directly. Note that other commands can use an
|
the name of the variable. It must be an internal-style variable,
|
||||||
equal-style versus internal-style variable interchangeably.
|
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
|
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
|
Currently, no information about this fix is written to :doc:`binary
|
||||||
are relevant to this fix.
|
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
|
This fix produces a global vector with 3 values which can be accessed
|
||||||
by various :doc:`output commands <Howto_output>`. The values can be
|
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".
|
"extensive".
|
||||||
|
|
||||||
No parameter of this fix can be used with the *start/stop* keywords of
|
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
|
Restrictions
|
||||||
""""""""""""
|
""""""""""""
|
||||||
|
|||||||
@ -225,22 +225,25 @@ rotated configuration of the molecule.
|
|||||||
|
|
||||||
.. versionadded:: 21Nov2023
|
.. versionadded:: 21Nov2023
|
||||||
|
|
||||||
The *var* and *set* keywords can be used together to provide a criterion
|
The *var* and *set* keywords can be used together to provide a
|
||||||
for accepting or rejecting the addition of an individual atom, based on its
|
criterion for accepting or rejecting the addition of an individual
|
||||||
coordinates. The *name* specified for the *var* keyword is the name of an
|
atom, based on its coordinates. The *name* specified for the *var*
|
||||||
:doc:`equal-style variable <variable>` that should evaluate to a zero or
|
keyword is the name of an :doc:`equal-style variable <variable>` that
|
||||||
non-zero value based on one or two or three variables that will store the
|
should evaluate to a zero or non-zero value based on one or two or
|
||||||
*x*, *y*, or *z* coordinates of an atom (one variable per coordinate). If
|
three variables that will store the *x*, *y*, or *z* coordinates of an
|
||||||
used, these other variables must be :doc:`internal-style variables
|
atom (one variable per coordinate). If used, these other variables
|
||||||
<variable>` defined in the input script; their initial numeric value can be
|
must be :doc:`internal-style variables <variable>` specified by the
|
||||||
anything. They must be internal-style variables, because this command
|
*set* keyword. They must be internal-style variables, because this
|
||||||
resets their values directly. The *set* keyword is used to identify the
|
command resets their values directly. The internal-style variables do
|
||||||
names of these other variables, one variable for the *x*-coordinate of a
|
not need to be defined in the input script (though they can be); if
|
||||||
created atom, one for *y*, and one for *z*. When an atom is created, its
|
one (or more) is not defined, then the *set* option creates an
|
||||||
:math:`(x,y,z)` coordinates become the values for any *set* variable that
|
:doc:`internal-style variable <variable>` with the specified name.
|
||||||
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
|
||||||
For an example of how to use these keywords, see the
|
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.
|
:doc:`create_atoms <create_atoms>` command.
|
||||||
|
|
||||||
The *rate* option moves the insertion volume in the z direction (3d)
|
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
|
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
|
This fix writes the state of the deposition to :doc:`binary restart
|
||||||
particles have been deposited, the random number generator seed, the
|
files <restart>`. This includes information about how many particles
|
||||||
next timestep for deposition, etc. See the
|
have been deposited, the random number generator seed, the next
|
||||||
:doc:`read_restart <read_restart>` command for info on how to re-specify
|
timestep for deposition, etc. See the :doc:`read_restart
|
||||||
a fix in an input script that reads a restart file, so that the
|
<read_restart>` command for info on how to re-specify a fix in an
|
||||||
operation of the fix continues in an uninterrupted fashion.
|
input script that reads a restart file, so that the operation of the
|
||||||
|
fix continues in an uninterrupted fashion.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|||||||
@ -10,43 +10,45 @@ Syntax
|
|||||||
|
|
||||||
python mode keyword args ...
|
python mode keyword args ...
|
||||||
|
|
||||||
* mode = *source* or name of Python function
|
* mode = *source* or *name* of Python function
|
||||||
|
|
||||||
if mode is *source*:
|
if mode is *source*:
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
keyword = *here* or name of a *Python file*
|
keyword = *here* or name of a *Python file*
|
||||||
*here* arg = inline
|
*here* arg = one or more lines of Python code
|
||||||
inline = one or more lines of Python code which defines func
|
must be a single argument, typically enclosed between triple quotes
|
||||||
must be a single argument, typically enclosed between triple quotes
|
the in-lined Python code will be executed immediately
|
||||||
*Python file* = name of a file with Python code which will be executed immediately
|
*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::
|
.. 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*
|
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 = none = invoke the previously-defined Python function
|
||||||
*input* args = N i1 i2 ... iN
|
*input* args = N i1 i2 ... iN
|
||||||
N = # of inputs to function
|
N = # of inputs to function
|
||||||
i1,...,iN = value, SELF, or LAMMPS variable name
|
i1,...,iN = value, SELF, or LAMMPS variable name
|
||||||
value = integer number, floating point number, or string
|
value = integer number, floating point number, or string
|
||||||
SELF = reference to LAMMPS itself which can be accessed by Python function
|
SELF = reference to LAMMPS itself which can then be accessed by Python function
|
||||||
variable = v_name, where name = name of LAMMPS variable, e.g. v_abc
|
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
|
*return* arg = varReturn
|
||||||
varReturn = v_name = LAMMPS variable name which the return value of the Python function will be assigned to
|
varReturn = v_name = LAMMPS variable name which the return value of the Python function will be assigned to
|
||||||
*format* arg = fstring with M characters
|
*format* arg = fstring with M characters
|
||||||
M = N if no return value, where N = # of inputs
|
M = N if no return value, where N = # of inputs
|
||||||
M = N+1 if there is a return value
|
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
|
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
|
'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF
|
||||||
*length* arg = Nlen
|
*length* arg = Nlen
|
||||||
Nlen = max length of string returned from Python function
|
Nlen = max length of string returned from Python function
|
||||||
*file* arg = filename
|
*file* arg = filename
|
||||||
filename = file of Python code, which defines func
|
filename = file of Python code, which defines the Python function
|
||||||
*here* arg = inline
|
*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
|
must be a single argument, typically enclosed between triple quotes
|
||||||
*exists* arg = none = Python code has been loaded by previous python command
|
*exists* arg = none = Python code has been loaded by previous python command
|
||||||
|
|
||||||
@ -87,37 +89,43 @@ Examples
|
|||||||
Description
|
Description
|
||||||
"""""""""""
|
"""""""""""
|
||||||
|
|
||||||
The *python* command allows interfacing LAMMPS with an embedded Python
|
The *python* command interfaces LAMMPS with an embedded Python
|
||||||
interpreter and enables either executing arbitrary python code in that
|
interpreter and enables executing arbitrary python code in that
|
||||||
interpreter, registering a Python function for future execution (as a
|
interpreter. This can be done immediately, by using *mode* =
|
||||||
python style variable, from a fix interfaced with python, or for direct
|
*source*. Or execution can be deferred, by registering a Python
|
||||||
invocation), or invoking such a previously registered function.
|
function for later execution, by using *mode* = *name* of a Python
|
||||||
|
function.
|
||||||
|
|
||||||
Arguments, including LAMMPS variables, can be passed to the function
|
Later execution can be triggered in one of two ways. One is to use
|
||||||
from the LAMMPS input script and a value returned by the Python function
|
the python command again with its *invoke* keyword. The other is to
|
||||||
assigned to a LAMMPS variable. The Python code for the function can be included
|
trigger the evaluation of a python-style, equal-style, or atom-style
|
||||||
directly in the input script or in a separate Python file. The function
|
variable. A python-style variable invokes its associated Python
|
||||||
can be standard Python code or it can make "callbacks" to LAMMPS through
|
function; its return value becomes the value of the python-style
|
||||||
its library interface to query or set internal values within LAMMPS.
|
variable. Equal- and atom-style variables can use a Python function
|
||||||
This is a powerful mechanism for performing complex operations in a
|
wrapper in their formulas which encodes the Python function name, and
|
||||||
LAMMPS input script that are not possible with the simple input script
|
specifies arguments to pass to the function.
|
||||||
and variable syntax which LAMMPS defines. Thus your input script can
|
|
||||||
operate more like a true programming language.
|
Note python-style, equal-style, and atom-style variables can be used
|
||||||
|
in many different ways within LAMMPS. They can be evaulated 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 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.
|
||||||
|
|
||||||
Use of this command requires building LAMMPS with the PYTHON package
|
Use of this command requires building LAMMPS with the PYTHON package
|
||||||
which links to the Python library so that the Python interpreter is
|
which links to the Python library so that the Python interpreter is
|
||||||
embedded in LAMMPS. More details about this process are given below.
|
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
|
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
|
:doc:`Use Python with LAMMPS <Python_head>` section of the
|
||||||
documentation. There also is an ``examples/python`` directory which
|
documentation. There also is an ``examples/python`` directory which
|
||||||
@ -125,25 +133,31 @@ illustrates use of the python command.
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The first argument of the *python* command is either the *source*
|
The first argument is the *mode* setting, which is either *source* or
|
||||||
keyword or the name of a Python function. This defines the mode
|
the *name* of a Python function.
|
||||||
of the python command.
|
|
||||||
|
|
||||||
.. versionchanged:: 22Dec2022
|
.. versionchanged:: 22Dec2022
|
||||||
|
|
||||||
If the *source* keyword is used, it is followed by either a file name or
|
If *source* is used, it is followed by either the *here* keyword or a
|
||||||
the *here* keyword. No other keywords can be used. The *here* keyword
|
file name containing Python code. The *here* keyword is followed by a
|
||||||
is followed by a string with python commands, either on a single line
|
string containing python commands, either on a single line enclosed in
|
||||||
enclosed in quotes, or as multiple lines enclosed in triple quotes.
|
quotes, or as multiple lines enclosed in triple quotes. In either
|
||||||
These Python commands will be passed to the python interpreter and
|
case, the in-line code or file contents are passed to the python
|
||||||
executed immediately without registering a Python function for future
|
interpreter and executed immediately. The code will be loaded into
|
||||||
execution. The code will be loaded into and run in the "main" module of
|
and run in the "main" module of the Python interpreter. This allows
|
||||||
the Python interpreter. This allows running arbitrary Python code at
|
running arbitrary Python code at any time while processing the SPARTA
|
||||||
any time while processing the LAMMPS input file. This can be used to
|
input file. This can be used to pre-load Python modules, initialize
|
||||||
pre-load Python modules, initialize global variables, define functions
|
global variables, define functions or classes, or perform operations
|
||||||
or classes, or perform operations using the python programming language.
|
using the Python programming language. The Python code will be
|
||||||
The Python code will be executed in parallel on all MPI processes. No
|
executed in parallel on all the MPI processes being used to run
|
||||||
arguments can be passed.
|
LAMMPS. Note that no arguments can be passed to the executed Python
|
||||||
|
code.
|
||||||
|
|
||||||
|
If the *mode* setting is the *name* of a Python function, then it will
|
||||||
|
be registered with SPARTA for future execution (or 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*.
|
||||||
|
|
||||||
In all other cases, the first argument is the name of a Python function
|
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
|
that will be registered with LAMMPS for future execution. The function
|
||||||
@ -154,40 +168,79 @@ If the *invoke* keyword is used, no other keywords can be used, and a
|
|||||||
previous *python* command must have registered the Python function
|
previous *python* command must have registered the Python function
|
||||||
referenced by this command. This invokes the Python function with the
|
referenced by this command. This invokes the Python function with the
|
||||||
previously defined arguments and the return value is processed as
|
previously defined arguments and the return value is processed as
|
||||||
explained below. You can invoke the function as many times as you wish
|
explained below. You can invoke a registered function as many times
|
||||||
in your input script.
|
as you wish in your input script.
|
||||||
|
|
||||||
|
NOTE: As indicated with a NOTE in python_impl.cpp, I don't think there
|
||||||
|
is any access to a value returned by invoking a Py function in this way.
|
||||||
|
If that is correct, I think this should be clarified in the doc page,
|
||||||
|
with a better explanation of the utility of using the *invoke* keyword.
|
||||||
|
|
||||||
The *input* keyword defines how many arguments *N* the Python function
|
The *input* keyword defines how many arguments *N* the Python function
|
||||||
expects. If it takes no arguments, then the *input* keyword should not
|
expects. If it takes no arguments, then the *input* keyword should
|
||||||
be used. Each argument can be specified directly as a value, e.g. '6'
|
not be used. Each argument can be specified directly as a value,
|
||||||
or '3.14159' or 'abc' (a string of characters). The type of each
|
e.g. '6' or '3.14159' or 'abc' (a string of characters). The type of
|
||||||
argument is specified by the *format* keyword as explained below, so
|
each argument is specified by the *format* keyword as explained below,
|
||||||
that Python will know how to interpret the value. If the word SELF is
|
so that Python will know how to interpret the value. If the word SELF
|
||||||
used for an argument it has a special meaning. A pointer is passed to
|
is used for an argument it has a special meaning. A pointer is passed
|
||||||
the Python function which it can convert into a reference to LAMMPS
|
to the Python function which it can convert into a reference to LAMMPS
|
||||||
itself using the :doc:`LAMMPS Python module <Python_module>`. This
|
itself using the :doc:`LAMMPS Python module <Python_module>`. This
|
||||||
enables the function to call back to LAMMPS through its library
|
enables the function to call back to LAMMPS through its library
|
||||||
interface as explained below. This allows the Python function to query
|
interface as explained below. This allows the Python function to
|
||||||
or set values internal to LAMMPS which can affect the subsequent
|
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
|
execution of the input script.
|
||||||
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,
|
A LAMMPS variable can also be used as an *input* argument, specified
|
||||||
as defined by the :doc:`variable <variable>` command. The *format*
|
as v_name, where "name" is the name of the variable defined in the
|
||||||
keyword must be used to set the type of data that is passed to Python.
|
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
|
Each time the Python function is invoked, the LAMMPS variable is
|
||||||
evaluated and its value is passed to the Python function.
|
evaluated and its value is passed as an argument to the Python
|
||||||
|
function.
|
||||||
|
|
||||||
|
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 or
|
||||||
|
atom-style variable triggers the invocation of the Python function
|
||||||
|
defined by this command, by including a Python function wrapper in its
|
||||||
|
formula, with one or more arguments also included in the formula.
|
||||||
|
|
||||||
|
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 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;
|
||||||
|
this 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).
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
The *return* keyword is only needed if the Python function returns a
|
The *return* keyword is only needed if the Python function returns a
|
||||||
value. The specified *varReturn* must be of the form v_name, where
|
value. The specified *varReturn* is of the form v_name, where "name"
|
||||||
"name" is the name of a python-style LAMMPS variable, defined by the
|
is the name of a python-style LAMMPS variable, defined by the
|
||||||
:doc:`variable <variable>` command. The Python function can return a
|
:doc:`variable <variable>` command. The Python function can return a
|
||||||
numeric or string value, as specified by the *format* keyword.
|
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
|
As explained on the :doc:`variable <variable>` doc page, the
|
||||||
the *python* command. For example these two commands would be
|
definition of a python-style variable associates a Python function
|
||||||
consistent:
|
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
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
@ -196,43 +249,43 @@ consistent:
|
|||||||
|
|
||||||
The two commands can appear in either order in the input script so
|
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
|
long as both are specified before the Python function is invoked for
|
||||||
the first time. Afterwards, the variable 'foo' is associated with
|
the first time.
|
||||||
the Python function 'myMultiply'.
|
|
||||||
|
|
||||||
The *format* keyword must be used if the *input* or *return* keywords
|
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
|
are used. It defines an *fstring* with M characters, where M = sum of
|
||||||
number of inputs and outputs. The order of characters corresponds to
|
number of inputs and outputs. The order of characters corresponds to
|
||||||
the N inputs, followed by the return value (if it exists). Each
|
the N inputs, followed by the return value (if it exists). Each
|
||||||
character must be one of the following: "i" for integer, "f" for
|
character must be one of the following: "i" for integer, "f" for
|
||||||
floating point, "s" for string, or "p" for SELF. Each character defines
|
floating point, "s" for string, or "p" for SELF. Each character
|
||||||
the type of the corresponding input or output value of the Python
|
defines the type of the corresponding input or output value of the
|
||||||
function and affects the type conversion that is performed internally as
|
Python function and affects the type conversion that is performed
|
||||||
data is passed back and forth between LAMMPS and Python. Note that it
|
internally as data is passed back and forth between LAMMPS and Python.
|
||||||
is permissible to use a :doc:`python-style variable <variable>` in a
|
Note that it is permissible to use a :doc:`python-style variable
|
||||||
LAMMPS command that allows for an equal-style variable as an argument,
|
<variable>` in a LAMMPS command that allows for an equal-style
|
||||||
but only if the output of the Python function is flagged as a numeric
|
variable as an argument, but only if the output of the Python function
|
||||||
value ("i" or "f") via the *format* keyword.
|
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
|
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
|
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
|
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*
|
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
|
value set to a larger number. LAMMPS will then allocate Nlen+1 space
|
||||||
include the string terminator). If the Python function generates a
|
to include the string terminator. If the Python function generates a
|
||||||
string longer than the default 63 or the specified *Nlen*, it will be
|
string longer than the default 63 or the specified *Nlen*, it will be
|
||||||
truncated.
|
truncated.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Either the *file*, *here*, or *exists* keyword must be used, but only
|
As noted above, either the *invoke*, *file*, *here*, or *exists*
|
||||||
one of them. These keywords specify what Python code to load into the
|
keyword must be used, but only one of them. These keywords specify
|
||||||
Python interpreter. The *file* keyword gives the name of a file
|
what Python code to load into the Python interpreter. The *file*
|
||||||
containing Python code, which should end with a ".py" suffix. The code
|
keyword gives the name of a file containing Python code, which should
|
||||||
will be immediately loaded into and run in the "main" module of the
|
end with a ".py" suffix. The code will be immediately loaded into and
|
||||||
Python interpreter. The Python code will be executed in parallel on all
|
run in the "main" module of the Python interpreter. The Python code
|
||||||
MPI processes. Note that Python code which contains a function
|
will be executed in parallel on all MPI processes. Note that Python
|
||||||
definition does not "execute" the function when it is run; it simply
|
code which contains a function definition does not "execute" the
|
||||||
defines the function so that it can be invoked later.
|
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
|
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
|
follows as a single argument to the *here* keyword. This can be done
|
||||||
@ -243,15 +296,18 @@ proper indentation, blank lines, and comments, as desired. See the
|
|||||||
how triple quotes can be used as part of input script syntax.
|
how triple quotes can be used as part of input script syntax.
|
||||||
|
|
||||||
The *exists* keyword takes no argument. It means that Python code
|
The *exists* keyword takes no argument. It means that Python code
|
||||||
containing the required Python function with the given name has already
|
containing the required Python function with the given name has
|
||||||
been executed, for example by a *python source* command or in the same
|
already been executed, for example by a *python source* command or in
|
||||||
file that was used previously with the *file* keyword.
|
the same file that was used 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 must contain a function
|
Note that the Python code that is loaded and run by the *file* or
|
||||||
with the specified function name. To operate properly when later
|
*here* keyword must contain a function with the specified function
|
||||||
invoked, the function code must match the *input* and *return* and
|
name. To operate properly when later invoked, the function code must
|
||||||
*format* keywords specified by the python command. Otherwise Python
|
match the *input* and *return* and *format* keywords specified by the
|
||||||
will generate an error.
|
python command. Otherwise Python will generate an error.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -308,13 +364,13 @@ previous value is simply returned, without re-computing it. The
|
|||||||
"global" statement inside the Python function allows it to overwrite the
|
"global" statement inside the Python function allows it to overwrite the
|
||||||
global variables from within the local context of the function.
|
global variables from within the local context of the function.
|
||||||
|
|
||||||
Note that if you load Python code multiple times (via multiple python
|
Also note that if you load Python code multiple times (via multiple
|
||||||
commands), you can overwrite previously loaded variables and functions
|
python commands), you can overwrite previously loaded variables and
|
||||||
if you are not careful. E.g. if the code above were loaded twice, the
|
functions if you are not careful. E.g. if the code above were loaded
|
||||||
global variables would be re-initialized, which might not be what you
|
twice, the global variables would be re-initialized, which might not
|
||||||
want. Likewise, if a function with the same name exists in two chunks
|
be what you want. Likewise, if a function with the same name exists
|
||||||
of Python code you load, the function loaded second will override the
|
in two chunks of Python code you load, the function loaded second will
|
||||||
function loaded first.
|
override the function loaded first.
|
||||||
|
|
||||||
It's important to realize that if you are running LAMMPS in parallel,
|
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
|
each MPI task will load the Python interpreter and execute a local
|
||||||
@ -325,15 +381,16 @@ This implies three important things.
|
|||||||
First, if you put a print or other statement creating output to the
|
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,
|
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
|
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
|
time, the P copies of the output may be mixed together.
|
||||||
the LAMMPS Python module into the embedded Python interpreter, it is
|
|
||||||
possible to pass the pointer to the current LAMMPS class instance and
|
It is possible to avoid this issue, by passing the pointer to the
|
||||||
via the Python interface to the LAMMPS library interface, it is possible
|
current LAMMPS class instance to the Python function via the {input}
|
||||||
to determine the MPI rank of the current process and thus adapt the
|
SELF argument described above. The Python function can then use the
|
||||||
Python code so that output will only appear on MPI rank 0. The
|
Python interface to the LAMMPS library interface, and determine the
|
||||||
following LAMMPS input demonstrates how this could be done. The text
|
MPI rank of the current process. The Python code can then ensure
|
||||||
'Hello, LAMMPS!' should be printed only once, even when running LAMMPS
|
output will only appear on MPI rank 0. The following LAMMPS input
|
||||||
in parallel.
|
demonstrates how this could be done. The text 'Hello, LAMPS!' should
|
||||||
|
be printed only once, even when running LAMMPS in parallel.
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
@ -348,13 +405,13 @@ in parallel.
|
|||||||
|
|
||||||
python python_hello invoke
|
python python_hello invoke
|
||||||
|
|
||||||
If your Python code loads Python modules that are not pre-loaded by the
|
Second, if your Python code loads Python modules that are not
|
||||||
Python library, then it will load the module from disk. This may be a
|
pre-loaded by the Python library, then it will load the module from
|
||||||
bottleneck if 1000s of processors try to load a module at the same time.
|
disk. This may be a bottleneck if 1000s of processors try to load a
|
||||||
On some large supercomputers, loading of modules from disk by Python may
|
module at the same time. On some large supercomputers, loading of
|
||||||
be disabled. In this case you would need to pre-build a Python library
|
modules from disk by Python may be disabled. In this case you would
|
||||||
that has the required modules pre-loaded and link LAMMPS with that
|
need to pre-build a Python library that has the required modules
|
||||||
library.
|
pre-loaded and link LAMMPS with that library.
|
||||||
|
|
||||||
Third, if your Python code calls back to LAMMPS (discussed in the
|
Third, if your Python code calls back to LAMMPS (discussed in the
|
||||||
next section) and causes LAMMPS to perform an MPI operation requires
|
next section) and causes LAMMPS to perform an MPI operation requires
|
||||||
@ -365,10 +422,10 @@ LAMMPS. Otherwise the code may hang.
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Your Python function can "call back" to LAMMPS through its
|
As mentioned above, a Python function can "call back" to LAMMPS
|
||||||
library interface, if you use the SELF input to pass Python
|
through its library interface, if the SELF input is used to pass
|
||||||
a pointer to LAMMPS. The mechanism for doing this in your
|
Python a pointer to LAMMPS. The mechanism for doing this is as
|
||||||
Python function is as follows:
|
follows:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@ -416,7 +473,7 @@ which loads and runs the following function from ``examples/python/funcs.py``:
|
|||||||
|
|
||||||
lmp.set_variable("cut",cut) # set a variable in LAMMPS
|
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 ${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("pair_coeff * * 1.0 1.0") # ditto
|
||||||
lmp.command("run 10") # ditto
|
lmp.command("run 10") # ditto
|
||||||
@ -449,9 +506,9 @@ 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
|
LAMMPS, more than the single value that can be passed back via a
|
||||||
return statement. This cutoff value in the "cut" variable is then
|
return statement. This cutoff value in the "cut" variable is then
|
||||||
substituted (by LAMMPS) in the pair_style command that is executed
|
substituted (by LAMMPS) in the pair_style command that is executed
|
||||||
next. Alternatively, the "LAMMPS command option" line could be used
|
next. Alternatively, the "alternate form of LAMMPS command" line
|
||||||
in place of the 2 preceding lines, to have Python insert the value
|
could be used in place of the 2 preceding lines, to have Python insert
|
||||||
into the LAMMPS command string.
|
the value into the LAMMPS command string.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -463,20 +520,109 @@ into the LAMMPS command string.
|
|||||||
file() functions, so long as the command would work if it were
|
file() functions, so long as the command would work if it were
|
||||||
executed in the LAMMPS input script directly at the same point.
|
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>`.
|
|
||||||
|
A Python function can also 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.
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
A Python function can also be invoked within the formula for an
|
||||||
|
equal-style or atom-style varaible. This means the Python function
|
||||||
|
will be invoked whenever the variable is invoked. In the case of an
|
||||||
|
atom-style varaible, the Python function can be invoked once per atom.
|
||||||
|
|
||||||
|
Here are two simple examples using equal- 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 atom-style
|
||||||
|
varaibles 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
|
||||||
|
|
||||||
|
Now 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
|
||||||
|
varaible formula or by *input* keyword to the *python command. 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_flags &
|
||||||
|
format fffffsf here """
|
||||||
|
def mixedargs(a,b,x,y,z,flags):
|
||||||
|
...
|
||||||
|
return result
|
||||||
|
"""
|
||||||
|
variable flags 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 arguements (7.5,v_myValue,v_flags) 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 teach 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.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -563,27 +709,30 @@ 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
|
argument explained above, there is an extra step required when building
|
||||||
LAMMPS. LAMMPS must also be built as a shared library and your Python
|
LAMMPS. LAMMPS must also be built as a shared library and your Python
|
||||||
function must be able to load the :doc:`"lammps" Python module
|
function must be able to load the :doc:`"lammps" Python module
|
||||||
<Python_module>` that wraps the LAMMPS library interface. These are the
|
<Python_module>` that wraps the LAMMPS library interface.
|
||||||
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.
|
These are the same steps required to use Python by itself to wrap
|
||||||
Note that it is important that the stand-alone LAMMPS executable and the
|
LAMMPS. Details on these steps are explained on the :doc:`Python
|
||||||
LAMMPS shared library be consistent (built from the same source code
|
<Python_head>` doc page. Note that it is important that the
|
||||||
files) in order for this to work. If the two have been built at
|
stand-alone LAMMPS executable and the LAMMPS shared library be
|
||||||
different times using different source files, problems may occur.
|
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
|
Another limitation of calling back to Python from the LAMMPS module
|
||||||
using the *python* command in a LAMMPS input is that both, the Python
|
using the *python* command in a LAMMPS input is that both, the Python
|
||||||
interpreter and LAMMPS, must be linked to the same Python runtime as a
|
interpreter and LAMMPS, must be linked to the same Python runtime as a
|
||||||
shared library. If the Python interpreter is linked to Python
|
shared library. If the Python interpreter is linked to Python
|
||||||
statically (which seems to happen with Conda) then loading the shared
|
statically (which seems to happen with Conda) then loading the shared
|
||||||
LAMMPS library will create a second python "main" module that hides the
|
LAMMPS library will create a second python "main" module that hides
|
||||||
one from the Python interpreter and all previous defined function and
|
the one from the Python interpreter and all previous defined function
|
||||||
global variables will become invisible.
|
and global variables will become invisible.
|
||||||
|
|
||||||
Related commands
|
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
|
Default
|
||||||
"""""""
|
"""""""
|
||||||
|
|||||||
@ -397,13 +397,24 @@ using the :doc:`command-line switch -var <Run_options>`.
|
|||||||
|
|
||||||
For the *internal* style a numeric value is provided. This value will
|
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
|
be assigned to the variable until a LAMMPS command sets it to a new
|
||||||
value. There are currently only two LAMMPS commands that require
|
value.
|
||||||
*internal* variables as inputs, because they reset them:
|
|
||||||
:doc:`create_atoms <create_atoms>` and :doc:`fix controller
|
Note however, that most commands which use internal-style variables do
|
||||||
<fix_controller>`. As mentioned above, an internal-style variable can
|
not require them to be defined in the input script. They create one
|
||||||
be used in place of an equal-style variable anywhere else in an input
|
or more internal-style variables if they do not already exist.
|
||||||
script, e.g. as an argument to another command that allows for
|
Examples are these commands:
|
||||||
equal-style variables.
|
|
||||||
|
* :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.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -449,12 +460,13 @@ anywhere in an input script, e.g. as an argument to another command
|
|||||||
that allows for equal-style variables.
|
that allows for equal-style variables.
|
||||||
|
|
||||||
A python-style variable can also be used within the formula for an
|
A python-style variable can also be used within the formula for an
|
||||||
equal-style or atom-style formula with the syntax
|
equal-style or atom-style formula in a Python function wrapper, as
|
||||||
py_varname(arg1,arg2,...) as explained below for variable formulas.
|
explained below for variable formulas. In this context, the usage
|
||||||
When used in an atom-style formula, it can the variable can be invoked
|
syntax is py_varname(arg1,arg2,...), where varname is the name of the
|
||||||
once per atom using arguments specific to each atom. The resulting
|
python-style variable. When a Python wrapper function is used in an
|
||||||
values in the atom-style variable can thus be calculated by Python
|
atom-style formula, it can be invoked once per atom using arguments
|
||||||
code.
|
specific to each atom. The resulting values in the atom-style
|
||||||
|
variable can thus be calculated by Python code.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -545,7 +557,7 @@ is a valid (though strange) variable formula:
|
|||||||
|
|
||||||
Specifically, a formula can contain numbers, constants, thermo
|
Specifically, a formula can contain numbers, constants, thermo
|
||||||
keywords, math operators, math functions, group functions, region
|
keywords, math operators, math functions, group functions, region
|
||||||
functions, special functions, feature functions, python function
|
functions, special functions, feature functions, Python function
|
||||||
wrappers, atom values, atom vectors, custom atom properties, compute
|
wrappers, atom values, atom vectors, custom atom properties, compute
|
||||||
references, fix references, and references to other variables.
|
references, fix references, and references to other variables.
|
||||||
|
|
||||||
@ -568,7 +580,7 @@ references, fix references, and references to other variables.
|
|||||||
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) |
|
| Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) |
|
||||||
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| Python func wrappers | py_varname(x,y,z,...) |
|
| 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 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] |
|
||||||
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
@ -1180,7 +1192,7 @@ variable name.
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Python Function wrappers
|
Python Function wrapper
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
A Python function wrapper enables the formula for an equal-style or
|
A Python function wrapper enables the formula for an equal-style or
|
||||||
@ -1211,11 +1223,10 @@ input script:
|
|||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
variable foo python truncate
|
variable foo python truncate
|
||||||
python truncate return v_foo input 1 v_pyarg1 format fi here """
|
python truncate return v_foo input 1 v_arg format fi here """
|
||||||
def truncate(x):
|
def truncate(x):
|
||||||
return int(x)
|
return int(x)
|
||||||
"""
|
"""
|
||||||
variable pyarg1 internal 0.0
|
|
||||||
variable xtrunc atom py_foo(x)
|
variable xtrunc atom py_foo(x)
|
||||||
variable ytrunc atom py_foo(y)
|
variable ytrunc atom py_foo(y)
|
||||||
variable ztrunc atom py_foo(z)
|
variable ztrunc atom py_foo(z)
|
||||||
@ -1228,12 +1239,6 @@ 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
|
command; it could also be contained in a file. See the :doc:`python
|
||||||
<python>` command doc page for details.
|
<python>` command doc page for details.
|
||||||
|
|
||||||
The *variable pyarg1* command defines an internal-style variable. It
|
|
||||||
MUST have the name pyarg1. If the Python function has *N* arguments,
|
|
||||||
*N* internal-style variables MUST be defined with names *pyarg1*,
|
|
||||||
*pyarg2*, ... *pyargN*. Note that multiple Python function wrappers
|
|
||||||
can use the same internal-style variables.
|
|
||||||
|
|
||||||
The next three commands define atom-style variables *xtrunc*,
|
The next three commands define atom-style variables *xtrunc*,
|
||||||
*ytrunc*, and *ztrunc*. Each of them include the same Python function
|
*ytrunc*, and *ztrunc*. Each of them include the same Python function
|
||||||
wrapper in their formula, with a different argument. The atom-style
|
wrapper in their formula, with a different argument. The atom-style
|
||||||
@ -1242,15 +1247,27 @@ will in turn invoke the Python-coded *truncate()* method. Because
|
|||||||
*xtrunc* is an atom-style variable, and the argument *x* in the Python
|
*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),
|
function wrapper is a per-atom quantity (the x-coord of each atom),
|
||||||
each processor will invoke the *truncate()* method once per atom, for
|
each processor will invoke the *truncate()* method once per atom, for
|
||||||
the atoms it owns. When invoked for the Ith atom, the x-coord of the
|
the atoms it owns.
|
||||||
Ith atom becomes the value of the *pyarg1* internal-style variable.
|
|
||||||
The call to the *truncate()* function uses the value of the *pyarg1*
|
When invoked for the Ith atom, the value of the *arg* internal-style
|
||||||
variable as its first (and only) argument.
|
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 its
|
||||||
|
first (and only) argument. Likewise, the return value of the Python
|
||||||
|
function becomes 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
|
The resulting per-atom vector for *xtrunc* will thus contain the
|
||||||
truncated x-coord of every atom in the system. The dump command
|
truncated x-coord of every atom in the system. The dump command
|
||||||
includes the truncated xyz coords for each atom in its output.
|
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
|
Atom Values and Vectors
|
||||||
|
|||||||
@ -25,11 +25,10 @@ neigh_modify delay 0 every 20 check no
|
|||||||
fix 1 all nve
|
fix 1 all nve
|
||||||
|
|
||||||
variable foo python truncate
|
variable foo python truncate
|
||||||
python truncate return v_foo input 1 v_pyarg1 format fi here """
|
python truncate return v_foo input 1 iv_arg format fi here """
|
||||||
def truncate(x):
|
def truncate(x):
|
||||||
return int(x)
|
return int(x)
|
||||||
"""
|
"""
|
||||||
variable pyarg1 internal 0.0
|
|
||||||
|
|
||||||
variable scalar equal py_foo(4.5)
|
variable scalar equal py_foo(4.5)
|
||||||
print "TRUNCATE ${scalar}"
|
print "TRUNCATE ${scalar}"
|
||||||
@ -40,7 +39,6 @@ variable ztrunc atom py_foo(z)
|
|||||||
|
|
||||||
# examine dump file to see truncated xyz coords of each atom
|
# examine dump file to see truncated xyz coords of each atom
|
||||||
|
|
||||||
#dump 1 all custom 100 tmp.dump id x y z
|
|
||||||
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
|
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
|
||||||
|
|
||||||
run 100
|
run 100
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
LAMMPS (2 Apr 2025 - Development - patch_2Apr2025-125-g7ca493917a-modified)
|
LAMMPS (2 Apr 2025 - Development - patch_2Apr2025-266-gebfb94a717-modified)
|
||||||
# 3d Lennard-Jones melt with equal- and atom-style variables which
|
# 3d Lennard-Jones melt with equal- and atom-style variables which
|
||||||
# use a Python function wrapper in their formulas
|
# use a Python function wrapper in their formulas
|
||||||
|
|
||||||
@ -35,11 +35,10 @@ neigh_modify delay 0 every 20 check no
|
|||||||
fix 1 all nve
|
fix 1 all nve
|
||||||
|
|
||||||
variable foo python truncate
|
variable foo python truncate
|
||||||
python truncate return v_foo input 1 v_pyarg1 format fi here """
|
python truncate return v_foo input 1 iv_arg format fi here """
|
||||||
def truncate(x):
|
def truncate(x):
|
||||||
return int(x)
|
return int(x)
|
||||||
"""
|
"""
|
||||||
variable pyarg1 internal 0.0
|
|
||||||
|
|
||||||
variable scalar equal py_foo(4.5)
|
variable scalar equal py_foo(4.5)
|
||||||
print "TRUNCATE ${scalar}"
|
print "TRUNCATE ${scalar}"
|
||||||
@ -49,7 +48,8 @@ variable xtrunc atom py_foo(x)
|
|||||||
variable ytrunc atom py_foo(y)
|
variable ytrunc atom py_foo(y)
|
||||||
variable ztrunc atom py_foo(z)
|
variable ztrunc atom py_foo(z)
|
||||||
|
|
||||||
#dump 1 all custom 100 tmp.dump id x y z
|
# examine dump file to see truncated xyz coords of each atom
|
||||||
|
|
||||||
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
|
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
|
||||||
|
|
||||||
run 100
|
run 100
|
||||||
@ -70,20 +70,20 @@ Per MPI rank memory allocation (min/avg/max) = 2.644 | 2.644 | 2.644 Mbytes
|
|||||||
Step Temp E_pair E_mol TotEng Press
|
Step Temp E_pair E_mol TotEng Press
|
||||||
0 1.44 -6.7733681 0 -4.6176881 -5.0221006
|
0 1.44 -6.7733681 0 -4.6176881 -5.0221006
|
||||||
100 0.75627408 -5.7580082 0 -4.6258659 0.21870071
|
100 0.75627408 -5.7580082 0 -4.6258659 0.21870071
|
||||||
Loop time of 0.0160255 on 1 procs for 100 steps with 500 atoms
|
Loop time of 0.014627 on 1 procs for 100 steps with 500 atoms
|
||||||
|
|
||||||
Performance: 2695709.610 tau/day, 6240.069 timesteps/s, 3.120 Matom-step/s
|
Performance: 2953445.899 tau/day, 6836.680 timesteps/s, 3.418 Matom-step/s
|
||||||
100.0% CPU use with 1 MPI tasks x no OpenMP threads
|
100.0% CPU use with 1 MPI tasks x no OpenMP threads
|
||||||
|
|
||||||
MPI task timing breakdown:
|
MPI task timing breakdown:
|
||||||
Section | min time | avg time | max time |%varavg| %total
|
Section | min time | avg time | max time |%varavg| %total
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
Pair | 0.011326 | 0.011326 | 0.011326 | 0.0 | 70.67
|
Pair | 0.010546 | 0.010546 | 0.010546 | 0.0 | 72.10
|
||||||
Neigh | 0.002924 | 0.002924 | 0.002924 | 0.0 | 18.25
|
Neigh | 0.0027775 | 0.0027775 | 0.0027775 | 0.0 | 18.99
|
||||||
Comm | 0.00046255 | 0.00046255 | 0.00046255 | 0.0 | 2.89
|
Comm | 0.00044818 | 0.00044818 | 0.00044818 | 0.0 | 3.06
|
||||||
Output | 0.0010398 | 0.0010398 | 0.0010398 | 0.0 | 6.49
|
Output | 0.00060601 | 0.00060601 | 0.00060601 | 0.0 | 4.14
|
||||||
Modify | 0.00020589 | 0.00020589 | 0.00020589 | 0.0 | 1.28
|
Modify | 0.00018516 | 0.00018516 | 0.00018516 | 0.0 | 1.27
|
||||||
Other | | 6.725e-05 | | | 0.42
|
Other | | 6.39e-05 | | | 0.44
|
||||||
|
|
||||||
Nlocal: 500 ave 500 max 500 min
|
Nlocal: 500 ave 500 max 500 min
|
||||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
LAMMPS (2 Apr 2025 - Development - patch_2Apr2025-125-g7ca493917a-modified)
|
LAMMPS (2 Apr 2025 - Development - patch_2Apr2025-266-gebfb94a717-modified)
|
||||||
# 3d Lennard-Jones melt with equal- and atom-style variables which
|
# 3d Lennard-Jones melt with equal- and atom-style variables which
|
||||||
# use a Python function wrapper in their formulas
|
# use a Python function wrapper in their formulas
|
||||||
|
|
||||||
@ -35,11 +35,10 @@ neigh_modify delay 0 every 20 check no
|
|||||||
fix 1 all nve
|
fix 1 all nve
|
||||||
|
|
||||||
variable foo python truncate
|
variable foo python truncate
|
||||||
python truncate return v_foo input 1 v_pyarg1 format fi here """
|
python truncate return v_foo input 1 iv_arg format fi here """
|
||||||
def truncate(x):
|
def truncate(x):
|
||||||
return int(x)
|
return int(x)
|
||||||
"""
|
"""
|
||||||
variable pyarg1 internal 0.0
|
|
||||||
|
|
||||||
variable scalar equal py_foo(4.5)
|
variable scalar equal py_foo(4.5)
|
||||||
print "TRUNCATE ${scalar}"
|
print "TRUNCATE ${scalar}"
|
||||||
@ -49,7 +48,8 @@ variable xtrunc atom py_foo(x)
|
|||||||
variable ytrunc atom py_foo(y)
|
variable ytrunc atom py_foo(y)
|
||||||
variable ztrunc atom py_foo(z)
|
variable ztrunc atom py_foo(z)
|
||||||
|
|
||||||
#dump 1 all custom 100 tmp.dump id x y z
|
# examine dump file to see truncated xyz coords of each atom
|
||||||
|
|
||||||
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
|
dump 1 all custom 100 tmp.dump id x y z v_xtrunc v_ytrunc v_ztrunc
|
||||||
|
|
||||||
run 100
|
run 100
|
||||||
@ -70,20 +70,20 @@ Per MPI rank memory allocation (min/avg/max) = 2.609 | 2.609 | 2.609 Mbytes
|
|||||||
Step Temp E_pair E_mol TotEng Press
|
Step Temp E_pair E_mol TotEng Press
|
||||||
0 1.44 -6.7733681 0 -4.6176881 -5.0221006
|
0 1.44 -6.7733681 0 -4.6176881 -5.0221006
|
||||||
100 0.75627408 -5.7580082 0 -4.6258659 0.21870071
|
100 0.75627408 -5.7580082 0 -4.6258659 0.21870071
|
||||||
Loop time of 0.00641075 on 4 procs for 100 steps with 500 atoms
|
Loop time of 0.0062374 on 4 procs for 100 steps with 500 atoms
|
||||||
|
|
||||||
Performance: 6738684.275 tau/day, 15598.806 timesteps/s, 7.799 Matom-step/s
|
Performance: 6925957.189 tau/day, 16032.308 timesteps/s, 8.016 Matom-step/s
|
||||||
100.0% CPU use with 4 MPI tasks x no OpenMP threads
|
74.7% CPU use with 4 MPI tasks x no OpenMP threads
|
||||||
|
|
||||||
MPI task timing breakdown:
|
MPI task timing breakdown:
|
||||||
Section | min time | avg time | max time |%varavg| %total
|
Section | min time | avg time | max time |%varavg| %total
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
Pair | 0.0028061 | 0.0028831 | 0.0029657 | 0.1 | 44.97
|
Pair | 0.0027648 | 0.0028431 | 0.0029465 | 0.1 | 45.58
|
||||||
Neigh | 0.00086635 | 0.00088279 | 0.00089739 | 0.0 | 13.77
|
Neigh | 0.00084567 | 0.00086563 | 0.00088168 | 0.0 | 13.88
|
||||||
Comm | 0.0020095 | 0.0020768 | 0.0021521 | 0.1 | 32.40
|
Comm | 0.0020822 | 0.0021609 | 0.0022418 | 0.1 | 34.64
|
||||||
Output | 0.00041634 | 0.00042457 | 0.00043221 | 0.0 | 6.62
|
Output | 0.00021567 | 0.00022125 | 0.00022624 | 0.0 | 3.55
|
||||||
Modify | 6.2967e-05 | 6.4188e-05 | 6.5205e-05 | 0.0 | 1.00
|
Modify | 6.2567e-05 | 6.4105e-05 | 6.63e-05 | 0.0 | 1.03
|
||||||
Other | | 7.934e-05 | | | 1.24
|
Other | | 8.241e-05 | | | 1.32
|
||||||
|
|
||||||
Nlocal: 125 ave 126 max 123 min
|
Nlocal: 125 ave 126 max 123 min
|
||||||
Histogram: 1 0 0 0 0 0 1 0 0 2
|
Histogram: 1 0 0 0 0 0 1 0 0 2
|
||||||
|
|||||||
@ -415,7 +415,7 @@ void PythonImpl::invoke_function(int ifunc, char *result, double *dvalue)
|
|||||||
strncpy(result, value.c_str(), Variable::VALUELENGTH - 1);
|
strncpy(result, value.c_str(), Variable::VALUELENGTH - 1);
|
||||||
}
|
}
|
||||||
} else if (otype == DOUBLE) {
|
} else if (otype == DOUBLE) {
|
||||||
if (*dvalue) *dvalue = PyFloat_AsDouble(pValue);
|
if (dvalue) *dvalue = PyFloat_AsDouble(pValue);
|
||||||
else {
|
else {
|
||||||
auto value = fmt::format("{:.15g}", PyFloat_AsDouble(pValue));
|
auto value = fmt::format("{:.15g}", PyFloat_AsDouble(pValue));
|
||||||
strncpy(result, value.c_str(), Variable::VALUELENGTH - 1);
|
strncpy(result, value.c_str(), Variable::VALUELENGTH - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user