234 lines
8.7 KiB
ReStructuredText
234 lines
8.7 KiB
ReStructuredText
.. index:: pair_style python
|
|
|
|
pair_style python command
|
|
=========================
|
|
|
|
Syntax
|
|
""""""
|
|
|
|
.. code-block:: LAMMPS
|
|
|
|
pair_style python cutoff
|
|
|
|
cutoff = global cutoff for interactions in python potential classes
|
|
|
|
Examples
|
|
""""""""
|
|
|
|
.. code-block:: LAMMPS
|
|
|
|
pair_style python 2.5
|
|
pair_coeff * * py_pot.LJCutMelt lj
|
|
|
|
pair_style hybrid/overlay coul/long 12.0 python 12.0
|
|
pair_coeff * * coul/long
|
|
pair_coeff * * python py_pot.LJCutSPCE OW NULL
|
|
|
|
Description
|
|
"""""""""""
|
|
|
|
The *python* pair style provides a way to define pairwise additive
|
|
potential functions as python script code that is loaded into LAMMPS
|
|
from a python file which must contain specific python class definitions.
|
|
This allows to rapidly evaluate different potential functions without
|
|
having to modify and re-compile LAMMPS. Due to python being an
|
|
interpreted language, however, the performance of this pair style is
|
|
going to be significantly slower (often between 20x and 100x) than
|
|
corresponding compiled code. This penalty can be significantly reduced
|
|
through generating tabulations from the python code through the
|
|
:doc:`pair_write <pair_write>` command, which is supported by this style.
|
|
|
|
Only a single pair_coeff command is used with the *python* pair style
|
|
which specifies a python class inside a python module or file that
|
|
LAMMPS will look up in the current directory, the folder pointed to by
|
|
the LAMMPS_POTENTIALS environment variable or somewhere in your python
|
|
path. A single python module can hold multiple python pair class
|
|
definitions. The class definitions itself have to follow specific
|
|
rules that are explained below.
|
|
|
|
Atom types in the python class are specified through symbolic
|
|
constants, typically strings. These are mapped to LAMMPS atom types by
|
|
specifying N additional arguments after the class name in the
|
|
pair_coeff command, where N must be the number of currently defined
|
|
atom types:
|
|
|
|
As an example, imagine a file *py_pot.py* has a python potential class
|
|
names *LJCutMelt* with parameters and potential functions for a two
|
|
Lennard-Jones atom types labeled as 'LJ1' and 'LJ2'. In your LAMMPS
|
|
input and you would have defined 3 atom types, out of which the first
|
|
two are supposed to be using the 'LJ1' parameters and the third the
|
|
'LJ2' parameters, then you would use the following pair_coeff command:
|
|
|
|
.. code-block:: LAMMPS
|
|
|
|
pair_coeff * * py_pot.LJCutMelt LJ1 LJ1 LJ2
|
|
|
|
The first two arguments **must** be \* \* so as to span all LAMMPS atom
|
|
types. The first two LJ1 arguments map LAMMPS atom types 1 and 2 to
|
|
the LJ1 atom type in the LJCutMelt class of the py_pot.py file. The
|
|
final LJ2 argument maps LAMMPS atom type 3 to the LJ2 atom type the
|
|
python file. If a mapping value is specified as NULL, the mapping is
|
|
not performed, any pair interaction with this atom type will be
|
|
skipped. This can be used when a *python* potential is used as part of
|
|
the *hybrid* or *hybrid/overlay* pair style. The NULL values are then
|
|
placeholders for atom types that will be used with other potentials.
|
|
|
|
----------
|
|
|
|
The python potential file has to start with the following code:
|
|
|
|
.. code-block:: python
|
|
|
|
from __future__ import print_function
|
|
|
|
class LAMMPSPairPotential(object):
|
|
def __init__(self):
|
|
self.pmap=dict()
|
|
self.units='lj'
|
|
def map_coeff(self,name,ltype):
|
|
self.pmap[ltype]=name
|
|
def check_units(self,units):
|
|
if (units != self.units):
|
|
raise Exception("Conflicting units: %s vs. %s" % (self.units,units))
|
|
|
|
Any classes with definitions of specific potentials have to be derived
|
|
from this class and should be initialize in a similar fashion to the
|
|
example given below.
|
|
|
|
.. note::
|
|
|
|
The class constructor has to set up a data structure containing
|
|
the potential parameters supported by this class. It should also
|
|
define a variable *self.units* containing a string matching one of the
|
|
options of LAMMPS' :doc:`units <units>` command, which is used to
|
|
verify, that the potential definition in the python class and in the
|
|
LAMMPS input match.
|
|
|
|
Here is an example for a single type Lennard-Jones potential class
|
|
*LJCutMelt* in reduced units, which defines an atom type *lj* for
|
|
which the parameters epsilon and sigma are both 1.0:
|
|
|
|
.. code-block:: python
|
|
|
|
class LJCutMelt(LAMMPSPairPotential):
|
|
def __init__(self):
|
|
super(LJCutMelt,self).__init__()
|
|
# set coeffs: 48*eps*sig**12, 24*eps*sig**6,
|
|
# 4*eps*sig**12, 4*eps*sig**6
|
|
self.units = 'lj'
|
|
self.coeff = {'lj' : {'lj' : (48.0,24.0,4.0,4.0)}}
|
|
|
|
The class also has to provide two methods for the computation of the
|
|
potential energy and forces, which have be named *compute_force*,
|
|
and *compute_energy*, which both take 3 numerical arguments:
|
|
|
|
* rsq = the square of the distance between a pair of atoms (float)
|
|
* itype = the (numerical) type of the first atom
|
|
* jtype = the (numerical) type of the second atom
|
|
|
|
This functions need to compute the force and the energy, respectively,
|
|
and use the result as return value. The functions need to use the
|
|
*pmap* dictionary to convert the LAMMPS atom type number to the symbolic
|
|
value of the internal potential parameter data structure. Following
|
|
the *LJCutMelt* example, here are the two functions:
|
|
|
|
.. code-block:: python
|
|
|
|
def compute_force(self,rsq,itype,jtype):
|
|
coeff = self.coeff[self.pmap[itype]][self.pmap[jtype]]
|
|
r2inv = 1.0/rsq
|
|
r6inv = r2inv*r2inv*r2inv
|
|
lj1 = coeff[0]
|
|
lj2 = coeff[1]
|
|
return (r6inv * (lj1*r6inv - lj2))*r2inv
|
|
|
|
def compute_energy(self,rsq,itype,jtype):
|
|
coeff = self.coeff[self.pmap[itype]][self.pmap[jtype]]
|
|
r2inv = 1.0/rsq
|
|
r6inv = r2inv*r2inv*r2inv
|
|
lj3 = coeff[2]
|
|
lj4 = coeff[3]
|
|
return (r6inv * (lj3*r6inv - lj4))
|
|
|
|
.. note::
|
|
|
|
for consistency with the C++ pair styles in LAMMPS, the
|
|
*compute_force* function follows the conventions of the Pair::single()
|
|
methods and does not return the full force, but the force scaled by
|
|
the distance between the two atoms, so this value only needs to be
|
|
multiplied by delta x, delta y, and delta z to conveniently obtain the
|
|
three components of the force vector between these two atoms.
|
|
|
|
----------
|
|
|
|
.. note::
|
|
|
|
The evaluation of scripted python code will slow down the
|
|
computation pair-wise interactions quite significantly. However, this
|
|
can be largely worked around through using the python pair style not
|
|
for the actual simulation, but to generate tabulated potentials on the
|
|
fly using the :doc:`pair_write <pair_write>` command. Please see below
|
|
for an example LAMMPS input of how to build a table file:
|
|
|
|
.. code-block:: LAMMPS
|
|
|
|
pair_style python 2.5
|
|
pair_coeff * * py_pot.LJCutMelt lj
|
|
shell rm -f melt.table
|
|
pair_write 1 1 2000 rsq 0.01 2.5 lj1_lj2.table lj
|
|
|
|
Note that it is strongly recommended to try to **delete** the potential
|
|
table file before generating it. Since the *pair_write* command will
|
|
always **append** to a table file, while pair style table will use the
|
|
**first match**\ . Thus when changing the potential function in the python
|
|
class, the table pair style will still read the old variant unless the
|
|
table file is first deleted.
|
|
|
|
After switching the pair style to *table*\ , the potential tables need
|
|
to be assigned to the LAMMPS atom types like this:
|
|
|
|
.. code-block:: LAMMPS
|
|
|
|
pair_style table linear 2000
|
|
pair_coeff 1 1 melt.table lj
|
|
|
|
This can also be done for more complex systems. Please see the
|
|
*examples/python* folders for a few more examples.
|
|
|
|
----------
|
|
|
|
**Mixing, shift, table, tail correction, restart, rRESPA info**\ :
|
|
|
|
Mixing of potential parameters has to be handled inside the provided
|
|
python module. The python pair style simply assumes that force and
|
|
energy computation can be correctly performed for all pairs of atom
|
|
types as they are mapped to the atom type labels inside the python
|
|
potential class.
|
|
|
|
This pair style does not support the :doc:`pair_modify <pair_modify>`
|
|
shift, table, and tail options.
|
|
|
|
This pair style does not write its information to :doc:`binary restart files <restart>`, since it is stored in potential files. Thus, you
|
|
need to re-specify the pair_style and pair_coeff commands in an input
|
|
script that reads a restart file.
|
|
|
|
This pair style can only be used via the *pair* keyword of the
|
|
:doc:`run_style respa <run_style>` command. It does not support the
|
|
*inner*\ , *middle*\ , *outer* keywords.
|
|
|
|
----------
|
|
|
|
Restrictions
|
|
""""""""""""
|
|
|
|
This pair style is part of the PYTHON package. It is only enabled if
|
|
LAMMPS was built with that package. See the :doc:`Build package <Build_package>` doc page for more info.
|
|
|
|
Related commands
|
|
""""""""""""""""
|
|
|
|
:doc:`pair_coeff <pair_coeff>`, :doc:`pair_write <pair_write>`,
|
|
:doc:`pair style table <pair_table>`
|
|
|
|
**Default:** none
|