Merge branch 'master' into mliappy3

This commit is contained in:
Richard Berger 2020-12-18 09:16:44 -05:00
commit 4c7f71bef3
No known key found for this signature in database
GPG Key ID: A9E83994E0BA0CAB
115 changed files with 1866 additions and 1632 deletions

View File

@ -220,6 +220,7 @@ if(BUILD_OMP)
endif()
if (((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0)) OR
(CMAKE_CXX_COMPILER_ID STREQUAL "PGI") OR
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)) OR
((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0)))
# GCC 9.x and later plus Clang 10.x and later implement strict OpenMP 4.0 semantics for consts.
@ -661,7 +662,7 @@ if(BUILD_SHARED_LIBS)
add_custom_target(
install-python
${Python_EXECUTABLE} install.py -v ${LAMMPS_SOURCE_DIR}/version.h
-m ${LAMMPS_PYTHON_DIR}/lammps.py
-p ${LAMMPS_PYTHON_DIR}/lammps
-l ${CMAKE_BINARY_DIR}/liblammps${CMAKE_SHARED_LIBRARY_SUFFIX}
WORKING_DIRECTORY ${LAMMPS_PYTHON_DIR}
COMMENT "Installing LAMMPS Python module")
@ -691,11 +692,8 @@ if(BUILD_SHARED_LIBS OR PKG_PYTHON)
find_package(Python COMPONENTS Interpreter)
endif()
if (Python_EXECUTABLE)
execute_process(COMMAND ${Python_EXECUTABLE}
-c "import distutils.sysconfig as cg; print(cg.get_python_lib(1,0,prefix='${CMAKE_INSTALL_PREFIX}'))"
OUTPUT_VARIABLE PYTHON_DEFAULT_INSTDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
set(PYTHON_INSTDIR ${PYTHON_DEFAULT_INSTDIR} CACHE PATH "Installation folder for LAMMPS Python module")
install(FILES ${LAMMPS_PYTHON_DIR}/lammps.py DESTINATION ${PYTHON_INSTDIR})
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python)
install(CODE "execute_process(COMMAND ${Python_EXECUTABLE} setup.py build -b ${CMAKE_BINARY_DIR}/python install --prefix=${CMAKE_INSTALL_PREFIX} --root=\$ENV{DESTDIR}/ WORKING_DIRECTORY ${LAMMPS_PYTHON_DIR})")
endif()
endif()

View File

@ -19,6 +19,8 @@ if(CURL_FOUND)
target_compile_definitions(lammps PRIVATE -DLMP_NO_SSL_CHECK)
endif()
endif()
set(KIM_EXTRA_UNITTESTS OFF CACHE STRING "Set extra unit tests verbose mode on/off. If on, extra tests are included.")
mark_as_advanced(KIM_EXTRA_UNITTESTS)
find_package(PkgConfig QUIET)
set(DOWNLOAD_KIM_DEFAULT ON)
if(PKG_CONFIG_FOUND)
@ -34,8 +36,8 @@ if(DOWNLOAD_KIM)
enable_language(C)
enable_language(Fortran)
ExternalProject_Add(kim_build
URL https://s3.openkim.org/kim-api/kim-api-2.2.0.txz
URL_MD5 e7f944e1593cffd7444679a660607f6c
URL https://s3.openkim.org/kim-api/kim-api-2.2.1.txz
URL_MD5 ae1ddda2ef7017ea07934e519d023dca
BINARY_DIR build
CMAKE_ARGS ${CMAKE_REQUEST_PIC}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}

16
cmake/presets/pgi.cmake Normal file
View File

@ -0,0 +1,16 @@
# preset that will enable clang/clang++ with support for MPI and OpenMP (on Linux boxes)
set(CMAKE_CXX_COMPILER "pgc++" CACHE STRING "" FORCE)
set(CMAKE_C_COMPILER "pgcc" CACHE STRING "" FORCE)
set(CMAKE_Fortran_COMPILER "pgfortran" CACHE STRING "" FORCE)
set(MPI_CXX "pgc++" CACHE STRING "" FORCE)
set(MPI_CXX_COMPILER "mpicxx" CACHE STRING "" FORCE)
unset(HAVE_OMP_H_INCLUDE CACHE)
set(OpenMP_C "pgcc" CACHE STRING "" FORCE)
set(OpenMP_C_FLAGS "-mp" CACHE STRING "" FORCE)
set(OpenMP_C_LIB_NAMES "omp" CACHE STRING "" FORCE)
set(OpenMP_CXX "pgc++" CACHE STRING "" FORCE)
set(OpenMP_CXX_FLAGS "-mp" CACHE STRING "" FORCE)
set(OpenMP_CXX_LIB_NAMES "omp" CACHE STRING "" FORCE)
set(OpenMP_omp_LIBRARY "libomp.so" CACHE PATH "" FORCE)

View File

@ -229,7 +229,7 @@ $(VENV):
$(VIRTUALENV) -p $(PYTHON) $(VENV); \
. $(VENV)/bin/activate; \
pip install --upgrade pip; \
pip install --use-feature=2020-resolver -r $(BUILDDIR)/utils/requirements.txt; \
pip install -r $(BUILDDIR)/utils/requirements.txt; \
deactivate;\
)

View File

@ -236,12 +236,15 @@ LAMMPS.
cmake ../cmake -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc -DCMAKE_Fortran_COMPILER=ifort
# Building with LLVM/Clang Compilers:
cmake ../cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_Fortran_COMPILER=flang
# Building with PGI/Nvidia Compilers:
cmake ../cmake -DCMAKE_C_COMPILER=pgcc -DCMAKE_CXX_COMPILER=pgc++ -DCMAKE_Fortran_COMPILER=pgfortran
For compiling with the Clang/LLVM compilers a CMake preset is
provided that can be loaded with
`-C ../cmake/presets/clang.cmake`. Similarly,
`-C ../cmake/presets/intel.cmake` should switch the compiler
toolchain to the Intel compilers.
toolchain to the Intel compilers and `-C ../cmake/presets/pgi.cmake`
should switch the compiler to the PGI compilers.
In addition you can set ``CMAKE_TUNE_FLAGS`` to specifically add
compiler flags to tune for optimal performance on given hosts. By

View File

