add more existing programmer guide docs

This commit is contained in:
Axel Kohlmeyer
2020-08-28 20:25:09 -04:00
parent 3be064748d
commit cb1a2601e1
12 changed files with 715 additions and 10 deletions

91
doc/src/pg_cplusplus.rst Normal file
View File

@ -0,0 +1,91 @@
Using the C++ API directly
**************************
Using the C++ classes of the LAMMPS library 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 and tighter
integration of LAMMPS into another code. While for the complete C
library API is provided in the ``library.h`` header file, for using
the C++ API it is required to include the individual header files
defining the individual classes in use. Typically the name of the
class and the name of the header follow some simple rule. Examples
are given below.
Creating or deleting a LAMMPS object
*************************************
When using the LAMMPS library interfaces, the core task is to create an
instance of the :cpp:class:`LAMMPS_NS::LAMMPS` class. In C++ this can
be done directly through the ``new`` operator. All further operations
are then initiated through calling member functions of some of the
components of the LAMMPS class or accessing their data members. The
destruction of the LAMMPS instance is correspondingly initiated by using
the ``delete`` operator. Here is a simple example:
.. code-block:: c++
#include "lammps.h"
#include "universe.h"
#include <mpi.h>
#include <iostream>
int main(int argc, char **argv)
{
LAMMPS_NS::LAMMPS *lmp;
// custom argument vector for LAMMPS library
const char *lmpargv[] {"liblammps", "-log", "none"};
int lmpargc = sizeof(lmpargv)/sizeof(const char *);
// explicitly initialize MPI
MPI_Init(&argc, &argv);
// create LAMMPS instance
lmp = new LAMMPS_NS::LAMMPS(lmpargc, (char **)lmpargv, MPI_COMM_WORLD);
// output numerical version string
std::cout << "LAMMPS version: " << lmp->universe->num_ver << std::endl;
// delete LAMMPS instance
delete lmp;
// stop MPI environment
MPI_Finalize();
return 0;
}
Please note that this requires to include the ``lammps.h`` header for accessing
the members of the LAMMPS class and then the ``universe.h`` header for accessing the ``num_ver`` member of the :cpp:class:`Universe` class.
Executing LAMMPS commands
*************************
Once a LAMMPS instance is created by your C++ code, you need to set up a
simulation and that is most conveniently done by "driving" it through
issuing commands like you would do when running a LAMMPS simulation from
an input script. Processing of input in LAMMPS is handled by the
:cpp:class:`Input <LAMMPS_NS::Input>` class an instance of which is a
member of the :cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class. You have
two options: reading commands from a file, or executing a single
command from a string. See below for a small example:
.. code-block:: c++
#include "lammps.h"
#include "input.h"
#include <mpi.h>
using namespace LAMMPS_NS;
int main(int argc, char **argv)
{
const char *lmpargv[] {"liblammps", "-log", "none"};
int lmpargc = sizeof(lmpargv)/sizeof(const char *);
MPI_Init(&argc, &argv);
LAMMPS *lmp = new LAMMPS(lmpargc, (char **)lmpargv, MPI_COMM_WORLD);
lmp->input->file("in.melt");
lmp->input->one("run 100 post no");
delete lmp;
return 0;
}

33
doc/src/pg_lib_add.rst Normal file
View File

@ -0,0 +1,33 @@
Adding code to the Library interface
====================================
The functionality of the LAMMPS library interface has historically
always been motivated by the needs of its users and functions were
added or expanded as they were needed and used. Contributions to
the interface are always welcome. However with a refactoring of
the library interface and its documentation that started in 2020,
there are now a few requirements for inclusion of changes.
- New functions should be orthogonal to existing ones and not
implement functionality that can already be achieved with the
existing APIs.
- All changes and additions should be documented with
`Doxygen <https://doxgygen.org>`_ style comments and references
to those functions added to the corresponding files in the
``doc/src`` folder.
- If possible, new unit tests to test those new features should
be added.
- The new feature should also be implemented and documented for
the Python and Fortran modules.
- All additions should work and be compatible with ``-DLAMMPS_BIGBIG``,
``-DLAMMPS_SMALLBIG``, ``-DLAMMPS_SMALLSMALL`` and compiling
with and without MPI support.
- The ``library.h`` file should be kept compatible to C code at
a level similar to C89. Its interfaces may not reference any
custom data types (e.g. ``bigint``, ``tagint``, and so on) only
known inside of LAMMPS.
- only C style comments, not C++ style
Please note, that these are *not* *strict* requirements, but the
LAMMPS developers appreciate if they are followed closely and will
assist with implementing what is missing.

