diff --git a/doc/src/Howto_couple.rst b/doc/src/Howto_couple.rst index c652d4f599..2eadbb522e 100644 --- a/doc/src/Howto_couple.rst +++ b/doc/src/Howto_couple.rst @@ -12,96 +12,52 @@ LAMMPS can be coupled to other codes in at least 4 ways. Each has advantages and disadvantages, which you will have to think about in the context of your application. ----------- +1. Define a new :doc:`fix ` command that calls the other code. In + this scenario, LAMMPS is the driver code. During timestepping, + the fix is invoked, and can make library calls to the other code, + which has been linked to LAMMPS as a library. This is the way how the + :ref:`LATTE ` package, which performs density-functional + tight-binding calculations using the `LATTE software `_ + to compute forces, is hooked to LAMMPS. + See the :doc:`fix latte ` command for more details. + Also see the :doc:`Modify ` doc pages for info on how to + add a new fix to LAMMPS. -(1) Define a new :doc:`fix ` command that calls the other code. In -this scenario, LAMMPS is the driver code. During its timestepping, -the fix is invoked, and can make library calls to the other code, -which has been linked to LAMMPS as a library. This is the way the -`POEMS `_ package that performs constrained rigid-body motion on -groups of atoms is hooked to LAMMPS. See the :doc:`fix poems ` command for more details. See the -:doc:`Modify ` doc pages for info on how to add a new fix to -LAMMPS. +.. spacer -.. _poems: http://www.rpi.edu/~anderk5/lab +2. Define a new LAMMPS command that calls the other code. This is + conceptually similar to method (1), but in this case LAMMPS and the + other code are on a more equal footing. Note that now the other code + is not called during the timestepping of a LAMMPS run, but between + runs. The LAMMPS input script can be used to alternate LAMMPS runs + with calls to the other code, invoked via the new command. The + :doc:`run ` command facilitates this with its *every* option, + which makes it easy to run a few steps, invoke the command, run a few + steps, invoke the command, etc. ----------- + In this scenario, the other code can be called as a library, as in + 1., or it could be a stand-alone code, invoked by a system() call + made by the command (assuming your parallel machine allows one or + more processors to start up another program). In the latter case the + stand-alone code could communicate with LAMMPS through files that the + command writes and reads. -(2) Define a new LAMMPS command that calls the other code. This is -conceptually similar to method (1), but in this case LAMMPS and the -other code are on a more equal footing. Note that now the other code -is not called during the timestepping of a LAMMPS run, but between -runs. The LAMMPS input script can be used to alternate LAMMPS runs -with calls to the other code, invoked via the new command. The -:doc:`run ` command facilitates this with its *every* option, which -makes it easy to run a few steps, invoke the command, run a few steps, -invoke the command, etc. + See the :doc:`Modify command ` doc page for info on how + to add a new command to LAMMPS. -In this scenario, the other code can be called as a library, as in -(1), or it could be a stand-alone code, invoked by a system() call -made by the command (assuming your parallel machine allows one or more -processors to start up another program). In the latter case the -stand-alone code could communicate with LAMMPS through files that the -command writes and reads. +.. spacer -See the :doc:`Modify command ` doc page for info on how -to add a new command to LAMMPS. +3. Use LAMMPS as a library called by another code. In this case the + other code is the driver and calls LAMMPS as needed. Or a wrapper + code could link and call both LAMMPS and another code as libraries. + Again, the :doc:`run ` command has options that allow it to be + invoked with minimal overhead (no setup or clean-up) if you wish to + do multiple short runs, driven by another program. Details about + using the library interface are given in the :doc:`library API + ` documentation. ----------- +.. spacer -(3) Use LAMMPS as a library called by another code. In this case the -other code is the driver and calls LAMMPS as needed. Or a wrapper -code could link and call both LAMMPS and another code as libraries. -Again, the :doc:`run ` command has options that allow it to be -invoked with minimal overhead (no setup or clean-up) if you wish to do -multiple short runs, driven by another program. - -Examples of driver codes that call LAMMPS as a library are included in -the examples/COUPLE directory of the LAMMPS distribution; see -examples/COUPLE/README for more details: - -* simple: simple driver programs in C++ and C which invoke LAMMPS as a - library -* plugin: simple driver program in C which invokes LAMMPS as a plugin - from a shared library. -* lammps_quest: coupling of LAMMPS and `Quest `_, to run classical - MD with quantum forces calculated by a density functional code -* lammps_spparks: coupling of LAMMPS and `SPPARKS `_, to couple - a kinetic Monte Carlo model for grain growth using MD to calculate - strain induced across grain boundaries - -.. _quest: http://dft.sandia.gov/Quest - -.. _spparks: http://www.sandia.gov/~sjplimp/spparks.html - -The :doc:`Build basics ` doc page describes how to build -LAMMPS as a library. Once this is done, you can interface with LAMMPS -either via C++, C, Fortran, or Python (or any other language that -supports a vanilla C-like interface). For example, from C++ you could -create one (or more) "instances" of LAMMPS, pass it an input script to -process, or execute individual commands, all by invoking the correct -class methods in LAMMPS. From C or Fortran you can make function -calls to do the same things. See the :doc:`Python ` doc -pages for a description of the Python wrapper provided with LAMMPS -that operates through the LAMMPS library interface. - -The files src/library.cpp and library.h contain the C-style interface -to LAMMPS. See the :doc:`Howto library ` doc page for a -description of the interface and how to extend it for your needs. - -Note that the lammps_open() function that creates an instance of -LAMMPS takes an MPI communicator as an argument. This means that -instance of LAMMPS will run on the set of processors in the -communicator. Thus the calling code can run LAMMPS on all or a subset -of processors. For example, a wrapper script might decide to -alternate between LAMMPS and another code, allowing them both to run -on all the processors. Or it might allocate half the processors to -LAMMPS and half to the other code and run both codes simultaneously -before syncing them up periodically. Or it might instantiate multiple -instances of LAMMPS to perform different calculations. - ----------- - -(4) Couple LAMMPS with another code in a client/server mode. This is -described on the :doc:`Howto client/server ` doc -page. +4. Couple LAMMPS with another code in a client/server mode. This is + described on the :doc:`Howto client/server ` doc + page. diff --git a/doc/src/Howto_library.rst b/doc/src/Howto_library.rst index 774d9838c1..afa8dde941 100644 --- a/doc/src/Howto_library.rst +++ b/doc/src/Howto_library.rst @@ -2,241 +2,36 @@ Library interface to LAMMPS =========================== As described on the :doc:`Build basics ` doc page, LAMMPS -can be built as a library, so that it can be called by another code, -used in a :doc:`coupled manner ` with other codes, or -driven through a :doc:`Python interface `. +can be built as a static or shared library, so that it can be called by +another code, used in a :doc:`coupled manner ` with other +codes, or driven through a :doc:`Python interface `. -All of these methodologies use a C-style interface to LAMMPS that is -provided in the files src/library.cpp and src/library.h. The -functions therein have a C-style argument list, but contain C++ code -you could write yourself in a C++ application that was invoking LAMMPS -directly. The C++ code in the functions illustrates how to invoke -internal LAMMPS operations. Note that LAMMPS classes are defined -within a LAMMPS namespace (LAMMPS_NS) if you use them from another C++ -application. +At the core of LAMMPS is the ``LAMMPS`` class which encapsulates the +state of the simulation program through the state of the various class +instances that it is composed of. So a calculation using LAMMPS +requires to create an instance of the ``LAMMPS`` class and then send it +(text) commands, either individually or from a file, or perform other +operations that modify the state stored inside that instance or drive +simulations. This is essentially what the ``src/main.cpp`` file does +as well for the standalone LAMMPS executable with reading commands +either from an input file or stdin. -The examples/COUPLE and python/examples directories have example C++ -and C and Python codes which show how a driver code can link to LAMMPS -as a library, run LAMMPS on a subset of processors, grab data from -LAMMPS, change it, and put it back into LAMMPS. +Creating a LAMMPS instance can be done by using C++ code directly or +through a C-style interface library to LAMMPS that is provided in the +files ``src/library.cpp`` and ``library.h``. This +:ref:`C language API `, can be used from C and C++, +and is also the basis for the :doc:`Python ` and +:doc:`Fortran ` interfaces or wrappers included in the +LAMMPS source code. -Thread-safety -------------- +The ``examples/COUPLE`` and ``python/examples`` directories contain some +example programs written in C++, C, Fortran, and Python, which show how +a driver code can link to LAMMPS as a library, run LAMMPS on a subset of +processors (so the others are available to run some other code +concurrently), grab data from LAMMPS, change it, and send it back into +LAMMPS. -LAMMPS has not initially been conceived as a thread-safe program, but -over the years changes have been applied to replace operations that -collide with creating multiple LAMMPS instances from multiple-threads -of the same process with thread-safe alternatives. This primarily -applies to the core LAMMPS code and less so on add-on packages, especially -when those packages require additional code in the *lib* folder, -interface LAMMPS to Fortran libraries, or the code uses static variables -(like the USER-COLVARS package. +A detailed documentation of the available APIs and examples of how to +use them can be found in the :doc:`Programmer Documentation +` section of this manual. -Another major issue to deal with is to correctly handle MPI. Creating -a LAMMPS instance requires passing an MPI communicator, or it assumes -the MPI_COMM_WORLD communicator, which spans all MPI processor ranks. -When creating multiple LAMMPS object instances from different threads, -this communicator has to be different for each thread or else collisions -can happen, or it has to be guaranteed, that only one thread at a time -is active. MPI communicators, however, are not a problem, if LAMMPS is -compiled with the MPI STUBS library, which implies that there is no MPI -communication and only 1 MPI rank. - -Provided APIs -------------- - -The file src/library.cpp contains the following functions for creating -and destroying an instance of LAMMPS and sending it commands to -execute. See the documentation in the src/library.cpp file for -details. - -.. note:: - - You can write code for additional functions as needed to define - how your code talks to LAMMPS and add them to src/library.cpp and - src/library.h, as well as to the :doc:`Python interface `. - The added functions can access or change any internal LAMMPS data you - wish. - -.. code-block:: c - - void lammps_open(int, char **, MPI_Comm, void **) - void lammps_open_no_mpi(int, char **, void **) - void lammps_close(void *) - int lammps_version(void *) - void lammps_file(void *, char *) - char *lammps_command(void *, char *) - void lammps_commands_list(void *, int, char **) - void lammps_commands_string(void *, char *) - void lammps_free(void *) - -The lammps_open() function is used to initialize LAMMPS, passing in a -list of strings as if they were :doc:`command-line arguments ` when LAMMPS is run in stand-alone mode -from the command line, and a MPI communicator for LAMMPS to run under. -It returns a ptr to the LAMMPS object that is created, and which is -used in subsequent library calls. The lammps_open() function can be -called multiple times, to create multiple instances of LAMMPS. - -LAMMPS will run on the set of processors in the communicator. This -means the calling code can run LAMMPS on all or a subset of -processors. For example, a wrapper script might decide to alternate -between LAMMPS and another code, allowing them both to run on all the -processors. Or it might allocate half the processors to LAMMPS and -half to the other code and run both codes simultaneously before -syncing them up periodically. Or it might instantiate multiple -instances of LAMMPS to perform different calculations. - -The lammps_open_no_mpi() function is similar except that no MPI -communicator is passed from the caller. Instead, MPI_COMM_WORLD is -used to instantiate LAMMPS, and MPI is initialized if necessary. - -The lammps_close() function is used to shut down an instance of LAMMPS -and free all its memory. - -The lammps_version() function can be used to determined the specific -version of the underlying LAMMPS code. This is particularly useful -when loading LAMMPS as a shared library via dlopen(). The code using -the library interface can than use this information to adapt to -changes to the LAMMPS command syntax between versions. The returned -LAMMPS version code is an integer (e.g. 2 Sep 2015 results in -20150902) that grows with every new LAMMPS version. - -The lammps_file(), lammps_command(), lammps_commands_list(), and -lammps_commands_string() functions are used to pass one or more -commands to LAMMPS to execute, the same as if they were coming from an -input script. - -Via these functions, the calling code can read or generate a series of -LAMMPS commands one or multiple at a time and pass it through the library -interface to setup a problem and then run it in stages. The caller -can interleave the command function calls with operations it performs, -calls to extract information from or set information within LAMMPS, or -calls to another code's library. - -The lammps_file() function passes the filename of an input script. -The lammps_command() function passes a single command as a string. -The lammps_commands_list() function passes multiple commands in a -char\*\* list. In both lammps_command() and lammps_commands_list(), -individual commands may or may not have a trailing newline. The -lammps_commands_string() function passes multiple commands -concatenated into one long string, separated by newline characters. -In both lammps_commands_list() and lammps_commands_string(), a single -command can be spread across multiple lines, if the last printable -character of all but the last line is "&", the same as if the lines -appeared in an input script. - -The lammps_free() function is a clean-up function to free memory that -the library allocated previously via other function calls. See -comments in src/library.cpp file for which other functions need this -clean-up. - -The file src/library.cpp also contains these functions for extracting -information from LAMMPS and setting value within LAMMPS. Again, see -the documentation in the src/library.cpp file for details, including -which quantities can be queried by name: - -.. code-block:: c - - int lammps_extract_setting(void *, char *) - void *lammps_extract_global(void *, char *) - void lammps_extract_box(void *, double *, double *, - double *, double *, double *, int *, int *) - void *lammps_extract_atom(void *, char *) - void *lammps_extract_compute(void *, char *, int, int) - void *lammps_extract_fix(void *, char *, int, int, int, int) - void *lammps_extract_variable(void *, char *, char *) - -The extract_setting() function returns info on the size -of data types (e.g. 32-bit or 64-bit atom IDs) used -by the LAMMPS executable (a compile-time choice). - -The other extract functions return a pointer to various global or -per-atom quantities stored in LAMMPS or to values calculated by a -compute, fix, or variable. The pointer returned by the -extract_global() function can be used as a permanent reference to a -value which may change. For the extract_atom() method, see the -extract() method in the src/atom.cpp file for a list of valid per-atom -properties. New names could easily be added if the property you want -is not listed. For the other extract functions, the underlying -storage may be reallocated as LAMMPS runs, so you need to re-call the -function to assure a current pointer or returned value(s). - -.. code-block:: c - - double lammps_get_thermo(void *, char *) - int lammps_get_natoms(void *) - - int lammps_set_variable(void *, char *, char *) - void lammps_reset_box(void *, double *, double *, double, double, double) - -The lammps_get_thermo() function returns the current value of a thermo -keyword as a double precision value. - -The lammps_get_natoms() function returns the total number of atoms in -the system and can be used by the caller to allocate memory for the -lammps_gather_atoms() and lammps_scatter_atoms() functions. - -The lammps_set_variable() function can set an existing string-style -variable to a new string value, so that subsequent LAMMPS commands can -access the variable. - -The lammps_reset_box() function resets the size and shape of the -simulation box, e.g. as part of restoring a previously extracted and -saved state of a simulation. - -.. code-block:: c - - void lammps_gather_atoms(void *, char *, int, int, void *) - void lammps_gather_atoms_concat(void *, char *, int, int, void *) - void lammps_gather_atoms_subset(void *, char *, int, int, int, int *, void *) - void lammps_scatter_atoms(void *, char *, int, int, void *) - void lammps_scatter_atoms_subset(void *, char *, int, int, int, int *, void *) - -The gather functions collect peratom info of the requested type (atom -coords, atom types, forces, etc) from all processors, and returns the -same vector of values to each calling processor. The scatter -functions do the inverse. They distribute a vector of peratom values, -passed by all calling processors, to individual atoms, which may be -owned by different processors. - -.. warning:: - - These functions are not compatible with the - -DLAMMPS_BIGBIG setting when compiling LAMMPS. Dummy functions - that result in an error message and abort will be substituted - instead of resulting in random crashes and memory corruption. - -The lammps_gather_atoms() function does this for all N atoms in the -system, ordered by atom ID, from 1 to N. The -lammps_gather_atoms_concat() function does it for all N atoms, but -simply concatenates the subset of atoms owned by each processor. The -resulting vector is not ordered by atom ID. Atom IDs can be requested -by the same function if the caller needs to know the ordering. The -lammps_gather_subset() function allows the caller to request values -for only a subset of atoms (identified by ID). -For all 3 gather function, per-atom image flags can be retrieved in 2 ways. -If the count is specified as 1, they are returned -in a packed format with all three image flags stored in a single integer. -If the count is specified as 3, the values are unpacked into xyz flags -by the library before returning them. - -The lammps_scatter_atoms() function takes a list of values for all N -atoms in the system, ordered by atom ID, from 1 to N, and assigns -those values to each atom in the system. The -lammps_scatter_atoms_subset() function takes a subset of IDs as an -argument and only scatters those values to the owning atoms. - -.. code-block:: c - - void lammps_create_atoms(void *, int, tagint *, int *, double *, double *, - imageint *, int) - -The lammps_create_atoms() function takes a list of N atoms as input -with atom types and coords (required), an optionally atom IDs and -velocities and image flags. It uses the coords of each atom to assign -it as a new atom to the processor that owns it. This function is -useful to add atoms to a simulation or (in tandem with -lammps_reset_box()) to restore a previously extracted and saved state -of a simulation. Additional properties for the new atoms can then be -assigned via the lammps_scatter_atoms() or lammps_extract_atom() -functions. diff --git a/doc/src/Manual.rst b/doc/src/Manual.rst index b43e60208c..a0697e1381 100644 --- a/doc/src/Manual.rst +++ b/doc/src/Manual.rst @@ -67,8 +67,8 @@ every LAMMPS command. :name: progdoc :includehidden: + pg_library pg_developer -.. pg_library .. pg_modify .. pg_base diff --git a/doc/src/pg_fortran.rst b/doc/src/pg_fortran.rst new file mode 100644 index 0000000000..d028337b2c --- /dev/null +++ b/doc/src/pg_fortran.rst @@ -0,0 +1,23 @@ +The ``LIBLAMMPS`` Fortran Module +******************************** + +The ``LIBLAMMPS`` module provides an interface to call LAMMPS from a +Fortran code. It is based on the LAMMPS C-library interface and +requires a Fortran 2003 compatible compiler to be compiled. + +While C libraries have a defined binary interface (ABI) and can thus be +used from multiple compiler versions from different vendors for as long +as they are compatible with the hosting operating system, the same is +not true for Fortran codes. Thus the LAMMPS Fortran module needs to be +compiled alongside the code using it from the source code in +``examples/COUPLE/fortran/lammps.f90``. When linking, you also need to +:doc:`link to the LAMMPS library `. A typical command line +for a simple program using the Fortran interface would be: + +.. code-block:: bash + + mpifort -o testlib.x lammps.f90 testlib.f90 -L. -llammps + +Please note, that the MPI compiler wrapper is only required when the +calling the library from an MPI parallel code. + diff --git a/doc/src/pg_library.rst b/doc/src/pg_library.rst new file mode 100644 index 0000000000..3cd8d2196d --- /dev/null +++ b/doc/src/pg_library.rst @@ -0,0 +1,158 @@ +LAMMPS Library Interfaces +************************* + +As described on the :doc:`library interface to LAMMPS ` +doc page, LAMMPS can be built as a library (static or shared), so that +it can be called by another code, used in a :doc:`coupled manner +` with other codes, or driven through a :doc:`Python +script `. Even the LAMMPS standalone executable is +essentially a thin wrapper on top of the LAMMPS library, creating a +LAMMPS instance, processing input and then existing. + +Several of these approaches are based on C language wrapper functions +in the files ``src/library.h`` and ``src/library.cpp``, but it is also +possible to use C++ directly. The basic procedure is always the same: +you create one or more instances of the +:cpp:class:`LAMMPS ` and then pass commands as +strings or from files to that LAMMPS instance to execute calculations, +or read, manipulate, and update data from the active class instances +inside the LAMMPS to do analysis or perform operations that are not +possible with existing commands. + +.. _thread-safety: + +.. admonition:: Thread-safety + :class: note + + LAMMPS was initially not conceived as a thread-safe program, but over + the years changes have been applied to replace operations that + collide with creating multiple LAMMPS instances from multiple-threads + of the same process with thread-safe alternatives. This primarily + applies to the core LAMMPS code and less so on add-on packages, + especially when those packages require additional code in the *lib* + folder, interface LAMMPS to Fortran libraries, or the code uses + static variables (like the USER-COLVARS package). + + Another major issue to deal with is to correctly handle MPI. + Creating a LAMMPS instance requires passing an MPI communicator, or + it assumes the ``MPI_COMM_WORLD`` communicator, which spans all MPI + processor ranks. When creating multiple LAMMPS object instances from + different threads, this communicator has to be different for each + thread or else collisions can happen. or it has to be guaranteed, + that only one thread at a time is active. MPI communicators, + however, are not a problem, if LAMMPS is compiled with the MPI STUBS + library, which implies that there is no MPI communication and only 1 + MPI rank. + +---------- + +.. _lammps_c_api: + +LAMMPS C Library API +==================== + +The C library interface is most commonly used path to manage LAMMPS +instances from a compiled code and it is the basis for the :doc:`Python +` and :doc:`Fortran ` modules. Almost all +functions of the C language API require an argument containing a +"handle" in the form of a ``void *`` type variable, which points to the +location of a LAMMPS class instance. + +The ``library.h`` header file by default includes the ``mpi.h`` header +for an MPI library, so it must be present when compiling code using the +library interface. This usually must be the header from the same MPI +library as the LAMMPS library was compiled with. The exception is when +LAMMPS was compiled in serial mode using the ``STUBS`` MPI library. In +that case the calling code may be compiled with a different MPI library +for as long as :cpp:func:`lammps_open_no_mpi` is called to create a +LAMMPS instance. Then you may set the define ``-DLAMMPS_LIB_NO_MPI`` +when compiling your code and the inclusion of ``mpi.h`` will be skipped +and consequently the function :cpp:func:`lammps_open` may not be used. + +.. admonition:: Errors versus exceptions + :class: note + + If any of the function calls in the LAMMPS library API will trigger + an error inside LAMMPS, this will result in an abort of the entire + program. This is not always desirable. Instead, LAMMPS can be + compiled to instead :ref:`throw a C++ exception `. + +.. warning:: + + No checks are made on the arguments of the function calls of the C + library interface. *All* function arguments must be non-NULL unless + *explicitly* allowed and point to consistent and valid data. Buffers + for storing returned data must be allocated to a suitable size. + Passing invalid or unsuitable information will likely cause crashes + or corrupt data. + +------------------------------ + +.. toctree:: + :maxdepth: 1 + +.. pg_lib_create +.. pg_lib_execute +.. pg_lib_properties +.. pg_lib_objects +.. pg_lib_scatter +.. pg_lib_neighbor +.. pg_lib_config +.. pg_lib_utility +.. pg_lib_add + +-------------------- + +.. _lammps_python_api: + +LAMMPS Python APIs +================== + +The LAMMPS Python module enables calling the LAMMPS C library API from +Python by dynamically loading functions in the LAMMPS shared library through +the `Python ctypes module `_. +Because of the dynamics loading, it is **required** that LAMMPS is compiled +in :ref:`"shared" mode `. The Python interface is object oriented, but +otherwise trying to be very similar to the C library API. Three different +Python classes to run LAMMPS are available and they build on each other. + +.. toctree:: + :maxdepth: 1 + + pg_python + +------------------- + +.. _lammps_fortran_api: + +LAMMPS Fortran API +================== + +The LAMMPS Fortran module is a wrapper around calling functions from the +LAMMPS C library API from Fortran through the ISO_C_BINDING feature in +Fortran 2003. The interface is object oriented but otherwise trying to +be very similar to the C library API and the basic Python module. + +.. toctree:: + :maxdepth: 1 + + pg_fortran + +------------------- + +.. _lammps_cplusplus_api: + +LAMMPS C++ API +============== + +It is also possible to invoke the LAMMPS C++ API directly in your code. +It is lacking some of the convenience of the C library API, but it allows +a more direct access to simulation data and thus more low-level manipulations. +The following links provide some examples and references to the C++ API. + +.. toctree:: + :maxdepth: 1 + +.. pg_cplusplus + + diff --git a/doc/src/pg_python.rst b/doc/src/pg_python.rst new file mode 100644 index 0000000000..66f5c08cd0 --- /dev/null +++ b/doc/src/pg_python.rst @@ -0,0 +1,29 @@ +The ``lammps`` Python module +**************************** + +.. py:module:: lammps + +The LAMMPS Python interface is implemented as a module called +:py:mod:`lammps` in the ``lammps.py`` file in the ``python`` folder of +the LAMMPS source code distribution. After compilation of LAMMPS, the +module can be installed into a Python system folder or a user folder +with ``make install-python``. Components of the module can then loaded +into a Python session with the ``import`` command. + +There are multiple Python interface classes in the :py:mod:`lammps` module: + +- the :py:class:`lammps ` class. This is a wrapper around + the C-library interface and its member functions try to replicate the + :doc:`C-library API ` closely. This is the most + feature-complete Python API. +- the :py:class:`PyLammps ` class. This is a more high-level + and more Python style class implemented on top of the + :py:class:`lammps ` class. +- the :py:class:`IPyLammps ` class is derived from + :py:class:`PyLammps ` and adds embedded graphics + features to conveniently include LAMMPS into `Jupyter + `_ notebooks. + +.. _mpi4py_url: https://mpi4py.readthedocs.io + +