@ -283,6 +283,7 @@ minutes to hours) to build. Of course you only need to do that once.)
-D DOWNLOAD_KIM=value # download OpenKIM API v2 for build, value = no (default) or yes
-D LMP_DEBUG_CURL=value # set libcurl verbose mode on/off, value = off (default) or on
-D LMP_NO_SSL_CHECK=value # tell libcurl to not verify the peer, value = no (default) or yes
-D KIM_EXTRA_UNITTESTS=value # enables extra unit tests, value = no (default) or yes
If ``DOWNLOAD_KIM`` is set to *yes* (or *on*), the KIM API library
will be downloaded and built inside the CMake build directory. If
@ -291,6 +292,11 @@ minutes to hours) to build. Of course you only need to do that once.)
``PKG_CONFIG_PATH`` environment variable so that libkim-api can be
found, or run the command ``source kim-api-activate``.
Extra unit tests can only be available if they are explicitly requested
(``KIM_EXTRA_UNITTESTS`` is set to *yes* (or *on*)) and the prerequisites
are met. See :ref:`KIM Extra unit tests <kim_extra_unittests>` for
more details on this.
.. tab:: Traditional make
You can download and build the KIM library manually if you prefer;
@ -339,6 +345,38 @@ specify your own CA cert path by setting the environment variable
``CURL_CA_BUNDLE`` to the path of your choice. A call to the KIM web
query would get this value from the environment variable.
.. _kim_extra_unittests:
KIM Extra unit tests (CMake only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
During development, testing, or debugging, if
:doc:`unit testing <Build_development>` is enabled in LAMMPS, one can also
enable extra tests on :doc:`KIM commands <kim_commands>` by setting the
``KIM_EXTRA_UNITTESTS`` to *yes* (or *on*).
Enabling the extra unit tests have some requirements,
* It requires to have internet access.
* It requires to have libcurl installed with the matching development headers
and the curl-config tool.
* It requires to build LAMMPS with the PYTHON package installed and linked to
Python 3.6 or later. See the :ref:`PYTHON package build info <python>` for
more details on this.
* It requires to have ``kim-property`` Python package installed, which can be
easily done using *pip* as ``pip install kim-property``, or from the
*conda-forge* channel as ``conda install kim-property`` if LAMMPS is built in
Conda. More detailed information is available at:
`kim-property installation <https://github.com/openkim/kim-property#installing-kim-property>`_.
* It is also necessary to install
``EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000``, and
``EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005`` KIM models.
See `Obtaining KIM Models <http://openkim.org/doc/usage/obtaining-models>`_
to learn how to install a pre-build binary of the OpenKIM Repository of
Models or see
`Installing KIM Models <https://openkim.org/doc/usage/obtaining-models/#installing_models>`_
to learn how to install the specific KIM models.
----------
.. _kokkos:

View File

@ -1,4 +1,5 @@
Include packages in build
=========================
In LAMMPS, a package is a group of files that enable a specific set of
@ -160,6 +161,7 @@ one of them as a starting point and customize it to your needs.
cmake -C ../cmake/presets/clang.cmake [OPTIONS] ../cmake # change settings to use the Clang compilers by default
cmake -C ../cmake/presets/gcc.cmake [OPTIONS] ../cmake # change settings to use the GNU compilers by default
cmake -C ../cmake/presets/intel.cmake [OPTIONS] ../cmake # change settings to use the Intel compilers by default
cmake -C ../cmake/presets/pgi.cmake [OPTIONS] ../cmake # change settings to use the PGI compilers by default
cmake -C ../cmake/presets/all_on.cmake [OPTIONS] ../cmake # enable all packages
cmake -C ../cmake/presets/all_off.cmake [OPTIONS] ../cmake # disable all packages
mingw64-cmake -C ../cmake/presets/mingw-cross.cmake [OPTIONS] ../cmake # compile with MinGW cross compilers

View File

@ -9,8 +9,8 @@ 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,
more "pythonic" interface to common LAMMPS functionality, in contrast to
the ``lammps.py`` wrapper for the C-style LAMMPS library interface which
is written using `Python ctypes <ctypes_>`_. The ``lammps.py`` wrapper
the ``lammps`` wrapper for the C-style LAMMPS library interface which
is written using `Python ctypes <ctypes_>`_. The ``lammps`` wrapper
is discussed on the :doc:`Python_head` doc page.
Unlike the flat ``ctypes`` interface, PyLammps exposes a discoverable

View File

@ -9,7 +9,7 @@ This means you can extend the Python wrapper by following these steps:
* Add a new interface function to ``src/library.cpp`` and
``src/library.h``.
* Rebuild LAMMPS as a shared library.
* Add a wrapper method to ``python/lammps.py`` for this interface
* Add a wrapper method to ``python/lammps/core.py`` for this interface
function.
* Define the corresponding ``argtypes`` list and ``restype``
in the ``lammps.__init__()`` function.

View File

@ -8,9 +8,9 @@ module. Because of the dynamic loading, it is required that LAMMPS is
compiled in :ref:`"shared" mode <exe>`. It is also recommended to
compile LAMMPS with :ref:`C++ exceptions <exceptions>` enabled.
Two files are necessary for Python to be able to invoke LAMMPS code:
Two components are necessary for Python to be able to invoke LAMMPS code:
* The LAMMPS Python Module (``lammps.py``) from the ``python`` folder
* The LAMMPS Python Package (``lammps``) from the ``python`` folder
* The LAMMPS Shared Library (``liblammps.so``, ``liblammps.dylib`` or
``liblammps.dll``) from the folder where you compiled LAMMPS.
@ -25,10 +25,10 @@ Installing the LAMMPS Python Module and Shared Library
======================================================
Making LAMMPS usable within Python and vice versa requires putting the
LAMMPS Python module file (``lammps.py``) into a location where the
LAMMPS Python package (``lammps``) into a location where the
Python interpreter can find it and installing the LAMMPS shared library
into a folder that the dynamic loader searches or into the same folder
where the ``lammps.py`` file is. There are multiple ways to achieve
into a folder that the dynamic loader searches or inside of the installed
``lammps`` package folder. There are multiple ways to achieve
this.
#. Do a full LAMMPS installation of libraries, executables, selected
@ -36,13 +36,13 @@ this.
available via CMake), which can also be either system-wide or into
user specific folders.
#. Install both files into a Python ``site-packages`` folder, either
#. Install both components into a Python ``site-packages`` folder, either
system-wide or in the corresponding user-specific folder. This way no
additional environment variables need to be set, but the shared
library is otherwise not accessible.
#. Do an installation into a virtual environment. This can either be
an installation of the python module only or a full installation.
#. Do an installation into a virtual environment. This can either be an
installation of the Python package only or a full installation of LAMMPS.
#. Leave the files where they are in the source/development tree and
adjust some environment variables.
@ -81,19 +81,19 @@ this.
This leads to an installation to the following locations:
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+===========================================================+=============================================================+
| LAMMPS Python Module | * ``$HOME/.local/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$HOME/.local/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$HOME/.local/lib/`` (32bit) | |
| | * ``$HOME/.local/lib64/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS executable | * ``$HOME/.local/bin/`` | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS potential files | * ``$HOME/.local/share/lammps/potentials/`` | Set ``LAMMPS_POTENTIALS`` environment variable to this path |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+=================================================================+=============================================================+
| LAMMPS Python package | * ``$HOME/.local/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$HOME/.local/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$HOME/.local/lib/`` (32bit) | Set shared loader environment variable to this path |
| | * ``$HOME/.local/lib64/`` (64bit) | (see below for more info on this) |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS executable | * ``$HOME/.local/bin/`` | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS potential files | * ``$HOME/.local/share/lammps/potentials/`` | Set ``LAMMPS_POTENTIALS`` environment variable to this path |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
For a system-wide installation you need to set
``CMAKE_INSTALL_PREFIX`` to a system folder like ``/usr`` (or
@ -102,19 +102,19 @@ this.
privilege, e.g. by using ``sudo cmake --install .``. The
installation folders will then by changed to:
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+===================================================+=============================================================+
| LAMMPS Python Module | * ``/usr/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``/usr/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``/usr/lib/`` (32bit) | |
| | * ``/usr/lib64/`` (64bit) | |
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
| LAMMPS executable | * ``/usr/bin/`` | |
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
| LAMMPS potential files | * ``/usr/share/lammps/potentials/`` | |
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+=========================================================+=============================================================+
| LAMMPS Python package | * ``/usr/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``/usr/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``/usr/lib/`` (32bit) | |
| | * ``/usr/lib64/`` (64bit) | |
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS executable | * ``/usr/bin/`` | |
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS potential files | * ``/usr/share/lammps/potentials/`` | |
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
To be able to use the "user" installation you have to ensure that
the folder containing the LAMMPS shared library is either included
@ -146,7 +146,7 @@ this.
necessary due to files installed in system folders that are loaded
automatically when a login shell is started.
.. tab:: Python module only
.. tab:: Python package only
Compile LAMMPS with either :doc:`CMake <Build_cmake>` or the
:doc:`traditional make <Build_make>` procedure in :ref:`shared
@ -157,37 +157,37 @@ this.
make install-python
This will try to install (only) the shared library and the python
module into a system folder and if that fails (due to missing
This will try to install (only) the shared library and the Python
package into a system folder and if that fails (due to missing
write permissions) will instead do the installation to a user
folder under ``$HOME/.local``. For a system-wide installation you
would have to gain superuser privilege, e.g. though ``sudo``
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+===========================================================+=============================================================+
| LAMMPS Python Module | * ``$HOME/.local/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$HOME/.local/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$HOME/.local/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$HOME/.local/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+=================================================================+=============================================================+
| LAMMPS Python package | * ``$HOME/.local/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$HOME/.local/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$HOME/.local/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$HOME/.local/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
For a system-wide installation those folders would then become.
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+===================================================+=============================================================+
| LAMMPS Python Module | * ``/usr/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``/usr/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``/usr/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``/usr/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+---------------------------------------------------+-------------------------------------------------------------+
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+=========================================================+=============================================================+
| LAMMPS Python package | * ``/usr/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``/usr/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``/usr/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``/usr/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+---------------------------------------------------------+-------------------------------------------------------------+
No environment variables need to be set for those, as those
folders are searched by default by Python or the LAMMPS Python
module.
package.
For the traditional make process you can override the python
version to version x.y when calling ``make`` with
@ -199,9 +199,9 @@ this.
.. code-block:: bash
$ python install.py -m <python module> -l <shared library> -v <version.h file> [-d <pydir>]
$ python install.py -p <python package> -l <shared library> -v <version.h file> [-d <pydir>]
* The ``-m`` flag points to the ``lammps.py`` python module file to be installed,
* The ``-p`` flag points to the ``lammps`` Python package folder to be installed,
* the ``-l`` flag points to the LAMMPS shared library file to be installed,
* the ``-v`` flag points to the ``version.h`` file in the LAMMPS source
* and the optional ``-d`` flag to a custom (legacy) installation folder
@ -249,38 +249,38 @@ this.
When using CMake to build LAMMPS, you need to set
``CMAKE_INSTALL_PREFIX`` to the value of the ``$VIRTUAL_ENV``
environment variable during the configuration step. For the
traditional make procedure, not additional steps are needed.
After compiling LAMMPS you can do a "Python module only"
traditional make procedure, no additional steps are needed.
After compiling LAMMPS you can do a "Python package only"
installation with ``make install-python`` and the LAMMPS Python
module and the shared library file are installed into the
package and the shared library file are installed into the
following locations:
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+===========================================================+=============================================================+
| LAMMPS Python Module | * ``$VIRTUAL_ENV/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$VIRTUAL_ENV/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$VIRTUAL_ENV/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$VIRTUAL_ENV/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+=================================================================+=============================================================+
| LAMMPS Python Module | * ``$VIRTUAL_ENV/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$VIRTUAL_ENV/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$VIRTUAL_ENV/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$VIRTUAL_ENV/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
If you do a full installation (CMake only) with "install", this
leads to the following installation locations:
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+===========================================================+=============================================================+
| LAMMPS Python Module | * ``$VIRTUAL_ENV/lib/pythonX.Y/site-packages/`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$VIRTUAL_ENV/lib64/pythonX.Y/site-packages/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$VIRTUAL_ENV/lib/`` (32bit) | |
| | * ``$VIRTUAL_ENV/lib64/`` (64bit) | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS executable | * ``$VIRTUAL_ENV/bin/`` | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS potential files | * ``$VIRTUAL_ENV/share/lammps/potentials/`` | |
+------------------------+-----------------------------------------------------------+-------------------------------------------------------------+
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| File | Location | Notes |
+========================+=================================================================+=============================================================+
| LAMMPS Python Module | * ``$VIRTUAL_ENV/lib/pythonX.Y/site-packages/lammps`` (32bit) | ``X.Y`` depends on the installed Python version |
| | * ``$VIRTUAL_ENV/lib64/pythonX.Y/site-packages/lammps`` (64bit) | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS shared library | * ``$VIRTUAL_ENV/lib/`` (32bit) | Set shared loader environment variable to this path |
| | * ``$VIRTUAL_ENV/lib64/`` (64bit) | (see below for more info on this) |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS executable | * ``$VIRTUAL_ENV/bin/`` | |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
| LAMMPS potential files | * ``$VIRTUAL_ENV/share/lammps/potentials/`` | Set ``LAMMPS_POTENTIALS`` environment variable to this path |
+------------------------+-----------------------------------------------------------------+-------------------------------------------------------------+
In that case you need to modify the ``$HOME/myenv/bin/activate``
script in a similar fashion you need to update your
@ -296,15 +296,15 @@ this.
echo 'export LD_LIBRARY_PATH=$VIRTUAL_ENV/lib:$LD_LIBRARY_PATH' >> $HOME/myenv/bin/activate
# MacOS
echo 'export DYLD_LIBRARY_PATH=$VIRTUAL_ENV/lib:$LD_LIBRARY_PATH' >> $HOME/myenv/bin/activate
echo 'export DYLD_LIBRARY_PATH=$VIRTUAL_ENV/lib:$DYLD_LIBRARY_PATH' >> $HOME/myenv/bin/activate
.. tab:: In place usage
You can also :doc:`compile LAMMPS <Build>` as usual in
:ref:`"shared" mode <exe>` leave the shared library and Python
module files inside the source/compilation folders. Instead of
package inside the source/compilation folders. Instead of
copying the files where they can be found, you need to set the environment
variables ``PYTHONPATH`` (for the Python module) and
variables ``PYTHONPATH`` (for the Python package) and
``LD_LIBRARY_PATH`` (or ``DYLD_LIBRARY_PATH`` on MacOS
For Bourne shells (bash, ksh and similar) the commands are:
@ -325,6 +325,10 @@ this.
You can make those changes permanent by editing your ``$HOME/.bashrc``
or ``$HOME/.login`` files, respectively.
.. note::
The ``PYTHONPATH`` needs to point to the parent folder that contains the ``lammps`` package!
To verify if LAMMPS can be successfully started from Python, start the
Python interpreter, load the ``lammps`` Python module and create a
@ -346,7 +350,7 @@ output similar to the following:
.. note::
Unless you opted for "In place use", you will have to rerun the installation
any time you recompile LAMMPS to ensure the latest Python module and shared
any time you recompile LAMMPS to ensure the latest Python package and shared
library are installed and used.
.. note::

View File

@ -3,12 +3,12 @@ The ``lammps`` Python module
.. py:module:: lammps
The LAMMPS Python interface is implemented as a module called
:py:mod:`lammps` in the ``lammps.py`` file in the ``python`` folder of
the LAMMPS source code distribution. After compilation of LAMMPS, the
module can be installed into a Python system folder or a user folder
with ``make install-python``. Components of the module can then loaded
into a Python session with the ``import`` command.
The LAMMPS Python interface is implemented as a module called :py:mod:`lammps`
which is defined in the ``lammps`` package in the ``python`` folder of the
LAMMPS source code distribution. After compilation of LAMMPS, the module can
be installed into a Python system folder or a user folder with ``make
install-python``. Components of the module can then loaded into a Python
session with the ``import`` command.
There are multiple Python interface classes in the :py:mod:`lammps` module:
@ -44,7 +44,7 @@ functions. Below is a detailed documentation of the API.
.. autoclass:: lammps.lammps
:members:
.. autoclass:: lammps.numpy_wrapper
.. autoclass:: lammps.numpy::numpy_wrapper
:members:
----------
@ -117,8 +117,8 @@ Style Constants
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`, :py:func:`lammps.extract_fix`, and their NumPy variants
:py:func:`lammps.numpy.extract_compute() <numpy_wrapper.extract_compute>` and
:py:func:`lammps.numpy.extract_fix() <numpy_wrapper.extract_fix>`.
:py:func:`lammps.numpy.extract_compute() <lammps.numpy.numpy_wrapper.extract_compute>` and
:py:func:`lammps.numpy.extract_fix() <lammps.numpy.numpy_wrapper.extract_fix>`.
.. _py_type_constants:
@ -132,8 +132,8 @@ Type Constants
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`, :py:func:`lammps.extract_fix`, and their NumPy variants
:py:func:`lammps.numpy.extract_compute() <numpy_wrapper.extract_compute>` and
:py:func:`lammps.numpy.extract_fix() <numpy_wrapper.extract_fix>`.
:py:func:`lammps.numpy.extract_compute() <lammps.numpy.numpy_wrapper.extract_compute>` and
:py:func:`lammps.numpy.extract_fix() <lammps.numpy.numpy_wrapper.extract_fix>`.
.. _py_vartype_constants:
@ -153,6 +153,6 @@ Classes representing internal objects
:members:
:no-undoc-members:
.. autoclass:: lammps.NumPyNeighList
.. autoclass:: lammps.numpy::NumPyNeighList
:members:
:no-undoc-members:

View File

@ -2,9 +2,9 @@ Overview
========
The LAMMPS distribution includes a ``python`` directory with the Python
code needed to run LAMMPS from Python. The ``python/lammps.py``
contains :doc:`the "lammps" Python <Python_module>` that wraps the
LAMMPS C-library interface. This file makes it is possible to do the
code needed to run LAMMPS from Python. The ``python/lammps`` package
contains :doc:`the "lammps" Python module <Python_module>` that wraps the
LAMMPS C-library interface. This module makes it is possible to do the
following either from a Python script, or interactively from a Python
prompt:
@ -20,8 +20,8 @@ have a version of Python that extends Python to enable multiple
instances of Python to read what you type.
To do all of this, you must build LAMMPS in :ref:`"shared" mode <exe>`
and make certain that your Python interpreter can find the ``lammps.py``
file and the LAMMPS shared library file.
and make certain that your Python interpreter can find the ``lammps``
Python package and the LAMMPS shared library file.
.. _ctypes: https://docs.python.org/3/library/ctypes.html

View File

@ -33,7 +33,7 @@ the constructor call as follows (see :ref:`python_create_lammps` for more detail
>>> lmp = lammps(name='mpi')
You can also test the load directly in Python as follows, without
first importing from the lammps.py file:
first importing from the ``lammps`` module:
.. code-block:: python

View File

@ -288,7 +288,7 @@ adjacent planes are closer together than the neighbor skin distance
(as specified by the :doc`neigh_modify <neigh_modify>` command), then
the plane positions are shifted to separate them by at least this
amount. This is to prevent particles being lost when dynamics are run
with processor subdomains that are too narrow in one or more
with processor sub-domains that are too narrow in one or more
dimensions.
Once the re-balancing is complete and final processor sub-domains

View File

@ -124,6 +124,19 @@ temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
An important feature of these thermostats is that they have an
associated effective energy that is a constant of motion.
The effective energy is the total energy (kinetic + potential) plus
the accumulated kinetic energy changes due to the thermostat. The
latter quantity is the global scalar computed by these fixes. This
feature is useful to check the integration of the equations of motion
against discretization errors. In other words, the conservation of
the effective energy can be used to choose an appropriate integration
:doc:`timestep <timestep>`. This is similar to the usual paradigm of
checking the conservation of the total energy in the microcanonical
ensemble.
----------
Restart, fix_modify, output, run start/stop, minimize info

View File

@ -20,7 +20,7 @@ Examples
pair_style meam/spline
pair_coeff * * Ti.meam.spline Ti
pair_coeff * * Ti.meam.spline Ti Ti Ti
pair_coeff * * Ti.meam.spline Ti O
Description
"""""""""""
@ -84,23 +84,22 @@ where N is the number of LAMMPS atom types:
See the :doc:`pair_coeff <pair_coeff>` doc page for alternate ways
to specify the path for the potential file.
As an example, imagine the Ti.meam.spline file has values for Ti (old style). If
your LAMMPS simulation has 3 atoms types and they are all to be
treated with this potentials, you would use the following pair_coeff
command:
As an example, imagine the Ti.meam.spline file has values for Ti (old style).
In that case your LAMMPS simulation may only have one atom type which has
to be mapped to the Ti element as follows:
.. code-block:: LAMMPS
pair_coeff * * Ti.meam.spline Ti Ti Ti
pair_coeff * * Ti.meam.spline Ti
The first 2 arguments must be \* \* so as to span all LAMMPS atom types.
The three Ti arguments map LAMMPS atom types 1,2,3 to the Ti element
in the potential file. If a mapping value is specified as NULL, the
mapping is not performed. This can be used when a *meam/spline*
potential is used as part of the *hybrid* pair style. The NULL values
are placeholders for atom types that will be used with other
potentials. The old-style potential maps any non-NULL species named
on the command line to that single type.
The first 2 arguments must be \* \* and there may be only one element
following or NULL. Systems where there would be multiple atom types
assigned to the same element are **not** supported by this pair style
due to limitations in its implementation. If a mapping value is
specified as NULL, the mapping is not performed. This can be used when
a *meam/spline* potential is used as part of the *hybrid* pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
An example with a two component spline (new style) is TiO.meam.spline, where
the command
@ -143,6 +142,8 @@ Restrictions
This pair style requires the :doc:`newton <newton>` setting to be "on"
for pair interactions.
This pair style does not support mapping multiple atom types to the same element.
This pair style is only enabled if LAMMPS was built with the USER-MISC
package. See the :doc:`Build package <Build_package>` doc page for more
info.

View File

@ -323,8 +323,8 @@ Python function is as follows:
The function definition must include a variable (lmpptr in this case)
which corresponds to SELF in the python command. The first line of the
function imports the Python module lammps.py in the python directory of
the distribution. The second line creates a Python object "lmp" which
function imports the :doc:`"lammps" Python module <Python_module>`.
The second line creates a Python object ``lmp`` which
wraps the instance of LAMMPS that called the function. The "ptr=lmpptr"
argument is what makes that happen. The third line invokes the
command() function in the LAMMPS library interface. It takes a single
@ -502,18 +502,16 @@ Python library on your system. Settings to enable this are in the
lib/python/Makefile.lammps file. See the lib/python/README file for
information on those settings.
If you use Python code which calls back to LAMMPS, via the SELF input
argument explained above, there is an extra step required when
building LAMMPS. LAMMPS must also be built as a shared library and
your Python function must be able to load the Python module in
python/lammps.py that wraps the LAMMPS library interface. These are
the same steps required to use Python by itself to wrap LAMMPS.
Details on these steps are explained on the :doc:`Python <Python_head>`
doc page. Note that it is important that the stand-alone LAMMPS
executable and the LAMMPS shared library be consistent (built from the
same source code files) in order for this to work. If the two have
been built at different times using different source files, problems
may occur.
If you use Python code which calls back to LAMMPS, via the SELF input argument
explained above, there is an extra step required when building LAMMPS. LAMMPS
must also be built as a shared library and your Python function must be able to
load the :doc:`"lammps" Python module <Python_module>` that wraps the LAMMPS
library interface. These are the same steps required to use Python by itself
to wrap LAMMPS. Details on these steps are explained on the :doc:`Python
<Python_head>` doc page. Note that it is important that the stand-alone LAMMPS
executable and the LAMMPS shared library be consistent (built from the same
source code files) in order for this to work. If the two have been built at
different times using different source files, problems may occur.
Related commands
""""""""""""""""

View File

@ -3002,6 +3002,7 @@ Sukumaran
Sulc
sumsq
Sunderland
supercell
superset
supersphere
Supinski

View File

@ -1,4 +1,4 @@
# this example requires the LAMMPS Python package (lammps.py) to be installed
# this example requires the LAMMPS Python package (python/lammps) to be installed
# and LAMMPS to be loadable as shared library in LD_LIBRARY_PATH
import lammps

View File

@ -18,13 +18,14 @@ parser = ArgumentParser(prog='Install.py',
# settings
thisdir = fullpath('.')
version = "2.2.0"
version = "2.2.1"
# known checksums for different KIM-API versions. used to validate the download.
checksums = { \
'2.1.2' : '6ac52e14ef52967fc7858220b208cba5', \
'2.1.3' : '6ee829a1bbba5f8b9874c88c4c4ebff8', \
'2.2.0' : 'e7f944e1593cffd7444679a660607f6c', \
'2.2.1' : 'ae1ddda2ef7017ea07934e519d023dca', \
}

View File

@ -2,6 +2,6 @@
# See the README file for more explanation
python_SYSINC = $(shell which python-config > /dev/null 2>&1 && python-config --includes || :)
python_SYSLIB = $(shell which python-config > /dev/null 2>&1 && python-config --ldflags || :)
python_SYSLIB = $(shell which python-config > /dev/null 2>&1 && python-config --ldflags --embed > /dev/null 2>&1 && python-config --ldflags --embed || (which python-config > /dev/null 2>&1 && python-config --ldflags || :) )
python_SYSPATH =
PYTHON=python

View File

@ -2,6 +2,6 @@
# See the README file for more explanation
python_SYSINC = $(shell which python3-config > /dev/null 2>&1 && python3-config --includes || (which python-config > /dev/null 2>&1 && python-config --includes || :))
python_SYSLIB = $(shell which python3-config > /dev/null 2>&1 && python3-config --ldflags || (which python-config > /dev/null 2>&1 && python-config --ldflags || :))
python_SYSLIB = $(shell which python3-config > /dev/null 2>&1 && python3-config --ldflags --embed > /dev/null 2>&1 && python3-config --ldflags --embed || (which python3-config > /dev/null 2>&1 && python3-config --ldflags || (which python-config > /dev/null 2>&1 && python-config --ldflags || :) ) )
python_SYSPATH =
PYTHON=$(shell which python3 > /dev/null 2>&1 && echo python3 || echo python)

View File

@ -1,42 +1,42 @@
#!/usr/bin/env python
"""
Installer script to install the LAMMPS python module and the corresponding
Installer script to install the LAMMPS python package and the corresponding
shared library into either the system-wide site-packages tree, or - failing
that - into the corresponding user tree. Called from the 'install-python'
build target in the conventional and CMake based build systems
"""
# copy LAMMPS shared library and lammps.py to system dirs
# copy LAMMPS shared library and lammps package to system dirs
from __future__ import print_function
import sys,os,shutil
from argparse import ArgumentParser
parser = ArgumentParser(prog='install.py',
description='LAMMPS python module installer script')
description='LAMMPS python package installer script')
parser.add_argument("-m", "--module", required=True,
help="path to the source of the LAMMPS Python module")
parser.add_argument("-p", "--package", required=True,
help="path to the LAMMPS Python package")
parser.add_argument("-l", "--lib", required=True,
help="path to the compiled LAMMPS shared library")
parser.add_argument("-v", "--version", required=True,
help="path to the LAMMPS version.h header file")
parser.add_argument("-d","--dir",
help="Legacy custom installation folder selection for module and library")
help="Legacy custom installation folder selection for package and library")
args = parser.parse_args()
# validate arguments and make paths absolute
if args.module:
if not os.path.exists(args.module):
print( "ERROR: LAMMPS module file %s does not exist" % args.module)
if args.package:
if not os.path.exists(args.package):
print( "ERROR: LAMMPS package %s does not exist" % args.package)
parser.print_help()
sys.exit(1)
else:
args.module = os.path.abspath(args.module)
args.package = os.path.abspath(args.package)
if args.lib:
if not os.path.exists(args.lib):
@ -66,9 +66,9 @@ if args.dir:
# without any special processing or additional steps to that folder
if args.dir:
print("Copying LAMMPS Python module to custom folder %s" % args.dir)
print("Copying LAMMPS Python package to custom folder %s" % args.dir)
try:
shutil.copyfile(args.module, os.path.join(args.dir,'lammps.py'))
shutil.copytree(args.package, os.path.join(args.dir,'lammps'))
except shutil.Error:
pass # fail silently
@ -81,15 +81,19 @@ if args.dir:
sys.exit()
# extract version string from header
fp = open(args.version,'r')
txt=fp.read().split('"')[1].split()
verstr=txt[0]+txt[1]+txt[2]
fp.close()
def get_lammps_version(header):
with open(header, 'r') as f:
line = f.readline()
start_pos = line.find('"')+1
end_pos = line.find('"', start_pos)
return "".join(line[start_pos:end_pos].split())
print("Installing LAMMPS Python module version %s into site-packages folder" % verstr)
verstr = get_lammps_version(args.version)
# we need to switch to the folder of the python module
os.chdir(os.path.dirname(args.module))
print("Installing LAMMPS Python package version %s into site-packages folder" % verstr)
# we need to switch to the folder of the python package
os.chdir(os.path.dirname(args.package))
from distutils.core import setup
from distutils.sysconfig import get_python_lib
@ -103,10 +107,10 @@ try:
author = "Steve Plimpton",
author_email = "sjplimp@sandia.gov",
url = "https://lammps.sandia.gov",
description = "LAMMPS Molecular Dynamics Python module",
description = "LAMMPS Molecular Dynamics Python package",
license = "GPL",
py_modules = ["lammps"],
data_files = [(get_python_lib(), [args.lib])])
packages=['lammps'],
data_files = [(os.path.join(get_python_lib(), 'lammps'), [args.lib])])
except:
tryuser=True
print ("Installation into global site-packages folder failed.\nTrying user folder %s now." % site.USER_SITE)
@ -119,9 +123,9 @@ if tryuser:
author = "Steve Plimpton",
author_email = "sjplimp@sandia.gov",
url = "https://lammps.sandia.gov",
description = "LAMMPS Molecular Dynamics Python module",
description = "LAMMPS Molecular Dynamics Python package",
license = "GPL",
py_modules = ["lammps"],
data_files = [(site.USER_SITE, [args.lib])])
packages=['lammps'],
data_files = [(os.path.join(site.USER_SITE, 'lammps'), [args.lib])])
except:
print("Installation into user site package folder failed.")

