Update python docs
This commit is contained in:
@ -73,12 +73,13 @@ Creating or deleting a LAMMPS object
|
|||||||
************************************
|
************************************
|
||||||
|
|
||||||
With the Python interface the creation of a :cpp:class:`LAMMPS
|
With the Python interface the creation of a :cpp:class:`LAMMPS
|
||||||
<LAMMPS_NS::LAMMPS>` instance is included in the constructor for the
|
<LAMMPS_NS::LAMMPS>` instance is included in the constructors for the
|
||||||
:py:func:`lammps <lammps.lammps>` class. Internally it will call either
|
:py:meth:`lammps <lammps.lammps.__init__()>`, :py:meth:`PyLammps <lammps.PyLammps.__init__()>`,
|
||||||
:cpp:func:`lammps_open` or :cpp:func:`lammps_open_no_mpi` from the C
|
and :py:meth:`PyLammps <lammps.IPyLammps.__init__()>` classes.
|
||||||
|
Internally it will call either :cpp:func:`lammps_open` or :cpp:func:`lammps_open_no_mpi` from the C
|
||||||
library API to create the class instance.
|
library API to create the class instance.
|
||||||
|
|
||||||
All arguments are optional. The *name* argument is to allow loading a
|
All arguments are optional. The *name* argument allows loading a
|
||||||
LAMMPS shared library that is named ``liblammps_machine.so`` instead of
|
LAMMPS shared library that is named ``liblammps_machine.so`` instead of
|
||||||
the default name of ``liblammps.so``. In most cases the latter will be
|
the default name of ``liblammps.so``. In most cases the latter will be
|
||||||
installed or used. The *ptr* argument is for use of the
|
installed or used. The *ptr* argument is for use of the
|
||||||
@ -89,22 +90,111 @@ to the Python class and used instead of creating a new instance. The
|
|||||||
*comm* argument may be used in combination with the `mpi4py <mpi4py_url_>`_
|
*comm* argument may be used in combination with the `mpi4py <mpi4py_url_>`_
|
||||||
module to pass an MPI communicator to LAMMPS and thus it is possible
|
module to pass an MPI communicator to LAMMPS and thus it is possible
|
||||||
to run the Python module like the library interface on a subset of the
|
to run the Python module like the library interface on a subset of the
|
||||||
MPI ranks after splitting the communicator. Here is a simple example:
|
MPI ranks after splitting the communicator.
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from lammps import lammps
|
Here are simple examples using all three Python interfaces:
|
||||||
|
|
||||||
# NOTE: argv[0] is set by the Python module
|
.. tabs::
|
||||||
args = ["-log", "none"]
|
|
||||||
# create LAMMPS instance
|
|
||||||
lmp = lammps(cmdargs=args)
|
|
||||||
# get and print numerical version code
|
|
||||||
print("LAMMPS Version: ", lmp.version())
|
|
||||||
# explicitly close and delete LAMMPS instance (optional)
|
|
||||||
lmp.close()
|
|
||||||
|
|
||||||
Same as with the :ref:`C library API <lammps_c_api>` this will use the
|
.. tab:: lammps API
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from lammps import lammps
|
||||||
|
|
||||||
|
# NOTE: argv[0] is set by the lammps class constructor
|
||||||
|
args = ["-log", "none"]
|
||||||
|
# create LAMMPS instance
|
||||||
|
lmp = lammps(cmdargs=args)
|
||||||
|
# get and print numerical version code
|
||||||
|
print("LAMMPS Version: ", lmp.version())
|
||||||
|
# explicitly close and delete LAMMPS instance (optional)
|
||||||
|
lmp.close()
|
||||||
|
|
||||||
|
.. tab:: PyLammps API
|
||||||
|
|
||||||
|
The :py:class:`PyLammps` class is a wrapper around the
|
||||||
|
:py:class:`lammps` class and all of its lower level functions.
|
||||||
|
By default, it will create a new instance of :py:class:`lammps` passing
|
||||||
|
along all arguments to the constructor of :py:class:`lammps`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from lammps import PyLammps
|
||||||
|
|
||||||
|
# NOTE: argv[0] is set by the lammps class constructor
|
||||||
|
args = ["-log", "none"]
|
||||||
|
# create LAMMPS instance
|
||||||
|
L = PyLammps(cmdargs=args)
|
||||||
|
# get and print numerical version code
|
||||||
|
print("LAMMPS Version: ", L.version())
|
||||||
|
# explicitly close and delete LAMMPS instance (optional)
|
||||||
|
L.close()
|
||||||
|
|
||||||
|
:py:class:`PyLammps` objects can also be created on top of an existing :py:class:`lammps` object:
|
||||||
|
|
||||||
|
.. code-block:: Python
|
||||||
|
|
||||||
|
from lammps import lammps, PyLammps
|
||||||
|
|
||||||
|
# NOTE: argv[0] is set by the lammps class constructor
|
||||||
|
args = ["-log", "none"]
|
||||||
|
# create LAMMPS instance
|
||||||
|
lmp = lammps(cmdargs=args)
|
||||||
|
# create PyLammps instance using previously created LAMMPS instance
|
||||||
|
L = PyLammps(ptr=lmp)
|
||||||
|
# get and print numerical version code
|
||||||
|
print("LAMMPS Version: ", L.version())
|
||||||
|
# explicitly close and delete LAMMPS instance (optional)
|
||||||
|
L.close()
|
||||||
|
|
||||||
|
This is useful if you have to create the :py:class:`lammps <lammps.lammps>`
|
||||||
|
instance is a specific way, but want to take advantage of the
|
||||||
|
:py:class:`PyLammps <lammps.PyLammps>` interface.
|
||||||
|
|
||||||
|
.. tab:: IPyLammps API
|
||||||
|
|
||||||
|
The :py:class:`IPyLammps` class is an extension of the
|
||||||
|
:py:class:`PyLammps` class. It has the same construction behavior. By
|
||||||
|
default, it will create a new instance of :py:class:`lammps` passing
|
||||||
|
along all arguments to the constructor of :py:class:`lammps`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from lammps import IPyLammps
|
||||||
|
|
||||||
|
# NOTE: argv[0] is set by the lammps class constructor
|
||||||
|
args = ["-log", "none"]
|
||||||
|
# create LAMMPS instance
|
||||||
|
L = IPyLammps(cmdargs=args)
|
||||||
|
# get and print numerical version code
|
||||||
|
print("LAMMPS Version: ", L.version())
|
||||||
|
# explicitly close and delete LAMMPS instance (optional)
|
||||||
|
L.close()
|
||||||
|
|
||||||
|
You can also initialize IPyLammps on top of an existing :py:class:`lammps` or :py:class:`PyLammps` object:
|
||||||
|
|
||||||
|
.. code-block:: Python
|
||||||
|
|
||||||
|
from lammps import lammps, IPyLammps
|
||||||
|
|
||||||
|
# NOTE: argv[0] is set by the lammps class constructor
|
||||||
|
args = ["-log", "none"]
|
||||||
|
# create LAMMPS instance
|
||||||
|
lmp = lammps(cmdargs=args)
|
||||||
|
# create IPyLammps instance using previously created LAMMPS instance
|
||||||
|
L = IPyLammps(ptr=lmp)
|
||||||
|
# get and print numerical version code
|
||||||
|
print("LAMMPS Version: ", L.version())
|
||||||
|
# explicitly close and delete LAMMPS instance (optional)
|
||||||
|
L.close()
|
||||||
|
|
||||||
|
This is useful if you have to create the :py:class:`lammps <lammps.lammps>`
|
||||||
|
instance is a specific way, but want to take advantage of the
|
||||||
|
:py:class:`IPyLammps <lammps.IPyLammps>` interface.
|
||||||
|
|
||||||
|
In all of the above cases, same as with the :ref:`C library API <lammps_c_api>`, this will use the
|
||||||
``MPI_COMM_WORLD`` communicator for the MPI library that LAMMPS was
|
``MPI_COMM_WORLD`` communicator for the MPI library that LAMMPS was
|
||||||
compiled with. The :py:func:`lmp.close() <lammps.lammps.close>` call is
|
compiled with. The :py:func:`lmp.close() <lammps.lammps.close>` call is
|
||||||
optional since the LAMMPS class instance will also be deleted
|
optional since the LAMMPS class instance will also be deleted
|
||||||
@ -114,39 +204,107 @@ destructor.
|
|||||||
Executing LAMMPS commands
|
Executing LAMMPS commands
|
||||||
*************************
|
*************************
|
||||||
|
|
||||||
Once an instance of the :py:class:`lammps <lammps.lammps>` class is
|
Once an instance of the :py:class:`lammps`, :py:class:`PyLammps`, or
|
||||||
created, there are multiple ways to "feed" it commands. In a way that is
|
:py:class:`IPyLammps` class is created, there are multiple ways to "feed" it
|
||||||
not very different from running a LAMMPS input script, except that
|
commands. In a way that is not very different from running a LAMMPS input
|
||||||
Python has many more facilities for structured programming than the
|
script, except that Python has many more facilities for structured
|
||||||
LAMMPS input script syntax. Furthermore it is possible to "compute"
|
programming than the LAMMPS input script syntax. Furthermore it is possible
|
||||||
what the next LAMMPS command should be. Same as in the equivalent `C
|
to "compute" what the next LAMMPS command should be.
|
||||||
library functions <pg_lib_execute>`, commands can be read from a file, a
|
|
||||||
single string, a list of strings and a block of commands in a single
|
|
||||||
multi-line string. They are processed under the same boundary conditions
|
|
||||||
as the C library counterparts. The example below demonstrates the use
|
|
||||||
of :py:func:`lammps.file`, :py:func:`lammps.command`,
|
|
||||||
:py:func:`lammps.commands_list`, and :py:func:`lammps.commands_string`:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. tabs::
|
||||||
|
|
||||||
from lammps import lammps
|
.. tab:: lammps API
|
||||||
|
|
||||||
lmp = lammps()
|
Same as in the equivalent
|
||||||
# read commands from file 'in.melt'
|
`C library functions <pg_lib_execute>`, commands can be read from a file, a
|
||||||
lmp.file('in.melt')
|
single string, a list of strings and a block of commands in a single
|
||||||
# issue a single command
|
multi-line string. They are processed under the same boundary conditions
|
||||||
lmp.command('variable zpos index 1.0')
|
as the C library counterparts. The example below demonstrates the use
|
||||||
# create 10 groups with 10 atoms each
|
of :py:func:`lammps.file`, :py:func:`lammps.command`,
|
||||||
cmds = ["group g{} id {}:{}".format(i,10*i+1,10*(i+1)) for i in range(10)]
|
:py:func:`lammps.commands_list`, and :py:func:`lammps.commands_string`:
|
||||||
lmp.commands_list(cmds)
|
|
||||||
# run commands from a multi-line string
|
.. code-block:: python
|
||||||
block = """
|
|
||||||
clear
|
from lammps import lammps
|
||||||
region box block 0 2 0 2 0 2
|
lmp = lammps()
|
||||||
create_box 1 box
|
# read commands from file 'in.melt'
|
||||||
create_atoms 1 single 1.0 1.0 ${zpos}
|
lmp.file('in.melt')
|
||||||
"""
|
# issue a single command
|
||||||
lmp.commands_string(block)
|
lmp.command('variable zpos index 1.0')
|
||||||
|
# create 10 groups with 10 atoms each
|
||||||
|
cmds = ["group g{} id {}:{}".format(i,10*i+1,10*(i+1)) for i in range(10)]
|
||||||
|
lmp.commands_list(cmds)
|
||||||
|
# run commands from a multi-line string
|
||||||
|
block = """
|
||||||
|
clear
|
||||||
|
region box block 0 2 0 2 0 2
|
||||||
|
create_box 1 box
|
||||||
|
create_atoms 1 single 1.0 1.0 ${zpos}
|
||||||
|
"""
|
||||||
|
lmp.commands_string(block)
|
||||||
|
|
||||||
|
.. tab:: PyLammps/IPyLammps API
|
||||||
|
|
||||||
|
Unlike the lammps API, the PyLammps/IPyLammps APIs allow running LAMMPS
|
||||||
|
commands by calling equivalent member functions.
|
||||||
|
|
||||||
|
For instance, the following LAMMPS command:
|
||||||
|
|
||||||
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
|
region box block 0 10 0 5 -0.5 0.5
|
||||||
|
|
||||||
|
In the original interface this command can be executed with the following
|
||||||
|
Python code if *L* was a lammps instance:
|
||||||
|
|
||||||
|
.. code-block:: Python
|
||||||
|
|
||||||
|
L.command("region box block 0 10 0 5 -0.5 0.5")
|
||||||
|
|
||||||
|
With the PyLammps interface, any command can be split up into arbitrary parts
|
||||||
|
separated by white-space, passed as individual arguments to a :code:`region` method.
|
||||||
|
|
||||||
|
.. code-block:: Python
|
||||||
|
|
||||||
|
L.region("box block", 0, 10, 0, 5, -0.5, 0.5)
|
||||||
|
|
||||||
|
Note that each parameter is set as Python literal floating-point number. In the
|
||||||
|
PyLammps interface, each command takes an arbitrary parameter list and transparently
|
||||||
|
merges it to a single command string, separating individual parameters by white-space.
|
||||||
|
|
||||||
|
The benefit of this approach is avoiding redundant command calls and easier
|
||||||
|
parameterization. In the original interface parameterization needed to be done
|
||||||
|
manually by creating formatted strings.
|
||||||
|
|
||||||
|
.. code-block:: Python
|
||||||
|
|
||||||
|
L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi))
|
||||||
|
|
||||||
|
In contrast, methods of PyLammps accept parameters directly and will convert
|
||||||
|
them automatically to a final command string.
|
||||||
|
|
||||||
|
.. code-block:: Python
|
||||||
|
|
||||||
|
L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi)
|
||||||
|
|
||||||
|
Using these facilities, the example shown for the lammps API can be rewritten as follows:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from lammps import PyLammps
|
||||||
|
L = PyLammps()
|
||||||
|
# read commands from file 'in.melt'
|
||||||
|
L.file('in.melt')
|
||||||
|
# issue a single command
|
||||||
|
L.variable('zpos', 'index', 1.0)
|
||||||
|
# create 10 groups with 10 atoms each
|
||||||
|
for i in range(10):
|
||||||
|
L.group(f"g{i}", "id", f"{10*i+1}:{10*(i+1)}")
|
||||||
|
|
||||||
|
L.clear()
|
||||||
|
L.region("box block", 0, 2, 0, 2, 0, 2)
|
||||||
|
L.create_box(1, "box")
|
||||||
|
L.create_atoms(1, "single", 1.0, 1.0, "${zpos}")
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -176,239 +334,17 @@ simpler, more "Pythonic" interface to common LAMMPS functionality. LAMMPS data
|
|||||||
structures are exposed through objects and properties. This makes Python scripts
|
structures are exposed through objects and properties. This makes Python scripts
|
||||||
shorter and more concise.
|
shorter and more concise.
|
||||||
|
|
||||||
Creating a new instance of PyLammps
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
To create a PyLammps object you need to first import the class from the lammps
|
|
||||||
module. By using the default constructor, a new :py:class:`lammps <lammps.lammps>` instance is created.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
from lammps import PyLammps
|
|
||||||
L = PyLammps()
|
|
||||||
|
|
||||||
You can also initialize PyLammps on top of this existing :py:class:`lammps <lammps.lammps>` object:
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
from lammps import lammps, PyLammps
|
|
||||||
lmp = lammps()
|
|
||||||
L = PyLammps(ptr=lmp)
|
|
||||||
|
|
||||||
This is useful if you have create the :py:class:`lammps <lammps.lammps>`
|
|
||||||
instance is a specific way, but want to take advantage of the
|
|
||||||
:py:class:`PyLammps <lammps.PyLammps>` interface.
|
|
||||||
|
|
||||||
Commands
|
|
||||||
--------
|
|
||||||
|
|
||||||
Sending a LAMMPS command with the existing library interfaces is done using
|
|
||||||
the command method of the lammps object instance.
|
|
||||||
|
|
||||||
For instance, let's take the following LAMMPS command:
|
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
|
||||||
|
|
||||||
region box block 0 10 0 5 -0.5 0.5
|
|
||||||
|
|
||||||
In the original interface this command can be executed with the following
|
|
||||||
Python code if *L* was a lammps instance:
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.command("region box block 0 10 0 5 -0.5 0.5")
|
|
||||||
|
|
||||||
With the PyLammps interface, any command can be split up into arbitrary parts
|
|
||||||
separated by white-space, passed as individual arguments to a region method.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.region("box block", 0, 10, 0, 5, -0.5, 0.5)
|
|
||||||
|
|
||||||
Note that each parameter is set as Python literal floating-point number. In the
|
|
||||||
PyLammps interface, each command takes an arbitrary parameter list and transparently
|
|
||||||
merges it to a single command string, separating individual parameters by white-space.
|
|
||||||
|
|
||||||
The benefit of this approach is avoiding redundant command calls and easier
|
|
||||||
parameterization. In the original interface parameterization needed to be done
|
|
||||||
manually by creating formatted strings.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi))
|
|
||||||
|
|
||||||
In contrast, methods of PyLammps accept parameters directly and will convert
|
|
||||||
them automatically to a final command string.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi)
|
|
||||||
|
|
||||||
System state
|
|
||||||
------------
|
|
||||||
|
|
||||||
In addition to dispatching commands directly through the PyLammps object, it
|
|
||||||
also provides several properties which allow you to query the system state.
|
|
||||||
|
|
||||||
:py:attr:`lammps.PyLammps.system`
|
|
||||||
Is a dictionary describing the system such as the bounding box or number of atoms
|
|
||||||
|
|
||||||
L.system.xlo, L.system.xhi
|
|
||||||
bounding box limits along x-axis
|
|
||||||
|
|
||||||
L.system.ylo, L.system.yhi
|
|
||||||
bounding box limits along y-axis
|
|
||||||
|
|
||||||
L.system.zlo, L.system.zhi
|
|
||||||
bounding box limits along z-axis
|
|
||||||
|
|
||||||
L.communication
|
|
||||||
configuration of communication subsystem, such as the number of threads or processors
|
|
||||||
|
|
||||||
L.communication.nthreads
|
|
||||||
number of threads used by each LAMMPS process
|
|
||||||
|
|
||||||
L.communication.nprocs
|
|
||||||
number of MPI processes used by LAMMPS
|
|
||||||
|
|
||||||
L.fixes
|
|
||||||
List of fixes in the current system
|
|
||||||
|
|
||||||
L.computes
|
|
||||||
List of active computes in the current system
|
|
||||||
|
|
||||||
L.dump
|
|
||||||
List of active dumps in the current system
|
|
||||||
|
|
||||||
L.groups
|
|
||||||
List of groups present in the current system
|
|
||||||
|
|
||||||
Working with LAMMPS variables
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
LAMMPS variables can be both defined and accessed via the PyLammps interface.
|
|
||||||
|
|
||||||
To define a variable you can use the :doc:`variable <variable>` command:
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.variable("a index 2")
|
|
||||||
|
|
||||||
A dictionary of all variables is returned by L.variables
|
|
||||||
|
|
||||||
you can access an individual variable by retrieving a variable object from the
|
|
||||||
L.variables dictionary by name
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
a = L.variables['a']
|
|
||||||
|
|
||||||
The variable value can then be easily read and written by accessing the value
|
|
||||||
property of this object.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
print(a.value)
|
|
||||||
a.value = 4
|
|
||||||
|
|
||||||
Retrieving the value of an arbitrary LAMMPS expressions
|
|
||||||
-------------------------------------------------------
|
|
||||||
|
|
||||||
LAMMPS expressions can be immediately evaluated by using the eval method. The
|
|
||||||
passed string parameter can be any expression containing global thermo values,
|
|
||||||
variables, compute or fix data.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
result = L.eval("ke") # kinetic energy
|
|
||||||
result = L.eval("pe") # potential energy
|
|
||||||
|
|
||||||
result = L.eval("v_t/2.0")
|
|
||||||
|
|
||||||
Accessing atom data
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
All atoms in the current simulation can be accessed by using the L.atoms list.
|
|
||||||
Each element of this list is an object which exposes its properties (id, type,
|
|
||||||
position, velocity, force, etc.).
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
# access first atom
|
|
||||||
L.atoms[0].id
|
|
||||||
L.atoms[0].type
|
|
||||||
|
|
||||||
# access second atom
|
|
||||||
L.atoms[1].position
|
|
||||||
L.atoms[1].velocity
|
|
||||||
L.atoms[1].force
|
|
||||||
|
|
||||||
Some properties can also be used to set:
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
# set position in 2D simulation
|
|
||||||
L.atoms[0].position = (1.0, 0.0)
|
|
||||||
|
|
||||||
# set position in 3D simulation
|
|
||||||
L.atoms[0].position = (1.0, 0.0, 1.)
|
|
||||||
|
|
||||||
Evaluating thermo data
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Each simulation run usually produces thermo output based on system state,
|
|
||||||
computes, fixes or variables. The trajectories of these values can be queried
|
|
||||||
after a run via the L.runs list. This list contains a growing list of run data.
|
|
||||||
The first element is the output of the first run, the second element that of
|
|
||||||
the second run.
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.run(1000)
|
|
||||||
L.runs[0] # data of first 1000 time steps
|
|
||||||
|
|
||||||
L.run(1000)
|
|
||||||
L.runs[1] # data of second 1000 time steps
|
|
||||||
|
|
||||||
Each run contains a dictionary of all trajectories. Each trajectory is
|
|
||||||
accessible through its thermo name:
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
L.runs[0].thermo.Step # list of time steps in first run
|
|
||||||
L.runs[0].thermo.Ke # list of kinetic energy values in first run
|
|
||||||
|
|
||||||
Together with matplotlib plotting data out of LAMMPS becomes simple:
|
|
||||||
|
|
||||||
.. code-block:: Python
|
|
||||||
|
|
||||||
import matplotlib.plot as plt
|
|
||||||
steps = L.runs[0].thermo.Step
|
|
||||||
ke = L.runs[0].thermo.Ke
|
|
||||||
plt.plot(steps, ke)
|
|
||||||
|
|
||||||
Error handling with PyLammps
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Compiling the shared library with C++ exception support provides a better error
|
|
||||||
handling experience. Without exceptions the LAMMPS code will terminate the
|
|
||||||
current Python process with an error message. C++ exceptions allow capturing
|
|
||||||
them on the C++ side and rethrowing them on the Python side. This way you
|
|
||||||
can handle LAMMPS errors through the Python exception handling mechanism.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Capturing a LAMMPS exception in Python can still mean that the
|
|
||||||
current LAMMPS process is in an illegal state and must be terminated. It is
|
|
||||||
advised to save your data and terminate the Python instance as quickly as
|
|
||||||
possible.
|
|
||||||
|
|
||||||
.. autoclass:: lammps.PyLammps
|
.. autoclass:: lammps.PyLammps
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. autoclass:: lammps.AtomList
|
.. autoclass:: lammps.AtomList
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: lammps.Atom
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: lammps.Atom2D
|
||||||
|
:members:
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -463,3 +399,19 @@ and the :py:class:`NeighList <lammps.NeighList>` class:
|
|||||||
:members:
|
:members:
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
|
|
||||||
|
LAMMPS error handling in Python
|
||||||
|
*******************************
|
||||||
|
|
||||||
|
Compiling the shared library with C++ exception support provides a better error
|
||||||
|
handling experience. Without exceptions the LAMMPS code will terminate the
|
||||||
|
current Python process with an error message. C++ exceptions allow capturing
|
||||||
|
them on the C++ side and rethrowing them on the Python side. This way
|
||||||
|
LAMMPS errors can be handled through the Python exception handling mechanism.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Capturing a LAMMPS exception in Python can still mean that the
|
||||||
|
current LAMMPS process is in an illegal state and must be terminated. It is
|
||||||
|
advised to save your data and terminate the Python instance as quickly as
|
||||||
|
possible.
|
||||||
|
|||||||
@ -1992,6 +1992,10 @@ class PyLammps(object):
|
|||||||
self.lmp = None
|
self.lmp = None
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
"""Explicitly delete a LAMMPS instance
|
||||||
|
|
||||||
|
This is a wrapper around the :py:meth:`lammps.close` of the Python interface.
|
||||||
|
"""
|
||||||
if self.lmp: self.lmp.close()
|
if self.lmp: self.lmp.close()
|
||||||
self.lmp = None
|
self.lmp = None
|
||||||
|
|
||||||
@ -2091,32 +2095,68 @@ class PyLammps(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def communication(self):
|
def communication(self):
|
||||||
|
"""
|
||||||
|
The communication state of this LAMMPS instance
|
||||||
|
|
||||||
|
:getter: Returns an object with properties storing the current communication state
|
||||||
|
:type: namedtuple
|
||||||
|
"""
|
||||||
output = self.info("communication")
|
output = self.info("communication")
|
||||||
d = self._parse_info_communication(output)
|
d = self._parse_info_communication(output)
|
||||||
return namedtuple('Communication', d.keys())(*d.values())
|
return namedtuple('Communication', d.keys())(*d.values())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def computes(self):
|
def computes(self):
|
||||||
|
"""
|
||||||
|
The list of active computes of this LAMMPS instance
|
||||||
|
|
||||||
|
:getter: Returns a list of computes that are currently active in this LAMMPS instance
|
||||||
|
:type: list
|
||||||
|
"""
|
||||||
output = self.info("computes")
|
output = self.info("computes")
|
||||||
return self._parse_element_list(output)
|
return self._parse_element_list(output)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dumps(self):
|
def dumps(self):
|
||||||
|
"""
|
||||||
|
The list of active dumps of this LAMMPS instance
|
||||||
|
|
||||||
|
:getter: Returns a list of dumps that are currently active in this LAMMPS instance
|
||||||
|
:type: list
|
||||||
|
"""
|
||||||
output = self.info("dumps")
|
output = self.info("dumps")
|
||||||
return self._parse_element_list(output)
|
return self._parse_element_list(output)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fixes(self):
|
def fixes(self):
|
||||||
|
"""
|
||||||
|
The list of active fixes of this LAMMPS instance
|
||||||
|
|
||||||
|
:getter: Returns a list of fixes that are currently active in this LAMMPS instance
|
||||||
|
:type: list
|
||||||
|
"""
|
||||||
output = self.info("fixes")
|
output = self.info("fixes")
|
||||||
return self._parse_element_list(output)
|
return self._parse_element_list(output)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def groups(self):
|
def groups(self):
|
||||||
|
"""
|
||||||
|
The list of active atom groups of this LAMMPS instance
|
||||||
|
|
||||||
|
:getter: Returns a list of atom groups that are currently active in this LAMMPS instance
|
||||||
|
:type: list
|
||||||
|
"""
|
||||||
output = self.info("groups")
|
output = self.info("groups")
|
||||||
return self._parse_groups(output)
|
return self._parse_groups(output)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def variables(self):
|
def variables(self):
|
||||||
|
"""
|
||||||
|
Returns a dictionary of all variables defined in the current LAMMPS instance
|
||||||
|
|
||||||
|
:getter: Returns a dictionary of all variables that are defined in this LAMMPS instance
|
||||||
|
:type: dict
|
||||||
|
"""
|
||||||
output = self.info("variables")
|
output = self.info("variables")
|
||||||
vars = {}
|
vars = {}
|
||||||
for v in self._parse_element_list(output):
|
for v in self._parse_element_list(output):
|
||||||
@ -2302,7 +2342,21 @@ class PyLammps(object):
|
|||||||
|
|
||||||
class IPyLammps(PyLammps):
|
class IPyLammps(PyLammps):
|
||||||
"""
|
"""
|
||||||
IPython wrapper for LAMMPS which adds embedded graphics capabilities
|
IPython wrapper for LAMMPS which adds embedded graphics capabilities to PyLammmps interface
|
||||||
|
|
||||||
|
It either creates its own instance of :py:class:`lammps` or can be
|
||||||
|
initialized with an existing instance. The arguments are the same of the
|
||||||
|
lower-level interface. The original interface can still be accessed via
|
||||||
|
:py:attr:`PyLammps.lmp`.
|
||||||
|
|
||||||
|
:param name: "machine" name of the shared LAMMPS library ("mpi" loads ``liblammps_mpi.so``, "" loads ``liblammps.so``)
|
||||||
|
:type name: string
|
||||||
|
:param cmdargs: list of command line arguments to be passed to the :cpp:func:`lammps_open` function. The executable name is automatically added.
|
||||||
|
:type cmdargs: list
|
||||||
|
:param ptr: pointer to a LAMMPS C++ class instance when called from an embedded Python interpreter. None means load symbols from shared library.
|
||||||
|
:type ptr: pointer
|
||||||
|
:param comm: MPI communicator (as provided by `mpi4py <mpi4py_docs_>`_). ``None`` means use ``MPI_COMM_WORLD`` implicitly.
|
||||||
|
:type comm: MPI_Comm
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,name="",cmdargs=None,ptr=None,comm=None):
|
def __init__(self,name="",cmdargs=None,ptr=None,comm=None):
|
||||||
@ -2310,6 +2364,34 @@ class IPyLammps(PyLammps):
|
|||||||
|
|
||||||
def image(self, filename="snapshot.png", group="all", color="type", diameter="type",
|
def image(self, filename="snapshot.png", group="all", color="type", diameter="type",
|
||||||
size=None, view=None, center=None, up=None, zoom=1.0, background_color="white"):
|
size=None, view=None, center=None, up=None, zoom=1.0, background_color="white"):
|
||||||
|
""" Generate image using write_dump command and display it
|
||||||
|
|
||||||
|
See :doc:`dump image <dump_image>` for more information.
|
||||||
|
|
||||||
|
:param filename: Name of the image file that should be generated. The extension determines whether it is PNG or JPEG
|
||||||
|
:type filename: string
|
||||||
|
:param group: the group of atoms write_image should use
|
||||||
|
:type group: string
|
||||||
|
:param color: name of property used to determine color
|
||||||
|
:type color: string
|
||||||
|
:param diameter: name of property used to determine atom diameter
|
||||||
|
:type diameter: string
|
||||||
|
:param size: dimensions of image
|
||||||
|
:type size: tuple (width, height)
|
||||||
|
:param view: view parameters
|
||||||
|
:type view: tuple (theta, phi)
|
||||||
|
:param center: center parameters
|
||||||
|
:type center: tuple (flag, center_x, center_y, center_z)
|
||||||
|
:param up: vector pointing to up direction
|
||||||
|
:type up: tuple (up_x, up_y, up_z)
|
||||||
|
:param zoom: zoom factor
|
||||||
|
:type zoom: float
|
||||||
|
:param background_color: background color of scene
|
||||||
|
:type background_color: string
|
||||||
|
|
||||||
|
:return: Image instance used to display image in notebook
|
||||||
|
:rtype: :py:class:`IPython.core.display.Image`
|
||||||
|
"""
|
||||||
cmd_args = [group, "image", filename, color, diameter]
|
cmd_args = [group, "image", filename, color, diameter]
|
||||||
|
|
||||||
if size:
|
if size:
|
||||||
@ -2345,5 +2427,15 @@ class IPyLammps(PyLammps):
|
|||||||
return Image(filename)
|
return Image(filename)
|
||||||
|
|
||||||
def video(self, filename):
|
def video(self, filename):
|
||||||
|
"""
|
||||||
|
Load video from file
|
||||||
|
|
||||||
|
Can be used to visualize videos from :doc:`dump_movie`.
|
||||||
|
|
||||||
|
:param filename: Path to video file
|
||||||
|
:type filename: string
|
||||||
|
:return: HTML Video Tag used by notebook to embed a video
|
||||||
|
:rtype: :py:class:`IPython.display.HTML`
|
||||||
|
"""
|
||||||
from IPython.display import HTML
|
from IPython.display import HTML
|
||||||
return HTML("<video controls><source src=\"" + filename + "\"></video>")
|
return HTML("<video controls><source src=\"" + filename + "\"></video>")
|
||||||
|
|||||||
Reference in New Issue
Block a user