Update Howto_pylammps.rst and remove Howto_pylammps.txt
This commit is contained in:
@ -57,7 +57,7 @@ output support enabled.
|
|||||||
Step 1a: For the CMake based build system, the steps are:
|
Step 1a: For the CMake based build system, the steps are:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
mkdir $LAMMPS_DIR/build-shared
|
mkdir $LAMMPS_DIR/build-shared
|
||||||
cd $LAMMPS_DIR/build-shared
|
cd $LAMMPS_DIR/build-shared
|
||||||
@ -69,7 +69,7 @@ Step 1a: For the CMake based build system, the steps are:
|
|||||||
Step 1b: For the legacy, make based build system, the steps are:
|
Step 1b: For the legacy, make based build system, the steps are:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
cd $LAMMPS_DIR/src
|
cd $LAMMPS_DIR/src
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ PyLammps is part of the lammps Python package. To install it simply install
|
|||||||
that package into your current Python installation with:
|
that package into your current Python installation with:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
make install-python
|
make install-python
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ Benefits of using a virtualenv
|
|||||||
**Prerequisite (e.g. on Ubuntu)**
|
**Prerequisite (e.g. on Ubuntu)**
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
apt-get install python-virtualenv
|
apt-get install python-virtualenv
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ Creating a virtualenv with lammps installed
|
|||||||
"""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
# create virtualenv named 'testing'
|
# create virtualenv named 'testing'
|
||||||
virtualenv $HOME/python/testing
|
virtualenv $HOME/python/testing
|
||||||
@ -133,7 +133,7 @@ need to re-run CMake to update the location of the python executable
|
|||||||
to the location in the virtual environment with:
|
to the location in the virtual environment with:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
cmake . -DPYTHON_EXECUTABLE=$(which python)
|
cmake . -DPYTHON_EXECUTABLE=$(which python)
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ To create a PyLammps object you need to first import the class from the lammps
|
|||||||
module. By using the default constructor, a new *lammps* instance is created.
|
module. By using the default constructor, a new *lammps* instance is created.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
from lammps import PyLammps
|
from lammps import PyLammps
|
||||||
L = PyLammps()
|
L = PyLammps()
|
||||||
@ -163,7 +163,7 @@ module. By using the default constructor, a new *lammps* instance is created.
|
|||||||
You can also initialize PyLammps on top of this existing *lammps* object:
|
You can also initialize PyLammps on top of this existing *lammps* object:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
from lammps import lammps, PyLammps
|
from lammps import lammps, PyLammps
|
||||||
lmp = lammps()
|
lmp = lammps()
|
||||||
@ -178,7 +178,7 @@ the command method of the lammps object instance.
|
|||||||
For instance, let's take the following LAMMPS command:
|
For instance, let's take the following LAMMPS command:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
region box block 0 10 0 5 -0.5 0.5
|
region box block 0 10 0 5 -0.5 0.5
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ In the original interface this command can be executed with the following
|
|||||||
Python code if *L* was a lammps instance:
|
Python code if *L* was a lammps instance:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.command("region box block 0 10 0 5 -0.5 0.5")
|
L.command("region box block 0 10 0 5 -0.5 0.5")
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ 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.
|
separated by white-space, passed as individual arguments to a region method.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.region("box block", 0, 10, 0, 5, -0.5, 0.5)
|
L.region("box block", 0, 10, 0, 5, -0.5, 0.5)
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ parameterization. In the original interface parameterization needed to be done
|
|||||||
manually by creating formatted strings.
|
manually by creating formatted strings.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi))
|
L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi))
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ In contrast, methods of PyLammps accept parameters directly and will convert
|
|||||||
them automatically to a final command string.
|
them automatically to a final command string.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi)
|
L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi)
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ LAMMPS variables can be both defined and accessed via the PyLammps interface.
|
|||||||
To define a variable you can use the :doc:`variable <variable>` command:
|
To define a variable you can use the :doc:`variable <variable>` command:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.variable("a index 2")
|
L.variable("a index 2")
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ you can access an individual variable by retrieving a variable object from the
|
|||||||
L.variables dictionary by name
|
L.variables dictionary by name
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
a = L.variables['a']
|
a = L.variables['a']
|
||||||
|
|
||||||
@ -288,7 +288,7 @@ The variable value can then be easily read and written by accessing the value
|
|||||||
property of this object.
|
property of this object.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
print(a.value)
|
print(a.value)
|
||||||
a.value = 4
|
a.value = 4
|
||||||
@ -301,7 +301,7 @@ passed string parameter can be any expression containing global thermo values,
|
|||||||
variables, compute or fix data.
|
variables, compute or fix data.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
result = L.eval("ke") # kinetic energy
|
result = L.eval("ke") # kinetic energy
|
||||||
result = L.eval("pe") # potential energy
|
result = L.eval("pe") # potential energy
|
||||||
@ -316,7 +316,7 @@ Each element of this list is an object which exposes its properties (id, type,
|
|||||||
position, velocity, force, etc.).
|
position, velocity, force, etc.).
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
# access first atom
|
# access first atom
|
||||||
L.atoms[0].id
|
L.atoms[0].id
|
||||||
@ -330,7 +330,7 @@ position, velocity, force, etc.).
|
|||||||
Some properties can also be used to set:
|
Some properties can also be used to set:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
# set position in 2D simulation
|
# set position in 2D simulation
|
||||||
L.atoms[0].position = (1.0, 0.0)
|
L.atoms[0].position = (1.0, 0.0)
|
||||||
@ -348,7 +348,7 @@ The first element is the output of the first run, the second element that of
|
|||||||
the second run.
|
the second run.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.run(1000)
|
L.run(1000)
|
||||||
L.runs[0] # data of first 1000 time steps
|
L.runs[0] # data of first 1000 time steps
|
||||||
@ -360,7 +360,7 @@ Each run contains a dictionary of all trajectories. Each trajectory is
|
|||||||
accessible through its thermo name:
|
accessible through its thermo name:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
L.runs[0].step # list of time steps in first run
|
L.runs[0].step # list of time steps in first run
|
||||||
L.runs[0].ke # list of kinetic energy values in first run
|
L.runs[0].ke # list of kinetic energy values in first run
|
||||||
@ -370,7 +370,7 @@ Together with matplotlib plotting data out of LAMMPS becomes simple:
|
|||||||
import matplotlib.plot as plt
|
import matplotlib.plot as plt
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
steps = L.runs[0].step
|
steps = L.runs[0].step
|
||||||
ke = L.runs[0].ke
|
ke = L.runs[0].ke
|
||||||
@ -408,7 +408,7 @@ To launch an instance of Jupyter simply run the following command inside your
|
|||||||
Python environment (this assumes you followed the Quick Start instructions):
|
Python environment (this assumes you followed the Quick Start instructions):
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
jupyter notebook
|
jupyter notebook
|
||||||
|
|
||||||
@ -431,7 +431,7 @@ them using a datafile. Then one of the atoms is rotated along the central axis b
|
|||||||
setting its position from Python, which changes the dihedral angle.
|
setting its position from Python, which changes the dihedral angle.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
phi = [d \* math.pi / 180 for d in range(360)]
|
phi = [d \* math.pi / 180 for d in range(360)]
|
||||||
|
|
||||||
@ -465,7 +465,7 @@ Initially, a 2D system is created in a state with minimal energy.
|
|||||||
It is then disordered by moving each atom by a random delta.
|
It is then disordered by moving each atom by a random delta.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
random.seed(27848)
|
random.seed(27848)
|
||||||
deltaperturb = 0.2
|
deltaperturb = 0.2
|
||||||
@ -485,7 +485,7 @@ Finally, the Monte Carlo algorithm is implemented in Python. It continuously
|
|||||||
moves random atoms by a random delta and only accepts certain moves.
|
moves random atoms by a random delta and only accepts certain moves.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
estart = L.eval("pe")
|
estart = L.eval("pe")
|
||||||
elast = estart
|
elast = estart
|
||||||
@ -538,7 +538,7 @@ Using PyLammps and mpi4py (Experimental)
|
|||||||
PyLammps can be run in parallel using mpi4py. This python package can be installed using
|
PyLammps can be run in parallel using mpi4py. This python package can be installed using
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
pip install mpi4py
|
pip install mpi4py
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ The following is a short example which reads in an existing LAMMPS input file an
|
|||||||
executes it in parallel. You can find in.melt in the examples/melt folder.
|
executes it in parallel. You can find in.melt in the examples/melt folder.
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: Python
|
||||||
|
|
||||||
from mpi4py import MPI
|
from mpi4py import MPI
|
||||||
from lammps import PyLammps
|
from lammps import PyLammps
|
||||||
@ -563,7 +563,7 @@ To run this script (melt.py) in parallel using 4 MPI processes we invoke the
|
|||||||
following mpirun command:
|
following mpirun command:
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. code-block:: bash
|
||||||
|
|
||||||
mpirun -np 4 python melt.py
|
mpirun -np 4 python melt.py
|
||||||
|
|
||||||
|
|||||||
@ -1,481 +0,0 @@
|
|||||||
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
|
|
||||||
|
|
||||||
:link(lws,http://lammps.sandia.gov)
|
|
||||||
:link(ld,Manual.html)
|
|
||||||
:link(lc,Commands_all.html)
|
|
||||||
|
|
||||||
:line
|
|
||||||
|
|
||||||
PyLammps Tutorial :h3
|
|
||||||
|
|
||||||
<!-- RST
|
|
||||||
.. contents::
|
|
||||||
|
|
||||||
END_RST -->
|
|
||||||
|
|
||||||
Overview :h4
|
|
||||||
|
|
||||||
PyLammps is a Python wrapper class which can be created on its own or
|
|
||||||
use an existing lammps Python object. It creates a simpler,
|
|
||||||
Python-like interface to common LAMMPS functionality, in contrast to
|
|
||||||
the lammps.py wrapper on the C-style LAMMPS library interface which is
|
|
||||||
written using Python ctypes. The lammps.py wrapper is discussed on
|
|
||||||
the "Python library"_Python_library.html doc page.
|
|
||||||
|
|
||||||
Unlike the flat ctypes interface, PyLammps exposes a discoverable API.
|
|
||||||
It no longer requires knowledge of the underlying C++ code
|
|
||||||
implementation. Finally, the IPyLammps wrapper builds on top of
|
|
||||||
PyLammps and adds some additional features for IPython integration
|
|
||||||
into IPython notebooks, e.g. for embedded visualization output from
|
|
||||||
dump/image.
|
|
||||||
|
|
||||||
Comparison of lammps and PyLammps interfaces :h5
|
|
||||||
|
|
||||||
lammps.lammps :h6
|
|
||||||
|
|
||||||
uses C-Types
|
|
||||||
direct memory access to native C++ data
|
|
||||||
provides functions to send and receive data to LAMMPS
|
|
||||||
requires knowledge of how LAMMPS internally works (C pointers, etc) :ul
|
|
||||||
|
|
||||||
lammps.PyLammps :h6
|
|
||||||
|
|
||||||
higher-level abstraction built on top of original C-Types interface
|
|
||||||
manipulation of Python objects
|
|
||||||
communication with LAMMPS is hidden from API user
|
|
||||||
shorter, more concise Python
|
|
||||||
better IPython integration, designed for quick prototyping :ul
|
|
||||||
|
|
||||||
Quick Start :h4
|
|
||||||
|
|
||||||
System-wide Installation :h5
|
|
||||||
|
|
||||||
Step 1: Building LAMMPS as a shared library :h6
|
|
||||||
|
|
||||||
To use LAMMPS inside of Python it has to be compiled as shared library. This
|
|
||||||
library is then loaded by the Python interface. In this example we enable the
|
|
||||||
MOLECULE package and compile LAMMPS with C++ exceptions, PNG, JPEG and FFMPEG
|
|
||||||
output support enabled.
|
|
||||||
|
|
||||||
Step 1a: For the CMake based build system, the steps are:
|
|
||||||
|
|
||||||
mkdir $LAMMPS_DIR/build-shared
|
|
||||||
cd $LAMMPS_DIR/build-shared :pre
|
|
||||||
|
|
||||||
# MPI, PNG, Jpeg, FFMPEG are auto-detected
|
|
||||||
cmake ../cmake -DPKG_MOLECULE=yes -DLAMMPS_EXCEPTIONS=yes -DBUILD_LIB=yes -DBUILD_SHARED_LIBS=yes
|
|
||||||
make :pre
|
|
||||||
|
|
||||||
Step 1b: For the legacy, make based build system, the steps are:
|
|
||||||
|
|
||||||
cd $LAMMPS_DIR/src :pre
|
|
||||||
|
|
||||||
# add packages if necessary
|
|
||||||
make yes-MOLECULE :pre
|
|
||||||
|
|
||||||
# compile shared library using Makefile
|
|
||||||
make mpi mode=shlib LMP_INC="-DLAMMPS_PNG -DLAMMPS_JPEG -DLAMMPS_FFMPEG -DLAMMPS_EXCEPTIONS" JPG_LIB="-lpng -ljpeg" :pre
|
|
||||||
|
|
||||||
Step 2: Installing the LAMMPS Python package :h6
|
|
||||||
|
|
||||||
PyLammps is part of the lammps Python package. To install it simply install
|
|
||||||
that package into your current Python installation with:
|
|
||||||
|
|
||||||
make install-python :pre
|
|
||||||
|
|
||||||
NOTE: Recompiling the shared library requires re-installing the Python package
|
|
||||||
|
|
||||||
|
|
||||||
Installation inside of a virtualenv :h5
|
|
||||||
|
|
||||||
You can use virtualenv to create a custom Python environment specifically tuned
|
|
||||||
for your workflow.
|
|
||||||
|
|
||||||
Benefits of using a virtualenv :h6
|
|
||||||
|
|
||||||
isolation of your system Python installation from your development installation
|
|
||||||
installation can happen in your user directory without root access (useful for HPC clusters)
|
|
||||||
installing packages through pip allows you to get newer versions of packages than e.g., through apt-get or yum package managers (and without root access)
|
|
||||||
you can even install specific old versions of a package if necessary :ul
|
|
||||||
|
|
||||||
[Prerequisite (e.g. on Ubuntu)]
|
|
||||||
|
|
||||||
apt-get install python-virtualenv :pre
|
|
||||||
|
|
||||||
Creating a virtualenv with lammps installed :h6
|
|
||||||
|
|
||||||
# create virtualenv named 'testing'
|
|
||||||
virtualenv $HOME/python/testing :pre
|
|
||||||
|
|
||||||
# activate 'testing' environment
|
|
||||||
source $HOME/python/testing/bin/activate :pre
|
|
||||||
|
|
||||||
Now configure and compile the LAMMPS shared library as outlined above.
|
|
||||||
When using CMake and the shared library has already been build, you
|
|
||||||
need to re-run CMake to update the location of the python executable
|
|
||||||
to the location in the virtual environment with:
|
|
||||||
|
|
||||||
cmake . -DPYTHON_EXECUTABLE=$(which python) :pre
|
|
||||||
|
|
||||||
# install LAMMPS package in virtualenv
|
|
||||||
(testing) make install-python :pre
|
|
||||||
|
|
||||||
# install other useful packages
|
|
||||||
(testing) pip install matplotlib jupyter mpi4py :pre
|
|
||||||
|
|
||||||
... :pre
|
|
||||||
|
|
||||||
# return to original shell
|
|
||||||
(testing) deactivate :pre
|
|
||||||
|
|
||||||
|
|
||||||
Creating a new instance of PyLammps :h4
|
|
||||||
|
|
||||||
To create a PyLammps object you need to first import the class from the lammps
|
|
||||||
module. By using the default constructor, a new {lammps} instance is created.
|
|
||||||
|
|
||||||
from lammps import PyLammps
|
|
||||||
L = PyLammps() :pre
|
|
||||||
|
|
||||||
You can also initialize PyLammps on top of this existing {lammps} object:
|
|
||||||
|
|
||||||
from lammps import lammps, PyLammps
|
|
||||||
lmp = lammps()
|
|
||||||
L = PyLammps(ptr=lmp) :pre
|
|
||||||
|
|
||||||
Commands :h4
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
region box block 0 10 0 5 -0.5 0.5 :pre
|
|
||||||
|
|
||||||
In the original interface this command can be executed with the following
|
|
||||||
Python code if {L} was a lammps instance:
|
|
||||||
|
|
||||||
L.command("region box block 0 10 0 5 -0.5 0.5") :pre
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
L.region("box block", 0, 10, 0, 5, -0.5, 0.5) :pre
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi)) :pre
|
|
||||||
|
|
||||||
In contrast, methods of PyLammps accept parameters directly and will convert
|
|
||||||
them automatically to a final command string.
|
|
||||||
|
|
||||||
L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi) :pre
|
|
||||||
|
|
||||||
System state :h4
|
|
||||||
|
|
||||||
In addition to dispatching commands directly through the PyLammps object, it
|
|
||||||
also provides several properties which allow you to query the system state.
|
|
||||||
|
|
||||||
:dlb
|
|
||||||
|
|
||||||
L.system :dt
|
|
||||||
|
|
||||||
Is a dictionary describing the system such as the bounding box or number of atoms :dd
|
|
||||||
|
|
||||||
L.system.xlo, L.system.xhi :dt
|
|
||||||
|
|
||||||
bounding box limits along x-axis :dd
|
|
||||||
|
|
||||||
L.system.ylo, L.system.yhi :dt
|
|
||||||
|
|
||||||
bounding box limits along y-axis :dd
|
|
||||||
|
|
||||||
L.system.zlo, L.system.zhi :dt
|
|
||||||
|
|
||||||
bounding box limits along z-axis :dd
|
|
||||||
|
|
||||||
L.communication :dt
|
|
||||||
|
|
||||||
configuration of communication subsystem, such as the number of threads or processors :dd
|
|
||||||
|
|
||||||
L.communication.nthreads :dt
|
|
||||||
|
|
||||||
number of threads used by each LAMMPS process :dd
|
|
||||||
|
|
||||||
L.communication.nprocs :dt
|
|
||||||
|
|
||||||
number of MPI processes used by LAMMPS :dd
|
|
||||||
|
|
||||||
L.fixes :dt
|
|
||||||
|
|
||||||
List of fixes in the current system :dd
|
|
||||||
|
|
||||||
L.computes :dt
|
|
||||||
|
|
||||||
List of active computes in the current system :dd
|
|
||||||
|
|
||||||
L.dump :dt
|
|
||||||
|
|
||||||
List of active dumps in the current system :dd
|
|
||||||
|
|
||||||
L.groups :dt
|
|
||||||
|
|
||||||
List of groups present in the current system :dd
|
|
||||||
|
|
||||||
:dle
|
|
||||||
|
|
||||||
Working with LAMMPS variables :h4
|
|
||||||
|
|
||||||
LAMMPS variables can be both defined and accessed via the PyLammps interface.
|
|
||||||
|
|
||||||
To define a variable you can use the "variable"_variable.html command:
|
|
||||||
|
|
||||||
L.variable("a index 2") :pre
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
a = L.variables\['a'\] :pre
|
|
||||||
|
|
||||||
The variable value can then be easily read and written by accessing the value
|
|
||||||
property of this object.
|
|
||||||
|
|
||||||
print(a.value)
|
|
||||||
a.value = 4 :pre
|
|
||||||
|
|
||||||
Retrieving the value of an arbitrary LAMMPS expressions :h4
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
result = L.eval("ke") # kinetic energy
|
|
||||||
result = L.eval("pe") # potential energy :pre
|
|
||||||
|
|
||||||
result = L.eval("v_t/2.0") :pre
|
|
||||||
|
|
||||||
Accessing atom data :h4
|
|
||||||
|
|
||||||
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.).
|
|
||||||
|
|
||||||
# access first atom
|
|
||||||
L.atoms\[0\].id
|
|
||||||
L.atoms\[0\].type :pre
|
|
||||||
|
|
||||||
# access second atom
|
|
||||||
L.atoms\[1\].position
|
|
||||||
L.atoms\[1\].velocity
|
|
||||||
L.atoms\[1\].force :pre
|
|
||||||
|
|
||||||
Some properties can also be used to set:
|
|
||||||
|
|
||||||
# set position in 2D simulation
|
|
||||||
L.atoms\[0\].position = (1.0, 0.0) :pre
|
|
||||||
|
|
||||||
# set position in 3D simulation
|
|
||||||
L.atoms\[0\].position = (1.0, 0.0, 1.) :pre
|
|
||||||
|
|
||||||
Evaluating thermo data :h4
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
L.run(1000)
|
|
||||||
L.runs\[0\] # data of first 1000 time steps :pre
|
|
||||||
|
|
||||||
L.run(1000)
|
|
||||||
L.runs\[1\] # data of second 1000 time steps :pre
|
|
||||||
|
|
||||||
Each run contains a dictionary of all trajectories. Each trajectory is
|
|
||||||
accessible through its thermo name:
|
|
||||||
|
|
||||||
L.runs\[0\].step # list of time steps in first run
|
|
||||||
L.runs\[0\].ke # list of kinetic energy values in first run :pre
|
|
||||||
|
|
||||||
Together with matplotlib plotting data out of LAMMPS becomes simple:
|
|
||||||
|
|
||||||
import matplotlib.plot as plt
|
|
||||||
|
|
||||||
steps = L.runs\[0\].step
|
|
||||||
ke = L.runs\[0\].ke
|
|
||||||
plt.plot(steps, ke) :pre
|
|
||||||
|
|
||||||
Error handling with PyLammps :h4
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
IMPORTANT NOTE: 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.
|
|
||||||
|
|
||||||
Using PyLammps in IPython notebooks and Jupyter :h4
|
|
||||||
|
|
||||||
If the LAMMPS Python package is installed for the same Python interpreter as
|
|
||||||
IPython, you can use PyLammps directly inside of an IPython notebook inside of
|
|
||||||
Jupyter. Jupyter is a powerful integrated development environment (IDE) for
|
|
||||||
many dynamic languages like Python, Julia and others, which operates inside of
|
|
||||||
any web browser. Besides auto-completion and syntax highlighting it allows you
|
|
||||||
to create formatted documents using Markup, mathematical formulas, graphics and
|
|
||||||
animations intermixed with executable Python code. It is a great format for
|
|
||||||
tutorials and showcasing your latest research.
|
|
||||||
|
|
||||||
To launch an instance of Jupyter simply run the following command inside your
|
|
||||||
Python environment (this assumes you followed the Quick Start instructions):
|
|
||||||
|
|
||||||
jupyter notebook :pre
|
|
||||||
|
|
||||||
IPyLammps Examples :h4
|
|
||||||
|
|
||||||
Examples of IPython notebooks can be found in the python/examples/pylammps
|
|
||||||
sub-directory. To open these notebooks launch {jupyter notebook} inside this
|
|
||||||
directory and navigate to one of them. If you compiled and installed
|
|
||||||
a LAMMPS shared library with exceptions, PNG, JPEG and FFMPEG support
|
|
||||||
you should be able to rerun all of these notebooks.
|
|
||||||
|
|
||||||
Validating a dihedral potential :h5
|
|
||||||
|
|
||||||
This example showcases how an IPython Notebook can be used to compare a simple
|
|
||||||
LAMMPS simulation of a harmonic dihedral potential to its analytical solution.
|
|
||||||
Four atoms are placed in the simulation and the dihedral potential is applied on
|
|
||||||
them using a datafile. Then one of the atoms is rotated along the central axis by
|
|
||||||
setting its position from Python, which changes the dihedral angle.
|
|
||||||
|
|
||||||
phi = \[d * math.pi / 180 for d in range(360)\] :pre
|
|
||||||
|
|
||||||
pos = \[(1.0, math.cos(p), math.sin(p)) for p in phi\] :pre
|
|
||||||
|
|
||||||
pe = \[\]
|
|
||||||
for p in pos:
|
|
||||||
L.atoms\[3\].position = p
|
|
||||||
L.run(0)
|
|
||||||
pe.append(L.eval("pe")) :pre
|
|
||||||
|
|
||||||
By evaluating the potential energy for each position we can verify that
|
|
||||||
trajectory with the analytical formula. To compare both solutions, we plot
|
|
||||||
both trajectories over each other using matplotlib, which embeds the generated
|
|
||||||
plot inside the IPython notebook.
|
|
||||||
|
|
||||||
:c,image(JPG/pylammps_dihedral.jpg)
|
|
||||||
|
|
||||||
Running a Monte Carlo relaxation :h5
|
|
||||||
|
|
||||||
This second example shows how to use PyLammps to create a 2D Monte Carlo Relaxation
|
|
||||||
simulation, computing and plotting energy terms and even embedding video output.
|
|
||||||
|
|
||||||
Initially, a 2D system is created in a state with minimal energy.
|
|
||||||
|
|
||||||
:c,image(JPG/pylammps_mc_minimum.jpg)
|
|
||||||
|
|
||||||
It is then disordered by moving each atom by a random delta.
|
|
||||||
|
|
||||||
random.seed(27848)
|
|
||||||
deltaperturb = 0.2 :pre
|
|
||||||
|
|
||||||
for i in range(L.system.natoms):
|
|
||||||
x, y = L.atoms\[i\].position
|
|
||||||
dx = deltaperturb * random.uniform(-1, 1)
|
|
||||||
dy = deltaperturb * random.uniform(-1, 1)
|
|
||||||
L.atoms\[i\].position = (x+dx, y+dy) :pre
|
|
||||||
|
|
||||||
L.run(0) :pre
|
|
||||||
|
|
||||||
:c,image(JPG/pylammps_mc_disordered.jpg)
|
|
||||||
|
|
||||||
Finally, the Monte Carlo algorithm is implemented in Python. It continuously
|
|
||||||
moves random atoms by a random delta and only accepts certain moves.
|
|
||||||
|
|
||||||
estart = L.eval("pe")
|
|
||||||
elast = estart :pre
|
|
||||||
|
|
||||||
naccept = 0
|
|
||||||
energies = \[estart\] :pre
|
|
||||||
|
|
||||||
niterations = 3000
|
|
||||||
deltamove = 0.1
|
|
||||||
kT = 0.05 :pre
|
|
||||||
|
|
||||||
natoms = L.system.natoms :pre
|
|
||||||
|
|
||||||
for i in range(niterations):
|
|
||||||
iatom = random.randrange(0, natoms)
|
|
||||||
current_atom = L.atoms\[iatom\] :pre
|
|
||||||
|
|
||||||
x0, y0 = current_atom.position :pre
|
|
||||||
|
|
||||||
dx = deltamove * random.uniform(-1, 1)
|
|
||||||
dy = deltamove * random.uniform(-1, 1) :pre
|
|
||||||
|
|
||||||
current_atom.position = (x0+dx, y0+dy) :pre
|
|
||||||
|
|
||||||
L.run(1, "pre no post no") :pre
|
|
||||||
|
|
||||||
e = L.eval("pe")
|
|
||||||
energies.append(e) :pre
|
|
||||||
|
|
||||||
if e <= elast:
|
|
||||||
naccept += 1
|
|
||||||
elast = e
|
|
||||||
elif random.random() <= math.exp(natoms*(elast-e)/kT):
|
|
||||||
naccept += 1
|
|
||||||
elast = e
|
|
||||||
else:
|
|
||||||
current_atom.position = (x0, y0) :pre
|
|
||||||
|
|
||||||
The energies of each iteration are collected in a Python list and finally plotted using matplotlib.
|
|
||||||
|
|
||||||
:c,image(JPG/pylammps_mc_energies_plot.jpg)
|
|
||||||
|
|
||||||
The IPython notebook also shows how to use dump commands and embed video files
|
|
||||||
inside of the IPython notebook.
|
|
||||||
|
|
||||||
Using PyLammps and mpi4py (Experimental) :h4
|
|
||||||
|
|
||||||
PyLammps can be run in parallel using mpi4py. This python package can be installed using
|
|
||||||
|
|
||||||
pip install mpi4py :pre
|
|
||||||
|
|
||||||
The following is a short example which reads in an existing LAMMPS input file and
|
|
||||||
executes it in parallel. You can find in.melt in the examples/melt folder.
|
|
||||||
|
|
||||||
from mpi4py import MPI
|
|
||||||
from lammps import PyLammps :pre
|
|
||||||
|
|
||||||
L = PyLammps()
|
|
||||||
L.file("in.melt") :pre
|
|
||||||
|
|
||||||
if MPI.COMM_WORLD.rank == 0:
|
|
||||||
print("Potential energy: ", L.eval("pe")) :pre
|
|
||||||
|
|
||||||
MPI.Finalize() :pre
|
|
||||||
|
|
||||||
To run this script (melt.py) in parallel using 4 MPI processes we invoke the
|
|
||||||
following mpirun command:
|
|
||||||
|
|
||||||
mpirun -np 4 python melt.py :pre
|
|
||||||
|
|
||||||
IMPORTANT NOTE: Any command must be executed by all MPI processes. However, evaluations and querying the system state is only available on rank 0.
|
|
||||||
|
|
||||||
Feedback and Contributing :h4
|
|
||||||
|
|
||||||
If you find this Python interface useful, please feel free to provide feedback
|
|
||||||
and ideas on how to improve it to Richard Berger (richard.berger@temple.edu). We also
|
|
||||||
want to encourage people to write tutorial style IPython notebooks showcasing LAMMPS usage
|
|
||||||
and maybe their latest research results.
|
|
||||||
Reference in New Issue
Block a user