View File

@ -0,0 +1,4 @@
from .constants import *
from .core import *
from .data import *
from .pylammps import *

View File

@ -0,0 +1,49 @@
# ----------------------------------------------------------------------
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
# http://lammps.sandia.gov, Sandia National Laboratories
# Steve Plimpton, sjplimp@sandia.gov
#
# Copyright (2003) Sandia Corporation. Under the terms of Contract
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
# certain rights in this software. This software is distributed under
# the GNU General Public License.
#
# See the README file in the top-level LAMMPS directory.
# -------------------------------------------------------------------------
from ctypes import c_int, c_int32, c_int64
# various symbolic constants to be used
# in certain calls to select data formats
LAMMPS_AUTODETECT = None
LAMMPS_INT = 0
LAMMPS_INT_2D = 1
LAMMPS_DOUBLE = 2
LAMMPS_DOUBLE_2D = 3
LAMMPS_INT64 = 4
LAMMPS_INT64_2D = 5
LAMMPS_STRING = 6
# these must be kept in sync with the enums in library.h
LMP_STYLE_GLOBAL = 0
LMP_STYLE_ATOM = 1
LMP_STYLE_LOCAL = 2
LMP_TYPE_SCALAR = 0
LMP_TYPE_VECTOR = 1
LMP_TYPE_ARRAY = 2
LMP_SIZE_VECTOR = 3
LMP_SIZE_ROWS = 4
LMP_SIZE_COLS = 5
LMP_VAR_EQUAL = 0
LMP_VAR_ATOM = 1
# -------------------------------------------------------------------------
def get_ctypes_int(size):
if size == 4:
return c_int32
elif size == 8:
return c_int64
return c_int

File diff suppressed because it is too large Load Diff

73
python/lammps/data.py Normal file
View File

@ -0,0 +1,73 @@
# ----------------------------------------------------------------------
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
# http://lammps.sandia.gov, Sandia National Laboratories
# Steve Plimpton, sjplimp@sandia.gov
#
# Copyright (2003) Sandia Corporation. Under the terms of Contract
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
# certain rights in this software. This software is distributed under
# the GNU General Public License.
#
# See the README file in the top-level LAMMPS directory.
# -------------------------------------------------------------------------
################################################################################
# LAMMPS data structures
# Written by Richard Berger <richard.berger@temple.edu>
################################################################################
class NeighList:
"""This is a wrapper class that exposes the contents of a neighbor list.
It can be used like a regular Python list. Each element is a tuple of:
* the atom local index
* its number of neighbors
* and a pointer to an c_int array containing local atom indices of its
neighbors
Internally it uses the lower-level LAMMPS C-library interface.
:param lmp: reference to instance of :py:class:`lammps`
:type lmp: lammps
:param idx: neighbor list index
:type idx: int
"""
def __init__(self, lmp, idx):
self.lmp = lmp
self.idx = idx
def __str__(self):
return "Neighbor List ({} atoms)".format(self.size)
def __repr__(self):
return self.__str__()
@property
def size(self):
"""
:return: number of elements in neighbor list
"""
return self.lmp.get_neighlist_size(self.idx)
def get(self, element):
"""
:return: tuple with atom local index, numpy array of neighbor local atom indices
:rtype: (int, int, ctypes.POINTER(c_int))
"""
iatom, numneigh, neighbors = self.lmp.get_neighlist_element_neighbors(self.idx, element)
return iatom, numneigh, neighbors
# the methods below implement the iterator interface, so NeighList can be used like a regular Python list
def __getitem__(self, element):
return self.get(element)
def __len__(self):
return self.size
def __iter__(self):
inum = self.size
for ii in range(inum):
yield self.get(ii)

338
python/lammps/numpy.py Normal file
View File

