diff --git a/doc/src/pg_cplusplus.rst b/doc/src/pg_cplusplus.rst new file mode 100644 index 0000000000..2a7028b0f8 --- /dev/null +++ b/doc/src/pg_cplusplus.rst @@ -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 + #include + + 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 ` class an instance of which is a +member of the :cpp:class:`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 + + 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; + } diff --git a/doc/src/pg_lib_add.rst b/doc/src/pg_lib_add.rst new file mode 100644 index 0000000000..139476c683 --- /dev/null +++ b/doc/src/pg_lib_add.rst @@ -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 `_ 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. diff --git a/doc/src/pg_lib_config.rst b/doc/src/pg_lib_config.rst new file mode 100644 index 0000000000..9576e31dcd --- /dev/null +++ b/doc/src/pg_lib_config.rst @@ -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 + diff --git a/doc/src/pg_lib_create.rst b/doc/src/pg_lib_create.rst new file mode 100644 index 0000000000..f8a8fb7829 --- /dev/null +++ b/doc/src/pg_lib_create.rst @@ -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 + + 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 ` 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 diff --git a/doc/src/pg_lib_execute.rst b/doc/src/pg_lib_execute.rst new file mode 100644 index 0000000000..3e79cb3cb4 --- /dev/null +++ b/doc/src/pg_lib_execute.rst @@ -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 ` 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 ` +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 + #include + + 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 + diff --git a/doc/src/pg_lib_neighbor.rst b/doc/src/pg_lib_neighbor.rst new file mode 100644 index 0000000000..b004e85d0e --- /dev/null +++ b/doc/src/pg_lib_neighbor.rst @@ -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 diff --git a/doc/src/pg_lib_objects.rst b/doc/src/pg_lib_objects.rst new file mode 100644 index 0000000000..5da858db0c --- /dev/null +++ b/doc/src/pg_lib_objects.rst @@ -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 diff --git a/doc/src/pg_lib_properties.rst b/doc/src/pg_lib_properties.rst new file mode 100644 index 0000000000..789c7e2441 --- /dev/null +++ b/doc/src/pg_lib_properties.rst @@ -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 + + diff --git a/doc/src/pg_lib_scatter.rst b/doc/src/pg_lib_scatter.rst new file mode 100644 index 0000000000..5865d22349 --- /dev/null +++ b/doc/src/pg_lib_scatter.rst @@ -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 diff --git a/doc/src/pg_lib_utility.rst b/doc/src/pg_lib_utility.rst new file mode 100644 index 0000000000..8eda4e4988 --- /dev/null +++ b/doc/src/pg_lib_utility.rst @@ -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 diff --git a/doc/src/pg_library.rst b/doc/src/pg_library.rst index 3cd8d2196d..871ac5aaa5 100644 --- a/doc/src/pg_library.rst +++ b/doc/src/pg_library.rst @@ -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 diff --git a/doc/src/pg_python.rst b/doc/src/pg_python.rst index 66f5c08cd0..72d07c5983 100644 --- a/doc/src/pg_python.rst +++ b/doc/src/pg_python.rst @@ -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 +` instance is included in the constructor for the +:py:func:`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 ` command, where a pointer to the already existing +:cpp:class:`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 `_ +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 ` this will use the +``MPI_COMM_WORLD`` communicator for the MPI library that LAMMPS was +compiled with. The :py:func:`lmp.close() ` call is +optional since the LAMMPS class instance will also be deleted +automatically during the :py:class:`lammps ` class +destructor. + +Executing LAMMPS commands +************************* + +Once an instance of the :py:class:`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 `, 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 ` class is the core of the LAMMPS +Python interfaces. It is a wrapper around the :doc:`LAMMPS C library +API ` using the `Python ctypes module +`_ 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 ` 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: