lammps/doc/html/Section_python.html

1045 lines
71 KiB
HTML

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>11. Python interface to LAMMPS &mdash; LAMMPS documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/sphinxcontrib-images/LightBox2/lightbox2/css/lightbox.css" type="text/css" />
<link rel="top" title="LAMMPS documentation" href="index.html"/>
<link rel="next" title="12. Errors" href="Section_errors.html"/>
<link rel="prev" title="10. Modifying &amp; extending LAMMPS" href="Section_modify.html"/>
<script src="_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-nav-search">
<a href="Manual.html" class="icon icon-home"> LAMMPS
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Section_intro.html">1. Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_start.html">2. Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_commands.html">3. Commands</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_packages.html">4. Packages</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_accelerate.html">5. Accelerating LAMMPS performance</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_howto.html">6. How-to discussions</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_example.html">7. Example problems</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_perf.html">8. Performance &amp; scalability</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_tools.html">9. Additional tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_modify.html">10. Modifying &amp; extending LAMMPS</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">11. Python interface to LAMMPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#overview-of-running-lammps-from-python">11.1. Overview of running LAMMPS from Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="#overview-of-using-python-from-a-lammps-script">11.2. Overview of using Python from a LAMMPS script</a></li>
<li class="toctree-l2"><a class="reference internal" href="#building-lammps-as-a-shared-library">11.3. Building LAMMPS as a shared library</a></li>
<li class="toctree-l2"><a class="reference internal" href="#installing-the-python-wrapper-into-python">11.4. Installing the Python wrapper into Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="#extending-python-with-mpi-to-run-in-parallel">11.5. Extending Python with MPI to run in parallel</a></li>
<li class="toctree-l2"><a class="reference internal" href="#testing-the-python-lammps-interface">11.6. Testing the Python-LAMMPS interface</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#test-lammps-and-python-in-serial">11.6.1. <strong>Test LAMMPS and Python in serial:</strong></a></li>
<li class="toctree-l3"><a class="reference internal" href="#test-lammps-and-python-in-parallel">11.6.2. <strong>Test LAMMPS and Python in parallel:</strong></a></li>
<li class="toctree-l3"><a class="reference internal" href="#running-python-scripts">11.6.3. <strong>Running Python scripts:</strong></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#using-lammps-from-python">11.7. Using LAMMPS from Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="#example-python-scripts-that-use-lammps">11.8. Example Python scripts that use LAMMPS</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Section_errors.html">12. Errors</a></li>
<li class="toctree-l1"><a class="reference internal" href="Section_history.html">13. Future and history</a></li>
</ul>
</div>
&nbsp;
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="Manual.html">LAMMPS</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="Manual.html">Docs</a> &raquo;</li>
<li>11. Python interface to LAMMPS</li>
<li class="wy-breadcrumbs-aside">
<a href="http://lammps.sandia.gov">Website</a>
<a href="Section_commands.html#comm">Commands</a>
</li>
</ul>
<hr/>
<div class="rst-footer-buttons" style="margin-bottom: 1em" role="navigation" aria-label="footer navigation">
<a href="Section_errors.html" class="btn btn-neutral float-right" title="12. Errors" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="Section_modify.html" class="btn btn-neutral" title="10. Modifying &amp; extending LAMMPS" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="python-interface-to-lammps">
<h1>11. Python interface to LAMMPS</h1>
<p>LAMMPS can work together with Python in two ways. First, Python can
wrap LAMMPS through the <a class="reference internal" href="Section_howto.html#howto-19"><span class="std std-ref">LAMMPS library interface</span></a>, so that a Python script can
create one or more instances of LAMMPS and launch one or more
simulations. In Python lingo, this is &#8220;extending&#8221; Python with LAMMPS.</p>
<p>Second, LAMMPS can use the Python interpreter, so that a LAMMPS input
script can invoke Python code, and pass information back-and-forth
between the input script and Python functions you write. The Python
code can also callback to LAMMPS to query or change its attributes.
In Python lingo, this is &#8220;embedding&#8221; Python in LAMMPS.</p>
<p>This section describes how to do both.</p>
<ul class="simple">
<li>11.1 <a class="reference internal" href="#py-1"><span class="std std-ref">Overview of running LAMMPS from Python</span></a></li>
<li>11.2 <a class="reference internal" href="#py-2"><span class="std std-ref">Overview of using Python from a LAMMPS script</span></a></li>
<li>11.3 <a class="reference internal" href="#py-3"><span class="std std-ref">Building LAMMPS as a shared library</span></a></li>
<li>11.4 <a class="reference internal" href="#py-4"><span class="std std-ref">Installing the Python wrapper into Python</span></a></li>
<li>11.5 <a class="reference internal" href="#py-5"><span class="std std-ref">Extending Python with MPI to run in parallel</span></a></li>
<li>11.6 <a class="reference internal" href="#py-6"><span class="std std-ref">Testing the Python-LAMMPS interface</span></a></li>
<li>11.7 <a class="reference internal" href="#py-7"><span class="std std-ref">Using LAMMPS from Python</span></a></li>
<li>11.8 <a class="reference internal" href="#py-8"><span class="std std-ref">Example Python scripts that use LAMMPS</span></a></li>
</ul>
<p>If you are not familiar with it, <a class="reference external" href="http://www.python.org">Python</a> is a
powerful scripting and programming language which can essentially do
anything that faster, lower-level languages like C or C++ can do, but
typically with much fewer lines of code. When used in embedded mode,
Python can perform operations that the simplistic LAMMPS input script
syntax cannot. Python can be also be used as a &#8220;glue&#8221; language to
drive a program through its library interface, or to hook multiple
pieces of software together, such as a simulation package plus a
visualization package, or to run a coupled multiscale or multiphysics
model.</p>
<p>See <a class="reference internal" href="Section_howto.html#howto-10"><span class="std std-ref">Section_howto 10</span></a> of the manual and
the couple directory of the distribution for more ideas about coupling
LAMMPS to other codes. See <a class="reference internal" href="Section_howto.html#howto-19"><span class="std std-ref">Section_howto 19</span></a> for a description of the LAMMPS
library interface provided in src/library.cpp and src/library.h, and
how to extend it for your needs. As described below, that interface
is what is exposed to Python either when calling LAMMPS from Python or
when calling Python from a LAMMPS input script and then calling back
to LAMMPS from Python code. The library interface is designed to be
easy to add functions to. Thus the Python interface to LAMMPS is also
easy to extend as well.</p>
<p>If you create interesting Python scripts that run LAMMPS or
interesting Python functions that can be called from a LAMMPS input
script, that you think would be useful to other users, please <a class="reference external" href="http://lammps.sandia.gov/authors.html">email them to the developers</a>. We can
include them in the LAMMPS distribution.</p>
<div class="section" id="overview-of-running-lammps-from-python">
<span id="py-1"></span><h2>11.1. Overview of running LAMMPS from Python</h2>
<p>The LAMMPS distribution includes a python directory with all you need
to run LAMMPS from Python. The python/lammps.py file wraps the LAMMPS
library interface, with one wrapper function per LAMMPS library
function. This file makes it is possible to do the following either
from a Python script, or interactively from a Python prompt: create
one or more instances of LAMMPS, invoke LAMMPS commands or give it an
input script, run LAMMPS incrementally, extract LAMMPS results, an
modify internal LAMMPS variables. From a Python script you can do
this in serial or parallel. Running Python interactively in parallel
does not generally work, unless you have a version of Python that
extends standard Python to enable multiple instances of Python to read
what you type.</p>
<p>To do all of this, you must first build LAMMPS as a shared library,
then insure that your Python can find the python/lammps.py file and
the shared library. These steps are explained in subsequent sections
11.3 and 11.4. Sections 11.5 and 11.6 discuss using MPI from a
parallel Python program and how to test that you are ready to use
LAMMPS from Python. Section 11.7 lists all the functions in the
current LAMMPS library interface and how to call them from Python.</p>
<p>Section 11.8 gives some examples of coupling LAMMPS to other tools via
Python. For example, LAMMPS can easily be coupled to a GUI or other
visualization tools that display graphs or animations in real time as
LAMMPS runs. Examples of such scripts are inlcluded in the python
directory.</p>
<p>Two advantages of using Python to run LAMMPS are how concise the
language is, and that it can be run interactively, enabling rapid
development and debugging of programs. If you use it to mostly invoke
costly operations within LAMMPS, such as running a simulation for a
reasonable number of timesteps, then the overhead cost of invoking
LAMMPS thru Python will be negligible.</p>
<p>The Python wrapper for LAMMPS uses the amazing and magical (to me)
&#8220;ctypes&#8221; package in Python, which auto-generates the interface code
needed between Python and a set of C interface routines for a library.
Ctypes is part of standard Python for versions 2.5 and later. You can
check which version of Python you have installed, by simply typing
&#8220;python&#8221; at a shell prompt.</p>
<hr class="docutils" />
</div>
<div class="section" id="overview-of-using-python-from-a-lammps-script">
<span id="py-2"></span><h2>11.2. Overview of using Python from a LAMMPS script</h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It is not currently possible to use the <a class="reference internal" href="python.html"><span class="doc">python</span></a>
command described in this section with Python 3, only with Python 2.
The C API changed from Python 2 to 3 and the LAMMPS code is not
compatible with both.</p>
</div>
<p>LAMMPS has a <a class="reference internal" href="python.html"><span class="doc">python</span></a> command which can be used in an
input script to define and execute a Python function that you write
the code for. The Python function can also be assigned to a LAMMPS
python-style variable via the <a class="reference internal" href="variable.html"><span class="doc">variable</span></a> command. Each
time the variable is evaluated, either in the LAMMPS input script
itself, or by another LAMMPS command that uses the variable, this will
trigger the Python function to be invoked.</p>
<p>The Python code for the function can be included directly in the input
script or in an auxiliary file. The function can have arguments which
are mapped to LAMMPS variables (also defined in the input script) and
it can return a value to a LAMMPS variable. This is thus a mechanism
for your input script to pass information to a piece of Python code,
ask Python to execute the code, and return information to your input
script.</p>
<p>Note that a Python function can be arbitrarily complex. It can import
other Python modules, instantiate Python classes, call other Python
functions, etc. The Python code that you provide can contain more
code than the single function. It can contain other functions or
Python classes, as well as global variables or other mechanisms for
storing state between calls from LAMMPS to the function.</p>
<p>The Python function you provide can consist of &#8220;pure&#8221; Python code that
only performs operations provided by standard Python. However, the
Python function can also &#8220;call back&#8221; to LAMMPS through its
Python-wrapped library interface, in the manner described in the
previous section 11.1. This means it can issue LAMMPS input script
commands or query and set internal LAMMPS state. As an example, this
can be useful in an input script to create a more complex loop with
branching logic, than can be created using the simple looping and
branching logic enabled by the <a class="reference internal" href="next.html"><span class="doc">next</span></a> and <a class="reference internal" href="if.html"><span class="doc">if</span></a>
commands.</p>
<p>See the <a class="reference internal" href="python.html"><span class="doc">python</span></a> doc page and the <a class="reference internal" href="variable.html"><span class="doc">variable</span></a>
doc page for its python-style variables for more info, including
examples of Python code you can write for both pure Python operations
and callbacks to LAMMPS.</p>
<p>To run pure Python code from LAMMPS, you only need to build LAMMPS
with the PYTHON package installed:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="n">yes</span><span class="o">-</span><span class="n">python</span>
<span class="n">make</span> <span class="n">machine</span>
</pre></div>
</div>
<p>Note that this will link LAMMPS with the Python library on your
system, which typically requires several auxiliary system libraries to
also be linked. The list of these libraries and the paths to find
them are specified in the lib/python/Makefile.lammps file. You need
to insure that file contains the correct information for your version
of Python and your machine to successfully build LAMMPS. See the
lib/python/README file for more info.</p>
<p>If you want to write Python code with callbacks to LAMMPS, then you
must also follow the steps overviewed in the preceeding section (11.1)
for running LAMMPS from Python. I.e. you must build LAMMPS as a
shared library and insure that Python can find the python/lammps.py
file and the shared library.</p>
<hr class="docutils" />
</div>
<div class="section" id="building-lammps-as-a-shared-library">
<span id="py-3"></span><h2>11.3. Building LAMMPS as a shared library</h2>
<p>Instructions on how to build LAMMPS as a shared library are given in
<a class="reference internal" href="Section_start.html#start-5"><span class="std std-ref">Section_start 5</span></a>. A shared library is one
that is dynamically loadable, which is what Python requires to wrap
LAMMPS. On Linux this is a library file that ends in &#8221;.so&#8221;, not &#8221;.a&#8221;.</p>
<p>From the src directory, type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="n">foo</span> <span class="n">mode</span><span class="o">=</span><span class="n">shlib</span>
</pre></div>
</div>
<p>where foo is the machine target name, such as linux or g++ or serial.
This should create the file liblammps_foo.so in the src directory, as
well as a soft link liblammps.so, which is what the Python wrapper will
load by default. Note that if you are building multiple machine
versions of the shared library, the soft link is always set to the
most recently built version.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are building LAMMPS with an MPI or FFT library or other
auxiliary libraries (used by various packages), then all of these
extra libraries must also be shared libraries. If the LAMMPS
shared-library build fails with an error complaining about this, see
<a class="reference internal" href="Section_start.html#start-5"><span class="std std-ref">Section_start 5</span></a> for more details.</p>
</div>
<hr class="docutils" />
</div>
<div class="section" id="installing-the-python-wrapper-into-python">
<span id="py-4"></span><h2>11.4. Installing the Python wrapper into Python</h2>
<p>For Python to invoke LAMMPS, there are 2 files it needs to know about:</p>
<ul class="simple">
<li>python/lammps.py</li>
<li>src/liblammps.so</li>
</ul>
<p>Lammps.py is the Python wrapper on the LAMMPS library interface.
Liblammps.so is the shared LAMMPS library that Python loads, as
described above.</p>
<p>You can insure Python can find these files in one of two ways:</p>
<ul class="simple">
<li>set two environment variables</li>
<li>run the python/install.py script</li>
</ul>
<p>If you set the paths to these files as environment variables, you only
have to do it once. For the csh or tcsh shells, add something like
this to your ~/.cshrc file, one line for each of the two files:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>setenv PYTHONPATH ${PYTHONPATH}:/home/sjplimp/lammps/python
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:/home/sjplimp/lammps/src
</pre></div>
</div>
<p>If you use the python/install.py script, you need to invoke it every
time you rebuild LAMMPS (as a shared library) or make changes to the
python/lammps.py file.</p>
<p>You can invoke install.py from the python directory as</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">python</span> <span class="n">install</span><span class="o">.</span><span class="n">py</span> <span class="p">[</span><span class="n">libdir</span><span class="p">]</span> <span class="p">[</span><span class="n">pydir</span><span class="p">]</span>
</pre></div>
</div>
<p>The optional libdir is where to copy the LAMMPS shared library to; the
default is /usr/local/lib. The optional pydir is where to copy the
lammps.py file to; the default is the site-packages directory of the
version of Python that is running the install script.</p>
<p>Note that libdir must be a location that is in your default
LD_LIBRARY_PATH, like /usr/local/lib or /usr/lib. And pydir must be a
location that Python looks in by default for imported modules, like
its site-packages dir. If you want to copy these files to
non-standard locations, such as within your own user space, you will
need to set your PYTHONPATH and LD_LIBRARY_PATH environment variables
accordingly, as above.</p>
<p>If the install.py script does not allow you to copy files into system
directories, prefix the python command with &#8220;sudo&#8221;. If you do this,
make sure that the Python that root runs is the same as the Python you
run. E.g. you may need to do something like</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">sudo</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">python</span> <span class="n">install</span><span class="o">.</span><span class="n">py</span> <span class="p">[</span><span class="n">libdir</span><span class="p">]</span> <span class="p">[</span><span class="n">pydir</span><span class="p">]</span>
</pre></div>
</div>
<p>You can also invoke install.py from the make command in the src
directory as</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">make</span> <span class="n">install</span><span class="o">-</span><span class="n">python</span>
</pre></div>
</div>
<p>In this mode you cannot append optional arguments. Again, you may
need to prefix this with &#8220;sudo&#8221;. In this mode you cannot control
which Python is invoked by root.</p>
<p>Note that if you want Python to be able to load different versions of
the LAMMPS shared library (see <a class="reference internal" href="#py-5"><span class="std std-ref">this section</span></a> below), you will
need to manually copy files like liblammps_g++.so into the appropriate
system directory. This is not needed if you set the LD_LIBRARY_PATH
environment variable as described above.</p>
<hr class="docutils" />
</div>
<div class="section" id="extending-python-with-mpi-to-run-in-parallel">
<span id="py-5"></span><h2>11.5. Extending Python with MPI to run in parallel</h2>
<p>If you wish to run LAMMPS in parallel from Python, you need to extend
your Python with an interface to MPI. This also allows you to
make MPI calls directly from Python in your script, if you desire.</p>
<p>There are several Python packages available that purport to wrap MPI
as a library and allow MPI functions to be called from Python.</p>
<p>These include</p>
<ul class="simple">
<li><a class="reference external" href="http://pympi.sourceforge.net/">pyMPI</a></li>
<li><a class="reference external" href="http://code.google.com/p/maroonmpi/">maroonmpi</a></li>
<li><a class="reference external" href="http://code.google.com/p/mpi4py/">mpi4py</a></li>
<li><a class="reference external" href="http://nbcr.sdsc.edu/forum/viewtopic.php?t=89&amp;sid=c997fefc3933bd66204875b436940f16">myMPI</a></li>
<li><a class="reference external" href="http://code.google.com/p/pypar">Pypar</a></li>
</ul>
<p>All of these except pyMPI work by wrapping the MPI library and
exposing (some portion of) its interface to your Python script. This
means Python cannot be used interactively in parallel, since they do
not address the issue of interactive input to multiple instances of
Python running on different processors. The one exception is pyMPI,
which alters the Python interpreter to address this issue, and (I
believe) creates a new alternate executable (in place of &#8220;python&#8221;
itself) as a result.</p>
<p>In principle any of these Python/MPI packages should work to invoke
LAMMPS in parallel and to make MPI calls themselves from a Python
script which is itself running in parallel. However, when I
downloaded and looked at a few of them, their documentation was
incomplete and I had trouble with their installation. It&#8217;s not clear
if some of the packages are still being actively developed and
supported.</p>
<p>The packages Pypar and mpi4py have both been successfully tested with
LAMMPS. Pypar is simpler and easy to set up and use, but supports
only a subset of MPI. Mpi4py is more MPI-feature complete, but also a
bit more complex to use. As of version 2.0.0, mpi4py is the only
python MPI wrapper that allows passing a custom MPI communicator to
the LAMMPS constructor, which means one can easily run one or more
LAMMPS instances on subsets of the total MPI ranks.</p>
<hr class="docutils" />
<p>Pypar requires the ubiquitous <a class="reference external" href="http://numpy.scipy.org">Numpy package</a>
be installed in your Python. After launching Python, type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">numpy</span>
</pre></div>
</div>
<p>to see if it is installed. If not, here is how to install it (version
1.3.0b1 as of April 2009). Unpack the numpy tarball and from its
top-level directory, type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">build</span>
<span class="n">sudo</span> <span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">install</span>
</pre></div>
</div>
<p>The &#8220;sudo&#8221; is only needed if required to copy Numpy files into your
Python distribution&#8217;s site-packages directory.</p>
<p>To install Pypar (version pypar-2.1.4_94 as of Aug 2012), unpack it
and from its &#8220;source&#8221; directory, type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">build</span>
<span class="n">sudo</span> <span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">install</span>
</pre></div>
</div>
<p>Again, the &#8220;sudo&#8221; is only needed if required to copy Pypar files into
your Python distribution&#8217;s site-packages directory.</p>
<p>If you have successully installed Pypar, you should be able to run
Python and type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pypar</span>
</pre></div>
</div>
<p>without error. You should also be able to run python in parallel
on a simple test script</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">mpirun</span> <span class="o">-</span><span class="n">np</span> <span class="mi">4</span> <span class="n">python</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>where test.py contains the lines</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pypar</span>
<span class="nb">print</span> <span class="s2">&quot;Proc </span><span class="si">%d</span><span class="s2"> out of </span><span class="si">%d</span><span class="s2"> procs&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pypar</span><span class="o">.</span><span class="n">rank</span><span class="p">(),</span><span class="n">pypar</span><span class="o">.</span><span class="n">size</span><span class="p">())</span>
</pre></div>
</div>
<p>and see one line of output for each processor you run on.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">To use Pypar and LAMMPS in parallel from Python, you must insure
both are using the same version of MPI. If you only have one MPI
installed on your system, this is not an issue, but it can be if you
have multiple MPIs. Your LAMMPS build is explicit about which MPI it
is using, since you specify the details in your lo-level
src/MAKE/Makefile.foo file. Pypar uses the &#8220;mpicc&#8221; command to find
information about the MPI it uses to build against. And it tries to
load &#8220;libmpi.so&#8221; from the LD_LIBRARY_PATH. This may or may not find
the MPI library that LAMMPS is using. If you have problems running
both Pypar and LAMMPS together, this is an issue you may need to
address, e.g. by moving other MPI installations so that Pypar finds
the right one.</p>
</div>
<hr class="docutils" />
<p>To install mpi4py (version mpi4py-2.0.0 as of Oct 2015), unpack it
and from its main directory, type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">build</span>
<span class="n">sudo</span> <span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">install</span>
</pre></div>
</div>
<p>Again, the &#8220;sudo&#8221; is only needed if required to copy mpi4py files into
your Python distribution&#8217;s site-packages directory. To install with
user privilege into the user local directory type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">install</span> <span class="o">--</span><span class="n">user</span>
</pre></div>
</div>
<p>If you have successully installed mpi4py, you should be able to run
Python and type</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mpi4py</span> <span class="k">import</span> <span class="n">MPI</span>
</pre></div>
</div>
<p>without error. You should also be able to run python in parallel
on a simple test script</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">mpirun</span> <span class="o">-</span><span class="n">np</span> <span class="mi">4</span> <span class="n">python</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>where test.py contains the lines</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mpi4py</span> <span class="k">import</span> <span class="n">MPI</span>
<span class="n">comm</span> <span class="o">=</span> <span class="n">MPI</span><span class="o">.</span><span class="n">COMM_WORLD</span>
<span class="nb">print</span> <span class="s2">&quot;Proc </span><span class="si">%d</span><span class="s2"> out of </span><span class="si">%d</span><span class="s2"> procs&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">comm</span><span class="o">.</span><span class="n">Get_rank</span><span class="p">(),</span><span class="n">comm</span><span class="o">.</span><span class="n">Get_size</span><span class="p">())</span>
</pre></div>
</div>
<p>and see one line of output for each processor you run on.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">To use mpi4py and LAMMPS in parallel from Python, you must
insure both are using the same version of MPI. If you only have one
MPI installed on your system, this is not an issue, but it can be if
you have multiple MPIs. Your LAMMPS build is explicit about which MPI
it is using, since you specify the details in your lo-level
src/MAKE/Makefile.foo file. Mpi4py uses the &#8220;mpicc&#8221; command to find
information about the MPI it uses to build against. And it tries to
load &#8220;libmpi.so&#8221; from the LD_LIBRARY_PATH. This may or may not find
the MPI library that LAMMPS is using. If you have problems running
both mpi4py and LAMMPS together, this is an issue you may need to
address, e.g. by moving other MPI installations so that mpi4py finds
the right one.</p>
</div>
<hr class="docutils" />
</div>
<div class="section" id="testing-the-python-lammps-interface">
<span id="py-6"></span><h2>11.6. Testing the Python-LAMMPS interface</h2>
<p>To test if LAMMPS is callable from Python, launch Python interactively
and type:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
</pre></div>
</div>
<p>If you get no errors, you&#8217;re ready to use LAMMPS from Python. If the
2nd command fails, the most common error to see is</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="ne">OSError</span><span class="p">:</span> <span class="n">Could</span> <span class="ow">not</span> <span class="n">load</span> <span class="n">LAMMPS</span> <span class="n">dynamic</span> <span class="n">library</span>
</pre></div>
</div>
<p>which means Python was unable to load the LAMMPS shared library. This
typically occurs if the system can&#8217;t find the LAMMPS shared library or
one of the auxiliary shared libraries it depends on, or if something
about the library is incompatible with your Python. The error message
should give you an indication of what went wrong.</p>
<p>You can also test the load directly in Python as follows, without
first importing from the lammps.py file:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">ctypes</span> <span class="k">import</span> <span class="n">CDLL</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">CDLL</span><span class="p">(</span><span class="s2">&quot;liblammps.so&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>If an error occurs, carefully go thru the steps in <a class="reference internal" href="Section_start.html#start-5"><span class="std std-ref">Section_start 5</span></a> and above about building a shared
library and about insuring Python can find the necessary two files
it needs.</p>
<div class="section" id="test-lammps-and-python-in-serial">
<h3>11.6.1. <strong>Test LAMMPS and Python in serial:</strong></h3>
<p>To run a LAMMPS test in serial, type these lines into Python
interactively from the bench directory:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">lmp</span><span class="o">.</span><span class="n">file</span><span class="p">(</span><span class="s2">&quot;in.lj&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Or put the same lines in the file test.py and run it as</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">python</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>Either way, you should see the results of running the in.lj benchmark
on a single processor appear on the screen, the same as if you had
typed something like:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">lmp_g</span><span class="o">++</span> <span class="o">-</span><span class="ow">in</span> <span class="ow">in</span><span class="o">.</span><span class="n">lj</span>
</pre></div>
</div>
</div>
<div class="section" id="test-lammps-and-python-in-parallel">
<h3>11.6.2. <strong>Test LAMMPS and Python in parallel:</strong></h3>
<p>To run LAMMPS in parallel, assuming you have installed the
<a class="reference external" href="Pypar">Pypar</a> package as discussed above, create a test.py file
containing these lines:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pypar</span>
<span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
<span class="n">lmp</span><span class="o">.</span><span class="n">file</span><span class="p">(</span><span class="s2">&quot;in.lj&quot;</span><span class="p">)</span>
<span class="nb">print</span> <span class="s2">&quot;Proc </span><span class="si">%d</span><span class="s2"> out of </span><span class="si">%d</span><span class="s2"> procs has&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pypar</span><span class="o">.</span><span class="n">rank</span><span class="p">(),</span><span class="n">pypar</span><span class="o">.</span><span class="n">size</span><span class="p">()),</span><span class="n">lmp</span>
<span class="n">pypar</span><span class="o">.</span><span class="n">finalize</span><span class="p">()</span>
</pre></div>
</div>
<p>To run LAMMPS in parallel, assuming you have installed the
<a class="reference external" href="mpi4py">mpi4py</a> package as discussed above, create a test.py file
containing these lines:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mpi4py</span> <span class="k">import</span> <span class="n">MPI</span>
<span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
<span class="n">lmp</span><span class="o">.</span><span class="n">file</span><span class="p">(</span><span class="s2">&quot;in.lj&quot;</span><span class="p">)</span>
<span class="n">me</span> <span class="o">=</span> <span class="n">MPI</span><span class="o">.</span><span class="n">COMM_WORLD</span><span class="o">.</span><span class="n">Get_rank</span><span class="p">()</span>
<span class="n">nprocs</span> <span class="o">=</span> <span class="n">MPI</span><span class="o">.</span><span class="n">COMM_WORLD</span><span class="o">.</span><span class="n">Get_size</span><span class="p">()</span>
<span class="nb">print</span> <span class="s2">&quot;Proc </span><span class="si">%d</span><span class="s2"> out of </span><span class="si">%d</span><span class="s2"> procs has&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">me</span><span class="p">,</span><span class="n">nprocs</span><span class="p">),</span><span class="n">lmp</span>
<span class="n">MPI</span><span class="o">.</span><span class="n">Finalize</span><span class="p">()</span>
</pre></div>
</div>
<p>You can either script in parallel as:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">mpirun</span> <span class="o">-</span><span class="n">np</span> <span class="mi">4</span> <span class="n">python</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>and you should see the same output as if you had typed</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">mpirun</span> <span class="o">-</span><span class="n">np</span> <span class="mi">4</span> <span class="n">lmp_g</span><span class="o">++</span> <span class="o">-</span><span class="ow">in</span> <span class="ow">in</span><span class="o">.</span><span class="n">lj</span>
</pre></div>
</div>
<p>Note that if you leave out the 3 lines from test.py that specify Pypar
commands you will instantiate and run LAMMPS independently on each of
the P processors specified in the mpirun command. In this case you
should get 4 sets of output, each showing that a LAMMPS run was made
on a single processor, instead of one set of output showing that
LAMMPS ran on 4 processors. If the 1-processor outputs occur, it
means that Pypar is not working correctly.</p>
<p>Also note that once you import the PyPar module, Pypar initializes MPI
for you, and you can use MPI calls directly in your Python script, as
described in the Pypar documentation. The last line of your Python
script should be pypar.finalize(), to insure MPI is shut down
correctly.</p>
</div>
<div class="section" id="running-python-scripts">
<h3>11.6.3. <strong>Running Python scripts:</strong></h3>
<p>Note that any Python script (not just for LAMMPS) can be invoked in
one of several ways:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">python</span> <span class="n">foo</span><span class="o">.</span><span class="n">script</span>
<span class="o">%</span> <span class="n">python</span> <span class="o">-</span><span class="n">i</span> <span class="n">foo</span><span class="o">.</span><span class="n">script</span>
<span class="o">%</span> <span class="n">foo</span><span class="o">.</span><span class="n">script</span>
</pre></div>
</div>
<p>The last command requires that the first line of the script be
something like this:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="ch">#!/usr/local/bin/python</span>
<span class="c1">#!/usr/local/bin/python -i</span>
</pre></div>
</div>
<p>where the path points to where you have Python installed, and that you
have made the script file executable:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">chmod</span> <span class="o">+</span><span class="n">x</span> <span class="n">foo</span><span class="o">.</span><span class="n">script</span>
</pre></div>
</div>
<p>Without the &#8220;-i&#8221; flag, Python will exit when the script finishes.
With the &#8220;-i&#8221; flag, you will be left in the Python interpreter when
the script finishes, so you can type subsequent commands. As
mentioned above, you can only run Python interactively when running
Python on a single processor, not in parallel.</p>
</div>
</div>
<div class="section" id="using-lammps-from-python">
<span id="py-7"></span><h2>11.7. Using LAMMPS from Python</h2>
<p>As described above, the Python interface to LAMMPS consists of a
Python &#8220;lammps&#8221; module, the source code for which is in
python/lammps.py, which creates a &#8220;lammps&#8221; object, with a set of
methods that can be invoked on that object. The sample Python code
below assumes you have first imported the &#8220;lammps&#8221; module in your
Python script, as follows:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
</pre></div>
</div>
<p>These are the methods defined by the lammps module. If you look at
the files src/library.cpp and src/library.h you will see that they
correspond one-to-one with calls you can make to the LAMMPS library
from a C++ or C or Fortran program.</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span> <span class="c1"># create a LAMMPS object using the default liblammps.so library</span>
<span class="mi">4</span> <span class="n">optional</span> <span class="n">args</span> <span class="n">are</span> <span class="n">allowed</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span> <span class="n">cmdargs</span><span class="p">,</span> <span class="n">ptr</span><span class="p">,</span> <span class="n">comm</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">(</span><span class="n">ptr</span><span class="o">=</span><span class="n">lmpptr</span><span class="p">)</span> <span class="c1"># use lmpptr as previously created LAMMPS object</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">(</span><span class="n">comm</span><span class="o">=</span><span class="n">split</span><span class="p">)</span> <span class="c1"># create a LAMMPS object with a custom communicator, requires mpi4py 2.0.0 or later</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;g++&quot;</span><span class="p">)</span> <span class="c1"># create a LAMMPS object using the liblammps_g++.so library</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;g++&quot;</span><span class="p">,</span><span class="n">cmdargs</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span> <span class="c1"># add LAMMPS command-line args, e.g. list = [&quot;-echo&quot;,&quot;screen&quot;]</span>
</pre></div>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">lmp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># destroy a LAMMPS object</span>
</pre></div>
</div>
<p>version = lmp.version() # return the numerical version id, e.g. LAMMPS 2 Sep 2015 -&gt; 20150902</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">lmp</span><span class="o">.</span><span class="n">file</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="c1"># run an entire input script, file = &quot;in.lj&quot;</span>
<span class="n">lmp</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span> <span class="c1"># invoke a single LAMMPS command, cmd = &quot;run 100&quot;</span>
</pre></div>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">xlo</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">extract_global</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="nb">type</span><span class="p">)</span> <span class="c1"># extract a global quantity</span>
<span class="c1"># name = &quot;boxxlo&quot;, &quot;nlocal&quot;, etc</span>
<span class="c1"># type = 0 = int</span>
<span class="c1"># 1 = double</span>
</pre></div>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">coords</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">extract_atom</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="nb">type</span><span class="p">)</span> <span class="c1"># extract a per-atom quantity</span>
<span class="c1"># name = &quot;x&quot;, &quot;type&quot;, etc</span>
<span class="c1"># type = 0 = vector of ints</span>
<span class="c1"># 1 = array of ints</span>
<span class="c1"># 2 = vector of doubles</span>
<span class="c1"># 3 = array of doubles</span>
</pre></div>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">eng</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">extract_compute</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span><span class="n">style</span><span class="p">,</span><span class="nb">type</span><span class="p">)</span> <span class="c1"># extract value(s) from a compute</span>
<span class="n">v3</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">extract_fix</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span><span class="n">style</span><span class="p">,</span><span class="nb">type</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">)</span> <span class="c1"># extract value(s) from a fix</span>
<span class="c1"># id = ID of compute or fix</span>
<span class="c1"># style = 0 = global data</span>
<span class="c1"># 1 = per-atom data</span>
<span class="c1"># 2 = local data</span>
<span class="c1"># type = 0 = scalar</span>
<span class="c1"># 1 = vector</span>
<span class="c1"># 2 = array</span>
<span class="c1"># i,j = indices of value in global vector or array</span>
</pre></div>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">var</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">extract_variable</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="n">group</span><span class="p">,</span><span class="n">flag</span><span class="p">)</span> <span class="c1"># extract value(s) from a variable</span>
<span class="c1"># name = name of variable</span>
<span class="c1"># group = group ID (ignored for equal-style variables)</span>
<span class="c1"># flag = 0 = equal-style variable</span>
<span class="c1"># 1 = atom-style variable</span>
</pre></div>
</div>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">flag</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">set_variable</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="n">value</span><span class="p">)</span> <span class="c1"># set existing named string-style variable to value, flag = 0 if successful</span>
<span class="n">natoms</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">get_natoms</span><span class="p">()</span> <span class="c1"># total # of atoms as int</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">gather_atoms</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="nb">type</span><span class="p">,</span><span class="n">count</span><span class="p">)</span> <span class="c1"># return atom attribute of all atoms gathered into data, ordered by atom ID</span>
<span class="c1"># name = &quot;x&quot;, &quot;charge&quot;, &quot;type&quot;, etc</span>
<span class="c1"># count = # of per-atom values, 1 or 3, etc</span>
<span class="n">lmp</span><span class="o">.</span><span class="n">scatter_atoms</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="nb">type</span><span class="p">,</span><span class="n">count</span><span class="p">,</span><span class="n">data</span><span class="p">)</span> <span class="c1"># scatter atom attribute of all atoms from data, ordered by atom ID</span>
<span class="c1"># name = &quot;x&quot;, &quot;charge&quot;, &quot;type&quot;, etc</span>
<span class="c1"># count = # of per-atom values, 1 or 3, etc</span>
</pre></div>
</div>
<hr class="docutils" />
<p>The lines</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
<span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
</pre></div>
</div>
<p>create an instance of LAMMPS, wrapped in a Python class by the lammps
Python module, and return an instance of the Python class as lmp. It
is used to make all subequent calls to the LAMMPS library.</p>
<p>Additional arguments can be used to tell Python the name of the shared
library to load or to pass arguments to the LAMMPS instance, the same
as if LAMMPS were launched from a command-line prompt.</p>
<p>If the ptr argument is set like this:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">lmp</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">(</span><span class="n">ptr</span><span class="o">=</span><span class="n">lmpptr</span><span class="p">)</span>
</pre></div>
</div>
<p>then lmpptr must be an argument passed to Python via the LAMMPS
<a class="reference internal" href="python.html"><span class="doc">python</span></a> command, when it is used to define a Python
function that is invoked by the LAMMPS input script. This mode of
using Python with LAMMPS is described above in 11.2. The variable
lmpptr refers to the instance of LAMMPS that called the embedded
Python interpreter. Using it as an argument to lammps() allows the
returned Python class instance &#8220;lmp&#8221; to make calls to that instance of
LAMMPS. See the <a class="reference internal" href="python.html"><span class="doc">python</span></a> command doc page for examples
using this syntax.</p>
<p>Note that you can create multiple LAMMPS objects in your Python
script, and coordinate and run multiple simulations, e.g.</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">lammps</span> <span class="k">import</span> <span class="n">lammps</span>
<span class="n">lmp1</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
<span class="n">lmp2</span> <span class="o">=</span> <span class="n">lammps</span><span class="p">()</span>
<span class="n">lmp1</span><span class="o">.</span><span class="n">file</span><span class="p">(</span><span class="s2">&quot;in.file1&quot;</span><span class="p">)</span>
<span class="n">lmp2</span><span class="o">.</span><span class="n">file</span><span class="p">(</span><span class="s2">&quot;in.file2&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>The file() and command() methods allow an input script or single
commands to be invoked.</p>
<p>The extract_global(), extract_atom(), extract_compute(),
extract_fix(), and extract_variable() methods return values or
pointers to data structures internal to LAMMPS.</p>
<p>For extract_global() see the src/library.cpp file for the list of
valid names. New names could easily be added. A double or integer is
returned. You need to specify the appropriate data type via the type
argument.</p>
<p>For extract_atom(), a pointer to internal LAMMPS atom-based data is
returned, which you can use via normal Python subscripting. See the
extract() method in the src/atom.cpp file for a list of valid names.
Again, new names could easily be added. A pointer to a vector of
doubles or integers, or a pointer to an array of doubles (double <a href="#id3"><span class="problematic" id="id4">**</span></a>)
or integers (int <a href="#id5"><span class="problematic" id="id6">**</span></a>) is returned. You need to specify the appropriate
data type via the type argument.</p>
<p>For extract_compute() and extract_fix(), the global, per-atom, or
local data calulated by the compute or fix can be accessed. What is
returned depends on whether the compute or fix calculates a scalar or
vector or array. For a scalar, a single double value is returned. If
the compute or fix calculates a vector or array, a pointer to the
internal LAMMPS data is returned, which you can use via normal Python
subscripting. The one exception is that for a fix that calculates a
global vector or array, a single double value from the vector or array
is returned, indexed by I (vector) or I and J (array). I,J are
zero-based indices. The I,J arguments can be left out if not needed.
See <a class="reference internal" href="Section_howto.html#howto-15"><span class="std std-ref">Section_howto 15</span></a> of the manual for a
discussion of global, per-atom, and local data, and of scalar, vector,
and array data types. See the doc pages for individual
<a class="reference internal" href="compute.html"><span class="doc">computes</span></a> and <a class="reference internal" href="fix.html"><span class="doc">fixes</span></a> for a description of what
they calculate and store.</p>
<p>For extract_variable(), an <a class="reference internal" href="variable.html"><span class="doc">equal-style or atom-style variable</span></a> is evaluated and its result returned.</p>
<p>For equal-style variables a single double value is returned and the
group argument is ignored. For atom-style variables, a vector of
doubles is returned, one value per atom, which you can use via normal
Python subscripting. The values will be zero for atoms not in the
specified group.</p>
<p>The get_natoms() method returns the total number of atoms in the
simulation, as an int.</p>
<p>The gather_atoms() method returns a ctypes vector of ints or doubles
as specified by type, of length count*natoms, for the property of all
the atoms in the simulation specified by name, ordered by count and
then by atom ID. The vector can be used via normal Python
subscripting. If atom IDs are not consecutively ordered within
LAMMPS, a None is returned as indication of an error.</p>
<p>Note that the data structure gather_atoms(&#8220;x&#8221;) returns is different
from the data structure returned by extract_atom(&#8220;x&#8221;) in four ways.
(1) Gather_atoms() returns a vector which you index as x[i];
extract_atom() returns an array which you index as x[i][j]. (2)
Gather_atoms() orders the atoms by atom ID while extract_atom() does
not. (3) Gathert_atoms() returns a list of all atoms in the
simulation; extract_atoms() returns just the atoms local to each
processor. (4) Finally, the gather_atoms() data structure is a copy
of the atom coords stored internally in LAMMPS, whereas extract_atom()
returns an array that effectively points directly to the internal
data. This means you can change values inside LAMMPS from Python by
assigning a new values to the extract_atom() array. To do this with
the gather_atoms() vector, you need to change values in the vector,
then invoke the scatter_atoms() method.</p>
<p>The scatter_atoms() method takes a vector of ints or doubles as
specified by type, of length count*natoms, for the property of all the
atoms in the simulation specified by name, ordered by bount and then
by atom ID. It uses the vector of data to overwrite the corresponding
properties for each atom inside LAMMPS. This requires LAMMPS to have
its &#8220;map&#8221; option enabled; see the <a class="reference internal" href="atom_modify.html"><span class="doc">atom_modify</span></a>
command for details. If it is not, or if atom IDs are not
consecutively ordered, no coordinates are reset.</p>
<p>The array of coordinates passed to scatter_atoms() must be a ctypes
vector of ints or doubles, allocated and initialized something like
this:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">ctypes</span> <span class="k">import</span> <span class="o">*</span>
<span class="n">natoms</span> <span class="o">=</span> <span class="n">lmp</span><span class="o">.</span><span class="n">get_natoms</span><span class="p">()</span>
<span class="n">n3</span> <span class="o">=</span> <span class="mi">3</span><span class="o">*</span><span class="n">natoms</span>
<span class="n">x</span> <span class="o">=</span> <span class="p">(</span><span class="n">n3</span><span class="o">*</span><span class="n">c_double</span><span class="p">)()</span>
<span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span> <span class="n">coord</span> <span class="n">of</span> <span class="n">atom</span> <span class="k">with</span> <span class="n">ID</span> <span class="mi">1</span>
<span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">y</span> <span class="n">coord</span> <span class="n">of</span> <span class="n">atom</span> <span class="k">with</span> <span class="n">ID</span> <span class="mi">1</span>
<span class="n">x</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">z</span> <span class="n">coord</span> <span class="n">of</span> <span class="n">atom</span> <span class="k">with</span> <span class="n">ID</span> <span class="mi">1</span>
<span class="n">x</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span> <span class="n">coord</span> <span class="n">of</span> <span class="n">atom</span> <span class="k">with</span> <span class="n">ID</span> <span class="mi">2</span>
<span class="o">...</span>
<span class="n">x</span><span class="p">[</span><span class="n">n3</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">z</span> <span class="n">coord</span> <span class="n">of</span> <span class="n">atom</span> <span class="k">with</span> <span class="n">ID</span> <span class="n">natoms</span>
<span class="n">lmp</span><span class="o">.</span><span class="n">scatter_coords</span><span class="p">(</span><span class="s2">&quot;x&quot;</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="n">x</span><span class="p">)</span>
</pre></div>
</div>
<p>Alternatively, you can just change values in the vector returned by
gather_atoms(&#8220;x&#8221;,1,3), since it is a ctypes vector of doubles.</p>
<hr class="docutils" />
<p>As noted above, these Python class methods correspond one-to-one with
the functions in the LAMMPS library interface in src/library.cpp and
library.h. This means you can extend the Python wrapper via the
following steps:</p>
<ul class="simple">
<li>Add a new interface function to src/library.cpp and
src/library.h.</li>
<li>Rebuild LAMMPS as a shared library.</li>
<li>Add a wrapper method to python/lammps.py for this interface
function.</li>
<li>You should now be able to invoke the new interface function from a
Python script. Isn&#8217;t ctypes amazing?</li>
</ul>
</div>
<div class="section" id="example-python-scripts-that-use-lammps">
<span id="py-8"></span><h2>11.8. Example Python scripts that use LAMMPS</h2>
<p>These are the Python scripts included as demos in the python/examples
directory of the LAMMPS distribution, to illustrate the kinds of
things that are possible when Python wraps LAMMPS. If you create your
own scripts, send them to us and we can include them in the LAMMPS
distribution.</p>
<table border="1" class="docutils">
<colgroup>
<col width="56%" />
<col width="44%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td>trivial.py</td>
<td>read/run a LAMMPS input script thru Python</td>
</tr>
<tr class="row-even"><td>demo.py</td>
<td>invoke various LAMMPS library interface routines</td>
</tr>
<tr class="row-odd"><td>simple.py</td>
<td>run in parallel</td>
</tr>
<tr class="row-even"><td>similar to examples/COUPLE/simple/simple.cpp</td>
<td>split.py</td>
</tr>
<tr class="row-odd"><td>same as simple.py but running in parallel on a subset of procs</td>
<td>gui.py</td>
</tr>
<tr class="row-even"><td>GUI go/stop/temperature-slider to control LAMMPS</td>
<td>plot.py</td>
</tr>
<tr class="row-odd"><td>real-time temeperature plot with GnuPlot via Pizza.py</td>
<td>viz_tool.py</td>
</tr>
<tr class="row-even"><td>real-time viz via some viz package</td>
<td>vizplotgui_tool.py</td>
</tr>
<tr class="row-odd"><td>combination of viz_tool.py and plot.py and gui.py</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<hr class="docutils" />
<p>For the viz_tool.py and vizplotgui_tool.py commands, replace &#8220;tool&#8221;
with &#8220;gl&#8221; or &#8220;atomeye&#8221; or &#8220;pymol&#8221; or &#8220;vmd&#8221;, depending on what
visualization package you have installed.</p>
<p>Note that for GL, you need to be able to run the Pizza.py GL tool,
which is included in the pizza sub-directory. See the <a class="reference external" href="http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py doc pages</a> for more info:</p>
<p>Note that for AtomEye, you need version 3, and there is a line in the
scripts that specifies the path and name of the executable. See the
AtomEye WWW pages <a class="reference external" href="http://mt.seas.upenn.edu/Archive/Graphics/A">here</a> or <a class="reference external" href="http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html">here</a> for more details:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">mt</span><span class="o">.</span><span class="n">seas</span><span class="o">.</span><span class="n">upenn</span><span class="o">.</span><span class="n">edu</span><span class="o">/</span><span class="n">Archive</span><span class="o">/</span><span class="n">Graphics</span><span class="o">/</span><span class="n">A</span>
<span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">mt</span><span class="o">.</span><span class="n">seas</span><span class="o">.</span><span class="n">upenn</span><span class="o">.</span><span class="n">edu</span><span class="o">/</span><span class="n">Archive</span><span class="o">/</span><span class="n">Graphics</span><span class="o">/</span><span class="n">A3</span><span class="o">/</span><span class="n">A3</span><span class="o">.</span><span class="n">html</span>
</pre></div>
</div>
<p>The latter link is to AtomEye 3 which has the scriping
capability needed by these Python scripts.</p>
<p>Note that for PyMol, you need to have built and installed the
open-source version of PyMol in your Python, so that you can import it
from a Python script. See the PyMol WWW pages <a class="reference external" href="http://www.pymol.org">here</a> or
<a class="reference external" href="http://sourceforge.net/scm/?type=svn&amp;group_id=4546">here</a> for more details:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>http://www.pymol.org
http://sourceforge.net/scm/?type=svn&amp;group_id=4546
</pre></div>
</div>
<p>The latter link is to the open-source version.</p>
<p>Note that for VMD, you need a fairly current version (1.8.7 works for
me) and there are some lines in the pizza/vmd.py script for 4 PIZZA
variables that have to match the VMD installation on your system.</p>
<hr class="docutils" />
<p>See the python/README file for instructions on how to run them and the
source code for individual scripts for comments about what they do.</p>
<p>Here are screenshots of the vizplotgui_tool.py script in action for
different visualization package options. Click to see larger images:</p>
<a class=""
data-lightbox="group-default"
href="_images/screenshot_gl.jpg"
title=""
data-title=""
><img src="_images/screenshot_gl.jpg"
class=""
width="25%"
height="auto"
alt=""/>
</a><a class=""
data-lightbox="group-default"
href="_images/screenshot_atomeye.jpg"
title=""
data-title=""
><img src="_images/screenshot_atomeye.jpg"
class=""
width="25%"
height="auto"
alt=""/>
</a><a class=""
data-lightbox="group-default"
href="_images/screenshot_pymol.jpg"
title=""
data-title=""
><img src="_images/screenshot_pymol.jpg"
class=""
width="25%"
height="auto"
alt=""/>
</a><a class=""
data-lightbox="group-default"
href="_images/screenshot_vmd.jpg"
title=""
data-title=""
><img src="_images/screenshot_vmd.jpg"
class=""
width="25%"
height="auto"
alt=""/>
</a></div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="Section_errors.html" class="btn btn-neutral float-right" title="12. Errors" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="Section_modify.html" class="btn btn-neutral" title="10. Modifying &amp; extending LAMMPS" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2013 Sandia Corporation.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/sphinxcontrib-images/LightBox2/lightbox2/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="_static/sphinxcontrib-images/LightBox2/lightbox2/js/lightbox.min.js"></script>
<script type="text/javascript" src="_static/sphinxcontrib-images/LightBox2/lightbox2-customize/jquery-noconflict.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
});
</script>
</body>
</html>