@ -0,0 +1,338 @@
# ----------------------------------------------------------------------
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
# http://lammps.sandia.gov, Sandia National Laboratories
# Steve Plimpton, sjplimp@sandia.gov
#
# Copyright (2003) Sandia Corporation. Under the terms of Contract
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
# certain rights in this software. This software is distributed under
# the GNU General Public License.
#
# See the README file in the top-level LAMMPS directory.
# -------------------------------------------------------------------------
################################################################################
# NumPy additions
# Written by Richard Berger <richard.berger@temple.edu>
################################################################################
import warnings
from ctypes import POINTER, c_double, c_int, c_int32, c_int64, cast
from .constants import *
from .data import NeighList
class numpy_wrapper:
"""lammps API NumPy Wrapper
This is a wrapper class that provides additional methods on top of an
existing :py:class:`lammps` instance. The methods transform raw ctypes
pointers into NumPy arrays, which give direct access to the
original data while protecting against out-of-bounds accesses.
There is no need to explicitly instantiate this class. Each instance
of :py:class:`lammps` has a :py:attr:`numpy <lammps.numpy>` property
that returns an instance.
:param lmp: instance of the :py:class:`lammps` class
:type lmp: lammps
"""
def __init__(self, lmp):
self.lmp = lmp
# -------------------------------------------------------------------------
def _ctype_to_numpy_int(self, ctype_int):
import numpy as np
if ctype_int == c_int32:
return np.int32
elif ctype_int == c_int64:
return np.int64
return np.intc
# -------------------------------------------------------------------------
def extract_atom(self, name, dtype=LAMMPS_AUTODETECT, nelem=LAMMPS_AUTODETECT, dim=LAMMPS_AUTODETECT):
"""Retrieve per-atom properties from LAMMPS as NumPy arrays
This is a wrapper around the :py:meth:`lammps.extract_atom()` method.
It behaves the same as the original method, but returns NumPy arrays
instead of ``ctypes`` pointers.
.. note::
While the returned arrays of per-atom data are dimensioned
for the range [0:nmax] - as is the underlying storage -
the data is usually only valid for the range of [0:nlocal],
unless the property of interest is also updated for ghost
atoms. In some cases, this depends on a LAMMPS setting, see
for example :doc:`comm_modify vel yes <comm_modify>`.
:param name: name of the property
:type name: string
:param dtype: type of the returned data (see :ref:`py_datatype_constants`)
:type dtype: int, optional
:param nelem: number of elements in array
:type nelem: int, optional
:param dim: dimension of each element
:type dim: int, optional
:return: requested data as NumPy array with direct access to C data or None
:rtype: numpy.array or NoneType
"""
if dtype == LAMMPS_AUTODETECT:
dtype = self.lmp.extract_atom_datatype(name)
if nelem == LAMMPS_AUTODETECT:
if name == "mass":
nelem = self.lmp.extract_global("ntypes") + 1
else:
nelem = self.lmp.extract_global("nlocal")
if dim == LAMMPS_AUTODETECT:
if dtype in (LAMMPS_INT_2D, LAMMPS_DOUBLE_2D, LAMMPS_INT64_2D):
# TODO add other fields
if name in ("x", "v", "f", "angmom", "torque", "csforce", "vforce"):
dim = 3
else:
dim = 2
else:
dim = 1
raw_ptr = self.lmp.extract_atom(name, dtype)
if dtype in (LAMMPS_DOUBLE, LAMMPS_DOUBLE_2D):
return self.darray(raw_ptr, nelem, dim)
elif dtype in (LAMMPS_INT, LAMMPS_INT_2D):
return self.iarray(c_int32, raw_ptr, nelem, dim)
elif dtype in (LAMMPS_INT64, LAMMPS_INT64_2D):
return self.iarray(c_int64, raw_ptr, nelem, dim)
return raw_ptr
# -------------------------------------------------------------------------
def extract_atom_iarray(self, name, nelem, dim=1):
warnings.warn("deprecated, use extract_atom instead", DeprecationWarning)
if name in ['id', 'molecule']:
c_int_type = self.lmp.c_tagint
elif name in ['image']:
c_int_type = self.lmp.c_imageint
else:
c_int_type = c_int
if dim == 1:
raw_ptr = self.lmp.extract_atom(name, LAMMPS_INT)
else:
raw_ptr = self.lmp.extract_atom(name, LAMMPS_INT_2D)
return self.iarray(c_int_type, raw_ptr, nelem, dim)
# -------------------------------------------------------------------------
def extract_atom_darray(self, name, nelem, dim=1):
warnings.warn("deprecated, use extract_atom instead", DeprecationWarning)
if dim == 1:
raw_ptr = self.lmp.extract_atom(name, LAMMPS_DOUBLE)
else:
raw_ptr = self.lmp.extract_atom(name, LAMMPS_DOUBLE_2D)
return self.darray(raw_ptr, nelem, dim)
# -------------------------------------------------------------------------
def extract_compute(self, cid, style, type):
"""Retrieve data from a LAMMPS compute
This is a wrapper around the
:py:meth:`lammps.extract_compute() <lammps.lammps.extract_compute()>` method.
It behaves the same as the original method, but returns NumPy arrays
instead of ``ctypes`` pointers.
:param id: compute ID
:type id: string
:param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
:type style: int
:param type: type of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
:type type: int
:return: requested data either as float, as NumPy array with direct access to C data, or None
:rtype: float, numpy.array, or NoneType
"""
value = self.lmp.extract_compute(cid, style, type)
if style in (LMP_STYLE_GLOBAL, LMP_STYLE_LOCAL):
if type == LMP_TYPE_VECTOR:
nrows = self.lmp.extract_compute(cid, style, LMP_SIZE_VECTOR)
return self.darray(value, nrows)
elif type == LMP_TYPE_ARRAY:
nrows = self.lmp.extract_compute(cid, style, LMP_SIZE_ROWS)
ncols = self.lmp.extract_compute(cid, style, LMP_SIZE_COLS)
return self.darray(value, nrows, ncols)
elif style == LMP_STYLE_ATOM:
if type == LMP_TYPE_VECTOR:
nlocal = self.lmp.extract_global("nlocal")
return self.darray(value, nlocal)
elif type == LMP_TYPE_ARRAY:
nlocal = self.lmp.extract_global("nlocal")
ncols = self.lmp.extract_compute(cid, style, LMP_SIZE_COLS)
return self.darray(value, nlocal, ncols)
return value
# -------------------------------------------------------------------------
def extract_fix(self, fid, style, type, nrow=0, ncol=0):
"""Retrieve data from a LAMMPS fix
This is a wrapper around the :py:meth:`lammps.extract_fix() <lammps.lammps.extract_fix()>` method.
It behaves the same as the original method, but returns NumPy arrays
instead of ``ctypes`` pointers.
:param id: fix ID
:type id: string
:param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
:type style: int
:param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
:type type: int
:param nrow: index of global vector element or row index of global array element
:type nrow: int
:param ncol: column index of global array element
:type ncol: int
:return: requested data
:rtype: integer or double value, pointer to 1d or 2d double array or None
"""
value = self.lmp.extract_fix(fid, style, type, nrow, ncol)
if style == LMP_STYLE_ATOM:
if type == LMP_TYPE_VECTOR:
nlocal = self.lmp.extract_global("nlocal")
return self.darray(value, nlocal)
elif type == LMP_TYPE_ARRAY:
nlocal = self.lmp.extract_global("nlocal")
ncols = self.lmp.extract_fix(fid, style, LMP_SIZE_COLS, 0, 0)
return self.darray(value, nlocal, ncols)
elif style == LMP_STYLE_LOCAL:
if type == LMP_TYPE_VECTOR:
nrows = self.lmp.extract_fix(fid, style, LMP_SIZE_ROWS, 0, 0)
return self.darray(value, nrows)
elif type == LMP_TYPE_ARRAY:
nrows = self.lmp.extract_fix(fid, style, LMP_SIZE_ROWS, 0, 0)
ncols = self.lmp.extract_fix(fid, style, LMP_SIZE_COLS, 0, 0)
return self.darray(value, nrows, ncols)
return value
# -------------------------------------------------------------------------
def extract_variable(self, name, group=None, vartype=LMP_VAR_EQUAL):
""" Evaluate a LAMMPS variable and return its data
This function is a wrapper around the function
:py:meth:`lammps.extract_variable() <lammps.lammps.extract_variable()>`
method. It behaves the same as the original method, but returns NumPy arrays
instead of ``ctypes`` pointers.
:param name: name of the variable to execute
:type name: string
:param group: name of group for atom-style variable (ignored for equal-style variables)
:type group: string
:param vartype: type of variable, see :ref:`py_vartype_constants`
:type vartype: int
:return: the requested data or None
:rtype: c_double, numpy.array, or NoneType
"""
import numpy as np
value = self.lmp.extract_variable(name, group, vartype)
if vartype == LMP_VAR_ATOM:
return np.ctypeslib.as_array(value)
return value
# -------------------------------------------------------------------------
def get_neighlist(self, idx):
"""Returns an instance of :class:`NumPyNeighList` which wraps access to the neighbor list with the given index
:param idx: index of neighbor list
:type idx: int
:return: an instance of :class:`NumPyNeighList` wrapping access to neighbor list data
:rtype: NumPyNeighList
"""
if idx < 0:
return None
return NumPyNeighList(self.lmp, idx)
# -------------------------------------------------------------------------
def get_neighlist_element_neighbors(self, idx, element):
"""Return data of neighbor list entry
This function is a wrapper around the function
:py:meth:`lammps.get_neighlist_element_neighbors() <lammps.lammps.get_neighlist_element_neighbors()>`
method. It behaves the same as the original method, but returns a NumPy array containing the neighbors
instead of a ``ctypes`` pointer.
:param element: neighbor list index
:type element: int
:param element: neighbor list element index
:type element: int
:return: tuple with atom local index and numpy array of neighbor local atom indices
:rtype: (int, numpy.array)
"""
iatom, numneigh, c_neighbors = self.lmp.get_neighlist_element_neighbors(idx, element)
neighbors = self.iarray(c_int, c_neighbors, numneigh, 1)
return iatom, neighbors
# -------------------------------------------------------------------------
def iarray(self, c_int_type, raw_ptr, nelem, dim=1):
import numpy as np
np_int_type = self._ctype_to_numpy_int(c_int_type)
if dim == 1:
ptr = cast(raw_ptr, POINTER(c_int_type * nelem))
else:
ptr = cast(raw_ptr[0], POINTER(c_int_type * nelem * dim))
a = np.frombuffer(ptr.contents, dtype=np_int_type)
a.shape = (nelem, dim)
return a
# -------------------------------------------------------------------------
def darray(self, raw_ptr, nelem, dim=1):
import numpy as np
if dim == 1:
ptr = cast(raw_ptr, POINTER(c_double * nelem))
else:
ptr = cast(raw_ptr[0], POINTER(c_double * nelem * dim))
a = np.frombuffer(ptr.contents)
a.shape = (nelem, dim)
return a
# -------------------------------------------------------------------------
class NumPyNeighList(NeighList):
"""This is a wrapper class that exposes the contents of a neighbor list.
It can be used like a regular Python list. Each element is a tuple of:
* the atom local index
* a NumPy array containing the local atom indices of its neighbors
Internally it uses the lower-level LAMMPS C-library interface.
:param lmp: reference to instance of :py:class:`lammps`
:type lmp: lammps
:param idx: neighbor list index
:type idx: int
"""
def __init__(self, lmp, idx):
super(NumPyNeighList, self).__init__(lmp, idx)
def get(self, element):
"""
:return: tuple with atom local index, numpy array of neighbor local atom indices
:rtype: (int, numpy.array)
"""
iatom, neighbors = self.lmp.numpy.get_neighlist_element_neighbors(self.idx, element)
return iatom, neighbors

861
python/lammps/pylammps.py Normal file
View File