67
doc/src/pg_lib_config.rst Normal file
View File

@ -0,0 +1,67 @@
Retrieving LAMMPS configuration information
===========================================
The following library functions can be used to query the
LAMMPS library about compile time settings and included
packages and styles.
-----------------------
.. doxygenfunction:: lammps_config_has_mpi_support
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_has_gzip_support
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_has_png_support
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_has_jpeg_support
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_has_ffmpeg_support
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_has_exceptions
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_has_package
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_package_count
:project: progguide
-----------------------
.. doxygenfunction:: lammps_config_package_name
:project: progguide
-----------------------
.. doxygenfunction:: lammps_has_style
:project: progguide
-----------------------
.. doxygenfunction:: lammps_style_count
:project: progguide
-----------------------
.. doxygenfunction:: lammps_style_name
:project: progguide

104
doc/src/pg_lib_create.rst Normal file
View File

@ -0,0 +1,104 @@
Creating or deleting a LAMMPS object
====================================
The :cpp:func:`lammps_open` and :cpp:func:`lammps_open_no_mpi`
functions are used to create and initialize a
:cpp:func:`LAMMPS` instance. The calling program has to
provide a handle where a reference to this instance can be stored and
which has to be used in all subsequent function calls until that
instance is destroyed by calling :cpp:func:`lammps_close`.
Here is a simple example demonstrating its use:
.. code-block:: C
#include "library.h"
#include <stdio.h>
int main(int argc, char **argv)
{
void *handle;
int version;
const char *lmpargv[] = { "liblammps", "-log", "none"};
int lmpargc = sizeof(lmpargv)/sizeof(const char *);
/* create LAMMPS instance */
handle = lammps_open_no_mpi(lmpargc, lmpargv, NULL);
if (handle == NULL) {
printf("LAMMPS initialization failed");
lammps_mpi_finalize();
return 1;
}
/* get and print numerical version code */
version = lammps_version(handle);
printf("LAMMPS Version: %d\n",version);
/* delete LAMMPS instance and shut down MPI */
lammps_close(handle);
lammps_mpi_finalize();
return 0;
}
The LAMMPS library will be using the MPI library it was compiled with
and will either run on all processors in the ``MPI_COMM_WORLD``
communicator or on the set of processors in the communicator given in
the ``comm`` argument of :cpp:func:`lammps_open`. This means
the calling code can run LAMMPS on all or a subset of processors. For
example, a wrapper code might decide to alternate between LAMMPS and
another code, allowing them both to run on all the processors. Or it
might allocate part of the processors to LAMMPS and the rest to the
other code by creating a custom communicator with ``MPI_Comm_split()``
and running both codes concurrently before syncing them up periodically.
Or it might instantiate multiple instances of LAMMPS to perform
different calculations and either alternate between them, run them
concurrently on split communicators, or run them one after the other.
The :cpp:func:`lammps_open` function may be called multiple
times for this latter purpose.
The :cpp:func:`lammps_close` function is used to shut down
the :cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class pointed to by the handle
passed as an argument and free all its memory. This has to be called for
every instance created with any of the :cpp:func:`lammps_open` functions. It will, however, **not** call
``MPI_Finalize()``, since that may only be called once. See
:cpp:func:`lammps_mpi_finalize` for an alternative to calling
``MPI_Finalize()`` explicitly in the calling program.
The :cpp:func:`lammps_free` function is a clean-up
function to free memory that the library allocated previously
via other function calls. See below for notes in the descriptions
of the individual commands where such memory buffers were allocated.
-----------------------
.. doxygenfunction:: lammps_open
:project: progguide
-----------------------
.. doxygenfunction:: lammps_open_no_mpi
:project: progguide
-----------------------
.. doxygenfunction:: lammps_open_fortran
:project: progguide
-----------------------
.. doxygenfunction:: lammps_close
:project: progguide
-----------------------
.. doxygenfunction:: lammps_mpi_init
:project: progguide
-----------------------
.. doxygenfunction:: lammps_mpi_finalize
:project: progguide
-----------------------
.. doxygenfunction:: lammps_free
:project: progguide

