diff --git a/doc/src/Howto_pylammps.rst b/doc/src/Howto_pylammps.rst index bce37d5ac7..5ef3248e1d 100644 --- a/doc/src/Howto_pylammps.rst +++ b/doc/src/Howto_pylammps.rst @@ -6,19 +6,22 @@ PyLammps Tutorial Overview -------- -``PyLammps`` is a Python wrapper class for LAMMPS which can be created -on its own or use an existing lammps Python object. It creates a simpler, +:py:class:`PyLammps ` is a Python wrapper class for +LAMMPS which can be created on its own or use an existing +:py:class:`lammps Python ` object. It creates a simpler, more "pythonic" interface to common LAMMPS functionality, in contrast to -the ``lammps`` wrapper for the C-style LAMMPS library interface which -is written using `Python ctypes `_. The ``lammps`` wrapper -is discussed on the :doc:`Python_head` doc page. +the :py:class:`lammps ` wrapper for the LAMMPS :ref:`C +language library interface API ` which is written using +`Python ctypes `_. The :py:class:`lammps ` +wrapper is discussed on the :doc:`Python_head` doc page. -Unlike the flat ``ctypes`` interface, PyLammps exposes a discoverable -API. It no longer requires knowledge of the underlying C++ code -implementation. Finally, the ``IPyLammps`` wrapper builds on top of -``PyLammps`` and adds some additional features for -`IPython integration `_ into `Jupyter notebooks `_, -e.g. for embedded visualization output from :doc:`dump style image `. +Unlike the flat `ctypes `_ interface, PyLammps exposes a +discoverable API. It no longer requires knowledge of the underlying C++ +code implementation. Finally, the :py:class:`IPyLammps +` wrapper builds on top of :py:class:`PyLammps +` and adds some additional features for `IPython +integration `_ into `Jupyter notebooks `_, e.g. for +embedded visualization output from :doc:`dump style image `. .. _ctypes: https://docs.python.org/3/library/ctypes.html .. _ipython: https://ipython.org/ @@ -30,19 +33,22 @@ Comparison of lammps and PyLammps interfaces lammps.lammps """"""""""""" -* uses ``ctypes`` -* direct memory access to native C++ data +* uses `ctypes `_ +* direct memory access to native C++ data with optional support for NumPy arrays * provides functions to send and receive data to LAMMPS +* interface modeled after the LAMMPS :ref:`C language library interface API ` * requires knowledge of how LAMMPS internally works (C pointers, etc) +* full support for running Python with MPI using `mpi4py `_ lammps.PyLammps """"""""""""""" -* higher-level abstraction built on top of original ctypes interface +* higher-level abstraction built on *top* of original :py:class:`ctypes based interface ` * manipulation of Python objects * communication with LAMMPS is hidden from API user * shorter, more concise Python * better IPython integration, designed for quick prototyping +* designed for serial execution Quick Start ----------- @@ -506,14 +512,26 @@ inside of the IPython notebook. Using PyLammps and mpi4py (Experimental) ---------------------------------------- -PyLammps can be run in parallel using mpi4py. This python package can be installed using +PyLammps can be run in parallel using `mpi4py +`_. This python package can be installed +using .. code-block:: bash pip install mpi4py -The following is a short example which reads in an existing LAMMPS input file and -executes it in parallel. You can find in.melt in the examples/melt folder. +.. warning:: + + Usually, any :py:class:`PyLammps ` command must be + executed by *all* MPI processes. However, evaluations and querying + the system state is only available on MPI rank 0. Using these + functions from other MPI ranks will raise an exception. + +The following is a short example which reads in an existing LAMMPS input +file and executes it in parallel. You can find in.melt in the +examples/melt folder. Please take note that the +:py:meth:`PyLammps.eval() ` is called only from +MPI rank 0. .. code-block:: python @@ -535,10 +553,6 @@ following mpirun command: mpirun -np 4 python melt.py -.. warning:: - - Any command must be executed by all MPI processes. However, evaluations and querying the system state is only available on rank 0. - Feedback and Contributing ------------------------- diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 649834ed7f..002e861dc7 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -3081,6 +3081,7 @@ qx qy qz Rackers +Radeon radi radialscreened radialscreenedspin diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index 96384255c2..49a2c6cb09 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -463,13 +463,19 @@ class PyLammps(object): self.lmp = lammps(name=name,cmdargs=cmdargs,ptr=ptr,comm=comm) else: self.lmp = lammps(name=name,cmdargs=cmdargs,ptr=None,comm=comm) - print("LAMMPS output is captured by PyLammps wrapper") + self.comm_nprocs = self.lmp.extract_setting("world_size") + self.comm_me = self.lmp.extract_setting("world_rank") + if self.comm_me == 0: + print("LAMMPS output is captured by PyLammps wrapper") + if self.comm_nprocs > 1: + print("WARNING: Using PyLammps with multiple MPI ranks is experimental. Not all functionality is supported.") self._cmd_history = [] self._enable_cmd_history = False self.runs = [] if not self.lmp.has_package("PYTHON"): - print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled") + if self.comm_me == 0: + print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled") def __enter__(self): return self @@ -727,7 +733,15 @@ class PyLammps(object): def eval(self, expr): """ - Evaluate expression + Evaluate LAMMPS input file expression. + + This is equivalent to using immediate variable expressions in the format "$(...)" + in the LAMMPS input and will return the result of that expression. + + .. warning:: + + This function is only supported on MPI rank 0. Calling it from a different + MPI rank will raise an exception. :param expr: the expression string that should be evaluated inside of LAMMPS :type expr: string @@ -735,6 +749,9 @@ class PyLammps(object): :return: the value of the evaluated expression :rtype: float if numeric, string otherwise """ + if self.comm_me > 0: + raise Exception("PyLammps.eval() may only be used on MPI rank 0") + value = self.lmp_print('"$(%s)"' % expr).strip() try: return float(value)