@ -0,0 +1,861 @@
# ----------------------------------------------------------------------
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
# http://lammps.sandia.gov, Sandia National Laboratories
# Steve Plimpton, sjplimp@sandia.gov
#
# Copyright (2003) Sandia Corporation. Under the terms of Contract
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
# certain rights in this software. This software is distributed under
# the GNU General Public License.
#
# See the README file in the top-level LAMMPS directory.
# -------------------------------------------------------------------------
################################################################################
# Alternative Python Wrapper
# Written by Richard Berger <richard.berger@temple.edu>
################################################################################
# for python2/3 compatibility
from __future__ import print_function
import os
import re
import select
import sys
from collections import namedtuple
from .core import lammps
class OutputCapture(object):
""" Utility class to capture LAMMPS library output """
def __init__(self):
self.stdout_pipe_read, self.stdout_pipe_write = os.pipe()
self.stdout_fd = 1
def __enter__(self):
self.stdout = os.dup(self.stdout_fd)
os.dup2(self.stdout_pipe_write, self.stdout_fd)
return self
def __exit__(self, type, value, tracebac):
os.dup2(self.stdout, self.stdout_fd)
os.close(self.stdout)
os.close(self.stdout_pipe_read)
os.close(self.stdout_pipe_write)
# check if we have more to read from the pipe
def more_data(self, pipe):
r, _, _ = select.select([pipe], [], [], 0)
return bool(r)
# read the whole pipe
def read_pipe(self, pipe):
out = ""
while self.more_data(pipe):
out += os.read(pipe, 1024).decode()
return out
@property
def output(self):
return self.read_pipe(self.stdout_pipe_read)
# -------------------------------------------------------------------------
class Variable(object):
def __init__(self, pylammps_instance, name, style, definition):
self._pylmp = pylammps_instance
self.name = name
self.style = style
self.definition = definition.split()
@property
def value(self):
if self.style == 'atom':
return list(self._pylmp.lmp.extract_variable(self.name, "all", 1))
else:
value = self._pylmp.lmp_print('"${%s}"' % self.name).strip()
try:
return float(value)
except ValueError:
return value
# -------------------------------------------------------------------------
class AtomList(object):
"""
A dynamic list of atoms that returns either an :py:class:`Atom` or
:py:class:`Atom2D` instance for each atom. Instances are only allocated
when accessed.
:ivar natoms: total number of atoms
:ivar dimensions: number of dimensions in system
"""
def __init__(self, pylammps_instance):
self._pylmp = pylammps_instance
self.natoms = self._pylmp.system.natoms
self.dimensions = self._pylmp.system.dimensions
self._loaded = {}
def __getitem__(self, index):
"""
Return Atom with given local index
:param index: Local index of atom
:type index: int
:rtype: Atom or Atom2D
"""
if index not in self._loaded:
if self.dimensions == 2:
atom = Atom2D(self._pylmp, index + 1)
else:
atom = Atom(self._pylmp, index + 1)
self._loaded[index] = atom
return self._loaded[index]
def __len__(self):
return self.natoms
# -------------------------------------------------------------------------
class Atom(object):
"""
A wrapper class then represents a single atom inside of LAMMPS
It provides access to properties of the atom and allows you to change some of them.
"""
def __init__(self, pylammps_instance, index):
self._pylmp = pylammps_instance
self.index = index
@property
def id(self):
"""
Return the atom ID
:type: int
"""
return int(self._pylmp.eval("id[%d]" % self.index))
@property
def type(self):
"""
Return the atom type
:type: int
"""
return int(self._pylmp.eval("type[%d]" % self.index))
@property
def mol(self):
"""
Return the atom molecule index
:type: int
"""
return self._pylmp.eval("mol[%d]" % self.index)
@property
def mass(self):
"""
Return the atom mass
:type: float
"""
return self._pylmp.eval("mass[%d]" % self.index)
@property
def position(self):
"""
:getter: Return position of atom
:setter: Set position of atom
:type: tuple (float, float, float)
"""
return (self._pylmp.eval("x[%d]" % self.index),
self._pylmp.eval("y[%d]" % self.index),
self._pylmp.eval("z[%d]" % self.index))
@position.setter
def position(self, value):
"""
:getter: Return velocity of atom
:setter: Set velocity of atom
:type: tuple (float, float, float)
"""
self._pylmp.set("atom", self.index, "x", value[0])
self._pylmp.set("atom", self.index, "y", value[1])
self._pylmp.set("atom", self.index, "z", value[2])
@property
def velocity(self):
return (self._pylmp.eval("vx[%d]" % self.index),
self._pylmp.eval("vy[%d]" % self.index),
self._pylmp.eval("vz[%d]" % self.index))
@velocity.setter
def velocity(self, value):
self._pylmp.set("atom", self.index, "vx", value[0])
self._pylmp.set("atom", self.index, "vy", value[1])
self._pylmp.set("atom", self.index, "vz", value[2])
@property
def force(self):
"""
Return the total force acting on the atom
:type: tuple (float, float, float)
"""
return (self._pylmp.eval("fx[%d]" % self.index),
self._pylmp.eval("fy[%d]" % self.index),
self._pylmp.eval("fz[%d]" % self.index))
@property
def charge(self):
"""
Return the atom charge
:type: float
"""
return self._pylmp.eval("q[%d]" % self.index)
# -------------------------------------------------------------------------
class Atom2D(Atom):
"""
A wrapper class then represents a single 2D atom inside of LAMMPS
Inherits all properties from the :py:class:`Atom` class, but returns 2D versions
of position, velocity, and force.
It provides access to properties of the atom and allows you to change some of them.
"""
def __init__(self, pylammps_instance, index):
super(Atom2D, self).__init__(pylammps_instance, index)
@property
def position(self):
"""
:getter: Return position of atom
:setter: Set position of atom
:type: tuple (float, float)
"""
return (self._pylmp.eval("x[%d]" % self.index),
self._pylmp.eval("y[%d]" % self.index))
@position.setter
def position(self, value):
self._pylmp.set("atom", self.index, "x", value[0])
self._pylmp.set("atom", self.index, "y", value[1])
@property
def velocity(self):
"""
:getter: Return velocity of atom
:setter: Set velocity of atom
:type: tuple (float, float)
"""
return (self._pylmp.eval("vx[%d]" % self.index),
self._pylmp.eval("vy[%d]" % self.index))
@velocity.setter
def velocity(self, value):
self._pylmp.set("atom", self.index, "vx", value[0])
self._pylmp.set("atom", self.index, "vy", value[1])
@property
def force(self):
"""
Return the total force acting on the atom
:type: tuple (float, float)
"""
return (self._pylmp.eval("fx[%d]" % self.index),
self._pylmp.eval("fy[%d]" % self.index))
# -------------------------------------------------------------------------
class variable_set:
def __init__(self, name, variable_dict):
self._name = name
array_pattern = re.compile(r"(?P<arr>.+)\[(?P<index>[0-9]+)\]")
for key, value in variable_dict.items():
m = array_pattern.match(key)
if m:
g = m.groupdict()
varname = g['arr']
idx = int(g['index'])
if varname not in self.__dict__:
self.__dict__[varname] = {}
self.__dict__[varname][idx] = value
else:
self.__dict__[key] = value
def __str__(self):
return "{}({})".format(self._name, ','.join(["{}={}".format(k, self.__dict__[k]) for k in self.__dict__.keys() if not k.startswith('_')]))
def __repr__(self):
return self.__str__()
# -------------------------------------------------------------------------
def get_thermo_data(output):
""" traverse output of runs and extract thermo data columns """
if isinstance(output, str):
lines = output.splitlines()
else:
lines = output
runs = []
columns = []
in_run = False
current_run = {}
for line in lines:
if line.startswith("Per MPI rank memory allocation"):
in_run = True
elif in_run and len(columns) == 0:
# first line after memory usage are column names
columns = line.split()
current_run = {}
for col in columns:
current_run[col] = []
elif line.startswith("Loop time of "):
in_run = False
columns = None
thermo_data = variable_set('ThermoData', current_run)
r = {'thermo' : thermo_data }
runs.append(namedtuple('Run', list(r.keys()))(*list(r.values())))
elif in_run and len(columns) > 0:
items = line.split()
# Convert thermo output and store it.
# It must have the same number of columns and
# all of them must be convertible to floats.
# Otherwise we ignore the line
if len(items) == len(columns):
try:
values = [float(x) for x in items]
for i, col in enumerate(columns):
current_run[col].append(values[i])
except ValueError:
pass
return runs
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
class PyLammps(object):
"""
This is a Python wrapper class around the lower-level
:py:class:`lammps` class, exposing a more Python-like,
object-oriented interface for prototyping system inside of IPython and
Jupyter notebooks.
It either creates its own instance of :py:class:`lammps` or can be
initialized with an existing instance. The arguments are the same of the
lower-level interface. The original interface can still be accessed via
:py:attr:`PyLammps.lmp`.
:param name: "machine" name of the shared LAMMPS library ("mpi" loads ``liblammps_mpi.so``, "" loads ``liblammps.so``)
:type name: string
:param cmdargs: list of command line arguments to be passed to the :cpp:func:`lammps_open` function. The executable name is automatically added.
:type cmdargs: list
:param ptr: pointer to a LAMMPS C++ class instance when called from an embedded Python interpreter. None means load symbols from shared library.
:type ptr: pointer
:param comm: MPI communicator (as provided by `mpi4py <mpi4py_docs_>`_). ``None`` means use ``MPI_COMM_WORLD`` implicitly.
:type comm: MPI_Comm
:ivar lmp: instance of original LAMMPS Python interface
:vartype lmp: :py:class:`lammps`
:ivar runs: list of completed runs, each storing the thermo output
:vartype run: list
"""
def __init__(self, name="", cmdargs=None, ptr=None, comm=None):
self.has_echo = False
if cmdargs:
if '-echo' in cmdargs:
idx = cmdargs.index('-echo')
# ensures that echo line is ignored during output capture
self.has_echo = idx+1 < len(cmdargs) and cmdargs[idx+1] in ('screen', 'both')
if ptr:
if isinstance(ptr,PyLammps):
self.lmp = ptr.lmp
elif isinstance(ptr,lammps):
self.lmp = ptr
else:
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._cmd_history = []
self.runs = []
def __del__(self):
if self.lmp: self.lmp.close()
self.lmp = None
def close(self):
"""Explicitly delete a LAMMPS instance
This is a wrapper around the :py:meth:`lammps.close` of the Python interface.
"""
if self.lmp: self.lmp.close()
self.lmp = None
def version(self):
"""Return a numerical representation of the LAMMPS version in use.
This is a wrapper around the :py:meth:`lammps.version` function of the Python interface.
:return: version number
:rtype: int
"""
return self.lmp.version()
def file(self, file):
"""Read LAMMPS commands from a file.
This is a wrapper around the :py:meth:`lammps.file` function of the Python interface.
:param path: Name of the file/path with LAMMPS commands
:type path: string
"""
self.lmp.file(file)
def write_script(self, filepath):
"""
Write LAMMPS script file containing all commands executed up until now
:param filepath: path to script file that should be written
:type filepath: string
"""
with open(filepath, "w") as f:
for cmd in self._cmd_history:
print(cmd, file=f)
def command(self, cmd):
"""
Execute LAMMPS command
All commands executed will be stored in a command history which can be
written to a file using :py:meth:`PyLammps.write_script()`
:param cmd: command string that should be executed
:type: cmd: string
"""
self.lmp.command(cmd)
self._cmd_history.append(cmd)
def run(self, *args, **kwargs):
"""
Execute LAMMPS run command with given arguments
All thermo output during the run is captured and saved as new entry in
:py:attr:`PyLammps.runs`. The latest run can be retrieved by
:py:attr:`PyLammps.last_run`.
"""
output = self.__getattr__('run')(*args, **kwargs)
comm = self.lmp.get_mpi_comm()
if comm:
output = self.lmp.comm.bcast(output, root=0)
self.runs += get_thermo_data(output)
return output
@property
def last_run(self):
"""
Return data produced of last completed run command
:getter: Returns an object containing information about the last run command
:type: dict
"""
if len(self.runs) > 0:
return self.runs[-1]
return None
@property
def atoms(self):
"""
All atoms of this LAMMPS instance
:getter: Returns a list of atoms currently in the system
:type: AtomList
"""
return AtomList(self)
@property
def system(self):
"""
The system state of this LAMMPS instance
:getter: Returns an object with properties storing the current system state
:type: namedtuple
"""
output = self.info("system")
d = self._parse_info_system(output)
return namedtuple('System', d.keys())(*d.values())
@property
def communication(self):
"""
The communication state of this LAMMPS instance
:getter: Returns an object with properties storing the current communication state
:type: namedtuple
"""
output = self.info("communication")
d = self._parse_info_communication(output)
return namedtuple('Communication', d.keys())(*d.values())
@property
def computes(self):
"""
The list of active computes of this LAMMPS instance
:getter: Returns a list of computes that are currently active in this LAMMPS instance
:type: list
"""
output = self.info("computes")
return self._parse_element_list(output)
@property
def dumps(self):
"""
The list of active dumps of this LAMMPS instance
:getter: Returns a list of dumps that are currently active in this LAMMPS instance
:type: list
"""
output = self.info("dumps")
return self._parse_element_list(output)
@property
def fixes(self):
"""
The list of active fixes of this LAMMPS instance
:getter: Returns a list of fixes that are currently active in this LAMMPS instance
:type: list
"""
output = self.info("fixes")
return self._parse_element_list(output)
@property
def groups(self):
"""
The list of active atom groups of this LAMMPS instance
:getter: Returns a list of atom groups that are currently active in this LAMMPS instance
:type: list
"""
output = self.info("groups")
return self._parse_groups(output)
@property
def variables(self):
"""
Returns a dictionary of all variables defined in the current LAMMPS instance
:getter: Returns a dictionary of all variables that are defined in this LAMMPS instance
:type: dict
"""
output = self.info("variables")
vars = {}
for v in self._parse_element_list(output):
vars[v['name']] = Variable(self, v['name'], v['style'], v['def'])
return vars
def eval(self, expr):
"""
Evaluate expression
:param expr: the expression string that should be evaluated inside of LAMMPS
:type expr: string
:return: the value of the evaluated expression
:rtype: float if numeric, string otherwise
"""
value = self.lmp_print('"$(%s)"' % expr).strip()
try:
return float(value)
except ValueError:
return value
def _split_values(self, line):
return [x.strip() for x in line.split(',')]
def _get_pair(self, value):
return [x.strip() for x in value.split('=')]
def _parse_info_system(self, output):
lines = output[6:-2]
system = {}
for line in lines:
if line.startswith("Units"):
system['units'] = self._get_pair(line)[1]
elif line.startswith("Atom style"):
system['atom_style'] = self._get_pair(line)[1]
elif line.startswith("Atom map"):
system['atom_map'] = self._get_pair(line)[1]
elif line.startswith("Atoms"):
parts = self._split_values(line)
system['natoms'] = int(self._get_pair(parts[0])[1])
system['ntypes'] = int(self._get_pair(parts[1])[1])
system['style'] = self._get_pair(parts[2])[1]
elif line.startswith("Kspace style"):
system['kspace_style'] = self._get_pair(line)[1]
elif line.startswith("Dimensions"):
system['dimensions'] = int(self._get_pair(line)[1])
elif line.startswith("Orthogonal box"):
system['orthogonal_box'] = [float(x) for x in self._get_pair(line)[1].split('x')]
elif line.startswith("Boundaries"):
system['boundaries'] = self._get_pair(line)[1]
elif line.startswith("xlo"):
keys, values = [self._split_values(x) for x in self._get_pair(line)]
for key, value in zip(keys, values):
system[key] = float(value)
elif line.startswith("ylo"):
keys, values = [self._split_values(x) for x in self._get_pair(line)]
for key, value in zip(keys, values):
system[key] = float(value)
elif line.startswith("zlo"):
keys, values = [self._split_values(x) for x in self._get_pair(line)]
for key, value in zip(keys, values):
system[key] = float(value)
elif line.startswith("Molecule type"):
system['molecule_type'] = self._get_pair(line)[1]
elif line.startswith("Bonds"):
parts = self._split_values(line)
system['nbonds'] = int(self._get_pair(parts[0])[1])
system['nbondtypes'] = int(self._get_pair(parts[1])[1])
system['bond_style'] = self._get_pair(parts[2])[1]
elif line.startswith("Angles"):
parts = self._split_values(line)
system['nangles'] = int(self._get_pair(parts[0])[1])
system['nangletypes'] = int(self._get_pair(parts[1])[1])
system['angle_style'] = self._get_pair(parts[2])[1]
elif line.startswith("Dihedrals"):
parts = self._split_values(line)
system['ndihedrals'] = int(self._get_pair(parts[0])[1])
system['ndihedraltypes'] = int(self._get_pair(parts[1])[1])
system['dihedral_style'] = self._get_pair(parts[2])[1]
elif line.startswith("Impropers"):
parts = self._split_values(line)
system['nimpropers'] = int(self._get_pair(parts[0])[1])
system['nimpropertypes'] = int(self._get_pair(parts[1])[1])
system['improper_style'] = self._get_pair(parts[2])[1]
return system
def _parse_info_communication(self, output):
lines = output[6:-3]
comm = {}
for line in lines:
if line.startswith("MPI library"):
comm['mpi_version'] = line.split(':')[1].strip()
elif line.startswith("Comm style"):
parts = self._split_values(line)
comm['comm_style'] = self._get_pair(parts[0])[1]
comm['comm_layout'] = self._get_pair(parts[1])[1]
elif line.startswith("Processor grid"):
comm['proc_grid'] = [int(x) for x in self._get_pair(line)[1].split('x')]
elif line.startswith("Communicate velocities for ghost atoms"):
comm['ghost_velocity'] = (self._get_pair(line)[1] == "yes")
elif line.startswith("Nprocs"):
parts = self._split_values(line)
comm['nprocs'] = int(self._get_pair(parts[0])[1])
comm['nthreads'] = int(self._get_pair(parts[1])[1])
return comm
def _parse_element_list(self, output):
lines = output[6:-3]
elements = []
for line in lines:
element_info = self._split_values(line.split(':')[1].strip())
element = {'name': element_info[0]}
for key, value in [self._get_pair(x) for x in element_info[1:]]:
element[key] = value
elements.append(element)
return elements
def _parse_groups(self, output):
lines = output[6:-3]
groups = []
group_pattern = re.compile(r"(?P<name>.+) \((?P<type>.+)\)")
for line in lines:
m = group_pattern.match(line.split(':')[1].strip())
group = {'name': m.group('name'), 'type': m.group('type')}
groups.append(group)
return groups
def lmp_print(self, s):
""" needed for Python2 compatibility, since print is a reserved keyword """
return self.__getattr__("print")(s)
def __dir__(self):
return ['angle_coeff', 'angle_style', 'atom_modify', 'atom_style', 'atom_style',
'bond_coeff', 'bond_style', 'boundary', 'change_box', 'communicate', 'compute',
'create_atoms', 'create_box', 'delete_atoms', 'delete_bonds', 'dielectric',
'dihedral_coeff', 'dihedral_style', 'dimension', 'dump', 'fix', 'fix_modify',
'group', 'improper_coeff', 'improper_style', 'include', 'kspace_modify',
'kspace_style', 'lattice', 'mass', 'minimize', 'min_style', 'neighbor',
'neigh_modify', 'newton', 'nthreads', 'pair_coeff', 'pair_modify',
'pair_style', 'processors', 'read', 'read_data', 'read_restart', 'region',
'replicate', 'reset_timestep', 'restart', 'run', 'run_style', 'thermo',
'thermo_modify', 'thermo_style', 'timestep', 'undump', 'unfix', 'units',
'variable', 'velocity', 'write_restart']
def __getattr__(self, name):
"""
This method is where the Python 'magic' happens. If a method is not
defined by the class PyLammps, it assumes it is a LAMMPS command. It takes
all the arguments, concatinates them to a single string, and executes it using
:py:meth:`lammps.PyLammps.command()`.
:param verbose: Print output of command
:type verbose: bool
:return: line or list of lines of output, None if no output
:rtype: list or string
"""
def handler(*args, **kwargs):
cmd_args = [name] + [str(x) for x in args]
with OutputCapture() as capture:
cmd = ' '.join(cmd_args)
self.command(cmd)
output = capture.output
if 'verbose' in kwargs and kwargs['verbose']:
print(output)
lines = output.splitlines()
if self.has_echo:
lines = lines[1:]
if len(lines) > 1:
return lines
elif len(lines) == 1:
return lines[0]
return None
return handler
class IPyLammps(PyLammps):
"""
IPython wrapper for LAMMPS which adds embedded graphics capabilities to PyLammmps interface
It either creates its own instance of :py:class:`lammps` or can be
initialized with an existing instance. The arguments are the same of the
lower-level interface. The original interface can still be accessed via
:py:attr:`PyLammps.lmp`.
:param name: "machine" name of the shared LAMMPS library ("mpi" loads ``liblammps_mpi.so``, "" loads ``liblammps.so``)
:type name: string
:param cmdargs: list of command line arguments to be passed to the :cpp:func:`lammps_open` function. The executable name is automatically added.
:type cmdargs: list
:param ptr: pointer to a LAMMPS C++ class instance when called from an embedded Python interpreter. None means load symbols from shared library.
:type ptr: pointer
:param comm: MPI communicator (as provided by `mpi4py <mpi4py_docs_>`_). ``None`` means use ``MPI_COMM_WORLD`` implicitly.
:type comm: MPI_Comm
"""
def __init__(self,name="",cmdargs=None,ptr=None,comm=None):
super(IPyLammps, self).__init__(name=name,cmdargs=cmdargs,ptr=ptr,comm=comm)
def image(self, filename="snapshot.png", group="all", color="type", diameter="type",
size=None, view=None, center=None, up=None, zoom=1.0, background_color="white"):
""" Generate image using write_dump command and display it
See :doc:`dump image <dump_image>` for more information.
:param filename: Name of the image file that should be generated. The extension determines whether it is PNG or JPEG
:type filename: string
:param group: the group of atoms write_image should use
:type group: string
:param color: name of property used to determine color
:type color: string
:param diameter: name of property used to determine atom diameter
:type diameter: string
:param size: dimensions of image
:type size: tuple (width, height)
:param view: view parameters
:type view: tuple (theta, phi)
:param center: center parameters
:type center: tuple (flag, center_x, center_y, center_z)
:param up: vector pointing to up direction
:type up: tuple (up_x, up_y, up_z)
:param zoom: zoom factor
:type zoom: float
:param background_color: background color of scene
:type background_color: string
:return: Image instance used to display image in notebook
:rtype: :py:class:`IPython.core.display.Image`
"""
cmd_args = [group, "image", filename, color, diameter]
if size:
width = size[0]
height = size[1]
cmd_args += ["size", width, height]
if view:
theta = view[0]
phi = view[1]
cmd_args += ["view", theta, phi]
if center:
flag = center[0]
Cx = center[1]
Cy = center[2]
Cz = center[3]
cmd_args += ["center", flag, Cx, Cy, Cz]
if up:
Ux = up[0]
Uy = up[1]
Uz = up[2]
cmd_args += ["up", Ux, Uy, Uz]
if zoom:
cmd_args += ["zoom", zoom]
cmd_args.append("modify backcolor " + background_color)
self.write_dump(*cmd_args)
from IPython.core.display import Image
return Image(filename)
def video(self, filename):
"""
Load video from file
Can be used to visualize videos from :doc:`dump movie <dump_image>`.
:param filename: Path to video file
:type filename: string
:return: HTML Video Tag used by notebook to embed a video
:rtype: :py:class:`IPython.display.HTML`
"""
from IPython.display import HTML
return HTML("<video controls><source src=\"" + filename + "\"></video>")