View File

@ -0,0 +1,69 @@
Executing LAMMPS commands
=========================
Once a LAMMPS instance is created, there are multiple ways to "drive" a
simulation. In most cases it is easiest to process single or multiple
LAMMPS commands like in an input file. This can be done through reading
a file or passing single commands or lists of commands or blocks of
commands with the following functions.
Via these functions, the calling code can have the LAMMPS instance act
on a series of :doc:`input file commands <Commands_all>` that are either
read from a file or passed as strings. This for, for example, allows to
setup a problem from a template file and then run it in stages while
performing other operations in between or concurrently. The caller can
interleave the LAMMPS function calls with operations it performs, calls
to extract information from or set information within LAMMPS, or calls
to another code's library.
Also equivalent to regular :doc:`input script parsing <Commands_parse>`
is the handling of comments and expansion of variables with ``${name}``
or ``$(expression)`` syntax before the commands are parsed and
executed. Below is a short example using some of these functions.
.. code-block:: C
#include "library.h"
#include <mpi.h>
#include <stdio.h>
int main(int argc, char **argv)
{
void *handle;
int i;
MPI_Init(&argc, &argv);
handle = lammps_open(0, NULL, MPI_COMM_WORLD, NULL);
lammps_file(handle,"in.sysinit");
lammps_command(handle,"run 1000 post no");
for (i=0; i < 100; ++i) {
lammps_commands_string(handle,"run 100 pre no post no\n"
"print 'PE = $(pe)'\n"
"print 'KE = $(ke)'\n");
}
lammps_close(handle);
MPI_Finalize();
return 0;
}
-----------------------
.. doxygenfunction:: lammps_file
:project: progguide
-----------------------
.. doxygenfunction:: lammps_command
:project: progguide
-----------------------
.. doxygenfunction:: lammps_commands_list
:project: progguide
-----------------------
.. doxygenfunction:: lammps_commands_string
:project: progguide

View File

@ -0,0 +1,30 @@
Accessing LAMMPS Neighbor lists
===============================
The following functions allow to access neighbor lists
generated by LAMMPS or query their properties.
-----------------------
.. doxygenfunction:: lammps_find_compute_neighlist
:project: progguide
-----------------------
.. doxygenfunction:: lammps_find_fix_neighlist
:project: progguide
-----------------------
.. doxygenfunction:: lammps_find_pair_neighlist
:project: progguide
-----------------------
.. doxygenfunction:: lammps_neighlist_num_elements
:project: progguide
-----------------------
.. doxygenfunction:: lammps_neighlist_element_neighbors
:project: progguide

View File

@ -0,0 +1,31 @@
Retrieving or setting properties of LAMMPS objects
==================================================
This section documents accessing or modifying data from objects like
computes, fixes, or variables in LAMMPS.
-----------------------
.. doxygenfunction:: lammps_extract_compute
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_fix
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_variable
:project: progguide
-----------------------
.. doxygenfunction:: lammps_set_variable
:project: progguide
-----------------------
.. doxygenenum:: _LMP_STYLE_CONST
.. doxygenenum:: _LMP_TYPE_CONST

View File

