update pair style python docs

This commit is contained in:
Axel Kohlmeyer 2017-05-18 00:29:02 -04:00
parent 67962b15fc
commit 9725708b90
1 changed files with 131 additions and 56 deletions

View File

@ -26,86 +26,161 @@ pair_coeff * * python py_pot.LJCutSPCE OW NULL :pre
[Description:]
The {python} pair style provides a way to define pairwise additive
potential functions as scripted python script code that is loaded
into LAMMPS from a python file which must contain specific python
class definitions. This allows to model potentials, that are not
currently available in LAMMPS without having to program a new
pair style or modify an existing one and recompile LAMMPS. Due to
python being an interpreted language, the performance of this pair
style is going to be significantly slower (often between 20x and 100x),
but this penalty can be significantly reduced through generating
tabulations from the python code through the "pair_write"_pair_write.html
command.
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 recompile 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
"pair_write"_pair_write.html 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 that LAMMPS will
look up either in the current directory, the folder pointed to by the
LAMMPS_POTENTIALS environment variable or somewhere in your python path.
The class definition has to follow specific rules as explained below.
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 filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
N additional arguments after the class name in the pair_coeff command,
where N must be the number of currently defined atom types:
module.class
N element names = mapping of python atom types to LAMMPS atom types :ul
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:
As an example, imagine a file py_pot.py has a python class LJCutMelt
with parameters and potential functions for a two Lennard-Jones
atom types labeled as 'LJ1' and 'LJ2', and you would have defined
4 atom types in LAMMPS, out which the first three are supposed to be
using the 'LJ1' parameters and the fourth the 'LJ2' parameters, then
you would use the following pair_coeff command:
pair_coeff * * py_pot.LJCutMelt LJ1 LJ1 LJ2 :pre
pair_coeff * * py_pot.LJCutMelt LJ1 LJ1 LJ1 LJ2 :pre
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 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three LJ1 arguments map LAMMPS atom types 1,2,3 to the LJ1
atom type in the py_pot.py file. The final LJ2 argument maps LAMMPS
atom type 4 to the LJ2 atom type the python file. If a mapping value
is specified as NULL, the mapping is not performed. This can be used
when a {python} potential is used as part of the {hybrid} pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
:line
The python potential file has to provide classes for the computation
of the potential energy and forces, which have to contain three methods:
{map_coeff}, {compute_force}, and {compute_energy}. For details please
see the provided examples in the examples/python folder.
The python potential file has to start with the following code:
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))
:pre
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' "units command"_units.html, which
is used to verify, that the potential definition in the python class and
in the LAMMPS input match. Example for a single type Lennard-Jones
potential class {LJCutMelt} in reducted units, which defines an atom
type {lj} for which the parameters epsilon and sigma are both 1.0:
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)}}
:pre
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) :li
itype = the (numerical) type of the first atom :li
jtype = the (numerical) type of the second atom :ul
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:
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 :pre
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)) :pre
IMPORTANT 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.
:line
IMPORTANT NOTE: The evaluation of scripted python code will slow down
the computation pair-wise interactions very significantly. However,
the computation pair-wise interactions quite significantly. However,
this can be largely worked around through using the python pair style
to generate tabulated potentials on the fly. Please see below for an
example of how to build the table file:
not for the actual simulation, but to generate tabulated potentials
on the fly using the "pair_write command"_pair_write.html . Please
see below for an example LAMMPS input of how to build a table file:
pair_style python 2.5
pair_coeff * * py_pot.LJCutMelt LJ1 LJ2 LJ2
shell rm -f lj1_lj2.table
pair_write 1 1 10000 rsq 0.01 2.5 lj1_lj2.table LJ1-LJ1
pair_write 1 2 10000 rsq 0.01 2.5 lj1_lj2.table LJ1-LJ2
pair_write 2 2 10000 rsq 0.01 2.5 lj1_lj2.table LJ2-LJ2 :pre
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 :pre
After switching the pair style to {table}, the various potential
function tables need to be assigned to the LAMMPS atom types:
Note, that it is strong recommended to try to [delete] the potential
table file before generating it. Since the {pair_write} command will
always append to a table file, which 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.
pair_style table linear 10000
pair_coeff 1 1 lj1_lj2.table LJ1-LJ1
pair_coeff 1 2* lj1_lj2.table LJ1-LJ2
pair_coeff 2* 2* lj1_lj2.table LJ2-LJ2 :pre
After switching the pair style to {table}, the potential tables need
to be assigned to the LAMMPS atom types like this:
pair_style table linear 2000
pair_coeff 1 1 melt.table lj :pre
This can also be done for more complex systems. Please see the
{examples/python} folders for a few more examples.
:line
[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 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.
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 "pair_modify"_pair_modify.html
shift, table, and tail options.