26
python/setup.py Normal file
View File

@ -0,0 +1,26 @@
# this only installs the LAMMPS python package
# it assumes the LAMMPS shared library is already installed
from distutils.core import setup
import os
LAMMPS_PYTHON_DIR = os.path.dirname(os.path.realpath(__file__))
LAMMPS_DIR = os.path.dirname(LAMMPS_PYTHON_DIR)
LAMMPS_SOURCE_DIR = os.path.join(LAMMPS_DIR, 'src')
def get_lammps_version():
with open(os.path.join(LAMMPS_SOURCE_DIR, 'version.h'), 'r') as f:
line = f.readline()
start_pos = line.find('"')+1
end_pos = line.find('"', start_pos)
return "".join(line[start_pos:end_pos].split())
setup(
name = "lammps",
version = get_lammps_version(),
author = "Steve Plimpton",
author_email = "sjplimp@sandia.gov",
url = "https://lammps.sandia.gov",
description = "LAMMPS Molecular Dynamics Python package",
license = "GPL",
packages=["lammps"]
)

View File

@ -79,7 +79,7 @@ size_t ZstdFileWriter::write(const void * buffer, size_t length)
do {
ZSTD_outBuffer output = { out_buffer, out_buffer_size, 0 };
size_t const remaining = ZSTD_compressStream2(cctx, &output, &input, mode);
ZSTD_compressStream2(cctx, &output, &input, mode);
fwrite(out_buffer, sizeof(char), output.pos, fp);
} while(input.pos < input.size);

View File

@ -291,10 +291,10 @@ void KimInteractions::KIM_SET_TYPE_PARAMETERS(const std::string &input_line) con
MPI_Bcast(&n,1,MPI_INT,0,world);
MPI_Bcast(line,n,MPI_CHAR,0,world);
if (ptr = strchr(line,'#')) *ptr = '\0';
if (strspn(line," \t\n\r") == strlen(line)) continue;
auto trimmed = utils::trim_comment(line);
if (trimmed.find_first_not_of(" \t\n\r") == std::string::npos) continue;
words = utils::split_words(line);
words = utils::split_words(trimmed);
if (key == "pair") {
for (int ia = 0; ia < atom->ntypes; ++ia) {
for (int ib = ia; ib < atom->ntypes; ++ib)

View File

@ -890,7 +890,7 @@ void PairKIM::set_argument_pointers()
KIM_SUPPORT_STATUS_notSupported)) {
if (KIM_SupportStatus_Equal(kim_model_support_for_energy,
KIM_SUPPORT_STATUS_required)
|| (eflag_global == 1)) {
|| (eflag_global != 0)) {
kimerror = kimerror ||
KIM_ComputeArguments_SetArgumentPointerDouble(
pargs,KIM_COMPUTE_ARGUMENT_NAME_partialEnergy,&(eng_vdwl));
@ -905,7 +905,7 @@ void PairKIM::set_argument_pointers()
// Set KIM pointer appropriately for particalEnergy
if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy,
KIM_SUPPORT_STATUS_required)
&& (eflag_atom != 1)) {
&& (eflag_atom == 0)) {
// reallocate per-atom energy array if necessary
if (atom->nmax > maxeatom) {
maxeatom = atom->nmax;
@ -916,13 +916,13 @@ void PairKIM::set_argument_pointers()
if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy,
KIM_SUPPORT_STATUS_optional)
&& (eflag_atom != 1)) {
&& (eflag_atom == 0)) {
kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble(
pargs,
KIM_COMPUTE_ARGUMENT_NAME_partialParticleEnergy,
static_cast<double *>(nullptr));
} else if (KIM_SupportStatus_NotEqual(kim_model_support_for_particleEnergy,
KIM_SUPPORT_STATUS_notSupported)) {
KIM_SUPPORT_STATUS_notSupported)) {
kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble(
pargs, KIM_COMPUTE_ARGUMENT_NAME_partialParticleEnergy, eatom);
}
@ -940,9 +940,9 @@ void PairKIM::set_argument_pointers()
}
// Set KIM pointer appropriately for particleVirial
if ((vflag_atom == 0) &&
KIM_SupportStatus_Equal(kim_model_support_for_particleVirial,
KIM_SUPPORT_STATUS_required)) {
if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial,
KIM_SUPPORT_STATUS_required)
&& (vflag_atom == 0)) {
// reallocate per-atom virial array if necessary
if (atom->nmax > maxvatom) {
maxvatom = atom->nmax;
@ -951,9 +951,9 @@ void PairKIM::set_argument_pointers()
}
}
if ((vflag_atom == 0) &&
KIM_SupportStatus_Equal(kim_model_support_for_particleVirial,
KIM_SUPPORT_STATUS_optional)) {
if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial,
KIM_SUPPORT_STATUS_optional)
&& (vflag_atom == 0)) {
kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble(
pargs,
KIM_COMPUTE_ARGUMENT_NAME_partialParticleVirial,

View File

@ -278,7 +278,7 @@ mpi-stubs:
sinclude ../lib/python/Makefile.lammps
install-python:
@$(PYTHON) ../python/install.py -v ../src/version.h \
-m ../python/lammps.py -l ../src/liblammps.so
-p ../python/lammps -l ../src/liblammps.so
# Create a tarball of src dir and packages

View File

@ -67,7 +67,15 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp)
#endif
Py_Initialize();
PyEval_InitThreads();
// only needed for Python 2.x and Python 3 < 3.7
// With Python 3.7 this function is now called by Py_Initialize()
// Deprecated since version 3.9, will be removed in version 3.11
#if PY_MAJOR_VERSION < 3 || PY_MINOR_VERSION < 7
if(!PyEval_ThreadsInitialized()) {
PyEval_InitThreads();
}
#endif
PyGILState_STATE gstate = PyGILState_Ensure();

View File

@ -554,7 +554,10 @@ void TAD::log_event(int ievent)
timer->barrier_start();
modify->addstep_compute_all(update->ntimestep);
update->integrate->setup_minimal(1);
// must reset whichflag so that computes won't fail.
update->whichflag = 1;
output->write_dump(update->ntimestep);
update->whichflag = 0;
timer->barrier_stop();
time_output += timer->get_wall(Timer::TOTAL);
}