@ -0,0 +1,62 @@
Retrieving or setting LAMMPS system properties
==============================================
The library interface allows to extract different kinds of information
about the active simulation instance and also to modify some of them.
This allows to combine MD simulation steps with other processing and
simulation methods computed in the calling code or another code that is
coupled to LAMMPS via the library interface. In some cases the data
returned is direct reference to the original data inside LAMMPS cast
to a void pointer. In that case the data needs to be cast to a suitable
pointer to be able to access it, and you need to know the correct dimensions
and lengths. When accessing per-atom data, please note that this data
is the per-processor **local** data and indexed accordingly. These arrays
can change sizes and order at every neighbor list rebuild and atom sort
event as atoms are migrating between sub-domains.
-----------------------
.. doxygenfunction:: lammps_version
:project: progguide
-----------------------
.. doxygenfunction:: lammps_get_natoms
:project: progguide
-----------------------
.. doxygenfunction:: lammps_get_thermo
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_box
:project: progguide
-----------------------
.. doxygenfunction:: lammps_reset_box
:project: progguide
-------------------
.. doxygenfunction:: lammps_extract_setting
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_global
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_atom
:project: progguide
-----------------------
.. doxygenfunction:: lammps_create_atoms(void *handle, int n, int *id, int *type, double *x, double *v, int *image, int bexpand)
:project: progguide

View File

@ -0,0 +1,29 @@
Library functions for scatter/gather operations
================================================
.. TODO add description
-----------------------
.. doxygenfunction:: lammps_gather_atoms
:project: progguide
-----------------------
.. doxygenfunction:: lammps_gather_atoms_concat
:project: progguide
-----------------------
.. doxygenfunction:: lammps_gather_atoms_subset
:project: progguide
-----------------------
.. doxygenfunction:: lammps_scatter_atoms
:project: progguide
-----------------------
.. doxygenfunction:: lammps_scatter_atoms_subset
:project: progguide

View File

@ -0,0 +1,30 @@
Library interface utility functions
===================================
To simplify some of the tasks, the library interface contains
some utility functions that are not directly calling LAMMPS.
-----------------------
.. doxygenfunction:: lammps_encode_image_flags
:project: progguide
-----------------------
.. doxygenfunction:: lammps_decode_image_flags(int image, int *flags)
:project: progguide
-----------------------
.. doxygenfunction:: lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*)
:project: progguide
-----------------------
.. doxygenfunction:: lammps_has_error
:project: progguide
-----------------------
.. doxygenfunction:: lammps_get_last_error_message
:project: progguide

View File

@ -91,15 +91,15 @@ and consequently the function :cpp:func:`lammps_open` may not be used.
.. 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
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
--------------------
@ -153,6 +153,6 @@ The following links provide some examples and references to the C++ API.
.. toctree::
:maxdepth: 1
.. pg_cplusplus
pg_cplusplus

View File

