From 093573b3d1fa30f02541a091d3d1d31a9e246af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 18 Jul 2023 22:49:51 -0600 Subject: [PATCH 1/5] Add a first version of a new sphinx based documentation --- docs/Makefile | 2 +- docs/_static/default.css | 27 ---- docs/_static/theme_extra.css | 66 ---------- docs/make.bat | 8 +- docs/requirements.txt | 1 - docs/source/conf.py | 81 ++---------- docs/source/development.md | 6 + docs/source/index.rst | 43 +++++- docs/source/installation.md | 26 ++++ docs/source/interfaces.md | 247 +++++++++++++++++++++++++++++++++++ docs/source/modules.rst | 7 - docs/source/pylammpsmpi.rst | 30 ----- 12 files changed, 338 insertions(+), 206 deletions(-) delete mode 100644 docs/_static/default.css delete mode 100644 docs/_static/theme_extra.css delete mode 100644 docs/requirements.txt create mode 100644 docs/source/development.md create mode 100644 docs/source/installation.md create mode 100644 docs/source/interfaces.md delete mode 100644 docs/source/modules.rst delete mode 100644 docs/source/pylammpsmpi.rst diff --git a/docs/Makefile b/docs/Makefile index d0c3cbf1..269cadcf 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/_static/default.css b/docs/_static/default.css deleted file mode 100644 index 0dd49b5a..00000000 --- a/docs/_static/default.css +++ /dev/null @@ -1,27 +0,0 @@ - - -/* main styles */ - -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 100%; - color: {{ theme_textcolor }}; - margin: 0; - padding: 0; - line-height: 135%; -} - -a { - color: #3498db; - text-decoration: none; -} - -a:visited { - color: #9b59b6; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - diff --git a/docs/_static/theme_extra.css b/docs/_static/theme_extra.css deleted file mode 100644 index f72bdea5..00000000 --- a/docs/_static/theme_extra.css +++ /dev/null @@ -1,66 +0,0 @@ -.wy-side-nav-search, .wy-nav-top { -background: #FCFCFC; -} -.wy-nav-side { -background: #FCFCFC; -} -.rst-versions .rst-current-version { -background: #FCFCFC; -} - -body { - color: #263238; -} - -h1 { - color: #455A64; -} - -h2 { - color: #455A64; -} - -h3 { - color: #455A64; -} - -h4 { - color: #455A64; -} - -a:link { - color: #21618C; -} - -/* visited link */ -a:visited { - color: #633974; -} - -/* mouse over link */ -a:hover { - text-decoration: underline; -} - -/* selected link */ -a:active { - color: blue; -} - -p { - font-family: "Verdana", Verdana, sans-serif; -} - -li a, h1, h2, h3, h4 { - font-family: "Verdana", Verdana, sans-serif; -} - -li a:hover { - background-color: #B0BEC5; - color: #263238; -} - -li a:hover:not(.active) { - background-color: #B0BEC5; - color: #263238; -} diff --git a/docs/make.bat b/docs/make.bat index 6247f7e2..6b9288be 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -10,8 +10,6 @@ if "%SPHINXBUILD%" == "" ( set SOURCEDIR=source set BUILDDIR=build -if "%1" == "" goto help - %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. @@ -21,10 +19,12 @@ if errorlevel 9009 ( echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ + echo.https://www.sphinx-doc.org/ exit /b 1 ) +if "%1" == "" goto help + %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end @@ -32,4 +32,4 @@ goto end %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end -popd +popd \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 483a4e96..00000000 --- a/docs/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -sphinx_rtd_theme diff --git a/docs/source/conf.py b/docs/source/conf.py index 9fb2f482..11c11c35 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,87 +1,34 @@ # Configuration file for the Sphinx documentation builder. # -# This file only contains a selection of the most common options. For a full -# list see the documentation: +# For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -import sphinx_rtd_theme - -sys.path.insert(0, os.path.abspath('../../')) - # -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = 'pylammpsmpi' +project = 'pympipool' copyright = '2020, Jan Janssen, Sarath Menon' author = 'Jan Janssen, Sarath Menon' -# The full version, including alpha/beta/rc tags -release = '0.0.1' - - # -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', - 'sphinx.ext.viewcode', - 'sphinx.ext.githubpages', - 'sphinx.ext.napoleon', - 'sphinx_rtd_theme', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['../_templates'] +extensions = ["myst_parser", 'sphinx.ext.autodoc', 'sphinx.ext.napoleon'] -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. +templates_path = ['_templates'] exclude_patterns = [] -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' -#html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -html_logo = "../_static/pyiron_logo.png" -html_theme_options = { - 'logo_only' : True, - 'canonical_url' : 'https://pylammpsmpi.readthedocs.io/', -} - -html_extra_path = ['../_static'] - -source_suffix = '.rst' +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -# The master toctree document. -master_doc = 'index' -pygments_style = None +html_theme = 'alabaster' +html_static_path = ['_static'] -html_static_path = ['../_static'] -def setup(app): - app.add_stylesheet("theme_extra.css") -latex_documents = [ - (master_doc, 'pylammpsmpi.tex', u'pylammpsmpi Documentation', - u'Sarath Menon, Jan Janssen', 'manual'), -] +# -- Generate API documentation ---------------------------------------------- +# https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html -man_pages = [ - (master_doc, 'pylammpsmpi', u'pylammpsmpi Documentation', - [author], 1) -] +from sphinx.ext.apidoc import main +main(['-e', '-o', 'apidoc', '../../pympipool/', '--force']) \ No newline at end of file diff --git a/docs/source/development.md b/docs/source/development.md new file mode 100644 index 00000000..7e9082ad --- /dev/null +++ b/docs/source/development.md @@ -0,0 +1,6 @@ +# Development +The `pylammpsmpi` package was developed to prototype improvements for the LAMMPS python library interface. In particular, +it is designed to simplify the development of `mpi4py` parallel LAMMPS workflows. The primary goal of these developments +is to demonstrate the viability of these new concepts and encourage the integration in the official LAMMPS distribution. + +Any feedback and contributions are welcome. \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 38a728db..d25ca705 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,9 +3,46 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to pylammpsmpi's documentation! -======================================= +Parallel Lammps Python interface +================================ +With :code:`pylammpsmpi` you can control a :code:`mpi4py` parallel LAMMPS instance from a serial python process or a +Jupyter notebook. Internally :code:`pylammpsmpi` leverages the :code:`pympipool` communication interface to connect the +serial python process the user interacts with, with the :code:`mpi4py` parallel LAMMPS instance. The advantage of +separating the :code:`mpi4py` parallel LAMMPS instance from the rest of the workflow is that the workflow can be written +as serial python code, while still benefiting from the parallel performance of LAMMPS. Still this comes at the cost of +additional data transfer, as the LAMMPS pointers cannot be transferred this way and the linked data has to be copied +instead. So copying large atomistic structures can decrease the performance of the :code:`pylammpsmpi` interface in +comparison to writing your own fully :code:`mpi4py` parallel LAMMPS workflows. + +Interfaces +---------- +The :code:`pylammpsmpi` module implements three different interfaces for different use cases: + +* :code:`pylammpsmpi.LammpsBase`: The most basic interface is the :code:`LammpsBase`, it implements the same commands + like the default :code:`lammps.lammps` interface and returns the same datatypes. With this API compatibility to the + standard interface, this interface is commonly the easiest way to accelerate a serial LAMMPS based workflow by + leveraging :code:`mpi4py` parallel LAMMPS instances. +* :code:`pylammpsmpi.LammpsConcurrent`: Inspired by the :code:`concurrent.futures` module in the standard python library + the :code:`pylammpsmpi.LammpsConcurrent` interface implements the same API as the :code:`pylammpsmpi.LammpsBase` class + but rather than holding the controlling process until the :code:`mpi4py` parallel LAMMPS instance finishes the + execution of a given set of commands, the :code:`pylammpsmpi.LammpsConcurrent` interface returns a + :code:`concurrent.futures.Future` object. This enables the development of asynchronous / concurrent workflows. +* :code:`pylammpsmpi.LammpsLibrary`: Finally, the :code:`pylammpsmpi.LammpsLibrary` interface adds a higher level + interface on top of the default :code:`lammps.lammps` interface. This higher level interface provides direct access to + the commands and thermodynamic properties used in the LAMMPS input files. Especially for experienced LAMMPS users who + are familiar with the LAMMPS input files this interface simplifies switching from file based input to using the python + interface. + +The choice of interface depends on the users background, experience and the simulation protocol the user wants to +implement. Still internally all three interfaces are based on the :code:`pylammpsmpi.LammpsConcurrent` interface, so +they use an additional thread to connect the :code:`mpi4py` parallel LAMMPS instance to the serial python process or +Jupyter notebook. + +Documentation +------------- .. toctree:: - modules + installation + interfaces + development \ No newline at end of file diff --git a/docs/source/installation.md b/docs/source/installation.md new file mode 100644 index 00000000..bb78a557 --- /dev/null +++ b/docs/source/installation.md @@ -0,0 +1,26 @@ +# Installation +The `pylammpsmpi` package can be installed either via `pip` or `conda`. While the package itself is written in pure +python and is therefore operation system independent, compiling the LAMMPS simulation code as library can be challenging +in particular on Windows. To simplify the installation for Mac OS and Linux users, the LAMMPS simulation code is +provided as `conda-forge` package. Consequently, the conda-based installation is recommended for `pylammpsmpi`. + +## conda-based installation +The `conda` package combines all dependencies in one package including the LAMMPS simulation code: +``` +conda install -c conda-forge pylammpsmpi +``` +When resolving the dependencies with `conda` gets slow it is recommended to use `mamba` instead of `conda`. So you can +also install `pylammpsmpi` using: +``` +mamba install -c conda-forge pylammpsmpi +``` + +## pypi-based installation +Alternatively, `pylammpsmpi` can also be installed from the python package index (pypi) using the following command: +``` +pip install pylammpsmpi +``` +This pypi package only contains the `pylammpsmpi` and the python dependencies it is build on, but it does not contain +the LAMMPS simulation code. This installation is recommended for advanced users who want to optimize their installation +for optimal performance, by compiling their own version of LAMMPS and `mpi4py` to match the MPI library on their +computer of high performance computing (HPC) cluster. diff --git a/docs/source/interfaces.md b/docs/source/interfaces.md new file mode 100644 index 00000000..9befbc86 --- /dev/null +++ b/docs/source/interfaces.md @@ -0,0 +1,247 @@ +# Interfaces +## LammpsBase +The most basic interface is the `LammpsBase`, it implements the same commands like the default `lammps.lammps` interface +and returns the same datatypes. With this API compatibility to the standard interface, this interface is commonly the +easiest way to accelerate a serial LAMMPS based workflow by leveraging `mpi4py` parallel LAMMPS instances. + +Import the `LammpsBase` class as: +```python +from pylammpsmpi import LammpsBase +``` + +Then an instance of this class can be instantiated using: +```python +lmp = LammpsBase( + cores=8, + oversubscribe=False, + enable_flux_backend=False, + working_directory=".", + cmdargs=None, + queue_adapter=None, + queue_adapter_kwargs=None, +) +``` +In this example the `mpi4py` parallel LAMMPS instances is set to be executed with 8 CPU cores `cores=8`. For OpenMPI +based installations of the LAMMPS library oversubscription can be enabled by the `oversubscribe` flag. In the same way +the `enable_flux_backend` flag enables the use of the flux framework as parallelization backend rather than using MPI +directly. This is primarily used in large allocation to distribute a number of tasks over the available resources. +Furthermore by providing a working directory `working_directory` the output of the LAMMPS simulation can be stored in +a predefined folder and with `cmdargs` additional command line arguments can be attached to the LAMMPS libary call. For +more information on the available command line arguments for the LAMMPS library, please refer to the official +documentation. In addition, the parameters `queue_adapter` and `queue_adapter_kwargs` provide an interface to +[pysqa](https://pysqa.readthedocs.org) the simple queue adapter for python. The `queue_adapter` can be set as +`pysqa.queueadapter.QueueAdapter` object and the `queue_adapter_kwargs` parameter represents a dictionary of input +arguments for the `submit_job()` function of the queue adapter. + +Read an input file named `in.simple` located in the `tests` folder of this repository: +```python +lmp.file("tests/in.simple") +``` + +In analogy to the `file()` function which executes a whole file with input commands the `command()` function can either +execute a single command provided as string: +```python +lmp.command("run 1") +``` + +Or alternatively execute a list of commands, when called with a list of strings as argument: +```python +lmp.command(["run 1", "run 1"]) +``` + +Other commands implemented by the `LammpsBase` class are: + +* `lmp.version`: to get the version of the LAMMPS library +* `lmp.extract_setting()`: to extract settings from the LAMMPS library +* `lmp.extract_global()`: to extract global variables from the LAMMPS library +* `lmp.extract_box()`: to extract the box size from the LAMMPS library +* `lmp.extract_atom()`: to extract an individual atom from the LAMMPS library +* `lmp.extract_fix()`: to extract a fix from the LAMMPS library +* `lmp.extract_variable()`: to extract a variable from the LAMMPS library +* `lmp.natoms`: to extract the total number of atoms from the LAMMPS library +* `lmp.get_natoms()`: to extract the total number of atoms from the LAMMPS library +* `lmp.set_variable()`: to set a variable for the LAMMPS library +* `lmp.reset_box()`: to reset the simulation box for the LAMMPS library +* `lmp.generate_atoms()`: to generate atoms inside the simulation box for the LAMMPS library +* `lmp.create_atoms()`: to create atoms inside the simulation box for the LAMMPS library +* `lmp.has_exceptions`: check if the LAMMPS library was compiled with the flag for exception handling +* `lmp.has_gzip_support`: check if the LAMMPS library was compiled with the flag for gzip compression +* `lmp.has_png_support`: check if the LAMMPS library was compiled with the flag for png graphics output +* `lmp.has_jpeg_support`: check if the LAMMPS library was compiled with the flag for jpeg graphics output +* `lmp.has_ffmpeg_support`: check if the LAMMPS library was compiled with the flag for ffmepg video output +* `lmp.installed_packages`: list packages installed in the LAMMPS library +* `lmp.set_fix_external_callback()`: set fix for external call back for the LAMMPS library +* `lmp.get_neighlist()`: get the neighbor list from the LAMMPS library +* `lmp.find_pair_neighlist()`: get the neighbor list pairs from LAMMPS library +* `lmp.find_fix_neighlist()`: find the list index of the fix neighbor list from the LAMMPS library +* `lmp.find_compute_neighlist()`: find the list index of the compute neighbor list from the LAMMPS library +* `lmp.get_neighlist_size()`: get the size of the neighbor list from the LAMMPS libary +* `lmp.get_neighlist_element_neighbors()`: get the neighbors of one specific element of the neighbor list from the + LAMMPS library. +* `lmp.gather_atoms()`: Gather information of the atoms from the LAMMPS library +* `lmp.scatter_atoms()`: Scatter information of the atoms to the LAMMPS library +* `lmp.get_thermo()`: Get a thermo entry from the LAMMPS library +* `lmp.extract_compute()`: Extract a compute from the LAMMPS library + +For more details about the individual commands of the `LammpsBase` class please refer to the LAMMPS python library +documentation. + +## LammpsConcurrent +Inspired by the `concurrent.futures` module in the standard python library the `pylammpsmpi.LammpsConcurrent` interface +implements the same API as the `pylammpsmpi.LammpsBase` class but rather than holding the controlling process until the +`mpi4py` parallel LAMMPS instance finishes the execution of a given set of commands, the `pylammpsmpi.LammpsConcurrent` +interface returns a `concurrent.futures.Future` object. This enables the development of asynchronous / concurrent +workflows. + +Import the `LammpsConcurrent` class as: +```python +from pylammpsmpi import LammpsConcurrent +``` + +Then an instance of this class can be instantiated using: +```python +lmp = LammpsConcurrent( + cores=8, + oversubscribe=False, + enable_flux_backend=False, + working_directory=".", + cmdargs=None, + queue_adapter=None, + queue_adapter_kwargs=None, +) +``` +In this example the `mpi4py` parallel LAMMPS instances is set to be executed with 8 CPU cores `cores=8`. For OpenMPI +based installations of the LAMMPS library oversubscription can be enabled by the `oversubscribe` flag. In the same way +the `enable_flux_backend` flag enables the use of the flux framework as parallelization backend rather than using MPI +directly. This is primarily used in large allocation to distribute a number of tasks over the available resources. +Furthermore by providing a working directory `working_directory` the output of the LAMMPS simulation can be stored in +a predefined folder and with `cmdargs` additional command line arguments can be attached to the LAMMPS libary call. For +more information on the available command line arguments for the LAMMPS library, please refer to the official +documentation. In addition, the parameters `queue_adapter` and `queue_adapter_kwargs` provide an interface to +[pysqa](https://pysqa.readthedocs.org) the simple queue adapter for python. The `queue_adapter` can be set as +`pysqa.queueadapter.QueueAdapter` object and the `queue_adapter_kwargs` parameter represents a dictionary of input +arguments for the `submit_job()` function of the queue adapter. + +Read an input file named `in.simple` located in the `tests` folder of this repository: +```python +fs = lmp.file("tests/in.simple") +fs.result() + +>>> True +``` +In contrast to the `LammpsBase` instance the `file()` function as well as any other function returns a +`concurrent.futures.Future` object. The status object can be checked with the `done()` function. Alternatively the +main process controlling the `mpi4py` parallel LAMMPS instances can be hold until the execution is completed using the +`result()` function. If the underlying LAMMPS library does not return any output then the `LammpsConcurrent` class +returns `True` to indicate the execution finished successful. + +In analogy to the `file()` function which executes a whole file with input commands the `command()` function can either +execute a single command provided as string: +```python +fs = lmp.command("run 1") +fs.result() + +>>> True +``` + +Or alternatively execute a list of commands, when called with a list of strings as argument: +```python +fs = lmp.command(["run 1", "run 1"]) +fs.result() + +>>> True +``` +Again in both cases the `command()` function returns again a `concurrent.futures.Future` object to track the status of +the execution and continue interacting with the main process while the corresponding commands are executed in the +`mpi4py` parallel LAMMPS instance. + +Other commands implemented by the `LammpsConcurrent` class are: + +* `lmp.version`: to get the version of the LAMMPS library +* `lmp.extract_setting()`: to extract settings from the LAMMPS library +* `lmp.extract_global()`: to extract global variables from the LAMMPS library +* `lmp.extract_box()`: to extract the box size from the LAMMPS library +* `lmp.extract_atom()`: to extract an individual atom from the LAMMPS library +* `lmp.extract_fix()`: to extract a fix from the LAMMPS library +* `lmp.extract_variable()`: to extract a variable from the LAMMPS library +* `lmp.natoms`: to extract the total number of atoms from the LAMMPS library +* `lmp.get_natoms()`: to extract the total number of atoms from the LAMMPS library +* `lmp.set_variable()`: to set a variable for the LAMMPS library +* `lmp.reset_box()`: to reset the simulation box for the LAMMPS library +* `lmp.generate_atoms()`: to generate atoms inside the simulation box for the LAMMPS library +* `lmp.create_atoms()`: to create atoms inside the simulation box for the LAMMPS library +* `lmp.has_exceptions`: check if the LAMMPS library was compiled with the flag for exception handling +* `lmp.has_gzip_support`: check if the LAMMPS library was compiled with the flag for gzip compression +* `lmp.has_png_support`: check if the LAMMPS library was compiled with the flag for png graphics output +* `lmp.has_jpeg_support`: check if the LAMMPS library was compiled with the flag for jpeg graphics output +* `lmp.has_ffmpeg_support`: check if the LAMMPS library was compiled with the flag for ffmepg video output +* `lmp.installed_packages`: list packages installed in the LAMMPS library +* `lmp.set_fix_external_callback()`: set fix for external call back for the LAMMPS library +* `lmp.get_neighlist()`: get the neighbor list from the LAMMPS library +* `lmp.find_pair_neighlist()`: get the neighbor list pairs from LAMMPS library +* `lmp.find_fix_neighlist()`: find the list index of the fix neighbor list from the LAMMPS library +* `lmp.find_compute_neighlist()`: find the list index of the compute neighbor list from the LAMMPS library +* `lmp.get_neighlist_size()`: get the size of the neighbor list from the LAMMPS libary +* `lmp.get_neighlist_element_neighbors()`: get the neighbors of one specific element of the neighbor list from the + LAMMPS library. +* `lmp.gather_atoms()`: Gather information of the atoms from the LAMMPS library +* `lmp.scatter_atoms()`: Scatter information of the atoms to the LAMMPS library +* `lmp.get_thermo()`: Get a thermo entry from the LAMMPS library +* `lmp.extract_compute()`: Extract a compute from the LAMMPS library + +For more details about the individual commands of the `LammpsBase` class please refer to the LAMMPS python library +documentation. + +## LammpsLibrary +Finally, the :code:`pylammpsmpi.LammpsLibrary` interface adds a higher level interface on top of the default +`lammps.lammps` interface. This higher level interface provides direct access to the commands and thermodynamic +properties used in the LAMMPS input files. Especially for experienced LAMMPS users who are familiar with the LAMMPS +input files this interface simplifies switching from file based input to using the python interface. + +Import the `LammpsLibrary` class as: +```python +from pylammpsmpi import LammpsLibrary +``` + +Then an instance of this class can be instantiated using: +```python +lmp = LammpsLibrary( + cores=8, + oversubscribe=False, + enable_flux_backend=False, + working_directory=".", + cmdargs=None, + queue_adapter=None, + queue_adapter_kwargs=None, +) +``` +In this example the `mpi4py` parallel LAMMPS instances is set to be executed with 8 CPU cores `cores=8`. For OpenMPI +based installations of the LAMMPS library oversubscription can be enabled by the `oversubscribe` flag. In the same way +the `enable_flux_backend` flag enables the use of the flux framework as parallelization backend rather than using MPI +directly. This is primarily used in large allocation to distribute a number of tasks over the available resources. +Furthermore by providing a working directory `working_directory` the output of the LAMMPS simulation can be stored in +a predefined folder and with `cmdargs` additional command line arguments can be attached to the LAMMPS libary call. For +more information on the available command line arguments for the LAMMPS library, please refer to the official +documentation. In addition, the parameters `queue_adapter` and `queue_adapter_kwargs` provide an interface to +[pysqa](https://pysqa.readthedocs.org) the simple queue adapter for python. The `queue_adapter` can be set as +`pysqa.queueadapter.QueueAdapter` object and the `queue_adapter_kwargs` parameter represents a dictionary of input +arguments for the `submit_job()` function of the queue adapter. + +Read an input file named `in.simple` located in the `tests` folder of this repository: +```python +lmp.file("tests/in.simple") +``` + +In analogy to the `file()` function which executes a whole file with input commands the `command()` function can either +execute a single command provided as string: +```python +lmp.command("run 1") +``` + +Or alternatively execute a list of commands, when called with a list of strings as argument: +```python +lmp.command(["run 1", "run 1"]) +``` + +Beyond the commands defined in the `LammpsBase` class, the `LammpsLibrary` implements a wide range of commands commonly +used in the LAMMPS input files. \ No newline at end of file diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index c3405931..00000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -pylammpsmpi -=========== - -.. toctree:: - :maxdepth: 4 - - pylammpsmpi diff --git a/docs/source/pylammpsmpi.rst b/docs/source/pylammpsmpi.rst deleted file mode 100644 index 0c574e31..00000000 --- a/docs/source/pylammpsmpi.rst +++ /dev/null @@ -1,30 +0,0 @@ -pylammpsmpi package -=================== - -Submodules ----------- - -pylammpsmpi.commands module ---------------------------- - -.. automodule:: pylammpsmpi.commands - :members: - :undoc-members: - :show-inheritance: - -pylammpsmpi.lammps module -------------------------- - -.. automodule:: pylammpsmpi.lammps - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pylammpsmpi - :members: - :undoc-members: - :show-inheritance: From 19b94d55bc8b45e29cf4822c39dc40e2cf7692da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 18 Jul 2023 22:52:50 -0600 Subject: [PATCH 2/5] Add readthedocs config and conda environment for documentation --- .ci_support/environment-docs.yml | 6 ++++++ .readthedocs.yml | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 .ci_support/environment-docs.yml create mode 100644 .readthedocs.yml diff --git a/.ci_support/environment-docs.yml b/.ci_support/environment-docs.yml new file mode 100644 index 00000000..d6f27bb0 --- /dev/null +++ b/.ci_support/environment-docs.yml @@ -0,0 +1,6 @@ +channels: +- conda-forge +dependencies: + - nbsphinx + - sphinx + - myst-parser \ No newline at end of file diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..b4de3480 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,28 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +build: + os: "ubuntu-20.04" + tools: + python: "mambaforge-4.10" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +formats: [] + +# Install pyiron from conda +conda: + environment: .ci_support/environment-docs.yml + +# Optionally set the version of Python and requirements required to build your docs +python: + install: + - method: pip + path: . \ No newline at end of file From 560cefdde21de4c390c90190cb93828d3a96eaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 18 Jul 2023 22:57:50 -0600 Subject: [PATCH 3/5] extend environment --- .ci_support/environment-docs.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.ci_support/environment-docs.yml b/.ci_support/environment-docs.yml index d6f27bb0..53a98fe2 100644 --- a/.ci_support/environment-docs.yml +++ b/.ci_support/environment-docs.yml @@ -3,4 +3,7 @@ channels: dependencies: - nbsphinx - sphinx - - myst-parser \ No newline at end of file + - myst-parser + - numpy + - mpi4py + - pympipool \ No newline at end of file From 3fef7183cf686936d4dcca54da6a95bd471ed927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 18 Jul 2023 23:06:21 -0600 Subject: [PATCH 4/5] update readme --- README.md | 339 +++++++----------------------------------- docs/source/conf.py | 2 +- docs/source/index.rst | 4 +- 3 files changed, 54 insertions(+), 291 deletions(-) diff --git a/README.md b/README.md index 22f6984e..624523ec 100644 --- a/README.md +++ b/README.md @@ -1,291 +1,54 @@ -# `PyLammpsMPI` +# pylammpsmpi - Parallel Lammps Python interface [![Coverage Status](https://coveralls.io/repos/github/pyiron/pylammpsmpi/badge.svg)](https://coveralls.io/github/pyiron/pylammpsmpi) [![Python package](https://github.com/pyiron/pylammpsmpi/workflows/Python%20package/badge.svg)](https://github.com/pyiron/pylammpsmpi/actions) -## Install with pip - -```bash -pip install pylammpsmpi -``` - -## Example usage - -### Setting up a simulation - - -```python -from pylammpsmpi import LammpsLibrary -``` - -Set up a job which runs on 2 cores - - -```python -lmp = LammpsLibrary(cores=2) -``` - -Read an input file - - -```python -lmp.file("tests/in.simple") -``` - -Check version of lammps - - -```python -lmp.version -``` - - - - - 20190807 - - - -Check number of atoms - - -```python -lmp.natoms -``` - - - - - 256 - - - -### Run commands - - -```python -lmp.command("run 1") -``` - - -```python -lmp.command(["run 1", "run 1"]) -``` - -Commands can also be direct - - -```python -lmp.run(10) -``` - - -```python -lmp.mass(1, 20) -``` - -### Extract a global property - - -```python -lmp.extract_global("boxxhi") -``` - - - - - 6.718384765530029 - - - -### Access thermo quantities - - -```python -lmp.get_thermo("temp") -``` - - - - - array(1.12985322) - - - -Thermo quantities can also be accessed directly, - - -```python -lmp.temp -``` - - - - - array(1.12985322) - - - - -```python -lmp.press -``` - - - - - array(-2.60581752) - - - -### Accessing simulation box - - -```python -lmp.extract_box() -``` - - - - - ([0.0, 0.0, 0.0], - [6.718384765530029, 6.718384765530029, 6.718384765530029], - 0.0, - 0.0, - 0.0, - [1, 1, 1], - 0) - - - -### Accessing and changing atom properties - -Get individual atom properties, for example force on each atoms - - -```python -ff = lmp.gather_atoms("f") -print(type(ff)) -print(len(ff)) -``` - - - 256 - - -Get atom properties by their ids - - -```python -ids = lmp.gather_atoms("id") -``` - - -```python -ff = lmp.gather_atoms("f", ids=ids[:10]) -len(ff) -``` - - - - - 10 - - - -Change atom properties - - -```python -ff = ff*0.5 -lmp.scatter_atoms("f", ff, ids=ids[:10]) -``` - -### Access value of variables - - -```python -temp = lmp.extract_variable("tt", "all", 0) -temp -``` - - - - - 0.8846341461467611 - - - -### Access value of computes - - -```python -ke = lmp.extract_compute("ke", 1, 1) -len(ke) -``` - - - - - 256 - - - - -```python -v = lmp.extract_compute("v", 1, 2, width=3) -v.shape -``` - - - - - (256, 3) - - - - -```python -lmp.extract_compute("1", 0, 0) -``` - - - - - 0.8846341461467611 - - - - -```python -msd = lmp.extract_compute("msd", 0, 1, length=4) -msd[0] -``` - - - - - 0.005507481618069701 - - - -### Access values from fix - - -```python -x = lmp.extract_fix("2", 0, 1, 1) -x -``` - - - - - -2.605817524153117 - - - -### Change the simulation box - - -```python -lmp.reset_box([0.0,0.0,0.0], [8.0,8.0,8.0], 0.0,0.0,0.0) -``` +With `pylammpsmpi` you can control a `mpi4py` parallel LAMMPS instance from a serial python process or a Jupyter +notebook. Internally `pylammpsmpi` leverages the `pympipool` communication interface to connect the serial python +process the user interacts with, with the `mpi4py` parallel LAMMPS instance. The advantage of separating the `mpi4py` +parallel LAMMPS instance from the rest of the workflow is that the workflow can be written as serial python code, while +still benefiting from the parallel performance of LAMMPS. Still this comes at the cost of additional data transfer, as +the LAMMPS pointers cannot be transferred this way and the linked data has to be copied instead. So copying large +atomistic structures can decrease the performance of the `pylammpsmpi` interface in comparison to writing your own fully +`mpi4py` parallel LAMMPS workflows. + +# Interfaces +The `pylammpsmpi` module implements three different interfaces for different use cases: + +* `pylammpsmpi.LammpsBase`: The most basic interface is the `LammpsBase`, it implements the same commands like the + default `lammps.lammps` interface and returns the same datatypes. With this API compatibility to the standard + interface, this interface is commonly the easiest way to accelerate a serial LAMMPS based workflow by leveraging + `mpi4py` parallel LAMMPS instances. +* `pylammpsmpi.LammpsConcurrent`: Inspired by the `concurrent.futures` module in the standard python library the + `pylammpsmpi.LammpsConcurrent` interface implements the same API as the `pylammpsmpi.LammpsBase` class but rather than + holding the controlling process until the `mpi4py` parallel LAMMPS instance finishes the execution of a given set of + commands, the `pylammpsmpi.LammpsConcurrent` interface returns a `concurrent.futures.Future` object. This enables the + development of asynchronous / concurrent workflows. +* `pylammpsmpi.LammpsLibrary`: Finally, the `pylammpsmpi.LammpsLibrary` interface adds a higher level interface on top + of the default `lammps.lammps` interface. This higher level interface provides direct access to the commands and + thermodynamic properties used in the LAMMPS input files. Especially for experienced LAMMPS users who are familiar with + the LAMMPS input files this interface simplifies switching from file based input to using the python interface. + +The choice of interface depends on the users background, experience and the simulation protocol the user wants to +implement. Still internally all three interfaces are based on the `pylammpsmpi.LammpsConcurrent` interface, so they use +an additional thread to connect the `mpi4py` parallel LAMMPS instance to the serial python process or Jupyter notebook. + +# Documentation + + +# License +`pylammpsmpi` is released under the BSD license https://github.com/pyiron/pympipool/blob/main/LICENSE . It is a spin-off +of the `pyiron` project https://github.com/pyiron/pyiron therefore if you use `pylammpsmpi` for calculation which result +in a scientific publication, please cite: + + @article{pyiron-paper, + title = {pyiron: An integrated development environment for computational materials science}, + journal = {Computational Materials Science}, + volume = {163}, + pages = {24 - 36}, + year = {2019}, + issn = {0927-0256}, + doi = {https://doi.org/10.1016/j.commatsci.2018.07.043}, + url = {http://www.sciencedirect.com/science/article/pii/S0927025618304786}, + author = {Jan Janssen and Sudarsan Surendralal and Yury Lysogorskiy and Mira Todorova and Tilmann Hickel and Ralf Drautz and Jörg Neugebauer}, + keywords = {Modelling workflow, Integrated development environment, Complex simulation protocols}, + } diff --git a/docs/source/conf.py b/docs/source/conf.py index 11c11c35..ea85f21d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -31,4 +31,4 @@ # https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html from sphinx.ext.apidoc import main -main(['-e', '-o', 'apidoc', '../../pympipool/', '--force']) \ No newline at end of file +main(['-e', '-o', 'apidoc', '../../pylammpsmpi/', '--force']) \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index d25ca705..a6b9ba95 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Parallel Lammps Python interface -================================ +pylammpsmpi - Parallel Lammps Python interface +============================================== With :code:`pylammpsmpi` you can control a :code:`mpi4py` parallel LAMMPS instance from a serial python process or a Jupyter notebook. Internally :code:`pylammpsmpi` leverages the :code:`pympipool` communication interface to connect the serial python process the user interacts with, with the :code:`mpi4py` parallel LAMMPS instance. The advantage of From 3b44ba9fe9639ca7d05faea997e3f9733ea8eed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 18 Jul 2023 23:13:22 -0600 Subject: [PATCH 5/5] update table of contents --- README.md | 9 ++++++++- docs/source/index.rst | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 624523ec..da16c1bb 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,14 @@ implement. Still internally all three interfaces are based on the `pylammpsmpi.L an additional thread to connect the `mpi4py` parallel LAMMPS instance to the serial python process or Jupyter notebook. # Documentation - +* [Installation](https://pylammpsmpi.readthedocs.io/en/latest/installation.html) + * [conda-based installation](https://pylammpsmpi.readthedocs.io/en/latest/installation.html#conda-based-installation) + * [pypi-based installation](https://pylammpsmpi.readthedocs.io/en/latest/installation.html#pypi-based-installation) +* [Interfaces](https://pylammpsmpi.readthedocs.io/en/latest/interfaces.html) + * [LammpsBase](https://pylammpsmpi.readthedocs.io/en/latest/interfaces.html#lammpsbase) + * [LammpsConcurrent](https://pylammpsmpi.readthedocs.io/en/latest/interfaces.html#lammpsconcurrent) + * [LammpsLibrary](https://pylammpsmpi.readthedocs.io/en/latest/interfaces.html#lammpslibrary) +* [Development](https://pylammpsmpi.readthedocs.io/en/latest/development.html) # License `pylammpsmpi` is released under the BSD license https://github.com/pyiron/pympipool/blob/main/LICENSE . It is a spin-off diff --git a/docs/source/index.rst b/docs/source/index.rst index a6b9ba95..9af17872 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -42,7 +42,10 @@ Documentation ------------- .. toctree:: + :maxdepth: 2 installation interfaces - development \ No newline at end of file + development + +* :ref:`modindex` \ No newline at end of file