View File

@ -173,6 +173,7 @@ void BondOxdnaFene::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
@ -190,9 +191,9 @@ void BondOxdnaFene::compute(int eflag, int vflag)
b = bondlist[in][0];
type = bondlist[in][2];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM-backbone site a and b

View File

@ -133,6 +133,7 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -154,7 +155,7 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
// vector COM a - stacking site a
@ -178,7 +179,7 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag)
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM b - stacking site b

View File

@ -102,6 +102,7 @@ void PairOxdna2Dh::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -120,7 +121,7 @@ void PairOxdna2Dh::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
// vector COM-backbone site a
@ -140,7 +141,7 @@ void PairOxdna2Dh::compute(int eflag, int vflag)
b &= NEIGHMASK;
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM-backbone site b

View File

@ -145,6 +145,7 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -166,7 +167,7 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
// vector COM a - stacking site a
@ -190,7 +191,7 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag)
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM b - stacking site b

View File

@ -134,6 +134,7 @@ void PairOxdnaExcv::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -152,7 +153,7 @@ void PairOxdnaExcv::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
// vector COM - backbone and base site a
@ -177,7 +178,7 @@ void PairOxdnaExcv::compute(int eflag, int vflag)
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM - backbone and base site b

View File

@ -164,6 +164,7 @@ void PairOxdnaHbond::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -185,7 +186,7 @@ void PairOxdnaHbond::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
ra_chb[0] = d_chb*ax[0];
@ -203,7 +204,7 @@ void PairOxdnaHbond::compute(int eflag, int vflag)
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
rb_chb[0] = d_chb*bx[0];

View File

@ -245,6 +245,7 @@ void PairOxdnaStk::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,in,atype,btype;
@ -262,9 +263,9 @@ void PairOxdnaStk::compute(int eflag, int vflag)
a = bondlist[in][1];
b = bondlist[in][0];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM a - stacking site a

View File

@ -142,6 +142,7 @@ void PairOxdnaXstk::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -163,7 +164,7 @@ void PairOxdnaXstk::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
ra_chb[0] = d_chb*ax[0];
@ -181,7 +182,7 @@ void PairOxdnaXstk::compute(int eflag, int vflag)
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
rb_chb[0] = d_chb*bx[0];

View File

@ -262,6 +262,7 @@ void PairOxrna2Stk::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,in,atype,btype;
@ -279,9 +280,9 @@ void PairOxrna2Stk::compute(int eflag, int vflag)
a = bondlist[in][1];
b = bondlist[in][0];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
// vector COM a - 3'-stacking site a

View File

@ -135,6 +135,7 @@ void PairOxrna2Xstk::compute(int eflag, int vflag)
AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
int *ellipsoid = atom->ellipsoid;
int a,b,ia,ib,anum,bnum,atype,btype;
@ -156,7 +157,7 @@ void PairOxrna2Xstk::compute(int eflag, int vflag)
a = alist[ia];
atype = type[a];
qa=bonus[a].quat;
qa=bonus[ellipsoid[a]].quat;
MathExtra::q_to_exyz(qa,ax,ay,az);
ra_chb[0] = d_chb*ax[0];
@ -174,7 +175,7 @@ void PairOxrna2Xstk::compute(int eflag, int vflag)
btype = type[b];
qb=bonus[b].quat;
qb=bonus[ellipsoid[b]].quat;
MathExtra::q_to_exyz(qb,bx,by,bz);
rb_chb[0] = d_chb*bx[0];

View File

@ -546,7 +546,7 @@ void PairMesoCNT::bond_neigh()
if (i2 > nlocal-1 && false) numneigh2 = 0;
else numneigh2 = numneigh[i2];
int numneigh_max_local = numneigh1 + numneigh1;
int numneigh_max_local = numneigh1 + numneigh2;
if (numneigh_max_local > numneigh_max) numneigh_max = numneigh_max_local;
}
if (numneigh_max > reduced_neigh_size) {

View File

@ -510,33 +510,28 @@ void PairMESONTTPM::compute(int eflag, int vflag) {
buckling[idx] = b_sort[i];
}
if (eflag_global) {
eng_vdwl = 0.0; energy_s = 0.0;
energy_b = 0.0; energy_t = 0.0;
energy_s = energy_b = energy_t = 0.0;
for (int i = 0; i < nall; i++) {
int idx = ntlist.get_idx(i);
energy_s += u_ts_sort[i];
energy_b += u_tb_sort[i];
energy_t += u_tt_sort[i];
}
eng_vdwl = energy_s + energy_b + energy_t;
eng_vdwl += energy_s + energy_b + energy_t;
}
if (eflag_atom) {
for (int i = 0; i < ntot; i++) {
eatom[i] = 0.0; eatom_s[i] = 0.0;
eatom_b[i] = 0.0; eatom_t[i] = 0.0;
}
for (int i = 0; i < ntot; i++)
eatom_s[i] = eatom_b[i] = eatom_t[i] = 0.0;
for (int i = 0; i < nall; i++) {
int idx = ntlist.get_idx(i);
eatom_s[idx] = u_ts_sort[i];
eatom_b[idx] = u_tb_sort[i];
eatom_t[idx] = u_tt_sort[i];
eatom[idx] = u_ts_sort[i] + u_tb_sort[i] + u_tt_sort[i];
eatom_s[idx] += u_ts_sort[i];
eatom_b[idx] += u_tb_sort[i];
eatom_t[idx] += u_tt_sort[i];
eatom[idx] += u_ts_sort[i] + u_tb_sort[i] + u_tt_sort[i];
}
}
if (vflag_global) {
for (int i = 0; i < 6; i++) virial[i] = 0.0;
for (int i = 0; i < nall; i++) {
int idx = ntlist.get_idx(i);
virial[0] += s_sort[9*i+0]; //xx
virial[1] += s_sort[9*i+4]; //yy
virial[2] += s_sort[9*i+8]; //zz
@ -546,16 +541,14 @@ void PairMESONTTPM::compute(int eflag, int vflag) {
}
}
if (vflag_atom) {
for (int i = 0; i < ntot; i++)
for (int j = 0; j < 6; j++) vatom[i][j] = 0.0;
for (int i = 0; i < nall; i++) {
int idx = ntlist.get_idx(i);
vatom[idx][0] = s_sort[9*i+0]; //xx
vatom[idx][1] = s_sort[9*i+4]; //yy
vatom[idx][2] = s_sort[9*i+8]; //zz
vatom[idx][3] = s_sort[9*i+1]; //xy
vatom[idx][4] = s_sort[9*i+2]; //xz
vatom[idx][5] = s_sort[9*i+5]; //yz
vatom[idx][0] += s_sort[9*i+0]; //xx
vatom[idx][1] += s_sort[9*i+4]; //yy
vatom[idx][2] += s_sort[9*i+8]; //zz
vatom[idx][3] += s_sort[9*i+1]; //xy
vatom[idx][4] += s_sort[9*i+2]; //xz
vatom[idx][5] += s_sort[9*i+5]; //yz
}
}

View File

@ -62,7 +62,7 @@ void AngleGaussian::compute(int eflag, int vflag)
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,tk;
double dtheta;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double prefactor, exponent, g_i, sum_g_i, sum_numerator;
@ -331,7 +331,6 @@ double AngleGaussian::single(int type, int i1, int i2, int i3)
double theta = acos(c) ;
double sum_g_i = 0.0;
double sum_numerator = 0.0;
for (int i = 0; i < nterms[type]; i++) {
double dtheta = theta - theta0[type][i];
double prefactor = (alpha[type][i]/(width[type][i]*sqrt(MY_PI2)));

View File

@ -62,9 +62,9 @@ static const char cite_fix_electron_stopping_fit_c[] =
// ---------------------------------------------------------------------
FixElectronStoppingFit::FixElectronStoppingFit(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp,narg,arg), energy_coh_in(nullptr), drag_fac_in_1(nullptr),
drag_fac_in_2(nullptr), drag_fac_1(nullptr), drag_fac_2(nullptr),
v_min_sq(nullptr), v_max_sq(nullptr)
Fix(lmp,narg,arg), energy_coh_in(nullptr), v_min_sq(nullptr), v_max_sq(nullptr),
drag_fac_in_1(nullptr), drag_fac_in_2(nullptr),
drag_fac_1(nullptr), drag_fac_2(nullptr)
{
if (lmp->citeme) lmp->citeme->add(cite_fix_electron_stopping_fit_c);
@ -151,7 +151,7 @@ void FixElectronStoppingFit::setup(int vflag)
// ---------------------------------------------------------------------
void FixElectronStoppingFit::post_force(int vflag)
void FixElectronStoppingFit::post_force(int /*vflag*/)
{
double **v = atom->v;
double **f = atom->f;
@ -192,7 +192,7 @@ void FixElectronStoppingFit::post_force(int vflag)
// ---------------------------------------------------------------------
void FixElectronStoppingFit::post_force_respa(int vflag, int ilevel, int iloop)
void FixElectronStoppingFit::post_force_respa(int vflag, int ilevel, int /*iloop*/)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
};

View File

@ -292,7 +292,7 @@ void DumpNetCDFMPIIO::openfile()
if (singlefile_opened) return;
singlefile_opened = 1;
NCERRX( ncmpi_open(MPI_COMM_WORLD, filecurrent, NC_WRITE, MPI_INFO_NULL,
NCERRX( ncmpi_open(world, filecurrent, NC_WRITE, MPI_INFO_NULL,
&ncid), filecurrent );
// dimensions
@ -372,7 +372,7 @@ void DumpNetCDFMPIIO::openfile()
if (singlefile_opened) return;
singlefile_opened = 1;
NCERRX( ncmpi_create(MPI_COMM_WORLD, filecurrent, NC_64BIT_DATA,
NCERRX( ncmpi_create(world, filecurrent, NC_64BIT_DATA,
MPI_INFO_NULL, &ncid), filecurrent );
// dimensions
@ -748,7 +748,7 @@ void DumpNetCDFMPIIO::write()
nme = count();
int *block_sizes = new int[comm->nprocs];
MPI_Allgather(&nme, 1, MPI_INT, block_sizes, 1, MPI_INT, MPI_COMM_WORLD);
MPI_Allgather(&nme, 1, MPI_INT, block_sizes, 1, MPI_INT, world);
blocki = 0;
for (int i = 0; i < comm->me; i++) blocki += block_sizes[i];
delete [] block_sizes;

View File

@ -76,7 +76,7 @@ FixPlumed::FixPlumed(LAMMPS *lmp, int narg, char **arg) :
// Check API version
int api_version;
int api_version=0;
p->cmd("getApiVersion",&api_version);
if ((api_version < 5) || (api_version > 7))
error->all(FLERR,"Incompatible API version for PLUMED in fix plumed. "

View File

@ -761,15 +761,15 @@ void FixBondReact::post_constructor()
void FixBondReact::init()
{
if (strstr(update->integrate_style,"respa"))
if (utils::strmatch(update->integrate_style,"^respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
// check cutoff for iatomtype,jatomtype
for (int i = 0; i < nreacts; i++) {
if (closeneigh[i] == -1) // indicates will search for non-bonded bonding atoms
if (force->pair == nullptr || cutsq[i][1] > force->pair->cutsq[iatomtype[i]][jatomtype[i]])
error->all(FLERR,"Bond/react: Fix bond/react cutoff is longer than pairwise cutoff");
}
// check cutoff for iatomtype,jatomtype
for (int i = 0; i < nreacts; i++) {
if (closeneigh[i] == -1) // indicates will search for non-bonded bonding atoms
if (force->pair == nullptr || cutsq[i][1] > force->pair->cutsq[iatomtype[i]][jatomtype[i]])
error->all(FLERR,"Bond/react: Fix bond/react cutoff is longer than pairwise cutoff");
}
// need a half neighbor list, built every Nevery steps
int irequest = neighbor->request(this,instance_me);
@ -1068,10 +1068,11 @@ void FixBondReact::far_partner()
continue;
}
if (molecule_keyword[rxnID] == INTER)
if (molecule_keyword[rxnID] == INTER) {
if (atom->molecule[i] == atom->molecule[j]) continue;
else if (molecule_keyword[rxnID] == INTRA)
} else if (molecule_keyword[rxnID] == INTRA) {
if (atom->molecule[i] != atom->molecule[j]) continue;
}
jtype = type[j];
possible = 0;
@ -1152,10 +1153,11 @@ void FixBondReact::close_partner()
if (i_limit_tags[i2] != 0) continue;
if (itype != iatomtype[rxnID] || jtype != jatomtype[rxnID]) continue;
if (molecule_keyword[rxnID] == INTER)
if (molecule_keyword[rxnID] == INTER) {
if (atom->molecule[i1] == atom->molecule[i2]) continue;
else if (molecule_keyword[rxnID] == INTRA)
} else if (molecule_keyword[rxnID] == INTRA) {
if (atom->molecule[i1] != atom->molecule[i2]) continue;
}
delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1];

View File

@ -44,10 +44,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax,
int lgflag = control->lgflag;
int errorflag = 1;
double val;
MPI_Comm comm;
int me;
comm = MPI_COMM_WORLD;
MPI_Comm_rank(comm, &me);
int me = control->me;
s = (char*) malloc(sizeof(char)*MAX_LINE);
tmp = (char**) malloc(sizeof(char*)*MAX_TOKENS);

View File

@ -154,9 +154,9 @@ void AtomVecHybrid::process_args(int narg, char **arg)
}
if (mass_pertype && mass_peratom && comm->me == 0)
error->warning(FLERR,
"Atom_style hybrid defines both pertype and peratom masses "
"- both must be set, only peratom masses will be used");
error->warning(FLERR, "Atom style hybrid defines both, per-type "
"and per-atom masses; both must be set, but only "
"per-atom masses will be used");
// free allstyles created by build_styles()
@ -216,8 +216,8 @@ void AtomVecHybrid::process_args(int narg, char **arg)
char *dup = (char *) dupfield[idup];
ptr = strstr(concat_grow,dup);
if ((ptr && strstr(ptr+1,dup)) && (comm->me == 0))
error->warning(FLERR,fmt::format("Peratom {} is in multiple sub-styles "
"- must be used consistently",dup));
error->warning(FLERR,fmt::format("Per-atom {} is used in multiple sub-"
"styles; must be used consistently",dup));
}
delete [] concat_grow;

View File

@ -375,7 +375,11 @@ struct ostream_params {
};
} // namespace detail
#if defined(__PGI)
static detail::buffer_size buffer_size;
#else
static constexpr detail::buffer_size buffer_size;
#endif
// A fast output stream which is not thread-safe.
class ostream final : private detail::buffer<char> {

View File

@ -1179,6 +1179,8 @@ std::string Info::get_compiler_info()
std::string buf;
#if __clang__
buf = fmt::format("Clang C++ {}", __VERSION__);
#elif __PGI
buf = fmt::format("PGI C++ {}.{}",__PGIC__,__PGIC_MINOR__);
#elif __INTEL_COMPILER
double version = static_cast<double>(__INTEL_COMPILER)*0.01;
buf = fmt::format("Intel C++ {:.2f}.{} / {}", version,

View File

@ -42,7 +42,7 @@
/** Data type constants for extracting data from atoms, computes and fixes
*
* Must be kept in sync with the equivalent constants in lammps.py */
* Must be kept in sync with the equivalent constants in lammps/constants.py */
enum _LMP_DATATYPE_CONST {
LAMMPS_INT = 0, /*!< 32-bit integer (array) */
@ -56,7 +56,7 @@ enum _LMP_DATATYPE_CONST {
/** Style constants for extracting data from computes and fixes.
*
* Must be kept in sync with the equivalent constants in lammps.py */
* Must be kept in sync with the equivalent constants in lammps/constants.py */
enum _LMP_STYLE_CONST {
LMP_STYLE_GLOBAL=0, /*!< return global data */
@ -66,7 +66,7 @@ enum _LMP_STYLE_CONST {
/** Type and size constants for extracting data from computes and fixes.
*
* Must be kept in sync with the equivalent constants in lammps.py */
* Must be kept in sync with the equivalent constants in lammps/constants.py */
enum _LMP_TYPE_CONST {
LMP_TYPE_SCALAR=0, /*!< return scalar */

View File

@ -268,6 +268,8 @@ The typecasts prevent compiler warnings about possible truncation issues.
# define _noopt __attribute__((optnone))
#elif defined(__INTEL_COMPILER)
# define _noopt
#elif defined(__PGI)
# define _noopt
#elif defined(__GNUC__)
# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
# if defined(_FORTIFY_SOURCE) && (_FORTIFY_SOURCE > 0)

View File

@ -2162,12 +2162,15 @@ void Neighbor::build_one(class NeighList *mylist, int preflag)
// if this is copy list and parent is occasional list,
// or this is halffull and parent is occasional list,
// or this is skip list and parent is occasional list,
// insure parent is current
if (mylist->listcopy && mylist->listcopy->occasional)
build_one(mylist->listcopy,preflag);
if (mylist->listfull && mylist->listfull->occasional)
build_one(mylist->listfull,preflag);
if (mylist->listskip && mylist->listskip->occasional)
build_one(mylist->listskip,preflag);
// create stencil if hasn't been created since last setup_bins() call

View File

@ -185,7 +185,7 @@ void Universe::add_world(char *str)
nper = atoi(part.c_str());
} else {
n = atoi(part.substr(0,found).c_str());
nper = atoi(part.substr(found-1).c_str());\
nper = atoi(part.substr(found+1).c_str());
}
}

View File

@ -8,6 +8,13 @@ target_link_libraries(test_lattice_region PRIVATE lammps GTest::GMock GTest::GTe
add_test(NAME LatticeRegion COMMAND test_lattice_region WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(test_kim_commands test_kim_commands.cpp)
if(KIM_EXTRA_UNITTESTS)
if(CURL_FOUND)
target_compile_definitions(test_kim_commands PRIVATE -DKIM_EXTRA_UNITTESTS)
else()
message(FATAL_ERROR "CURL not found. Enabling KIM extra unit tests requires to have libcurl installed.")
endif()
endif()
target_link_libraries(test_kim_commands PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME KimCommands COMMAND test_kim_commands WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -326,7 +326,8 @@ TEST_F(KimCommandsTest, kim_property)
"3 >= 3.6 support.*",
lmp->input->one("kim_property"););
} else {
TEST_FAILURE(".*ERROR: Invalid kim_property command.*", lmp->input->one("kim_property"););
TEST_FAILURE(".*ERROR: Invalid kim_property command.*",
lmp->input->one("kim_property"););
TEST_FAILURE(".*ERROR: Invalid kim_property command.*",
lmp->input->one("kim_property create"););
TEST_FAILURE(".*ERROR: Incorrect arguments in kim_property command.\n"
@ -334,6 +335,29 @@ TEST_F(KimCommandsTest, kim_property)
"is mandatory.*",
lmp->input->one("kim_property unknown 1 atomic-mass"););
}
#if defined(KIM_EXTRA_UNITTESTS)
TEST_FAILURE(".*ERROR: Invalid 'kim_property create' command.*",
lmp->input->one("kim_property create 1"););
TEST_FAILURE(".*ERROR: Invalid 'kim_property destroy' command.*",
lmp->input->one("kim_property destroy 1 cohesive-potential-energy-cubic-crystal"););
TEST_FAILURE(".*ERROR: Invalid 'kim_property modify' command.*",
lmp->input->one("kim_property modify 1 key short-name"););
TEST_FAILURE(".*ERROR: There is no property instance to modify the content.*",
lmp->input->one("kim_property modify 1 key short-name source-value 1 fcc"););
TEST_FAILURE(".*ERROR: Invalid 'kim_property remove' command.*",
lmp->input->one("kim_property remove 1 key"););
TEST_FAILURE(".*ERROR: There is no property instance to remove the content.*",
lmp->input->one("kim_property remove 1 key short-name"););
TEST_FAILURE(".*ERROR: There is no property instance to dump the content.*",
lmp->input->one("kim_property dump results.edn"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones612_UniversalShifted__MO_959249795837_003 real");
lmp->input->one("kim_property create 1 cohesive-potential-energy-cubic-crystal");
lmp->input->one("kim_property modify 1 key short-name source-value 1 fcc");
lmp->input->one("kim_property destroy 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
#endif
}
TEST_F(KimCommandsTest, kim_query)
@ -420,48 +444,50 @@ TEST_F(KimCommandsTest, kim_query)
"units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
#if defined(KIM_EXTRA_UNITTESTS)
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
// squery = "kim_query latconst split get_lattice_constant_hexagonal ";
// squery += "crystal=[\"hcp\"] species=[\"Zr\"] units=[\"angstrom\"]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
squery = "kim_query latconst split get_lattice_constant_hexagonal ";
squery += "crystal=[\"hcp\"] species=[\"Zr\"] units=[\"angstrom\"]";
lmp->input->one(squery);
if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_1")) ==
// std::string("3.234055244384789")));
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_2")) ==
// std::string("5.167650199630013")));
ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_1")) ==
std::string("3.234055244384789")));
ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_2")) ==
std::string("5.167650199630013")));
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
// squery = "kim_query latconst list get_lattice_constant_hexagonal ";
// squery += "crystal=[hcp] species=[Zr] units=[angstrom]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
squery = "kim_query latconst list get_lattice_constant_hexagonal ";
squery += "crystal=[hcp] species=[Zr] units=[angstrom]";
lmp->input->one(squery);
if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst")) ==
// std::string("3.234055244384789 5.167650199630013")));
ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst")) ==
std::string("3.234055244384789 5.167650199630013")));
// squery = "kim_query latconst list get_lattice_constant_hexagonal ";
// squery += "crystal=[bcc] species=[Zr] units=[angstrom]";
// TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
squery = "kim_query latconst list get_lattice_constant_hexagonal ";
squery += "crystal=[bcc] species=[Zr] units=[angstrom]";
TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005 metal");
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005 metal");
// squery = "kim_query alpha get_linear_thermal_expansion_coefficient_cubic ";
// squery += "crystal=[fcc] species=[Al] units=[1/K] temperature=[293.15] ";
// squery += "temperature_units=[K]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
squery = "kim_query alpha get_linear_thermal_expansion_coefficient_cubic ";
squery += "crystal=[fcc] species=[Al] units=[1/K] temperature=[293.15] ";
squery += "temperature_units=[K]";
lmp->input->one(squery);
if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("alpha")) ==
// std::string("1.654960564704273e-05")));
ASSERT_TRUE((std::string(lmp->input->variable->retrieve("alpha")) ==
std::string("1.654960564704273e-05")));
#endif
}
} // namespace LAMMPS_NS

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
epsilon: 2.5e-13
epsilon: 5e-13
prerequisites: ! |
atom full
angle harmonic

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
epsilon: 2.5e-13
epsilon: 5e-13
prerequisites: ! |
atom full
angle table

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
epsilon: 2.5e-13
epsilon: 5e-13
prerequisites: ! |
atom full
angle table

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
epsilon: 5e-12
epsilon: 1e-11
prerequisites: ! |
pair eam/fs
pre_commands: ! ""

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:39 202
epsilon: 5e-12
epsilon: 9e-12
prerequisites: ! |
atom full
fix addforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:39 202
epsilon: 5e-12
epsilon: 2e-11
prerequisites: ! |
atom full
fix addforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 5e-12
epsilon: 2e-11
prerequisites: ! |
atom full
fix aveforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 2e-11
epsilon: 2.5e-11
prerequisites: ! |
atom full
fix aveforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 1e-14
epsilon: 5e-14
prerequisites: ! |
atom full
fix drag

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix heat

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 2e-14
epsilon: 4e-14
prerequisites: ! |
atom full
fix momentum

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 2e-12
epsilon: 4e-11
prerequisites: ! |
atom full
fix npt

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 5e-13
epsilon: 2e-12
prerequisites: ! |
atom full
fix npt

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:40 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix nve

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:41 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix nve/limit

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:41 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix nve/noforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:41 202
epsilon: 5e-14
epsilon: 2e-13
prerequisites: ! |
atom full
fix nvt

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:41 202
epsilon: 2e-13
epsilon: 2e-12
prerequisites: ! |
atom full
fix press/berendsen

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:41 202
epsilon: 9e-12
epsilon: 1e-10
prerequisites: ! |
atom full
fix rattle

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 22:36:55 202
epsilon: 5e-13
epsilon: 6.5e-13
prerequisites: ! |
atom full
fix rigid/nph/small

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:42 202
epsilon: 5e-12
epsilon: 2e-11
prerequisites: ! |
atom full
fix setforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:42 202
epsilon: 5e-12
epsilon: 1e-11
prerequisites: ! |
atom full
fix setforce

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:42 202
epsilon: 2e-12
epsilon: 3e-10
prerequisites: ! |
atom full
fix shake

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:42 202
epsilon: 2e-12
epsilon: 3.5e-11
prerequisites: ! |
atom full
fix shake

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:42 202
epsilon: 2e-14
epsilon: 1e-11
prerequisites: ! |
atom full
fix spring/chunk

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 2e-14
epsilon: 5e-14
prerequisites: ! |
atom full
fix spring/self

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix temp/berendsen

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix temp/csld

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix temp/csvr

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 2e-14
epsilon: 3e-14
prerequisites: ! |
atom full
fix wall/harmonic

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 5e-14
prerequisites: ! |
atom full
fix wall/lj1043

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix wall/lj126

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 2e-14
prerequisites: ! |
atom full
fix wall/lj93

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:43 202
epsilon: 1e-14
epsilon: 4e-14
prerequisites: ! |
atom full
fix wall/morse

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:39 202
epsilon: 2e-13
epsilon: 3e-13
prerequisites: ! |
atom full
pair tip4p/long

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:39 202
epsilon: 2e-13
epsilon: 5e-13
prerequisites: ! |
atom full
pair tip4p/long

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:31 202
epsilon: 1e-12
epsilon: 4e-12
prerequisites: ! |
pair polymorphic
pre_commands: ! |

Some files were not shown because too many files have changed in this diff Show More