@ -26,4 +26,163 @@ There are multiple Python interface classes in the :py:mod:`lammps` module:
.. _mpi4py_url: https://mpi4py.readthedocs.io
----------
Creating or deleting a LAMMPS object
************************************
With the Python interface the creation of a :cpp:class:`LAMMPS
<LAMMPS_NS::LAMMPS>` instance is included in the constructor for the
:py:func:`lammps <lammps.lammps>` class. Internally it will call either
:cpp:func:`lammps_open` or :cpp:func:`lammps_open_no_mpi` from the C
library API to create the class instance.
All arguments are optional. The *name* argument is to allow loading a
LAMMPS shared library that is named ``liblammps_machine.so`` instead of
the default name of ``liblammps.so``. In most cases the latter will be
installed or used. The *ptr* argument is for use of the
:py:mod:`lammps` module from inside a LAMMPS instance, e.g. with the
:doc:`python <python>` command, where a pointer to the already existing
:cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class instance can be passed
to the Python class and used instead of creating a new instance. The
*comm* argument may be used in combination with the `mpi4py <mpi4py_url_>`_
module to pass an MPI communicator to LAMMPS and thus it is possible
to run the Python module like the library interface on a subset of the
MPI ranks after splitting the communicator. Here is a simple example:
.. code-block:: python
from lammps import lammps
# NOTE: argv[0] is set by the Python module
args = ["-log", "none"]
# create LAMMPS instance
lmp = lammps(cmdargs=args)
# get and print numerical version code
print("LAMMPS Version: ", lmp.version())
# explicitly close and delete LAMMPS instance (optional)
lmp.close()
Same as with the :doc:`C library API <pg_lib_create>` this will use the
``MPI_COMM_WORLD`` communicator for the MPI library that LAMMPS was
compiled with. The :py:func:`lmp.close() <lammps.lammps.close>` call is
optional since the LAMMPS class instance will also be deleted
automatically during the :py:class:`lammps <lammps.lammps>` class
destructor.
Executing LAMMPS commands
*************************
Once an instance of the :py:class:`lammps <lammps.lammps>` class is
created, there are multiple ways to "feed" it commands. In a way that is
not very different from running a LAMMPS input script, except that
Python has many more facilities for structured programming than the
LAMMPS input script syntax. Furthermore it is possible to "compute"
what the next LAMMPS command should be. Same as in the equivalent `C
library functions <pg_lib_execute>`, commands can be read from a file, a
single string, a list of strings and a block of commands in a single
multi-line string. They are processed under the same boundary conditions
as the C library counterparts. The example below demonstrates the use
of :py:func:`lammps.file`, :py:func:`lammps.command`,
:py:func:`lammps.commands_list`, and :py:func:`lammps.commands_string`:
.. code-block:: python
from lammps import lammps
lmp = lammps()
# read commands from file 'in.melt'
lmp.file('in.melt')
# issue a single command
lmp.command('variable zpos index 1.0')
# create 10 groups with 10 atoms each
cmds = ["group g{} id {}:{}".format(i,10*i+1,10*(i+1)) for i in range(10)]
lmp.commands_list(cmds)
# run commands from a multi-line string
block = """
clear
region box block 0 2 0 2 0 2
create_box 1 box
create_atoms 1 single 1.0 1.0 ${zpos}
"""
lmp.commands_string(block)
----------
The ``lammps`` class API
************************
The :py:class:`lammps <lammps.lammps>` class is the core of the LAMMPS
Python interfaces. It is a wrapper around the :doc:`LAMMPS C library
API <pg_library>` using the `Python ctypes module
<https://docs.python.org/3/library/ctypes.html>`_ and a shared library
compiled from the LAMMPS sources code. The individual methods in this
class try to closely follow the corresponding C functions. The handle
argument that needs to be passed to the C functions is stored internally
in the class and automatically added when calling the C library
functions. Below is a detailed documentation of the API.
.. autoclass:: lammps.lammps
:members:
----------
The ``PyLammps`` class API
**************************
.. autoclass:: lammps.PyLammps
:members:
----------
The ``IPyLammps`` class API
***************************
.. autoclass:: lammps.IPyLammps
:members:
----------
Additional components of the ``lammps`` module
**********************************************
The :py:mod:`lammps` module additionally contains several constants
and the :py:class:`NeighList <lammps.NeighList>` class:
.. _py_data_constants:
.. py:data:: LAMMPS_INT, LAMMPS_DOUBLE, LAMMPS_BIGINT, LAMMPS_TAGINT, LAMMPS_STRING
:type: int
Constants in the :py:mod:`lammps` module to indicate how to
cast data when the C library function returns a void pointer.
Used in :py:func:`lammps.extract_global`.
.. _py_style_constants:
.. py:data:: LMP_STYLE_GLOBAL, LMP_STYLE_ATOM, LMP_STYLE_LOCAL
:type: int
Constants in the :py:mod:`lammps` module to select what style of data
to request from computes or fixes. See :cpp:enum:`_LMP_STYLE_CONST`
for the equivalent constants in the C library interface. Used in
:py:func:`lammps.extract_compute` and :py:func:`lammps.extract_fix`.
.. _py_type_constants:
.. py:data:: LMP_TYPE_SCALAR, LMP_TYLE_VECTOR, LMP_TYPE_ARRAY, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS
:type: int
Constants in the :py:mod:`lammps` module to select what type of data
to request from computes or fixes. See :cpp:enum:`_LMP_TYPE_CONST`
for the equivalent constants in the C library interface. Used in
:py:func:`lammps.extract_compute` and :py:func:`lammps.extract_fix`.
.. _py_var_constants:
.. py:data:: LMP_VAR_EQUAL, LMP_VAR_ATOM
:type: int
Constants in the :py:mod:`lammps` module to select what style of
variable to query when calling :py:func:`lammps.extract_variable`.
.. autoclass:: lammps.NeighList
:members:
:no-undoc-members: